]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.15
authorSasha Levin <sashal@kernel.org>
Tue, 10 Jun 2025 11:54:34 +0000 (07:54 -0400)
committerSasha Levin <sashal@kernel.org>
Tue, 10 Jun 2025 11:54:34 +0000 (07:54 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
660 files changed:
queue-6.15/accel-amdxdna-fix-incorrect-size-of-ert_start_npu-co.patch [new file with mode: 0644]
queue-6.15/accel-ivpu-reorder-doorbell-unregister-and-command-q.patch [new file with mode: 0644]
queue-6.15/acpi-osi-stop-advertising-support-for-3.0-_scp-exten.patch [new file with mode: 0644]
queue-6.15/acpi-platform_profile-avoid-initializing-on-non-acpi.patch [new file with mode: 0644]
queue-6.15/acpi-resource-fix-a-typo-for-mechrevo-in-irq1_edge_l.patch [new file with mode: 0644]
queue-6.15/acpi-thermal-execute-_scp-before-reading-trip-points.patch [new file with mode: 0644]
queue-6.15/acpica-exserial-don-t-forget-to-handle-ffixedhw-opre.patch [new file with mode: 0644]
queue-6.15/af_packet-move-notifier-s-packet_dev_mc-out-of-rcu-c.patch [new file with mode: 0644]
queue-6.15/alsa-core-fix-up-bus-match-const-issues.patch [new file with mode: 0644]
queue-6.15/alsa-hda-allow-to-fetch-hlink-by-id.patch [new file with mode: 0644]
queue-6.15/arm-aspeed-don-t-select-sram.patch [new file with mode: 0644]
queue-6.15/arm-dts-at91-at91sam9263-fix-nand-chip-selects.patch [new file with mode: 0644]
queue-6.15/arm-dts-at91-usb_a9263-fix-gpio-for-dataflash-chip-s.patch [new file with mode: 0644]
queue-6.15/arm-dts-qcom-apq8064-add-missing-clocks-to-the-timer.patch [new file with mode: 0644]
queue-6.15/arm-dts-qcom-apq8064-merge-hw-splinlock-into-corresp.patch [new file with mode: 0644]
queue-6.15/arm-dts-qcom-apq8064-move-replicator-out-of-soc-node.patch [new file with mode: 0644]
queue-6.15/arm64-defconfig-mediatek-enable-phy-drivers.patch [new file with mode: 0644]
queue-6.15/arm64-dts-allwinner-a100-set-maximum-mmc-frequency.patch [new file with mode: 0644]
queue-6.15/arm64-dts-imx8mm-beacon-fix-rtc-capacitive-load.patch [new file with mode: 0644]
queue-6.15/arm64-dts-imx8mm-beacon-set-sai5-mclk-direction-to-o.patch [new file with mode: 0644]
queue-6.15/arm64-dts-imx8mn-beacon-fix-rtc-capacitive-load.patch [new file with mode: 0644]
queue-6.15/arm64-dts-imx8mn-beacon-set-sai5-mclk-direction-to-o.patch [new file with mode: 0644]
queue-6.15/arm64-dts-imx8mp-beacon-fix-rtc-capacitive-load.patch [new file with mode: 0644]
queue-6.15/arm64-dts-mediatek-mt6357-drop-regulator-fixed-compa.patch [new file with mode: 0644]
queue-6.15/arm64-dts-mediatek-mt8188-fix-iommu-device-for-rdma0.patch [new file with mode: 0644]
queue-6.15/arm64-dts-mediatek-mt8195-reparent-vdec1-2-and-venc1.patch [new file with mode: 0644]
queue-6.15/arm64-dts-mediatek-mt8390-genio-common-set-ssusb2-de.patch [new file with mode: 0644]
queue-6.15/arm64-dts-mt6359-add-missing-compatible-property-to-.patch [new file with mode: 0644]
queue-6.15/arm64-dts-mt6359-rename-rtc-node-to-match-binding-ex.patch [new file with mode: 0644]
queue-6.15/arm64-dts-mt8183-add-port-node-to-mt8183.dtsi.patch [new file with mode: 0644]
queue-6.15/arm64-dts-qcom-ipq9574-fix-the-msi-interrupt-numbers.patch [new file with mode: 0644]
queue-6.15/arm64-dts-qcom-ipq9574-fix-usb-vdd-info.patch [new file with mode: 0644]
queue-6.15/arm64-dts-qcom-msm8998-remove-mdss_hdmi_phy-phandle-.patch [new file with mode: 0644]
queue-6.15/arm64-dts-qcom-msm8998-use-the-header-with-dsi-phy-c.patch [new file with mode: 0644]
queue-6.15/arm64-dts-qcom-qcm2290-fix-some-of-qup-interconnects.patch [new file with mode: 0644]
queue-6.15/arm64-dts-qcom-qcs615-fix-up-ufs-clocks.patch [new file with mode: 0644]
queue-6.15/arm64-dts-qcom-qcs615-remove-disallowed-property-in-.patch [new file with mode: 0644]
queue-6.15/arm64-dts-qcom-qcs8300-partially-revert-arm64-dts-qc.patch [new file with mode: 0644]
queue-6.15/arm64-dts-qcom-sa8775p-partially-revert-arm64-dts-qc.patch [new file with mode: 0644]
queue-6.15/arm64-dts-qcom-sc8280xp-x13s-drop-duplicate-dmic-sup.patch [new file with mode: 0644]
queue-6.15/arm64-dts-qcom-sda660-ifc6560-fix-dt-validate-warnin.patch [new file with mode: 0644]
queue-6.15/arm64-dts-qcom-sdm660-lavender-add-missing-usb-phy-s.patch [new file with mode: 0644]
queue-6.15/arm64-dts-qcom-sdm660-xiaomi-lavender-add-missing-sd.patch [new file with mode: 0644]
queue-6.15/arm64-dts-qcom-sdm845-starqltechn-fix-usb-regulator-.patch [new file with mode: 0644]
queue-6.15/arm64-dts-qcom-sdm845-starqltechn-refactor-node-orde.patch [new file with mode: 0644]
queue-6.15/arm64-dts-qcom-sdm845-starqltechn-remove-excess-rese.patch [new file with mode: 0644]
queue-6.15/arm64-dts-qcom-sdm845-starqltechn-remove-wifi.patch [new file with mode: 0644]
queue-6.15/arm64-dts-qcom-sm8250-fix-cpu7-opp-table.patch [new file with mode: 0644]
queue-6.15/arm64-dts-qcom-sm8350-reenable-crypto-cryptobam.patch [new file with mode: 0644]
queue-6.15/arm64-dts-qcom-sm8550-add-missing-cpu-cfg-interconne.patch [new file with mode: 0644]
queue-6.15/arm64-dts-qcom-sm8550-use-icc-tag-for-all-interconne.patch [new file with mode: 0644]
queue-6.15/arm64-dts-qcom-sm8650-add-missing-cpu-cfg-interconne.patch [new file with mode: 0644]
queue-6.15/arm64-dts-qcom-sm8650-add-the-missing-l2-cache-node.patch [new file with mode: 0644]
queue-6.15/arm64-dts-qcom-sm8650-fix-domain-idle-state-for-cpu2.patch [new file with mode: 0644]
queue-6.15/arm64-dts-qcom-sm8650-setup-gpu-thermal-with-higher-.patch [new file with mode: 0644]
queue-6.15/arm64-dts-qcom-sm8750-correct-clocks-property-for-ua.patch [new file with mode: 0644]
queue-6.15/arm64-dts-qcom-sm8750-fix-cluster-hierarchy-for-idle.patch [new file with mode: 0644]
queue-6.15/arm64-dts-qcom-x1e001de-devkit-describe-usb-retimers.patch [new file with mode: 0644]
queue-6.15/arm64-dts-qcom-x1e001de-devkit-fix-pin-config-for-us.patch [new file with mode: 0644]
queue-6.15/arm64-dts-qcom-x1e80100-mark-usb_2-as-dma-coherent.patch [new file with mode: 0644]
queue-6.15/arm64-dts-qcom-x1e80100-romulus-keep-l12b-and-l15b-a.patch [new file with mode: 0644]
queue-6.15/arm64-dts-renesas-white-hawk-ard-audio-fix-tpu0-grou.patch [new file with mode: 0644]
queue-6.15/arm64-dts-renesas-white-hawk-single-improve-ethernet.patch [new file with mode: 0644]
queue-6.15/arm64-dts-rockchip-add-missing-uart3-interrupt-for-r.patch [new file with mode: 0644]
queue-6.15/arm64-dts-rockchip-add-vcc-supply-to-spi-flash-on-rk.patch [new file with mode: 0644]
queue-6.15/arm64-dts-rockchip-disable-unrouted-usb-controllers-.patch [new file with mode: 0644]
queue-6.15/arm64-dts-rockchip-disable-unrouted-usb-controllers-.patch-25959 [new file with mode: 0644]
queue-6.15/arm64-dts-rockchip-move-shmem-memory-to-reserved-mem.patch [new file with mode: 0644]
queue-6.15/arm64-dts-rockchip-update-emmc-for-nanopi-r5-series.patch [new file with mode: 0644]
queue-6.15/arm64-dts-ti-k3-j721e-common-proc-board-enable-ospi1.patch [new file with mode: 0644]
queue-6.15/arm64-fpsimd-avoid-clobbering-kernel-fpsimd-state-wi.patch [new file with mode: 0644]
queue-6.15/arm64-fpsimd-avoid-res0-bits-in-the-sme-trap-handler.patch [new file with mode: 0644]
queue-6.15/arm64-fpsimd-avoid-warning-when-sve_to_fpsimd-is-unu.patch [new file with mode: 0644]
queue-6.15/arm64-fpsimd-discard-stale-cpu-state-when-handling-s.patch [new file with mode: 0644]
queue-6.15/arm64-fpsimd-don-t-corrupt-fpmr-when-streaming-mode-.patch [new file with mode: 0644]
queue-6.15/arm64-fpsimd-fix-merging-of-fpsimd-state-during-sign.patch [new file with mode: 0644]
queue-6.15/arm64-fpsimd-reset-fpmr-upon-exec.patch [new file with mode: 0644]
queue-6.15/arm64-support-arm64_va_bits-52-when-setting-arch_mma.patch [new file with mode: 0644]
queue-6.15/arm64-tegra-add-uartd-serial-alias-for-jetson-tx1-mo.patch [new file with mode: 0644]
queue-6.15/arm64-tegra-drop-remaining-serial-clock-names-and-re.patch [new file with mode: 0644]
queue-6.15/asoc-apple-mca-constrain-channels-according-to-tdm-m.patch [new file with mode: 0644]
queue-6.15/asoc-codecs-hda-fix-rpm-usage-count-underflow.patch [new file with mode: 0644]
queue-6.15/asoc-intel-avs-fix-deadlock-when-the-failing-ipc-is-.patch [new file with mode: 0644]
queue-6.15/asoc-intel-avs-fix-kcalloc-sizes.patch [new file with mode: 0644]
queue-6.15/asoc-intel-avs-fix-paths-in-module_firmware-hints.patch [new file with mode: 0644]
queue-6.15/asoc-intel-avs-fix-possible-null-ptr-deref-when-init.patch [new file with mode: 0644]
queue-6.15/asoc-intel-avs-fix-pplcxfmt-calculation.patch [new file with mode: 0644]
queue-6.15/asoc-intel-avs-ignore-vendor-space-manipulation-for-.patch [new file with mode: 0644]
queue-6.15/asoc-intel-avs-pcm-operations-for-lnl-based-platform.patch [new file with mode: 0644]
queue-6.15/asoc-intel-avs-read-hw-capabilities-when-possible.patch [new file with mode: 0644]
queue-6.15/asoc-intel-avs-relocate-dsp-status-registers.patch [new file with mode: 0644]
queue-6.15/asoc-intel-avs-verify-content-returned-by-parse_int_.patch [new file with mode: 0644]
queue-6.15/asoc-intel-avs-verify-kcalloc-status-when-setting-co.patch [new file with mode: 0644]
queue-6.15/asoc-mediatek-mt8195-set-etdm1-2-in-out-to-comp_dumm.patch [new file with mode: 0644]
queue-6.15/asoc-sof-amd-add-missing-acp-descriptor-field.patch [new file with mode: 0644]
queue-6.15/asoc-sof-ipc4-pcm-adjust-pipeline_list-pipelines-all.patch [new file with mode: 0644]
queue-6.15/asoc-tas2764-enable-main-irqs.patch [new file with mode: 0644]
queue-6.15/asoc-tas2764-reinit-cache-on-part-reset.patch [new file with mode: 0644]
queue-6.15/asoc-ti-omap-hdmi-re-add-dai_link-platform-to-fix-ca.patch [new file with mode: 0644]
queue-6.15/backlight-pm8941-add-null-check-in-wled_configure.patch [new file with mode: 0644]
queue-6.15/blk-throttle-fix-wrong-tg-bytes-io-_disp-update-in-_.patch [new file with mode: 0644]
queue-6.15/block-flip-iter-directions-in-blk_rq_integrity_map_u.patch [new file with mode: 0644]
queue-6.15/bluetooth-btintel-check-dsbr-size-from-efi-variable.patch [new file with mode: 0644]
queue-6.15/bluetooth-iso-fix-not-using-sid-from-adv-report.patch [new file with mode: 0644]
queue-6.15/bluetooth-l2cap-fix-not-responding-with-l2cap_cr_le_.patch [new file with mode: 0644]
queue-6.15/bluetooth-mgmt-iterate-over-mesh-commands-in-mgmt_me.patch [new file with mode: 0644]
queue-6.15/bluetooth-mgmt-reject-malformed-hci_cmd_sync-command.patch [new file with mode: 0644]
queue-6.15/bluetooth-separate-cis_link-and-bis_link-link-types.patch [new file with mode: 0644]
queue-6.15/bonding-assign-random-address-if-device-address-is-s.patch [new file with mode: 0644]
queue-6.15/bonding-fix-multiple-long-standing-offload-races.patch [new file with mode: 0644]
queue-6.15/bonding-mark-active-offloaded-xfrm_states.patch [new file with mode: 0644]
queue-6.15/bpf-allow-xdp-dev-bound-programs-to-perform-xdp_redi.patch [new file with mode: 0644]
queue-6.15/bpf-avoid-__bpf_prog_ret0_warn-when-jit-fails.patch [new file with mode: 0644]
queue-6.15/bpf-check-link_create.flags-parameter-for-multi_kpro.patch [new file with mode: 0644]
queue-6.15/bpf-check-link_create.flags-parameter-for-multi_upro.patch [new file with mode: 0644]
queue-6.15/bpf-clarify-the-meaning-of-bpf_f_pseudo_hdr.patch [new file with mode: 0644]
queue-6.15/bpf-do-not-include-stack-ptr-register-in-precision-b.patch [new file with mode: 0644]
queue-6.15/bpf-fix-ktls-panic-with-sockmap.patch [new file with mode: 0644]
queue-6.15/bpf-fix-l4-csum-update-on-ipv6-in-checksum_complete.patch [new file with mode: 0644]
queue-6.15/bpf-fix-uninitialized-values-in-bpf_-core-probe-_rea.patch [new file with mode: 0644]
queue-6.15/bpf-fix-warn-in-get_bpf_raw_tp_regs.patch [new file with mode: 0644]
queue-6.15/bpf-revert-bpf-remove-unnecessary-rcu_read_-lock-unl.patch [new file with mode: 0644]
queue-6.15/bpf-sockmap-avoid-using-sk_socket-after-free-when-se.patch [new file with mode: 0644]
queue-6.15/bpf-sockmap-fix-duplicated-data-transmission.patch [new file with mode: 0644]
queue-6.15/bpf-sockmap-fix-panic-when-calling-skb_linearize.patch [new file with mode: 0644]
queue-6.15/bpftool-fix-regression-of-bpftool-cgroup-tree-einval.patch [new file with mode: 0644]
queue-6.15/brd-fix-aligned_sector-from-brd_do_discard.patch [new file with mode: 0644]
queue-6.15/brd-fix-discard-end-sector.patch [new file with mode: 0644]
queue-6.15/btrfs-fix-invalid-data-space-release-when-truncating.patch [new file with mode: 0644]
queue-6.15/btrfs-fix-wrong-start-offset-for-delalloc-space-rele.patch [new file with mode: 0644]
queue-6.15/btrfs-scrub-fix-a-wrong-error-type-when-metadata-byt.patch [new file with mode: 0644]
queue-6.15/btrfs-scrub-update-device-stats-when-an-error-is-det.patch [new file with mode: 0644]
queue-6.15/bus-fsl-mc-fix-double-free-on-mc_dev.patch [new file with mode: 0644]
queue-6.15/bus-fsl_mc-fix-driver_managed_dma-check.patch [new file with mode: 0644]
queue-6.15/calipso-don-t-call-calipso-functions-for-af_inet-sk.patch [new file with mode: 0644]
queue-6.15/char-tlclk-fix-correct-sysfs-directory-path-for-tlcl.patch [new file with mode: 0644]
queue-6.15/cifs-fix-validation-of-smb1-query-reparse-point-resp.patch [new file with mode: 0644]
queue-6.15/clk-bcm-rpi-add-null-check-in-raspberrypi_clk_regist.patch [new file with mode: 0644]
queue-6.15/clk-qcom-camcc-sm6350-add-_wait_val-values-for-gdscs.patch [new file with mode: 0644]
queue-6.15/clk-qcom-dispcc-sm6350-add-_wait_val-values-for-gdsc.patch [new file with mode: 0644]
queue-6.15/clk-qcom-gcc-msm8939-fix-mclk0-mclk1-for-24-mhz.patch [new file with mode: 0644]
queue-6.15/clk-qcom-gcc-sm6350-add-_wait_val-values-for-gdscs.patch [new file with mode: 0644]
queue-6.15/clk-qcom-gpucc-sm6350-add-_wait_val-values-for-gdscs.patch [new file with mode: 0644]
queue-6.15/clk-test-forward-declare-struct-of_phandle_args-in-k.patch [new file with mode: 0644]
queue-6.15/clone_private_mnt-make-sure-that-caller-has-cap_sys_.patch [new file with mode: 0644]
queue-6.15/coresight-catu-introduce-refcount-and-spinlock-for-e.patch [new file with mode: 0644]
queue-6.15/coresight-core-disable-helpers-for-devices-that-fail.patch [new file with mode: 0644]
queue-6.15/coresight-etm4-fix-missing-disable-active-config.patch [new file with mode: 0644]
queue-6.15/coresight-etm4x-fix-timestamp-bit-field-handling.patch [new file with mode: 0644]
queue-6.15/coresight-fixes-device-s-owner-field-for-registered-.patch [new file with mode: 0644]
queue-6.15/coresight-holding-cscfg_csdev_lock-while-removing-cs.patch [new file with mode: 0644]
queue-6.15/coresight-prevent-deactivate-active-config-while-ena.patch [new file with mode: 0644]
queue-6.15/coresight-tmc-fix-failure-to-disable-enable-etf-afte.patch [new file with mode: 0644]
queue-6.15/counter-interrupt-cnt-protect-enable-disable-ops-wit.patch [new file with mode: 0644]
queue-6.15/crypto-api-redo-lookup-on-eexist.patch [new file with mode: 0644]
queue-6.15/crypto-ecdsa-fix-enc-dec-size-reported-by-keyctl_pke.patch [new file with mode: 0644]
queue-6.15/crypto-ecdsa-fix-nist-p521-key-size-reported-by-keyc.patch [new file with mode: 0644]
queue-6.15/crypto-iaa-do-not-clobber-req-base.data.patch [new file with mode: 0644]
queue-6.15/crypto-krb5-fix-change-to-use-sg-miter-to-use-offset.patch [new file with mode: 0644]
queue-6.15/crypto-lrw-only-add-ecb-if-it-is-not-already-there.patch [new file with mode: 0644]
queue-6.15/crypto-marvell-cesa-avoid-empty-transfer-descriptor.patch [new file with mode: 0644]
queue-6.15/crypto-marvell-cesa-handle-zero-length-skcipher-requ.patch [new file with mode: 0644]
queue-6.15/crypto-sun8i-ce-cipher-fix-error-handling-in-sun8i_c.patch [new file with mode: 0644]
queue-6.15/crypto-sun8i-ce-hash-fix-error-handling-in-sun8i_ce_.patch [new file with mode: 0644]
queue-6.15/crypto-sun8i-ce-move-fallback-ahash_request-to-the-e.patch [new file with mode: 0644]
queue-6.15/crypto-sun8i-ce-undo-runtime-pm-changes-during-drive.patch [new file with mode: 0644]
queue-6.15/crypto-sun8i-ss-do-not-use-sg_dma_len-before-calling.patch [new file with mode: 0644]
queue-6.15/crypto-xts-only-add-ecb-if-it-is-not-already-there.patch [new file with mode: 0644]
queue-6.15/crypto-zynqmp-sha-add-locking.patch [new file with mode: 0644]
queue-6.15/dm-don-t-change-md-if-dm_table_set_restrictions-fail.patch [new file with mode: 0644]
queue-6.15/dm-fix-dm_blk_report_zones.patch [new file with mode: 0644]
queue-6.15/dm-flakey-error-all-ios-when-num_features-is-absent.patch [new file with mode: 0644]
queue-6.15/dm-flakey-make-corrupting-read-bios-work.patch [new file with mode: 0644]
queue-6.15/dm-free-table-mempools-if-not-used-in-__bind.patch [new file with mode: 0644]
queue-6.15/dm-handle-failures-in-dm_table_set_restrictions.patch [new file with mode: 0644]
queue-6.15/dm-limit-swapping-tables-for-devices-with-zone-write.patch [new file with mode: 0644]
queue-6.15/dmaengine-ti-add-null-check-in-udma_probe.patch [new file with mode: 0644]
queue-6.15/do_change_type-refuse-to-operate-on-unmounted-not-ou.patch [new file with mode: 0644]
queue-6.15/driver-net-ethernet-mtk_star_emac-fix-suspend-resume.patch [new file with mode: 0644]
queue-6.15/drivers-hv-always-select-config_sysfb-for-hyper-v-gu.patch [new file with mode: 0644]
queue-6.15/drm-amd-display-don-t-check-for-null-divisor-in-fixp.patch [new file with mode: 0644]
queue-6.15/drm-amd-pp-fix-potential-null-pointer-dereference-in.patch [new file with mode: 0644]
queue-6.15/drm-amdgpu-gfx10-refine-cleaner-shader-for-gfx10.1.1.patch [new file with mode: 0644]
queue-6.15/drm-amdgpu-refine-cleaner-shader-mec-firmware-versio.patch [new file with mode: 0644]
queue-6.15/drm-bridge-analogix_dp-add-support-to-get-panel-from.patch [new file with mode: 0644]
queue-6.15/drm-bridge-analogix_dp-fix-clk-disable-removal.patch [new file with mode: 0644]
queue-6.15/drm-bridge-analogix_dp-remove-config_pm-related-chec.patch [new file with mode: 0644]
queue-6.15/drm-bridge-analogix_dp-remove-the-unnecessary-calls-.patch [new file with mode: 0644]
queue-6.15/drm-bridge-lt9611uxc-fix-an-error-handling-path-in-l.patch [new file with mode: 0644]
queue-6.15/drm-ci-fix-merge-request-rules.patch [new file with mode: 0644]
queue-6.15/drm-connector-only-call-hdmi-audio-helper-plugged-cb.patch [new file with mode: 0644]
queue-6.15/drm-i915-display-fix-u32-overflow-in-snps-phy-hdmi-p.patch [new file with mode: 0644]
queue-6.15/drm-i915-dp_mst-use-the-correct-connector-while-comp.patch [new file with mode: 0644]
queue-6.15/drm-i915-guc-check-if-expecting-reply-before-decreme.patch [new file with mode: 0644]
queue-6.15/drm-i915-guc-handle-race-condition-where-wakeref-cou.patch [new file with mode: 0644]
queue-6.15/drm-i915-psr-fix-using-wrong-mask-in-reg_field_prep.patch [new file with mode: 0644]
queue-6.15/drm-mediatek-fix-kobject-put-for-component-sub-drive.patch [new file with mode: 0644]
queue-6.15/drm-mediatek-mtk_drm_drv-fix-kobject-put-for-mtk_mut.patch [new file with mode: 0644]
queue-6.15/drm-mediatek-mtk_drm_drv-unbind-secondary-mmsys-comp.patch [new file with mode: 0644]
queue-6.15/drm-msm-a6xx-disable-rgb565_predicator-on-adreno-7c3.patch [new file with mode: 0644]
queue-6.15/drm-msm-dp-account-for-lttprs-capabilities.patch [new file with mode: 0644]
queue-6.15/drm-msm-dp-fix-support-of-lttpr-initialization.patch [new file with mode: 0644]
queue-6.15/drm-msm-dp-prepare-for-link-training-per-segment-for.patch [new file with mode: 0644]
queue-6.15/drm-msm-dpu-enable-smartdma-on-sc8180x.patch [new file with mode: 0644]
queue-6.15/drm-msm-dpu-enable-smartdma-on-sm8150.patch [new file with mode: 0644]
queue-6.15/drm-msm-dpu-remove-dsc-feature-bit-for-pingpong-on-m.patch [new file with mode: 0644]
queue-6.15/drm-msm-dpu-remove-dsc-feature-bit-for-pingpong-on-m.patch-13942 [new file with mode: 0644]
queue-6.15/drm-msm-dpu-remove-dsc-feature-bit-for-pingpong-on-m.patch-8756 [new file with mode: 0644]
queue-6.15/drm-panel-samsung-sofef00-drop-s6e3fc2x01-support.patch [new file with mode: 0644]
queue-6.15/drm-panel-simple-fix-the-warnings-for-the-evervision.patch [new file with mode: 0644]
queue-6.15/drm-panic-clean-clippy-warning.patch [new file with mode: 0644]
queue-6.15/drm-panic-use-a-decimal-fifo-to-avoid-u64-by-u64-div.patch [new file with mode: 0644]
queue-6.15/drm-panthor-call-panthor_gpu_coherency_init-after-pm.patch [new file with mode: 0644]
queue-6.15/drm-panthor-fix-gpu_coherency_ace-_lite-definitions.patch [new file with mode: 0644]
queue-6.15/drm-panthor-fix-the-panthor_gpu_coherency_init-error.patch [new file with mode: 0644]
queue-6.15/drm-panthor-update-panthor_mmu-irq-mask-when-needed.patch [new file with mode: 0644]
queue-6.15/drm-rcar-du-fix-memory-leak-in-rcar_du_vsps_init.patch [new file with mode: 0644]
queue-6.15/drm-tegra-rgb-fix-the-unbound-reference-count.patch [new file with mode: 0644]
queue-6.15/drm-v3d-associate-a-v3d-tech-revision-to-all-support.patch [new file with mode: 0644]
queue-6.15/drm-v3d-client-ranges-from-axi_ids-are-different-wit.patch [new file with mode: 0644]
queue-6.15/drm-v3d-fix-client-obtained-from-axi_ids-on-v3d-4.1.patch [new file with mode: 0644]
queue-6.15/drm-vc4-hdmi-call-hdmi-hotplug-helper-on-disconnect.patch [new file with mode: 0644]
queue-6.15/drm-vc4-tests-retry-pv-muxing-tests-when-edeadlk.patch [new file with mode: 0644]
queue-6.15/drm-vc4-tests-stop-allocating-the-state-in-test-init.patch [new file with mode: 0644]
queue-6.15/drm-vc4-tests-use-return-instead-of-assert.patch [new file with mode: 0644]
queue-6.15/drm-vkms-adjust-vkms_state-active_planes-allocation-.patch [new file with mode: 0644]
queue-6.15/drm-vmwgfx-add-error-path-for-xa_store-in-vmw_bo_add.patch [new file with mode: 0644]
queue-6.15/drm-vmwgfx-add-seqno-waiter-for-sync_files.patch [new file with mode: 0644]
queue-6.15/drm-vmwgfx-fix-dumb-buffer-leak.patch [new file with mode: 0644]
queue-6.15/drm-xe-add-missing-documentation-of-rpa_freq.patch [new file with mode: 0644]
queue-6.15/drm-xe-d3cold-set-power-state-to-d3cold-during-s2idl.patch [new file with mode: 0644]
queue-6.15/drm-xe-guc-don-t-expose-guc-privileged-debugfs-files.patch [new file with mode: 0644]
queue-6.15/drm-xe-guc-make-creation-of-slpc-debugfs-files-condi.patch [new file with mode: 0644]
queue-6.15/drm-xe-guc-refactor-guc-debugfs-initialization.patch [new file with mode: 0644]
queue-6.15/drm-xe-make-xe_gt_freq-part-of-the-documentation.patch [new file with mode: 0644]
queue-6.15/drm-xe-pxp-clarify-pxp-queue-creation-behavior-if-px.patch [new file with mode: 0644]
queue-6.15/drm-xe-pxp-use-the-correct-define-in-the-set_propert.patch [new file with mode: 0644]
queue-6.15/drm-xe-rework-eviction-rejection-of-bound-external-b.patch [new file with mode: 0644]
queue-6.15/drm-xe-vm-move-xe_svm_init-earlier.patch [new file with mode: 0644]
queue-6.15/drm-xe-vsec-fix-config_intel_vsec-dependency.patch [new file with mode: 0644]
queue-6.15/drm-xlnx-zynqmp_dpsub-fix-kconfig-dependencies-for-a.patch [new file with mode: 0644]
queue-6.15/dt-bindings-soc-fsl-qman-fqd-fix-reserved-memory.yam.patch [new file with mode: 0644]
queue-6.15/dt-bindings-vendor-prefixes-add-liontron-name.patch [new file with mode: 0644]
queue-6.15/edac-bluefield-don-t-use-bluefield_edac_readl-result.patch [new file with mode: 0644]
queue-6.15/edac-skx_common-fix-general-protection-fault.patch [new file with mode: 0644]
queue-6.15/edac-skx_common-i10nm-fix-the-loss-of-saved-rrl-for-.patch [new file with mode: 0644]
queue-6.15/efi-libstub-describe-missing-out-parameter-in-efi_lo.patch [new file with mode: 0644]
queue-6.15/erofs-avoid-using-multiple-devices-with-different-ty.patch [new file with mode: 0644]
queue-6.15/erofs-fix-file-handle-encoding-for-64-bit-nids.patch [new file with mode: 0644]
queue-6.15/exportfs-require-fh_to_parent-to-encode-connectable-.patch [new file with mode: 0644]
queue-6.15/f2fs-clean-up-unnecessary-indentation.patch [new file with mode: 0644]
queue-6.15/f2fs-clean-up-w-fscrypt_is_bounce_page.patch [new file with mode: 0644]
queue-6.15/f2fs-fix-to-correct-check-conditions-in-f2fs_cross_r.patch [new file with mode: 0644]
queue-6.15/f2fs-fix-to-detect-gcing-page-in-f2fs_is_cp_guarante.patch [new file with mode: 0644]
queue-6.15/f2fs-fix-to-do-sanity-check-on-sbi-total_valid_block.patch [new file with mode: 0644]
queue-6.15/f2fs-fix-to-skip-f2fs_balance_fs-if-checkpoint-is-di.patch [new file with mode: 0644]
queue-6.15/f2fs-prevent-the-current-section-from-being-selected.patch [new file with mode: 0644]
queue-6.15/f2fs-use-d_inode-dentry-cleanup-dentry-d_inode.patch [new file with mode: 0644]
queue-6.15/f2fs-zone-fix-to-avoid-inconsistence-in-between-sit-.patch [new file with mode: 0644]
queue-6.15/f2fs-zone-fix-to-calculate-first_zoned_segno-correct.patch [new file with mode: 0644]
queue-6.15/fbdev-core-fbcvt-avoid-division-by-0-in-fb_cvt_hperi.patch [new file with mode: 0644]
queue-6.15/finish_automount-don-t-leak-mnt_locked-from-parent-t.patch [new file with mode: 0644]
queue-6.15/firmware-exynos-acpm-fix-reading-longer-results.patch [new file with mode: 0644]
queue-6.15/firmware-exynos-acpm-silence-eprobe_defer-error-on-b.patch [new file with mode: 0644]
queue-6.15/firmware-psci-fix-refcount-leak-in-psci_dt_init.patch [new file with mode: 0644]
queue-6.15/firmware-sdei-allow-sdei-initialization-without-acpi.patch [new file with mode: 0644]
queue-6.15/fix-propagation-graph-breakage-by-move_mount_set_gro.patch [new file with mode: 0644]
queue-6.15/fix-sock_exceed_buf_limit-not-being-triggered-in-__s.patch [new file with mode: 0644]
queue-6.15/fpga-fix-potential-null-pointer-deref-in-fpga_mgr_te.patch [new file with mode: 0644]
queue-6.15/fs-allow-clone_private_mount-for-a-path-on-real-root.patch [new file with mode: 0644]
queue-6.15/fs-convert-mount-flags-to-enum.patch [new file with mode: 0644]
queue-6.15/fs-dax-fix-don-t-skip-locked-entries-when-scanning-e.patch [new file with mode: 0644]
queue-6.15/fs-fhandle.c-fix-a-race-in-call-of-has_locked_childr.patch [new file with mode: 0644]
queue-6.15/fs-ntfs3-add-missing-direct_io-in-ntfs_aops_cmpr.patch [new file with mode: 0644]
queue-6.15/fs-ntfs3-handle-hdr_first_de-return-value.patch [new file with mode: 0644]
queue-6.15/genksyms-fix-enum-consts-from-a-reference-affecting-.patch [new file with mode: 0644]
queue-6.15/gfs2-deallocate-inodes-in-gfs2_create_inode.patch [new file with mode: 0644]
queue-6.15/gfs2-don-t-start-unnecessary-transactions-during-log.patch [new file with mode: 0644]
queue-6.15/gfs2-gfs2_create_inode-error-handling-fix.patch [new file with mode: 0644]
queue-6.15/gfs2-move-gfs2_dinode_dealloc.patch [new file with mode: 0644]
queue-6.15/gfs2-move-gfs2_trans_add_databufs.patch [new file with mode: 0644]
queue-6.15/gfs2-move-gif_alloc_failed-check-out-of-gfs2_ea_deal.patch [new file with mode: 0644]
queue-6.15/gfs2-replace-sd_aspace-with-sd_inode.patch [new file with mode: 0644]
queue-6.15/gve-add-missing-null-check-for-gve_alloc_pending_pac.patch [new file with mode: 0644]
queue-6.15/gve-fix-rx_buffers_posted-stat-to-report-per-queue-f.patch [new file with mode: 0644]
queue-6.15/hid-hid_appletb_bl-should-depend-on-x86.patch [new file with mode: 0644]
queue-6.15/hid-hid_appletb_kbd-should-depend-on-x86.patch [new file with mode: 0644]
queue-6.15/hid-intel-thc-hid-intel-quicki2c-pass-correct-argume.patch [new file with mode: 0644]
queue-6.15/hisi_acc_vfio_pci-add-eq-and-aeq-interruption-restor.patch [new file with mode: 0644]
queue-6.15/hisi_acc_vfio_pci-bugfix-cache-write-back-issue.patch [new file with mode: 0644]
queue-6.15/hisi_acc_vfio_pci-bugfix-live-migration-function-wit.patch [new file with mode: 0644]
queue-6.15/hisi_acc_vfio_pci-bugfix-the-problem-of-uninstalling.patch [new file with mode: 0644]
queue-6.15/hisi_acc_vfio_pci-fix-xqe-dma-address-error.patch [new file with mode: 0644]
queue-6.15/hwmon-asus-ec-sensors-check-sensor-index-in-read_str.patch [new file with mode: 0644]
queue-6.15/iavf-centralize-watchdog-requeueing-itself.patch [new file with mode: 0644]
queue-6.15/iavf-extract-iavf_watchdog_step-out-of-iavf_watchdog.patch [new file with mode: 0644]
queue-6.15/iavf-get-rid-of-the-crit-lock.patch [new file with mode: 0644]
queue-6.15/iavf-iavf_suspend-take-rtnl-before-netdev_lock.patch [new file with mode: 0644]
queue-6.15/iavf-simplify-watchdog_task-in-terms-of-adminq-task-.patch [new file with mode: 0644]
queue-6.15/iavf-sprinkle-netdev_assert_locked-annotations.patch [new file with mode: 0644]
queue-6.15/ib-cm-drop-lockdep-assert-and-warn-when-freeing-old-.patch [new file with mode: 0644]
queue-6.15/ib-cm-use-rwlock-for-mad-agent-lock.patch [new file with mode: 0644]
queue-6.15/ice-create-new-tx-scheduler-nodes-for-new-queues-onl.patch [new file with mode: 0644]
queue-6.15/ice-fix-rebuilding-the-tx-scheduler-tree-for-large-q.patch [new file with mode: 0644]
queue-6.15/ice-fix-tx-scheduler-error-handling-in-xdp-callback.patch [new file with mode: 0644]
queue-6.15/idpf-avoid-mailbox-timeout-delays-during-reset.patch [new file with mode: 0644]
queue-6.15/idpf-fix-a-race-in-txq-wakeup.patch [new file with mode: 0644]
queue-6.15/iio-adc-ad4851-fix-ad4858-chan-pointer-handling.patch [new file with mode: 0644]
queue-6.15/iio-adc-ad7124-fix-3db-filter-frequency-reading.patch [new file with mode: 0644]
queue-6.15/iio-adc-mcp3911-fix-device-dependent-mappings-for-co.patch [new file with mode: 0644]
queue-6.15/iio-adc-pac1934-fix-typo-in-documentation-link.patch [new file with mode: 0644]
queue-6.15/iio-dac-adi-axi-dac-fix-bus-read.patch [new file with mode: 0644]
queue-6.15/iio-filter-admv8818-fix-band-4-state-15.patch [new file with mode: 0644]
queue-6.15/iio-filter-admv8818-fix-integer-overflow.patch [new file with mode: 0644]
queue-6.15/iio-filter-admv8818-fix-range-calculation.patch [new file with mode: 0644]
queue-6.15/iio-filter-admv8818-support-frequencies-2-32.patch [new file with mode: 0644]
queue-6.15/iomap-don-t-lose-folio-dropbehind-state-for-overwrit.patch [new file with mode: 0644]
queue-6.15/iommu-arm-smmu-v3-fix-incorrect-return-in-arm_smmu_a.patch [new file with mode: 0644]
queue-6.15/iommu-io-pgtable-arm-dynamically-allocate-selftest-d.patch [new file with mode: 0644]
queue-6.15/iommu-ipmmu-vmsa-avoid-wformat-security-warning.patch [new file with mode: 0644]
queue-6.15/iommu-protect-against-overflow-in-iommu_pgsize.patch [new file with mode: 0644]
queue-6.15/iommu-remove-duplicate-selection-of-dmar_table.patch [new file with mode: 0644]
queue-6.15/iov_iter-use-iov_offset-for-length-calculation-in-io.patch [new file with mode: 0644]
queue-6.15/kernfs-relax-constraint-in-draining-guard.patch [new file with mode: 0644]
queue-6.15/kselftest-arm64-fp-ptrace-fix-expected-fpmr-value-wh.patch [new file with mode: 0644]
queue-6.15/kselftest-cpufreq-get-rid-of-double-suspend-in-rtcwa.patch [new file with mode: 0644]
queue-6.15/ktls-sockmap-fix-missing-uncharge-operation.patch [new file with mode: 0644]
queue-6.15/kunit-fix-wrong-parameter-to-kunit_deactivate_static.patch [new file with mode: 0644]
queue-6.15/kunit-qemu_configs-disable-faulting-tests-on-32-bit-.patch [new file with mode: 0644]
queue-6.15/kunit-qemu_configs-sparc-explicitly-enable-config_sp.patch [new file with mode: 0644]
queue-6.15/kunit-usercopy-disable-u64-test-on-32-bit-sparc.patch [new file with mode: 0644]
queue-6.15/libbpf-fix-buffer-overflow-in-bpf_object__init_prog.patch [new file with mode: 0644]
queue-6.15/libbpf-fix-event-name-too-long-error.patch [new file with mode: 0644]
queue-6.15/libbpf-fix-implicit-memfd_create-for-bionic.patch [new file with mode: 0644]
queue-6.15/libbpf-remove-sample_period-init-in-perf_buffer.patch [new file with mode: 0644]
queue-6.15/libbpf-use-proper-errno-value-in-linker.patch [new file with mode: 0644]
queue-6.15/libbpf-use-proper-errno-value-in-nlattr.patch [new file with mode: 0644]
queue-6.15/loop-add-file_start_write-and-file_end_write.patch [new file with mode: 0644]
queue-6.15/m68k-mac-fix-macintosh_config-for-mac-ii.patch [new file with mode: 0644]
queue-6.15/mailbox-imx-fix-txdb_v2-sending.patch [new file with mode: 0644]
queue-6.15/mailbox-mchp-ipc-sbi-fix-compile_test-build-error.patch [new file with mode: 0644]
queue-6.15/mailbox-mtk-cmdq-refine-gce_gctl_value-setting.patch [new file with mode: 0644]
queue-6.15/md-raid1-raid10-don-t-handle-io-error-for-req_rahead.patch [new file with mode: 0644]
queue-6.15/media-rkvdec-fix-frame-size-enumeration.patch [new file with mode: 0644]
queue-6.15/media-synopsys-hdmirx-count-dropped-frames.patch [new file with mode: 0644]
queue-6.15/media-synopsys-hdmirx-renamed-frame_idx-to-sequence.patch [new file with mode: 0644]
queue-6.15/media-verisilicon-free-post-processor-buffers-on-err.patch [new file with mode: 0644]
queue-6.15/mei-vsc-cast-tx_buf-to-__be32-when-passed-to-cpu_to_.patch [new file with mode: 0644]
queue-6.15/mfd-exynos-lpass-avoid-calling-exynos_lpass_disable-.patch [new file with mode: 0644]
queue-6.15/mfd-exynos-lpass-fix-an-error-handling-path-in-exyno.patch [new file with mode: 0644]
queue-6.15/mfd-exynos-lpass-fix-another-error-handling-path-in-.patch [new file with mode: 0644]
queue-6.15/mfd-stmpe-spi-correct-the-name-used-in-module_device.patch [new file with mode: 0644]
queue-6.15/mips-loongson64-add-missing-interrupt-cells-for-loon.patch [new file with mode: 0644]
queue-6.15/misc-lis3lv02d-fix-correct-sysfs-directory-path-for-.patch [new file with mode: 0644]
queue-6.15/mtd-nand-ecc-mxic-fix-use-of-uninitialized-variable-.patch [new file with mode: 0644]
queue-6.15/net-airoha-add-the-capability-to-allocate-hfwd-descr.patch [new file with mode: 0644]
queue-6.15/net-airoha-fix-an-error-handling-path-in-airoha_allo.patch [new file with mode: 0644]
queue-6.15/net-airoha-initialize-ppe-updmem-source-mac-table.patch [new file with mode: 0644]
queue-6.15/net-annotate-data-races-around-cleanup_net_task.patch [new file with mode: 0644]
queue-6.15/net-dsa-b53-allow-rgmii-for-bcm63xx-rgmii-ports.patch [new file with mode: 0644]
queue-6.15/net-dsa-b53-do-not-configure-bcm63xx-s-imp-port-inte.patch [new file with mode: 0644]
queue-6.15/net-dsa-b53-do-not-enable-eee-on-bcm63xx.patch [new file with mode: 0644]
queue-6.15/net-dsa-b53-do-not-enable-rgmii-delay-on-bcm63xx.patch [new file with mode: 0644]
queue-6.15/net-dsa-b53-do-not-touch-dll_iqqd-on-bcm53115.patch [new file with mode: 0644]
queue-6.15/net-dsa-b53-implement-setting-ageing-time.patch [new file with mode: 0644]
queue-6.15/net-dsa-tag_brcm-legacy-fix-pskb_may_pull-length.patch [new file with mode: 0644]
queue-6.15/net-fix-checksum-update-for-ila-adj-transport.patch [new file with mode: 0644]
queue-6.15/net-fix-udp-gso-skb_segment-after-pull-from-frag_lis.patch [new file with mode: 0644]
queue-6.15/net-lan743x-fix-phy-reset-handling-during-initializa.patch [new file with mode: 0644]
queue-6.15/net-lan743x-rename-lan743x_reset_phy-to-lan743x_hw_r.patch [new file with mode: 0644]
queue-6.15/net-lan966x-fix-1-step-timestamping-over-ipv4-or-ipv.patch [new file with mode: 0644]
queue-6.15/net-lan966x-make-sure-to-insert-the-vlan-tags-also-i.patch [new file with mode: 0644]
queue-6.15/net-mctp-start-tx-queue-on-netdev-open.patch [new file with mode: 0644]
queue-6.15/net-mlx4_en-prevent-potential-integer-overflow-calcu.patch [new file with mode: 0644]
queue-6.15/net-mlx5-avoid-using-xso.real_dev-unnecessarily.patch [new file with mode: 0644]
queue-6.15/net-mlx5-hws-fix-matcher-action-template-attach.patch [new file with mode: 0644]
queue-6.15/net-ncsi-fix-gcps-64-bit-member-variables.patch [new file with mode: 0644]
queue-6.15/net-openvswitch-fix-the-dead-loop-of-mpls-parse.patch [new file with mode: 0644]
queue-6.15/net-phy-clear-phydev-devlink-when-the-link-is-delete.patch [new file with mode: 0644]
queue-6.15/net-phy-fix-up-const-issues-in-to_mdio_device-and-to.patch [new file with mode: 0644]
queue-6.15/net-phy-mediatek-permit-to-compile-test-ge-soc-phy-d.patch [new file with mode: 0644]
queue-6.15/net-phy-mscc-fix-memory-leak-when-using-one-step-tim.patch [new file with mode: 0644]
queue-6.15/net-phy-mscc-stop-clearing-the-the-udpv4-checksum-fo.patch [new file with mode: 0644]
queue-6.15/net-prevent-a-null-deref-in-rtnl_create_link.patch [new file with mode: 0644]
queue-6.15/net-stmmac-make-sure-that-ptp_rate-is-not-0-before-c.patch [new file with mode: 0644]
queue-6.15/net-stmmac-make-sure-that-ptp_rate-is-not-0-before-c.patch-22075 [new file with mode: 0644]
queue-6.15/net-stmmac-platform-guarantee-uniqueness-of-bus_id.patch [new file with mode: 0644]
queue-6.15/net-ti-icssg-prueth-fix-swapped-tx-stats-for-mii-int.patch [new file with mode: 0644]
queue-6.15/net-tipc-fix-refcount-warning-in-tipc_aead_encrypt.patch [new file with mode: 0644]
queue-6.15/net-usb-aqc111-fix-error-handling-of-usbnet-read-cal.patch [new file with mode: 0644]
queue-6.15/net-wwan-mhi_wwan_mbim-use-correct-mux_id-for-multip.patch [new file with mode: 0644]
queue-6.15/net-wwan-t7xx-fix-napi-rx-poll-issue.patch [new file with mode: 0644]
queue-6.15/net-xilinx-axienet-fix-tx-skb-circular-buffer-occupa.patch [new file with mode: 0644]
queue-6.15/netfilter-bridge-move-specific-fragmented-packet-to-.patch [new file with mode: 0644]
queue-6.15/netfilter-nf_nat-also-check-reverse-tuple-to-obtain-.patch [new file with mode: 0644]
queue-6.15/netfilter-nf_set_pipapo_avx2-fix-initial-map-fill.patch [new file with mode: 0644]
queue-6.15/netfilter-nf_tables-nft_fib-consistent-l3mdev-handli.patch [new file with mode: 0644]
queue-6.15/netfilter-nf_tables-nft_fib_ipv6-fix-vrf-ipv4-ipv6-r.patch [new file with mode: 0644]
queue-6.15/netfilter-nft_quota-match-correctly-when-the-quota-j.patch [new file with mode: 0644]
queue-6.15/netfilter-nft_set_pipapo-prevent-overflow-in-lookup-.patch [new file with mode: 0644]
queue-6.15/netfilter-nft_tunnel-fix-geneve_opt-dump.patch [new file with mode: 0644]
queue-6.15/netfilter-xtables-support-arpt_mark-and-ipv6-optstri.patch [new file with mode: 0644]
queue-6.15/netfs-fix-oops-in-write-retry-from-mis-resetting-the.patch [new file with mode: 0644]
queue-6.15/netfs-fix-setting-of-transferred-bytes-with-short-di.patch [new file with mode: 0644]
queue-6.15/netfs-fix-the-request-s-work-item-to-not-require-a-r.patch [new file with mode: 0644]
queue-6.15/netfs-fix-undifferentiation-of-dio-reads-from-unbuff.patch [new file with mode: 0644]
queue-6.15/netfs-fix-wait-wake-to-be-consistent-about-the-waitq.patch [new file with mode: 0644]
queue-6.15/netlink-specs-rt-link-add-missing-byte-order-propert.patch [new file with mode: 0644]
queue-6.15/netlink-specs-rt-link-decode-ip6gre.patch [new file with mode: 0644]
queue-6.15/nfs-clear-sb_rdonly-before-getting-superblock.patch [new file with mode: 0644]
queue-6.15/nfs-fix-incorrect-handling-of-large-number-nfs-error.patch [new file with mode: 0644]
queue-6.15/nfs-ignore-sb_rdonly-when-remounting-nfs.patch [new file with mode: 0644]
queue-6.15/nfs_localio-always-hold-nfsd-net-ref-with-nfsd_file-.patch [new file with mode: 0644]
queue-6.15/nfs_localio-change-nfsd_file_put_local-to-take-a-poi.patch [new file with mode: 0644]
queue-6.15/nfs_localio-duplicate-nfs_close_local_fh.patch [new file with mode: 0644]
queue-6.15/nfs_localio-protect-race-between-nfs_uuid_put-and-nf.patch [new file with mode: 0644]
queue-6.15/nfs_localio-simplify-interface-to-nfsd-for-getting-n.patch [new file with mode: 0644]
queue-6.15/nfs_localio-use-cmpxchg-to-install-new-nfs_file_loca.patch [new file with mode: 0644]
queue-6.15/nilfs2-add-pointer-check-for-nilfs_direct_propagate.patch [new file with mode: 0644]
queue-6.15/nilfs2-do-not-propagate-enoent-error-from-nilfs_btre.patch [new file with mode: 0644]
queue-6.15/nvme-fix-command-limits-status-code.patch [new file with mode: 0644]
queue-6.15/nvme-fix-implicit-bool-to-flags-conversion.patch [new file with mode: 0644]
queue-6.15/ocfs2-fix-possible-memory-leak-in-ocfs2_finish_quota.patch [new file with mode: 0644]
queue-6.15/octeontx2-af-send-link-events-one-by-one.patch [new file with mode: 0644]
queue-6.15/octeontx2-pf-qos-perform-cache-sync-on-send-queue-te.patch [new file with mode: 0644]
queue-6.15/octeontx2-pf-qos-refactor-tc_htb_leaf_del_last-callb.patch [new file with mode: 0644]
queue-6.15/of-unittest-unlock-on-error-in-unittest_data_add.patch [new file with mode: 0644]
queue-6.15/overflow-fix-direct-struct-member-initialization-in-.patch [new file with mode: 0644]
queue-6.15/page_pool-fix-use-after-free-in-page_pool_recycle_in.patch [new file with mode: 0644]
queue-6.15/page_pool-move-pp_magic-check-into-helper-functions.patch [new file with mode: 0644]
queue-6.15/page_pool-track-dma-mapped-pages-and-unmap-them-when.patch [new file with mode: 0644]
queue-6.15/path_overmount-avoid-false-negatives.patch [new file with mode: 0644]
queue-6.15/pci-acpi-fix-allocated-memory-release-on-error-in-pc.patch [new file with mode: 0644]
queue-6.15/pci-apple-use-gpiod_set_value_cansleep-in-probe-flow.patch [new file with mode: 0644]
queue-6.15/pci-cadence-fix-runtime-atomic-count-underflow.patch [new file with mode: 0644]
queue-6.15/pci-dpc-initialize-aer_err_info-before-using-it.patch [new file with mode: 0644]
queue-6.15/pci-dpc-log-error-source-id-only-when-valid.patch [new file with mode: 0644]
queue-6.15/pci-endpoint-retain-fixed-size-bar-size-as-well-as-a.patch [new file with mode: 0644]
queue-6.15/pci-explicitly-put-devices-into-d0-when-initializing.patch [new file with mode: 0644]
queue-6.15/pci-imx6-save-and-restore-the-lut-setting-during-sus.patch [new file with mode: 0644]
queue-6.15/pci-pciehp-ignore-link-down-up-caused-by-secondary-b.patch [new file with mode: 0644]
queue-6.15/pci-pciehp-ignore-presence-detect-changed-caused-by-.patch [new file with mode: 0644]
queue-6.15/pci-print-the-actual-delay-time-in-pci_bridge_wait_f.patch [new file with mode: 0644]
queue-6.15/pci-pwrctrl-cancel-outstanding-rescan-work-when-unre.patch [new file with mode: 0644]
queue-6.15/pci-rcar-gen4-set-ep-bar4-fixed-size.patch [new file with mode: 0644]
queue-6.15/pci-rockchip-fix-order-of-rockchip_pci_core_rsts.patch [new file with mode: 0644]
queue-6.15/perf-amlogic-replace-smp_processor_id-with-raw_smp_p.patch [new file with mode: 0644]
queue-6.15/perf-arm-ni-fix-missing-platform_set_drvdata.patch [new file with mode: 0644]
queue-6.15/perf-arm-ni-unregister-pmus-on-probe-failure.patch [new file with mode: 0644]
queue-6.15/perf-build-warn-when-libdebuginfod-devel-files-are-n.patch [new file with mode: 0644]
queue-6.15/perf-callchain-always-populate-the-addr_location-map.patch [new file with mode: 0644]
queue-6.15/perf-core-fix-broken-throttling-when-max_samples_per.patch [new file with mode: 0644]
queue-6.15/perf-intel-pt-fix-pebs-via-pt-data_src.patch [new file with mode: 0644]
queue-6.15/perf-pmu-avoid-segv-for-missing-name-alias_name-in-w.patch [new file with mode: 0644]
queue-6.15/perf-record-fix-incorrect-user-regs-comments.patch [new file with mode: 0644]
queue-6.15/perf-scripts-python-exported-sql-viewer.py-fix-patte.patch [new file with mode: 0644]
queue-6.15/perf-symbol-fix-use-after-free-in-filename__read_bui.patch [new file with mode: 0644]
queue-6.15/perf-symbol-minimal-fix-double-free-in-filename__rea.patch [new file with mode: 0644]
queue-6.15/perf-tests-fix-perf-report-tests-installation.patch [new file with mode: 0644]
queue-6.15/perf-tests-metric-only-perf-stat-fix-tests-84-and-86.patch [new file with mode: 0644]
queue-6.15/perf-tests-switch-tracking-fix-timestamp-comparison.patch [new file with mode: 0644]
queue-6.15/perf-tool_pmu-fix-aggregation-on-duration_time.patch [new file with mode: 0644]
queue-6.15/perf-tools-fix-arm64-source-package-build.patch [new file with mode: 0644]
queue-6.15/perf-trace-always-print-return-value-for-syscalls-re.patch [new file with mode: 0644]
queue-6.15/perf-trace-fix-leaks-of-struct-thread-in-fprintf_sys.patch [new file with mode: 0644]
queue-6.15/perf-trace-fix-leaks-of-struct-thread-in-set_filter_.patch [new file with mode: 0644]
queue-6.15/perf-trace-set-errpid-to-false-for-rseq-and-set_robu.patch [new file with mode: 0644]
queue-6.15/perf-ui-browser-hists-set-actions-thread-before-call.patch [new file with mode: 0644]
queue-6.15/perf-x86-amd-uncore-prevent-umc-counters-from-satura.patch [new file with mode: 0644]
queue-6.15/perf-x86-amd-uncore-remove-unused-struct-amd_uncore_.patch [new file with mode: 0644]
queue-6.15/phy-qcom-qmp-usb-fix-an-null-vs-is_err-bug.patch [new file with mode: 0644]
queue-6.15/phy-qcom-qusb2-reuse-the-ipq6018-settings-for-ipq542.patch [new file with mode: 0644]
queue-6.15/phy-rockchip-samsung-hdptx-do-no-set-rk_hdptx_phy-ra.patch [new file with mode: 0644]
queue-6.15/phy-rockchip-samsung-hdptx-fix-clock-ratio-setup.patch [new file with mode: 0644]
queue-6.15/pinctrl-at91-fix-possible-out-of-boundary-access.patch [new file with mode: 0644]
queue-6.15/pinctrl-mediatek-fix-the-invalid-conditions.patch [new file with mode: 0644]
queue-6.15/pinctrl-qcom-correct-the-ngpios-entry-for-qcs615.patch [new file with mode: 0644]
queue-6.15/pinctrl-qcom-correct-the-ngpios-entry-for-qcs8300.patch [new file with mode: 0644]
queue-6.15/pinctrl-qcom-tlmm-test-fix-potential-null-dereferenc.patch [new file with mode: 0644]
queue-6.15/platform-chrome-cros_ec_typec-set-pin-assignment-e-i.patch [new file with mode: 0644]
queue-6.15/pm-em-fix-potential-division-by-zero-error-in-em_com.patch [new file with mode: 0644]
queue-6.15/pm-runtime-add-new-devm-functions.patch [new file with mode: 0644]
queue-6.15/pm-sleep-fix-power.is_suspended-cleanup-for-direct-c.patch [new file with mode: 0644]
queue-6.15/pm-sleep-print-pm-debug-messages-during-hibernation.patch [new file with mode: 0644]
queue-6.15/pm-wakeup-delete-space-in-the-end-of-string-shown-by.patch [new file with mode: 0644]
queue-6.15/power-reset-at91-reset-optimize-at91_reset.patch [new file with mode: 0644]
queue-6.15/power-supply-max77705-fix-workqueue-error-handling-i.patch [new file with mode: 0644]
queue-6.15/powerpc-crash-fix-non-smp-kexec-preparation.patch [new file with mode: 0644]
queue-6.15/powerpc-do-not-build-ppc_save_regs.o-always.patch [new file with mode: 0644]
queue-6.15/powerpc-pseries-iommu-fix-kmemleak-in-tce-table-user.patch [new file with mode: 0644]
queue-6.15/randstruct-gcc-plugin-fix-attribute-addition.patch [new file with mode: 0644]
queue-6.15/randstruct-gcc-plugin-remove-bogus-void-member.patch [new file with mode: 0644]
queue-6.15/rcu-cpu_stall_cputime-fix-the-hardirq-count-for-x86-.patch [new file with mode: 0644]
queue-6.15/rdma-bnxt_re-fix-incorrect-display-of-inactivity_cp-.patch [new file with mode: 0644]
queue-6.15/rdma-bnxt_re-fix-missing-error-handling-for-tx_queue.patch [new file with mode: 0644]
queue-6.15/rdma-bnxt_re-fix-return-code-of-bnxt_re_configure_cc.patch [new file with mode: 0644]
queue-6.15/rdma-cma-fix-hang-when-cma_netevent_callback-fails-t.patch [new file with mode: 0644]
queue-6.15/rdma-hns-include-hnae3.h-in-hns_roce_hw_v2.h.patch [new file with mode: 0644]
queue-6.15/rdma-mlx5-fix-error-flow-upon-firmware-failure-for-r.patch [new file with mode: 0644]
queue-6.15/rdma-rxe-fix-trying-to-register-non-static-key-in-rx.patch [new file with mode: 0644]
queue-6.15/remoteproc-k3-dsp-drop-check-performed-in-k3_dsp_rpr.patch [new file with mode: 0644]
queue-6.15/remoteproc-k3-r5-drop-check-performed-in-k3_r5_rproc.patch [new file with mode: 0644]
queue-6.15/remoteproc-k3-r5-refactor-sequential-core-power-up-d.patch [new file with mode: 0644]
queue-6.15/remoteproc-qcom_wcnss_iris-add-missing-put_device-on.patch [new file with mode: 0644]
queue-6.15/revert-phy-qcom-qusb2-add-qusb2-support-for-ipq5424.patch [new file with mode: 0644]
queue-6.15/risc-v-kvm-lock-the-correct-mp_state-during-reset.patch [new file with mode: 0644]
queue-6.15/riscv-misaligned-fix-sleeping-function-called-during.patch [new file with mode: 0644]
queue-6.15/rpmsg-qcom_smd-fix-uninitialized-return-variable-in-.patch [new file with mode: 0644]
queue-6.15/rtc-loongson-add-missing-alarm-notifications-for-acp.patch [new file with mode: 0644]
queue-6.15/rtc-sh-assign-correct-interrupts-with-dt.patch [new file with mode: 0644]
queue-6.15/rtla-define-_gnu_source-in-timerlat_bpf.c.patch [new file with mode: 0644]
queue-6.15/rust-alloc-add-missing-invariant-in-vec-set_len.patch [new file with mode: 0644]
queue-6.15/rust-file-mark-localfile-as-repr-transparent.patch [new file with mode: 0644]
queue-6.15/rust-miscdevice-fix-typo-in-miscdevice-ioctl-documen.patch [new file with mode: 0644]
queue-6.15/rust-pci-fix-docs-related-to-missing-markdown-code-s.patch [new file with mode: 0644]
queue-6.15/s390-bpf-store-backchain-even-for-leaf-progs.patch [new file with mode: 0644]
queue-6.15/s390-uv-always-return-0-from-s390_wiggle_split_folio.patch [new file with mode: 0644]
queue-6.15/s390-uv-don-t-return-0-from-make_hva_secure-if-the-o.patch [new file with mode: 0644]
queue-6.15/s390-uv-improve-splitting-of-large-folios-that-canno.patch [new file with mode: 0644]
queue-6.15/sched-core-tweak-wait_task_inactive-to-force-dequeue.patch [new file with mode: 0644]
queue-6.15/sched-fair-fixup-wake_up_sync-vs-delayed_dequeue.patch [new file with mode: 0644]
queue-6.15/sched-fix-trace_sched_switch-.prev_state.patch [new file with mode: 0644]
queue-6.15/sched_ext-idle-skip-cross-node-search-with-config_nu.patch [new file with mode: 0644]
queue-6.15/scsi-hisi_sas-call-i_t_nexus-after-soft-reset-for-sa.patch [new file with mode: 0644]
queue-6.15/scsi-lpfc-avoid-potential-ndlp-use-after-free-in-dev.patch [new file with mode: 0644]
queue-6.15/scsi-mpt3sas-fix-_ctl_get_mpt_mctp_passthru_adapter-.patch [new file with mode: 0644]
queue-6.15/scsi-qedf-use-designated-initializer-for-struct-qed_.patch [new file with mode: 0644]
queue-6.15/scsi-smartpqi-fix-smp_processor_id-call-trace-for-pr.patch [new file with mode: 0644]
queue-6.15/scsi-ufs-mcq-delete-ufshcd_release_scsi_cmd-in-ufshc.patch [new file with mode: 0644]
queue-6.15/scsi-ufs-qcom-check-gear-against-max-gear-in-vop-fre.patch [new file with mode: 0644]
queue-6.15/scsi-ufs-qcom-map-devfreq-opp-freq-to-unipro-core-cl.patch [new file with mode: 0644]
queue-6.15/scsi-ufs-qcom-prevent-calling-phy_exit-before-phy_in.patch [new file with mode: 0644]
queue-6.15/seg6-fix-validation-of-nexthop-addresses.patch [new file with mode: 0644]
queue-6.15/selftests-bpf-avoid-passing-out-of-range-values-to-_.patch [new file with mode: 0644]
queue-6.15/selftests-bpf-fix-bpf_nf-selftest-failure.patch [new file with mode: 0644]
queue-6.15/selftests-bpf-fix-caps-for-__xlated-jited_unpriv.patch [new file with mode: 0644]
queue-6.15/selftests-bpf-fix-kmem_cache-iterator-draining.patch [new file with mode: 0644]
queue-6.15/selftests-coredump-fix-test-failure-for-slow-machine.patch [new file with mode: 0644]
queue-6.15/selftests-coredump-properly-initialize-pointer.patch [new file with mode: 0644]
queue-6.15/selftests-coredump-raise-timeout-to-2-minutes.patch [new file with mode: 0644]
queue-6.15/selftests-drv-net-tso-fix-the-gre-device-name.patch [new file with mode: 0644]
queue-6.15/selftests-drv-net-tso-make-bkg-wait-for-socat-to-qui.patch [new file with mode: 0644]
queue-6.15/selftests-net-build-net-lib-dependency-in-all-target.patch [new file with mode: 0644]
queue-6.15/selftests-seccomp-fix-negative_enosys-tracer-tests-o.patch [new file with mode: 0644]
queue-6.15/selftests-seccomp-fix-syscall_restart-test-for-arm-c.patch [new file with mode: 0644]
queue-6.15/serial-fix-potential-null-ptr-deref-in-mlb_usio_prob.patch [new file with mode: 0644]
queue-6.15/series [new file with mode: 0644]
queue-6.15/soc-aspeed-add-null-check-in-aspeed_lpc_enable_snoop.patch [new file with mode: 0644]
queue-6.15/soc-aspeed-lpc-fix-impossible-judgment-condition.patch [new file with mode: 0644]
queue-6.15/soc-qcom-smp2p-fix-fallback-to-qcom-ipc-parse.patch [new file with mode: 0644]
queue-6.15/soundwire-only-compute-port-params-in-specific-strea.patch [new file with mode: 0644]
queue-6.15/spi-atmel-quadspi-fix-unbalanced-pm_runtime-by-using.patch [new file with mode: 0644]
queue-6.15/spi-bcm63xx-hsspi-fix-shared-reset.patch [new file with mode: 0644]
queue-6.15/spi-bcm63xx-spi-fix-shared-reset.patch [new file with mode: 0644]
queue-6.15/spi-sh-msiof-fix-maximum-dma-transfer-size.patch [new file with mode: 0644]
queue-6.15/spi-spi-qpic-snand-use-kmalloc-for-oob-buffer-alloca.patch [new file with mode: 0644]
queue-6.15/spi-spi-qpic-snand-validate-user-chip-specific-ecc-p.patch [new file with mode: 0644]
queue-6.15/spi-tegra210-quad-fix-x1_x2_x4-encoding-and-support-.patch [new file with mode: 0644]
queue-6.15/spi-tegra210-quad-modify-chip-select-cs-deactivation.patch [new file with mode: 0644]
queue-6.15/spi-tegra210-quad-remove-redundant-error-handling-co.patch [new file with mode: 0644]
queue-6.15/squashfs-check-return-result-of-sb_min_blocksize.patch [new file with mode: 0644]
queue-6.15/staging-gpib-fix-pcmcia-config-identifier.patch [new file with mode: 0644]
queue-6.15/staging-gpib-fix-secondary-address-restriction.patch [new file with mode: 0644]
queue-6.15/svcrdma-reduce-the-number-of-rdma_rw-contexts-per-qp.patch [new file with mode: 0644]
queue-6.15/thermal-drivers-mediatek-lvts-fix-debugfs-unregister.patch [new file with mode: 0644]
queue-6.15/thunderbolt-fix-a-logic-error-in-wake-on-connect.patch [new file with mode: 0644]
queue-6.15/tools-build-don-t-set-libunwind-as-available-if-test.patch [new file with mode: 0644]
queue-6.15/tools-build-don-t-show-libbfd-build-status-as-it-is-.patch [new file with mode: 0644]
queue-6.15/tools-build-don-t-show-libunwind-build-status-as-it-.patch [new file with mode: 0644]
queue-6.15/tools-nolibc-fix-integer-overflow-in-i-64-toa_r-and.patch [new file with mode: 0644]
queue-6.15/tools-nolibc-properly-align-dirent-buffer.patch [new file with mode: 0644]
queue-6.15/tools-nolibc-types.h-fix-mismatched-parenthesis-in-m.patch [new file with mode: 0644]
queue-6.15/tools-power-turbostat-fix-amd-package-energy-reporti.patch [new file with mode: 0644]
queue-6.15/tools-x86-kcpuid-fix-error-handling.patch [new file with mode: 0644]
queue-6.15/tracing-fix-error-handling-in-event_trigger_parse.patch [new file with mode: 0644]
queue-6.15/tracing-move-histogram-trigger-variables-from-stack-.patch [new file with mode: 0644]
queue-6.15/tracing-rename-event_trigger_alloc-to-trigger_data_a.patch [new file with mode: 0644]
queue-6.15/ubsan-integer-overflow-depend-on-broken-to-keep-this.patch [new file with mode: 0644]
queue-6.15/udp-properly-deal-with-xfrm-encap-and-addrform.patch [new file with mode: 0644]
queue-6.15/udp_tunnel-create-a-fastpath-gro-lookup.patch [new file with mode: 0644]
queue-6.15/udp_tunnel-use-static-call-for-gro-hooks-when-possib.patch [new file with mode: 0644]
queue-6.15/um-fix-tgkill-compile-error-on-old-host-oses.patch [new file with mode: 0644]
queue-6.15/usb-acpi-prevent-null-pointer-dereference-in-usb_acp.patch [new file with mode: 0644]
queue-6.15/usb-gadget-udc-fix-const-issue-in-gadget_match_drive.patch [new file with mode: 0644]
queue-6.15/usb-renesas_usbhs-reorder-clock-handling-and-power-m.patch [new file with mode: 0644]
queue-6.15/usb-serial-bus-fix-const-issue-in-usb_serial_device_.patch [new file with mode: 0644]
queue-6.15/usb-typec-fix-const-issue-in-typec_match.patch [new file with mode: 0644]
queue-6.15/use-thread-safe-function-pointer-in-libbpf_print.patch [new file with mode: 0644]
queue-6.15/vfio-type1-fix-error-unwind-in-migration-dirty-bitma.patch [new file with mode: 0644]
queue-6.15/virtio-pci-fix-result-size-returned-for-the-admin-co.patch [new file with mode: 0644]
queue-6.15/vmxnet3-correctly-report-gso-type-for-udp-tunnels.patch [new file with mode: 0644]
queue-6.15/vsock-virtio-fix-rx_bytes-accounting-for-stream-sock.patch [new file with mode: 0644]
queue-6.15/vt-remove-vt_resize-and-vt_resizex-from-vt_compat_io.patch [new file with mode: 0644]
queue-6.15/watchdog-exar-shorten-identity-name-to-fit-correctly.patch [new file with mode: 0644]
queue-6.15/watchdog-lenovo_se30_wdt-fix-possible-devm_ioremap-n.patch [new file with mode: 0644]
queue-6.15/wifi-ath11k-fix-node-corruption-in-ar-arvifs-list.patch [new file with mode: 0644]
queue-6.15/wifi-ath12k-add-extra-tlv-tag-parsing-support-in-mon.patch [new file with mode: 0644]
queue-6.15/wifi-ath12k-add-msdu-length-validation-for-tkip-mic-.patch [new file with mode: 0644]
queue-6.15/wifi-ath12k-add-rx_info-to-capture-required-field-fr.patch [new file with mode: 0644]
queue-6.15/wifi-ath12k-avoid-fetch-error-bitmap-and-decap-forma.patch [new file with mode: 0644]
queue-6.15/wifi-ath12k-change-the-status-update-in-the-monitor-.patch [new file with mode: 0644]
queue-6.15/wifi-ath12k-fix-ath12k_flag_registered-flag-handling.patch [new file with mode: 0644]
queue-6.15/wifi-ath12k-fix-buffer-overflow-in-debugfs.patch [new file with mode: 0644]
queue-6.15/wifi-ath12k-fix-cleanup-path-after-mhi-init.patch [new file with mode: 0644]
queue-6.15/wifi-ath12k-fix-invalid-access-to-memory.patch [new file with mode: 0644]
queue-6.15/wifi-ath12k-fix-invalid-memory-access-while-forming-.patch [new file with mode: 0644]
queue-6.15/wifi-ath12k-fix-invalid-rssi-values-in-station-dump.patch [new file with mode: 0644]
queue-6.15/wifi-ath12k-fix-memory-corruption-during-mlo-multica.patch [new file with mode: 0644]
queue-6.15/wifi-ath12k-fix-memory-leak-during-vdev_id-mismatch.patch [new file with mode: 0644]
queue-6.15/wifi-ath12k-fix-memory-leak-in-ath12k_service_ready_.patch [new file with mode: 0644]
queue-6.15/wifi-ath12k-fix-node-corruption-in-ar-arvifs-list.patch [new file with mode: 0644]
queue-6.15/wifi-ath12k-fix-null-access-in-assign-channel-contex.patch [new file with mode: 0644]
queue-6.15/wifi-ath12k-fix-slub-bug-object-already-free-in-ath1.patch [new file with mode: 0644]
queue-6.15/wifi-ath12k-fix-the-qos-control-field-offset-to-buil.patch [new file with mode: 0644]
queue-6.15/wifi-ath12k-fix-wmi-tag-for-eht-rate-in-peer-assoc.patch [new file with mode: 0644]
queue-6.15/wifi-ath12k-fix-wrong-handling-of-ccmp256-and-gcmp-c.patch [new file with mode: 0644]
queue-6.15/wifi-ath12k-handle-error-cases-during-extended-skb-a.patch [new file with mode: 0644]
queue-6.15/wifi-ath12k-prevent-sending-wmi-commands-to-firmware.patch [new file with mode: 0644]
queue-6.15/wifi-ath12k-reorder-and-relocate-the-release-of-reso.patch [new file with mode: 0644]
queue-6.15/wifi-ath12k-replace-band-define-g-with-ghz-where-app.patch [new file with mode: 0644]
queue-6.15/wifi-ath12k-replace-the-usage-of-rx-desc-with-rx_inf.patch [new file with mode: 0644]
queue-6.15/wifi-ath12k-resolve-multicast-packet-drop-by-populat.patch [new file with mode: 0644]
queue-6.15/wifi-ath9k_htc-abort-software-beacon-handling-if-dis.patch [new file with mode: 0644]
queue-6.15/wifi-cfg80211-mac80211-correctly-parse-s1g-beacon-op.patch [new file with mode: 0644]
queue-6.15/wifi-iwlfiwi-mvm-fix-the-rate-reporting.patch [new file with mode: 0644]
queue-6.15/wifi-iwlwifi-mld-avoid-panic-on-init-failure.patch [new file with mode: 0644]
queue-6.15/wifi-iwlwifi-re-add-iwl_amsdu_8k-case.patch [new file with mode: 0644]
queue-6.15/wifi-mt76-fix-available_antennas-setting.patch [new file with mode: 0644]
queue-6.15/wifi-mt76-mt7915-fix-null-ptr-deref-in-mt7915_mmio_w.patch [new file with mode: 0644]
queue-6.15/wifi-mt76-mt7925-ensure-all-mcu-commands-wait-for-re.patch [new file with mode: 0644]
queue-6.15/wifi-mt76-mt7925-fix-logical-vs-bitwise-typo.patch [new file with mode: 0644]
queue-6.15/wifi-mt76-mt7925-prevent-multiple-scan-commands.patch [new file with mode: 0644]
queue-6.15/wifi-mt76-mt7925-refine-the-sniffer-commnad.patch [new file with mode: 0644]
queue-6.15/wifi-mt76-mt7996-add-null-check-in-mt7996_thermal_in.patch [new file with mode: 0644]
queue-6.15/wifi-mt76-mt7996-avoid-null-deref-in-mt7996_stop_phy.patch [new file with mode: 0644]
queue-6.15/wifi-mt76-mt7996-avoid-null-pointer-dereference-in-m.patch [new file with mode: 0644]
queue-6.15/wifi-mt76-mt7996-fix-beamformee-ss-field.patch [new file with mode: 0644]
queue-6.15/wifi-mt76-mt7996-fix-invalid-nss-setting-when-tx-pat.patch [new file with mode: 0644]
queue-6.15/wifi-mt76-mt7996-fix-null-ptr-deref-in-mt7996_mmio_w.patch [new file with mode: 0644]
queue-6.15/wifi-mt76-mt7996-fix-rx-buffer-size-of-mcu-event.patch [new file with mode: 0644]
queue-6.15/wifi-mt76-mt7996-prevent-uninit-return-in-mt7996_mac.patch [new file with mode: 0644]
queue-6.15/wifi-mt76-mt7996-set-eht-max-ampdu-length-capability.patch [new file with mode: 0644]
queue-6.15/wifi-mt76-scan-fix-mlink-dereferenced-before-is_err_.patch [new file with mode: 0644]
queue-6.15/wifi-rtw88-do-not-ignore-hardware-read-error-during-.patch [new file with mode: 0644]
queue-6.15/wifi-rtw88-fix-the-para-buffer-size-to-avoid-reading.patch [new file with mode: 0644]
queue-6.15/wifi-rtw88-sdio-call-rtw_sdio_indicate_tx_status-unc.patch [new file with mode: 0644]
queue-6.15/wifi-rtw88-sdio-map-mgmt-frames-to-queue-tx_desc_qse.patch [new file with mode: 0644]
queue-6.15/wifi-rtw89-fix-firmware-scan-delay-unit-for-wifi-6-c.patch [new file with mode: 0644]
queue-6.15/wifi-rtw89-pci-configure-manual-dac-mode-via-pci-con.patch [new file with mode: 0644]
queue-6.15/wifi-rtw89-pci-enlarge-retry-times-of-rx-tag-to-1000.patch [new file with mode: 0644]
queue-6.15/wireguard-device-enable-threaded-napi.patch [new file with mode: 0644]
queue-6.15/x86-cpu-sanitize-cpuid-0x80000000-output.patch [new file with mode: 0644]
queue-6.15/x86-idle-remove-mfences-for-x86_bug_clflush_monitor-.patch [new file with mode: 0644]
queue-6.15/x86-insn-fix-opcode-map-rex2-superscript-tags.patch [new file with mode: 0644]
queue-6.15/x86-irq-ensure-initial-pir-loads-are-performed-exact.patch [new file with mode: 0644]
queue-6.15/x86-microcode-amd-do-not-return-error-when-microcode.patch [new file with mode: 0644]
queue-6.15/x86-mtrr-check-if-fixed-range-mtrrs-exist-in-mtrr_sa.patch [new file with mode: 0644]
queue-6.15/xen-x86-fix-initial-memory-balloon-target.patch [new file with mode: 0644]
queue-6.15/xfrm-add-explicit-dev-to-.xdo_dev_state_-add-delete-.patch [new file with mode: 0644]
queue-6.15/xfrm-use-xdo.dev-instead-of-xdo.real_dev.patch [new file with mode: 0644]

diff --git a/queue-6.15/accel-amdxdna-fix-incorrect-size-of-ert_start_npu-co.patch b/queue-6.15/accel-amdxdna-fix-incorrect-size-of-ert_start_npu-co.patch
new file mode 100644 (file)
index 0000000..c07df88
--- /dev/null
@@ -0,0 +1,85 @@
+From be822c21efdebf50e70be0236e90d80b28b48182 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Apr 2025 14:00:13 -0700
+Subject: accel/amdxdna: Fix incorrect size of ERT_START_NPU commands
+
+From: Lizhi Hou <lizhi.hou@amd.com>
+
+[ Upstream commit 6c161732ea6467c6dea0c35810ca8e8d1ae135f1 ]
+
+When multiple ERT_START_NPU commands are combined in one buffer, the
+buffer size calculation is incorrect. Also, the condition to make sure
+the buffer size is not beyond 4K is also fixed.
+
+Fixes: aac243092b70 ("accel/amdxdna: Add command execution")
+Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
+Reviewed-by: Maciej Falkowski <maciej.falkowski@linux.intel.com>
+Signed-off-by: Lizhi Hou <lizhi.hou@amd.com>
+Link: https://lore.kernel.org/r/20250409210013.10854-1-lizhi.hou@amd.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/accel/amdxdna/aie2_message.c  |  6 +++---
+ drivers/accel/amdxdna/aie2_msg_priv.h | 10 ++++------
+ 2 files changed, 7 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/accel/amdxdna/aie2_message.c b/drivers/accel/amdxdna/aie2_message.c
+index bf4219e32cc19..82412eec9a4b8 100644
+--- a/drivers/accel/amdxdna/aie2_message.c
++++ b/drivers/accel/amdxdna/aie2_message.c
+@@ -525,7 +525,7 @@ aie2_cmdlist_fill_one_slot_cf(void *cmd_buf, u32 offset,
+       if (!payload)
+               return -EINVAL;
+-      if (!slot_cf_has_space(offset, payload_len))
++      if (!slot_has_space(*buf, offset, payload_len))
+               return -ENOSPC;
+       buf->cu_idx = cu_idx;
+@@ -558,7 +558,7 @@ aie2_cmdlist_fill_one_slot_dpu(void *cmd_buf, u32 offset,
+       if (payload_len < sizeof(*sn) || arg_sz > MAX_DPU_ARGS_SIZE)
+               return -EINVAL;
+-      if (!slot_dpu_has_space(offset, arg_sz))
++      if (!slot_has_space(*buf, offset, arg_sz))
+               return -ENOSPC;
+       buf->inst_buf_addr = sn->buffer;
+@@ -569,7 +569,7 @@ aie2_cmdlist_fill_one_slot_dpu(void *cmd_buf, u32 offset,
+       memcpy(buf->args, sn->prop_args, arg_sz);
+       /* Accurate buf size to hint firmware to do necessary copy */
+-      *size += sizeof(*buf) + arg_sz;
++      *size = sizeof(*buf) + arg_sz;
+       return 0;
+ }
+diff --git a/drivers/accel/amdxdna/aie2_msg_priv.h b/drivers/accel/amdxdna/aie2_msg_priv.h
+index 4e02e744b470e..6df9065b13f68 100644
+--- a/drivers/accel/amdxdna/aie2_msg_priv.h
++++ b/drivers/accel/amdxdna/aie2_msg_priv.h
+@@ -319,18 +319,16 @@ struct async_event_msg_resp {
+ } __packed;
+ #define MAX_CHAIN_CMDBUF_SIZE SZ_4K
+-#define slot_cf_has_space(offset, payload_size) \
+-      (MAX_CHAIN_CMDBUF_SIZE - ((offset) + (payload_size)) > \
+-       offsetof(struct cmd_chain_slot_execbuf_cf, args[0]))
++#define slot_has_space(slot, offset, payload_size)            \
++      (MAX_CHAIN_CMDBUF_SIZE >= (offset) + (payload_size) +   \
++       sizeof(typeof(slot)))
++
+ struct cmd_chain_slot_execbuf_cf {
+       __u32 cu_idx;
+       __u32 arg_cnt;
+       __u32 args[] __counted_by(arg_cnt);
+ };
+-#define slot_dpu_has_space(offset, payload_size) \
+-      (MAX_CHAIN_CMDBUF_SIZE - ((offset) + (payload_size)) > \
+-       offsetof(struct cmd_chain_slot_dpu, args[0]))
+ struct cmd_chain_slot_dpu {
+       __u64 inst_buf_addr;
+       __u32 inst_size;
+-- 
+2.39.5
+
diff --git a/queue-6.15/accel-ivpu-reorder-doorbell-unregister-and-command-q.patch b/queue-6.15/accel-ivpu-reorder-doorbell-unregister-and-command-q.patch
new file mode 100644 (file)
index 0000000..b08b5b9
--- /dev/null
@@ -0,0 +1,60 @@
+From a81f65224e3353d17593e9398cd718340574dc83 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 May 2025 11:41:24 +0200
+Subject: accel/ivpu: Reorder Doorbell Unregister and Command Queue Destruction
+
+From: Karol Wachowski <karol.wachowski@intel.com>
+
+[ Upstream commit 4557cc834712eca4eae7adbd9f0a06bdd8f79c99 ]
+
+Refactor ivpu_cmdq_unregister() to ensure the doorbell is unregistered
+before destroying the command queue. The NPU firmware requires doorbells
+to be unregistered prior to command queue destruction.
+
+If doorbell remains registered when command queue destroy command is sent
+firmware will automatically unregister the doorbell, making subsequent
+unregister attempts no-operations (NOPs).
+
+Ensure compliance with firmware expectations by moving the doorbell
+unregister call ahead of the command queue destruction logic,
+thus preventing unnecessary NOP operation.
+
+Fixes: 465a3914b254 ("accel/ivpu: Add API for command queue create/destroy/submit")
+Signed-off-by: Karol Wachowski <karol.wachowski@intel.com>
+Reviewed-by: Jeff Hugo <jeff.hugo@oss.qualcomm.com>
+Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
+Link: https://lore.kernel.org/r/20250515094124.255141-1-jacek.lawrynowicz@linux.intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/accel/ivpu/ivpu_job.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c
+index b28da35c30b67..1c8e283ad9854 100644
+--- a/drivers/accel/ivpu/ivpu_job.c
++++ b/drivers/accel/ivpu/ivpu_job.c
+@@ -247,6 +247,10 @@ static int ivpu_cmdq_unregister(struct ivpu_file_priv *file_priv, struct ivpu_cm
+       if (!cmdq->db_id)
+               return 0;
++      ret = ivpu_jsm_unregister_db(vdev, cmdq->db_id);
++      if (!ret)
++              ivpu_dbg(vdev, JOB, "DB %d unregistered\n", cmdq->db_id);
++
+       if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) {
+               ret = ivpu_jsm_hws_destroy_cmdq(vdev, file_priv->ctx.id, cmdq->id);
+               if (!ret)
+@@ -254,10 +258,6 @@ static int ivpu_cmdq_unregister(struct ivpu_file_priv *file_priv, struct ivpu_cm
+                                cmdq->id, file_priv->ctx.id);
+       }
+-      ret = ivpu_jsm_unregister_db(vdev, cmdq->db_id);
+-      if (!ret)
+-              ivpu_dbg(vdev, JOB, "DB %d unregistered\n", cmdq->db_id);
+-
+       xa_erase(&file_priv->vdev->db_xa, cmdq->db_id);
+       cmdq->db_id = 0;
+-- 
+2.39.5
+
diff --git a/queue-6.15/acpi-osi-stop-advertising-support-for-3.0-_scp-exten.patch b/queue-6.15/acpi-osi-stop-advertising-support-for-3.0-_scp-exten.patch
new file mode 100644 (file)
index 0000000..44b595b
--- /dev/null
@@ -0,0 +1,44 @@
+From 0fb1e82a51ab506f349f589d86213f1a53843d42 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Apr 2025 18:54:54 +0200
+Subject: ACPI: OSI: Stop advertising support for "3.0 _SCP Extensions"
+
+From: Armin Wolf <W_Armin@gmx.de>
+
+[ Upstream commit 8cf4fdac9bdead7bca15fc56fdecdf78d11c3ec6 ]
+
+As specified in section 5.7.2 of the ACPI specification the feature
+group string "3.0 _SCP Extensions" implies that the operating system
+evaluates the _SCP control method with additional parameters.
+
+However the ACPI thermal driver evaluates the _SCP control method
+without those additional parameters, conflicting with the above
+feature group string advertised to the firmware thru _OSI.
+
+Stop advertising support for this feature string to avoid confusing
+the ACPI firmware.
+
+Fixes: e5f660ebef68 ("ACPI / osi: Collect _OSI handling into one single file")
+Signed-off-by: Armin Wolf <W_Armin@gmx.de>
+Link: https://patch.msgid.link/20250410165456.4173-2-W_Armin@gmx.de
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/osi.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/acpi/osi.c b/drivers/acpi/osi.c
+index df9328c850bd3..f2c943b934be0 100644
+--- a/drivers/acpi/osi.c
++++ b/drivers/acpi/osi.c
+@@ -42,7 +42,6 @@ static struct acpi_osi_entry
+ osi_setup_entries[OSI_STRING_ENTRIES_MAX] __initdata = {
+       {"Module Device", true},
+       {"Processor Device", true},
+-      {"3.0 _SCP Extensions", true},
+       {"Processor Aggregator Device", true},
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.15/acpi-platform_profile-avoid-initializing-on-non-acpi.patch b/queue-6.15/acpi-platform_profile-avoid-initializing-on-non-acpi.patch
new file mode 100644 (file)
index 0000000..591db2c
--- /dev/null
@@ -0,0 +1,67 @@
+From 70a5f512edc0251fdc96e998cb8893a390e2ae88 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 May 2025 16:13:56 +0200
+Subject: ACPI: platform_profile: Avoid initializing on non-ACPI platforms
+
+From: Alexandre Ghiti <alexghiti@rivosinc.com>
+
+[ Upstream commit dd133162c9cff5951a692fab9811fadf46a46457 ]
+
+The platform profile driver is loaded even on platforms that do not have
+ACPI enabled. The initialization of the sysfs entries was recently moved
+from platform_profile_register() to the module init call, and those
+entries need acpi_kobj to be initialized which is not the case when ACPI
+is disabled.
+
+This results in the following warning:
+
+ WARNING: CPU: 5 PID: 1 at fs/sysfs/group.c:131 internal_create_group+0xa22/0xdd8
+ Modules linked in:
+ CPU: 5 UID: 0 PID: 1 Comm: swapper/0 Tainted: G        W           6.15.0-rc7-dirty #6 PREEMPT
+ Tainted: [W]=WARN
+ Hardware name: riscv-virtio,qemu (DT)
+ epc : internal_create_group+0xa22/0xdd8
+  ra : internal_create_group+0xa22/0xdd8
+
+ Call Trace:
+
+ internal_create_group+0xa22/0xdd8
+ sysfs_create_group+0x22/0x2e
+ platform_profile_init+0x74/0xb2
+ do_one_initcall+0x198/0xa9e
+ kernel_init_freeable+0x6d8/0x780
+ kernel_init+0x28/0x24c
+ ret_from_fork+0xe/0x18
+
+Fix this by checking if ACPI is enabled before trying to create sysfs
+entries.
+
+Fixes: 77be5cacb2c2 ("ACPI: platform_profile: Create class for ACPI platform profile")
+Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Reviewed-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Mark Pearson <mpearson-lenovo@squebb.ca>
+Link: https://patch.msgid.link/20250522141410.31315-1-alexghiti@rivosinc.com
+[ rjw: Subject and changelog edits ]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/platform_profile.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/acpi/platform_profile.c b/drivers/acpi/platform_profile.c
+index ffbfd32f4cf1b..b43f4459a4f61 100644
+--- a/drivers/acpi/platform_profile.c
++++ b/drivers/acpi/platform_profile.c
+@@ -688,6 +688,9 @@ static int __init platform_profile_init(void)
+ {
+       int err;
++      if (acpi_disabled)
++              return -EOPNOTSUPP;
++
+       err = class_register(&platform_profile_class);
+       if (err)
+               return err;
+-- 
+2.39.5
+
diff --git a/queue-6.15/acpi-resource-fix-a-typo-for-mechrevo-in-irq1_edge_l.patch b/queue-6.15/acpi-resource-fix-a-typo-for-mechrevo-in-irq1_edge_l.patch
new file mode 100644 (file)
index 0000000..d862f1e
--- /dev/null
@@ -0,0 +1,40 @@
+From f459322648c87692f5acff6d2f6d7ed61eb829ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Apr 2025 15:39:46 +0800
+Subject: ACPI: resource: fix a typo for MECHREVO in
+ irq1_edge_low_force_override[]
+
+From: Mingcong Bai <jeffbai@aosc.io>
+
+[ Upstream commit 113e04276018bd13978051d8b05a613b4d390cc9 ]
+
+The vendor name for MECHREVO was incorrectly spelled in commit
+b53f09ecd602 ("ACPI: resource: Do IRQ override on MECHREV GM7XG0M").
+
+Correct this typo in this trivial patch.
+
+Fixes: b53f09ecd602 ("ACPI: resource: Do IRQ override on MECHREV GM7XG0M")
+Signed-off-by: Mingcong Bai <jeffbai@aosc.io>
+Link: https://patch.msgid.link/20250417073947.47419-1-jeffbai@aosc.io
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/resource.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c
+index 14c7bac4100b4..7d59c6c9185fc 100644
+--- a/drivers/acpi/resource.c
++++ b/drivers/acpi/resource.c
+@@ -534,7 +534,7 @@ static const struct dmi_system_id irq1_level_low_skip_override[] = {
+  */
+ static const struct dmi_system_id irq1_edge_low_force_override[] = {
+       {
+-              /* MECHREV Jiaolong17KS Series GM7XG0M */
++              /* MECHREVO Jiaolong17KS Series GM7XG0M */
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_NAME, "GM7XG0M"),
+               },
+-- 
+2.39.5
+
diff --git a/queue-6.15/acpi-thermal-execute-_scp-before-reading-trip-points.patch b/queue-6.15/acpi-thermal-execute-_scp-before-reading-trip-points.patch
new file mode 100644 (file)
index 0000000..a1077b3
--- /dev/null
@@ -0,0 +1,57 @@
+From e8829aa4e8a574017e811d7f547211f8efc5cc92 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Apr 2025 18:54:55 +0200
+Subject: ACPI: thermal: Execute _SCP before reading trip points
+
+From: Armin Wolf <W_Armin@gmx.de>
+
+[ Upstream commit 3f7cd28ae3d1a1d6f151178469cfaef1b07fdbcc ]
+
+As specified in section 11.4.13 of the ACPI specification the
+operating system is required to evaluate the _ACx and _PSV objects
+after executing the _SCP control method.
+
+Move the execution of the _SCP control method before the invocation
+of acpi_thermal_get_trip_points() to avoid missing updates to the
+_ACx and _PSV objects.
+
+Fixes: b09872a652d3 ("ACPI: thermal: Fold acpi_thermal_get_info() into its caller")
+Signed-off-by: Armin Wolf <W_Armin@gmx.de>
+Link: https://patch.msgid.link/20250410165456.4173-3-W_Armin@gmx.de
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/thermal.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
+index 0c874186f8aed..5c2defe55898f 100644
+--- a/drivers/acpi/thermal.c
++++ b/drivers/acpi/thermal.c
+@@ -803,6 +803,12 @@ static int acpi_thermal_add(struct acpi_device *device)
+       acpi_thermal_aml_dependency_fix(tz);
++      /*
++       * Set the cooling mode [_SCP] to active cooling. This needs to happen before
++       * we retrieve the trip point values.
++       */
++      acpi_execute_simple_method(tz->device->handle, "_SCP", ACPI_THERMAL_MODE_ACTIVE);
++
+       /* Get trip points [_ACi, _PSV, etc.] (required). */
+       acpi_thermal_get_trip_points(tz);
+@@ -814,10 +820,6 @@ static int acpi_thermal_add(struct acpi_device *device)
+       if (result)
+               goto free_memory;
+-      /* Set the cooling mode [_SCP] to active cooling. */
+-      acpi_execute_simple_method(tz->device->handle, "_SCP",
+-                                 ACPI_THERMAL_MODE_ACTIVE);
+-
+       /* Determine the default polling frequency [_TZP]. */
+       if (tzp)
+               tz->polling_frequency = tzp;
+-- 
+2.39.5
+
diff --git a/queue-6.15/acpica-exserial-don-t-forget-to-handle-ffixedhw-opre.patch b/queue-6.15/acpica-exserial-don-t-forget-to-handle-ffixedhw-opre.patch
new file mode 100644 (file)
index 0000000..5470ab4
--- /dev/null
@@ -0,0 +1,45 @@
+From c1ce74a1d4abed5e35a80738fcea1c45760e1ceb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 21:43:11 +0300
+Subject: ACPICA: exserial: don't forget to handle FFixedHW opregions for
+ reading
+
+From: Daniil Tatianin <d-tatianin@yandex-team.ru>
+
+[ Upstream commit 0f8af0356a45547683a216e4921006a3c6a6d922 ]
+
+The initial commit that introduced support for FFixedHW operation
+regions did add a special case in the AcpiExReadSerialBus If, but
+forgot to actually handle it inside the switch, so add the missing case
+to prevent reads from failing with AE_AML_INVALID_SPACE_ID.
+
+Link: https://github.com/acpica/acpica/pull/998
+Fixes: ee64b827a9a ("ACPICA: Add support for FFH Opregion special context data")
+Signed-off-by: Daniil Tatianin <d-tatianin@yandex-team.ru>
+Link: https://patch.msgid.link/20250401184312.599962-1-d-tatianin@yandex-team.ru
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/acpica/exserial.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/acpi/acpica/exserial.c b/drivers/acpi/acpica/exserial.c
+index 5241f4c01c765..89a4ac447a2be 100644
+--- a/drivers/acpi/acpica/exserial.c
++++ b/drivers/acpi/acpica/exserial.c
+@@ -201,6 +201,12 @@ acpi_ex_read_serial_bus(union acpi_operand_object *obj_desc,
+               function = ACPI_READ;
+               break;
++      case ACPI_ADR_SPACE_FIXED_HARDWARE:
++
++              buffer_length = ACPI_FFH_INPUT_BUFFER_SIZE;
++              function = ACPI_READ;
++              break;
++
+       default:
+               return_ACPI_STATUS(AE_AML_INVALID_SPACE_ID);
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/af_packet-move-notifier-s-packet_dev_mc-out-of-rcu-c.patch b/queue-6.15/af_packet-move-notifier-s-packet_dev_mc-out-of-rcu-c.patch
new file mode 100644 (file)
index 0000000..f135e9f
--- /dev/null
@@ -0,0 +1,136 @@
+From e1d62964d3bf047cfcc378202bfe61caebc4678c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 May 2025 20:11:28 -0700
+Subject: af_packet: move notifier's packet_dev_mc out of rcu critical section
+
+From: Stanislav Fomichev <stfomichev@gmail.com>
+
+[ Upstream commit d8d85ef0a631df9127f202e6371bb33a0b589952 ]
+
+Syzkaller reports the following issue:
+
+ BUG: sleeping function called from invalid context at kernel/locking/mutex.c:578
+ __mutex_lock+0x106/0xe80 kernel/locking/mutex.c:746
+ team_change_rx_flags+0x38/0x220 drivers/net/team/team_core.c:1781
+ dev_change_rx_flags net/core/dev.c:9145 [inline]
+ __dev_set_promiscuity+0x3f8/0x590 net/core/dev.c:9189
+ netif_set_promiscuity+0x50/0xe0 net/core/dev.c:9201
+ dev_set_promiscuity+0x126/0x260 net/core/dev_api.c:286 packet_dev_mc net/packet/af_packet.c:3698 [inline]
+ packet_dev_mclist_delete net/packet/af_packet.c:3722 [inline]
+ packet_notifier+0x292/0xa60 net/packet/af_packet.c:4247
+ notifier_call_chain+0x1b3/0x3e0 kernel/notifier.c:85
+ call_netdevice_notifiers_extack net/core/dev.c:2214 [inline]
+ call_netdevice_notifiers net/core/dev.c:2228 [inline]
+ unregister_netdevice_many_notify+0x15d8/0x2330 net/core/dev.c:11972
+ rtnl_delete_link net/core/rtnetlink.c:3522 [inline]
+ rtnl_dellink+0x488/0x710 net/core/rtnetlink.c:3564
+ rtnetlink_rcv_msg+0x7cf/0xb70 net/core/rtnetlink.c:6955
+ netlink_rcv_skb+0x219/0x490 net/netlink/af_netlink.c:2534
+
+Calling `PACKET_ADD_MEMBERSHIP` on an ops-locked device can trigger
+the `NETDEV_UNREGISTER` notifier, which may require disabling promiscuous
+and/or allmulti mode. Both of these operations require acquiring
+the netdev instance lock.
+
+Move the call to `packet_dev_mc` outside of the RCU critical section.
+The `mclist` modifications (add, del, flush, unregister) are protected by
+the RTNL, not the RCU. The RCU only protects the `sklist` and its
+associated `sks`. The delayed operation on the `mclist` entry remains
+within the RTNL.
+
+Reported-by: syzbot+b191b5ccad8d7a986286@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=b191b5ccad8d7a986286
+Fixes: ad7c7b2172c3 ("net: hold netdev instance lock during sysfs operations")
+Signed-off-by: Stanislav Fomichev <stfomichev@gmail.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20250522031129.3247266-1-stfomichev@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/packet/af_packet.c | 21 ++++++++++++++++-----
+ net/packet/internal.h  |  1 +
+ 2 files changed, 17 insertions(+), 5 deletions(-)
+
+diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
+index d4dba06297c33..20be2c47cf419 100644
+--- a/net/packet/af_packet.c
++++ b/net/packet/af_packet.c
+@@ -3713,15 +3713,15 @@ static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i,
+ }
+ static void packet_dev_mclist_delete(struct net_device *dev,
+-                                   struct packet_mclist **mlp)
++                                   struct packet_mclist **mlp,
++                                   struct list_head *list)
+ {
+       struct packet_mclist *ml;
+       while ((ml = *mlp) != NULL) {
+               if (ml->ifindex == dev->ifindex) {
+-                      packet_dev_mc(dev, ml, -1);
++                      list_add(&ml->remove_list, list);
+                       *mlp = ml->next;
+-                      kfree(ml);
+               } else
+                       mlp = &ml->next;
+       }
+@@ -3769,6 +3769,7 @@ static int packet_mc_add(struct sock *sk, struct packet_mreq_max *mreq)
+       memcpy(i->addr, mreq->mr_address, i->alen);
+       memset(i->addr + i->alen, 0, sizeof(i->addr) - i->alen);
+       i->count = 1;
++      INIT_LIST_HEAD(&i->remove_list);
+       i->next = po->mclist;
+       po->mclist = i;
+       err = packet_dev_mc(dev, i, 1);
+@@ -4233,9 +4234,11 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
+ static int packet_notifier(struct notifier_block *this,
+                          unsigned long msg, void *ptr)
+ {
+-      struct sock *sk;
+       struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+       struct net *net = dev_net(dev);
++      struct packet_mclist *ml, *tmp;
++      LIST_HEAD(mclist);
++      struct sock *sk;
+       rcu_read_lock();
+       sk_for_each_rcu(sk, &net->packet.sklist) {
+@@ -4244,7 +4247,8 @@ static int packet_notifier(struct notifier_block *this,
+               switch (msg) {
+               case NETDEV_UNREGISTER:
+                       if (po->mclist)
+-                              packet_dev_mclist_delete(dev, &po->mclist);
++                              packet_dev_mclist_delete(dev, &po->mclist,
++                                                       &mclist);
+                       fallthrough;
+               case NETDEV_DOWN:
+@@ -4277,6 +4281,13 @@ static int packet_notifier(struct notifier_block *this,
+               }
+       }
+       rcu_read_unlock();
++
++      /* packet_dev_mc might grab instance locks so can't run under rcu */
++      list_for_each_entry_safe(ml, tmp, &mclist, remove_list) {
++              packet_dev_mc(dev, ml, -1);
++              kfree(ml);
++      }
++
+       return NOTIFY_DONE;
+ }
+diff --git a/net/packet/internal.h b/net/packet/internal.h
+index d5d70712007ad..1e743d0316fdd 100644
+--- a/net/packet/internal.h
++++ b/net/packet/internal.h
+@@ -11,6 +11,7 @@ struct packet_mclist {
+       unsigned short          type;
+       unsigned short          alen;
+       unsigned char           addr[MAX_ADDR_LEN];
++      struct list_head        remove_list;
+ };
+ /* kbdq - kernel block descriptor queue */
+-- 
+2.39.5
+
diff --git a/queue-6.15/alsa-core-fix-up-bus-match-const-issues.patch b/queue-6.15/alsa-core-fix-up-bus-match-const-issues.patch
new file mode 100644 (file)
index 0000000..f261b2e
--- /dev/null
@@ -0,0 +1,118 @@
+From c27644b6330efe447cf5d6385998795958b6ef3f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 May 2025 12:08:05 +0200
+Subject: ALSA: core: fix up bus match const issues.
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+[ Upstream commit 62f134ab190c5fd5c9f68fe638ad8e13bb8a4cb4 ]
+
+In commit d69d80484598 ("driver core: have match() callback in struct
+bus_type take a const *"), the match bus callback was changed to have
+the driver be a const pointer.  Unfortunately that const attribute was
+thrown away when container_of() is called, which is not correct and was
+not caught by the compiler due to how container_of() is implemented.
+Fix this up by correctly preserving the const attribute of the driver
+passed to the bus match function which requires the hdac_driver match
+function to also take a const pointer for the driver structure.
+
+Cc: Jaroslav Kysela <perex@perex.cz>
+Cc: Takashi Iwai <tiwai@suse.com>
+Fixes: d69d80484598 ("driver core: have match() callback in struct bus_type take a const *")
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Link: https://patch.msgid.link/2025052204-hyphen-thermal-3e72@gregkh
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/sound/hdaudio.h  | 4 ++--
+ sound/core/seq_device.c  | 2 +-
+ sound/hda/hda_bus_type.c | 6 +++---
+ sound/pci/hda/hda_bind.c | 4 ++--
+ 4 files changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
+index b098ceadbe74b..9a70048adbc06 100644
+--- a/include/sound/hdaudio.h
++++ b/include/sound/hdaudio.h
+@@ -223,7 +223,7 @@ struct hdac_driver {
+       struct device_driver driver;
+       int type;
+       const struct hda_device_id *id_table;
+-      int (*match)(struct hdac_device *dev, struct hdac_driver *drv);
++      int (*match)(struct hdac_device *dev, const struct hdac_driver *drv);
+       void (*unsol_event)(struct hdac_device *dev, unsigned int event);
+       /* fields used by ext bus APIs */
+@@ -235,7 +235,7 @@ struct hdac_driver {
+ #define drv_to_hdac_driver(_drv) container_of(_drv, struct hdac_driver, driver)
+ const struct hda_device_id *
+-hdac_get_device_id(struct hdac_device *hdev, struct hdac_driver *drv);
++hdac_get_device_id(struct hdac_device *hdev, const struct hdac_driver *drv);
+ /*
+  * Bus verb operators
+diff --git a/sound/core/seq_device.c b/sound/core/seq_device.c
+index 4492be5d2317c..bac9f86037342 100644
+--- a/sound/core/seq_device.c
++++ b/sound/core/seq_device.c
+@@ -43,7 +43,7 @@ MODULE_LICENSE("GPL");
+ static int snd_seq_bus_match(struct device *dev, const struct device_driver *drv)
+ {
+       struct snd_seq_device *sdev = to_seq_dev(dev);
+-      struct snd_seq_driver *sdrv = to_seq_drv(drv);
++      const struct snd_seq_driver *sdrv = to_seq_drv(drv);
+       return strcmp(sdrv->id, sdev->id) == 0 &&
+               sdrv->argsize == sdev->argsize;
+diff --git a/sound/hda/hda_bus_type.c b/sound/hda/hda_bus_type.c
+index 7545ace7b0ee4..eb72a7af2e56e 100644
+--- a/sound/hda/hda_bus_type.c
++++ b/sound/hda/hda_bus_type.c
+@@ -21,7 +21,7 @@ MODULE_LICENSE("GPL");
+  * driver id_table and returns the matching device id entry.
+  */
+ const struct hda_device_id *
+-hdac_get_device_id(struct hdac_device *hdev, struct hdac_driver *drv)
++hdac_get_device_id(struct hdac_device *hdev, const struct hdac_driver *drv)
+ {
+       if (drv->id_table) {
+               const struct hda_device_id *id  = drv->id_table;
+@@ -38,7 +38,7 @@ hdac_get_device_id(struct hdac_device *hdev, struct hdac_driver *drv)
+ }
+ EXPORT_SYMBOL_GPL(hdac_get_device_id);
+-static int hdac_codec_match(struct hdac_device *dev, struct hdac_driver *drv)
++static int hdac_codec_match(struct hdac_device *dev, const struct hdac_driver *drv)
+ {
+       if (hdac_get_device_id(dev, drv))
+               return 1;
+@@ -49,7 +49,7 @@ static int hdac_codec_match(struct hdac_device *dev, struct hdac_driver *drv)
+ static int hda_bus_match(struct device *dev, const struct device_driver *drv)
+ {
+       struct hdac_device *hdev = dev_to_hdac_dev(dev);
+-      struct hdac_driver *hdrv = drv_to_hdac_driver(drv);
++      const struct hdac_driver *hdrv = drv_to_hdac_driver(drv);
+       if (hdev->type != hdrv->type)
+               return 0;
+diff --git a/sound/pci/hda/hda_bind.c b/sound/pci/hda/hda_bind.c
+index 9521e5e0e6e6f..1fef350d821ef 100644
+--- a/sound/pci/hda/hda_bind.c
++++ b/sound/pci/hda/hda_bind.c
+@@ -18,10 +18,10 @@
+ /*
+  * find a matching codec id
+  */
+-static int hda_codec_match(struct hdac_device *dev, struct hdac_driver *drv)
++static int hda_codec_match(struct hdac_device *dev, const struct hdac_driver *drv)
+ {
+       struct hda_codec *codec = container_of(dev, struct hda_codec, core);
+-      struct hda_codec_driver *driver =
++      const struct hda_codec_driver *driver =
+               container_of(drv, struct hda_codec_driver, core);
+       const struct hda_device_id *list;
+       /* check probe_id instead of vendor_id if set */
+-- 
+2.39.5
+
diff --git a/queue-6.15/alsa-hda-allow-to-fetch-hlink-by-id.patch b/queue-6.15/alsa-hda-allow-to-fetch-hlink-by-id.patch
new file mode 100644 (file)
index 0000000..dbb6125
--- /dev/null
@@ -0,0 +1,113 @@
+From 767cb1883846adb4a1d815eb6eda9e660a75180f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Apr 2025 13:23:43 +0200
+Subject: ALSA: hda: Allow to fetch hlink by ID
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cezary Rojewski <cezary.rojewski@intel.com>
+
+[ Upstream commit 318c9eef63dd30b59dc8d63c7205ae997aa1e524 ]
+
+Starting with LNL platform, Intel HDAudio Links carry IDs specifying
+non-HDAudio transfer type they help facilitate e.g.: 0xC0 for I2S as
+defined by AZX_REG_ML_LEPTR_ID_INTEL_SSP.
+
+The mechanism accounts for LEPTR register as it is Reserved if
+LCAP.ALT for given Link equals 0.
+
+Reviewed-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
+Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
+Acked-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
+Link: https://patch.msgid.link/20250407112352.3720779-2-cezary.rojewski@intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 347c8d6db7c9 ("ASoC: Intel: avs: Fix PPLCxFMT calculation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/sound/hdaudio_ext.h         |  5 +++++
+ sound/hda/ext/hdac_ext_controller.c | 18 ++++++++++++++++++
+ 2 files changed, 23 insertions(+)
+
+diff --git a/include/sound/hdaudio_ext.h b/include/sound/hdaudio_ext.h
+index 4c7a40e149a59..60ec12e3b72f8 100644
+--- a/include/sound/hdaudio_ext.h
++++ b/include/sound/hdaudio_ext.h
+@@ -22,6 +22,7 @@ void snd_hdac_ext_bus_ppcap_enable(struct hdac_bus *chip, bool enable);
+ void snd_hdac_ext_bus_ppcap_int_enable(struct hdac_bus *chip, bool enable);
+ int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_bus *bus);
++struct hdac_ext_link *snd_hdac_ext_bus_get_hlink_by_id(struct hdac_bus *bus, u32 id);
+ struct hdac_ext_link *snd_hdac_ext_bus_get_hlink_by_addr(struct hdac_bus *bus, int addr);
+ struct hdac_ext_link *snd_hdac_ext_bus_get_hlink_by_name(struct hdac_bus *bus,
+                                                        const char *codec_name);
+@@ -97,12 +98,16 @@ struct hdac_ext_link {
+       void __iomem *ml_addr; /* link output stream reg pointer */
+       u32 lcaps;   /* link capablities */
+       u16 lsdiid;  /* link sdi identifier */
++      u32 id;
+       int ref_count;
+       struct list_head list;
+ };
++#define hdac_ext_link_alt(link)               ((link)->lcaps & AZX_ML_HDA_LCAP_ALT)
++#define hdac_ext_link_ofls(link)      ((link)->lcaps & AZX_ML_HDA_LCAP_OFLS)
++
+ int snd_hdac_ext_bus_link_power_up(struct hdac_ext_link *hlink);
+ int snd_hdac_ext_bus_link_power_down(struct hdac_ext_link *hlink);
+ int snd_hdac_ext_bus_link_power_up_all(struct hdac_bus *bus);
+diff --git a/sound/hda/ext/hdac_ext_controller.c b/sound/hda/ext/hdac_ext_controller.c
+index 6199bb60ccf00..2ec1531d1c1b5 100644
+--- a/sound/hda/ext/hdac_ext_controller.c
++++ b/sound/hda/ext/hdac_ext_controller.c
+@@ -9,6 +9,7 @@
+  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  */
++#include <linux/bitfield.h>
+ #include <linux/delay.h>
+ #include <linux/slab.h>
+ #include <sound/hda_register.h>
+@@ -81,6 +82,7 @@ int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_bus *bus)
+       int idx;
+       u32 link_count;
+       struct hdac_ext_link *hlink;
++      u32 leptr;
+       link_count = readl(bus->mlcap + AZX_REG_ML_MLCD) + 1;
+@@ -97,6 +99,11 @@ int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_bus *bus)
+               hlink->lcaps  = readl(hlink->ml_addr + AZX_REG_ML_LCAP);
+               hlink->lsdiid = readw(hlink->ml_addr + AZX_REG_ML_LSDIID);
++              if (hdac_ext_link_alt(hlink)) {
++                      leptr = readl(hlink->ml_addr + AZX_REG_ML_LEPTR);
++                      hlink->id = FIELD_GET(AZX_REG_ML_LEPTR_ID, leptr);
++              }
++
+               /* since link in On, update the ref */
+               hlink->ref_count = 1;
+@@ -125,6 +132,17 @@ void snd_hdac_ext_link_free_all(struct hdac_bus *bus)
+ }
+ EXPORT_SYMBOL_GPL(snd_hdac_ext_link_free_all);
++struct hdac_ext_link *snd_hdac_ext_bus_get_hlink_by_id(struct hdac_bus *bus, u32 id)
++{
++      struct hdac_ext_link *hlink;
++
++      list_for_each_entry(hlink, &bus->hlink_list, list)
++              if (hdac_ext_link_alt(hlink) && hlink->id == id)
++                      return hlink;
++      return NULL;
++}
++EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_get_hlink_by_id);
++
+ /**
+  * snd_hdac_ext_bus_get_hlink_by_addr - get hlink at specified address
+  * @bus: hlink's parent bus device
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm-aspeed-don-t-select-sram.patch b/queue-6.15/arm-aspeed-don-t-select-sram.patch
new file mode 100644 (file)
index 0000000..9962a5c
--- /dev/null
@@ -0,0 +1,37 @@
+From a788950cd4f8cf0239f7bf83c6d7378aac908479 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 May 2025 16:00:42 +0930
+Subject: ARM: aspeed: Don't select SRAM
+
+From: Joel Stanley <joel@jms.id.au>
+
+[ Upstream commit e4f59f873c3ffe2a0150e11115a83e2dfb671dbf ]
+
+The ASPEED devices have SRAM, but don't require it for basic function
+(or any function; there's no known users of the driver).
+
+Fixes: 8c2ed9bcfbeb ("arm: Add Aspeed machine")
+Signed-off-by: Joel Stanley <joel@jms.id.au>
+Link: https://patch.msgid.link/20250115103942.421429-1-joel@jms.id.au
+Signed-off-by: Andrew Jeffery <andrew@codeconstruct.com.au>
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-aspeed/Kconfig | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/arch/arm/mach-aspeed/Kconfig b/arch/arm/mach-aspeed/Kconfig
+index 080019aa6fcd8..fcf287edd0e5e 100644
+--- a/arch/arm/mach-aspeed/Kconfig
++++ b/arch/arm/mach-aspeed/Kconfig
+@@ -2,7 +2,6 @@
+ menuconfig ARCH_ASPEED
+       bool "Aspeed BMC architectures"
+       depends on (CPU_LITTLE_ENDIAN && ARCH_MULTI_V5) || ARCH_MULTI_V6 || ARCH_MULTI_V7
+-      select SRAM
+       select WATCHDOG
+       select ASPEED_WATCHDOG
+       select MFD_SYSCON
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm-dts-at91-at91sam9263-fix-nand-chip-selects.patch b/queue-6.15/arm-dts-at91-at91sam9263-fix-nand-chip-selects.patch
new file mode 100644 (file)
index 0000000..17cf5d1
--- /dev/null
@@ -0,0 +1,67 @@
+From 0b0afa45489a29cab050b43e8643ab4185835b24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Apr 2025 23:04:46 +0200
+Subject: ARM: dts: at91: at91sam9263: fix NAND chip selects
+
+From: Wolfram Sang <wsa+renesas@sang-engineering.com>
+
+[ Upstream commit c72ede1c24be689733bcd2233a3a56f2478429c8 ]
+
+NAND did not work on my USB-A9263. I discovered that the offending
+commit converted the PIO bank for chip selects wrongly, so all A9263
+boards need to be fixed.
+
+Fixes: 1004a2977bdc ("ARM: dts: at91: Switch to the new NAND bindings")
+Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Link: https://lore.kernel.org/r/20250402210446.5972-2-wsa+renesas@sang-engineering.com
+Signed-off-by: Claudiu Beznea <claudiu.beznea@tuxon.dev>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/microchip/at91sam9263ek.dts | 2 +-
+ arch/arm/boot/dts/microchip/tny_a9263.dts     | 2 +-
+ arch/arm/boot/dts/microchip/usb_a9263.dts     | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm/boot/dts/microchip/at91sam9263ek.dts b/arch/arm/boot/dts/microchip/at91sam9263ek.dts
+index 471ea25296aa1..93c5268a0845d 100644
+--- a/arch/arm/boot/dts/microchip/at91sam9263ek.dts
++++ b/arch/arm/boot/dts/microchip/at91sam9263ek.dts
+@@ -152,7 +152,7 @@
+                               nand@3 {
+                                       reg = <0x3 0x0 0x800000>;
+                                       rb-gpios = <&pioA 22 GPIO_ACTIVE_HIGH>;
+-                                      cs-gpios = <&pioA 15 GPIO_ACTIVE_HIGH>;
++                                      cs-gpios = <&pioD 15 GPIO_ACTIVE_HIGH>;
+                                       nand-bus-width = <8>;
+                                       nand-ecc-mode = "soft";
+                                       nand-on-flash-bbt;
+diff --git a/arch/arm/boot/dts/microchip/tny_a9263.dts b/arch/arm/boot/dts/microchip/tny_a9263.dts
+index 3dd48b3e06da5..fd8244b56e059 100644
+--- a/arch/arm/boot/dts/microchip/tny_a9263.dts
++++ b/arch/arm/boot/dts/microchip/tny_a9263.dts
+@@ -64,7 +64,7 @@
+                               nand@3 {
+                                       reg = <0x3 0x0 0x800000>;
+                                       rb-gpios = <&pioA 22 GPIO_ACTIVE_HIGH>;
+-                                      cs-gpios = <&pioA 15 GPIO_ACTIVE_HIGH>;
++                                      cs-gpios = <&pioD 15 GPIO_ACTIVE_HIGH>;
+                                       nand-bus-width = <8>;
+                                       nand-ecc-mode = "soft";
+                                       nand-on-flash-bbt;
+diff --git a/arch/arm/boot/dts/microchip/usb_a9263.dts b/arch/arm/boot/dts/microchip/usb_a9263.dts
+index 6af450cb387c9..8e1a3fb61087c 100644
+--- a/arch/arm/boot/dts/microchip/usb_a9263.dts
++++ b/arch/arm/boot/dts/microchip/usb_a9263.dts
+@@ -84,7 +84,7 @@
+                               nand@3 {
+                                       reg = <0x3 0x0 0x800000>;
+                                       rb-gpios = <&pioA 22 GPIO_ACTIVE_HIGH>;
+-                                      cs-gpios = <&pioA 15 GPIO_ACTIVE_HIGH>;
++                                      cs-gpios = <&pioD 15 GPIO_ACTIVE_HIGH>;
+                                       nand-bus-width = <8>;
+                                       nand-ecc-mode = "soft";
+                                       nand-on-flash-bbt;
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm-dts-at91-usb_a9263-fix-gpio-for-dataflash-chip-s.patch b/queue-6.15/arm-dts-at91-usb_a9263-fix-gpio-for-dataflash-chip-s.patch
new file mode 100644 (file)
index 0000000..8ac2530
--- /dev/null
@@ -0,0 +1,39 @@
+From 687e1b08f542079b52e1e74872e51da35bc592df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Apr 2025 13:27:43 +0200
+Subject: ARM: dts: at91: usb_a9263: fix GPIO for Dataflash chip select
+
+From: Wolfram Sang <wsa+renesas@sang-engineering.com>
+
+[ Upstream commit 67ba341e57ab158423818ed33bfa1c40eb0e5e7e ]
+
+Dataflash did not work on my board. After checking schematics and using
+the proper GPIO, it works now. Also, make it active low to avoid:
+
+flash@0 enforce active low on GPIO handle
+
+Fixes: 2432d201468d ("ARM: at91: dt: usb-a9263: add dataflash support")
+Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Link: https://lore.kernel.org/r/20250404112742.67416-2-wsa+renesas@sang-engineering.com
+Signed-off-by: Claudiu Beznea <claudiu.beznea@tuxon.dev>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/microchip/usb_a9263.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/microchip/usb_a9263.dts b/arch/arm/boot/dts/microchip/usb_a9263.dts
+index 60d7936dc5627..6af450cb387c9 100644
+--- a/arch/arm/boot/dts/microchip/usb_a9263.dts
++++ b/arch/arm/boot/dts/microchip/usb_a9263.dts
+@@ -58,7 +58,7 @@
+                       };
+                       spi0: spi@fffa4000 {
+-                              cs-gpios = <&pioB 15 GPIO_ACTIVE_HIGH>;
++                              cs-gpios = <&pioA 5 GPIO_ACTIVE_LOW>;
+                               status = "okay";
+                               flash@0 {
+                                       compatible = "atmel,at45", "atmel,dataflash";
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm-dts-qcom-apq8064-add-missing-clocks-to-the-timer.patch b/queue-6.15/arm-dts-qcom-apq8064-add-missing-clocks-to-the-timer.patch
new file mode 100644 (file)
index 0000000..331d7fc
--- /dev/null
@@ -0,0 +1,38 @@
+From dd646538b4fe5a54e5a61a43c52826e2607e962d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Mar 2025 15:21:59 +0200
+Subject: ARM: dts: qcom: apq8064: add missing clocks to the timer node
+
+From: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+
+[ Upstream commit 4b0eb149df58b6750cd8113e5ee5b3ac7cc51743 ]
+
+In order to fix DT schema warning and describe hardware properly, add
+missing sleep clock to the timer node.
+
+Fixes: f335b8af4fd5 ("ARM: dts: qcom: Add initial APQ8064 SoC and IFC6410 board device trees")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Link: https://lore.kernel.org/r/20250318-fix-nexus-4-v2-6-bcedd1406790@oss.qualcomm.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/qcom/qcom-apq8064.dtsi | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi
+index 5f1a6b4b76449..ba99e794dcd22 100644
+--- a/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi
++++ b/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi
+@@ -326,6 +326,8 @@
+                                    <GIC_PPI 3 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_EDGE_RISING)>;
+                       reg = <0x0200a000 0x100>;
+                       clock-frequency = <27000000>;
++                      clocks = <&sleep_clk>;
++                      clock-names = "sleep";
+                       cpu-offset = <0x80000>;
+               };
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm-dts-qcom-apq8064-merge-hw-splinlock-into-corresp.patch b/queue-6.15/arm-dts-qcom-apq8064-merge-hw-splinlock-into-corresp.patch
new file mode 100644 (file)
index 0000000..1141b61
--- /dev/null
@@ -0,0 +1,58 @@
+From db6e46c0ab0a488bb6b25818dbc03fe1b04693ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Mar 2025 15:22:00 +0200
+Subject: ARM: dts: qcom: apq8064 merge hw splinlock into corresponding syscon
+ device
+
+From: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+
+[ Upstream commit 325c6a441ae1f8fcb1db9bb945b8bdbd3142141e ]
+
+Follow up the expected way of describing the SFPB hwspinlock and merge
+hwspinlock node into corresponding syscon node, fixing several dt-schema
+warnings.
+
+Fixes: 24a9baf933dc ("ARM: dts: qcom: apq8064: Add hwmutex and SMEM nodes")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Link: https://lore.kernel.org/r/20250318-fix-nexus-4-v2-7-bcedd1406790@oss.qualcomm.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/qcom/qcom-apq8064.dtsi | 13 ++++---------
+ 1 file changed, 4 insertions(+), 9 deletions(-)
+
+diff --git a/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi
+index ba99e794dcd22..41f8dcde20819 100644
+--- a/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi
++++ b/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi
+@@ -213,12 +213,6 @@
+               };
+       };
+-      sfpb_mutex: hwmutex {
+-              compatible = "qcom,sfpb-mutex";
+-              syscon = <&sfpb_wrapper_mutex 0x604 0x4>;
+-              #hwlock-cells = <1>;
+-      };
+-
+       smem {
+               compatible = "qcom,smem";
+               memory-region = <&smem_region>;
+@@ -305,9 +299,10 @@
+                       pinctrl-0 = <&ps_hold_default_state>;
+               };
+-              sfpb_wrapper_mutex: syscon@1200000 {
+-                      compatible = "syscon";
+-                      reg = <0x01200000 0x8000>;
++              sfpb_mutex: hwmutex@1200600 {
++                      compatible = "qcom,sfpb-mutex";
++                      reg = <0x01200600 0x100>;
++                      #hwlock-cells = <1>;
+               };
+               intc: interrupt-controller@2000000 {
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm-dts-qcom-apq8064-move-replicator-out-of-soc-node.patch b/queue-6.15/arm-dts-qcom-apq8064-move-replicator-out-of-soc-node.patch
new file mode 100644 (file)
index 0000000..c5fabd0
--- /dev/null
@@ -0,0 +1,112 @@
+From 3332264ecebb1df9feee5b9234c2f3440b2666cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Mar 2025 15:22:03 +0200
+Subject: ARM: dts: qcom: apq8064: move replicator out of soc node
+
+From: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+
+[ Upstream commit f2420037d90a8354594b3da541e19dcbb60c75e1 ]
+
+The CoreSight static replicator device isn't a part of the system MMIO
+bus, as such it should not be a part of the soc node. Follow the example
+of other platforms and move it out of the soc bus to the top-level (and
+reoder ports to follow alphabetic order).
+
+Fixes: 7a5c275fd821 ("ARM: dts: qcom: Add apq8064 CoreSight components")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Link: https://lore.kernel.org/r/20250318-fix-nexus-4-v2-10-bcedd1406790@oss.qualcomm.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/qcom/qcom-apq8064.dtsi | 67 ++++++++++++------------
+ 1 file changed, 34 insertions(+), 33 deletions(-)
+
+diff --git a/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi
+index 41f8dcde20819..1dad4e4493926 100644
+--- a/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi
++++ b/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi
+@@ -278,6 +278,40 @@
+               };
+       };
++      replicator {
++              compatible = "arm,coresight-static-replicator";
++
++              clocks = <&rpmcc RPM_QDSS_CLK>;
++              clock-names = "apb_pclk";
++
++              in-ports {
++                      port {
++                              replicator_in: endpoint {
++                                      remote-endpoint = <&funnel_out>;
++                              };
++                      };
++              };
++
++              out-ports {
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++
++                      port@0 {
++                              reg = <0>;
++                              replicator_out0: endpoint {
++                                      remote-endpoint = <&etb_in>;
++                              };
++                      };
++
++                      port@1 {
++                              reg = <1>;
++                              replicator_out1: endpoint {
++                                      remote-endpoint = <&tpiu_in>;
++                              };
++                      };
++              };
++      };
++
+       soc: soc {
+               #address-cells = <1>;
+               #size-cells = <1>;
+@@ -1529,39 +1563,6 @@
+                       };
+               };
+-              replicator {
+-                      compatible = "arm,coresight-static-replicator";
+-
+-                      clocks = <&rpmcc RPM_QDSS_CLK>;
+-                      clock-names = "apb_pclk";
+-
+-                      out-ports {
+-                              #address-cells = <1>;
+-                              #size-cells = <0>;
+-
+-                              port@0 {
+-                                      reg = <0>;
+-                                      replicator_out0: endpoint {
+-                                              remote-endpoint = <&etb_in>;
+-                                      };
+-                              };
+-                              port@1 {
+-                                      reg = <1>;
+-                                      replicator_out1: endpoint {
+-                                              remote-endpoint = <&tpiu_in>;
+-                                      };
+-                              };
+-                      };
+-
+-                      in-ports {
+-                              port {
+-                                      replicator_in: endpoint {
+-                                              remote-endpoint = <&funnel_out>;
+-                                      };
+-                              };
+-                      };
+-              };
+-
+               funnel@1a04000 {
+                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+                       reg = <0x1a04000 0x1000>;
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-defconfig-mediatek-enable-phy-drivers.patch b/queue-6.15/arm64-defconfig-mediatek-enable-phy-drivers.patch
new file mode 100644 (file)
index 0000000..5f20319
--- /dev/null
@@ -0,0 +1,52 @@
+From cb3032a2d880962e87afd4b4c5932db015d06c7f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 May 2025 18:49:24 +0530
+Subject: arm64: defconfig: mediatek: enable PHY drivers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Vignesh Raman <vignesh.raman@collabora.com>
+
+[ Upstream commit f52cd248d844f9451858992f924988ac413fdc7e ]
+
+The mediatek display driver fails to probe on mt8173-elm-hana and
+mt8183-kukui-jacuzzi-juniper-sku16 in v6.14-rc4 due to missing PHY
+configurations.
+
+Commit 924d66011f24 ("drm/mediatek: stop selecting foreign drivers")
+stopped selecting the MediaTek PHY drivers, requiring them to be
+explicitly enabled in defconfig.
+
+Enable the following PHY drivers for MediaTek platforms:
+CONFIG_PHY_MTK_HDMI=m for HDMI display
+CONFIG_PHY_MTK_MIPI_DSI=m for DSI display
+CONFIG_PHY_MTK_DP=m for DP display
+
+Fixes: 924d66011f24 ("drm/mediatek: stop selecting foreign drivers")
+Reviewed-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Signed-off-by: Vignesh Raman <vignesh.raman@collabora.com>
+Link: https://lore.kernel.org/r/20250512131933.1247830-1-vignesh.raman@collabora.com
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/configs/defconfig | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
+index c4ce2c67c0e06..8e5d4dbd74e50 100644
+--- a/arch/arm64/configs/defconfig
++++ b/arch/arm64/configs/defconfig
+@@ -1587,6 +1587,9 @@ CONFIG_PHY_HISTB_COMBPHY=y
+ CONFIG_PHY_HISI_INNO_USB2=y
+ CONFIG_PHY_MVEBU_CP110_COMPHY=y
+ CONFIG_PHY_MTK_TPHY=y
++CONFIG_PHY_MTK_HDMI=m
++CONFIG_PHY_MTK_MIPI_DSI=m
++CONFIG_PHY_MTK_DP=m
+ CONFIG_PHY_QCOM_EDP=m
+ CONFIG_PHY_QCOM_PCIE2=m
+ CONFIG_PHY_QCOM_QMP=m
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-allwinner-a100-set-maximum-mmc-frequency.patch b/queue-6.15/arm64-dts-allwinner-a100-set-maximum-mmc-frequency.patch
new file mode 100644 (file)
index 0000000..63f75a4
--- /dev/null
@@ -0,0 +1,55 @@
+From f86f0a2f52ef4f2fa311144fa24a9512c8f7efc1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 May 2025 21:24:16 +0100
+Subject: arm64: dts: allwinner: a100: set maximum MMC frequency
+
+From: Andre Przywara <andre.przywara@arm.com>
+
+[ Upstream commit d8f10550448b03d3c5c6d9392119205c65ebfc89 ]
+
+The manual for the Allwinner A133 SoC mentions that the maximum
+supported MMC frequency is 150 MHz, for all of the MMC devices.
+
+Describe that in the DT entry, to help drivers setting the right
+interface frequency.
+
+Fixes: fcfbb8d9ec58 ("arm64: allwinner: a100: Add MMC related nodes")
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Link: https://patch.msgid.link/20250505202416.23753-1-andre.przywara@arm.com
+Signed-off-by: Chen-Yu Tsai <wens@csie.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi
+index f9f6fea03b744..bd366389b2389 100644
+--- a/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi
++++ b/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi
+@@ -252,6 +252,7 @@
+                       interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&mmc0_pins>;
++                      max-frequency = <150000000>;
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+@@ -267,6 +268,7 @@
+                       interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&mmc1_pins>;
++                      max-frequency = <150000000>;
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+@@ -282,6 +284,7 @@
+                       interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&mmc2_pins>;
++                      max-frequency = <150000000>;
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-imx8mm-beacon-fix-rtc-capacitive-load.patch b/queue-6.15/arm64-dts-imx8mm-beacon-fix-rtc-capacitive-load.patch
new file mode 100644 (file)
index 0000000..0456a65
--- /dev/null
@@ -0,0 +1,37 @@
+From f526917e9ed57ebd1cdab0c9873f47fbabd8a7d5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Apr 2025 20:01:27 -0500
+Subject: arm64: dts: imx8mm-beacon: Fix RTC capacitive load
+
+From: Adam Ford <aford173@gmail.com>
+
+[ Upstream commit 2e98d456666d63f897ba153210bcef9d78ba0f3a ]
+
+Although not noticeable when used every day, the RTC appears to drift when
+left to sit over time.  This is due to the capacitive load not being
+properly set. Fix RTC drift by correcting the capacitive load setting
+from 7000 to 12500, which matches the actual hardware configuration.
+
+Fixes: 593816fa2f35 ("arm64: dts: imx: Add Beacon i.MX8m-Mini development kit")
+Signed-off-by: Adam Ford <aford173@gmail.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi
+index 62ed64663f495..9ba0cb89fa24e 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi
+@@ -233,6 +233,7 @@
+       rtc: rtc@51 {
+               compatible = "nxp,pcf85263";
+               reg = <0x51>;
++              quartz-load-femtofarads = <12500>;
+       };
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-imx8mm-beacon-set-sai5-mclk-direction-to-o.patch b/queue-6.15/arm64-dts-imx8mm-beacon-set-sai5-mclk-direction-to-o.patch
new file mode 100644 (file)
index 0000000..f20dd2a
--- /dev/null
@@ -0,0 +1,41 @@
+From 6a1e3131efbd90c1928d0994188dddb87324a511 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Apr 2025 20:01:30 -0500
+Subject: arm64: dts: imx8mm-beacon: Set SAI5 MCLK direction to output for HDMI
+ audio
+
+From: Adam Ford <aford173@gmail.com>
+
+[ Upstream commit 8c716f80dfe8cd6ed9a2696847cea1affeeff6ff ]
+
+The HDMI bridge chip fails to generate an audio source due to the SAI5
+master clock (MCLK) direction not being set to output. This prevents proper
+clocking of the HDMI audio interface.
+
+Add the `fsl,sai-mclk-direction-output` property to the SAI5 node to ensure
+the MCLK is driven by the SoC, resolving the HDMI sound issue.
+
+Fixes: 8ad7d14d99f3 ("arm64: dts: imx8mm-beacon: Add HDMI video with sound")
+Signed-off-by: Adam Ford <aford173@gmail.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/freescale/imx8mm-beacon-kit.dts | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm-beacon-kit.dts b/arch/arm64/boot/dts/freescale/imx8mm-beacon-kit.dts
+index 97ff1ddd63188..734a75198f06e 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mm-beacon-kit.dts
++++ b/arch/arm64/boot/dts/freescale/imx8mm-beacon-kit.dts
+@@ -124,6 +124,7 @@
+       assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
+       assigned-clock-rates = <24576000>;
+       #sound-dai-cells = <0>;
++      fsl,sai-mclk-direction-output;
+       status = "okay";
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-imx8mn-beacon-fix-rtc-capacitive-load.patch b/queue-6.15/arm64-dts-imx8mn-beacon-fix-rtc-capacitive-load.patch
new file mode 100644 (file)
index 0000000..a6bd211
--- /dev/null
@@ -0,0 +1,38 @@
+From 80fb8dc88712f1a47d8381ad3b2b51399ed13832 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Apr 2025 20:01:28 -0500
+Subject: arm64: dts: imx8mn-beacon: Fix RTC capacitive load
+
+From: Adam Ford <aford173@gmail.com>
+
+[ Upstream commit c3f03bec30efd5082b55876846d57b5d17dae7b9 ]
+
+Although not noticeable when used every day, the RTC appears to drift when
+left to sit over time.  This is due to the capacitive load not being
+properly set. Fix RTC drift by correcting the capacitive load setting
+from 7000 to 12500, which matches the actual hardware configuration.
+
+Fixes: 36ca3c8ccb53 ("arm64: dts: imx: Add Beacon i.MX8M Nano development kit")
+Signed-off-by: Adam Ford <aford173@gmail.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/freescale/imx8mn-beacon-som.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mn-beacon-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mn-beacon-som.dtsi
+index 2a64115eebf1c..bb11590473a4c 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mn-beacon-som.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mn-beacon-som.dtsi
+@@ -242,6 +242,7 @@
+       rtc: rtc@51 {
+               compatible = "nxp,pcf85263";
+               reg = <0x51>;
++              quartz-load-femtofarads = <12500>;
+       };
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-imx8mn-beacon-set-sai5-mclk-direction-to-o.patch b/queue-6.15/arm64-dts-imx8mn-beacon-set-sai5-mclk-direction-to-o.patch
new file mode 100644 (file)
index 0000000..6e9e263
--- /dev/null
@@ -0,0 +1,41 @@
+From a605c4820dd8d0690dbf00281ed7f7f934790c55 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Apr 2025 20:01:31 -0500
+Subject: arm64: dts: imx8mn-beacon: Set SAI5 MCLK direction to output for HDMI
+ audio
+
+From: Adam Ford <aford173@gmail.com>
+
+[ Upstream commit a747c4dd2a60c4d0179b372032a4b98548135096 ]
+
+The HDMI bridge chip fails to generate an audio source due to the SAI5
+master clock (MCLK) direction not being set to output. This prevents proper
+clocking of the HDMI audio interface.
+
+Add the `fsl,sai-mclk-direction-output` property to the SAI5 node to ensure
+the MCLK is driven by the SoC, resolving the HDMI sound issue.
+
+Fixes: 1d6880ceef43 ("arm64: dts: imx8mn-beacon: Add HDMI video with sound")
+Signed-off-by: Adam Ford <aford173@gmail.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/freescale/imx8mn-beacon-kit.dts | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mn-beacon-kit.dts b/arch/arm64/boot/dts/freescale/imx8mn-beacon-kit.dts
+index 1df5ceb113879..37fc5ed98d7f6 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mn-beacon-kit.dts
++++ b/arch/arm64/boot/dts/freescale/imx8mn-beacon-kit.dts
+@@ -124,6 +124,7 @@
+       assigned-clock-parents = <&clk IMX8MN_AUDIO_PLL1_OUT>;
+       assigned-clock-rates = <24576000>;
+       #sound-dai-cells = <0>;
++      fsl,sai-mclk-direction-output;
+       status = "okay";
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-imx8mp-beacon-fix-rtc-capacitive-load.patch b/queue-6.15/arm64-dts-imx8mp-beacon-fix-rtc-capacitive-load.patch
new file mode 100644 (file)
index 0000000..30d5ef5
--- /dev/null
@@ -0,0 +1,38 @@
+From b13947f6ace696464a1adfc6be0e6b12c8db16db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Apr 2025 20:01:29 -0500
+Subject: arm64: dts: imx8mp-beacon: Fix RTC capacitive load
+
+From: Adam Ford <aford173@gmail.com>
+
+[ Upstream commit 6821ee17537938e919e8b86a541aae451f73165b ]
+
+Although not noticeable when used every day, the RTC appears to drift when
+left to sit over time.  This is due to the capacitive load not being
+properly set. Fix RTC drift by correcting the capacitive load setting
+from 7000 to 12500, which matches the actual hardware configuration.
+
+Fixes: 25a5ccdce767 ("arm64: dts: freescale: Introduce imx8mp-beacon-kit")
+Signed-off-by: Adam Ford <aford173@gmail.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/freescale/imx8mp-beacon-som.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mp-beacon-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-beacon-som.dtsi
+index 15f7ab58db36c..88561df70d03a 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mp-beacon-som.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mp-beacon-som.dtsi
+@@ -257,6 +257,7 @@
+       rtc: rtc@51 {
+               compatible = "nxp,pcf85263";
+               reg = <0x51>;
++              quartz-load-femtofarads = <12500>;
+       };
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-mediatek-mt6357-drop-regulator-fixed-compa.patch b/queue-6.15/arm64-dts-mediatek-mt6357-drop-regulator-fixed-compa.patch
new file mode 100644 (file)
index 0000000..4926445
--- /dev/null
@@ -0,0 +1,121 @@
+From 1b12dd2361e391dae8dfbca99b9ea16149f621f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 May 2025 11:32:10 -0400
+Subject: arm64: dts: mediatek: mt6357: Drop regulator-fixed compatibles
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+
+[ Upstream commit d77e89b7b03fb945b4353f2dcc4a70b34baa7bcb ]
+
+Some of the regulators in the MT6357 PMIC dtsi have compatible set to
+regulator-fixed, even though they don't serve any purpose: all those
+regulators are handled as a whole by the mt6357-regulator driver. In
+fact this is the only dtsi in this family of chips where this is the
+case: mt6359 and mt6358 don't have any such compatibles.
+
+A side-effect caused by this is that the DT kselftest, which is supposed
+to identify nodes with compatibles that can be probed, but haven't,
+shows these nodes as failures.
+
+Remove the useless compatibles to move the dtsi in line with the others
+in its family and fix the DT kselftest failures.
+
+Fixes: 55749bb478f8 ("arm64: dts: mediatek: add mt6357 device-tree")
+Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Link: https://lore.kernel.org/r/20250502-mt6357-regulator-fixed-compatibles-removal-v1-1-a582c16743fe@collabora.com
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt6357.dtsi | 10 ----------
+ 1 file changed, 10 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt6357.dtsi b/arch/arm64/boot/dts/mediatek/mt6357.dtsi
+index 5fafa842d312f..dca4e5c3d8e21 100644
+--- a/arch/arm64/boot/dts/mediatek/mt6357.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt6357.dtsi
+@@ -60,7 +60,6 @@
+                       };
+                       mt6357_vfe28_reg: ldo-vfe28 {
+-                              compatible = "regulator-fixed";
+                               regulator-name = "vfe28";
+                               regulator-min-microvolt = <2800000>;
+                               regulator-max-microvolt = <2800000>;
+@@ -75,7 +74,6 @@
+                       };
+                       mt6357_vrf18_reg: ldo-vrf18 {
+-                              compatible = "regulator-fixed";
+                               regulator-name = "vrf18";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+@@ -83,7 +81,6 @@
+                       };
+                       mt6357_vrf12_reg: ldo-vrf12 {
+-                              compatible = "regulator-fixed";
+                               regulator-name = "vrf12";
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <1200000>;
+@@ -112,7 +109,6 @@
+                       };
+                       mt6357_vcn28_reg: ldo-vcn28 {
+-                              compatible = "regulator-fixed";
+                               regulator-name = "vcn28";
+                               regulator-min-microvolt = <2800000>;
+                               regulator-max-microvolt = <2800000>;
+@@ -120,7 +116,6 @@
+                       };
+                       mt6357_vcn18_reg: ldo-vcn18 {
+-                              compatible = "regulator-fixed";
+                               regulator-name = "vcn18";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+@@ -142,7 +137,6 @@
+                       };
+                       mt6357_vcamio_reg: ldo-vcamio18 {
+-                              compatible = "regulator-fixed";
+                               regulator-name = "vcamio";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+@@ -175,7 +169,6 @@
+                       };
+                       mt6357_vaux18_reg: ldo-vaux18 {
+-                              compatible = "regulator-fixed";
+                               regulator-name = "vaux18";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+@@ -183,7 +176,6 @@
+                       };
+                       mt6357_vaud28_reg: ldo-vaud28 {
+-                              compatible = "regulator-fixed";
+                               regulator-name = "vaud28";
+                               regulator-min-microvolt = <2800000>;
+                               regulator-max-microvolt = <2800000>;
+@@ -191,7 +183,6 @@
+                       };
+                       mt6357_vio28_reg: ldo-vio28 {
+-                              compatible = "regulator-fixed";
+                               regulator-name = "vio28";
+                               regulator-min-microvolt = <2800000>;
+                               regulator-max-microvolt = <2800000>;
+@@ -199,7 +190,6 @@
+                       };
+                       mt6357_vio18_reg: ldo-vio18 {
+-                              compatible = "regulator-fixed";
+                               regulator-name = "vio18";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-mediatek-mt8188-fix-iommu-device-for-rdma0.patch b/queue-6.15/arm64-dts-mediatek-mt8188-fix-iommu-device-for-rdma0.patch
new file mode 100644 (file)
index 0000000..45c64b9
--- /dev/null
@@ -0,0 +1,53 @@
+From 5870f37dd5601d0a606c590efad9d486007e77d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Apr 2025 17:23:02 +0800
+Subject: arm64: dts: mediatek: mt8188: Fix IOMMU device for rdma0
+
+From: Chen-Yu Tsai <wenst@chromium.org>
+
+[ Upstream commit 267623000d11f6d483214be2484555f600393a12 ]
+
+Based on the comments in the MT8188 IOMMU binding header, the rdma0
+device specifies the wrong IOMMU device for the IOMMU port it is
+tied to:
+
+    This SoC have two MM IOMMU HWs, this is the connected information:
+    iommu-vdo: larb0/2/5/9/10/11A/11C/13/16B/17B/19/21
+    iommu-vpp: larb1/3/4/6/7/11B/12/14/15/16A/17A/23/27
+
+rdma0's endpoint is M4U_PORT_L1_DISP_RDMA0 (on larb1), which should use
+iommu-vpp, but it is currently tied to iommu-vdo.
+
+Somehow this went undetected until recently in Linux v6.15-rc1 with some
+IOMMU subsystem framework changes that caused the IOMMU to no longer
+work. The IOMMU would fail to probe if any devices associated with it
+could not be successfully attached. Prior to these changes, only the
+end device would be left without an IOMMU attached.
+
+Fixes: 7075b21d1a8e ("arm64: dts: mediatek: mt8188: Add display nodes for vdosys0")
+Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: Jason-JH Lin <jason-jh.lin@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20250408092303.3563231-1-wenst@chromium.org
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt8188.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt8188.dtsi b/arch/arm64/boot/dts/mediatek/mt8188.dtsi
+index 69a8423d38589..29d35ca945973 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8188.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8188.dtsi
+@@ -2579,7 +2579,7 @@
+                       reg = <0 0x1c002000 0 0x1000>;
+                       clocks = <&vdosys0 CLK_VDO0_DISP_RDMA0>;
+                       interrupts = <GIC_SPI 638 IRQ_TYPE_LEVEL_HIGH 0>;
+-                      iommus = <&vdo_iommu M4U_PORT_L1_DISP_RDMA0>;
++                      iommus = <&vpp_iommu M4U_PORT_L1_DISP_RDMA0>;
+                       power-domains = <&spm MT8188_POWER_DOMAIN_VDOSYS0>;
+                       mediatek,gce-client-reg = <&gce0 SUBSYS_1c00XXXX 0x2000 0x1000>;
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-mediatek-mt8195-reparent-vdec1-2-and-venc1.patch b/queue-6.15/arm64-dts-mediatek-mt8195-reparent-vdec1-2-and-venc1.patch
new file mode 100644 (file)
index 0000000..0eeeed5
--- /dev/null
@@ -0,0 +1,110 @@
+From 41cf40cb82861118a2b3244acf9e82eed1bdc3f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Apr 2025 11:06:15 +0200
+Subject: arm64: dts: mediatek: mt8195: Reparent vdec1/2 and venc1 power
+ domains
+
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+[ Upstream commit 394f29033324e2317bfd6a7ed99b9a60832b36a2 ]
+
+By hardware, the first and second core of the video decoder IP
+need the VDEC_SOC to be powered up in order to be able to be
+accessed (both internally, by firmware, and externally, by the
+kernel).
+Similarly, for the video encoder IP, the second core needs the
+first core to be powered up in order to be accessible.
+
+Fix that by reparenting the VDEC1/2 power domains to be children
+of VDEC0 (VDEC_SOC), and the VENC1 to be a child of VENC0.
+
+Fixes: 2b515194bf0c ("arm64: dts: mt8195: Add power domains controller")
+Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
+Link: https://lore.kernel.org/r/20250402090615.25871-3-angelogioacchino.delregno@collabora.com
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt8195.dtsi | 50 +++++++++++++-----------
+ 1 file changed, 27 insertions(+), 23 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+index 4f2dc0a755661..1ded4b3f87605 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+@@ -617,22 +617,6 @@
+                                       #size-cells = <0>;
+                                       #power-domain-cells = <1>;
+-                                      power-domain@MT8195_POWER_DOMAIN_VDEC1 {
+-                                              reg = <MT8195_POWER_DOMAIN_VDEC1>;
+-                                              clocks = <&vdecsys CLK_VDEC_LARB1>;
+-                                              clock-names = "vdec1-0";
+-                                              mediatek,infracfg = <&infracfg_ao>;
+-                                              #power-domain-cells = <0>;
+-                                      };
+-
+-                                      power-domain@MT8195_POWER_DOMAIN_VENC_CORE1 {
+-                                              reg = <MT8195_POWER_DOMAIN_VENC_CORE1>;
+-                                              clocks = <&vencsys_core1 CLK_VENC_CORE1_LARB>;
+-                                              clock-names = "venc1-larb";
+-                                              mediatek,infracfg = <&infracfg_ao>;
+-                                              #power-domain-cells = <0>;
+-                                      };
+-
+                                       power-domain@MT8195_POWER_DOMAIN_VDOSYS0 {
+                                               reg = <MT8195_POWER_DOMAIN_VDOSYS0>;
+                                               clocks = <&topckgen CLK_TOP_CFG_VDO0>,
+@@ -678,15 +662,25 @@
+                                                       clocks = <&vdecsys_soc CLK_VDEC_SOC_LARB1>;
+                                                       clock-names = "vdec0-0";
+                                                       mediatek,infracfg = <&infracfg_ao>;
++                                                      #address-cells = <1>;
++                                                      #size-cells = <0>;
+                                                       #power-domain-cells = <0>;
+-                                              };
+-                                              power-domain@MT8195_POWER_DOMAIN_VDEC2 {
+-                                                      reg = <MT8195_POWER_DOMAIN_VDEC2>;
+-                                                      clocks = <&vdecsys_core1 CLK_VDEC_CORE1_LARB1>;
+-                                                      clock-names = "vdec2-0";
+-                                                      mediatek,infracfg = <&infracfg_ao>;
+-                                                      #power-domain-cells = <0>;
++                                                      power-domain@MT8195_POWER_DOMAIN_VDEC1 {
++                                                              reg = <MT8195_POWER_DOMAIN_VDEC1>;
++                                                              clocks = <&vdecsys CLK_VDEC_LARB1>;
++                                                              clock-names = "vdec1-0";
++                                                              mediatek,infracfg = <&infracfg_ao>;
++                                                              #power-domain-cells = <0>;
++                                                      };
++
++                                                      power-domain@MT8195_POWER_DOMAIN_VDEC2 {
++                                                              reg = <MT8195_POWER_DOMAIN_VDEC2>;
++                                                              clocks = <&vdecsys_core1 CLK_VDEC_CORE1_LARB1>;
++                                                              clock-names = "vdec2-0";
++                                                              mediatek,infracfg = <&infracfg_ao>;
++                                                              #power-domain-cells = <0>;
++                                                      };
+                                               };
+                                               power-domain@MT8195_POWER_DOMAIN_VENC {
+@@ -694,7 +688,17 @@
+                                                       clocks = <&vencsys CLK_VENC_LARB>;
+                                                       clock-names = "venc0-larb";
+                                                       mediatek,infracfg = <&infracfg_ao>;
++                                                      #address-cells = <1>;
++                                                      #size-cells = <0>;
+                                                       #power-domain-cells = <0>;
++
++                                                      power-domain@MT8195_POWER_DOMAIN_VENC_CORE1 {
++                                                              reg = <MT8195_POWER_DOMAIN_VENC_CORE1>;
++                                                              clocks = <&vencsys_core1 CLK_VENC_CORE1_LARB>;
++                                                              clock-names = "venc1-larb";
++                                                              mediatek,infracfg = <&infracfg_ao>;
++                                                              #power-domain-cells = <0>;
++                                                      };
+                                               };
+                                               power-domain@MT8195_POWER_DOMAIN_VDOSYS1 {
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-mediatek-mt8390-genio-common-set-ssusb2-de.patch b/queue-6.15/arm64-dts-mediatek-mt8390-genio-common-set-ssusb2-de.patch
new file mode 100644 (file)
index 0000000..6d073cd
--- /dev/null
@@ -0,0 +1,68 @@
+From 7e8d938dc293b2bd3a6898f24638a04f043e1290 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 May 2025 15:17:19 +0200
+Subject: arm64: dts: mediatek: mt8390-genio-common: Set ssusb2 default dual
+ role mode to host
+
+From: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
+
+[ Upstream commit f9167f15dd4e70b124023a2f7ba2b09401b3b6ff ]
+
+On the Mediatek Genio 510-EVK and 700-EVK boards, ssusb2 controller is
+one but has two ports: one is routed to the M.2 slot, the other is on
+the RPi header who does support full OTG.
+Since Mediatek Genio 700-EVK USB support was added, dual role mode
+property is set to otg for ssusb2. This config prevents the M.2
+Wifi/Bluetooth module, present on those boards and exposing Bluetooth
+as an USB device to be properly detected at startup as the default role
+is device.
+To keep the OTG functionality and make the M.2 module be detected at
+the same time, add role-switch-default-mode property set to host and
+also fix the polarity of GPIO associated to the USB connector, so the
+ssusb2 controller role is properly set to host when the other port is
+unused.
+
+Fixes: 1afaeca17238 ("arm64: dts: mediatek: mt8390-genio-700: Add USB, TypeC Controller, MUX")
+Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
+Link: https://lore.kernel.org/r/20250502-mtk-genio-510-700-fix-bt-detection-v2-1-870aa2145480@collabora.com
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../arm64/boot/dts/mediatek/mt8390-genio-common.dtsi | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt8390-genio-common.dtsi b/arch/arm64/boot/dts/mediatek/mt8390-genio-common.dtsi
+index 60139e6dffd8e..6a75b230282ed 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8390-genio-common.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8390-genio-common.dtsi
+@@ -1199,8 +1199,18 @@
+ };
+ &ssusb2 {
++      /*
++       * the ssusb2 controller is one but we got two ports : one is routed
++       * to the M.2 slot, the other is on the RPi header who does support
++       * full OTG.
++       * As the controller is shared between them, the role switch default
++       * mode is set to host to make any peripheral inserted in the M.2
++       * slot (i.e BT/WIFI module) be detected when the other port is
++       * unused.
++       */
+       dr_mode = "otg";
+       maximum-speed = "high-speed";
++      role-switch-default-mode = "host";
+       usb-role-switch;
+       vusb33-supply = <&mt6359_vusb_ldo_reg>;
+       wakeup-source;
+@@ -1211,7 +1221,7 @@
+       connector {
+               compatible = "gpio-usb-b-connector", "usb-b-connector";
+               type = "micro";
+-              id-gpios = <&pio 89 GPIO_ACTIVE_HIGH>;
++              id-gpios = <&pio 89 GPIO_ACTIVE_LOW>;
+               vbus-supply = <&usb_p2_vbus>;
+       };
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-mt6359-add-missing-compatible-property-to-.patch b/queue-6.15/arm64-dts-mt6359-add-missing-compatible-property-to-.patch
new file mode 100644 (file)
index 0000000..b01bede
--- /dev/null
@@ -0,0 +1,41 @@
+From d1e7da9f35b0d9842836c7c7a10f7ea34497816b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 May 2025 15:23:39 +0200
+Subject: arm64: dts: mt6359: Add missing 'compatible' property to regulators
+ node
+
+From: Julien Massot <julien.massot@collabora.com>
+
+[ Upstream commit 1fe38d2a19950fa6dbc384ee8967c057aef9faf4 ]
+
+The 'compatible' property is required by the
+'mfd/mediatek,mt6397.yaml' binding. Add it to fix the following
+dtb-check error:
+mediatek/mt8395-radxa-nio-12l.dtb: pmic: regulators:
+'compatible' is a required property
+
+Fixes: 3b7d143be4b7 ("arm64: dts: mt6359: add PMIC MT6359 related nodes")
+Signed-off-by: Julien Massot <julien.massot@collabora.com>
+Link: https://lore.kernel.org/r/20250505-mt8395-dtb-errors-v1-3-9c4714dcdcdb@collabora.com
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt6359.dtsi | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt6359.dtsi b/arch/arm64/boot/dts/mediatek/mt6359.dtsi
+index 7b10f9c59819a..0c479404b3fe3 100644
+--- a/arch/arm64/boot/dts/mediatek/mt6359.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt6359.dtsi
+@@ -20,6 +20,8 @@
+               };
+               regulators {
++                      compatible = "mediatek,mt6359-regulator";
++
+                       mt6359_vs1_buck_reg: buck_vs1 {
+                               regulator-name = "vs1";
+                               regulator-min-microvolt = <800000>;
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-mt6359-rename-rtc-node-to-match-binding-ex.patch b/queue-6.15/arm64-dts-mt6359-rename-rtc-node-to-match-binding-ex.patch
new file mode 100644 (file)
index 0000000..b2d99d2
--- /dev/null
@@ -0,0 +1,42 @@
+From 72dfa519dce82bca697ca08ae8d3b4beb4a77942 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 May 2025 10:19:58 +0200
+Subject: arm64: dts: mt6359: Rename RTC node to match binding expectations
+
+From: Julien Massot <julien.massot@collabora.com>
+
+[ Upstream commit cfe035d8662cfbd6edff9bd89c4b516bbb34c350 ]
+
+Rename the node 'mt6359rtc' to 'rtc', as required by the binding.
+
+Fix the following dtb-check error:
+
+mediatek/mt8395-radxa-nio-12l.dtb: pmic: 'mt6359rtc' do not match
+any of the regexes: 'pinctrl-[0-9]+'
+
+Fixes: 3b7d143be4b7 ("arm64: dts: mt6359: add PMIC MT6359 related nodes")
+Signed-off-by: Julien Massot <julien.massot@collabora.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20250514-mt8395-dtb-errors-v2-3-d67b9077c59a@collabora.com
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt6359.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt6359.dtsi b/arch/arm64/boot/dts/mediatek/mt6359.dtsi
+index 0c479404b3fe3..467d8a4c2aa7f 100644
+--- a/arch/arm64/boot/dts/mediatek/mt6359.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt6359.dtsi
+@@ -300,7 +300,7 @@
+                       };
+               };
+-              mt6359rtc: mt6359rtc {
++              mt6359rtc: rtc {
+                       compatible = "mediatek,mt6358-rtc";
+               };
+       };
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-mt8183-add-port-node-to-mt8183.dtsi.patch b/queue-6.15/arm64-dts-mt8183-add-port-node-to-mt8183.dtsi.patch
new file mode 100644 (file)
index 0000000..0740c77
--- /dev/null
@@ -0,0 +1,63 @@
+From c4dfc52b87a835c7caa42e208b5cf45bdaab1be6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Apr 2025 12:03:39 +0800
+Subject: arm64: dts: mt8183: Add port node to mt8183.dtsi
+
+From: Pin-yen Lin <treapking@chromium.org>
+
+[ Upstream commit d15059f7be59f887c1a370037cc2337c2ff2ad56 ]
+
+Add the port node to fix the binding schema check. Also update
+mt8183-kukui to reference the new port node.
+
+Fixes: 88ec840270e6 ("arm64: dts: mt8183: Add dsi node")
+Fixes: 27eaf34df364 ("arm64: dts: mt8183: config dsi node")
+Signed-off-by: Pin-yen Lin <treapking@chromium.org>
+Link: https://lore.kernel.org/r/20250423040354.2847447-1-treapking@chromium.org
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi | 10 +++-------
+ arch/arm64/boot/dts/mediatek/mt8183.dtsi       |  4 ++++
+ 2 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
+index e1495f1900a7b..f9ca6b3720e91 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
+@@ -259,14 +259,10 @@
+                       };
+               };
+       };
++};
+-      ports {
+-              port {
+-                      dsi_out: endpoint {
+-                              remote-endpoint = <&panel_in>;
+-                      };
+-              };
+-      };
++&dsi_out {
++      remote-endpoint = <&panel_in>;
+ };
+ &gic {
+diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+index 0aa34e5bbaaa8..3c1fe80e64b9c 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+@@ -1836,6 +1836,10 @@
+                       phys = <&mipi_tx0>;
+                       phy-names = "dphy";
+                       status = "disabled";
++
++                      port {
++                              dsi_out: endpoint { };
++                      };
+               };
+               dpi0: dpi@14015000 {
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-qcom-ipq9574-fix-the-msi-interrupt-numbers.patch b/queue-6.15/arm64-dts-qcom-ipq9574-fix-the-msi-interrupt-numbers.patch
new file mode 100644 (file)
index 0000000..91e4f79
--- /dev/null
@@ -0,0 +1,53 @@
+From 6a7e2cf047a9350204db8701f7d364c925574078 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Mar 2025 12:44:22 +0530
+Subject: arm64: dts: qcom: ipq9574: fix the msi interrupt numbers of pcie3
+
+From: Manikanta Mylavarapu <quic_mmanikan@quicinc.com>
+
+[ Upstream commit c87d58bc7f831bf3d887e6ec846246cb673c2e50 ]
+
+The MSI interrupt numbers of the PCIe3 controller are incorrect. Due
+to this, the functional bring up of the QDSP6 processor on the PCIe
+endpoint has failed. Correct the MSI interrupt numbers to properly
+bring up the QDSP6 processor on the PCIe endpoint.
+
+Fixes: d80c7fbfa908 ("arm64: dts: qcom: ipq9574: Add PCIe PHYs and controller nodes")
+Signed-off-by: Manikanta Mylavarapu <quic_mmanikan@quicinc.com>
+Link: https://lore.kernel.org/r/20250313071422.510-1-quic_mmanikan@quicinc.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/ipq9574.dtsi | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/ipq9574.dtsi b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
+index 3c02351fbb156..b790a6b288abb 100644
+--- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
++++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
+@@ -974,14 +974,14 @@
+                       ranges = <0x01000000 0x0 0x00000000 0x18200000 0x0 0x100000>,
+                                <0x02000000 0x0 0x18300000 0x18300000 0x0 0x7d00000>;
+-                      interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
+-                                   <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+-                                   <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+-                                   <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+-                                   <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+-                                   <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+-                                   <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+-                                   <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
++                      interrupts = <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 415 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 494 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 495 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "msi0",
+                                         "msi1",
+                                         "msi2",
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-qcom-ipq9574-fix-usb-vdd-info.patch b/queue-6.15/arm64-dts-qcom-ipq9574-fix-usb-vdd-info.patch
new file mode 100644 (file)
index 0000000..6217b33
--- /dev/null
@@ -0,0 +1,65 @@
+From 8e3ec4149c283acb3134e2b54c38f9968e1036e6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Feb 2025 13:05:45 +0530
+Subject: arm64: dts: qcom: ipq9574: Fix USB vdd info
+
+From: Varadarajan Narayanan <quic_varada@quicinc.com>
+
+[ Upstream commit 4f4c905e6a2a4e884f4e9b7326c94fac3500e0f9 ]
+
+USB phys in ipq9574 use the 'L5' regulator. The commit ec4f047679d5
+("arm64: dts: qcom: ipq9574: Enable USB") incorrectly specified it as
+'L2'. Because of this when the phy module turns off/on its regulators,
+the wrong regulator is turned off/on resulting in 2 issues, namely the
+correct regulator related to the USB phy is not turned off/on and the
+module powered by the incorrect regulator is affected.
+
+Fixes: ec4f047679d5 ("arm64: dts: qcom: ipq9574: Enable USB")
+Signed-off-by: Varadarajan Narayanan <quic_varada@quicinc.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Link: https://lore.kernel.org/r/20250207073545.1768990-2-quic_varada@quicinc.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
+index ae12f069f26fa..b24b795873d41 100644
+--- a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
++++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
+@@ -111,6 +111,13 @@
+                       regulator-always-on;
+                       regulator-boot-on;
+               };
++
++              mp5496_l5: l5 {
++                      regulator-min-microvolt = <1800000>;
++                      regulator-max-microvolt = <1800000>;
++                      regulator-always-on;
++                      regulator-boot-on;
++              };
+       };
+ };
+@@ -146,7 +153,7 @@
+ };
+ &usb_0_qmpphy {
+-      vdda-pll-supply = <&mp5496_l2>;
++      vdda-pll-supply = <&mp5496_l5>;
+       vdda-phy-supply = <&regulator_fixed_0p925>;
+       status = "okay";
+@@ -154,7 +161,7 @@
+ &usb_0_qusbphy {
+       vdd-supply = <&regulator_fixed_0p925>;
+-      vdda-pll-supply = <&mp5496_l2>;
++      vdda-pll-supply = <&mp5496_l5>;
+       vdda-phy-dpdm-supply = <&regulator_fixed_3p3>;
+       status = "okay";
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-qcom-msm8998-remove-mdss_hdmi_phy-phandle-.patch b/queue-6.15/arm64-dts-qcom-msm8998-remove-mdss_hdmi_phy-phandle-.patch
new file mode 100644 (file)
index 0000000..80ae6ad
--- /dev/null
@@ -0,0 +1,51 @@
+From 7a3819822625941b61c00fdbdf84aa7b7c489f1e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Mar 2025 02:47:06 +0100
+Subject: arm64: dts: qcom: msm8998: Remove mdss_hdmi_phy phandle argument
+
+From: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+
+[ Upstream commit 7ebdb205d4b9dd839a93a9b8975ce8ccf86b882a ]
+
+The node has #clock-cells = <0>, as it only provides a single clock
+output.
+
+This leads to a turbo sneaky bug, where the dt checker shows that we
+have additional clocks in the array:
+
+clock-controller@c8c0000: clocks: [[3, 0], [39, 178], [156, 1],
+[156, 0], [157, 1], [157, 0], [158], [0], [0], [0], [39, 184]]
+is too long
+
+..which happens due to dtc interpreting <&mdss_hdmi_phy 0> as
+<&mdss_hdmi_phy>, <0> after taking cells into account.
+
+Remove the superfluous argument to both silence the warning and fix
+the index-based lookup of subsequent entries in "clocks".
+
+Fixes: 2150c87db80c ("arm64: dts: qcom: msm8998: add HDMI nodes")
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Link: https://lore.kernel.org/r/20250327-topic-more_dt_bindings_fixes-v2-4-b763d958545f@oss.qualcomm.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/msm8998.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8998.dtsi b/arch/arm64/boot/dts/qcom/msm8998.dtsi
+index 7eca38440cd7e..fa6769320a238 100644
+--- a/arch/arm64/boot/dts/qcom/msm8998.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8998.dtsi
+@@ -2795,7 +2795,7 @@
+                                <&mdss_dsi0_phy DSI_BYTE_PLL_CLK>,
+                                <&mdss_dsi1_phy DSI_PIXEL_PLL_CLK>,
+                                <&mdss_dsi1_phy DSI_BYTE_PLL_CLK>,
+-                               <&mdss_hdmi_phy 0>,
++                               <&mdss_hdmi_phy>,
+                                <0>,
+                                <0>,
+                                <&gcc GCC_MMSS_GPLL0_DIV_CLK>;
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-qcom-msm8998-use-the-header-with-dsi-phy-c.patch b/queue-6.15/arm64-dts-qcom-msm8998-use-the-header-with-dsi-phy-c.patch
new file mode 100644 (file)
index 0000000..d02e203
--- /dev/null
@@ -0,0 +1,74 @@
+From 373c14366d770ea66026a552a0bc1067230b6962 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Apr 2025 11:32:06 +0200
+Subject: arm64: dts: qcom: msm8998: Use the header with DSI phy clock IDs
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit f4220c41decc1944ef319c859840aa5405eee6fa ]
+
+Use the header with DSI phy clock IDs to make code more readable.
+
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20250408-dts-qcom-dsi-phy-clocks-v2-9-73b482a6dd02@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Stable-dep-of: 7ebdb205d4b9 ("arm64: dts: qcom: msm8998: Remove mdss_hdmi_phy phandle argument")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/msm8998.dtsi | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8998.dtsi b/arch/arm64/boot/dts/qcom/msm8998.dtsi
+index c2caad85c668d..7eca38440cd7e 100644
+--- a/arch/arm64/boot/dts/qcom/msm8998.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8998.dtsi
+@@ -2,6 +2,7 @@
+ /* Copyright (c) 2016, The Linux Foundation. All rights reserved. */
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
++#include <dt-bindings/clock/qcom,dsi-phy-28nm.h>
+ #include <dt-bindings/clock/qcom,gcc-msm8998.h>
+ #include <dt-bindings/clock/qcom,gpucc-msm8998.h>
+ #include <dt-bindings/clock/qcom,mmcc-msm8998.h>
+@@ -2790,10 +2791,10 @@
+                                     "gpll0_div";
+                       clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>,
+                                <&gcc GCC_MMSS_GPLL0_CLK>,
+-                               <&mdss_dsi0_phy 1>,
+-                               <&mdss_dsi0_phy 0>,
+-                               <&mdss_dsi1_phy 1>,
+-                               <&mdss_dsi1_phy 0>,
++                               <&mdss_dsi0_phy DSI_PIXEL_PLL_CLK>,
++                               <&mdss_dsi0_phy DSI_BYTE_PLL_CLK>,
++                               <&mdss_dsi1_phy DSI_PIXEL_PLL_CLK>,
++                               <&mdss_dsi1_phy DSI_BYTE_PLL_CLK>,
+                                <&mdss_hdmi_phy 0>,
+                                <0>,
+                                <0>,
+@@ -2932,8 +2933,8 @@
+                                             "bus";
+                               assigned-clocks = <&mmcc BYTE0_CLK_SRC>,
+                                                 <&mmcc PCLK0_CLK_SRC>;
+-                              assigned-clock-parents = <&mdss_dsi0_phy 0>,
+-                                                       <&mdss_dsi0_phy 1>;
++                              assigned-clock-parents = <&mdss_dsi0_phy DSI_BYTE_PLL_CLK>,
++                                                       <&mdss_dsi0_phy DSI_PIXEL_PLL_CLK>;
+                               operating-points-v2 = <&dsi_opp_table>;
+                               power-domains = <&rpmpd MSM8998_VDDCX>;
+@@ -3008,8 +3009,8 @@
+                                             "bus";
+                               assigned-clocks = <&mmcc BYTE1_CLK_SRC>,
+                                                 <&mmcc PCLK1_CLK_SRC>;
+-                              assigned-clock-parents = <&mdss_dsi1_phy 0>,
+-                                                       <&mdss_dsi1_phy 1>;
++                              assigned-clock-parents = <&mdss_dsi1_phy DSI_BYTE_PLL_CLK>,
++                                                       <&mdss_dsi1_phy DSI_PIXEL_PLL_CLK>;
+                               operating-points-v2 = <&dsi_opp_table>;
+                               power-domains = <&rpmpd MSM8998_VDDCX>;
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-qcom-qcm2290-fix-some-of-qup-interconnects.patch b/queue-6.15/arm64-dts-qcom-qcm2290-fix-some-of-qup-interconnects.patch
new file mode 100644 (file)
index 0000000..20c949c
--- /dev/null
@@ -0,0 +1,103 @@
+From a95f2ec48b0a747400dce4f2188796e4b916acce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Feb 2025 22:41:18 +0200
+Subject: arm64: dts: qcom: qcm2290: fix (some) of QUP interconnects
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit e07d2d57a1c7254d25597dcdd34f318a91ec9398 ]
+
+While adding interconnect support for the QCM2290 platform some of them
+got the c&p error, rogue MASTER_APPSS_PROC for the config_noc
+interconnect. Turn that into SLAVE_QUP_0 as expected.
+
+Fixes: 5b970ff0193d ("arm64: dts: qcom: qcm2290: Hook up interconnects")
+Reported-by: Konrad Dybcio <konradybcio@kernel.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://lore.kernel.org/r/20250207-rb1-bt-v4-4-d810fc8c94a9@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/qcm2290.dtsi | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/qcm2290.dtsi b/arch/arm64/boot/dts/qcom/qcm2290.dtsi
+index f0746123e594d..6e3e57dd02612 100644
+--- a/arch/arm64/boot/dts/qcom/qcm2290.dtsi
++++ b/arch/arm64/boot/dts/qcom/qcm2290.dtsi
+@@ -1073,7 +1073,7 @@
+                               interconnects = <&qup_virt MASTER_QUP_CORE_0 RPM_ALWAYS_TAG
+                                                &qup_virt SLAVE_QUP_CORE_0 RPM_ALWAYS_TAG>,
+                                               <&bimc MASTER_APPSS_PROC RPM_ALWAYS_TAG
+-                                               &config_noc MASTER_APPSS_PROC RPM_ALWAYS_TAG>;
++                                               &config_noc SLAVE_QUP_0 RPM_ALWAYS_TAG>;
+                               interconnect-names = "qup-core",
+                                                    "qup-config";
+                               #address-cells = <1>;
+@@ -1092,7 +1092,7 @@
+                               interconnects = <&qup_virt MASTER_QUP_CORE_0 RPM_ALWAYS_TAG
+                                                &qup_virt SLAVE_QUP_CORE_0 RPM_ALWAYS_TAG>,
+                                               <&bimc MASTER_APPSS_PROC RPM_ALWAYS_TAG
+-                                               &config_noc MASTER_APPSS_PROC RPM_ALWAYS_TAG>;
++                                               &config_noc SLAVE_QUP_0 RPM_ALWAYS_TAG>;
+                               interconnect-names = "qup-core",
+                                                    "qup-config";
+                               status = "disabled";
+@@ -1137,7 +1137,7 @@
+                               interconnects = <&qup_virt MASTER_QUP_CORE_0 RPM_ALWAYS_TAG
+                                                &qup_virt SLAVE_QUP_CORE_0 RPM_ALWAYS_TAG>,
+                                               <&bimc MASTER_APPSS_PROC RPM_ALWAYS_TAG
+-                                               &config_noc MASTER_APPSS_PROC RPM_ALWAYS_TAG>;
++                                               &config_noc SLAVE_QUP_0 RPM_ALWAYS_TAG>;
+                               interconnect-names = "qup-core",
+                                                    "qup-config";
+                               #address-cells = <1>;
+@@ -1184,7 +1184,7 @@
+                               interconnects = <&qup_virt MASTER_QUP_CORE_0 RPM_ALWAYS_TAG
+                                                &qup_virt SLAVE_QUP_CORE_0 RPM_ALWAYS_TAG>,
+                                               <&bimc MASTER_APPSS_PROC RPM_ALWAYS_TAG
+-                                               &config_noc MASTER_APPSS_PROC RPM_ALWAYS_TAG>;
++                                               &config_noc SLAVE_QUP_0 RPM_ALWAYS_TAG>;
+                               interconnect-names = "qup-core",
+                                                    "qup-config";
+                               #address-cells = <1>;
+@@ -1231,7 +1231,7 @@
+                               interconnects = <&qup_virt MASTER_QUP_CORE_0 RPM_ALWAYS_TAG
+                                                &qup_virt SLAVE_QUP_CORE_0 RPM_ALWAYS_TAG>,
+                                               <&bimc MASTER_APPSS_PROC RPM_ALWAYS_TAG
+-                                               &config_noc MASTER_APPSS_PROC RPM_ALWAYS_TAG>;
++                                               &config_noc SLAVE_QUP_0 RPM_ALWAYS_TAG>;
+                               interconnect-names = "qup-core",
+                                                    "qup-config";
+                               #address-cells = <1>;
+@@ -1278,7 +1278,7 @@
+                               interconnects = <&qup_virt MASTER_QUP_CORE_0 RPM_ALWAYS_TAG
+                                                &qup_virt SLAVE_QUP_CORE_0 RPM_ALWAYS_TAG>,
+                                               <&bimc MASTER_APPSS_PROC RPM_ALWAYS_TAG
+-                                               &config_noc MASTER_APPSS_PROC RPM_ALWAYS_TAG>;
++                                               &config_noc SLAVE_QUP_0 RPM_ALWAYS_TAG>;
+                               interconnect-names = "qup-core",
+                                                    "qup-config";
+                               #address-cells = <1>;
+@@ -1297,7 +1297,7 @@
+                               interconnects = <&qup_virt MASTER_QUP_CORE_0 RPM_ALWAYS_TAG
+                                                &qup_virt SLAVE_QUP_CORE_0 RPM_ALWAYS_TAG>,
+                                               <&bimc MASTER_APPSS_PROC RPM_ALWAYS_TAG
+-                                               &config_noc MASTER_APPSS_PROC RPM_ALWAYS_TAG>;
++                                               &config_noc SLAVE_QUP_0 RPM_ALWAYS_TAG>;
+                               interconnect-names = "qup-core",
+                                                    "qup-config";
+                               status = "disabled";
+@@ -1342,7 +1342,7 @@
+                               interconnects = <&qup_virt MASTER_QUP_CORE_0 RPM_ALWAYS_TAG
+                                                &qup_virt SLAVE_QUP_CORE_0 RPM_ALWAYS_TAG>,
+                                               <&bimc MASTER_APPSS_PROC RPM_ALWAYS_TAG
+-                                               &config_noc MASTER_APPSS_PROC RPM_ALWAYS_TAG>;
++                                               &config_noc SLAVE_QUP_0 RPM_ALWAYS_TAG>;
+                               interconnect-names = "qup-core",
+                                                    "qup-config";
+                               #address-cells = <1>;
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-qcom-qcs615-fix-up-ufs-clocks.patch b/queue-6.15/arm64-dts-qcom-qcs615-fix-up-ufs-clocks.patch
new file mode 100644 (file)
index 0000000..048ea9f
--- /dev/null
@@ -0,0 +1,82 @@
+From b72ac80444e5e5e381161c9f266b8b3e8d8083a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Mar 2025 02:47:14 +0100
+Subject: arm64: dts: qcom: qcs615: Fix up UFS clocks
+
+From: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+
+[ Upstream commit ea172f61f4fdb17aaaf8def980ee309a3b727eea ]
+
+The clocks are out of order with the bindings' expectations.
+
+Reorder them to resolve the errors.
+
+Fixes: a6a9d10e7969 ("arm64: dts: qcom: qcs615: add UFS node")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Link: https://lore.kernel.org/r/20250327-topic-more_dt_bindings_fixes-v2-12-b763d958545f@oss.qualcomm.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/qcs615.dtsi | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/qcs615.dtsi b/arch/arm64/boot/dts/qcom/qcs615.dtsi
+index 8db06d17eb474..1206548490438 100644
+--- a/arch/arm64/boot/dts/qcom/qcs615.dtsi
++++ b/arch/arm64/boot/dts/qcom/qcs615.dtsi
+@@ -1022,10 +1022,10 @@
+                                     "bus_aggr_clk",
+                                     "iface_clk",
+                                     "core_clk_unipro",
+-                                    "core_clk_ice",
+                                     "ref_clk",
+                                     "tx_lane0_sync_clk",
+-                                    "rx_lane0_sync_clk";
++                                    "rx_lane0_sync_clk",
++                                    "ice_core_clk";
+                       resets = <&gcc GCC_UFS_PHY_BCR>;
+                       reset-names = "rst";
+@@ -1060,10 +1060,10 @@
+                                                /bits/ 64 <0>,
+                                                /bits/ 64 <0>,
+                                                /bits/ 64 <37500000>,
+-                                               /bits/ 64 <75000000>,
+                                                /bits/ 64 <0>,
+                                                /bits/ 64 <0>,
+-                                               /bits/ 64 <0>;
++                                               /bits/ 64 <0>,
++                                               /bits/ 64 <75000000>;
+                                       required-opps = <&rpmhpd_opp_low_svs>;
+                               };
+@@ -1072,10 +1072,10 @@
+                                                /bits/ 64 <0>,
+                                                /bits/ 64 <0>,
+                                                /bits/ 64 <75000000>,
+-                                               /bits/ 64 <150000000>,
+                                                /bits/ 64 <0>,
+                                                /bits/ 64 <0>,
+-                                               /bits/ 64 <0>;
++                                               /bits/ 64 <0>,
++                                               /bits/ 64 <150000000>;
+                                       required-opps = <&rpmhpd_opp_svs>;
+                               };
+@@ -1084,10 +1084,10 @@
+                                                /bits/ 64 <0>,
+                                                /bits/ 64 <0>,
+                                                /bits/ 64 <150000000>,
+-                                               /bits/ 64 <300000000>,
+                                                /bits/ 64 <0>,
+                                                /bits/ 64 <0>,
+-                                               /bits/ 64 <0>;
++                                               /bits/ 64 <0>,
++                                               /bits/ 64 <300000000>;
+                                       required-opps = <&rpmhpd_opp_nom>;
+                               };
+                       };
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-qcom-qcs615-remove-disallowed-property-in-.patch b/queue-6.15/arm64-dts-qcom-qcs615-remove-disallowed-property-in-.patch
new file mode 100644 (file)
index 0000000..4f35bbd
--- /dev/null
@@ -0,0 +1,41 @@
+From 487187f889a6b5a45b78cad311123b2b38bf3c2e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jan 2025 11:24:31 +0800
+Subject: arm64: dts: qcom: qcs615: remove disallowed property in spmi bus node
+
+From: Tingguo Cheng <quic_tingguoc@quicinc.com>
+
+[ Upstream commit 54040a3e3da67ef0e014e5f04f9f3fe680fc4b55 ]
+
+Remove the unevaluated 'cell-index' property from qcs615-ride.dtb
+spmi@c440000 to fix the Devicetree validation error reported by the
+kernel test robot.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/r/202412272210.GpGmqcPC-lkp@intel.com/
+Fixes: 27554e2bef4d ("arm64: dts: qcom: qcs615: Adds SPMI support")
+Signed-off-by: Tingguo Cheng <quic_tingguoc@quicinc.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Link: https://lore.kernel.org/r/20250117-fix-kernel-test-robot-unexpected-property-issue-v2-1-0b68cf481249@quicinc.com
+[bjorn: Fixes commit message wording about LKP]
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/qcs615.dtsi | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/qcs615.dtsi b/arch/arm64/boot/dts/qcom/qcs615.dtsi
+index f4abfad474ea6..8db06d17eb474 100644
+--- a/arch/arm64/boot/dts/qcom/qcs615.dtsi
++++ b/arch/arm64/boot/dts/qcom/qcs615.dtsi
+@@ -3304,7 +3304,6 @@
+                       #interrupt-cells = <4>;
+                       #address-cells = <2>;
+                       #size-cells = <0>;
+-                      cell-index = <0>;
+                       qcom,channel = <0>;
+                       qcom,ee = <0>;
+               };
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-qcom-qcs8300-partially-revert-arm64-dts-qc.patch b/queue-6.15/arm64-dts-qcom-qcs8300-partially-revert-arm64-dts-qc.patch
new file mode 100644 (file)
index 0000000..ee0ced4
--- /dev/null
@@ -0,0 +1,56 @@
+From 56921e8c6462439deb156278aa0477668941a52e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Jan 2025 12:53:33 +0100
+Subject: arm64: dts: qcom: qcs8300: Partially revert "arm64: dts: qcom:
+ qcs8300: add QCrypto nodes"
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit cdc117c40537c5babfa7f261360d5a98e434d59e ]
+
+Partially revert commit a86d84409947 ("arm64: dts: qcom: qcs8300: add
+QCrypto nodes") by dropping the untested QCE device node.  Devicetree
+bindings test failures were reported on mailing list on 16th of January
+and after two weeks still no fixes:
+
+  qcs8300-ride.dtb: crypto@1dfa000: compatible: 'oneOf' conditional failed, one must be fixed:
+    ...
+    'qcom,qcs8300-qce' is not one of ['qcom,ipq4019-qce', 'qcom,sm8150-qce']
+
+Reported-by: Rob Herring <robh@kernel.org>
+Closes: https://lore.kernel.org/all/CAL_JsqL0HzzGXnCD+z4GASeXNsBxrdw8-qyfHj8S+C2ucK6EPQ@mail.gmail.com/
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Link: https://lore.kernel.org/r/20250128115333.95021-2-krzysztof.kozlowski@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/qcs8300.dtsi | 12 ------------
+ 1 file changed, 12 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/qcs8300.dtsi b/arch/arm64/boot/dts/qcom/qcs8300.dtsi
+index 4a057f7c0d9fa..13b1121cdf175 100644
+--- a/arch/arm64/boot/dts/qcom/qcs8300.dtsi
++++ b/arch/arm64/boot/dts/qcom/qcs8300.dtsi
+@@ -798,18 +798,6 @@
+                                <&apps_smmu 0x481 0x00>;
+               };
+-              crypto: crypto@1dfa000 {
+-                      compatible = "qcom,qcs8300-qce", "qcom,qce";
+-                      reg = <0x0 0x01dfa000 0x0 0x6000>;
+-                      dmas = <&cryptobam 4>, <&cryptobam 5>;
+-                      dma-names = "rx", "tx";
+-                      iommus = <&apps_smmu 0x480 0x00>,
+-                               <&apps_smmu 0x481 0x00>;
+-                      interconnects = <&aggre2_noc MASTER_CRYPTO_CORE0 QCOM_ICC_TAG_ALWAYS
+-                                       &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+-                      interconnect-names = "memory";
+-              };
+-
+               ice: crypto@1d88000 {
+                       compatible = "qcom,qcs8300-inline-crypto-engine",
+                                    "qcom,inline-crypto-engine";
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-qcom-sa8775p-partially-revert-arm64-dts-qc.patch b/queue-6.15/arm64-dts-qcom-sa8775p-partially-revert-arm64-dts-qc.patch
new file mode 100644 (file)
index 0000000..33cec86
--- /dev/null
@@ -0,0 +1,55 @@
+From b37a16e70cd0f09f0bfe775716c09600c022de2c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Jan 2025 12:53:32 +0100
+Subject: arm64: dts: qcom: sa8775p: Partially revert "arm64: dts: qcom:
+ sa8775p: add QCrypto nodes"
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 92979f12a201c54ea94b8b3c9f0737c33bb45e23 ]
+
+Partially revert commit 7ff3da43ef44 ("arm64: dts: qcom: sa8775p: add
+QCrypto nodes") by dropping the untested QCE device node.  Devicetree
+bindings test failures were reported on mailing list on 16th of January
+and after two weeks still no fixes:
+
+  sa8775p-ride.dtb: crypto@1dfa000: compatible: 'oneOf' conditional failed, one must be fixed:
+    ...
+    'qcom,sa8775p-qce' is not one of ['qcom,ipq4019-qce', 'qcom,sm8150-qce']
+
+Reported-by: Rob Herring <robh@kernel.org>
+Closes: https://lore.kernel.org/all/CAL_JsqJG_w9jyWjVR=QnPuJganG4uj9+9cEXZ__UAiCw2ZYZZA@mail.gmail.com/
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Link: https://lore.kernel.org/r/20250128115333.95021-1-krzysztof.kozlowski@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sa8775p.dtsi | 11 -----------
+ 1 file changed, 11 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sa8775p.dtsi b/arch/arm64/boot/dts/qcom/sa8775p.dtsi
+index 2329460b21038..2010b7988b6cc 100644
+--- a/arch/arm64/boot/dts/qcom/sa8775p.dtsi
++++ b/arch/arm64/boot/dts/qcom/sa8775p.dtsi
+@@ -2420,17 +2420,6 @@
+                                <&apps_smmu 0x481 0x00>;
+               };
+-              crypto: crypto@1dfa000 {
+-                      compatible = "qcom,sa8775p-qce", "qcom,qce";
+-                      reg = <0x0 0x01dfa000 0x0 0x6000>;
+-                      dmas = <&cryptobam 4>, <&cryptobam 5>;
+-                      dma-names = "rx", "tx";
+-                      iommus = <&apps_smmu 0x480 0x00>,
+-                               <&apps_smmu 0x481 0x00>;
+-                      interconnects = <&aggre2_noc MASTER_CRYPTO_CORE0 0 &mc_virt SLAVE_EBI1 0>;
+-                      interconnect-names = "memory";
+-              };
+-
+               stm: stm@4002000 {
+                       compatible = "arm,coresight-stm", "arm,primecell";
+                       reg = <0x0 0x4002000 0x0 0x1000>,
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-qcom-sc8280xp-x13s-drop-duplicate-dmic-sup.patch b/queue-6.15/arm64-dts-qcom-sc8280xp-x13s-drop-duplicate-dmic-sup.patch
new file mode 100644 (file)
index 0000000..e781cbe
--- /dev/null
@@ -0,0 +1,53 @@
+From 6a0634ff016de490a6b0be2c107c8928b5e9f37d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Dec 2024 18:44:02 +0100
+Subject: arm64: dts: qcom: sc8280xp-x13s: Drop duplicate DMIC supplies
+
+From: Stephan Gerhold <stephan.gerhold@linaro.org>
+
+[ Upstream commit a2e617f4e6981aa514a569e927f90b0d39bb31b2 ]
+
+The WCD938x codec provides two controls for each of the MIC_BIASn outputs:
+
+ - "MIC BIASn" enables an internal regulator to generate the output
+   with a configurable voltage (qcom,micbiasN-microvolt).
+
+ - "VA MIC BIASn" enables "pull-up mode" that bypasses the internal
+   regulator and directly outputs fixed 1.8V from the VDD_PX pin.
+   This is intended for low-power VA (voice activation) use cases.
+
+The audio-routing setup for the ThinkPad X13s currently specifies both
+as power supplies for the DMICs, but only one of them can be active
+at the same time. In practice, only the internal regulator is used
+with the current setup because the driver prefers it over pull-up mode.
+
+Make this more clear by dropping the redundant routes to the pull-up
+"VA MIC BIASn" supply. There is no functional difference except that we
+skip briefly switching to pull-up mode when shutting down the microphone.
+
+Fixes: 2e498f35c385 ("arm64: dts: qcom: sc8280xp-x13s: fix va dmic dai links and routing")
+Signed-off-by: Stephan Gerhold <stephan.gerhold@linaro.org>
+Link: https://lore.kernel.org/r/20241203-x1e80100-va-mic-bias-v1-1-0dfd4d9b492c@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts b/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts
+index f3190f408f4b2..0f1ebd869ce31 100644
+--- a/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts
++++ b/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts
+@@ -1202,9 +1202,6 @@
+               "VA DMIC0", "MIC BIAS1",
+               "VA DMIC1", "MIC BIAS1",
+               "VA DMIC2", "MIC BIAS3",
+-              "VA DMIC0", "VA MIC BIAS1",
+-              "VA DMIC1", "VA MIC BIAS1",
+-              "VA DMIC2", "VA MIC BIAS3",
+               "TX SWR_ADC1", "ADC2_OUTPUT";
+       wcd-playback-dai-link {
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-qcom-sda660-ifc6560-fix-dt-validate-warnin.patch b/queue-6.15/arm64-dts-qcom-sda660-ifc6560-fix-dt-validate-warnin.patch
new file mode 100644 (file)
index 0000000..c587ecf
--- /dev/null
@@ -0,0 +1,47 @@
+From cd38fd5740e7a95f22760a9970c427db36148945 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 4 May 2025 14:51:20 +0300
+Subject: arm64: dts: qcom: sda660-ifc6560: Fix dt-validate warning
+
+From: Alexey Minnekhanov <alexeymin@postmarketos.org>
+
+[ Upstream commit f5110806b41eaa0eb0ab1bf2787876a580c6246c ]
+
+If you remove clocks property, you should remove clock-names, too.
+Fixes warning with dtbs check:
+
+ 'clocks' is a dependency of 'clock-names'
+
+Fixes: 34279d6e3f32c ("arm64: dts: qcom: sdm660: Add initial Inforce IFC6560 board support")
+Signed-off-by: Alexey Minnekhanov <alexeymin@postmarketos.org>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Link: https://lore.kernel.org/r/20250504115120.1432282-4-alexeymin@postmarketos.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sda660-inforce-ifc6560.dts | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/sda660-inforce-ifc6560.dts b/arch/arm64/boot/dts/qcom/sda660-inforce-ifc6560.dts
+index d402f4c85b11d..ee696317f78cc 100644
+--- a/arch/arm64/boot/dts/qcom/sda660-inforce-ifc6560.dts
++++ b/arch/arm64/boot/dts/qcom/sda660-inforce-ifc6560.dts
+@@ -175,6 +175,7 @@
+        * BAM DMA interconnects support is in place.
+        */
+       /delete-property/ clocks;
++      /delete-property/ clock-names;
+ };
+ &blsp1_uart2 {
+@@ -187,6 +188,7 @@
+        * BAM DMA interconnects support is in place.
+        */
+       /delete-property/ clocks;
++      /delete-property/ clock-names;
+ };
+ &blsp2_uart1 {
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-qcom-sdm660-lavender-add-missing-usb-phy-s.patch b/queue-6.15/arm64-dts-qcom-sdm660-lavender-add-missing-usb-phy-s.patch
new file mode 100644 (file)
index 0000000..61f6f1e
--- /dev/null
@@ -0,0 +1,38 @@
+From 320556ed61df28099d76c0e557d668861b13a735 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 4 May 2025 14:51:19 +0300
+Subject: arm64: dts: qcom: sdm660-lavender: Add missing USB phy supply
+
+From: Alexey Minnekhanov <alexeymin@postmarketos.org>
+
+[ Upstream commit dbf62a117a1b7f605a98dd1fd1fd6c85ec324ea0 ]
+
+Fixes the following dtbs check error:
+
+ phy@c012000: 'vdda-pll-supply' is a required property
+
+Fixes: e5d3e752b050e ("arm64: dts: qcom: sdm660-xiaomi-lavender: Add USB")
+Signed-off-by: Alexey Minnekhanov <alexeymin@postmarketos.org>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Link: https://lore.kernel.org/r/20250504115120.1432282-3-alexeymin@postmarketos.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts b/arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts
+index 0b4d71c14a772..a9926ad6c6f9f 100644
+--- a/arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts
++++ b/arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts
+@@ -107,6 +107,7 @@
+       status = "okay";
+       vdd-supply = <&vreg_l1b_0p925>;
++      vdda-pll-supply = <&vreg_l10a_1p8>;
+       vdda-phy-dpdm-supply = <&vreg_l7b_3p125>;
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-qcom-sdm660-xiaomi-lavender-add-missing-sd.patch b/queue-6.15/arm64-dts-qcom-sdm660-xiaomi-lavender-add-missing-sd.patch
new file mode 100644 (file)
index 0000000..de273a0
--- /dev/null
@@ -0,0 +1,40 @@
+From 58e7471975a50c5ab0cc623ece4c5996412eb904 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Apr 2025 16:01:01 +0300
+Subject: arm64: dts: qcom: sdm660-xiaomi-lavender: Add missing SD card detect
+ GPIO
+
+From: Alexey Minnekhanov <alexeymin@postmarketos.org>
+
+[ Upstream commit 2eca6af66709de0d1ba14cdf8b6d200a1337a3a2 ]
+
+During initial porting these cd-gpios were missed. Having card detect is
+beneficial because driver does not need to do polling every second and it
+can just use IRQ. SD card detection in U-Boot is also fixed by this.
+
+Fixes: cf85e9aee210 ("arm64: dts: qcom: sdm660-xiaomi-lavender: Add eMMC and SD")
+Signed-off-by: Alexey Minnekhanov <alexeymin@postmarketos.org>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Link: https://lore.kernel.org/r/20250415130101.1429281-1-alexeymin@postmarketos.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts b/arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts
+index 7167f75bced3f..0b4d71c14a772 100644
+--- a/arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts
++++ b/arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts
+@@ -404,6 +404,8 @@
+ &sdhc_2 {
+       status = "okay";
++      cd-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>;
++
+       vmmc-supply = <&vreg_l5b_2p95>;
+       vqmmc-supply = <&vreg_l2b_2p95>;
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-qcom-sdm845-starqltechn-fix-usb-regulator-.patch b/queue-6.15/arm64-dts-qcom-sdm845-starqltechn-fix-usb-regulator-.patch
new file mode 100644 (file)
index 0000000..1230fb8
--- /dev/null
@@ -0,0 +1,46 @@
+From cdc6e56ba6b26a70349334d37c62c682113974b0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Feb 2025 19:38:54 +0300
+Subject: arm64: dts: qcom: sdm845-starqltechn: fix usb regulator mistake
+
+From: Dzmitry Sankouski <dsankouski@gmail.com>
+
+[ Upstream commit 242e4126ee007b95765c21a9d74651fdcf221f2b ]
+
+Usb regulator was wrongly pointed to vreg_l1a_0p875.
+However, on starqltechn it's powered from vreg_l5a_0p8.
+
+Fixes: d711b22eee55 ("arm64: dts: qcom: starqltechn: add initial device tree for starqltechn")
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Signed-off-by: Dzmitry Sankouski <dsankouski@gmail.com>
+Link: https://lore.kernel.org/r/20250225-starqltechn_integration_upstream-v9-3-a5d80375cb66@gmail.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts
+index 6fc30fd1262b8..f3f2b25883d81 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts
++++ b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts
+@@ -135,8 +135,6 @@
+               vdda_sp_sensor:
+               vdda_ufs1_core:
+               vdda_ufs2_core:
+-              vdda_usb1_ss_core:
+-              vdda_usb2_ss_core:
+               vreg_l1a_0p875: ldo1 {
+                       regulator-min-microvolt = <880000>;
+                       regulator-max-microvolt = <880000>;
+@@ -157,6 +155,7 @@
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
++              vdda_usb1_ss_core:
+               vdd_wcss_cx:
+               vdd_wcss_mx:
+               vdda_wcss_pll:
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-qcom-sdm845-starqltechn-refactor-node-orde.patch b/queue-6.15/arm64-dts-qcom-sdm845-starqltechn-refactor-node-orde.patch
new file mode 100644 (file)
index 0000000..ba696b7
--- /dev/null
@@ -0,0 +1,35 @@
+From cc2ea80ab4714fafbf466aa21922c08ca80a74e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Feb 2025 19:38:55 +0300
+Subject: arm64: dts: qcom: sdm845-starqltechn: refactor node order
+
+From: Dzmitry Sankouski <dsankouski@gmail.com>
+
+[ Upstream commit cba1dd3d851ebc1b6c5ae4000208a9753320694b ]
+
+Fixes: d711b22eee55 ("arm64: dts: qcom: starqltechn: add initial device tree for starqltechn")
+Signed-off-by: Dzmitry Sankouski <dsankouski@gmail.com>
+Link: https://lore.kernel.org/r/20250225-starqltechn_integration_upstream-v9-4-a5d80375cb66@gmail.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts
+index f3f2b25883d81..8a0d63bd594b3 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts
++++ b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts
+@@ -382,8 +382,8 @@
+ };
+ &sdhc_2 {
+-      pinctrl-names = "default";
+       pinctrl-0 = <&sdc2_clk_state &sdc2_cmd_state &sdc2_data_state &sd_card_det_n_state>;
++      pinctrl-names = "default";
+       cd-gpios = <&tlmm 126 GPIO_ACTIVE_LOW>;
+       vmmc-supply = <&vreg_l21a_2p95>;
+       vqmmc-supply = <&vddpx_2>;
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-qcom-sdm845-starqltechn-remove-excess-rese.patch b/queue-6.15/arm64-dts-qcom-sdm845-starqltechn-remove-excess-rese.patch
new file mode 100644 (file)
index 0000000..70ff1a0
--- /dev/null
@@ -0,0 +1,42 @@
+From 2607a848b9098a9140362bc1a42324adf731b124 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Feb 2025 19:38:56 +0300
+Subject: arm64: dts: qcom: sdm845-starqltechn: remove excess reserved gpios
+
+From: Dzmitry Sankouski <dsankouski@gmail.com>
+
+[ Upstream commit fb5fce873b952f8b1c5f7edcabcc8611ef45ea7a ]
+
+Starqltechn has 2 reserved gpio ranges <27 4>, <85 4>.
+<27 4> is spi for eSE(embedded Secure Element).
+<85 4> is spi for fingerprint.
+
+Remove excess reserved gpio regions.
+
+Fixes: d711b22eee55 ("arm64: dts: qcom: starqltechn: add initial device tree for starqltechn")
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Signed-off-by: Dzmitry Sankouski <dsankouski@gmail.com>
+Link: https://lore.kernel.org/r/20250225-starqltechn_integration_upstream-v9-5-a5d80375cb66@gmail.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts
+index 8a0d63bd594b3..5948b401165ce 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts
++++ b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts
+@@ -418,7 +418,8 @@
+ };
+ &tlmm {
+-      gpio-reserved-ranges = <0 4>, <27 4>, <81 4>, <85 4>;
++      gpio-reserved-ranges = <27 4>, /* SPI (eSE - embedded Secure Element) */
++                             <85 4>; /* SPI (fingerprint reader) */
+       sdc2_clk_state: sdc2-clk-state {
+               pins = "sdc2_clk";
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-qcom-sdm845-starqltechn-remove-wifi.patch b/queue-6.15/arm64-dts-qcom-sdm845-starqltechn-remove-wifi.patch
new file mode 100644 (file)
index 0000000..4aebaf2
--- /dev/null
@@ -0,0 +1,46 @@
+From 7bc5e3851452e2d8e0b5a363345b9adfc3b17471 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Feb 2025 19:38:53 +0300
+Subject: arm64: dts: qcom: sdm845-starqltechn: remove wifi
+
+From: Dzmitry Sankouski <dsankouski@gmail.com>
+
+[ Upstream commit 2d3dd4b237638853b8a99353401ab8d88a6afb6c ]
+
+Starqltechn has broadcom chip for wifi, so sdm845 wifi part
+can be disabled.
+
+Fixes: d711b22eee55 ("arm64: dts: qcom: starqltechn: add initial device tree for starqltechn")
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Dzmitry Sankouski <dsankouski@gmail.com>
+Fixes: d711b22eee55 ("arm64: dts: qcom: starqltechn: add initial device  tree for starqltechn")
+Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Link: https://lore.kernel.org/r/20250225-starqltechn_integration_upstream-v9-2-a5d80375cb66@gmail.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts | 8 --------
+ 1 file changed, 8 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts
+index d37a433130b98..6fc30fd1262b8 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts
++++ b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts
+@@ -418,14 +418,6 @@
+       status = "okay";
+ };
+-&wifi {
+-      vdd-0.8-cx-mx-supply = <&vreg_l5a_0p8>;
+-      vdd-1.8-xo-supply = <&vreg_l7a_1p8>;
+-      vdd-1.3-rfa-supply = <&vreg_l17a_1p3>;
+-      vdd-3.3-ch0-supply = <&vreg_l25a_3p3>;
+-      status = "okay";
+-};
+-
+ &tlmm {
+       gpio-reserved-ranges = <0 4>, <27 4>, <81 4>, <85 4>;
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-qcom-sm8250-fix-cpu7-opp-table.patch b/queue-6.15/arm64-dts-qcom-sm8250-fix-cpu7-opp-table.patch
new file mode 100644 (file)
index 0000000..d711db6
--- /dev/null
@@ -0,0 +1,41 @@
+From da6c79af77be2e0330ac0eb0ba4d9be88fc740fc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Mar 2025 18:27:51 +0800
+Subject: arm64: dts: qcom: sm8250: Fix CPU7 opp table
+
+From: Xilin Wu <wuxilin123@gmail.com>
+
+[ Upstream commit 28f997b89967afdc0855d8aa7538b251fb44f654 ]
+
+There is a typo in cpu7_opp9. Fix it to get rid of the following
+errors.
+
+[    0.198043] cpu cpu7: Voltage update failed freq=1747200
+[    0.198052] cpu cpu7: failed to update OPP for freq=1747200
+
+Fixes: 8e0e8016cb79 ("arm64: dts: qcom: sm8250: Add CPU opp tables")
+Signed-off-by: Xilin Wu <wuxilin123@gmail.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Link: https://lore.kernel.org/r/20250308-fix-sm8250-cpufreq-v1-1-8a0226721399@gmail.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8250.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi
+index c2937b4d9f180..68613ea7146c8 100644
+--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi
+@@ -606,7 +606,7 @@
+               };
+               cpu7_opp9: opp-1747200000 {
+-                      opp-hz = /bits/ 64 <1708800000>;
++                      opp-hz = /bits/ 64 <1747200000>;
+                       opp-peak-kBps = <5412000 42393600>;
+               };
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-qcom-sm8350-reenable-crypto-cryptobam.patch b/queue-6.15/arm64-dts-qcom-sm8350-reenable-crypto-cryptobam.patch
new file mode 100644 (file)
index 0000000..2ca72de
--- /dev/null
@@ -0,0 +1,59 @@
+From 76ce20cdf073518e106f1e3f7c271562ca0ea0d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Feb 2025 18:03:47 +0100
+Subject: arm64: dts: qcom: sm8350: Reenable crypto & cryptobam
+
+From: Luca Weiss <luca.weiss@fairphone.com>
+
+[ Upstream commit 75eefd474469abf95aa9ef6da8161d69f86b98b4 ]
+
+When num-channels and qcom,num-ees is not provided in devicetree, the
+driver will try to read these values from the registers during probe but
+this fails if the interconnect is not on and then crashes the system.
+
+So we can provide these properties in devicetree (queried after patching
+BAM driver to enable the necessary interconnect) so we can probe
+cryptobam without reading registers and then also use the QCE as
+expected.
+
+Fixes: 4d29db204361 ("arm64: dts: qcom: sm8350: fix BAM DMA crash and reboot")
+Fixes: f1040a7fe8f0 ("arm64: dts: qcom: sm8350: Add Crypto Engine support")
+Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
+Signed-off-by: Stephan Gerhold <stephan.gerhold@linaro.org>
+Link: https://lore.kernel.org/r/20250212-bam-dma-fixes-v1-1-f560889e65d8@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8350.dtsi | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi
+index f055600d6cfe5..a86d0067634e8 100644
+--- a/arch/arm64/boot/dts/qcom/sm8350.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi
+@@ -1806,11 +1806,11 @@
+                       interrupts = <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>;
+                       #dma-cells = <1>;
+                       qcom,ee = <0>;
++                      qcom,num-ees = <4>;
++                      num-channels = <16>;
+                       qcom,controlled-remotely;
+                       iommus = <&apps_smmu 0x594 0x0011>,
+                                <&apps_smmu 0x596 0x0011>;
+-                      /* FIXME: Probing BAM DMA causes some abort and system hang */
+-                      status = "fail";
+               };
+               crypto: crypto@1dfa000 {
+@@ -1822,8 +1822,6 @@
+                                <&apps_smmu 0x596 0x0011>;
+                       interconnects = <&aggre2_noc MASTER_CRYPTO 0 &mc_virt SLAVE_EBI1 0>;
+                       interconnect-names = "memory";
+-                      /* FIXME: dependency BAM DMA is disabled */
+-                      status = "disabled";
+               };
+               ipa: ipa@1e40000 {
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-qcom-sm8550-add-missing-cpu-cfg-interconne.patch b/queue-6.15/arm64-dts-qcom-sm8550-add-missing-cpu-cfg-interconne.patch
new file mode 100644 (file)
index 0000000..e32d1dd
--- /dev/null
@@ -0,0 +1,45 @@
+From 58a45cc44bbd72db7c2ad31762668ad318417a38 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 10:00:32 +0100
+Subject: arm64: dts: qcom: sm8550: add missing cpu-cfg interconnect path in
+ the mdss node
+
+From: Neil Armstrong <neil.armstrong@linaro.org>
+
+[ Upstream commit 327d489d1ecaf16182952f079cc21f04cf83f967 ]
+
+The bindings requires the mdp0-mem and the cpu-cfg interconnect path,
+add the missing cpu-cfg path to fix the dtbs check error and also to ensure
+that MDSS has enough bandwidth to let HLOS write config registers.
+
+Fixes: b8591df49cde ("arm64: dts: qcom: sm8550: correct MDSS interconnects")
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://lore.kernel.org/r/20250227-topic-sm8x50-mdss-interconnect-bindings-fix-v5-1-bf6233c6ebe5@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8550.dtsi | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi
+index 9465b00f1e74c..65ebddd124e2a 100644
+--- a/arch/arm64/boot/dts/qcom/sm8550.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi
+@@ -3146,8 +3146,10 @@
+                       power-domains = <&dispcc MDSS_GDSC>;
+                       interconnects = <&mmss_noc MASTER_MDP QCOM_ICC_TAG_ALWAYS
+-                                       &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+-                      interconnect-names = "mdp0-mem";
++                                       &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
++                                      <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
++                                       &config_noc SLAVE_DISPLAY_CFG QCOM_ICC_TAG_ACTIVE_ONLY>;
++                      interconnect-names = "mdp0-mem", "cpu-cfg";
+                       iommus = <&apps_smmu 0x1c00 0x2>;
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-qcom-sm8550-use-icc-tag-for-all-interconne.patch b/queue-6.15/arm64-dts-qcom-sm8550-use-icc-tag-for-all-interconne.patch
new file mode 100644 (file)
index 0000000..9e34a3a
--- /dev/null
@@ -0,0 +1,804 @@
+From 36e5cd27936f87e443670641041aa1bc43861b88 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jan 2025 14:43:53 +0100
+Subject: arm64: dts: qcom: sm8550: use ICC tag for all interconnect phandles
+
+From: Neil Armstrong <neil.armstrong@linaro.org>
+
+[ Upstream commit 54df5e52777e1126862778a2796c3809df85acd7 ]
+
+Use the proper QCOM_ICC_TAG_ define instead of passing 0 in all
+interconnect paths phandle third argument.
+
+Use QCOM_ICC_TAG_ALWAYS which is the fallback mask if 0 is used
+as third phandle argument.
+
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Acked-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Link: https://lore.kernel.org/r/20250115-topic-sm8x50-upstream-dt-icc-update-v1-1-eaa8b10e2af7@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Stable-dep-of: 327d489d1eca ("arm64: dts: qcom: sm8550: add missing cpu-cfg interconnect path in the mdss node")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8550.dtsi | 387 ++++++++++++++++++---------
+ 1 file changed, 258 insertions(+), 129 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi
+index ac3e00ad41771..9465b00f1e74c 100644
+--- a/arch/arm64/boot/dts/qcom/sm8550.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi
+@@ -331,7 +331,8 @@
+               scm: scm {
+                       compatible = "qcom,scm-sm8550", "qcom,scm";
+                       qcom,dload-mode = <&tcsr 0x19000>;
+-                      interconnects = <&aggre2_noc MASTER_CRYPTO 0 &mc_virt SLAVE_EBI1 0>;
++                      interconnects = <&aggre2_noc MASTER_CRYPTO QCOM_ICC_TAG_ALWAYS
++                                       &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+               };
+       };
+@@ -850,9 +851,12 @@
+                               interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_2 0 &clk_virt SLAVE_QUP_CORE_2 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>,
+-                                              <&aggre2_noc MASTER_QUP_2 0 &mc_virt  SLAVE_EBI1 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>,
++                                              <&aggre2_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS
++                                               &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config", "qup-memory";
+                               dmas = <&gpi_dma2 0 0 QCOM_GPI_I2C>,
+                                      <&gpi_dma2 1 0 QCOM_GPI_I2C>;
+@@ -868,9 +872,12 @@
+                               interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi8_data_clk>, <&qup_spi8_cs>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_2 0 &clk_virt SLAVE_QUP_CORE_2 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>,
+-                                              <&aggre2_noc MASTER_QUP_2 0 &mc_virt  SLAVE_EBI1 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>,
++                                              <&aggre2_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS
++                                               &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config", "qup-memory";
+                               dmas = <&gpi_dma2 0 0 QCOM_GPI_SPI>,
+                                      <&gpi_dma2 1 0 QCOM_GPI_SPI>;
+@@ -890,9 +897,12 @@
+                               interrupts = <GIC_SPI 583 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_2 0 &clk_virt SLAVE_QUP_CORE_2 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>,
+-                                              <&aggre2_noc MASTER_QUP_2 0 &mc_virt  SLAVE_EBI1 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>,
++                                              <&aggre2_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS
++                                               &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config", "qup-memory";
+                               dmas = <&gpi_dma2 0 1 QCOM_GPI_I2C>,
+                                      <&gpi_dma2 1 1 QCOM_GPI_I2C>;
+@@ -908,9 +918,12 @@
+                               interrupts = <GIC_SPI 583 IRQ_TYPE_LEVEL_HIGH>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi9_data_clk>, <&qup_spi9_cs>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_2 0 &clk_virt SLAVE_QUP_CORE_2 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>,
+-                                              <&aggre2_noc MASTER_QUP_2 0 &mc_virt  SLAVE_EBI1 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>,
++                                              <&aggre2_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS
++                                               &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config", "qup-memory";
+                               dmas = <&gpi_dma2 0 1 QCOM_GPI_SPI>,
+                                      <&gpi_dma2 1 1 QCOM_GPI_SPI>;
+@@ -930,9 +943,12 @@
+                               interrupts = <GIC_SPI 584 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_2 0 &clk_virt SLAVE_QUP_CORE_2 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>,
+-                                              <&aggre2_noc MASTER_QUP_2 0 &mc_virt  SLAVE_EBI1 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>,
++                                              <&aggre2_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS
++                                               &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config", "qup-memory";
+                               dmas = <&gpi_dma2 0 2 QCOM_GPI_I2C>,
+                                      <&gpi_dma2 1 2 QCOM_GPI_I2C>;
+@@ -948,9 +964,12 @@
+                               interrupts = <GIC_SPI 584 IRQ_TYPE_LEVEL_HIGH>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi10_data_clk>, <&qup_spi10_cs>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_2 0 &clk_virt SLAVE_QUP_CORE_2 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>,
+-                                              <&aggre2_noc MASTER_QUP_2 0 &mc_virt  SLAVE_EBI1 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>,
++                                              <&aggre2_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS
++                                               &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config", "qup-memory";
+                               dmas = <&gpi_dma2 0 2 QCOM_GPI_SPI>,
+                                      <&gpi_dma2 1 2 QCOM_GPI_SPI>;
+@@ -970,9 +989,12 @@
+                               interrupts = <GIC_SPI 585 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_2 0 &clk_virt SLAVE_QUP_CORE_2 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>,
+-                                              <&aggre2_noc MASTER_QUP_2 0 &mc_virt  SLAVE_EBI1 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>,
++                                              <&aggre2_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS
++                                               &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config", "qup-memory";
+                               dmas = <&gpi_dma2 0 3 QCOM_GPI_I2C>,
+                                      <&gpi_dma2 1 3 QCOM_GPI_I2C>;
+@@ -988,9 +1010,12 @@
+                               interrupts = <GIC_SPI 585 IRQ_TYPE_LEVEL_HIGH>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi11_data_clk>, <&qup_spi11_cs>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_2 0 &clk_virt SLAVE_QUP_CORE_2 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>,
+-                                              <&aggre2_noc MASTER_QUP_2 0 &mc_virt  SLAVE_EBI1 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>,
++                                              <&aggre2_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS
++                                               &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config", "qup-memory";
+                               dmas = <&gpi_dma2 0 3 QCOM_GPI_I2C>,
+                                      <&gpi_dma2 1 3 QCOM_GPI_I2C>;
+@@ -1010,9 +1035,12 @@
+                               interrupts = <GIC_SPI 586 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_2 0 &clk_virt SLAVE_QUP_CORE_2 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>,
+-                                              <&aggre2_noc MASTER_QUP_2 0 &mc_virt  SLAVE_EBI1 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>,
++                                              <&aggre2_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS
++                                               &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config", "qup-memory";
+                               dmas = <&gpi_dma2 0 4 QCOM_GPI_I2C>,
+                                      <&gpi_dma2 1 4 QCOM_GPI_I2C>;
+@@ -1028,9 +1056,12 @@
+                               interrupts = <GIC_SPI 586 IRQ_TYPE_LEVEL_HIGH>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi12_data_clk>, <&qup_spi12_cs>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_2 0 &clk_virt SLAVE_QUP_CORE_2 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>,
+-                                              <&aggre2_noc MASTER_QUP_2 0 &mc_virt  SLAVE_EBI1 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>,
++                                              <&aggre2_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS
++                                               &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config", "qup-memory";
+                               dmas = <&gpi_dma2 0 4 QCOM_GPI_I2C>,
+                                      <&gpi_dma2 1 4 QCOM_GPI_I2C>;
+@@ -1050,9 +1081,12 @@
+                               interrupts = <GIC_SPI 587 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_2 0 &clk_virt SLAVE_QUP_CORE_2 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>,
+-                                              <&aggre2_noc MASTER_QUP_2 0 &mc_virt  SLAVE_EBI1 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>,
++                                              <&aggre2_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS
++                                               &mc_virt  SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config", "qup-memory";
+                               dmas = <&gpi_dma2 0 5 QCOM_GPI_I2C>,
+                                      <&gpi_dma2 1 5 QCOM_GPI_I2C>;
+@@ -1068,9 +1102,12 @@
+                               interrupts = <GIC_SPI 587 IRQ_TYPE_LEVEL_HIGH>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi13_data_clk>, <&qup_spi13_cs>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_2 0 &clk_virt SLAVE_QUP_CORE_2 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>,
+-                                              <&aggre2_noc MASTER_QUP_2 0 &mc_virt  SLAVE_EBI1 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>,
++                                              <&aggre2_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS
++                                               &mc_virt  SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config", "qup-memory";
+                               dmas = <&gpi_dma2 0 5 QCOM_GPI_SPI>,
+                                      <&gpi_dma2 1 5 QCOM_GPI_SPI>;
+@@ -1088,8 +1125,10 @@
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_uart14_default>, <&qup_uart14_cts_rts>;
+                               interrupts = <GIC_SPI 461 IRQ_TYPE_LEVEL_HIGH>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_2 0 &clk_virt SLAVE_QUP_CORE_2 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config";
+                               status = "disabled";
+                       };
+@@ -1104,9 +1143,12 @@
+                               interrupts = <GIC_SPI 462 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_2 0 &clk_virt SLAVE_QUP_CORE_2 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>,
+-                                              <&aggre2_noc MASTER_QUP_2 0 &mc_virt  SLAVE_EBI1 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>,
++                                              <&aggre2_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS
++                                               &mc_virt  SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config", "qup-memory";
+                               dmas = <&gpi_dma2 0 7 QCOM_GPI_I2C>,
+                                      <&gpi_dma2 1 7 QCOM_GPI_I2C>;
+@@ -1122,9 +1164,12 @@
+                               interrupts = <GIC_SPI 462 IRQ_TYPE_LEVEL_HIGH>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi15_data_clk>, <&qup_spi15_cs>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_2 0 &clk_virt SLAVE_QUP_CORE_2 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>,
+-                                              <&aggre2_noc MASTER_QUP_2 0 &mc_virt  SLAVE_EBI1 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>,
++                                              <&aggre2_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS
++                                               &mc_virt  SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config", "qup-memory";
+                               dmas = <&gpi_dma2 0 7 QCOM_GPI_SPI>,
+                                      <&gpi_dma2 1 7 QCOM_GPI_SPI>;
+@@ -1156,8 +1201,10 @@
+                               interrupts = <GIC_SPI 464 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_I2C 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_I2C QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config";
+                               status = "disabled";
+                       };
+@@ -1173,8 +1220,10 @@
+                               interrupts = <GIC_SPI 465 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_I2C 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_I2C QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config";
+                               status = "disabled";
+                       };
+@@ -1190,8 +1239,10 @@
+                               interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_I2C 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_I2C QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config";
+                               status = "disabled";
+                       };
+@@ -1207,8 +1258,10 @@
+                               interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_I2C 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_I2C QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config";
+                               status = "disabled";
+                       };
+@@ -1224,8 +1277,10 @@
+                               interrupts = <GIC_SPI 468 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_I2C 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_I2C QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config";
+                               status = "disabled";
+                       };
+@@ -1241,8 +1296,10 @@
+                               interrupts = <GIC_SPI 469 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_I2C 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_I2C QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config";
+                               status = "disabled";
+                       };
+@@ -1258,8 +1315,10 @@
+                               interrupts = <GIC_SPI 470 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_I2C 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_I2C QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config";
+                               status = "disabled";
+                       };
+@@ -1275,8 +1334,10 @@
+                               interrupts = <GIC_SPI 471 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_I2C 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_I2C QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config";
+                               status = "disabled";
+                       };
+@@ -1292,8 +1353,10 @@
+                               interrupts = <GIC_SPI 472 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_I2C 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_I2C QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config";
+                               status = "disabled";
+                       };
+@@ -1309,8 +1372,10 @@
+                               interrupts = <GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_I2C 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_I2C QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config";
+                               status = "disabled";
+                       };
+@@ -1347,7 +1412,8 @@
+                       clocks = <&gcc GCC_QUPV3_WRAP_1_M_AHB_CLK>,
+                                <&gcc GCC_QUPV3_WRAP_1_S_AHB_CLK>;
+                       iommus = <&apps_smmu 0xa3 0>;
+-                      interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>;
++                      interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
++                                       &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>;
+                       interconnect-names = "qup-core";
+                       dma-coherent;
+                       #address-cells = <2>;
+@@ -1364,9 +1430,12 @@
+                               interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>,
+-                                              <&aggre1_noc MASTER_QUP_1 0 &mc_virt  SLAVE_EBI1 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>,
++                                              <&aggre1_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS
++                                               &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config", "qup-memory";
+                               dmas = <&gpi_dma1 0 0 QCOM_GPI_I2C>,
+                                      <&gpi_dma1 1 0 QCOM_GPI_I2C>;
+@@ -1382,9 +1451,12 @@
+                               interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi0_data_clk>, <&qup_spi0_cs>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>,
+-                                              <&aggre1_noc MASTER_QUP_1 0 &mc_virt  SLAVE_EBI1 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>,
++                                              <&aggre1_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS
++                                               &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config", "qup-memory";
+                               dmas = <&gpi_dma1 0 0 QCOM_GPI_SPI>,
+                                      <&gpi_dma1 1 0 QCOM_GPI_SPI>;
+@@ -1404,9 +1476,12 @@
+                               interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>,
+-                                              <&aggre1_noc MASTER_QUP_1 0 &mc_virt  SLAVE_EBI1 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>,
++                                              <&aggre1_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS
++                                               &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config", "qup-memory";
+                               dmas = <&gpi_dma1 0 1 QCOM_GPI_I2C>,
+                                      <&gpi_dma1 1 1 QCOM_GPI_I2C>;
+@@ -1422,9 +1497,12 @@
+                               interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi1_data_clk>, <&qup_spi1_cs>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>,
+-                                              <&aggre1_noc MASTER_QUP_1 0 &mc_virt  SLAVE_EBI1 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>,
++                                              <&aggre1_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS
++                                               &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config", "qup-memory";
+                               dmas = <&gpi_dma1 0 1 QCOM_GPI_SPI>,
+                                      <&gpi_dma1 1 1 QCOM_GPI_SPI>;
+@@ -1444,9 +1522,12 @@
+                               interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>,
+-                                              <&aggre1_noc MASTER_QUP_1 0 &mc_virt  SLAVE_EBI1 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>,
++                                              <&aggre1_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS
++                                               &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config", "qup-memory";
+                               dmas = <&gpi_dma1 0 2 QCOM_GPI_I2C>,
+                                      <&gpi_dma1 1 2 QCOM_GPI_I2C>;
+@@ -1462,9 +1543,12 @@
+                               interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi2_data_clk>, <&qup_spi2_cs>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>,
+-                                              <&aggre1_noc MASTER_QUP_1 0 &mc_virt  SLAVE_EBI1 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>,
++                                              <&aggre1_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS
++                                               &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config", "qup-memory";
+                               dmas = <&gpi_dma1 0 2 QCOM_GPI_SPI>,
+                                      <&gpi_dma1 1 2 QCOM_GPI_SPI>;
+@@ -1484,9 +1568,12 @@
+                               interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>,
+-                                              <&aggre1_noc MASTER_QUP_1 0 &mc_virt  SLAVE_EBI1 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>,
++                                              <&aggre1_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS
++                                               &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config", "qup-memory";
+                               dmas = <&gpi_dma1 0 3 QCOM_GPI_I2C>,
+                                      <&gpi_dma1 1 3 QCOM_GPI_I2C>;
+@@ -1502,9 +1589,12 @@
+                               interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi3_data_clk>, <&qup_spi3_cs>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>,
+-                                              <&aggre1_noc MASTER_QUP_1 0 &mc_virt  SLAVE_EBI1 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>,
++                                              <&aggre1_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS
++                                               &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config", "qup-memory";
+                               dmas = <&gpi_dma1 0 3 QCOM_GPI_SPI>,
+                                      <&gpi_dma1 1 3 QCOM_GPI_SPI>;
+@@ -1524,9 +1614,12 @@
+                               interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>,
+-                                              <&aggre1_noc MASTER_QUP_1 0 &mc_virt  SLAVE_EBI1 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>,
++                                              <&aggre1_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS
++                                               &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config", "qup-memory";
+                               dmas = <&gpi_dma1 0 4 QCOM_GPI_I2C>,
+                                      <&gpi_dma1 1 4 QCOM_GPI_I2C>;
+@@ -1542,9 +1635,12 @@
+                               interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi4_data_clk>, <&qup_spi4_cs>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>,
+-                                              <&aggre1_noc MASTER_QUP_1 0 &mc_virt  SLAVE_EBI1 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>,
++                                              <&aggre1_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS
++                                               &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config", "qup-memory";
+                               dmas = <&gpi_dma1 0 4 QCOM_GPI_SPI>,
+                                      <&gpi_dma1 1 4 QCOM_GPI_SPI>;
+@@ -1562,9 +1658,12 @@
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_i2c5_data_clk>;
+                               interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>,
+-                                              <&aggre1_noc MASTER_QUP_1 0 &mc_virt  SLAVE_EBI1 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>,
++                                              <&aggre1_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS
++                                               &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config", "qup-memory";
+                               dmas = <&gpi_dma1 0 5 QCOM_GPI_I2C>,
+                                      <&gpi_dma1 1 5 QCOM_GPI_I2C>;
+@@ -1582,9 +1681,12 @@
+                               interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi5_data_clk>, <&qup_spi5_cs>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>,
+-                                              <&aggre1_noc MASTER_QUP_1 0 &mc_virt  SLAVE_EBI1 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>,
++                                              <&aggre1_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS
++                                               &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config", "qup-memory";
+                               dmas = <&gpi_dma1 0 5 QCOM_GPI_SPI>,
+                                      <&gpi_dma1 1 5 QCOM_GPI_SPI>;
+@@ -1602,9 +1704,12 @@
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_i2c6_data_clk>;
+                               interrupts = <GIC_SPI 363 IRQ_TYPE_LEVEL_HIGH>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>,
+-                                              <&aggre1_noc MASTER_QUP_1 0 &mc_virt  SLAVE_EBI1 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>,
++                                              <&aggre1_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS
++                                               &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config", "qup-memory";
+                               dmas = <&gpi_dma1 0 6 QCOM_GPI_I2C>,
+                                      <&gpi_dma1 1 6 QCOM_GPI_I2C>;
+@@ -1622,9 +1727,12 @@
+                               interrupts = <GIC_SPI 363 IRQ_TYPE_LEVEL_HIGH>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi6_data_clk>, <&qup_spi6_cs>;
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>,
+-                                              <&aggre1_noc MASTER_QUP_1 0 &mc_virt  SLAVE_EBI1 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>,
++                                              <&aggre1_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS
++                                               &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+                               interconnect-names = "qup-core", "qup-config", "qup-memory";
+                               dmas = <&gpi_dma1 0 6 QCOM_GPI_SPI>,
+                                      <&gpi_dma1 1 6 QCOM_GPI_SPI>;
+@@ -1643,8 +1751,10 @@
+                               pinctrl-0 = <&qup_uart7_default>;
+                               interrupts = <GIC_SPI 579 IRQ_TYPE_LEVEL_HIGH>;
+                               interconnect-names = "qup-core", "qup-config";
+-                              interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+-                                              <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>;
++                              interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
++                                               &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
++                                              <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                               &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>;
+                               status = "disabled";
+                       };
+               };
+@@ -1768,8 +1878,10 @@
+                                     "ddrss_sf_tbu",
+                                     "noc_aggr";
+-                      interconnects = <&pcie_noc MASTER_PCIE_0 0 &mc_virt SLAVE_EBI1 0>,
+-                                      <&gem_noc MASTER_APPSS_PROC 0 &cnoc_main SLAVE_PCIE_0 0>;
++                      interconnects = <&pcie_noc MASTER_PCIE_0 QCOM_ICC_TAG_ALWAYS
++                                       &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
++                                      <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                       &cnoc_main SLAVE_PCIE_0 QCOM_ICC_TAG_ALWAYS>;
+                       interconnect-names = "pcie-mem", "cpu-pcie";
+                       msi-map = <0x0 &gic_its 0x1400 0x1>,
+@@ -1891,8 +2003,10 @@
+                       assigned-clocks = <&gcc GCC_PCIE_1_AUX_CLK>;
+                       assigned-clock-rates = <19200000>;
+-                      interconnects = <&pcie_noc MASTER_PCIE_1 0 &mc_virt SLAVE_EBI1 0>,
+-                                      <&gem_noc MASTER_APPSS_PROC 0 &cnoc_main SLAVE_PCIE_1 0>;
++                      interconnects = <&pcie_noc MASTER_PCIE_1 QCOM_ICC_TAG_ALWAYS
++                                       &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
++                                      <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                       &cnoc_main SLAVE_PCIE_1 QCOM_ICC_TAG_ALWAYS>;
+                       interconnect-names = "pcie-mem", "cpu-pcie";
+                       msi-map = <0x0 &gic_its 0x1480 0x1>,
+@@ -1971,7 +2085,8 @@
+                       dma-names = "rx", "tx";
+                       iommus = <&apps_smmu 0x480 0x0>,
+                                <&apps_smmu 0x481 0x0>;
+-                      interconnects = <&aggre2_noc MASTER_CRYPTO 0 &mc_virt SLAVE_EBI1 0>;
++                      interconnects = <&aggre2_noc MASTER_CRYPTO QCOM_ICC_TAG_ALWAYS
++                                       &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+                       interconnect-names = "memory";
+               };
+@@ -2015,8 +2130,10 @@
+                       dma-coherent;
+                       operating-points-v2 = <&ufs_opp_table>;
+-                      interconnects = <&aggre1_noc MASTER_UFS_MEM 0 &mc_virt SLAVE_EBI1 0>,
+-                                      <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_UFS_MEM_CFG 0>;
++                      interconnects = <&aggre1_noc MASTER_UFS_MEM QCOM_ICC_TAG_ALWAYS
++                                       &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
++                                      <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                       &config_noc SLAVE_UFS_MEM_CFG QCOM_ICC_TAG_ALWAYS>;
+                       interconnect-names = "ufs-ddr", "cpu-ufs";
+                       clock-names = "core_clk",
+@@ -2316,8 +2433,10 @@
+                       clocks = <&rpmhcc RPMH_IPA_CLK>;
+                       clock-names = "core";
+-                      interconnects = <&aggre2_noc MASTER_IPA 0 &mc_virt SLAVE_EBI1 0>,
+-                                      <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_IPA_CFG 0>;
++                      interconnects = <&aggre2_noc MASTER_IPA QCOM_ICC_TAG_ALWAYS
++                                       &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
++                                      <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                       &config_noc SLAVE_IPA_CFG QCOM_ICC_TAG_ALWAYS>;
+                       interconnect-names = "memory",
+                                            "config";
+@@ -2351,7 +2470,8 @@
+                                       <&rpmhpd RPMHPD_MSS>;
+                       power-domain-names = "cx", "mss";
+-                      interconnects = <&mc_virt MASTER_LLCC 0 &mc_virt SLAVE_EBI1 0>;
++                      interconnects = <&mc_virt MASTER_LLCC QCOM_ICC_TAG_ALWAYS
++                                       &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+                       memory-region = <&mpss_mem>, <&q6_mpss_dtb_mem>, <&mpss_dsm_mem>;
+@@ -2392,7 +2512,8 @@
+                                       <&rpmhpd RPMHPD_LMX>;
+                       power-domain-names = "lcx", "lmx";
+-                      interconnects = <&lpass_lpicx_noc MASTER_LPASS_PROC 0 &mc_virt SLAVE_EBI1 0>;
++                      interconnects = <&lpass_lpicx_noc MASTER_LPASS_PROC QCOM_ICC_TAG_ALWAYS
++                                       &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+                       memory-region = <&adspslpi_mem>, <&q6_adsp_dtb_mem>;
+@@ -2850,8 +2971,10 @@
+                       power-domains = <&rpmhpd RPMHPD_CX>;
+                       operating-points-v2 = <&sdhc2_opp_table>;
+-                      interconnects = <&aggre2_noc MASTER_SDCC_2 0 &mc_virt SLAVE_EBI1 0>,
+-                                      <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_SDCC_2 0>;
++                      interconnects = <&aggre2_noc MASTER_SDCC_2 QCOM_ICC_TAG_ALWAYS
++                                       &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
++                                      <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                       &config_noc SLAVE_SDCC_2 QCOM_ICC_TAG_ALWAYS>;
+                       interconnect-names = "sdhc-ddr", "cpu-sdhc";
+                       bus-width = <4>;
+                       dma-coherent;
+@@ -3022,7 +3145,8 @@
+                       power-domains = <&dispcc MDSS_GDSC>;
+-                      interconnects = <&mmss_noc MASTER_MDP 0 &mc_virt SLAVE_EBI1 0>;
++                      interconnects = <&mmss_noc MASTER_MDP QCOM_ICC_TAG_ALWAYS
++                                       &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+                       interconnect-names = "mdp0-mem";
+                       iommus = <&apps_smmu 0x1c00 0x2>;
+@@ -3495,8 +3619,10 @@
+                       resets = <&gcc GCC_USB30_PRIM_BCR>;
+-                      interconnects = <&aggre1_noc MASTER_USB3_0 0 &mc_virt SLAVE_EBI1 0>,
+-                                      <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_USB3_0 0>;
++                      interconnects = <&aggre1_noc MASTER_USB3_0 QCOM_ICC_TAG_ALWAYS
++                                       &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
++                                      <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
++                                       &config_noc SLAVE_USB3_0 QCOM_ICC_TAG_ALWAYS>;
+                       interconnect-names = "usb-ddr", "apps-usb";
+                       status = "disabled";
+@@ -4619,7 +4745,8 @@
+                       compatible = "qcom,sm8550-llcc-bwmon", "qcom,sc7280-llcc-bwmon";
+                       reg = <0 0x24091000 0 0x1000>;
+                       interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+-                      interconnects = <&mc_virt MASTER_LLCC 3 &mc_virt SLAVE_EBI1 3>;
++                      interconnects = <&mc_virt MASTER_LLCC QCOM_ICC_TAG_ACTIVE_ONLY
++                                       &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>;
+                       operating-points-v2 = <&llcc_bwmon_opp_table>;
+@@ -4668,7 +4795,8 @@
+                       compatible = "qcom,sm8550-cpu-bwmon", "qcom,sdm845-bwmon";
+                       reg = <0 0x240b6400 0 0x600>;
+                       interrupts = <GIC_SPI 581 IRQ_TYPE_LEVEL_HIGH>;
+-                      interconnects = <&gem_noc MASTER_APPSS_PROC 3 &gem_noc SLAVE_LLCC 3>;
++                      interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
++                                       &gem_noc SLAVE_LLCC QCOM_ICC_TAG_ACTIVE_ONLY>;
+                       operating-points-v2 = <&cpu_bwmon_opp_table>;
+@@ -4752,7 +4880,8 @@
+                                       <&rpmhpd RPMHPD_NSP>;
+                       power-domain-names = "cx", "mxc", "nsp";
+-                      interconnects = <&nsp_noc MASTER_CDSP_PROC 0 &mc_virt SLAVE_EBI1 0>;
++                      interconnects = <&nsp_noc MASTER_CDSP_PROC QCOM_ICC_TAG_ALWAYS
++                                       &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+                       memory-region = <&cdsp_mem>, <&q6_cdsp_dtb_mem>;
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-qcom-sm8650-add-missing-cpu-cfg-interconne.patch b/queue-6.15/arm64-dts-qcom-sm8650-add-missing-cpu-cfg-interconne.patch
new file mode 100644 (file)
index 0000000..312b1b6
--- /dev/null
@@ -0,0 +1,46 @@
+From 7a1fd4649b7819da9ab11974744b0395c6ca5ef0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 10:00:33 +0100
+Subject: arm64: dts: qcom: sm8650: add missing cpu-cfg interconnect path in
+ the mdss node
+
+From: Neil Armstrong <neil.armstrong@linaro.org>
+
+[ Upstream commit f22be5c1dd3e12519e3f3b80c14d10b90be2c2fc ]
+
+The bindings requires the mdp0-mem and the cpu-cfg interconnect path,
+add the missing cpu-cfg path to fix the dtbs check error and also to ensure
+that MDSS has enough bandwidth to let HLOS write config registers.
+
+Fixes: 9fa33cbca3d2 ("arm64: dts: qcom: sm8650: correct MDSS interconnects")
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://lore.kernel.org/r/20250227-topic-sm8x50-mdss-interconnect-bindings-fix-v5-2-bf6233c6ebe5@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8650.dtsi | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8650.dtsi b/arch/arm64/boot/dts/qcom/sm8650.dtsi
+index 9591c13edbb9d..36919efc888c2 100644
+--- a/arch/arm64/boot/dts/qcom/sm8650.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8650.dtsi
+@@ -3658,8 +3658,11 @@
+                       resets = <&dispcc DISP_CC_MDSS_CORE_BCR>;
+                       interconnects = <&mmss_noc MASTER_MDP QCOM_ICC_TAG_ALWAYS
+-                                       &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+-                      interconnect-names = "mdp0-mem";
++                                       &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
++                                      <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
++                                       &config_noc SLAVE_DISPLAY_CFG QCOM_ICC_TAG_ACTIVE_ONLY>;
++                      interconnect-names = "mdp0-mem",
++                                           "cpu-cfg";
+                       power-domains = <&dispcc MDSS_GDSC>;
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-qcom-sm8650-add-the-missing-l2-cache-node.patch b/queue-6.15/arm64-dts-qcom-sm8650-add-the-missing-l2-cache-node.patch
new file mode 100644 (file)
index 0000000..6365f86
--- /dev/null
@@ -0,0 +1,52 @@
+From 9e2d0e4ca8322ab00cba1f9c5be41dd71e8e6489 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 5 Apr 2025 18:55:28 +0800
+Subject: arm64: dts: qcom: sm8650: add the missing l2 cache node
+
+From: Pengyu Luo <mitltlatltl@gmail.com>
+
+[ Upstream commit 4becd72352b6861de0c24074a8502ca85080fd63 ]
+
+Only two little a520s share the same L2, every a720 has their own L2
+cache.
+
+Fixes: d2350377997f ("arm64: dts: qcom: add initial SM8650 dtsi")
+Signed-off-by: Pengyu Luo <mitltlatltl@gmail.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://lore.kernel.org/r/20250405105529.309711-1-mitltlatltl@gmail.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8650.dtsi | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8650.dtsi b/arch/arm64/boot/dts/qcom/sm8650.dtsi
+index bf6590e09a4c4..76acce6754986 100644
+--- a/arch/arm64/boot/dts/qcom/sm8650.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8650.dtsi
+@@ -159,13 +159,20 @@
+                       power-domain-names = "psci";
+                       enable-method = "psci";
+-                      next-level-cache = <&l2_200>;
++                      next-level-cache = <&l2_300>;
+                       capacity-dmips-mhz = <1792>;
+                       dynamic-power-coefficient = <238>;
+                       qcom,freq-domain = <&cpufreq_hw 3>;
+                       #cooling-cells = <2>;
++
++                      l2_300: l2-cache {
++                              compatible = "cache";
++                              cache-level = <2>;
++                              cache-unified;
++                              next-level-cache = <&l3_0>;
++                      };
+               };
+               cpu4: cpu@400 {
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-qcom-sm8650-fix-domain-idle-state-for-cpu2.patch b/queue-6.15/arm64-dts-qcom-sm8650-fix-domain-idle-state-for-cpu2.patch
new file mode 100644 (file)
index 0000000..6e58cdf
--- /dev/null
@@ -0,0 +1,40 @@
+From 205cad877700b11007699f307635ec57639a2777 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Mar 2025 09:21:16 +0100
+Subject: arm64: dts: qcom: sm8650: Fix domain-idle-state for CPU2
+
+From: Luca Weiss <luca.weiss@fairphone.com>
+
+[ Upstream commit 9bb5ca464100e7c8f2d740148088f60e04fed8ed ]
+
+On SM8650 the CPUs 0-1 are "silver" (Cortex-A520), CPU 2-6 are "gold"
+(Cortex-A720) and CPU 7 is "gold-plus" (Cortex-X4).
+
+So reference the correct "gold" idle-state for CPU core 2.
+
+Fixes: d2350377997f ("arm64: dts: qcom: add initial SM8650 dtsi")
+Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Link: https://lore.kernel.org/r/20250314-sm8650-cpu2-sleep-v1-1-31d5c7c87a5d@fairphone.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8650.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8650.dtsi b/arch/arm64/boot/dts/qcom/sm8650.dtsi
+index 36919efc888c2..bf6590e09a4c4 100644
+--- a/arch/arm64/boot/dts/qcom/sm8650.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8650.dtsi
+@@ -460,7 +460,7 @@
+               cpu_pd2: power-domain-cpu2 {
+                       #power-domain-cells = <0>;
+                       power-domains = <&cluster_pd>;
+-                      domain-idle-states = <&silver_cpu_sleep_0>;
++                      domain-idle-states = <&gold_cpu_sleep_0>;
+               };
+               cpu_pd3: power-domain-cpu3 {
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-qcom-sm8650-setup-gpu-thermal-with-higher-.patch b/queue-6.15/arm64-dts-qcom-sm8650-setup-gpu-thermal-with-higher-.patch
new file mode 100644 (file)
index 0000000..636d6ef
--- /dev/null
@@ -0,0 +1,240 @@
+From 3532ef5ef450bfdf60629b0baca5c57fdd9a5b2b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Feb 2025 14:23:18 +0100
+Subject: arm64: dts: qcom: sm8650: setup gpu thermal with higher temperatures
+
+From: Neil Armstrong <neil.armstrong@linaro.org>
+
+[ Upstream commit 2250f65b32565eb8b757e89248c75977f370f498 ]
+
+On the SM8650, the dynamic clock and voltage scaling (DCVS) for the GPU
+is done from the HLOS, but the GPU can achieve a much higher temperature
+before failing according the reference downstream implementation.
+
+Set higher temperatures in the GPU trip points corresponding to
+the temperatures provided by Qualcomm in the dowstream source, much
+closer to the junction temperature and with a higher critical
+temperature trip in the case the HLOS DCVS cannot handle the
+temperature surge.
+
+The tsens MAX_THRESHOLD is set to 120C on those platforms, so set
+the hot to 110C to leave a chance to HLOS to react and critical to
+115C to avoid the monitor thermal shutdown.
+
+Fixes: 497624ed5506 ("arm64: dts: qcom: sm8650: Throttle the GPU when overheating")
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Link: https://lore.kernel.org/r/20250203-topic-sm8650-thermal-cpu-idle-v4-2-65e35f307301@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8650.dtsi | 64 ++++++++++++++--------------
+ 1 file changed, 32 insertions(+), 32 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8650.dtsi b/arch/arm64/boot/dts/qcom/sm8650.dtsi
+index c8a2a76a98f00..9591c13edbb9d 100644
+--- a/arch/arm64/boot/dts/qcom/sm8650.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8650.dtsi
+@@ -6537,20 +6537,20 @@
+                       trips {
+                               gpu0_alert0: trip-point0 {
+-                                      temperature = <85000>;
++                                      temperature = <95000>;
+                                       hysteresis = <1000>;
+                                       type = "passive";
+                               };
+                               trip-point1 {
+-                                      temperature = <90000>;
++                                      temperature = <110000>;
+                                       hysteresis = <1000>;
+                                       type = "hot";
+                               };
+                               trip-point2 {
+-                                      temperature = <110000>;
+-                                      hysteresis = <1000>;
++                                      temperature = <115000>;
++                                      hysteresis = <0>;
+                                       type = "critical";
+                               };
+                       };
+@@ -6570,20 +6570,20 @@
+                       trips {
+                               gpu1_alert0: trip-point0 {
+-                                      temperature = <85000>;
++                                      temperature = <95000>;
+                                       hysteresis = <1000>;
+                                       type = "passive";
+                               };
+                               trip-point1 {
+-                                      temperature = <90000>;
++                                      temperature = <110000>;
+                                       hysteresis = <1000>;
+                                       type = "hot";
+                               };
+                               trip-point2 {
+-                                      temperature = <110000>;
+-                                      hysteresis = <1000>;
++                                      temperature = <115000>;
++                                      hysteresis = <0>;
+                                       type = "critical";
+                               };
+                       };
+@@ -6603,20 +6603,20 @@
+                       trips {
+                               gpu2_alert0: trip-point0 {
+-                                      temperature = <85000>;
++                                      temperature = <95000>;
+                                       hysteresis = <1000>;
+                                       type = "passive";
+                               };
+                               trip-point1 {
+-                                      temperature = <90000>;
++                                      temperature = <110000>;
+                                       hysteresis = <1000>;
+                                       type = "hot";
+                               };
+                               trip-point2 {
+-                                      temperature = <110000>;
+-                                      hysteresis = <1000>;
++                                      temperature = <115000>;
++                                      hysteresis = <0>;
+                                       type = "critical";
+                               };
+                       };
+@@ -6636,20 +6636,20 @@
+                       trips {
+                               gpu3_alert0: trip-point0 {
+-                                      temperature = <85000>;
++                                      temperature = <95000>;
+                                       hysteresis = <1000>;
+                                       type = "passive";
+                               };
+                               trip-point1 {
+-                                      temperature = <90000>;
++                                      temperature = <110000>;
+                                       hysteresis = <1000>;
+                                       type = "hot";
+                               };
+                               trip-point2 {
+-                                      temperature = <110000>;
+-                                      hysteresis = <1000>;
++                                      temperature = <115000>;
++                                      hysteresis = <0>;
+                                       type = "critical";
+                               };
+                       };
+@@ -6669,20 +6669,20 @@
+                       trips {
+                               gpu4_alert0: trip-point0 {
+-                                      temperature = <85000>;
++                                      temperature = <95000>;
+                                       hysteresis = <1000>;
+                                       type = "passive";
+                               };
+                               trip-point1 {
+-                                      temperature = <90000>;
++                                      temperature = <110000>;
+                                       hysteresis = <1000>;
+                                       type = "hot";
+                               };
+                               trip-point2 {
+-                                      temperature = <110000>;
+-                                      hysteresis = <1000>;
++                                      temperature = <115000>;
++                                      hysteresis = <0>;
+                                       type = "critical";
+                               };
+                       };
+@@ -6702,20 +6702,20 @@
+                       trips {
+                               gpu5_alert0: trip-point0 {
+-                                      temperature = <85000>;
++                                      temperature = <95000>;
+                                       hysteresis = <1000>;
+                                       type = "passive";
+                               };
+                               trip-point1 {
+-                                      temperature = <90000>;
++                                      temperature = <110000>;
+                                       hysteresis = <1000>;
+                                       type = "hot";
+                               };
+                               trip-point2 {
+-                                      temperature = <110000>;
+-                                      hysteresis = <1000>;
++                                      temperature = <115000>;
++                                      hysteresis = <0>;
+                                       type = "critical";
+                               };
+                       };
+@@ -6735,20 +6735,20 @@
+                       trips {
+                               gpu6_alert0: trip-point0 {
+-                                      temperature = <85000>;
++                                      temperature = <95000>;
+                                       hysteresis = <1000>;
+                                       type = "passive";
+                               };
+                               trip-point1 {
+-                                      temperature = <90000>;
++                                      temperature = <110000>;
+                                       hysteresis = <1000>;
+                                       type = "hot";
+                               };
+                               trip-point2 {
+-                                      temperature = <110000>;
+-                                      hysteresis = <1000>;
++                                      temperature = <115000>;
++                                      hysteresis = <0>;
+                                       type = "critical";
+                               };
+                       };
+@@ -6768,20 +6768,20 @@
+                       trips {
+                               gpu7_alert0: trip-point0 {
+-                                      temperature = <85000>;
++                                      temperature = <95000>;
+                                       hysteresis = <1000>;
+                                       type = "passive";
+                               };
+                               trip-point1 {
+-                                      temperature = <90000>;
++                                      temperature = <110000>;
+                                       hysteresis = <1000>;
+                                       type = "hot";
+                               };
+                               trip-point2 {
+-                                      temperature = <110000>;
+-                                      hysteresis = <1000>;
++                                      temperature = <115000>;
++                                      hysteresis = <0>;
+                                       type = "critical";
+                               };
+                       };
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-qcom-sm8750-correct-clocks-property-for-ua.patch b/queue-6.15/arm64-dts-qcom-sm8750-correct-clocks-property-for-ua.patch
new file mode 100644 (file)
index 0000000..564cefa
--- /dev/null
@@ -0,0 +1,40 @@
+From 41a65755e296db221f277e87aa39af4f5c0877cc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Mar 2025 16:13:58 +0530
+Subject: arm64: dts: qcom: sm8750: Correct clocks property for uart14 node
+
+From: Jyothi Kumar Seerapu <quic_jseerapu@quicinc.com>
+
+[ Upstream commit 515551e65635b988f2afa9e8683a6b57d6cfba36 ]
+
+Correct the clocks property for the uart14 node to fix UART functionality
+on QUP2_SE6. The current failure is due to an incorrect clocks assignment.
+
+Change the clocks property to GCC_QUPV3_WRAP2_S6_CLK to resolve the issue.
+
+Signed-off-by: Jyothi Kumar Seerapu <quic_jseerapu@quicinc.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Fixes: 068c3d3c83be ("arm64: dts: qcom: Add base SM8750 dtsi")
+Link: https://lore.kernel.org/r/20250312104358.2558-1-quic_jseerapu@quicinc.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8750.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8750.dtsi b/arch/arm64/boot/dts/qcom/sm8750.dtsi
+index d08a2dbeb0f79..e8bb587a7813f 100644
+--- a/arch/arm64/boot/dts/qcom/sm8750.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8750.dtsi
+@@ -993,7 +993,7 @@
+                               interrupts = <GIC_SPI 461 IRQ_TYPE_LEVEL_HIGH>;
+-                              clocks = <&gcc GCC_QUPV3_WRAP2_S5_CLK>;
++                              clocks = <&gcc GCC_QUPV3_WRAP2_S6_CLK>;
+                               clock-names = "se";
+                               interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-qcom-sm8750-fix-cluster-hierarchy-for-idle.patch b/queue-6.15/arm64-dts-qcom-sm8750-fix-cluster-hierarchy-for-idle.patch
new file mode 100644 (file)
index 0000000..f87de28
--- /dev/null
@@ -0,0 +1,104 @@
+From ae9fbbad680c2637d312fbfaa9264797131d94fd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Feb 2025 12:21:27 +0530
+Subject: arm64: dts: qcom: sm8750: Fix cluster hierarchy for idle states
+
+From: Maulik Shah <maulik.shah@oss.qualcomm.com>
+
+[ Upstream commit 778dc0f876c70b3d781a49981560ec88e1b7083a ]
+
+SM8750 have two different clusters. cluster0 have CPU 0-5 as child and
+cluster1 have CPU 6-7 as child. Each cluster requires its own idle state
+and power domain in order to achieve complete domain sleep state.
+
+However only single cluster idle state is added mapping CPU 0-7 to the
+same power domain. Fix this by correctly mapping each CPU to respective
+cluster power domain and make cluster1 power domain use same domain idle
+state as cluster0 since both use same idle state parameters.
+
+Fixes: 068c3d3c83be ("arm64: dts: qcom: Add base SM8750 dtsi")
+Signed-off-by: Maulik Shah <maulik.shah@oss.qualcomm.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Link: https://lore.kernel.org/r/20250226-sm8750_cluster_idle-v2-1-ef0ac81e242f@oss.qualcomm.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8750.dtsi | 24 +++++++++++++++---------
+ 1 file changed, 15 insertions(+), 9 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8750.dtsi b/arch/arm64/boot/dts/qcom/sm8750.dtsi
+index 3bbd7d18598ee..d08a2dbeb0f79 100644
+--- a/arch/arm64/boot/dts/qcom/sm8750.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8750.dtsi
+@@ -233,53 +233,59 @@
+               cpu_pd0: power-domain-cpu0 {
+                       #power-domain-cells = <0>;
+-                      power-domains = <&cluster_pd>;
++                      power-domains = <&cluster0_pd>;
+                       domain-idle-states = <&cluster0_c4>;
+               };
+               cpu_pd1: power-domain-cpu1 {
+                       #power-domain-cells = <0>;
+-                      power-domains = <&cluster_pd>;
++                      power-domains = <&cluster0_pd>;
+                       domain-idle-states = <&cluster0_c4>;
+               };
+               cpu_pd2: power-domain-cpu2 {
+                       #power-domain-cells = <0>;
+-                      power-domains = <&cluster_pd>;
++                      power-domains = <&cluster0_pd>;
+                       domain-idle-states = <&cluster0_c4>;
+               };
+               cpu_pd3: power-domain-cpu3 {
+                       #power-domain-cells = <0>;
+-                      power-domains = <&cluster_pd>;
++                      power-domains = <&cluster0_pd>;
+                       domain-idle-states = <&cluster0_c4>;
+               };
+               cpu_pd4: power-domain-cpu4 {
+                       #power-domain-cells = <0>;
+-                      power-domains = <&cluster_pd>;
++                      power-domains = <&cluster0_pd>;
+                       domain-idle-states = <&cluster0_c4>;
+               };
+               cpu_pd5: power-domain-cpu5 {
+                       #power-domain-cells = <0>;
+-                      power-domains = <&cluster_pd>;
++                      power-domains = <&cluster0_pd>;
+                       domain-idle-states = <&cluster0_c4>;
+               };
+               cpu_pd6: power-domain-cpu6 {
+                       #power-domain-cells = <0>;
+-                      power-domains = <&cluster_pd>;
++                      power-domains = <&cluster1_pd>;
+                       domain-idle-states = <&cluster1_c4>;
+               };
+               cpu_pd7: power-domain-cpu7 {
+                       #power-domain-cells = <0>;
+-                      power-domains = <&cluster_pd>;
++                      power-domains = <&cluster1_pd>;
+                       domain-idle-states = <&cluster1_c4>;
+               };
+-              cluster_pd: power-domain-cluster {
++              cluster0_pd: power-domain-cluster0 {
++                      #power-domain-cells = <0>;
++                      domain-idle-states = <&cluster_cl5>;
++                      power-domains = <&system_pd>;
++              };
++
++              cluster1_pd: power-domain-cluster1 {
+                       #power-domain-cells = <0>;
+                       domain-idle-states = <&cluster_cl5>;
+                       power-domains = <&system_pd>;
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-qcom-x1e001de-devkit-describe-usb-retimers.patch b/queue-6.15/arm64-dts-qcom-x1e001de-devkit-describe-usb-retimers.patch
new file mode 100644 (file)
index 0000000..1781628
--- /dev/null
@@ -0,0 +1,101 @@
+From 5387e31ef4e687fa16c005ce2cfec75dff9c5f18 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Apr 2025 14:25:22 +0300
+Subject: arm64: dts: qcom: x1e001de-devkit: Describe USB retimers resets pin
+ configs
+
+From: Abel Vesa <abel.vesa@linaro.org>
+
+[ Upstream commit f76fdcd2550991c854a698a9f881b1579455fc0a ]
+
+Currently, on the X Elite Devkit, the pin configuration of the reset
+gpios for all three PS8830 USB retimers are left configured by the
+bootloader.
+
+Fix that by describing their pin configuration.
+
+Fixes: 019e1ee32fec ("arm64: dts: qcom: x1e001de-devkit: Enable external DP support")
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
+Link: https://lore.kernel.org/r/20250422-x1e001de-devkit-dts-fix-retimer-gpios-v2-1-0129c4f2b6d7@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/x1e001de-devkit.dts | 32 ++++++++++++++++++++
+ 1 file changed, 32 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/x1e001de-devkit.dts b/arch/arm64/boot/dts/qcom/x1e001de-devkit.dts
+index f5063a0df9fbf..8f4482ade0f98 100644
+--- a/arch/arm64/boot/dts/qcom/x1e001de-devkit.dts
++++ b/arch/arm64/boot/dts/qcom/x1e001de-devkit.dts
+@@ -790,6 +790,9 @@
+               reset-gpios = <&tlmm 185 GPIO_ACTIVE_HIGH>;
++              pinctrl-0 = <&rtmr2_default>;
++              pinctrl-names = "default";
++
+               orientation-switch;
+               retimer-switch;
+@@ -845,6 +848,9 @@
+               reset-gpios = <&pm8550_gpios 10 GPIO_ACTIVE_HIGH>;
++              pinctrl-0 = <&rtmr0_default>;
++              pinctrl-names = "default";
++
+               retimer-switch;
+               orientation-switch;
+@@ -900,6 +906,9 @@
+               reset-gpios = <&tlmm 176 GPIO_ACTIVE_HIGH>;
++              pinctrl-0 = <&rtmr1_default>;
++              pinctrl-names = "default";
++
+               retimer-switch;
+               orientation-switch;
+@@ -1018,6 +1027,15 @@
+ };
+ &pm8550_gpios {
++      rtmr0_default: rtmr0-reset-n-active-state {
++              pins = "gpio10";
++              function = "normal";
++              power-source = <1>; /* 1.8 V */
++              bias-disable;
++              input-disable;
++              output-enable;
++      };
++
+       usb0_3p3_reg_en: usb0-3p3-reg-en-state {
+               pins = "gpio11";
+               function = "normal";
+@@ -1205,6 +1223,20 @@
+               };
+       };
++      rtmr1_default: rtmr1-reset-n-active-state {
++              pins = "gpio176";
++              function = "gpio";
++              drive-strength = <2>;
++              bias-disable;
++      };
++
++      rtmr2_default: rtmr2-reset-n-active-state {
++              pins = "gpio185";
++              function = "gpio";
++              drive-strength = <2>;
++              bias-disable;
++      };
++
+       rtmr1_1p15_reg_en: rtmr1-1p15-reg-en-state {
+               pins = "gpio188";
+               function = "gpio";
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-qcom-x1e001de-devkit-fix-pin-config-for-us.patch b/queue-6.15/arm64-dts-qcom-x1e001de-devkit-fix-pin-config-for-us.patch
new file mode 100644 (file)
index 0000000..7d82550
--- /dev/null
@@ -0,0 +1,64 @@
+From 99ba80c52999472755e946d8e8095054fb68a6c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Apr 2025 14:25:23 +0300
+Subject: arm64: dts: qcom: x1e001de-devkit: Fix pin config for USB0 retimer
+ vregs
+
+From: Abel Vesa <abel.vesa@linaro.org>
+
+[ Upstream commit 635d0c8edf26994dc1dcbc09add9423aa61869b0 ]
+
+Describe the missing power source, bias and direction for each of the USB0
+retimer gpio-controlled voltage regulators related pin configuration.
+
+Fixes: 019e1ee32fec ("arm64: dts: qcom: x1e001de-devkit: Enable external DP support")
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
+Link: https://lore.kernel.org/r/20250422-x1e001de-devkit-dts-fix-retimer-gpios-v2-2-0129c4f2b6d7@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/x1e001de-devkit.dts | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/x1e001de-devkit.dts b/arch/arm64/boot/dts/qcom/x1e001de-devkit.dts
+index 8f4482ade0f98..3cfe42ec08914 100644
+--- a/arch/arm64/boot/dts/qcom/x1e001de-devkit.dts
++++ b/arch/arm64/boot/dts/qcom/x1e001de-devkit.dts
+@@ -1039,6 +1039,10 @@
+       usb0_3p3_reg_en: usb0-3p3-reg-en-state {
+               pins = "gpio11";
+               function = "normal";
++              power-source = <1>; /* 1.8 V */
++              bias-disable;
++              input-disable;
++              output-enable;
+       };
+ };
+@@ -1046,6 +1050,10 @@
+       usb0_pwr_1p15_en: usb0-pwr-1p15-en-state {
+               pins = "gpio8";
+               function = "normal";
++              power-source = <1>; /* 1.8 V */
++              bias-disable;
++              input-disable;
++              output-enable;
+       };
+ };
+@@ -1053,6 +1061,10 @@
+       usb0_1p8_reg_en: usb0-1p8-reg-en-state {
+               pins = "gpio8";
+               function = "normal";
++              power-source = <1>; /* 1.8 V */
++              bias-disable;
++              input-disable;
++              output-enable;
+       };
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-qcom-x1e80100-mark-usb_2-as-dma-coherent.patch b/queue-6.15/arm64-dts-qcom-x1e80100-mark-usb_2-as-dma-coherent.patch
new file mode 100644 (file)
index 0000000..69c5f23
--- /dev/null
@@ -0,0 +1,37 @@
+From 8859f2a0a49c0ffe4da6c3891b78b3c81fd8b125 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jan 2025 21:52:31 +0100
+Subject: arm64: dts: qcom: x1e80100: Mark usb_2 as dma-coherent
+
+From: Mark Kettenis <kettenis@openbsd.org>
+
+[ Upstream commit 45bd6ff900cfe5038e2718a900f153ded3fa5392 ]
+
+Make this USB controller consistent with the others on this platform.
+
+Fixes: 4af46b7bd66f ("arm64: dts: qcom: x1e80100: Add USB nodes")
+Signed-off-by: Mark Kettenis <kettenis@openbsd.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Link: https://lore.kernel.org/r/20250109205232.92336-1-kettenis@openbsd.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/x1e80100.dtsi | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/x1e80100.dtsi b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
+index 5aeecf711340d..607d32f68c340 100644
+--- a/arch/arm64/boot/dts/qcom/x1e80100.dtsi
++++ b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
+@@ -4815,6 +4815,8 @@
+                               snps,dis-u1-entry-quirk;
+                               snps,dis-u2-entry-quirk;
++                              dma-coherent;
++
+                               ports {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-qcom-x1e80100-romulus-keep-l12b-and-l15b-a.patch b/queue-6.15/arm64-dts-qcom-x1e80100-romulus-keep-l12b-and-l15b-a.patch
new file mode 100644 (file)
index 0000000..70675b4
--- /dev/null
@@ -0,0 +1,47 @@
+From a5e8a384fb90c1823866fbaa989327d72fc636f4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Mar 2025 18:10:46 +0100
+Subject: arm64: dts: qcom: x1e80100-romulus: Keep L12B and L15B always on
+
+From: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+
+[ Upstream commit 0783c8b3c06b9cf16b5108d558e2faffb8c533b7 ]
+
+These regulators power some electronic components onboard. They're
+most likely kept online by other pieces of firmware, but you can never
+be sure enough.
+
+Fixes: 09d77be56093 ("arm64: dts: qcom: Add support for X1-based Surface Laptop 7 devices")
+Reported-by: Johan Hovold <johan+linaro@kernel.org>
+Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
+Link: https://lore.kernel.org/r/20250304-topic-sl7_vregs_aon-v1-1-b2dc706e4157@oss.qualcomm.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/x1e80100-microsoft-romulus.dtsi | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/x1e80100-microsoft-romulus.dtsi b/arch/arm64/boot/dts/qcom/x1e80100-microsoft-romulus.dtsi
+index 5867953c73564..6a883fafe3c77 100644
+--- a/arch/arm64/boot/dts/qcom/x1e80100-microsoft-romulus.dtsi
++++ b/arch/arm64/boot/dts/qcom/x1e80100-microsoft-romulus.dtsi
+@@ -510,6 +510,7 @@
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1200000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
++                      regulator-always-on;
+               };
+               vreg_l13b: ldo13 {
+@@ -531,6 +532,7 @@
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
++                      regulator-always-on;
+               };
+               vreg_l16b: ldo16 {
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-renesas-white-hawk-ard-audio-fix-tpu0-grou.patch b/queue-6.15/arm64-dts-renesas-white-hawk-ard-audio-fix-tpu0-grou.patch
new file mode 100644 (file)
index 0000000..ef325f4
--- /dev/null
@@ -0,0 +1,42 @@
+From 43d0829211bfd5f8aa2480479086fa893d5ec920 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 May 2025 06:43:24 +0000
+Subject: arm64: dts: renesas: white-hawk-ard-audio: Fix TPU0 groups
+
+From: Thuan Nguyen <thuan.nguyen-hong@banvien.com.vn>
+
+[ Upstream commit 652eea251dd852f02cef6223f367220acb3d1867 ]
+
+White Hawk ARD audio uses a clock generated by the TPU, but commit
+3d144ef10a44 ("pinctrl: renesas: r8a779g0: Fix TPU suffixes") renamed
+pin group "tpu_to0_a" to "tpu_to0_b".  Update DTS accordingly otherwise
+the sound driver does not receive a clock signal.
+
+Fixes: 3d144ef10a448f89 ("pinctrl: renesas: r8a779g0: Fix TPU suffixes")
+Signed-off-by: Thuan Nguyen <thuan.nguyen-hong@banvien.com.vn>
+Signed-off-by: Duy Nguyen <duy.nguyen.rh@renesas.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Acked-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Link: https://lore.kernel.org/TYCPR01MB8740608B675365215ADB0374B49CA@TYCPR01MB8740.jpnprd01.prod.outlook.com
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/renesas/white-hawk-ard-audio-da7212.dtso | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/white-hawk-ard-audio-da7212.dtso b/arch/arm64/boot/dts/renesas/white-hawk-ard-audio-da7212.dtso
+index c27b9b3d4e5f4..f2d53e958da11 100644
+--- a/arch/arm64/boot/dts/renesas/white-hawk-ard-audio-da7212.dtso
++++ b/arch/arm64/boot/dts/renesas/white-hawk-ard-audio-da7212.dtso
+@@ -108,7 +108,7 @@
+       };
+       tpu0_pins: tpu0 {
+-              groups = "tpu_to0_a";
++              groups = "tpu_to0_b";
+               function = "tpu";
+       };
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-renesas-white-hawk-single-improve-ethernet.patch b/queue-6.15/arm64-dts-renesas-white-hawk-single-improve-ethernet.patch
new file mode 100644 (file)
index 0000000..677958c
--- /dev/null
@@ -0,0 +1,65 @@
+From da3600163ceb941ac7f4390bdf23f33f348b6309 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 May 2025 15:31:55 +0200
+Subject: arm64: dts: renesas: white-hawk-single: Improve Ethernet TSN
+ description
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 8ffec7d62c6956199f442dac3b2d5d02231c3977 ]
+
+  - Add the missing "ethernet3" alias for the Ethernet TSN port, so
+    U-Boot will fill its local-mac-address property based on the
+    "eth3addr" environment variable (if set), avoiding a random MAC
+    address being assigned by the OS,
+  - Rename the numerical Ethernet PHY label to "tsn0_phy", to avoid
+    future conflicts, and for consistency with the "avbN_phy" labels.
+
+Fixes: 3d8e475bd7a724a9 ("arm64: dts: renesas: white-hawk-single: Wire-up Ethernet TSN")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+Link: https://lore.kernel.org/367f10a18aa196ff1c96734dd9bd5634b312c421.1746624368.git.geert+renesas@glider.be
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/renesas/white-hawk-single.dtsi | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/white-hawk-single.dtsi b/arch/arm64/boot/dts/renesas/white-hawk-single.dtsi
+index 20e8232f2f323..976a3ab44e5a5 100644
+--- a/arch/arm64/boot/dts/renesas/white-hawk-single.dtsi
++++ b/arch/arm64/boot/dts/renesas/white-hawk-single.dtsi
+@@ -11,6 +11,10 @@
+ / {
+       model = "Renesas White Hawk Single board";
+       compatible = "renesas,white-hawk-single";
++
++      aliases {
++              ethernet3 = &tsn0;
++      };
+ };
+ &hscif0 {
+@@ -53,7 +57,7 @@
+       pinctrl-0 = <&tsn0_pins>;
+       pinctrl-names = "default";
+       phy-mode = "rgmii";
+-      phy-handle = <&phy3>;
++      phy-handle = <&tsn0_phy>;
+       status = "okay";
+       mdio {
+@@ -63,7 +67,7 @@
+               reset-gpios = <&gpio1 23 GPIO_ACTIVE_LOW>;
+               reset-post-delay-us = <4000>;
+-              phy3: ethernet-phy@0 {
++              tsn0_phy: ethernet-phy@0 {
+                       compatible = "ethernet-phy-id002b.0980",
+                                    "ethernet-phy-ieee802.3-c22";
+                       reg = <0>;
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-rockchip-add-missing-uart3-interrupt-for-r.patch b/queue-6.15/arm64-dts-rockchip-add-missing-uart3-interrupt-for-r.patch
new file mode 100644 (file)
index 0000000..2e326fc
--- /dev/null
@@ -0,0 +1,40 @@
+From e1a1f8f0f7a7042a18420980ee0e1422aabe5f8b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 18:00:18 +0800
+Subject: arm64: dts: rockchip: Add missing uart3 interrupt for RK3528
+
+From: Chukun Pan <amadeus@jmu.edu.cn>
+
+[ Upstream commit a37d21a9b45e47ed6bc1f94e738096c07db78a07 ]
+
+The interrupt of uart3 node on rk3528 is missing, fix it.
+
+Fixes: 7983e6c379a9 ("arm64: dts: rockchip: Add base DT for rk3528 SoC")
+Reviewed-by: Yao Zi <ziyao@disroot.org>
+Signed-off-by: Chukun Pan <amadeus@jmu.edu.cn>
+Link: https://lore.kernel.org/r/20250401100020.944658-2-amadeus@jmu.edu.cn
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/rockchip/rk3528.dtsi | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/rockchip/rk3528.dtsi b/arch/arm64/boot/dts/rockchip/rk3528.dtsi
+index 26c3559d6a6de..7f1ffd6003f58 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3528.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3528.dtsi
+@@ -404,9 +404,10 @@
+               uart3: serial@ffa08000 {
+                       compatible = "rockchip,rk3528-uart", "snps,dw-apb-uart";
++                      reg = <0x0 0xffa08000 0x0 0x100>;
+                       clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>;
+                       clock-names = "baudclk", "apb_pclk";
+-                      reg = <0x0 0xffa08000 0x0 0x100>;
++                      interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+                       reg-io-width = <4>;
+                       reg-shift = <2>;
+                       status = "disabled";
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-rockchip-add-vcc-supply-to-spi-flash-on-rk.patch b/queue-6.15/arm64-dts-rockchip-add-vcc-supply-to-spi-flash-on-rk.patch
new file mode 100644 (file)
index 0000000..960cf55
--- /dev/null
@@ -0,0 +1,41 @@
+From 57affa2c393625676ca08c40eb0ac7ce33d22a84 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 May 2025 20:56:55 +0100
+Subject: arm64: dts: rockchip: Add vcc-supply to SPI flash on rk3566-rock3c
+
+From: Peter Robinson <pbrobinson@gmail.com>
+
+[ Upstream commit a706a593cb19796f31d3a888423ef1a71885ae72 ]
+
+As described in the radxa_rock_3c_v1400_schematic.pdf, the SPI Flash's
+VCC connector is connected to VCCIO_FLASH and according to the
+that same schematic, that belongs to the VCC_1V8 power source.
+
+This fixes the following warning:
+
+  spi-nor spi4.0: supply vcc not found, using dummy regulator
+
+Fixes: ee219017ddb5 ("arm64: dts: rockchip: Add Radxa ROCK 3C")
+Signed-off-by: Peter Robinson <pbrobinson@gmail.com>
+Link: https://lore.kernel.org/r/20250506195702.593044-1-pbrobinson@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
+index 53e71528e4c4c..6224d72813e59 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
+@@ -636,6 +636,7 @@
+               spi-max-frequency = <104000000>;
+               spi-rx-bus-width = <4>;
+               spi-tx-bus-width = <1>;
++              vcc-supply = <&vcc_1v8>;
+       };
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-rockchip-disable-unrouted-usb-controllers-.patch b/queue-6.15/arm64-dts-rockchip-disable-unrouted-usb-controllers-.patch
new file mode 100644 (file)
index 0000000..9d88167
--- /dev/null
@@ -0,0 +1,63 @@
+From c67b62638ff383f86f71b14cb9fa94daaf574379 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 17:18:09 +0200
+Subject: arm64: dts: rockchip: disable unrouted USB controllers and PHY on
+ RK3399 Puma
+
+From: Quentin Schulz <quentin.schulz@cherry.de>
+
+[ Upstream commit 3373af1d76bacd054b37f3e10266dd335ce425f8 ]
+
+The u2phy1_host port is the part of the USB PHY1 (namely the
+HOST1_DP/DM lanes) which routes directly to the USB2.0 HOST
+controller[1]. The other lanes of the PHY are routed to the USB3.0 OTG
+controller (dwc3), which we do use.
+
+The HOST1_DP/DM lanes aren't routed on RK3399 Puma so let's simply
+disable the USB2.0 controllers and associated part in USB2.0 PHY.
+
+No intended functional change.
+
+[1] https://rockchip.fr/Rockchip%20RK3399%20TRM%20V1.3%20Part2.pdf
+    Chapter 2 USB2.0 PHY
+
+Fixes: 2c66fc34e945 ("arm64: dts: rockchip: add RK3399-Q7 (Puma) SoM")
+Signed-off-by: Quentin Schulz <quentin.schulz@cherry.de>
+Signed-off-by: Lukasz Czechowski <lukasz.czechowski@thaumatec.com>
+Link: https://lore.kernel.org/r/20250425-onboard_usb_dev-v2-4-4a76a474a010@thaumatec.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi | 12 ------------
+ 1 file changed, 12 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
+index 314d9dfdba573..587e89d7fc5e4 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
+@@ -585,10 +585,6 @@
+       u2phy1_otg: otg-port {
+               status = "okay";
+       };
+-
+-      u2phy1_host: host-port {
+-              status = "okay";
+-      };
+ };
+ &usbdrd3_1 {
+@@ -622,11 +618,3 @@
+               vdd2-supply = <&vcc3v3_sys>;
+       };
+ };
+-
+-&usb_host1_ehci {
+-      status = "okay";
+-};
+-
+-&usb_host1_ohci {
+-      status = "okay";
+-};
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-rockchip-disable-unrouted-usb-controllers-.patch-25959 b/queue-6.15/arm64-dts-rockchip-disable-unrouted-usb-controllers-.patch-25959
new file mode 100644 (file)
index 0000000..12a248b
--- /dev/null
@@ -0,0 +1,67 @@
+From 6e1d511f66b22d5af63ac9ce09a134fffbbf65f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 17:18:10 +0200
+Subject: arm64: dts: rockchip: disable unrouted USB controllers and PHY on
+ RK3399 Puma with Haikou
+
+From: Quentin Schulz <quentin.schulz@cherry.de>
+
+[ Upstream commit febd8c6ab52c683b447fe22fc740918c86feae43 ]
+
+The u2phy0_host port is the part of the USB PHY0 (namely the
+HOST0_DP/DM lanes) which routes directly to the USB2.0 HOST
+controller[1]. The other lanes of the PHY are routed to the USB3.0 OTG
+controller (dwc3), which we do use.
+
+The HOST0_DP/DM lanes aren't routed on RK3399 Puma so let's simply
+disable the USB2.0 controllers.
+
+USB3 OTG has been known to be unstable on RK3399 Puma Haikou for a
+while, one of the recurring issues being that only USB2 is detected and
+not USB3 in host mode. Reading the justification above and seeing that
+we are keeping u2phy0_host in the Haikou carrierboard DTS probably may
+have bothered you since it should be changed to u2phy0_otg. The issue is
+that if it's switched to that, USB OTG on Haikou is entirely broken. I
+have checked the routing in the Gerber file, the lanes are going to the
+expected ball pins (that is, NOT HOST0_DP/DM).
+u2phy0_host is for sure the wrong part of the PHY to use, but it's the
+only one that works at the moment for that board so keep it until we
+figure out what exactly is broken.
+
+No intended functional change.
+
+[1] https://rockchip.fr/Rockchip%20RK3399%20TRM%20V1.3%20Part2.pdf
+    Chapter 2 USB2.0 PHY
+
+Fixes: 2c66fc34e945 ("arm64: dts: rockchip: add RK3399-Q7 (Puma) SoM")
+Signed-off-by: Quentin Schulz <quentin.schulz@cherry.de>
+Signed-off-by: Lukasz Czechowski <lukasz.czechowski@thaumatec.com>
+Link: https://lore.kernel.org/r/20250425-onboard_usb_dev-v2-5-4a76a474a010@thaumatec.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts | 8 --------
+ 1 file changed, 8 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts b/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts
+index f2234dabd6641..70979079923c1 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts
+@@ -312,14 +312,6 @@
+       status = "okay";
+ };
+-&usb_host0_ehci {
+-      status = "okay";
+-};
+-
+-&usb_host0_ohci {
+-      status = "okay";
+-};
+-
+ &vopb {
+       status = "okay";
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-rockchip-move-shmem-memory-to-reserved-mem.patch b/queue-6.15/arm64-dts-rockchip-move-shmem-memory-to-reserved-mem.patch
new file mode 100644 (file)
index 0000000..4016dc7
--- /dev/null
@@ -0,0 +1,52 @@
+From d9250249bf0c570df08dfea0568844904fd1793b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 17:00:09 +0800
+Subject: arm64: dts: rockchip: Move SHMEM memory to reserved memory on rk3588
+
+From: Chukun Pan <amadeus@jmu.edu.cn>
+
+[ Upstream commit 8ecd096d018be8a6bd3bd930f3a41a85db66a67d ]
+
+0x0 to 0xf0000000 are SDRAM memory areas where 0x10f000 is located.
+So move the SHMEM memory of arm_scmi to the reserved memory node.
+
+Fixes: c9211fa2602b ("arm64: dts: rockchip: Add base DT for rk3588 SoC")
+Signed-off-by: Chukun Pan <amadeus@jmu.edu.cn>
+Link: https://lore.kernel.org/r/20250401090009.733771-2-amadeus@jmu.edu.cn
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 15 +++++++--------
+ 1 file changed, 7 insertions(+), 8 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
+index 1e18ad93ba0eb..c52af310c7062 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
+@@ -439,16 +439,15 @@
+               #clock-cells = <0>;
+       };
+-      pmu_sram: sram@10f000 {
+-              compatible = "mmio-sram";
+-              reg = <0x0 0x0010f000 0x0 0x100>;
+-              ranges = <0 0x0 0x0010f000 0x100>;
+-              #address-cells = <1>;
+-              #size-cells = <1>;
++      reserved-memory {
++              #address-cells = <2>;
++              #size-cells = <2>;
++              ranges;
+-              scmi_shmem: sram@0 {
++              scmi_shmem: shmem@10f000 {
+                       compatible = "arm,scmi-shmem";
+-                      reg = <0x0 0x100>;
++                      reg = <0x0 0x0010f000 0x0 0x100>;
++                      no-map;
+               };
+       };
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-rockchip-update-emmc-for-nanopi-r5-series.patch b/queue-6.15/arm64-dts-rockchip-update-emmc-for-nanopi-r5-series.patch
new file mode 100644 (file)
index 0000000..53f9899
--- /dev/null
@@ -0,0 +1,45 @@
+From 3a88ce813794eecf34ddfe221148b34106553b34 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 May 2025 23:25:28 +0100
+Subject: arm64: dts: rockchip: Update eMMC for NanoPi R5 series
+
+From: Peter Robinson <pbrobinson@gmail.com>
+
+[ Upstream commit 8eca9e979a1efbcc3d090f6eb3f4da621e7c87e0 ]
+
+Add the 3.3v and 1.8v regulators that are connected to
+the eMMC on the R5 series devices, as well as adding the
+eMMC data strobe, and enable eMMC HS200 mode as the
+Foresee FEMDNN0xxG-A3A55 modules support it.
+
+Fixes: c8ec73b05a95d ("arm64: dts: rockchip: create common dtsi for NanoPi R5 series")
+Signed-off-by: Peter Robinson <pbrobinson@gmail.com>
+Reviewed-by: Diederik de Haas <didi.debian@cknow.org>
+Link: https://lore.kernel.org/r/20250506222531.625157-1-pbrobinson@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dtsi | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dtsi b/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dtsi
+index 00c479aa18711..a28b4af10d13a 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dtsi
+@@ -486,9 +486,12 @@
+ &sdhci {
+       bus-width = <8>;
+       max-frequency = <200000000>;
++      mmc-hs200-1_8v;
+       non-removable;
+       pinctrl-names = "default";
+-      pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd>;
++      pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
++      vmmc-supply = <&vcc_3v3>;
++      vqmmc-supply = <&vcc_1v8>;
+       status = "okay";
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-dts-ti-k3-j721e-common-proc-board-enable-ospi1.patch b/queue-6.15/arm64-dts-ti-k3-j721e-common-proc-board-enable-ospi1.patch
new file mode 100644 (file)
index 0000000..b073fc6
--- /dev/null
@@ -0,0 +1,36 @@
+From 814f436cc42a9709380a25947e6db494bfc7bff0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 May 2025 10:37:01 +0530
+Subject: arm64: dts: ti: k3-j721e-common-proc-board: Enable OSPI1 on J721E
+
+From: Prasanth Babu Mantena <p-mantena@ti.com>
+
+[ Upstream commit 6b8deb2ff0d31848c43a73f6044e69ba9276b3ec ]
+
+J721E SoM has MT25QU512AB Serial NOR flash connected to
+OSPI1 controller. Enable ospi1 node in device tree.
+
+Fixes: 73676c480b72 ("arm64: dts: ti: k3-j721e: Enable OSPI nodes at the board level")
+Signed-off-by: Prasanth Babu Mantena <p-mantena@ti.com>
+Link: https://lore.kernel.org/r/20250507050701.3007209-1-p-mantena@ti.com
+Signed-off-by: Nishanth Menon <nm@ti.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts
+index 4421852161dd6..da4e0cacd6d72 100644
+--- a/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts
++++ b/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts
+@@ -573,6 +573,7 @@
+ &ospi1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mcu_fss0_ospi1_pins_default>;
++      status = "okay";
+       flash@0 {
+               compatible = "jedec,spi-nor";
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-fpsimd-avoid-clobbering-kernel-fpsimd-state-wi.patch b/queue-6.15/arm64-fpsimd-avoid-clobbering-kernel-fpsimd-state-wi.patch
new file mode 100644 (file)
index 0000000..44c9402
--- /dev/null
@@ -0,0 +1,55 @@
+From 4790c6b473be2ee7d22db9572bf5affbe915e79d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Apr 2025 17:40:04 +0100
+Subject: arm64/fpsimd: Avoid clobbering kernel FPSIMD state with SMSTOP
+
+From: Mark Rutland <mark.rutland@arm.com>
+
+[ Upstream commit 01098d893fa8a6edb2b56e178b798e3e6b674f02 ]
+
+On system with SME, a thread's kernel FPSIMD state may be erroneously
+clobbered during a context switch immediately after that state is
+restored. Systems without SME are unaffected.
+
+If the CPU happens to be in streaming SVE mode before a context switch
+to a thread with kernel FPSIMD state, fpsimd_thread_switch() will
+restore the kernel FPSIMD state using fpsimd_load_kernel_state() while
+the CPU is still in streaming SVE mode. When fpsimd_thread_switch()
+subsequently calls fpsimd_flush_cpu_state(), this will execute an
+SMSTOP, causing an exit from streaming SVE mode. The exit from
+streaming SVE mode will cause the hardware to reset a number of
+FPSIMD/SVE/SME registers, clobbering the FPSIMD state.
+
+Fix this by calling fpsimd_flush_cpu_state() before restoring the kernel
+FPSIMD state.
+
+Fixes: e92bee9f861b ("arm64/fpsimd: Avoid erroneous elide of user state reload")
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Cc: Ard Biesheuvel <ardb@kernel.org>
+Cc: Mark Brown <broonie@kernel.org>
+Cc: Will Deacon <will@kernel.org>
+Reviewed-by: Mark Brown <broonie@kernel.org>
+Link: https://lore.kernel.org/r/20250409164010.3480271-8-mark.rutland@arm.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/kernel/fpsimd.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
+index 9466b3c5021ac..72ab9649c705b 100644
+--- a/arch/arm64/kernel/fpsimd.c
++++ b/arch/arm64/kernel/fpsimd.c
+@@ -1575,8 +1575,8 @@ void fpsimd_thread_switch(struct task_struct *next)
+               fpsimd_save_user_state();
+       if (test_tsk_thread_flag(next, TIF_KERNEL_FPSTATE)) {
+-              fpsimd_load_kernel_state(next);
+               fpsimd_flush_cpu_state();
++              fpsimd_load_kernel_state(next);
+       } else {
+               /*
+                * Fix up TIF_FOREIGN_FPSTATE to correctly describe next's
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-fpsimd-avoid-res0-bits-in-the-sme-trap-handler.patch b/queue-6.15/arm64-fpsimd-avoid-res0-bits-in-the-sme-trap-handler.patch
new file mode 100644 (file)
index 0000000..5b58d32
--- /dev/null
@@ -0,0 +1,78 @@
+From 20e4aac75a921ccec3eb558b4acb1df161e8b70b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Apr 2025 17:39:58 +0100
+Subject: arm64/fpsimd: Avoid RES0 bits in the SME trap handler
+
+From: Mark Rutland <mark.rutland@arm.com>
+
+[ Upstream commit 95507570fb2f75544af69760cd5d8f48fc5c7f20 ]
+
+The SME trap handler consumes RES0 bits from the ESR when determining
+the reason for the trap, and depends upon those bits reading as zero.
+This may break in future when those RES0 bits are allocated a meaning
+and stop reading as zero.
+
+For SME traps taken with ESR_ELx.EC == 0b011101, the specific reason for
+the trap is indicated by ESR_ELx.ISS.SMTC ("SME Trap Code"). This field
+occupies bits [2:0] of ESR_ELx.ISS, and as of ARM DDI 0487 L.a, bits
+[24:3] of ESR_ELx.ISS are RES0. ESR_ELx.ISS itself occupies bits [24:0]
+of ESR_ELx.
+
+Extract the SMTC field specifically, matching the way we handle ESR_ELx
+fields elsewhere, and ensuring that the handler is future-proof.
+
+Fixes: 8bd7f91c03d8 ("arm64/sme: Implement traps and syscall handling for SME")
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Cc: Marc Zyngier <maz@kernel.org>
+Cc: Mark Brown <broonie@kernel.org>
+Cc: Will Deacon <will@kernel.org>
+Reviewed-by: Mark Brown <broonie@kernel.org>
+Link: https://lore.kernel.org/r/20250409164010.3480271-2-mark.rutland@arm.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/include/asm/esr.h | 14 ++++++++------
+ arch/arm64/kernel/fpsimd.c   |  2 +-
+ 2 files changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
+index e4f77757937e6..71f0cbf7b2887 100644
+--- a/arch/arm64/include/asm/esr.h
++++ b/arch/arm64/include/asm/esr.h
+@@ -378,12 +378,14 @@
+ /*
+  * ISS values for SME traps
+  */
+-
+-#define ESR_ELx_SME_ISS_SME_DISABLED  0
+-#define ESR_ELx_SME_ISS_ILL           1
+-#define ESR_ELx_SME_ISS_SM_DISABLED   2
+-#define ESR_ELx_SME_ISS_ZA_DISABLED   3
+-#define ESR_ELx_SME_ISS_ZT_DISABLED   4
++#define ESR_ELx_SME_ISS_SMTC_MASK             GENMASK(2, 0)
++#define ESR_ELx_SME_ISS_SMTC(esr)             ((esr) & ESR_ELx_SME_ISS_SMTC_MASK)
++
++#define ESR_ELx_SME_ISS_SMTC_SME_DISABLED     0
++#define ESR_ELx_SME_ISS_SMTC_ILL              1
++#define ESR_ELx_SME_ISS_SMTC_SM_DISABLED      2
++#define ESR_ELx_SME_ISS_SMTC_ZA_DISABLED      3
++#define ESR_ELx_SME_ISS_SMTC_ZT_DISABLED      4
+ /* ISS field definitions for MOPS exceptions */
+ #define ESR_ELx_MOPS_ISS_MEM_INST     (UL(1) << 24)
+diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
+index 8370d55f03533..1ee5f330b8ed3 100644
+--- a/arch/arm64/kernel/fpsimd.c
++++ b/arch/arm64/kernel/fpsimd.c
+@@ -1436,7 +1436,7 @@ void do_sme_acc(unsigned long esr, struct pt_regs *regs)
+        * If this not a trap due to SME being disabled then something
+        * is being used in the wrong mode, report as SIGILL.
+        */
+-      if (ESR_ELx_ISS(esr) != ESR_ELx_SME_ISS_SME_DISABLED) {
++      if (ESR_ELx_SME_ISS_SMTC(esr) != ESR_ELx_SME_ISS_SMTC_SME_DISABLED) {
+               force_signal_inject(SIGILL, ILL_ILLOPC, regs->pc, 0);
+               return;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-fpsimd-avoid-warning-when-sve_to_fpsimd-is-unu.patch b/queue-6.15/arm64-fpsimd-avoid-warning-when-sve_to_fpsimd-is-unu.patch
new file mode 100644 (file)
index 0000000..2d4731f
--- /dev/null
@@ -0,0 +1,77 @@
+From 122397b2b6fc7dfe6369c6e83f0d770afb49bc92 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Apr 2025 18:32:40 +0100
+Subject: arm64/fpsimd: Avoid warning when sve_to_fpsimd() is unused
+
+From: Mark Rutland <mark.rutland@arm.com>
+
+[ Upstream commit f699c66691fb7e08a5a631c5baf5f2a19b7a6468 ]
+
+Historically fpsimd_to_sve() and sve_to_fpsimd() were (conditionally)
+called by functions which were defined regardless of CONFIG_ARM64_SVE.
+Hence it was necessary that both fpsimd_to_sve() and sve_to_fpsimd()
+were always defined and not guarded by ifdeffery.
+
+As a result of the removal of fpsimd_signal_preserve_current_state() in
+commit:
+
+  929fa99b1215966f ("arm64/fpsimd: signal: Always save+flush state early")
+
+... sve_to_fpsimd() has no callers when CONFIG_ARM64_SVE=n, resulting in
+a build-time warnign that it is unused:
+
+| arch/arm64/kernel/fpsimd.c:676:13: warning: unused function 'sve_to_fpsimd' [-Wunused-function]
+|   676 | static void sve_to_fpsimd(struct task_struct *task)
+|       |             ^~~~~~~~~~~~~
+| 1 warning generated.
+
+In contrast, fpsimd_to_sve() still has callers which are defined when
+CONFIG_ARM64_SVE=n, and it would be awkward to hide this behind
+ifdeffery and/or to use stub functions.
+
+For now, suppress the warning by marking both fpsimd_to_sve() and
+sve_to_fpsimd() as 'static inline', as we usually do for stub functions.
+The compiler will no longer warn if either function is unused.
+
+Aside from suppressing the warning, there should be no functional change
+as a result of this patch.
+
+Link: https://lore.kernel.org/linux-arm-kernel/20250429194600.GA26883@willie-the-truck/
+Reported-by: Will Deacon <will@kernel.org>
+Fixes: 929fa99b1215 ("arm64/fpsimd: signal: Always save+flush state early")
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Cc: Marc Zyngier <maz@kernel.org>
+Cc: Mark Brown <broonie@kernel.org>
+Cc: Will Deacon <will@kernel.org>
+Link: https://lore.kernel.org/r/20250430173240.4023627-1-mark.rutland@arm.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/kernel/fpsimd.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
+index 1edf797d2c710..0e649d0e59b06 100644
+--- a/arch/arm64/kernel/fpsimd.c
++++ b/arch/arm64/kernel/fpsimd.c
+@@ -651,7 +651,7 @@ static void __fpsimd_to_sve(void *sst, struct user_fpsimd_state const *fst,
+  * task->thread.uw.fpsimd_state must be up to date before calling this
+  * function.
+  */
+-static void fpsimd_to_sve(struct task_struct *task)
++static inline void fpsimd_to_sve(struct task_struct *task)
+ {
+       unsigned int vq;
+       void *sst = task->thread.sve_state;
+@@ -675,7 +675,7 @@ static void fpsimd_to_sve(struct task_struct *task)
+  * bytes of allocated kernel memory.
+  * task->thread.sve_state must be up to date before calling this function.
+  */
+-static void sve_to_fpsimd(struct task_struct *task)
++static inline void sve_to_fpsimd(struct task_struct *task)
+ {
+       unsigned int vq, vl;
+       void const *sst = task->thread.sve_state;
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-fpsimd-discard-stale-cpu-state-when-handling-s.patch b/queue-6.15/arm64-fpsimd-discard-stale-cpu-state-when-handling-s.patch
new file mode 100644 (file)
index 0000000..ab4115b
--- /dev/null
@@ -0,0 +1,101 @@
+From c3409a00dfed250617f611e2ea1290d3136bd869 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Apr 2025 17:40:02 +0100
+Subject: arm64/fpsimd: Discard stale CPU state when handling SME traps
+
+From: Mark Brown <broonie@kernel.org>
+
+[ Upstream commit d3eaab3c70905c5467e5c4ea403053d67505adeb ]
+
+The logic for handling SME traps manipulates saved FPSIMD/SVE/SME state
+incorrectly, and a race with preemption can result in a task having
+TIF_SME set and TIF_FOREIGN_FPSTATE clear even though the live CPU state
+is stale (e.g. with SME traps enabled). This can result in warnings from
+do_sme_acc() where SME traps are not expected while TIF_SME is set:
+
+|        /* With TIF_SME userspace shouldn't generate any traps */
+|        if (test_and_set_thread_flag(TIF_SME))
+|                WARN_ON(1);
+
+This is very similar to the SVE issue we fixed in commit:
+
+  751ecf6afd6568ad ("arm64/sve: Discard stale CPU state when handling SVE traps")
+
+The race can occur when the SME trap handler is preempted before and
+after manipulating the saved FPSIMD/SVE/SME state, starting and ending on
+the same CPU, e.g.
+
+| void do_sme_acc(unsigned long esr, struct pt_regs *regs)
+| {
+|         // Trap on CPU 0 with TIF_SME clear, SME traps enabled
+|         // task->fpsimd_cpu is 0.
+|         // per_cpu_ptr(&fpsimd_last_state, 0) is task.
+|
+|         ...
+|
+|         // Preempted; migrated from CPU 0 to CPU 1.
+|         // TIF_FOREIGN_FPSTATE is set.
+|
+|         get_cpu_fpsimd_context();
+|
+|         /* With TIF_SME userspace shouldn't generate any traps */
+|         if (test_and_set_thread_flag(TIF_SME))
+|                 WARN_ON(1);
+|
+|         if (!test_thread_flag(TIF_FOREIGN_FPSTATE)) {
+|                 unsigned long vq_minus_one =
+|                         sve_vq_from_vl(task_get_sme_vl(current)) - 1;
+|                 sme_set_vq(vq_minus_one);
+|
+|                 fpsimd_bind_task_to_cpu();
+|         }
+|
+|         put_cpu_fpsimd_context();
+|
+|         // Preempted; migrated from CPU 1 to CPU 0.
+|         // task->fpsimd_cpu is still 0
+|         // If per_cpu_ptr(&fpsimd_last_state, 0) is still task then:
+|         // - Stale HW state is reused (with SME traps enabled)
+|         // - TIF_FOREIGN_FPSTATE is cleared
+|         // - A return to userspace skips HW state restore
+| }
+
+Fix the case where the state is not live and TIF_FOREIGN_FPSTATE is set
+by calling fpsimd_flush_task_state() to detach from the saved CPU
+state. This ensures that a subsequent context switch will not reuse the
+stale CPU state, and will instead set TIF_FOREIGN_FPSTATE, forcing the
+new state to be reloaded from memory prior to a return to userspace.
+
+Note: this was originallly posted as [1].
+
+Fixes: 8bd7f91c03d8 ("arm64/sme: Implement traps and syscall handling for SME")
+Reported-by: Mark Rutland <mark.rutland@arm.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Link: https://lore.kernel.org/linux-arm-kernel/20241204-arm64-sme-reenable-v2-1-bae87728251d@kernel.org/
+[ Rutland: rewrite commit message ]
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Cc: Marc Zyngier <maz@kernel.org>
+Cc: Will Deacon <will@kernel.org>
+Link: https://lore.kernel.org/r/20250409164010.3480271-6-mark.rutland@arm.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/kernel/fpsimd.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
+index 1ee5f330b8ed3..c92c0a08370b2 100644
+--- a/arch/arm64/kernel/fpsimd.c
++++ b/arch/arm64/kernel/fpsimd.c
+@@ -1460,6 +1460,8 @@ void do_sme_acc(unsigned long esr, struct pt_regs *regs)
+               sme_set_vq(vq_minus_one);
+               fpsimd_bind_task_to_cpu();
++      } else {
++              fpsimd_flush_task_state(current);
+       }
+       put_cpu_fpsimd_context();
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-fpsimd-don-t-corrupt-fpmr-when-streaming-mode-.patch b/queue-6.15/arm64-fpsimd-don-t-corrupt-fpmr-when-streaming-mode-.patch
new file mode 100644 (file)
index 0000000..6d76980
--- /dev/null
@@ -0,0 +1,73 @@
+From 89b075bf856edbd1d5f220e7b9a9fc19be502044 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Apr 2025 17:40:03 +0100
+Subject: arm64/fpsimd: Don't corrupt FPMR when streaming mode changes
+
+From: Mark Brown <broonie@kernel.org>
+
+[ Upstream commit e5fa85fce08b21ed41643cb7968bf66bbd0532e3 ]
+
+When the effective value of PSTATE.SM is changed from 0 to 1 or from 1
+to 0 by any method, an entry or exit to/from streaming SVE mode is
+performed, and hardware automatically resets a number of registers. As
+of ARM DDI 0487 L.a, this means:
+
+* All implemented bits of the SVE vector registers are set to zero.
+
+* All implemented bits of the SVE predicate registers are set to zero.
+
+* All implemented bits of FFR are set to zero, if FFR is implemented in
+  the new mode.
+
+* FPSR is set to 0x0000_0000_0800_009f.
+
+* FPMR is set to 0, if FPMR is implemented.
+
+Currently task_fpsimd_load() restores FPMR before restoring SVCR (which
+is an accessor for PSTATE.{SM,ZA}), and so the restored value of FPMR
+may be clobbered if the restored value of PSTATE.SM happens to differ
+from the initial value of PSTATE.SM.
+
+Fix this by moving the restore of FPMR later.
+
+Note: this was originally posted as [1].
+
+Fixes: 203f2b95a882 ("arm64/fpsimd: Support FEAT_FPMR")
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Link: https://lore.kernel.org/linux-arm-kernel/20241204-arm64-sme-reenable-v2-2-bae87728251d@kernel.org/
+[ Rutland: rewrite commit message ]
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Link: https://lore.kernel.org/r/20250409164010.3480271-7-mark.rutland@arm.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/kernel/fpsimd.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
+index c92c0a08370b2..9466b3c5021ac 100644
+--- a/arch/arm64/kernel/fpsimd.c
++++ b/arch/arm64/kernel/fpsimd.c
+@@ -359,9 +359,6 @@ static void task_fpsimd_load(void)
+       WARN_ON(preemptible());
+       WARN_ON(test_thread_flag(TIF_KERNEL_FPSTATE));
+-      if (system_supports_fpmr())
+-              write_sysreg_s(current->thread.uw.fpmr, SYS_FPMR);
+-
+       if (system_supports_sve() || system_supports_sme()) {
+               switch (current->thread.fp_type) {
+               case FP_STATE_FPSIMD:
+@@ -413,6 +410,9 @@ static void task_fpsimd_load(void)
+                       restore_ffr = system_supports_fa64();
+       }
++      if (system_supports_fpmr())
++              write_sysreg_s(current->thread.uw.fpmr, SYS_FPMR);
++
+       if (restore_sve_regs) {
+               WARN_ON_ONCE(current->thread.fp_type != FP_STATE_SVE);
+               sve_load_state(sve_pffr(&current->thread),
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-fpsimd-fix-merging-of-fpsimd-state-during-sign.patch b/queue-6.15/arm64-fpsimd-fix-merging-of-fpsimd-state-during-sign.patch
new file mode 100644 (file)
index 0000000..8f003d8
--- /dev/null
@@ -0,0 +1,105 @@
+From 1a23c5b8ac4d066d1307e8e5b5267304f9ca01ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Apr 2025 17:40:06 +0100
+Subject: arm64/fpsimd: Fix merging of FPSIMD state during signal return
+
+From: Mark Rutland <mark.rutland@arm.com>
+
+[ Upstream commit c94f2f326146a34066a0070ed90b8bc656b1842f ]
+
+For backwards compatibility reasons, when a signal return occurs which
+restores SVE state, the effective lower 128 bits of each of the SVE
+vector registers are restored from the corresponding FPSIMD vector
+register in the FPSIMD signal frame, overriding the values in the SVE
+signal frame. This is intended to be the case regardless of streaming
+mode.
+
+To make this happen, restore_sve_fpsimd_context() uses
+fpsimd_update_current_state() to merge the lower 128 bits from the
+FPSIMD signal frame into the SVE register state. Unfortunately,
+fpsimd_update_current_state() performs this merging dependent upon
+TIF_SVE, which is not always correct for streaming SVE register state:
+
+* When restoring non-streaming SVE register state there is no observable
+  problem, as the signal return code configures TIF_SVE and the saved
+  fp_type to match before calling fpsimd_update_current_state(), which
+  observes either:
+
+  - TIF_SVE set    AND  fp_type == FP_STATE_SVE
+  - TIF_SVE clear  AND  fp_type == FP_STATE_FPSIMD
+
+* On systems which have SME but not SVE, TIF_SVE cannot be set. Thus the
+  merging will never happen for the streaming SVE register state.
+
+* On systems which have SVE and SME, TIF_SVE can be set and cleared
+  independently of PSTATE.SM. Thus the merging may or may not happen for
+  streaming SVE register state.
+
+  As TIF_SVE can be cleared non-deterministically during syscalls
+  (including at the start of sigreturn()), the merging may occur
+  non-deterministically from the perspective of userspace.
+
+This logic has been broken since its introduction in commit:
+
+  85ed24dad2904f7c ("arm64/sme: Implement streaming SVE signal handling")
+
+... at which point both fpsimd_signal_preserve_current_state() and
+fpsimd_update_current_state() only checked TIF SVE. When PSTATE.SM==1
+and TIF_SVE was clear, signal delivery would place stale FPSIMD state
+into the FPSIMD signal frame, and signal return would not merge this
+into the restored register state.
+
+Subsequently, signal delivery was fixed as part of commit:
+
+  61da7c8e2a602f66 ("arm64/signal: Don't assume that TIF_SVE means we saved SVE state")
+
+... but signal restore was not given a corresponding fix, and when
+TIF_SVE was clear, signal restore would still fail to merge the FPSIMD
+state into the restored SVE register state. The 'Fixes' tag did not
+indicate that this had been broken since its introduction.
+
+Fix this by merging the FPSIMD state dependent upon the saved fp_type,
+matching what we (currently) do during signal delivery.
+
+As described above, when backporting this commit, it will also be
+necessary to backport commit:
+
+  61da7c8e2a602f66 ("arm64/signal: Don't assume that TIF_SVE means we saved SVE state")
+
+... and prior to commit:
+
+  baa8515281b30861 ("arm64/fpsimd: Track the saved FPSIMD state type separately to TIF_SVE")
+
+... it will be necessary for fpsimd_signal_preserve_current_state() and
+fpsimd_update_current_state() to consider both TIF_SVE and
+thread_sm_enabled(&current->thread), in place of the saved fp_type.
+
+Fixes: 85ed24dad290 ("arm64/sme: Implement streaming SVE signal handling")
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Cc: Marc Zyngier <maz@kernel.org>
+Cc: Mark Brown <broonie@kernel.org>
+Cc: Will Deacon <will@kernel.org>
+Reviewed-by: Mark Brown <broonie@kernel.org>
+Link: https://lore.kernel.org/r/20250409164010.3480271-10-mark.rutland@arm.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/kernel/fpsimd.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
+index 7ae01f02e18b7..1edf797d2c710 100644
+--- a/arch/arm64/kernel/fpsimd.c
++++ b/arch/arm64/kernel/fpsimd.c
+@@ -1806,7 +1806,7 @@ void fpsimd_update_current_state(struct user_fpsimd_state const *state)
+       get_cpu_fpsimd_context();
+       current->thread.uw.fpsimd_state = *state;
+-      if (test_thread_flag(TIF_SVE))
++      if (current->thread.fp_type == FP_STATE_SVE)
+               fpsimd_to_sve(current);
+       task_fpsimd_load();
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-fpsimd-reset-fpmr-upon-exec.patch b/queue-6.15/arm64-fpsimd-reset-fpmr-upon-exec.patch
new file mode 100644 (file)
index 0000000..02ab60a
--- /dev/null
@@ -0,0 +1,50 @@
+From 81b3fd56cdf79f1d1d88a9b7e813c192bb9e0cc3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Apr 2025 17:40:05 +0100
+Subject: arm64/fpsimd: Reset FPMR upon exec()
+
+From: Mark Rutland <mark.rutland@arm.com>
+
+[ Upstream commit a90878f297d3dba906a6261deccb1bd4a791ba52 ]
+
+An exec() is expected to reset all FPSIMD/SVE/SME state, and barring
+special handling of the vector lengths, the state is expected to reset
+to zero. This reset is handled in fpsimd_flush_thread(), which the core
+exec() code calls via flush_thread().
+
+When support was added for FPMR, no logic was added to
+fpsimd_flush_thread() to reset the FPMR value, and thus it is
+erroneously inherited across an exec().
+
+Add the missing reset of FPMR.
+
+Fixes: 203f2b95a882 ("arm64/fpsimd: Support FEAT_FPMR")
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Cc: Marc Zyngier <maz@kernel.org>
+Cc: Mark Brown <broonie@kernel.org>
+Cc: Will Deacon <will@kernel.org>
+Reviewed-by: Mark Brown <broonie@kernel.org>
+Link: https://lore.kernel.org/r/20250409164010.3480271-9-mark.rutland@arm.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/kernel/fpsimd.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
+index 72ab9649c705b..7ae01f02e18b7 100644
+--- a/arch/arm64/kernel/fpsimd.c
++++ b/arch/arm64/kernel/fpsimd.c
+@@ -1663,6 +1663,9 @@ void fpsimd_flush_thread(void)
+               current->thread.svcr = 0;
+       }
++      if (system_supports_fpmr())
++              current->thread.uw.fpmr = 0;
++
+       current->thread.fp_type = FP_STATE_FPSIMD;
+       put_cpu_fpsimd_context();
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-support-arm64_va_bits-52-when-setting-arch_mma.patch b/queue-6.15/arm64-support-arm64_va_bits-52-when-setting-arch_mma.patch
new file mode 100644 (file)
index 0000000..08ecf28
--- /dev/null
@@ -0,0 +1,56 @@
+From 4c05ed0f4884d2a7f1bd35f915f466efbbd97dab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Apr 2025 11:47:54 +0000
+Subject: arm64: Support ARM64_VA_BITS=52 when setting ARCH_MMAP_RND_BITS_MAX
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Kornel Dulęba <korneld@google.com>
+
+[ Upstream commit f101c56447717c595d803894ba0e215f56c6fba4 ]
+
+When the 52-bit virtual addressing was introduced the select like
+ARCH_MMAP_RND_BITS_MAX logic was never updated to account for it.
+Because of that the rnd max bits knob is set to the default value of 18
+when ARM64_VA_BITS=52.
+Fix this by setting ARCH_MMAP_RND_BITS_MAX to the same value that would
+be used if 48-bit addressing was used. Higher values can't used here
+because 52-bit addressing is used only if the caller provides a hint to
+mmap, with a fallback to 48-bit. The knob in question is an upper bound
+for what the user can set in /proc/sys/vm/mmap_rnd_bits, which in turn
+is used to determine how many random bits can be inserted into the base
+address used for mmap allocations. Since 48-bit allocations are legal
+with ARM64_VA_BITS=52, we need to make sure that the base address is
+small enough to facilitate this.
+
+Fixes: b6d00d47e81a ("arm64: mm: Introduce 52-bit Kernel VAs")
+Signed-off-by: Kornel Dulęba <korneld@google.com>
+Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
+Link: https://lore.kernel.org/r/20250417114754.3238273-1-korneld@google.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/Kconfig | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
+index a182295e6f08b..6527d0d5656a1 100644
+--- a/arch/arm64/Kconfig
++++ b/arch/arm64/Kconfig
+@@ -333,9 +333,9 @@ config ARCH_MMAP_RND_BITS_MAX
+       default 24 if ARM64_VA_BITS=39
+       default 27 if ARM64_VA_BITS=42
+       default 30 if ARM64_VA_BITS=47
+-      default 29 if ARM64_VA_BITS=48 && ARM64_64K_PAGES
+-      default 31 if ARM64_VA_BITS=48 && ARM64_16K_PAGES
+-      default 33 if ARM64_VA_BITS=48
++      default 29 if (ARM64_VA_BITS=48 || ARM64_VA_BITS=52) && ARM64_64K_PAGES
++      default 31 if (ARM64_VA_BITS=48 || ARM64_VA_BITS=52) && ARM64_16K_PAGES
++      default 33 if (ARM64_VA_BITS=48 || ARM64_VA_BITS=52)
+       default 14 if ARM64_64K_PAGES
+       default 16 if ARM64_16K_PAGES
+       default 18
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-tegra-add-uartd-serial-alias-for-jetson-tx1-mo.patch b/queue-6.15/arm64-tegra-add-uartd-serial-alias-for-jetson-tx1-mo.patch
new file mode 100644 (file)
index 0000000..d486a36
--- /dev/null
@@ -0,0 +1,39 @@
+From dfd36b06c992dcb7653d9e430477681f1b7ced19 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 20 Apr 2025 09:35:37 -0500
+Subject: arm64: tegra: Add uartd serial alias for Jetson TX1 module
+
+From: Aaron Kling <webgeek1234@gmail.com>
+
+[ Upstream commit dfb25484bd73c8590954ead6fd58a1587ba3bbc5 ]
+
+If a serial-tegra interface does not have an alias, the driver fails to
+probe with an error:
+serial-tegra 70006300.serial: failed to get alias id, errno -19
+This prevents the bluetooth device from being accessible.
+
+Fixes: 6eba6471bbb7 ("arm64: tegra: Wire up Bluetooth on Jetson TX1 module")
+Signed-off-by: Aaron Kling <webgeek1234@gmail.com>
+Reviewed-by: Tomasz Maciej Nowak <tmn505@gmail.com>
+Link: https://lore.kernel.org/r/20250420-tx1-bt-v1-1-153cba105a4e@gmail.com
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi b/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
+index 9b9d1d15b0c7e..1bb1f9640a800 100644
+--- a/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
+@@ -11,6 +11,7 @@
+               rtc0 = "/i2c@7000d000/pmic@3c";
+               rtc1 = "/rtc@7000e000";
+               serial0 = &uarta;
++              serial3 = &uartd;
+       };
+       chosen {
+-- 
+2.39.5
+
diff --git a/queue-6.15/arm64-tegra-drop-remaining-serial-clock-names-and-re.patch b/queue-6.15/arm64-tegra-drop-remaining-serial-clock-names-and-re.patch
new file mode 100644 (file)
index 0000000..c6d3595
--- /dev/null
@@ -0,0 +1,153 @@
+From e7bcb196a921f02e3d7d847c5a8210a61531a2f4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Apr 2025 20:51:47 -0500
+Subject: arm64: tegra: Drop remaining serial clock-names and reset-names
+
+From: Aaron Kling <webgeek1234@gmail.com>
+
+[ Upstream commit 4cd763297c2203c6ba587d7d4a9105f96597b998 ]
+
+The referenced commit only removed some of the names, missing all that
+weren't in use at the time. The commit removes the rest.
+
+Fixes: 71de0a054d0e ("arm64: tegra: Drop serial clock-names and reset-names")
+Signed-off-by: Aaron Kling <webgeek1234@gmail.com>
+Link: https://lore.kernel.org/r/20250428-tegra-serial-fixes-v1-1-4f47c5d85bf6@gmail.com
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/nvidia/tegra186.dtsi | 12 ------------
+ arch/arm64/boot/dts/nvidia/tegra194.dtsi | 12 ------------
+ 2 files changed, 24 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
+index 2b3bb5d0af17b..f0b7949df92c0 100644
+--- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
+@@ -621,9 +621,7 @@
+               reg-shift = <2>;
+               interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&bpmp TEGRA186_CLK_UARTB>;
+-              clock-names = "serial";
+               resets = <&bpmp TEGRA186_RESET_UARTB>;
+-              reset-names = "serial";
+               status = "disabled";
+       };
+@@ -633,9 +631,7 @@
+               reg-shift = <2>;
+               interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&bpmp TEGRA186_CLK_UARTD>;
+-              clock-names = "serial";
+               resets = <&bpmp TEGRA186_RESET_UARTD>;
+-              reset-names = "serial";
+               status = "disabled";
+       };
+@@ -645,9 +641,7 @@
+               reg-shift = <2>;
+               interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&bpmp TEGRA186_CLK_UARTE>;
+-              clock-names = "serial";
+               resets = <&bpmp TEGRA186_RESET_UARTE>;
+-              reset-names = "serial";
+               status = "disabled";
+       };
+@@ -657,9 +651,7 @@
+               reg-shift = <2>;
+               interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&bpmp TEGRA186_CLK_UARTF>;
+-              clock-names = "serial";
+               resets = <&bpmp TEGRA186_RESET_UARTF>;
+-              reset-names = "serial";
+               status = "disabled";
+       };
+@@ -1236,9 +1228,7 @@
+               reg-shift = <2>;
+               interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&bpmp TEGRA186_CLK_UARTC>;
+-              clock-names = "serial";
+               resets = <&bpmp TEGRA186_RESET_UARTC>;
+-              reset-names = "serial";
+               status = "disabled";
+       };
+@@ -1248,9 +1238,7 @@
+               reg-shift = <2>;
+               interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&bpmp TEGRA186_CLK_UARTG>;
+-              clock-names = "serial";
+               resets = <&bpmp TEGRA186_RESET_UARTG>;
+-              reset-names = "serial";
+               status = "disabled";
+       };
+diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
+index 33f92b77cd9d9..c369507747851 100644
+--- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
+@@ -766,9 +766,7 @@
+                       reg-shift = <2>;
+                       interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&bpmp TEGRA194_CLK_UARTD>;
+-                      clock-names = "serial";
+                       resets = <&bpmp TEGRA194_RESET_UARTD>;
+-                      reset-names = "serial";
+                       status = "disabled";
+               };
+@@ -778,9 +776,7 @@
+                       reg-shift = <2>;
+                       interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&bpmp TEGRA194_CLK_UARTE>;
+-                      clock-names = "serial";
+                       resets = <&bpmp TEGRA194_RESET_UARTE>;
+-                      reset-names = "serial";
+                       status = "disabled";
+               };
+@@ -790,9 +786,7 @@
+                       reg-shift = <2>;
+                       interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&bpmp TEGRA194_CLK_UARTF>;
+-                      clock-names = "serial";
+                       resets = <&bpmp TEGRA194_RESET_UARTF>;
+-                      reset-names = "serial";
+                       status = "disabled";
+               };
+@@ -817,9 +811,7 @@
+                       reg-shift = <2>;
+                       interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&bpmp TEGRA194_CLK_UARTH>;
+-                      clock-names = "serial";
+                       resets = <&bpmp TEGRA194_RESET_UARTH>;
+-                      reset-names = "serial";
+                       status = "disabled";
+               };
+@@ -1616,9 +1608,7 @@
+                       reg-shift = <2>;
+                       interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&bpmp TEGRA194_CLK_UARTC>;
+-                      clock-names = "serial";
+                       resets = <&bpmp TEGRA194_RESET_UARTC>;
+-                      reset-names = "serial";
+                       status = "disabled";
+               };
+@@ -1628,9 +1618,7 @@
+                       reg-shift = <2>;
+                       interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&bpmp TEGRA194_CLK_UARTG>;
+-                      clock-names = "serial";
+                       resets = <&bpmp TEGRA194_RESET_UARTG>;
+-                      reset-names = "serial";
+                       status = "disabled";
+               };
+-- 
+2.39.5
+
diff --git a/queue-6.15/asoc-apple-mca-constrain-channels-according-to-tdm-m.patch b/queue-6.15/asoc-apple-mca-constrain-channels-according-to-tdm-m.patch
new file mode 100644 (file)
index 0000000..0d47fe2
--- /dev/null
@@ -0,0 +1,70 @@
+From cf415b1cfdaf416f109c3befea02079bb51aeb48 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 May 2025 20:50:46 +1000
+Subject: ASoC: apple: mca: Constrain channels according to TDM mask
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Martin Povišer <povik+lin@cutebit.org>
+
+[ Upstream commit e717c661e2d1a660e96c40b0fe9933e23a1d7747 ]
+
+We don't (and can't) configure the hardware correctly if the number of
+channels exceeds the weight of the TDM mask. Report that constraint in
+startup of FE.
+
+Fixes: 3df5d0d97289 ("ASoC: apple: mca: Start new platform driver")
+Signed-off-by: Martin Povišer <povik+lin@cutebit.org>
+Signed-off-by: James Calligeros <jcalligeros99@gmail.com>
+Link: https://patch.msgid.link/20250518-mca-fixes-v1-1-ee1015a695f6@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/apple/mca.c | 23 +++++++++++++++++++++++
+ 1 file changed, 23 insertions(+)
+
+diff --git a/sound/soc/apple/mca.c b/sound/soc/apple/mca.c
+index b4f4696809dd2..5dd24ab90d0f0 100644
+--- a/sound/soc/apple/mca.c
++++ b/sound/soc/apple/mca.c
+@@ -464,6 +464,28 @@ static int mca_configure_serdes(struct mca_cluster *cl, int serdes_unit,
+       return -EINVAL;
+ }
++static int mca_fe_startup(struct snd_pcm_substream *substream,
++                        struct snd_soc_dai *dai)
++{
++      struct mca_cluster *cl = mca_dai_to_cluster(dai);
++      unsigned int mask, nchannels;
++
++      if (cl->tdm_slots) {
++              if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
++                      mask = cl->tdm_tx_mask;
++              else
++                      mask = cl->tdm_rx_mask;
++
++              nchannels = hweight32(mask);
++      } else {
++              nchannels = 2;
++      }
++
++      return snd_pcm_hw_constraint_minmax(substream->runtime,
++                                          SNDRV_PCM_HW_PARAM_CHANNELS,
++                                          1, nchannels);
++}
++
+ static int mca_fe_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+                              unsigned int rx_mask, int slots, int slot_width)
+ {
+@@ -680,6 +702,7 @@ static int mca_fe_hw_params(struct snd_pcm_substream *substream,
+ }
+ static const struct snd_soc_dai_ops mca_fe_ops = {
++      .startup = mca_fe_startup,
+       .set_fmt = mca_fe_set_fmt,
+       .set_bclk_ratio = mca_set_bclk_ratio,
+       .set_tdm_slot = mca_fe_set_tdm_slot,
+-- 
+2.39.5
+
diff --git a/queue-6.15/asoc-codecs-hda-fix-rpm-usage-count-underflow.patch b/queue-6.15/asoc-codecs-hda-fix-rpm-usage-count-underflow.patch
new file mode 100644 (file)
index 0000000..5778bb8
--- /dev/null
@@ -0,0 +1,60 @@
+From 400ced6c6a13976ba644784096c8273d150b6078 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 May 2025 16:10:17 +0200
+Subject: ASoC: codecs: hda: Fix RPM usage count underflow
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cezary Rojewski <cezary.rojewski@intel.com>
+
+[ Upstream commit ff0045de4ee0288dec683690f66f2f369b7d3466 ]
+
+RPM manipulation in hda_codec_probe_complete()'s error path is
+superfluous and leads to RPM usage count underflow if the
+build-controls operation fails.
+
+hda_codec_probe_complete() is called in:
+
+1) hda_codec_probe() for all non-HDMI codecs
+2) in card->late_probe() for HDMI codecs
+
+Error path for hda_codec_probe() takes care of bus' RPM already.
+For 2) if late_probe() fails, ASoC performs card cleanup what
+triggers hda_codec_remote() - same treatment is in 1).
+
+Fixes: b5df2a7dca1c ("ASoC: codecs: Add HD-Audio codec driver")
+Reviewed-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
+Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
+Link: https://patch.msgid.link/20250530141025.2942936-2-cezary.rojewski@intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/hda.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/codecs/hda.c b/sound/soc/codecs/hda.c
+index ddc00927313cf..dc7794c9ac44c 100644
+--- a/sound/soc/codecs/hda.c
++++ b/sound/soc/codecs/hda.c
+@@ -152,7 +152,7 @@ int hda_codec_probe_complete(struct hda_codec *codec)
+       ret = snd_hda_codec_build_controls(codec);
+       if (ret < 0) {
+               dev_err(&hdev->dev, "unable to create controls %d\n", ret);
+-              goto out;
++              return ret;
+       }
+       /* Bus suspended codecs as it does not manage their pm */
+@@ -160,7 +160,7 @@ int hda_codec_probe_complete(struct hda_codec *codec)
+       /* rpm was forbidden in snd_hda_codec_device_new() */
+       snd_hda_codec_set_power_save(codec, 2000);
+       snd_hda_codec_register(codec);
+-out:
++
+       /* Complement pm_runtime_get_sync(bus) in probe */
+       pm_runtime_mark_last_busy(bus->dev);
+       pm_runtime_put_autosuspend(bus->dev);
+-- 
+2.39.5
+
diff --git a/queue-6.15/asoc-intel-avs-fix-deadlock-when-the-failing-ipc-is-.patch b/queue-6.15/asoc-intel-avs-fix-deadlock-when-the-failing-ipc-is-.patch
new file mode 100644 (file)
index 0000000..a05fd5e
--- /dev/null
@@ -0,0 +1,45 @@
+From f8bd412db306d9cac36a7ef0fce1b175b3a8c397 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 May 2025 16:10:18 +0200
+Subject: ASoC: Intel: avs: Fix deadlock when the failing IPC is SET_D0IX
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cezary Rojewski <cezary.rojewski@intel.com>
+
+[ Upstream commit 9ad1f3cd0d60444c69948854c7e50d2a61b63755 ]
+
+The procedure handling IPC timeouts and EXCEPTION_CAUGHT notification
+shall cancel any D0IX work before proceeding with DSP recovery. If
+SET_D0IX called from delayed_work is the failing IPC the procedure will
+deadlock. Conditionally skip cancelling the work to fix that.
+
+Fixes: 335c4cbd201d ("ASoC: Intel: avs: D0ix power state support")
+Reviewed-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
+Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
+Link: https://patch.msgid.link/20250530141025.2942936-3-cezary.rojewski@intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/avs/ipc.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/intel/avs/ipc.c b/sound/soc/intel/avs/ipc.c
+index 08ed9d96738a0..0314f9d4ea5f4 100644
+--- a/sound/soc/intel/avs/ipc.c
++++ b/sound/soc/intel/avs/ipc.c
+@@ -169,7 +169,9 @@ static void avs_dsp_exception_caught(struct avs_dev *adev, union avs_notify_msg
+       dev_crit(adev->dev, "communication severed, rebooting dsp..\n");
+-      cancel_delayed_work_sync(&ipc->d0ix_work);
++      /* Avoid deadlock as the exception may be the response to SET_D0IX. */
++      if (current_work() != &ipc->d0ix_work.work)
++              cancel_delayed_work_sync(&ipc->d0ix_work);
+       ipc->in_d0ix = false;
+       /* Re-enabled on recovery completion. */
+       pm_runtime_disable(adev->dev);
+-- 
+2.39.5
+
diff --git a/queue-6.15/asoc-intel-avs-fix-kcalloc-sizes.patch b/queue-6.15/asoc-intel-avs-fix-kcalloc-sizes.patch
new file mode 100644 (file)
index 0000000..9b10e72
--- /dev/null
@@ -0,0 +1,46 @@
+From 206575d8f5d57dd359fe9adf5f664957126924a0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 26 Apr 2025 16:13:41 +0200
+Subject: ASoC: Intel: avs: Fix kcalloc() sizes
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Thorsten Blum <thorsten.blum@linux.dev>
+
+[ Upstream commit d20df86b056b95845f6ed52da1010059202a0c23 ]
+
+rlist, clist, and slist are allocated using sizeof(pointer) instead of
+sizeof(*pointer). Fix the allocations by using sizeof(*pointer) and
+avoid overallocating memory on 64-bit systems.
+
+Fixes: f2f847461fb7 ("ASoC: Intel: avs: Constrain path based on BE capabilities")
+Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
+Reviewed-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
+Link: https://patch.msgid.link/20250426141342.94134-2-thorsten.blum@linux.dev
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/avs/path.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/sound/soc/intel/avs/path.c b/sound/soc/intel/avs/path.c
+index cafb8c6198bed..8f1bf8d0af8f9 100644
+--- a/sound/soc/intel/avs/path.c
++++ b/sound/soc/intel/avs/path.c
+@@ -131,9 +131,9 @@ int avs_path_set_constraint(struct avs_dev *adev, struct avs_tplg_path_template
+       list_for_each_entry(path_template, &template->path_list, node)
+               i++;
+-      rlist = kcalloc(i, sizeof(rlist), GFP_KERNEL);
+-      clist = kcalloc(i, sizeof(clist), GFP_KERNEL);
+-      slist = kcalloc(i, sizeof(slist), GFP_KERNEL);
++      rlist = kcalloc(i, sizeof(*rlist), GFP_KERNEL);
++      clist = kcalloc(i, sizeof(*clist), GFP_KERNEL);
++      slist = kcalloc(i, sizeof(*slist), GFP_KERNEL);
+       i = 0;
+       list_for_each_entry(path_template, &template->path_list, node) {
+-- 
+2.39.5
+
diff --git a/queue-6.15/asoc-intel-avs-fix-paths-in-module_firmware-hints.patch b/queue-6.15/asoc-intel-avs-fix-paths-in-module_firmware-hints.patch
new file mode 100644 (file)
index 0000000..ec1dd0d
--- /dev/null
@@ -0,0 +1,57 @@
+From 0b77956f02a1d03c243e94bd593f0336cedddc26 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 May 2025 16:10:21 +0200
+Subject: ASoC: Intel: avs: Fix paths in MODULE_FIRMWARE hints
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
+
+[ Upstream commit 9e3285be55e6c0829e451b4a341e3059da47ec9d ]
+
+The binaries for cAVS architecture are located in "intel/avs"
+subdirectory, not "intel".
+
+Fixes: 94aa347d34e0 ("ASoC: Intel: avs: Add MODULE_FIRMWARE to inform about FW")
+Reviewed-by: Cezary Rojewski <cezary.rojewski@intel.com>
+Signed-off-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
+Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
+Link: https://patch.msgid.link/20250530141025.2942936-6-cezary.rojewski@intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/avs/core.c | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c
+index 1495e163d47ef..cbbc656fcc3f8 100644
+--- a/sound/soc/intel/avs/core.c
++++ b/sound/soc/intel/avs/core.c
+@@ -921,13 +921,13 @@ MODULE_AUTHOR("Cezary Rojewski <cezary.rojewski@intel.com>");
+ MODULE_AUTHOR("Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>");
+ MODULE_DESCRIPTION("Intel cAVS sound driver");
+ MODULE_LICENSE("GPL");
+-MODULE_FIRMWARE("intel/skl/dsp_basefw.bin");
+-MODULE_FIRMWARE("intel/apl/dsp_basefw.bin");
+-MODULE_FIRMWARE("intel/cnl/dsp_basefw.bin");
+-MODULE_FIRMWARE("intel/icl/dsp_basefw.bin");
+-MODULE_FIRMWARE("intel/jsl/dsp_basefw.bin");
+-MODULE_FIRMWARE("intel/lkf/dsp_basefw.bin");
+-MODULE_FIRMWARE("intel/tgl/dsp_basefw.bin");
+-MODULE_FIRMWARE("intel/ehl/dsp_basefw.bin");
+-MODULE_FIRMWARE("intel/adl/dsp_basefw.bin");
+-MODULE_FIRMWARE("intel/adl_n/dsp_basefw.bin");
++MODULE_FIRMWARE("intel/avs/skl/dsp_basefw.bin");
++MODULE_FIRMWARE("intel/avs/apl/dsp_basefw.bin");
++MODULE_FIRMWARE("intel/avs/cnl/dsp_basefw.bin");
++MODULE_FIRMWARE("intel/avs/icl/dsp_basefw.bin");
++MODULE_FIRMWARE("intel/avs/jsl/dsp_basefw.bin");
++MODULE_FIRMWARE("intel/avs/lkf/dsp_basefw.bin");
++MODULE_FIRMWARE("intel/avs/tgl/dsp_basefw.bin");
++MODULE_FIRMWARE("intel/avs/ehl/dsp_basefw.bin");
++MODULE_FIRMWARE("intel/avs/adl/dsp_basefw.bin");
++MODULE_FIRMWARE("intel/avs/adl_n/dsp_basefw.bin");
+-- 
+2.39.5
+
diff --git a/queue-6.15/asoc-intel-avs-fix-possible-null-ptr-deref-when-init.patch b/queue-6.15/asoc-intel-avs-fix-possible-null-ptr-deref-when-init.patch
new file mode 100644 (file)
index 0000000..32c571e
--- /dev/null
@@ -0,0 +1,54 @@
+From 60e2f5118abe69243e7fb28660f6a0f23c8d8545 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 May 2025 16:10:20 +0200
+Subject: ASoC: Intel: avs: Fix possible null-ptr-deref when initing hw
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cezary Rojewski <cezary.rojewski@intel.com>
+
+[ Upstream commit 2f78724d4f0c665c83e202e3989d5333a2cb1036 ]
+
+Search result of avs_dai_find_path_template() shall be verified before
+being used. As 'template' is already known when
+avs_hw_constraints_init() is fired, drop the search entirely.
+
+Fixes: f2f847461fb7 ("ASoC: Intel: avs: Constrain path based on BE capabilities")
+Reviewed-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
+Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
+Link: https://patch.msgid.link/20250530141025.2942936-5-cezary.rojewski@intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/avs/pcm.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c
+index fc51fa1fd40d2..5a2330e4e4225 100644
+--- a/sound/soc/intel/avs/pcm.c
++++ b/sound/soc/intel/avs/pcm.c
+@@ -82,10 +82,8 @@ void avs_period_elapsed(struct snd_pcm_substream *substream)
+ static int hw_rule_param_size(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule);
+ static int avs_hw_constraints_init(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
+ {
+-      struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct snd_pcm_hw_constraint_list *r, *c, *s;
+-      struct avs_tplg_path_template *template;
+       struct avs_dma_data *data;
+       int ret;
+@@ -98,8 +96,7 @@ static int avs_hw_constraints_init(struct snd_pcm_substream *substream, struct s
+       c = &(data->channels_list);
+       s = &(data->sample_bits_list);
+-      template = avs_dai_find_path_template(dai, !rtd->dai_link->no_pcm, substream->stream);
+-      ret = avs_path_set_constraint(data->adev, template, r, c, s);
++      ret = avs_path_set_constraint(data->adev, data->template, r, c, s);
+       if (ret <= 0)
+               return ret;
+-- 
+2.39.5
+
diff --git a/queue-6.15/asoc-intel-avs-fix-pplcxfmt-calculation.patch b/queue-6.15/asoc-intel-avs-fix-pplcxfmt-calculation.patch
new file mode 100644 (file)
index 0000000..1bea952
--- /dev/null
@@ -0,0 +1,68 @@
+From 5d2352af273a08a29c3b72f7309ca5b6a2594993 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 May 2025 16:10:19 +0200
+Subject: ASoC: Intel: avs: Fix PPLCxFMT calculation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cezary Rojewski <cezary.rojewski@intel.com>
+
+[ Upstream commit 347c8d6db7c9d65d93ef226849b273823f54eaea ]
+
+HDAudio transfer types utilize SDxFMT for front-end (HOST) and PPLCxFMT
+for back-end (LINK) side when setting up the stream. BE's
+substream->runtime duplicates FE runtime so switch to using BE's
+hw_params to address incorrect format values on the LINK side when FE
+and BE formats differ.
+
+The problem is introduced with commit d070002a20fc ("ASoC: Intel: avs:
+HDA PCM BE operations") but the code has been shuffled around since then
+so direct 'Fixes:' tag does not apply.
+
+Reviewed-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
+Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
+Link: https://patch.msgid.link/20250530141025.2942936-4-cezary.rojewski@intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/avs/pcm.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c
+index 6116465c8f9b1..fc51fa1fd40d2 100644
+--- a/sound/soc/intel/avs/pcm.c
++++ b/sound/soc/intel/avs/pcm.c
+@@ -449,9 +449,10 @@ static int avs_dai_hda_be_hw_free(struct snd_pcm_substream *substream, struct sn
+ static int avs_dai_hda_be_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
+ {
+-      struct snd_pcm_runtime *runtime = substream->runtime;
++      struct snd_soc_pcm_runtime *be = snd_soc_substream_to_rtd(substream);
+       const struct snd_soc_pcm_stream *stream_info;
+       struct hdac_ext_stream *link_stream;
++      const struct snd_pcm_hw_params *p;
+       struct avs_dma_data *data;
+       unsigned int format_val;
+       unsigned int bits;
+@@ -459,14 +460,15 @@ static int avs_dai_hda_be_prepare(struct snd_pcm_substream *substream, struct sn
+       data = snd_soc_dai_get_dma_data(dai, substream);
+       link_stream = data->link_stream;
++      p = &be->dpcm[substream->stream].hw_params;
+       if (link_stream->link_prepared)
+               return 0;
+       stream_info = snd_soc_dai_get_pcm_stream(dai, substream->stream);
+-      bits = snd_hdac_stream_format_bits(runtime->format, runtime->subformat,
++      bits = snd_hdac_stream_format_bits(params_format(p), params_subformat(p),
+                                          stream_info->sig_bits);
+-      format_val = snd_hdac_stream_format(runtime->channels, bits, runtime->rate);
++      format_val = snd_hdac_stream_format(params_channels(p), bits, params_rate(p));
+       snd_hdac_ext_stream_decouple(&data->adev->base.core, link_stream, true);
+       snd_hdac_ext_stream_reset(link_stream);
+-- 
+2.39.5
+
diff --git a/queue-6.15/asoc-intel-avs-ignore-vendor-space-manipulation-for-.patch b/queue-6.15/asoc-intel-avs-ignore-vendor-space-manipulation-for-.patch
new file mode 100644 (file)
index 0000000..4beb9ea
--- /dev/null
@@ -0,0 +1,95 @@
+From 56ccaea08d0d6407940e25ac89064e82f3bb9984 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Apr 2025 13:23:44 +0200
+Subject: ASoC: Intel: avs: Ignore Vendor-space manipulation for ACE
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cezary Rojewski <cezary.rojewski@intel.com>
+
+[ Upstream commit acd2563f30886730757062b9b3efe8043daabbc3 ]
+
+A number of Vendor Specific registers utilized on cAVS architecture
+(SkyLake till RaptorLake) are not present on ACE hardware (MeteorLake
+onward). Similarly, certain recommended procedures do not apply. Adjust
+existing code to be ACE-friendly.
+
+Reviewed-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
+Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
+Acked-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
+Link: https://patch.msgid.link/20250407112352.3720779-3-cezary.rojewski@intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 9e3285be55e6 ("ASoC: Intel: avs: Fix paths in MODULE_FIRMWARE hints")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/avs/avs.h  |  1 +
+ sound/soc/intel/avs/core.c | 13 ++++++++++---
+ 2 files changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/sound/soc/intel/avs/avs.h b/sound/soc/intel/avs/avs.h
+index 585543f872fcc..91872d1df97a5 100644
+--- a/sound/soc/intel/avs/avs.h
++++ b/sound/soc/intel/avs/avs.h
+@@ -72,6 +72,7 @@ extern const struct avs_dsp_ops avs_tgl_dsp_ops;
+ #define AVS_PLATATTR_CLDMA            BIT_ULL(0)
+ #define AVS_PLATATTR_IMR              BIT_ULL(1)
++#define AVS_PLATATTR_ACE              BIT_ULL(2)
+ #define avs_platattr_test(adev, attr) \
+       ((adev)->spec->attributes & AVS_PLATATTR_##attr)
+diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c
+index 8fbf33e30dfc3..72a14dca1a1ed 100644
+--- a/sound/soc/intel/avs/core.c
++++ b/sound/soc/intel/avs/core.c
+@@ -54,14 +54,17 @@ void avs_hda_power_gating_enable(struct avs_dev *adev, bool enable)
+ {
+       u32 value = enable ? 0 : pgctl_mask;
+-      avs_hda_update_config_dword(&adev->base.core, AZX_PCIREG_PGCTL, pgctl_mask, value);
++      if (!avs_platattr_test(adev, ACE))
++              avs_hda_update_config_dword(&adev->base.core, AZX_PCIREG_PGCTL, pgctl_mask, value);
+ }
+ static void avs_hdac_clock_gating_enable(struct hdac_bus *bus, bool enable)
+ {
++      struct avs_dev *adev = hdac_to_avs(bus);
+       u32 value = enable ? cgctl_mask : 0;
+-      avs_hda_update_config_dword(bus, AZX_PCIREG_CGCTL, cgctl_mask, value);
++      if (!avs_platattr_test(adev, ACE))
++              avs_hda_update_config_dword(bus, AZX_PCIREG_CGCTL, cgctl_mask, value);
+ }
+ void avs_hda_clock_gating_enable(struct avs_dev *adev, bool enable)
+@@ -71,6 +74,8 @@ void avs_hda_clock_gating_enable(struct avs_dev *adev, bool enable)
+ void avs_hda_l1sen_enable(struct avs_dev *adev, bool enable)
+ {
++      if (avs_platattr_test(adev, ACE))
++              return;
+       if (enable) {
+               if (atomic_inc_and_test(&adev->l1sen_counter))
+                       snd_hdac_chip_updatel(&adev->base.core, VS_EM2, AZX_VS_EM2_L1SEN,
+@@ -99,6 +104,7 @@ static int avs_hdac_bus_init_streams(struct hdac_bus *bus)
+ static bool avs_hdac_bus_init_chip(struct hdac_bus *bus, bool full_reset)
+ {
++      struct avs_dev *adev = hdac_to_avs(bus);
+       struct hdac_ext_link *hlink;
+       bool ret;
+@@ -114,7 +120,8 @@ static bool avs_hdac_bus_init_chip(struct hdac_bus *bus, bool full_reset)
+       /* Set DUM bit to address incorrect position reporting for capture
+        * streams. In order to do so, CTRL needs to be out of reset state
+        */
+-      snd_hdac_chip_updatel(bus, VS_EM2, AZX_VS_EM2_DUM, AZX_VS_EM2_DUM);
++      if (!avs_platattr_test(adev, ACE))
++              snd_hdac_chip_updatel(bus, VS_EM2, AZX_VS_EM2_DUM, AZX_VS_EM2_DUM);
+       return ret;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/asoc-intel-avs-pcm-operations-for-lnl-based-platform.patch b/queue-6.15/asoc-intel-avs-pcm-operations-for-lnl-based-platform.patch
new file mode 100644 (file)
index 0000000..0e07cdb
--- /dev/null
@@ -0,0 +1,253 @@
+From f19f1d049ff546111433b6a62d41a2edff483b00 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Apr 2025 13:23:48 +0200
+Subject: ASoC: Intel: avs: PCM operations for LNL-based platforms
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cezary Rojewski <cezary.rojewski@intel.com>
+
+[ Upstream commit 716643786f140f2d68f22424c75b9198ffe14290 ]
+
+Starting from LNL platform the so-called non-HDAudio transfer types,
+e.g.: I2S/DMIC, utilize HDAudio LINK DMA rather than GPDMA for the data
+streaming. In essence, all transfer types now utilize HDAudio Link. Most
+of the existing code can be reused with the major difference being
+HDAudio Link query method:
+
+- fetch the Link by codec.addr in standard HDAudio transfer case
+- fetch the Link by LEPTR.ID in non-HDAudio transfer case
+
+To make the unification happen, store pointer to the Link in dma_data
+and utilize it in the common code. And to avoid confusion in
+transfer-type naming between cAVS-ACE 1.x (SkyLake till MeteorLake) and
+ACE 2.0+ architecture (LunarLake onward), use:
+
+- 'hda' for typical HDAudio transfer case
+- 'nonhda' for non-HDAudio transfer case, cAVS-ACE 1.x
+- 'althda' for non-HDAudio transfer case, ACE 2.0+
+
+Reviewed-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
+Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
+Acked-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
+Link: https://patch.msgid.link/20250407112352.3720779-7-cezary.rojewski@intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 347c8d6db7c9 ("ASoC: Intel: avs: Fix PPLCxFMT calculation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/avs/pcm.c | 116 ++++++++++++++++++++++++++++----------
+ 1 file changed, 85 insertions(+), 31 deletions(-)
+
+diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c
+index d83ef504643bb..6116465c8f9b1 100644
+--- a/sound/soc/intel/avs/pcm.c
++++ b/sound/soc/intel/avs/pcm.c
+@@ -36,6 +36,7 @@ struct avs_dma_data {
+       struct snd_pcm_hw_constraint_list sample_bits_list;
+       struct work_struct period_elapsed_work;
++      struct hdac_ext_link *link;
+       struct snd_pcm_substream *substream;
+ };
+@@ -325,32 +326,75 @@ static const struct snd_soc_dai_ops avs_dai_nonhda_be_ops = {
+       .trigger = avs_dai_nonhda_be_trigger,
+ };
+-static int avs_dai_hda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
++static int __avs_dai_hda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai,
++                                  struct hdac_ext_link *link)
+ {
+-      struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
+       struct hdac_ext_stream *link_stream;
+       struct avs_dma_data *data;
+-      struct hda_codec *codec;
+       int ret;
+       ret = avs_dai_startup(substream, dai);
+       if (ret)
+               return ret;
+-      codec = dev_to_hda_codec(snd_soc_rtd_to_codec(rtd, 0)->dev);
+-      link_stream = snd_hdac_ext_stream_assign(&codec->bus->core, substream,
++      data = snd_soc_dai_get_dma_data(dai, substream);
++      link_stream = snd_hdac_ext_stream_assign(&data->adev->base.core, substream,
+                                                HDAC_EXT_STREAM_TYPE_LINK);
+       if (!link_stream) {
+               avs_dai_shutdown(substream, dai);
+               return -EBUSY;
+       }
+-      data = snd_soc_dai_get_dma_data(dai, substream);
+       data->link_stream = link_stream;
+-      substream->runtime->private_data = link_stream;
++      data->link = link;
+       return 0;
+ }
++static int avs_dai_hda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
++{
++      struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
++      struct hdac_ext_link *link;
++      struct avs_dma_data *data;
++      struct hda_codec *codec;
++      int ret;
++
++      codec = dev_to_hda_codec(snd_soc_rtd_to_codec(rtd, 0)->dev);
++
++      link = snd_hdac_ext_bus_get_hlink_by_addr(&codec->bus->core, codec->core.addr);
++      if (!link)
++              return -EINVAL;
++
++      ret = __avs_dai_hda_be_startup(substream, dai, link);
++      if (!ret) {
++              data = snd_soc_dai_get_dma_data(dai, substream);
++              substream->runtime->private_data = data->link_stream;
++      }
++
++      return ret;
++}
++
++static int avs_dai_i2shda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
++{
++      struct avs_dev *adev = to_avs_dev(dai->component->dev);
++      struct hdac_ext_link *link;
++
++      link = snd_hdac_ext_bus_get_hlink_by_id(&adev->base.core, AZX_REG_ML_LEPTR_ID_INTEL_SSP);
++      if (!link)
++              return -EINVAL;
++      return __avs_dai_hda_be_startup(substream, dai, link);
++}
++
++static int avs_dai_dmichda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
++{
++      struct avs_dev *adev = to_avs_dev(dai->component->dev);
++      struct hdac_ext_link *link;
++
++      link = snd_hdac_ext_bus_get_hlink_by_id(&adev->base.core, AZX_REG_ML_LEPTR_ID_INTEL_DMIC);
++      if (!link)
++              return -EINVAL;
++      return __avs_dai_hda_be_startup(substream, dai, link);
++}
++
+ static void avs_dai_hda_be_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
+ {
+       struct avs_dma_data *data = snd_soc_dai_get_dma_data(dai, substream);
+@@ -360,6 +404,14 @@ static void avs_dai_hda_be_shutdown(struct snd_pcm_substream *substream, struct
+       avs_dai_shutdown(substream, dai);
+ }
++static void avs_dai_althda_be_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
++{
++      struct avs_dma_data *data = snd_soc_dai_get_dma_data(dai, substream);
++
++      snd_hdac_ext_stream_release(data->link_stream, HDAC_EXT_STREAM_TYPE_LINK);
++      avs_dai_shutdown(substream, dai);
++}
++
+ static int avs_dai_hda_be_hw_params(struct snd_pcm_substream *substream,
+                                   struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
+ {
+@@ -375,13 +427,8 @@ static int avs_dai_hda_be_hw_params(struct snd_pcm_substream *substream,
+ static int avs_dai_hda_be_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
+ {
+-      struct avs_dma_data *data;
+-      struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
+       struct hdac_ext_stream *link_stream;
+-      struct hdac_ext_link *link;
+-      struct hda_codec *codec;
+-
+-      dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
++      struct avs_dma_data *data;
+       data = snd_soc_dai_get_dma_data(dai, substream);
+       if (!data->path)
+@@ -393,27 +440,19 @@ static int avs_dai_hda_be_hw_free(struct snd_pcm_substream *substream, struct sn
+       data->path = NULL;
+       /* clear link <-> stream mapping */
+-      codec = dev_to_hda_codec(snd_soc_rtd_to_codec(rtd, 0)->dev);
+-      link = snd_hdac_ext_bus_get_hlink_by_addr(&codec->bus->core, codec->core.addr);
+-      if (!link)
+-              return -EINVAL;
+-
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+-              snd_hdac_ext_bus_link_clear_stream_id(link, hdac_stream(link_stream)->stream_tag);
++              snd_hdac_ext_bus_link_clear_stream_id(data->link,
++                                                    hdac_stream(link_stream)->stream_tag);
+       return 0;
+ }
+ static int avs_dai_hda_be_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
+ {
+-      struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       const struct snd_soc_pcm_stream *stream_info;
+       struct hdac_ext_stream *link_stream;
+-      struct hdac_ext_link *link;
+       struct avs_dma_data *data;
+-      struct hda_codec *codec;
+-      struct hdac_bus *bus;
+       unsigned int format_val;
+       unsigned int bits;
+       int ret;
+@@ -424,23 +463,18 @@ static int avs_dai_hda_be_prepare(struct snd_pcm_substream *substream, struct sn
+       if (link_stream->link_prepared)
+               return 0;
+-      codec = dev_to_hda_codec(snd_soc_rtd_to_codec(rtd, 0)->dev);
+-      bus = &codec->bus->core;
+       stream_info = snd_soc_dai_get_pcm_stream(dai, substream->stream);
+       bits = snd_hdac_stream_format_bits(runtime->format, runtime->subformat,
+                                          stream_info->sig_bits);
+       format_val = snd_hdac_stream_format(runtime->channels, bits, runtime->rate);
+-      snd_hdac_ext_stream_decouple(bus, link_stream, true);
++      snd_hdac_ext_stream_decouple(&data->adev->base.core, link_stream, true);
+       snd_hdac_ext_stream_reset(link_stream);
+       snd_hdac_ext_stream_setup(link_stream, format_val);
+-      link = snd_hdac_ext_bus_get_hlink_by_addr(bus, codec->core.addr);
+-      if (!link)
+-              return -EINVAL;
+-
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+-              snd_hdac_ext_bus_link_set_stream_id(link, hdac_stream(link_stream)->stream_tag);
++              snd_hdac_ext_bus_link_set_stream_id(data->link,
++                                                  hdac_stream(link_stream)->stream_tag);
+       ret = avs_dai_prepare(substream, dai);
+       if (ret)
+@@ -515,6 +549,26 @@ static const struct snd_soc_dai_ops avs_dai_hda_be_ops = {
+       .trigger = avs_dai_hda_be_trigger,
+ };
++__maybe_unused
++static const struct snd_soc_dai_ops avs_dai_i2shda_be_ops = {
++      .startup = avs_dai_i2shda_be_startup,
++      .shutdown = avs_dai_althda_be_shutdown,
++      .hw_params = avs_dai_hda_be_hw_params,
++      .hw_free = avs_dai_hda_be_hw_free,
++      .prepare = avs_dai_hda_be_prepare,
++      .trigger = avs_dai_hda_be_trigger,
++};
++
++__maybe_unused
++static const struct snd_soc_dai_ops avs_dai_dmichda_be_ops = {
++      .startup = avs_dai_dmichda_be_startup,
++      .shutdown = avs_dai_althda_be_shutdown,
++      .hw_params = avs_dai_hda_be_hw_params,
++      .hw_free = avs_dai_hda_be_hw_free,
++      .prepare = avs_dai_hda_be_prepare,
++      .trigger = avs_dai_hda_be_trigger,
++};
++
+ static int hw_rule_param_size(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule)
+ {
+       struct snd_interval *interval = hw_param_interval(params, rule->var);
+-- 
+2.39.5
+
diff --git a/queue-6.15/asoc-intel-avs-read-hw-capabilities-when-possible.patch b/queue-6.15/asoc-intel-avs-read-hw-capabilities-when-possible.patch
new file mode 100644 (file)
index 0000000..d16d80c
--- /dev/null
@@ -0,0 +1,97 @@
+From 57dcc43e9dc51ab3e9221c20192f83daf4695e9c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Apr 2025 13:23:45 +0200
+Subject: ASoC: Intel: avs: Read HW capabilities when possible
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cezary Rojewski <cezary.rojewski@intel.com>
+
+[ Upstream commit b9a3ec604993074eb6f5d08b14fb7913d1fae48b ]
+
+Starting with LunarLake (LNL) and onward, some hardware capabilities are
+visible to the sound driver directly. At the same time, these may no
+longer be visible to the AudioDSP firmware. Update resource allocation
+function to rely on the registers when possible.
+
+Reviewed-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
+Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
+Acked-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
+Link: https://patch.msgid.link/20250407112352.3720779-4-cezary.rojewski@intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 9e3285be55e6 ("ASoC: Intel: avs: Fix paths in MODULE_FIRMWARE hints")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/sound/hdaudio_ext.h         | 1 +
+ sound/hda/ext/hdac_ext_controller.c | 1 +
+ sound/soc/intel/avs/avs.h           | 1 +
+ sound/soc/intel/avs/loader.c        | 9 +++++++++
+ 4 files changed, 12 insertions(+)
+
+diff --git a/include/sound/hdaudio_ext.h b/include/sound/hdaudio_ext.h
+index 60ec12e3b72f8..7de390022ac26 100644
+--- a/include/sound/hdaudio_ext.h
++++ b/include/sound/hdaudio_ext.h
+@@ -99,6 +99,7 @@ struct hdac_ext_link {
+       u32 lcaps;   /* link capablities */
+       u16 lsdiid;  /* link sdi identifier */
+       u32 id;
++      u8 slcount;
+       int ref_count;
+diff --git a/sound/hda/ext/hdac_ext_controller.c b/sound/hda/ext/hdac_ext_controller.c
+index 2ec1531d1c1b5..c84754434d162 100644
+--- a/sound/hda/ext/hdac_ext_controller.c
++++ b/sound/hda/ext/hdac_ext_controller.c
+@@ -98,6 +98,7 @@ int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_bus *bus)
+                                       (AZX_ML_INTERVAL * idx);
+               hlink->lcaps  = readl(hlink->ml_addr + AZX_REG_ML_LCAP);
+               hlink->lsdiid = readw(hlink->ml_addr + AZX_REG_ML_LSDIID);
++              hlink->slcount = FIELD_GET(AZX_ML_HDA_LCAP_SLCOUNT, hlink->lcaps) + 1;
+               if (hdac_ext_link_alt(hlink)) {
+                       leptr = readl(hlink->ml_addr + AZX_REG_ML_LEPTR);
+diff --git a/sound/soc/intel/avs/avs.h b/sound/soc/intel/avs/avs.h
+index 91872d1df97a5..201897c5bdc04 100644
+--- a/sound/soc/intel/avs/avs.h
++++ b/sound/soc/intel/avs/avs.h
+@@ -73,6 +73,7 @@ extern const struct avs_dsp_ops avs_tgl_dsp_ops;
+ #define AVS_PLATATTR_CLDMA            BIT_ULL(0)
+ #define AVS_PLATATTR_IMR              BIT_ULL(1)
+ #define AVS_PLATATTR_ACE              BIT_ULL(2)
++#define AVS_PLATATTR_ALTHDA           BIT_ULL(3)
+ #define avs_platattr_test(adev, attr) \
+       ((adev)->spec->attributes & AVS_PLATATTR_##attr)
+diff --git a/sound/soc/intel/avs/loader.c b/sound/soc/intel/avs/loader.c
+index 0b29941feb0ef..ecf050c2c0c7f 100644
+--- a/sound/soc/intel/avs/loader.c
++++ b/sound/soc/intel/avs/loader.c
+@@ -683,6 +683,7 @@ int avs_dsp_boot_firmware(struct avs_dev *adev, bool purge)
+ static int avs_dsp_alloc_resources(struct avs_dev *adev)
+ {
++      struct hdac_ext_link *link;
+       int ret, i;
+       ret = avs_ipc_get_hw_config(adev, &adev->hw_cfg);
+@@ -693,6 +694,14 @@ static int avs_dsp_alloc_resources(struct avs_dev *adev)
+       if (ret)
+               return AVS_IPC_RET(ret);
++      /* If hw allows, read capabilities directly from it. */
++      if (avs_platattr_test(adev, ALTHDA)) {
++              link = snd_hdac_ext_bus_get_hlink_by_id(&adev->base.core,
++                                                      AZX_REG_ML_LEPTR_ID_INTEL_SSP);
++              if (link)
++                      adev->hw_cfg.i2s_caps.ctrl_count = link->slcount;
++      }
++
+       adev->core_refs = devm_kcalloc(adev->dev, adev->hw_cfg.dsp_cores,
+                                      sizeof(*adev->core_refs), GFP_KERNEL);
+       adev->lib_names = devm_kcalloc(adev->dev, adev->fw_cfg.max_libs_count,
+-- 
+2.39.5
+
diff --git a/queue-6.15/asoc-intel-avs-relocate-dsp-status-registers.patch b/queue-6.15/asoc-intel-avs-relocate-dsp-status-registers.patch
new file mode 100644 (file)
index 0000000..01987f1
--- /dev/null
@@ -0,0 +1,137 @@
+From ccefe314874382e066aa4f3653e3083660bb3639 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Apr 2025 13:23:46 +0200
+Subject: ASoC: Intel: avs: Relocate DSP status registers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cezary Rojewski <cezary.rojewski@intel.com>
+
+[ Upstream commit 75f3c607b1fa1f4d42cde8377cd2276ab01e287d ]
+
+The firmware status and error registers are not part of SRAM on ACE
+platforms. As these registers take part in IPC on ACE and cAVS platforms
+both, relocate the field denoting their offset to Host-IPC descriptor.
+
+In consequence, code remains cohesive with the ACE specs while still
+maintaining high readability for the cAVS platforms.
+
+Reviewed-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
+Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
+Acked-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
+Link: https://patch.msgid.link/20250407112352.3720779-5-cezary.rojewski@intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 9e3285be55e6 ("ASoC: Intel: avs: Fix paths in MODULE_FIRMWARE hints")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/avs/avs.h       |  2 +-
+ sound/soc/intel/avs/core.c      | 18 +++++++++++++++---
+ sound/soc/intel/avs/loader.c    |  2 +-
+ sound/soc/intel/avs/registers.h |  2 +-
+ 4 files changed, 18 insertions(+), 6 deletions(-)
+
+diff --git a/sound/soc/intel/avs/avs.h b/sound/soc/intel/avs/avs.h
+index 201897c5bdc04..ec5502f9d5cb1 100644
+--- a/sound/soc/intel/avs/avs.h
++++ b/sound/soc/intel/avs/avs.h
+@@ -81,7 +81,6 @@ extern const struct avs_dsp_ops avs_tgl_dsp_ops;
+ struct avs_sram_spec {
+       const u32 base_offset;
+       const u32 window_size;
+-      const u32 rom_status_offset;
+ };
+ struct avs_hipc_spec {
+@@ -93,6 +92,7 @@ struct avs_hipc_spec {
+       const u32 rsp_offset;
+       const u32 rsp_busy_mask;
+       const u32 ctl_offset;
++      const u32 sts_offset;
+ };
+ /* Platform specific descriptor */
+diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c
+index 72a14dca1a1ed..1495e163d47ef 100644
+--- a/sound/soc/intel/avs/core.c
++++ b/sound/soc/intel/avs/core.c
+@@ -755,13 +755,11 @@ static const struct dev_pm_ops avs_dev_pm = {
+ static const struct avs_sram_spec skl_sram_spec = {
+       .base_offset = SKL_ADSP_SRAM_BASE_OFFSET,
+       .window_size = SKL_ADSP_SRAM_WINDOW_SIZE,
+-      .rom_status_offset = SKL_ADSP_SRAM_BASE_OFFSET,
+ };
+ static const struct avs_sram_spec apl_sram_spec = {
+       .base_offset = APL_ADSP_SRAM_BASE_OFFSET,
+       .window_size = APL_ADSP_SRAM_WINDOW_SIZE,
+-      .rom_status_offset = APL_ADSP_SRAM_BASE_OFFSET,
+ };
+ static const struct avs_hipc_spec skl_hipc_spec = {
+@@ -773,6 +771,19 @@ static const struct avs_hipc_spec skl_hipc_spec = {
+       .rsp_offset = SKL_ADSP_REG_HIPCT,
+       .rsp_busy_mask = SKL_ADSP_HIPCT_BUSY,
+       .ctl_offset = SKL_ADSP_REG_HIPCCTL,
++      .sts_offset = SKL_ADSP_SRAM_BASE_OFFSET,
++};
++
++static const struct avs_hipc_spec apl_hipc_spec = {
++      .req_offset = SKL_ADSP_REG_HIPCI,
++      .req_ext_offset = SKL_ADSP_REG_HIPCIE,
++      .req_busy_mask = SKL_ADSP_HIPCI_BUSY,
++      .ack_offset = SKL_ADSP_REG_HIPCIE,
++      .ack_done_mask = SKL_ADSP_HIPCIE_DONE,
++      .rsp_offset = SKL_ADSP_REG_HIPCT,
++      .rsp_busy_mask = SKL_ADSP_HIPCT_BUSY,
++      .ctl_offset = SKL_ADSP_REG_HIPCCTL,
++      .sts_offset = APL_ADSP_SRAM_BASE_OFFSET,
+ };
+ static const struct avs_hipc_spec cnl_hipc_spec = {
+@@ -784,6 +795,7 @@ static const struct avs_hipc_spec cnl_hipc_spec = {
+       .rsp_offset = CNL_ADSP_REG_HIPCTDR,
+       .rsp_busy_mask = CNL_ADSP_HIPCTDR_BUSY,
+       .ctl_offset = CNL_ADSP_REG_HIPCCTL,
++      .sts_offset = APL_ADSP_SRAM_BASE_OFFSET,
+ };
+ static const struct avs_spec skl_desc = {
+@@ -803,7 +815,7 @@ static const struct avs_spec apl_desc = {
+       .core_init_mask = 3,
+       .attributes = AVS_PLATATTR_IMR,
+       .sram = &apl_sram_spec,
+-      .hipc = &skl_hipc_spec,
++      .hipc = &apl_hipc_spec,
+ };
+ static const struct avs_spec cnl_desc = {
+diff --git a/sound/soc/intel/avs/loader.c b/sound/soc/intel/avs/loader.c
+index ecf050c2c0c7f..138e4e9de5e30 100644
+--- a/sound/soc/intel/avs/loader.c
++++ b/sound/soc/intel/avs/loader.c
+@@ -310,7 +310,7 @@ avs_hda_init_rom(struct avs_dev *adev, unsigned int dma_id, bool purge)
+       }
+       /* await ROM init */
+-      ret = snd_hdac_adsp_readl_poll(adev, spec->sram->rom_status_offset, reg,
++      ret = snd_hdac_adsp_readl_poll(adev, spec->hipc->sts_offset, reg,
+                                      (reg & 0xF) == AVS_ROM_INIT_DONE ||
+                                      (reg & 0xF) == APL_ROM_FW_ENTERED,
+                                      AVS_ROM_INIT_POLLING_US, APL_ROM_INIT_TIMEOUT_US);
+diff --git a/sound/soc/intel/avs/registers.h b/sound/soc/intel/avs/registers.h
+index 368ede05f2cda..4db0cdf68ffc7 100644
+--- a/sound/soc/intel/avs/registers.h
++++ b/sound/soc/intel/avs/registers.h
+@@ -74,7 +74,7 @@
+ #define APL_ADSP_SRAM_WINDOW_SIZE     0x20000
+ /* Constants used when accessing SRAM, space shared with firmware */
+-#define AVS_FW_REG_BASE(adev)         ((adev)->spec->sram->base_offset)
++#define AVS_FW_REG_BASE(adev)         ((adev)->spec->hipc->sts_offset)
+ #define AVS_FW_REG_STATUS(adev)               (AVS_FW_REG_BASE(adev) + 0x0)
+ #define AVS_FW_REG_ERROR(adev)                (AVS_FW_REG_BASE(adev) + 0x4)
+-- 
+2.39.5
+
diff --git a/queue-6.15/asoc-intel-avs-verify-content-returned-by-parse_int_.patch b/queue-6.15/asoc-intel-avs-verify-content-returned-by-parse_int_.patch
new file mode 100644 (file)
index 0000000..a8f4427
--- /dev/null
@@ -0,0 +1,52 @@
+From 9a5eff92d6f263d4eec4532f934542399db1a046 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 May 2025 16:10:23 +0200
+Subject: ASoC: Intel: avs: Verify content returned by parse_int_array()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cezary Rojewski <cezary.rojewski@intel.com>
+
+[ Upstream commit 93e246b6769bdacb09cfff4ea0f00fe5ab4f0d7a ]
+
+The first element of the returned array stores its length. If it is 0,
+any manipulation beyond the element at index 0 ends with null-ptr-deref.
+
+Fixes: 5a565ba23abe ("ASoC: Intel: avs: Probing and firmware tracing over debugfs")
+Reviewed-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
+Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
+Link: https://patch.msgid.link/20250530141025.2942936-8-cezary.rojewski@intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/avs/debugfs.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/intel/avs/debugfs.c b/sound/soc/intel/avs/debugfs.c
+index 8c4edda97f757..0e826ca20619c 100644
+--- a/sound/soc/intel/avs/debugfs.c
++++ b/sound/soc/intel/avs/debugfs.c
+@@ -373,7 +373,10 @@ static ssize_t trace_control_write(struct file *file, const char __user *from, s
+               return ret;
+       num_elems = *array;
+-      resource_mask = array[1];
++      if (!num_elems) {
++              ret = -EINVAL;
++              goto free_array;
++      }
+       /*
+        * Disable if just resource mask is provided - no log priority flags.
+@@ -381,6 +384,7 @@ static ssize_t trace_control_write(struct file *file, const char __user *from, s
+        * Enable input format:   mask, prio1, .., prioN
+        * Where 'N' equals number of bits set in the 'mask'.
+        */
++      resource_mask = array[1];
+       if (num_elems == 1) {
+               ret = disable_logs(adev, resource_mask);
+       } else {
+-- 
+2.39.5
+
diff --git a/queue-6.15/asoc-intel-avs-verify-kcalloc-status-when-setting-co.patch b/queue-6.15/asoc-intel-avs-verify-kcalloc-status-when-setting-co.patch
new file mode 100644 (file)
index 0000000..f560bd9
--- /dev/null
@@ -0,0 +1,40 @@
+From 4a4f447df7713229875fa9b9b85fd3b6e9615033 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 May 2025 16:10:22 +0200
+Subject: ASoC: Intel: avs: Verify kcalloc() status when setting constraints
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cezary Rojewski <cezary.rojewski@intel.com>
+
+[ Upstream commit 5f342aeee2724d31046172eb5caab8e0e8afd57d ]
+
+All memory operations shall be checked.
+
+Fixes: f2f847461fb7 ("ASoC: Intel: avs: Constrain path based on BE capabilities")
+Reviewed-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
+Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
+Link: https://patch.msgid.link/20250530141025.2942936-7-cezary.rojewski@intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/avs/path.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/sound/soc/intel/avs/path.c b/sound/soc/intel/avs/path.c
+index 8f1bf8d0af8f9..43b3d99539107 100644
+--- a/sound/soc/intel/avs/path.c
++++ b/sound/soc/intel/avs/path.c
+@@ -134,6 +134,8 @@ int avs_path_set_constraint(struct avs_dev *adev, struct avs_tplg_path_template
+       rlist = kcalloc(i, sizeof(*rlist), GFP_KERNEL);
+       clist = kcalloc(i, sizeof(*clist), GFP_KERNEL);
+       slist = kcalloc(i, sizeof(*slist), GFP_KERNEL);
++      if (!rlist || !clist || !slist)
++              return -ENOMEM;
+       i = 0;
+       list_for_each_entry(path_template, &template->path_list, node) {
+-- 
+2.39.5
+
diff --git a/queue-6.15/asoc-mediatek-mt8195-set-etdm1-2-in-out-to-comp_dumm.patch b/queue-6.15/asoc-mediatek-mt8195-set-etdm1-2-in-out-to-comp_dumm.patch
new file mode 100644 (file)
index 0000000..1700a9e
--- /dev/null
@@ -0,0 +1,98 @@
+From b0645f62ea8513f96192524e19f060d2a2f7caa6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Apr 2025 10:44:33 +0200
+Subject: ASoC: mediatek: mt8195: Set ETDM1/2 IN/OUT to COMP_DUMMY()
+
+From: Julien Massot <julien.massot@collabora.com>
+
+[ Upstream commit 7af317f7faaab09d5a78f24605057d11f5955115 ]
+
+ETDM2_IN_BE and ETDM1_OUT_BE are defined as COMP_EMPTY(),
+in the case the codec dai_name will be null.
+
+Avoid a crash if the device tree is not assigning a codec
+to these links.
+
+[    1.179936] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
+[    1.181065] Mem abort info:
+[    1.181420]   ESR = 0x0000000096000004
+[    1.181892]   EC = 0x25: DABT (current EL), IL = 32 bits
+[    1.182576]   SET = 0, FnV = 0
+[    1.182964]   EA = 0, S1PTW = 0
+[    1.183367]   FSC = 0x04: level 0 translation fault
+[    1.183983] Data abort info:
+[    1.184406]   ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
+[    1.185097]   CM = 0, WnR = 0, TnD = 0, TagAccess = 0
+[    1.185766]   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
+[    1.186439] [0000000000000000] user address but active_mm is swapper
+[    1.187239] Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP
+[    1.188029] Modules linked in:
+[    1.188420] CPU: 7 UID: 0 PID: 70 Comm: kworker/u32:1 Not tainted 6.14.0-rc4-next-20250226+ #85
+[    1.189515] Hardware name: Radxa NIO 12L (DT)
+[    1.190065] Workqueue: events_unbound deferred_probe_work_func
+[    1.190808] pstate: 40400009 (nZcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+[    1.191683] pc : __pi_strcmp+0x24/0x140
+[    1.192170] lr : mt8195_mt6359_soc_card_probe+0x224/0x7b0
+[    1.192854] sp : ffff800083473970
+[    1.193271] x29: ffff800083473a10 x28: 0000000000001008 x27: 0000000000000002
+[    1.194168] x26: ffff800082408960 x25: ffff800082417db0 x24: ffff800082417d88
+[    1.195065] x23: 000000000000001e x22: ffff800082dbf480 x21: ffff800082dc07b8
+[    1.195961] x20: 0000000000000000 x19: 0000000000000013 x18: 00000000ffffffff
+[    1.196858] x17: 000000040044ffff x16: 005000f2b5503510 x15: 0000000000000006
+[    1.197755] x14: ffff800082407af0 x13: 6e6f69737265766e x12: 692d6b636f6c6374
+[    1.198651] x11: 0000000000000002 x10: ffff80008240b920 x9 : 0000000000000018
+[    1.199547] x8 : 0101010101010101 x7 : 0000000000000000 x6 : 0000000000000000
+[    1.200443] x5 : 0000000000000000 x4 : 8080808080000000 x3 : 303933383978616d
+[    1.201339] x2 : 0000000000000000 x1 : ffff80008240b920 x0 : 0000000000000000
+[    1.202236] Call trace:
+[    1.202545]  __pi_strcmp+0x24/0x140 (P)
+[    1.203029]  mtk_soundcard_common_probe+0x3bc/0x5b8
+[    1.203644]  platform_probe+0x70/0xe8
+[    1.204106]  really_probe+0xc8/0x3a0
+[    1.204556]  __driver_probe_device+0x84/0x160
+[    1.205104]  driver_probe_device+0x44/0x130
+[    1.205630]  __device_attach_driver+0xc4/0x170
+[    1.206189]  bus_for_each_drv+0x8c/0xf8
+[    1.206672]  __device_attach+0xa8/0x1c8
+[    1.207155]  device_initial_probe+0x1c/0x30
+[    1.207681]  bus_probe_device+0xb0/0xc0
+[    1.208165]  deferred_probe_work_func+0xa4/0x100
+[    1.208747]  process_one_work+0x158/0x3e0
+[    1.209254]  worker_thread+0x2c4/0x3e8
+[    1.209727]  kthread+0x134/0x1f0
+[    1.210136]  ret_from_fork+0x10/0x20
+[    1.210589] Code: 54000401 b50002c6 d503201f f86a6803 (f8408402)
+[    1.211355] ---[ end trace 0000000000000000 ]---
+
+Signed-off-by: Julien Massot <julien.massot@collabora.com>
+Fixes: e70b8dd26711 ("ASoC: mediatek: mt8195: Remove afe-dai component and rework codec link")
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://patch.msgid.link/20250417-mt8395-audio-sof-v1-2-30587426e5dd@collabora.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/mediatek/mt8195/mt8195-mt6359.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/mediatek/mt8195/mt8195-mt6359.c b/sound/soc/mediatek/mt8195/mt8195-mt6359.c
+index df29a9fa5aee5..1fa664b56f30f 100644
+--- a/sound/soc/mediatek/mt8195/mt8195-mt6359.c
++++ b/sound/soc/mediatek/mt8195/mt8195-mt6359.c
+@@ -822,12 +822,12 @@ SND_SOC_DAILINK_DEFS(ETDM1_IN_BE,
+ SND_SOC_DAILINK_DEFS(ETDM2_IN_BE,
+                    DAILINK_COMP_ARRAY(COMP_CPU("ETDM2_IN")),
+-                   DAILINK_COMP_ARRAY(COMP_EMPTY()),
++                   DAILINK_COMP_ARRAY(COMP_DUMMY()),
+                    DAILINK_COMP_ARRAY(COMP_EMPTY()));
+ SND_SOC_DAILINK_DEFS(ETDM1_OUT_BE,
+                    DAILINK_COMP_ARRAY(COMP_CPU("ETDM1_OUT")),
+-                   DAILINK_COMP_ARRAY(COMP_EMPTY()),
++                   DAILINK_COMP_ARRAY(COMP_DUMMY()),
+                    DAILINK_COMP_ARRAY(COMP_EMPTY()));
+ SND_SOC_DAILINK_DEFS(ETDM2_OUT_BE,
+-- 
+2.39.5
+
diff --git a/queue-6.15/asoc-sof-amd-add-missing-acp-descriptor-field.patch b/queue-6.15/asoc-sof-amd-add-missing-acp-descriptor-field.patch
new file mode 100644 (file)
index 0000000..1077ddc
--- /dev/null
@@ -0,0 +1,38 @@
+From 5cce598559bdd3094966804c8fe431440c1edbac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 May 2025 21:12:41 +0530
+Subject: ASoC: SOF: amd: add missing acp descriptor field
+
+From: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+
+[ Upstream commit 7c2bad7b95db5b4b978853cd4dd042ae3ec83e63 ]
+
+Add missing acp descriptor field acp_error_stat for ACP7.0 platform.
+
+Fixes: 490be7ba2a01 ("ASoC: SOF: amd: add support for acp7.0 based platform")
+
+Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
+Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Link: https://patch.msgid.link/20250502154445.3008598-3-Vijendar.Mukunda@amd.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/sof/amd/pci-acp70.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/sound/soc/sof/amd/pci-acp70.c b/sound/soc/sof/amd/pci-acp70.c
+index 8fa1170a2161e..9108f1139ff2d 100644
+--- a/sound/soc/sof/amd/pci-acp70.c
++++ b/sound/soc/sof/amd/pci-acp70.c
+@@ -33,6 +33,7 @@ static const struct sof_amd_acp_desc acp70_chip_info = {
+       .ext_intr_cntl = ACP70_EXTERNAL_INTR_CNTL,
+       .ext_intr_stat  = ACP70_EXT_INTR_STAT,
+       .ext_intr_stat1 = ACP70_EXT_INTR_STAT1,
++      .acp_error_stat = ACP70_ERROR_STATUS,
+       .dsp_intr_base  = ACP70_DSP_SW_INTR_BASE,
+       .acp_sw0_i2s_err_reason = ACP7X_SW0_I2S_ERROR_REASON,
+       .sram_pte_offset = ACP70_SRAM_PTE_OFFSET,
+-- 
+2.39.5
+
diff --git a/queue-6.15/asoc-sof-ipc4-pcm-adjust-pipeline_list-pipelines-all.patch b/queue-6.15/asoc-sof-ipc4-pcm-adjust-pipeline_list-pipelines-all.patch
new file mode 100644 (file)
index 0000000..5c10892
--- /dev/null
@@ -0,0 +1,46 @@
+From c77b43641c6d2757b71034c1c47e4b93666c5c59 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 23:25:12 -0700
+Subject: ASoC: SOF: ipc4-pcm: Adjust pipeline_list->pipelines allocation type
+
+From: Kees Cook <kees@kernel.org>
+
+[ Upstream commit 00a371adbbfb46db561db85a9d7b53b2363880a1 ]
+
+In preparation for making the kmalloc family of allocators type aware,
+we need to make sure that the returned type from the allocation matches
+the type of the variable being assigned. (Before, the allocator would
+always return "void *", which can be implicitly cast to any pointer type.)
+
+The assigned type is "struct snd_sof_pipeline **", but the returned type
+will be "struct snd_sof_widget **". These are the same size allocation
+(pointer size) but the types don't match. Adjust the allocation type to
+match the assignment.
+
+Signed-off-by: Kees Cook <kees@kernel.org>
+Fixes: 9c04363d222b ("ASoC: SOF: Introduce struct snd_sof_pipeline")
+Acked-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
+Link: https://patch.msgid.link/20250426062511.work.859-kees@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/sof/ipc4-pcm.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/sof/ipc4-pcm.c b/sound/soc/sof/ipc4-pcm.c
+index c09b424ab863d..8eee3e1aadf93 100644
+--- a/sound/soc/sof/ipc4-pcm.c
++++ b/sound/soc/sof/ipc4-pcm.c
+@@ -784,7 +784,8 @@ static int sof_ipc4_pcm_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm
+               /* allocate memory for max number of pipeline IDs */
+               pipeline_list->pipelines = kcalloc(ipc4_data->max_num_pipelines,
+-                                                 sizeof(struct snd_sof_widget *), GFP_KERNEL);
++                                                 sizeof(*pipeline_list->pipelines),
++                                                 GFP_KERNEL);
+               if (!pipeline_list->pipelines) {
+                       sof_ipc4_pcm_free(sdev, spcm);
+                       return -ENOMEM;
+-- 
+2.39.5
+
diff --git a/queue-6.15/asoc-tas2764-enable-main-irqs.patch b/queue-6.15/asoc-tas2764-enable-main-irqs.patch
new file mode 100644 (file)
index 0000000..07d7be1
--- /dev/null
@@ -0,0 +1,41 @@
+From 8bb5d0143d7d7c3b6444f223073516ba0ff31415 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 6 Apr 2025 09:15:08 +1000
+Subject: ASoC: tas2764: Enable main IRQs
+
+From: Hector Martin <marcan@marcan.st>
+
+[ Upstream commit dd50f0e38563f15819059c923bf142200453e003 ]
+
+IRQ handling was added in commit dae191fb957f ("ASoC: tas2764: Add IRQ
+handling") however that same commit masks all interrupts coming from
+the chip. Unmask the "main" interrupts so that we can see and
+deal with a number of errors including clock, voltage, and current.
+
+Fixes: dae191fb957f ("ASoC: tas2764: Add IRQ handling")
+Reviewed-by: Neal Gompa <neal@gompa.dev>
+Signed-off-by: Hector Martin <marcan@marcan.st>
+Signed-off-by: James Calligeros <jcalligeros99@gmail.com>
+Link: https://patch.msgid.link/20250406-apple-codec-changes-v5-4-50a00ec850a3@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/tas2764.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/codecs/tas2764.c b/sound/soc/codecs/tas2764.c
+index 49b73b74b2d9d..fbfe4d032df7b 100644
+--- a/sound/soc/codecs/tas2764.c
++++ b/sound/soc/codecs/tas2764.c
+@@ -564,7 +564,7 @@ static int tas2764_codec_probe(struct snd_soc_component *component)
+       regmap_reinit_cache(tas2764->regmap, &tas2764_i2c_regmap);
+       if (tas2764->irq) {
+-              ret = snd_soc_component_write(tas2764->component, TAS2764_INT_MASK0, 0xff);
++              ret = snd_soc_component_write(tas2764->component, TAS2764_INT_MASK0, 0x00);
+               if (ret < 0)
+                       return ret;
+-- 
+2.39.5
+
diff --git a/queue-6.15/asoc-tas2764-reinit-cache-on-part-reset.patch b/queue-6.15/asoc-tas2764-reinit-cache-on-part-reset.patch
new file mode 100644 (file)
index 0000000..19e8083
--- /dev/null
@@ -0,0 +1,53 @@
+From bb177e03f53302dcd32b656c3f71800a226a451d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 6 Apr 2025 09:15:07 +1000
+Subject: ASoC: tas2764: Reinit cache on part reset
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Martin Povišer <povik+lin@cutebit.org>
+
+[ Upstream commit 592ab3936b096da5deb64d4c906edbeb989174d6 ]
+
+When the part is reset in component_probe, do not forget to reinit the
+regcache, otherwise the cache can get out of sync with the part's
+actual state. This fix is similar to commit 0a0342ede303
+("ASoC: tas2770: Reinit regcache on reset") which concerned the
+tas2770 driver.
+
+Fixes: 827ed8a0fa50 ("ASoC: tas2764: Add the driver for the TAS2764")
+Reviewed-by: Neal Gompa <neal@gompa.dev>
+Signed-off-by: Martin Povišer <povik+lin@cutebit.org>
+Signed-off-by: James Calligeros <jcalligeros99@gmail.com>
+Link: https://patch.msgid.link/20250406-apple-codec-changes-v5-3-50a00ec850a3@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/tas2764.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/sound/soc/codecs/tas2764.c b/sound/soc/codecs/tas2764.c
+index 08aa7ee342568..49b73b74b2d9d 100644
+--- a/sound/soc/codecs/tas2764.c
++++ b/sound/soc/codecs/tas2764.c
+@@ -546,6 +546,8 @@ static uint8_t sn012776_bop_presets[] = {
+       0x06, 0x3e, 0x37, 0x30, 0xff, 0xe6
+ };
++static const struct regmap_config tas2764_i2c_regmap;
++
+ static int tas2764_codec_probe(struct snd_soc_component *component)
+ {
+       struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component);
+@@ -559,6 +561,7 @@ static int tas2764_codec_probe(struct snd_soc_component *component)
+       }
+       tas2764_reset(tas2764);
++      regmap_reinit_cache(tas2764->regmap, &tas2764_i2c_regmap);
+       if (tas2764->irq) {
+               ret = snd_soc_component_write(tas2764->component, TAS2764_INT_MASK0, 0xff);
+-- 
+2.39.5
+
diff --git a/queue-6.15/asoc-ti-omap-hdmi-re-add-dai_link-platform-to-fix-ca.patch b/queue-6.15/asoc-ti-omap-hdmi-re-add-dai_link-platform-to-fix-ca.patch
new file mode 100644 (file)
index 0000000..7a53580
--- /dev/null
@@ -0,0 +1,77 @@
+From 5c9b68646421bc5c8397e481af74b9f00845c261 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 31 May 2025 23:13:41 +0900
+Subject: ASoC: ti: omap-hdmi: Re-add dai_link->platform to fix card init
+
+From: Yuuki NAGAO <wf.yn386@gmail.com>
+
+[ Upstream commit bae071aa7bcd034054cec91666c80f812adeccd9 ]
+
+The removed dai_link->platform component cause a fail which
+is exposed at runtime. (ex: when a sound tool is used)
+This patch re-adds the dai_link->platform component to have
+a full card registered.
+
+Before this patch:
+$ aplay -l
+**** List of PLAYBACK Hardware Devices ****
+card 1: HDMI [HDMI], device 0: HDMI snd-soc-dummy-dai-0 []
+  Subdevices: 1/1
+  Subdevice #0: subdevice #0
+
+$ speaker-test -D plughw:1,0 -t sine
+speaker-test 1.2.8
+Playback device is plughw:1,0
+Stream parameters are 48000Hz, S16_LE, 1 channels
+Sine wave rate is 440.0000Hz
+Playback open error: -22,Invalid argument
+
+After this patch which restores the platform component:
+$ aplay -l
+**** List of PLAYBACK Hardware Devices ****
+card 0: HDMI [HDMI], device 0: HDMI snd-soc-dummy-dai-0 [HDMI snd-soc-dummy-dai-0]
+  Subdevices: 0/1
+  Subdevice #0: subdevice #0
+
+-> Resolve the playback error.
+
+Fixes: 3b0db249cf8f ("ASoC: ti: remove unnecessary dai_link->platform")
+
+Signed-off-by: Yuuki NAGAO <wf.yn386@gmail.com>
+Link: https://patch.msgid.link/20250531141341.81164-1-wf.yn386@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/ti/omap-hdmi.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/ti/omap-hdmi.c b/sound/soc/ti/omap-hdmi.c
+index cf43ac19c4a6d..55e7cb96858fc 100644
+--- a/sound/soc/ti/omap-hdmi.c
++++ b/sound/soc/ti/omap-hdmi.c
+@@ -361,17 +361,20 @@ static int omap_hdmi_audio_probe(struct platform_device *pdev)
+       if (!card->dai_link)
+               return -ENOMEM;
+-      compnent = devm_kzalloc(dev, sizeof(*compnent), GFP_KERNEL);
++      compnent = devm_kzalloc(dev, 2 * sizeof(*compnent), GFP_KERNEL);
+       if (!compnent)
+               return -ENOMEM;
+-      card->dai_link->cpus            = compnent;
++      card->dai_link->cpus            = &compnent[0];
+       card->dai_link->num_cpus        = 1;
+       card->dai_link->codecs          = &snd_soc_dummy_dlc;
+       card->dai_link->num_codecs      = 1;
++      card->dai_link->platforms       = &compnent[1];
++      card->dai_link->num_platforms   = 1;
+       card->dai_link->name = card->name;
+       card->dai_link->stream_name = card->name;
+       card->dai_link->cpus->dai_name = dev_name(ad->dssdev);
++      card->dai_link->platforms->name = dev_name(ad->dssdev);
+       card->num_links = 1;
+       card->dev = dev;
+-- 
+2.39.5
+
diff --git a/queue-6.15/backlight-pm8941-add-null-check-in-wled_configure.patch b/queue-6.15/backlight-pm8941-add-null-check-in-wled_configure.patch
new file mode 100644 (file)
index 0000000..412e097
--- /dev/null
@@ -0,0 +1,47 @@
+From 0fe56fcae17f1b1d4b0c716347806a0338775309 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 17:16:47 +0800
+Subject: backlight: pm8941: Add NULL check in wled_configure()
+
+From: Henry Martin <bsdhenrymartin@gmail.com>
+
+[ Upstream commit e12d3e1624a02706cdd3628bbf5668827214fa33 ]
+
+devm_kasprintf() returns NULL when memory allocation fails. Currently,
+wled_configure() does not check for this case, which results in a NULL
+pointer dereference.
+
+Add NULL check after devm_kasprintf() to prevent this issue.
+
+Fixes: f86b77583d88 ("backlight: pm8941: Convert to using %pOFn instead of device_node.name")
+Signed-off-by: Henry Martin <bsdhenrymartin@gmail.com>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Reviewed-by: "Daniel Thompson (RISCstar)" <danielt@kernel.org>
+Link: https://lore.kernel.org/r/20250401091647.22784-1-bsdhenrymartin@gmail.com
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/backlight/qcom-wled.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/video/backlight/qcom-wled.c b/drivers/video/backlight/qcom-wled.c
+index 9afe701b2a1b6..a63bb42c8f8b0 100644
+--- a/drivers/video/backlight/qcom-wled.c
++++ b/drivers/video/backlight/qcom-wled.c
+@@ -1406,9 +1406,11 @@ static int wled_configure(struct wled *wled)
+       wled->ctrl_addr = be32_to_cpu(*prop_addr);
+       rc = of_property_read_string(dev->of_node, "label", &wled->name);
+-      if (rc)
++      if (rc) {
+               wled->name = devm_kasprintf(dev, GFP_KERNEL, "%pOFn", dev->of_node);
+-
++              if (!wled->name)
++                      return -ENOMEM;
++      }
+       switch (wled->version) {
+       case 3:
+               u32_opts = wled3_opts;
+-- 
+2.39.5
+
diff --git a/queue-6.15/blk-throttle-fix-wrong-tg-bytes-io-_disp-update-in-_.patch b/queue-6.15/blk-throttle-fix-wrong-tg-bytes-io-_disp-update-in-_.patch
new file mode 100644 (file)
index 0000000..e87d0e3
--- /dev/null
@@ -0,0 +1,81 @@
+From 28bfcb95754ee666329ca8c33dd2f80e09e9a6b2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Apr 2025 21:20:52 +0800
+Subject: blk-throttle: Fix wrong tg->[bytes/io]_disp update in
+ __tg_update_carryover()
+
+From: Zizhi Wo <wozizhi@huawei.com>
+
+[ Upstream commit f66cf69eb8765341bbeff0e92a7d0d2027f62452 ]
+
+In commit 6cc477c36875 ("blk-throttle: carry over directly"), the carryover
+bytes/ios was be carried to [bytes/io]_disp. However, its update mechanism
+has some issues.
+
+In __tg_update_carryover(), we calculate "bytes" and "ios" to represent the
+carryover, but the computation when updating [bytes/io]_disp is incorrect.
+And if the sq->nr_queued is empty, we may not update tg->[bytes/io]_disp to
+0 in tg_update_carryover(). We should set it to 0 in non carryover case.
+This patch fixes the issue.
+
+Fixes: 6cc477c36875 ("blk-throttle: carry over directly")
+Signed-off-by: Zizhi Wo <wozizhi@huawei.com>
+Reviewed-by: Yu Kuai <yukuai3@huawei.com>
+Reviewed-by: Ming Lei <ming.lei@redhat.com>
+Link: https://lore.kernel.org/r/20250417132054.2866409-2-wozizhi@huaweicloud.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-throttle.c | 22 ++++++++++++++++------
+ 1 file changed, 16 insertions(+), 6 deletions(-)
+
+diff --git a/block/blk-throttle.c b/block/blk-throttle.c
+index d6dd2e0478749..7437de947120e 100644
+--- a/block/blk-throttle.c
++++ b/block/blk-throttle.c
+@@ -644,6 +644,18 @@ static void __tg_update_carryover(struct throtl_grp *tg, bool rw,
+       u64 bps_limit = tg_bps_limit(tg, rw);
+       u32 iops_limit = tg_iops_limit(tg, rw);
++      /*
++       * If the queue is empty, carryover handling is not needed. In such cases,
++       * tg->[bytes/io]_disp should be reset to 0 to avoid impacting the dispatch
++       * of subsequent bios. The same handling applies when the previous BPS/IOPS
++       * limit was set to max.
++       */
++      if (tg->service_queue.nr_queued[rw] == 0) {
++              tg->bytes_disp[rw] = 0;
++              tg->io_disp[rw] = 0;
++              return;
++      }
++
+       /*
+        * If config is updated while bios are still throttled, calculate and
+        * accumulate how many bytes/ios are waited across changes. And
+@@ -656,8 +668,8 @@ static void __tg_update_carryover(struct throtl_grp *tg, bool rw,
+       if (iops_limit != UINT_MAX)
+               *ios = calculate_io_allowed(iops_limit, jiffy_elapsed) -
+                       tg->io_disp[rw];
+-      tg->bytes_disp[rw] -= *bytes;
+-      tg->io_disp[rw] -= *ios;
++      tg->bytes_disp[rw] = -*bytes;
++      tg->io_disp[rw] = -*ios;
+ }
+ static void tg_update_carryover(struct throtl_grp *tg)
+@@ -665,10 +677,8 @@ static void tg_update_carryover(struct throtl_grp *tg)
+       long long bytes[2] = {0};
+       int ios[2] = {0};
+-      if (tg->service_queue.nr_queued[READ])
+-              __tg_update_carryover(tg, READ, &bytes[READ], &ios[READ]);
+-      if (tg->service_queue.nr_queued[WRITE])
+-              __tg_update_carryover(tg, WRITE, &bytes[WRITE], &ios[WRITE]);
++      __tg_update_carryover(tg, READ, &bytes[READ], &ios[READ]);
++      __tg_update_carryover(tg, WRITE, &bytes[WRITE], &ios[WRITE]);
+       /* see comments in struct throtl_grp for meaning of these fields. */
+       throtl_log(&tg->service_queue, "%s: %lld %lld %d %d\n", __func__,
+-- 
+2.39.5
+
diff --git a/queue-6.15/block-flip-iter-directions-in-blk_rq_integrity_map_u.patch b/queue-6.15/block-flip-iter-directions-in-blk_rq_integrity_map_u.patch
new file mode 100644 (file)
index 0000000..07862a1
--- /dev/null
@@ -0,0 +1,46 @@
+From 8c98741d454cf9ad349e36c75fc61e1e68b21d79 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Jun 2025 12:47:51 -0600
+Subject: block: flip iter directions in blk_rq_integrity_map_user()
+
+From: Caleb Sander Mateos <csander@purestorage.com>
+
+[ Upstream commit 43a67dd812c5d3de163c0b6971046b4a4b633d3f ]
+
+blk_rq_integrity_map_user() creates the ubuf iter with ITER_DEST for
+write-direction operations and ITER_SOURCE for read-direction ones.
+This is backwards; writes use the user buffer as a source for metadata
+and reads use it as a destination. Switch to the rq_data_dir() helper,
+which maps writes to ITER_SOURCE (WRITE) and reads to ITER_DEST(READ).
+
+Signed-off-by: Caleb Sander Mateos <csander@purestorage.com>
+Fixes: fe8f4ca7107e ("block: modify bio_integrity_map_user to accept iov_iter as argument")
+Link: https://lore.kernel.org/r/20250603184752.1185676-1-csander@purestorage.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-integrity.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+diff --git a/block/blk-integrity.c b/block/blk-integrity.c
+index a1678f0a9f81f..e4e2567061f9d 100644
+--- a/block/blk-integrity.c
++++ b/block/blk-integrity.c
+@@ -117,13 +117,8 @@ int blk_rq_integrity_map_user(struct request *rq, void __user *ubuf,
+ {
+       int ret;
+       struct iov_iter iter;
+-      unsigned int direction;
+-      if (op_is_write(req_op(rq)))
+-              direction = ITER_DEST;
+-      else
+-              direction = ITER_SOURCE;
+-      iov_iter_ubuf(&iter, direction, ubuf, bytes);
++      iov_iter_ubuf(&iter, rq_data_dir(rq), ubuf, bytes);
+       ret = bio_integrity_map_user(rq->bio, &iter);
+       if (ret)
+               return ret;
+-- 
+2.39.5
+
diff --git a/queue-6.15/bluetooth-btintel-check-dsbr-size-from-efi-variable.patch b/queue-6.15/bluetooth-btintel-check-dsbr-size-from-efi-variable.patch
new file mode 100644 (file)
index 0000000..9285b14
--- /dev/null
@@ -0,0 +1,58 @@
+From 7470d309505ba03f1d592d71b4e19065cdced8a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 May 2025 09:31:35 -0700
+Subject: Bluetooth: btintel: Check dsbr size from EFI variable
+
+From: Kees Cook <kees@kernel.org>
+
+[ Upstream commit 3aa1dc3c9060e335e82e9c182bf3d1db29220b1b ]
+
+Since the size of struct btintel_dsbr is already known, we can just
+start there instead of querying the EFI variable size. If the final
+result doesn't match what we expect also fail. This fixes a stack buffer
+overflow when the EFI variable is larger than struct btintel_dsbr.
+
+Reported-by: zepta <z3ptaa@gmail.com>
+Closes: https://lore.kernel.org/all/CAPBS6KoaWV9=dtjTESZiU6KK__OZX0KpDk-=JEH8jCHFLUYv3Q@mail.gmail.com
+Fixes: eb9e749c0182 ("Bluetooth: btintel: Allow configuring drive strength of BRI")
+Signed-off-by: Kees Cook <kees@kernel.org>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btintel.c | 10 ++--------
+ 1 file changed, 2 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
+index 48e2f400957bc..46d9bbd8e411b 100644
+--- a/drivers/bluetooth/btintel.c
++++ b/drivers/bluetooth/btintel.c
+@@ -2719,7 +2719,7 @@ static int btintel_uefi_get_dsbr(u32 *dsbr_var)
+       } __packed data;
+       efi_status_t status;
+-      unsigned long data_size = 0;
++      unsigned long data_size = sizeof(data);
+       efi_guid_t guid = EFI_GUID(0xe65d8884, 0xd4af, 0x4b20, 0x8d, 0x03,
+                                  0x77, 0x2e, 0xcc, 0x3d, 0xa5, 0x31);
+@@ -2729,16 +2729,10 @@ static int btintel_uefi_get_dsbr(u32 *dsbr_var)
+       if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE))
+               return -EOPNOTSUPP;
+-      status = efi.get_variable(BTINTEL_EFI_DSBR, &guid, NULL, &data_size,
+-                                NULL);
+-
+-      if (status != EFI_BUFFER_TOO_SMALL || !data_size)
+-              return -EIO;
+-
+       status = efi.get_variable(BTINTEL_EFI_DSBR, &guid, NULL, &data_size,
+                                 &data);
+-      if (status != EFI_SUCCESS)
++      if (status != EFI_SUCCESS || data_size != sizeof(data))
+               return -ENXIO;
+       *dsbr_var = data.dsbr;
+-- 
+2.39.5
+
diff --git a/queue-6.15/bluetooth-iso-fix-not-using-sid-from-adv-report.patch b/queue-6.15/bluetooth-iso-fix-not-using-sid-from-adv-report.patch
new file mode 100644 (file)
index 0000000..44f4fde
--- /dev/null
@@ -0,0 +1,299 @@
+From 93816a400cc21b4b13abf7702be19a1267771208 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Apr 2025 12:37:50 -0400
+Subject: Bluetooth: ISO: Fix not using SID from adv report
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit e2d471b7806b09744d65a64bcf41337468f2443b ]
+
+Up until now it has been assumed that the application would be able to
+enter the advertising SID in sockaddr_iso_bc.bc_sid, but userspace has
+no access to SID since the likes of MGMT_EV_DEVICE_FOUND cannot carry
+it, so it was left unset (0x00) which means it would be unable to
+synchronize if the broadcast source is using a different SID e.g. 0x04:
+
+> HCI Event: LE Meta Event (0x3e) plen 57
+      LE Extended Advertising Report (0x0d)
+        Num reports: 1
+        Entry 0
+          Event type: 0x0000
+            Props: 0x0000
+            Data status: Complete
+          Address type: Random (0x01)
+          Address: 0B:82:E8:50:6D:C8 (Non-Resolvable)
+          Primary PHY: LE 1M
+          Secondary PHY: LE 2M
+          SID: 0x04
+          TX power: 127 dBm
+          RSSI: -55 dBm (0xc9)
+          Periodic advertising interval: 180.00 msec (0x0090)
+          Direct address type: Public (0x00)
+          Direct address: 00:00:00:00:00:00 (OUI 00-00-00)
+          Data length: 0x1f
+        06 16 52 18 5b 0b e1 05 16 56 18 04 00 11 30 4c  ..R.[....V....0L
+        75 69 7a 27 73 20 53 32 33 20 55 6c 74 72 61     uiz's S23 Ultra
+        Service Data: Broadcast Audio Announcement (0x1852)
+        Broadcast ID: 14748507 (0xe10b5b)
+        Service Data: Public Broadcast Announcement (0x1856)
+          Data[2]: 0400
+        Unknown EIR field 0x30[16]: 4c75697a27732053323320556c747261
+< HCI Command: LE Periodic Advertising Create Sync (0x08|0x0044) plen 14
+        Options: 0x0000
+        Use advertising SID, Advertiser Address Type and address
+        Reporting initially enabled
+        SID: 0x00 (<- Invalid)
+        Adv address type: Random (0x01)
+        Adv address: 0B:82:E8:50:6D:C8 (Non-Resolvable)
+        Skip: 0x0000
+        Sync timeout: 20000 msec (0x07d0)
+        Sync CTE type: 0x0000
+
+So instead this changes now allow application to set HCI_SID_INVALID
+which will make hci_le_pa_create_sync to wait for a report, update the
+conn->sid using the report SID and only then issue PA create sync
+command:
+
+< HCI Command: LE Periodic Advertising Create Sync
+        Options: 0x0000
+        Use advertising SID, Advertiser Address Type and address
+        Reporting initially enabled
+        SID: 0x04
+        Adv address type: Random (0x01)
+        Adv address: 0B:82:E8:50:6D:C8 (Non-Resolvable)
+        Skip: 0x0000
+        Sync timeout: 20000 msec (0x07d0)
+        Sync CTE type: 0x0000
+> HCI Event: LE Meta Event (0x3e) plen 16
+      LE Periodic Advertising Sync Established (0x0e)
+        Status: Success (0x00)
+        Sync handle: 64
+        Advertising SID: 0x04
+        Advertiser address type: Random (0x01)
+        Advertiser address: 0B:82:E8:50:6D:C8 (Non-Resolvable)
+        Advertiser PHY: LE 2M (0x02)
+        Periodic advertising interval: 180.00 msec (0x0090)
+        Advertiser clock accuracy: 0x05
+
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: 23205562ffc8 ("Bluetooth: separate CIS_LINK and BIS_LINK link types")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_conn.c  |  2 ++
+ net/bluetooth/hci_core.c  | 13 ++++++-----
+ net/bluetooth/hci_event.c | 16 ++++++++++++-
+ net/bluetooth/hci_sync.c  | 49 +++++++++++++++++++++++++++++++++++----
+ net/bluetooth/iso.c       |  9 +++++--
+ 5 files changed, 75 insertions(+), 14 deletions(-)
+
+diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
+index 946d2ae551f86..c0207812f4328 100644
+--- a/net/bluetooth/hci_conn.c
++++ b/net/bluetooth/hci_conn.c
+@@ -2070,6 +2070,8 @@ struct hci_conn *hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst,
+ {
+       struct hci_conn *conn;
++      bt_dev_dbg(hdev, "dst %pMR type %d sid %d", dst, dst_type, sid);
++
+       conn = hci_conn_add_unset(hdev, ISO_LINK, dst, HCI_ROLE_SLAVE);
+       if (IS_ERR(conn))
+               return conn;
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index 5eb0600bbd03c..75da6f6e39c9e 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -4057,10 +4057,13 @@ static void hci_send_cmd_sync(struct hci_dev *hdev, struct sk_buff *skb)
+               return;
+       }
+-      err = hci_send_frame(hdev, skb);
+-      if (err < 0) {
+-              hci_cmd_sync_cancel_sync(hdev, -err);
+-              return;
++      if (hci_skb_opcode(skb) != HCI_OP_NOP) {
++              err = hci_send_frame(hdev, skb);
++              if (err < 0) {
++                      hci_cmd_sync_cancel_sync(hdev, -err);
++                      return;
++              }
++              atomic_dec(&hdev->cmd_cnt);
+       }
+       if (hdev->req_status == HCI_REQ_PEND &&
+@@ -4068,8 +4071,6 @@ static void hci_send_cmd_sync(struct hci_dev *hdev, struct sk_buff *skb)
+               kfree_skb(hdev->req_skb);
+               hdev->req_skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
+       }
+-
+-      atomic_dec(&hdev->cmd_cnt);
+ }
+ static void hci_cmd_work(struct work_struct *work)
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index c38ada69c3d7f..4183560582a3a 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -6351,6 +6351,17 @@ static void hci_le_ext_adv_report_evt(struct hci_dev *hdev, void *data,
+                       info->secondary_phy &= 0x1f;
+               }
++              /* Check if PA Sync is pending and if the hci_conn SID has not
++               * been set update it.
++               */
++              if (hci_dev_test_flag(hdev, HCI_PA_SYNC)) {
++                      struct hci_conn *conn;
++
++                      conn = hci_conn_hash_lookup_create_pa_sync(hdev);
++                      if (conn && conn->sid == HCI_SID_INVALID)
++                              conn->sid = info->sid;
++              }
++
+               if (legacy_evt_type != LE_ADV_INVALID) {
+                       process_adv_report(hdev, legacy_evt_type, &info->bdaddr,
+                                          info->bdaddr_type, NULL, 0,
+@@ -7155,7 +7166,8 @@ static void hci_le_meta_evt(struct hci_dev *hdev, void *data,
+       /* Only match event if command OGF is for LE */
+       if (hdev->req_skb &&
+-          hci_opcode_ogf(hci_skb_opcode(hdev->req_skb)) == 0x08 &&
++         (hci_opcode_ogf(hci_skb_opcode(hdev->req_skb)) == 0x08 ||
++          hci_skb_opcode(hdev->req_skb) == HCI_OP_NOP) &&
+           hci_skb_event(hdev->req_skb) == ev->subevent) {
+               *opcode = hci_skb_opcode(hdev->req_skb);
+               hci_req_cmd_complete(hdev, *opcode, 0x00, req_complete,
+@@ -7511,8 +7523,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
+               goto done;
+       }
++      hci_dev_lock(hdev);
+       kfree_skb(hdev->recv_event);
+       hdev->recv_event = skb_clone(skb, GFP_KERNEL);
++      hci_dev_unlock(hdev);
+       event = hdr->evt;
+       if (!event) {
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index e56b1cbedab90..d00ff18f3be0d 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -6898,20 +6898,37 @@ int hci_le_conn_update_sync(struct hci_dev *hdev, struct hci_conn *conn,
+ static void create_pa_complete(struct hci_dev *hdev, void *data, int err)
+ {
++      struct hci_conn *conn = data;
++      struct hci_conn *pa_sync;
++
+       bt_dev_dbg(hdev, "err %d", err);
+-      if (!err)
++      if (err == -ECANCELED)
+               return;
++      hci_dev_lock(hdev);
++
+       hci_dev_clear_flag(hdev, HCI_PA_SYNC);
+-      if (err == -ECANCELED)
+-              return;
++      if (!hci_conn_valid(hdev, conn))
++              clear_bit(HCI_CONN_CREATE_PA_SYNC, &conn->flags);
+-      hci_dev_lock(hdev);
++      if (!err)
++              goto unlock;
+-      hci_update_passive_scan_sync(hdev);
++      /* Add connection to indicate PA sync error */
++      pa_sync = hci_conn_add_unset(hdev, ISO_LINK, BDADDR_ANY,
++                                   HCI_ROLE_SLAVE);
++      if (IS_ERR(pa_sync))
++              goto unlock;
++
++      set_bit(HCI_CONN_PA_SYNC_FAILED, &pa_sync->flags);
++
++      /* Notify iso layer */
++      hci_connect_cfm(pa_sync, bt_status(err));
++
++unlock:
+       hci_dev_unlock(hdev);
+ }
+@@ -6925,9 +6942,23 @@ static int hci_le_pa_create_sync(struct hci_dev *hdev, void *data)
+       if (!hci_conn_valid(hdev, conn))
+               return -ECANCELED;
++      if (conn->sync_handle != HCI_SYNC_HANDLE_INVALID)
++              return -EINVAL;
++
+       if (hci_dev_test_and_set_flag(hdev, HCI_PA_SYNC))
+               return -EBUSY;
++      /* Stop scanning if SID has not been set and active scanning is enabled
++       * so we use passive scanning which will be scanning using the allow
++       * list programmed to contain only the connection address.
++       */
++      if (conn->sid == HCI_SID_INVALID &&
++          hci_dev_test_flag(hdev, HCI_LE_SCAN)) {
++              hci_scan_disable_sync(hdev);
++              hci_dev_set_flag(hdev, HCI_LE_SCAN_INTERRUPTED);
++              hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
++      }
++
+       /* Mark HCI_CONN_CREATE_PA_SYNC so hci_update_passive_scan_sync can
+        * program the address in the allow list so PA advertisements can be
+        * received.
+@@ -6936,6 +6967,14 @@ static int hci_le_pa_create_sync(struct hci_dev *hdev, void *data)
+       hci_update_passive_scan_sync(hdev);
++      /* SID has not been set listen for HCI_EV_LE_EXT_ADV_REPORT to update
++       * it.
++       */
++      if (conn->sid == HCI_SID_INVALID)
++              __hci_cmd_sync_status_sk(hdev, HCI_OP_NOP, 0, NULL,
++                                       HCI_EV_LE_EXT_ADV_REPORT,
++                                       conn->conn_timeout, NULL);
++
+       memset(&cp, 0, sizeof(cp));
+       cp.options = qos->bcast.options;
+       cp.sid = conn->sid;
+diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
+index 2819cda616bce..7c0012ce1b890 100644
+--- a/net/bluetooth/iso.c
++++ b/net/bluetooth/iso.c
+@@ -941,7 +941,7 @@ static int iso_sock_bind_bc(struct socket *sock, struct sockaddr *addr,
+       iso_pi(sk)->dst_type = sa->iso_bc->bc_bdaddr_type;
+-      if (sa->iso_bc->bc_sid > 0x0f)
++      if (sa->iso_bc->bc_sid > 0x0f && sa->iso_bc->bc_sid != HCI_SID_INVALID)
+               return -EINVAL;
+       iso_pi(sk)->bc_sid = sa->iso_bc->bc_sid;
+@@ -2029,6 +2029,9 @@ static bool iso_match_sid(struct sock *sk, void *data)
+ {
+       struct hci_ev_le_pa_sync_established *ev = data;
++      if (iso_pi(sk)->bc_sid == HCI_SID_INVALID)
++              return true;
++
+       return ev->sid == iso_pi(sk)->bc_sid;
+ }
+@@ -2075,8 +2078,10 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
+       if (ev1) {
+               sk = iso_get_sock(&hdev->bdaddr, bdaddr, BT_LISTEN,
+                                 iso_match_sid, ev1);
+-              if (sk && !ev1->status)
++              if (sk && !ev1->status) {
+                       iso_pi(sk)->sync_handle = le16_to_cpu(ev1->handle);
++                      iso_pi(sk)->bc_sid = ev1->sid;
++              }
+               goto done;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/bluetooth-l2cap-fix-not-responding-with-l2cap_cr_le_.patch b/queue-6.15/bluetooth-l2cap-fix-not-responding-with-l2cap_cr_le_.patch
new file mode 100644 (file)
index 0000000..873087c
--- /dev/null
@@ -0,0 +1,40 @@
+From 99fe155285e4d6b6d445eaa29ebea2ab747a42f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 May 2025 14:53:11 -0400
+Subject: Bluetooth: L2CAP: Fix not responding with L2CAP_CR_LE_ENCRYPTION
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 03dba9cea72f977e873e4e60e220fa596959dd8f ]
+
+Depending on the security set the response to L2CAP_LE_CONN_REQ shall be
+just L2CAP_CR_LE_ENCRYPTION if only encryption when BT_SECURITY_MEDIUM
+is selected since that means security mode 2 which doesn't require
+authentication which is something that is covered in the qualification
+test L2CAP/LE/CFC/BV-25-C.
+
+Link: https://github.com/bluez/bluez/issues/1270
+Fixes: 27e2d4c8d28b ("Bluetooth: Add basic LE L2CAP connect request receiving support")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_core.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 042d3ac3b4a38..a5bde5db58efc 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -4870,7 +4870,8 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn,
+       if (!smp_sufficient_security(conn->hcon, pchan->sec_level,
+                                    SMP_ALLOW_STK)) {
+-              result = L2CAP_CR_LE_AUTHENTICATION;
++              result = pchan->sec_level == BT_SECURITY_MEDIUM ?
++                      L2CAP_CR_LE_ENCRYPTION : L2CAP_CR_LE_AUTHENTICATION;
+               chan = NULL;
+               goto response_unlock;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/bluetooth-mgmt-iterate-over-mesh-commands-in-mgmt_me.patch b/queue-6.15/bluetooth-mgmt-iterate-over-mesh-commands-in-mgmt_me.patch
new file mode 100644 (file)
index 0000000..1465f31
--- /dev/null
@@ -0,0 +1,36 @@
+From 4fb0c17d6bc69f6d219fb2dc616a234b9a27ee8e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 May 2025 11:42:30 +0300
+Subject: Bluetooth: MGMT: iterate over mesh commands in mgmt_mesh_foreach()
+
+From: Dmitry Antipov <dmantipov@yandex.ru>
+
+[ Upstream commit 3bb88524b7d030160bb3c9b35f928b2778092111 ]
+
+In 'mgmt_mesh_foreach()', iterate over mesh commands
+rather than generic mgmt ones. Compile tested only.
+
+Fixes: b338d91703fa ("Bluetooth: Implement support for Mesh")
+Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/mgmt_util.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/mgmt_util.c b/net/bluetooth/mgmt_util.c
+index e5ff65e424b5b..3713ff490c65d 100644
+--- a/net/bluetooth/mgmt_util.c
++++ b/net/bluetooth/mgmt_util.c
+@@ -304,7 +304,7 @@ void mgmt_mesh_foreach(struct hci_dev *hdev,
+ {
+       struct mgmt_mesh_tx *mesh_tx, *tmp;
+-      list_for_each_entry_safe(mesh_tx, tmp, &hdev->mgmt_pending, list) {
++      list_for_each_entry_safe(mesh_tx, tmp, &hdev->mesh_pending, list) {
+               if (!sk || mesh_tx->sk == sk)
+                       cb(mesh_tx, data);
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/bluetooth-mgmt-reject-malformed-hci_cmd_sync-command.patch b/queue-6.15/bluetooth-mgmt-reject-malformed-hci_cmd_sync-command.patch
new file mode 100644 (file)
index 0000000..dea154d
--- /dev/null
@@ -0,0 +1,43 @@
+From 3ea7bc5a6683d86a8dad9d0e39de9f356a42340c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 May 2025 21:16:02 +0300
+Subject: Bluetooth: MGMT: reject malformed HCI_CMD_SYNC commands
+
+From: Dmitry Antipov <dmantipov@yandex.ru>
+
+[ Upstream commit 03f1700b9b4d4f2fed3165370f3c23db76553178 ]
+
+In 'mgmt_hci_cmd_sync()', check whether the size of parameters passed
+in 'struct mgmt_cp_hci_cmd_sync' matches the total size of the data
+(i.e. 'sizeof(struct mgmt_cp_hci_cmd_sync)' plus trailing bytes).
+Otherwise, large invalid 'params_len' will cause 'hci_cmd_sync_alloc()'
+to do 'skb_put_data()' from an area beyond the one actually passed to
+'mgmt_hci_cmd_sync()'.
+
+Reported-by: syzbot+5fe2d5bfbfbec0b675a0@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=5fe2d5bfbfbec0b675a0
+Fixes: 827af4787e74 ("Bluetooth: MGMT: Add initial implementation of MGMT_OP_HCI_CMD_SYNC")
+Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/mgmt.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 261926dccc7e8..14a9462fced5e 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -2566,7 +2566,8 @@ static int mgmt_hci_cmd_sync(struct sock *sk, struct hci_dev *hdev,
+       struct mgmt_pending_cmd *cmd;
+       int err;
+-      if (len < sizeof(*cp))
++      if (len != (offsetof(struct mgmt_cp_hci_cmd_sync, params) +
++                  le16_to_cpu(cp->params_len)))
+               return mgmt_cmd_status(sk, hdev->id, MGMT_OP_HCI_CMD_SYNC,
+                                      MGMT_STATUS_INVALID_PARAMS);
+-- 
+2.39.5
+
diff --git a/queue-6.15/bluetooth-separate-cis_link-and-bis_link-link-types.patch b/queue-6.15/bluetooth-separate-cis_link-and-bis_link-link-types.patch
new file mode 100644 (file)
index 0000000..27ce93e
--- /dev/null
@@ -0,0 +1,627 @@
+From 3537f09d47584991ea8c040057ec62d1d20c19c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 3 May 2025 17:08:21 +0300
+Subject: Bluetooth: separate CIS_LINK and BIS_LINK link types
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit 23205562ffc8de20f57afdd984858cab29e77968 ]
+
+Use separate link type id for unicast and broadcast ISO connections.
+These connection types are handled with separate HCI commands, socket
+API is different, and hci_conn has union fields that are different in
+the two cases, so they shall not be mixed up.
+
+Currently in most places it is attempted to distinguish ucast by
+bacmp(&c->dst, BDADDR_ANY) but it is wrong as dst is set for bcast sink
+hci_conn in iso_conn_ready(). Additionally checking sync_handle might be
+OK, but depends on details of bcast conn configuration flow.
+
+To avoid complicating it, use separate link types.
+
+Fixes: f764a6c2c1e4 ("Bluetooth: ISO: Add broadcast support")
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/hci.h      |  3 +-
+ include/net/bluetooth/hci_core.h | 48 ++++++++++++++------------------
+ net/bluetooth/hci_conn.c         | 44 +++++++++++++++++------------
+ net/bluetooth/hci_core.c         | 21 ++++++++------
+ net/bluetooth/hci_event.c        | 24 ++++++++--------
+ net/bluetooth/hci_sync.c         | 16 +++++++----
+ net/bluetooth/iso.c              |  4 +--
+ net/bluetooth/mgmt.c             |  3 +-
+ 8 files changed, 89 insertions(+), 74 deletions(-)
+
+diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
+index 797992019f9ee..521a9d0acac69 100644
+--- a/include/net/bluetooth/hci.h
++++ b/include/net/bluetooth/hci.h
+@@ -557,7 +557,8 @@ enum {
+ #define ESCO_LINK     0x02
+ /* Low Energy links do not have defined link type. Use invented one */
+ #define LE_LINK               0x80
+-#define ISO_LINK      0x82
++#define CIS_LINK      0x82
++#define BIS_LINK      0x83
+ #define INVALID_LINK  0xff
+ /* LMP features */
+diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
+index 54bfeeaa09959..fc66d9b61198e 100644
+--- a/include/net/bluetooth/hci_core.h
++++ b/include/net/bluetooth/hci_core.h
+@@ -996,7 +996,8 @@ static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c)
+       case ESCO_LINK:
+               h->sco_num++;
+               break;
+-      case ISO_LINK:
++      case CIS_LINK:
++      case BIS_LINK:
+               h->iso_num++;
+               break;
+       }
+@@ -1022,7 +1023,8 @@ static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c)
+       case ESCO_LINK:
+               h->sco_num--;
+               break;
+-      case ISO_LINK:
++      case CIS_LINK:
++      case BIS_LINK:
+               h->iso_num--;
+               break;
+       }
+@@ -1039,7 +1041,8 @@ static inline unsigned int hci_conn_num(struct hci_dev *hdev, __u8 type)
+       case SCO_LINK:
+       case ESCO_LINK:
+               return h->sco_num;
+-      case ISO_LINK:
++      case CIS_LINK:
++      case BIS_LINK:
+               return h->iso_num;
+       default:
+               return 0;
+@@ -1100,7 +1103,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_bis(struct hci_dev *hdev,
+       rcu_read_lock();
+       list_for_each_entry_rcu(c, &h->list, list) {
+-              if (bacmp(&c->dst, ba) || c->type != ISO_LINK)
++              if (bacmp(&c->dst, ba) || c->type != BIS_LINK)
+                       continue;
+               if (c->iso_qos.bcast.bis == bis) {
+@@ -1122,7 +1125,7 @@ hci_conn_hash_lookup_create_pa_sync(struct hci_dev *hdev)
+       rcu_read_lock();
+       list_for_each_entry_rcu(c, &h->list, list) {
+-              if (c->type != ISO_LINK)
++              if (c->type != BIS_LINK)
+                       continue;
+               if (!test_bit(HCI_CONN_CREATE_PA_SYNC, &c->flags))
+@@ -1148,8 +1151,8 @@ hci_conn_hash_lookup_per_adv_bis(struct hci_dev *hdev,
+       rcu_read_lock();
+       list_for_each_entry_rcu(c, &h->list, list) {
+-              if (bacmp(&c->dst, ba) || c->type != ISO_LINK ||
+-                      !test_bit(HCI_CONN_PER_ADV, &c->flags))
++              if (bacmp(&c->dst, ba) || c->type != BIS_LINK ||
++                  !test_bit(HCI_CONN_PER_ADV, &c->flags))
+                       continue;
+               if (c->iso_qos.bcast.big == big &&
+@@ -1238,7 +1241,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_cis(struct hci_dev *hdev,
+       rcu_read_lock();
+       list_for_each_entry_rcu(c, &h->list, list) {
+-              if (c->type != ISO_LINK || !bacmp(&c->dst, BDADDR_ANY))
++              if (c->type != CIS_LINK)
+                       continue;
+               /* Match CIG ID if set */
+@@ -1270,7 +1273,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_cig(struct hci_dev *hdev,
+       rcu_read_lock();
+       list_for_each_entry_rcu(c, &h->list, list) {
+-              if (c->type != ISO_LINK || !bacmp(&c->dst, BDADDR_ANY))
++              if (c->type != CIS_LINK)
+                       continue;
+               if (handle == c->iso_qos.ucast.cig) {
+@@ -1293,17 +1296,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_big(struct hci_dev *hdev,
+       rcu_read_lock();
+       list_for_each_entry_rcu(c, &h->list, list) {
+-              if (c->type != ISO_LINK)
+-                      continue;
+-
+-              /* An ISO_LINK hcon with BDADDR_ANY as destination
+-               * address is a Broadcast connection. A Broadcast
+-               * slave connection is associated with a PA train,
+-               * so the sync_handle can be used to differentiate
+-               * from unicast.
+-               */
+-              if (bacmp(&c->dst, BDADDR_ANY) &&
+-                  c->sync_handle == HCI_SYNC_HANDLE_INVALID)
++              if (c->type != BIS_LINK)
+                       continue;
+               if (handle == c->iso_qos.bcast.big) {
+@@ -1327,7 +1320,7 @@ hci_conn_hash_lookup_big_sync_pend(struct hci_dev *hdev,
+       rcu_read_lock();
+       list_for_each_entry_rcu(c, &h->list, list) {
+-              if (c->type != ISO_LINK)
++              if (c->type != BIS_LINK)
+                       continue;
+               if (handle == c->iso_qos.bcast.big && num_bis == c->num_bis) {
+@@ -1350,8 +1343,8 @@ hci_conn_hash_lookup_big_state(struct hci_dev *hdev, __u8 handle,  __u16 state)
+       rcu_read_lock();
+       list_for_each_entry_rcu(c, &h->list, list) {
+-              if (bacmp(&c->dst, BDADDR_ANY) || c->type != ISO_LINK ||
+-                      c->state != state)
++              if (c->type != BIS_LINK || bacmp(&c->dst, BDADDR_ANY) ||
++                  c->state != state)
+                       continue;
+               if (handle == c->iso_qos.bcast.big) {
+@@ -1374,8 +1367,8 @@ hci_conn_hash_lookup_pa_sync_big_handle(struct hci_dev *hdev, __u8 big)
+       rcu_read_lock();
+       list_for_each_entry_rcu(c, &h->list, list) {
+-              if (c->type != ISO_LINK ||
+-                      !test_bit(HCI_CONN_PA_SYNC, &c->flags))
++              if (c->type != BIS_LINK ||
++                  !test_bit(HCI_CONN_PA_SYNC, &c->flags))
+                       continue;
+               if (c->iso_qos.bcast.big == big) {
+@@ -1397,7 +1390,7 @@ hci_conn_hash_lookup_pa_sync_handle(struct hci_dev *hdev, __u16 sync_handle)
+       rcu_read_lock();
+       list_for_each_entry_rcu(c, &h->list, list) {
+-              if (c->type != ISO_LINK)
++              if (c->type != BIS_LINK)
+                       continue;
+               /* Ignore the listen hcon, we are looking
+@@ -2012,7 +2005,8 @@ static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr,
+       case ESCO_LINK:
+               return sco_connect_ind(hdev, bdaddr, flags);
+-      case ISO_LINK:
++      case CIS_LINK:
++      case BIS_LINK:
+               return iso_connect_ind(hdev, bdaddr, flags);
+       default:
+diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
+index c0207812f4328..fccdb864af726 100644
+--- a/net/bluetooth/hci_conn.c
++++ b/net/bluetooth/hci_conn.c
+@@ -785,7 +785,7 @@ static int hci_le_big_terminate(struct hci_dev *hdev, u8 big, struct hci_conn *c
+       d->sync_handle = conn->sync_handle;
+       if (test_and_clear_bit(HCI_CONN_PA_SYNC, &conn->flags)) {
+-              hci_conn_hash_list_flag(hdev, find_bis, ISO_LINK,
++              hci_conn_hash_list_flag(hdev, find_bis, BIS_LINK,
+                                       HCI_CONN_PA_SYNC, d);
+               if (!d->count)
+@@ -795,7 +795,7 @@ static int hci_le_big_terminate(struct hci_dev *hdev, u8 big, struct hci_conn *c
+       }
+       if (test_and_clear_bit(HCI_CONN_BIG_SYNC, &conn->flags)) {
+-              hci_conn_hash_list_flag(hdev, find_bis, ISO_LINK,
++              hci_conn_hash_list_flag(hdev, find_bis, BIS_LINK,
+                                       HCI_CONN_BIG_SYNC, d);
+               if (!d->count)
+@@ -885,9 +885,11 @@ static void cis_cleanup(struct hci_conn *conn)
+       /* Check if ISO connection is a CIS and remove CIG if there are
+        * no other connections using it.
+        */
+-      hci_conn_hash_list_state(hdev, find_cis, ISO_LINK, BT_BOUND, &d);
+-      hci_conn_hash_list_state(hdev, find_cis, ISO_LINK, BT_CONNECT, &d);
+-      hci_conn_hash_list_state(hdev, find_cis, ISO_LINK, BT_CONNECTED, &d);
++      hci_conn_hash_list_state(hdev, find_cis, CIS_LINK, BT_BOUND, &d);
++      hci_conn_hash_list_state(hdev, find_cis, CIS_LINK, BT_CONNECT,
++                               &d);
++      hci_conn_hash_list_state(hdev, find_cis, CIS_LINK, BT_CONNECTED,
++                               &d);
+       if (d.count)
+               return;
+@@ -910,7 +912,8 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t
+               if (!hdev->acl_mtu)
+                       return ERR_PTR(-ECONNREFUSED);
+               break;
+-      case ISO_LINK:
++      case CIS_LINK:
++      case BIS_LINK:
+               if (hdev->iso_mtu)
+                       /* Dedicated ISO Buffer exists */
+                       break;
+@@ -974,7 +977,8 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t
+               hci_copy_identity_address(hdev, &conn->src, &conn->src_type);
+               conn->mtu = hdev->le_mtu ? hdev->le_mtu : hdev->acl_mtu;
+               break;
+-      case ISO_LINK:
++      case CIS_LINK:
++      case BIS_LINK:
+               /* conn->src should reflect the local identity address */
+               hci_copy_identity_address(hdev, &conn->src, &conn->src_type);
+@@ -1071,7 +1075,8 @@ static void hci_conn_cleanup_child(struct hci_conn *conn, u8 reason)
+               if (HCI_CONN_HANDLE_UNSET(conn->handle))
+                       hci_conn_failed(conn, reason);
+               break;
+-      case ISO_LINK:
++      case CIS_LINK:
++      case BIS_LINK:
+               if ((conn->state != BT_CONNECTED &&
+                   !test_bit(HCI_CONN_CREATE_CIS, &conn->flags)) ||
+                   test_bit(HCI_CONN_BIG_CREATED, &conn->flags))
+@@ -1146,7 +1151,8 @@ void hci_conn_del(struct hci_conn *conn)
+                       hdev->acl_cnt += conn->sent;
+       } else {
+               /* Unacked ISO frames */
+-              if (conn->type == ISO_LINK) {
++              if (conn->type == CIS_LINK ||
++                  conn->type == BIS_LINK) {
+                       if (hdev->iso_pkts)
+                               hdev->iso_cnt += conn->sent;
+                       else if (hdev->le_pkts)
+@@ -1532,7 +1538,7 @@ static struct hci_conn *hci_add_bis(struct hci_dev *hdev, bdaddr_t *dst,
+                    memcmp(conn->le_per_adv_data, base, base_len)))
+               return ERR_PTR(-EADDRINUSE);
+-      conn = hci_conn_add_unset(hdev, ISO_LINK, dst, HCI_ROLE_MASTER);
++      conn = hci_conn_add_unset(hdev, BIS_LINK, dst, HCI_ROLE_MASTER);
+       if (IS_ERR(conn))
+               return conn;
+@@ -1740,7 +1746,7 @@ static int hci_le_create_big(struct hci_conn *conn, struct bt_iso_qos *qos)
+       data.count = 0;
+       /* Create a BIS for each bound connection */
+-      hci_conn_hash_list_state(hdev, bis_list, ISO_LINK,
++      hci_conn_hash_list_state(hdev, bis_list, BIS_LINK,
+                                BT_BOUND, &data);
+       cp.handle = qos->bcast.big;
+@@ -1829,12 +1835,12 @@ static bool hci_le_set_cig_params(struct hci_conn *conn, struct bt_iso_qos *qos)
+               for (data.cig = 0x00; data.cig < 0xf0; data.cig++) {
+                       data.count = 0;
+-                      hci_conn_hash_list_state(hdev, find_cis, ISO_LINK,
++                      hci_conn_hash_list_state(hdev, find_cis, CIS_LINK,
+                                                BT_CONNECT, &data);
+                       if (data.count)
+                               continue;
+-                      hci_conn_hash_list_state(hdev, find_cis, ISO_LINK,
++                      hci_conn_hash_list_state(hdev, find_cis, CIS_LINK,
+                                                BT_CONNECTED, &data);
+                       if (!data.count)
+                               break;
+@@ -1884,7 +1890,8 @@ struct hci_conn *hci_bind_cis(struct hci_dev *hdev, bdaddr_t *dst,
+       cis = hci_conn_hash_lookup_cis(hdev, dst, dst_type, qos->ucast.cig,
+                                      qos->ucast.cis);
+       if (!cis) {
+-              cis = hci_conn_add_unset(hdev, ISO_LINK, dst, HCI_ROLE_MASTER);
++              cis = hci_conn_add_unset(hdev, CIS_LINK, dst,
++                                       HCI_ROLE_MASTER);
+               if (IS_ERR(cis))
+                       return cis;
+               cis->cleanup = cis_cleanup;
+@@ -1976,7 +1983,7 @@ bool hci_iso_setup_path(struct hci_conn *conn)
+ int hci_conn_check_create_cis(struct hci_conn *conn)
+ {
+-      if (conn->type != ISO_LINK || !bacmp(&conn->dst, BDADDR_ANY))
++      if (conn->type != CIS_LINK)
+               return -EINVAL;
+       if (!conn->parent || conn->parent->state != BT_CONNECTED ||
+@@ -2072,7 +2079,7 @@ struct hci_conn *hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst,
+       bt_dev_dbg(hdev, "dst %pMR type %d sid %d", dst, dst_type, sid);
+-      conn = hci_conn_add_unset(hdev, ISO_LINK, dst, HCI_ROLE_SLAVE);
++      conn = hci_conn_add_unset(hdev, BIS_LINK, dst, HCI_ROLE_SLAVE);
+       if (IS_ERR(conn))
+               return conn;
+@@ -2221,7 +2228,7 @@ struct hci_conn *hci_connect_bis(struct hci_dev *hdev, bdaddr_t *dst,
+        * the start periodic advertising and create BIG commands have
+        * been queued
+        */
+-      hci_conn_hash_list_state(hdev, bis_mark_per_adv, ISO_LINK,
++      hci_conn_hash_list_state(hdev, bis_mark_per_adv, BIS_LINK,
+                                BT_BOUND, &data);
+       /* Queue start periodic advertising and create BIG */
+@@ -2953,7 +2960,8 @@ void hci_conn_tx_queue(struct hci_conn *conn, struct sk_buff *skb)
+        * TODO: SCO support without flowctl (needs to be done in drivers)
+        */
+       switch (conn->type) {
+-      case ISO_LINK:
++      case CIS_LINK:
++      case BIS_LINK:
+       case ACL_LINK:
+       case LE_LINK:
+               break;
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index 75da6f6e39c9e..2668e0e563c43 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -2898,12 +2898,13 @@ int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
+               break;
+       case HCI_ACLDATA_PKT:
+               /* Detect if ISO packet has been sent as ACL */
+-              if (hci_conn_num(hdev, ISO_LINK)) {
++              if (hci_conn_num(hdev, CIS_LINK) ||
++                  hci_conn_num(hdev, BIS_LINK)) {
+                       __u16 handle = __le16_to_cpu(hci_acl_hdr(skb)->handle);
+                       __u8 type;
+                       type = hci_conn_lookup_type(hdev, hci_handle(handle));
+-                      if (type == ISO_LINK)
++                      if (type == CIS_LINK || type == BIS_LINK)
+                               hci_skb_pkt_type(skb) = HCI_ISODATA_PKT;
+               }
+               break;
+@@ -3345,7 +3346,8 @@ static inline void hci_quote_sent(struct hci_conn *conn, int num, int *quote)
+       case LE_LINK:
+               cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
+               break;
+-      case ISO_LINK:
++      case CIS_LINK:
++      case BIS_LINK:
+               cnt = hdev->iso_mtu ? hdev->iso_cnt :
+                       hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
+               break;
+@@ -3359,7 +3361,7 @@ static inline void hci_quote_sent(struct hci_conn *conn, int num, int *quote)
+ }
+ static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
+-                                   int *quote)
++                                   __u8 type2, int *quote)
+ {
+       struct hci_conn_hash *h = &hdev->conn_hash;
+       struct hci_conn *conn = NULL, *c;
+@@ -3371,7 +3373,8 @@ static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
+       rcu_read_lock();
+       list_for_each_entry_rcu(c, &h->list, list) {
+-              if (c->type != type || skb_queue_empty(&c->data_q))
++              if ((c->type != type && c->type != type2) ||
++                  skb_queue_empty(&c->data_q))
+                       continue;
+               if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
+@@ -3579,7 +3582,7 @@ static void hci_sched_sco(struct hci_dev *hdev, __u8 type)
+       else
+               cnt = &hdev->sco_cnt;
+-      while (*cnt && (conn = hci_low_sent(hdev, type, &quote))) {
++      while (*cnt && (conn = hci_low_sent(hdev, type, type, &quote))) {
+               while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
+                       BT_DBG("skb %p len %d", skb, skb->len);
+                       hci_send_conn_frame(hdev, conn, skb);
+@@ -3707,12 +3710,14 @@ static void hci_sched_iso(struct hci_dev *hdev)
+       BT_DBG("%s", hdev->name);
+-      if (!hci_conn_num(hdev, ISO_LINK))
++      if (!hci_conn_num(hdev, CIS_LINK) &&
++          !hci_conn_num(hdev, BIS_LINK))
+               return;
+       cnt = hdev->iso_pkts ? &hdev->iso_cnt :
+               hdev->le_pkts ? &hdev->le_cnt : &hdev->acl_cnt;
+-      while (*cnt && (conn = hci_low_sent(hdev, ISO_LINK, &quote))) {
++      while (*cnt && (conn = hci_low_sent(hdev, CIS_LINK, BIS_LINK,
++                                          &quote))) {
+               while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
+                       BT_DBG("skb %p len %d", skb, skb->len);
+                       hci_send_conn_frame(hdev, conn, skb);
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 4183560582a3a..66052d6aaa1d5 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -3804,7 +3804,7 @@ static void hci_unbound_cis_failed(struct hci_dev *hdev, u8 cig, u8 status)
+       lockdep_assert_held(&hdev->lock);
+       list_for_each_entry_safe(conn, tmp, &hdev->conn_hash.list, list) {
+-              if (conn->type != ISO_LINK || !bacmp(&conn->dst, BDADDR_ANY) ||
++              if (conn->type != CIS_LINK ||
+                   conn->state == BT_OPEN || conn->iso_qos.ucast.cig != cig)
+                       continue;
+@@ -4467,7 +4467,8 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data,
+                       break;
+-              case ISO_LINK:
++              case CIS_LINK:
++              case BIS_LINK:
+                       if (hdev->iso_pkts) {
+                               hdev->iso_cnt += count;
+                               if (hdev->iso_cnt > hdev->iso_pkts)
+@@ -6413,7 +6414,8 @@ static void hci_le_pa_sync_estabilished_evt(struct hci_dev *hdev, void *data,
+       conn->sync_handle = le16_to_cpu(ev->handle);
+       conn->sid = HCI_SID_INVALID;
+-      mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ISO_LINK, &flags);
++      mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, BIS_LINK,
++                                    &flags);
+       if (!(mask & HCI_LM_ACCEPT)) {
+               hci_le_pa_term_sync(hdev, ev->handle);
+               goto unlock;
+@@ -6423,7 +6425,7 @@ static void hci_le_pa_sync_estabilished_evt(struct hci_dev *hdev, void *data,
+               goto unlock;
+       /* Add connection to indicate PA sync event */
+-      pa_sync = hci_conn_add_unset(hdev, ISO_LINK, BDADDR_ANY,
++      pa_sync = hci_conn_add_unset(hdev, BIS_LINK, BDADDR_ANY,
+                                    HCI_ROLE_SLAVE);
+       if (IS_ERR(pa_sync))
+@@ -6454,7 +6456,7 @@ static void hci_le_per_adv_report_evt(struct hci_dev *hdev, void *data,
+       hci_dev_lock(hdev);
+-      mask |= hci_proto_connect_ind(hdev, BDADDR_ANY, ISO_LINK, &flags);
++      mask |= hci_proto_connect_ind(hdev, BDADDR_ANY, BIS_LINK, &flags);
+       if (!(mask & HCI_LM_ACCEPT))
+               goto unlock;
+@@ -6738,7 +6740,7 @@ static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data,
+               goto unlock;
+       }
+-      if (conn->type != ISO_LINK) {
++      if (conn->type != CIS_LINK) {
+               bt_dev_err(hdev,
+                          "Invalid connection link type handle 0x%4.4x",
+                          handle);
+@@ -6856,7 +6858,7 @@ static void hci_le_cis_req_evt(struct hci_dev *hdev, void *data,
+       if (!acl)
+               goto unlock;
+-      mask = hci_proto_connect_ind(hdev, &acl->dst, ISO_LINK, &flags);
++      mask = hci_proto_connect_ind(hdev, &acl->dst, CIS_LINK, &flags);
+       if (!(mask & HCI_LM_ACCEPT)) {
+               hci_le_reject_cis(hdev, ev->cis_handle);
+               goto unlock;
+@@ -6864,8 +6866,8 @@ static void hci_le_cis_req_evt(struct hci_dev *hdev, void *data,
+       cis = hci_conn_hash_lookup_handle(hdev, cis_handle);
+       if (!cis) {
+-              cis = hci_conn_add(hdev, ISO_LINK, &acl->dst, HCI_ROLE_SLAVE,
+-                                 cis_handle);
++              cis = hci_conn_add(hdev, CIS_LINK, &acl->dst,
++                                 HCI_ROLE_SLAVE, cis_handle);
+               if (IS_ERR(cis)) {
+                       hci_le_reject_cis(hdev, ev->cis_handle);
+                       goto unlock;
+@@ -6980,7 +6982,7 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data,
+                               bt_dev_dbg(hdev, "ignore too large handle %u", handle);
+                               continue;
+                       }
+-                      bis = hci_conn_add(hdev, ISO_LINK, BDADDR_ANY,
++                      bis = hci_conn_add(hdev, BIS_LINK, BDADDR_ANY,
+                                          HCI_ROLE_SLAVE, handle);
+                       if (IS_ERR(bis))
+                               continue;
+@@ -7036,7 +7038,7 @@ static void hci_le_big_info_adv_report_evt(struct hci_dev *hdev, void *data,
+       hci_dev_lock(hdev);
+-      mask |= hci_proto_connect_ind(hdev, BDADDR_ANY, ISO_LINK, &flags);
++      mask |= hci_proto_connect_ind(hdev, BDADDR_ANY, BIS_LINK, &flags);
+       if (!(mask & HCI_LM_ACCEPT))
+               goto unlock;
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index d00ff18f3be0d..62d1ff951ebe6 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -2860,7 +2860,7 @@ static int hci_le_set_ext_scan_param_sync(struct hci_dev *hdev, u8 type,
+               if (sent) {
+                       struct hci_conn *conn;
+-                      conn = hci_conn_hash_lookup_ba(hdev, ISO_LINK,
++                      conn = hci_conn_hash_lookup_ba(hdev, BIS_LINK,
+                                                      &sent->bdaddr);
+                       if (conn) {
+                               struct bt_iso_qos *qos = &conn->iso_qos;
+@@ -5477,7 +5477,7 @@ static int hci_connect_cancel_sync(struct hci_dev *hdev, struct hci_conn *conn,
+       if (conn->type == LE_LINK)
+               return hci_le_connect_cancel_sync(hdev, conn, reason);
+-      if (conn->type == ISO_LINK) {
++      if (conn->type == CIS_LINK) {
+               /* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E
+                * page 1857:
+                *
+@@ -5490,9 +5490,10 @@ static int hci_connect_cancel_sync(struct hci_dev *hdev, struct hci_conn *conn,
+                       return hci_disconnect_sync(hdev, conn, reason);
+               /* CIS with no Create CIS sent have nothing to cancel */
+-              if (bacmp(&conn->dst, BDADDR_ANY))
+-                      return HCI_ERROR_LOCAL_HOST_TERM;
++              return HCI_ERROR_LOCAL_HOST_TERM;
++      }
++      if (conn->type == BIS_LINK) {
+               /* There is no way to cancel a BIS without terminating the BIG
+                * which is done later on connection cleanup.
+                */
+@@ -5554,9 +5555,12 @@ static int hci_reject_conn_sync(struct hci_dev *hdev, struct hci_conn *conn,
+ {
+       struct hci_cp_reject_conn_req cp;
+-      if (conn->type == ISO_LINK)
++      if (conn->type == CIS_LINK)
+               return hci_le_reject_cis_sync(hdev, conn, reason);
++      if (conn->type == BIS_LINK)
++              return -EINVAL;
++
+       if (conn->type == SCO_LINK || conn->type == ESCO_LINK)
+               return hci_reject_sco_sync(hdev, conn, reason);
+@@ -6917,7 +6921,7 @@ static void create_pa_complete(struct hci_dev *hdev, void *data, int err)
+               goto unlock;
+       /* Add connection to indicate PA sync error */
+-      pa_sync = hci_conn_add_unset(hdev, ISO_LINK, BDADDR_ANY,
++      pa_sync = hci_conn_add_unset(hdev, BIS_LINK, BDADDR_ANY,
+                                    HCI_ROLE_SLAVE);
+       if (IS_ERR(pa_sync))
+diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
+index 7c0012ce1b890..5389af86bdae4 100644
+--- a/net/bluetooth/iso.c
++++ b/net/bluetooth/iso.c
+@@ -2208,7 +2208,7 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
+ static void iso_connect_cfm(struct hci_conn *hcon, __u8 status)
+ {
+-      if (hcon->type != ISO_LINK) {
++      if (hcon->type != CIS_LINK && hcon->type != BIS_LINK) {
+               if (hcon->type != LE_LINK)
+                       return;
+@@ -2249,7 +2249,7 @@ static void iso_connect_cfm(struct hci_conn *hcon, __u8 status)
+ static void iso_disconn_cfm(struct hci_conn *hcon, __u8 reason)
+ {
+-      if (hcon->type != ISO_LINK)
++      if (hcon->type != CIS_LINK && hcon->type != BIS_LINK)
+               return;
+       BT_DBG("hcon %p reason %d", hcon, reason);
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 46b22708dfbd2..261926dccc7e8 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -3221,7 +3221,8 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data,
+ static u8 link_to_bdaddr(u8 link_type, u8 addr_type)
+ {
+       switch (link_type) {
+-      case ISO_LINK:
++      case CIS_LINK:
++      case BIS_LINK:
+       case LE_LINK:
+               switch (addr_type) {
+               case ADDR_LE_DEV_PUBLIC:
+-- 
+2.39.5
+
diff --git a/queue-6.15/bonding-assign-random-address-if-device-address-is-s.patch b/queue-6.15/bonding-assign-random-address-if-device-address-is-s.patch
new file mode 100644 (file)
index 0000000..5673faf
--- /dev/null
@@ -0,0 +1,92 @@
+From b9d5a5df261c0b52c6ba38667c73af45c85026da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Apr 2025 04:22:38 +0000
+Subject: bonding: assign random address if device address is same as bond
+
+From: Hangbin Liu <liuhangbin@gmail.com>
+
+[ Upstream commit 5c3bf6cba7911f470afd748606be5c03a9512fcc ]
+
+This change addresses a MAC address conflict issue in failover scenarios,
+similar to the problem described in commit a951bc1e6ba5 ("bonding: correct
+the MAC address for 'follow' fail_over_mac policy").
+
+In fail_over_mac=follow mode, the bonding driver expects the formerly active
+slave to swap MAC addresses with the newly active slave during failover.
+However, under certain conditions, two slaves may end up with the same MAC
+address, which breaks this policy:
+
+1) ip link set eth0 master bond0
+   -> bond0 adopts eth0's MAC address (MAC0).
+
+2) ip link set eth1 master bond0
+   -> eth1 is added as a backup with its own MAC (MAC1).
+
+3) ip link set eth0 nomaster
+   -> eth0 is released and restores its MAC (MAC0).
+   -> eth1 becomes the active slave, and bond0 assigns MAC0 to eth1.
+
+4) ip link set eth0 master bond0
+   -> eth0 is re-added to bond0, now both eth0 and eth1 have MAC0.
+
+This results in a MAC address conflict and violates the expected behavior
+of the failover policy.
+
+To fix this, we assign a random MAC address to any newly added slave if
+its current MAC address matches that of the bond. The original (permanent)
+MAC address is saved and will be restored when the device is released
+from the bond.
+
+This ensures that each slave has a unique MAC address during failover
+transitions, preserving the integrity of the fail_over_mac=follow policy.
+
+Fixes: 3915c1e8634a ("bonding: Add "follow" option to fail_over_mac")
+Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
+Acked-by: Jay Vosburgh <jv@jvosburgh.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/bonding/bond_main.c | 25 ++++++++++++++++++-------
+ 1 file changed, 18 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index 4461220bcd58d..17ae4b819a597 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -2115,15 +2115,26 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
+                * set the master's mac address to that of the first slave
+                */
+               memcpy(ss.__data, bond_dev->dev_addr, bond_dev->addr_len);
+-              ss.ss_family = slave_dev->type;
+-              res = dev_set_mac_address(slave_dev, (struct sockaddr *)&ss,
+-                                        extack);
+-              if (res) {
+-                      slave_err(bond_dev, slave_dev, "Error %d calling set_mac_address\n", res);
+-                      goto err_restore_mtu;
+-              }
++      } else if (bond->params.fail_over_mac == BOND_FOM_FOLLOW &&
++                 BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP &&
++                 memcmp(slave_dev->dev_addr, bond_dev->dev_addr, bond_dev->addr_len) == 0) {
++              /* Set slave to random address to avoid duplicate mac
++               * address in later fail over.
++               */
++              eth_random_addr(ss.__data);
++      } else {
++              goto skip_mac_set;
+       }
++      ss.ss_family = slave_dev->type;
++      res = dev_set_mac_address(slave_dev, (struct sockaddr *)&ss, extack);
++      if (res) {
++              slave_err(bond_dev, slave_dev, "Error %d calling set_mac_address\n", res);
++              goto err_restore_mtu;
++      }
++
++skip_mac_set:
++
+       /* set no_addrconf flag before open to prevent IPv6 addrconf */
+       slave_dev->priv_flags |= IFF_NO_ADDRCONF;
+-- 
+2.39.5
+
diff --git a/queue-6.15/bonding-fix-multiple-long-standing-offload-races.patch b/queue-6.15/bonding-fix-multiple-long-standing-offload-races.patch
new file mode 100644 (file)
index 0000000..c4b927e
--- /dev/null
@@ -0,0 +1,220 @@
+From 56b88b94b098fa14f13a0495f550d0c5f118cb2b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Apr 2025 10:49:58 +0300
+Subject: bonding: Fix multiple long standing offload races
+
+From: Cosmin Ratiu <cratiu@nvidia.com>
+
+[ Upstream commit d2fddbd3479928e52061e1c8dd302006b6283ce8 ]
+
+Refactor the bonding ipsec offload operations to fix a number of
+long-standing control plane races between state migration and user
+deletion and a few other issues.
+
+xfrm state deletion can happen concurrently with
+bond_change_active_slave() operation. This manifests itself as a
+bond_ipsec_del_sa() call with x->lock held, followed by a
+bond_ipsec_free_sa() a bit later from a wq. The alternate path of
+these calls coming from xfrm_dev_state_flush() can't happen, as that
+needs the RTNL lock and bond_change_active_slave() already holds it.
+
+1. bond_ipsec_del_sa_all() might call xdo_dev_state_delete() a second
+   time on an xfrm state that was concurrently killed. This is bad.
+2. bond_ipsec_add_sa_all() can add a state on the new device, but
+   pending bond_ipsec_free_sa() calls from the old device will then hit
+   the WARN_ON() and then, worse, call xdo_dev_state_free() on the new
+   device without a corresponding xdo_dev_state_delete().
+3. Resolve a sleeping in atomic context introduced by the mentioned
+   "Fixes" commit.
+
+bond_ipsec_del_sa_all() and bond_ipsec_add_sa_all() now acquire x->lock
+and check for x->km.state to help with problems 1 and 2. And since
+xso.real_dev is now a private pointer managed by the bonding driver in
+xfrm state, make better use of it to fully fix problems 1 and 2. In
+bond_ipsec_del_sa_all(), set xso.real_dev to NULL while holding both the
+mutex and x->lock, which makes sure that neither bond_ipsec_del_sa() nor
+bond_ipsec_free_sa() could run concurrently.
+
+Fix problem 3 by moving the list cleanup (which requires the mutex) from
+bond_ipsec_del_sa() (called from atomic context) to bond_ipsec_free_sa()
+
+Finally, simplify bond_ipsec_del_sa() and bond_ipsec_free_sa() by using
+xso->real_dev directly, since it's now protected by locks and can be
+trusted to always reflect the offload device.
+
+Fixes: 2aeeef906d5a ("bonding: change ipsec_lock from spin lock to mutex")
+Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
+Reviewed-by: Hangbin Liu <liuhangbin@gmail.com>
+Tested-by: Hangbin Liu <liuhangbin@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/bonding/bond_main.c | 82 +++++++++++++++------------------
+ include/net/xfrm.h              |  7 ++-
+ 2 files changed, 41 insertions(+), 48 deletions(-)
+
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index 14ebbe82a2c5b..4461220bcd58d 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -545,7 +545,20 @@ static void bond_ipsec_add_sa_all(struct bonding *bond)
+                       slave_warn(bond_dev, real_dev, "%s: failed to add SA\n", __func__);
+                       continue;
+               }
++
++              spin_lock_bh(&ipsec->xs->lock);
++              /* xs might have been killed by the user during the migration
++               * to the new dev, but bond_ipsec_del_sa() should have done
++               * nothing, as xso.real_dev is NULL.
++               * Delete it from the device we just added it to. The pending
++               * bond_ipsec_free_sa() call will do the rest of the cleanup.
++               */
++              if (ipsec->xs->km.state == XFRM_STATE_DEAD &&
++                  real_dev->xfrmdev_ops->xdo_dev_state_delete)
++                      real_dev->xfrmdev_ops->xdo_dev_state_delete(real_dev,
++                                                                  ipsec->xs);
+               ipsec->xs->xso.real_dev = real_dev;
++              spin_unlock_bh(&ipsec->xs->lock);
+       }
+ out:
+       mutex_unlock(&bond->ipsec_lock);
+@@ -560,48 +573,20 @@ static void bond_ipsec_del_sa(struct net_device *bond_dev,
+                             struct xfrm_state *xs)
+ {
+       struct net_device *real_dev;
+-      netdevice_tracker tracker;
+-      struct bond_ipsec *ipsec;
+-      struct bonding *bond;
+-      struct slave *slave;
+-      if (!bond_dev)
++      if (!bond_dev || !xs->xso.real_dev)
+               return;
+-      rcu_read_lock();
+-      bond = netdev_priv(bond_dev);
+-      slave = rcu_dereference(bond->curr_active_slave);
+-      real_dev = slave ? slave->dev : NULL;
+-      netdev_hold(real_dev, &tracker, GFP_ATOMIC);
+-      rcu_read_unlock();
+-
+-      if (!slave)
+-              goto out;
+-
+-      if (!xs->xso.real_dev)
+-              goto out;
+-
+-      WARN_ON(xs->xso.real_dev != real_dev);
++      real_dev = xs->xso.real_dev;
+       if (!real_dev->xfrmdev_ops ||
+           !real_dev->xfrmdev_ops->xdo_dev_state_delete ||
+           netif_is_bond_master(real_dev)) {
+               slave_warn(bond_dev, real_dev, "%s: no slave xdo_dev_state_delete\n", __func__);
+-              goto out;
++              return;
+       }
+       real_dev->xfrmdev_ops->xdo_dev_state_delete(real_dev, xs);
+-out:
+-      netdev_put(real_dev, &tracker);
+-      mutex_lock(&bond->ipsec_lock);
+-      list_for_each_entry(ipsec, &bond->ipsec_list, list) {
+-              if (ipsec->xs == xs) {
+-                      list_del(&ipsec->list);
+-                      kfree(ipsec);
+-                      break;
+-              }
+-      }
+-      mutex_unlock(&bond->ipsec_lock);
+ }
+ static void bond_ipsec_del_sa_all(struct bonding *bond)
+@@ -629,9 +614,15 @@ static void bond_ipsec_del_sa_all(struct bonding *bond)
+                                  __func__);
+                       continue;
+               }
++
++              spin_lock_bh(&ipsec->xs->lock);
+               ipsec->xs->xso.real_dev = NULL;
+-              real_dev->xfrmdev_ops->xdo_dev_state_delete(real_dev,
+-                                                          ipsec->xs);
++              /* Don't double delete states killed by the user. */
++              if (ipsec->xs->km.state != XFRM_STATE_DEAD)
++                      real_dev->xfrmdev_ops->xdo_dev_state_delete(real_dev,
++                                                                  ipsec->xs);
++              spin_unlock_bh(&ipsec->xs->lock);
++
+               if (real_dev->xfrmdev_ops->xdo_dev_state_free)
+                       real_dev->xfrmdev_ops->xdo_dev_state_free(real_dev,
+                                                                 ipsec->xs);
+@@ -643,34 +634,33 @@ static void bond_ipsec_free_sa(struct net_device *bond_dev,
+                              struct xfrm_state *xs)
+ {
+       struct net_device *real_dev;
+-      netdevice_tracker tracker;
++      struct bond_ipsec *ipsec;
+       struct bonding *bond;
+-      struct slave *slave;
+       if (!bond_dev)
+               return;
+-      rcu_read_lock();
+       bond = netdev_priv(bond_dev);
+-      slave = rcu_dereference(bond->curr_active_slave);
+-      real_dev = slave ? slave->dev : NULL;
+-      netdev_hold(real_dev, &tracker, GFP_ATOMIC);
+-      rcu_read_unlock();
+-
+-      if (!slave)
+-              goto out;
++      mutex_lock(&bond->ipsec_lock);
+       if (!xs->xso.real_dev)
+               goto out;
+-      WARN_ON(xs->xso.real_dev != real_dev);
++      real_dev = xs->xso.real_dev;
+       xs->xso.real_dev = NULL;
+-      if (real_dev && real_dev->xfrmdev_ops &&
++      if (real_dev->xfrmdev_ops &&
+           real_dev->xfrmdev_ops->xdo_dev_state_free)
+               real_dev->xfrmdev_ops->xdo_dev_state_free(real_dev, xs);
+ out:
+-      netdev_put(real_dev, &tracker);
++      list_for_each_entry(ipsec, &bond->ipsec_list, list) {
++              if (ipsec->xs == xs) {
++                      list_del(&ipsec->list);
++                      kfree(ipsec);
++                      break;
++              }
++      }
++      mutex_unlock(&bond->ipsec_lock);
+ }
+ /**
+diff --git a/include/net/xfrm.h b/include/net/xfrm.h
+index 01783dc3d0e32..1f1861c57e2ad 100644
+--- a/include/net/xfrm.h
++++ b/include/net/xfrm.h
+@@ -154,8 +154,11 @@ struct xfrm_dev_offload {
+        */
+       struct net_device       *dev;
+       netdevice_tracker       dev_tracker;
+-      /* This is a private pointer used by the bonding driver.
+-       * Device drivers should not use it.
++      /* This is a private pointer used by the bonding driver (and eventually
++       * should be moved there). Device drivers should not use it.
++       * Protected by xfrm_state.lock AND bond.ipsec_lock in most cases,
++       * except in the .xdo_dev_state_del() flow, where only xfrm_state.lock
++       * is held.
+        */
+       struct net_device       *real_dev;
+       unsigned long           offload_handle;
+-- 
+2.39.5
+
diff --git a/queue-6.15/bonding-mark-active-offloaded-xfrm_states.patch b/queue-6.15/bonding-mark-active-offloaded-xfrm_states.patch
new file mode 100644 (file)
index 0000000..6c57fd2
--- /dev/null
@@ -0,0 +1,135 @@
+From 445c32aa3a1a40e8dd96ee10dbe6ed332284520f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Apr 2025 10:49:57 +0300
+Subject: bonding: Mark active offloaded xfrm_states
+
+From: Cosmin Ratiu <cratiu@nvidia.com>
+
+[ Upstream commit fd4e41ebf66cb8b43de2f640b97314c4ee3b4499 ]
+
+When the active link is changed for a bond device, the existing xfrm
+states need to be migrated over to the new link. This is done with:
+- bond_ipsec_del_sa_all() goes through the offloaded states list and
+  removes all of them from hw.
+- bond_ipsec_add_sa_all() re-offloads all states to the new device.
+
+But because the offload status of xfrm states isn't marked in any way,
+there can be bugs.
+
+When all bond links are down, bond_ipsec_del_sa_all() unoffloads
+everything from the previous active link. If the same link then comes
+back up, nothing gets reoffloaded by bond_ipsec_add_sa_all().
+This results in a stack trace like this a bit later when user space
+removes the offloaded rules, because mlx5e_xfrm_del_state() is asked to
+remove a rule that's no longer offloaded:
+
+ [] Call Trace:
+ []  <TASK>
+ []  ? __warn+0x7d/0x110
+ []  ? mlx5e_xfrm_del_state+0x90/0xa0 [mlx5_core]
+ []  ? report_bug+0x16d/0x180
+ []  ? handle_bug+0x4f/0x90
+ []  ? exc_invalid_op+0x14/0x70
+ []  ? asm_exc_invalid_op+0x16/0x20
+ []  ? mlx5e_xfrm_del_state+0x73/0xa0 [mlx5_core]
+ []  ? mlx5e_xfrm_del_state+0x90/0xa0 [mlx5_core]
+ []  bond_ipsec_del_sa+0x1ab/0x200 [bonding]
+ []  xfrm_dev_state_delete+0x1f/0x60
+ []  __xfrm_state_delete+0x196/0x200
+ []  xfrm_state_delete+0x21/0x40
+ []  xfrm_del_sa+0x69/0x110
+ []  xfrm_user_rcv_msg+0x11d/0x300
+ []  ? release_pages+0xca/0x140
+ []  ? copy_to_user_tmpl.part.0+0x110/0x110
+ []  netlink_rcv_skb+0x54/0x100
+ []  xfrm_netlink_rcv+0x31/0x40
+ []  netlink_unicast+0x1fc/0x2d0
+ []  netlink_sendmsg+0x1e4/0x410
+ []  __sock_sendmsg+0x38/0x60
+ []  sock_write_iter+0x94/0xf0
+ []  vfs_write+0x338/0x3f0
+ []  ksys_write+0xba/0xd0
+ []  do_syscall_64+0x4c/0x100
+ []  entry_SYSCALL_64_after_hwframe+0x4b/0x53
+
+There's also another theoretical bug:
+Calling bond_ipsec_del_sa_all() multiple times can result in corruption
+in the driver implementation if the double-free isn't tolerated. This
+isn't nice.
+
+Before the "Fixes" commit, xs->xso.real_dev was set to NULL when an xfrm
+state was unoffloaded from a device, but a race with netdevsim's
+.xdo_dev_offload_ok() accessing real_dev was considered a sufficient
+reason to not set real_dev to NULL anymore. This unfortunately
+introduced the new bugs.
+
+Since .xdo_dev_offload_ok() was significantly refactored by [1] and
+there are no more users in the stack of xso.real_dev, that
+race is now gone and xs->xso.real_dev can now once again be used to
+represent which device (if any) currently holds the offloaded rule.
+
+Go one step further and set real_dev after add/before delete calls, to
+catch any future driver misuses of real_dev.
+
+[1] https://lore.kernel.org/netdev/cover.1739972570.git.leon@kernel.org/
+Fixes: f8cde9805981 ("bonding: fix xfrm real_dev null pointer dereference")
+Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
+Reviewed-by: Hangbin Liu <liuhangbin@gmail.com>
+Tested-by: Hangbin Liu <liuhangbin@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/bonding/bond_main.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index b183a3c99f627..14ebbe82a2c5b 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -496,9 +496,9 @@ static int bond_ipsec_add_sa(struct net_device *bond_dev,
+               goto out;
+       }
+-      xs->xso.real_dev = real_dev;
+       err = real_dev->xfrmdev_ops->xdo_dev_state_add(real_dev, xs, extack);
+       if (!err) {
++              xs->xso.real_dev = real_dev;
+               ipsec->xs = xs;
+               INIT_LIST_HEAD(&ipsec->list);
+               mutex_lock(&bond->ipsec_lock);
+@@ -540,12 +540,12 @@ static void bond_ipsec_add_sa_all(struct bonding *bond)
+               if (ipsec->xs->xso.real_dev == real_dev)
+                       continue;
+-              ipsec->xs->xso.real_dev = real_dev;
+               if (real_dev->xfrmdev_ops->xdo_dev_state_add(real_dev,
+                                                            ipsec->xs, NULL)) {
+                       slave_warn(bond_dev, real_dev, "%s: failed to add SA\n", __func__);
+-                      ipsec->xs->xso.real_dev = NULL;
++                      continue;
+               }
++              ipsec->xs->xso.real_dev = real_dev;
+       }
+ out:
+       mutex_unlock(&bond->ipsec_lock);
+@@ -629,6 +629,7 @@ static void bond_ipsec_del_sa_all(struct bonding *bond)
+                                  __func__);
+                       continue;
+               }
++              ipsec->xs->xso.real_dev = NULL;
+               real_dev->xfrmdev_ops->xdo_dev_state_delete(real_dev,
+                                                           ipsec->xs);
+               if (real_dev->xfrmdev_ops->xdo_dev_state_free)
+@@ -664,6 +665,7 @@ static void bond_ipsec_free_sa(struct net_device *bond_dev,
+       WARN_ON(xs->xso.real_dev != real_dev);
++      xs->xso.real_dev = NULL;
+       if (real_dev && real_dev->xfrmdev_ops &&
+           real_dev->xfrmdev_ops->xdo_dev_state_free)
+               real_dev->xfrmdev_ops->xdo_dev_state_free(real_dev, xs);
+-- 
+2.39.5
+
diff --git a/queue-6.15/bpf-allow-xdp-dev-bound-programs-to-perform-xdp_redi.patch b/queue-6.15/bpf-allow-xdp-dev-bound-programs-to-perform-xdp_redi.patch
new file mode 100644 (file)
index 0000000..abe67de
--- /dev/null
@@ -0,0 +1,91 @@
+From 83b40e6aca6ac71312a44f0bf8bd38d7d6d86b56 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Apr 2025 17:44:02 +0200
+Subject: bpf: Allow XDP dev-bound programs to perform XDP_REDIRECT into maps
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit 714070c4cb7a10ff57450a618a936775f3036245 ]
+
+In the current implementation if the program is dev-bound to a specific
+device, it will not be possible to perform XDP_REDIRECT into a DEVMAP
+or CPUMAP even if the program is running in the driver NAPI context and
+it is not attached to any map entry. This seems in contrast with the
+explanation available in bpf_prog_map_compatible routine.
+Fix the issue introducing __bpf_prog_map_compatible utility routine in
+order to avoid bpf_prog_is_dev_bound() check running bpf_check_tail_call()
+at program load time (bpf_prog_select_runtime()).
+Continue forbidding to attach a dev-bound program to XDP maps
+(BPF_MAP_TYPE_PROG_ARRAY, BPF_MAP_TYPE_DEVMAP and BPF_MAP_TYPE_CPUMAP).
+
+Fixes: 3d76a4d3d4e59 ("bpf: XDP metadata RX kfuncs")
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Acked-by: Stanislav Fomichev <sdf@fomichev.me>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/core.c | 27 ++++++++++++++++-----------
+ 1 file changed, 16 insertions(+), 11 deletions(-)
+
+diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
+index ba6b6118cf504..a3e5716884211 100644
+--- a/kernel/bpf/core.c
++++ b/kernel/bpf/core.c
+@@ -2358,8 +2358,8 @@ static unsigned int __bpf_prog_ret0_warn(const void *ctx,
+       return 0;
+ }
+-bool bpf_prog_map_compatible(struct bpf_map *map,
+-                           const struct bpf_prog *fp)
++static bool __bpf_prog_map_compatible(struct bpf_map *map,
++                                    const struct bpf_prog *fp)
+ {
+       enum bpf_prog_type prog_type = resolve_prog_type(fp);
+       bool ret;
+@@ -2368,14 +2368,6 @@ bool bpf_prog_map_compatible(struct bpf_map *map,
+       if (fp->kprobe_override)
+               return false;
+-      /* XDP programs inserted into maps are not guaranteed to run on
+-       * a particular netdev (and can run outside driver context entirely
+-       * in the case of devmap and cpumap). Until device checks
+-       * are implemented, prohibit adding dev-bound programs to program maps.
+-       */
+-      if (bpf_prog_is_dev_bound(aux))
+-              return false;
+-
+       spin_lock(&map->owner.lock);
+       if (!map->owner.type) {
+               /* There's no owner yet where we could check for
+@@ -2409,6 +2401,19 @@ bool bpf_prog_map_compatible(struct bpf_map *map,
+       return ret;
+ }
++bool bpf_prog_map_compatible(struct bpf_map *map, const struct bpf_prog *fp)
++{
++      /* XDP programs inserted into maps are not guaranteed to run on
++       * a particular netdev (and can run outside driver context entirely
++       * in the case of devmap and cpumap). Until device checks
++       * are implemented, prohibit adding dev-bound programs to program maps.
++       */
++      if (bpf_prog_is_dev_bound(fp->aux))
++              return false;
++
++      return __bpf_prog_map_compatible(map, fp);
++}
++
+ static int bpf_check_tail_call(const struct bpf_prog *fp)
+ {
+       struct bpf_prog_aux *aux = fp->aux;
+@@ -2421,7 +2426,7 @@ static int bpf_check_tail_call(const struct bpf_prog *fp)
+               if (!map_type_contains_progs(map))
+                       continue;
+-              if (!bpf_prog_map_compatible(map, fp)) {
++              if (!__bpf_prog_map_compatible(map, fp)) {
+                       ret = -EINVAL;
+                       goto out;
+               }
+-- 
+2.39.5
+
diff --git a/queue-6.15/bpf-avoid-__bpf_prog_ret0_warn-when-jit-fails.patch b/queue-6.15/bpf-avoid-__bpf_prog_ret0_warn-when-jit-fails.patch
new file mode 100644 (file)
index 0000000..98074c1
--- /dev/null
@@ -0,0 +1,57 @@
+From fd0fd3d8e239eb7f62d5d2e8861e18415732d14e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 May 2025 21:33:58 +0800
+Subject: bpf: Avoid __bpf_prog_ret0_warn when jit fails
+
+From: KaFai Wan <mannkafai@gmail.com>
+
+[ Upstream commit 86bc9c742426a16b52a10ef61f5b721aecca2344 ]
+
+syzkaller reported an issue:
+
+WARNING: CPU: 3 PID: 217 at kernel/bpf/core.c:2357 __bpf_prog_ret0_warn+0xa/0x20 kernel/bpf/core.c:2357
+Modules linked in:
+CPU: 3 UID: 0 PID: 217 Comm: kworker/u32:6 Not tainted 6.15.0-rc4-syzkaller-00040-g8bac8898fe39
+RIP: 0010:__bpf_prog_ret0_warn+0xa/0x20 kernel/bpf/core.c:2357
+Call Trace:
+ <TASK>
+ bpf_dispatcher_nop_func include/linux/bpf.h:1316 [inline]
+ __bpf_prog_run include/linux/filter.h:718 [inline]
+ bpf_prog_run include/linux/filter.h:725 [inline]
+ cls_bpf_classify+0x74a/0x1110 net/sched/cls_bpf.c:105
+ ...
+
+When creating bpf program, 'fp->jit_requested' depends on bpf_jit_enable.
+This issue is triggered because of CONFIG_BPF_JIT_ALWAYS_ON is not set
+and bpf_jit_enable is set to 1, causing the arch to attempt JIT the prog,
+but jit failed due to FAULT_INJECTION. As a result, incorrectly
+treats the program as valid, when the program runs it calls
+`__bpf_prog_ret0_warn` and triggers the WARN_ON_ONCE(1).
+
+Reported-by: syzbot+0903f6d7f285e41cdf10@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/bpf/6816e34e.a70a0220.254cdc.002c.GAE@google.com
+Fixes: fa9dd599b4da ("bpf: get rid of pure_initcall dependency to enable jits")
+Signed-off-by: KaFai Wan <mannkafai@gmail.com>
+Link: https://lore.kernel.org/r/20250526133358.2594176-1-mannkafai@gmail.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
+index a3e5716884211..c20babbf998f4 100644
+--- a/kernel/bpf/core.c
++++ b/kernel/bpf/core.c
+@@ -2474,7 +2474,7 @@ struct bpf_prog *bpf_prog_select_runtime(struct bpf_prog *fp, int *err)
+       /* In case of BPF to BPF calls, verifier did all the prep
+        * work with regards to JITing, etc.
+        */
+-      bool jit_needed = false;
++      bool jit_needed = fp->jit_requested;
+       if (fp->bpf_func)
+               goto finalize;
+-- 
+2.39.5
+
diff --git a/queue-6.15/bpf-check-link_create.flags-parameter-for-multi_kpro.patch b/queue-6.15/bpf-check-link_create.flags-parameter-for-multi_kpro.patch
new file mode 100644 (file)
index 0000000..7b57d80
--- /dev/null
@@ -0,0 +1,41 @@
+From 22da30cb6775c98dafbaea72f71caa0b3ae6e013 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Apr 2025 11:57:51 +0800
+Subject: bpf: Check link_create.flags parameter for multi_kprobe
+
+From: Tao Chen <chen.dylane@linux.dev>
+
+[ Upstream commit 243911982aa9faf4361aa952f879331ad66933fe ]
+
+The link_create.flags are currently not used for multi-kprobes, so return
+-EINVAL if it is set, same as for other attach APIs.
+
+We allow target_fd, on the other hand, to have an arbitrary value for
+multi-kprobe, as there are existing users (libbpf) relying on this.
+
+Fixes: 0dcac2725406 ("bpf: Add multi kprobe link")
+Signed-off-by: Tao Chen <chen.dylane@linux.dev>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20250407035752.1108927-1-chen.dylane@linux.dev
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/bpf_trace.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
+index 187dc37d61d4a..ec19942321e6d 100644
+--- a/kernel/trace/bpf_trace.c
++++ b/kernel/trace/bpf_trace.c
+@@ -2987,6 +2987,9 @@ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr
+       if (sizeof(u64) != sizeof(void *))
+               return -EOPNOTSUPP;
++      if (attr->link_create.flags)
++              return -EINVAL;
++
+       if (!is_kprobe_multi(prog))
+               return -EINVAL;
+-- 
+2.39.5
+
diff --git a/queue-6.15/bpf-check-link_create.flags-parameter-for-multi_upro.patch b/queue-6.15/bpf-check-link_create.flags-parameter-for-multi_upro.patch
new file mode 100644 (file)
index 0000000..0f9fdb9
--- /dev/null
@@ -0,0 +1,41 @@
+From 3d21b21abd206d0504cabb0c5666ebef690c6d4c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Apr 2025 11:57:52 +0800
+Subject: bpf: Check link_create.flags parameter for multi_uprobe
+
+From: Tao Chen <chen.dylane@linux.dev>
+
+[ Upstream commit a76116f422c442ab691b4dcabb25613486d34360 ]
+
+The link_create.flags are currently not used for multi-uprobes, so return
+-EINVAL if it is set, same as for other attach APIs.
+
+We allow target_fd to have an arbitrary value for multi-uprobe, though,
+as there are existing users (libbpf) relying on this.
+
+Fixes: 89ae89f53d20 ("bpf: Add multi uprobe link")
+Signed-off-by: Tao Chen <chen.dylane@linux.dev>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20250407035752.1108927-2-chen.dylane@linux.dev
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/bpf_trace.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
+index ec19942321e6d..0f5906f43d7ca 100644
+--- a/kernel/trace/bpf_trace.c
++++ b/kernel/trace/bpf_trace.c
+@@ -3379,6 +3379,9 @@ int bpf_uprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr
+       if (sizeof(u64) != sizeof(void *))
+               return -EOPNOTSUPP;
++      if (attr->link_create.flags)
++              return -EINVAL;
++
+       if (!is_uprobe_multi(prog))
+               return -EINVAL;
+-- 
+2.39.5
+
diff --git a/queue-6.15/bpf-clarify-the-meaning-of-bpf_f_pseudo_hdr.patch b/queue-6.15/bpf-clarify-the-meaning-of-bpf_f_pseudo_hdr.patch
new file mode 100644 (file)
index 0000000..f97490f
--- /dev/null
@@ -0,0 +1,55 @@
+From 1cbc9775430d2f008fac9dd5beb2dea8dad1de85 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Apr 2025 11:00:51 +0200
+Subject: bpf: Clarify the meaning of BPF_F_PSEUDO_HDR
+
+From: Paul Chaignon <paul.chaignon@gmail.com>
+
+[ Upstream commit 5a15a050df714959f0d5a57ac3201bd1c6594984 ]
+
+In the bpf_l4_csum_replace helper, the BPF_F_PSEUDO_HDR flag should only
+be set if the modified header field is part of the pseudo-header.
+
+If you modify for example the UDP ports and pass BPF_F_PSEUDO_HDR,
+inet_proto_csum_replace4 will update skb->csum even though it shouldn't
+(the port and the UDP checksum updates null each other).
+
+Signed-off-by: Paul Chaignon <paul.chaignon@gmail.com>
+Link: https://lore.kernel.org/r/5126ef84ba75425b689482cbc98bffe75e5d8ab0.1744102490.git.paul.chaignon@gmail.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Stable-dep-of: ead7f9b8de65 ("bpf: Fix L4 csum update on IPv6 in CHECKSUM_COMPLETE")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/uapi/linux/bpf.h       | 2 +-
+ tools/include/uapi/linux/bpf.h | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
+index fd404729b1154..bceb1950ec204 100644
+--- a/include/uapi/linux/bpf.h
++++ b/include/uapi/linux/bpf.h
+@@ -2051,7 +2051,7 @@ union bpf_attr {
+  *            untouched (unless **BPF_F_MARK_ENFORCE** is added as well), and
+  *            for updates resulting in a null checksum the value is set to
+  *            **CSUM_MANGLED_0** instead. Flag **BPF_F_PSEUDO_HDR** indicates
+- *            the checksum is to be computed against a pseudo-header.
++ *            that the modified header field is part of the pseudo-header.
+  *
+  *            This helper works in combination with **bpf_csum_diff**\ (),
+  *            which does not update the checksum in-place, but offers more
+diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
+index fd404729b1154..bceb1950ec204 100644
+--- a/tools/include/uapi/linux/bpf.h
++++ b/tools/include/uapi/linux/bpf.h
+@@ -2051,7 +2051,7 @@ union bpf_attr {
+  *            untouched (unless **BPF_F_MARK_ENFORCE** is added as well), and
+  *            for updates resulting in a null checksum the value is set to
+  *            **CSUM_MANGLED_0** instead. Flag **BPF_F_PSEUDO_HDR** indicates
+- *            the checksum is to be computed against a pseudo-header.
++ *            that the modified header field is part of the pseudo-header.
+  *
+  *            This helper works in combination with **bpf_csum_diff**\ (),
+  *            which does not update the checksum in-place, but offers more
+-- 
+2.39.5
+
diff --git a/queue-6.15/bpf-do-not-include-stack-ptr-register-in-precision-b.patch b/queue-6.15/bpf-do-not-include-stack-ptr-register-in-precision-b.patch
new file mode 100644 (file)
index 0000000..ff2afe4
--- /dev/null
@@ -0,0 +1,209 @@
+From 37fb275e75777b34f266a874f0c2ed61c1510502 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 May 2025 21:13:35 -0700
+Subject: bpf: Do not include stack ptr register in precision backtracking
+ bookkeeping
+
+From: Yonghong Song <yonghong.song@linux.dev>
+
+[ Upstream commit e2d2115e56c4a02377189bfc3a9a7933552a7b0f ]
+
+Yi Lai reported an issue ([1]) where the following warning appears
+in kernel dmesg:
+  [   60.643604] verifier backtracking bug
+  [   60.643635] WARNING: CPU: 10 PID: 2315 at kernel/bpf/verifier.c:4302 __mark_chain_precision+0x3a6c/0x3e10
+  [   60.648428] Modules linked in: bpf_testmod(OE)
+  [   60.650471] CPU: 10 UID: 0 PID: 2315 Comm: test_progs Tainted: G           OE       6.15.0-rc4-gef11287f8289-dirty #327 PREEMPT(full)
+  [   60.654385] Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
+  [   60.656682] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
+  [   60.660475] RIP: 0010:__mark_chain_precision+0x3a6c/0x3e10
+  [   60.662814] Code: 5a 30 84 89 ea e8 c4 d9 01 00 80 3d 3e 7d d8 04 00 0f 85 60 fa ff ff c6 05 31 7d d8 04
+                       01 48 c7 c7 00 58 30 84 e8 c4 06 a5 ff <0f> 0b e9 46 fa ff ff 48 ...
+  [   60.668720] RSP: 0018:ffff888116cc7298 EFLAGS: 00010246
+  [   60.671075] RAX: 54d70e82dfd31900 RBX: ffff888115b65e20 RCX: 0000000000000000
+  [   60.673659] RDX: 0000000000000001 RSI: 0000000000000004 RDI: 00000000ffffffff
+  [   60.676241] RBP: 0000000000000400 R08: ffff8881f6f23bd3 R09: 1ffff1103ede477a
+  [   60.678787] R10: dffffc0000000000 R11: ffffed103ede477b R12: ffff888115b60ae8
+  [   60.681420] R13: 1ffff11022b6cbc4 R14: 00000000fffffff2 R15: 0000000000000001
+  [   60.684030] FS:  00007fc2aedd80c0(0000) GS:ffff88826fa8a000(0000) knlGS:0000000000000000
+  [   60.686837] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+  [   60.689027] CR2: 000056325369e000 CR3: 000000011088b002 CR4: 0000000000370ef0
+  [   60.691623] Call Trace:
+  [   60.692821]  <TASK>
+  [   60.693960]  ? __pfx_verbose+0x10/0x10
+  [   60.695656]  ? __pfx_disasm_kfunc_name+0x10/0x10
+  [   60.697495]  check_cond_jmp_op+0x16f7/0x39b0
+  [   60.699237]  do_check+0x58fa/0xab10
+  ...
+
+Further analysis shows the warning is at line 4302 as below:
+
+  4294                 /* static subprog call instruction, which
+  4295                  * means that we are exiting current subprog,
+  4296                  * so only r1-r5 could be still requested as
+  4297                  * precise, r0 and r6-r10 or any stack slot in
+  4298                  * the current frame should be zero by now
+  4299                  */
+  4300                 if (bt_reg_mask(bt) & ~BPF_REGMASK_ARGS) {
+  4301                         verbose(env, "BUG regs %x\n", bt_reg_mask(bt));
+  4302                         WARN_ONCE(1, "verifier backtracking bug");
+  4303                         return -EFAULT;
+  4304                 }
+
+With the below test (also in the next patch):
+  __used __naked static void __bpf_jmp_r10(void)
+  {
+       asm volatile (
+       "r2 = 2314885393468386424 ll;"
+       "goto +0;"
+       "if r2 <= r10 goto +3;"
+       "if r1 >= -1835016 goto +0;"
+       "if r2 <= 8 goto +0;"
+       "if r3 <= 0 goto +0;"
+       "exit;"
+       ::: __clobber_all);
+  }
+
+  SEC("?raw_tp")
+  __naked void bpf_jmp_r10(void)
+  {
+       asm volatile (
+       "r3 = 0 ll;"
+       "call __bpf_jmp_r10;"
+       "r0 = 0;"
+       "exit;"
+       ::: __clobber_all);
+  }
+
+The following is the verifier failure log:
+  0: (18) r3 = 0x0                      ; R3_w=0
+  2: (85) call pc+2
+  caller:
+   R10=fp0
+  callee:
+   frame1: R1=ctx() R3_w=0 R10=fp0
+  5: frame1: R1=ctx() R3_w=0 R10=fp0
+  ; asm volatile ("                                 \ @ verifier_precision.c:184
+  5: (18) r2 = 0x20202000256c6c78       ; frame1: R2_w=0x20202000256c6c78
+  7: (05) goto pc+0
+  8: (bd) if r2 <= r10 goto pc+3        ; frame1: R2_w=0x20202000256c6c78 R10=fp0
+  9: (35) if r1 >= 0xffe3fff8 goto pc+0         ; frame1: R1=ctx()
+  10: (b5) if r2 <= 0x8 goto pc+0
+  mark_precise: frame1: last_idx 10 first_idx 0 subseq_idx -1
+  mark_precise: frame1: regs=r2 stack= before 9: (35) if r1 >= 0xffe3fff8 goto pc+0
+  mark_precise: frame1: regs=r2 stack= before 8: (bd) if r2 <= r10 goto pc+3
+  mark_precise: frame1: regs=r2,r10 stack= before 7: (05) goto pc+0
+  mark_precise: frame1: regs=r2,r10 stack= before 5: (18) r2 = 0x20202000256c6c78
+  mark_precise: frame1: regs=r10 stack= before 2: (85) call pc+2
+  BUG regs 400
+
+The main failure reason is due to r10 in precision backtracking bookkeeping.
+Actually r10 is always precise and there is no need to add it for the precision
+backtracking bookkeeping.
+
+One way to fix the issue is to prevent bt_set_reg() if any src/dst reg is
+r10. Andrii suggested to go with push_insn_history() approach to avoid
+explicitly checking r10 in backtrack_insn().
+
+This patch added push_insn_history() support for cond_jmp like 'rX <op> rY'
+operations. In check_cond_jmp_op(), if any of rX or rY is a stack pointer,
+push_insn_history() will record such information, and later backtrack_insn()
+will do bt_set_reg() properly for those register(s).
+
+  [1] https://lore.kernel.org/bpf/Z%2F8q3xzpU59CIYQE@ly-workstation/
+
+Reported by: Yi Lai <yi1.lai@linux.intel.com>
+
+Fixes: 407958a0e980 ("bpf: encapsulate precision backtracking bookkeeping")
+Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20250524041335.4046126-1-yonghong.song@linux.dev
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/bpf_verifier.h | 12 ++++++++----
+ kernel/bpf/verifier.c        | 18 ++++++++++++++++--
+ 2 files changed, 24 insertions(+), 6 deletions(-)
+
+diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
+index 9734544b6957c..d1f02f8e3e55f 100644
+--- a/include/linux/bpf_verifier.h
++++ b/include/linux/bpf_verifier.h
+@@ -356,7 +356,11 @@ enum {
+       INSN_F_SPI_MASK = 0x3f, /* 6 bits */
+       INSN_F_SPI_SHIFT = 3, /* shifted 3 bits to the left */
+-      INSN_F_STACK_ACCESS = BIT(9), /* we need 10 bits total */
++      INSN_F_STACK_ACCESS = BIT(9),
++
++      INSN_F_DST_REG_STACK = BIT(10), /* dst_reg is PTR_TO_STACK */
++      INSN_F_SRC_REG_STACK = BIT(11), /* src_reg is PTR_TO_STACK */
++      /* total 12 bits are used now. */
+ };
+ static_assert(INSN_F_FRAMENO_MASK + 1 >= MAX_CALL_FRAMES);
+@@ -365,9 +369,9 @@ static_assert(INSN_F_SPI_MASK + 1 >= MAX_BPF_STACK / 8);
+ struct bpf_insn_hist_entry {
+       u32 idx;
+       /* insn idx can't be bigger than 1 million */
+-      u32 prev_idx : 22;
+-      /* special flags, e.g., whether insn is doing register stack spill/load */
+-      u32 flags : 10;
++      u32 prev_idx : 20;
++      /* special INSN_F_xxx flags */
++      u32 flags : 12;
+       /* additional registers that need precision tracking when this
+        * jump is backtracked, vector of six 10-bit records
+        */
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 54c6953a8b84c..efa7014117129 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -4413,8 +4413,10 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx, int subseq_idx,
+                        * before it would be equally necessary to
+                        * propagate it to dreg.
+                        */
+-                      bt_set_reg(bt, dreg);
+-                      bt_set_reg(bt, sreg);
++                      if (!hist || !(hist->flags & INSN_F_SRC_REG_STACK))
++                              bt_set_reg(bt, sreg);
++                      if (!hist || !(hist->flags & INSN_F_DST_REG_STACK))
++                              bt_set_reg(bt, dreg);
+               } else if (BPF_SRC(insn->code) == BPF_K) {
+                        /* dreg <cond> K
+                         * Only dreg still needs precision before
+@@ -16377,6 +16379,7 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env,
+       struct bpf_reg_state *eq_branch_regs;
+       struct linked_regs linked_regs = {};
+       u8 opcode = BPF_OP(insn->code);
++      int insn_flags = 0;
+       bool is_jmp32;
+       int pred = -1;
+       int err;
+@@ -16435,6 +16438,9 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env,
+                               insn->src_reg);
+                       return -EACCES;
+               }
++
++              if (src_reg->type == PTR_TO_STACK)
++                      insn_flags |= INSN_F_SRC_REG_STACK;
+       } else {
+               if (insn->src_reg != BPF_REG_0) {
+                       verbose(env, "BPF_JMP/JMP32 uses reserved fields\n");
+@@ -16446,6 +16452,14 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env,
+               __mark_reg_known(src_reg, insn->imm);
+       }
++      if (dst_reg->type == PTR_TO_STACK)
++              insn_flags |= INSN_F_DST_REG_STACK;
++      if (insn_flags) {
++              err = push_insn_history(env, this_branch, insn_flags, 0);
++              if (err)
++                      return err;
++      }
++
+       is_jmp32 = BPF_CLASS(insn->code) == BPF_JMP32;
+       pred = is_branch_taken(dst_reg, src_reg, opcode, is_jmp32);
+       if (pred >= 0) {
+-- 
+2.39.5
+
diff --git a/queue-6.15/bpf-fix-ktls-panic-with-sockmap.patch b/queue-6.15/bpf-fix-ktls-panic-with-sockmap.patch
new file mode 100644 (file)
index 0000000..e6dbbe8
--- /dev/null
@@ -0,0 +1,123 @@
+From 624fdb1c76353b71281e2e4ca13509a199d93553 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Feb 2025 13:20:14 +0800
+Subject: bpf: fix ktls panic with sockmap
+
+From: Jiayuan Chen <jiayuan.chen@linux.dev>
+
+[ Upstream commit 54a3ecaeeeae8176da8badbd7d72af1017032c39 ]
+
+[ 2172.936997] ------------[ cut here ]------------
+[ 2172.936999] kernel BUG at lib/iov_iter.c:629!
+......
+[ 2172.944996] PKRU: 55555554
+[ 2172.945155] Call Trace:
+[ 2172.945299]  <TASK>
+[ 2172.945428]  ? die+0x36/0x90
+[ 2172.945601]  ? do_trap+0xdd/0x100
+[ 2172.945795]  ? iov_iter_revert+0x178/0x180
+[ 2172.946031]  ? iov_iter_revert+0x178/0x180
+[ 2172.946267]  ? do_error_trap+0x7d/0x110
+[ 2172.946499]  ? iov_iter_revert+0x178/0x180
+[ 2172.946736]  ? exc_invalid_op+0x50/0x70
+[ 2172.946961]  ? iov_iter_revert+0x178/0x180
+[ 2172.947197]  ? asm_exc_invalid_op+0x1a/0x20
+[ 2172.947446]  ? iov_iter_revert+0x178/0x180
+[ 2172.947683]  ? iov_iter_revert+0x5c/0x180
+[ 2172.947913]  tls_sw_sendmsg_locked.isra.0+0x794/0x840
+[ 2172.948206]  tls_sw_sendmsg+0x52/0x80
+[ 2172.948420]  ? inet_sendmsg+0x1f/0x70
+[ 2172.948634]  __sys_sendto+0x1cd/0x200
+[ 2172.948848]  ? find_held_lock+0x2b/0x80
+[ 2172.949072]  ? syscall_trace_enter+0x140/0x270
+[ 2172.949330]  ? __lock_release.isra.0+0x5e/0x170
+[ 2172.949595]  ? find_held_lock+0x2b/0x80
+[ 2172.949817]  ? syscall_trace_enter+0x140/0x270
+[ 2172.950211]  ? lockdep_hardirqs_on_prepare+0xda/0x190
+[ 2172.950632]  ? ktime_get_coarse_real_ts64+0xc2/0xd0
+[ 2172.951036]  __x64_sys_sendto+0x24/0x30
+[ 2172.951382]  do_syscall_64+0x90/0x170
+......
+
+After calling bpf_exec_tx_verdict(), the size of msg_pl->sg may increase,
+e.g., when the BPF program executes bpf_msg_push_data().
+
+If the BPF program sets cork_bytes and sg.size is smaller than cork_bytes,
+it will return -ENOSPC and attempt to roll back to the non-zero copy
+logic. However, during rollback, msg->msg_iter is reset, but since
+msg_pl->sg.size has been increased, subsequent executions will exceed the
+actual size of msg_iter.
+'''
+iov_iter_revert(&msg->msg_iter, msg_pl->sg.size - orig_size);
+'''
+
+The changes in this commit are based on the following considerations:
+
+1. When cork_bytes is set, rolling back to non-zero copy logic is
+pointless and can directly go to zero-copy logic.
+
+2. We can not calculate the correct number of bytes to revert msg_iter.
+
+Assume the original data is "abcdefgh" (8 bytes), and after 3 pushes
+by the BPF program, it becomes 11-byte data: "abc?de?fgh?".
+Then, we set cork_bytes to 6, which means the first 6 bytes have been
+processed, and the remaining 5 bytes "?fgh?" will be cached until the
+length meets the cork_bytes requirement.
+
+However, some data in "?fgh?" is not within 'sg->msg_iter'
+(but in msg_pl instead), especially the data "?" we pushed.
+
+So it doesn't seem as simple as just reverting through an offset of
+msg_iter.
+
+3. For non-TLS sockets in tcp_bpf_sendmsg, when a "cork" situation occurs,
+the user-space send() doesn't return an error, and the returned length is
+the same as the input length parameter, even if some data is cached.
+
+Additionally, I saw that the current non-zero-copy logic for handling
+corking is written as:
+'''
+line 1177
+else if (ret != -EAGAIN) {
+       if (ret == -ENOSPC)
+               ret = 0;
+       goto send_end;
+'''
+
+So it's ok to just return 'copied' without error when a "cork" situation
+occurs.
+
+Fixes: fcb14cb1bdac ("new iov_iter flavour - ITER_UBUF")
+Fixes: d3b18ad31f93 ("tls: add bpf support to sk_msg handling")
+Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
+Acked-by: John Fastabend <john.fastabend@gmail.com>
+Link: https://lore.kernel.org/r/20250219052015.274405-2-jiayuan.chen@linux.dev
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tls/tls_sw.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
+index 914d4e1516a3c..f3d7d19482da9 100644
+--- a/net/tls/tls_sw.c
++++ b/net/tls/tls_sw.c
+@@ -1120,9 +1120,13 @@ static int tls_sw_sendmsg_locked(struct sock *sk, struct msghdr *msg,
+                                       num_async++;
+                               else if (ret == -ENOMEM)
+                                       goto wait_for_memory;
+-                              else if (ctx->open_rec && ret == -ENOSPC)
++                              else if (ctx->open_rec && ret == -ENOSPC) {
++                                      if (msg_pl->cork_bytes) {
++                                              ret = 0;
++                                              goto send_end;
++                                      }
+                                       goto rollback_iter;
+-                              else if (ret != -EAGAIN)
++                              } else if (ret != -EAGAIN)
+                                       goto send_end;
+                       }
+                       continue;
+-- 
+2.39.5
+
diff --git a/queue-6.15/bpf-fix-l4-csum-update-on-ipv6-in-checksum_complete.patch b/queue-6.15/bpf-fix-l4-csum-update-on-ipv6-in-checksum_complete.patch
new file mode 100644 (file)
index 0000000..d0d98b8
--- /dev/null
@@ -0,0 +1,137 @@
+From 5198484f1e3da4937755a06d6c74abd8b091cd3d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 May 2025 12:28:35 +0200
+Subject: bpf: Fix L4 csum update on IPv6 in CHECKSUM_COMPLETE
+
+From: Paul Chaignon <paul.chaignon@gmail.com>
+
+[ Upstream commit ead7f9b8de65632ef8060b84b0c55049a33cfea1 ]
+
+In Cilium, we use bpf_csum_diff + bpf_l4_csum_replace to, among other
+things, update the L4 checksum after reverse SNATing IPv6 packets. That
+use case is however not currently supported and leads to invalid
+skb->csum values in some cases. This patch adds support for IPv6 address
+changes in bpf_l4_csum_update via a new flag.
+
+When calling bpf_l4_csum_replace in Cilium, it ends up calling
+inet_proto_csum_replace_by_diff:
+
+    1:  void inet_proto_csum_replace_by_diff(__sum16 *sum, struct sk_buff *skb,
+    2:                                       __wsum diff, bool pseudohdr)
+    3:  {
+    4:      if (skb->ip_summed != CHECKSUM_PARTIAL) {
+    5:          csum_replace_by_diff(sum, diff);
+    6:          if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr)
+    7:              skb->csum = ~csum_sub(diff, skb->csum);
+    8:      } else if (pseudohdr) {
+    9:          *sum = ~csum_fold(csum_add(diff, csum_unfold(*sum)));
+    10:     }
+    11: }
+
+The bug happens when we're in the CHECKSUM_COMPLETE state. We've just
+updated one of the IPv6 addresses. The helper now updates the L4 header
+checksum on line 5. Next, it updates skb->csum on line 7. It shouldn't.
+
+For an IPv6 packet, the updates of the IPv6 address and of the L4
+checksum will cancel each other. The checksums are set such that
+computing a checksum over the packet including its checksum will result
+in a sum of 0. So the same is true here when we update the L4 checksum
+on line 5. We'll update it as to cancel the previous IPv6 address
+update. Hence skb->csum should remain untouched in this case.
+
+The same bug doesn't affect IPv4 packets because, in that case, three
+fields are updated: the IPv4 address, the IP checksum, and the L4
+checksum. The change to the IPv4 address and one of the checksums still
+cancel each other in skb->csum, but we're left with one checksum update
+and should therefore update skb->csum accordingly. That's exactly what
+inet_proto_csum_replace_by_diff does.
+
+This special case for IPv6 L4 checksums is also described atop
+inet_proto_csum_replace16, the function we should be using in this case.
+
+This patch introduces a new bpf_l4_csum_replace flag, BPF_F_IPV6,
+to indicate that we're updating the L4 checksum of an IPv6 packet. When
+the flag is set, inet_proto_csum_replace_by_diff will skip the
+skb->csum update.
+
+Fixes: 7d672345ed295 ("bpf: add generic bpf_csum_diff helper")
+Signed-off-by: Paul Chaignon <paul.chaignon@gmail.com>
+Acked-by: Daniel Borkmann <daniel@iogearbox.net>
+Link: https://patch.msgid.link/96a6bc3a443e6f0b21ff7b7834000e17fb549e05.1748509484.git.paul.chaignon@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/uapi/linux/bpf.h       | 2 ++
+ net/core/filter.c              | 5 +++--
+ tools/include/uapi/linux/bpf.h | 2 ++
+ 3 files changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
+index bceb1950ec204..fe5df2a9fe8ee 100644
+--- a/include/uapi/linux/bpf.h
++++ b/include/uapi/linux/bpf.h
+@@ -2052,6 +2052,7 @@ union bpf_attr {
+  *            for updates resulting in a null checksum the value is set to
+  *            **CSUM_MANGLED_0** instead. Flag **BPF_F_PSEUDO_HDR** indicates
+  *            that the modified header field is part of the pseudo-header.
++ *            Flag **BPF_F_IPV6** should be set for IPv6 packets.
+  *
+  *            This helper works in combination with **bpf_csum_diff**\ (),
+  *            which does not update the checksum in-place, but offers more
+@@ -6068,6 +6069,7 @@ enum {
+       BPF_F_PSEUDO_HDR                = (1ULL << 4),
+       BPF_F_MARK_MANGLED_0            = (1ULL << 5),
+       BPF_F_MARK_ENFORCE              = (1ULL << 6),
++      BPF_F_IPV6                      = (1ULL << 7),
+ };
+ /* BPF_FUNC_skb_set_tunnel_key and BPF_FUNC_skb_get_tunnel_key flags. */
+diff --git a/net/core/filter.c b/net/core/filter.c
+index 3c93765742c9c..357d26b76c22d 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -1968,10 +1968,11 @@ BPF_CALL_5(bpf_l4_csum_replace, struct sk_buff *, skb, u32, offset,
+       bool is_pseudo = flags & BPF_F_PSEUDO_HDR;
+       bool is_mmzero = flags & BPF_F_MARK_MANGLED_0;
+       bool do_mforce = flags & BPF_F_MARK_ENFORCE;
++      bool is_ipv6   = flags & BPF_F_IPV6;
+       __sum16 *ptr;
+       if (unlikely(flags & ~(BPF_F_MARK_MANGLED_0 | BPF_F_MARK_ENFORCE |
+-                             BPF_F_PSEUDO_HDR | BPF_F_HDR_FIELD_MASK)))
++                             BPF_F_PSEUDO_HDR | BPF_F_HDR_FIELD_MASK | BPF_F_IPV6)))
+               return -EINVAL;
+       if (unlikely(offset > 0xffff || offset & 1))
+               return -EFAULT;
+@@ -1987,7 +1988,7 @@ BPF_CALL_5(bpf_l4_csum_replace, struct sk_buff *, skb, u32, offset,
+               if (unlikely(from != 0))
+                       return -EINVAL;
+-              inet_proto_csum_replace_by_diff(ptr, skb, to, is_pseudo, false);
++              inet_proto_csum_replace_by_diff(ptr, skb, to, is_pseudo, is_ipv6);
+               break;
+       case 2:
+               inet_proto_csum_replace2(ptr, skb, from, to, is_pseudo);
+diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
+index bceb1950ec204..fe5df2a9fe8ee 100644
+--- a/tools/include/uapi/linux/bpf.h
++++ b/tools/include/uapi/linux/bpf.h
+@@ -2052,6 +2052,7 @@ union bpf_attr {
+  *            for updates resulting in a null checksum the value is set to
+  *            **CSUM_MANGLED_0** instead. Flag **BPF_F_PSEUDO_HDR** indicates
+  *            that the modified header field is part of the pseudo-header.
++ *            Flag **BPF_F_IPV6** should be set for IPv6 packets.
+  *
+  *            This helper works in combination with **bpf_csum_diff**\ (),
+  *            which does not update the checksum in-place, but offers more
+@@ -6068,6 +6069,7 @@ enum {
+       BPF_F_PSEUDO_HDR                = (1ULL << 4),
+       BPF_F_MARK_MANGLED_0            = (1ULL << 5),
+       BPF_F_MARK_ENFORCE              = (1ULL << 6),
++      BPF_F_IPV6                      = (1ULL << 7),
+ };
+ /* BPF_FUNC_skb_set_tunnel_key and BPF_FUNC_skb_get_tunnel_key flags. */
+-- 
+2.39.5
+
diff --git a/queue-6.15/bpf-fix-uninitialized-values-in-bpf_-core-probe-_rea.patch b/queue-6.15/bpf-fix-uninitialized-values-in-bpf_-core-probe-_rea.patch
new file mode 100644 (file)
index 0000000..ebf821c
--- /dev/null
@@ -0,0 +1,58 @@
+From 445ecc1cc49eaf97c6045e5e11b9d2fc891b8cce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 May 2025 19:30:31 +0000
+Subject: bpf: Fix uninitialized values in BPF_{CORE,PROBE}_READ
+
+From: Anton Protopopov <a.s.protopopov@gmail.com>
+
+[ Upstream commit 41d4ce6df3f4945341ec509a840cc002a413b6cc ]
+
+With the latest LLVM bpf selftests build will fail with
+the following error message:
+
+    progs/profiler.inc.h:710:31: error: default initialization of an object of type 'typeof ((parent_task)->real_cred->uid.val)' (aka 'const unsigned int') leaves the object uninitialized and is incompatible with C++ [-Werror,-Wdefault-const-init-unsafe]
+      710 |         proc_exec_data->parent_uid = BPF_CORE_READ(parent_task, real_cred, uid.val);
+          |                                      ^
+    tools/testing/selftests/bpf/tools/include/bpf/bpf_core_read.h:520:35: note: expanded from macro 'BPF_CORE_READ'
+      520 |         ___type((src), a, ##__VA_ARGS__) __r;                               \
+          |                                          ^
+
+This happens because BPF_CORE_READ (and other macro) declare the
+variable __r using the ___type macro which can inherit const modifier
+from intermediate types.
+
+Fix this by using __typeof_unqual__, when supported. (And when it
+is not supported, the problem shouldn't appear, as older compilers
+haven't complained.)
+
+Fixes: 792001f4f7aa ("libbpf: Add user-space variants of BPF_CORE_READ() family of macros")
+Fixes: a4b09a9ef945 ("libbpf: Add non-CO-RE variants of BPF_CORE_READ() macro family")
+Signed-off-by: Anton Protopopov <a.s.protopopov@gmail.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20250502193031.3522715-1-a.s.protopopov@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/bpf_core_read.h | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/tools/lib/bpf/bpf_core_read.h b/tools/lib/bpf/bpf_core_read.h
+index c0e13cdf96607..b997c68bd9453 100644
+--- a/tools/lib/bpf/bpf_core_read.h
++++ b/tools/lib/bpf/bpf_core_read.h
+@@ -388,7 +388,13 @@ extern void *bpf_rdonly_cast(const void *obj, __u32 btf_id) __ksym __weak;
+ #define ___arrow10(a, b, c, d, e, f, g, h, i, j) a->b->c->d->e->f->g->h->i->j
+ #define ___arrow(...) ___apply(___arrow, ___narg(__VA_ARGS__))(__VA_ARGS__)
++#if defined(__clang__) && (__clang_major__ >= 19)
++#define ___type(...) __typeof_unqual__(___arrow(__VA_ARGS__))
++#elif defined(__GNUC__) && (__GNUC__ >= 14)
++#define ___type(...) __typeof_unqual__(___arrow(__VA_ARGS__))
++#else
+ #define ___type(...) typeof(___arrow(__VA_ARGS__))
++#endif
+ #define ___read(read_fn, dst, src_type, src, accessor)                            \
+       read_fn((void *)(dst), sizeof(*(dst)), &((src_type)(src))->accessor)
+-- 
+2.39.5
+
diff --git a/queue-6.15/bpf-fix-warn-in-get_bpf_raw_tp_regs.patch b/queue-6.15/bpf-fix-warn-in-get_bpf_raw_tp_regs.patch
new file mode 100644 (file)
index 0000000..29b3689
--- /dev/null
@@ -0,0 +1,86 @@
+From 1b42059105a6a28c0184a2294a92e3c6c407872d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 May 2025 12:27:47 +0800
+Subject: bpf: Fix WARN() in get_bpf_raw_tp_regs
+
+From: Tao Chen <chen.dylane@linux.dev>
+
+[ Upstream commit 3880cdbed1c4607e378f58fa924c5d6df900d1d3 ]
+
+syzkaller reported an issue:
+
+WARNING: CPU: 3 PID: 5971 at kernel/trace/bpf_trace.c:1861 get_bpf_raw_tp_regs+0xa4/0x100 kernel/trace/bpf_trace.c:1861
+Modules linked in:
+CPU: 3 UID: 0 PID: 5971 Comm: syz-executor205 Not tainted 6.15.0-rc5-syzkaller-00038-g707df3375124 #0 PREEMPT(full)
+Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014
+RIP: 0010:get_bpf_raw_tp_regs+0xa4/0x100 kernel/trace/bpf_trace.c:1861
+RSP: 0018:ffffc90003636fa8 EFLAGS: 00010293
+RAX: 0000000000000000 RBX: 0000000000000003 RCX: ffffffff81c6bc4c
+RDX: ffff888032efc880 RSI: ffffffff81c6bc83 RDI: 0000000000000005
+RBP: ffff88806a730860 R08: 0000000000000005 R09: 0000000000000003
+R10: 0000000000000004 R11: 0000000000000000 R12: 0000000000000004
+R13: 0000000000000001 R14: ffffc90003637008 R15: 0000000000000900
+FS:  0000000000000000(0000) GS:ffff8880d6cdf000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00007f7baee09130 CR3: 0000000029f5a000 CR4: 0000000000352ef0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+Call Trace:
+ <TASK>
+ ____bpf_get_stack_raw_tp kernel/trace/bpf_trace.c:1934 [inline]
+ bpf_get_stack_raw_tp+0x24/0x160 kernel/trace/bpf_trace.c:1931
+ bpf_prog_ec3b2eefa702d8d3+0x43/0x47
+ bpf_dispatcher_nop_func include/linux/bpf.h:1316 [inline]
+ __bpf_prog_run include/linux/filter.h:718 [inline]
+ bpf_prog_run include/linux/filter.h:725 [inline]
+ __bpf_trace_run kernel/trace/bpf_trace.c:2363 [inline]
+ bpf_trace_run3+0x23f/0x5a0 kernel/trace/bpf_trace.c:2405
+ __bpf_trace_mmap_lock_acquire_returned+0xfc/0x140 include/trace/events/mmap_lock.h:47
+ __traceiter_mmap_lock_acquire_returned+0x79/0xc0 include/trace/events/mmap_lock.h:47
+ __do_trace_mmap_lock_acquire_returned include/trace/events/mmap_lock.h:47 [inline]
+ trace_mmap_lock_acquire_returned include/trace/events/mmap_lock.h:47 [inline]
+ __mmap_lock_do_trace_acquire_returned+0x138/0x1f0 mm/mmap_lock.c:35
+ __mmap_lock_trace_acquire_returned include/linux/mmap_lock.h:36 [inline]
+ mmap_read_trylock include/linux/mmap_lock.h:204 [inline]
+ stack_map_get_build_id_offset+0x535/0x6f0 kernel/bpf/stackmap.c:157
+ __bpf_get_stack+0x307/0xa10 kernel/bpf/stackmap.c:483
+ ____bpf_get_stack kernel/bpf/stackmap.c:499 [inline]
+ bpf_get_stack+0x32/0x40 kernel/bpf/stackmap.c:496
+ ____bpf_get_stack_raw_tp kernel/trace/bpf_trace.c:1941 [inline]
+ bpf_get_stack_raw_tp+0x124/0x160 kernel/trace/bpf_trace.c:1931
+ bpf_prog_ec3b2eefa702d8d3+0x43/0x47
+
+Tracepoint like trace_mmap_lock_acquire_returned may cause nested call
+as the corner case show above, which will be resolved with more general
+method in the future. As a result, WARN_ON_ONCE will be triggered. As
+Alexei suggested, remove the WARN_ON_ONCE first.
+
+Fixes: 9594dc3c7e71 ("bpf: fix nested bpf tracepoints with per-cpu data")
+Reported-by: syzbot+45b0c89a0fc7ae8dbadc@syzkaller.appspotmail.com
+Suggested-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Tao Chen <chen.dylane@linux.dev>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20250513042747.757042-1-chen.dylane@linux.dev
+
+Closes: https://lore.kernel.org/bpf/8bc2554d-1052-4922-8832-e0078a033e1d@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/bpf_trace.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
+index 0f5906f43d7ca..e1bf9c06007fb 100644
+--- a/kernel/trace/bpf_trace.c
++++ b/kernel/trace/bpf_trace.c
+@@ -1858,7 +1858,7 @@ static struct pt_regs *get_bpf_raw_tp_regs(void)
+       struct bpf_raw_tp_regs *tp_regs = this_cpu_ptr(&bpf_raw_tp_regs);
+       int nest_level = this_cpu_inc_return(bpf_raw_tp_nest_level);
+-      if (WARN_ON_ONCE(nest_level > ARRAY_SIZE(tp_regs->regs))) {
++      if (nest_level > ARRAY_SIZE(tp_regs->regs)) {
+               this_cpu_dec(bpf_raw_tp_nest_level);
+               return ERR_PTR(-EBUSY);
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/bpf-revert-bpf-remove-unnecessary-rcu_read_-lock-unl.patch b/queue-6.15/bpf-revert-bpf-remove-unnecessary-rcu_read_-lock-unl.patch
new file mode 100644 (file)
index 0000000..9d96f80
--- /dev/null
@@ -0,0 +1,48 @@
+From fc63d298e1b6dae828253d16a48cd3252f12bddf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 May 2025 13:49:43 +0800
+Subject: bpf: Revert "bpf: remove unnecessary rcu_read_{lock,unlock}() in
+ multi-uprobe attach logic"
+
+From: Di Shen <di.shen@unisoc.com>
+
+[ Upstream commit 4e2e6841ff761cc15a54e8bebcf35d7325ec78a2 ]
+
+This reverts commit 4a8f635a6054.
+
+Althought get_pid_task() internally already calls rcu_read_lock() and
+rcu_read_unlock(), the find_vpid() was not.
+
+The documentation for find_vpid() clearly states:
+"Must be called with the tasklist_lock or rcu_read_lock() held."
+
+Add proper rcu_read_lock/unlock() to protect the find_vpid().
+
+Fixes: 4a8f635a6054 ("bpf: remove unnecessary rcu_read_{lock,unlock}() in multi-uprobe attach logic")
+Reported-by: Xuewen Yan <xuewen.yan@unisoc.com>
+Signed-off-by: Di Shen <di.shen@unisoc.com>
+Acked-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/r/20250520054943.5002-1-xuewen.yan@unisoc.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/bpf_trace.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
+index e1bf9c06007fb..090cdab38f0cc 100644
+--- a/kernel/trace/bpf_trace.c
++++ b/kernel/trace/bpf_trace.c
+@@ -3423,7 +3423,9 @@ int bpf_uprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr
+       }
+       if (pid) {
++              rcu_read_lock();
+               task = get_pid_task(find_vpid(pid), PIDTYPE_TGID);
++              rcu_read_unlock();
+               if (!task) {
+                       err = -ESRCH;
+                       goto error_path_put;
+-- 
+2.39.5
+
diff --git a/queue-6.15/bpf-sockmap-avoid-using-sk_socket-after-free-when-se.patch b/queue-6.15/bpf-sockmap-avoid-using-sk_socket-after-free-when-se.patch
new file mode 100644 (file)
index 0000000..a976b50
--- /dev/null
@@ -0,0 +1,125 @@
+From f01a98b7f53be046d02dfe02cfe8233568d37d79 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 May 2025 22:17:12 +0800
+Subject: bpf, sockmap: Avoid using sk_socket after free when sending
+
+From: Jiayuan Chen <jiayuan.chen@linux.dev>
+
+[ Upstream commit 8259eb0e06d8f64c700f5fbdb28a5c18e10de291 ]
+
+The sk->sk_socket is not locked or referenced in backlog thread, and
+during the call to skb_send_sock(), there is a race condition with
+the release of sk_socket. All types of sockets(tcp/udp/unix/vsock)
+will be affected.
+
+Race conditions:
+'''
+CPU0                               CPU1
+
+backlog::skb_send_sock
+  sendmsg_unlocked
+    sock_sendmsg
+      sock_sendmsg_nosec
+                                   close(fd):
+                                     ...
+                                     ops->release() -> sock_map_close()
+                                     sk_socket->ops = NULL
+                                     free(socket)
+      sock->ops->sendmsg
+            ^
+            panic here
+'''
+
+The ref of psock become 0 after sock_map_close() executed.
+'''
+void sock_map_close()
+{
+    ...
+    if (likely(psock)) {
+    ...
+    // !! here we remove psock and the ref of psock become 0
+    sock_map_remove_links(sk, psock)
+    psock = sk_psock_get(sk);
+    if (unlikely(!psock))
+        goto no_psock; <=== Control jumps here via goto
+        ...
+        cancel_delayed_work_sync(&psock->work); <=== not executed
+        sk_psock_put(sk, psock);
+        ...
+}
+'''
+
+Based on the fact that we already wait for the workqueue to finish in
+sock_map_close() if psock is held, we simply increase the psock
+reference count to avoid race conditions.
+
+With this patch, if the backlog thread is running, sock_map_close() will
+wait for the backlog thread to complete and cancel all pending work.
+
+If no backlog running, any pending work that hasn't started by then will
+fail when invoked by sk_psock_get(), as the psock reference count have
+been zeroed, and sk_psock_drop() will cancel all jobs via
+cancel_delayed_work_sync().
+
+In summary, we require synchronization to coordinate the backlog thread
+and close() thread.
+
+The panic I catched:
+'''
+Workqueue: events sk_psock_backlog
+RIP: 0010:sock_sendmsg+0x21d/0x440
+RAX: 0000000000000000 RBX: ffffc9000521fad8 RCX: 0000000000000001
+...
+Call Trace:
+ <TASK>
+ ? die_addr+0x40/0xa0
+ ? exc_general_protection+0x14c/0x230
+ ? asm_exc_general_protection+0x26/0x30
+ ? sock_sendmsg+0x21d/0x440
+ ? sock_sendmsg+0x3e0/0x440
+ ? __pfx_sock_sendmsg+0x10/0x10
+ __skb_send_sock+0x543/0xb70
+ sk_psock_backlog+0x247/0xb80
+...
+'''
+
+Fixes: 4b4647add7d3 ("sock_map: avoid race between sock_map_close and sk_psock_put")
+Reported-by: Michal Luczaj <mhal@rbox.co>
+Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Reviewed-by: John Fastabend <john.fastabend@gmail.com>
+Link: https://lore.kernel.org/r/20250516141713.291150-1-jiayuan.chen@linux.dev
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/skmsg.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/net/core/skmsg.c b/net/core/skmsg.c
+index 061f1409bd5a9..6d689918c2b39 100644
+--- a/net/core/skmsg.c
++++ b/net/core/skmsg.c
+@@ -656,6 +656,13 @@ static void sk_psock_backlog(struct work_struct *work)
+       bool ingress;
+       int ret;
++      /* Increment the psock refcnt to synchronize with close(fd) path in
++       * sock_map_close(), ensuring we wait for backlog thread completion
++       * before sk_socket freed. If refcnt increment fails, it indicates
++       * sock_map_close() completed with sk_socket potentially already freed.
++       */
++      if (!sk_psock_get(psock->sk))
++              return;
+       mutex_lock(&psock->work_mutex);
+       while ((skb = skb_peek(&psock->ingress_skb))) {
+               len = skb->len;
+@@ -707,6 +714,7 @@ static void sk_psock_backlog(struct work_struct *work)
+       }
+ end:
+       mutex_unlock(&psock->work_mutex);
++      sk_psock_put(psock->sk, psock);
+ }
+ struct sk_psock *sk_psock_init(struct sock *sk, int node)
+-- 
+2.39.5
+
diff --git a/queue-6.15/bpf-sockmap-fix-duplicated-data-transmission.patch b/queue-6.15/bpf-sockmap-fix-duplicated-data-transmission.patch
new file mode 100644 (file)
index 0000000..b97bb12
--- /dev/null
@@ -0,0 +1,68 @@
+From ae327a0a5650192983d1166f555afd1393323c0a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Apr 2025 22:21:21 +0800
+Subject: bpf, sockmap: fix duplicated data transmission
+
+From: Jiayuan Chen <jiayuan.chen@linux.dev>
+
+[ Upstream commit 3b4f14b794287be137ea2c6158765d1ea1e018a4 ]
+
+In the !ingress path under sk_psock_handle_skb(), when sending data to the
+remote under snd_buf limitations, partial skb data might be transmitted.
+
+Although we preserved the partial transmission state (offset/length), the
+state wasn't properly consumed during retries. This caused the retry path
+to resend the entire skb data instead of continuing from the previous
+offset, resulting in data overlap at the receiver side.
+
+Fixes: 405df89dd52c ("bpf, sockmap: Improved check for empty queue")
+Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
+Link: https://lore.kernel.org/r/20250407142234.47591-3-jiayuan.chen@linux.dev
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/skmsg.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+diff --git a/net/core/skmsg.c b/net/core/skmsg.c
+index 0ddc4c7188332..dc136603c42ce 100644
+--- a/net/core/skmsg.c
++++ b/net/core/skmsg.c
+@@ -656,11 +656,6 @@ static void sk_psock_backlog(struct work_struct *work)
+       int ret;
+       mutex_lock(&psock->work_mutex);
+-      if (unlikely(state->len)) {
+-              len = state->len;
+-              off = state->off;
+-      }
+-
+       while ((skb = skb_peek(&psock->ingress_skb))) {
+               len = skb->len;
+               off = 0;
+@@ -670,6 +665,13 @@ static void sk_psock_backlog(struct work_struct *work)
+                       off = stm->offset;
+                       len = stm->full_len;
+               }
++
++              /* Resume processing from previous partial state */
++              if (unlikely(state->len)) {
++                      len = state->len;
++                      off = state->off;
++              }
++
+               ingress = skb_bpf_ingress(skb);
+               skb_bpf_redirect_clear(skb);
+               do {
+@@ -697,6 +699,8 @@ static void sk_psock_backlog(struct work_struct *work)
+                       len -= ret;
+               } while (len);
++              /* The entire skb sent, clear state */
++              sk_psock_skb_state(psock, state, 0, 0);
+               skb = skb_dequeue(&psock->ingress_skb);
+               kfree_skb(skb);
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/bpf-sockmap-fix-panic-when-calling-skb_linearize.patch b/queue-6.15/bpf-sockmap-fix-panic-when-calling-skb_linearize.patch
new file mode 100644 (file)
index 0000000..667894e
--- /dev/null
@@ -0,0 +1,198 @@
+From 094698e3943f84d0a305c537a8044d00be9a61df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Apr 2025 22:21:22 +0800
+Subject: bpf, sockmap: Fix panic when calling skb_linearize
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jiayuan Chen <jiayuan.chen@linux.dev>
+
+[ Upstream commit 5ca2e29f6834c64c0e5a9ccf1278c21fb49b827e ]
+
+The panic can be reproduced by executing the command:
+./bench sockmap -c 2 -p 1 -a --rx-verdict-ingress --rx-strp 100000
+
+Then a kernel panic was captured:
+'''
+[  657.460555] kernel BUG at net/core/skbuff.c:2178!
+[  657.462680] Tainted: [W]=WARN
+[  657.463287] Workqueue: events sk_psock_backlog
+...
+[  657.469610]  <TASK>
+[  657.469738]  ? die+0x36/0x90
+[  657.469916]  ? do_trap+0x1d0/0x270
+[  657.470118]  ? pskb_expand_head+0x612/0xf40
+[  657.470376]  ? pskb_expand_head+0x612/0xf40
+[  657.470620]  ? do_error_trap+0xa3/0x170
+[  657.470846]  ? pskb_expand_head+0x612/0xf40
+[  657.471092]  ? handle_invalid_op+0x2c/0x40
+[  657.471335]  ? pskb_expand_head+0x612/0xf40
+[  657.471579]  ? exc_invalid_op+0x2d/0x40
+[  657.471805]  ? asm_exc_invalid_op+0x1a/0x20
+[  657.472052]  ? pskb_expand_head+0xd1/0xf40
+[  657.472292]  ? pskb_expand_head+0x612/0xf40
+[  657.472540]  ? lock_acquire+0x18f/0x4e0
+[  657.472766]  ? find_held_lock+0x2d/0x110
+[  657.472999]  ? __pfx_pskb_expand_head+0x10/0x10
+[  657.473263]  ? __kmalloc_cache_noprof+0x5b/0x470
+[  657.473537]  ? __pfx___lock_release.isra.0+0x10/0x10
+[  657.473826]  __pskb_pull_tail+0xfd/0x1d20
+[  657.474062]  ? __kasan_slab_alloc+0x4e/0x90
+[  657.474707]  sk_psock_skb_ingress_enqueue+0x3bf/0x510
+[  657.475392]  ? __kasan_kmalloc+0xaa/0xb0
+[  657.476010]  sk_psock_backlog+0x5cf/0xd70
+[  657.476637]  process_one_work+0x858/0x1a20
+'''
+
+The panic originates from the assertion BUG_ON(skb_shared(skb)) in
+skb_linearize(). A previous commit(see Fixes tag) introduced skb_get()
+to avoid race conditions between skb operations in the backlog and skb
+release in the recvmsg path. However, this caused the panic to always
+occur when skb_linearize is executed.
+
+The "--rx-strp 100000" parameter forces the RX path to use the strparser
+module which aggregates data until it reaches 100KB before calling sockmap
+logic. The 100KB payload exceeds MAX_MSG_FRAGS, triggering skb_linearize.
+
+To fix this issue, just move skb_get into sk_psock_skb_ingress_enqueue.
+
+'''
+sk_psock_backlog:
+    sk_psock_handle_skb
+       skb_get(skb) <== we move it into 'sk_psock_skb_ingress_enqueue'
+       sk_psock_skb_ingress____________
+                                       ↓
+                                       |
+                                       | → sk_psock_skb_ingress_self
+                                       |      sk_psock_skb_ingress_enqueue
+sk_psock_verdict_apply_________________↑          skb_linearize
+'''
+
+Note that for verdict_apply path, the skb_get operation is unnecessary so
+we add 'take_ref' param to control it's behavior.
+
+Fixes: a454d84ee20b ("bpf, sockmap: Fix skb refcnt race after locking changes")
+Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
+Link: https://lore.kernel.org/r/20250407142234.47591-4-jiayuan.chen@linux.dev
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/skmsg.c | 31 ++++++++++++++++---------------
+ 1 file changed, 16 insertions(+), 15 deletions(-)
+
+diff --git a/net/core/skmsg.c b/net/core/skmsg.c
+index dc136603c42ce..061f1409bd5a9 100644
+--- a/net/core/skmsg.c
++++ b/net/core/skmsg.c
+@@ -530,16 +530,22 @@ static int sk_psock_skb_ingress_enqueue(struct sk_buff *skb,
+                                       u32 off, u32 len,
+                                       struct sk_psock *psock,
+                                       struct sock *sk,
+-                                      struct sk_msg *msg)
++                                      struct sk_msg *msg,
++                                      bool take_ref)
+ {
+       int num_sge, copied;
++      /* skb_to_sgvec will fail when the total number of fragments in
++       * frag_list and frags exceeds MAX_MSG_FRAGS. For example, the
++       * caller may aggregate multiple skbs.
++       */
+       num_sge = skb_to_sgvec(skb, msg->sg.data, off, len);
+       if (num_sge < 0) {
+               /* skb linearize may fail with ENOMEM, but lets simply try again
+                * later if this happens. Under memory pressure we don't want to
+                * drop the skb. We need to linearize the skb so that the mapping
+                * in skb_to_sgvec can not error.
++               * Note that skb_linearize requires the skb not to be shared.
+                */
+               if (skb_linearize(skb))
+                       return -EAGAIN;
+@@ -556,7 +562,7 @@ static int sk_psock_skb_ingress_enqueue(struct sk_buff *skb,
+       msg->sg.start = 0;
+       msg->sg.size = copied;
+       msg->sg.end = num_sge;
+-      msg->skb = skb;
++      msg->skb = take_ref ? skb_get(skb) : skb;
+       sk_psock_queue_msg(psock, msg);
+       sk_psock_data_ready(sk, psock);
+@@ -564,7 +570,7 @@ static int sk_psock_skb_ingress_enqueue(struct sk_buff *skb,
+ }
+ static int sk_psock_skb_ingress_self(struct sk_psock *psock, struct sk_buff *skb,
+-                                   u32 off, u32 len);
++                                   u32 off, u32 len, bool take_ref);
+ static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb,
+                               u32 off, u32 len)
+@@ -578,7 +584,7 @@ static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb,
+        * correctly.
+        */
+       if (unlikely(skb->sk == sk))
+-              return sk_psock_skb_ingress_self(psock, skb, off, len);
++              return sk_psock_skb_ingress_self(psock, skb, off, len, true);
+       msg = sk_psock_create_ingress_msg(sk, skb);
+       if (!msg)
+               return -EAGAIN;
+@@ -590,7 +596,7 @@ static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb,
+        * into user buffers.
+        */
+       skb_set_owner_r(skb, sk);
+-      err = sk_psock_skb_ingress_enqueue(skb, off, len, psock, sk, msg);
++      err = sk_psock_skb_ingress_enqueue(skb, off, len, psock, sk, msg, true);
+       if (err < 0)
+               kfree(msg);
+       return err;
+@@ -601,7 +607,7 @@ static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb,
+  * because the skb is already accounted for here.
+  */
+ static int sk_psock_skb_ingress_self(struct sk_psock *psock, struct sk_buff *skb,
+-                                   u32 off, u32 len)
++                                   u32 off, u32 len, bool take_ref)
+ {
+       struct sk_msg *msg = alloc_sk_msg(GFP_ATOMIC);
+       struct sock *sk = psock->sk;
+@@ -610,7 +616,7 @@ static int sk_psock_skb_ingress_self(struct sk_psock *psock, struct sk_buff *skb
+       if (unlikely(!msg))
+               return -EAGAIN;
+       skb_set_owner_r(skb, sk);
+-      err = sk_psock_skb_ingress_enqueue(skb, off, len, psock, sk, msg);
++      err = sk_psock_skb_ingress_enqueue(skb, off, len, psock, sk, msg, take_ref);
+       if (err < 0)
+               kfree(msg);
+       return err;
+@@ -619,18 +625,13 @@ static int sk_psock_skb_ingress_self(struct sk_psock *psock, struct sk_buff *skb
+ static int sk_psock_handle_skb(struct sk_psock *psock, struct sk_buff *skb,
+                              u32 off, u32 len, bool ingress)
+ {
+-      int err = 0;
+-
+       if (!ingress) {
+               if (!sock_writeable(psock->sk))
+                       return -EAGAIN;
+               return skb_send_sock(psock->sk, skb, off, len);
+       }
+-      skb_get(skb);
+-      err = sk_psock_skb_ingress(psock, skb, off, len);
+-      if (err < 0)
+-              kfree_skb(skb);
+-      return err;
++
++      return sk_psock_skb_ingress(psock, skb, off, len);
+ }
+ static void sk_psock_skb_state(struct sk_psock *psock,
+@@ -1018,7 +1019,7 @@ static int sk_psock_verdict_apply(struct sk_psock *psock, struct sk_buff *skb,
+                               off = stm->offset;
+                               len = stm->full_len;
+                       }
+-                      err = sk_psock_skb_ingress_self(psock, skb, off, len);
++                      err = sk_psock_skb_ingress_self(psock, skb, off, len, false);
+               }
+               if (err < 0) {
+                       spin_lock_bh(&psock->ingress_lock);
+-- 
+2.39.5
+
diff --git a/queue-6.15/bpftool-fix-regression-of-bpftool-cgroup-tree-einval.patch b/queue-6.15/bpftool-fix-regression-of-bpftool-cgroup-tree-einval.patch
new file mode 100644 (file)
index 0000000..f5722ed
--- /dev/null
@@ -0,0 +1,60 @@
+From f586efeecbc1a86192390df68ae84f43aead7dff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Apr 2025 21:15:36 +0000
+Subject: bpftool: Fix regression of "bpftool cgroup tree" EINVAL on older
+ kernels
+
+From: YiFei Zhu <zhuyifei@google.com>
+
+[ Upstream commit 43745d11bfd9683abdf08ad7a5cc403d6a9ffd15 ]
+
+If cgroup_has_attached_progs queries an attach type not supported
+by the running kernel, due to the kernel being older than the bpftool
+build, it would encounter an -EINVAL from BPF_PROG_QUERY syscall.
+
+Prior to commit 98b303c9bf05 ("bpftool: Query only cgroup-related
+attach types"), this EINVAL would be ignored by the function, allowing
+the function to only consider supported attach types. The commit
+changed so that, instead of querying all attach types, only attach
+types from the array `cgroup_attach_types` is queried. The assumption
+is that because these are only cgroup attach types, they should all
+be supported. Unfortunately this assumption may be false when the
+kernel is older than the bpftool build, where the attach types queried
+by bpftool is not yet implemented in the kernel. This would result in
+errors such as:
+
+  $ bpftool cgroup tree
+  CgroupPath
+  ID       AttachType      AttachFlags     Name
+  Error: can't query bpf programs attached to /sys/fs/cgroup: Invalid argument
+
+This patch restores the logic of ignoring EINVAL from prior to that patch.
+
+Fixes: 98b303c9bf05 ("bpftool: Query only cgroup-related attach types")
+Reported-by: Sagarika Sharma <sharmasagarika@google.com>
+Reported-by: Minh-Anh Nguyen <minhanhdn@google.com>
+Signed-off-by: YiFei Zhu <zhuyifei@google.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Acked-by: Quentin Monnet <qmo@kernel.org>
+Link: https://lore.kernel.org/bpf/20250428211536.1651456-1-zhuyifei@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/bpf/bpftool/cgroup.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/bpf/bpftool/cgroup.c b/tools/bpf/bpftool/cgroup.c
+index 93b139bfb9880..3f1d6be512151 100644
+--- a/tools/bpf/bpftool/cgroup.c
++++ b/tools/bpf/bpftool/cgroup.c
+@@ -221,7 +221,7 @@ static int cgroup_has_attached_progs(int cgroup_fd)
+       for (i = 0; i < ARRAY_SIZE(cgroup_attach_types); i++) {
+               int count = count_attached_bpf_progs(cgroup_fd, cgroup_attach_types[i]);
+-              if (count < 0)
++              if (count < 0 && errno != EINVAL)
+                       return -1;
+               if (count > 0) {
+-- 
+2.39.5
+
diff --git a/queue-6.15/brd-fix-aligned_sector-from-brd_do_discard.patch b/queue-6.15/brd-fix-aligned_sector-from-brd_do_discard.patch
new file mode 100644 (file)
index 0000000..f170b10
--- /dev/null
@@ -0,0 +1,37 @@
+From d61302134e940c9f6822ad6c86d5d0c7c99fc744 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 May 2025 14:17:55 +0800
+Subject: brd: fix aligned_sector from brd_do_discard()
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit d4099f8893b057ad7e8d61df76bdeaf807ebd679 ]
+
+The calculation is just wrong, fix it by round_up().
+
+Fixes: 9ead7efc6f3f ("brd: implement discard support")
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Link: https://lore.kernel.org/r/20250506061756.2970934-3-yukuai1@huaweicloud.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/brd.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/block/brd.c b/drivers/block/brd.c
+index 292f127cae0ab..9549cd71e083b 100644
+--- a/drivers/block/brd.c
++++ b/drivers/block/brd.c
+@@ -224,7 +224,7 @@ static int brd_do_bvec(struct brd_device *brd, struct page *page,
+ static void brd_do_discard(struct brd_device *brd, sector_t sector, u32 size)
+ {
+-      sector_t aligned_sector = (sector + PAGE_SECTORS) & ~PAGE_SECTORS;
++      sector_t aligned_sector = round_up(sector, PAGE_SECTORS);
+       struct page *page;
+       size -= (aligned_sector - sector) * SECTOR_SIZE;
+-- 
+2.39.5
+
diff --git a/queue-6.15/brd-fix-discard-end-sector.patch b/queue-6.15/brd-fix-discard-end-sector.patch
new file mode 100644 (file)
index 0000000..c86063b
--- /dev/null
@@ -0,0 +1,60 @@
+From d9139db584c86b0a1e138a2517d51dd305177d89 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 May 2025 14:17:56 +0800
+Subject: brd: fix discard end sector
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit a26a339a654b9403f0ee1004f1db4c2b2a355460 ]
+
+brd_do_discard() just aligned start sector to page, this can only work
+if the discard size if at least one page. For example:
+
+blkdiscard /dev/ram0 -o 5120 -l 1024
+
+In this case, size = (1024 - (8192 - 5120)), which is a huge value.
+
+Fix the problem by round_down() the end sector.
+
+Fixes: 9ead7efc6f3f ("brd: implement discard support")
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Link: https://lore.kernel.org/r/20250506061756.2970934-4-yukuai1@huaweicloud.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/brd.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/block/brd.c b/drivers/block/brd.c
+index 9549cd71e083b..02fa8106ef549 100644
+--- a/drivers/block/brd.c
++++ b/drivers/block/brd.c
+@@ -225,18 +225,21 @@ static int brd_do_bvec(struct brd_device *brd, struct page *page,
+ static void brd_do_discard(struct brd_device *brd, sector_t sector, u32 size)
+ {
+       sector_t aligned_sector = round_up(sector, PAGE_SECTORS);
++      sector_t aligned_end = round_down(
++                      sector + (size >> SECTOR_SHIFT), PAGE_SECTORS);
+       struct page *page;
+-      size -= (aligned_sector - sector) * SECTOR_SIZE;
++      if (aligned_end <= aligned_sector)
++              return;
++
+       xa_lock(&brd->brd_pages);
+-      while (size >= PAGE_SIZE && aligned_sector < rd_size * 2) {
++      while (aligned_sector < aligned_end && aligned_sector < rd_size * 2) {
+               page = __xa_erase(&brd->brd_pages, aligned_sector >> PAGE_SECTORS_SHIFT);
+               if (page) {
+                       __free_page(page);
+                       brd->brd_nr_pages--;
+               }
+               aligned_sector += PAGE_SECTORS;
+-              size -= PAGE_SIZE;
+       }
+       xa_unlock(&brd->brd_pages);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/btrfs-fix-invalid-data-space-release-when-truncating.patch b/queue-6.15/btrfs-fix-invalid-data-space-release-when-truncating.patch
new file mode 100644 (file)
index 0000000..ec3ad69
--- /dev/null
@@ -0,0 +1,57 @@
+From 7c859cac1cff1fd82d52457d601e42f3bbd61dd3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 May 2025 17:08:50 +0100
+Subject: btrfs: fix invalid data space release when truncating block in NOCOW
+ mode
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit d3914d6030aa6be2993dfc223d096ff93018c236 ]
+
+If when truncating a block we fail to reserve data space and then we
+proceed anyway because we can do a NOCOW write, if we later get an error
+when trying to get the folio from the inode's mapping, we end up releasing
+data space that we haven't reserved, screwing up the bytes_may_use counter
+from the data space_info, eventually resulting in an underflow when all
+other reservations done by other tasks are released, if any, or right away
+if there are no other reservations at the moment.
+
+This is because when we get an error when trying to grab the block's folio
+we call btrfs_delalloc_release_space(), which releases metadata (which we
+have reserved) and data (which we haven't reserved).
+
+Fix this by calling btrfs_delalloc_release_space() only if we did reserve
+data space, that is, if we aren't falling back to NOCOW, meaning the local
+variable @only_release_metadata has a false value, otherwise release only
+metadata by calling btrfs_delalloc_release_metadata().
+
+Fixes: 6d4572a9d71d ("btrfs: allow btrfs_truncate_block() to fallback to nocow for data space reservation")
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/inode.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
+index 90f5da3c520ac..8a3f44302788c 100644
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -4849,8 +4849,11 @@ int btrfs_truncate_block(struct btrfs_inode *inode, loff_t from, loff_t len,
+       folio = __filemap_get_folio(mapping, index,
+                                   FGP_LOCK | FGP_ACCESSED | FGP_CREAT, mask);
+       if (IS_ERR(folio)) {
+-              btrfs_delalloc_release_space(inode, data_reserved, block_start,
+-                                           blocksize, true);
++              if (only_release_metadata)
++                      btrfs_delalloc_release_metadata(inode, blocksize, true);
++              else
++                      btrfs_delalloc_release_space(inode, data_reserved,
++                                                   block_start, blocksize, true);
+               btrfs_delalloc_release_extents(inode, blocksize);
+               ret = -ENOMEM;
+               goto out;
+-- 
+2.39.5
+
diff --git a/queue-6.15/btrfs-fix-wrong-start-offset-for-delalloc-space-rele.patch b/queue-6.15/btrfs-fix-wrong-start-offset-for-delalloc-space-rele.patch
new file mode 100644 (file)
index 0000000..af51c13
--- /dev/null
@@ -0,0 +1,50 @@
+From 0a3843cbfd45270db0f9fa008634b6de1d84b9f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 May 2025 10:30:58 +0100
+Subject: btrfs: fix wrong start offset for delalloc space release during mmap
+ write
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit 17a85f520469a1838379de8ad24f63e778f7c277 ]
+
+If we're doing a mmap write against a folio that has i_size somewhere in
+the middle and we have multiple sectors in the folio, we may have to
+release excess space previously reserved, for the range going from the
+rounded up (to sector size) i_size to the folio's end offset. We are
+calculating the right amount to release and passing it to
+btrfs_delalloc_release_space(), but we are passing the wrong start offset
+of that range - we're passing the folio's start offset instead of the
+end offset, plus 1, of the range for which we keep the reservation. This
+may result in releasing more space then we should and eventually trigger
+an underflow of the data space_info's bytes_may_use counter.
+
+So fix this by passing the start offset as 'end + 1' instead of
+'page_start' to btrfs_delalloc_release_space().
+
+Fixes: d0b7da88f640 ("Btrfs: btrfs_page_mkwrite: Reserve space in sectorsized units")
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/file.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
+index 71b8a825c4479..22455fbcb29eb 100644
+--- a/fs/btrfs/file.c
++++ b/fs/btrfs/file.c
+@@ -1862,7 +1862,7 @@ static vm_fault_t btrfs_page_mkwrite(struct vm_fault *vmf)
+               if (reserved_space < fsize) {
+                       end = page_start + reserved_space - 1;
+                       btrfs_delalloc_release_space(BTRFS_I(inode),
+-                                      data_reserved, page_start,
++                                      data_reserved, end + 1,
+                                       fsize - reserved_space, true);
+               }
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/btrfs-scrub-fix-a-wrong-error-type-when-metadata-byt.patch b/queue-6.15/btrfs-scrub-fix-a-wrong-error-type-when-metadata-byt.patch
new file mode 100644 (file)
index 0000000..3042878
--- /dev/null
@@ -0,0 +1,38 @@
+From 80f2e9fcd5761c5fd889e1702288f880ccebacce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 May 2025 18:56:18 +0930
+Subject: btrfs: scrub: fix a wrong error type when metadata bytenr mismatches
+
+From: Qu Wenruo <wqu@suse.com>
+
+[ Upstream commit f2c19541e421b3235efc515dad88b581f00592ae ]
+
+When the bytenr doesn't match for a metadata tree block, we will report
+it as an csum error, which is incorrect and should be reported as a
+metadata error instead.
+
+Fixes: a3ddbaebc7c9 ("btrfs: scrub: introduce a helper to verify one metadata block")
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/scrub.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
+index 61812298325a2..4c525a0408125 100644
+--- a/fs/btrfs/scrub.c
++++ b/fs/btrfs/scrub.c
+@@ -619,7 +619,7 @@ static void scrub_verify_one_metadata(struct scrub_stripe *stripe, int sector_nr
+       memcpy(on_disk_csum, header->csum, fs_info->csum_size);
+       if (logical != btrfs_stack_header_bytenr(header)) {
+-              bitmap_set(&stripe->csum_error_bitmap, sector_nr, sectors_per_tree);
++              bitmap_set(&stripe->meta_error_bitmap, sector_nr, sectors_per_tree);
+               bitmap_set(&stripe->error_bitmap, sector_nr, sectors_per_tree);
+               btrfs_warn_rl(fs_info,
+               "tree block %llu mirror %u has bad bytenr, has %llu want %llu",
+-- 
+2.39.5
+
diff --git a/queue-6.15/btrfs-scrub-update-device-stats-when-an-error-is-det.patch b/queue-6.15/btrfs-scrub-update-device-stats-when-an-error-is-det.patch
new file mode 100644 (file)
index 0000000..12c5c58
--- /dev/null
@@ -0,0 +1,184 @@
+From 7d3d8a4b700ba4942b3ccd5c3c79370f0ba390a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 May 2025 08:37:54 +0930
+Subject: btrfs: scrub: update device stats when an error is detected
+
+From: Qu Wenruo <wqu@suse.com>
+
+[ Upstream commit ec1f3a207cdf314eae4d4ae145f1ffdb829f0652 ]
+
+[BUG]
+Since the migration to the new scrub_stripe interface, scrub no longer
+updates the device stats when hitting an error, no matter if it's a read
+or checksum mismatch error. E.g:
+
+  BTRFS info (device dm-2): scrub: started on devid 1
+  BTRFS error (device dm-2): unable to fixup (regular) error at logical 13631488 on dev /dev/mapper/test-scratch1 physical 13631488
+  BTRFS warning (device dm-2): checksum error at logical 13631488 on dev /dev/mapper/test-scratch1, physical 13631488, root 5, inode 257, offset 0, length 4096, links 1 (path: file)
+  BTRFS error (device dm-2): unable to fixup (regular) error at logical 13631488 on dev /dev/mapper/test-scratch1 physical 13631488
+  BTRFS warning (device dm-2): checksum error at logical 13631488 on dev /dev/mapper/test-scratch1, physical 13631488, root 5, inode 257, offset 0, length 4096, links 1 (path: file)
+  BTRFS info (device dm-2): scrub: finished on devid 1 with status: 0
+
+Note there is no line showing the device stats error update.
+
+[CAUSE]
+In the migration to the new scrub_stripe interface, we no longer call
+btrfs_dev_stat_inc_and_print().
+
+[FIX]
+- Introduce a new bitmap for metadata generation errors
+  * A new bitmap
+    @meta_gen_error_bitmap is introduced to record which blocks have
+    metadata generation mismatch errors.
+
+  * A new counter for that bitmap
+    @init_nr_meta_gen_errors, is also introduced to store the number of
+    generation mismatch errors that are found during the initial read.
+
+    This is for the error reporting at scrub_stripe_report_errors().
+
+  * New dedicated error message for unrepaired generation mismatches
+
+  * Update @meta_gen_error_bitmap if a transid mismatch is hit
+
+- Add btrfs_dev_stat_inc_and_print() calls to the following call sites
+  * scrub_stripe_report_errors()
+  * scrub_write_endio()
+    This is only for the write errors.
+
+This means there is a minor behavior change:
+
+- The timing of device stats error message
+  Since we concentrate the error messages at
+  scrub_stripe_report_errors(), the device stats error messages will all
+  show up in one go, after the detailed scrub error messages:
+
+   BTRFS error (device dm-2): unable to fixup (regular) error at logical 13631488 on dev /dev/mapper/test-scratch1 physical 13631488
+   BTRFS warning (device dm-2): checksum error at logical 13631488 on dev /dev/mapper/test-scratch1, physical 13631488, root 5, inode 257, offset 0, length 4096, links 1 (path: file)
+   BTRFS error (device dm-2): unable to fixup (regular) error at logical 13631488 on dev /dev/mapper/test-scratch1 physical 13631488
+   BTRFS warning (device dm-2): checksum error at logical 13631488 on dev /dev/mapper/test-scratch1, physical 13631488, root 5, inode 257, offset 0, length 4096, links 1 (path: file)
+   BTRFS error (device dm-2): bdev /dev/mapper/test-scratch1 errs: wr 0, rd 0, flush 0, corrupt 1, gen 0
+   BTRFS error (device dm-2): bdev /dev/mapper/test-scratch1 errs: wr 0, rd 0, flush 0, corrupt 2, gen 0
+
+Fixes: e02ee89baa66 ("btrfs: scrub: switch scrub_simple_mirror() to scrub_stripe infrastructure")
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/scrub.c | 32 +++++++++++++++++++++++++++++---
+ 1 file changed, 29 insertions(+), 3 deletions(-)
+
+diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
+index c3b2e29e3e019..61812298325a2 100644
+--- a/fs/btrfs/scrub.c
++++ b/fs/btrfs/scrub.c
+@@ -153,12 +153,14 @@ struct scrub_stripe {
+       unsigned int init_nr_io_errors;
+       unsigned int init_nr_csum_errors;
+       unsigned int init_nr_meta_errors;
++      unsigned int init_nr_meta_gen_errors;
+       /*
+        * The following error bitmaps are all for the current status.
+        * Every time we submit a new read, these bitmaps may be updated.
+        *
+-       * error_bitmap = io_error_bitmap | csum_error_bitmap | meta_error_bitmap;
++       * error_bitmap = io_error_bitmap | csum_error_bitmap |
++       *                meta_error_bitmap | meta_generation_bitmap;
+        *
+        * IO and csum errors can happen for both metadata and data.
+        */
+@@ -166,6 +168,7 @@ struct scrub_stripe {
+       unsigned long io_error_bitmap;
+       unsigned long csum_error_bitmap;
+       unsigned long meta_error_bitmap;
++      unsigned long meta_gen_error_bitmap;
+       /* For writeback (repair or replace) error reporting. */
+       unsigned long write_error_bitmap;
+@@ -672,7 +675,7 @@ static void scrub_verify_one_metadata(struct scrub_stripe *stripe, int sector_nr
+       }
+       if (stripe->sectors[sector_nr].generation !=
+           btrfs_stack_header_generation(header)) {
+-              bitmap_set(&stripe->meta_error_bitmap, sector_nr, sectors_per_tree);
++              bitmap_set(&stripe->meta_gen_error_bitmap, sector_nr, sectors_per_tree);
+               bitmap_set(&stripe->error_bitmap, sector_nr, sectors_per_tree);
+               btrfs_warn_rl(fs_info,
+               "tree block %llu mirror %u has bad generation, has %llu want %llu",
+@@ -684,6 +687,7 @@ static void scrub_verify_one_metadata(struct scrub_stripe *stripe, int sector_nr
+       bitmap_clear(&stripe->error_bitmap, sector_nr, sectors_per_tree);
+       bitmap_clear(&stripe->csum_error_bitmap, sector_nr, sectors_per_tree);
+       bitmap_clear(&stripe->meta_error_bitmap, sector_nr, sectors_per_tree);
++      bitmap_clear(&stripe->meta_gen_error_bitmap, sector_nr, sectors_per_tree);
+ }
+ static void scrub_verify_one_sector(struct scrub_stripe *stripe, int sector_nr)
+@@ -972,8 +976,22 @@ static void scrub_stripe_report_errors(struct scrub_ctx *sctx,
+                       if (__ratelimit(&rs) && dev)
+                               scrub_print_common_warning("header error", dev, false,
+                                                    stripe->logical, physical);
++              if (test_bit(sector_nr, &stripe->meta_gen_error_bitmap))
++                      if (__ratelimit(&rs) && dev)
++                              scrub_print_common_warning("generation error", dev, false,
++                                                   stripe->logical, physical);
+       }
++      /* Update the device stats. */
++      for (int i = 0; i < stripe->init_nr_io_errors; i++)
++              btrfs_dev_stat_inc_and_print(stripe->dev, BTRFS_DEV_STAT_READ_ERRS);
++      for (int i = 0; i < stripe->init_nr_csum_errors; i++)
++              btrfs_dev_stat_inc_and_print(stripe->dev, BTRFS_DEV_STAT_CORRUPTION_ERRS);
++      /* Generation mismatch error is based on each metadata, not each block. */
++      for (int i = 0; i < stripe->init_nr_meta_gen_errors;
++           i += (fs_info->nodesize >> fs_info->sectorsize_bits))
++              btrfs_dev_stat_inc_and_print(stripe->dev, BTRFS_DEV_STAT_GENERATION_ERRS);
++
+       spin_lock(&sctx->stat_lock);
+       sctx->stat.data_extents_scrubbed += stripe->nr_data_extents;
+       sctx->stat.tree_extents_scrubbed += stripe->nr_meta_extents;
+@@ -982,7 +1000,8 @@ static void scrub_stripe_report_errors(struct scrub_ctx *sctx,
+       sctx->stat.no_csum += nr_nodatacsum_sectors;
+       sctx->stat.read_errors += stripe->init_nr_io_errors;
+       sctx->stat.csum_errors += stripe->init_nr_csum_errors;
+-      sctx->stat.verify_errors += stripe->init_nr_meta_errors;
++      sctx->stat.verify_errors += stripe->init_nr_meta_errors +
++                                  stripe->init_nr_meta_gen_errors;
+       sctx->stat.uncorrectable_errors +=
+               bitmap_weight(&stripe->error_bitmap, stripe->nr_sectors);
+       sctx->stat.corrected_errors += nr_repaired_sectors;
+@@ -1028,6 +1047,8 @@ static void scrub_stripe_read_repair_worker(struct work_struct *work)
+                                                   stripe->nr_sectors);
+       stripe->init_nr_meta_errors = bitmap_weight(&stripe->meta_error_bitmap,
+                                                   stripe->nr_sectors);
++      stripe->init_nr_meta_gen_errors = bitmap_weight(&stripe->meta_gen_error_bitmap,
++                                                      stripe->nr_sectors);
+       if (bitmap_empty(&stripe->init_error_bitmap, stripe->nr_sectors))
+               goto out;
+@@ -1142,6 +1163,9 @@ static void scrub_write_endio(struct btrfs_bio *bbio)
+               bitmap_set(&stripe->write_error_bitmap, sector_nr,
+                          bio_size >> fs_info->sectorsize_bits);
+               spin_unlock_irqrestore(&stripe->write_error_lock, flags);
++              for (int i = 0; i < (bio_size >> fs_info->sectorsize_bits); i++)
++                      btrfs_dev_stat_inc_and_print(stripe->dev,
++                                                   BTRFS_DEV_STAT_WRITE_ERRS);
+       }
+       bio_put(&bbio->bio);
+@@ -1508,10 +1532,12 @@ static void scrub_stripe_reset_bitmaps(struct scrub_stripe *stripe)
+       stripe->init_nr_io_errors = 0;
+       stripe->init_nr_csum_errors = 0;
+       stripe->init_nr_meta_errors = 0;
++      stripe->init_nr_meta_gen_errors = 0;
+       stripe->error_bitmap = 0;
+       stripe->io_error_bitmap = 0;
+       stripe->csum_error_bitmap = 0;
+       stripe->meta_error_bitmap = 0;
++      stripe->meta_gen_error_bitmap = 0;
+ }
+ /*
+-- 
+2.39.5
+
diff --git a/queue-6.15/bus-fsl-mc-fix-double-free-on-mc_dev.patch b/queue-6.15/bus-fsl-mc-fix-double-free-on-mc_dev.patch
new file mode 100644 (file)
index 0000000..fb67568
--- /dev/null
@@ -0,0 +1,52 @@
+From b86fdfd900ce4f958632bff0360ae8dabcbcb3db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Apr 2025 13:58:09 +0300
+Subject: bus: fsl-mc: fix double-free on mc_dev
+
+From: Ioana Ciornei <ioana.ciornei@nxp.com>
+
+[ Upstream commit d694bf8a9acdbd061596f3e7549bc8cb70750a60 ]
+
+The blamed commit tried to simplify how the deallocations are done but,
+in the process, introduced a double-free on the mc_dev variable.
+
+In case the MC device is a DPRC, a new mc_bus is allocated and the
+mc_dev variable is just a reference to one of its fields. In this
+circumstance, on the error path only the mc_bus should be freed.
+
+This commit introduces back the following checkpatch warning which is a
+false-positive.
+
+WARNING: kfree(NULL) is safe and this check is probably not required
++       if (mc_bus)
++               kfree(mc_bus);
+
+Fixes: a042fbed0290 ("staging: fsl-mc: simplify couple of deallocations")
+Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
+Link: https://lore.kernel.org/r/20250408105814.2837951-2-ioana.ciornei@nxp.com
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bus/fsl-mc/fsl-mc-bus.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c
+index a8be8cf246fb6..0c3a38d7f3358 100644
+--- a/drivers/bus/fsl-mc/fsl-mc-bus.c
++++ b/drivers/bus/fsl-mc/fsl-mc-bus.c
+@@ -906,8 +906,10 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc,
+ error_cleanup_dev:
+       kfree(mc_dev->regions);
+-      kfree(mc_bus);
+-      kfree(mc_dev);
++      if (mc_bus)
++              kfree(mc_bus);
++      else
++              kfree(mc_dev);
+       return error;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/bus-fsl_mc-fix-driver_managed_dma-check.patch b/queue-6.15/bus-fsl_mc-fix-driver_managed_dma-check.patch
new file mode 100644 (file)
index 0000000..3b41872
--- /dev/null
@@ -0,0 +1,60 @@
+From e87adfaa9cff6b693e78f8f9421c793bff31f12f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 14:39:28 +0100
+Subject: bus: fsl_mc: Fix driver_managed_dma check
+
+From: Robin Murphy <robin.murphy@arm.com>
+
+[ Upstream commit 152f33ee30ee6a7f4c15bedd7529dc5945315547 ]
+
+Since it's not currently safe to take device_lock() in the IOMMU probe
+path, that can race against really_probe() setting dev->driver before
+attempting to bind. The race itself isn't so bad, since we're only
+concerned with dereferencing dev->driver itself anyway, but sadly my
+attempt to implement the check with minimal churn leads to a kind of
+TOCTOU issue, where dev->driver becomes valid after to_fsl_mc_driver(NULL)
+is already computed, and thus the check fails to work as intended.
+
+Will and I both hit this with the platform bus, but the pattern here is
+the same, so fix it for correctness too.
+
+Reported-by: Will McVicker <willmcvicker@google.com>
+Fixes: bcb81ac6ae3c ("iommu: Get DT/ACPI parsing into the proper probe path")
+Signed-off-by: Robin Murphy <robin.murphy@arm.com>
+Reviewed-by: Will McVicker <willmcvicker@google.com>
+Link: https://lore.kernel.org/r/20250425133929.646493-3-robin.murphy@arm.com
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bus/fsl-mc/fsl-mc-bus.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c
+index 0c3a38d7f3358..7671bd1585455 100644
+--- a/drivers/bus/fsl-mc/fsl-mc-bus.c
++++ b/drivers/bus/fsl-mc/fsl-mc-bus.c
+@@ -139,9 +139,9 @@ static int fsl_mc_bus_uevent(const struct device *dev, struct kobj_uevent_env *e
+ static int fsl_mc_dma_configure(struct device *dev)
+ {
++      const struct device_driver *drv = READ_ONCE(dev->driver);
+       struct device *dma_dev = dev;
+       struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
+-      struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(dev->driver);
+       u32 input_id = mc_dev->icid;
+       int ret;
+@@ -153,8 +153,8 @@ static int fsl_mc_dma_configure(struct device *dev)
+       else
+               ret = acpi_dma_configure_id(dev, DEV_DMA_COHERENT, &input_id);
+-      /* @mc_drv may not be valid when we're called from the IOMMU layer */
+-      if (!ret && dev->driver && !mc_drv->driver_managed_dma) {
++      /* @drv may not be valid when we're called from the IOMMU layer */
++      if (!ret && drv && !to_fsl_mc_driver(drv)->driver_managed_dma) {
+               ret = iommu_device_use_default_domain(dev);
+               if (ret)
+                       arch_teardown_dma_ops(dev);
+-- 
+2.39.5
+
diff --git a/queue-6.15/calipso-don-t-call-calipso-functions-for-af_inet-sk.patch b/queue-6.15/calipso-don-t-call-calipso-functions-for-af_inet-sk.patch
new file mode 100644 (file)
index 0000000..29e35a7
--- /dev/null
@@ -0,0 +1,108 @@
+From 18c1409ed79efe5532e2c442a0685816d0ff2ca4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 May 2025 15:18:56 -0700
+Subject: calipso: Don't call calipso functions for AF_INET sk.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 6e9f2df1c550ead7cecb3e450af1105735020c92 ]
+
+syzkaller reported a null-ptr-deref in txopt_get(). [0]
+
+The offset 0x70 was of struct ipv6_txoptions in struct ipv6_pinfo,
+so struct ipv6_pinfo was NULL there.
+
+However, this never happens for IPv6 sockets as inet_sk(sk)->pinet6
+is always set in inet6_create(), meaning the socket was not IPv6 one.
+
+The root cause is missing validation in netlbl_conn_setattr().
+
+netlbl_conn_setattr() switches branches based on struct
+sockaddr.sa_family, which is passed from userspace.  However,
+netlbl_conn_setattr() does not check if the address family matches
+the socket.
+
+The syzkaller must have called connect() for an IPv6 address on
+an IPv4 socket.
+
+We have a proper validation in tcp_v[46]_connect(), but
+security_socket_connect() is called in the earlier stage.
+
+Let's copy the validation to netlbl_conn_setattr().
+
+[0]:
+Oops: general protection fault, probably for non-canonical address 0xdffffc000000000e: 0000 [#1] PREEMPT SMP KASAN NOPTI
+KASAN: null-ptr-deref in range [0x0000000000000070-0x0000000000000077]
+CPU: 2 UID: 0 PID: 12928 Comm: syz.9.1677 Not tainted 6.12.0 #1
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
+RIP: 0010:txopt_get include/net/ipv6.h:390 [inline]
+RIP: 0010:
+Code: 02 00 00 49 8b ac 24 f8 02 00 00 e8 84 69 2a fd e8 ff 00 16 fd 48 8d 7d 70 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 <80> 3c 02 00 0f 85 53 02 00 00 48 8b 6d 70 48 85 ed 0f 84 ab 01 00
+RSP: 0018:ffff88811b8afc48 EFLAGS: 00010212
+RAX: dffffc0000000000 RBX: 1ffff11023715f8a RCX: ffffffff841ab00c
+RDX: 000000000000000e RSI: ffffc90007d9e000 RDI: 0000000000000070
+RBP: 0000000000000000 R08: ffffed1023715f9d R09: ffffed1023715f9e
+R10: ffffed1023715f9d R11: 0000000000000003 R12: ffff888123075f00
+R13: ffff88810245bd80 R14: ffff888113646780 R15: ffff888100578a80
+FS:  00007f9019bd7640(0000) GS:ffff8882d2d00000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00007f901b927bac CR3: 0000000104788003 CR4: 0000000000770ef0
+PKRU: 80000000
+Call Trace:
+ <TASK>
+ calipso_sock_setattr+0x56/0x80 net/netlabel/netlabel_calipso.c:557
+ netlbl_conn_setattr+0x10c/0x280 net/netlabel/netlabel_kapi.c:1177
+ selinux_netlbl_socket_connect_helper+0xd3/0x1b0 security/selinux/netlabel.c:569
+ selinux_netlbl_socket_connect_locked security/selinux/netlabel.c:597 [inline]
+ selinux_netlbl_socket_connect+0xb6/0x100 security/selinux/netlabel.c:615
+ selinux_socket_connect+0x5f/0x80 security/selinux/hooks.c:4931
+ security_socket_connect+0x50/0xa0 security/security.c:4598
+ __sys_connect_file+0xa4/0x190 net/socket.c:2067
+ __sys_connect+0x12c/0x170 net/socket.c:2088
+ __do_sys_connect net/socket.c:2098 [inline]
+ __se_sys_connect net/socket.c:2095 [inline]
+ __x64_sys_connect+0x73/0xb0 net/socket.c:2095
+ do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+ do_syscall_64+0xaa/0x1b0 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+RIP: 0033:0x7f901b61a12d
+Code: 02 b8 ff ff ff ff c3 66 0f 1f 44 00 00 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48
+RSP: 002b:00007f9019bd6fa8 EFLAGS: 00000246 ORIG_RAX: 000000000000002a
+RAX: ffffffffffffffda RBX: 00007f901b925fa0 RCX: 00007f901b61a12d
+RDX: 000000000000001c RSI: 0000200000000140 RDI: 0000000000000003
+RBP: 00007f901b701505 R08: 0000000000000000 R09: 0000000000000000
+R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
+R13: 0000000000000000 R14: 00007f901b5b62a0 R15: 00007f9019bb7000
+ </TASK>
+Modules linked in:
+
+Fixes: ceba1832b1b2 ("calipso: Set the calipso socket label to match the secattr.")
+Reported-by: syzkaller <syzkaller@googlegroups.com>
+Reported-by: John Cheung <john.cs.hey@gmail.com>
+Closes: https://lore.kernel.org/netdev/CAP=Rh=M1LzunrcQB1fSGauMrJrhL6GGps5cPAKzHJXj6GQV+-g@mail.gmail.com/
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Acked-by: Paul Moore <paul@paul-moore.com>
+Link: https://patch.msgid.link/20250522221858.91240-1-kuniyu@amazon.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netlabel/netlabel_kapi.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
+index cd9160bbc9197..6ea16138582c0 100644
+--- a/net/netlabel/netlabel_kapi.c
++++ b/net/netlabel/netlabel_kapi.c
+@@ -1165,6 +1165,9 @@ int netlbl_conn_setattr(struct sock *sk,
+               break;
+ #if IS_ENABLED(CONFIG_IPV6)
+       case AF_INET6:
++              if (sk->sk_family != AF_INET6)
++                      return -EAFNOSUPPORT;
++
+               addr6 = (struct sockaddr_in6 *)addr;
+               entry = netlbl_domhsh_getentry_af6(secattr->domain,
+                                                  &addr6->sin6_addr);
+-- 
+2.39.5
+
diff --git a/queue-6.15/char-tlclk-fix-correct-sysfs-directory-path-for-tlcl.patch b/queue-6.15/char-tlclk-fix-correct-sysfs-directory-path-for-tlcl.patch
new file mode 100644 (file)
index 0000000..a3dc62e
--- /dev/null
@@ -0,0 +1,39 @@
+From 2d47f3173a5301ebe251e530433b07a1b47deb98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 May 2025 20:05:00 +0000
+Subject: char: tlclk: Fix correct sysfs directory path for tlclk
+
+From: Roxana Nicolescu <nicolescu.roxana@protonmail.com>
+
+[ Upstream commit 46a4d12a005c58317e89b5644774c683365dc2ca ]
+
+The tlckl driver does not create a platform device anymore. It was
+recently changed to use a faux device instead. Therefore the sysfs path
+has changed from /sys/devices/platform/telco_clock to
+/sys/devices/faux/telco_clock.
+
+Fixes: 72239a78f9f5 ("tlclk: convert to use faux_device")
+Signed-off-by: Roxana Nicolescu <nicolescu.roxana@protonmail.com>
+Link: https://lore.kernel.org/r/20250501200457.18506-1-nicolescu.roxana@protonmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
+index 8fb33c90482f7..ae61967605563 100644
+--- a/drivers/char/Kconfig
++++ b/drivers/char/Kconfig
+@@ -404,7 +404,7 @@ config TELCLOCK
+         configuration of the telecom clock configuration settings.  This
+         device is used for hardware synchronization across the ATCA backplane
+         fabric.  Upon loading, the driver exports a sysfs directory,
+-        /sys/devices/platform/telco_clock, with a number of files for
++        /sys/devices/faux/telco_clock, with a number of files for
+         controlling the behavior of this hardware.
+ source "drivers/s390/char/Kconfig"
+-- 
+2.39.5
+
diff --git a/queue-6.15/cifs-fix-validation-of-smb1-query-reparse-point-resp.patch b/queue-6.15/cifs-fix-validation-of-smb1-query-reparse-point-resp.patch
new file mode 100644 (file)
index 0000000..ac3d4a1
--- /dev/null
@@ -0,0 +1,83 @@
+From 2a7ee387dceea810f0c4b79f37dce40ddc18876c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 Dec 2024 19:55:13 +0100
+Subject: cifs: Fix validation of SMB1 query reparse point response
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+[ Upstream commit 56e84c64fc257a95728ee73165456b025c48d408 ]
+
+Validate the SMB1 query reparse point response per [MS-CIFS] section
+2.2.7.2 NT_TRANSACT_IOCTL.
+
+NT_TRANSACT_IOCTL response contains one word long setup data after which is
+ByteCount member. So check that SetupCount is 1 before trying to read and
+use ByteCount member.
+
+Output setup data contains ReturnedDataLen member which is the output
+length of executed IOCTL command by remote system. So check that output was
+not truncated before transferring over network.
+
+Change MaxSetupCount of NT_TRANSACT_IOCTL request from 4 to 1 as io_rsp
+structure already expects one word long output setup data. This should
+prevent server sending incompatible structure (in case it would be extended
+in future, which is unlikely).
+
+Change MaxParameterCount of NT_TRANSACT_IOCTL request from 2 to 0 as
+NT IOCTL does not have any documented output parameters and this function
+does not parse any output parameters at all.
+
+Fixes: ed3e0a149b58 ("smb: client: implement ->query_reparse_point() for SMB1")
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/cifssmb.c | 20 ++++++++++++++++++--
+ 1 file changed, 18 insertions(+), 2 deletions(-)
+
+diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c
+index 477792c07d458..a3ba3346ed313 100644
+--- a/fs/smb/client/cifssmb.c
++++ b/fs/smb/client/cifssmb.c
+@@ -2753,10 +2753,10 @@ int cifs_query_reparse_point(const unsigned int xid,
+       io_req->TotalParameterCount = 0;
+       io_req->TotalDataCount = 0;
+-      io_req->MaxParameterCount = cpu_to_le32(2);
++      io_req->MaxParameterCount = cpu_to_le32(0);
+       /* BB find exact data count max from sess structure BB */
+       io_req->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
+-      io_req->MaxSetupCount = 4;
++      io_req->MaxSetupCount = 1;
+       io_req->Reserved = 0;
+       io_req->ParameterOffset = 0;
+       io_req->DataCount = 0;
+@@ -2783,6 +2783,22 @@ int cifs_query_reparse_point(const unsigned int xid,
+               goto error;
+       }
++      /* SetupCount must be 1, otherwise offset to ByteCount is incorrect. */
++      if (io_rsp->SetupCount != 1) {
++              rc = -EIO;
++              goto error;
++      }
++
++      /*
++       * ReturnedDataLen is output length of executed IOCTL.
++       * DataCount is output length transferred over network.
++       * Check that we have full FSCTL_GET_REPARSE_POINT buffer.
++       */
++      if (data_count != le16_to_cpu(io_rsp->ReturnedDataLen)) {
++              rc = -EIO;
++              goto error;
++      }
++
+       end = 2 + get_bcc(&io_rsp->hdr) + (__u8 *)&io_rsp->ByteCount;
+       start = (__u8 *)&io_rsp->hdr.Protocol + data_offset;
+       if (start >= end) {
+-- 
+2.39.5
+
diff --git a/queue-6.15/clk-bcm-rpi-add-null-check-in-raspberrypi_clk_regist.patch b/queue-6.15/clk-bcm-rpi-add-null-check-in-raspberrypi_clk_regist.patch
new file mode 100644 (file)
index 0000000..96f4620
--- /dev/null
@@ -0,0 +1,42 @@
+From 320c1433a67be4ea9ca4aaebdd90f619934f0e0d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Apr 2025 10:05:13 +0800
+Subject: clk: bcm: rpi: Add NULL check in raspberrypi_clk_register()
+
+From: Henry Martin <bsdhenrymartin@gmail.com>
+
+[ Upstream commit 73c46d9a93d071ca69858dea3f569111b03e549e ]
+
+devm_kasprintf() returns NULL when memory allocation fails. Currently,
+raspberrypi_clk_register() does not check for this case, which results
+in a NULL pointer dereference.
+
+Add NULL check after devm_kasprintf() to prevent this issue.
+
+Fixes: 93d2725affd6 ("clk: bcm: rpi: Discover the firmware clocks")
+Signed-off-by: Henry Martin <bsdhenrymartin@gmail.com>
+Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Link: https://lore.kernel.org/r/20250402020513.42628-1-bsdhenrymartin@gmail.com
+Reviewed-by: Stefan Wahren <wahrenst@gmx.net>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/bcm/clk-raspberrypi.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/clk/bcm/clk-raspberrypi.c b/drivers/clk/bcm/clk-raspberrypi.c
+index 0e1fe3759530a..720acc10f8aa4 100644
+--- a/drivers/clk/bcm/clk-raspberrypi.c
++++ b/drivers/clk/bcm/clk-raspberrypi.c
+@@ -286,6 +286,8 @@ static struct clk_hw *raspberrypi_clk_register(struct raspberrypi_clk *rpi,
+       init.name = devm_kasprintf(rpi->dev, GFP_KERNEL,
+                                  "fw-clk-%s",
+                                  rpi_firmware_clk_names[id]);
++      if (!init.name)
++              return ERR_PTR(-ENOMEM);
+       init.ops = &raspberrypi_firmware_clk_ops;
+       init.flags = CLK_GET_RATE_NOCACHE;
+-- 
+2.39.5
+
diff --git a/queue-6.15/clk-qcom-camcc-sm6350-add-_wait_val-values-for-gdscs.patch b/queue-6.15/clk-qcom-camcc-sm6350-add-_wait_val-values-for-gdscs.patch
new file mode 100644 (file)
index 0000000..ed108fd
--- /dev/null
@@ -0,0 +1,95 @@
+From 8486d3ad6b09c3dd905d1bbadd7466833258afd1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 14:12:55 +0200
+Subject: clk: qcom: camcc-sm6350: Add *_wait_val values for GDSCs
+
+From: Luca Weiss <luca.weiss@fairphone.com>
+
+[ Upstream commit e7b1c13280ad866f3b935f6c658713c41db61635 ]
+
+Compared to the msm-4.19 driver the mainline GDSC driver always sets the
+bits for en_rest, en_few & clk_dis, and if those values are not set
+per-GDSC in the respective driver then the default value from the GDSC
+driver is used. The downstream driver only conditionally sets
+clk_dis_wait_val if qcom,clk-dis-wait-val is given in devicetree.
+
+Correct this situation by explicitly setting those values. For all GDSCs
+the reset value of those bits are used.
+
+Fixes: 80f5451d9a7c ("clk: qcom: Add camera clock controller driver for SM6350")
+Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
+Reviewed-by: Taniya Das <quic_tdas@quicinc.com>
+Link: https://lore.kernel.org/r/20250425-sm6350-gdsc-val-v1-1-1f252d9c5e4e@fairphone.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/camcc-sm6350.c | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/drivers/clk/qcom/camcc-sm6350.c b/drivers/clk/qcom/camcc-sm6350.c
+index 1871970fb046d..8aac97d29ce3f 100644
+--- a/drivers/clk/qcom/camcc-sm6350.c
++++ b/drivers/clk/qcom/camcc-sm6350.c
+@@ -1695,6 +1695,9 @@ static struct clk_branch camcc_sys_tmr_clk = {
+ static struct gdsc bps_gdsc = {
+       .gdscr = 0x6004,
++      .en_rest_wait_val = 0x2,
++      .en_few_wait_val = 0x2,
++      .clk_dis_wait_val = 0xf,
+       .pd = {
+               .name = "bps_gdsc",
+       },
+@@ -1704,6 +1707,9 @@ static struct gdsc bps_gdsc = {
+ static struct gdsc ipe_0_gdsc = {
+       .gdscr = 0x7004,
++      .en_rest_wait_val = 0x2,
++      .en_few_wait_val = 0x2,
++      .clk_dis_wait_val = 0xf,
+       .pd = {
+               .name = "ipe_0_gdsc",
+       },
+@@ -1713,6 +1719,9 @@ static struct gdsc ipe_0_gdsc = {
+ static struct gdsc ife_0_gdsc = {
+       .gdscr = 0x9004,
++      .en_rest_wait_val = 0x2,
++      .en_few_wait_val = 0x2,
++      .clk_dis_wait_val = 0xf,
+       .pd = {
+               .name = "ife_0_gdsc",
+       },
+@@ -1721,6 +1730,9 @@ static struct gdsc ife_0_gdsc = {
+ static struct gdsc ife_1_gdsc = {
+       .gdscr = 0xa004,
++      .en_rest_wait_val = 0x2,
++      .en_few_wait_val = 0x2,
++      .clk_dis_wait_val = 0xf,
+       .pd = {
+               .name = "ife_1_gdsc",
+       },
+@@ -1729,6 +1741,9 @@ static struct gdsc ife_1_gdsc = {
+ static struct gdsc ife_2_gdsc = {
+       .gdscr = 0xb004,
++      .en_rest_wait_val = 0x2,
++      .en_few_wait_val = 0x2,
++      .clk_dis_wait_val = 0xf,
+       .pd = {
+               .name = "ife_2_gdsc",
+       },
+@@ -1737,6 +1752,9 @@ static struct gdsc ife_2_gdsc = {
+ static struct gdsc titan_top_gdsc = {
+       .gdscr = 0x14004,
++      .en_rest_wait_val = 0x2,
++      .en_few_wait_val = 0x2,
++      .clk_dis_wait_val = 0xf,
+       .pd = {
+               .name = "titan_top_gdsc",
+       },
+-- 
+2.39.5
+
diff --git a/queue-6.15/clk-qcom-dispcc-sm6350-add-_wait_val-values-for-gdsc.patch b/queue-6.15/clk-qcom-dispcc-sm6350-add-_wait_val-values-for-gdsc.patch
new file mode 100644 (file)
index 0000000..5b7eac5
--- /dev/null
@@ -0,0 +1,45 @@
+From 921f0617f305e68be0393d33c8e1714d31d0f089 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 14:12:56 +0200
+Subject: clk: qcom: dispcc-sm6350: Add *_wait_val values for GDSCs
+
+From: Luca Weiss <luca.weiss@fairphone.com>
+
+[ Upstream commit 673989d27123618afab56df1143a75454178b4ae ]
+
+Compared to the msm-4.19 driver the mainline GDSC driver always sets the
+bits for en_rest, en_few & clk_dis, and if those values are not set
+per-GDSC in the respective driver then the default value from the GDSC
+driver is used. The downstream driver only conditionally sets
+clk_dis_wait_val if qcom,clk-dis-wait-val is given in devicetree.
+
+Correct this situation by explicitly setting those values. For all GDSCs
+the reset value of those bits are used.
+
+Fixes: 837519775f1d ("clk: qcom: Add display clock controller driver for SM6350")
+Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
+Reviewed-by: Taniya Das <quic_tdas@quicinc.com>
+Link: https://lore.kernel.org/r/20250425-sm6350-gdsc-val-v1-2-1f252d9c5e4e@fairphone.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/dispcc-sm6350.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/clk/qcom/dispcc-sm6350.c b/drivers/clk/qcom/dispcc-sm6350.c
+index e703ecf00e440..b0bd163a449cc 100644
+--- a/drivers/clk/qcom/dispcc-sm6350.c
++++ b/drivers/clk/qcom/dispcc-sm6350.c
+@@ -681,6 +681,9 @@ static struct clk_branch disp_cc_xo_clk = {
+ static struct gdsc mdss_gdsc = {
+       .gdscr = 0x1004,
++      .en_rest_wait_val = 0x2,
++      .en_few_wait_val = 0x2,
++      .clk_dis_wait_val = 0xf,
+       .pd = {
+               .name = "mdss_gdsc",
+       },
+-- 
+2.39.5
+
diff --git a/queue-6.15/clk-qcom-gcc-msm8939-fix-mclk0-mclk1-for-24-mhz.patch b/queue-6.15/clk-qcom-gcc-msm8939-fix-mclk0-mclk1-for-24-mhz.patch
new file mode 100644 (file)
index 0000000..1f3b2c5
--- /dev/null
@@ -0,0 +1,49 @@
+From 8ab9d9d2ebe4138ae12f3367ea6ecec88bdba3e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Apr 2025 18:45:12 +0200
+Subject: clk: qcom: gcc-msm8939: Fix mclk0 & mclk1 for 24 MHz
+
+From: Vincent Knecht <vincent.knecht@mailoo.org>
+
+[ Upstream commit 9e7acf70cf6aa7b22f67d911f50a8cd510e8fb00 ]
+
+Fix mclk0 & mclk1 parent map to use correct GPLL6 configuration and
+freq_tbl to use GPLL6 instead of GPLL0 so that they tick at 24 MHz.
+
+Fixes: 1664014e4679 ("clk: qcom: gcc-msm8939: Add MSM8939 Generic Clock Controller")
+Suggested-by: Stephan Gerhold <stephan@gerhold.net>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Signed-off-by: Vincent Knecht <vincent.knecht@mailoo.org>
+Link: https://lore.kernel.org/r/20250414-gcc-msm8939-fixes-mclk-v2-resend2-v2-1-5ddcf572a6de@mailoo.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-msm8939.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/qcom/gcc-msm8939.c b/drivers/clk/qcom/gcc-msm8939.c
+index 7431c9a65044f..45193b3d714ba 100644
+--- a/drivers/clk/qcom/gcc-msm8939.c
++++ b/drivers/clk/qcom/gcc-msm8939.c
+@@ -432,7 +432,7 @@ static const struct parent_map gcc_xo_gpll0_gpll1a_gpll6_sleep_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL1_AUX, 2 },
+-      { P_GPLL6, 2 },
++      { P_GPLL6, 3 },
+       { P_SLEEP_CLK, 6 },
+ };
+@@ -1113,7 +1113,7 @@ static struct clk_rcg2 jpeg0_clk_src = {
+ };
+ static const struct freq_tbl ftbl_gcc_camss_mclk0_1_clk[] = {
+-      F(24000000, P_GPLL0, 1, 1, 45),
++      F(24000000, P_GPLL6, 1, 1, 45),
+       F(66670000, P_GPLL0, 12, 0, 0),
+       { }
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.15/clk-qcom-gcc-sm6350-add-_wait_val-values-for-gdscs.patch b/queue-6.15/clk-qcom-gcc-sm6350-add-_wait_val-values-for-gdscs.patch
new file mode 100644 (file)
index 0000000..8706ae9
--- /dev/null
@@ -0,0 +1,55 @@
+From 1895a4a0865657b768a575cb39042e9ee5d32052 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 14:12:57 +0200
+Subject: clk: qcom: gcc-sm6350: Add *_wait_val values for GDSCs
+
+From: Luca Weiss <luca.weiss@fairphone.com>
+
+[ Upstream commit afdfd829a99e467869e3ca1955fb6c6e337c340a ]
+
+Compared to the msm-4.19 driver the mainline GDSC driver always sets the
+bits for en_rest, en_few & clk_dis, and if those values are not set
+per-GDSC in the respective driver then the default value from the GDSC
+driver is used. The downstream driver only conditionally sets
+clk_dis_wait_val if qcom,clk-dis-wait-val is given in devicetree.
+
+Correct this situation by explicitly setting those values. For all GDSCs
+the reset value of those bits are used.
+
+Fixes: 131abae905df ("clk: qcom: Add SM6350 GCC driver")
+Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
+Reviewed-by: Taniya Das <quic_tdas@quicinc.com>
+Link: https://lore.kernel.org/r/20250425-sm6350-gdsc-val-v1-3-1f252d9c5e4e@fairphone.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-sm6350.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/clk/qcom/gcc-sm6350.c b/drivers/clk/qcom/gcc-sm6350.c
+index 74346dc026068..a4d6dff9d0f7f 100644
+--- a/drivers/clk/qcom/gcc-sm6350.c
++++ b/drivers/clk/qcom/gcc-sm6350.c
+@@ -2320,6 +2320,9 @@ static struct clk_branch gcc_video_xo_clk = {
+ static struct gdsc usb30_prim_gdsc = {
+       .gdscr = 0x1a004,
++      .en_rest_wait_val = 0x2,
++      .en_few_wait_val = 0x2,
++      .clk_dis_wait_val = 0xf,
+       .pd = {
+               .name = "usb30_prim_gdsc",
+       },
+@@ -2328,6 +2331,9 @@ static struct gdsc usb30_prim_gdsc = {
+ static struct gdsc ufs_phy_gdsc = {
+       .gdscr = 0x3a004,
++      .en_rest_wait_val = 0x2,
++      .en_few_wait_val = 0x2,
++      .clk_dis_wait_val = 0xf,
+       .pd = {
+               .name = "ufs_phy_gdsc",
+       },
+-- 
+2.39.5
+
diff --git a/queue-6.15/clk-qcom-gpucc-sm6350-add-_wait_val-values-for-gdscs.patch b/queue-6.15/clk-qcom-gpucc-sm6350-add-_wait_val-values-for-gdscs.patch
new file mode 100644 (file)
index 0000000..791481e
--- /dev/null
@@ -0,0 +1,56 @@
+From a9b76c16fb3f4b775fe4b48e7d8abf753bd37638 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 14:12:58 +0200
+Subject: clk: qcom: gpucc-sm6350: Add *_wait_val values for GDSCs
+
+From: Luca Weiss <luca.weiss@fairphone.com>
+
+[ Upstream commit d988b0b866c2aeb23aa74022b5bbd463165a7a33 ]
+
+Compared to the msm-4.19 driver the mainline GDSC driver always sets the
+bits for en_rest, en_few & clk_dis, and if those values are not set
+per-GDSC in the respective driver then the default value from the GDSC
+driver is used. The downstream driver only conditionally sets
+clk_dis_wait_val if qcom,clk-dis-wait-val is given in devicetree.
+
+Correct this situation by explicitly setting those values. For all GDSCs
+the reset value of those bits are used, with the exception of
+gpu_cx_gdsc which has an explicit value (qcom,clk-dis-wait-val = <8>).
+
+Fixes: 013804a727a0 ("clk: qcom: Add GPU clock controller driver for SM6350")
+Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
+Reviewed-by: Taniya Das <quic_tdas@quicinc.com>
+Link: https://lore.kernel.org/r/20250425-sm6350-gdsc-val-v1-4-1f252d9c5e4e@fairphone.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gpucc-sm6350.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/clk/qcom/gpucc-sm6350.c b/drivers/clk/qcom/gpucc-sm6350.c
+index 35ed0500bc593..ee89c42413f88 100644
+--- a/drivers/clk/qcom/gpucc-sm6350.c
++++ b/drivers/clk/qcom/gpucc-sm6350.c
+@@ -413,6 +413,9 @@ static struct clk_branch gpu_cc_gx_vsense_clk = {
+ static struct gdsc gpu_cx_gdsc = {
+       .gdscr = 0x106c,
+       .gds_hw_ctrl = 0x1540,
++      .en_rest_wait_val = 0x2,
++      .en_few_wait_val = 0x2,
++      .clk_dis_wait_val = 0x8,
+       .pd = {
+               .name = "gpu_cx_gdsc",
+       },
+@@ -423,6 +426,9 @@ static struct gdsc gpu_cx_gdsc = {
+ static struct gdsc gpu_gx_gdsc = {
+       .gdscr = 0x100c,
+       .clamp_io_ctrl = 0x1508,
++      .en_rest_wait_val = 0x2,
++      .en_few_wait_val = 0x2,
++      .clk_dis_wait_val = 0x2,
+       .pd = {
+               .name = "gpu_gx_gdsc",
+               .power_on = gdsc_gx_do_nothing_enable,
+-- 
+2.39.5
+
diff --git a/queue-6.15/clk-test-forward-declare-struct-of_phandle_args-in-k.patch b/queue-6.15/clk-test-forward-declare-struct-of_phandle_args-in-k.patch
new file mode 100644 (file)
index 0000000..bf751e1
--- /dev/null
@@ -0,0 +1,44 @@
+From f8cf17e10300187efd5ad23c7bb3b9bbc937ee28 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Mar 2025 12:52:14 +0000
+Subject: clk: test: Forward-declare struct of_phandle_args in kunit/clk.h
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Richard Fitzgerald <rf@opensource.cirrus.com>
+
+[ Upstream commit 7a0c1872ee7db25d711ac29a55f36844a7108308 ]
+
+Add a forward-declare of struct of_phandle_args to prevent the compiler
+warning:
+
+../include/kunit/clk.h:29:63: warning: ‘struct of_phandle_args’ declared
+inside parameter list will not be visible outside of this definition or
+declaration
+   struct clk_hw *(*get)(struct of_phandle_args *clkspec, void *data),
+
+Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
+Link: https://lore.kernel.org/r/20250327125214.82598-1-rf@opensource.cirrus.com
+Fixes: a82fcb16d977 ("clk: test: Add test managed of_clk_add_hw_provider()")
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/kunit/clk.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/include/kunit/clk.h b/include/kunit/clk.h
+index 0afae7688157b..f226044cc78d1 100644
+--- a/include/kunit/clk.h
++++ b/include/kunit/clk.h
+@@ -6,6 +6,7 @@ struct clk;
+ struct clk_hw;
+ struct device;
+ struct device_node;
++struct of_phandle_args;
+ struct kunit;
+ struct clk *
+-- 
+2.39.5
+
diff --git a/queue-6.15/clone_private_mnt-make-sure-that-caller-has-cap_sys_.patch b/queue-6.15/clone_private_mnt-make-sure-that-caller-has-cap_sys_.patch
new file mode 100644 (file)
index 0000000..c7d4ed4
--- /dev/null
@@ -0,0 +1,48 @@
+From 4d2327f1f6610e1ebf8dd48ded9ac2e0f85a0c1c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 1 Jun 2025 20:11:06 -0400
+Subject: clone_private_mnt(): make sure that caller has CAP_SYS_ADMIN in the
+ right userns
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+[ Upstream commit c28f922c9dcee0e4876a2c095939d77fe7e15116 ]
+
+What we want is to verify there is that clone won't expose something
+hidden by a mount we wouldn't be able to undo.  "Wouldn't be able to undo"
+may be a result of MNT_LOCKED on a child, but it may also come from
+lacking admin rights in the userns of the namespace mount belongs to.
+
+clone_private_mnt() checks the former, but not the latter.
+
+There's a number of rather confusing CAP_SYS_ADMIN checks in various
+userns during the mount, especially with the new mount API; they serve
+different purposes and in case of clone_private_mnt() they usually,
+but not always end up covering the missing check mentioned above.
+
+Reviewed-by: Christian Brauner <brauner@kernel.org>
+Reported-by: "Orlando, Noah" <Noah.Orlando@deshaw.com>
+Fixes: 427215d85e8d ("ovl: prevent private clone if bind mount is not allowed")
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/namespace.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/fs/namespace.c b/fs/namespace.c
+index 07bc500a248ec..163ffdc042284 100644
+--- a/fs/namespace.c
++++ b/fs/namespace.c
+@@ -2509,6 +2509,9 @@ struct vfsmount *clone_private_mount(const struct path *path)
+                       return ERR_PTR(-EINVAL);
+       }
++        if (!ns_capable(old_mnt->mnt_ns->user_ns, CAP_SYS_ADMIN))
++              return ERR_PTR(-EPERM);
++
+       if (__has_locked_children(old_mnt, path->dentry))
+               return ERR_PTR(-EINVAL);
+-- 
+2.39.5
+
diff --git a/queue-6.15/coresight-catu-introduce-refcount-and-spinlock-for-e.patch b/queue-6.15/coresight-catu-introduce-refcount-and-spinlock-for-e.patch
new file mode 100644 (file)
index 0000000..ad6aa5f
--- /dev/null
@@ -0,0 +1,110 @@
+From 5975456b946109edf82f2bcd0b81d2d53315943c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Apr 2025 16:12:59 -0700
+Subject: coresight: catu: Introduce refcount and spinlock for
+ enabling/disabling
+
+From: Yabin Cui <yabinc@google.com>
+
+[ Upstream commit a03a0a08c6fe5e50c1b12ea41b9e228e7f649c22 ]
+
+When tracing ETM data on multiple CPUs concurrently via the
+perf interface, the CATU device is shared across different CPU
+paths. This can lead to race conditions when multiple CPUs attempt
+to enable or disable the CATU device simultaneously.
+
+To address these race conditions, this patch introduces the
+following changes:
+
+1. The enable and disable operations for the CATU device are not
+   reentrant. Therefore, a spinlock is added to ensure that only
+   one CPU can enable or disable a given CATU device at any point
+   in time.
+
+2. A reference counter is used to manage the enable/disable state
+   of the CATU device. The device is enabled when the first CPU
+   requires it and is only disabled when the last CPU finishes
+   using it. This ensures the device remains active as long as at
+   least one CPU needs it.
+
+Fixes: fcacb5c154ba ("coresight: Introduce support for Coresight Address Translation Unit")
+Signed-off-by: Yabin Cui <yabinc@google.com>
+Reviewed-by: James Clark <james.clark@linaro.org>
+Reviewed-by: Leo Yan <leo.yan@arm.com>
+Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Link: https://lore.kernel.org/r/20250429231301.1952246-2-yabinc@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwtracing/coresight/coresight-catu.c | 25 +++++++++++++-------
+ drivers/hwtracing/coresight/coresight-catu.h |  1 +
+ 2 files changed, 18 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c
+index 96cb48b140afa..d4e2e175e0770 100644
+--- a/drivers/hwtracing/coresight/coresight-catu.c
++++ b/drivers/hwtracing/coresight/coresight-catu.c
+@@ -458,12 +458,17 @@ static int catu_enable_hw(struct catu_drvdata *drvdata, enum cs_mode cs_mode,
+ static int catu_enable(struct coresight_device *csdev, enum cs_mode mode,
+                      void *data)
+ {
+-      int rc;
++      int rc = 0;
+       struct catu_drvdata *catu_drvdata = csdev_to_catu_drvdata(csdev);
+-      CS_UNLOCK(catu_drvdata->base);
+-      rc = catu_enable_hw(catu_drvdata, mode, data);
+-      CS_LOCK(catu_drvdata->base);
++      guard(raw_spinlock_irqsave)(&catu_drvdata->spinlock);
++      if (csdev->refcnt == 0) {
++              CS_UNLOCK(catu_drvdata->base);
++              rc = catu_enable_hw(catu_drvdata, mode, data);
++              CS_LOCK(catu_drvdata->base);
++      }
++      if (!rc)
++              csdev->refcnt++;
+       return rc;
+ }
+@@ -486,12 +491,15 @@ static int catu_disable_hw(struct catu_drvdata *drvdata)
+ static int catu_disable(struct coresight_device *csdev, void *__unused)
+ {
+-      int rc;
++      int rc = 0;
+       struct catu_drvdata *catu_drvdata = csdev_to_catu_drvdata(csdev);
+-      CS_UNLOCK(catu_drvdata->base);
+-      rc = catu_disable_hw(catu_drvdata);
+-      CS_LOCK(catu_drvdata->base);
++      guard(raw_spinlock_irqsave)(&catu_drvdata->spinlock);
++      if (--csdev->refcnt == 0) {
++              CS_UNLOCK(catu_drvdata->base);
++              rc = catu_disable_hw(catu_drvdata);
++              CS_LOCK(catu_drvdata->base);
++      }
+       return rc;
+ }
+@@ -550,6 +558,7 @@ static int __catu_probe(struct device *dev, struct resource *res)
+       dev->platform_data = pdata;
+       drvdata->base = base;
++      raw_spin_lock_init(&drvdata->spinlock);
+       catu_desc.access = CSDEV_ACCESS_IOMEM(base);
+       catu_desc.pdata = pdata;
+       catu_desc.dev = dev;
+diff --git a/drivers/hwtracing/coresight/coresight-catu.h b/drivers/hwtracing/coresight/coresight-catu.h
+index 141feac1c14b0..755776cd19c5b 100644
+--- a/drivers/hwtracing/coresight/coresight-catu.h
++++ b/drivers/hwtracing/coresight/coresight-catu.h
+@@ -65,6 +65,7 @@ struct catu_drvdata {
+       void __iomem *base;
+       struct coresight_device *csdev;
+       int irq;
++      raw_spinlock_t spinlock;
+ };
+ #define CATU_REG32(name, offset)                                      \
+-- 
+2.39.5
+
diff --git a/queue-6.15/coresight-core-disable-helpers-for-devices-that-fail.patch b/queue-6.15/coresight-core-disable-helpers-for-devices-that-fail.patch
new file mode 100644 (file)
index 0000000..232758c
--- /dev/null
@@ -0,0 +1,76 @@
+From 90db0d92324c994235253c4dfc72f9de2ffb4e20 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Apr 2025 16:13:00 -0700
+Subject: coresight: core: Disable helpers for devices that fail to enable
+
+From: Yabin Cui <yabinc@google.com>
+
+[ Upstream commit f6028eeeb5e4cf86f93f805098c84974a79bba8a ]
+
+When enabling a SINK or LINK type coresight device fails, the
+associated helpers should be disabled.
+
+Fixes: 6148652807ba ("coresight: Enable and disable helper devices adjacent to the path")
+Signed-off-by: Yabin Cui <yabinc@google.com>
+Suggested-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Reviewed-by: James Clark <james.clark@linaro.org>
+Reviewed-by: Mike Leach <mike.leach@linaro.org>
+Reviewed-by: Leo Yan <leo.yan@arm.com>
+Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Link: https://lore.kernel.org/r/20250429231301.1952246-3-yabinc@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwtracing/coresight/coresight-core.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
+index dabec7073aeda..d3523f0262af8 100644
+--- a/drivers/hwtracing/coresight/coresight-core.c
++++ b/drivers/hwtracing/coresight/coresight-core.c
+@@ -465,7 +465,7 @@ int coresight_enable_path(struct coresight_path *path, enum cs_mode mode,
+               /* Enable all helpers adjacent to the path first */
+               ret = coresight_enable_helpers(csdev, mode, path);
+               if (ret)
+-                      goto err;
++                      goto err_disable_path;
+               /*
+                * ETF devices are tricky... They can be a link or a sink,
+                * depending on how they are configured.  If an ETF has been
+@@ -486,8 +486,10 @@ int coresight_enable_path(struct coresight_path *path, enum cs_mode mode,
+                        * that need disabling. Disabling the path here
+                        * would mean we could disrupt an existing session.
+                        */
+-                      if (ret)
++                      if (ret) {
++                              coresight_disable_helpers(csdev, path);
+                               goto out;
++                      }
+                       break;
+               case CORESIGHT_DEV_TYPE_SOURCE:
+                       /* sources are enabled from either sysFS or Perf */
+@@ -497,16 +499,19 @@ int coresight_enable_path(struct coresight_path *path, enum cs_mode mode,
+                       child = list_next_entry(nd, link)->csdev;
+                       ret = coresight_enable_link(csdev, parent, child, source);
+                       if (ret)
+-                              goto err;
++                              goto err_disable_helpers;
+                       break;
+               default:
+-                      goto err;
++                      ret = -EINVAL;
++                      goto err_disable_helpers;
+               }
+       }
+ out:
+       return ret;
+-err:
++err_disable_helpers:
++      coresight_disable_helpers(csdev, path);
++err_disable_path:
+       coresight_disable_path_from(path, nd);
+       goto out;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/coresight-etm4-fix-missing-disable-active-config.patch b/queue-6.15/coresight-etm4-fix-missing-disable-active-config.patch
new file mode 100644 (file)
index 0000000..de5657d
--- /dev/null
@@ -0,0 +1,39 @@
+From f78dec8472793ea9696400d6ef39c855b850f9fd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 May 2025 17:19:49 +0100
+Subject: coresight/etm4: fix missing disable active config
+
+From: Yeoreum Yun <yeoreum.yun@arm.com>
+
+[ Upstream commit 895b12b7d7b8c651f73f57a1ea040d35aa7048cb ]
+
+When etm4 device is disabled via sysfs, it should disable its active
+count.
+
+Fixes: 7ebd0ec6cf94 ("coresight: configfs: Allow configfs to activate configuration")
+Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
+Reviewed-by: Leo Yan <leo.yan@arm.com>
+Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Link: https://lore.kernel.org/r/20250514161951.3427590-2-yeoreum.yun@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwtracing/coresight/coresight-etm4x-core.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
+index b42b03dba516d..88ef381ee6dd9 100644
+--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
+@@ -1020,6 +1020,9 @@ static void etm4_disable_sysfs(struct coresight_device *csdev)
+       smp_call_function_single(drvdata->cpu, etm4_disable_hw, drvdata, 1);
+       raw_spin_unlock(&drvdata->spinlock);
++
++      cscfg_csdev_disable_active_config(csdev);
++
+       cpus_read_unlock();
+       /*
+-- 
+2.39.5
+
diff --git a/queue-6.15/coresight-etm4x-fix-timestamp-bit-field-handling.patch b/queue-6.15/coresight-etm4x-fix-timestamp-bit-field-handling.patch
new file mode 100644 (file)
index 0000000..07f9e4b
--- /dev/null
@@ -0,0 +1,65 @@
+From c184f60a3fe664da7d7b9ca19d01a9569206f3e9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 May 2025 18:49:44 +0100
+Subject: coresight: etm4x: Fix timestamp bit field handling
+
+From: Leo Yan <leo.yan@arm.com>
+
+[ Upstream commit ee811bc733be5c57a2bfecdf2f6f5d4db466200a ]
+
+Timestamps in the trace data appear as all zeros on recent kernels,
+although the feature works correctly on old kernels (e.g., v6.12).
+
+Since commit c382ee674c8b ("arm64/sysreg/tools: Move TRFCR definitions
+to sysreg"), the TRFCR_ELx_TS_{VIRTUAL|GUEST_PHYSICAL|PHYSICAL} macros
+were updated to remove the bit shift. As a result, the driver no longer
+shifts bits when operates the timestamp field.
+
+Fix this by using the FIELD_PREP() and FIELD_GET() helpers.
+
+Reported-by: Tamas Zsoldos <tamas.zsoldos@arm.com>
+Fixes: c382ee674c8b ("arm64/sysreg/tools: Move TRFCR definitions to sysreg")
+Signed-off-by: Leo Yan <leo.yan@arm.com>
+Reviewed-by: James Clark <james.clark@linaro.org>
+Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Link: https://lore.kernel.org/r/20250519174945.2245271-2-leo.yan@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwtracing/coresight/coresight-etm4x-core.c  | 2 +-
+ drivers/hwtracing/coresight/coresight-etm4x-sysfs.c | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
+index 2b8f104638402..b42b03dba516d 100644
+--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
+@@ -1176,7 +1176,7 @@ static void cpu_detect_trace_filtering(struct etmv4_drvdata *drvdata)
+        * tracing at the kernel EL and EL0, forcing to use the
+        * virtual time as the timestamp.
+        */
+-      trfcr = (TRFCR_EL1_TS_VIRTUAL |
++      trfcr = (FIELD_PREP(TRFCR_EL1_TS_MASK, TRFCR_EL1_TS_VIRTUAL) |
+                TRFCR_EL1_ExTRE |
+                TRFCR_EL1_E0TRE);
+diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
+index fdd0956fecb36..c3ca904de584d 100644
+--- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
++++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
+@@ -2320,11 +2320,11 @@ static ssize_t ts_source_show(struct device *dev,
+               goto out;
+       }
+-      switch (drvdata->trfcr & TRFCR_EL1_TS_MASK) {
++      val = FIELD_GET(TRFCR_EL1_TS_MASK, drvdata->trfcr);
++      switch (val) {
+       case TRFCR_EL1_TS_VIRTUAL:
+       case TRFCR_EL1_TS_GUEST_PHYSICAL:
+       case TRFCR_EL1_TS_PHYSICAL:
+-              val = FIELD_GET(TRFCR_EL1_TS_MASK, drvdata->trfcr);
+               break;
+       default:
+               val = -1;
+-- 
+2.39.5
+
diff --git a/queue-6.15/coresight-fixes-device-s-owner-field-for-registered-.patch b/queue-6.15/coresight-fixes-device-s-owner-field-for-registered-.patch
new file mode 100644 (file)
index 0000000..7f83dca
--- /dev/null
@@ -0,0 +1,175 @@
+From f8dadd35c386c3176fd2dce103bc97660981a10b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Sep 2024 11:53:27 +0800
+Subject: coresight: Fixes device's owner field for registered using
+ coresight_init_driver()
+
+From: Junhao He <hejunhao3@huawei.com>
+
+[ Upstream commit 9f52aecc952ddf307571517d5c91136c8c4e87c9 ]
+
+The coresight_init_driver() of the coresight-core module is called from
+the sub coresgiht device (such as tmc/stm/funnle/...) module. It calls
+amba_driver_register() and Platform_driver_register(), which are macro
+functions that use the coresight-core's module to initialize the caller's
+owner field.  Therefore, when the sub coresight device calls
+coresight_init_driver(), an incorrect THIS_MODULE value is captured.
+
+The sub coesgiht modules can be removed while their callbacks are
+running, resulting in a general protection failure.
+
+Add module parameter to coresight_init_driver() so can be called
+with the module of the callback.
+
+Fixes: 075b7cd7ad7d ("coresight: Add helpers registering/removing both AMBA and platform drivers")
+Signed-off-by: Junhao He <hejunhao3@huawei.com>
+Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Link: https://lore.kernel.org/r/20240918035327.9710-1-hejunhao3@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwtracing/coresight/coresight-catu.c       | 2 +-
+ drivers/hwtracing/coresight/coresight-core.c       | 6 +++---
+ drivers/hwtracing/coresight/coresight-cpu-debug.c  | 3 ++-
+ drivers/hwtracing/coresight/coresight-funnel.c     | 3 ++-
+ drivers/hwtracing/coresight/coresight-replicator.c | 3 ++-
+ drivers/hwtracing/coresight/coresight-stm.c        | 2 +-
+ drivers/hwtracing/coresight/coresight-tmc-core.c   | 2 +-
+ drivers/hwtracing/coresight/coresight-tpiu.c       | 2 +-
+ include/linux/coresight.h                          | 2 +-
+ 9 files changed, 14 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c
+index fa170c966bc3b..96cb48b140afa 100644
+--- a/drivers/hwtracing/coresight/coresight-catu.c
++++ b/drivers/hwtracing/coresight/coresight-catu.c
+@@ -702,7 +702,7 @@ static int __init catu_init(void)
+ {
+       int ret;
+-      ret = coresight_init_driver("catu", &catu_driver, &catu_platform_driver);
++      ret = coresight_init_driver("catu", &catu_driver, &catu_platform_driver, THIS_MODULE);
+       tmc_etr_set_catu_ops(&etr_catu_buf_ops);
+       return ret;
+ }
+diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
+index fb43ef6a3b1f0..dabec7073aeda 100644
+--- a/drivers/hwtracing/coresight/coresight-core.c
++++ b/drivers/hwtracing/coresight/coresight-core.c
+@@ -1585,17 +1585,17 @@ module_init(coresight_init);
+ module_exit(coresight_exit);
+ int coresight_init_driver(const char *drv, struct amba_driver *amba_drv,
+-                        struct platform_driver *pdev_drv)
++                        struct platform_driver *pdev_drv, struct module *owner)
+ {
+       int ret;
+-      ret = amba_driver_register(amba_drv);
++      ret = __amba_driver_register(amba_drv, owner);
+       if (ret) {
+               pr_err("%s: error registering AMBA driver\n", drv);
+               return ret;
+       }
+-      ret = platform_driver_register(pdev_drv);
++      ret = __platform_driver_register(pdev_drv, owner);
+       if (!ret)
+               return 0;
+diff --git a/drivers/hwtracing/coresight/coresight-cpu-debug.c b/drivers/hwtracing/coresight/coresight-cpu-debug.c
+index 342c3aaf414dd..a871d997330b0 100644
+--- a/drivers/hwtracing/coresight/coresight-cpu-debug.c
++++ b/drivers/hwtracing/coresight/coresight-cpu-debug.c
+@@ -774,7 +774,8 @@ static struct platform_driver debug_platform_driver = {
+ static int __init debug_init(void)
+ {
+-      return coresight_init_driver("debug", &debug_driver, &debug_platform_driver);
++      return coresight_init_driver("debug", &debug_driver, &debug_platform_driver,
++                                   THIS_MODULE);
+ }
+ static void __exit debug_exit(void)
+diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c
+index 0541712b2bcb6..124fc2e26cfb1 100644
+--- a/drivers/hwtracing/coresight/coresight-funnel.c
++++ b/drivers/hwtracing/coresight/coresight-funnel.c
+@@ -433,7 +433,8 @@ static struct amba_driver dynamic_funnel_driver = {
+ static int __init funnel_init(void)
+ {
+-      return coresight_init_driver("funnel", &dynamic_funnel_driver, &funnel_driver);
++      return coresight_init_driver("funnel", &dynamic_funnel_driver, &funnel_driver,
++                                   THIS_MODULE);
+ }
+ static void __exit funnel_exit(void)
+diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c
+index ee7ee79f6cf77..572dcd2bac16d 100644
+--- a/drivers/hwtracing/coresight/coresight-replicator.c
++++ b/drivers/hwtracing/coresight/coresight-replicator.c
+@@ -438,7 +438,8 @@ static struct amba_driver dynamic_replicator_driver = {
+ static int __init replicator_init(void)
+ {
+-      return coresight_init_driver("replicator", &dynamic_replicator_driver, &replicator_driver);
++      return coresight_init_driver("replicator", &dynamic_replicator_driver, &replicator_driver,
++                                   THIS_MODULE);
+ }
+ static void __exit replicator_exit(void)
+diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
+index 26f9339f38b93..527347e4d16c5 100644
+--- a/drivers/hwtracing/coresight/coresight-stm.c
++++ b/drivers/hwtracing/coresight/coresight-stm.c
+@@ -1058,7 +1058,7 @@ static struct platform_driver stm_platform_driver = {
+ static int __init stm_init(void)
+ {
+-      return coresight_init_driver("stm", &stm_driver, &stm_platform_driver);
++      return coresight_init_driver("stm", &stm_driver, &stm_platform_driver, THIS_MODULE);
+ }
+ static void __exit stm_exit(void)
+diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
+index a7814e8e657b2..455b1c9b15682 100644
+--- a/drivers/hwtracing/coresight/coresight-tmc-core.c
++++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
+@@ -1060,7 +1060,7 @@ static struct platform_driver tmc_platform_driver = {
+ static int __init tmc_init(void)
+ {
+-      return coresight_init_driver("tmc", &tmc_driver, &tmc_platform_driver);
++      return coresight_init_driver("tmc", &tmc_driver, &tmc_platform_driver, THIS_MODULE);
+ }
+ static void __exit tmc_exit(void)
+diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c
+index 97ef36f03ec20..3e01592884280 100644
+--- a/drivers/hwtracing/coresight/coresight-tpiu.c
++++ b/drivers/hwtracing/coresight/coresight-tpiu.c
+@@ -318,7 +318,7 @@ static struct platform_driver tpiu_platform_driver = {
+ static int __init tpiu_init(void)
+ {
+-      return coresight_init_driver("tpiu", &tpiu_driver, &tpiu_platform_driver);
++      return coresight_init_driver("tpiu", &tpiu_driver, &tpiu_platform_driver, THIS_MODULE);
+ }
+ static void __exit tpiu_exit(void)
+diff --git a/include/linux/coresight.h b/include/linux/coresight.h
+index d79a242b271d6..cfcf6e4707ed9 100644
+--- a/include/linux/coresight.h
++++ b/include/linux/coresight.h
+@@ -723,7 +723,7 @@ coresight_find_output_type(struct coresight_platform_data *pdata,
+                          union coresight_dev_subtype subtype);
+ int coresight_init_driver(const char *drv, struct amba_driver *amba_drv,
+-                        struct platform_driver *pdev_drv);
++                        struct platform_driver *pdev_drv, struct module *owner);
+ void coresight_remove_driver(struct amba_driver *amba_drv,
+                            struct platform_driver *pdev_drv);
+-- 
+2.39.5
+
diff --git a/queue-6.15/coresight-holding-cscfg_csdev_lock-while-removing-cs.patch b/queue-6.15/coresight-holding-cscfg_csdev_lock-while-removing-cs.patch
new file mode 100644 (file)
index 0000000..3f09f62
--- /dev/null
@@ -0,0 +1,58 @@
+From f4946fffdbb3f57b0409b5c69c679ae695b72c4b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 May 2025 17:19:50 +0100
+Subject: coresight: holding cscfg_csdev_lock while removing cscfg from csdev
+
+From: Yeoreum Yun <yeoreum.yun@arm.com>
+
+[ Upstream commit 53b9e2659719b04f5ba7593f2af0f2335f75e94a ]
+
+There'll be possible race scenario for coresight config:
+
+CPU0                                          CPU1
+(perf enable)                                 load module
+                                              cscfg_load_config_sets()
+                                              activate config. // sysfs
+                                              (sys_active_cnt == 1)
+...
+cscfg_csdev_enable_active_config()
+  lock(csdev->cscfg_csdev_lock)
+                                              deactivate config // sysfs
+                                              (sys_activec_cnt == 0)
+                                              cscfg_unload_config_sets()
+  <iterating config_csdev_list>               cscfg_remove_owned_csdev_configs()
+  // here load config activate by CPU1
+  unlock(csdev->cscfg_csdev_lock)
+
+iterating config_csdev_list could be raced with config_csdev_list's
+entry delete.
+
+To resolve this race , hold csdev->cscfg_csdev_lock() while
+cscfg_remove_owned_csdev_configs()
+
+Fixes: 02bd588e12df ("coresight: configuration: Update API to permit dynamic load/unload")
+Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
+Reviewed-by: Leo Yan <leo.yan@arm.com>
+Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Link: https://lore.kernel.org/r/20250514161951.3427590-3-yeoreum.yun@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwtracing/coresight/coresight-syscfg.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
+index a70c1454b4106..23017612f2eae 100644
+--- a/drivers/hwtracing/coresight/coresight-syscfg.c
++++ b/drivers/hwtracing/coresight/coresight-syscfg.c
+@@ -395,6 +395,8 @@ static void cscfg_remove_owned_csdev_configs(struct coresight_device *csdev, voi
+       if (list_empty(&csdev->config_csdev_list))
+               return;
++  guard(raw_spinlock_irqsave)(&csdev->cscfg_csdev_lock);
++
+       list_for_each_entry_safe(config_csdev, tmp, &csdev->config_csdev_list, node) {
+               if (config_csdev->config_desc->load_owner == load_owner)
+                       list_del(&config_csdev->node);
+-- 
+2.39.5
+
diff --git a/queue-6.15/coresight-prevent-deactivate-active-config-while-ena.patch b/queue-6.15/coresight-prevent-deactivate-active-config-while-ena.patch
new file mode 100644 (file)
index 0000000..bb06ed9
--- /dev/null
@@ -0,0 +1,179 @@
+From af0f05eece93129628e3a0542d4c4903c3322243 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 May 2025 17:19:51 +0100
+Subject: coresight: prevent deactivate active config while enabling the config
+
+From: Yeoreum Yun <yeoreum.yun@arm.com>
+
+[ Upstream commit 408c97c4a5e0b634dcd15bf8b8808b382e888164 ]
+
+While enable active config via cscfg_csdev_enable_active_config(),
+active config could be deactivated via configfs' sysfs interface.
+This could make UAF issue in below scenario:
+
+CPU0                                          CPU1
+(sysfs enable)                                load module
+                                              cscfg_load_config_sets()
+                                              activate config. // sysfs
+                                              (sys_active_cnt == 1)
+...
+cscfg_csdev_enable_active_config()
+lock(csdev->cscfg_csdev_lock)
+// here load config activate by CPU1
+unlock(csdev->cscfg_csdev_lock)
+
+                                              deactivate config // sysfs
+                                              (sys_activec_cnt == 0)
+                                              cscfg_unload_config_sets()
+                                              unload module
+
+// access to config_desc which freed
+// while unloading module.
+cscfg_csdev_enable_config
+
+To address this, use cscfg_config_desc's active_cnt as a reference count
+ which will be holded when
+    - activate the config.
+    - enable the activated config.
+and put the module reference when config_active_cnt == 0.
+
+Fixes: f8cce2ff3c04 ("coresight: syscfg: Add API to activate and enable configurations")
+Suggested-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
+Reviewed-by: Leo Yan <leo.yan@arm.com>
+Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Link: https://lore.kernel.org/r/20250514161951.3427590-4-yeoreum.yun@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../hwtracing/coresight/coresight-config.h    |  2 +-
+ .../hwtracing/coresight/coresight-syscfg.c    | 49 +++++++++++++------
+ 2 files changed, 35 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h
+index b9ebc9fcfb7f2..90fd937d3bd83 100644
+--- a/drivers/hwtracing/coresight/coresight-config.h
++++ b/drivers/hwtracing/coresight/coresight-config.h
+@@ -228,7 +228,7 @@ struct cscfg_feature_csdev {
+  * @feats_csdev:references to the device features to enable.
+  */
+ struct cscfg_config_csdev {
+-      const struct cscfg_config_desc *config_desc;
++      struct cscfg_config_desc *config_desc;
+       struct coresight_device *csdev;
+       bool enabled;
+       struct list_head node;
+diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
+index 23017612f2eae..83dad24e0116d 100644
+--- a/drivers/hwtracing/coresight/coresight-syscfg.c
++++ b/drivers/hwtracing/coresight/coresight-syscfg.c
+@@ -869,6 +869,25 @@ void cscfg_csdev_reset_feats(struct coresight_device *csdev)
+ }
+ EXPORT_SYMBOL_GPL(cscfg_csdev_reset_feats);
++static bool cscfg_config_desc_get(struct cscfg_config_desc *config_desc)
++{
++      if (!atomic_fetch_inc(&config_desc->active_cnt)) {
++              /* must ensure that config cannot be unloaded in use */
++              if (unlikely(cscfg_owner_get(config_desc->load_owner))) {
++                      atomic_dec(&config_desc->active_cnt);
++                      return false;
++              }
++      }
++
++      return true;
++}
++
++static void cscfg_config_desc_put(struct cscfg_config_desc *config_desc)
++{
++      if (!atomic_dec_return(&config_desc->active_cnt))
++              cscfg_owner_put(config_desc->load_owner);
++}
++
+ /*
+  * This activate configuration for either perf or sysfs. Perf can have multiple
+  * active configs, selected per event, sysfs is limited to one.
+@@ -892,22 +911,17 @@ static int _cscfg_activate_config(unsigned long cfg_hash)
+                       if (config_desc->available == false)
+                               return -EBUSY;
+-                      /* must ensure that config cannot be unloaded in use */
+-                      err = cscfg_owner_get(config_desc->load_owner);
+-                      if (err)
++                      if (!cscfg_config_desc_get(config_desc)) {
++                              err = -EINVAL;
+                               break;
++                      }
++
+                       /*
+                        * increment the global active count - control changes to
+                        * active configurations
+                        */
+                       atomic_inc(&cscfg_mgr->sys_active_cnt);
+-                      /*
+-                       * mark the descriptor as active so enable config on a
+-                       * device instance will use it
+-                       */
+-                      atomic_inc(&config_desc->active_cnt);
+-
+                       err = 0;
+                       dev_dbg(cscfg_device(), "Activate config %s.\n", config_desc->name);
+                       break;
+@@ -922,9 +936,8 @@ static void _cscfg_deactivate_config(unsigned long cfg_hash)
+       list_for_each_entry(config_desc, &cscfg_mgr->config_desc_list, item) {
+               if ((unsigned long)config_desc->event_ea->var == cfg_hash) {
+-                      atomic_dec(&config_desc->active_cnt);
+                       atomic_dec(&cscfg_mgr->sys_active_cnt);
+-                      cscfg_owner_put(config_desc->load_owner);
++                      cscfg_config_desc_put(config_desc);
+                       dev_dbg(cscfg_device(), "Deactivate config %s.\n", config_desc->name);
+                       break;
+               }
+@@ -1049,7 +1062,7 @@ int cscfg_csdev_enable_active_config(struct coresight_device *csdev,
+                                    unsigned long cfg_hash, int preset)
+ {
+       struct cscfg_config_csdev *config_csdev_active = NULL, *config_csdev_item;
+-      const struct cscfg_config_desc *config_desc;
++      struct cscfg_config_desc *config_desc;
+       unsigned long flags;
+       int err = 0;
+@@ -1064,8 +1077,8 @@ int cscfg_csdev_enable_active_config(struct coresight_device *csdev,
+       raw_spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
+       list_for_each_entry(config_csdev_item, &csdev->config_csdev_list, node) {
+               config_desc = config_csdev_item->config_desc;
+-              if ((atomic_read(&config_desc->active_cnt)) &&
+-                  ((unsigned long)config_desc->event_ea->var == cfg_hash)) {
++              if (((unsigned long)config_desc->event_ea->var == cfg_hash) &&
++                              cscfg_config_desc_get(config_desc)) {
+                       config_csdev_active = config_csdev_item;
+                       csdev->active_cscfg_ctxt = (void *)config_csdev_active;
+                       break;
+@@ -1099,7 +1112,11 @@ int cscfg_csdev_enable_active_config(struct coresight_device *csdev,
+                               err = -EBUSY;
+                       raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
+               }
++
++              if (err)
++                      cscfg_config_desc_put(config_desc);
+       }
++
+       return err;
+ }
+ EXPORT_SYMBOL_GPL(cscfg_csdev_enable_active_config);
+@@ -1138,8 +1155,10 @@ void cscfg_csdev_disable_active_config(struct coresight_device *csdev)
+       raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
+       /* true if there was an enabled active config */
+-      if (config_csdev)
++      if (config_csdev) {
+               cscfg_csdev_disable_config(config_csdev);
++              cscfg_config_desc_put(config_csdev->config_desc);
++      }
+ }
+ EXPORT_SYMBOL_GPL(cscfg_csdev_disable_active_config);
+-- 
+2.39.5
+
diff --git a/queue-6.15/coresight-tmc-fix-failure-to-disable-enable-etf-afte.patch b/queue-6.15/coresight-tmc-fix-failure-to-disable-enable-etf-afte.patch
new file mode 100644 (file)
index 0000000..5a9f6fe
--- /dev/null
@@ -0,0 +1,57 @@
+From b9c07ce5d55413172197b1c834c0818691ad3336 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 May 2025 23:37:16 -0700
+Subject: coresight: tmc: fix failure to disable/enable ETF after reading
+
+From: Mao Jinlong <quic_jinlmao@quicinc.com>
+
+[ Upstream commit d23bc38e8aa4efbd617bf660bb1a25fee9f6c177 ]
+
+ETF may fail to re-enable after reading, and driver->reading will
+not be set to false, this will cause failure to enable/disable to ETF.
+This change set driver->reading to false even if re-enabling fail.
+
+Fixes: 669c4614236a ("coresight: tmc: Don't enable TMC when it's not ready.")
+Co-developed-by: Yuanfang Zhang <quic_yuanfang@quicinc.com>
+Signed-off-by: Yuanfang Zhang <quic_yuanfang@quicinc.com>
+Signed-off-by: Mao Jinlong <quic_jinlmao@quicinc.com>
+[ Added a comment to explain why we ignore the error ]
+Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Link: https://lore.kernel.org/r/20250507063716.1945213-1-quic_jinlmao@quicinc.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwtracing/coresight/coresight-tmc-etf.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c
+index d858740001c27..a922e3b709638 100644
+--- a/drivers/hwtracing/coresight/coresight-tmc-etf.c
++++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c
+@@ -747,7 +747,6 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata)
+       char *buf = NULL;
+       enum tmc_mode mode;
+       unsigned long flags;
+-      int rc = 0;
+       /* config types are set a boot time and never change */
+       if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETB &&
+@@ -773,11 +772,11 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata)
+                * can't be NULL.
+                */
+               memset(drvdata->buf, 0, drvdata->size);
+-              rc = __tmc_etb_enable_hw(drvdata);
+-              if (rc) {
+-                      raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
+-                      return rc;
+-              }
++              /*
++               * Ignore failures to enable the TMC to make sure, we don't
++               * leave the TMC in a "reading" state.
++               */
++              __tmc_etb_enable_hw(drvdata);
+       } else {
+               /*
+                * The ETB/ETF is not tracing and the buffer was just read.
+-- 
+2.39.5
+
diff --git a/queue-6.15/counter-interrupt-cnt-protect-enable-disable-ops-wit.patch b/queue-6.15/counter-interrupt-cnt-protect-enable-disable-ops-wit.patch
new file mode 100644 (file)
index 0000000..0b8a1af
--- /dev/null
@@ -0,0 +1,109 @@
+From d1214cf824b2162bb73b63e43e077ed4c43ae04b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Mar 2025 18:36:40 +0200
+Subject: counter: interrupt-cnt: Protect enable/disable OPs with mutex
+
+From: Alexander Sverdlin <alexander.sverdlin@siemens.com>
+
+[ Upstream commit 7351312632e831e51383f48957d47712fae791ef ]
+
+Enable/disable seems to be racy on SMP, consider the following scenario:
+
+CPU0                                   CPU1
+
+interrupt_cnt_enable_write(true)
+{
+       if (priv->enabled == enable)
+               return 0;
+
+       if (enable) {
+               priv->enabled = true;
+                                       interrupt_cnt_enable_write(false)
+                                       {
+                                               if (priv->enabled == enable)
+                                                       return 0;
+
+                                               if (enable) {
+                                                       priv->enabled = true;
+                                                       enable_irq(priv->irq);
+                                               } else {
+                                                       disable_irq(priv->irq)
+                                                       priv->enabled = false;
+                                               }
+               enable_irq(priv->irq);
+       } else {
+               disable_irq(priv->irq);
+               priv->enabled = false;
+       }
+
+The above would result in priv->enabled == false, but IRQ left enabled.
+Protect both write (above race) and read (to propagate the value on SMP)
+callbacks with a mutex.
+
+Signed-off-by: Alexander Sverdlin <alexander.sverdlin@siemens.com>
+Fixes: a55ebd47f21f ("counter: add IRQ or GPIO based counter")
+Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Link: https://lore.kernel.org/r/20250331163642.2382651-1-alexander.sverdlin@siemens.com
+Signed-off-by: William Breathitt Gray <wbg@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/counter/interrupt-cnt.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/counter/interrupt-cnt.c b/drivers/counter/interrupt-cnt.c
+index 949598d51575a..d83848d0fe2af 100644
+--- a/drivers/counter/interrupt-cnt.c
++++ b/drivers/counter/interrupt-cnt.c
+@@ -3,12 +3,14 @@
+  * Copyright (c) 2021 Pengutronix, Oleksij Rempel <kernel@pengutronix.de>
+  */
++#include <linux/cleanup.h>
+ #include <linux/counter.h>
+ #include <linux/gpio/consumer.h>
+ #include <linux/interrupt.h>
+ #include <linux/irq.h>
+ #include <linux/mod_devicetable.h>
+ #include <linux/module.h>
++#include <linux/mutex.h>
+ #include <linux/platform_device.h>
+ #include <linux/types.h>
+@@ -19,6 +21,7 @@ struct interrupt_cnt_priv {
+       struct gpio_desc *gpio;
+       int irq;
+       bool enabled;
++      struct mutex lock;
+       struct counter_signal signals;
+       struct counter_synapse synapses;
+       struct counter_count cnts;
+@@ -41,6 +44,8 @@ static int interrupt_cnt_enable_read(struct counter_device *counter,
+ {
+       struct interrupt_cnt_priv *priv = counter_priv(counter);
++      guard(mutex)(&priv->lock);
++
+       *enable = priv->enabled;
+       return 0;
+@@ -51,6 +56,8 @@ static int interrupt_cnt_enable_write(struct counter_device *counter,
+ {
+       struct interrupt_cnt_priv *priv = counter_priv(counter);
++      guard(mutex)(&priv->lock);
++
+       if (priv->enabled == enable)
+               return 0;
+@@ -227,6 +234,8 @@ static int interrupt_cnt_probe(struct platform_device *pdev)
+       if (ret)
+               return ret;
++      mutex_init(&priv->lock);
++
+       ret = devm_counter_add(dev, counter);
+       if (ret < 0)
+               return dev_err_probe(dev, ret, "Failed to add counter\n");
+-- 
+2.39.5
+
diff --git a/queue-6.15/crypto-api-redo-lookup-on-eexist.patch b/queue-6.15/crypto-api-redo-lookup-on-eexist.patch
new file mode 100644 (file)
index 0000000..ad3d857
--- /dev/null
@@ -0,0 +1,56 @@
+From c69aab527912dbec4c841b0c004825fde3dd957b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 May 2025 18:29:38 +0800
+Subject: crypto: api - Redo lookup on EEXIST
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+[ Upstream commit 0a3cf32da469ff1df6e016f5f82b439a63d14461 ]
+
+When two crypto algorithm lookups occur at the same time with
+different names for the same algorithm, e.g., ctr(aes-generic)
+and ctr(aes), they will both be instantiated.  However, only one
+of them can be registered.  The second instantiation will fail
+with EEXIST.
+
+Avoid failing the second lookup by making it retry, but only once
+because there are tricky names such as gcm_base(ctr(aes),ghash)
+that will always fail, despite triggering instantiation and EEXIST.
+
+Reported-by: Ingo Franzki <ifranzki@linux.ibm.com>
+Fixes: 2825982d9d66 ("[CRYPTO] api: Added event notification")
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ crypto/api.c | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/crypto/api.c b/crypto/api.c
+index 3416e98128a05..8592d3dccc64e 100644
+--- a/crypto/api.c
++++ b/crypto/api.c
+@@ -220,10 +220,19 @@ static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg,
+               if (crypto_is_test_larval(larval))
+                       crypto_larval_kill(larval);
+               alg = ERR_PTR(-ETIMEDOUT);
+-      } else if (!alg) {
++      } else if (!alg || PTR_ERR(alg) == -EEXIST) {
++              int err = alg ? -EEXIST : -EAGAIN;
++
++              /*
++               * EEXIST is expected because two probes can be scheduled
++               * at the same time with one using alg_name and the other
++               * using driver_name.  Do a re-lookup but do not retry in
++               * case we hit a quirk like gcm_base(ctr(aes),...) which
++               * will never match.
++               */
+               alg = &larval->alg;
+               alg = crypto_alg_lookup(alg->cra_name, type, mask) ?:
+-                    ERR_PTR(-EAGAIN);
++                    ERR_PTR(err);
+       } else if (IS_ERR(alg))
+               ;
+       else if (crypto_is_test_larval(larval) &&
+-- 
+2.39.5
+
diff --git a/queue-6.15/crypto-ecdsa-fix-enc-dec-size-reported-by-keyctl_pke.patch b/queue-6.15/crypto-ecdsa-fix-enc-dec-size-reported-by-keyctl_pke.patch
new file mode 100644 (file)
index 0000000..acbe393
--- /dev/null
@@ -0,0 +1,73 @@
+From f2c58b3de210f0e2ee4beb9e83b0d6a6b66fde7d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Apr 2025 21:32:41 +0200
+Subject: crypto: ecdsa - Fix enc/dec size reported by KEYCTL_PKEY_QUERY
+
+From: Lukas Wunner <lukas@wunner.de>
+
+[ Upstream commit 3828485e1c7b111290122ab6e083c2a37132b5c2 ]
+
+KEYCTL_PKEY_QUERY system calls for ecdsa keys return the key size as
+max_enc_size and max_dec_size, even though such keys cannot be used for
+encryption/decryption.  They're exclusively for signature generation or
+verification.
+
+Only rsa keys with pkcs1 encoding can also be used for encryption or
+decryption.
+
+Return 0 instead for ecdsa keys (as well as ecrdsa keys).
+
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
+Reviewed-by: Ignat Korchagin <ignat@cloudflare.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Stable-dep-of: 6b7f9397c98c ("crypto: ecdsa - Fix NIST P521 key size reported by KEYCTL_PKEY_QUERY")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ crypto/asymmetric_keys/public_key.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c
+index bf165d321440d..dd44a966947fb 100644
+--- a/crypto/asymmetric_keys/public_key.c
++++ b/crypto/asymmetric_keys/public_key.c
+@@ -188,6 +188,8 @@ static int software_key_query(const struct kernel_pkey_params *params,
+       ptr = pkey_pack_u32(ptr, pkey->paramlen);
+       memcpy(ptr, pkey->params, pkey->paramlen);
++      memset(info, 0, sizeof(*info));
++
+       if (issig) {
+               sig = crypto_alloc_sig(alg_name, 0, 0);
+               if (IS_ERR(sig)) {
+@@ -211,6 +213,9 @@ static int software_key_query(const struct kernel_pkey_params *params,
+                       info->supported_ops |= KEYCTL_SUPPORTS_SIGN;
+               if (strcmp(params->encoding, "pkcs1") == 0) {
++                      info->max_enc_size = len;
++                      info->max_dec_size = len;
++
+                       info->supported_ops |= KEYCTL_SUPPORTS_ENCRYPT;
+                       if (pkey->key_is_private)
+                               info->supported_ops |= KEYCTL_SUPPORTS_DECRYPT;
+@@ -232,6 +237,8 @@ static int software_key_query(const struct kernel_pkey_params *params,
+               len = crypto_akcipher_maxsize(tfm);
+               info->max_sig_size = len;
+               info->max_data_size = len;
++              info->max_enc_size = len;
++              info->max_dec_size = len;
+               info->supported_ops = KEYCTL_SUPPORTS_ENCRYPT;
+               if (pkey->key_is_private)
+@@ -239,8 +246,6 @@ static int software_key_query(const struct kernel_pkey_params *params,
+       }
+       info->key_size = len * 8;
+-      info->max_enc_size = len;
+-      info->max_dec_size = len;
+       ret = 0;
+-- 
+2.39.5
+
diff --git a/queue-6.15/crypto-ecdsa-fix-nist-p521-key-size-reported-by-keyc.patch b/queue-6.15/crypto-ecdsa-fix-nist-p521-key-size-reported-by-keyc.patch
new file mode 100644 (file)
index 0000000..aa932d9
--- /dev/null
@@ -0,0 +1,211 @@
+From 80fda8553049f0342490e899a9703591338f4893 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Apr 2025 21:32:42 +0200
+Subject: crypto: ecdsa - Fix NIST P521 key size reported by KEYCTL_PKEY_QUERY
+
+From: Lukas Wunner <lukas@wunner.de>
+
+[ Upstream commit 6b7f9397c98c72902f9364056413c73fe6dee1d8 ]
+
+When user space issues a KEYCTL_PKEY_QUERY system call for a NIST P521
+key, the key_size is incorrectly reported as 528 bits instead of 521.
+
+That's because the key size obtained through crypto_sig_keysize() is in
+bytes and software_key_query() multiplies by 8 to yield the size in bits.
+The underlying assumption is that the key size is always a multiple of 8.
+With the recent addition of NIST P521, that's no longer the case.
+
+Fix by returning the key_size in bits from crypto_sig_keysize() and
+adjusting the calculations in software_key_query().
+
+The ->key_size() callbacks of sig_alg algorithms now return the size in
+bits, whereas the ->digest_size() and ->max_size() callbacks return the
+size in bytes.  This matches with the units in struct keyctl_pkey_query.
+
+Fixes: a7d45ba77d3d ("crypto: ecdsa - Register NIST P521 and extend test suite")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
+Reviewed-by: Ignat Korchagin <ignat@cloudflare.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ crypto/asymmetric_keys/public_key.c | 8 ++++----
+ crypto/ecdsa-p1363.c                | 6 ++++--
+ crypto/ecdsa-x962.c                 | 5 +++--
+ crypto/ecdsa.c                      | 2 +-
+ crypto/ecrdsa.c                     | 2 +-
+ crypto/rsassa-pkcs1.c               | 2 +-
+ crypto/sig.c                        | 9 +++++++--
+ include/crypto/sig.h                | 2 +-
+ 8 files changed, 22 insertions(+), 14 deletions(-)
+
+diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c
+index dd44a966947fb..89dc887d2c5c7 100644
+--- a/crypto/asymmetric_keys/public_key.c
++++ b/crypto/asymmetric_keys/public_key.c
+@@ -205,6 +205,7 @@ static int software_key_query(const struct kernel_pkey_params *params,
+                       goto error_free_tfm;
+               len = crypto_sig_keysize(sig);
++              info->key_size = len;
+               info->max_sig_size = crypto_sig_maxsize(sig);
+               info->max_data_size = crypto_sig_digestsize(sig);
+@@ -213,8 +214,8 @@ static int software_key_query(const struct kernel_pkey_params *params,
+                       info->supported_ops |= KEYCTL_SUPPORTS_SIGN;
+               if (strcmp(params->encoding, "pkcs1") == 0) {
+-                      info->max_enc_size = len;
+-                      info->max_dec_size = len;
++                      info->max_enc_size = len / BITS_PER_BYTE;
++                      info->max_dec_size = len / BITS_PER_BYTE;
+                       info->supported_ops |= KEYCTL_SUPPORTS_ENCRYPT;
+                       if (pkey->key_is_private)
+@@ -235,6 +236,7 @@ static int software_key_query(const struct kernel_pkey_params *params,
+                       goto error_free_tfm;
+               len = crypto_akcipher_maxsize(tfm);
++              info->key_size = len * BITS_PER_BYTE;
+               info->max_sig_size = len;
+               info->max_data_size = len;
+               info->max_enc_size = len;
+@@ -245,8 +247,6 @@ static int software_key_query(const struct kernel_pkey_params *params,
+                       info->supported_ops |= KEYCTL_SUPPORTS_DECRYPT;
+       }
+-      info->key_size = len * 8;
+-
+       ret = 0;
+ error_free_tfm:
+diff --git a/crypto/ecdsa-p1363.c b/crypto/ecdsa-p1363.c
+index 4454f1f8f33f5..e0c55c64711c8 100644
+--- a/crypto/ecdsa-p1363.c
++++ b/crypto/ecdsa-p1363.c
+@@ -21,7 +21,8 @@ static int ecdsa_p1363_verify(struct crypto_sig *tfm,
+                             const void *digest, unsigned int dlen)
+ {
+       struct ecdsa_p1363_ctx *ctx = crypto_sig_ctx(tfm);
+-      unsigned int keylen = crypto_sig_keysize(ctx->child);
++      unsigned int keylen = DIV_ROUND_UP_POW2(crypto_sig_keysize(ctx->child),
++                                              BITS_PER_BYTE);
+       unsigned int ndigits = DIV_ROUND_UP_POW2(keylen, sizeof(u64));
+       struct ecdsa_raw_sig sig;
+@@ -45,7 +46,8 @@ static unsigned int ecdsa_p1363_max_size(struct crypto_sig *tfm)
+ {
+       struct ecdsa_p1363_ctx *ctx = crypto_sig_ctx(tfm);
+-      return 2 * crypto_sig_keysize(ctx->child);
++      return 2 * DIV_ROUND_UP_POW2(crypto_sig_keysize(ctx->child),
++                                   BITS_PER_BYTE);
+ }
+ static unsigned int ecdsa_p1363_digest_size(struct crypto_sig *tfm)
+diff --git a/crypto/ecdsa-x962.c b/crypto/ecdsa-x962.c
+index 90a04f4b9a2f5..ee71594d10a06 100644
+--- a/crypto/ecdsa-x962.c
++++ b/crypto/ecdsa-x962.c
+@@ -82,7 +82,7 @@ static int ecdsa_x962_verify(struct crypto_sig *tfm,
+       int err;
+       sig_ctx.ndigits = DIV_ROUND_UP_POW2(crypto_sig_keysize(ctx->child),
+-                                          sizeof(u64));
++                                          sizeof(u64) * BITS_PER_BYTE);
+       err = asn1_ber_decoder(&ecdsasignature_decoder, &sig_ctx, src, slen);
+       if (err < 0)
+@@ -103,7 +103,8 @@ static unsigned int ecdsa_x962_max_size(struct crypto_sig *tfm)
+ {
+       struct ecdsa_x962_ctx *ctx = crypto_sig_ctx(tfm);
+       struct sig_alg *alg = crypto_sig_alg(ctx->child);
+-      int slen = crypto_sig_keysize(ctx->child);
++      int slen = DIV_ROUND_UP_POW2(crypto_sig_keysize(ctx->child),
++                                   BITS_PER_BYTE);
+       /*
+        * Verify takes ECDSA-Sig-Value (described in RFC 5480) as input,
+diff --git a/crypto/ecdsa.c b/crypto/ecdsa.c
+index 117526d15ddeb..a70b60a90a3c7 100644
+--- a/crypto/ecdsa.c
++++ b/crypto/ecdsa.c
+@@ -167,7 +167,7 @@ static unsigned int ecdsa_key_size(struct crypto_sig *tfm)
+ {
+       struct ecc_ctx *ctx = crypto_sig_ctx(tfm);
+-      return DIV_ROUND_UP(ctx->curve->nbits, 8);
++      return ctx->curve->nbits;
+ }
+ static unsigned int ecdsa_digest_size(struct crypto_sig *tfm)
+diff --git a/crypto/ecrdsa.c b/crypto/ecrdsa.c
+index b3dd8a3ddeb79..2c0602f0cd406 100644
+--- a/crypto/ecrdsa.c
++++ b/crypto/ecrdsa.c
+@@ -249,7 +249,7 @@ static unsigned int ecrdsa_key_size(struct crypto_sig *tfm)
+        * Verify doesn't need any output, so it's just informational
+        * for keyctl to determine the key bit size.
+        */
+-      return ctx->pub_key.ndigits * sizeof(u64);
++      return ctx->pub_key.ndigits * sizeof(u64) * BITS_PER_BYTE;
+ }
+ static unsigned int ecrdsa_max_size(struct crypto_sig *tfm)
+diff --git a/crypto/rsassa-pkcs1.c b/crypto/rsassa-pkcs1.c
+index d01ac75635e00..94fa5e9600e79 100644
+--- a/crypto/rsassa-pkcs1.c
++++ b/crypto/rsassa-pkcs1.c
+@@ -301,7 +301,7 @@ static unsigned int rsassa_pkcs1_key_size(struct crypto_sig *tfm)
+ {
+       struct rsassa_pkcs1_ctx *ctx = crypto_sig_ctx(tfm);
+-      return ctx->key_size;
++      return ctx->key_size * BITS_PER_BYTE;
+ }
+ static int rsassa_pkcs1_set_pub_key(struct crypto_sig *tfm,
+diff --git a/crypto/sig.c b/crypto/sig.c
+index dfc7cae908028..53a3dd6fbe3fe 100644
+--- a/crypto/sig.c
++++ b/crypto/sig.c
+@@ -102,6 +102,11 @@ static int sig_default_set_key(struct crypto_sig *tfm,
+       return -ENOSYS;
+ }
++static unsigned int sig_default_size(struct crypto_sig *tfm)
++{
++      return DIV_ROUND_UP_POW2(crypto_sig_keysize(tfm), BITS_PER_BYTE);
++}
++
+ static int sig_prepare_alg(struct sig_alg *alg)
+ {
+       struct crypto_alg *base = &alg->base;
+@@ -117,9 +122,9 @@ static int sig_prepare_alg(struct sig_alg *alg)
+       if (!alg->key_size)
+               return -EINVAL;
+       if (!alg->max_size)
+-              alg->max_size = alg->key_size;
++              alg->max_size = sig_default_size;
+       if (!alg->digest_size)
+-              alg->digest_size = alg->key_size;
++              alg->digest_size = sig_default_size;
+       base->cra_type = &crypto_sig_type;
+       base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK;
+diff --git a/include/crypto/sig.h b/include/crypto/sig.h
+index 11024708c0692..fa6dafafab3f0 100644
+--- a/include/crypto/sig.h
++++ b/include/crypto/sig.h
+@@ -128,7 +128,7 @@ static inline void crypto_free_sig(struct crypto_sig *tfm)
+ /**
+  * crypto_sig_keysize() - Get key size
+  *
+- * Function returns the key size in bytes.
++ * Function returns the key size in bits.
+  * Function assumes that the key is already set in the transformation. If this
+  * function is called without a setkey or with a failed setkey, you may end up
+  * in a NULL dereference.
+-- 
+2.39.5
+
diff --git a/queue-6.15/crypto-iaa-do-not-clobber-req-base.data.patch b/queue-6.15/crypto-iaa-do-not-clobber-req-base.data.patch
new file mode 100644 (file)
index 0000000..805a01d
--- /dev/null
@@ -0,0 +1,49 @@
+From a6bdb35480a44e0ae3df479ad1abccef9788d831 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Mar 2025 12:04:18 +0800
+Subject: crypto: iaa - Do not clobber req->base.data
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+[ Upstream commit cc98d8ce934b99789d30421957fd6a20fffb1c22 ]
+
+The req->base.data field is for the user and must not be touched by
+the driver, unless you save it first.
+
+The iaa driver doesn't seem to be using the req->base.data value
+so just remove the assignment.
+
+Fixes: 09646c98d0bf ("crypto: iaa - Add irq support for the crypto async interface")
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/intel/iaa/iaa_crypto_main.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/crypto/intel/iaa/iaa_crypto_main.c b/drivers/crypto/intel/iaa/iaa_crypto_main.c
+index 09d9589f2d681..33a285981dfd4 100644
+--- a/drivers/crypto/intel/iaa/iaa_crypto_main.c
++++ b/drivers/crypto/intel/iaa/iaa_crypto_main.c
+@@ -1187,8 +1187,7 @@ static int iaa_compress(struct crypto_tfm *tfm,  struct acomp_req *req,
+                       " src_addr %llx, dst_addr %llx\n", __func__,
+                       active_compression_mode->name,
+                       src_addr, dst_addr);
+-      } else if (ctx->async_mode)
+-              req->base.data = idxd_desc;
++      }
+       dev_dbg(dev, "%s: compression mode %s,"
+               " desc->src1_addr %llx, desc->src1_size %d,"
+@@ -1425,8 +1424,7 @@ static int iaa_decompress(struct crypto_tfm *tfm, struct acomp_req *req,
+                       " src_addr %llx, dst_addr %llx\n", __func__,
+                       active_compression_mode->name,
+                       src_addr, dst_addr);
+-      } else if (ctx->async_mode && !disable_async)
+-              req->base.data = idxd_desc;
++      }
+       dev_dbg(dev, "%s: decompression mode %s,"
+               " desc->src1_addr %llx, desc->src1_size %d,"
+-- 
+2.39.5
+
diff --git a/queue-6.15/crypto-krb5-fix-change-to-use-sg-miter-to-use-offset.patch b/queue-6.15/crypto-krb5-fix-change-to-use-sg-miter-to-use-offset.patch
new file mode 100644 (file)
index 0000000..28c2a52
--- /dev/null
@@ -0,0 +1,59 @@
+From 9aa46b53d1f0fd4421f6a742a03feb87ca80a539 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Apr 2025 11:22:06 +0100
+Subject: crypto/krb5: Fix change to use SG miter to use offset
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit eed848871c96d4b5a7b06307755b75abd0cc7a06 ]
+
+The recent patch to make the rfc3961 simplified code use sg_miter rather
+than manually walking the scatterlist to hash the contents of a buffer
+described by that scatterlist failed to take the starting offset into
+account.
+
+This is indicated by the selftests reporting:
+
+    krb5: Running aes128-cts-hmac-sha256-128 mic
+    krb5: !!! TESTFAIL crypto/krb5/selftest.c:446
+    krb5: MIC mismatch
+
+Fix this by calling sg_miter_skip() before doing the loop to advance
+by the offset.
+
+This only affects packet signing modes and not full encryption in RxGK
+because, for full encryption, the message digest is handled inside the
+authenc and krb5enc drivers.
+
+Note: Nothing in linus/master uses the krb5lib, though the bug is there.
+It is used by AF_RXRPC's RxGK implementation in -next, no need to backport.
+
+Fixes: da6f9bf40ac2 ("crypto: krb5 - Use SG miter instead of doing it by hand")
+Reported-by: Marc Dionne <marc.dionne@auristor.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Chuck Lever <chuck.lever@oracle.com>
+cc: Simon Horman <horms@kernel.org>
+cc: linux-afs@lists.infradead.org
+Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
+Link: https://patch.msgid.link/3824017.1745835726@warthog.procyon.org.uk
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ crypto/krb5/rfc3961_simplified.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/crypto/krb5/rfc3961_simplified.c b/crypto/krb5/rfc3961_simplified.c
+index 79180d28baa9f..e49cbdec7c404 100644
+--- a/crypto/krb5/rfc3961_simplified.c
++++ b/crypto/krb5/rfc3961_simplified.c
+@@ -89,6 +89,7 @@ int crypto_shash_update_sg(struct shash_desc *desc, struct scatterlist *sg,
+       sg_miter_start(&miter, sg, sg_nents(sg),
+                      SG_MITER_FROM_SG | SG_MITER_LOCAL);
++      sg_miter_skip(&miter, offset);
+       for (i = 0; i < len; i += n) {
+               sg_miter_next(&miter);
+               n = min(miter.length, len - i);
+-- 
+2.39.5
+
diff --git a/queue-6.15/crypto-lrw-only-add-ecb-if-it-is-not-already-there.patch b/queue-6.15/crypto-lrw-only-add-ecb-if-it-is-not-already-there.patch
new file mode 100644 (file)
index 0000000..ad4b244
--- /dev/null
@@ -0,0 +1,48 @@
+From 349e1e27569ad3cbf95579fb0c53d18476689eb7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 May 2025 16:28:08 +0800
+Subject: crypto: lrw - Only add ecb if it is not already there
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+[ Upstream commit 3d73909bddc2ebb3224a8bc2e5ce00e9df70c15d ]
+
+Only add ecb to the cipher name if it isn't already ecb.
+
+Also use memcmp instead of strncmp since these strings are all
+stored in an array of length CRYPTO_MAX_ALG_NAME.
+
+Fixes: 700cb3f5fe75 ("crypto: lrw - Convert to skcipher")
+Reported-by: kernel test robot <oliver.sang@intel.com>
+Closes: https://lore.kernel.org/oe-lkp/202505151503.d8a6cf10-lkp@intel.com
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ crypto/lrw.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/crypto/lrw.c b/crypto/lrw.c
+index 391ae0f7641ff..15f579a768614 100644
+--- a/crypto/lrw.c
++++ b/crypto/lrw.c
+@@ -322,7 +322,7 @@ static int lrw_create(struct crypto_template *tmpl, struct rtattr **tb)
+       err = crypto_grab_skcipher(spawn, skcipher_crypto_instance(inst),
+                                  cipher_name, 0, mask);
+-      if (err == -ENOENT) {
++      if (err == -ENOENT && memcmp(cipher_name, "ecb(", 4)) {
+               err = -ENAMETOOLONG;
+               if (snprintf(ecb_name, CRYPTO_MAX_ALG_NAME, "ecb(%s)",
+                            cipher_name) >= CRYPTO_MAX_ALG_NAME)
+@@ -356,7 +356,7 @@ static int lrw_create(struct crypto_template *tmpl, struct rtattr **tb)
+       /* Alas we screwed up the naming so we have to mangle the
+        * cipher name.
+        */
+-      if (!strncmp(cipher_name, "ecb(", 4)) {
++      if (!memcmp(cipher_name, "ecb(", 4)) {
+               int len;
+               len = strscpy(ecb_name, cipher_name + 4, sizeof(ecb_name));
+-- 
+2.39.5
+
diff --git a/queue-6.15/crypto-marvell-cesa-avoid-empty-transfer-descriptor.patch b/queue-6.15/crypto-marvell-cesa-avoid-empty-transfer-descriptor.patch
new file mode 100644 (file)
index 0000000..af6f535
--- /dev/null
@@ -0,0 +1,36 @@
+From f58e03a2fae029a81cff2a0f6716eeaaf78b84ca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 10 May 2025 18:43:33 +0800
+Subject: crypto: marvell/cesa - Avoid empty transfer descriptor
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+[ Upstream commit 1bafd82d9a40cf09c6c40f1c09cc35b7050b1a9f ]
+
+The user may set req->src even if req->nbytes == 0.  If there
+is no data to hash from req->src, do not generate an empty TDMA
+descriptor.
+
+Fixes: db509a45339f ("crypto: marvell/cesa - add TDMA support")
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/marvell/cesa/hash.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/marvell/cesa/hash.c b/drivers/crypto/marvell/cesa/hash.c
+index f150861ceaf69..6815eddc90681 100644
+--- a/drivers/crypto/marvell/cesa/hash.c
++++ b/drivers/crypto/marvell/cesa/hash.c
+@@ -663,7 +663,7 @@ static int mv_cesa_ahash_dma_req_init(struct ahash_request *req)
+       if (ret)
+               goto err_free_tdma;
+-      if (iter.src.sg) {
++      if (iter.base.len > iter.src.op_offset) {
+               /*
+                * Add all the new data, inserting an operation block and
+                * launch command between each full SRAM block-worth of
+-- 
+2.39.5
+
diff --git a/queue-6.15/crypto-marvell-cesa-handle-zero-length-skcipher-requ.patch b/queue-6.15/crypto-marvell-cesa-handle-zero-length-skcipher-requ.patch
new file mode 100644 (file)
index 0000000..fef9c23
--- /dev/null
@@ -0,0 +1,36 @@
+From f3e2632b41c7120c36a166db0cd3f83a94d90a04 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 10 May 2025 18:41:31 +0800
+Subject: crypto: marvell/cesa - Handle zero-length skcipher requests
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+[ Upstream commit 8a4e047c6cc07676f637608a9dd675349b5de0a7 ]
+
+Do not access random memory for zero-length skcipher requests.
+Just return 0.
+
+Fixes: f63601fd616a ("crypto: marvell/cesa - add a new driver for Marvell's CESA")
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/marvell/cesa/cipher.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/crypto/marvell/cesa/cipher.c b/drivers/crypto/marvell/cesa/cipher.c
+index cf62db50f9585..48c5c8ea8c43e 100644
+--- a/drivers/crypto/marvell/cesa/cipher.c
++++ b/drivers/crypto/marvell/cesa/cipher.c
+@@ -459,6 +459,9 @@ static int mv_cesa_skcipher_queue_req(struct skcipher_request *req,
+       struct mv_cesa_skcipher_req *creq = skcipher_request_ctx(req);
+       struct mv_cesa_engine *engine;
++      if (!req->cryptlen)
++              return 0;
++
+       ret = mv_cesa_skcipher_req_init(req, tmpl);
+       if (ret)
+               return ret;
+-- 
+2.39.5
+
diff --git a/queue-6.15/crypto-sun8i-ce-cipher-fix-error-handling-in-sun8i_c.patch b/queue-6.15/crypto-sun8i-ce-cipher-fix-error-handling-in-sun8i_c.patch
new file mode 100644 (file)
index 0000000..f997c56
--- /dev/null
@@ -0,0 +1,77 @@
+From 60e7b28e442515ebdb7afded588c26775be4b6fc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 15:45:14 +0300
+Subject: crypto: sun8i-ce-cipher - fix error handling in
+ sun8i_ce_cipher_prepare()
+
+From: Ovidiu Panait <ovidiu.panait.oss@gmail.com>
+
+[ Upstream commit f31adc3e356f7350d4a4d68c98d3f60f2f6e26b3 ]
+
+Fix two DMA cleanup issues on the error path in sun8i_ce_cipher_prepare():
+
+1] If dma_map_sg() fails for areq->dst, the device driver would try to free
+   DMA memory it has not allocated in the first place. To fix this, on the
+   "theend_sgs" error path, call dma unmap only if the corresponding dma
+   map was successful.
+
+2] If the dma_map_single() call for the IV fails, the device driver would
+   try to free an invalid DMA memory address on the "theend_iv" path:
+   ------------[ cut here ]------------
+   DMA-API: sun8i-ce 1904000.crypto: device driver tries to free an invalid DMA memory address
+   WARNING: CPU: 2 PID: 69 at kernel/dma/debug.c:968 check_unmap+0x123c/0x1b90
+   Modules linked in: skcipher_example(O+)
+   CPU: 2 UID: 0 PID: 69 Comm: 1904000.crypto- Tainted: G           O        6.15.0-rc3+ #24 PREEMPT
+   Tainted: [O]=OOT_MODULE
+   Hardware name: OrangePi Zero2 (DT)
+   pc : check_unmap+0x123c/0x1b90
+   lr : check_unmap+0x123c/0x1b90
+   ...
+   Call trace:
+    check_unmap+0x123c/0x1b90 (P)
+    debug_dma_unmap_page+0xac/0xc0
+    dma_unmap_page_attrs+0x1f4/0x5fc
+    sun8i_ce_cipher_do_one+0x1bd4/0x1f40
+    crypto_pump_work+0x334/0x6e0
+    kthread_worker_fn+0x21c/0x438
+    kthread+0x374/0x664
+    ret_from_fork+0x10/0x20
+   ---[ end trace 0000000000000000 ]---
+
+To fix this, check for !dma_mapping_error() before calling
+dma_unmap_single() on the "theend_iv" path.
+
+Fixes: 06f751b61329 ("crypto: allwinner - Add sun8i-ce Crypto Engine")
+Signed-off-by: Ovidiu Panait <ovidiu.panait.oss@gmail.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c
+index 19b7fb4a93e86..05f67661553c9 100644
+--- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c
++++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c
+@@ -275,13 +275,16 @@ static int sun8i_ce_cipher_prepare(struct crypto_engine *engine, void *async_req
+       } else {
+               if (nr_sgs > 0)
+                       dma_unmap_sg(ce->dev, areq->src, ns, DMA_TO_DEVICE);
+-              dma_unmap_sg(ce->dev, areq->dst, nd, DMA_FROM_DEVICE);
++
++              if (nr_sgd > 0)
++                      dma_unmap_sg(ce->dev, areq->dst, nd, DMA_FROM_DEVICE);
+       }
+ theend_iv:
+       if (areq->iv && ivsize > 0) {
+-              if (rctx->addr_iv)
++              if (!dma_mapping_error(ce->dev, rctx->addr_iv))
+                       dma_unmap_single(ce->dev, rctx->addr_iv, rctx->ivlen, DMA_TO_DEVICE);
++
+               offset = areq->cryptlen - ivsize;
+               if (rctx->op_dir & CE_DECRYPTION) {
+                       memcpy(areq->iv, chan->backup_iv, ivsize);
+-- 
+2.39.5
+
diff --git a/queue-6.15/crypto-sun8i-ce-hash-fix-error-handling-in-sun8i_ce_.patch b/queue-6.15/crypto-sun8i-ce-hash-fix-error-handling-in-sun8i_ce_.patch
new file mode 100644 (file)
index 0000000..c9c18f6
--- /dev/null
@@ -0,0 +1,131 @@
+From 0cfda2b77a4c0c1ef91f47c00529887e56b54ce7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 22:23:16 +0300
+Subject: crypto: sun8i-ce-hash - fix error handling in sun8i_ce_hash_run()
+
+From: Ovidiu Panait <ovidiu.panait.oss@gmail.com>
+
+[ Upstream commit ea4dd134ef332bd9e3e734c1ba0a1521f436b678 ]
+
+Rework error handling in sun8i_ce_hash_run() to unmap the dma buffers in
+case of failure. Currently, the dma unmap functions are not called if the
+function errors out at various points.
+
+Fixes: 56f6d5aee88d1 ("crypto: sun8i-ce - support hash algorithms")
+Signed-off-by: Ovidiu Panait <ovidiu.panait.oss@gmail.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../crypto/allwinner/sun8i-ce/sun8i-ce-hash.c | 34 ++++++++++++-------
+ 1 file changed, 21 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c
+index 6072dd9f390b4..3f9d79ea01aaa 100644
+--- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c
++++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c
+@@ -343,9 +343,8 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
+       u32 common;
+       u64 byte_count;
+       __le32 *bf;
+-      void *buf = NULL;
++      void *buf, *result;
+       int j, i, todo;
+-      void *result = NULL;
+       u64 bs;
+       int digestsize;
+       dma_addr_t addr_res, addr_pad;
+@@ -365,14 +364,14 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
+       buf = kcalloc(2, bs, GFP_KERNEL | GFP_DMA);
+       if (!buf) {
+               err = -ENOMEM;
+-              goto theend;
++              goto err_out;
+       }
+       bf = (__le32 *)buf;
+       result = kzalloc(digestsize, GFP_KERNEL | GFP_DMA);
+       if (!result) {
+               err = -ENOMEM;
+-              goto theend;
++              goto err_free_buf;
+       }
+       flow = rctx->flow;
+@@ -398,7 +397,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
+       if (nr_sgs <= 0 || nr_sgs > MAX_SG) {
+               dev_err(ce->dev, "Invalid sg number %d\n", nr_sgs);
+               err = -EINVAL;
+-              goto theend;
++              goto err_free_result;
+       }
+       len = areq->nbytes;
+@@ -411,7 +410,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
+       if (len > 0) {
+               dev_err(ce->dev, "remaining len %d\n", len);
+               err = -EINVAL;
+-              goto theend;
++              goto err_unmap_src;
+       }
+       addr_res = dma_map_single(ce->dev, result, digestsize, DMA_FROM_DEVICE);
+       cet->t_dst[0].addr = desc_addr_val_le32(ce, addr_res);
+@@ -419,7 +418,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
+       if (dma_mapping_error(ce->dev, addr_res)) {
+               dev_err(ce->dev, "DMA map dest\n");
+               err = -EINVAL;
+-              goto theend;
++              goto err_unmap_src;
+       }
+       byte_count = areq->nbytes;
+@@ -441,7 +440,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
+       }
+       if (!j) {
+               err = -EINVAL;
+-              goto theend;
++              goto err_unmap_result;
+       }
+       addr_pad = dma_map_single(ce->dev, buf, j * 4, DMA_TO_DEVICE);
+@@ -450,7 +449,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
+       if (dma_mapping_error(ce->dev, addr_pad)) {
+               dev_err(ce->dev, "DMA error on padding SG\n");
+               err = -EINVAL;
+-              goto theend;
++              goto err_unmap_result;
+       }
+       if (ce->variant->hash_t_dlen_in_bits)
+@@ -463,16 +462,25 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
+       err = sun8i_ce_run_task(ce, flow, crypto_ahash_alg_name(tfm));
+       dma_unmap_single(ce->dev, addr_pad, j * 4, DMA_TO_DEVICE);
+-      dma_unmap_sg(ce->dev, areq->src, ns, DMA_TO_DEVICE);
++
++err_unmap_result:
+       dma_unmap_single(ce->dev, addr_res, digestsize, DMA_FROM_DEVICE);
++      if (!err)
++              memcpy(areq->result, result, algt->alg.hash.base.halg.digestsize);
++err_unmap_src:
++      dma_unmap_sg(ce->dev, areq->src, ns, DMA_TO_DEVICE);
+-      memcpy(areq->result, result, algt->alg.hash.base.halg.digestsize);
+-theend:
+-      kfree(buf);
++err_free_result:
+       kfree(result);
++
++err_free_buf:
++      kfree(buf);
++
++err_out:
+       local_bh_disable();
+       crypto_finalize_hash_request(engine, breq, err);
+       local_bh_enable();
++
+       return 0;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/crypto-sun8i-ce-move-fallback-ahash_request-to-the-e.patch b/queue-6.15/crypto-sun8i-ce-move-fallback-ahash_request-to-the-e.patch
new file mode 100644 (file)
index 0000000..68bf99b
--- /dev/null
@@ -0,0 +1,41 @@
+From 04d0f0ccd9a121f5d98f8dcace2f947375e95108 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 May 2025 15:06:56 +0300
+Subject: crypto: sun8i-ce - move fallback ahash_request to the end of the
+ struct
+
+From: Ovidiu Panait <ovidiu.panait.oss@gmail.com>
+
+[ Upstream commit c822831b426307a6ca426621504d3c7f99765a39 ]
+
+'struct ahash_request' has a flexible array at the end, so it must be the
+last member in a struct, to avoid overwriting other struct members.
+
+Therefore, move 'fallback_req' to the end of the 'sun8i_ce_hash_reqctx'
+struct.
+
+Fixes: 56f6d5aee88d ("crypto: sun8i-ce - support hash algorithms")
+Signed-off-by: Ovidiu Panait <ovidiu.panait.oss@gmail.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h
+index 3b5c2af013d0d..83df4d7190531 100644
+--- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h
++++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h
+@@ -308,8 +308,8 @@ struct sun8i_ce_hash_tfm_ctx {
+  * @flow:     the flow to use for this request
+  */
+ struct sun8i_ce_hash_reqctx {
+-      struct ahash_request fallback_req;
+       int flow;
++      struct ahash_request fallback_req; // keep at the end
+ };
+ /*
+-- 
+2.39.5
+
diff --git a/queue-6.15/crypto-sun8i-ce-undo-runtime-pm-changes-during-drive.patch b/queue-6.15/crypto-sun8i-ce-undo-runtime-pm-changes-during-drive.patch
new file mode 100644 (file)
index 0000000..dcf8db5
--- /dev/null
@@ -0,0 +1,78 @@
+From 6c94575e044a793c7de4b7daeee162ab6c1d5879 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 May 2025 22:06:50 +0300
+Subject: crypto: sun8i-ce - undo runtime PM changes during driver removal
+
+From: Ovidiu Panait <ovidiu.panait.oss@gmail.com>
+
+[ Upstream commit 9334f427576e6d361a409959b52246b0aa10476f ]
+
+The pm_runtime_use_autosuspend() call must be undone with
+pm_runtime_dont_use_autosuspend() at driver exit, but this is not
+currently handled in the driver.
+
+To fix this issue and at the same time simplify error handling, switch
+to devm_pm_runtime_enable(). It will call both pm_runtime_disable() and
+pm_runtime_dont_use_autosuspend() during driver removal.
+
+Fixes: 06f751b61329 ("crypto: allwinner - Add sun8i-ce Crypto Engine")
+Signed-off-by: Ovidiu Panait <ovidiu.panait.oss@gmail.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../crypto/allwinner/sun8i-ce/sun8i-ce-core.c   | 17 ++++++-----------
+ 1 file changed, 6 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c
+index ec1ffda9ea32e..658f520cee0ca 100644
+--- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c
++++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c
+@@ -832,13 +832,12 @@ static int sun8i_ce_pm_init(struct sun8i_ce_dev *ce)
+       err = pm_runtime_set_suspended(ce->dev);
+       if (err)
+               return err;
+-      pm_runtime_enable(ce->dev);
+-      return err;
+-}
+-static void sun8i_ce_pm_exit(struct sun8i_ce_dev *ce)
+-{
+-      pm_runtime_disable(ce->dev);
++      err = devm_pm_runtime_enable(ce->dev);
++      if (err)
++              return err;
++
++      return 0;
+ }
+ static int sun8i_ce_get_clks(struct sun8i_ce_dev *ce)
+@@ -1041,7 +1040,7 @@ static int sun8i_ce_probe(struct platform_device *pdev)
+                              "sun8i-ce-ns", ce);
+       if (err) {
+               dev_err(ce->dev, "Cannot request CryptoEngine Non-secure IRQ (err=%d)\n", err);
+-              goto error_irq;
++              goto error_pm;
+       }
+       err = sun8i_ce_register_algs(ce);
+@@ -1082,8 +1081,6 @@ static int sun8i_ce_probe(struct platform_device *pdev)
+       return 0;
+ error_alg:
+       sun8i_ce_unregister_algs(ce);
+-error_irq:
+-      sun8i_ce_pm_exit(ce);
+ error_pm:
+       sun8i_ce_free_chanlist(ce, MAXFLOW - 1);
+       return err;
+@@ -1104,8 +1101,6 @@ static void sun8i_ce_remove(struct platform_device *pdev)
+ #endif
+       sun8i_ce_free_chanlist(ce, MAXFLOW - 1);
+-
+-      sun8i_ce_pm_exit(ce);
+ }
+ static const struct of_device_id sun8i_ce_crypto_of_match_table[] = {
+-- 
+2.39.5
+
diff --git a/queue-6.15/crypto-sun8i-ss-do-not-use-sg_dma_len-before-calling.patch b/queue-6.15/crypto-sun8i-ss-do-not-use-sg_dma_len-before-calling.patch
new file mode 100644 (file)
index 0000000..7988920
--- /dev/null
@@ -0,0 +1,39 @@
+From 8144e3dc6586d39c729d71ffd4a9d9384f32e96e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 27 Apr 2025 13:12:36 +0200
+Subject: crypto: sun8i-ss - do not use sg_dma_len before calling DMA functions
+
+From: Corentin Labbe <clabbe.montjoie@gmail.com>
+
+[ Upstream commit 2dfc7cd74a5e062a5405560447517e7aab1c7341 ]
+
+When testing sun8i-ss with multi_v7_defconfig, all CBC algorithm fail crypto
+selftests.
+This is strange since on sunxi_defconfig, everything was ok.
+The problem was in the IV setup loop which never run because sg_dma_len
+was 0.
+
+Fixes: 359e893e8af4 ("crypto: sun8i-ss - rework handling of IV")
+Signed-off-by: Corentin Labbe <clabbe.montjoie@gmail.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
+index 9b9605ce8ee62..8831bcb230c2d 100644
+--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
++++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
+@@ -141,7 +141,7 @@ static int sun8i_ss_setup_ivs(struct skcipher_request *areq)
+       /* we need to copy all IVs from source in case DMA is bi-directionnal */
+       while (sg && len) {
+-              if (sg_dma_len(sg) == 0) {
++              if (sg->length == 0) {
+                       sg = sg_next(sg);
+                       continue;
+               }
+-- 
+2.39.5
+
diff --git a/queue-6.15/crypto-xts-only-add-ecb-if-it-is-not-already-there.patch b/queue-6.15/crypto-xts-only-add-ecb-if-it-is-not-already-there.patch
new file mode 100644 (file)
index 0000000..9a3d3cb
--- /dev/null
@@ -0,0 +1,46 @@
+From eb6cd177ea2b5f2f99685719b342825ff2d54ac3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 May 2025 16:34:04 +0800
+Subject: crypto: xts - Only add ecb if it is not already there
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+[ Upstream commit 270b6f13454cb7f2f7058c50df64df409c5dcf55 ]
+
+Only add ecb to the cipher name if it isn't already ecb.
+
+Also use memcmp instead of strncmp since these strings are all
+stored in an array of length CRYPTO_MAX_ALG_NAME.
+
+Fixes: f1c131b45410 ("crypto: xts - Convert to skcipher")
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ crypto/xts.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/crypto/xts.c b/crypto/xts.c
+index 31529c9ef08f8..46b7c70ea54bb 100644
+--- a/crypto/xts.c
++++ b/crypto/xts.c
+@@ -363,7 +363,7 @@ static int xts_create(struct crypto_template *tmpl, struct rtattr **tb)
+       err = crypto_grab_skcipher(&ctx->spawn, skcipher_crypto_instance(inst),
+                                  cipher_name, 0, mask);
+-      if (err == -ENOENT) {
++      if (err == -ENOENT && memcmp(cipher_name, "ecb(", 4)) {
+               err = -ENAMETOOLONG;
+               if (snprintf(name, CRYPTO_MAX_ALG_NAME, "ecb(%s)",
+                            cipher_name) >= CRYPTO_MAX_ALG_NAME)
+@@ -397,7 +397,7 @@ static int xts_create(struct crypto_template *tmpl, struct rtattr **tb)
+       /* Alas we screwed up the naming so we have to mangle the
+        * cipher name.
+        */
+-      if (!strncmp(cipher_name, "ecb(", 4)) {
++      if (!memcmp(cipher_name, "ecb(", 4)) {
+               int len;
+               len = strscpy(name, cipher_name + 4, sizeof(name));
+-- 
+2.39.5
+
diff --git a/queue-6.15/crypto-zynqmp-sha-add-locking.patch b/queue-6.15/crypto-zynqmp-sha-add-locking.patch
new file mode 100644 (file)
index 0000000..b144424
--- /dev/null
@@ -0,0 +1,81 @@
+From 7521f54c03a9574a13c5c71b48214f1cbb330265 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 12 Apr 2025 18:57:22 +0800
+Subject: crypto: zynqmp-sha - Add locking
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+[ Upstream commit c7e68043620e0d5f89a37e573c667beab72d2937 ]
+
+The hardwrae is only capable of one hash at a time, so add a lock
+to make sure that it isn't used concurrently.
+
+Fixes: 7ecc3e34474b ("crypto: xilinx - Add Xilinx SHA3 driver")
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/xilinx/zynqmp-sha.c | 18 ++++++++++++++----
+ 1 file changed, 14 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/crypto/xilinx/zynqmp-sha.c b/drivers/crypto/xilinx/zynqmp-sha.c
+index 580649f9bff81..0edf8eb264b55 100644
+--- a/drivers/crypto/xilinx/zynqmp-sha.c
++++ b/drivers/crypto/xilinx/zynqmp-sha.c
+@@ -3,18 +3,19 @@
+  * Xilinx ZynqMP SHA Driver.
+  * Copyright (c) 2022 Xilinx Inc.
+  */
+-#include <linux/cacheflush.h>
+ #include <crypto/hash.h>
+ #include <crypto/internal/hash.h>
+ #include <crypto/sha3.h>
+-#include <linux/crypto.h>
++#include <linux/cacheflush.h>
++#include <linux/cleanup.h>
+ #include <linux/device.h>
+ #include <linux/dma-mapping.h>
++#include <linux/err.h>
+ #include <linux/firmware/xlnx-zynqmp.h>
+-#include <linux/init.h>
+ #include <linux/io.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
++#include <linux/spinlock.h>
+ #include <linux/platform_device.h>
+ #define ZYNQMP_DMA_BIT_MASK           32U
+@@ -43,6 +44,8 @@ struct zynqmp_sha_desc_ctx {
+ static dma_addr_t update_dma_addr, final_dma_addr;
+ static char *ubuf, *fbuf;
++static DEFINE_SPINLOCK(zynqmp_sha_lock);
++
+ static int zynqmp_sha_init_tfm(struct crypto_shash *hash)
+ {
+       const char *fallback_driver_name = crypto_shash_alg_name(hash);
+@@ -124,7 +127,8 @@ static int zynqmp_sha_export(struct shash_desc *desc, void *out)
+       return crypto_shash_export(&dctx->fbk_req, out);
+ }
+-static int zynqmp_sha_digest(struct shash_desc *desc, const u8 *data, unsigned int len, u8 *out)
++static int __zynqmp_sha_digest(struct shash_desc *desc, const u8 *data,
++                             unsigned int len, u8 *out)
+ {
+       unsigned int remaining_len = len;
+       int update_size;
+@@ -159,6 +163,12 @@ static int zynqmp_sha_digest(struct shash_desc *desc, const u8 *data, unsigned i
+       return ret;
+ }
++static int zynqmp_sha_digest(struct shash_desc *desc, const u8 *data, unsigned int len, u8 *out)
++{
++      scoped_guard(spinlock_bh, &zynqmp_sha_lock)
++              return __zynqmp_sha_digest(desc, data, len, out);
++}
++
+ static struct zynqmp_sha_drv_ctx sha3_drv_ctx = {
+       .sha3_384 = {
+               .init = zynqmp_sha_init,
+-- 
+2.39.5
+
diff --git a/queue-6.15/dm-don-t-change-md-if-dm_table_set_restrictions-fail.patch b/queue-6.15/dm-don-t-change-md-if-dm_table_set_restrictions-fail.patch
new file mode 100644 (file)
index 0000000..2da96ee
--- /dev/null
@@ -0,0 +1,81 @@
+From fcfaaaa9ed08996fe035529b3d7b2518142e5237 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Apr 2025 15:49:38 -0400
+Subject: dm: don't change md if dm_table_set_restrictions() fails
+
+From: Benjamin Marzinski <bmarzins@redhat.com>
+
+[ Upstream commit 9eb7109a5bfc5b8226e9517e9f3cc6d414391884 ]
+
+__bind was changing the disk capacity, geometry and mempools of the
+mapped device before calling dm_table_set_restrictions() which could
+fail, forcing dm to drop the new table. Failing here would leave the
+device using the old table but with the wrong capacity and mempools.
+
+Move dm_table_set_restrictions() earlier in __bind(). Since it needs the
+capacity to be set, save the old version and restore it on failure.
+
+Fixes: bb37d77239af2 ("dm: introduce zone append emulation")
+Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
+Tested-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm.c | 22 ++++++++++++----------
+ 1 file changed, 12 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/md/dm.c b/drivers/md/dm.c
+index 5ab7574c0c76a..f5c5ccb6f8d25 100644
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -2421,21 +2421,29 @@ static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t,
+                              struct queue_limits *limits)
+ {
+       struct dm_table *old_map;
+-      sector_t size;
++      sector_t size, old_size;
+       int ret;
+       lockdep_assert_held(&md->suspend_lock);
+       size = dm_table_get_size(t);
++      old_size = dm_get_size(md);
++      set_capacity(md->disk, size);
++
++      ret = dm_table_set_restrictions(t, md->queue, limits);
++      if (ret) {
++              set_capacity(md->disk, old_size);
++              old_map = ERR_PTR(ret);
++              goto out;
++      }
++
+       /*
+        * Wipe any geometry if the size of the table changed.
+        */
+-      if (size != dm_get_size(md))
++      if (size != old_size)
+               memset(&md->geometry, 0, sizeof(md->geometry));
+-      set_capacity(md->disk, size);
+-
+       dm_table_event_callback(t, event_callback, md);
+       if (dm_table_request_based(t)) {
+@@ -2468,12 +2476,6 @@ static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t,
+               t->mempools = NULL;
+       }
+-      ret = dm_table_set_restrictions(t, md->queue, limits);
+-      if (ret) {
+-              old_map = ERR_PTR(ret);
+-              goto out;
+-      }
+-
+       old_map = rcu_dereference_protected(md->map, lockdep_is_held(&md->suspend_lock));
+       rcu_assign_pointer(md->map, (void *)t);
+       md->immutable_target_type = dm_table_get_immutable_target_type(t);
+-- 
+2.39.5
+
diff --git a/queue-6.15/dm-fix-dm_blk_report_zones.patch b/queue-6.15/dm-fix-dm_blk_report_zones.patch
new file mode 100644 (file)
index 0000000..8c47892
--- /dev/null
@@ -0,0 +1,120 @@
+From e3917a705c4004f1da6cba0406b2ff56a0b8e97e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Apr 2025 15:49:41 -0400
+Subject: dm: fix dm_blk_report_zones
+
+From: Benjamin Marzinski <bmarzins@redhat.com>
+
+[ Upstream commit 37f53a2c60d03743e0eacf7a0c01c279776fef4e ]
+
+If dm_get_live_table() returned NULL, dm_put_live_table() was never
+called. Also, it is possible that md->zone_revalidate_map will change
+while calling this function. Only read it once, so that we are always
+using the same value. Otherwise we might miss a call to
+dm_put_live_table().
+
+Finally, while md->zone_revalidate_map is set and a process is calling
+blk_revalidate_disk_zones() to set up the zone append emulation
+resources, it is possible that another process, perhaps triggered by
+blkdev_report_zones_ioctl(), will call dm_blk_report_zones(). If
+blk_revalidate_disk_zones() fails, these resources can be freed while
+the other process is still using them, causing a use-after-free error.
+
+blk_revalidate_disk_zones() will only ever be called when initially
+setting up the zone append emulation resources, such as when setting up
+a zoned dm-crypt table for the first time. Further table swaps will not
+set md->zone_revalidate_map or call blk_revalidate_disk_zones().
+However it must be called using the new table (referenced by
+md->zone_revalidate_map) and the new queue limits while the DM device is
+suspended. dm_blk_report_zones() needs some way to distinguish between a
+call from blk_revalidate_disk_zones(), which must be allowed to use
+md->zone_revalidate_map to access this not yet activated table, and all
+other calls to dm_blk_report_zones(), which should not be allowed while
+the device is suspended and cannot use md->zone_revalidate_map, since
+the zone resources might be freed by the process currently calling
+blk_revalidate_disk_zones().
+
+Solve this by tracking the process that sets md->zone_revalidate_map in
+dm_revalidate_zones() and only allowing that process to make use of it
+in dm_blk_report_zones().
+
+Fixes: f211268ed1f9b ("dm: Use the block layer zone append emulation")
+Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
+Tested-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm-core.h |  1 +
+ drivers/md/dm-zone.c | 25 +++++++++++++++++--------
+ 2 files changed, 18 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/md/dm-core.h b/drivers/md/dm-core.h
+index 3637761f35853..f3a3f2ef63226 100644
+--- a/drivers/md/dm-core.h
++++ b/drivers/md/dm-core.h
+@@ -141,6 +141,7 @@ struct mapped_device {
+ #ifdef CONFIG_BLK_DEV_ZONED
+       unsigned int nr_zones;
+       void *zone_revalidate_map;
++      struct task_struct *revalidate_map_task;
+ #endif
+ #ifdef CONFIG_IMA
+diff --git a/drivers/md/dm-zone.c b/drivers/md/dm-zone.c
+index 681058feb63b5..ff9a1a94eea96 100644
+--- a/drivers/md/dm-zone.c
++++ b/drivers/md/dm-zone.c
+@@ -56,24 +56,31 @@ int dm_blk_report_zones(struct gendisk *disk, sector_t sector,
+ {
+       struct mapped_device *md = disk->private_data;
+       struct dm_table *map;
+-      int srcu_idx, ret;
++      struct dm_table *zone_revalidate_map = md->zone_revalidate_map;
++      int srcu_idx, ret = -EIO;
++      bool put_table = false;
+-      if (!md->zone_revalidate_map) {
+-              /* Regular user context */
++      if (!zone_revalidate_map || md->revalidate_map_task != current) {
++              /*
++               * Regular user context or
++               * Zone revalidation during __bind() is in progress, but this
++               * call is from a different process
++               */
+               if (dm_suspended_md(md))
+                       return -EAGAIN;
+               map = dm_get_live_table(md, &srcu_idx);
+-              if (!map)
+-                      return -EIO;
++              put_table = true;
+       } else {
+               /* Zone revalidation during __bind() */
+-              map = md->zone_revalidate_map;
++              map = zone_revalidate_map;
+       }
+-      ret = dm_blk_do_report_zones(md, map, sector, nr_zones, cb, data);
++      if (map)
++              ret = dm_blk_do_report_zones(md, map, sector, nr_zones, cb,
++                                           data);
+-      if (!md->zone_revalidate_map)
++      if (put_table)
+               dm_put_live_table(md, srcu_idx);
+       return ret;
+@@ -175,7 +182,9 @@ int dm_revalidate_zones(struct dm_table *t, struct request_queue *q)
+        * our table for dm_blk_report_zones() to use directly.
+        */
+       md->zone_revalidate_map = t;
++      md->revalidate_map_task = current;
+       ret = blk_revalidate_disk_zones(disk);
++      md->revalidate_map_task = NULL;
+       md->zone_revalidate_map = NULL;
+       if (ret) {
+-- 
+2.39.5
+
diff --git a/queue-6.15/dm-flakey-error-all-ios-when-num_features-is-absent.patch b/queue-6.15/dm-flakey-error-all-ios-when-num_features-is-absent.patch
new file mode 100644 (file)
index 0000000..07e4c7a
--- /dev/null
@@ -0,0 +1,68 @@
+From 05fe5dcf68b32c9152e06c69bbfcd698b4ee4929 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Apr 2025 19:47:36 -0400
+Subject: dm-flakey: error all IOs when num_features is absent
+
+From: Benjamin Marzinski <bmarzins@redhat.com>
+
+[ Upstream commit 40ed054f39bc99eac09871c33198e501f4acdf24 ]
+
+dm-flakey would error all IOs if num_features was 0, but if it was
+absent, dm-flakey would never error any IO. Fix this so that no
+num_features works the same as num_features set to 0.
+
+Fixes: aa7d7bc99fed7 ("dm flakey: add an "error_reads" option")
+Reported-by: Kent Overstreet <kent.overstreet@linux.dev>
+Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm-flakey.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c
+index b690905ab89ff..806a80dd3bd9b 100644
+--- a/drivers/md/dm-flakey.c
++++ b/drivers/md/dm-flakey.c
+@@ -53,8 +53,8 @@ struct per_bio_data {
+ static int parse_features(struct dm_arg_set *as, struct flakey_c *fc,
+                         struct dm_target *ti)
+ {
+-      int r;
+-      unsigned int argc;
++      int r = 0;
++      unsigned int argc = 0;
+       const char *arg_name;
+       static const struct dm_arg _args[] = {
+@@ -65,14 +65,13 @@ static int parse_features(struct dm_arg_set *as, struct flakey_c *fc,
+               {0, PROBABILITY_BASE, "Invalid random corrupt argument"},
+       };
+-      /* No feature arguments supplied. */
+-      if (!as->argc)
+-              return 0;
+-
+-      r = dm_read_arg_group(_args, as, &argc, &ti->error);
+-      if (r)
++      if (as->argc && (r = dm_read_arg_group(_args, as, &argc, &ti->error)))
+               return r;
++      /* No feature arguments supplied. */
++      if (!argc)
++              goto error_all_io;
++
+       while (argc) {
+               arg_name = dm_shift_arg(as);
+               argc--;
+@@ -217,6 +216,7 @@ static int parse_features(struct dm_arg_set *as, struct flakey_c *fc,
+       if (!fc->corrupt_bio_byte && !test_bit(ERROR_READS, &fc->flags) &&
+           !test_bit(DROP_WRITES, &fc->flags) && !test_bit(ERROR_WRITES, &fc->flags) &&
+           !fc->random_read_corrupt && !fc->random_write_corrupt) {
++error_all_io:
+               set_bit(ERROR_WRITES, &fc->flags);
+               set_bit(ERROR_READS, &fc->flags);
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/dm-flakey-make-corrupting-read-bios-work.patch b/queue-6.15/dm-flakey-make-corrupting-read-bios-work.patch
new file mode 100644 (file)
index 0000000..1e7eae4
--- /dev/null
@@ -0,0 +1,180 @@
+From 989f67ff7edeaaf0663f6dfb3eb48e5133782f99 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Apr 2025 19:47:38 -0400
+Subject: dm-flakey: make corrupting read bios work
+
+From: Benjamin Marzinski <bmarzins@redhat.com>
+
+[ Upstream commit 13e79076c89f6e96a6cca8f6df38b40d025907b4 ]
+
+dm-flakey corrupts the read bios in the endio function.  However, the
+corrupt_bio_* functions checked bio_has_data() to see if there was data
+to corrupt. Since this was the endio function, there was no data left to
+complete, so bio_has_data() was always false. Fix this by saving a copy
+of the bio's bi_iter in flakey_map(), and using this to initialize the
+iter for corrupting the read bios. This patch also skips cloning the bio
+for write bios with no data.
+
+Reported-by: Kent Overstreet <kent.overstreet@linux.dev>
+Fixes: a3998799fb4df ("dm flakey: add corrupt_bio_byte feature")
+Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm-flakey.c | 54 ++++++++++++++++++++++--------------------
+ 1 file changed, 28 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c
+index 806a80dd3bd9b..347881f323d5b 100644
+--- a/drivers/md/dm-flakey.c
++++ b/drivers/md/dm-flakey.c
+@@ -47,7 +47,8 @@ enum feature_flag_bits {
+ };
+ struct per_bio_data {
+-      bool bio_submitted;
++      bool bio_can_corrupt;
++      struct bvec_iter saved_iter;
+ };
+ static int parse_features(struct dm_arg_set *as, struct flakey_c *fc,
+@@ -339,7 +340,8 @@ static void flakey_map_bio(struct dm_target *ti, struct bio *bio)
+ }
+ static void corrupt_bio_common(struct bio *bio, unsigned int corrupt_bio_byte,
+-                             unsigned char corrupt_bio_value)
++                             unsigned char corrupt_bio_value,
++                             struct bvec_iter start)
+ {
+       struct bvec_iter iter;
+       struct bio_vec bvec;
+@@ -348,7 +350,7 @@ static void corrupt_bio_common(struct bio *bio, unsigned int corrupt_bio_byte,
+        * Overwrite the Nth byte of the bio's data, on whichever page
+        * it falls.
+        */
+-      bio_for_each_segment(bvec, bio, iter) {
++      __bio_for_each_segment(bvec, bio, iter, start) {
+               if (bio_iter_len(bio, iter) > corrupt_bio_byte) {
+                       unsigned char *segment = bvec_kmap_local(&bvec);
+                       segment[corrupt_bio_byte] = corrupt_bio_value;
+@@ -357,36 +359,31 @@ static void corrupt_bio_common(struct bio *bio, unsigned int corrupt_bio_byte,
+                               "(rw=%c bi_opf=%u bi_sector=%llu size=%u)\n",
+                               bio, corrupt_bio_value, corrupt_bio_byte,
+                               (bio_data_dir(bio) == WRITE) ? 'w' : 'r', bio->bi_opf,
+-                              (unsigned long long)bio->bi_iter.bi_sector,
+-                              bio->bi_iter.bi_size);
++                              (unsigned long long)start.bi_sector,
++                              start.bi_size);
+                       break;
+               }
+               corrupt_bio_byte -= bio_iter_len(bio, iter);
+       }
+ }
+-static void corrupt_bio_data(struct bio *bio, struct flakey_c *fc)
++static void corrupt_bio_data(struct bio *bio, struct flakey_c *fc,
++                           struct bvec_iter start)
+ {
+       unsigned int corrupt_bio_byte = fc->corrupt_bio_byte - 1;
+-      if (!bio_has_data(bio))
+-              return;
+-
+-      corrupt_bio_common(bio, corrupt_bio_byte, fc->corrupt_bio_value);
++      corrupt_bio_common(bio, corrupt_bio_byte, fc->corrupt_bio_value, start);
+ }
+-static void corrupt_bio_random(struct bio *bio)
++static void corrupt_bio_random(struct bio *bio, struct bvec_iter start)
+ {
+       unsigned int corrupt_byte;
+       unsigned char corrupt_value;
+-      if (!bio_has_data(bio))
+-              return;
+-
+-      corrupt_byte = get_random_u32() % bio->bi_iter.bi_size;
++      corrupt_byte = get_random_u32() % start.bi_size;
+       corrupt_value = get_random_u8();
+-      corrupt_bio_common(bio, corrupt_byte, corrupt_value);
++      corrupt_bio_common(bio, corrupt_byte, corrupt_value, start);
+ }
+ static void clone_free(struct bio *clone)
+@@ -481,7 +478,7 @@ static int flakey_map(struct dm_target *ti, struct bio *bio)
+       unsigned int elapsed;
+       struct per_bio_data *pb = dm_per_bio_data(bio, sizeof(struct per_bio_data));
+-      pb->bio_submitted = false;
++      pb->bio_can_corrupt = false;
+       if (op_is_zone_mgmt(bio_op(bio)))
+               goto map_bio;
+@@ -490,10 +487,11 @@ static int flakey_map(struct dm_target *ti, struct bio *bio)
+       elapsed = (jiffies - fc->start_time) / HZ;
+       if (elapsed % (fc->up_interval + fc->down_interval) >= fc->up_interval) {
+               bool corrupt_fixed, corrupt_random;
+-              /*
+-               * Flag this bio as submitted while down.
+-               */
+-              pb->bio_submitted = true;
++
++              if (bio_has_data(bio)) {
++                      pb->bio_can_corrupt = true;
++                      pb->saved_iter = bio->bi_iter;
++              }
+               /*
+                * Error reads if neither corrupt_bio_byte or drop_writes or error_writes are set.
+@@ -516,6 +514,8 @@ static int flakey_map(struct dm_target *ti, struct bio *bio)
+                       return DM_MAPIO_SUBMITTED;
+               }
++              if (!pb->bio_can_corrupt)
++                      goto map_bio;
+               /*
+                * Corrupt matching writes.
+                */
+@@ -535,9 +535,11 @@ static int flakey_map(struct dm_target *ti, struct bio *bio)
+                       struct bio *clone = clone_bio(ti, fc, bio);
+                       if (clone) {
+                               if (corrupt_fixed)
+-                                      corrupt_bio_data(clone, fc);
++                                      corrupt_bio_data(clone, fc,
++                                                       clone->bi_iter);
+                               if (corrupt_random)
+-                                      corrupt_bio_random(clone);
++                                      corrupt_bio_random(clone,
++                                                         clone->bi_iter);
+                               submit_bio(clone);
+                               return DM_MAPIO_SUBMITTED;
+                       }
+@@ -559,21 +561,21 @@ static int flakey_end_io(struct dm_target *ti, struct bio *bio,
+       if (op_is_zone_mgmt(bio_op(bio)))
+               return DM_ENDIO_DONE;
+-      if (!*error && pb->bio_submitted && (bio_data_dir(bio) == READ)) {
++      if (!*error && pb->bio_can_corrupt && (bio_data_dir(bio) == READ)) {
+               if (fc->corrupt_bio_byte) {
+                       if ((fc->corrupt_bio_rw == READ) &&
+                           all_corrupt_bio_flags_match(bio, fc)) {
+                               /*
+                                * Corrupt successful matching READs while in down state.
+                                */
+-                              corrupt_bio_data(bio, fc);
++                              corrupt_bio_data(bio, fc, pb->saved_iter);
+                       }
+               }
+               if (fc->random_read_corrupt) {
+                       u64 rnd = get_random_u64();
+                       u32 rem = do_div(rnd, PROBABILITY_BASE);
+                       if (rem < fc->random_read_corrupt)
+-                              corrupt_bio_random(bio);
++                              corrupt_bio_random(bio, pb->saved_iter);
+               }
+               if (test_bit(ERROR_READS, &fc->flags)) {
+                       /*
+-- 
+2.39.5
+
diff --git a/queue-6.15/dm-free-table-mempools-if-not-used-in-__bind.patch b/queue-6.15/dm-free-table-mempools-if-not-used-in-__bind.patch
new file mode 100644 (file)
index 0000000..fb4cace
--- /dev/null
@@ -0,0 +1,54 @@
+From 85094613f59ba4cb44966df5bddadaad33db2b09 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Apr 2025 15:49:39 -0400
+Subject: dm: free table mempools if not used in __bind
+
+From: Benjamin Marzinski <bmarzins@redhat.com>
+
+[ Upstream commit e8819e7f03470c5b468720630d9e4e1d5b99159e ]
+
+With request-based dm, the mempools don't need reloading when switching
+tables, but the unused table mempools are not freed until the active
+table is finally freed. Free them immediately if they are not needed.
+
+Fixes: 29dec90a0f1d9 ("dm: fix bio_set allocation")
+Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
+Tested-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/md/dm.c b/drivers/md/dm.c
+index f5c5ccb6f8d25..292414da871da 100644
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -2461,10 +2461,10 @@ static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t,
+                * requests in the queue may refer to bio from the old bioset,
+                * so you must walk through the queue to unprep.
+                */
+-              if (!md->mempools) {
++              if (!md->mempools)
+                       md->mempools = t->mempools;
+-                      t->mempools = NULL;
+-              }
++              else
++                      dm_free_md_mempools(t->mempools);
+       } else {
+               /*
+                * The md may already have mempools that need changing.
+@@ -2473,8 +2473,8 @@ static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t,
+                */
+               dm_free_md_mempools(md->mempools);
+               md->mempools = t->mempools;
+-              t->mempools = NULL;
+       }
++      t->mempools = NULL;
+       old_map = rcu_dereference_protected(md->map, lockdep_is_held(&md->suspend_lock));
+       rcu_assign_pointer(md->map, (void *)t);
+-- 
+2.39.5
+
diff --git a/queue-6.15/dm-handle-failures-in-dm_table_set_restrictions.patch b/queue-6.15/dm-handle-failures-in-dm_table_set_restrictions.patch
new file mode 100644 (file)
index 0000000..07cd59b
--- /dev/null
@@ -0,0 +1,163 @@
+From 1252450ca0c297d6d6289384e2df076e10808d35 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Apr 2025 15:49:40 -0400
+Subject: dm: handle failures in dm_table_set_restrictions
+
+From: Benjamin Marzinski <bmarzins@redhat.com>
+
+[ Upstream commit 4ea30ec6fb3bb598bd1df04cdfab13b1140074d2 ]
+
+If dm_table_set_restrictions() fails while swapping tables,
+device-mapper will continue using the previous table. It must be sure to
+leave the mapped_device in it's previous state on failure.  Otherwise
+device-mapper could end up using the old table with settings from the
+unused table.
+
+Do not update the mapped device in dm_set_zones_restrictions(). Wait
+till after dm_table_set_restrictions() is sure to succeed to update the
+md zoned settings. Do the same with the dax settings, and if
+dm_revalidate_zones() fails, restore the original queue limits.
+
+Fixes: 7f91ccd8a608d ("dm: Call dm_revalidate_zones() after setting the queue limits")
+Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
+Tested-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm-table.c | 26 +++++++++++++++++---------
+ drivers/md/dm-zone.c  | 26 ++++++++++++++++++--------
+ drivers/md/dm.h       |  1 +
+ 3 files changed, 36 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
+index 6b23e777e10e7..9cf82e0513c16 100644
+--- a/drivers/md/dm-table.c
++++ b/drivers/md/dm-table.c
+@@ -1834,6 +1834,7 @@ int dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
+                             struct queue_limits *limits)
+ {
+       int r;
++      struct queue_limits old_limits;
+       if (!dm_table_supports_nowait(t))
+               limits->features &= ~BLK_FEAT_NOWAIT;
+@@ -1860,16 +1861,11 @@ int dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
+       if (dm_table_supports_flush(t))
+               limits->features |= BLK_FEAT_WRITE_CACHE | BLK_FEAT_FUA;
+-      if (dm_table_supports_dax(t, device_not_dax_capable)) {
++      if (dm_table_supports_dax(t, device_not_dax_capable))
+               limits->features |= BLK_FEAT_DAX;
+-              if (dm_table_supports_dax(t, device_not_dax_synchronous_capable))
+-                      set_dax_synchronous(t->md->dax_dev);
+-      } else
++      else
+               limits->features &= ~BLK_FEAT_DAX;
+-      if (dm_table_any_dev_attr(t, device_dax_write_cache_enabled, NULL))
+-              dax_write_cache(t->md->dax_dev, true);
+-
+       /* For a zoned table, setup the zone related queue attributes. */
+       if (IS_ENABLED(CONFIG_BLK_DEV_ZONED) &&
+           (limits->features & BLK_FEAT_ZONED)) {
+@@ -1881,7 +1877,8 @@ int dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
+       if (dm_table_supports_atomic_writes(t))
+               limits->features |= BLK_FEAT_ATOMIC_WRITES;
+-      r = queue_limits_set(q, limits);
++      old_limits = queue_limits_start_update(q);
++      r = queue_limits_commit_update(q, limits);
+       if (r)
+               return r;
+@@ -1892,10 +1889,21 @@ int dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
+       if (IS_ENABLED(CONFIG_BLK_DEV_ZONED) &&
+           (limits->features & BLK_FEAT_ZONED)) {
+               r = dm_revalidate_zones(t, q);
+-              if (r)
++              if (r) {
++                      queue_limits_set(q, &old_limits);
+                       return r;
++              }
+       }
++      if (IS_ENABLED(CONFIG_BLK_DEV_ZONED))
++              dm_finalize_zone_settings(t, limits);
++
++      if (dm_table_supports_dax(t, device_not_dax_synchronous_capable))
++              set_dax_synchronous(t->md->dax_dev);
++
++      if (dm_table_any_dev_attr(t, device_dax_write_cache_enabled, NULL))
++              dax_write_cache(t->md->dax_dev, true);
++
+       dm_update_crypto_profile(q, t);
+       return 0;
+ }
+diff --git a/drivers/md/dm-zone.c b/drivers/md/dm-zone.c
+index 20edd3fabbabf..681058feb63b5 100644
+--- a/drivers/md/dm-zone.c
++++ b/drivers/md/dm-zone.c
+@@ -340,12 +340,8 @@ int dm_set_zones_restrictions(struct dm_table *t, struct request_queue *q,
+        * mapped device queue as needing zone append emulation.
+        */
+       WARN_ON_ONCE(queue_is_mq(q));
+-      if (dm_table_supports_zone_append(t)) {
+-              clear_bit(DMF_EMULATE_ZONE_APPEND, &md->flags);
+-      } else {
+-              set_bit(DMF_EMULATE_ZONE_APPEND, &md->flags);
++      if (!dm_table_supports_zone_append(t))
+               lim->max_hw_zone_append_sectors = 0;
+-      }
+       /*
+        * Determine the max open and max active zone limits for the mapped
+@@ -383,9 +379,6 @@ int dm_set_zones_restrictions(struct dm_table *t, struct request_queue *q,
+               lim->zone_write_granularity = 0;
+               lim->chunk_sectors = 0;
+               lim->features &= ~BLK_FEAT_ZONED;
+-              clear_bit(DMF_EMULATE_ZONE_APPEND, &md->flags);
+-              md->nr_zones = 0;
+-              disk->nr_zones = 0;
+               return 0;
+       }
+@@ -408,6 +401,23 @@ int dm_set_zones_restrictions(struct dm_table *t, struct request_queue *q,
+       return 0;
+ }
++void dm_finalize_zone_settings(struct dm_table *t, struct queue_limits *lim)
++{
++      struct mapped_device *md = t->md;
++
++      if (lim->features & BLK_FEAT_ZONED) {
++              if (dm_table_supports_zone_append(t))
++                      clear_bit(DMF_EMULATE_ZONE_APPEND, &md->flags);
++              else
++                      set_bit(DMF_EMULATE_ZONE_APPEND, &md->flags);
++      } else {
++              clear_bit(DMF_EMULATE_ZONE_APPEND, &md->flags);
++              md->nr_zones = 0;
++              md->disk->nr_zones = 0;
++      }
++}
++
++
+ /*
+  * IO completion callback called from clone_endio().
+  */
+diff --git a/drivers/md/dm.h b/drivers/md/dm.h
+index a0a8ff1198158..e5d3a9f46a912 100644
+--- a/drivers/md/dm.h
++++ b/drivers/md/dm.h
+@@ -102,6 +102,7 @@ int dm_setup_md_queue(struct mapped_device *md, struct dm_table *t);
+ int dm_set_zones_restrictions(struct dm_table *t, struct request_queue *q,
+               struct queue_limits *lim);
+ int dm_revalidate_zones(struct dm_table *t, struct request_queue *q);
++void dm_finalize_zone_settings(struct dm_table *t, struct queue_limits *lim);
+ void dm_zone_endio(struct dm_io *io, struct bio *clone);
+ #ifdef CONFIG_BLK_DEV_ZONED
+ int dm_blk_report_zones(struct gendisk *disk, sector_t sector,
+-- 
+2.39.5
+
diff --git a/queue-6.15/dm-limit-swapping-tables-for-devices-with-zone-write.patch b/queue-6.15/dm-limit-swapping-tables-for-devices-with-zone-write.patch
new file mode 100644 (file)
index 0000000..4d4a977
--- /dev/null
@@ -0,0 +1,242 @@
+From 4fb763300584562dbfb3fab730155ee50a53d6e4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Apr 2025 15:49:42 -0400
+Subject: dm: limit swapping tables for devices with zone write plugs
+
+From: Benjamin Marzinski <bmarzins@redhat.com>
+
+[ Upstream commit 121218bef4c1df165181f5cd8fc3a2246bac817e ]
+
+dm_revalidate_zones() only allowed new or previously unzoned devices to
+call blk_revalidate_disk_zones(). If the device was already zoned,
+disk->nr_zones would always equal md->nr_zones, so dm_revalidate_zones()
+returned without doing any work. This would make the zoned settings for
+the device not match the new table. If the device had zone write plug
+resources, it could run into errors like bdev_zone_is_seq() reading
+invalid memory because disk->conv_zones_bitmap was the wrong size.
+
+If the device doesn't have any zone write plug resources, calling
+blk_revalidate_disk_zones() will always correctly update device.  If
+blk_revalidate_disk_zones() fails, it can still overwrite or clear the
+current disk->nr_zones value. In this case, DM must restore the previous
+value of disk->nr_zones, so that the zoned settings will continue to
+match the previous value that it fell back to.
+
+If the device already has zone write plug resources,
+blk_revalidate_disk_zones() will not correctly update them, if it is
+called for arbitrary zoned device changes.  Since there is not much need
+for this ability, the easiest solution is to disallow any table reloads
+that change the zoned settings, for devices that already have zone plug
+resources.  Specifically, if a device already has zone plug resources
+allocated, it can only switch to another zoned table that also emulates
+zone append.  Also, it cannot change the device size or the zone size. A
+device can switch to an error target.
+
+Fixes: bb37d77239af2 ("dm: introduce zone append emulation")
+Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
+Tested-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm-table.c | 41 ++++++++++++++++++++++++++++++++++++-----
+ drivers/md/dm-zone.c  | 35 ++++++++++++++++++++++++++---------
+ drivers/md/dm.c       |  6 ++++++
+ drivers/md/dm.h       |  5 +++++
+ 4 files changed, 73 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
+index 9cf82e0513c16..e009bba52d4c0 100644
+--- a/drivers/md/dm-table.c
++++ b/drivers/md/dm-table.c
+@@ -1490,6 +1490,18 @@ bool dm_table_has_no_data_devices(struct dm_table *t)
+       return true;
+ }
++bool dm_table_is_wildcard(struct dm_table *t)
++{
++      for (unsigned int i = 0; i < t->num_targets; i++) {
++              struct dm_target *ti = dm_table_get_target(t, i);
++
++              if (!dm_target_is_wildcard(ti->type))
++                      return false;
++      }
++
++      return true;
++}
++
+ static int device_not_zoned(struct dm_target *ti, struct dm_dev *dev,
+                           sector_t start, sector_t len, void *data)
+ {
+@@ -1830,6 +1842,19 @@ static bool dm_table_supports_atomic_writes(struct dm_table *t)
+       return true;
+ }
++bool dm_table_supports_size_change(struct dm_table *t, sector_t old_size,
++                                 sector_t new_size)
++{
++      if (IS_ENABLED(CONFIG_BLK_DEV_ZONED) && dm_has_zone_plugs(t->md) &&
++          old_size != new_size) {
++              DMWARN("%s: device has zone write plug resources. "
++                     "Cannot change size",
++                     dm_device_name(t->md));
++              return false;
++      }
++      return true;
++}
++
+ int dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
+                             struct queue_limits *limits)
+ {
+@@ -1867,11 +1892,17 @@ int dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
+               limits->features &= ~BLK_FEAT_DAX;
+       /* For a zoned table, setup the zone related queue attributes. */
+-      if (IS_ENABLED(CONFIG_BLK_DEV_ZONED) &&
+-          (limits->features & BLK_FEAT_ZONED)) {
+-              r = dm_set_zones_restrictions(t, q, limits);
+-              if (r)
+-                      return r;
++      if (IS_ENABLED(CONFIG_BLK_DEV_ZONED)) {
++              if (limits->features & BLK_FEAT_ZONED) {
++                      r = dm_set_zones_restrictions(t, q, limits);
++                      if (r)
++                              return r;
++              } else if (dm_has_zone_plugs(t->md)) {
++                      DMWARN("%s: device has zone write plug resources. "
++                             "Cannot switch to non-zoned table.",
++                             dm_device_name(t->md));
++                      return -EINVAL;
++              }
+       }
+       if (dm_table_supports_atomic_writes(t))
+diff --git a/drivers/md/dm-zone.c b/drivers/md/dm-zone.c
+index ff9a1a94eea96..4af78111d0b4d 100644
+--- a/drivers/md/dm-zone.c
++++ b/drivers/md/dm-zone.c
+@@ -160,22 +160,22 @@ int dm_revalidate_zones(struct dm_table *t, struct request_queue *q)
+ {
+       struct mapped_device *md = t->md;
+       struct gendisk *disk = md->disk;
++      unsigned int nr_zones = disk->nr_zones;
+       int ret;
+       if (!get_capacity(disk))
+               return 0;
+-      /* Revalidate only if something changed. */
+-      if (!disk->nr_zones || disk->nr_zones != md->nr_zones) {
+-              DMINFO("%s using %s zone append",
+-                     disk->disk_name,
+-                     queue_emulates_zone_append(q) ? "emulated" : "native");
+-              md->nr_zones = 0;
+-      }
+-
+-      if (md->nr_zones)
++      /*
++       * Do not revalidate if zone write plug resources have already
++       * been allocated.
++       */
++      if (dm_has_zone_plugs(md))
+               return 0;
++      DMINFO("%s using %s zone append", disk->disk_name,
++             queue_emulates_zone_append(q) ? "emulated" : "native");
++
+       /*
+        * Our table is not live yet. So the call to dm_get_live_table()
+        * in dm_blk_report_zones() will fail. Set a temporary pointer to
+@@ -189,6 +189,7 @@ int dm_revalidate_zones(struct dm_table *t, struct request_queue *q)
+       if (ret) {
+               DMERR("Revalidate zones failed %d", ret);
++              disk->nr_zones = nr_zones;
+               return ret;
+       }
+@@ -385,12 +386,28 @@ int dm_set_zones_restrictions(struct dm_table *t, struct request_queue *q,
+               lim->max_open_zones = 0;
+               lim->max_active_zones = 0;
+               lim->max_hw_zone_append_sectors = 0;
++              lim->max_zone_append_sectors = 0;
+               lim->zone_write_granularity = 0;
+               lim->chunk_sectors = 0;
+               lim->features &= ~BLK_FEAT_ZONED;
+               return 0;
+       }
++      if (get_capacity(disk) && dm_has_zone_plugs(t->md)) {
++              if (q->limits.chunk_sectors != lim->chunk_sectors) {
++                      DMWARN("%s: device has zone write plug resources. "
++                             "Cannot change zone size",
++                             disk->disk_name);
++                      return -EINVAL;
++              }
++              if (lim->max_hw_zone_append_sectors != 0 &&
++                  !dm_table_is_wildcard(t)) {
++                      DMWARN("%s: device has zone write plug resources. "
++                             "New table must emulate zone append",
++                             disk->disk_name);
++                      return -EINVAL;
++              }
++      }
+       /*
+        * Warn once (when the capacity is not yet set) if the mapped device is
+        * partially using zone resources of the target devices as that leads to
+diff --git a/drivers/md/dm.c b/drivers/md/dm.c
+index 292414da871da..240f6dab8ddaf 100644
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -2429,6 +2429,12 @@ static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t,
+       size = dm_table_get_size(t);
+       old_size = dm_get_size(md);
++
++      if (!dm_table_supports_size_change(t, old_size, size)) {
++              old_map = ERR_PTR(-EINVAL);
++              goto out;
++      }
++
+       set_capacity(md->disk, size);
+       ret = dm_table_set_restrictions(t, md->queue, limits);
+diff --git a/drivers/md/dm.h b/drivers/md/dm.h
+index e5d3a9f46a912..245f52b592154 100644
+--- a/drivers/md/dm.h
++++ b/drivers/md/dm.h
+@@ -58,6 +58,7 @@ void dm_table_event_callback(struct dm_table *t,
+                            void (*fn)(void *), void *context);
+ struct dm_target *dm_table_find_target(struct dm_table *t, sector_t sector);
+ bool dm_table_has_no_data_devices(struct dm_table *table);
++bool dm_table_is_wildcard(struct dm_table *t);
+ int dm_calculate_queue_limits(struct dm_table *table,
+                             struct queue_limits *limits);
+ int dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
+@@ -72,6 +73,8 @@ struct target_type *dm_table_get_immutable_target_type(struct dm_table *t);
+ struct dm_target *dm_table_get_immutable_target(struct dm_table *t);
+ struct dm_target *dm_table_get_wildcard_target(struct dm_table *t);
+ bool dm_table_request_based(struct dm_table *t);
++bool dm_table_supports_size_change(struct dm_table *t, sector_t old_size,
++                                 sector_t new_size);
+ void dm_lock_md_type(struct mapped_device *md);
+ void dm_unlock_md_type(struct mapped_device *md);
+@@ -111,12 +114,14 @@ bool dm_is_zone_write(struct mapped_device *md, struct bio *bio);
+ int dm_zone_get_reset_bitmap(struct mapped_device *md, struct dm_table *t,
+                            sector_t sector, unsigned int nr_zones,
+                            unsigned long *need_reset);
++#define dm_has_zone_plugs(md) ((md)->disk->zone_wplugs_hash != NULL)
+ #else
+ #define dm_blk_report_zones   NULL
+ static inline bool dm_is_zone_write(struct mapped_device *md, struct bio *bio)
+ {
+       return false;
+ }
++#define dm_has_zone_plugs(md) false
+ #endif
+ /*
+-- 
+2.39.5
+
diff --git a/queue-6.15/dmaengine-ti-add-null-check-in-udma_probe.patch b/queue-6.15/dmaengine-ti-add-null-check-in-udma_probe.patch
new file mode 100644 (file)
index 0000000..ffca0a1
--- /dev/null
@@ -0,0 +1,43 @@
+From c1b4a34fd024c54b02b2668ebfe4c59346f9593b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Apr 2025 10:39:00 +0800
+Subject: dmaengine: ti: Add NULL check in udma_probe()
+
+From: Henry Martin <bsdhenrymartin@gmail.com>
+
+[ Upstream commit fd447415e74bccd7362f760d4ea727f8e1ebfe91 ]
+
+devm_kasprintf() returns NULL when memory allocation fails. Currently,
+udma_probe() does not check for this case, which results in a NULL
+pointer dereference.
+
+Add NULL check after devm_kasprintf() to prevent this issue.
+
+Fixes: 25dcb5dd7b7c ("dmaengine: ti: New driver for K3 UDMA")
+Signed-off-by: Henry Martin <bsdhenrymartin@gmail.com>
+Reviewed-by: Nathan Lynch <nathan.lynch@amd.com>
+Acked-by: Peter Ujfalusi <peter.ujfalusi@gmail.com>
+Link: https://lore.kernel.org/r/20250402023900.43440-1-bsdhenrymartin@gmail.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/ti/k3-udma.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c
+index b6255c0601bb2..aa2dc762140f6 100644
+--- a/drivers/dma/ti/k3-udma.c
++++ b/drivers/dma/ti/k3-udma.c
+@@ -5624,7 +5624,8 @@ static int udma_probe(struct platform_device *pdev)
+               uc->config.dir = DMA_MEM_TO_MEM;
+               uc->name = devm_kasprintf(dev, GFP_KERNEL, "%s chan%d",
+                                         dev_name(dev), i);
+-
++              if (!uc->name)
++                      return -ENOMEM;
+               vchan_init(&uc->vc, &ud->ddev);
+               /* Use custom vchan completion handling */
+               tasklet_setup(&uc->vc.task, udma_vchan_complete);
+-- 
+2.39.5
+
diff --git a/queue-6.15/do_change_type-refuse-to-operate-on-unmounted-not-ou.patch b/queue-6.15/do_change_type-refuse-to-operate-on-unmounted-not-ou.patch
new file mode 100644 (file)
index 0000000..3455f10
--- /dev/null
@@ -0,0 +1,40 @@
+From 06dd45df8f1824fae785dbf048a804c1fa5703b8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Jun 2025 12:27:08 -0400
+Subject: do_change_type(): refuse to operate on unmounted/not ours mounts
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+[ Upstream commit 12f147ddd6de7382dad54812e65f3f08d05809fc ]
+
+Ensure that propagation settings can only be changed for mounts located
+in the caller's mount namespace. This change aligns permission checking
+with the rest of mount(2).
+
+Reviewed-by: Christian Brauner <brauner@kernel.org>
+Fixes: 07b20889e305 ("beginning of the shared-subtree proper")
+Reported-by: "Orlando, Noah" <Noah.Orlando@deshaw.com>
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/namespace.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/fs/namespace.c b/fs/namespace.c
+index 163ffdc042284..2de4b7ad1dc5d 100644
+--- a/fs/namespace.c
++++ b/fs/namespace.c
+@@ -2958,6 +2958,10 @@ static int do_change_type(struct path *path, int ms_flags)
+               return -EINVAL;
+       namespace_lock();
++      if (!check_mnt(mnt)) {
++              err = -EINVAL;
++              goto out_unlock;
++      }
+       if (type == MS_SHARED) {
+               err = invent_group_ids(mnt, recurse);
+               if (err)
+-- 
+2.39.5
+
diff --git a/queue-6.15/driver-net-ethernet-mtk_star_emac-fix-suspend-resume.patch b/queue-6.15/driver-net-ethernet-mtk_star_emac-fix-suspend-resume.patch
new file mode 100644 (file)
index 0000000..af883b0
--- /dev/null
@@ -0,0 +1,53 @@
+From b7bf88f239992879b3eb3c8fb15d22e035ce37c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 May 2025 15:53:51 +0800
+Subject: driver: net: ethernet: mtk_star_emac: fix suspend/resume issue
+
+From: Yanqing Wang <ot_yanqing.wang@mediatek.com>
+
+[ Upstream commit ba99c627aac85bc746fb4a6e2d79edb3ad100326 ]
+
+Identify the cause of the suspend/resume hang: netif_carrier_off()
+is called during link state changes and becomes stuck while
+executing linkwatch_work().
+
+To resolve this issue, call netif_device_detach() during the Ethernet
+suspend process to temporarily detach the network device from the
+kernel and prevent the suspend/resume hang.
+
+Fixes: 8c7bd5a454ff ("net: ethernet: mtk-star-emac: new driver")
+Signed-off-by: Yanqing Wang <ot_yanqing.wang@mediatek.com>
+Signed-off-by: Macpaul Lin <macpaul.lin@mediatek.com>
+Signed-off-by: Biao Huang <biao.huang@mediatek.com>
+Link: https://patch.msgid.link/20250528075351.593068-1-macpaul.lin@mediatek.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_star_emac.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
+index b175119a6a7da..b83886a411210 100644
+--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
++++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
+@@ -1463,6 +1463,8 @@ static __maybe_unused int mtk_star_suspend(struct device *dev)
+       if (netif_running(ndev))
+               mtk_star_disable(ndev);
++      netif_device_detach(ndev);
++
+       clk_bulk_disable_unprepare(MTK_STAR_NCLKS, priv->clks);
+       return 0;
+@@ -1487,6 +1489,8 @@ static __maybe_unused int mtk_star_resume(struct device *dev)
+                       clk_bulk_disable_unprepare(MTK_STAR_NCLKS, priv->clks);
+       }
++      netif_device_attach(ndev);
++
+       return ret;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/drivers-hv-always-select-config_sysfb-for-hyper-v-gu.patch b/queue-6.15/drivers-hv-always-select-config_sysfb-for-hyper-v-gu.patch
new file mode 100644 (file)
index 0000000..dddbf18
--- /dev/null
@@ -0,0 +1,74 @@
+From 9766859ee9884c35dde0411df167a06452fee3ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 May 2025 21:01:43 -0700
+Subject: Drivers: hv: Always select CONFIG_SYSFB for Hyper-V guests
+
+From: Michael Kelley <mhklinux@outlook.com>
+
+[ Upstream commit 96959283a58d91ae20d025546f00e16f0a555208 ]
+
+The Hyper-V host provides guest VMs with a range of MMIO addresses
+that guest VMBus drivers can use. The VMBus driver in Linux manages
+that MMIO space, and allocates portions to drivers upon request. As
+part of managing that MMIO space in a Generation 2 VM, the VMBus
+driver must reserve the portion of the MMIO space that Hyper-V has
+designated for the synthetic frame buffer, and not allocate this
+space to VMBus drivers other than graphics framebuffer drivers. The
+synthetic frame buffer MMIO area is described by the screen_info data
+structure that is passed to the Linux kernel at boot time, so the
+VMBus driver must access screen_info for Generation 2 VMs. (In
+Generation 1 VMs, the framebuffer MMIO space is communicated to
+the guest via a PCI pseudo-device, and access to screen_info is
+not needed.)
+
+In commit a07b50d80ab6 ("hyperv: avoid dependency on screen_info")
+the VMBus driver's access to screen_info is restricted to when
+CONFIG_SYSFB is enabled. CONFIG_SYSFB is typically enabled in kernels
+built for Hyper-V by virtue of having at least one of CONFIG_FB_EFI,
+CONFIG_FB_VESA, or CONFIG_SYSFB_SIMPLEFB enabled, so the restriction
+doesn't usually affect anything. But it's valid to have none of these
+enabled, in which case CONFIG_SYSFB is not enabled, and the VMBus driver
+is unable to properly reserve the framebuffer MMIO space for graphics
+framebuffer drivers. The framebuffer MMIO space may be assigned to
+some other VMBus driver, with undefined results. As an example, if
+a VM is using a PCI pass-thru NVMe controller to host the OS disk,
+the PCI NVMe controller is probed before any graphics devices, and the
+NVMe controller is assigned a portion of the framebuffer MMIO space.
+Hyper-V reports an error to Linux during the probe, and the OS disk
+fails to get setup. Then Linux fails to boot in the VM.
+
+Fix this by having CONFIG_HYPERV always select SYSFB. Then the
+VMBus driver in a Gen 2 VM can always reserve the MMIO space for the
+graphics framebuffer driver, and prevent the undefined behavior. But
+don't select SYSFB when building for HYPERV_VTL_MODE as VTLs other
+than VTL 0 don't have a framebuffer and aren't subject to the issue.
+Adding SYSFB in such cases is harmless, but would increase the image
+size for no purpose.
+
+Fixes: a07b50d80ab6 ("hyperv: avoid dependency on screen_info")
+Signed-off-by: Michael Kelley <mhklinux@outlook.com>
+Reviewed-by: Saurabh Sengar <ssengar@linux.microsoft.com>
+Link: https://lore.kernel.org/stable/20250520040143.6964-1-mhklinux%40outlook.com
+Link: https://lore.kernel.org/r/20250520040143.6964-1-mhklinux@outlook.com
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Message-ID: <20250520040143.6964-1-mhklinux@outlook.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hv/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
+index 6c1416167bd2e..724fc08a73e70 100644
+--- a/drivers/hv/Kconfig
++++ b/drivers/hv/Kconfig
+@@ -9,6 +9,7 @@ config HYPERV
+       select PARAVIRT
+       select X86_HV_CALLBACK_VECTOR if X86
+       select OF_EARLY_FLATTREE if OF
++      select SYSFB if !HYPERV_VTL_MODE
+       help
+         Select this option to run Linux as a Hyper-V client operating
+         system.
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-amd-display-don-t-check-for-null-divisor-in-fixp.patch b/queue-6.15/drm-amd-display-don-t-check-for-null-divisor-in-fixp.patch
new file mode 100644 (file)
index 0000000..88b1348
--- /dev/null
@@ -0,0 +1,81 @@
+From f7f012e6b95d327b03ed1f636550cdce497e08c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Apr 2025 16:26:20 -0400
+Subject: drm/amd/display: Don't check for NULL divisor in fixpt code
+
+From: Harry Wentland <harry.wentland@amd.com>
+
+[ Upstream commit d01ca8708d95a561f6462a15cad94a2c0bec7042 ]
+
+[Why]
+We check for a NULL divisor but don't act on it.
+This check does nothing other than throw a warning.
+It does confuse static checkers though:
+See https://lkml.org/lkml/2025/4/26/371
+
+[How]
+Drop the ASSERTs in both DC and SPL variants.
+
+Fixes: 4562236b3bc0 ("drm/amd/dc: Add dc display driver (v2)")
+Fixes: 6efc0ab3b05d ("drm/amd/display: add back quality EASF and ISHARP and dc dependency changes")
+Signed-off-by: Harry Wentland <harry.wentland@amd.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Leo Li <sunpeng.li@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Acked-by: Alex Deucher <alexander.deucher@amd.com>
+Reviewed-by: Alex Hung <alex.hung@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c   | 5 -----
+ drivers/gpu/drm/amd/display/dc/sspl/spl_fixpt31_32.c | 4 ----
+ 2 files changed, 9 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c b/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c
+index 88d3f9d7dd556..452206b5095eb 100644
+--- a/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c
++++ b/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c
+@@ -51,8 +51,6 @@ static inline unsigned long long complete_integer_division_u64(
+ {
+       unsigned long long result;
+-      ASSERT(divisor);
+-
+       result = div64_u64_rem(dividend, divisor, remainder);
+       return result;
+@@ -213,9 +211,6 @@ struct fixed31_32 dc_fixpt_recip(struct fixed31_32 arg)
+        * @note
+        * Good idea to use Newton's method
+        */
+-
+-      ASSERT(arg.value);
+-
+       return dc_fixpt_from_fraction(
+               dc_fixpt_one.value,
+               arg.value);
+diff --git a/drivers/gpu/drm/amd/display/dc/sspl/spl_fixpt31_32.c b/drivers/gpu/drm/amd/display/dc/sspl/spl_fixpt31_32.c
+index 52d97918a3bd2..ebf0287417e0e 100644
+--- a/drivers/gpu/drm/amd/display/dc/sspl/spl_fixpt31_32.c
++++ b/drivers/gpu/drm/amd/display/dc/sspl/spl_fixpt31_32.c
+@@ -29,8 +29,6 @@ static inline unsigned long long spl_complete_integer_division_u64(
+ {
+       unsigned long long result;
+-      SPL_ASSERT(divisor);
+-
+       result = spl_div64_u64_rem(dividend, divisor, remainder);
+       return result;
+@@ -196,8 +194,6 @@ struct spl_fixed31_32 spl_fixpt_recip(struct spl_fixed31_32 arg)
+        * Good idea to use Newton's method
+        */
+-      SPL_ASSERT(arg.value);
+-
+       return spl_fixpt_from_fraction(
+               spl_fixpt_one.value,
+               arg.value);
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-amd-pp-fix-potential-null-pointer-dereference-in.patch b/queue-6.15/drm-amd-pp-fix-potential-null-pointer-dereference-in.patch
new file mode 100644 (file)
index 0000000..075220e
--- /dev/null
@@ -0,0 +1,54 @@
+From 443bfffba78d4685b4adef4f9ce283aa7138ebaf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Mar 2025 12:04:35 +0800
+Subject: drm/amd/pp: Fix potential NULL pointer dereference in
+ atomctrl_initialize_mc_reg_table
+
+From: Charles Han <hanchunchao@inspur.com>
+
+[ Upstream commit 820116a39f96bdc7d426c33a804b52f53700a919 ]
+
+The function atomctrl_initialize_mc_reg_table() and
+atomctrl_initialize_mc_reg_table_v2_2() does not check the return
+value of smu_atom_get_data_table(). If smu_atom_get_data_table()
+fails to retrieve vram_info, it returns NULL which is later
+dereferenced.
+
+Fixes: b3892e2bb519 ("drm/amd/pp: Use atombios api directly in powerplay (v2)")
+Fixes: 5f92b48cf62c ("drm/amd/pm: add mc register table initialization")
+Signed-off-by: Charles Han <hanchunchao@inspur.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c
+index 4bd92fd782be6..8d40ed0f0e838 100644
+--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c
++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c
+@@ -143,6 +143,10 @@ int atomctrl_initialize_mc_reg_table(
+       vram_info = (ATOM_VRAM_INFO_HEADER_V2_1 *)
+               smu_atom_get_data_table(hwmgr->adev,
+                               GetIndexIntoMasterTable(DATA, VRAM_Info), &size, &frev, &crev);
++      if (!vram_info) {
++              pr_err("Could not retrieve the VramInfo table!");
++              return -EINVAL;
++      }
+       if (module_index >= vram_info->ucNumOfVRAMModule) {
+               pr_err("Invalid VramInfo table.");
+@@ -180,6 +184,10 @@ int atomctrl_initialize_mc_reg_table_v2_2(
+       vram_info = (ATOM_VRAM_INFO_HEADER_V2_2 *)
+               smu_atom_get_data_table(hwmgr->adev,
+                               GetIndexIntoMasterTable(DATA, VRAM_Info), &size, &frev, &crev);
++      if (!vram_info) {
++              pr_err("Could not retrieve the VramInfo table!");
++              return -EINVAL;
++      }
+       if (module_index >= vram_info->ucNumOfVRAMModule) {
+               pr_err("Invalid VramInfo table.");
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-amdgpu-gfx10-refine-cleaner-shader-for-gfx10.1.1.patch b/queue-6.15/drm-amdgpu-gfx10-refine-cleaner-shader-for-gfx10.1.1.patch
new file mode 100644 (file)
index 0000000..117ff8a
--- /dev/null
@@ -0,0 +1,95 @@
+From 6b753021c257e71e1d67b92d82a9572ea60a8af3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 May 2025 16:45:33 -0400
+Subject: drm/amdgpu/gfx10: Refine Cleaner Shader for GFX10.1.10
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Vitaly Prosyak <vitaly.prosyak@amd.com>
+
+[ Upstream commit d26625d034fb8d596f0488472969493fa02d03f3 ]
+
+This patch updates the cleaner shader, which is responsible for
+initializing GPU resources such as Local Data Share (LDS), Vector
+General Purpose Registers (VGPRs), and Scalar General Purpose Registers
+(SGPRs). Changes include adjustments to register clearing and shader
+configuration.
+
+- Updated GPU resource initialization addresses in the cleaner shader
+  from `be803080` to `be803000`.
+- Simplified the logic in the SGPR clearing section, ensuring all SGPRs
+  are set to zero.
+
+Fixes: 25961bad9212 ("drm/amdgpu/gfx10: Add cleaner shader for GFX10.1.10")
+Cc: Christian König <christian.koenig@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Manu Rastogi <manu.rastogi@amd.com>
+Signed-off-by: Vitaly Prosyak <vitaly.prosyak@amd.com>
+Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+Acked-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/amd/amdgpu/gfx_v10_0_cleaner_shader.h   |  6 +++---
+ .../drm/amd/amdgpu/gfx_v10_1_10_cleaner_shader.asm  | 13 ++++++-------
+ 2 files changed, 9 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0_cleaner_shader.h b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0_cleaner_shader.h
+index 5255378af53c0..f67569ccf9f60 100644
+--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0_cleaner_shader.h
++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0_cleaner_shader.h
+@@ -43,9 +43,9 @@ static const u32 gfx_10_1_10_cleaner_shader_hex[] = {
+       0xd70f6a01, 0x000202ff,
+       0x00000400, 0x80828102,
+       0xbf84fff7, 0xbefc03ff,
+-      0x00000068, 0xbe803080,
+-      0xbe813080, 0xbe823080,
+-      0xbe833080, 0x80fc847c,
++      0x00000068, 0xbe803000,
++      0xbe813000, 0xbe823000,
++      0xbe833000, 0x80fc847c,
+       0xbf84fffa, 0xbeea0480,
+       0xbeec0480, 0xbeee0480,
+       0xbef00480, 0xbef20480,
+diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_1_10_cleaner_shader.asm b/drivers/gpu/drm/amd/amdgpu/gfx_v10_1_10_cleaner_shader.asm
+index 9ba3359253c95..54f7ed9e2801c 100644
+--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_1_10_cleaner_shader.asm
++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_1_10_cleaner_shader.asm
+@@ -40,7 +40,6 @@ shader main
+   type(CS)
+   wave_size(32)
+ // Note: original source code from SQ team
+-
+ //
+ // Create 32 waves in a threadgroup (CS waves)
+ // Each allocates 64 VGPRs
+@@ -71,8 +70,8 @@ label_0005:
+   s_sub_u32     s2, s2, 8
+   s_cbranch_scc0  label_0005
+   //
+-  s_mov_b32     s2, 0x80000000                     // Bit31 is first_wave
+-  s_and_b32     s2, s2, s0                                  // sgpr0 has tg_size (first_wave) term as in ucode only COMPUTE_PGM_RSRC2.tg_size_en is set
++  s_mov_b32     s2, 0x80000000                       // Bit31 is first_wave
++  s_and_b32     s2, s2, s1                           // sgpr0 has tg_size (first_wave) term as in ucode only COMPUTE_PGM_RSRC2.tg_size_en is set
+   s_cbranch_scc0  label_0023                         // Clean LDS if its first wave of ThreadGroup/WorkGroup
+   // CLEAR LDS
+   //
+@@ -99,10 +98,10 @@ label_001F:
+ label_0023:
+   s_mov_b32     m0, 0x00000068  // Loop 108/4=27 times  (loop unrolled for performance)
+ label_sgpr_loop:
+-  s_movreld_b32     s0, 0
+-  s_movreld_b32     s1, 0
+-  s_movreld_b32     s2, 0
+-  s_movreld_b32     s3, 0
++  s_movreld_b32     s0, s0
++  s_movreld_b32     s1, s0
++  s_movreld_b32     s2, s0
++  s_movreld_b32     s3, s0
+   s_sub_u32         m0, m0, 4
+   s_cbranch_scc0  label_sgpr_loop
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-amdgpu-refine-cleaner-shader-mec-firmware-versio.patch b/queue-6.15/drm-amdgpu-refine-cleaner-shader-mec-firmware-versio.patch
new file mode 100644 (file)
index 0000000..38d7d7e
--- /dev/null
@@ -0,0 +1,47 @@
+From 36858bc7eb9f38f2c18b5d7180c038559d8169ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Apr 2025 21:05:35 +0530
+Subject: drm/amdgpu: Refine Cleaner Shader MEC firmware version for GFX10.1.x
+ GPUs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+
+[ Upstream commit d30f61076268fd7ce01e4ec9e4d84bfaf90365f7 ]
+
+Update the minimum firmware version for the Cleaner Shader in the
+gfx_v10_0_sw_init function.
+
+This change adjusts the minimum required firmware version for the MEC
+firmware from 152 to 151, allowing for broader compatibility with
+GFX10.1 GPUs.
+
+Fixes: 25961bad9212 ("drm/amdgpu/gfx10: Add cleaner shader for GFX10.1.10")
+Cc: Christian König <christian.koenig@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+Acked-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+index 23e6a05359c24..c68c2e2f4d61a 100644
+--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+@@ -4800,7 +4800,7 @@ static int gfx_v10_0_sw_init(struct amdgpu_ip_block *ip_block)
+               adev->gfx.cleaner_shader_size = sizeof(gfx_10_1_10_cleaner_shader_hex);
+               if (adev->gfx.me_fw_version >= 101 &&
+                   adev->gfx.pfp_fw_version  >= 158 &&
+-                  adev->gfx.mec_fw_version >= 152) {
++                  adev->gfx.mec_fw_version >= 151) {
+                       adev->gfx.enable_cleaner_shader = true;
+                       r = amdgpu_gfx_cleaner_shader_sw_init(adev, adev->gfx.cleaner_shader_size);
+                       if (r) {
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-bridge-analogix_dp-add-support-to-get-panel-from.patch b/queue-6.15/drm-bridge-analogix_dp-add-support-to-get-panel-from.patch
new file mode 100644 (file)
index 0000000..6b3a522
--- /dev/null
@@ -0,0 +1,66 @@
+From 285c65d45e799d001f3b156a928068b2cabe32a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Mar 2025 18:41:07 +0800
+Subject: drm/bridge: analogix_dp: Add support to get panel from the DP AUX bus
+
+From: Damon Ding <damon.ding@rock-chips.com>
+
+[ Upstream commit e5e9fa9f7aad4ad7eedb6359baea9193531bf4ac ]
+
+The main modification is moving the DP AUX initialization from function
+analogix_dp_bind() to analogix_dp_probe(). In order to get the EDID of
+eDP panel during probing, it is also needed to advance PM operations to
+ensure that eDP controller and phy are prepared for AUX transmission.
+
+Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Link: https://lore.kernel.org/r/20250310104114.2608063-7-damon.ding@rock-chips.com
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Stable-dep-of: fd03f82a026c ("drm/bridge: analogix_dp: Fix clk-disable removal")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../drm/bridge/analogix/analogix_dp_core.c    | 20 ++++++++++---------
+ 1 file changed, 11 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+index b7a96f5bc0074..28a5326e11b35 100644
+--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
++++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+@@ -1643,6 +1643,17 @@ analogix_dp_probe(struct device *dev, struct analogix_dp_plat_data *plat_data)
+       }
+       disable_irq(dp->irq);
++      dp->aux.name = "DP-AUX";
++      dp->aux.transfer = analogix_dpaux_transfer;
++      dp->aux.dev = dp->dev;
++      drm_dp_aux_init(&dp->aux);
++
++      pm_runtime_use_autosuspend(dp->dev);
++      pm_runtime_set_autosuspend_delay(dp->dev, 100);
++      ret = devm_pm_runtime_enable(dp->dev);
++      if (ret)
++              goto err_disable_clk;
++
+       return dp;
+ }
+ EXPORT_SYMBOL_GPL(analogix_dp_probe);
+@@ -1688,15 +1699,6 @@ int analogix_dp_bind(struct analogix_dp_device *dp, struct drm_device *drm_dev)
+       dp->drm_dev = drm_dev;
+       dp->encoder = dp->plat_data->encoder;
+-      pm_runtime_use_autosuspend(dp->dev);
+-      pm_runtime_set_autosuspend_delay(dp->dev, 100);
+-      ret = devm_pm_runtime_enable(dp->dev);
+-      if (ret)
+-              return ret;
+-
+-      dp->aux.name = "DP-AUX";
+-      dp->aux.transfer = analogix_dpaux_transfer;
+-      dp->aux.dev = dp->dev;
+       dp->aux.drm_dev = drm_dev;
+       ret = drm_dp_aux_register(&dp->aux);
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-bridge-analogix_dp-fix-clk-disable-removal.patch b/queue-6.15/drm-bridge-analogix_dp-fix-clk-disable-removal.patch
new file mode 100644 (file)
index 0000000..12257a7
--- /dev/null
@@ -0,0 +1,65 @@
+From e7ce81cc44796a503b1071113ef31f2aa3fdabdd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 May 2025 00:51:19 +0200
+Subject: drm/bridge: analogix_dp: Fix clk-disable removal
+
+From: Heiko Stuebner <heiko@sntech.de>
+
+[ Upstream commit fd03f82a026cc03cb8051a8c6487c99f96c9029f ]
+
+Commit 6579a03e68ff ("drm/bridge: analogix_dp: Remove the unnecessary
+calls to clk_disable_unprepare() during probing") removed the mismatched
+clock_disable calls from analogix_dp_probe.
+
+But that patch was created and sent before
+commit e5e9fa9f7aad ("drm/bridge: analogix_dp: Add support to get panel
+from the DP AUX bus") was merged, so couldn't know about this change.
+
+So in the original patch the last change is
+    if (ret) {
+       dev_err(&pdev->dev, "failed to request irq\n");
+-              goto err_disable_clk;
++              return ERR_PTR(ret);
+    }
+    disable_irq(dp->irq);
+
+    return dp;
+-
+-err_disable_clk:
+-      clk_disable_unprepare(dp->clock);
+-      return ERR_PTR(ret);
+ }
+ EXPORT_SYMBOL_GPL(analogix_dp_probe);
+
+the analogix_dp_core.c actually now has the runtime-pm handling between
+disable_irq() and return do introducing another goto err_clk_disable there.
+
+So remove that one too and return an error pointer, to not create build
+breakage.
+
+Fixes: 6579a03e68ff ("drm/bridge: analogix_dp: Remove the unnecessary calls to clk_disable_unprepare() during probing")
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Link: https://lore.kernel.org/r/20250527225120.3361663-1-heiko@sntech.de
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+index 28a5326e11b35..5222b1e9f533d 100644
+--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
++++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+@@ -1652,7 +1652,7 @@ analogix_dp_probe(struct device *dev, struct analogix_dp_plat_data *plat_data)
+       pm_runtime_set_autosuspend_delay(dp->dev, 100);
+       ret = devm_pm_runtime_enable(dp->dev);
+       if (ret)
+-              goto err_disable_clk;
++              return ERR_PTR(ret);
+       return dp;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-bridge-analogix_dp-remove-config_pm-related-chec.patch b/queue-6.15/drm-bridge-analogix_dp-remove-config_pm-related-chec.patch
new file mode 100644 (file)
index 0000000..fae7eec
--- /dev/null
@@ -0,0 +1,92 @@
+From 3932934a44f01fd4fc62ab31576e5174231840fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Mar 2025 18:41:03 +0800
+Subject: drm/bridge: analogix_dp: Remove CONFIG_PM related check in
+ analogix_dp_bind()/analogix_dp_unbind()
+
+From: Damon Ding <damon.ding@rock-chips.com>
+
+[ Upstream commit c71db051142a74b255cb61b84d8fedae3b70952f ]
+
+Remove the check related to CONFIG_PM in order to make the code more
+concise, as the CONFIG_PM should be a required option for many drivers.
+
+In addition, it is preferable to use devm_pm_runtime_enable() instead of
+manually invoking pm_runtime_enable() followed by pm_runtime_disable().
+
+Suggested-by: Douglas Anderson <dianders@chromium.org>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
+Link: https://lore.kernel.org/r/20250310104114.2608063-3-damon.ding@rock-chips.com
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Stable-dep-of: fd03f82a026c ("drm/bridge: analogix_dp: Fix clk-disable removal")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../drm/bridge/analogix/analogix_dp_core.c    | 30 ++++---------------
+ 1 file changed, 6 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+index 533a6e17cf674..b7a96f5bc0074 100644
+--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
++++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+@@ -1688,15 +1688,11 @@ int analogix_dp_bind(struct analogix_dp_device *dp, struct drm_device *drm_dev)
+       dp->drm_dev = drm_dev;
+       dp->encoder = dp->plat_data->encoder;
+-      if (IS_ENABLED(CONFIG_PM)) {
+-              pm_runtime_use_autosuspend(dp->dev);
+-              pm_runtime_set_autosuspend_delay(dp->dev, 100);
+-              pm_runtime_enable(dp->dev);
+-      } else {
+-              ret = analogix_dp_resume(dp);
+-              if (ret)
+-                      return ret;
+-      }
++      pm_runtime_use_autosuspend(dp->dev);
++      pm_runtime_set_autosuspend_delay(dp->dev, 100);
++      ret = devm_pm_runtime_enable(dp->dev);
++      if (ret)
++              return ret;
+       dp->aux.name = "DP-AUX";
+       dp->aux.transfer = analogix_dpaux_transfer;
+@@ -1706,7 +1702,7 @@ int analogix_dp_bind(struct analogix_dp_device *dp, struct drm_device *drm_dev)
+       ret = drm_dp_aux_register(&dp->aux);
+       if (ret) {
+               DRM_ERROR("failed to register AUX (%d)\n", ret);
+-              goto err_disable_pm_runtime;
++              return ret;
+       }
+       ret = analogix_dp_create_bridge(drm_dev, dp);
+@@ -1719,13 +1715,6 @@ int analogix_dp_bind(struct analogix_dp_device *dp, struct drm_device *drm_dev)
+ err_unregister_aux:
+       drm_dp_aux_unregister(&dp->aux);
+-err_disable_pm_runtime:
+-      if (IS_ENABLED(CONFIG_PM)) {
+-              pm_runtime_dont_use_autosuspend(dp->dev);
+-              pm_runtime_disable(dp->dev);
+-      } else {
+-              analogix_dp_suspend(dp);
+-      }
+       return ret;
+ }
+@@ -1742,13 +1731,6 @@ void analogix_dp_unbind(struct analogix_dp_device *dp)
+       }
+       drm_dp_aux_unregister(&dp->aux);
+-
+-      if (IS_ENABLED(CONFIG_PM)) {
+-              pm_runtime_dont_use_autosuspend(dp->dev);
+-              pm_runtime_disable(dp->dev);
+-      } else {
+-              analogix_dp_suspend(dp);
+-      }
+ }
+ EXPORT_SYMBOL_GPL(analogix_dp_unbind);
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-bridge-analogix_dp-remove-the-unnecessary-calls-.patch b/queue-6.15/drm-bridge-analogix_dp-remove-the-unnecessary-calls-.patch
new file mode 100644 (file)
index 0000000..d0f770b
--- /dev/null
@@ -0,0 +1,85 @@
+From a2ac0a8a5c1c9b235493e863fe0b71517fb71b49 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 2 Mar 2025 16:30:43 +0800
+Subject: drm/bridge: analogix_dp: Remove the unnecessary calls to
+ clk_disable_unprepare() during probing
+
+From: Damon Ding <damon.ding@rock-chips.com>
+
+[ Upstream commit 6579a03e68ffa5feb2d2823dea16ca7466f6de16 ]
+
+With the commit f37952339cc2 ("drm/bridge: analogix_dp: handle clock via
+runtime PM"), the PM operations can help enable/disable the clock. The
+err_disable_clk label and clk_disable_unprepare() operations are no
+longer necessary because the analogix_dp_resume() will not be called
+during probing.
+
+Fixes: f37952339cc2 ("drm/bridge: analogix_dp: handle clock via runtime PM")
+Suggested-by: Douglas Anderson <dianders@chromium.org>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
+Reviewed-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://lore.kernel.org/r/20250302083043.3197235-1-damon.ding@rock-chips.com
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/bridge/analogix/analogix_dp_core.c | 18 +++++-------------
+ 1 file changed, 5 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+index 071168aa0c3bd..533a6e17cf674 100644
+--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
++++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+@@ -1597,10 +1597,8 @@ analogix_dp_probe(struct device *dev, struct analogix_dp_plat_data *plat_data)
+       }
+       dp->reg_base = devm_platform_ioremap_resource(pdev, 0);
+-      if (IS_ERR(dp->reg_base)) {
+-              ret = PTR_ERR(dp->reg_base);
+-              goto err_disable_clk;
+-      }
++      if (IS_ERR(dp->reg_base))
++              return ERR_CAST(dp->reg_base);
+       dp->force_hpd = of_property_read_bool(dev->of_node, "force-hpd");
+@@ -1612,8 +1610,7 @@ analogix_dp_probe(struct device *dev, struct analogix_dp_plat_data *plat_data)
+       if (IS_ERR(dp->hpd_gpiod)) {
+               dev_err(dev, "error getting HDP GPIO: %ld\n",
+                       PTR_ERR(dp->hpd_gpiod));
+-              ret = PTR_ERR(dp->hpd_gpiod);
+-              goto err_disable_clk;
++              return ERR_CAST(dp->hpd_gpiod);
+       }
+       if (dp->hpd_gpiod) {
+@@ -1633,8 +1630,7 @@ analogix_dp_probe(struct device *dev, struct analogix_dp_plat_data *plat_data)
+       if (dp->irq == -ENXIO) {
+               dev_err(&pdev->dev, "failed to get irq\n");
+-              ret = -ENODEV;
+-              goto err_disable_clk;
++              return ERR_PTR(-ENODEV);
+       }
+       ret = devm_request_threaded_irq(&pdev->dev, dp->irq,
+@@ -1643,15 +1639,11 @@ analogix_dp_probe(struct device *dev, struct analogix_dp_plat_data *plat_data)
+                                       irq_flags, "analogix-dp", dp);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to request irq\n");
+-              goto err_disable_clk;
++              return ERR_PTR(ret);
+       }
+       disable_irq(dp->irq);
+       return dp;
+-
+-err_disable_clk:
+-      clk_disable_unprepare(dp->clock);
+-      return ERR_PTR(ret);
+ }
+ EXPORT_SYMBOL_GPL(analogix_dp_probe);
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-bridge-lt9611uxc-fix-an-error-handling-path-in-l.patch b/queue-6.15/drm-bridge-lt9611uxc-fix-an-error-handling-path-in-l.patch
new file mode 100644 (file)
index 0000000..7f17bea
--- /dev/null
@@ -0,0 +1,45 @@
+From 3cc7b78f2121758e1431208ababe9b48bb078877 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Apr 2025 08:48:16 +0200
+Subject: drm/bridge: lt9611uxc: Fix an error handling path in
+ lt9611uxc_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit b848cd418aebdb313364b4843f41fae82281a823 ]
+
+If lt9611uxc_audio_init() fails, some resources still need to be released
+before returning the error code.
+
+Use the existing error handling path.
+
+Fixes: 0cbbd5b1a012 ("drm: bridge: add support for lontium LT9611UXC bridge")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://lore.kernel.org/r/f167608e392c6b4d7d7f6e45e3c21878feb60cbd.1744958833.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
+index f4c3ff1fdc692..f6e714feeea54 100644
+--- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
++++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
+@@ -880,7 +880,11 @@ static int lt9611uxc_probe(struct i2c_client *client)
+               }
+       }
+-      return lt9611uxc_audio_init(dev, lt9611uxc);
++      ret = lt9611uxc_audio_init(dev, lt9611uxc);
++      if (ret)
++              goto err_remove_bridge;
++
++      return 0;
+ err_remove_bridge:
+       free_irq(client->irq, lt9611uxc);
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-ci-fix-merge-request-rules.patch b/queue-6.15/drm-ci-fix-merge-request-rules.patch
new file mode 100644 (file)
index 0000000..b127cb8
--- /dev/null
@@ -0,0 +1,78 @@
+From 2b51caf449379a00c0b136f0a72930eae6f6d01f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Feb 2025 18:56:18 +0530
+Subject: drm/ci: fix merge request rules
+
+From: Vignesh Raman <vignesh.raman@collabora.com>
+
+[ Upstream commit 10646ddac2917b31c985ceff0e4982c42a9c924b ]
+
+Merge request pipelines were only created when changes
+were made to drivers/gpu/drm/ci/, causing MRs that
+didn't touch this path to break. Fix MR pipeline rules
+to trigger jobs for all changes.
+
+Run jobs automatically for marge-bot and scheduled
+pipelines, but in all other cases run manually. Also
+remove CI_PROJECT_NAMESPACE checks specific to mesa.
+
+Fixes: df54f04f2020 ("drm/ci: update gitlab rules")
+Signed-off-by: Vignesh Raman <vignesh.raman@collabora.com>
+Reviewed-by: Daniel Stone <daniels@collabora.com>
+Signed-off-by: Helen Koike <helen.fornazier@gmail.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250228132620.556079-1-vignesh.raman@collabora.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/ci/gitlab-ci.yml | 19 ++++---------------
+ 1 file changed, 4 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/gpu/drm/ci/gitlab-ci.yml b/drivers/gpu/drm/ci/gitlab-ci.yml
+index f04aabe8327c6..b06b9e7d3d09b 100644
+--- a/drivers/gpu/drm/ci/gitlab-ci.yml
++++ b/drivers/gpu/drm/ci/gitlab-ci.yml
+@@ -143,11 +143,11 @@ stages:
+     # Pre-merge pipeline
+     - if: &is-pre-merge $CI_PIPELINE_SOURCE == "merge_request_event"
+     # Push to a branch on a fork
+-    - if: &is-fork-push $CI_PROJECT_NAMESPACE != "mesa" && $CI_PIPELINE_SOURCE == "push"
++    - if: &is-fork-push $CI_PIPELINE_SOURCE == "push"
+     # nightly pipeline
+     - if: &is-scheduled-pipeline $CI_PIPELINE_SOURCE == "schedule"
+     # pipeline for direct pushes that bypassed the CI
+-    - if: &is-direct-push $CI_PROJECT_NAMESPACE == "mesa" && $CI_PIPELINE_SOURCE == "push" && $GITLAB_USER_LOGIN != "marge-bot"
++    - if: &is-direct-push $CI_PIPELINE_SOURCE == "push" && $GITLAB_USER_LOGIN != "marge-bot"
+ # Rules applied to every job in the pipeline
+@@ -170,26 +170,15 @@ stages:
+     - !reference [.disable-farm-mr-rules, rules]
+     # Never run immediately after merging, as we just ran everything
+     - !reference [.never-post-merge-rules, rules]
+-    # Build everything in merge pipelines, if any files affecting the pipeline
+-    # were changed
++    # Build everything in merge pipelines
+     - if: *is-merge-attempt
+-      changes: &all_paths
+-      - drivers/gpu/drm/ci/**/*
+       when: on_success
+     # Same as above, but for pre-merge pipelines
+     - if: *is-pre-merge
+-      changes:
+-        *all_paths
+       when: manual
+-    # Skip everything for pre-merge and merge pipelines which don't change
+-    # anything in the build
+-    - if: *is-merge-attempt
+-      when: never
+-    - if: *is-pre-merge
+-      when: never
+     # Build everything after someone bypassed the CI
+     - if: *is-direct-push
+-      when: on_success
++      when: manual
+     # Build everything in scheduled pipelines
+     - if: *is-scheduled-pipeline
+       when: on_success
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-connector-only-call-hdmi-audio-helper-plugged-cb.patch b/queue-6.15/drm-connector-only-call-hdmi-audio-helper-plugged-cb.patch
new file mode 100644 (file)
index 0000000..b5f2740
--- /dev/null
@@ -0,0 +1,47 @@
+From db1bbc43e241338fed9380fa3da61ab7298089a3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 May 2025 19:57:08 +0200
+Subject: drm/connector: only call HDMI audio helper plugged cb if non-null
+
+From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
+
+[ Upstream commit be9b3f9a54101c19226c25ba7163d291183777a0 ]
+
+On driver remove, sound/soc/codecs/hdmi-codec.c calls the plugged_cb
+with NULL as the callback function and codec_dev, as seen in its
+hdmi_remove function.
+
+The HDMI audio helper then happily tries calling said null function
+pointer, and produces an Oops as a result.
+
+Fix this by only executing the callback if fn is non-null. This means
+the .plugged_cb and .plugged_cb_dev members still get appropriately
+cleared.
+
+Fixes: baf616647fe6 ("drm/connector: implement generic HDMI audio helpers")
+Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Link: https://lore.kernel.org/r/20250527-hdmi-audio-helper-remove-fix-v1-1-6cf77de364d8@collabora.com
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/display/drm_hdmi_audio_helper.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/display/drm_hdmi_audio_helper.c b/drivers/gpu/drm/display/drm_hdmi_audio_helper.c
+index 05afc9f0bdd6b..ae8a0cf595fc6 100644
+--- a/drivers/gpu/drm/display/drm_hdmi_audio_helper.c
++++ b/drivers/gpu/drm/display/drm_hdmi_audio_helper.c
+@@ -103,7 +103,8 @@ static int drm_connector_hdmi_audio_hook_plugged_cb(struct device *dev,
+       connector->hdmi_audio.plugged_cb = fn;
+       connector->hdmi_audio.plugged_cb_dev = codec_dev;
+-      fn(codec_dev, connector->hdmi_audio.last_state);
++      if (fn)
++              fn(codec_dev, connector->hdmi_audio.last_state);
+       mutex_unlock(&connector->hdmi_audio.lock);
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-i915-display-fix-u32-overflow-in-snps-phy-hdmi-p.patch b/queue-6.15/drm-i915-display-fix-u32-overflow-in-snps-phy-hdmi-p.patch
new file mode 100644 (file)
index 0000000..958148b
--- /dev/null
@@ -0,0 +1,88 @@
+From 4b566aac294b9f2e8278c61f5fb907fa883af042 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 May 2025 12:15:56 +0530
+Subject: drm/i915/display: Fix u32 overflow in SNPS PHY HDMI PLL setup
+
+From: Dibin Moolakadan Subrahmanian <dibin.moolakadan.subrahmanian@intel.com>
+
+[ Upstream commit 791d76005de0ab556b590473eb4cbfede727fce0 ]
+
+When configuring the HDMI PLL, calculations use DIV_ROUND_UP_ULL and
+DIV_ROUND_DOWN_ULL macros, which internally rely on do_div. However, do_div
+expects a 32-bit (u32) divisor, and at higher data rates, the divisor can
+exceed this limit. This leads to incorrect division results and
+ultimately misconfigured PLL values.
+This fix replaces do_div calls with  div64_base64 calls where diviser
+can exceed u32 limit.
+
+Fixes: 5947642004bf ("drm/i915/display: Add support for SNPS PHY HDMI PLL algorithm for DG2")
+Cc: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
+Cc: Suraj Kandpal <suraj.kandpal@intel.com>
+Cc: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Dibin Moolakadan Subrahmanian <dibin.moolakadan.subrahmanian@intel.com>
+Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
+Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
+Link: https://lore.kernel.org/r/20250528064557.4172149-1-dibin.moolakadan.subrahmanian@intel.com
+(cherry picked from commit ce924116e43ffbfa544d82976c4b9d11bcde9334)
+Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/i915/display/intel_snps_hdmi_pll.c   | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/display/intel_snps_hdmi_pll.c b/drivers/gpu/drm/i915/display/intel_snps_hdmi_pll.c
+index c6321dafef4f3..74bb3bedf30f5 100644
+--- a/drivers/gpu/drm/i915/display/intel_snps_hdmi_pll.c
++++ b/drivers/gpu/drm/i915/display/intel_snps_hdmi_pll.c
+@@ -41,12 +41,12 @@ static s64 interp(s64 x, s64 x1, s64 x2, s64 y1, s64 y2)
+ {
+       s64 dydx;
+-      dydx = DIV_ROUND_UP_ULL((y2 - y1) * 100000, (x2 - x1));
++      dydx = DIV64_U64_ROUND_UP((y2 - y1) * 100000, (x2 - x1));
+-      return (y1 + DIV_ROUND_UP_ULL(dydx * (x - x1), 100000));
++      return (y1 + DIV64_U64_ROUND_UP(dydx * (x - x1), 100000));
+ }
+-static void get_ana_cp_int_prop(u32 vco_clk,
++static void get_ana_cp_int_prop(u64 vco_clk,
+                               u32 refclk_postscalar,
+                               int mpll_ana_v2i,
+                               int c, int a,
+@@ -115,16 +115,16 @@ static void get_ana_cp_int_prop(u32 vco_clk,
+                                                                     CURVE0_MULTIPLIER));
+       scaled_interpolated_sqrt =
+-                      int_sqrt(DIV_ROUND_UP_ULL(interpolated_product, vco_div_refclk_float) *
++                      int_sqrt(DIV64_U64_ROUND_UP(interpolated_product, vco_div_refclk_float) *
+                       DIV_ROUND_DOWN_ULL(1000000000000ULL, 55));
+       /* Scale vco_div_refclk for ana_cp_int */
+       scaled_vco_div_refclk2 = DIV_ROUND_UP_ULL(vco_div_refclk_float, 1000000);
+-      adjusted_vco_clk2 = 1460281 * DIV_ROUND_UP_ULL(scaled_interpolated_sqrt *
++      adjusted_vco_clk2 = 1460281 * DIV64_U64_ROUND_UP(scaled_interpolated_sqrt *
+                                                      scaled_vco_div_refclk2,
+                                                      curve_1_interpolated);
+-      *ana_cp_prop = DIV_ROUND_UP_ULL(adjusted_vco_clk2, curve_2_scaled2);
++      *ana_cp_prop = DIV64_U64_ROUND_UP(adjusted_vco_clk2, curve_2_scaled2);
+       *ana_cp_prop = max(1, min(*ana_cp_prop, 127));
+ }
+@@ -165,10 +165,10 @@ static void compute_hdmi_tmds_pll(u64 pixel_clock, u32 refclk,
+       /* Select appropriate v2i point */
+       if (datarate <= INTEL_SNPS_PHY_HDMI_9999MHZ) {
+               mpll_ana_v2i = 2;
+-              tx_clk_div = ilog2(DIV_ROUND_DOWN_ULL(INTEL_SNPS_PHY_HDMI_9999MHZ, datarate));
++              tx_clk_div = ilog2(div64_u64(INTEL_SNPS_PHY_HDMI_9999MHZ, datarate));
+       } else {
+               mpll_ana_v2i = 3;
+-              tx_clk_div = ilog2(DIV_ROUND_DOWN_ULL(INTEL_SNPS_PHY_HDMI_16GHZ, datarate));
++              tx_clk_div = ilog2(div64_u64(INTEL_SNPS_PHY_HDMI_16GHZ, datarate));
+       }
+       vco_clk = (datarate << tx_clk_div) >> 1;
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-i915-dp_mst-use-the-correct-connector-while-comp.patch b/queue-6.15/drm-i915-dp_mst-use-the-correct-connector-while-comp.patch
new file mode 100644 (file)
index 0000000..eead35a
--- /dev/null
@@ -0,0 +1,109 @@
+From 386ef6a18ac083e7ef778b72d98aa0e8003c1243 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 May 2025 21:03:28 +0300
+Subject: drm/i915/dp_mst: Use the correct connector while computing the link
+ BPP limit on MST
+
+From: Imre Deak <imre.deak@intel.com>
+
+[ Upstream commit a92e390e0d438e021de0e52065121484b6cca675 ]
+
+Atm, on an MST link in DSC mode
+intel_dp_compute_config_link_bpp_limits() calculates the maximum link
+bpp limit using the MST root connector's DSC capabilities. That's not
+correct in general: the decompression could be performed by a branch
+device downstream of the root branch device or the sink itself.
+
+Fix the above by passing to intel_dp_compute_config_link_bpp_limits()
+the actual connector being modeset, containing the correct DSC
+capabilities.
+
+Cc: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
+Fixes: 1c5b72daff46 ("drm/i915/dp: Set the DSC link limits in intel_dp_compute_config_link_bpp_limits")
+Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
+Reviewed-by: Luca Coelho <luciano.coelho@intel.com>
+Signed-off-by: Imre Deak <imre.deak@intel.com>
+Link: https://lore.kernel.org/r/20250509180340.554867-2-imre.deak@intel.com
+(cherry picked from commit 266e2fcfe2ea0d062ea392cd22f6250ae0d11c04)
+Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/display/intel_dp.c     | 7 ++++---
+ drivers/gpu/drm/i915/display/intel_dp.h     | 1 +
+ drivers/gpu/drm/i915/display/intel_dp_mst.c | 5 +++--
+ 3 files changed, 8 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
+index 392c3653d0d73..cd8f728d5fddc 100644
+--- a/drivers/gpu/drm/i915/display/intel_dp.c
++++ b/drivers/gpu/drm/i915/display/intel_dp.c
+@@ -2523,6 +2523,7 @@ intel_dp_dsc_compute_pipe_bpp_limits(struct intel_dp *intel_dp,
+ bool
+ intel_dp_compute_config_limits(struct intel_dp *intel_dp,
++                             struct intel_connector *connector,
+                              struct intel_crtc_state *crtc_state,
+                              bool respect_downstream_limits,
+                              bool dsc,
+@@ -2576,7 +2577,7 @@ intel_dp_compute_config_limits(struct intel_dp *intel_dp,
+       intel_dp_test_compute_config(intel_dp, crtc_state, limits);
+       return intel_dp_compute_config_link_bpp_limits(intel_dp,
+-                                                     intel_dp->attached_connector,
++                                                     connector,
+                                                      crtc_state,
+                                                      dsc,
+                                                      limits);
+@@ -2637,7 +2638,7 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
+       joiner_needs_dsc = intel_dp_joiner_needs_dsc(display, num_joined_pipes);
+       dsc_needed = joiner_needs_dsc || intel_dp->force_dsc_en ||
+-                   !intel_dp_compute_config_limits(intel_dp, pipe_config,
++                   !intel_dp_compute_config_limits(intel_dp, connector, pipe_config,
+                                                    respect_downstream_limits,
+                                                    false,
+                                                    &limits);
+@@ -2671,7 +2672,7 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
+                           str_yes_no(ret), str_yes_no(joiner_needs_dsc),
+                           str_yes_no(intel_dp->force_dsc_en));
+-              if (!intel_dp_compute_config_limits(intel_dp, pipe_config,
++              if (!intel_dp_compute_config_limits(intel_dp, connector, pipe_config,
+                                                   respect_downstream_limits,
+                                                   true,
+                                                   &limits))
+diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
+index 9189db4c25946..98f90955fdb1d 100644
+--- a/drivers/gpu/drm/i915/display/intel_dp.h
++++ b/drivers/gpu/drm/i915/display/intel_dp.h
+@@ -194,6 +194,7 @@ void intel_dp_wait_source_oui(struct intel_dp *intel_dp);
+ int intel_dp_output_bpp(enum intel_output_format output_format, int bpp);
+ bool intel_dp_compute_config_limits(struct intel_dp *intel_dp,
++                                  struct intel_connector *connector,
+                                   struct intel_crtc_state *crtc_state,
+                                   bool respect_downstream_limits,
+                                   bool dsc,
+diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
+index 6dc2d31ccb5a5..fe685f098ba9a 100644
+--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
++++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
+@@ -590,12 +590,13 @@ adjust_limits_for_dsc_hblank_expansion_quirk(struct intel_dp *intel_dp,
+ static bool
+ mst_stream_compute_config_limits(struct intel_dp *intel_dp,
+-                               const struct intel_connector *connector,
++                               struct intel_connector *connector,
+                                struct intel_crtc_state *crtc_state,
+                                bool dsc,
+                                struct link_config_limits *limits)
+ {
+-      if (!intel_dp_compute_config_limits(intel_dp, crtc_state, false, dsc,
++      if (!intel_dp_compute_config_limits(intel_dp, connector,
++                                          crtc_state, false, dsc,
+                                           limits))
+               return false;
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-i915-guc-check-if-expecting-reply-before-decreme.patch b/queue-6.15/drm-i915-guc-check-if-expecting-reply-before-decreme.patch
new file mode 100644 (file)
index 0000000..d4d496b
--- /dev/null
@@ -0,0 +1,53 @@
+From edf769c1128eace7a4c6c2700550e5f7bc01a9f0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 May 2025 15:52:24 -0700
+Subject: drm/i915/guc: Check if expecting reply before decrementing
+ outstanding_submission_g2h
+
+From: Jesus Narvaez <jesus.narvaez@intel.com>
+
+[ Upstream commit c557fd1050f6691dde36818dfc1a4c415c42901b ]
+
+When sending a H2G message where a reply is expected in
+guc_submission_send_busy_loop(), outstanding_submission_g2h is
+incremented before the send. However, if there is an error sending the
+message, outstanding_submission_g2h is decremented without checking if a
+reply is expected.
+
+Therefore, check if reply is expected when there is a failure before
+decrementing outstanding_submission_g2h.
+
+Fixes: 2f2cc53b5fe7 ("drm/i915/guc: Close deregister-context race against CT-loss")
+Signed-off-by: Jesus Narvaez <jesus.narvaez@intel.com>
+Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
+Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
+Cc: Anshuman Gupta <anshuman.gupta@intel.com>
+Cc: Mousumi Jana <mousumi.jana@intel.com>
+Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Cc: Matt Roper <matthew.d.roper@intel.com>
+Reviewed-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
+Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
+Link: https://lore.kernel.org/r/20250514225224.4142684-1-jesus.narvaez@intel.com
+(cherry picked from commit a6a26786f22a4ab0227bcf610510c4c9c2df0808)
+Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+index f8cb7c630d5b8..108331a699958 100644
+--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+@@ -633,7 +633,7 @@ static int guc_submission_send_busy_loop(struct intel_guc *guc,
+               atomic_inc(&guc->outstanding_submission_g2h);
+       ret = intel_guc_send_busy_loop(guc, action, len, g2h_len_dw, loop);
+-      if (ret)
++      if (ret && g2h_len_dw)
+               atomic_dec(&guc->outstanding_submission_g2h);
+       return ret;
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-i915-guc-handle-race-condition-where-wakeref-cou.patch b/queue-6.15/drm-i915-guc-handle-race-condition-where-wakeref-cou.patch
new file mode 100644 (file)
index 0000000..137623d
--- /dev/null
@@ -0,0 +1,82 @@
+From 826b9f1868a5bae2265251b42416fdd153263463 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 May 2025 16:05:51 -0700
+Subject: drm/i915/guc: Handle race condition where wakeref count drops below 0
+
+From: Jesus Narvaez <jesus.narvaez@intel.com>
+
+[ Upstream commit 0323a5127e7c534cfc88efe0f850a0cb777e938b ]
+
+There is a rare race condition when preparing for a reset where
+guc_lrc_desc_unpin() could be in the process of deregistering a context
+while a different thread is scrubbing outstanding contexts and it alters
+the context state and does a wakeref put. Then, if there is a failure
+with deregister_context(), a second wakeref put could occur. As a result
+the wakeref count could drop below 0 and fail an INTEL_WAKEREF_BUG_ON()
+check.
+
+Therefore if there is a failure with deregister_context(), undo the
+context state changes and do a wakeref put only if the context was set
+to be destroyed earlier.
+
+v2: Expand comment to better explain change. (Daniele)
+v3: Removed addition to the original comment. (Daniele)
+
+Fixes: 2f2cc53b5fe7 ("drm/i915/guc: Close deregister-context race against CT-loss")
+Signed-off-by: Jesus Narvaez <jesus.narvaez@intel.com>
+Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
+Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
+Cc: Anshuman Gupta <anshuman.gupta@intel.com>
+Cc: Mousumi Jana <mousumi.jana@intel.com>
+Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Cc: Matt Roper <matthew.d.roper@intel.com>
+Reviewed-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
+Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
+Link: https://lore.kernel.org/r/20250528230551.1855177-1-jesus.narvaez@intel.com
+(cherry picked from commit f36a75aba1c3176d177964bca76f86a075d2943a)
+Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/i915/gt/uc/intel_guc_submission.c   | 17 ++++++++++++++---
+ 1 file changed, 14 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+index 108331a699958..127316d2c8aa9 100644
+--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+@@ -3443,18 +3443,29 @@ static inline int guc_lrc_desc_unpin(struct intel_context *ce)
+        * GuC is active, lets destroy this context, but at this point we can still be racing
+        * with suspend, so we undo everything if the H2G fails in deregister_context so
+        * that GuC reset will find this context during clean up.
++       *
++       * There is a race condition where the reset code could have altered
++       * this context's state and done a wakeref put before we try to
++       * deregister it here. So check if the context is still set to be
++       * destroyed before undoing earlier changes, to avoid two wakeref puts
++       * on the same context.
+        */
+       ret = deregister_context(ce, ce->guc_id.id);
+       if (ret) {
++              bool pending_destroyed;
+               spin_lock_irqsave(&ce->guc_state.lock, flags);
+-              set_context_registered(ce);
+-              clr_context_destroyed(ce);
++              pending_destroyed = context_destroyed(ce);
++              if (pending_destroyed) {
++                      set_context_registered(ce);
++                      clr_context_destroyed(ce);
++              }
+               spin_unlock_irqrestore(&ce->guc_state.lock, flags);
+               /*
+                * As gt-pm is awake at function entry, intel_wakeref_put_async merely decrements
+                * the wakeref immediately but per function spec usage call this after unlock.
+                */
+-              intel_wakeref_put_async(&gt->wakeref);
++              if (pending_destroyed)
++                      intel_wakeref_put_async(&gt->wakeref);
+       }
+       return ret;
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-i915-psr-fix-using-wrong-mask-in-reg_field_prep.patch b/queue-6.15/drm-i915-psr-fix-using-wrong-mask-in-reg_field_prep.patch
new file mode 100644 (file)
index 0000000..6a37847
--- /dev/null
@@ -0,0 +1,44 @@
+From a66695c8c1a63160cc5db9ce968f2bd5e2e34a12 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 May 2025 15:05:11 +0300
+Subject: drm/i915/psr: Fix using wrong mask in REG_FIELD_PREP
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jouni Högander <jouni.hogander@intel.com>
+
+[ Upstream commit 57d63c6cd0851d3af612a556ec61b0f2a9bd522f ]
+
+Wrong mask is used in PORT_ALPM_LFPS_CTL_FIRST_LFPS_HALF_CYCLE_DURATION and
+PORT_ALPM_LFPS_CTL_LAST_LFPS_HALF_CYCLE_DURATION.
+
+Fixes: 295099580f04 ("drm/i915/psr: Add missing ALPM AUX-Less register definitions")
+Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
+Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
+Link: https://lore.kernel.org/r/20250526120512.1702815-12-jouni.hogander@intel.com
+(cherry picked from commit 8097128a40ff378761034ec72cdbf6f46e466dc0)
+Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/display/intel_psr_regs.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/display/intel_psr_regs.h b/drivers/gpu/drm/i915/display/intel_psr_regs.h
+index 795e6b9cc575c..248136456048e 100644
+--- a/drivers/gpu/drm/i915/display/intel_psr_regs.h
++++ b/drivers/gpu/drm/i915/display/intel_psr_regs.h
+@@ -325,8 +325,8 @@
+ #define  PORT_ALPM_LFPS_CTL_LFPS_HALF_CYCLE_DURATION_MASK     REG_GENMASK(20, 16)
+ #define  PORT_ALPM_LFPS_CTL_LFPS_HALF_CYCLE_DURATION(val)     REG_FIELD_PREP(PORT_ALPM_LFPS_CTL_LFPS_HALF_CYCLE_DURATION_MASK, val)
+ #define  PORT_ALPM_LFPS_CTL_FIRST_LFPS_HALF_CYCLE_DURATION_MASK       REG_GENMASK(12, 8)
+-#define  PORT_ALPM_LFPS_CTL_FIRST_LFPS_HALF_CYCLE_DURATION(val)       REG_FIELD_PREP(PORT_ALPM_LFPS_CTL_LFPS_HALF_CYCLE_DURATION_MASK, val)
++#define  PORT_ALPM_LFPS_CTL_FIRST_LFPS_HALF_CYCLE_DURATION(val)       REG_FIELD_PREP(PORT_ALPM_LFPS_CTL_FIRST_LFPS_HALF_CYCLE_DURATION_MASK, val)
+ #define  PORT_ALPM_LFPS_CTL_LAST_LFPS_HALF_CYCLE_DURATION_MASK        REG_GENMASK(4, 0)
+-#define  PORT_ALPM_LFPS_CTL_LAST_LFPS_HALF_CYCLE_DURATION(val)        REG_FIELD_PREP(PORT_ALPM_LFPS_CTL_LFPS_HALF_CYCLE_DURATION_MASK, val)
++#define  PORT_ALPM_LFPS_CTL_LAST_LFPS_HALF_CYCLE_DURATION(val)        REG_FIELD_PREP(PORT_ALPM_LFPS_CTL_LAST_LFPS_HALF_CYCLE_DURATION_MASK, val)
+ #endif /* __INTEL_PSR_REGS_H__ */
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-mediatek-fix-kobject-put-for-component-sub-drive.patch b/queue-6.15/drm-mediatek-fix-kobject-put-for-component-sub-drive.patch
new file mode 100644 (file)
index 0000000..39975e2
--- /dev/null
@@ -0,0 +1,67 @@
+From e542ad12da25cab9bf046577e05577fd4c129b95 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Apr 2025 12:47:38 +0200
+Subject: drm/mediatek: Fix kobject put for component sub-drivers
+
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+[ Upstream commit 80805b62ea5b95eda54c225b989f929ca0691ab0 ]
+
+In function mtk_drm_get_all_drm_priv(), this driver is incrementing
+the refcount for the sub-drivers of mediatek-drm with a call to
+device_find_child() when taking a reference to all of those child
+devices.
+
+When the component bind fails multiple times this results in a
+refcount_t overflow, as the reference count is never decremented:
+fix that by adding a call to put_device() for all of the mmsys
+devices in a loop, in error cases of mtk_drm_bind() and in the
+mtk_drm_unbind() callback.
+
+Fixes: 1ef7ed48356c ("drm/mediatek: Modify mediatek-drm for mt8195 multi mmsys support")
+Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://patchwork.kernel.org/project/dri-devel/patch/20250403104741.71045-3-angelogioacchino.delregno@collabora.com/
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_drm_drv.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+index 5994e2a97dc13..593193555c07e 100644
+--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
++++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+@@ -682,6 +682,10 @@ static int mtk_drm_bind(struct device *dev)
+       for (i = 0; i < private->data->mmsys_dev_num; i++)
+               private->all_drm_private[i]->drm = NULL;
+ err_put_dev:
++      for (i = 0; i < private->data->mmsys_dev_num; i++) {
++              /* For device_find_child in mtk_drm_get_all_priv() */
++              put_device(private->all_drm_private[i]->dev);
++      }
+       put_device(private->mutex_dev);
+       return ret;
+ }
+@@ -689,6 +693,7 @@ static int mtk_drm_bind(struct device *dev)
+ static void mtk_drm_unbind(struct device *dev)
+ {
+       struct mtk_drm_private *private = dev_get_drvdata(dev);
++      int i;
+       /* for multi mmsys dev, unregister drm dev in mmsys master */
+       if (private->drm_master) {
+@@ -696,6 +701,10 @@ static void mtk_drm_unbind(struct device *dev)
+               mtk_drm_kms_deinit(private->drm);
+               drm_dev_put(private->drm);
++              for (i = 0; i < private->data->mmsys_dev_num; i++) {
++                      /* For device_find_child in mtk_drm_get_all_priv() */
++                      put_device(private->all_drm_private[i]->dev);
++              }
+               put_device(private->mutex_dev);
+       }
+       private->mtk_drm_bound = false;
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-mediatek-mtk_drm_drv-fix-kobject-put-for-mtk_mut.patch b/queue-6.15/drm-mediatek-mtk_drm_drv-fix-kobject-put-for-mtk_mut.patch
new file mode 100644 (file)
index 0000000..6d3aeaf
--- /dev/null
@@ -0,0 +1,107 @@
+From b657de6bc53fc7a9b82112dcd795f35a1e7694be Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Apr 2025 12:47:37 +0200
+Subject: drm/mediatek: mtk_drm_drv: Fix kobject put for mtk_mutex device ptr
+
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+[ Upstream commit 22918591fb747a6d16801e74a170cf98e886f83b ]
+
+This driver is taking a kobject for mtk_mutex only once per mmsys
+device for each drm-mediatek driver instance, differently from the
+behavior with other components, but it is decrementing the kobj's
+refcount in a loop and once per mmsys: this is not right and will
+result in a refcount_t underflow warning when mediatek-drm returns
+multiple probe deferrals in one boot (or when manually bound and
+unbound).
+
+Besides that, the refcount for mutex_dev was not decremented for
+error cases in mtk_drm_bind(), causing another refcount_t warning
+but this time for overflow, when the failure happens not during
+driver bind but during component bind.
+
+In order to fix one of the reasons why this is happening, remove
+the put_device(xx->mutex_dev) loop from the mtk_drm_kms_init()'s
+put_mutex_dev label (and drop the label) and add a single call to
+correctly free the single incremented refcount of mutex_dev to
+the mtk_drm_unbind() function to fix the refcount_t underflow.
+
+Moreover, add the same call to the error cases in mtk_drm_bind()
+to fix the refcount_t overflow.
+
+Fixes: 1ef7ed48356c ("drm/mediatek: Modify mediatek-drm for mt8195 multi mmsys support")
+Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://patchwork.kernel.org/project/dri-devel/patch/20250403104741.71045-2-angelogioacchino.delregno@collabora.com/
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_drm_drv.c | 17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+index 74158b9d65035..5994e2a97dc13 100644
+--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
++++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+@@ -470,7 +470,7 @@ static int mtk_drm_kms_init(struct drm_device *drm)
+       ret = drmm_mode_config_init(drm);
+       if (ret)
+-              goto put_mutex_dev;
++              return ret;
+       drm->mode_config.min_width = 64;
+       drm->mode_config.min_height = 64;
+@@ -489,7 +489,7 @@ static int mtk_drm_kms_init(struct drm_device *drm)
+               drm->dev_private = private->all_drm_private[i];
+               ret = component_bind_all(private->all_drm_private[i]->dev, drm);
+               if (ret)
+-                      goto put_mutex_dev;
++                      return ret;
+       }
+       /*
+@@ -582,9 +582,6 @@ static int mtk_drm_kms_init(struct drm_device *drm)
+ err_component_unbind:
+       for (i = 0; i < private->data->mmsys_dev_num; i++)
+               component_unbind_all(private->all_drm_private[i]->dev, drm);
+-put_mutex_dev:
+-      for (i = 0; i < private->data->mmsys_dev_num; i++)
+-              put_device(private->all_drm_private[i]->mutex_dev);
+       return ret;
+ }
+@@ -655,8 +652,10 @@ static int mtk_drm_bind(struct device *dev)
+               return 0;
+       drm = drm_dev_alloc(&mtk_drm_driver, dev);
+-      if (IS_ERR(drm))
+-              return PTR_ERR(drm);
++      if (IS_ERR(drm)) {
++              ret = PTR_ERR(drm);
++              goto err_put_dev;
++      }
+       private->drm_master = true;
+       drm->dev_private = private;
+@@ -682,6 +681,8 @@ static int mtk_drm_bind(struct device *dev)
+       drm_dev_put(drm);
+       for (i = 0; i < private->data->mmsys_dev_num; i++)
+               private->all_drm_private[i]->drm = NULL;
++err_put_dev:
++      put_device(private->mutex_dev);
+       return ret;
+ }
+@@ -694,6 +695,8 @@ static void mtk_drm_unbind(struct device *dev)
+               drm_dev_unregister(private->drm);
+               mtk_drm_kms_deinit(private->drm);
+               drm_dev_put(private->drm);
++
++              put_device(private->mutex_dev);
+       }
+       private->mtk_drm_bound = false;
+       private->drm_master = false;
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-mediatek-mtk_drm_drv-unbind-secondary-mmsys-comp.patch b/queue-6.15/drm-mediatek-mtk_drm_drv-unbind-secondary-mmsys-comp.patch
new file mode 100644 (file)
index 0000000..94c3f91
--- /dev/null
@@ -0,0 +1,58 @@
+From b945461f23df26f20390b707eec0cdbbeb2bebd0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Apr 2025 12:47:39 +0200
+Subject: drm/mediatek: mtk_drm_drv: Unbind secondary mmsys components on err
+
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+[ Upstream commit 94c933716567084bfb9e79dcd81eb2b2308e84e1 ]
+
+When calling component_bind_all(), if a component that is included
+in the list fails, all of those that have been successfully bound
+will be unbound, but this driver has two components lists for two
+actual devices, as in, each mmsys instance has its own components
+list.
+
+In case mmsys0 (or actually vdosys0) is able to bind all of its
+components, but the secondary one fails, all of the components of
+the first are kept bound, while the ones of mmsys1/vdosys1 are
+correctly cleaned up.
+
+This is not right because, in case of a failure, the components
+are re-bound for all of the mmsys/vdosys instances without caring
+about the ones that were previously left in a bound state.
+
+Fix that by calling component_unbind_all() on all of the previous
+component masters that succeeded binding all subdevices when any
+of the other masters errors out.
+
+Fixes: 1ef7ed48356c ("drm/mediatek: Modify mediatek-drm for mt8195 multi mmsys support")
+Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://patchwork.kernel.org/project/dri-devel/patch/20250403104741.71045-4-angelogioacchino.delregno@collabora.com/
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_drm_drv.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+index 593193555c07e..7c0c12dde4885 100644
+--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
++++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+@@ -488,8 +488,11 @@ static int mtk_drm_kms_init(struct drm_device *drm)
+       for (i = 0; i < private->data->mmsys_dev_num; i++) {
+               drm->dev_private = private->all_drm_private[i];
+               ret = component_bind_all(private->all_drm_private[i]->dev, drm);
+-              if (ret)
++              if (ret) {
++                      while (--i >= 0)
++                              component_unbind_all(private->all_drm_private[i]->dev, drm);
+                       return ret;
++              }
+       }
+       /*
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-msm-a6xx-disable-rgb565_predicator-on-adreno-7c3.patch b/queue-6.15/drm-msm-a6xx-disable-rgb565_predicator-on-adreno-7c3.patch
new file mode 100644 (file)
index 0000000..2829e22
--- /dev/null
@@ -0,0 +1,39 @@
+From 9e1684257d5b3991e3cb28e79dcdc78ab73da8fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 May 2025 13:13:40 +0200
+Subject: drm/msm/a6xx: Disable rgb565_predicator on Adreno 7c3
+
+From: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+
+[ Upstream commit 5a9c1bea011fb42088ba08ceaa252fb20e695626 ]
+
+This feature is supposed to be enabled with UBWC v4 or later.
+Implementations of this SKU feature an effective UBWC version of 3, so
+disable it, in line with the BSP kernel.
+
+Reported-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Reviewed-by: Akhil P Oommen <quic_akhilpo@quicinc.com>
+Fixes: 192f4ee3e408 ("drm/msm/a6xx: Add support for Adreno 7c Gen 3 gpu")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Patchwork: https://patchwork.freedesktop.org/patch/651759/
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+index 242d02d48c0cd..90991ba5a4ae1 100644
+--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
++++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+@@ -655,7 +655,6 @@ static void a6xx_calc_ubwc_config(struct adreno_gpu *gpu)
+       if (adreno_is_7c3(gpu)) {
+               gpu->ubwc_config.highest_bank_bit = 14;
+               gpu->ubwc_config.amsbc = 1;
+-              gpu->ubwc_config.rgb565_predicator = 1;
+               gpu->ubwc_config.uavflagprd_inv = 2;
+               gpu->ubwc_config.macrotile_mode = 1;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-msm-dp-account-for-lttprs-capabilities.patch b/queue-6.15/drm-msm-dp-account-for-lttprs-capabilities.patch
new file mode 100644 (file)
index 0000000..e480396
--- /dev/null
@@ -0,0 +1,104 @@
+From e0d240d24c72ae4d8007b1c50de156497721fd3d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 May 2025 00:59:00 +0200
+Subject: drm/msm/dp: Account for LTTPRs capabilities
+
+From: Aleksandrs Vinarskis <alex.vinarskis@gmail.com>
+
+[ Upstream commit c156fe2dd46774321c8eaaff9a6f04b64e6b9742 ]
+
+Take into account LTTPR capabilities when selecting maximum allowed
+link rate, number of data lines.
+
+Fixes: 72d0af4accd9 ("drm/msm/dp: Add support for LTTPR handling")
+Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Signed-off-by: Aleksandrs Vinarskis <alex.vinarskis@gmail.com>
+Tested-by: Jessica Zhang <quic_jesszhan@quicinc.com> # SA8775P
+Tested-by: Johan Hovold <johan+linaro@kernel.org>
+Tested-by: Rob Clark <robdclark@gmail.com>
+Patchwork: https://patchwork.freedesktop.org/patch/652302/
+Link: https://lore.kernel.org/r/20250507230113.14270-3-alex.vinarskis@gmail.com
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/dp/dp_display.c |  5 ++---
+ drivers/gpu/drm/msm/dp/dp_link.h    |  3 +++
+ drivers/gpu/drm/msm/dp/dp_panel.c   | 12 +++++++++++-
+ 3 files changed, 16 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
+index fc07cce68382a..5c57c1d7ac601 100644
+--- a/drivers/gpu/drm/msm/dp/dp_display.c
++++ b/drivers/gpu/drm/msm/dp/dp_display.c
+@@ -369,13 +369,12 @@ static int msm_dp_display_send_hpd_notification(struct msm_dp_display_private *d
+ static void msm_dp_display_lttpr_init(struct msm_dp_display_private *dp, u8 *dpcd)
+ {
+-      u8 lttpr_caps[DP_LTTPR_COMMON_CAP_SIZE];
+       int rc;
+-      if (drm_dp_read_lttpr_common_caps(dp->aux, dpcd, lttpr_caps))
++      if (drm_dp_read_lttpr_common_caps(dp->aux, dpcd, dp->link->lttpr_common_caps))
+               return;
+-      rc = drm_dp_lttpr_init(dp->aux, drm_dp_lttpr_count(lttpr_caps));
++      rc = drm_dp_lttpr_init(dp->aux, drm_dp_lttpr_count(dp->link->lttpr_common_caps));
+       if (rc)
+               DRM_ERROR("failed to set LTTPRs transparency mode, rc=%d\n", rc);
+ }
+diff --git a/drivers/gpu/drm/msm/dp/dp_link.h b/drivers/gpu/drm/msm/dp/dp_link.h
+index 8db5d5698a97c..c47d75cfc720c 100644
+--- a/drivers/gpu/drm/msm/dp/dp_link.h
++++ b/drivers/gpu/drm/msm/dp/dp_link.h
+@@ -7,6 +7,7 @@
+ #define _DP_LINK_H_
+ #include "dp_aux.h"
++#include <drm/display/drm_dp_helper.h>
+ #define DS_PORT_STATUS_CHANGED 0x200
+ #define DP_TEST_BIT_DEPTH_UNKNOWN 0xFFFFFFFF
+@@ -60,6 +61,8 @@ struct msm_dp_link_phy_params {
+ };
+ struct msm_dp_link {
++      u8 lttpr_common_caps[DP_LTTPR_COMMON_CAP_SIZE];
++
+       u32 sink_request;
+       u32 test_response;
+diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c b/drivers/gpu/drm/msm/dp/dp_panel.c
+index 92415bf8aa166..4e8ab75c771b1 100644
+--- a/drivers/gpu/drm/msm/dp/dp_panel.c
++++ b/drivers/gpu/drm/msm/dp/dp_panel.c
+@@ -47,7 +47,7 @@ static void msm_dp_panel_read_psr_cap(struct msm_dp_panel_private *panel)
+ static int msm_dp_panel_read_dpcd(struct msm_dp_panel *msm_dp_panel)
+ {
+-      int rc;
++      int rc, max_lttpr_lanes, max_lttpr_rate;
+       struct msm_dp_panel_private *panel;
+       struct msm_dp_link_info *link_info;
+       u8 *dpcd, major, minor;
+@@ -75,6 +75,16 @@ static int msm_dp_panel_read_dpcd(struct msm_dp_panel *msm_dp_panel)
+       if (link_info->rate > msm_dp_panel->max_dp_link_rate)
+               link_info->rate = msm_dp_panel->max_dp_link_rate;
++      /* Limit data lanes from LTTPR capabilities, if any */
++      max_lttpr_lanes = drm_dp_lttpr_max_lane_count(panel->link->lttpr_common_caps);
++      if (max_lttpr_lanes && max_lttpr_lanes < link_info->num_lanes)
++              link_info->num_lanes = max_lttpr_lanes;
++
++      /* Limit link rate from LTTPR capabilities, if any */
++      max_lttpr_rate = drm_dp_lttpr_max_link_rate(panel->link->lttpr_common_caps);
++      if (max_lttpr_rate && max_lttpr_rate < link_info->rate)
++              link_info->rate = max_lttpr_rate;
++
+       drm_dbg_dp(panel->drm_dev, "version: %d.%d\n", major, minor);
+       drm_dbg_dp(panel->drm_dev, "link_rate=%d\n", link_info->rate);
+       drm_dbg_dp(panel->drm_dev, "lane_count=%d\n", link_info->num_lanes);
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-msm-dp-fix-support-of-lttpr-initialization.patch b/queue-6.15/drm-msm-dp-fix-support-of-lttpr-initialization.patch
new file mode 100644 (file)
index 0000000..8f3a0f8
--- /dev/null
@@ -0,0 +1,70 @@
+From 2686405d26cea1cbd4462d1171ae30d72aa0599f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 May 2025 00:58:59 +0200
+Subject: drm/msm/dp: Fix support of LTTPR initialization
+
+From: Aleksandrs Vinarskis <alex.vinarskis@gmail.com>
+
+[ Upstream commit 9351d3d302060d114de2f0c648579c0aadbd8f72 ]
+
+Initialize LTTPR before msm_dp_panel_read_sink_caps, as DPTX shall
+(re)read DPRX caps after LTTPR detection, as required by DP 2.1a,
+Section 3.6.7.6.1.
+
+Fixes: 72d0af4accd9 ("drm/msm/dp: Add support for LTTPR handling")
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Signed-off-by: Aleksandrs Vinarskis <alex.vinarskis@gmail.com>
+Tested-by: Jessica Zhang <quic_jesszhan@quicinc.com> # SA8775P
+Tested-by: Johan Hovold <johan+linaro@kernel.org>
+Tested-by: Rob Clark <robdclark@gmail.com>
+Patchwork: https://patchwork.freedesktop.org/patch/652301/
+Link: https://lore.kernel.org/r/20250507230113.14270-2-alex.vinarskis@gmail.com
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/dp/dp_display.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
+index bbc47d86ae9e6..fc07cce68382a 100644
+--- a/drivers/gpu/drm/msm/dp/dp_display.c
++++ b/drivers/gpu/drm/msm/dp/dp_display.c
+@@ -367,12 +367,12 @@ static int msm_dp_display_send_hpd_notification(struct msm_dp_display_private *d
+       return 0;
+ }
+-static void msm_dp_display_lttpr_init(struct msm_dp_display_private *dp)
++static void msm_dp_display_lttpr_init(struct msm_dp_display_private *dp, u8 *dpcd)
+ {
+       u8 lttpr_caps[DP_LTTPR_COMMON_CAP_SIZE];
+       int rc;
+-      if (drm_dp_read_lttpr_common_caps(dp->aux, dp->panel->dpcd, lttpr_caps))
++      if (drm_dp_read_lttpr_common_caps(dp->aux, dpcd, lttpr_caps))
+               return;
+       rc = drm_dp_lttpr_init(dp->aux, drm_dp_lttpr_count(lttpr_caps));
+@@ -385,12 +385,17 @@ static int msm_dp_display_process_hpd_high(struct msm_dp_display_private *dp)
+       struct drm_connector *connector = dp->msm_dp_display.connector;
+       const struct drm_display_info *info = &connector->display_info;
+       int rc = 0;
++      u8 dpcd[DP_RECEIVER_CAP_SIZE];
+-      rc = msm_dp_panel_read_sink_caps(dp->panel, connector);
++      rc = drm_dp_read_dpcd_caps(dp->aux, dpcd);
+       if (rc)
+               goto end;
+-      msm_dp_display_lttpr_init(dp);
++      msm_dp_display_lttpr_init(dp, dpcd);
++
++      rc = msm_dp_panel_read_sink_caps(dp->panel, connector);
++      if (rc)
++              goto end;
+       msm_dp_link_process_request(dp->link);
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-msm-dp-prepare-for-link-training-per-segment-for.patch b/queue-6.15/drm-msm-dp-prepare-for-link-training-per-segment-for.patch
new file mode 100644 (file)
index 0000000..57c2bc0
--- /dev/null
@@ -0,0 +1,84 @@
+From 2bcf49618c57fa8ec2fd1ba7b7551cc1253b68f4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 May 2025 00:59:01 +0200
+Subject: drm/msm/dp: Prepare for link training per-segment for LTTPRs
+
+From: Aleksandrs Vinarskis <alex.vinarskis@gmail.com>
+
+[ Upstream commit 7513ccb8840b54e35579f3c2cce08c3443a6e2d4 ]
+
+Per-segment link training requires knowing the number of LTTPRs
+(if any) present. Store the count during LTTPRs' initialization.
+
+Fixes: 72d0af4accd9 ("drm/msm/dp: Add support for LTTPR handling")
+Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Signed-off-by: Aleksandrs Vinarskis <alex.vinarskis@gmail.com>
+Tested-by: Jessica Zhang <quic_jesszhan@quicinc.com> # SA8775P
+Tested-by: Johan Hovold <johan+linaro@kernel.org>
+Tested-by: Rob Clark <robdclark@gmail.com>
+Patchwork: https://patchwork.freedesktop.org/patch/652306/
+Link: https://lore.kernel.org/r/20250507230113.14270-4-alex.vinarskis@gmail.com
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/dp/dp_display.c | 17 +++++++++++------
+ drivers/gpu/drm/msm/dp/dp_link.h    |  1 +
+ 2 files changed, 12 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
+index 5c57c1d7ac601..ab8c1f19dcb42 100644
+--- a/drivers/gpu/drm/msm/dp/dp_display.c
++++ b/drivers/gpu/drm/msm/dp/dp_display.c
+@@ -367,16 +367,21 @@ static int msm_dp_display_send_hpd_notification(struct msm_dp_display_private *d
+       return 0;
+ }
+-static void msm_dp_display_lttpr_init(struct msm_dp_display_private *dp, u8 *dpcd)
++static int msm_dp_display_lttpr_init(struct msm_dp_display_private *dp, u8 *dpcd)
+ {
+-      int rc;
++      int rc, lttpr_count;
+       if (drm_dp_read_lttpr_common_caps(dp->aux, dpcd, dp->link->lttpr_common_caps))
+-              return;
++              return 0;
+-      rc = drm_dp_lttpr_init(dp->aux, drm_dp_lttpr_count(dp->link->lttpr_common_caps));
+-      if (rc)
++      lttpr_count = drm_dp_lttpr_count(dp->link->lttpr_common_caps);
++      rc = drm_dp_lttpr_init(dp->aux, lttpr_count);
++      if (rc) {
+               DRM_ERROR("failed to set LTTPRs transparency mode, rc=%d\n", rc);
++              return 0;
++      }
++
++      return lttpr_count;
+ }
+ static int msm_dp_display_process_hpd_high(struct msm_dp_display_private *dp)
+@@ -390,7 +395,7 @@ static int msm_dp_display_process_hpd_high(struct msm_dp_display_private *dp)
+       if (rc)
+               goto end;
+-      msm_dp_display_lttpr_init(dp, dpcd);
++      dp->link->lttpr_count = msm_dp_display_lttpr_init(dp, dpcd);
+       rc = msm_dp_panel_read_sink_caps(dp->panel, connector);
+       if (rc)
+diff --git a/drivers/gpu/drm/msm/dp/dp_link.h b/drivers/gpu/drm/msm/dp/dp_link.h
+index c47d75cfc720c..ba47c6d19fbfa 100644
+--- a/drivers/gpu/drm/msm/dp/dp_link.h
++++ b/drivers/gpu/drm/msm/dp/dp_link.h
+@@ -62,6 +62,7 @@ struct msm_dp_link_phy_params {
+ struct msm_dp_link {
+       u8 lttpr_common_caps[DP_LTTPR_COMMON_CAP_SIZE];
++      int lttpr_count;
+       u32 sink_request;
+       u32 test_response;
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-msm-dpu-enable-smartdma-on-sc8180x.patch b/queue-6.15/drm-msm-dpu-enable-smartdma-on-sc8180x.patch
new file mode 100644 (file)
index 0000000..4c0e2f0
--- /dev/null
@@ -0,0 +1,101 @@
+From 0342e9ddea0731d3fbed6b6a7991d120ca5b5d75 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 22:49:09 +0300
+Subject: drm/msm/dpu: enable SmartDMA on SC8180X
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 8dcccd7a156ffb3157de7f527cc7c6100e9a455a ]
+
+Reworking of the catalog dropped the SmartDMA feature bit on the SC8180X
+platform. Renable SmartDMA support on this SoC.
+
+Fixes: 460c410f02e4 ("drm/msm/dpu: duplicate sdm845 catalog entries")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Patchwork: https://patchwork.freedesktop.org/patch/650421/
+Link: https://lore.kernel.org/r/20250425-dpu-rework-vig-masks-v2-2-c71900687d08@oss.qualcomm.com
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h  | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
+index d76b8992a6c18..e736eb73a7e61 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
++++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
+@@ -75,7 +75,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = {
+       {
+               .name = "sspp_0", .id = SSPP_VIG0,
+               .base = 0x4000, .len = 0x1f0,
+-              .features = VIG_SDM845_MASK,
++              .features = VIG_SDM845_MASK_SDMA,
+               .sblk = &dpu_vig_sblk_qseed3_1_4,
+               .xin_id = 0,
+               .type = SSPP_TYPE_VIG,
+@@ -83,7 +83,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = {
+       }, {
+               .name = "sspp_1", .id = SSPP_VIG1,
+               .base = 0x6000, .len = 0x1f0,
+-              .features = VIG_SDM845_MASK,
++              .features = VIG_SDM845_MASK_SDMA,
+               .sblk = &dpu_vig_sblk_qseed3_1_4,
+               .xin_id = 4,
+               .type = SSPP_TYPE_VIG,
+@@ -91,7 +91,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = {
+       }, {
+               .name = "sspp_2", .id = SSPP_VIG2,
+               .base = 0x8000, .len = 0x1f0,
+-              .features = VIG_SDM845_MASK,
++              .features = VIG_SDM845_MASK_SDMA,
+               .sblk = &dpu_vig_sblk_qseed3_1_4,
+               .xin_id = 8,
+               .type = SSPP_TYPE_VIG,
+@@ -99,7 +99,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = {
+       }, {
+               .name = "sspp_3", .id = SSPP_VIG3,
+               .base = 0xa000, .len = 0x1f0,
+-              .features = VIG_SDM845_MASK,
++              .features = VIG_SDM845_MASK_SDMA,
+               .sblk = &dpu_vig_sblk_qseed3_1_4,
+               .xin_id = 12,
+               .type = SSPP_TYPE_VIG,
+@@ -107,7 +107,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = {
+       }, {
+               .name = "sspp_8", .id = SSPP_DMA0,
+               .base = 0x24000, .len = 0x1f0,
+-              .features = DMA_SDM845_MASK,
++              .features = DMA_SDM845_MASK_SDMA,
+               .sblk = &dpu_dma_sblk,
+               .xin_id = 1,
+               .type = SSPP_TYPE_DMA,
+@@ -115,7 +115,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = {
+       }, {
+               .name = "sspp_9", .id = SSPP_DMA1,
+               .base = 0x26000, .len = 0x1f0,
+-              .features = DMA_SDM845_MASK,
++              .features = DMA_SDM845_MASK_SDMA,
+               .sblk = &dpu_dma_sblk,
+               .xin_id = 5,
+               .type = SSPP_TYPE_DMA,
+@@ -123,7 +123,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = {
+       }, {
+               .name = "sspp_10", .id = SSPP_DMA2,
+               .base = 0x28000, .len = 0x1f0,
+-              .features = DMA_CURSOR_SDM845_MASK,
++              .features = DMA_CURSOR_SDM845_MASK_SDMA,
+               .sblk = &dpu_dma_sblk,
+               .xin_id = 9,
+               .type = SSPP_TYPE_DMA,
+@@ -131,7 +131,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = {
+       }, {
+               .name = "sspp_11", .id = SSPP_DMA3,
+               .base = 0x2a000, .len = 0x1f0,
+-              .features = DMA_CURSOR_SDM845_MASK,
++              .features = DMA_CURSOR_SDM845_MASK_SDMA,
+               .sblk = &dpu_dma_sblk,
+               .xin_id = 13,
+               .type = SSPP_TYPE_DMA,
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-msm-dpu-enable-smartdma-on-sm8150.patch b/queue-6.15/drm-msm-dpu-enable-smartdma-on-sm8150.patch
new file mode 100644 (file)
index 0000000..652d0e6
--- /dev/null
@@ -0,0 +1,101 @@
+From f0c5ea79a8439a77b6770d8fbc1a9fb4db46103a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 22:49:08 +0300
+Subject: drm/msm/dpu: enable SmartDMA on SM8150
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 6a2343de0b6f70a21bf503ac4688dc905cb068e1 ]
+
+Reworking of the catalog dropped the SmartDMA feature bit on the SM8150
+platform. Renable SmartDMA support on this SoC.
+
+Fixes: 460c410f02e4 ("drm/msm/dpu: duplicate sdm845 catalog entries")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Patchwork: https://patchwork.freedesktop.org/patch/650418/
+Link: https://lore.kernel.org/r/20250425-dpu-rework-vig-masks-v2-1-c71900687d08@oss.qualcomm.com
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h   | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
+index 979527d98fbcb..8e23dbfeef354 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
++++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
+@@ -76,7 +76,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {
+       {
+               .name = "sspp_0", .id = SSPP_VIG0,
+               .base = 0x4000, .len = 0x1f0,
+-              .features = VIG_SDM845_MASK,
++              .features = VIG_SDM845_MASK_SDMA,
+               .sblk = &dpu_vig_sblk_qseed3_1_4,
+               .xin_id = 0,
+               .type = SSPP_TYPE_VIG,
+@@ -84,7 +84,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {
+       }, {
+               .name = "sspp_1", .id = SSPP_VIG1,
+               .base = 0x6000, .len = 0x1f0,
+-              .features = VIG_SDM845_MASK,
++              .features = VIG_SDM845_MASK_SDMA,
+               .sblk = &dpu_vig_sblk_qseed3_1_4,
+               .xin_id = 4,
+               .type = SSPP_TYPE_VIG,
+@@ -92,7 +92,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {
+       }, {
+               .name = "sspp_2", .id = SSPP_VIG2,
+               .base = 0x8000, .len = 0x1f0,
+-              .features = VIG_SDM845_MASK,
++              .features = VIG_SDM845_MASK_SDMA,
+               .sblk = &dpu_vig_sblk_qseed3_1_4,
+               .xin_id = 8,
+               .type = SSPP_TYPE_VIG,
+@@ -100,7 +100,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {
+       }, {
+               .name = "sspp_3", .id = SSPP_VIG3,
+               .base = 0xa000, .len = 0x1f0,
+-              .features = VIG_SDM845_MASK,
++              .features = VIG_SDM845_MASK_SDMA,
+               .sblk = &dpu_vig_sblk_qseed3_1_4,
+               .xin_id = 12,
+               .type = SSPP_TYPE_VIG,
+@@ -108,7 +108,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {
+       }, {
+               .name = "sspp_8", .id = SSPP_DMA0,
+               .base = 0x24000, .len = 0x1f0,
+-              .features = DMA_SDM845_MASK,
++              .features = DMA_SDM845_MASK_SDMA,
+               .sblk = &dpu_dma_sblk,
+               .xin_id = 1,
+               .type = SSPP_TYPE_DMA,
+@@ -116,7 +116,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {
+       }, {
+               .name = "sspp_9", .id = SSPP_DMA1,
+               .base = 0x26000, .len = 0x1f0,
+-              .features = DMA_SDM845_MASK,
++              .features = DMA_SDM845_MASK_SDMA,
+               .sblk = &dpu_dma_sblk,
+               .xin_id = 5,
+               .type = SSPP_TYPE_DMA,
+@@ -124,7 +124,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {
+       }, {
+               .name = "sspp_10", .id = SSPP_DMA2,
+               .base = 0x28000, .len = 0x1f0,
+-              .features = DMA_CURSOR_SDM845_MASK,
++              .features = DMA_CURSOR_SDM845_MASK_SDMA,
+               .sblk = &dpu_dma_sblk,
+               .xin_id = 9,
+               .type = SSPP_TYPE_DMA,
+@@ -132,7 +132,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {
+       }, {
+               .name = "sspp_11", .id = SSPP_DMA3,
+               .base = 0x2a000, .len = 0x1f0,
+-              .features = DMA_CURSOR_SDM845_MASK,
++              .features = DMA_CURSOR_SDM845_MASK_SDMA,
+               .sblk = &dpu_dma_sblk,
+               .xin_id = 13,
+               .type = SSPP_TYPE_DMA,
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-msm-dpu-remove-dsc-feature-bit-for-pingpong-on-m.patch b/queue-6.15/drm-msm-dpu-remove-dsc-feature-bit-for-pingpong-on-m.patch
new file mode 100644 (file)
index 0000000..742d4f4
--- /dev/null
@@ -0,0 +1,49 @@
+From b0fd72f9a3f6f12d7f124ac211ab0ea817c2b279 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 Mar 2025 11:24:54 +0200
+Subject: drm/msm/dpu: remove DSC feature bit for PINGPONG on MSM8937
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit b43c524134e0b0ae38acecc4e1dc585940ff6f88 ]
+
+The MSM8937 platform doesn't have DSC blocks nor does have it DSC
+registers in the PINGPONG block. Drop the DPU_PINGPONG_DSC feature bit
+from the PINGPONG's feature mask and, as it is the only remaining bit,
+drop the .features assignment completely.
+
+Fixes: c079680bb0fa ("drm/msm/dpu: Add support for MSM8937")
+Reported-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Patchwork: https://patchwork.freedesktop.org/patch/640299/
+Link: https://lore.kernel.org/r/20250301-dpu-fix-catalog-v2-1-498271be8b50@linaro.org
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_14_msm8937.h | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_14_msm8937.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_14_msm8937.h
+index ad60089f18ea6..39027a21c6fee 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_14_msm8937.h
++++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_14_msm8937.h
+@@ -100,14 +100,12 @@ static const struct dpu_pingpong_cfg msm8937_pp[] = {
+       {
+               .name = "pingpong_0", .id = PINGPONG_0,
+               .base = 0x70000, .len = 0xd4,
+-              .features = PINGPONG_MSM8996_MASK,
+               .sblk = &msm8996_pp_sblk,
+               .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
+               .intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12),
+       }, {
+               .name = "pingpong_1", .id = PINGPONG_1,
+               .base = 0x70800, .len = 0xd4,
+-              .features = PINGPONG_MSM8996_MASK,
+               .sblk = &msm8996_pp_sblk,
+               .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
+               .intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13),
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-msm-dpu-remove-dsc-feature-bit-for-pingpong-on-m.patch-13942 b/queue-6.15/drm-msm-dpu-remove-dsc-feature-bit-for-pingpong-on-m.patch-13942
new file mode 100644 (file)
index 0000000..c2bd791
--- /dev/null
@@ -0,0 +1,42 @@
+From ddd2dbef1d37b4f45b0982b1c3da482f2c5c7c61 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 Mar 2025 11:24:55 +0200
+Subject: drm/msm/dpu: remove DSC feature bit for PINGPONG on MSM8917
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 5be98120115c46907921e29344291628cf79912a ]
+
+The MSM8917 platform doesn't have DSC blocks nor does have it DSC
+registers in the PINGPONG block. Drop the DPU_PINGPONG_DSC feature bit
+from the PINGPONG's feature mask and, as it is the only remaining bit,
+drop the .features assignment completely.
+
+Fixes: 62af6e1cb596 ("drm/msm/dpu: Add support for MSM8917")
+Reported-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Patchwork: https://patchwork.freedesktop.org/patch/640301/
+Link: https://lore.kernel.org/r/20250301-dpu-fix-catalog-v2-2-498271be8b50@linaro.org
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_15_msm8917.h | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_15_msm8917.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_15_msm8917.h
+index a1cf89a0a42d5..8d1b43ea1663c 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_15_msm8917.h
++++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_15_msm8917.h
+@@ -93,7 +93,6 @@ static const struct dpu_pingpong_cfg msm8917_pp[] = {
+       {
+               .name = "pingpong_0", .id = PINGPONG_0,
+               .base = 0x70000, .len = 0xd4,
+-              .features = PINGPONG_MSM8996_MASK,
+               .sblk = &msm8996_pp_sblk,
+               .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
+               .intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12),
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-msm-dpu-remove-dsc-feature-bit-for-pingpong-on-m.patch-8756 b/queue-6.15/drm-msm-dpu-remove-dsc-feature-bit-for-pingpong-on-m.patch-8756
new file mode 100644 (file)
index 0000000..801211c
--- /dev/null
@@ -0,0 +1,49 @@
+From 318fd7a91f28f0651c293c3ddc82d160a21420c4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 Mar 2025 11:24:56 +0200
+Subject: drm/msm/dpu: remove DSC feature bit for PINGPONG on MSM8953
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 5232a29ebc74df4abf790147a06db451d824cd92 ]
+
+The MSM8953 platform doesn't have DSC blocks nor does have it DSC
+registers in the PINGPONG block. Drop the DPU_PINGPONG_DSC feature bit
+from the PINGPONG's feature mask and, as it is the only remaining bit,
+drop the .features assignment completely.
+
+Fixes: 7a6109ce1c2c ("drm/msm/dpu: Add support for MSM8953")
+Reported-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Patchwork: https://patchwork.freedesktop.org/patch/640303/
+Link: https://lore.kernel.org/r/20250301-dpu-fix-catalog-v2-3-498271be8b50@linaro.org
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_16_msm8953.h | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_16_msm8953.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_16_msm8953.h
+index eea9b80e2287a..16c12499b24bb 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_16_msm8953.h
++++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_16_msm8953.h
+@@ -100,14 +100,12 @@ static const struct dpu_pingpong_cfg msm8953_pp[] = {
+       {
+               .name = "pingpong_0", .id = PINGPONG_0,
+               .base = 0x70000, .len = 0xd4,
+-              .features = PINGPONG_MSM8996_MASK,
+               .sblk = &msm8996_pp_sblk,
+               .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
+               .intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12),
+       }, {
+               .name = "pingpong_1", .id = PINGPONG_1,
+               .base = 0x70800, .len = 0xd4,
+-              .features = PINGPONG_MSM8996_MASK,
+               .sblk = &msm8996_pp_sblk,
+               .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
+               .intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13),
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-panel-samsung-sofef00-drop-s6e3fc2x01-support.patch b/queue-6.15/drm-panel-samsung-sofef00-drop-s6e3fc2x01-support.patch
new file mode 100644 (file)
index 0000000..97d4620
--- /dev/null
@@ -0,0 +1,96 @@
+From 05a1077d4addee90e61f3f9e3be21db624a08585 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Apr 2025 18:31:44 +0200
+Subject: drm/panel: samsung-sofef00: Drop s6e3fc2x01 support
+
+From: Casey Connolly <casey.connolly@linaro.org>
+
+[ Upstream commit e1eb7293ab4107e9e19fa609835e657fe30dfec7 ]
+
+We never properly supported this panel and always used the wrong init
+sequence. Drop support so we can move it to it's own proper driver.
+
+Fixes: 5933baa36e26 ("drm/panel/samsung-sofef00: Add panel for OnePlus 6/T devices")
+Signed-off-by: Casey Connolly <casey.connolly@linaro.org>
+Signed-off-by: David Heidelberg <david@ixit.cz>
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://lore.kernel.org/r/20250419-drop-s6e3fc2x01-support-v1-1-05edfe0d27aa@ixit.cz
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/panel/panel-samsung-sofef00.c | 34 ++-----------------
+ 1 file changed, 2 insertions(+), 32 deletions(-)
+
+diff --git a/drivers/gpu/drm/panel/panel-samsung-sofef00.c b/drivers/gpu/drm/panel/panel-samsung-sofef00.c
+index 04ce925b3d9db..49cfa84b34f0c 100644
+--- a/drivers/gpu/drm/panel/panel-samsung-sofef00.c
++++ b/drivers/gpu/drm/panel/panel-samsung-sofef00.c
+@@ -22,7 +22,6 @@ struct sofef00_panel {
+       struct mipi_dsi_device *dsi;
+       struct regulator *supply;
+       struct gpio_desc *reset_gpio;
+-      const struct drm_display_mode *mode;
+ };
+ static inline
+@@ -159,26 +158,11 @@ static const struct drm_display_mode enchilada_panel_mode = {
+       .height_mm = 145,
+ };
+-static const struct drm_display_mode fajita_panel_mode = {
+-      .clock = (1080 + 72 + 16 + 36) * (2340 + 32 + 4 + 18) * 60 / 1000,
+-      .hdisplay = 1080,
+-      .hsync_start = 1080 + 72,
+-      .hsync_end = 1080 + 72 + 16,
+-      .htotal = 1080 + 72 + 16 + 36,
+-      .vdisplay = 2340,
+-      .vsync_start = 2340 + 32,
+-      .vsync_end = 2340 + 32 + 4,
+-      .vtotal = 2340 + 32 + 4 + 18,
+-      .width_mm = 68,
+-      .height_mm = 145,
+-};
+-
+ static int sofef00_panel_get_modes(struct drm_panel *panel, struct drm_connector *connector)
+ {
+       struct drm_display_mode *mode;
+-      struct sofef00_panel *ctx = to_sofef00_panel(panel);
+-      mode = drm_mode_duplicate(connector->dev, ctx->mode);
++      mode = drm_mode_duplicate(connector->dev, &enchilada_panel_mode);
+       if (!mode)
+               return -ENOMEM;
+@@ -239,13 +223,6 @@ static int sofef00_panel_probe(struct mipi_dsi_device *dsi)
+       if (!ctx)
+               return -ENOMEM;
+-      ctx->mode = of_device_get_match_data(dev);
+-
+-      if (!ctx->mode) {
+-              dev_err(dev, "Missing device mode\n");
+-              return -ENODEV;
+-      }
+-
+       ctx->supply = devm_regulator_get(dev, "vddio");
+       if (IS_ERR(ctx->supply))
+               return dev_err_probe(dev, PTR_ERR(ctx->supply),
+@@ -295,14 +272,7 @@ static void sofef00_panel_remove(struct mipi_dsi_device *dsi)
+ }
+ static const struct of_device_id sofef00_panel_of_match[] = {
+-      { // OnePlus 6 / enchilada
+-              .compatible = "samsung,sofef00",
+-              .data = &enchilada_panel_mode,
+-      },
+-      { // OnePlus 6T / fajita
+-              .compatible = "samsung,s6e3fc2x01",
+-              .data = &fajita_panel_mode,
+-      },
++      { .compatible = "samsung,sofef00" },
+       { /* sentinel */ }
+ };
+ MODULE_DEVICE_TABLE(of, sofef00_panel_of_match);
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-panel-simple-fix-the-warnings-for-the-evervision.patch b/queue-6.15/drm-panel-simple-fix-the-warnings-for-the-evervision.patch
new file mode 100644 (file)
index 0000000..afbc77d
--- /dev/null
@@ -0,0 +1,47 @@
+From 6a4664f526343a3e0f9533178ade8aa7b48143fd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 May 2025 09:41:10 +0200
+Subject: drm/panel-simple: fix the warnings for the Evervision VGG644804
+
+From: Michael Walle <mwalle@kernel.org>
+
+[ Upstream commit 5dc1ea903588a73fb03b3a3e5a041a7c63a4bccd ]
+
+The panel lacked the connector type which causes a warning. Adding the
+connector type reveals wrong bus_flags and bits per pixel. Fix all of
+it.
+
+Fixes: 1319f2178bdf ("drm/panel-simple: add Evervision VGG644804 panel entry")
+Signed-off-by: Michael Walle <mwalle@kernel.org>
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://lore.kernel.org/r/20250520074110.655114-1-mwalle@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/panel/panel-simple.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
+index 33a37539de574..3aaac96c0bfbf 100644
+--- a/drivers/gpu/drm/panel/panel-simple.c
++++ b/drivers/gpu/drm/panel/panel-simple.c
+@@ -2199,13 +2199,14 @@ static const struct display_timing evervision_vgg644804_timing = {
+ static const struct panel_desc evervision_vgg644804 = {
+       .timings = &evervision_vgg644804_timing,
+       .num_timings = 1,
+-      .bpc = 8,
++      .bpc = 6,
+       .size = {
+               .width = 115,
+               .height = 86,
+       },
+       .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
+-      .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE,
++      .bus_flags = DRM_BUS_FLAG_DE_HIGH,
++      .connector_type = DRM_MODE_CONNECTOR_LVDS,
+ };
+ static const struct display_timing evervision_vgg804821_timing = {
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-panic-clean-clippy-warning.patch b/queue-6.15/drm-panic-clean-clippy-warning.patch
new file mode 100644 (file)
index 0000000..9fa7166
--- /dev/null
@@ -0,0 +1,49 @@
+From e0551f88519412b8b0939d041018a6934c7582ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Mar 2025 10:32:42 +0100
+Subject: drm/panic: clean Clippy warning
+
+From: Miguel Ojeda <ojeda@kernel.org>
+
+[ Upstream commit 57145afa3326947154c3a890b1118774b55212a0 ]
+
+Clippy warns:
+
+    error: manual implementation of an assign operation
+       --> drivers/gpu/drm/drm_panic_qr.rs:418:25
+        |
+    418 |                         self.carry = self.carry % pow;
+        |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `self.carry %= pow`
+        |
+        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#assign_op_pattern
+
+Thus clean it up.
+
+Fixes: dbed4a797e00 ("drm/panic: Better binary encoding in QR code")
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Reviewed-by: Alice Ryhl <aliceryhl@google.com>
+Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
+Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250303093242.1011790-1-ojeda@kernel.org
+Stable-dep-of: 675008f196ca ("drm/panic: Use a decimal fifo to avoid u64 by u64 divide")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_panic_qr.rs | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/drm_panic_qr.rs b/drivers/gpu/drm/drm_panic_qr.rs
+index f2a99681b9985..ba6724aed51c9 100644
+--- a/drivers/gpu/drm/drm_panic_qr.rs
++++ b/drivers/gpu/drm/drm_panic_qr.rs
+@@ -415,7 +415,7 @@ impl Iterator for SegmentIterator<'_> {
+                         self.carry_len -= out_len;
+                         let pow = u64::pow(10, self.carry_len as u32);
+                         let out = (self.carry / pow) as u16;
+-                        self.carry = self.carry % pow;
++                        self.carry %= pow;
+                         Some((out, NUM_CHARS_BITS[out_len]))
+                     }
+                 }
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-panic-use-a-decimal-fifo-to-avoid-u64-by-u64-div.patch b/queue-6.15/drm-panic-use-a-decimal-fifo-to-avoid-u64-by-u64-div.patch
new file mode 100644 (file)
index 0000000..54aa17d
--- /dev/null
@@ -0,0 +1,130 @@
+From 68fb18e0be3dbc0560abe6fbae5b19a2e6b28399 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Apr 2025 18:48:16 +0200
+Subject: drm/panic: Use a decimal fifo to avoid u64 by u64 divide
+
+From: Jocelyn Falempe <jfalempe@redhat.com>
+
+[ Upstream commit 675008f196ca5c8d8413204e861cc2a2238581aa ]
+
+On 32bits ARM, u64/u64 is not supported [1], so change the algorithm
+to use a simple fifo with decimal digits as u8 instead.
+This is slower but should compile on all architecture.
+
+Link: https://lore.kernel.org/dri-devel/CANiq72ke45eOwckMhWHvmwxc03dxr4rnxxKvx+HvWdBLopZfrQ@mail.gmail.com/ [1]
+Reported-by: Miguel Ojeda <ojeda@kernel.org>
+Closes: https://lore.kernel.org/dri-devel/CANiq72ke45eOwckMhWHvmwxc03dxr4rnxxKvx+HvWdBLopZfrQ@mail.gmail.com/
+Fixes: ccb8ce526807 ("ARM: 9441/1: rust: Enable Rust support for ARMv7")
+Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
+Link: https://lore.kernel.org/r/20250418165059.560503-1-jfalempe@redhat.com
+Acked-by: Javier Martinez Canillas <javierm@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_panic_qr.rs | 71 ++++++++++++++++++++++-----------
+ 1 file changed, 48 insertions(+), 23 deletions(-)
+
+diff --git a/drivers/gpu/drm/drm_panic_qr.rs b/drivers/gpu/drm/drm_panic_qr.rs
+index ba6724aed51c9..de2ddf5dbbd3f 100644
+--- a/drivers/gpu/drm/drm_panic_qr.rs
++++ b/drivers/gpu/drm/drm_panic_qr.rs
+@@ -366,8 +366,48 @@ impl Segment<'_> {
+         SegmentIterator {
+             segment: self,
+             offset: 0,
+-            carry: 0,
+-            carry_len: 0,
++            decfifo: Default::default(),
++        }
++    }
++}
++
++/// Max fifo size is 17 (max push) + 2 (max remaining)
++const MAX_FIFO_SIZE: usize = 19;
++
++/// A simple Decimal digit FIFO
++#[derive(Default)]
++struct DecFifo {
++    decimals: [u8; MAX_FIFO_SIZE],
++    len: usize,
++}
++
++impl DecFifo {
++    fn push(&mut self, data: u64, len: usize) {
++        let mut chunk = data;
++        for i in (0..self.len).rev() {
++            self.decimals[i + len] = self.decimals[i];
++        }
++        for i in 0..len {
++            self.decimals[i] = (chunk % 10) as u8;
++            chunk /= 10;
++        }
++        self.len += len;
++    }
++
++    /// Pop 3 decimal digits from the FIFO
++    fn pop3(&mut self) -> Option<(u16, usize)> {
++        if self.len == 0 {
++            None
++        } else {
++            let poplen = 3.min(self.len);
++            self.len -= poplen;
++            let mut out = 0;
++            let mut exp = 1;
++            for i in 0..poplen {
++                out += self.decimals[self.len + i] as u16 * exp;
++                exp *= 10;
++            }
++            Some((out, NUM_CHARS_BITS[poplen]))
+         }
+     }
+ }
+@@ -375,8 +415,7 @@ impl Segment<'_> {
+ struct SegmentIterator<'a> {
+     segment: &'a Segment<'a>,
+     offset: usize,
+-    carry: u64,
+-    carry_len: usize,
++    decfifo: DecFifo,
+ }
+ impl Iterator for SegmentIterator<'_> {
+@@ -394,31 +433,17 @@ impl Iterator for SegmentIterator<'_> {
+                 }
+             }
+             Segment::Numeric(data) => {
+-                if self.carry_len < 3 && self.offset < data.len() {
+-                    // If there are less than 3 decimal digits in the carry,
+-                    // take the next 7 bytes of input, and add them to the carry.
++                if self.decfifo.len < 3 && self.offset < data.len() {
++                    // If there are less than 3 decimal digits in the fifo,
++                    // take the next 7 bytes of input, and push them to the fifo.
+                     let mut buf = [0u8; 8];
+                     let len = 7.min(data.len() - self.offset);
+                     buf[..len].copy_from_slice(&data[self.offset..self.offset + len]);
+                     let chunk = u64::from_le_bytes(buf);
+-                    let pow = u64::pow(10, BYTES_TO_DIGITS[len] as u32);
+-                    self.carry = chunk + self.carry * pow;
++                    self.decfifo.push(chunk, BYTES_TO_DIGITS[len]);
+                     self.offset += len;
+-                    self.carry_len += BYTES_TO_DIGITS[len];
+-                }
+-                match self.carry_len {
+-                    0 => None,
+-                    len => {
+-                        // take the next 3 decimal digits of the carry
+-                        // and return 10bits of numeric data.
+-                        let out_len = 3.min(len);
+-                        self.carry_len -= out_len;
+-                        let pow = u64::pow(10, self.carry_len as u32);
+-                        let out = (self.carry / pow) as u16;
+-                        self.carry %= pow;
+-                        Some((out, NUM_CHARS_BITS[out_len]))
+-                    }
+                 }
++                self.decfifo.pop3()
+             }
+         }
+     }
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-panthor-call-panthor_gpu_coherency_init-after-pm.patch b/queue-6.15/drm-panthor-call-panthor_gpu_coherency_init-after-pm.patch
new file mode 100644 (file)
index 0000000..db77fb3
--- /dev/null
@@ -0,0 +1,61 @@
+From c1b51850d16716d4bf82d271b288e5922a8dcf6a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Apr 2025 10:09:30 +0200
+Subject: drm/panthor: Call panthor_gpu_coherency_init() after PM resume()
+
+From: Boris Brezillon <boris.brezillon@collabora.com>
+
+[ Upstream commit 7d5a3b22f5b58ef89ab8770d7a44c24eecde8d66 ]
+
+When the device is coherent, panthor_gpu_coherency_init() will read
+GPU_COHERENCY_FEATURES to make sure the GPU supports the ACE-Lite
+coherency protocol, which will fail if the clocks/power-domains are
+not enabled when the read is done. Move the
+panthor_gpu_coherency_init() call after the device has been resumed
+to prevent that.
+
+Changes in v2:
+- Add Liviu's R-b
+
+Changes in v3:
+- Add Steve's R-b
+
+Fixes: dd7db8d911a1 ("drm/panthor: Explicitly set the coherency mode")
+Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
+Reviewed-by: Steven Price <steven.price@arm.com>
+Link: https://lore.kernel.org/r/20250404080933.2912674-3-boris.brezillon@collabora.com
+Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/panthor/panthor_device.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/panthor/panthor_device.c b/drivers/gpu/drm/panthor/panthor_device.c
+index a9da1d1eeb707..c73c1608d6e68 100644
+--- a/drivers/gpu/drm/panthor/panthor_device.c
++++ b/drivers/gpu/drm/panthor/panthor_device.c
+@@ -171,10 +171,6 @@ int panthor_device_init(struct panthor_device *ptdev)
+       struct page *p;
+       int ret;
+-      ret = panthor_gpu_coherency_init(ptdev);
+-      if (ret)
+-              return ret;
+-
+       init_completion(&ptdev->unplug.done);
+       ret = drmm_mutex_init(&ptdev->base, &ptdev->unplug.lock);
+       if (ret)
+@@ -247,6 +243,10 @@ int panthor_device_init(struct panthor_device *ptdev)
+       if (ret)
+               goto err_rpm_put;
++      ret = panthor_gpu_coherency_init(ptdev);
++      if (ret)
++              return ret;
++
+       ret = panthor_mmu_init(ptdev);
+       if (ret)
+               goto err_unplug_gpu;
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-panthor-fix-gpu_coherency_ace-_lite-definitions.patch b/queue-6.15/drm-panthor-fix-gpu_coherency_ace-_lite-definitions.patch
new file mode 100644 (file)
index 0000000..505bc13
--- /dev/null
@@ -0,0 +1,47 @@
+From e2572fec8497fd715928e6a016a199b2abc31b63 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Apr 2025 10:09:29 +0200
+Subject: drm/panthor: Fix GPU_COHERENCY_ACE[_LITE] definitions
+
+From: Boris Brezillon <boris.brezillon@collabora.com>
+
+[ Upstream commit d1df2907fb69df56aad8e4a0734dac0778c234a7 ]
+
+GPU_COHERENCY_ACE and GPU_COHERENCY_ACE_LITE definitions have been
+swapped.
+
+Changes in v2:
+- New patch
+
+Changes in v3:
+- Add Steve's R-b
+
+Reported-by: Liviu Dudau <liviu.dudau@arm.com>
+Fixes: 546b366600ef ("drm/panthor: Add GPU register definitions")
+Reviewed-by: Steven Price <steven.price@arm.com>
+Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
+Link: https://lore.kernel.org/r/20250404080933.2912674-2-boris.brezillon@collabora.com
+Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/panthor/panthor_regs.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/panthor/panthor_regs.h b/drivers/gpu/drm/panthor/panthor_regs.h
+index b7b3b3add1662..a7a323dc5cf92 100644
+--- a/drivers/gpu/drm/panthor/panthor_regs.h
++++ b/drivers/gpu/drm/panthor/panthor_regs.h
+@@ -133,8 +133,8 @@
+ #define GPU_COHERENCY_PROT_BIT(name)                  BIT(GPU_COHERENCY_  ## name)
+ #define GPU_COHERENCY_PROTOCOL                                0x304
+-#define   GPU_COHERENCY_ACE                           0
+-#define   GPU_COHERENCY_ACE_LITE                      1
++#define   GPU_COHERENCY_ACE_LITE                      0
++#define   GPU_COHERENCY_ACE                           1
+ #define   GPU_COHERENCY_NONE                          31
+ #define MCU_CONTROL                                   0x700
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-panthor-fix-the-panthor_gpu_coherency_init-error.patch b/queue-6.15/drm-panthor-fix-the-panthor_gpu_coherency_init-error.patch
new file mode 100644 (file)
index 0000000..a8aaab7
--- /dev/null
@@ -0,0 +1,41 @@
+From a9e5c2faa49cfd72909d6caa3389a652ab06ffbb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Apr 2025 15:01:20 +0200
+Subject: drm/panthor: Fix the panthor_gpu_coherency_init() error path
+
+From: Boris Brezillon <boris.brezillon@collabora.com>
+
+[ Upstream commit 938aaed555f3add76531cd204e2d4128ecb84ace ]
+
+The panthor_gpu_coherency_init() call has been moved around, but the
+error path hasn't been adjusted accordingly. Make sure we undo what
+has been done before this call in case of failure.
+
+Fixes: 7d5a3b22f5b5 ("drm/panthor: Call panthor_gpu_coherency_init() after PM resume()")
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Closes: https://lore.kernel.org/dri-devel/4da470aa-4f84-460e-aff8-dabc8cc4da15@stanley.mountain/T/#t
+Reviewed-by: Steven Price <steven.price@arm.com>
+Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
+Link: https://lore.kernel.org/r/20250414130120.581274-1-boris.brezillon@collabora.com
+Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/panthor/panthor_device.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/panthor/panthor_device.c b/drivers/gpu/drm/panthor/panthor_device.c
+index c73c1608d6e68..1e8811c6716df 100644
+--- a/drivers/gpu/drm/panthor/panthor_device.c
++++ b/drivers/gpu/drm/panthor/panthor_device.c
+@@ -245,7 +245,7 @@ int panthor_device_init(struct panthor_device *ptdev)
+       ret = panthor_gpu_coherency_init(ptdev);
+       if (ret)
+-              return ret;
++              goto err_unplug_gpu;
+       ret = panthor_mmu_init(ptdev);
+       if (ret)
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-panthor-update-panthor_mmu-irq-mask-when-needed.patch b/queue-6.15/drm-panthor-update-panthor_mmu-irq-mask-when-needed.patch
new file mode 100644 (file)
index 0000000..570be5e
--- /dev/null
@@ -0,0 +1,44 @@
+From ed38060cb61a75e35679349b966169f2d4d030ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Apr 2025 10:09:31 +0200
+Subject: drm/panthor: Update panthor_mmu::irq::mask when needed
+
+From: Boris Brezillon <boris.brezillon@collabora.com>
+
+[ Upstream commit 8ba64cf2f358079d09faba7529aad2b0a46c7903 ]
+
+When we clear the faulty bits in the AS mask, we also need to update
+the panthor_mmu::irq::mask field otherwise our IRQ handler won't get
+called again until the GPU is reset.
+
+Changes in v2:
+- Add Liviu's R-b
+
+Changes in v3:
+- Add Steve's R-b
+
+Fixes: 647810ec2476 ("drm/panthor: Add the MMU/VM logical block")
+Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
+Reviewed-by: Steven Price <steven.price@arm.com>
+Link: https://lore.kernel.org/r/20250404080933.2912674-4-boris.brezillon@collabora.com
+Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/panthor/panthor_mmu.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c
+index 12a02e28f50fd..7cca97d298ea1 100644
+--- a/drivers/gpu/drm/panthor/panthor_mmu.c
++++ b/drivers/gpu/drm/panthor/panthor_mmu.c
+@@ -781,6 +781,7 @@ int panthor_vm_active(struct panthor_vm *vm)
+       if (ptdev->mmu->as.faulty_mask & panthor_mmu_as_fault_mask(ptdev, as)) {
+               gpu_write(ptdev, MMU_INT_CLEAR, panthor_mmu_as_fault_mask(ptdev, as));
+               ptdev->mmu->as.faulty_mask &= ~panthor_mmu_as_fault_mask(ptdev, as);
++              ptdev->mmu->irq.mask |= panthor_mmu_as_fault_mask(ptdev, as);
+               gpu_write(ptdev, MMU_INT_MASK, ~ptdev->mmu->as.faulty_mask);
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-rcar-du-fix-memory-leak-in-rcar_du_vsps_init.patch b/queue-6.15/drm-rcar-du-fix-memory-leak-in-rcar_du_vsps_init.patch
new file mode 100644 (file)
index 0000000..8ca593a
--- /dev/null
@@ -0,0 +1,61 @@
+From cd408515078237f70d0c9664412c2e6aaeb9b561 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Nov 2023 12:24:24 +0000
+Subject: drm: rcar-du: Fix memory leak in rcar_du_vsps_init()
+
+From: Biju Das <biju.das.jz@bp.renesas.com>
+
+[ Upstream commit 91e3bf09a90bb4340c0c3c51396e7531555efda4 ]
+
+The rcar_du_vsps_init() doesn't free the np allocated by
+of_parse_phandle_with_fixed_args() for the non-error case.
+
+Fix memory leak for the non-error case.
+
+While at it, replace the label 'error'->'done' as it applies to non-error
+case as well and update the error check condition for rcar_du_vsp_init()
+to avoid breakage in future, if it returns positive value.
+
+Fixes: 3e81374e2014 ("drm: rcar-du: Support multiple sources from the same VSP")
+Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
+Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
+Link: https://lore.kernel.org/r/20231116122424.80136-1-biju.das.jz@bp.renesas.com
+Signed-off-by: Tomi Valkeinen <tomi.valkeinen+renesas@ideasonboard.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c
+index 70d8ad065bfa1..4c8fe83dd6101 100644
+--- a/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c
++++ b/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c
+@@ -705,7 +705,7 @@ static int rcar_du_vsps_init(struct rcar_du_device *rcdu)
+               ret = of_parse_phandle_with_fixed_args(np, vsps_prop_name,
+                                                      cells, i, &args);
+               if (ret < 0)
+-                      goto error;
++                      goto done;
+               /*
+                * Add the VSP to the list or update the corresponding existing
+@@ -743,13 +743,11 @@ static int rcar_du_vsps_init(struct rcar_du_device *rcdu)
+               vsp->dev = rcdu;
+               ret = rcar_du_vsp_init(vsp, vsps[i].np, vsps[i].crtcs_mask);
+-              if (ret < 0)
+-                      goto error;
++              if (ret)
++                      goto done;
+       }
+-      return 0;
+-
+-error:
++done:
+       for (i = 0; i < ARRAY_SIZE(vsps); ++i)
+               of_node_put(vsps[i].np);
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-tegra-rgb-fix-the-unbound-reference-count.patch b/queue-6.15/drm-tegra-rgb-fix-the-unbound-reference-count.patch
new file mode 100644 (file)
index 0000000..41f1ab6
--- /dev/null
@@ -0,0 +1,57 @@
+From 4f85ed64ff8d7b8972719fbfe4983397c2d6aefd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Feb 2025 11:21:35 +0000
+Subject: drm/tegra: rgb: Fix the unbound reference count
+
+From: Biju Das <biju.das.jz@bp.renesas.com>
+
+[ Upstream commit 3c3642335065c3bde0742b0edc505b6ea8fdc2b3 ]
+
+The of_get_child_by_name() increments the refcount in tegra_dc_rgb_probe,
+but the driver does not decrement the refcount during unbind. Fix the
+unbound reference count using devm_add_action_or_reset() helper.
+
+Fixes: d8f4a9eda006 ("drm: Add NVIDIA Tegra20 support")
+Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Link: https://lore.kernel.org/r/20250205112137.36055-1-biju.das.jz@bp.renesas.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/tegra/rgb.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/tegra/rgb.c b/drivers/gpu/drm/tegra/rgb.c
+index 1e8ec50b759e4..ff5a749710db3 100644
+--- a/drivers/gpu/drm/tegra/rgb.c
++++ b/drivers/gpu/drm/tegra/rgb.c
+@@ -200,6 +200,11 @@ static const struct drm_encoder_helper_funcs tegra_rgb_encoder_helper_funcs = {
+       .atomic_check = tegra_rgb_encoder_atomic_check,
+ };
++static void tegra_dc_of_node_put(void *data)
++{
++      of_node_put(data);
++}
++
+ int tegra_dc_rgb_probe(struct tegra_dc *dc)
+ {
+       struct device_node *np;
+@@ -207,7 +212,14 @@ int tegra_dc_rgb_probe(struct tegra_dc *dc)
+       int err;
+       np = of_get_child_by_name(dc->dev->of_node, "rgb");
+-      if (!np || !of_device_is_available(np))
++      if (!np)
++              return -ENODEV;
++
++      err = devm_add_action_or_reset(dc->dev, tegra_dc_of_node_put, np);
++      if (err < 0)
++              return err;
++
++      if (!of_device_is_available(np))
+               return -ENODEV;
+       rgb = devm_kzalloc(dc->dev, sizeof(*rgb), GFP_KERNEL);
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-v3d-associate-a-v3d-tech-revision-to-all-support.patch b/queue-6.15/drm-v3d-associate-a-v3d-tech-revision-to-all-support.patch
new file mode 100644 (file)
index 0000000..dbfb734
--- /dev/null
@@ -0,0 +1,450 @@
+From 7de0c448794493751b6e5d62ea351d2d524fc2a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Mar 2025 22:01:09 -0300
+Subject: drm/v3d: Associate a V3D tech revision to all supported devices
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Maíra Canal <mcanal@igalia.com>
+
+[ Upstream commit 76dbd0973c555037931d2ed055a4a69e592caad4 ]
+
+The V3D driver currently determines the GPU tech version (33, 41...)
+by reading a register. This approach has worked so far since this
+information wasn’t needed before powering on the GPU.
+
+V3D 7.1 introduces new registers that must be written to power on the
+GPU, requiring us to know the V3D version beforehand. To address this,
+associate each supported SoC with the corresponding VideoCore GPU version
+as part of the device data.
+
+To prevent possible mistakes, add an assertion to verify that the version
+specified in the device data matches the one reported by the hardware.
+If there is a mismatch, the kernel will trigger a warning.
+
+With the goal of maintaining consistency around the driver, use `enum
+v3d_gen` to assign values to `v3d->ver` and for comparisons with other
+V3D generations. Note that all mentions of unsupported or non-existing V3D
+generations (such as V3D 4.0) were removed by this commit and replaced
+with supported generations without functional changes.
+
+Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
+Reviewed-by: Stefan Wahren <wahrenst@gmx.net>
+Signed-off-by: Maíra Canal <mcanal@igalia.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250317-v3d-gpu-reset-fixes-v6-1-f3ee7717ed17@igalia.com
+Stable-dep-of: d0e4c6537005 ("drm/v3d: fix client obtained from axi_ids on V3D 4.1")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/v3d/v3d_debugfs.c | 126 +++++++++++++++---------------
+ drivers/gpu/drm/v3d/v3d_drv.c     |  22 ++++--
+ drivers/gpu/drm/v3d/v3d_drv.h     |  11 ++-
+ drivers/gpu/drm/v3d/v3d_gem.c     |  10 +--
+ drivers/gpu/drm/v3d/v3d_irq.c     |   6 +-
+ drivers/gpu/drm/v3d/v3d_perfmon.c |   4 +-
+ drivers/gpu/drm/v3d/v3d_sched.c   |   6 +-
+ 7 files changed, 101 insertions(+), 84 deletions(-)
+
+diff --git a/drivers/gpu/drm/v3d/v3d_debugfs.c b/drivers/gpu/drm/v3d/v3d_debugfs.c
+index 76816f2551c10..7e789e181af0a 100644
+--- a/drivers/gpu/drm/v3d/v3d_debugfs.c
++++ b/drivers/gpu/drm/v3d/v3d_debugfs.c
+@@ -21,74 +21,74 @@ struct v3d_reg_def {
+ };
+ static const struct v3d_reg_def v3d_hub_reg_defs[] = {
+-      REGDEF(33, 42, V3D_HUB_AXICFG),
+-      REGDEF(33, 71, V3D_HUB_UIFCFG),
+-      REGDEF(33, 71, V3D_HUB_IDENT0),
+-      REGDEF(33, 71, V3D_HUB_IDENT1),
+-      REGDEF(33, 71, V3D_HUB_IDENT2),
+-      REGDEF(33, 71, V3D_HUB_IDENT3),
+-      REGDEF(33, 71, V3D_HUB_INT_STS),
+-      REGDEF(33, 71, V3D_HUB_INT_MSK_STS),
+-
+-      REGDEF(33, 71, V3D_MMU_CTL),
+-      REGDEF(33, 71, V3D_MMU_VIO_ADDR),
+-      REGDEF(33, 71, V3D_MMU_VIO_ID),
+-      REGDEF(33, 71, V3D_MMU_DEBUG_INFO),
+-
+-      REGDEF(71, 71, V3D_GMP_STATUS(71)),
+-      REGDEF(71, 71, V3D_GMP_CFG(71)),
+-      REGDEF(71, 71, V3D_GMP_VIO_ADDR(71)),
++      REGDEF(V3D_GEN_33, V3D_GEN_42, V3D_HUB_AXICFG),
++      REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_HUB_UIFCFG),
++      REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_HUB_IDENT0),
++      REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_HUB_IDENT1),
++      REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_HUB_IDENT2),
++      REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_HUB_IDENT3),
++      REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_HUB_INT_STS),
++      REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_HUB_INT_MSK_STS),
++
++      REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_MMU_CTL),
++      REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_MMU_VIO_ADDR),
++      REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_MMU_VIO_ID),
++      REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_MMU_DEBUG_INFO),
++
++      REGDEF(V3D_GEN_71, V3D_GEN_71, V3D_GMP_STATUS(71)),
++      REGDEF(V3D_GEN_71, V3D_GEN_71, V3D_GMP_CFG(71)),
++      REGDEF(V3D_GEN_71, V3D_GEN_71, V3D_GMP_VIO_ADDR(71)),
+ };
+ static const struct v3d_reg_def v3d_gca_reg_defs[] = {
+-      REGDEF(33, 33, V3D_GCA_SAFE_SHUTDOWN),
+-      REGDEF(33, 33, V3D_GCA_SAFE_SHUTDOWN_ACK),
++      REGDEF(V3D_GEN_33, V3D_GEN_33, V3D_GCA_SAFE_SHUTDOWN),
++      REGDEF(V3D_GEN_33, V3D_GEN_33, V3D_GCA_SAFE_SHUTDOWN_ACK),
+ };
+ static const struct v3d_reg_def v3d_core_reg_defs[] = {
+-      REGDEF(33, 71, V3D_CTL_IDENT0),
+-      REGDEF(33, 71, V3D_CTL_IDENT1),
+-      REGDEF(33, 71, V3D_CTL_IDENT2),
+-      REGDEF(33, 71, V3D_CTL_MISCCFG),
+-      REGDEF(33, 71, V3D_CTL_INT_STS),
+-      REGDEF(33, 71, V3D_CTL_INT_MSK_STS),
+-      REGDEF(33, 71, V3D_CLE_CT0CS),
+-      REGDEF(33, 71, V3D_CLE_CT0CA),
+-      REGDEF(33, 71, V3D_CLE_CT0EA),
+-      REGDEF(33, 71, V3D_CLE_CT1CS),
+-      REGDEF(33, 71, V3D_CLE_CT1CA),
+-      REGDEF(33, 71, V3D_CLE_CT1EA),
+-
+-      REGDEF(33, 71, V3D_PTB_BPCA),
+-      REGDEF(33, 71, V3D_PTB_BPCS),
+-
+-      REGDEF(33, 42, V3D_GMP_STATUS(33)),
+-      REGDEF(33, 42, V3D_GMP_CFG(33)),
+-      REGDEF(33, 42, V3D_GMP_VIO_ADDR(33)),
+-
+-      REGDEF(33, 71, V3D_ERR_FDBGO),
+-      REGDEF(33, 71, V3D_ERR_FDBGB),
+-      REGDEF(33, 71, V3D_ERR_FDBGS),
+-      REGDEF(33, 71, V3D_ERR_STAT),
++      REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_CTL_IDENT0),
++      REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_CTL_IDENT1),
++      REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_CTL_IDENT2),
++      REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_CTL_MISCCFG),
++      REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_CTL_INT_STS),
++      REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_CTL_INT_MSK_STS),
++      REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_CLE_CT0CS),
++      REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_CLE_CT0CA),
++      REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_CLE_CT0EA),
++      REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_CLE_CT1CS),
++      REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_CLE_CT1CA),
++      REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_CLE_CT1EA),
++
++      REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_PTB_BPCA),
++      REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_PTB_BPCS),
++
++      REGDEF(V3D_GEN_33, V3D_GEN_42, V3D_GMP_STATUS(33)),
++      REGDEF(V3D_GEN_33, V3D_GEN_42, V3D_GMP_CFG(33)),
++      REGDEF(V3D_GEN_33, V3D_GEN_42, V3D_GMP_VIO_ADDR(33)),
++
++      REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_ERR_FDBGO),
++      REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_ERR_FDBGB),
++      REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_ERR_FDBGS),
++      REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_ERR_STAT),
+ };
+ static const struct v3d_reg_def v3d_csd_reg_defs[] = {
+-      REGDEF(41, 71, V3D_CSD_STATUS),
+-      REGDEF(41, 42, V3D_CSD_CURRENT_CFG0(41)),
+-      REGDEF(41, 42, V3D_CSD_CURRENT_CFG1(41)),
+-      REGDEF(41, 42, V3D_CSD_CURRENT_CFG2(41)),
+-      REGDEF(41, 42, V3D_CSD_CURRENT_CFG3(41)),
+-      REGDEF(41, 42, V3D_CSD_CURRENT_CFG4(41)),
+-      REGDEF(41, 42, V3D_CSD_CURRENT_CFG5(41)),
+-      REGDEF(41, 42, V3D_CSD_CURRENT_CFG6(41)),
+-      REGDEF(71, 71, V3D_CSD_CURRENT_CFG0(71)),
+-      REGDEF(71, 71, V3D_CSD_CURRENT_CFG1(71)),
+-      REGDEF(71, 71, V3D_CSD_CURRENT_CFG2(71)),
+-      REGDEF(71, 71, V3D_CSD_CURRENT_CFG3(71)),
+-      REGDEF(71, 71, V3D_CSD_CURRENT_CFG4(71)),
+-      REGDEF(71, 71, V3D_CSD_CURRENT_CFG5(71)),
+-      REGDEF(71, 71, V3D_CSD_CURRENT_CFG6(71)),
+-      REGDEF(71, 71, V3D_V7_CSD_CURRENT_CFG7),
++      REGDEF(V3D_GEN_41, V3D_GEN_71, V3D_CSD_STATUS),
++      REGDEF(V3D_GEN_41, V3D_GEN_42, V3D_CSD_CURRENT_CFG0(41)),
++      REGDEF(V3D_GEN_41, V3D_GEN_42, V3D_CSD_CURRENT_CFG1(41)),
++      REGDEF(V3D_GEN_41, V3D_GEN_42, V3D_CSD_CURRENT_CFG2(41)),
++      REGDEF(V3D_GEN_41, V3D_GEN_42, V3D_CSD_CURRENT_CFG3(41)),
++      REGDEF(V3D_GEN_41, V3D_GEN_42, V3D_CSD_CURRENT_CFG4(41)),
++      REGDEF(V3D_GEN_41, V3D_GEN_42, V3D_CSD_CURRENT_CFG5(41)),
++      REGDEF(V3D_GEN_41, V3D_GEN_42, V3D_CSD_CURRENT_CFG6(41)),
++      REGDEF(V3D_GEN_71, V3D_GEN_71, V3D_CSD_CURRENT_CFG0(71)),
++      REGDEF(V3D_GEN_71, V3D_GEN_71, V3D_CSD_CURRENT_CFG1(71)),
++      REGDEF(V3D_GEN_71, V3D_GEN_71, V3D_CSD_CURRENT_CFG2(71)),
++      REGDEF(V3D_GEN_71, V3D_GEN_71, V3D_CSD_CURRENT_CFG3(71)),
++      REGDEF(V3D_GEN_71, V3D_GEN_71, V3D_CSD_CURRENT_CFG4(71)),
++      REGDEF(V3D_GEN_71, V3D_GEN_71, V3D_CSD_CURRENT_CFG5(71)),
++      REGDEF(V3D_GEN_71, V3D_GEN_71, V3D_CSD_CURRENT_CFG6(71)),
++      REGDEF(V3D_GEN_71, V3D_GEN_71, V3D_V7_CSD_CURRENT_CFG7),
+ };
+ static int v3d_v3d_debugfs_regs(struct seq_file *m, void *unused)
+@@ -164,7 +164,7 @@ static int v3d_v3d_debugfs_ident(struct seq_file *m, void *unused)
+                  str_yes_no(ident2 & V3D_HUB_IDENT2_WITH_MMU));
+       seq_printf(m, "TFU:        %s\n",
+                  str_yes_no(ident1 & V3D_HUB_IDENT1_WITH_TFU));
+-      if (v3d->ver <= 42) {
++      if (v3d->ver <= V3D_GEN_42) {
+               seq_printf(m, "TSY:        %s\n",
+                          str_yes_no(ident1 & V3D_HUB_IDENT1_WITH_TSY));
+       }
+@@ -196,11 +196,11 @@ static int v3d_v3d_debugfs_ident(struct seq_file *m, void *unused)
+               seq_printf(m, "  QPUs:         %d\n", nslc * qups);
+               seq_printf(m, "  Semaphores:   %d\n",
+                          V3D_GET_FIELD(ident1, V3D_IDENT1_NSEM));
+-              if (v3d->ver <= 42) {
++              if (v3d->ver <= V3D_GEN_42) {
+                       seq_printf(m, "  BCG int:      %d\n",
+                                  (ident2 & V3D_IDENT2_BCG_INT) != 0);
+               }
+-              if (v3d->ver < 40) {
++              if (v3d->ver < V3D_GEN_41) {
+                       seq_printf(m, "  Override TMU: %d\n",
+                                  (misccfg & V3D_MISCCFG_OVRTMUOUT) != 0);
+               }
+@@ -234,7 +234,7 @@ static int v3d_measure_clock(struct seq_file *m, void *unused)
+       int core = 0;
+       int measure_ms = 1000;
+-      if (v3d->ver >= 40) {
++      if (v3d->ver >= V3D_GEN_41) {
+               int cycle_count_reg = V3D_PCTR_CYCLE_COUNT(v3d->ver);
+               V3D_CORE_WRITE(core, V3D_V4_PCTR_0_SRC_0_3,
+                              V3D_SET_FIELD_VER(cycle_count_reg,
+diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c
+index 852015214e971..aa68be8fe86b7 100644
+--- a/drivers/gpu/drm/v3d/v3d_drv.c
++++ b/drivers/gpu/drm/v3d/v3d_drv.c
+@@ -17,6 +17,7 @@
+ #include <linux/dma-mapping.h>
+ #include <linux/io.h>
+ #include <linux/module.h>
++#include <linux/of.h>
+ #include <linux/of_platform.h>
+ #include <linux/platform_device.h>
+ #include <linux/sched/clock.h>
+@@ -92,7 +93,7 @@ static int v3d_get_param_ioctl(struct drm_device *dev, void *data,
+               args->value = 1;
+               return 0;
+       case DRM_V3D_PARAM_SUPPORTS_PERFMON:
+-              args->value = (v3d->ver >= 40);
++              args->value = (v3d->ver >= V3D_GEN_41);
+               return 0;
+       case DRM_V3D_PARAM_SUPPORTS_MULTISYNC_EXT:
+               args->value = 1;
+@@ -254,10 +255,10 @@ static const struct drm_driver v3d_drm_driver = {
+ };
+ static const struct of_device_id v3d_of_match[] = {
+-      { .compatible = "brcm,2711-v3d" },
+-      { .compatible = "brcm,2712-v3d" },
+-      { .compatible = "brcm,7268-v3d" },
+-      { .compatible = "brcm,7278-v3d" },
++      { .compatible = "brcm,2711-v3d", .data = (void *)V3D_GEN_42 },
++      { .compatible = "brcm,2712-v3d", .data = (void *)V3D_GEN_71 },
++      { .compatible = "brcm,7268-v3d", .data = (void *)V3D_GEN_33 },
++      { .compatible = "brcm,7278-v3d", .data = (void *)V3D_GEN_41 },
+       {},
+ };
+ MODULE_DEVICE_TABLE(of, v3d_of_match);
+@@ -274,6 +275,7 @@ static int v3d_platform_drm_probe(struct platform_device *pdev)
+       struct device *dev = &pdev->dev;
+       struct drm_device *drm;
+       struct v3d_dev *v3d;
++      enum v3d_gen gen;
+       int ret;
+       u32 mmu_debug;
+       u32 ident1, ident3;
+@@ -287,6 +289,9 @@ static int v3d_platform_drm_probe(struct platform_device *pdev)
+       platform_set_drvdata(pdev, drm);
++      gen = (uintptr_t)of_device_get_match_data(dev);
++      v3d->ver = gen;
++
+       ret = map_regs(v3d, &v3d->hub_regs, "hub");
+       if (ret)
+               return ret;
+@@ -316,6 +321,11 @@ static int v3d_platform_drm_probe(struct platform_device *pdev)
+       ident1 = V3D_READ(V3D_HUB_IDENT1);
+       v3d->ver = (V3D_GET_FIELD(ident1, V3D_HUB_IDENT1_TVER) * 10 +
+                   V3D_GET_FIELD(ident1, V3D_HUB_IDENT1_REV));
++      /* Make sure that the V3D tech version retrieved from the HW is equal
++       * to the one advertised by the device tree.
++       */
++      WARN_ON(v3d->ver != gen);
++
+       v3d->cores = V3D_GET_FIELD(ident1, V3D_HUB_IDENT1_NCORES);
+       WARN_ON(v3d->cores > 1); /* multicore not yet implemented */
+@@ -340,7 +350,7 @@ static int v3d_platform_drm_probe(struct platform_device *pdev)
+               }
+       }
+-      if (v3d->ver < 41) {
++      if (v3d->ver < V3D_GEN_41) {
+               ret = map_regs(v3d, &v3d->gca_regs, "gca");
+               if (ret)
+                       goto clk_disable;
+diff --git a/drivers/gpu/drm/v3d/v3d_drv.h b/drivers/gpu/drm/v3d/v3d_drv.h
+index 9deaefa0f95b7..de4a9e18f6a90 100644
+--- a/drivers/gpu/drm/v3d/v3d_drv.h
++++ b/drivers/gpu/drm/v3d/v3d_drv.h
+@@ -94,11 +94,18 @@ struct v3d_perfmon {
+       u64 values[] __counted_by(ncounters);
+ };
++enum v3d_gen {
++      V3D_GEN_33 = 33,
++      V3D_GEN_41 = 41,
++      V3D_GEN_42 = 42,
++      V3D_GEN_71 = 71,
++};
++
+ struct v3d_dev {
+       struct drm_device drm;
+       /* Short representation (e.g. 33, 41) of the V3D tech version */
+-      int ver;
++      enum v3d_gen ver;
+       /* Short representation (e.g. 5, 6) of the V3D tech revision */
+       int rev;
+@@ -199,7 +206,7 @@ to_v3d_dev(struct drm_device *dev)
+ static inline bool
+ v3d_has_csd(struct v3d_dev *v3d)
+ {
+-      return v3d->ver >= 41;
++      return v3d->ver >= V3D_GEN_41;
+ }
+ #define v3d_to_pdev(v3d) to_platform_device((v3d)->drm.dev)
+diff --git a/drivers/gpu/drm/v3d/v3d_gem.c b/drivers/gpu/drm/v3d/v3d_gem.c
+index b1e681630ded0..1ea6d3832c221 100644
+--- a/drivers/gpu/drm/v3d/v3d_gem.c
++++ b/drivers/gpu/drm/v3d/v3d_gem.c
+@@ -25,7 +25,7 @@ v3d_init_core(struct v3d_dev *v3d, int core)
+        * type.  If you want the default behavior, you can still put
+        * "2" in the indirect texture state's output_type field.
+        */
+-      if (v3d->ver < 40)
++      if (v3d->ver < V3D_GEN_41)
+               V3D_CORE_WRITE(core, V3D_CTL_MISCCFG, V3D_MISCCFG_OVRTMUOUT);
+       /* Whenever we flush the L2T cache, we always want to flush
+@@ -58,7 +58,7 @@ v3d_idle_axi(struct v3d_dev *v3d, int core)
+ static void
+ v3d_idle_gca(struct v3d_dev *v3d)
+ {
+-      if (v3d->ver >= 41)
++      if (v3d->ver >= V3D_GEN_41)
+               return;
+       V3D_GCA_WRITE(V3D_GCA_SAFE_SHUTDOWN, V3D_GCA_SAFE_SHUTDOWN_EN);
+@@ -132,13 +132,13 @@ v3d_reset(struct v3d_dev *v3d)
+ static void
+ v3d_flush_l3(struct v3d_dev *v3d)
+ {
+-      if (v3d->ver < 41) {
++      if (v3d->ver < V3D_GEN_41) {
+               u32 gca_ctrl = V3D_GCA_READ(V3D_GCA_CACHE_CTRL);
+               V3D_GCA_WRITE(V3D_GCA_CACHE_CTRL,
+                             gca_ctrl | V3D_GCA_CACHE_CTRL_FLUSH);
+-              if (v3d->ver < 33) {
++              if (v3d->ver < V3D_GEN_33) {
+                       V3D_GCA_WRITE(V3D_GCA_CACHE_CTRL,
+                                     gca_ctrl & ~V3D_GCA_CACHE_CTRL_FLUSH);
+               }
+@@ -151,7 +151,7 @@ v3d_flush_l3(struct v3d_dev *v3d)
+ static void
+ v3d_invalidate_l2c(struct v3d_dev *v3d, int core)
+ {
+-      if (v3d->ver > 32)
++      if (v3d->ver >= V3D_GEN_33)
+               return;
+       V3D_CORE_WRITE(core, V3D_CTL_L2CACTL,
+diff --git a/drivers/gpu/drm/v3d/v3d_irq.c b/drivers/gpu/drm/v3d/v3d_irq.c
+index 72b6a119412fa..29f63f572d35b 100644
+--- a/drivers/gpu/drm/v3d/v3d_irq.c
++++ b/drivers/gpu/drm/v3d/v3d_irq.c
+@@ -143,7 +143,7 @@ v3d_irq(int irq, void *arg)
+       /* We shouldn't be triggering these if we have GMP in
+        * always-allowed mode.
+        */
+-      if (v3d->ver < 71 && (intsts & V3D_INT_GMPV))
++      if (v3d->ver < V3D_GEN_71 && (intsts & V3D_INT_GMPV))
+               dev_err(v3d->drm.dev, "GMP violation\n");
+       /* V3D 4.2 wires the hub and core IRQs together, so if we &
+@@ -200,7 +200,7 @@ v3d_hub_irq(int irq, void *arg)
+               V3D_WRITE(V3D_MMU_CTL, V3D_READ(V3D_MMU_CTL));
+-              if (v3d->ver >= 41) {
++              if (v3d->ver >= V3D_GEN_41) {
+                       axi_id = axi_id >> 5;
+                       if (axi_id < ARRAY_SIZE(v3d41_axi_ids))
+                               client = v3d41_axi_ids[axi_id];
+@@ -217,7 +217,7 @@ v3d_hub_irq(int irq, void *arg)
+               status = IRQ_HANDLED;
+       }
+-      if (v3d->ver >= 71 && (intsts & V3D_V7_HUB_INT_GMPV)) {
++      if (v3d->ver >= V3D_GEN_71 && (intsts & V3D_V7_HUB_INT_GMPV)) {
+               dev_err(v3d->drm.dev, "GMP Violation\n");
+               status = IRQ_HANDLED;
+       }
+diff --git a/drivers/gpu/drm/v3d/v3d_perfmon.c b/drivers/gpu/drm/v3d/v3d_perfmon.c
+index 3ebda2fa46fc4..9a3fe52558746 100644
+--- a/drivers/gpu/drm/v3d/v3d_perfmon.c
++++ b/drivers/gpu/drm/v3d/v3d_perfmon.c
+@@ -200,10 +200,10 @@ void v3d_perfmon_init(struct v3d_dev *v3d)
+       const struct v3d_perf_counter_desc *counters = NULL;
+       unsigned int max = 0;
+-      if (v3d->ver >= 71) {
++      if (v3d->ver >= V3D_GEN_71) {
+               counters = v3d_v71_performance_counters;
+               max = ARRAY_SIZE(v3d_v71_performance_counters);
+-      } else if (v3d->ver >= 42) {
++      } else if (v3d->ver >= V3D_GEN_42) {
+               counters = v3d_v42_performance_counters;
+               max = ARRAY_SIZE(v3d_v42_performance_counters);
+       }
+diff --git a/drivers/gpu/drm/v3d/v3d_sched.c b/drivers/gpu/drm/v3d/v3d_sched.c
+index eb35482f6fb57..35f131a46d070 100644
+--- a/drivers/gpu/drm/v3d/v3d_sched.c
++++ b/drivers/gpu/drm/v3d/v3d_sched.c
+@@ -357,11 +357,11 @@ v3d_tfu_job_run(struct drm_sched_job *sched_job)
+       V3D_WRITE(V3D_TFU_ICA(v3d->ver), job->args.ica);
+       V3D_WRITE(V3D_TFU_IUA(v3d->ver), job->args.iua);
+       V3D_WRITE(V3D_TFU_IOA(v3d->ver), job->args.ioa);
+-      if (v3d->ver >= 71)
++      if (v3d->ver >= V3D_GEN_71)
+               V3D_WRITE(V3D_V7_TFU_IOC, job->args.v71.ioc);
+       V3D_WRITE(V3D_TFU_IOS(v3d->ver), job->args.ios);
+       V3D_WRITE(V3D_TFU_COEF0(v3d->ver), job->args.coef[0]);
+-      if (v3d->ver >= 71 || (job->args.coef[0] & V3D_TFU_COEF0_USECOEF)) {
++      if (v3d->ver >= V3D_GEN_71 || (job->args.coef[0] & V3D_TFU_COEF0_USECOEF)) {
+               V3D_WRITE(V3D_TFU_COEF1(v3d->ver), job->args.coef[1]);
+               V3D_WRITE(V3D_TFU_COEF2(v3d->ver), job->args.coef[2]);
+               V3D_WRITE(V3D_TFU_COEF3(v3d->ver), job->args.coef[3]);
+@@ -412,7 +412,7 @@ v3d_csd_job_run(struct drm_sched_job *sched_job)
+        *
+        * XXX: Set the CFG7 register
+        */
+-      if (v3d->ver >= 71)
++      if (v3d->ver >= V3D_GEN_71)
+               V3D_CORE_WRITE(0, V3D_V7_CSD_QUEUED_CFG7, 0);
+       /* CFG0 write kicks off the job. */
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-v3d-client-ranges-from-axi_ids-are-different-wit.patch b/queue-6.15/drm-v3d-client-ranges-from-axi_ids-are-different-wit.patch
new file mode 100644 (file)
index 0000000..42f0579
--- /dev/null
@@ -0,0 +1,70 @@
+From eca7b6dbb03b748e12e6231584a5685b885af44b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 14:25:08 +0200
+Subject: drm/v3d: client ranges from axi_ids are different with V3D 7.1
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jose Maria Casanova Crespo <jmcasanova@igalia.com>
+
+[ Upstream commit a22e0051f9eb2281b181218d97f77cebc299310d ]
+
+The client mask has been reduced from 8 bits on V3D 4.1 to 7 bits
+on V3D 7.1, so the ranges for each client are not compatible.
+
+On V3D 7.1, the CSD client can also report MMU errors.
+Therefore, add its AXI ID to the IDs list.
+
+Fixes: 0ad5bc1ce463 ("drm/v3d: fix up register addresses for V3D 7.x")
+Signed-off-by: Jose Maria Casanova Crespo <jmcasanova@igalia.com>
+Reviewed-by: Maíra Canal <mcanal@igalia.com>
+Link: https://lore.kernel.org/r/20250425122522.18425-2-jmcasanova@igalia.com
+Signed-off-by: Maíra Canal <mcanal@igalia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/v3d/v3d_irq.c | 23 ++++++++++++++++++++++-
+ 1 file changed, 22 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/v3d/v3d_irq.c b/drivers/gpu/drm/v3d/v3d_irq.c
+index d6ce1324905df..2cca5d3a26a22 100644
+--- a/drivers/gpu/drm/v3d/v3d_irq.c
++++ b/drivers/gpu/drm/v3d/v3d_irq.c
+@@ -199,12 +199,33 @@ v3d_hub_irq(int irq, void *arg)
+                       {0xA0, 0xA1, "TFU"},
+                       {0xC0, 0xE0, "MMU"},
+                       {0xE0, 0xE1, "GMP"},
++              }, v3d71_axi_ids[] = {
++                      {0x00, 0x30, "L2T"},
++                      {0x30, 0x38, "CLE"},
++                      {0x38, 0x39, "PTB"},
++                      {0x39, 0x3A, "PSE"},
++                      {0x3A, 0x3B, "CSD"},
++                      {0x40, 0x60, "TLB"},
++                      {0x60, 0x70, "MMU"},
++                      {0x7C, 0x7E, "TFU"},
++                      {0x7F, 0x80, "GMP"},
+               };
+               const char *client = "?";
+               V3D_WRITE(V3D_MMU_CTL, V3D_READ(V3D_MMU_CTL));
+-              if (v3d->ver >= V3D_GEN_41) {
++              if (v3d->ver >= V3D_GEN_71) {
++                      size_t i;
++
++                      axi_id = axi_id & 0x7F;
++                      for (i = 0; i < ARRAY_SIZE(v3d71_axi_ids); i++) {
++                              if (axi_id >= v3d71_axi_ids[i].begin &&
++                                  axi_id < v3d71_axi_ids[i].end) {
++                                      client = v3d71_axi_ids[i].client;
++                                      break;
++                              }
++                      }
++              } else if (v3d->ver >= V3D_GEN_41) {
+                       size_t i;
+                       axi_id = axi_id & 0xFF;
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-v3d-fix-client-obtained-from-axi_ids-on-v3d-4.1.patch b/queue-6.15/drm-v3d-fix-client-obtained-from-axi_ids-on-v3d-4.1.patch
new file mode 100644 (file)
index 0000000..91907cf
--- /dev/null
@@ -0,0 +1,96 @@
+From d110470084d25855f95854e6e8dc149ed503ffc4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 14:25:07 +0200
+Subject: drm/v3d: fix client obtained from axi_ids on V3D 4.1
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jose Maria Casanova Crespo <jmcasanova@igalia.com>
+
+[ Upstream commit d0e4c6537005dd106b101d4434a0c3dafd936d05 ]
+
+In the case of MMU errors caused by the TFU unit, the
+client that causes the MMU error is expected to be reported.
+But in the case of MMU TFU errors, a non existing client was
+being reported. This happened because the client calculation
+was taking into account more than the bits 0-7 from the
+axi_id that were representing the client.
+
+[   27.845132] v3d fec00000.v3d: MMU error from client ? (13) at 0x3bb1000, pte invalid
+
+Masking the bits and using the correct axi_id ranges fixes the
+calculation to report the real guilty client on V3D 4.1 and 4.2.
+
+Make the MMU error print axi_id with hexadecimal as used in the
+ranges.
+
+Fixes: 38c2c7917adc ("drm/v3d: Fix and extend MMU error handling.")
+Signed-off-by: Jose Maria Casanova Crespo <jmcasanova@igalia.com>
+Reviewed-by: Maíra Canal <mcanal@igalia.com>
+Link: https://lore.kernel.org/r/20250425122522.18425-1-jmcasanova@igalia.com
+Signed-off-by: Maíra Canal <mcanal@igalia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/v3d/v3d_irq.c | 37 +++++++++++++++++++++++------------
+ 1 file changed, 24 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/gpu/drm/v3d/v3d_irq.c b/drivers/gpu/drm/v3d/v3d_irq.c
+index 29f63f572d35b..d6ce1324905df 100644
+--- a/drivers/gpu/drm/v3d/v3d_irq.c
++++ b/drivers/gpu/drm/v3d/v3d_irq.c
+@@ -186,27 +186,38 @@ v3d_hub_irq(int irq, void *arg)
+               u32 axi_id = V3D_READ(V3D_MMU_VIO_ID);
+               u64 vio_addr = ((u64)V3D_READ(V3D_MMU_VIO_ADDR) <<
+                               (v3d->va_width - 32));
+-              static const char *const v3d41_axi_ids[] = {
+-                      "L2T",
+-                      "PTB",
+-                      "PSE",
+-                      "TLB",
+-                      "CLE",
+-                      "TFU",
+-                      "MMU",
+-                      "GMP",
++              static const struct {
++                      u32 begin;
++                      u32 end;
++                      const char *client;
++              } v3d41_axi_ids[] = {
++                      {0x00, 0x20, "L2T"},
++                      {0x20, 0x21, "PTB"},
++                      {0x40, 0x41, "PSE"},
++                      {0x60, 0x80, "TLB"},
++                      {0x80, 0x88, "CLE"},
++                      {0xA0, 0xA1, "TFU"},
++                      {0xC0, 0xE0, "MMU"},
++                      {0xE0, 0xE1, "GMP"},
+               };
+               const char *client = "?";
+               V3D_WRITE(V3D_MMU_CTL, V3D_READ(V3D_MMU_CTL));
+               if (v3d->ver >= V3D_GEN_41) {
+-                      axi_id = axi_id >> 5;
+-                      if (axi_id < ARRAY_SIZE(v3d41_axi_ids))
+-                              client = v3d41_axi_ids[axi_id];
++                      size_t i;
++
++                      axi_id = axi_id & 0xFF;
++                      for (i = 0; i < ARRAY_SIZE(v3d41_axi_ids); i++) {
++                              if (axi_id >= v3d41_axi_ids[i].begin &&
++                                  axi_id < v3d41_axi_ids[i].end) {
++                                      client = v3d41_axi_ids[i].client;
++                                      break;
++                              }
++                      }
+               }
+-              dev_err(v3d->drm.dev, "MMU error from client %s (%d) at 0x%llx%s%s%s\n",
++              dev_err(v3d->drm.dev, "MMU error from client %s (0x%x) at 0x%llx%s%s%s\n",
+                       client, axi_id, (long long)vio_addr,
+                       ((intsts & V3D_HUB_INT_MMU_WRV) ?
+                        ", write violation" : ""),
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-vc4-hdmi-call-hdmi-hotplug-helper-on-disconnect.patch b/queue-6.15/drm-vc4-hdmi-call-hdmi-hotplug-helper-on-disconnect.patch
new file mode 100644 (file)
index 0000000..13917c7
--- /dev/null
@@ -0,0 +1,48 @@
+From fd120120e6afe36fec07b6cdc2b777cbaf011abc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Mar 2025 17:12:23 +0000
+Subject: drm/vc4: hdmi: Call HDMI hotplug helper on disconnect
+
+From: Stefan Wahren <wahrenst@gmx.net>
+
+[ Upstream commit 34f051accedb642087fdcf19b3501fe150fbee49 ]
+
+drm_atomic_helper_connector_hdmi_hotplug() must be called
+regardless of the connection status, otherwise the HDMI audio
+disconnect event won't be notified.
+
+Fixes: 2ea9ec5d2c20 ("drm/vc4: hdmi: use drm_atomic_helper_connector_hdmi_hotplug()")
+Suggested-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
+Reviewed-by: Maxime Ripard <mripard@kernel.org>
+Signed-off-by: David Turner <david.turner@raspberrypi.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250317-vc4_hotplug-v4-2-2af625629186@raspberrypi.com
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
+index 37238a12baa58..37a7d45695f23 100644
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -372,13 +372,13 @@ static void vc4_hdmi_handle_hotplug(struct vc4_hdmi *vc4_hdmi,
+        * the lock for now.
+        */
++      drm_atomic_helper_connector_hdmi_hotplug(connector, status);
++
+       if (status == connector_status_disconnected) {
+               cec_phys_addr_invalidate(vc4_hdmi->cec_adap);
+               return;
+       }
+-      drm_atomic_helper_connector_hdmi_hotplug(connector, status);
+-
+       cec_s_phys_addr(vc4_hdmi->cec_adap,
+                       connector->display_info.source_physical_address, false);
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-vc4-tests-retry-pv-muxing-tests-when-edeadlk.patch b/queue-6.15/drm-vc4-tests-retry-pv-muxing-tests-when-edeadlk.patch
new file mode 100644 (file)
index 0000000..bd7ebd4
--- /dev/null
@@ -0,0 +1,265 @@
+From 86cc929185f7bf56069530ab4137985f1e0ed30d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Apr 2025 15:33:33 +0200
+Subject: drm/vc4: tests: Retry pv-muxing tests when EDEADLK
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Maxime Ripard <mripard@kernel.org>
+
+[ Upstream commit d5be7722d1736827a850556fd4d93e0fe2608c15 ]
+
+Some functions used by the HVS->PV muxing tests can return with EDEADLK,
+meaning the entire sequence should be restarted. It's not a fatal error
+and we should treat it as a recoverable error, and recover, instead of
+failing the test like we currently do.
+
+Fixes: 76ec18dc5afa ("drm/vc4: tests: Add unit test suite for the PV muxing")
+Reviewed-by: Maíra Canal <mcanal@igalia.com>
+Link: https://lore.kernel.org/r/20250403-drm-vc4-kunit-failures-v2-4-e09195cc8840@kernel.org
+Signed-off-by: Maxime Ripard <mripard@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/vc4/tests/vc4_test_pv_muxing.c    | 113 +++++++++++++++++-
+ 1 file changed, 112 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/vc4/tests/vc4_test_pv_muxing.c b/drivers/gpu/drm/vc4/tests/vc4_test_pv_muxing.c
+index 52c04ef33206b..d1f694029169a 100644
+--- a/drivers/gpu/drm/vc4/tests/vc4_test_pv_muxing.c
++++ b/drivers/gpu/drm/vc4/tests/vc4_test_pv_muxing.c
+@@ -687,16 +687,30 @@ static void drm_vc4_test_pv_muxing(struct kunit *test)
+       vc4 = priv->vc4;
+       drm = &vc4->base;
++
++retry:
+       state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+       for (i = 0; i < params->nencoders; i++) {
+               enum vc4_encoder_type enc_type = params->encoders[i];
+               ret = vc4_mock_atomic_add_output(test, state, enc_type);
++              if (ret == -EDEADLK) {
++                      drm_atomic_state_clear(state);
++                      ret = drm_modeset_backoff(&ctx);
++                      if (!ret)
++                              goto retry;
++              }
+               KUNIT_ASSERT_EQ(test, ret, 0);
+       }
+       ret = drm_atomic_check_only(state);
++      if (ret == -EDEADLK) {
++              drm_atomic_state_clear(state);
++              ret = drm_modeset_backoff(&ctx);
++              if (!ret)
++                      goto retry;
++      }
+       KUNIT_EXPECT_EQ(test, ret, 0);
+       KUNIT_EXPECT_TRUE(test,
+@@ -728,6 +742,8 @@ static void drm_vc4_test_pv_muxing_invalid(struct kunit *test)
+       vc4 = priv->vc4;
+       drm = &vc4->base;
++
++retry:
+       state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+@@ -735,10 +751,22 @@ static void drm_vc4_test_pv_muxing_invalid(struct kunit *test)
+               enum vc4_encoder_type enc_type = params->encoders[i];
+               ret = vc4_mock_atomic_add_output(test, state, enc_type);
++              if (ret == -EDEADLK) {
++                      drm_atomic_state_clear(state);
++                      ret = drm_modeset_backoff(&ctx);
++                      if (!ret)
++                              goto retry;
++              }
+               KUNIT_ASSERT_EQ(test, ret, 0);
+       }
+       ret = drm_atomic_check_only(state);
++      if (ret == -EDEADLK) {
++              drm_atomic_state_clear(state);
++              ret = drm_modeset_backoff(&ctx);
++              if (!ret)
++                      goto retry;
++      }
+       KUNIT_EXPECT_LT(test, ret, 0);
+       drm_modeset_drop_locks(&ctx);
+@@ -813,13 +841,26 @@ static void drm_test_vc5_pv_muxing_bugs_subsequent_crtc_enable(struct kunit *tes
+       drm_modeset_acquire_init(&ctx, 0);
+       drm = &vc4->base;
++retry_first:
+       state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+       ret = vc4_mock_atomic_add_output(test, state, VC4_ENCODER_TYPE_HDMI0);
++      if (ret == -EDEADLK) {
++              drm_atomic_state_clear(state);
++              ret = drm_modeset_backoff(&ctx);
++              if (!ret)
++                      goto retry_first;
++      }
+       KUNIT_ASSERT_EQ(test, ret, 0);
+       ret = drm_atomic_check_only(state);
++      if (ret == -EDEADLK) {
++              drm_atomic_state_clear(state);
++              ret = drm_modeset_backoff(&ctx);
++              if (!ret)
++                      goto retry_first;
++      }
+       KUNIT_ASSERT_EQ(test, ret, 0);
+       new_hvs_state = vc4_hvs_get_new_global_state(state);
+@@ -836,13 +877,26 @@ static void drm_test_vc5_pv_muxing_bugs_subsequent_crtc_enable(struct kunit *tes
+       ret = drm_atomic_helper_swap_state(state, false);
+       KUNIT_ASSERT_EQ(test, ret, 0);
++retry_second:
+       state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+       ret = vc4_mock_atomic_add_output(test, state, VC4_ENCODER_TYPE_HDMI1);
++      if (ret == -EDEADLK) {
++              drm_atomic_state_clear(state);
++              ret = drm_modeset_backoff(&ctx);
++              if (!ret)
++                      goto retry_second;
++      }
+       KUNIT_ASSERT_EQ(test, ret, 0);
+       ret = drm_atomic_check_only(state);
++      if (ret == -EDEADLK) {
++              drm_atomic_state_clear(state);
++              ret = drm_modeset_backoff(&ctx);
++              if (!ret)
++                      goto retry_second;
++      }
+       KUNIT_ASSERT_EQ(test, ret, 0);
+       new_hvs_state = vc4_hvs_get_new_global_state(state);
+@@ -887,16 +941,35 @@ static void drm_test_vc5_pv_muxing_bugs_stable_fifo(struct kunit *test)
+       drm_modeset_acquire_init(&ctx, 0);
+       drm = &vc4->base;
++retry_first:
+       state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+       ret = vc4_mock_atomic_add_output(test, state, VC4_ENCODER_TYPE_HDMI0);
++      if (ret == -EDEADLK) {
++              drm_atomic_state_clear(state);
++              ret = drm_modeset_backoff(&ctx);
++              if (!ret)
++                      goto retry_first;
++      }
+       KUNIT_ASSERT_EQ(test, ret, 0);
+       ret = vc4_mock_atomic_add_output(test, state, VC4_ENCODER_TYPE_HDMI1);
++      if (ret == -EDEADLK) {
++              drm_atomic_state_clear(state);
++              ret = drm_modeset_backoff(&ctx);
++              if (!ret)
++                      goto retry_first;
++      }
+       KUNIT_ASSERT_EQ(test, ret, 0);
+       ret = drm_atomic_check_only(state);
++      if (ret == -EDEADLK) {
++              drm_atomic_state_clear(state);
++              ret = drm_modeset_backoff(&ctx);
++              if (!ret)
++                      goto retry_first;
++      }
+       KUNIT_ASSERT_EQ(test, ret, 0);
+       new_hvs_state = vc4_hvs_get_new_global_state(state);
+@@ -921,13 +994,26 @@ static void drm_test_vc5_pv_muxing_bugs_stable_fifo(struct kunit *test)
+       ret = drm_atomic_helper_swap_state(state, false);
+       KUNIT_ASSERT_EQ(test, ret, 0);
++retry_second:
+       state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+       ret = vc4_mock_atomic_del_output(test, state, VC4_ENCODER_TYPE_HDMI0);
++      if (ret == -EDEADLK) {
++              drm_atomic_state_clear(state);
++              ret = drm_modeset_backoff(&ctx);
++              if (!ret)
++                      goto retry_second;
++      }
+       KUNIT_ASSERT_EQ(test, ret, 0);
+       ret = drm_atomic_check_only(state);
++      if (ret == -EDEADLK) {
++              drm_atomic_state_clear(state);
++              ret = drm_modeset_backoff(&ctx);
++              if (!ret)
++                      goto retry_second;
++      }
+       KUNIT_ASSERT_EQ(test, ret, 0);
+       new_hvs_state = vc4_hvs_get_new_global_state(state);
+@@ -981,25 +1067,50 @@ drm_test_vc5_pv_muxing_bugs_subsequent_crtc_enable_too_many_crtc_state(struct ku
+       drm_modeset_acquire_init(&ctx, 0);
+       drm = &vc4->base;
++retry_first:
+       state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+       ret = vc4_mock_atomic_add_output(test, state, VC4_ENCODER_TYPE_HDMI0);
++      if (ret == -EDEADLK) {
++              drm_atomic_state_clear(state);
++              ret = drm_modeset_backoff(&ctx);
++              if (!ret)
++                      goto retry_first;
++      }
+       KUNIT_ASSERT_EQ(test, ret, 0);
+       ret = drm_atomic_check_only(state);
++      if (ret == -EDEADLK) {
++              drm_atomic_state_clear(state);
++              ret = drm_modeset_backoff(&ctx);
++              if (!ret)
++                      goto retry_first;
++      }
+       KUNIT_ASSERT_EQ(test, ret, 0);
+-
+       ret = drm_atomic_helper_swap_state(state, false);
+       KUNIT_ASSERT_EQ(test, ret, 0);
++retry_second:
+       state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+       ret = vc4_mock_atomic_add_output(test, state, VC4_ENCODER_TYPE_HDMI1);
++      if (ret == -EDEADLK) {
++              drm_atomic_state_clear(state);
++              ret = drm_modeset_backoff(&ctx);
++              if (!ret)
++                      goto retry_second;
++      }
+       KUNIT_ASSERT_EQ(test, ret, 0);
+       ret = drm_atomic_check_only(state);
++      if (ret == -EDEADLK) {
++              drm_atomic_state_clear(state);
++              ret = drm_modeset_backoff(&ctx);
++              if (!ret)
++                      goto retry_second;
++      }
+       KUNIT_ASSERT_EQ(test, ret, 0);
+       new_vc4_crtc_state = get_vc4_crtc_state_for_encoder(test, state,
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-vc4-tests-stop-allocating-the-state-in-test-init.patch b/queue-6.15/drm-vc4-tests-stop-allocating-the-state-in-test-init.patch
new file mode 100644 (file)
index 0000000..1dcbdd7
--- /dev/null
@@ -0,0 +1,138 @@
+From 9c107411f503126ae533a9f859d6e92228ea3cc7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Apr 2025 15:33:32 +0200
+Subject: drm/vc4: tests: Stop allocating the state in test init
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Maxime Ripard <mripard@kernel.org>
+
+[ Upstream commit 7e0351ae91ed2b6178abbfae96c3c6aaa1652567 ]
+
+The vc4-pv-muxing-combinations and vc5-pv-muxing-combinations test
+suites use a common test init function which, in part, allocates the
+drm atomic state the test will use.
+
+That allocation relies on  drm_kunit_helper_atomic_state_alloc(), and
+thus requires a struct drm_modeset_acquire_ctx. This context will then
+be stored in the allocated state->acquire_ctx field.
+
+However, the context is local to the test init function, and is cleared
+as soon as drm_kunit_helper_atomic_state_alloc() is done. We thus end up
+with an dangling pointer to a cleared context in state->acquire_ctx for
+our test to consumes.
+
+We should really allocate the context and the state in the test
+functions, so we can also control when we're done with it.
+
+Fixes: 30188df0c387 ("drm/tests: Drop drm_kunit_helper_acquire_ctx_alloc()")
+Reviewed-by: Maíra Canal <mcanal@igalia.com>
+Link: https://lore.kernel.org/r/20250403-drm-vc4-kunit-failures-v2-3-e09195cc8840@kernel.org
+Signed-off-by: Maxime Ripard <mripard@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/vc4/tests/vc4_test_pv_muxing.c    | 41 ++++++++++++-------
+ 1 file changed, 27 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/gpu/drm/vc4/tests/vc4_test_pv_muxing.c b/drivers/gpu/drm/vc4/tests/vc4_test_pv_muxing.c
+index 992e8f5c5c6ea..52c04ef33206b 100644
+--- a/drivers/gpu/drm/vc4/tests/vc4_test_pv_muxing.c
++++ b/drivers/gpu/drm/vc4/tests/vc4_test_pv_muxing.c
+@@ -20,7 +20,6 @@
+ struct pv_muxing_priv {
+       struct vc4_dev *vc4;
+-      struct drm_atomic_state *state;
+ };
+ static bool check_fifo_conflict(struct kunit *test,
+@@ -677,10 +676,19 @@ static void drm_vc4_test_pv_muxing(struct kunit *test)
+ {
+       const struct pv_muxing_param *params = test->param_value;
+       const struct pv_muxing_priv *priv = test->priv;
+-      struct drm_atomic_state *state = priv->state;
++      struct drm_modeset_acquire_ctx ctx;
++      struct drm_atomic_state *state;
++      struct drm_device *drm;
++      struct vc4_dev *vc4;
+       unsigned int i;
+       int ret;
++      drm_modeset_acquire_init(&ctx, 0);
++
++      vc4 = priv->vc4;
++      drm = &vc4->base;
++      state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
++      KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+       for (i = 0; i < params->nencoders; i++) {
+               enum vc4_encoder_type enc_type = params->encoders[i];
+@@ -700,16 +708,29 @@ static void drm_vc4_test_pv_muxing(struct kunit *test)
+               KUNIT_EXPECT_TRUE(test, check_channel_for_encoder(test, state, enc_type,
+                                                                 params->check_fn));
+       }
++
++      drm_modeset_drop_locks(&ctx);
++      drm_modeset_acquire_fini(&ctx);
+ }
+ static void drm_vc4_test_pv_muxing_invalid(struct kunit *test)
+ {
+       const struct pv_muxing_param *params = test->param_value;
+       const struct pv_muxing_priv *priv = test->priv;
+-      struct drm_atomic_state *state = priv->state;
++      struct drm_modeset_acquire_ctx ctx;
++      struct drm_atomic_state *state;
++      struct drm_device *drm;
++      struct vc4_dev *vc4;
+       unsigned int i;
+       int ret;
++      drm_modeset_acquire_init(&ctx, 0);
++
++      vc4 = priv->vc4;
++      drm = &vc4->base;
++      state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
++      KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
++
+       for (i = 0; i < params->nencoders; i++) {
+               enum vc4_encoder_type enc_type = params->encoders[i];
+@@ -719,14 +740,15 @@ static void drm_vc4_test_pv_muxing_invalid(struct kunit *test)
+       ret = drm_atomic_check_only(state);
+       KUNIT_EXPECT_LT(test, ret, 0);
++
++      drm_modeset_drop_locks(&ctx);
++      drm_modeset_acquire_fini(&ctx);
+ }
+ static int vc4_pv_muxing_test_init(struct kunit *test)
+ {
+       const struct pv_muxing_param *params = test->param_value;
+-      struct drm_modeset_acquire_ctx ctx;
+       struct pv_muxing_priv *priv;
+-      struct drm_device *drm;
+       struct vc4_dev *vc4;
+       priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
+@@ -737,15 +759,6 @@ static int vc4_pv_muxing_test_init(struct kunit *test)
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4);
+       priv->vc4 = vc4;
+-      drm_modeset_acquire_init(&ctx, 0);
+-
+-      drm = &vc4->base;
+-      priv->state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
+-      KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->state);
+-
+-      drm_modeset_drop_locks(&ctx);
+-      drm_modeset_acquire_fini(&ctx);
+-
+       return 0;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-vc4-tests-use-return-instead-of-assert.patch b/queue-6.15/drm-vc4-tests-use-return-instead-of-assert.patch
new file mode 100644 (file)
index 0000000..d7056ec
--- /dev/null
@@ -0,0 +1,113 @@
+From df45095201f3367b46e2c7f04b88e1436e52c7ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Apr 2025 15:33:30 +0200
+Subject: drm/vc4: tests: Use return instead of assert
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Maxime Ripard <mripard@kernel.org>
+
+[ Upstream commit 9e26a3740cc08ef8bcdc5e5d824792cd677affce ]
+
+The vc4_mock_atomic_add_output() and vc4_mock_atomic_del_output() assert
+that the functions they are calling didn't fail. Since some of them can
+return EDEADLK, we can't properly deal with it.
+
+Since both functions are expected to return an int, and all caller check
+the return value, let's just properly propagate the errors when they
+occur.
+
+Fixes: f759f5b53f1c ("drm/vc4: tests: Introduce a mocking infrastructure")
+Fixes: 76ec18dc5afa ("drm/vc4: tests: Add unit test suite for the PV muxing")
+Reviewed-by: Maíra Canal <mcanal@igalia.com>
+Link: https://lore.kernel.org/r/20250403-drm-vc4-kunit-failures-v2-1-e09195cc8840@kernel.org
+Signed-off-by: Maxime Ripard <mripard@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/tests/vc4_mock_output.c | 36 ++++++++++++++-------
+ 1 file changed, 24 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock_output.c b/drivers/gpu/drm/vc4/tests/vc4_mock_output.c
+index e70d7c3076acf..f0ddc223c1f83 100644
+--- a/drivers/gpu/drm/vc4/tests/vc4_mock_output.c
++++ b/drivers/gpu/drm/vc4/tests/vc4_mock_output.c
+@@ -75,24 +75,30 @@ int vc4_mock_atomic_add_output(struct kunit *test,
+       int ret;
+       encoder = vc4_find_encoder_by_type(drm, type);
+-      KUNIT_ASSERT_NOT_ERR_OR_NULL(test, encoder);
++      if (!encoder)
++              return -ENODEV;
+       crtc = vc4_find_crtc_for_encoder(test, drm, encoder);
+-      KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc);
++      if (!crtc)
++              return -ENODEV;
+       output = encoder_to_vc4_dummy_output(encoder);
+       conn = &output->connector;
+       conn_state = drm_atomic_get_connector_state(state, conn);
+-      KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
++      if (IS_ERR(conn_state))
++              return PTR_ERR(conn_state);
+       ret = drm_atomic_set_crtc_for_connector(conn_state, crtc);
+-      KUNIT_EXPECT_EQ(test, ret, 0);
++      if (ret)
++              return ret;
+       crtc_state = drm_atomic_get_crtc_state(state, crtc);
+-      KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
++      if (IS_ERR(crtc_state))
++              return PTR_ERR(crtc_state);
+       ret = drm_atomic_set_mode_for_crtc(crtc_state, &default_mode);
+-      KUNIT_EXPECT_EQ(test, ret, 0);
++      if (ret)
++              return ret;
+       crtc_state->active = true;
+@@ -113,26 +119,32 @@ int vc4_mock_atomic_del_output(struct kunit *test,
+       int ret;
+       encoder = vc4_find_encoder_by_type(drm, type);
+-      KUNIT_ASSERT_NOT_ERR_OR_NULL(test, encoder);
++      if (!encoder)
++              return -ENODEV;
+       crtc = vc4_find_crtc_for_encoder(test, drm, encoder);
+-      KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc);
++      if (!crtc)
++              return -ENODEV;
+       crtc_state = drm_atomic_get_crtc_state(state, crtc);
+-      KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
++      if (IS_ERR(crtc_state))
++              return PTR_ERR(crtc_state);
+       crtc_state->active = false;
+       ret = drm_atomic_set_mode_for_crtc(crtc_state, NULL);
+-      KUNIT_ASSERT_EQ(test, ret, 0);
++      if (ret)
++              return ret;
+       output = encoder_to_vc4_dummy_output(encoder);
+       conn = &output->connector;
+       conn_state = drm_atomic_get_connector_state(state, conn);
+-      KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
++      if (IS_ERR(conn_state))
++              return PTR_ERR(conn_state);
+       ret = drm_atomic_set_crtc_for_connector(conn_state, NULL);
+-      KUNIT_ASSERT_EQ(test, ret, 0);
++      if (ret)
++              return ret;
+       return 0;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-vkms-adjust-vkms_state-active_planes-allocation-.patch b/queue-6.15/drm-vkms-adjust-vkms_state-active_planes-allocation-.patch
new file mode 100644 (file)
index 0000000..0674df8
--- /dev/null
@@ -0,0 +1,44 @@
+From fa329e4749e07781ce00e87c9127bb33934247a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 23:14:32 -0700
+Subject: drm/vkms: Adjust vkms_state->active_planes allocation type
+
+From: Kees Cook <kees@kernel.org>
+
+[ Upstream commit 258aebf100540d36aba910f545d4d5ddf4ecaf0b ]
+
+In preparation for making the kmalloc family of allocators type aware,
+we need to make sure that the returned type from the allocation matches
+the type of the variable being assigned. (Before, the allocator would
+always return "void *", which can be implicitly cast to any pointer type.)
+
+The assigned type is "struct vkms_plane_state **", but the returned type
+will be "struct drm_plane **". These are the same size (pointer size), but
+the types don't match. Adjust the allocation type to match the assignment.
+
+Signed-off-by: Kees Cook <kees@kernel.org>
+Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
+Fixes: 8b1865873651 ("drm/vkms: totally reworked crc data tracking")
+Link: https://lore.kernel.org/r/20250426061431.work.304-kees@kernel.org
+Signed-off-by: Louis Chauvet <contact@louischauvet.fr>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vkms/vkms_crtc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c
+index 12034ec120299..8c9898b9055d4 100644
+--- a/drivers/gpu/drm/vkms/vkms_crtc.c
++++ b/drivers/gpu/drm/vkms/vkms_crtc.c
+@@ -194,7 +194,7 @@ static int vkms_crtc_atomic_check(struct drm_crtc *crtc,
+               i++;
+       }
+-      vkms_state->active_planes = kcalloc(i, sizeof(plane), GFP_KERNEL);
++      vkms_state->active_planes = kcalloc(i, sizeof(*vkms_state->active_planes), GFP_KERNEL);
+       if (!vkms_state->active_planes)
+               return -ENOMEM;
+       vkms_state->num_active_planes = i;
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-vmwgfx-add-error-path-for-xa_store-in-vmw_bo_add.patch b/queue-6.15/drm-vmwgfx-add-error-path-for-xa_store-in-vmw_bo_add.patch
new file mode 100644 (file)
index 0000000..f1e6632
--- /dev/null
@@ -0,0 +1,102 @@
+From 8bb34be219ada8c54016a62f284fd03c2f9d1f49 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Feb 2025 15:52:23 +0100
+Subject: drm/vmwgfx: Add error path for xa_store in
+ vmw_bo_add_detached_resource
+
+From: Keisuke Nishimura <keisuke.nishimura@inria.fr>
+
+[ Upstream commit 3282422bf251db541fe07c548ca304130d37d754 ]
+
+The xa_store() may fail due to memory allocation failure because there
+is no guarantee that the index is already used. This fix introduces new
+paths to handle the error.
+
+This patch also aligns the order of function calls by calling
+vmw_bo_add_detached_resource() before ttm_prime_object_init() in order
+to allow consistent error handling.
+
+Fixes: d6667f0ddf46 ("drm/vmwgfx: Fix handling of dumb buffers")
+Signed-off-by: Keisuke Nishimura <keisuke.nishimura@inria.fr>
+Signed-off-by: Zack Rusin <zack.rusin@broadcom.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250225145223.34773-1-keisuke.nishimura@inria.fr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vmwgfx/vmwgfx_bo.c      |  4 ++--
+ drivers/gpu/drm/vmwgfx/vmwgfx_bo.h      |  2 +-
+ drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 16 ++++++++++++++--
+ 3 files changed, 17 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
+index 9b5b8c1f063bb..aa13e4061ff15 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
+@@ -848,9 +848,9 @@ void vmw_bo_placement_set_default_accelerated(struct vmw_bo *bo)
+       vmw_bo_placement_set(bo, domain, domain);
+ }
+-void vmw_bo_add_detached_resource(struct vmw_bo *vbo, struct vmw_resource *res)
++int vmw_bo_add_detached_resource(struct vmw_bo *vbo, struct vmw_resource *res)
+ {
+-      xa_store(&vbo->detached_resources, (unsigned long)res, res, GFP_KERNEL);
++      return xa_err(xa_store(&vbo->detached_resources, (unsigned long)res, res, GFP_KERNEL));
+ }
+ void vmw_bo_del_detached_resource(struct vmw_bo *vbo, struct vmw_resource *res)
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h
+index 11e330c7c7f52..51790a11fe649 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h
+@@ -141,7 +141,7 @@ void vmw_bo_move_notify(struct ttm_buffer_object *bo,
+                       struct ttm_resource *mem);
+ void vmw_bo_swap_notify(struct ttm_buffer_object *bo);
+-void vmw_bo_add_detached_resource(struct vmw_bo *vbo, struct vmw_resource *res);
++int vmw_bo_add_detached_resource(struct vmw_bo *vbo, struct vmw_resource *res);
+ void vmw_bo_del_detached_resource(struct vmw_bo *vbo, struct vmw_resource *res);
+ struct vmw_surface *vmw_bo_surface(struct vmw_bo *vbo);
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
+index 5721c74da3e0b..1f7626f6ac0b1 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
+@@ -871,7 +871,12 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
+                       vmw_resource_unreference(&res);
+                       goto out_unlock;
+               }
+-              vmw_bo_add_detached_resource(res->guest_memory_bo, res);
++
++              ret = vmw_bo_add_detached_resource(res->guest_memory_bo, res);
++              if (unlikely(ret != 0)) {
++                      vmw_resource_unreference(&res);
++                      goto out_unlock;
++              }
+       }
+       tmp = vmw_resource_reference(&srf->res);
+@@ -1670,6 +1675,14 @@ vmw_gb_surface_define_internal(struct drm_device *dev,
+       }
++      if (res->guest_memory_bo) {
++              ret = vmw_bo_add_detached_resource(res->guest_memory_bo, res);
++              if (unlikely(ret != 0)) {
++                      vmw_resource_unreference(&res);
++                      goto out_unlock;
++              }
++      }
++
+       tmp = vmw_resource_reference(res);
+       ret = ttm_prime_object_init(tfile, res->guest_memory_size, &user_srf->prime,
+                                   VMW_RES_SURFACE,
+@@ -1684,7 +1697,6 @@ vmw_gb_surface_define_internal(struct drm_device *dev,
+       rep->handle      = user_srf->prime.base.handle;
+       rep->backup_size = res->guest_memory_size;
+       if (res->guest_memory_bo) {
+-              vmw_bo_add_detached_resource(res->guest_memory_bo, res);
+               rep->buffer_map_handle =
+                       drm_vma_node_offset_addr(&res->guest_memory_bo->tbo.base.vma_node);
+               rep->buffer_size = res->guest_memory_bo->tbo.base.size;
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-vmwgfx-add-seqno-waiter-for-sync_files.patch b/queue-6.15/drm-vmwgfx-add-seqno-waiter-for-sync_files.patch
new file mode 100644 (file)
index 0000000..ae7a5bd
--- /dev/null
@@ -0,0 +1,89 @@
+From 54422ec5fb2241cbdad09652491fb63a67818451 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Feb 2025 14:06:33 -0600
+Subject: drm/vmwgfx: Add seqno waiter for sync_files
+
+From: Ian Forbes <ian.forbes@broadcom.com>
+
+[ Upstream commit 0039a3b35b10d9c15d3d26320532ab56cc566750 ]
+
+Because sync_files are passive waiters they do not participate in
+the processing of fences like the traditional vmw_fence_wait IOCTL.
+If userspace exclusively uses sync_files for synchronization then
+nothing in the kernel actually processes fence updates as interrupts
+for fences are masked and ignored if the kernel does not indicate to the
+SVGA device that there are active waiters.
+
+This oversight results in a bug where the entire GUI can freeze waiting
+on a sync_file that will never be signalled as we've masked the interrupts
+to signal its completion. This bug is incredibly racy as any process which
+interacts with the fencing code via the 3D stack can process the stuck
+fences on behalf of the stuck process causing it to run again. Even a
+simple app like eglinfo is enough to resume the stuck process. Usually
+this bug is seen at a login screen like GDM because there are no other
+3D apps running.
+
+By adding a seqno waiter we re-enable interrupt based processing of the
+dma_fences associated with the sync_file which is signalled as part of a
+dma_fence_callback.
+
+This has likely been broken since it was initially added to the kernel in
+2017 but has gone unnoticed until mutter recently started using sync_files
+heavily over the course of 2024 as part of their explicit sync support.
+
+Fixes: c906965dee22 ("drm/vmwgfx: Add export fence to file descriptor support")
+Signed-off-by: Ian Forbes <ian.forbes@broadcom.com>
+Signed-off-by: Zack Rusin <zack.rusin@broadcom.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250228200633.642417-1-ian.forbes@broadcom.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 26 +++++++++++++++++++++++++
+ 1 file changed, 26 insertions(+)
+
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
+index 2e52d73eba484..ea741bc4ac3fc 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
+@@ -4086,6 +4086,23 @@ static int vmw_execbuf_tie_context(struct vmw_private *dev_priv,
+       return 0;
+ }
++/*
++ * DMA fence callback to remove a seqno_waiter
++ */
++struct seqno_waiter_rm_context {
++      struct dma_fence_cb base;
++      struct vmw_private *dev_priv;
++};
++
++static void seqno_waiter_rm_cb(struct dma_fence *f, struct dma_fence_cb *cb)
++{
++      struct seqno_waiter_rm_context *ctx =
++              container_of(cb, struct seqno_waiter_rm_context, base);
++
++      vmw_seqno_waiter_remove(ctx->dev_priv);
++      kfree(ctx);
++}
++
+ int vmw_execbuf_process(struct drm_file *file_priv,
+                       struct vmw_private *dev_priv,
+                       void __user *user_commands, void *kernel_commands,
+@@ -4266,6 +4283,15 @@ int vmw_execbuf_process(struct drm_file *file_priv,
+               } else {
+                       /* Link the fence with the FD created earlier */
+                       fd_install(out_fence_fd, sync_file->file);
++                      struct seqno_waiter_rm_context *ctx =
++                              kmalloc(sizeof(*ctx), GFP_KERNEL);
++                      ctx->dev_priv = dev_priv;
++                      vmw_seqno_waiter_add(dev_priv);
++                      if (dma_fence_add_callback(&fence->base, &ctx->base,
++                                                 seqno_waiter_rm_cb) < 0) {
++                              vmw_seqno_waiter_remove(dev_priv);
++                              kfree(ctx);
++                      }
+               }
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-vmwgfx-fix-dumb-buffer-leak.patch b/queue-6.15/drm-vmwgfx-fix-dumb-buffer-leak.patch
new file mode 100644 (file)
index 0000000..234f1c3
--- /dev/null
@@ -0,0 +1,135 @@
+From c083d524f5b71472eeca70b93ee9c5002b3c4fcc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jan 2025 14:44:24 -0600
+Subject: drm/vmwgfx: Fix dumb buffer leak
+
+From: Ian Forbes <ian.forbes@broadcom.com>
+
+[ Upstream commit f42c09e614f1bda96f5690be8d0bb273234febbc ]
+
+Dumb buffers were not being freed because the GEM reference that was
+acquired in gb_surface_define was not dropped like it is in the 2D case.
+Dropping this ref uncovered a few additional issues with freeing the
+resources associated with dirty tracking in vmw_bo_free/release.
+
+Additionally the TTM object associated with the surface were also leaking
+which meant that when the ttm_object_file was closed at process exit the
+destructor unreferenced an already destroyed surface.
+
+The solution is to remove the destructor from the vmw_user_surface
+associated with the dumb_buffer and immediately unreferencing the TTM
+object which his removes it from the ttm_object_file.
+
+This also allows the early return in vmw_user_surface_base_release for the
+dumb buffer case to be removed as it should no longer occur.
+
+The chain of references now has the GEM handle(s) owning the dumb buffer.
+The GEM handles have a singular GEM reference to the vmw_bo which is
+dropped when all handles are closed. When the GEM reference count hits
+zero the vmw_bo is freed which then unreferences the surface via
+vmw_resource_release in vmw_bo_release.
+
+Fixes: d6667f0ddf46 ("drm/vmwgfx: Fix handling of dumb buffers")
+Signed-off-by: Ian Forbes <ian.forbes@broadcom.com>
+Reviewed-by: Zack Rusin <zack.rusin@broadcom.com>
+Signed-off-by: Zack Rusin <zack.rusin@broadcom.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250123204424.836896-1-ian.forbes@broadcom.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vmwgfx/vmwgfx_bo.c       |  6 ++++--
+ drivers/gpu/drm/vmwgfx/vmwgfx_resource.c |  2 +-
+ drivers/gpu/drm/vmwgfx/vmwgfx_surface.c  | 18 ++++++++++++------
+ 3 files changed, 17 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
+index aa13e4061ff15..f30df3dc871fd 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
+@@ -51,11 +51,13 @@ static void vmw_bo_release(struct vmw_bo *vbo)
+                       mutex_lock(&res->dev_priv->cmdbuf_mutex);
+                       (void)vmw_resource_reserve(res, false, true);
+                       vmw_resource_mob_detach(res);
++                      if (res->dirty)
++                              res->func->dirty_free(res);
+                       if (res->coherent)
+                               vmw_bo_dirty_release(res->guest_memory_bo);
+                       res->guest_memory_bo = NULL;
+                       res->guest_memory_offset = 0;
+-                      vmw_resource_unreserve(res, false, false, false, NULL,
++                      vmw_resource_unreserve(res, true, false, false, NULL,
+                                              0);
+                       mutex_unlock(&res->dev_priv->cmdbuf_mutex);
+               }
+@@ -73,9 +75,9 @@ static void vmw_bo_free(struct ttm_buffer_object *bo)
+ {
+       struct vmw_bo *vbo = to_vmw_bo(&bo->base);
+-      WARN_ON(vbo->dirty);
+       WARN_ON(!RB_EMPTY_ROOT(&vbo->res_tree));
+       vmw_bo_release(vbo);
++      WARN_ON(vbo->dirty);
+       kfree(vbo);
+ }
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
+index a73af8a355fbf..c4d5fe5f330f9 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
+@@ -273,7 +273,7 @@ int vmw_user_resource_lookup_handle(struct vmw_private *dev_priv,
+               goto out_bad_resource;
+       res = converter->base_obj_to_res(base);
+-      kref_get(&res->kref);
++      vmw_resource_reference(res);
+       *p_res = res;
+       ret = 0;
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
+index 1f7626f6ac0b1..d7a8070330ba5 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
+@@ -658,7 +658,7 @@ static void vmw_user_surface_free(struct vmw_resource *res)
+       struct vmw_user_surface *user_srf =
+           container_of(srf, struct vmw_user_surface, srf);
+-      WARN_ON_ONCE(res->dirty);
++      WARN_ON(res->dirty);
+       if (user_srf->master)
+               drm_master_put(&user_srf->master);
+       kfree(srf->offsets);
+@@ -689,8 +689,7 @@ static void vmw_user_surface_base_release(struct ttm_base_object **p_base)
+        * Dumb buffers own the resource and they'll unref the
+        * resource themselves
+        */
+-      if (res && res->guest_memory_bo && res->guest_memory_bo->is_dumb)
+-              return;
++      WARN_ON(res && res->guest_memory_bo && res->guest_memory_bo->is_dumb);
+       vmw_resource_unreference(&res);
+ }
+@@ -2370,12 +2369,19 @@ int vmw_dumb_create(struct drm_file *file_priv,
+       vbo = res->guest_memory_bo;
+       vbo->is_dumb = true;
+       vbo->dumb_surface = vmw_res_to_srf(res);
+-
++      drm_gem_object_put(&vbo->tbo.base);
++      /*
++       * Unset the user surface dtor since this in not actually exposed
++       * to userspace. The suface is owned via the dumb_buffer's GEM handle
++       */
++      struct vmw_user_surface *usurf = container_of(vbo->dumb_surface,
++                                              struct vmw_user_surface, srf);
++      usurf->prime.base.refcount_release = NULL;
+ err:
+       if (res)
+               vmw_resource_unreference(&res);
+-      if (ret)
+-              ttm_ref_object_base_unref(tfile, arg.rep.handle);
++
++      ttm_ref_object_base_unref(tfile, arg.rep.handle);
+       return ret;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-xe-add-missing-documentation-of-rpa_freq.patch b/queue-6.15/drm-xe-add-missing-documentation-of-rpa_freq.patch
new file mode 100644 (file)
index 0000000..f84540c
--- /dev/null
@@ -0,0 +1,47 @@
+From 986c210aba023e95d51c843181c9a2e7a1222705 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 May 2025 12:51:48 -0400
+Subject: drm/xe: Add missing documentation of rpa_freq
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rodrigo Vivi <rodrigo.vivi@intel.com>
+
+[ Upstream commit 40493d97b329f8185c0f04dc0ef2b9ffc58e7f3b ]
+
+While at it, already adjust the rpe_freq frequency, to highlight
+that both are calculated by PCODE at runtime.
+
+Fixes: c6aac2fa77a3 ("drm/xe: Introduce the RPa information")
+Cc: Vinay Belgaumkar <vinay.belgaumkar@intel.com>
+Cc: Lucas De Marchi <lucas.demarchi@intel.com>
+Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>
+Reviewed-by: Vinay Belgaumkar <vinay.belgaumkar@intel.com>
+Link: https://lore.kernel.org/r/20250521165146.39616-4-rodrigo.vivi@intel.com
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+(cherry picked from commit 39578fa40420fb11dbe4f42225a347e945d8fd0e)
+Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_gt_freq.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/gpu/drm/xe/xe_gt_freq.c b/drivers/gpu/drm/xe/xe_gt_freq.c
+index 985efbc685286..552ac92496a40 100644
+--- a/drivers/gpu/drm/xe/xe_gt_freq.c
++++ b/drivers/gpu/drm/xe/xe_gt_freq.c
+@@ -36,7 +36,10 @@
+  * - act_freq: The actual resolved frequency decided by PCODE.
+  * - cur_freq: The current one requested by GuC PC to the PCODE.
+  * - rpn_freq: The Render Performance (RP) N level, which is the minimal one.
++ * - rpa_freq: The Render Performance (RP) A level, which is the achiveable one.
++ *   Calculated by PCODE at runtime based on multiple running conditions
+  * - rpe_freq: The Render Performance (RP) E level, which is the efficient one.
++ *   Calculated by PCODE at runtime based on multiple running conditions
+  * - rp0_freq: The Render Performance (RP) 0 level, which is the maximum one.
+  *
+  * device/tile#/gt#/freq0/<item>_freq *read-write* files:
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-xe-d3cold-set-power-state-to-d3cold-during-s2idl.patch b/queue-6.15/drm-xe-d3cold-set-power-state-to-d3cold-during-s2idl.patch
new file mode 100644 (file)
index 0000000..a3c2937
--- /dev/null
@@ -0,0 +1,45 @@
+From 43fb3e86e9850447a71994782ebea7887b122e01 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Mar 2025 21:49:14 +0530
+Subject: drm/xe/d3cold: Set power state to D3Cold during s2idle/s3
+
+From: Badal Nilawar <badal.nilawar@intel.com>
+
+[ Upstream commit f945dd89fa8da3f662508165453dafdb4035d9d3 ]
+
+According to pci core guidelines, pci_save_config is recommended when the
+driver explicitly needs to set the pci power state. As of now xe kmd is
+only doing pci_save_config while entering to s2idle/s3 state, which makes
+pci core think that device driver has already applied required pci power
+state. This leads to GPU remain in D0 state. To fix the issue setting
+the pci power state to D3Cold.
+
+Fixes:dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs")
+
+Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Badal Nilawar <badal.nilawar@intel.com>
+Signed-off-by: Anshuman Gupta <anshuman.gupta@intel.com>
+Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Link: https://lore.kernel.org/r/20250327161914.432552-1-badal.nilawar@intel.com
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_pci.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c
+index f4d108dc49b1b..30f7ce06c8969 100644
+--- a/drivers/gpu/drm/xe/xe_pci.c
++++ b/drivers/gpu/drm/xe/xe_pci.c
+@@ -922,6 +922,7 @@ static int xe_pci_suspend(struct device *dev)
+       pci_save_state(pdev);
+       pci_disable_device(pdev);
++      pci_set_power_state(pdev, PCI_D3cold);
+       return 0;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-xe-guc-don-t-expose-guc-privileged-debugfs-files.patch b/queue-6.15/drm-xe-guc-don-t-expose-guc-privileged-debugfs-files.patch
new file mode 100644 (file)
index 0000000..529351b
--- /dev/null
@@ -0,0 +1,66 @@
+From 9fcbd741bfe73d10237dadbbc72c8fc6f7a4956b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Apr 2025 16:26:34 +0200
+Subject: drm/xe/guc: Don't expose GuC privileged debugfs files if VF
+
+From: Michal Wajdeczko <michal.wajdeczko@intel.com>
+
+[ Upstream commit 387444984d7b53dbaee263887cad4ea7c8e57b34 ]
+
+Some of the GuC debugfs files require access to the data that is
+not available on the VFs. Don't expose those files on the VF driver.
+
+Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
+Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>
+Link: https://lore.kernel.org/r/20250403142635.1821-3-michal.wajdeczko@intel.com
+Stable-dep-of: e22d7acf9f47 ("drm/xe/guc: Make creation of SLPC debugfs files conditional")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_guc_debugfs.c | 22 ++++++++++++++++++----
+ 1 file changed, 18 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_guc_debugfs.c b/drivers/gpu/drm/xe/xe_guc_debugfs.c
+index 9a1c78b89f457..f33013f8a0f38 100644
+--- a/drivers/gpu/drm/xe/xe_guc_debugfs.c
++++ b/drivers/gpu/drm/xe/xe_guc_debugfs.c
+@@ -103,11 +103,20 @@ static int guc_pc(struct xe_guc *guc, struct drm_printer *p)
+       return 0;
+ }
+-static const struct drm_info_list debugfs_list[] = {
++/*
++ * only for GuC debugfs files which can be safely used on the VF as well:
++ * - without access to the GuC privileged registers
++ * - without access to the PF specific GuC objects
++ */
++static const struct drm_info_list vf_safe_debugfs_list[] = {
+       { "guc_info", .show = guc_debugfs_show, .data = xe_guc_print_info },
++      { "guc_ctb", .show = guc_debugfs_show, .data = guc_ctb },
++};
++
++/* everything else should be added here */
++static const struct drm_info_list pf_only_debugfs_list[] = {
+       { "guc_log", .show = guc_debugfs_show, .data = guc_log },
+       { "guc_log_dmesg", .show = guc_debugfs_show, .data = guc_log_dmesg },
+-      { "guc_ctb", .show = guc_debugfs_show, .data = guc_ctb },
+       { "guc_pc", .show = guc_debugfs_show, .data = guc_pc },
+ };
+@@ -115,7 +124,12 @@ void xe_guc_debugfs_register(struct xe_guc *guc, struct dentry *parent)
+ {
+       struct drm_minor *minor = guc_to_xe(guc)->drm.primary;
+-      drm_debugfs_create_files(debugfs_list,
+-                               ARRAY_SIZE(debugfs_list),
++      drm_debugfs_create_files(vf_safe_debugfs_list,
++                               ARRAY_SIZE(vf_safe_debugfs_list),
+                                parent, minor);
++
++      if (!IS_SRIOV_VF(guc_to_xe(guc)))
++              drm_debugfs_create_files(pf_only_debugfs_list,
++                                       ARRAY_SIZE(pf_only_debugfs_list),
++                                       parent, minor);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-xe-guc-make-creation-of-slpc-debugfs-files-condi.patch b/queue-6.15/drm-xe-guc-make-creation-of-slpc-debugfs-files-condi.patch
new file mode 100644 (file)
index 0000000..d63e155
--- /dev/null
@@ -0,0 +1,81 @@
+From 502b19c0da11fcb6e494c6786b0153c1ca7dc35d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 May 2025 14:19:02 +0000
+Subject: drm/xe/guc: Make creation of SLPC debugfs files conditional
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Aradhya Bhatia <aradhya.bhatia@intel.com>
+
+[ Upstream commit e22d7acf9f47b01c9a538f3dac5c8e8d46fbca96 ]
+
+Platforms that do not support SLPC are exempted from the GuC PC support.
+The GuC PC does not get initialized, and neither do its BOs get created.
+
+This causes a problem because the GuC PC debugfs file is still being
+created. Whenever the file is attempted to read, it causes a NULL
+pointer dereference on the supposed BO of the GuC PC.
+
+So, make the creation of SLPC debugfs files conditional to when SLPC
+features are supported.
+
+Fixes: aaab5404b16f ("drm/xe: Introduce GuC PC debugfs")
+Suggested-by: Matt Roper <matthew.d.roper@intel.com>
+Reviewed-by: Tejas Upadhyay <tejas.upadhyay@intel.com>
+Reviewed-by: Stuart Summers <stuart.summers@intel.com>
+Signed-off-by: Aradhya Bhatia <aradhya.bhatia@intel.com>
+Link: https://lore.kernel.org/r/20250516141902.5614-1-aradhya.bhatia@intel.com
+Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+(cherry picked from commit 17486cf3df5320752cc67ee8bcb2379d1b9de76c)
+Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_guc_debugfs.c | 17 ++++++++++++++---
+ 1 file changed, 14 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_guc_debugfs.c b/drivers/gpu/drm/xe/xe_guc_debugfs.c
+index f33013f8a0f38..0b102ab46c4df 100644
+--- a/drivers/gpu/drm/xe/xe_guc_debugfs.c
++++ b/drivers/gpu/drm/xe/xe_guc_debugfs.c
+@@ -113,23 +113,34 @@ static const struct drm_info_list vf_safe_debugfs_list[] = {
+       { "guc_ctb", .show = guc_debugfs_show, .data = guc_ctb },
+ };
++/* For GuC debugfs files that require the SLPC support */
++static const struct drm_info_list slpc_debugfs_list[] = {
++      { "guc_pc", .show = guc_debugfs_show, .data = guc_pc },
++};
++
+ /* everything else should be added here */
+ static const struct drm_info_list pf_only_debugfs_list[] = {
+       { "guc_log", .show = guc_debugfs_show, .data = guc_log },
+       { "guc_log_dmesg", .show = guc_debugfs_show, .data = guc_log_dmesg },
+-      { "guc_pc", .show = guc_debugfs_show, .data = guc_pc },
+ };
+ void xe_guc_debugfs_register(struct xe_guc *guc, struct dentry *parent)
+ {
+-      struct drm_minor *minor = guc_to_xe(guc)->drm.primary;
++      struct xe_device *xe =  guc_to_xe(guc);
++      struct drm_minor *minor = xe->drm.primary;
+       drm_debugfs_create_files(vf_safe_debugfs_list,
+                                ARRAY_SIZE(vf_safe_debugfs_list),
+                                parent, minor);
+-      if (!IS_SRIOV_VF(guc_to_xe(guc)))
++      if (!IS_SRIOV_VF(xe)) {
+               drm_debugfs_create_files(pf_only_debugfs_list,
+                                        ARRAY_SIZE(pf_only_debugfs_list),
+                                        parent, minor);
++
++              if (!xe->info.skip_guc_pc)
++                      drm_debugfs_create_files(slpc_debugfs_list,
++                                               ARRAY_SIZE(slpc_debugfs_list),
++                                               parent, minor);
++      }
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-xe-guc-refactor-guc-debugfs-initialization.patch b/queue-6.15/drm-xe-guc-refactor-guc-debugfs-initialization.patch
new file mode 100644 (file)
index 0000000..ba1c943
--- /dev/null
@@ -0,0 +1,202 @@
+From 04ee27df0d5ad0ff082aff13901908755ae5de19 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Apr 2025 16:26:33 +0200
+Subject: drm/xe/guc: Refactor GuC debugfs initialization
+
+From: Michal Wajdeczko <michal.wajdeczko@intel.com>
+
+[ Upstream commit e15826bb3c2c5377eedc757f2adec8dcaa5255f7 ]
+
+We don't have to drmm_kmalloc() local copy of debugfs_list to
+write there our pointer to the struct xe_guc as we can extract
+pointer to the struct xe_gt from the grandparent debugfs entry,
+in similar way to what we did for GT debugfs files.
+
+Note that there is no change in file/directory structure, just
+refactored how files are created and how functions are called.
+
+Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
+Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>
+Link: https://lore.kernel.org/r/20250403142635.1821-2-michal.wajdeczko@intel.com
+Stable-dep-of: e22d7acf9f47 ("drm/xe/guc: Make creation of SLPC debugfs files conditional")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_guc_debugfs.c | 130 ++++++++++++++--------------
+ 1 file changed, 67 insertions(+), 63 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_guc_debugfs.c b/drivers/gpu/drm/xe/xe_guc_debugfs.c
+index c569ff456e741..9a1c78b89f457 100644
+--- a/drivers/gpu/drm/xe/xe_guc_debugfs.c
++++ b/drivers/gpu/drm/xe/xe_guc_debugfs.c
+@@ -17,101 +17,105 @@
+ #include "xe_macros.h"
+ #include "xe_pm.h"
+-static struct xe_guc *node_to_guc(struct drm_info_node *node)
+-{
+-      return node->info_ent->data;
+-}
+-
+-static int guc_info(struct seq_file *m, void *data)
++/*
++ * guc_debugfs_show - A show callback for struct drm_info_list
++ * @m: the &seq_file
++ * @data: data used by the drm debugfs helpers
++ *
++ * This callback can be used in struct drm_info_list to describe debugfs
++ * files that are &xe_guc specific in similar way how we handle &xe_gt
++ * specific files using &xe_gt_debugfs_simple_show.
++ *
++ * It is assumed that those debugfs files will be created on directory entry
++ * which grandparent struct dentry d_inode->i_private points to &xe_gt.
++ *
++ *      /sys/kernel/debug/dri/0/
++ *      ├── gt0                 # dent->d_parent->d_parent (d_inode->i_private == gt)
++ *      │   ├── uc          # dent->d_parent
++ *      │   │   ├── guc_info    # dent
++ *      │   │   ├── guc_...
++ *
++ * This function assumes that &m->private will be set to the &struct
++ * drm_info_node corresponding to the instance of the info on a given &struct
++ * drm_minor (see struct drm_info_list.show for details).
++ *
++ * This function also assumes that struct drm_info_list.data will point to the
++ * function code that will actually print a file content::
++ *
++ *    int (*print)(struct xe_guc *, struct drm_printer *)
++ *
++ * Example::
++ *
++ *    int foo(struct xe_guc *guc, struct drm_printer *p)
++ *    {
++ *        drm_printf(p, "enabled %d\n", guc->submission_state.enabled);
++ *        return 0;
++ *    }
++ *
++ *    static const struct drm_info_list bar[] = {
++ *        { name = "foo", .show = guc_debugfs_show, .data = foo },
++ *    };
++ *
++ *    parent = debugfs_create_dir("uc", gtdir);
++ *    drm_debugfs_create_files(bar, ARRAY_SIZE(bar), parent, minor);
++ *
++ * Return: 0 on success or a negative error code on failure.
++ */
++static int guc_debugfs_show(struct seq_file *m, void *data)
+ {
+-      struct xe_guc *guc = node_to_guc(m->private);
+-      struct xe_device *xe = guc_to_xe(guc);
+       struct drm_printer p = drm_seq_file_printer(m);
++      struct drm_info_node *node = m->private;
++      struct dentry *parent = node->dent->d_parent;
++      struct dentry *grandparent = parent->d_parent;
++      struct xe_gt *gt = grandparent->d_inode->i_private;
++      struct xe_device *xe = gt_to_xe(gt);
++      int (*print)(struct xe_guc *, struct drm_printer *) = node->info_ent->data;
++      int ret;
+       xe_pm_runtime_get(xe);
+-      xe_guc_print_info(guc, &p);
++      ret = print(&gt->uc.guc, &p);
+       xe_pm_runtime_put(xe);
+-      return 0;
++      return ret;
+ }
+-static int guc_log(struct seq_file *m, void *data)
++static int guc_log(struct xe_guc *guc, struct drm_printer *p)
+ {
+-      struct xe_guc *guc = node_to_guc(m->private);
+-      struct xe_device *xe = guc_to_xe(guc);
+-      struct drm_printer p = drm_seq_file_printer(m);
+-
+-      xe_pm_runtime_get(xe);
+-      xe_guc_log_print(&guc->log, &p);
+-      xe_pm_runtime_put(xe);
+-
++      xe_guc_log_print(&guc->log, p);
+       return 0;
+ }
+-static int guc_log_dmesg(struct seq_file *m, void *data)
++static int guc_log_dmesg(struct xe_guc *guc, struct drm_printer *p)
+ {
+-      struct xe_guc *guc = node_to_guc(m->private);
+-      struct xe_device *xe = guc_to_xe(guc);
+-
+-      xe_pm_runtime_get(xe);
+       xe_guc_log_print_dmesg(&guc->log);
+-      xe_pm_runtime_put(xe);
+-
+       return 0;
+ }
+-static int guc_ctb(struct seq_file *m, void *data)
++static int guc_ctb(struct xe_guc *guc, struct drm_printer *p)
+ {
+-      struct xe_guc *guc = node_to_guc(m->private);
+-      struct xe_device *xe = guc_to_xe(guc);
+-      struct drm_printer p = drm_seq_file_printer(m);
+-
+-      xe_pm_runtime_get(xe);
+-      xe_guc_ct_print(&guc->ct, &p, true);
+-      xe_pm_runtime_put(xe);
+-
++      xe_guc_ct_print(&guc->ct, p, true);
+       return 0;
+ }
+-static int guc_pc(struct seq_file *m, void *data)
++static int guc_pc(struct xe_guc *guc, struct drm_printer *p)
+ {
+-      struct xe_guc *guc = node_to_guc(m->private);
+-      struct xe_device *xe = guc_to_xe(guc);
+-      struct drm_printer p = drm_seq_file_printer(m);
+-
+-      xe_pm_runtime_get(xe);
+-      xe_guc_pc_print(&guc->pc, &p);
+-      xe_pm_runtime_put(xe);
+-
++      xe_guc_pc_print(&guc->pc, p);
+       return 0;
+ }
+ static const struct drm_info_list debugfs_list[] = {
+-      {"guc_info", guc_info, 0},
+-      {"guc_log", guc_log, 0},
+-      {"guc_log_dmesg", guc_log_dmesg, 0},
+-      {"guc_ctb", guc_ctb, 0},
+-      {"guc_pc", guc_pc, 0},
++      { "guc_info", .show = guc_debugfs_show, .data = xe_guc_print_info },
++      { "guc_log", .show = guc_debugfs_show, .data = guc_log },
++      { "guc_log_dmesg", .show = guc_debugfs_show, .data = guc_log_dmesg },
++      { "guc_ctb", .show = guc_debugfs_show, .data = guc_ctb },
++      { "guc_pc", .show = guc_debugfs_show, .data = guc_pc },
+ };
+ void xe_guc_debugfs_register(struct xe_guc *guc, struct dentry *parent)
+ {
+       struct drm_minor *minor = guc_to_xe(guc)->drm.primary;
+-      struct drm_info_list *local;
+-      int i;
+-
+-#define DEBUGFS_SIZE  (ARRAY_SIZE(debugfs_list) * sizeof(struct drm_info_list))
+-      local = drmm_kmalloc(&guc_to_xe(guc)->drm, DEBUGFS_SIZE, GFP_KERNEL);
+-      if (!local)
+-              return;
+-
+-      memcpy(local, debugfs_list, DEBUGFS_SIZE);
+-#undef DEBUGFS_SIZE
+-
+-      for (i = 0; i < ARRAY_SIZE(debugfs_list); ++i)
+-              local[i].data = guc;
+-      drm_debugfs_create_files(local,
++      drm_debugfs_create_files(debugfs_list,
+                                ARRAY_SIZE(debugfs_list),
+                                parent, minor);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-xe-make-xe_gt_freq-part-of-the-documentation.patch b/queue-6.15/drm-xe-make-xe_gt_freq-part-of-the-documentation.patch
new file mode 100644 (file)
index 0000000..8bedba1
--- /dev/null
@@ -0,0 +1,87 @@
+From 6a94f7a9352e5e9e4a24a62b10341cf4bbabb20c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 May 2025 12:51:47 -0400
+Subject: drm/xe: Make xe_gt_freq part of the Documentation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rodrigo Vivi <rodrigo.vivi@intel.com>
+
+[ Upstream commit 55f8aa083604ce098c9d6a0911c6bcde15d03a80 ]
+
+The documentation was created with the creation of the component,
+however it has never been actually shown in the actual Documentation.
+
+While doing this, fixes the identation style, to avoid new warnings
+while building htmldocs.
+
+Fixes: bef52b5c7a19 ("drm/xe: Create a xe_gt_freq component for raw management and sysfs")
+Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>
+Link: https://lore.kernel.org/r/20250521165146.39616-3-rodrigo.vivi@intel.com
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+(cherry picked from commit af53f0fd99c3bbb3afd29f1612c9e88c5a92cc01)
+Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/gpu/xe/index.rst      |  1 +
+ Documentation/gpu/xe/xe_gt_freq.rst | 14 ++++++++++++++
+ drivers/gpu/drm/xe/xe_gt_freq.c     |  2 ++
+ 3 files changed, 17 insertions(+)
+ create mode 100644 Documentation/gpu/xe/xe_gt_freq.rst
+
+diff --git a/Documentation/gpu/xe/index.rst b/Documentation/gpu/xe/index.rst
+index 92cfb25e64d32..b53a0cc7f66a3 100644
+--- a/Documentation/gpu/xe/index.rst
++++ b/Documentation/gpu/xe/index.rst
+@@ -16,6 +16,7 @@ DG2, etc is provided to prototype the driver.
+    xe_migrate
+    xe_cs
+    xe_pm
++   xe_gt_freq
+    xe_pcode
+    xe_gt_mcr
+    xe_wa
+diff --git a/Documentation/gpu/xe/xe_gt_freq.rst b/Documentation/gpu/xe/xe_gt_freq.rst
+new file mode 100644
+index 0000000000000..c0811200e3275
+--- /dev/null
++++ b/Documentation/gpu/xe/xe_gt_freq.rst
+@@ -0,0 +1,14 @@
++.. SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++
++==========================
++Xe GT Frequency Management
++==========================
++
++.. kernel-doc:: drivers/gpu/drm/xe/xe_gt_freq.c
++   :doc: Xe GT Frequency Management
++
++Internal API
++============
++
++.. kernel-doc:: drivers/gpu/drm/xe/xe_gt_freq.c
++   :internal:
+diff --git a/drivers/gpu/drm/xe/xe_gt_freq.c b/drivers/gpu/drm/xe/xe_gt_freq.c
+index 604bdc7c81736..985efbc685286 100644
+--- a/drivers/gpu/drm/xe/xe_gt_freq.c
++++ b/drivers/gpu/drm/xe/xe_gt_freq.c
+@@ -32,6 +32,7 @@
+  * Xe's Freq provides a sysfs API for frequency management:
+  *
+  * device/tile#/gt#/freq0/<item>_freq *read-only* files:
++ *
+  * - act_freq: The actual resolved frequency decided by PCODE.
+  * - cur_freq: The current one requested by GuC PC to the PCODE.
+  * - rpn_freq: The Render Performance (RP) N level, which is the minimal one.
+@@ -39,6 +40,7 @@
+  * - rp0_freq: The Render Performance (RP) 0 level, which is the maximum one.
+  *
+  * device/tile#/gt#/freq0/<item>_freq *read-write* files:
++ *
+  * - min_freq: Min frequency request.
+  * - max_freq: Max frequency request.
+  *             If max <= min, then freq_min becomes a fixed frequency request.
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-xe-pxp-clarify-pxp-queue-creation-behavior-if-px.patch b/queue-6.15/drm-xe-pxp-clarify-pxp-queue-creation-behavior-if-px.patch
new file mode 100644 (file)
index 0000000..282db75
--- /dev/null
@@ -0,0 +1,86 @@
+From 96dd782c798a1eacb42755e73dcd474b762c494c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 May 2025 15:54:04 -0700
+Subject: drm/xe/pxp: Clarify PXP queue creation behavior if PXP is not ready
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
+
+[ Upstream commit 69a58ef4fa77759b0e0c2f79834fa51b00a50c0b ]
+
+The expected flow of operations when using PXP is to query the PXP
+status and wait for it to transition to "ready" before attempting to
+create an exec_queue. This flow is followed by the Mesa driver, but
+there is no guarantee that an incorrectly coded (or malicious) app
+will not attempt to create the queue first without querying the status.
+Therefore, we need to clarify what the expected behavior of the queue
+creation ioctl is in this scenario.
+
+Currently, the ioctl always fails with an -EBUSY code no matter the
+error, but for consistency it is better to distinguish between "failed
+to init" (-EIO) and "not ready" (-EBUSY), the same way the query ioctl
+does. Note that, while this is a change in the return code of an ioctl,
+the behavior of the ioctl in this particular corner case was not clearly
+spec'd, so no one should have been relying on it (and we know that Mesa,
+which is the only known userspace for this, didn't).
+
+v2: Minor rework of the doc (Rodrigo)
+
+Fixes: 72d479601d67 ("drm/xe/pxp/uapi: Add userspace and LRC support for PXP-using queues")
+Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
+Cc: John Harrison <John.C.Harrison@Intel.com>
+Cc: José Roberto de Souza <jose.souza@intel.com>
+Reviewed-by: José Roberto de Souza <jose.souza@intel.com>
+Reviewed-by: John Harrison <John.C.Harrison@Intel.com>
+Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Link: https://lore.kernel.org/r/20250522225401.3953243-7-daniele.ceraolospurio@intel.com
+(cherry picked from commit 21784ca96025b62d95b670b7639ad70ddafa69b8)
+Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_pxp.c | 8 ++++++--
+ include/uapi/drm/xe_drm.h   | 5 +++++
+ 2 files changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_pxp.c b/drivers/gpu/drm/xe/xe_pxp.c
+index 454ea7dc08ac8..b5bc15f436fa2 100644
+--- a/drivers/gpu/drm/xe/xe_pxp.c
++++ b/drivers/gpu/drm/xe/xe_pxp.c
+@@ -541,10 +541,14 @@ int xe_pxp_exec_queue_add(struct xe_pxp *pxp, struct xe_exec_queue *q)
+        */
+       xe_pm_runtime_get(pxp->xe);
+-      if (!pxp_prerequisites_done(pxp)) {
+-              ret = -EBUSY;
++      /* get_readiness_status() returns 0 for in-progress and 1 for done */
++      ret = xe_pxp_get_readiness_status(pxp);
++      if (ret <= 0) {
++              if (!ret)
++                      ret = -EBUSY;
+               goto out;
+       }
++      ret = 0;
+ wait_for_idle:
+       /*
+diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h
+index 616916985e3f3..5e5442d03f878 100644
+--- a/include/uapi/drm/xe_drm.h
++++ b/include/uapi/drm/xe_drm.h
+@@ -1206,6 +1206,11 @@ struct drm_xe_vm_bind {
+  *    there is no need to explicitly set that. When a queue of type
+  *    %DRM_XE_PXP_TYPE_HWDRM is created, the PXP default HWDRM session
+  *    (%XE_PXP_HWDRM_DEFAULT_SESSION) will be started, if isn't already running.
++ *    The user is expected to query the PXP status via the query ioctl (see
++ *    %DRM_XE_DEVICE_QUERY_PXP_STATUS) and to wait for PXP to be ready before
++ *    attempting to create a queue with this property. When a queue is created
++ *    before PXP is ready, the ioctl will return -EBUSY if init is still in
++ *    progress or -EIO if init failed.
+  *    Given that going into a power-saving state kills PXP HWDRM sessions,
+  *    runtime PM will be blocked while queues of this type are alive.
+  *    All PXP queues will be killed if a PXP invalidation event occurs.
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-xe-pxp-use-the-correct-define-in-the-set_propert.patch b/queue-6.15/drm-xe-pxp-use-the-correct-define-in-the-set_propert.patch
new file mode 100644 (file)
index 0000000..278049e
--- /dev/null
@@ -0,0 +1,44 @@
+From 97a4241a8169fb87516bc54c9f20c6d97cfe69e6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 May 2025 15:54:03 -0700
+Subject: drm/xe/pxp: Use the correct define in the set_property_funcs array
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
+
+[ Upstream commit 6bf4d5649230ca65725ec4793333fb5eba18d646 ]
+
+The define of the extension type was accidentally used instead of the
+one of the property itself. They're both zero, so no functional issue,
+but we should use the correct define for code correctness.
+
+Fixes: 41a97c4a1294 ("drm/xe/pxp/uapi: Add API to mark a BO as using PXP")
+Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
+Cc: John Harrison <John.C.Harrison@Intel.com>
+Reviewed-by: John Harrison <John.C.Harrison@Intel.com>
+Link: https://lore.kernel.org/r/20250522225401.3953243-6-daniele.ceraolospurio@intel.com
+(cherry picked from commit 1d891ee820fd0fbb4101eacb0d922b5050a24933)
+Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_bo.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
+index b98526d271f2f..5922302c3e00c 100644
+--- a/drivers/gpu/drm/xe/xe_bo.c
++++ b/drivers/gpu/drm/xe/xe_bo.c
+@@ -2396,7 +2396,7 @@ typedef int (*xe_gem_create_set_property_fn)(struct xe_device *xe,
+                                            u64 value);
+ static const xe_gem_create_set_property_fn gem_create_set_property_funcs[] = {
+-      [DRM_XE_GEM_CREATE_EXTENSION_SET_PROPERTY] = gem_create_set_pxp_type,
++      [DRM_XE_GEM_CREATE_SET_PROPERTY_PXP_TYPE] = gem_create_set_pxp_type,
+ };
+ static int gem_create_user_ext_set_property(struct xe_device *xe,
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-xe-rework-eviction-rejection-of-bound-external-b.patch b/queue-6.15/drm-xe-rework-eviction-rejection-of-bound-external-b.patch
new file mode 100644 (file)
index 0000000..90fb626
--- /dev/null
@@ -0,0 +1,239 @@
+From 80eaa5c3142ce1103bfc7c29e5a692846dc24bf9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 May 2025 18:41:05 +0200
+Subject: drm/xe: Rework eviction rejection of bound external bos
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+
+[ Upstream commit 5cc3325584c425069c1c3355c775314d64bf8770 ]
+
+For preempt_fence mode VM's we're rejecting eviction of
+shared bos during VM_BIND. However, since we do this in the
+move() callback, we're getting an eviction failure warning from
+TTM. The TTM callback intended for these things is
+eviction_valuable().
+
+However, the latter doesn't pass in the struct ttm_operation_ctx
+needed to determine whether the caller needs this.
+
+Instead, attach the needed information to the vm under the
+vm->resv, until we've been able to update TTM to provide the
+needed information. And add sufficient lockdep checks to prevent
+misuse and races.
+
+v2:
+- Fix a copy-paste error in xe_vm_clear_validating()
+v3:
+- Fix kerneldoc errors.
+
+Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Fixes: 0af944f0e308 ("drm/xe: Reject BO eviction if BO is bound to current VM")
+Reviewed-by: Matthew Brost <matthew.brost@intel.com>
+Link: https://lore.kernel.org/r/20250528164105.234718-1-thomas.hellstrom@linux.intel.com
+(cherry picked from commit 9d5558649f68e2e84a87a909631b30e15ca0f8ec)
+Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_bo.c       | 46 ++++++++++++---------
+ drivers/gpu/drm/xe/xe_vm.h       | 69 ++++++++++++++++++++++++++++++++
+ drivers/gpu/drm/xe/xe_vm_types.h |  8 ++++
+ 3 files changed, 105 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
+index 64f9c936eea06..b98526d271f2f 100644
+--- a/drivers/gpu/drm/xe/xe_bo.c
++++ b/drivers/gpu/drm/xe/xe_bo.c
+@@ -816,21 +816,6 @@ static int xe_bo_move(struct ttm_buffer_object *ttm_bo, bool evict,
+               goto out;
+       }
+-      /* Reject BO eviction if BO is bound to current VM. */
+-      if (evict && ctx->resv) {
+-              struct drm_gpuvm_bo *vm_bo;
+-
+-              drm_gem_for_each_gpuvm_bo(vm_bo, &bo->ttm.base) {
+-                      struct xe_vm *vm = gpuvm_to_vm(vm_bo->vm);
+-
+-                      if (xe_vm_resv(vm) == ctx->resv &&
+-                          xe_vm_in_preempt_fence_mode(vm)) {
+-                              ret = -EBUSY;
+-                              goto out;
+-                      }
+-              }
+-      }
+-
+       /*
+        * Failed multi-hop where the old_mem is still marked as
+        * TTM_PL_FLAG_TEMPORARY, should just be a dummy move.
+@@ -1023,6 +1008,25 @@ static long xe_bo_shrink_purge(struct ttm_operation_ctx *ctx,
+       return lret;
+ }
++static bool
++xe_bo_eviction_valuable(struct ttm_buffer_object *bo, const struct ttm_place *place)
++{
++      struct drm_gpuvm_bo *vm_bo;
++
++      if (!ttm_bo_eviction_valuable(bo, place))
++              return false;
++
++      if (!xe_bo_is_xe_bo(bo))
++              return true;
++
++      drm_gem_for_each_gpuvm_bo(vm_bo, &bo->base) {
++              if (xe_vm_is_validating(gpuvm_to_vm(vm_bo->vm)))
++                      return false;
++      }
++
++      return true;
++}
++
+ /**
+  * xe_bo_shrink() - Try to shrink an xe bo.
+  * @ctx: The struct ttm_operation_ctx used for shrinking.
+@@ -1057,7 +1061,7 @@ long xe_bo_shrink(struct ttm_operation_ctx *ctx, struct ttm_buffer_object *bo,
+           (flags.purge && !xe_tt->purgeable))
+               return -EBUSY;
+-      if (!ttm_bo_eviction_valuable(bo, &place))
++      if (!xe_bo_eviction_valuable(bo, &place))
+               return -EBUSY;
+       if (!xe_bo_is_xe_bo(bo) || !xe_bo_get_unless_zero(xe_bo))
+@@ -1418,7 +1422,7 @@ const struct ttm_device_funcs xe_ttm_funcs = {
+       .io_mem_pfn = xe_ttm_io_mem_pfn,
+       .access_memory = xe_ttm_access_memory,
+       .release_notify = xe_ttm_bo_release_notify,
+-      .eviction_valuable = ttm_bo_eviction_valuable,
++      .eviction_valuable = xe_bo_eviction_valuable,
+       .delete_mem_notify = xe_ttm_bo_delete_mem_notify,
+       .swap_notify = xe_ttm_bo_swap_notify,
+ };
+@@ -2260,6 +2264,8 @@ int xe_bo_validate(struct xe_bo *bo, struct xe_vm *vm, bool allow_res_evict)
+               .no_wait_gpu = false,
+               .gfp_retry_mayfail = true,
+       };
++      struct pin_cookie cookie;
++      int ret;
+       if (vm) {
+               lockdep_assert_held(&vm->lock);
+@@ -2269,8 +2275,12 @@ int xe_bo_validate(struct xe_bo *bo, struct xe_vm *vm, bool allow_res_evict)
+               ctx.resv = xe_vm_resv(vm);
+       }
++      cookie = xe_vm_set_validating(vm, allow_res_evict);
+       trace_xe_bo_validate(bo);
+-      return ttm_bo_validate(&bo->ttm, &bo->placement, &ctx);
++      ret = ttm_bo_validate(&bo->ttm, &bo->placement, &ctx);
++      xe_vm_clear_validating(vm, allow_res_evict, cookie);
++
++      return ret;
+ }
+ bool xe_bo_is_xe_bo(struct ttm_buffer_object *bo)
+diff --git a/drivers/gpu/drm/xe/xe_vm.h b/drivers/gpu/drm/xe/xe_vm.h
+index 0ef811fc2bdee..494af6bdc646b 100644
+--- a/drivers/gpu/drm/xe/xe_vm.h
++++ b/drivers/gpu/drm/xe/xe_vm.h
+@@ -301,6 +301,75 @@ void xe_vm_snapshot_capture_delayed(struct xe_vm_snapshot *snap);
+ void xe_vm_snapshot_print(struct xe_vm_snapshot *snap, struct drm_printer *p);
+ void xe_vm_snapshot_free(struct xe_vm_snapshot *snap);
++/**
++ * xe_vm_set_validating() - Register this task as currently making bos resident
++ * @allow_res_evict: Allow eviction of buffer objects bound to @vm when
++ * validating.
++ * @vm: Pointer to the vm or NULL.
++ *
++ * Register this task as currently making bos resident for the vm. Intended
++ * to avoid eviction by the same task of shared bos bound to the vm.
++ * Call with the vm's resv lock held.
++ *
++ * Return: A pin cookie that should be used for xe_vm_clear_validating().
++ */
++static inline struct pin_cookie xe_vm_set_validating(struct xe_vm *vm,
++                                                   bool allow_res_evict)
++{
++      struct pin_cookie cookie = {};
++
++      if (vm && !allow_res_evict) {
++              xe_vm_assert_held(vm);
++              cookie = lockdep_pin_lock(&xe_vm_resv(vm)->lock.base);
++              /* Pairs with READ_ONCE in xe_vm_is_validating() */
++              WRITE_ONCE(vm->validating, current);
++      }
++
++      return cookie;
++}
++
++/**
++ * xe_vm_clear_validating() - Unregister this task as currently making bos resident
++ * @vm: Pointer to the vm or NULL
++ * @allow_res_evict: Eviction from @vm was allowed. Must be set to the same
++ * value as for xe_vm_set_validation().
++ * @cookie: Cookie obtained from xe_vm_set_validating().
++ *
++ * Register this task as currently making bos resident for the vm. Intended
++ * to avoid eviction by the same task of shared bos bound to the vm.
++ * Call with the vm's resv lock held.
++ */
++static inline void xe_vm_clear_validating(struct xe_vm *vm, bool allow_res_evict,
++                                        struct pin_cookie cookie)
++{
++      if (vm && !allow_res_evict) {
++              lockdep_unpin_lock(&xe_vm_resv(vm)->lock.base, cookie);
++              /* Pairs with READ_ONCE in xe_vm_is_validating() */
++              WRITE_ONCE(vm->validating, NULL);
++      }
++}
++
++/**
++ * xe_vm_is_validating() - Whether bos bound to the vm are currently being made resident
++ * by the current task.
++ * @vm: Pointer to the vm.
++ *
++ * If this function returns %true, we should be in a vm resv locked region, since
++ * the current process is the same task that called xe_vm_set_validating().
++ * The function asserts that that's indeed the case.
++ *
++ * Return: %true if the task is currently making bos resident, %false otherwise.
++ */
++static inline bool xe_vm_is_validating(struct xe_vm *vm)
++{
++      /* Pairs with WRITE_ONCE in xe_vm_is_validating() */
++      if (READ_ONCE(vm->validating) == current) {
++              xe_vm_assert_held(vm);
++              return true;
++      }
++      return false;
++}
++
+ #if IS_ENABLED(CONFIG_DRM_XE_USERPTR_INVAL_INJECT)
+ void xe_vma_userptr_force_invalidate(struct xe_userptr_vma *uvma);
+ #else
+diff --git a/drivers/gpu/drm/xe/xe_vm_types.h b/drivers/gpu/drm/xe/xe_vm_types.h
+index 84fa41b9fa20f..0882674ce1cba 100644
+--- a/drivers/gpu/drm/xe/xe_vm_types.h
++++ b/drivers/gpu/drm/xe/xe_vm_types.h
+@@ -310,6 +310,14 @@ struct xe_vm {
+        * protected by the vm resv.
+        */
+       u64 tlb_flush_seqno;
++      /**
++       * @validating: The task that is currently making bos resident for this vm.
++       * Protected by the VM's resv for writing. Opportunistic reading can be done
++       * using READ_ONCE. Note: This is a workaround for the
++       * TTM eviction_valuable() callback not being passed a struct
++       * ttm_operation_context(). Future work might want to address this.
++       */
++      struct task_struct *validating;
+       /** @batch_invalidate_tlb: Always invalidate TLB before batch start */
+       bool batch_invalidate_tlb;
+       /** @xef: XE file handle for tracking this VM's drm client */
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-xe-vm-move-xe_svm_init-earlier.patch b/queue-6.15/drm-xe-vm-move-xe_svm_init-earlier.patch
new file mode 100644 (file)
index 0000000..d6f5fcc
--- /dev/null
@@ -0,0 +1,80 @@
+From e1579d000677153c4951fc7f5ff41ebf81ccba87 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 May 2025 16:24:26 +0100
+Subject: drm/xe/vm: move xe_svm_init() earlier
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Matthew Auld <matthew.auld@intel.com>
+
+[ Upstream commit 8cf8cde41ad01150afbd1327ad1942387787f7fd ]
+
+In xe_vm_close_and_put() we need to be able to call xe_svm_fini(),
+however during vm creation we can call this on the error path, before
+having actually initialised the svm state, leading to various splats
+followed by a fatal NPD.
+
+Fixes: 6fd979c2f331 ("drm/xe: Add SVM init / close / fini to faulting VMs")
+Link: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/4967
+Signed-off-by: Matthew Auld <matthew.auld@intel.com>
+Cc: Matthew Brost <matthew.brost@intel.com>
+Reviewed-by: Matthew Brost <matthew.brost@intel.com>
+Link: https://lore.kernel.org/r/20250514152424.149591-4-matthew.auld@intel.com
+(cherry picked from commit 4f296d77cf49fcb5f90b4674123ad7f3a0676165)
+Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_vm.c | 19 ++++++++++++-------
+ 1 file changed, 12 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
+index 367c84b90e9ef..737172013a8f9 100644
+--- a/drivers/gpu/drm/xe/xe_vm.c
++++ b/drivers/gpu/drm/xe/xe_vm.c
+@@ -1681,10 +1681,16 @@ struct xe_vm *xe_vm_create(struct xe_device *xe, u32 flags)
+       if (flags & XE_VM_FLAG_LR_MODE)
+               xe_pm_runtime_get_noresume(xe);
++      if (flags & XE_VM_FLAG_FAULT_MODE) {
++              err = xe_svm_init(vm);
++              if (err)
++                      goto err_no_resv;
++      }
++
+       vm_resv_obj = drm_gpuvm_resv_object_alloc(&xe->drm);
+       if (!vm_resv_obj) {
+               err = -ENOMEM;
+-              goto err_no_resv;
++              goto err_svm_fini;
+       }
+       drm_gpuvm_init(&vm->gpuvm, "Xe VM", DRM_GPUVM_RESV_PROTECTED, &xe->drm,
+@@ -1757,12 +1763,6 @@ struct xe_vm *xe_vm_create(struct xe_device *xe, u32 flags)
+               }
+       }
+-      if (flags & XE_VM_FLAG_FAULT_MODE) {
+-              err = xe_svm_init(vm);
+-              if (err)
+-                      goto err_close;
+-      }
+-
+       if (number_tiles > 1)
+               vm->composite_fence_ctx = dma_fence_context_alloc(1);
+@@ -1776,6 +1776,11 @@ struct xe_vm *xe_vm_create(struct xe_device *xe, u32 flags)
+       xe_vm_close_and_put(vm);
+       return ERR_PTR(err);
++err_svm_fini:
++      if (flags & XE_VM_FLAG_FAULT_MODE) {
++              vm->size = 0; /* close the vm */
++              xe_svm_fini(vm);
++      }
+ err_no_resv:
+       mutex_destroy(&vm->snap_mutex);
+       for_each_tile(tile, xe, id)
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-xe-vsec-fix-config_intel_vsec-dependency.patch b/queue-6.15/drm-xe-vsec-fix-config_intel_vsec-dependency.patch
new file mode 100644 (file)
index 0000000..52c9575
--- /dev/null
@@ -0,0 +1,67 @@
+From 7ddbd8816c8ecb1b48f180df8681120a95769623 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 May 2025 10:23:56 -0700
+Subject: drm/xe/vsec: fix CONFIG_INTEL_VSEC dependency
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 2182f358fb138f81a586ffdddd510f2a4fc61702 ]
+
+The XE driver can be built with or without VSEC support, but fails to link as
+built-in if vsec is in a loadable module:
+
+x86_64-linux-ld: vmlinux.o: in function `xe_vsec_init':
+(.text+0x1e83e16): undefined reference to `intel_vsec_register'
+
+The normal fix for this is to add a 'depends on INTEL_VSEC || !INTEL_VSEC',
+forcing XE to be a loadable module as well, but that causes a circular
+dependency:
+
+        symbol DRM_XE depends on INTEL_VSEC
+        symbol INTEL_VSEC depends on X86_PLATFORM_DEVICES
+        symbol X86_PLATFORM_DEVICES is selected by DRM_XE
+
+The problem here is selecting a symbol from another subsystem, so change
+that as well and rephrase the 'select' into the corresponding dependency.
+Since X86_PLATFORM_DEVICES is 'default y', there is no change to
+defconfig builds here.
+
+Fixes: 0c45e76fcc62 ("drm/xe/vsec: Support BMG devices")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>
+Link: https://lore.kernel.org/r/20250529172355.2395634-2-lucas.demarchi@intel.com
+Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
+(cherry picked from commit e4931f8be347ec5f19df4d6d33aea37145378c42)
+Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/Kconfig | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/xe/Kconfig b/drivers/gpu/drm/xe/Kconfig
+index 5c2f459a2925a..9a46aafcb33ba 100644
+--- a/drivers/gpu/drm/xe/Kconfig
++++ b/drivers/gpu/drm/xe/Kconfig
+@@ -2,6 +2,8 @@
+ config DRM_XE
+       tristate "Intel Xe Graphics"
+       depends on DRM && PCI && MMU && (m || (y && KUNIT=y))
++      depends on INTEL_VSEC || !INTEL_VSEC
++      depends on X86_PLATFORM_DEVICES || !(X86 && ACPI)
+       select INTERVAL_TREE
+       # we need shmfs for the swappable backing store, and in particular
+       # the shmem_readpage() which depends upon tmpfs
+@@ -27,7 +29,6 @@ config DRM_XE
+       select BACKLIGHT_CLASS_DEVICE if ACPI
+       select INPUT if ACPI
+       select ACPI_VIDEO if X86 && ACPI
+-      select X86_PLATFORM_DEVICES if X86 && ACPI
+       select ACPI_WMI if X86 && ACPI
+       select SYNC_FILE
+       select IOSF_MBI
+-- 
+2.39.5
+
diff --git a/queue-6.15/drm-xlnx-zynqmp_dpsub-fix-kconfig-dependencies-for-a.patch b/queue-6.15/drm-xlnx-zynqmp_dpsub-fix-kconfig-dependencies-for-a.patch
new file mode 100644 (file)
index 0000000..e591017
--- /dev/null
@@ -0,0 +1,44 @@
+From e3234857d4d733c15dafc3396aa82b446ee3fc82 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 14:20:32 +0100
+Subject: drm: xlnx: zynqmp_dpsub: fix Kconfig dependencies for ASoC
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit f9f087d946266bc5da7c3a17bd8fd9d01969e3cf ]
+
+The new audio code fails to build when sounds support is in a loadable
+module but the GPU driver is built-in:
+
+x86_64-linux-ld: zynqmp_dp_audio.c:(.text+0x6a8): undefined reference to `devm_snd_soc_register_card'
+x86_64-linux-ld: drivers/gpu/drm/xlnx/zynqmp_dp_audio.o:(.rodata+0x1bc): undefined reference to `snd_soc_info_volsw'
+x86_64-linux-ld: drivers/gpu/drm/xlnx/zynqmp_dp_audio.o:(.rodata+0x1f0): undefined reference to `snd_soc_get_volsw'
+x86_64-linux-ld: drivers/gpu/drm/xlnx/zynqmp_dp_audio.o:(.rodata+0x1f4): undefined reference to `snd_soc_put_volsw'
+
+Change the Kconfig dependency to disallow the sound support in this
+configuration.
+
+Fixes: 3ec5c1579305 ("drm: xlnx: zynqmp_dpsub: Add DP audio support")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250227132036.1136600-1-arnd@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xlnx/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/xlnx/Kconfig b/drivers/gpu/drm/xlnx/Kconfig
+index dbecca9bdd544..cfabf5e2a0bb0 100644
+--- a/drivers/gpu/drm/xlnx/Kconfig
++++ b/drivers/gpu/drm/xlnx/Kconfig
+@@ -22,6 +22,7 @@ config DRM_ZYNQMP_DPSUB_AUDIO
+       bool "ZynqMP DisplayPort Audio Support"
+       depends on DRM_ZYNQMP_DPSUB
+       depends on SND && SND_SOC
++      depends on SND_SOC=y || DRM_ZYNQMP_DPSUB=m
+       select SND_SOC_GENERIC_DMAENGINE_PCM
+       help
+         Choose this option to enable DisplayPort audio support in the ZynqMP
+-- 
+2.39.5
+
diff --git a/queue-6.15/dt-bindings-soc-fsl-qman-fqd-fix-reserved-memory.yam.patch b/queue-6.15/dt-bindings-soc-fsl-qman-fqd-fix-reserved-memory.yam.patch
new file mode 100644 (file)
index 0000000..14e696f
--- /dev/null
@@ -0,0 +1,47 @@
+From afccec63c775cfe4f169ee16090cf07ba0571e87 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 May 2025 10:42:31 -0500
+Subject: dt-bindings: soc: fsl,qman-fqd: Fix reserved-memory.yaml reference
+
+From: Rob Herring (Arm) <robh@kernel.org>
+
+[ Upstream commit 1090c38bbfd9ab7f22830c0e8a5c605e7d4ef084 ]
+
+The reserved-memory.yaml reference needs the full path. No warnings were
+generated because the example has the wrong compatible string, so fix
+that too.
+
+Fixes: 304a90c4f75d ("dt-bindings: soc: fsl: Convert q(b)man-* to yaml format")
+Acked-by: Conor Dooley <conor.dooley@microchip.com>
+Link: https://lore.kernel.org/r/20250507154231.1590634-1-robh@kernel.org
+Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/devicetree/bindings/soc/fsl/fsl,qman-fqd.yaml | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/soc/fsl/fsl,qman-fqd.yaml b/Documentation/devicetree/bindings/soc/fsl/fsl,qman-fqd.yaml
+index de0b4ae740ff2..a975bce599750 100644
+--- a/Documentation/devicetree/bindings/soc/fsl/fsl,qman-fqd.yaml
++++ b/Documentation/devicetree/bindings/soc/fsl/fsl,qman-fqd.yaml
+@@ -50,7 +50,7 @@ required:
+   - compatible
+ allOf:
+-  - $ref: reserved-memory.yaml
++  - $ref: /schemas/reserved-memory/reserved-memory.yaml
+ unevaluatedProperties: false
+@@ -61,7 +61,7 @@ examples:
+         #size-cells = <2>;
+         qman-fqd {
+-            compatible = "shared-dma-pool";
++            compatible = "fsl,qman-fqd";
+             size = <0 0x400000>;
+             alignment = <0 0x400000>;
+             no-map;
+-- 
+2.39.5
+
diff --git a/queue-6.15/dt-bindings-vendor-prefixes-add-liontron-name.patch b/queue-6.15/dt-bindings-vendor-prefixes-add-liontron-name.patch
new file mode 100644 (file)
index 0000000..a93171c
--- /dev/null
@@ -0,0 +1,40 @@
+From 060473ca0fec66101d2bcb1adb02e9f1b34734cb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 May 2025 17:47:27 +0100
+Subject: dt-bindings: vendor-prefixes: Add Liontron name
+
+From: Andre Przywara <andre.przywara@arm.com>
+
+[ Upstream commit 9baa27a2e9fc746143ab686b6dbe2d515284a4c5 ]
+
+Liontron is a company based in Shenzen, China, making industrial
+development boards and embedded computers, mostly using Rockchip and
+Allwinner SoCs.
+
+Add their name to the list of vendors.
+
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Acked-by: Rob Herring (Arm) <robh@kernel.org>
+Link: https://patch.msgid.link/20250505164729.18175-2-andre.przywara@arm.com
+Signed-off-by: Chen-Yu Tsai <wens@csie.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
+index 86f6a19b28ae2..190ab40cf23af 100644
+--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
++++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
+@@ -864,6 +864,8 @@ patternProperties:
+     description: Linux-specific binding
+   "^linx,.*":
+     description: Linx Technologies
++  "^liontron,.*":
++    description: Shenzhen Liontron Technology Co., Ltd
+   "^liteon,.*":
+     description: LITE-ON Technology Corp.
+   "^litex,.*":
+-- 
+2.39.5
+
diff --git a/queue-6.15/edac-bluefield-don-t-use-bluefield_edac_readl-result.patch b/queue-6.15/edac-bluefield-don-t-use-bluefield_edac_readl-result.patch
new file mode 100644 (file)
index 0000000..389b23a
--- /dev/null
@@ -0,0 +1,84 @@
+From 08c4784c01d2f0cbcee7bb54bc6a4d5417f2a4ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Mar 2025 17:47:47 -0400
+Subject: EDAC/bluefield: Don't use bluefield_edac_readl() result on error
+
+From: David Thompson <davthompson@nvidia.com>
+
+[ Upstream commit ea3b0b7f541b9511abe2b89547c95458804f38e2 ]
+
+The bluefield_edac_readl() routine returns an uninitialized result on error
+paths. In those cases the calling routine should not use the uninitialized
+result. The driver should simply log the error, and then return early.
+
+Fixes: e41967575474 ("EDAC/bluefield: Use Arm SMC for EMI access on BlueField-2")
+Signed-off-by: David Thompson <davthompson@nvidia.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Reviewed-by: Shravan Kumar Ramani <shravankr@nvidia.com>
+Link: https://lore.kernel.org/20250318214747.12271-1-davthompson@nvidia.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/edac/bluefield_edac.c | 20 +++++++++++++++-----
+ 1 file changed, 15 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/edac/bluefield_edac.c b/drivers/edac/bluefield_edac.c
+index 4942a240c30f2..ae3bb7afa103e 100644
+--- a/drivers/edac/bluefield_edac.c
++++ b/drivers/edac/bluefield_edac.c
+@@ -199,8 +199,10 @@ static void bluefield_gather_report_ecc(struct mem_ctl_info *mci,
+        * error without the detailed information.
+        */
+       err = bluefield_edac_readl(priv, MLXBF_SYNDROM, &dram_syndrom);
+-      if (err)
++      if (err) {
+               dev_err(priv->dev, "DRAM syndrom read failed.\n");
++              return;
++      }
+       serr = FIELD_GET(MLXBF_SYNDROM__SERR, dram_syndrom);
+       derr = FIELD_GET(MLXBF_SYNDROM__DERR, dram_syndrom);
+@@ -213,20 +215,26 @@ static void bluefield_gather_report_ecc(struct mem_ctl_info *mci,
+       }
+       err = bluefield_edac_readl(priv, MLXBF_ADD_INFO, &dram_additional_info);
+-      if (err)
++      if (err) {
+               dev_err(priv->dev, "DRAM additional info read failed.\n");
++              return;
++      }
+       err_prank = FIELD_GET(MLXBF_ADD_INFO__ERR_PRANK, dram_additional_info);
+       ecc_dimm = (err_prank >= 2 && priv->dimm_ranks[0] <= 2) ? 1 : 0;
+       err = bluefield_edac_readl(priv, MLXBF_ERR_ADDR_0, &edea0);
+-      if (err)
++      if (err) {
+               dev_err(priv->dev, "Error addr 0 read failed.\n");
++              return;
++      }
+       err = bluefield_edac_readl(priv, MLXBF_ERR_ADDR_1, &edea1);
+-      if (err)
++      if (err) {
+               dev_err(priv->dev, "Error addr 1 read failed.\n");
++              return;
++      }
+       ecc_dimm_addr = ((u64)edea1 << 32) | edea0;
+@@ -250,8 +258,10 @@ static void bluefield_edac_check(struct mem_ctl_info *mci)
+               return;
+       err = bluefield_edac_readl(priv, MLXBF_ECC_CNT, &ecc_count);
+-      if (err)
++      if (err) {
+               dev_err(priv->dev, "ECC count read failed.\n");
++              return;
++      }
+       single_error_count = FIELD_GET(MLXBF_ECC_CNT__SERR_CNT, ecc_count);
+       double_error_count = FIELD_GET(MLXBF_ECC_CNT__DERR_CNT, ecc_count);
+-- 
+2.39.5
+
diff --git a/queue-6.15/edac-skx_common-fix-general-protection-fault.patch b/queue-6.15/edac-skx_common-fix-general-protection-fault.patch
new file mode 100644 (file)
index 0000000..727a5ce
--- /dev/null
@@ -0,0 +1,68 @@
+From d55cf1e486c01f6dbb153032d05300bc6d6b3974 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Apr 2025 23:07:18 +0800
+Subject: EDAC/skx_common: Fix general protection fault
+
+From: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+
+[ Upstream commit 20d2d476b3ae18041be423671a8637ed5ffd6958 ]
+
+After loading i10nm_edac (which automatically loads skx_edac_common), if
+unload only i10nm_edac, then reload it and perform error injection testing,
+a general protection fault may occur:
+
+  mce: [Hardware Error]: Machine check events logged
+  Oops: general protection fault ...
+  ...
+  Workqueue: events mce_gen_pool_process
+  RIP: 0010:string+0x53/0xe0
+  ...
+  Call Trace:
+  <TASK>
+  ? die_addr+0x37/0x90
+  ? exc_general_protection+0x1e7/0x3f0
+  ? asm_exc_general_protection+0x26/0x30
+  ? string+0x53/0xe0
+  vsnprintf+0x23e/0x4c0
+  snprintf+0x4d/0x70
+  skx_adxl_decode+0x16a/0x330 [skx_edac_common]
+  skx_mce_check_error.part.0+0xf8/0x220 [skx_edac_common]
+  skx_mce_check_error+0x17/0x20 [skx_edac_common]
+  ...
+
+The issue arose was because the variable 'adxl_component_count' (inside
+skx_edac_common), which counts the ADXL components, was not reset. During
+the reloading of i10nm_edac, the count was incremented by the actual number
+of ADXL components again, resulting in a count that was double the real
+number of ADXL components. This led to an out-of-bounds reference to the
+ADXL component array, causing the general protection fault above.
+
+Fix this issue by resetting the 'adxl_component_count' in adxl_put(),
+which is called during the unloading of {skx,i10nm}_edac.
+
+Fixes: 123b15863550 ("EDAC, i10nm: make skx_common.o a separate module")
+Reported-by: Feng Xu <feng.f.xu@intel.com>
+Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+Signed-off-by: Tony Luck <tony.luck@intel.com>
+Tested-by: Feng Xu <feng.f.xu@intel.com>
+Link: https://lore.kernel.org/r/20250417150724.1170168-2-qiuxu.zhuo@intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/edac/skx_common.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/edac/skx_common.c b/drivers/edac/skx_common.c
+index fa5b442b18449..c9ade45c1a99f 100644
+--- a/drivers/edac/skx_common.c
++++ b/drivers/edac/skx_common.c
+@@ -116,6 +116,7 @@ EXPORT_SYMBOL_GPL(skx_adxl_get);
+ void skx_adxl_put(void)
+ {
++      adxl_component_count = 0;
+       kfree(adxl_values);
+       kfree(adxl_msg);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/edac-skx_common-i10nm-fix-the-loss-of-saved-rrl-for-.patch b/queue-6.15/edac-skx_common-i10nm-fix-the-loss-of-saved-rrl-for-.patch
new file mode 100644 (file)
index 0000000..3bb1e40
--- /dev/null
@@ -0,0 +1,164 @@
+From 8440f370c38fdb5e32b6df9cdfefb5b9b348f635 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Apr 2025 23:07:19 +0800
+Subject: EDAC/{skx_common,i10nm}: Fix the loss of saved RRL for HBM pseudo
+ channel 0
+
+From: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+
+[ Upstream commit eeed3e03f4261e5e381a72ae099ff00ccafbb437 ]
+
+When enabling the retry_rd_err_log (RRL) feature during the loading of the
+i10nm_edac driver with the module parameter retry_rd_err_log=2 (Linux RRL
+control mode), the default values of the control bits of RRL are saved so
+that they can be restored during the unloading of the driver.
+
+In the current code, the RRL of pseudo channel 1 of HBM overwrites pseudo
+channel 0 during the loading of the driver, resulting in the loss of saved
+RRL for pseudo channel 0. This causes the RRL of pseudo channel 0 of HBM to
+be wrongly restored with the values from pseudo channel 1 when unloading
+the driver.
+
+Fix this issue by creating two separate groups of RRL control registers
+per channel to save default RRL settings of two {sub-,pseudo-}channels.
+
+Fixes: acd4cf68fefe ("EDAC/i10nm: Retrieve and print retry_rd_err_log registers for HBM")
+Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+Signed-off-by: Tony Luck <tony.luck@intel.com>
+Tested-by: Feng Xu <feng.f.xu@intel.com>
+Link: https://lore.kernel.org/r/20250417150724.1170168-3-qiuxu.zhuo@intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/edac/i10nm_base.c | 35 +++++++++++++++++++----------------
+ drivers/edac/skx_common.h | 11 ++++++++---
+ 2 files changed, 27 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/edac/i10nm_base.c b/drivers/edac/i10nm_base.c
+index 355a977019e94..355b527d839e7 100644
+--- a/drivers/edac/i10nm_base.c
++++ b/drivers/edac/i10nm_base.c
+@@ -95,7 +95,7 @@ static u32 offsets_demand2_spr[] = {0x22c70, 0x22d80, 0x22f18, 0x22d58, 0x22c64,
+ static u32 offsets_demand_spr_hbm0[] = {0x2a54, 0x2a60, 0x2b10, 0x2a58, 0x2a5c, 0x0ee0};
+ static u32 offsets_demand_spr_hbm1[] = {0x2e54, 0x2e60, 0x2f10, 0x2e58, 0x2e5c, 0x0fb0};
+-static void __enable_retry_rd_err_log(struct skx_imc *imc, int chan, bool enable,
++static void __enable_retry_rd_err_log(struct skx_imc *imc, int chan, bool enable, u32 *rrl_ctl,
+                                     u32 *offsets_scrub, u32 *offsets_demand,
+                                     u32 *offsets_demand2)
+ {
+@@ -108,10 +108,10 @@ static void __enable_retry_rd_err_log(struct skx_imc *imc, int chan, bool enable
+       if (enable) {
+               /* Save default configurations */
+-              imc->chan[chan].retry_rd_err_log_s = s;
+-              imc->chan[chan].retry_rd_err_log_d = d;
++              rrl_ctl[0] = s;
++              rrl_ctl[1] = d;
+               if (offsets_demand2)
+-                      imc->chan[chan].retry_rd_err_log_d2 = d2;
++                      rrl_ctl[2] = d2;
+               s &= ~RETRY_RD_ERR_LOG_NOOVER_UC;
+               s |=  RETRY_RD_ERR_LOG_EN;
+@@ -125,25 +125,25 @@ static void __enable_retry_rd_err_log(struct skx_imc *imc, int chan, bool enable
+               }
+       } else {
+               /* Restore default configurations */
+-              if (imc->chan[chan].retry_rd_err_log_s & RETRY_RD_ERR_LOG_UC)
++              if (rrl_ctl[0] & RETRY_RD_ERR_LOG_UC)
+                       s |=  RETRY_RD_ERR_LOG_UC;
+-              if (imc->chan[chan].retry_rd_err_log_s & RETRY_RD_ERR_LOG_NOOVER)
++              if (rrl_ctl[0] & RETRY_RD_ERR_LOG_NOOVER)
+                       s |=  RETRY_RD_ERR_LOG_NOOVER;
+-              if (!(imc->chan[chan].retry_rd_err_log_s & RETRY_RD_ERR_LOG_EN))
++              if (!(rrl_ctl[0] & RETRY_RD_ERR_LOG_EN))
+                       s &= ~RETRY_RD_ERR_LOG_EN;
+-              if (imc->chan[chan].retry_rd_err_log_d & RETRY_RD_ERR_LOG_UC)
++              if (rrl_ctl[1] & RETRY_RD_ERR_LOG_UC)
+                       d |=  RETRY_RD_ERR_LOG_UC;
+-              if (imc->chan[chan].retry_rd_err_log_d & RETRY_RD_ERR_LOG_NOOVER)
++              if (rrl_ctl[1] & RETRY_RD_ERR_LOG_NOOVER)
+                       d |=  RETRY_RD_ERR_LOG_NOOVER;
+-              if (!(imc->chan[chan].retry_rd_err_log_d & RETRY_RD_ERR_LOG_EN))
++              if (!(rrl_ctl[1] & RETRY_RD_ERR_LOG_EN))
+                       d &= ~RETRY_RD_ERR_LOG_EN;
+               if (offsets_demand2) {
+-                      if (imc->chan[chan].retry_rd_err_log_d2 & RETRY_RD_ERR_LOG_UC)
++                      if (rrl_ctl[2] & RETRY_RD_ERR_LOG_UC)
+                               d2 |=  RETRY_RD_ERR_LOG_UC;
+-                      if (!(imc->chan[chan].retry_rd_err_log_d2 & RETRY_RD_ERR_LOG_NOOVER))
++                      if (!(rrl_ctl[2] & RETRY_RD_ERR_LOG_NOOVER))
+                               d2 &=  ~RETRY_RD_ERR_LOG_NOOVER;
+-                      if (!(imc->chan[chan].retry_rd_err_log_d2 & RETRY_RD_ERR_LOG_EN))
++                      if (!(rrl_ctl[2] & RETRY_RD_ERR_LOG_EN))
+                               d2 &= ~RETRY_RD_ERR_LOG_EN;
+               }
+       }
+@@ -157,6 +157,7 @@ static void __enable_retry_rd_err_log(struct skx_imc *imc, int chan, bool enable
+ static void enable_retry_rd_err_log(bool enable)
+ {
+       int i, j, imc_num, chan_num;
++      struct skx_channel *chan;
+       struct skx_imc *imc;
+       struct skx_dev *d;
+@@ -171,8 +172,9 @@ static void enable_retry_rd_err_log(bool enable)
+                       if (!imc->mbase)
+                               continue;
++                      chan = d->imc[i].chan;
+                       for (j = 0; j < chan_num; j++)
+-                              __enable_retry_rd_err_log(imc, j, enable,
++                              __enable_retry_rd_err_log(imc, j, enable, chan[j].rrl_ctl[0],
+                                                         res_cfg->offsets_scrub,
+                                                         res_cfg->offsets_demand,
+                                                         res_cfg->offsets_demand2);
+@@ -186,12 +188,13 @@ static void enable_retry_rd_err_log(bool enable)
+                       if (!imc->mbase || !imc->hbm_mc)
+                               continue;
++                      chan = d->imc[i].chan;
+                       for (j = 0; j < chan_num; j++) {
+-                              __enable_retry_rd_err_log(imc, j, enable,
++                              __enable_retry_rd_err_log(imc, j, enable, chan[j].rrl_ctl[0],
+                                                         res_cfg->offsets_scrub_hbm0,
+                                                         res_cfg->offsets_demand_hbm0,
+                                                         NULL);
+-                              __enable_retry_rd_err_log(imc, j, enable,
++                              __enable_retry_rd_err_log(imc, j, enable, chan[j].rrl_ctl[1],
+                                                         res_cfg->offsets_scrub_hbm1,
+                                                         res_cfg->offsets_demand_hbm1,
+                                                         NULL);
+diff --git a/drivers/edac/skx_common.h b/drivers/edac/skx_common.h
+index ca5408803f878..5afd425f3b4ff 100644
+--- a/drivers/edac/skx_common.h
++++ b/drivers/edac/skx_common.h
+@@ -79,6 +79,9 @@
+  */
+ #define MCACOD_EXT_MEM_ERR    0x280
++/* Max RRL register sets per {,sub-,pseudo-}channel. */
++#define NUM_RRL_SET           3
++
+ /*
+  * Each cpu socket contains some pci devices that provide global
+  * information, and also some that are local to each of the two
+@@ -117,9 +120,11 @@ struct skx_dev {
+               struct skx_channel {
+                       struct pci_dev  *cdev;
+                       struct pci_dev  *edev;
+-                      u32 retry_rd_err_log_s;
+-                      u32 retry_rd_err_log_d;
+-                      u32 retry_rd_err_log_d2;
++                      /*
++                       * Two groups of RRL control registers per channel to save default RRL
++                       * settings of two {sub-,pseudo-}channels in Linux RRL control mode.
++                       */
++                      u32 rrl_ctl[2][NUM_RRL_SET];
+                       struct skx_dimm {
+                               u8 close_pg;
+                               u8 bank_xor_enable;
+-- 
+2.39.5
+
diff --git a/queue-6.15/efi-libstub-describe-missing-out-parameter-in-efi_lo.patch b/queue-6.15/efi-libstub-describe-missing-out-parameter-in-efi_lo.patch
new file mode 100644 (file)
index 0000000..f01f23f
--- /dev/null
@@ -0,0 +1,40 @@
+From 7d34f9f31e6fef739e10043c0e32a8c6a9811b78 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 May 2025 00:31:11 +0800
+Subject: efi/libstub: Describe missing 'out' parameter in efi_load_initrd
+
+From: Hans Zhang <18255117159@163.com>
+
+[ Upstream commit c8e1927e7f7d63721e32ec41d27ccb0eb1a1b0fc ]
+
+The function efi_load_initrd() had a documentation warning due to
+the missing description for the 'out' parameter. Add the parameter
+description to the kernel-doc comment to resolve the warning and
+improve API documentation.
+
+Fixes the following compiler warning:
+drivers/firmware/efi/libstub/efi-stub-helper.c:611: warning: Function parameter or struct member 'out' not described in 'efi_load_initrd'
+
+Fixes: f4dc7fffa987 ("efi: libstub: unify initrd loading between architectures")
+Signed-off-by: Hans Zhang <18255117159@163.com>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/efi/libstub/efi-stub-helper.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c
+index fd6dc790c5a89..7aa2f9ad29356 100644
+--- a/drivers/firmware/efi/libstub/efi-stub-helper.c
++++ b/drivers/firmware/efi/libstub/efi-stub-helper.c
+@@ -601,6 +601,7 @@ efi_status_t efi_load_initrd_cmdline(efi_loaded_image_t *image,
+  * @image:    EFI loaded image protocol
+  * @soft_limit:       preferred address for loading the initrd
+  * @hard_limit:       upper limit address for loading the initrd
++ * @out:      pointer to store the address of the initrd table
+  *
+  * Return:    status code
+  */
+-- 
+2.39.5
+
diff --git a/queue-6.15/erofs-avoid-using-multiple-devices-with-different-ty.patch b/queue-6.15/erofs-avoid-using-multiple-devices-with-different-ty.patch
new file mode 100644 (file)
index 0000000..2bc2d4a
--- /dev/null
@@ -0,0 +1,64 @@
+From 7948e4cf699393b6203240989a73475ca4a363ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 May 2025 09:48:37 +0800
+Subject: erofs: avoid using multiple devices with different type
+
+From: Sheng Yong <shengyong1@xiaomi.com>
+
+[ Upstream commit 9748f2f54f66743ac77275c34886a9f890e18409 ]
+
+For multiple devices, both primary and extra devices should be the
+same type. `erofs_init_device` has already guaranteed that if the
+primary is a file-backed device, extra devices should also be
+regular files.
+
+However, if the primary is a block device while the extra device
+is a file-backed device, `erofs_init_device` will get an ENOTBLK,
+which is not treated as an error in `erofs_fc_get_tree`, and that
+leads to an UAF:
+
+  erofs_fc_get_tree
+    get_tree_bdev_flags(erofs_fc_fill_super)
+      erofs_read_superblock
+        erofs_init_device  // sbi->dif0 is not inited yet,
+                           // return -ENOTBLK
+      deactivate_locked_super
+        free(sbi)
+    if (err is -ENOTBLK)
+      sbi->dif0.file = filp_open()  // sbi UAF
+
+So if -ENOTBLK is hitted in `erofs_init_device`, it means the
+primary device must be a block device, and the extra device
+is not a block device. The error can be converted to -EINVAL.
+
+Fixes: fb176750266a ("erofs: add file-backed mount support")
+Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
+Reviewed-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+Reviewed-by: Hongbo Li <lihongbo22@huawei.com>
+Link: https://lore.kernel.org/r/20250515014837.3315886-1-shengyong1@xiaomi.com
+Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/erofs/super.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/fs/erofs/super.c b/fs/erofs/super.c
+index bcb99c3c2594b..6e57b9cc6ed2e 100644
+--- a/fs/erofs/super.c
++++ b/fs/erofs/super.c
+@@ -165,8 +165,11 @@ static int erofs_init_device(struct erofs_buf *buf, struct super_block *sb,
+                               filp_open(dif->path, O_RDONLY | O_LARGEFILE, 0) :
+                               bdev_file_open_by_path(dif->path,
+                                               BLK_OPEN_READ, sb->s_type, NULL);
+-              if (IS_ERR(file))
++              if (IS_ERR(file)) {
++                      if (file == ERR_PTR(-ENOTBLK))
++                              return -EINVAL;
+                       return PTR_ERR(file);
++              }
+               if (!erofs_is_fileio_mode(sbi)) {
+                       dif->dax_dev = fs_dax_get_by_bdev(file_bdev(file),
+-- 
+2.39.5
+
diff --git a/queue-6.15/erofs-fix-file-handle-encoding-for-64-bit-nids.patch b/queue-6.15/erofs-fix-file-handle-encoding-for-64-bit-nids.patch
new file mode 100644 (file)
index 0000000..bcfbdd8
--- /dev/null
@@ -0,0 +1,115 @@
+From 763d97dc2be9e449891e671dbce1fbc5331236cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 May 2025 09:40:15 +0000
+Subject: erofs: fix file handle encoding for 64-bit NIDs
+
+From: Hongbo Li <lihongbo22@huawei.com>
+
+[ Upstream commit 510de8363f2c3d8e67fa9dfb2366e821382036e0 ]
+
+EROFS uses NID to indicate the on-disk inode offset, which can
+exceed 32 bits. However, the default encode_fh uses the ino32,
+thus it doesn't work if the image is larger than 128GiB.
+
+Let's introduce our own helpers to encode file handles.
+
+It's easy to reproduce:
+  1. prepare an erofs image with nid bigger than U32_MAX
+  2. mount -t erofs foo.img /mnt/erofs
+  3. set exportfs with configuration: /mnt/erofs *(rw,sync,
+     no_root_squash)
+  4. mount -t nfs $IP:/mnt/erofs /mnt/nfs
+  5. md5sum /mnt/nfs/foo # foo is the file which nid bigger
+     than U32_MAX.  # you will get ESTALE error.
+
+In the case of overlayfs, the underlying filesystem's file
+handle is encoded in ovl_fb.fid, which is similar to NFS's
+case. If the NID of file is larger than U32_MAX, the overlay
+will get -ESTALE error when calls exportfs_decode_fh.
+
+Fixes: 3e917cc305c6 ("erofs: make filesystem exportable")
+Signed-off-by: Hongbo Li <lihongbo22@huawei.com>
+Reviewed-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+Link: https://lore.kernel.org/r/20250507094015.14007-1-lihongbo22@huawei.com
+Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/erofs/super.c | 44 ++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 36 insertions(+), 8 deletions(-)
+
+diff --git a/fs/erofs/super.c b/fs/erofs/super.c
+index da6ee7c39290d..bcb99c3c2594b 100644
+--- a/fs/erofs/super.c
++++ b/fs/erofs/super.c
+@@ -510,24 +510,52 @@ static int erofs_fc_parse_param(struct fs_context *fc,
+       return 0;
+ }
+-static struct inode *erofs_nfs_get_inode(struct super_block *sb,
+-                                       u64 ino, u32 generation)
++static int erofs_encode_fh(struct inode *inode, u32 *fh, int *max_len,
++                         struct inode *parent)
+ {
+-      return erofs_iget(sb, ino);
++      erofs_nid_t nid = EROFS_I(inode)->nid;
++      int len = parent ? 6 : 3;
++
++      if (*max_len < len) {
++              *max_len = len;
++              return FILEID_INVALID;
++      }
++
++      fh[0] = (u32)(nid >> 32);
++      fh[1] = (u32)(nid & 0xffffffff);
++      fh[2] = inode->i_generation;
++
++      if (parent) {
++              nid = EROFS_I(parent)->nid;
++
++              fh[3] = (u32)(nid >> 32);
++              fh[4] = (u32)(nid & 0xffffffff);
++              fh[5] = parent->i_generation;
++      }
++
++      *max_len = len;
++      return parent ? FILEID_INO64_GEN_PARENT : FILEID_INO64_GEN;
+ }
+ static struct dentry *erofs_fh_to_dentry(struct super_block *sb,
+               struct fid *fid, int fh_len, int fh_type)
+ {
+-      return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
+-                                  erofs_nfs_get_inode);
++      if ((fh_type != FILEID_INO64_GEN &&
++           fh_type != FILEID_INO64_GEN_PARENT) || fh_len < 3)
++              return NULL;
++
++      return d_obtain_alias(erofs_iget(sb,
++              ((u64)fid->raw[0] << 32) | fid->raw[1]));
+ }
+ static struct dentry *erofs_fh_to_parent(struct super_block *sb,
+               struct fid *fid, int fh_len, int fh_type)
+ {
+-      return generic_fh_to_parent(sb, fid, fh_len, fh_type,
+-                                  erofs_nfs_get_inode);
++      if (fh_type != FILEID_INO64_GEN_PARENT || fh_len < 6)
++              return NULL;
++
++      return d_obtain_alias(erofs_iget(sb,
++              ((u64)fid->raw[3] << 32) | fid->raw[4]));
+ }
+ static struct dentry *erofs_get_parent(struct dentry *child)
+@@ -543,7 +571,7 @@ static struct dentry *erofs_get_parent(struct dentry *child)
+ }
+ static const struct export_operations erofs_export_ops = {
+-      .encode_fh = generic_encode_ino32_fh,
++      .encode_fh = erofs_encode_fh,
+       .fh_to_dentry = erofs_fh_to_dentry,
+       .fh_to_parent = erofs_fh_to_parent,
+       .get_parent = erofs_get_parent,
+-- 
+2.39.5
+
diff --git a/queue-6.15/exportfs-require-fh_to_parent-to-encode-connectable-.patch b/queue-6.15/exportfs-require-fh_to_parent-to-encode-connectable-.patch
new file mode 100644 (file)
index 0000000..477c4e0
--- /dev/null
@@ -0,0 +1,54 @@
+From d15739a6b0c4633db908403c8fc8aaa863bab741 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 25 May 2025 12:47:31 +0200
+Subject: exportfs: require ->fh_to_parent() to encode connectable file handles
+
+From: Amir Goldstein <amir73il@gmail.com>
+
+[ Upstream commit 5402c4d4d2000a9baa30c1157c97152ec6383733 ]
+
+When user requests a connectable file handle explicitly with the
+AT_HANDLE_CONNECTABLE flag, fail the request if filesystem (e.g. nfs)
+does not know how to decode a connected non-dir dentry.
+
+Fixes: c374196b2b9f ("fs: name_to_handle_at() support for "explicit connectable" file handles")
+Signed-off-by: Amir Goldstein <amir73il@gmail.com>
+Link: https://lore.kernel.org/20250525104731.1461704-1-amir73il@gmail.com
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/exportfs.h | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h
+index fc93f0abf513c..25c4a5afbd443 100644
+--- a/include/linux/exportfs.h
++++ b/include/linux/exportfs.h
+@@ -314,6 +314,9 @@ static inline bool exportfs_can_decode_fh(const struct export_operations *nop)
+ static inline bool exportfs_can_encode_fh(const struct export_operations *nop,
+                                         int fh_flags)
+ {
++      if (!nop)
++              return false;
++
+       /*
+        * If a non-decodeable file handle was requested, we only need to make
+        * sure that filesystem did not opt-out of encoding fid.
+@@ -321,6 +324,13 @@ static inline bool exportfs_can_encode_fh(const struct export_operations *nop,
+       if (fh_flags & EXPORT_FH_FID)
+               return exportfs_can_encode_fid(nop);
++      /*
++       * If a connectable file handle was requested, we need to make sure that
++       * filesystem can also decode connected file handles.
++       */
++      if ((fh_flags & EXPORT_FH_CONNECTABLE) && !nop->fh_to_parent)
++              return false;
++
+       /*
+        * If a decodeable file handle was requested, we need to make sure that
+        * filesystem can also decode file handles.
+-- 
+2.39.5
+
diff --git a/queue-6.15/f2fs-clean-up-unnecessary-indentation.patch b/queue-6.15/f2fs-clean-up-unnecessary-indentation.patch
new file mode 100644 (file)
index 0000000..0a20a52
--- /dev/null
@@ -0,0 +1,89 @@
+From 9895a2982b5807c3fe3ccc7df64946fa509f5fb3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Apr 2025 19:03:03 +0000
+Subject: f2fs: clean up unnecessary indentation
+
+From: Jaegeuk Kim <jaegeuk@kernel.org>
+
+[ Upstream commit 05d3273ad03fa5ea1177b4f3dfeeb6de4899b504 ]
+
+No functional change.
+
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Stable-dep-of: d26fecb03e1f ("f2fs: prevent the current section from being selected as a victim during GC")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/segment.h | 40 ++++++++++++++++++++++++----------------
+ 1 file changed, 24 insertions(+), 16 deletions(-)
+
+diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
+index 0465dc00b349d..5fcb1f92d506f 100644
+--- a/fs/f2fs/segment.h
++++ b/fs/f2fs/segment.h
+@@ -429,7 +429,6 @@ static inline void __set_free(struct f2fs_sb_info *sbi, unsigned int segno)
+       unsigned int secno = GET_SEC_FROM_SEG(sbi, segno);
+       unsigned int start_segno = GET_SEG_FROM_SEC(sbi, secno);
+       unsigned int next;
+-      unsigned int usable_segs = f2fs_usable_segs_in_sec(sbi);
+       spin_lock(&free_i->segmap_lock);
+       clear_bit(segno, free_i->free_segmap);
+@@ -437,7 +436,7 @@ static inline void __set_free(struct f2fs_sb_info *sbi, unsigned int segno)
+       next = find_next_bit(free_i->free_segmap,
+                       start_segno + SEGS_PER_SEC(sbi), start_segno);
+-      if (next >= start_segno + usable_segs) {
++      if (next >= start_segno + f2fs_usable_segs_in_sec(sbi)) {
+               clear_bit(secno, free_i->free_secmap);
+               free_i->free_sections++;
+       }
+@@ -463,22 +462,31 @@ static inline void __set_test_and_free(struct f2fs_sb_info *sbi,
+       unsigned int secno = GET_SEC_FROM_SEG(sbi, segno);
+       unsigned int start_segno = GET_SEG_FROM_SEC(sbi, secno);
+       unsigned int next;
+-      unsigned int usable_segs = f2fs_usable_segs_in_sec(sbi);
++      bool ret;
+       spin_lock(&free_i->segmap_lock);
+-      if (test_and_clear_bit(segno, free_i->free_segmap)) {
+-              free_i->free_segments++;
+-
+-              if (!inmem && IS_CURSEC(sbi, secno))
+-                      goto skip_free;
+-              next = find_next_bit(free_i->free_segmap,
+-                              start_segno + SEGS_PER_SEC(sbi), start_segno);
+-              if (next >= start_segno + usable_segs) {
+-                      if (test_and_clear_bit(secno, free_i->free_secmap))
+-                              free_i->free_sections++;
+-              }
+-      }
+-skip_free:
++      ret = test_and_clear_bit(segno, free_i->free_segmap);
++      if (!ret)
++              goto unlock_out;
++
++      free_i->free_segments++;
++
++      if (!inmem && IS_CURSEC(sbi, secno))
++              goto unlock_out;
++
++      /* check large section */
++      next = find_next_bit(free_i->free_segmap,
++                           start_segno + SEGS_PER_SEC(sbi), start_segno);
++      if (next < start_segno + f2fs_usable_segs_in_sec(sbi))
++              goto unlock_out;
++
++      ret = test_and_clear_bit(secno, free_i->free_secmap);
++      if (!ret)
++              goto unlock_out;
++
++      free_i->free_sections++;
++
++unlock_out:
+       spin_unlock(&free_i->segmap_lock);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/f2fs-clean-up-w-fscrypt_is_bounce_page.patch b/queue-6.15/f2fs-clean-up-w-fscrypt_is_bounce_page.patch
new file mode 100644 (file)
index 0000000..c62b898
--- /dev/null
@@ -0,0 +1,35 @@
+From d9016c7d8a04ca1106ad992d7cbb9cc14c037060 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Apr 2025 18:52:36 +0800
+Subject: f2fs: clean up w/ fscrypt_is_bounce_page()
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 0c708e35cf26449ca317fcbfc274704660b6d269 ]
+
+Just cleanup, no logic changes.
+
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Stable-dep-of: aa1be8dd6416 ("f2fs: fix to detect gcing page in f2fs_is_cp_guaranteed()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/data.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index 54f89f0ee69b1..5a7888a5923ca 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -53,7 +53,7 @@ bool f2fs_is_cp_guaranteed(struct page *page)
+       struct inode *inode;
+       struct f2fs_sb_info *sbi;
+-      if (!mapping)
++      if (fscrypt_is_bounce_page(page))
+               return false;
+       inode = mapping->host;
+-- 
+2.39.5
+
diff --git a/queue-6.15/f2fs-fix-to-correct-check-conditions-in-f2fs_cross_r.patch b/queue-6.15/f2fs-fix-to-correct-check-conditions-in-f2fs_cross_r.patch
new file mode 100644 (file)
index 0000000..4c9b2ad
--- /dev/null
@@ -0,0 +1,36 @@
+From b6d751942831e91dc6148fc8c3076a8fb04953fd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 May 2025 16:45:49 +0800
+Subject: f2fs: fix to correct check conditions in f2fs_cross_rename
+
+From: Zhiguo Niu <zhiguo.niu@unisoc.com>
+
+[ Upstream commit 9883494c45a13dc88d27dde4f988c04823b42a2f ]
+
+Should be "old_dir" here.
+
+Fixes: 5c57132eaf52 ("f2fs: support project quota")
+Signed-off-by: Zhiguo Niu <zhiguo.niu@unisoc.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/namei.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
+index faa5191cf4ca6..28137d499f8f6 100644
+--- a/fs/f2fs/namei.c
++++ b/fs/f2fs/namei.c
+@@ -1108,7 +1108,7 @@ static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry,
+       if ((is_inode_flag_set(new_dir, FI_PROJ_INHERIT) &&
+                       !projid_eq(F2FS_I(new_dir)->i_projid,
+                       F2FS_I(old_inode)->i_projid)) ||
+-          (is_inode_flag_set(new_dir, FI_PROJ_INHERIT) &&
++          (is_inode_flag_set(old_dir, FI_PROJ_INHERIT) &&
+                       !projid_eq(F2FS_I(old_dir)->i_projid,
+                       F2FS_I(new_inode)->i_projid)))
+               return -EXDEV;
+-- 
+2.39.5
+
diff --git a/queue-6.15/f2fs-fix-to-detect-gcing-page-in-f2fs_is_cp_guarante.patch b/queue-6.15/f2fs-fix-to-detect-gcing-page-in-f2fs_is_cp_guarante.patch
new file mode 100644 (file)
index 0000000..d22ef0c
--- /dev/null
@@ -0,0 +1,91 @@
+From 1cc425da4183369a6afb8108b685f87238d9d335 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Apr 2025 18:52:37 +0800
+Subject: f2fs: fix to detect gcing page in f2fs_is_cp_guaranteed()
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit aa1be8dd64163eca4dde7fd2557eb19927a06a47 ]
+
+Jan Prusakowski reported a f2fs bug as below:
+
+f2fs/007 will hang kernel during testing w/ below configs:
+
+kernel 6.12.18 (from pixel-kernel/android16-6.12)
+export MKFS_OPTIONS="-O encrypt -O extra_attr -O project_quota -O quota"
+export F2FS_MOUNT_OPTIONS="test_dummy_encryption,discard,fsync_mode=nobarrier,reserve_root=32768,checkpoint_merge,atgc"
+
+cat /proc/<umount_proc_id>/stack
+f2fs_wait_on_all_pages+0xa3/0x130
+do_checkpoint+0x40c/0x5d0
+f2fs_write_checkpoint+0x258/0x550
+kill_f2fs_super+0x14f/0x190
+deactivate_locked_super+0x30/0xb0
+cleanup_mnt+0xba/0x150
+task_work_run+0x59/0xa0
+syscall_exit_to_user_mode+0x12d/0x130
+do_syscall_64+0x57/0x110
+entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+cat /sys/kernel/debug/f2fs/status
+
+  - IO_W (CP: -256, Data:  256, Flush: (   0    0    1), Discard: (   0    0)) cmd:    0 undiscard:   0
+
+CP IOs reference count becomes negative.
+
+The root cause is:
+
+After 4961acdd65c9 ("f2fs: fix to tag gcing flag on page during block
+migration"), we will tag page w/ gcing flag for raw page of cluster
+during its migration.
+
+However, if the inode is both encrypted and compressed, during
+ioc_decompress(), it will tag page w/ gcing flag, and it increase
+F2FS_WB_DATA reference count:
+- f2fs_write_multi_page
+ - f2fs_write_raw_page
+  - f2fs_write_single_page
+   - do_write_page
+    - f2fs_submit_page_write
+     - WB_DATA_TYPE(bio_page, fio->compressed_page)
+     : bio_page is encrypted, so mapping is NULL, and fio->compressed_page
+       is NULL, it returns F2FS_WB_DATA
+     - inc_page_count(.., F2FS_WB_DATA)
+
+Then, during end_io(), it decrease F2FS_WB_CP_DATA reference count:
+- f2fs_write_end_io
+ - f2fs_compress_write_end_io
+  - fscrypt_pagecache_folio
+  : get raw page from encrypted page
+  - WB_DATA_TYPE(&folio->page, false)
+  : raw page has gcing flag, it returns F2FS_WB_CP_DATA
+  - dec_page_count(.., F2FS_WB_CP_DATA)
+
+In order to fix this issue, we need to detect gcing flag in raw page
+in f2fs_is_cp_guaranteed().
+
+Fixes: 4961acdd65c9 ("f2fs: fix to tag gcing flag on page during block migration")
+Reported-by: Jan Prusakowski <jprusakowski@google.com>
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/data.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index 5a7888a5923ca..81b25dd15a0b9 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -54,7 +54,7 @@ bool f2fs_is_cp_guaranteed(struct page *page)
+       struct f2fs_sb_info *sbi;
+       if (fscrypt_is_bounce_page(page))
+-              return false;
++              return page_private_gcing(fscrypt_pagecache_page(page));
+       inode = mapping->host;
+       sbi = F2FS_I_SB(inode);
+-- 
+2.39.5
+
diff --git a/queue-6.15/f2fs-fix-to-do-sanity-check-on-sbi-total_valid_block.patch b/queue-6.15/f2fs-fix-to-do-sanity-check-on-sbi-total_valid_block.patch
new file mode 100644 (file)
index 0000000..9939aff
--- /dev/null
@@ -0,0 +1,76 @@
+From 9db1eb30666524b1dfe4317dca9924bd6b0c6dfc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Apr 2025 20:22:08 +0800
+Subject: f2fs: fix to do sanity check on sbi->total_valid_block_count
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 05872a167c2cab80ef186ef23cc34a6776a1a30c ]
+
+syzbot reported a f2fs bug as below:
+
+------------[ cut here ]------------
+kernel BUG at fs/f2fs/f2fs.h:2521!
+RIP: 0010:dec_valid_block_count+0x3b2/0x3c0 fs/f2fs/f2fs.h:2521
+Call Trace:
+ f2fs_truncate_data_blocks_range+0xc8c/0x11a0 fs/f2fs/file.c:695
+ truncate_dnode+0x417/0x740 fs/f2fs/node.c:973
+ truncate_nodes+0x3ec/0xf50 fs/f2fs/node.c:1014
+ f2fs_truncate_inode_blocks+0x8e3/0x1370 fs/f2fs/node.c:1197
+ f2fs_do_truncate_blocks+0x840/0x12b0 fs/f2fs/file.c:810
+ f2fs_truncate_blocks+0x10d/0x300 fs/f2fs/file.c:838
+ f2fs_truncate+0x417/0x720 fs/f2fs/file.c:888
+ f2fs_setattr+0xc4f/0x12f0 fs/f2fs/file.c:1112
+ notify_change+0xbca/0xe90 fs/attr.c:552
+ do_truncate+0x222/0x310 fs/open.c:65
+ handle_truncate fs/namei.c:3466 [inline]
+ do_open fs/namei.c:3849 [inline]
+ path_openat+0x2e4f/0x35d0 fs/namei.c:4004
+ do_filp_open+0x284/0x4e0 fs/namei.c:4031
+ do_sys_openat2+0x12b/0x1d0 fs/open.c:1429
+ do_sys_open fs/open.c:1444 [inline]
+ __do_sys_creat fs/open.c:1522 [inline]
+ __se_sys_creat fs/open.c:1516 [inline]
+ __x64_sys_creat+0x124/0x170 fs/open.c:1516
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xf3/0x230 arch/x86/entry/syscall_64.c:94
+
+The reason is: in fuzzed image, sbi->total_valid_block_count is
+inconsistent w/ mapped blocks indexed by inode, so, we should
+not trigger panic for such case, instead, let's print log and
+set fsck flag.
+
+Fixes: 39a53e0ce0df ("f2fs: add superblock and major in-memory structure")
+Reported-by: syzbot+8b376a77b2f364097fbe@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/linux-f2fs-devel/67f3c0b2.050a0220.396535.0547.GAE@google.com
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/f2fs.h | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index f1576dc6ec679..6dcac5ab041c8 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -2518,8 +2518,14 @@ static inline void dec_valid_block_count(struct f2fs_sb_info *sbi,
+       blkcnt_t sectors = count << F2FS_LOG_SECTORS_PER_BLOCK;
+       spin_lock(&sbi->stat_lock);
+-      f2fs_bug_on(sbi, sbi->total_valid_block_count < (block_t) count);
+-      sbi->total_valid_block_count -= (block_t)count;
++      if (unlikely(sbi->total_valid_block_count < count)) {
++              f2fs_warn(sbi, "Inconsistent total_valid_block_count:%u, ino:%lu, count:%u",
++                        sbi->total_valid_block_count, inode->i_ino, count);
++              sbi->total_valid_block_count = 0;
++              set_sbi_flag(sbi, SBI_NEED_FSCK);
++      } else {
++              sbi->total_valid_block_count -= count;
++      }
+       if (sbi->reserved_blocks &&
+               sbi->current_reserved_blocks < sbi->reserved_blocks)
+               sbi->current_reserved_blocks = min(sbi->reserved_blocks,
+-- 
+2.39.5
+
diff --git a/queue-6.15/f2fs-fix-to-skip-f2fs_balance_fs-if-checkpoint-is-di.patch b/queue-6.15/f2fs-fix-to-skip-f2fs_balance_fs-if-checkpoint-is-di.patch
new file mode 100644 (file)
index 0000000..452bf65
--- /dev/null
@@ -0,0 +1,112 @@
+From 5a6f6664c6aa6dd576c75170bfdd9b2e7452a215 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 May 2025 11:25:45 +0800
+Subject: f2fs: fix to skip f2fs_balance_fs() if checkpoint is disabled
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit c836d3b8d94e3dd381e7d4bb918875084f85715e ]
+
+Syzbot reports a f2fs bug as below:
+
+INFO: task syz-executor328:5856 blocked for more than 144 seconds.
+      Not tainted 6.15.0-rc6-syzkaller-00208-g3c21441eeffc #0
+"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+task:syz-executor328 state:D stack:24392 pid:5856  tgid:5832  ppid:5826   task_flags:0x400040 flags:0x00004006
+Call Trace:
+ <TASK>
+ context_switch kernel/sched/core.c:5382 [inline]
+ __schedule+0x168f/0x4c70 kernel/sched/core.c:6767
+ __schedule_loop kernel/sched/core.c:6845 [inline]
+ schedule+0x165/0x360 kernel/sched/core.c:6860
+ io_schedule+0x81/0xe0 kernel/sched/core.c:7742
+ f2fs_balance_fs+0x4b4/0x780 fs/f2fs/segment.c:444
+ f2fs_map_blocks+0x3af1/0x43b0 fs/f2fs/data.c:1791
+ f2fs_expand_inode_data+0x653/0xaf0 fs/f2fs/file.c:1872
+ f2fs_fallocate+0x4f5/0x990 fs/f2fs/file.c:1975
+ vfs_fallocate+0x6a0/0x830 fs/open.c:338
+ ioctl_preallocate fs/ioctl.c:290 [inline]
+ file_ioctl fs/ioctl.c:-1 [inline]
+ do_vfs_ioctl+0x1b8f/0x1eb0 fs/ioctl.c:885
+ __do_sys_ioctl fs/ioctl.c:904 [inline]
+ __se_sys_ioctl+0x82/0x170 fs/ioctl.c:892
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xf6/0x210 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+The root cause is after commit 84b5bb8bf0f6 ("f2fs: modify
+f2fs_is_checkpoint_ready logic to allow more data to be written with the
+CP disable"), we will get chance to allow f2fs_is_checkpoint_ready() to
+return true once below conditions are all true:
+1. checkpoint is disabled
+2. there are not enough free segments
+3. there are enough free blocks
+
+Then it will cause f2fs_balance_fs() to trigger foreground GC.
+
+void f2fs_balance_fs(struct f2fs_sb_info *sbi, bool need)
+...
+       if (!f2fs_is_checkpoint_ready(sbi))
+               return;
+
+And the testcase mounts f2fs image w/ gc_merge,checkpoint=disable, so deadloop
+will happen through below race condition:
+
+- f2fs_do_shutdown             - vfs_fallocate                         - gc_thread_func
+                                - file_start_write
+                                 - __sb_start_write(SB_FREEZE_WRITE)
+                                - f2fs_fallocate
+                                 - f2fs_expand_inode_data
+                                  - f2fs_map_blocks
+                                   - f2fs_balance_fs
+                                    - prepare_to_wait
+                                    - wake_up(gc_wait_queue_head)
+                                    - io_schedule
+ - bdev_freeze
+  - freeze_super
+   - sb->s_writers.frozen = SB_FREEZE_WRITE;
+   - sb_wait_write(sb, SB_FREEZE_WRITE);
+                                                                        - if (sbi->sb->s_writers.frozen >= SB_FREEZE_WRITE) continue;
+                                                                        : cause deadloop
+
+This patch fix to add check condition in f2fs_balance_fs(), so that if
+checkpoint is disabled, we will just skip trigger foreground GC to
+avoid such deadloop issue.
+
+Meanwhile let's remove f2fs_is_checkpoint_ready() check condition in
+f2fs_balance_fs(), since it's redundant, due to the main logic in the
+function is to check:
+a) whether checkpoint is disabled
+b) there is enough free segments
+
+f2fs_balance_fs() still has all logics after f2fs_is_checkpoint_ready()'s
+removal.
+
+Reported-by: syzbot+aa5bb5f6860e08a60450@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/linux-f2fs-devel/682d743a.a00a0220.29bc26.0289.GAE@google.com
+Fixes: 84b5bb8bf0f6 ("f2fs: modify f2fs_is_checkpoint_ready logic to allow more data to be written with the CP disable")
+Cc: Qi Han <hanqi@vivo.com>
+Signed-off-by: Chao Yu <chao@kernel.org>
+Reviewed-by: Zhiguo Niu <zhiguo.niu@unisoc.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/segment.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index 2a71e70c9ac97..41ca73622c8d4 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -424,7 +424,7 @@ void f2fs_balance_fs(struct f2fs_sb_info *sbi, bool need)
+       if (need && excess_cached_nats(sbi))
+               f2fs_balance_fs_bg(sbi, false);
+-      if (!f2fs_is_checkpoint_ready(sbi))
++      if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED)))
+               return;
+       /*
+-- 
+2.39.5
+
diff --git a/queue-6.15/f2fs-prevent-the-current-section-from-being-selected.patch b/queue-6.15/f2fs-prevent-the-current-section-from-being-selected.patch
new file mode 100644 (file)
index 0000000..83effeb
--- /dev/null
@@ -0,0 +1,67 @@
+From bf74c8f452220be80c1698302f89ff33ecb37043 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Apr 2025 08:21:06 +0900
+Subject: f2fs: prevent the current section from being selected as a victim
+ during GC
+
+From: yohan.joung <yohan.joung@sk.com>
+
+[ Upstream commit d26fecb03e1f1069480d41fa2a6cea87ebbb89b8 ]
+
+When selecting a victim using next_victim_seg in a large section, the
+selected section might already have been cleared and designated as the
+new current section, making it actively in use.
+This behavior causes inconsistency between the SIT and SSA.
+
+F2FS-fs (dm-54): Inconsistent segment (70961) type [0, 1] in SSA and SIT
+Call trace:
+dump_backtrace+0xe8/0x10c
+show_stack+0x18/0x28
+dump_stack_lvl+0x50/0x6c
+dump_stack+0x18/0x28
+f2fs_stop_checkpoint+0x1c/0x3c
+do_garbage_collect+0x41c/0x271c
+f2fs_gc+0x27c/0x828
+gc_thread_func+0x290/0x88c
+kthread+0x11c/0x164
+ret_from_fork+0x10/0x20
+
+issue scenario
+segs_per_sec=2
+- seg#0 and seg#1 are all dirty
+- all valid blocks are removed in seg#1
+- gc select this sec and next_victim_seg=seg#0
+- migrate seg#0, next_victim_seg=seg#1
+- checkpoint -> sec(seg#0, seg#1)  becomes free
+- allocator assigns sec(seg#0, seg#1) to curseg
+- gc tries to migrate seg#1
+
+Fixes: e3080b0120a1 ("f2fs: support subsectional garbage collection")
+Signed-off-by: yohan.joung <yohan.joung@sk.com>
+Signed-off-by: Chao Yu <chao@kernel.org>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/segment.h | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
+index 5fcb1f92d506f..503f6df690bf2 100644
+--- a/fs/f2fs/segment.h
++++ b/fs/f2fs/segment.h
+@@ -486,6 +486,11 @@ static inline void __set_test_and_free(struct f2fs_sb_info *sbi,
+       free_i->free_sections++;
++      if (GET_SEC_FROM_SEG(sbi, sbi->next_victim_seg[BG_GC]) == secno)
++              sbi->next_victim_seg[BG_GC] = NULL_SEGNO;
++      if (GET_SEC_FROM_SEG(sbi, sbi->next_victim_seg[FG_GC]) == secno)
++              sbi->next_victim_seg[FG_GC] = NULL_SEGNO;
++
+ unlock_out:
+       spin_unlock(&free_i->segmap_lock);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/f2fs-use-d_inode-dentry-cleanup-dentry-d_inode.patch b/queue-6.15/f2fs-use-d_inode-dentry-cleanup-dentry-d_inode.patch
new file mode 100644 (file)
index 0000000..863c49a
--- /dev/null
@@ -0,0 +1,75 @@
+From caf0e1735a646023c90ac56f0f57b2197aa8fd9b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 May 2025 16:45:48 +0800
+Subject: f2fs: use d_inode(dentry) cleanup dentry->d_inode
+
+From: Zhiguo Niu <zhiguo.niu@unisoc.com>
+
+[ Upstream commit a6c397a31f58a1d577c2c8d04b624e9baa31951c ]
+
+no logic changes.
+
+Signed-off-by: Zhiguo Niu <zhiguo.niu@unisoc.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Stable-dep-of: 9883494c45a1 ("f2fs: fix to correct check conditions in f2fs_cross_rename")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/namei.c | 8 ++++----
+ fs/f2fs/super.c | 4 ++--
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
+index 8f8b9b843bdf4..faa5191cf4ca6 100644
+--- a/fs/f2fs/namei.c
++++ b/fs/f2fs/namei.c
+@@ -414,7 +414,7 @@ static int f2fs_link(struct dentry *old_dentry, struct inode *dir,
+       if (is_inode_flag_set(dir, FI_PROJ_INHERIT) &&
+                       (!projid_eq(F2FS_I(dir)->i_projid,
+-                      F2FS_I(old_dentry->d_inode)->i_projid)))
++                      F2FS_I(inode)->i_projid)))
+               return -EXDEV;
+       err = f2fs_dquot_initialize(dir);
+@@ -914,7 +914,7 @@ static int f2fs_rename(struct mnt_idmap *idmap, struct inode *old_dir,
+       if (is_inode_flag_set(new_dir, FI_PROJ_INHERIT) &&
+                       (!projid_eq(F2FS_I(new_dir)->i_projid,
+-                      F2FS_I(old_dentry->d_inode)->i_projid)))
++                      F2FS_I(old_inode)->i_projid)))
+               return -EXDEV;
+       /*
+@@ -1107,10 +1107,10 @@ static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry,
+       if ((is_inode_flag_set(new_dir, FI_PROJ_INHERIT) &&
+                       !projid_eq(F2FS_I(new_dir)->i_projid,
+-                      F2FS_I(old_dentry->d_inode)->i_projid)) ||
++                      F2FS_I(old_inode)->i_projid)) ||
+           (is_inode_flag_set(new_dir, FI_PROJ_INHERIT) &&
+                       !projid_eq(F2FS_I(old_dir)->i_projid,
+-                      F2FS_I(new_dentry->d_inode)->i_projid)))
++                      F2FS_I(new_inode)->i_projid)))
+               return -EXDEV;
+       err = f2fs_dquot_initialize(old_dir);
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index 7a3bc85df6a7a..386326f7a440e 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -1882,9 +1882,9 @@ static int f2fs_statfs(struct dentry *dentry, struct kstatfs *buf)
+       buf->f_fsid    = u64_to_fsid(id);
+ #ifdef CONFIG_QUOTA
+-      if (is_inode_flag_set(dentry->d_inode, FI_PROJ_INHERIT) &&
++      if (is_inode_flag_set(d_inode(dentry), FI_PROJ_INHERIT) &&
+                       sb_has_quota_limits_enabled(sb, PRJQUOTA)) {
+-              f2fs_statfs_project(sb, F2FS_I(dentry->d_inode)->i_projid, buf);
++              f2fs_statfs_project(sb, F2FS_I(d_inode(dentry))->i_projid, buf);
+       }
+ #endif
+       return 0;
+-- 
+2.39.5
+
diff --git a/queue-6.15/f2fs-zone-fix-to-avoid-inconsistence-in-between-sit-.patch b/queue-6.15/f2fs-zone-fix-to-avoid-inconsistence-in-between-sit-.patch
new file mode 100644 (file)
index 0000000..b036c81
--- /dev/null
@@ -0,0 +1,75 @@
+From 01d2e6a2b93fe07a02eda94509cfdffc05c729b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Mar 2025 16:06:46 +0800
+Subject: f2fs: zone: fix to avoid inconsistence in between SIT and SSA
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 773704c1ef96a8b70d0d186ab725f50548de82c4 ]
+
+w/ below testcase, it will cause inconsistence in between SIT and SSA.
+
+create_null_blk 512 2 1024 1024
+mkfs.f2fs -m /dev/nullb0
+mount /dev/nullb0 /mnt/f2fs/
+touch /mnt/f2fs/file
+f2fs_io pinfile set /mnt/f2fs/file
+fallocate -l 4GiB /mnt/f2fs/file
+
+F2FS-fs (nullb0): Inconsistent segment (0) type [1, 0] in SSA and SIT
+CPU: 5 UID: 0 PID: 2398 Comm: fallocate Tainted: G           O       6.13.0-rc1 #84
+Tainted: [O]=OOT_MODULE
+Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0xb3/0xd0
+ dump_stack+0x14/0x20
+ f2fs_handle_critical_error+0x18c/0x220 [f2fs]
+ f2fs_stop_checkpoint+0x38/0x50 [f2fs]
+ do_garbage_collect+0x674/0x6e0 [f2fs]
+ f2fs_gc_range+0x12b/0x230 [f2fs]
+ f2fs_allocate_pinning_section+0x5c/0x150 [f2fs]
+ f2fs_expand_inode_data+0x1cc/0x3c0 [f2fs]
+ f2fs_fallocate+0x3c3/0x410 [f2fs]
+ vfs_fallocate+0x15f/0x4b0
+ __x64_sys_fallocate+0x4a/0x80
+ x64_sys_call+0x15e8/0x1b80
+ do_syscall_64+0x68/0x130
+ entry_SYSCALL_64_after_hwframe+0x67/0x6f
+RIP: 0033:0x7f9dba5197ca
+F2FS-fs (nullb0): Stopped filesystem due to reason: 4
+
+The reason is f2fs_gc_range() may try to migrate block in curseg, however,
+its SSA block is not uptodate due to the last summary block data is still
+in cache of curseg.
+
+In this patch, we add a condition in f2fs_gc_range() to check whether
+section is opened or not, and skip block migration for opened section.
+
+Fixes: 9703d69d9d15 ("f2fs: support file pinning for zoned devices")
+Reviewed-by: Daeho Jeong <daehojeong@google.com>
+Cc: Daeho Jeong <daehojeong@google.com>
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/gc.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
+index 2b8f9239bede7..8b5a55b72264d 100644
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -2066,6 +2066,9 @@ int f2fs_gc_range(struct f2fs_sb_info *sbi,
+                       .iroot = RADIX_TREE_INIT(gc_list.iroot, GFP_NOFS),
+               };
++              if (IS_CURSEC(sbi, GET_SEC_FROM_SEG(sbi, segno)))
++                      continue;
++
+               do_garbage_collect(sbi, segno, &gc_list, FG_GC, true, false);
+               put_gc_inode(&gc_list);
+-- 
+2.39.5
+
diff --git a/queue-6.15/f2fs-zone-fix-to-calculate-first_zoned_segno-correct.patch b/queue-6.15/f2fs-zone-fix-to-calculate-first_zoned_segno-correct.patch
new file mode 100644 (file)
index 0000000..72ccfb7
--- /dev/null
@@ -0,0 +1,267 @@
+From 44a87dc65593c6dbee3544e16bd1e9646db7807c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Apr 2025 11:10:19 +0800
+Subject: f2fs: zone: fix to calculate first_zoned_segno correctly
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit dc6d9ef57fcf42fac1b3be4bff5ac5b3f1e8f9f3 ]
+
+A zoned device can has both conventional zones and sequential zones,
+so we should not treat first segment of zoned device as first_zoned_segno,
+instead, we need to check zone type for each zone during traversing zoned
+device to find first_zoned_segno.
+
+Otherwise, for below case, first_zoned_segno will be 0, which could be
+wrong.
+
+create_null_blk 512 2 1024 1024
+mkfs.f2fs -m /dev/nullb0
+
+Testcase:
+
+export SCRIPTS_PATH=/share/git/scripts
+
+test multiple devices w/ zoned device
+for ((i=0;i<8;i++)) do {
+       zonesize=$((2<<$i))
+       conzone=$((4096/$zonesize))
+       seqzone=$((4096/$zonesize))
+       $SCRIPTS_PATH/nullblk_create.sh 512 $zonesize $conzone $seqzone
+       mkfs.f2fs -f -m /dev/vdb -c /dev/nullb0
+       mount /dev/vdb /mnt/f2fs
+       touch /mnt/f2fs/file
+       f2fs_io pinfile set /mnt/f2fs/file $((8589934592*2))
+       stat /mnt/f2fs/file
+       df
+       cat /proc/fs/f2fs/vdb/segment_info
+       umount /mnt/f2fs
+       $SCRIPTS_PATH/nullblk_remove.sh 0
+} done
+
+test single zoned device
+for ((i=0;i<8;i++)) do {
+       zonesize=$((2<<$i))
+       conzone=$((4096/$zonesize))
+       seqzone=$((4096/$zonesize))
+       $SCRIPTS_PATH/nullblk_create.sh 512 $zonesize $conzone $seqzone
+       mkfs.f2fs -f -m /dev/nullb0
+       mount /dev/nullb0 /mnt/f2fs
+       touch /mnt/f2fs/file
+       f2fs_io pinfile set /mnt/f2fs/file $((8589934592*2))
+       stat /mnt/f2fs/file
+       df
+       cat /proc/fs/f2fs/nullb0/segment_info
+       umount /mnt/f2fs
+       $SCRIPTS_PATH/nullblk_remove.sh 0
+} done
+
+Fixes: 9703d69d9d15 ("f2fs: support file pinning for zoned devices")
+Cc: Daeho Jeong <daehojeong@google.com>
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/data.c    |  2 +-
+ fs/f2fs/f2fs.h    | 36 ++++++++++++++++++++++++++++--------
+ fs/f2fs/segment.c | 10 +++++-----
+ fs/f2fs/super.c   | 41 +++++++++++++++++++++++++++++++++++------
+ 4 files changed, 69 insertions(+), 20 deletions(-)
+
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index 81b25dd15a0b9..b0b8748ae287f 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -3966,7 +3966,7 @@ static int check_swap_activate(struct swap_info_struct *sis,
+               if ((pblock - SM_I(sbi)->main_blkaddr) % blks_per_sec ||
+                               nr_pblocks % blks_per_sec ||
+-                              !f2fs_valid_pinned_area(sbi, pblock)) {
++                              f2fs_is_sequential_zone_area(sbi, pblock)) {
+                       bool last_extent = false;
+                       not_aligned++;
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 6dcac5ab041c8..4f34a7d9760a1 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -1780,7 +1780,7 @@ struct f2fs_sb_info {
+       unsigned int dirty_device;              /* for checkpoint data flush */
+       spinlock_t dev_lock;                    /* protect dirty_device */
+       bool aligned_blksize;                   /* all devices has the same logical blksize */
+-      unsigned int first_zoned_segno;         /* first zoned segno */
++      unsigned int first_seq_zone_segno;      /* first segno in sequential zone */
+       /* For write statistics */
+       u64 sectors_written_start;
+@@ -4628,12 +4628,16 @@ F2FS_FEATURE_FUNCS(readonly, RO);
+ F2FS_FEATURE_FUNCS(device_alias, DEVICE_ALIAS);
+ #ifdef CONFIG_BLK_DEV_ZONED
+-static inline bool f2fs_blkz_is_seq(struct f2fs_sb_info *sbi, int devi,
+-                                  block_t blkaddr)
++static inline bool f2fs_zone_is_seq(struct f2fs_sb_info *sbi, int devi,
++                                                      unsigned int zone)
+ {
+-      unsigned int zno = blkaddr / sbi->blocks_per_blkz;
++      return test_bit(zone, FDEV(devi).blkz_seq);
++}
+-      return test_bit(zno, FDEV(devi).blkz_seq);
++static inline bool f2fs_blkz_is_seq(struct f2fs_sb_info *sbi, int devi,
++                                                              block_t blkaddr)
++{
++      return f2fs_zone_is_seq(sbi, devi, blkaddr / sbi->blocks_per_blkz);
+ }
+ #endif
+@@ -4705,15 +4709,31 @@ static inline bool f2fs_lfs_mode(struct f2fs_sb_info *sbi)
+       return F2FS_OPTION(sbi).fs_mode == FS_MODE_LFS;
+ }
+-static inline bool f2fs_valid_pinned_area(struct f2fs_sb_info *sbi,
++static inline bool f2fs_is_sequential_zone_area(struct f2fs_sb_info *sbi,
+                                         block_t blkaddr)
+ {
+       if (f2fs_sb_has_blkzoned(sbi)) {
++#ifdef CONFIG_BLK_DEV_ZONED
+               int devi = f2fs_target_device_index(sbi, blkaddr);
+-              return !bdev_is_zoned(FDEV(devi).bdev);
++              if (!bdev_is_zoned(FDEV(devi).bdev))
++                      return false;
++
++              if (f2fs_is_multi_device(sbi)) {
++                      if (blkaddr < FDEV(devi).start_blk ||
++                              blkaddr > FDEV(devi).end_blk) {
++                              f2fs_err(sbi, "Invalid block %x", blkaddr);
++                              return false;
++                      }
++                      blkaddr -= FDEV(devi).start_blk;
++              }
++
++              return f2fs_blkz_is_seq(sbi, devi, blkaddr);
++#else
++              return false;
++#endif
+       }
+-      return true;
++      return false;
+ }
+ static inline bool f2fs_low_mem_mode(struct f2fs_sb_info *sbi)
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index 396ef71f41e35..2a71e70c9ac97 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -2777,7 +2777,7 @@ static int get_new_segment(struct f2fs_sb_info *sbi,
+               if (sbi->blkzone_alloc_policy == BLKZONE_ALLOC_PRIOR_CONV || pinning)
+                       segno = 0;
+               else
+-                      segno = max(sbi->first_zoned_segno, *newseg);
++                      segno = max(sbi->first_seq_zone_segno, *newseg);
+               hint = GET_SEC_FROM_SEG(sbi, segno);
+       }
+ #endif
+@@ -2789,7 +2789,7 @@ static int get_new_segment(struct f2fs_sb_info *sbi,
+       if (secno >= MAIN_SECS(sbi) && f2fs_sb_has_blkzoned(sbi)) {
+               /* Write only to sequential zones */
+               if (sbi->blkzone_alloc_policy == BLKZONE_ALLOC_ONLY_SEQ) {
+-                      hint = GET_SEC_FROM_SEG(sbi, sbi->first_zoned_segno);
++                      hint = GET_SEC_FROM_SEG(sbi, sbi->first_seq_zone_segno);
+                       secno = find_next_zero_bit(free_i->free_secmap, MAIN_SECS(sbi), hint);
+               } else
+                       secno = find_first_zero_bit(free_i->free_secmap,
+@@ -2838,9 +2838,9 @@ static int get_new_segment(struct f2fs_sb_info *sbi,
+       /* set it as dirty segment in free segmap */
+       f2fs_bug_on(sbi, test_bit(segno, free_i->free_segmap));
+-      /* no free section in conventional zone */
++      /* no free section in conventional device or conventional zone */
+       if (new_sec && pinning &&
+-              !f2fs_valid_pinned_area(sbi, START_BLOCK(sbi, segno))) {
++              f2fs_is_sequential_zone_area(sbi, START_BLOCK(sbi, segno))) {
+               ret = -EAGAIN;
+               goto out_unlock;
+       }
+@@ -3311,7 +3311,7 @@ int f2fs_allocate_pinning_section(struct f2fs_sb_info *sbi)
+       if (f2fs_sb_has_blkzoned(sbi) && err == -EAGAIN && gc_required) {
+               f2fs_down_write(&sbi->gc_lock);
+-              err = f2fs_gc_range(sbi, 0, GET_SEGNO(sbi, FDEV(0).end_blk),
++              err = f2fs_gc_range(sbi, 0, sbi->first_seq_zone_segno - 1,
+                               true, ZONED_PIN_SEC_REQUIRED_COUNT);
+               f2fs_up_write(&sbi->gc_lock);
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index f087b2b71c898..7a3bc85df6a7a 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -4304,14 +4304,35 @@ static void f2fs_record_error_work(struct work_struct *work)
+       f2fs_record_stop_reason(sbi);
+ }
+-static inline unsigned int get_first_zoned_segno(struct f2fs_sb_info *sbi)
++static inline unsigned int get_first_seq_zone_segno(struct f2fs_sb_info *sbi)
+ {
++#ifdef CONFIG_BLK_DEV_ZONED
++      unsigned int zoneno, total_zones;
+       int devi;
+-      for (devi = 0; devi < sbi->s_ndevs; devi++)
+-              if (bdev_is_zoned(FDEV(devi).bdev))
+-                      return GET_SEGNO(sbi, FDEV(devi).start_blk);
+-      return 0;
++      if (!f2fs_sb_has_blkzoned(sbi))
++              return NULL_SEGNO;
++
++      for (devi = 0; devi < sbi->s_ndevs; devi++) {
++              if (!bdev_is_zoned(FDEV(devi).bdev))
++                      continue;
++
++              total_zones = GET_ZONE_FROM_SEG(sbi, FDEV(devi).total_segments);
++
++              for (zoneno = 0; zoneno < total_zones; zoneno++) {
++                      unsigned int segs, blks;
++
++                      if (!f2fs_zone_is_seq(sbi, devi, zoneno))
++                              continue;
++
++                      segs = GET_SEG_FROM_SEC(sbi,
++                                      zoneno * sbi->secs_per_zone);
++                      blks = SEGS_TO_BLKS(sbi, segs);
++                      return GET_SEGNO(sbi, FDEV(devi).start_blk + blks);
++              }
++      }
++#endif
++      return NULL_SEGNO;
+ }
+ static int f2fs_scan_devices(struct f2fs_sb_info *sbi)
+@@ -4348,6 +4369,14 @@ static int f2fs_scan_devices(struct f2fs_sb_info *sbi)
+ #endif
+       for (i = 0; i < max_devices; i++) {
++              if (max_devices == 1) {
++                      FDEV(i).total_segments =
++                              le32_to_cpu(raw_super->segment_count_main);
++                      FDEV(i).start_blk = 0;
++                      FDEV(i).end_blk = FDEV(i).total_segments *
++                                              BLKS_PER_SEG(sbi);
++              }
++
+               if (i == 0)
+                       FDEV(0).bdev_file = sbi->sb->s_bdev_file;
+               else if (!RDEV(i).path[0])
+@@ -4718,7 +4747,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
+       sbi->sectors_written_start = f2fs_get_sectors_written(sbi);
+       /* get segno of first zoned block device */
+-      sbi->first_zoned_segno = get_first_zoned_segno(sbi);
++      sbi->first_seq_zone_segno = get_first_seq_zone_segno(sbi);
+       /* Read accumulated write IO statistics if exists */
+       seg_i = CURSEG_I(sbi, CURSEG_HOT_NODE);
+-- 
+2.39.5
+
diff --git a/queue-6.15/fbdev-core-fbcvt-avoid-division-by-0-in-fb_cvt_hperi.patch b/queue-6.15/fbdev-core-fbcvt-avoid-division-by-0-in-fb_cvt_hperi.patch
new file mode 100644 (file)
index 0000000..625bfee
--- /dev/null
@@ -0,0 +1,42 @@
+From af3493f1ba0c86a317480bff230d55d937d9f32a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 May 2025 23:35:58 +0300
+Subject: fbdev: core: fbcvt: avoid division by 0 in fb_cvt_hperiod()
+
+From: Sergey Shtylyov <s.shtylyov@omp.ru>
+
+[ Upstream commit 3f6dae09fc8c306eb70fdfef70726e1f154e173a ]
+
+In fb_find_mode_cvt(), iff mode->refresh somehow happens to be 0x80000000,
+cvt.f_refresh will become 0 when multiplying it by 2 due to overflow. It's
+then passed to fb_cvt_hperiod(), where it's used as a divider -- division
+by 0 will result in kernel oops. Add a sanity check for cvt.f_refresh to
+avoid such overflow...
+
+Found by Linux Verification Center (linuxtesting.org) with the Svace static
+analysis tool.
+
+Fixes: 96fe6a2109db ("[PATCH] fbdev: Add VESA Coordinated Video Timings (CVT) support")
+Signed-off-by: Sergey Shtylyov <s.shtylyov@omp.ru>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/core/fbcvt.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/video/fbdev/core/fbcvt.c b/drivers/video/fbdev/core/fbcvt.c
+index 64843464c6613..cd3821bd82e56 100644
+--- a/drivers/video/fbdev/core/fbcvt.c
++++ b/drivers/video/fbdev/core/fbcvt.c
+@@ -312,7 +312,7 @@ int fb_find_mode_cvt(struct fb_videomode *mode, int margins, int rb)
+       cvt.f_refresh = cvt.refresh;
+       cvt.interlace = 1;
+-      if (!cvt.xres || !cvt.yres || !cvt.refresh) {
++      if (!cvt.xres || !cvt.yres || !cvt.refresh || cvt.f_refresh > INT_MAX) {
+               printk(KERN_INFO "fbcvt: Invalid input parameters\n");
+               return 1;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/finish_automount-don-t-leak-mnt_locked-from-parent-t.patch b/queue-6.15/finish_automount-don-t-leak-mnt_locked-from-parent-t.patch
new file mode 100644 (file)
index 0000000..ed637c1
--- /dev/null
@@ -0,0 +1,54 @@
+From 0b904cb1bd43adb73d37951580d9ff90b2746283 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 4 May 2025 13:28:37 -0400
+Subject: finish_automount(): don't leak MNT_LOCKED from parent to child
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+[ Upstream commit bab77c0d191e241d2d59a845c7ed68bfa6e1b257 ]
+
+Intention for MNT_LOCKED had always been to protect the internal
+mountpoints within a subtree that got copied across the userns boundary,
+not the mountpoint that tree got attached to - after all, it _was_
+exposed before the copying.
+
+For roots of secondary copies that is enforced in attach_recursive_mnt() -
+MNT_LOCKED is explicitly stripped for those.  For the root of primary
+copy we are almost always guaranteed that MNT_LOCKED won't be there,
+so attach_recursive_mnt() doesn't bother.  Unfortunately, one call
+chain got overlooked - triggering e.g. NFS referral will have the
+submount inherit the public flags from parent; that's fine for such
+things as read-only, nosuid, etc., but not for MNT_LOCKED.
+
+This is particularly pointless since the mount attached by finish_automount()
+is usually expirable, which makes any protection granted by MNT_LOCKED
+null and void; just wait for a while and that mount will go away on its own.
+
+Include MNT_LOCKED into the set of flags to be ignored by do_add_mount() - it
+really is an internal flag.
+
+Reviewed-by: Christian Brauner <brauner@kernel.org>
+Fixes: 5ff9d8a65ce8 ("vfs: Lock in place mounts from more privileged users")
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/mount.h | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/include/linux/mount.h b/include/linux/mount.h
+index 6904ad33ee7a3..1a3136e53eaa0 100644
+--- a/include/linux/mount.h
++++ b/include/linux/mount.h
+@@ -65,7 +65,8 @@ enum mount_flags {
+       MNT_ATIME_MASK = MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME,
+       MNT_INTERNAL_FLAGS = MNT_SHARED | MNT_WRITE_HOLD | MNT_INTERNAL |
+-                           MNT_DOOMED | MNT_SYNC_UMOUNT | MNT_MARKED,
++                           MNT_DOOMED | MNT_SYNC_UMOUNT | MNT_MARKED |
++                           MNT_LOCKED,
+ };
+ struct vfsmount {
+-- 
+2.39.5
+
diff --git a/queue-6.15/firmware-exynos-acpm-fix-reading-longer-results.patch b/queue-6.15/firmware-exynos-acpm-fix-reading-longer-results.patch
new file mode 100644 (file)
index 0000000..4250d29
--- /dev/null
@@ -0,0 +1,115 @@
+From f3e31568914264af0249419f7bc1f24f85839e67 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Mar 2025 05:38:23 +0000
+Subject: firmware: exynos-acpm: fix reading longer results
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: André Draszik <andre.draszik@linaro.org>
+
+[ Upstream commit 67af3cd813695fd3e6432b0849c453250c4685aa ]
+
+ACPM commands that return more than 8 bytes currently don't work
+correctly, as this driver ignores any such returned bytes.
+
+This is evident in at least acpm_pmic_bulk_read(), where up to 8
+registers can be read back and those 8 register values are placed
+starting at &xfer->rxd[8].
+
+The reason is that xfter->rxlen is initialized with the size of a
+pointer (8 bytes), rather than the size of the byte array that pointer
+points to (16 bytes)
+
+Update the code such that we set the number of bytes expected to be the
+size of the rx buffer.
+
+Note1: While different commands have different lengths rx buffers, we
+have to specify the same length for all rx buffers since acpm_get_rx()
+assumes they're all the same length.
+
+Note2: The different commands also have different lengths tx buffers,
+but before switching the code to use the minimum possible length, some
+more testing would have to be done to ensure this works correctly in
+all situations. It seems wiser to just apply this fix here without
+additional logic changes for now.
+
+Fixes: a88927b534ba ("firmware: add Exynos ACPM protocol driver")
+Reviewed-by: Tudor Ambarus <tudor.ambarus@linaro.org>
+Signed-off-by: André Draszik <andre.draszik@linaro.org>
+Link: https://lore.kernel.org/r/20250319-acpm-fixes-v2-1-ac2c1bcf322b@linaro.org
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/samsung/exynos-acpm-pmic.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/firmware/samsung/exynos-acpm-pmic.c b/drivers/firmware/samsung/exynos-acpm-pmic.c
+index 85e90d236da21..39b33a356ebd2 100644
+--- a/drivers/firmware/samsung/exynos-acpm-pmic.c
++++ b/drivers/firmware/samsung/exynos-acpm-pmic.c
+@@ -43,13 +43,13 @@ static inline u32 acpm_pmic_get_bulk(u32 data, unsigned int i)
+       return (data >> (ACPM_PMIC_BULK_SHIFT * i)) & ACPM_PMIC_BULK_MASK;
+ }
+-static void acpm_pmic_set_xfer(struct acpm_xfer *xfer, u32 *cmd,
++static void acpm_pmic_set_xfer(struct acpm_xfer *xfer, u32 *cmd, size_t cmdlen,
+                              unsigned int acpm_chan_id)
+ {
+       xfer->txd = cmd;
+       xfer->rxd = cmd;
+-      xfer->txlen = sizeof(cmd);
+-      xfer->rxlen = sizeof(cmd);
++      xfer->txlen = cmdlen;
++      xfer->rxlen = cmdlen;
+       xfer->acpm_chan_id = acpm_chan_id;
+ }
+@@ -71,7 +71,7 @@ int acpm_pmic_read_reg(const struct acpm_handle *handle,
+       int ret;
+       acpm_pmic_init_read_cmd(cmd, type, reg, chan);
+-      acpm_pmic_set_xfer(&xfer, cmd, acpm_chan_id);
++      acpm_pmic_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id);
+       ret = acpm_do_xfer(handle, &xfer);
+       if (ret)
+@@ -104,7 +104,7 @@ int acpm_pmic_bulk_read(const struct acpm_handle *handle,
+               return -EINVAL;
+       acpm_pmic_init_bulk_read_cmd(cmd, type, reg, chan, count);
+-      acpm_pmic_set_xfer(&xfer, cmd, acpm_chan_id);
++      acpm_pmic_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id);
+       ret = acpm_do_xfer(handle, &xfer);
+       if (ret)
+@@ -144,7 +144,7 @@ int acpm_pmic_write_reg(const struct acpm_handle *handle,
+       int ret;
+       acpm_pmic_init_write_cmd(cmd, type, reg, chan, value);
+-      acpm_pmic_set_xfer(&xfer, cmd, acpm_chan_id);
++      acpm_pmic_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id);
+       ret = acpm_do_xfer(handle, &xfer);
+       if (ret)
+@@ -184,7 +184,7 @@ int acpm_pmic_bulk_write(const struct acpm_handle *handle,
+               return -EINVAL;
+       acpm_pmic_init_bulk_write_cmd(cmd, type, reg, chan, count, buf);
+-      acpm_pmic_set_xfer(&xfer, cmd, acpm_chan_id);
++      acpm_pmic_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id);
+       ret = acpm_do_xfer(handle, &xfer);
+       if (ret)
+@@ -214,7 +214,7 @@ int acpm_pmic_update_reg(const struct acpm_handle *handle,
+       int ret;
+       acpm_pmic_init_update_cmd(cmd, type, reg, chan, value, mask);
+-      acpm_pmic_set_xfer(&xfer, cmd, acpm_chan_id);
++      acpm_pmic_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id);
+       ret = acpm_do_xfer(handle, &xfer);
+       if (ret)
+-- 
+2.39.5
+
diff --git a/queue-6.15/firmware-exynos-acpm-silence-eprobe_defer-error-on-b.patch b/queue-6.15/firmware-exynos-acpm-silence-eprobe_defer-error-on-b.patch
new file mode 100644 (file)
index 0000000..713dfef
--- /dev/null
@@ -0,0 +1,66 @@
+From 7211cac92829489f6c148b6894a6e4a425f61057 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Mar 2025 05:38:24 +0000
+Subject: firmware: exynos-acpm: silence EPROBE_DEFER error on boot
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: André Draszik <andre.draszik@linaro.org>
+
+[ Upstream commit 53734383a73888e6d765aa07f4523802fdf1ee10 ]
+
+This driver emits error messages when client drivers are trying to get
+an interface handle to this driver here before this driver has
+completed _probe().
+
+Given this driver returns -EPROBE_DEFER in that case, this is not an
+error and shouldn't be emitted to the log, similar to how
+dev_err_probe() behaves, so just remove them.
+
+This change also allows us to simplify the logic around releasing of
+the acpm_np handle.
+
+Fixes: a88927b534ba ("firmware: add Exynos ACPM protocol driver")
+Signed-off-by: André Draszik <andre.draszik@linaro.org>
+Link: https://lore.kernel.org/r/20250319-acpm-fixes-v2-2-ac2c1bcf322b@linaro.org
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/samsung/exynos-acpm.c | 11 ++---------
+ 1 file changed, 2 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/firmware/samsung/exynos-acpm.c b/drivers/firmware/samsung/exynos-acpm.c
+index 15e991b99f5a3..e80cb7a8da8f2 100644
+--- a/drivers/firmware/samsung/exynos-acpm.c
++++ b/drivers/firmware/samsung/exynos-acpm.c
+@@ -696,24 +696,17 @@ static const struct acpm_handle *acpm_get_by_phandle(struct device *dev,
+               return ERR_PTR(-ENODEV);
+       pdev = of_find_device_by_node(acpm_np);
+-      if (!pdev) {
+-              dev_err(dev, "Cannot find device node %s\n", acpm_np->name);
+-              of_node_put(acpm_np);
+-              return ERR_PTR(-EPROBE_DEFER);
+-      }
+-
+       of_node_put(acpm_np);
++      if (!pdev)
++              return ERR_PTR(-EPROBE_DEFER);
+       acpm = platform_get_drvdata(pdev);
+       if (!acpm) {
+-              dev_err(dev, "Cannot get drvdata from %s\n",
+-                      dev_name(&pdev->dev));
+               platform_device_put(pdev);
+               return ERR_PTR(-EPROBE_DEFER);
+       }
+       if (!try_module_get(pdev->dev.driver->owner)) {
+-              dev_err(dev, "Cannot get module reference.\n");
+               platform_device_put(pdev);
+               return ERR_PTR(-EPROBE_DEFER);
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/firmware-psci-fix-refcount-leak-in-psci_dt_init.patch b/queue-6.15/firmware-psci-fix-refcount-leak-in-psci_dt_init.patch
new file mode 100644 (file)
index 0000000..4cf8879
--- /dev/null
@@ -0,0 +1,42 @@
+From 0c9730bb6d1e216e9204fe5c659805df56794efa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Mar 2025 23:17:12 +0800
+Subject: firmware: psci: Fix refcount leak in psci_dt_init
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 7ff37d29fd5c27617b9767e1b8946d115cf93a1e ]
+
+Fix a reference counter leak in psci_dt_init() where of_node_put(np) was
+missing after of_find_matching_node_and_match() when np is unavailable.
+
+Fixes: d09a0011ec0d ("drivers: psci: Allow PSCI node to be disabled")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Reviewed-by: Gavin Shan <gshan@redhat.com>
+Acked-by: Mark Rutland <mark.rutland@arm.com>
+Link: https://lore.kernel.org/r/20250318151712.28763-1-linmq006@gmail.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/psci/psci.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c
+index a1ebbe9b73b13..38ca190d4a22d 100644
+--- a/drivers/firmware/psci/psci.c
++++ b/drivers/firmware/psci/psci.c
+@@ -804,8 +804,10 @@ int __init psci_dt_init(void)
+       np = of_find_matching_node_and_match(NULL, psci_of_match, &matched_np);
+-      if (!np || !of_device_is_available(np))
++      if (!np || !of_device_is_available(np)) {
++              of_node_put(np);
+               return -ENODEV;
++      }
+       init_fn = (psci_initcall_t)matched_np->data;
+       ret = init_fn(np);
+-- 
+2.39.5
+
diff --git a/queue-6.15/firmware-sdei-allow-sdei-initialization-without-acpi.patch b/queue-6.15/firmware-sdei-allow-sdei-initialization-without-acpi.patch
new file mode 100644 (file)
index 0000000..419b06d
--- /dev/null
@@ -0,0 +1,136 @@
+From cb83bbb501614fef89fe64e6e420c9596d0fa56a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 May 2025 12:57:57 +0800
+Subject: firmware: SDEI: Allow sdei initialization without ACPI_APEI_GHES
+
+From: Huang Yiwei <quic_hyiwei@quicinc.com>
+
+[ Upstream commit 59529bbe642de4eb2191a541d9b4bae7eb73862e ]
+
+SDEI usually initialize with the ACPI table, but on platforms where
+ACPI is not used, the SDEI feature can still be used to handle
+specific firmware calls or other customized purposes. Therefore, it
+is not necessary for ARM_SDE_INTERFACE to depend on ACPI_APEI_GHES.
+
+In commit dc4e8c07e9e2 ("ACPI: APEI: explicit init of HEST and GHES
+in acpi_init()"), to make APEI ready earlier, sdei_init was moved
+into acpi_ghes_init instead of being a standalone initcall, adding
+ACPI_APEI_GHES dependency to ARM_SDE_INTERFACE. This restricts the
+flexibility and usability of SDEI.
+
+This patch corrects the dependency in Kconfig and splits sdei_init()
+into two separate functions: sdei_init() and acpi_sdei_init().
+sdei_init() will be called by arch_initcall and will only initialize
+the platform driver, while acpi_sdei_init() will initialize the
+device from acpi_ghes_init() when ACPI is ready. This allows the
+initialization of SDEI without ACPI_APEI_GHES enabled.
+
+Fixes: dc4e8c07e9e2 ("ACPI: APEI: explicit init of HEST and GHES in apci_init()")
+Cc: Shuai Xue <xueshuai@linux.alibaba.com>
+Signed-off-by: Huang Yiwei <quic_hyiwei@quicinc.com>
+Reviewed-by: Shuai Xue <xueshuai@linux.alibaba.com>
+Reviewed-by: Gavin Shan <gshan@redhat.com>
+Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Link: https://lore.kernel.org/r/20250507045757.2658795-1-quic_hyiwei@quicinc.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/apei/Kconfig   |  1 +
+ drivers/acpi/apei/ghes.c    |  2 +-
+ drivers/firmware/Kconfig    |  1 -
+ drivers/firmware/arm_sdei.c | 11 ++++++++---
+ include/linux/arm_sdei.h    |  4 ++--
+ 5 files changed, 12 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig
+index 3cfe7e7475f2f..070c07d68dfb2 100644
+--- a/drivers/acpi/apei/Kconfig
++++ b/drivers/acpi/apei/Kconfig
+@@ -23,6 +23,7 @@ config ACPI_APEI_GHES
+       select ACPI_HED
+       select IRQ_WORK
+       select GENERIC_ALLOCATOR
++      select ARM_SDE_INTERFACE if ARM64
+       help
+         Generic Hardware Error Source provides a way to report
+         platform hardware errors (such as that from chipset). It
+diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
+index 289e365f84b24..0f3c663c1b0a3 100644
+--- a/drivers/acpi/apei/ghes.c
++++ b/drivers/acpi/apei/ghes.c
+@@ -1715,7 +1715,7 @@ void __init acpi_ghes_init(void)
+ {
+       int rc;
+-      sdei_init();
++      acpi_sdei_init();
+       if (acpi_disabled)
+               return;
+diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
+index aadc395ee1681..7df19d82aa689 100644
+--- a/drivers/firmware/Kconfig
++++ b/drivers/firmware/Kconfig
+@@ -31,7 +31,6 @@ config ARM_SCPI_PROTOCOL
+ config ARM_SDE_INTERFACE
+       bool "ARM Software Delegated Exception Interface (SDEI)"
+       depends on ARM64
+-      depends on ACPI_APEI_GHES
+       help
+         The Software Delegated Exception Interface (SDEI) is an ARM
+         standard for registering callbacks from the platform firmware
+diff --git a/drivers/firmware/arm_sdei.c b/drivers/firmware/arm_sdei.c
+index 3e8051fe82965..71e2a9a89f6ad 100644
+--- a/drivers/firmware/arm_sdei.c
++++ b/drivers/firmware/arm_sdei.c
+@@ -1062,13 +1062,12 @@ static bool __init sdei_present_acpi(void)
+       return true;
+ }
+-void __init sdei_init(void)
++void __init acpi_sdei_init(void)
+ {
+       struct platform_device *pdev;
+       int ret;
+-      ret = platform_driver_register(&sdei_driver);
+-      if (ret || !sdei_present_acpi())
++      if (!sdei_present_acpi())
+               return;
+       pdev = platform_device_register_simple(sdei_driver.driver.name,
+@@ -1081,6 +1080,12 @@ void __init sdei_init(void)
+       }
+ }
++static int __init sdei_init(void)
++{
++      return platform_driver_register(&sdei_driver);
++}
++arch_initcall(sdei_init);
++
+ int sdei_event_handler(struct pt_regs *regs,
+                      struct sdei_registered_event *arg)
+ {
+diff --git a/include/linux/arm_sdei.h b/include/linux/arm_sdei.h
+index 255701e1251b4..f652a5028b590 100644
+--- a/include/linux/arm_sdei.h
++++ b/include/linux/arm_sdei.h
+@@ -46,12 +46,12 @@ int sdei_unregister_ghes(struct ghes *ghes);
+ /* For use by arch code when CPU hotplug notifiers are not appropriate. */
+ int sdei_mask_local_cpu(void);
+ int sdei_unmask_local_cpu(void);
+-void __init sdei_init(void);
++void __init acpi_sdei_init(void);
+ void sdei_handler_abort(void);
+ #else
+ static inline int sdei_mask_local_cpu(void) { return 0; }
+ static inline int sdei_unmask_local_cpu(void) { return 0; }
+-static inline void sdei_init(void) { }
++static inline void acpi_sdei_init(void) { }
+ static inline void sdei_handler_abort(void) { }
+ #endif /* CONFIG_ARM_SDE_INTERFACE */
+-- 
+2.39.5
+
diff --git a/queue-6.15/fix-propagation-graph-breakage-by-move_mount_set_gro.patch b/queue-6.15/fix-propagation-graph-breakage-by-move_mount_set_gro.patch
new file mode 100644 (file)
index 0000000..c951a78
--- /dev/null
@@ -0,0 +1,60 @@
+From e937b6a1519c590b7c7bd53874728eeeef29707c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Jun 2025 17:57:27 -0400
+Subject: fix propagation graph breakage by MOVE_MOUNT_SET_GROUP move_mount(2)
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+[ Upstream commit d8cc0362f918d020ca1340d7694f07062dc30f36 ]
+
+9ffb14ef61ba "move_mount: allow to add a mount into an existing group"
+breaks assertions on ->mnt_share/->mnt_slave.  For once, the data structures
+in question are actually documented.
+
+Documentation/filesystem/sharedsubtree.rst:
+        All vfsmounts in a peer group have the same ->mnt_master.  If it is
+       non-NULL, they form a contiguous (ordered) segment of slave list.
+
+do_set_group() puts a mount into the same place in propagation graph
+as the old one.  As the result, if old mount gets events from somewhere
+and is not a pure event sink, new one needs to be placed next to the
+old one in the slave list the old one's on.  If it is a pure event
+sink, we only need to make sure the new one doesn't end up in the
+middle of some peer group.
+
+"move_mount: allow to add a mount into an existing group" ends up putting
+the new one in the beginning of list; that's definitely not going to be
+in the middle of anything, so that's fine for case when old is not marked
+shared.  In case when old one _is_ marked shared (i.e. is not a pure event
+sink), that breaks the assumptions of propagation graph iterators.
+
+Put the new mount next to the old one on the list - that does the right thing
+in "old is marked shared" case and is just as correct as the current behaviour
+if old is not marked shared (kudos to Pavel for pointing that out - my original
+suggested fix changed behaviour in the "nor marked" case, which complicated
+things for no good reason).
+
+Reviewed-by: Christian Brauner <brauner@kernel.org>
+Fixes: 9ffb14ef61ba ("move_mount: allow to add a mount into an existing group")
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/namespace.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/namespace.c b/fs/namespace.c
+index cb5126b06dcb9..e2780f413a2e0 100644
+--- a/fs/namespace.c
++++ b/fs/namespace.c
+@@ -3452,7 +3452,7 @@ static int do_set_group(struct path *from_path, struct path *to_path)
+       if (IS_MNT_SLAVE(from)) {
+               struct mount *m = from->mnt_master;
+-              list_add(&to->mnt_slave, &m->mnt_slave_list);
++              list_add(&to->mnt_slave, &from->mnt_slave);
+               to->mnt_master = m;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/fix-sock_exceed_buf_limit-not-being-triggered-in-__s.patch b/queue-6.15/fix-sock_exceed_buf_limit-not-being-triggered-in-__s.patch
new file mode 100644 (file)
index 0000000..935929b
--- /dev/null
@@ -0,0 +1,64 @@
+From e3cecc53d9aa6183ac1a7bdd91b25c499bc154ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 May 2025 11:04:19 +0800
+Subject: Fix sock_exceed_buf_limit not being triggered in
+ __sk_mem_raise_allocated
+
+From: Tengteng Yang <yangtengteng@bytedance.com>
+
+[ Upstream commit 8542d6fac25c03b4bf36b2d762cfe60fda8491bb ]
+
+When a process under memory pressure is not part of any cgroup and
+the charged flag is false, trace_sock_exceed_buf_limit was not called
+as expected.
+
+This regression was introduced by commit 2def8ff3fdb6 ("sock:
+Code cleanup on __sk_mem_raise_allocated()"). The fix changes the
+default value of charged to true while preserving existing logic.
+
+Fixes: 2def8ff3fdb6 ("sock: Code cleanup on __sk_mem_raise_allocated()")
+Signed-off-by: Abel Wu <wuyun.abel@bytedance.com>
+Signed-off-by: Tengteng Yang <yangtengteng@bytedance.com>
+Link: https://patch.msgid.link/20250527030419.67693-1-yangtengteng@bytedance.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/sock.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/net/core/sock.c b/net/core/sock.c
+index e54449c9ab0ba..5034d0fbd4a42 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -3234,16 +3234,16 @@ int __sk_mem_raise_allocated(struct sock *sk, int size, int amt, int kind)
+ {
+       struct mem_cgroup *memcg = mem_cgroup_sockets_enabled ? sk->sk_memcg : NULL;
+       struct proto *prot = sk->sk_prot;
+-      bool charged = false;
++      bool charged = true;
+       long allocated;
+       sk_memory_allocated_add(sk, amt);
+       allocated = sk_memory_allocated(sk);
+       if (memcg) {
+-              if (!mem_cgroup_charge_skmem(memcg, amt, gfp_memcg_charge()))
++              charged = mem_cgroup_charge_skmem(memcg, amt, gfp_memcg_charge());
++              if (!charged)
+                       goto suppress_allocation;
+-              charged = true;
+       }
+       /* Under limit. */
+@@ -3328,7 +3328,7 @@ int __sk_mem_raise_allocated(struct sock *sk, int size, int amt, int kind)
+       sk_memory_allocated_sub(sk, amt);
+-      if (charged)
++      if (memcg && charged)
+               mem_cgroup_uncharge_skmem(memcg, amt);
+       return 0;
+-- 
+2.39.5
+
diff --git a/queue-6.15/fpga-fix-potential-null-pointer-deref-in-fpga_mgr_te.patch b/queue-6.15/fpga-fix-potential-null-pointer-deref-in-fpga_mgr_te.patch
new file mode 100644 (file)
index 0000000..ab91db8
--- /dev/null
@@ -0,0 +1,45 @@
+From 94cf82296655ba20ed8c18875e73b016214fe8d1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Apr 2025 16:37:37 +0100
+Subject: fpga: fix potential null pointer deref in
+ fpga_mgr_test_img_load_sgt()
+
+From: Qasim Ijaz <qasdev00@gmail.com>
+
+[ Upstream commit 6ebf1982038af12f3588417e4fd0417d2551da28 ]
+
+fpga_mgr_test_img_load_sgt() allocates memory for sgt using
+kunit_kzalloc() however it does not check if the allocation failed.
+It then passes sgt to sg_alloc_table(), which passes it to
+__sg_alloc_table(). This function calls memset() on sgt in an attempt to
+zero it out. If the allocation fails then sgt will be NULL and the
+memset will trigger a NULL pointer dereference.
+
+Fix this by checking the allocation with KUNIT_ASSERT_NOT_ERR_OR_NULL().
+
+Reviewed-by: Marco Pagani <marco.pagani@linux.dev>
+Fixes: ccbc1c302115 ("fpga: add an initial KUnit suite for the FPGA Manager")
+Signed-off-by: Qasim Ijaz <qasdev00@gmail.com>
+Acked-by: Xu Yilun <yilun.xu@intel.com>
+Link: https://lore.kernel.org/r/20250422153737.5264-1-qasdev00@gmail.com
+Signed-off-by: Xu Yilun <yilun.xu@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/fpga/tests/fpga-mgr-test.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/fpga/tests/fpga-mgr-test.c b/drivers/fpga/tests/fpga-mgr-test.c
+index 8748babb05045..62975a39ee14e 100644
+--- a/drivers/fpga/tests/fpga-mgr-test.c
++++ b/drivers/fpga/tests/fpga-mgr-test.c
+@@ -263,6 +263,7 @@ static void fpga_mgr_test_img_load_sgt(struct kunit *test)
+       img_buf = init_test_buffer(test, IMAGE_SIZE);
+       sgt = kunit_kzalloc(test, sizeof(*sgt), GFP_KERNEL);
++      KUNIT_ASSERT_NOT_ERR_OR_NULL(test, sgt);
+       ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
+       KUNIT_ASSERT_EQ(test, ret, 0);
+       sg_init_one(sgt->sgl, img_buf, IMAGE_SIZE);
+-- 
+2.39.5
+
diff --git a/queue-6.15/fs-allow-clone_private_mount-for-a-path-on-real-root.patch b/queue-6.15/fs-allow-clone_private_mount-for-a-path-on-real-root.patch
new file mode 100644 (file)
index 0000000..4512dbe
--- /dev/null
@@ -0,0 +1,77 @@
+From b1117f7c58bcb817d6375114063606cbee07628e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 May 2025 12:18:30 +0000
+Subject: fs: allow clone_private_mount() for a path on real rootfs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: KONDO KAZUMA(近藤 和真) <kazuma-kondo@nec.com>
+
+[ Upstream commit 4954346d80fb047cb78776d9f2ebd6a050f80c5f ]
+
+Mounting overlayfs with a directory on real rootfs (initramfs)
+as upperdir has failed with following message since commit
+db04662e2f4f ("fs: allow detached mounts in clone_private_mount()").
+
+  [    4.080134] overlayfs: failed to clone upperpath
+
+Overlayfs mount uses clone_private_mount() to create internal mount
+for the underlying layers.
+
+The commit made clone_private_mount() reject real rootfs because
+it does not have a parent mount and is in the initial mount namespace,
+that is not an anonymous mount namespace.
+
+This issue can be fixed by modifying the permission check
+of clone_private_mount() following [1].
+
+Reviewed-by: Christian Brauner <brauner@kernel.org>
+Fixes: db04662e2f4f ("fs: allow detached mounts in clone_private_mount()")
+Link: https://lore.kernel.org/all/20250514190252.GQ2023217@ZenIV/ [1]
+Link: https://lore.kernel.org/all/20250506194849.GT2023217@ZenIV/
+Suggested-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Kazuma Kondo <kazuma-kondo@nec.com>
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/namespace.c | 21 +++++++++++----------
+ 1 file changed, 11 insertions(+), 10 deletions(-)
+
+diff --git a/fs/namespace.c b/fs/namespace.c
+index e2780f413a2e0..07bc500a248ec 100644
+--- a/fs/namespace.c
++++ b/fs/namespace.c
+@@ -2492,18 +2492,19 @@ struct vfsmount *clone_private_mount(const struct path *path)
+       if (IS_MNT_UNBINDABLE(old_mnt))
+               return ERR_PTR(-EINVAL);
+-      if (mnt_has_parent(old_mnt)) {
+-              if (!check_mnt(old_mnt))
+-                      return ERR_PTR(-EINVAL);
+-      } else {
+-              if (!is_mounted(&old_mnt->mnt))
+-                      return ERR_PTR(-EINVAL);
+-
+-              /* Make sure this isn't something purely kernel internal. */
+-              if (!is_anon_ns(old_mnt->mnt_ns))
++      /*
++       * Make sure the source mount is acceptable.
++       * Anything mounted in our mount namespace is allowed.
++       * Otherwise, it must be the root of an anonymous mount
++       * namespace, and we need to make sure no namespace
++       * loops get created.
++       */
++      if (!check_mnt(old_mnt)) {
++              if (!is_mounted(&old_mnt->mnt) ||
++                      !is_anon_ns(old_mnt->mnt_ns) ||
++                      mnt_has_parent(old_mnt))
+                       return ERR_PTR(-EINVAL);
+-              /* Make sure we don't create mount namespace loops. */
+               if (!check_for_nsfs_mounts(old_mnt))
+                       return ERR_PTR(-EINVAL);
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/fs-convert-mount-flags-to-enum.patch b/queue-6.15/fs-convert-mount-flags-to-enum.patch
new file mode 100644 (file)
index 0000000..6765108
--- /dev/null
@@ -0,0 +1,135 @@
+From 1796925f8fde74f91a2c3b9ece1fa7315606eeb5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 May 2025 15:34:01 -0700
+Subject: fs: convert mount flags to enum
+
+From: Stephen Brennan <stephen.s.brennan@oracle.com>
+
+[ Upstream commit 101f2bbab541116ab861b9c3ac0ece07a7eaa756 ]
+
+In prior kernel versions (5.8-6.8), commit 9f6c61f96f2d9 ("proc/mounts:
+add cursor") introduced MNT_CURSOR, a flag used by readers from
+/proc/mounts to keep their place while reading the file. Later, commit
+2eea9ce4310d8 ("mounts: keep list of mounts in an rbtree") removed this
+flag and its value has since been repurposed.
+
+For debuggers iterating over the list of mounts, cursors should be
+skipped as they are irrelevant. Detecting whether an element is a cursor
+can be difficult. Since the MNT_CURSOR flag is a preprocessor constant,
+it's not present in debuginfo, and since its value is repurposed, we
+cannot hard-code it. For this specific issue, cursors are possible to
+detect in other ways, but ideally, we would be able to read the mount
+flag definitions out of the debuginfo. For that reason, convert the
+mount flags to an enum.
+
+Link: https://github.com/osandov/drgn/pull/496
+Signed-off-by: Stephen Brennan <stephen.s.brennan@oracle.com>
+Link: https://lore.kernel.org/20250507223402.2795029-1-stephen.s.brennan@oracle.com
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Stable-dep-of: bab77c0d191e ("finish_automount(): don't leak MNT_LOCKED from parent to child")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/mount.h | 87 ++++++++++++++++++++++---------------------
+ 1 file changed, 45 insertions(+), 42 deletions(-)
+
+diff --git a/include/linux/mount.h b/include/linux/mount.h
+index dcc17ce8a959e..6904ad33ee7a3 100644
+--- a/include/linux/mount.h
++++ b/include/linux/mount.h
+@@ -22,48 +22,51 @@ struct fs_context;
+ struct file;
+ struct path;
+-#define MNT_NOSUID    0x01
+-#define MNT_NODEV     0x02
+-#define MNT_NOEXEC    0x04
+-#define MNT_NOATIME   0x08
+-#define MNT_NODIRATIME        0x10
+-#define MNT_RELATIME  0x20
+-#define MNT_READONLY  0x40    /* does the user want this to be r/o? */
+-#define MNT_NOSYMFOLLOW       0x80
+-
+-#define MNT_SHRINKABLE        0x100
+-#define MNT_WRITE_HOLD        0x200
+-
+-#define MNT_SHARED    0x1000  /* if the vfsmount is a shared mount */
+-#define MNT_UNBINDABLE        0x2000  /* if the vfsmount is a unbindable mount */
+-/*
+- * MNT_SHARED_MASK is the set of flags that should be cleared when a
+- * mount becomes shared.  Currently, this is only the flag that says a
+- * mount cannot be bind mounted, since this is how we create a mount
+- * that shares events with another mount.  If you add a new MNT_*
+- * flag, consider how it interacts with shared mounts.
+- */
+-#define MNT_SHARED_MASK       (MNT_UNBINDABLE)
+-#define MNT_USER_SETTABLE_MASK  (MNT_NOSUID | MNT_NODEV | MNT_NOEXEC \
+-                               | MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME \
+-                               | MNT_READONLY | MNT_NOSYMFOLLOW)
+-#define MNT_ATIME_MASK (MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME )
+-
+-#define MNT_INTERNAL_FLAGS (MNT_SHARED | MNT_WRITE_HOLD | MNT_INTERNAL | \
+-                          MNT_DOOMED | MNT_SYNC_UMOUNT | MNT_MARKED)
+-
+-#define MNT_INTERNAL  0x4000
+-
+-#define MNT_LOCK_ATIME                0x040000
+-#define MNT_LOCK_NOEXEC               0x080000
+-#define MNT_LOCK_NOSUID               0x100000
+-#define MNT_LOCK_NODEV                0x200000
+-#define MNT_LOCK_READONLY     0x400000
+-#define MNT_LOCKED            0x800000
+-#define MNT_DOOMED            0x1000000
+-#define MNT_SYNC_UMOUNT               0x2000000
+-#define MNT_MARKED            0x4000000
+-#define MNT_UMOUNT            0x8000000
++enum mount_flags {
++      MNT_NOSUID      = 0x01,
++      MNT_NODEV       = 0x02,
++      MNT_NOEXEC      = 0x04,
++      MNT_NOATIME     = 0x08,
++      MNT_NODIRATIME  = 0x10,
++      MNT_RELATIME    = 0x20,
++      MNT_READONLY    = 0x40, /* does the user want this to be r/o? */
++      MNT_NOSYMFOLLOW = 0x80,
++
++      MNT_SHRINKABLE  = 0x100,
++      MNT_WRITE_HOLD  = 0x200,
++
++      MNT_SHARED      = 0x1000, /* if the vfsmount is a shared mount */
++      MNT_UNBINDABLE  = 0x2000, /* if the vfsmount is a unbindable mount */
++
++      MNT_INTERNAL    = 0x4000,
++
++      MNT_LOCK_ATIME          = 0x040000,
++      MNT_LOCK_NOEXEC         = 0x080000,
++      MNT_LOCK_NOSUID         = 0x100000,
++      MNT_LOCK_NODEV          = 0x200000,
++      MNT_LOCK_READONLY       = 0x400000,
++      MNT_LOCKED              = 0x800000,
++      MNT_DOOMED              = 0x1000000,
++      MNT_SYNC_UMOUNT         = 0x2000000,
++      MNT_MARKED              = 0x4000000,
++      MNT_UMOUNT              = 0x8000000,
++
++      /*
++       * MNT_SHARED_MASK is the set of flags that should be cleared when a
++       * mount becomes shared.  Currently, this is only the flag that says a
++       * mount cannot be bind mounted, since this is how we create a mount
++       * that shares events with another mount.  If you add a new MNT_*
++       * flag, consider how it interacts with shared mounts.
++       */
++      MNT_SHARED_MASK = MNT_UNBINDABLE,
++      MNT_USER_SETTABLE_MASK  = MNT_NOSUID | MNT_NODEV | MNT_NOEXEC
++                                | MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME
++                                | MNT_READONLY | MNT_NOSYMFOLLOW,
++      MNT_ATIME_MASK = MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME,
++
++      MNT_INTERNAL_FLAGS = MNT_SHARED | MNT_WRITE_HOLD | MNT_INTERNAL |
++                           MNT_DOOMED | MNT_SYNC_UMOUNT | MNT_MARKED,
++};
+ struct vfsmount {
+       struct dentry *mnt_root;        /* root of the mounted tree */
+-- 
+2.39.5
+
diff --git a/queue-6.15/fs-dax-fix-don-t-skip-locked-entries-when-scanning-e.patch b/queue-6.15/fs-dax-fix-don-t-skip-locked-entries-when-scanning-e.patch
new file mode 100644 (file)
index 0000000..5b01e0c
--- /dev/null
@@ -0,0 +1,118 @@
+From cf755cc20d10c68cc5b0e322d37b7f174572dfa3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 May 2025 14:37:49 +1000
+Subject: fs/dax: Fix "don't skip locked entries when scanning entries"
+
+From: Alistair Popple <apopple@nvidia.com>
+
+[ Upstream commit dd59137bfe70cf3646021b4721e430213b9c71bd ]
+
+Commit 6be3e21d25ca ("fs/dax: don't skip locked entries when scanning
+entries") introduced a new function, wait_entry_unlocked_exclusive(),
+which waits for the current entry to become unlocked without advancing
+the XArray iterator state.
+
+Waiting for the entry to become unlocked requires dropping the XArray
+lock. This requires calling xas_pause() prior to dropping the lock
+which leaves the xas in a suitable state for the next iteration. However
+this has the side-effect of advancing the xas state to the next index.
+Normally this isn't an issue because xas_for_each() contains code to
+detect this state and thus avoid advancing the index a second time on
+the next loop iteration.
+
+However both callers of and wait_entry_unlocked_exclusive() itself
+subsequently use the xas state to reload the entry. As xas_pause()
+updated the state to the next index this will cause the current entry
+which is being waited on to be skipped. This caused the following
+warning to fire intermittently when running xftest generic/068 on an XFS
+filesystem with FS DAX enabled:
+
+[   35.067397] ------------[ cut here ]------------
+[   35.068229] WARNING: CPU: 21 PID: 1640 at mm/truncate.c:89 truncate_folio_batch_exceptionals+0xd8/0x1e0
+[   35.069717] Modules linked in: nd_pmem dax_pmem nd_btt nd_e820 libnvdimm
+[   35.071006] CPU: 21 UID: 0 PID: 1640 Comm: fstest Not tainted 6.15.0-rc7+ #77 PREEMPT(voluntary)
+[   35.072613] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/204
+[   35.074845] RIP: 0010:truncate_folio_batch_exceptionals+0xd8/0x1e0
+[   35.075962] Code: a1 00 00 00 f6 47 0d 20 0f 84 97 00 00 00 4c 63 e8 41 39 c4 7f 0b eb 61 49 83 c5 01 45 39 ec 7e 58 42 f68
+[   35.079522] RSP: 0018:ffffb04e426c7850 EFLAGS: 00010202
+[   35.080359] RAX: 0000000000000000 RBX: ffff9d21e3481908 RCX: ffffb04e426c77f4
+[   35.081477] RDX: ffffb04e426c79e8 RSI: ffffb04e426c79e0 RDI: ffff9d21e34816e8
+[   35.082590] RBP: ffffb04e426c79e0 R08: 0000000000000001 R09: 0000000000000003
+[   35.083733] R10: 0000000000000000 R11: 822b53c0f7a49868 R12: 000000000000001f
+[   35.084850] R13: 0000000000000000 R14: ffffb04e426c78e8 R15: fffffffffffffffe
+[   35.085953] FS:  00007f9134c87740(0000) GS:ffff9d22abba0000(0000) knlGS:0000000000000000
+[   35.087346] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[   35.088244] CR2: 00007f9134c86000 CR3: 000000040afff000 CR4: 00000000000006f0
+[   35.089354] Call Trace:
+[   35.089749]  <TASK>
+[   35.090168]  truncate_inode_pages_range+0xfc/0x4d0
+[   35.091078]  truncate_pagecache+0x47/0x60
+[   35.091735]  xfs_setattr_size+0xc7/0x3e0
+[   35.092648]  xfs_vn_setattr+0x1ea/0x270
+[   35.093437]  notify_change+0x1f4/0x510
+[   35.094219]  ? do_truncate+0x97/0xe0
+[   35.094879]  do_truncate+0x97/0xe0
+[   35.095640]  path_openat+0xabd/0xca0
+[   35.096278]  do_filp_open+0xd7/0x190
+[   35.096860]  do_sys_openat2+0x8a/0xe0
+[   35.097459]  __x64_sys_openat+0x6d/0xa0
+[   35.098076]  do_syscall_64+0xbb/0x1d0
+[   35.098647]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
+[   35.099444] RIP: 0033:0x7f9134d81fc1
+[   35.100033] Code: 75 57 89 f0 25 00 00 41 00 3d 00 00 41 00 74 49 80 3d 2a 26 0e 00 00 74 6d 89 da 48 89 ee bf 9c ff ff ff5
+[   35.102993] RSP: 002b:00007ffcd41e0d10 EFLAGS: 00000202 ORIG_RAX: 0000000000000101
+[   35.104263] RAX: ffffffffffffffda RBX: 0000000000000242 RCX: 00007f9134d81fc1
+[   35.105452] RDX: 0000000000000242 RSI: 00007ffcd41e1200 RDI: 00000000ffffff9c
+[   35.106663] RBP: 00007ffcd41e1200 R08: 0000000000000000 R09: 0000000000000064
+[   35.107923] R10: 00000000000001a4 R11: 0000000000000202 R12: 0000000000000066
+[   35.109112] R13: 0000000000100000 R14: 0000000000100000 R15: 0000000000000400
+[   35.110357]  </TASK>
+[   35.110769] irq event stamp: 8415587
+[   35.111486] hardirqs last  enabled at (8415599): [<ffffffff8d74b562>] __up_console_sem+0x52/0x60
+[   35.113067] hardirqs last disabled at (8415610): [<ffffffff8d74b547>] __up_console_sem+0x37/0x60
+[   35.114575] softirqs last  enabled at (8415300): [<ffffffff8d6ac625>] handle_softirqs+0x315/0x3f0
+[   35.115933] softirqs last disabled at (8415291): [<ffffffff8d6ac811>] __irq_exit_rcu+0xa1/0xc0
+[   35.117316] ---[ end trace 0000000000000000 ]---
+
+Fix this by using xas_reset() instead, which is equivalent in
+implementation to xas_pause() but does not advance the XArray state.
+
+Fixes: 6be3e21d25ca ("fs/dax: don't skip locked entries when scanning entries")
+Signed-off-by: Alistair Popple <apopple@nvidia.com>
+Link: https://lore.kernel.org/20250523043749.1460780-1-apopple@nvidia.com
+Reviewed-by: Dan Williams <dan.j.williams@intel.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Cc: Dan Williams <dan.j.williams@intel.com>
+Cc: Alison Schofield <alison.schofield@intel.com>
+Cc: "Matthew Wilcow (Oracle)" <willy@infradead.org>
+Cc: Balbir Singh <balbirs@nvidia.com>
+Cc: "Darrick J. Wong" <djwong@kernel.org>
+Cc: Dave Chinner <david@fromorbit.com>
+Cc: David Hildenbrand <david@redhat.com>
+Cc: Jan Kara <jack@suse.cz>
+Cc: John Hubbard <jhubbard@nvidia.com>
+Cc: Ted Ts'o <tytso@mit.edu>
+Cc: Alexander Viro <viro@zeniv.linux.org.uk>
+Cc: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/dax.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/dax.c b/fs/dax.c
+index 676303419e9e8..f8d8b1afd2324 100644
+--- a/fs/dax.c
++++ b/fs/dax.c
+@@ -257,7 +257,7 @@ static void *wait_entry_unlocked_exclusive(struct xa_state *xas, void *entry)
+               wq = dax_entry_waitqueue(xas, entry, &ewait.key);
+               prepare_to_wait_exclusive(wq, &ewait.wait,
+                                       TASK_UNINTERRUPTIBLE);
+-              xas_pause(xas);
++              xas_reset(xas);
+               xas_unlock_irq(xas);
+               schedule();
+               finish_wait(wq, &ewait.wait);
+-- 
+2.39.5
+
diff --git a/queue-6.15/fs-fhandle.c-fix-a-race-in-call-of-has_locked_childr.patch b/queue-6.15/fs-fhandle.c-fix-a-race-in-call-of-has_locked_childr.patch
new file mode 100644 (file)
index 0000000..fef9f86
--- /dev/null
@@ -0,0 +1,90 @@
+From 9014b42cd47f3602ebcf175f5f3083d6e84ad235 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 1 Jun 2025 14:23:52 -0400
+Subject: fs/fhandle.c: fix a race in call of has_locked_children()
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+[ Upstream commit 1f282cdc1d219c4a557f7009e81bc792820d9d9a ]
+
+may_decode_fh() is calling has_locked_children() while holding no locks.
+That's an oopsable race...
+
+The rest of the callers are safe since they are holding namespace_sem and
+are guaranteed a positive refcount on the mount in question.
+
+Rename the current has_locked_children() to __has_locked_children(), make
+it static and switch the fs/namespace.c users to it.
+
+Make has_locked_children() a wrapper for __has_locked_children(), calling
+the latter under read_seqlock_excl(&mount_lock).
+
+Reviewed-by: Christian Brauner <brauner@kernel.org>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Fixes: 620c266f3949 ("fhandle: relax open_by_handle_at() permission checks")
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/namespace.c | 18 ++++++++++++++----
+ 1 file changed, 14 insertions(+), 4 deletions(-)
+
+diff --git a/fs/namespace.c b/fs/namespace.c
+index 1b466c54a357d..216807f772cd2 100644
+--- a/fs/namespace.c
++++ b/fs/namespace.c
+@@ -2424,7 +2424,7 @@ void drop_collected_mounts(struct vfsmount *mnt)
+       namespace_unlock();
+ }
+-bool has_locked_children(struct mount *mnt, struct dentry *dentry)
++static bool __has_locked_children(struct mount *mnt, struct dentry *dentry)
+ {
+       struct mount *child;
+@@ -2438,6 +2438,16 @@ bool has_locked_children(struct mount *mnt, struct dentry *dentry)
+       return false;
+ }
++bool has_locked_children(struct mount *mnt, struct dentry *dentry)
++{
++      bool res;
++
++      read_seqlock_excl(&mount_lock);
++      res = __has_locked_children(mnt, dentry);
++      read_sequnlock_excl(&mount_lock);
++      return res;
++}
++
+ /*
+  * Check that there aren't references to earlier/same mount namespaces in the
+  * specified subtree.  Such references can act as pins for mount namespaces
+@@ -2498,7 +2508,7 @@ struct vfsmount *clone_private_mount(const struct path *path)
+                       return ERR_PTR(-EINVAL);
+       }
+-      if (has_locked_children(old_mnt, path->dentry))
++      if (__has_locked_children(old_mnt, path->dentry))
+               return ERR_PTR(-EINVAL);
+       new_mnt = clone_mnt(old_mnt, path->dentry, CL_PRIVATE);
+@@ -3035,7 +3045,7 @@ static struct mount *__do_loopback(struct path *old_path, int recurse)
+       if (!may_copy_tree(old_path))
+               return mnt;
+-      if (!recurse && has_locked_children(old, old_path->dentry))
++      if (!recurse && __has_locked_children(old, old_path->dentry))
+               return mnt;
+       if (recurse)
+@@ -3428,7 +3438,7 @@ static int do_set_group(struct path *from_path, struct path *to_path)
+               goto out;
+       /* From mount should not have locked children in place of To's root */
+-      if (has_locked_children(from, to->mnt.mnt_root))
++      if (__has_locked_children(from, to->mnt.mnt_root))
+               goto out;
+       /* Setting sharing groups is only allowed on private mounts */
+-- 
+2.39.5
+
diff --git a/queue-6.15/fs-ntfs3-add-missing-direct_io-in-ntfs_aops_cmpr.patch b/queue-6.15/fs-ntfs3-add-missing-direct_io-in-ntfs_aops_cmpr.patch
new file mode 100644 (file)
index 0000000..845da1a
--- /dev/null
@@ -0,0 +1,47 @@
+From b865bfe20c1efa82c61af9a36e5c7051c412dd92 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Apr 2025 17:26:37 +0800
+Subject: fs/ntfs3: Add missing direct_IO in ntfs_aops_cmpr
+
+From: Lizhi Xu <lizhi.xu@windriver.com>
+
+[ Upstream commit 8b26c8c376b29cf29710fbfd093df194cefe26ad ]
+
+The ntfs3 can use the page cache directly, so its address_space_operations
+need direct_IO. Exit ntfs_direct_IO() if it is a compressed file.
+
+Fixes: b432163ebd15 ("fs/ntfs3: Update inode->i_mapping->a_ops on compression state")
+Reported-by: syzbot+e36cc3297bd3afd25e19@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=e36cc3297bd3afd25e19
+Signed-off-by: Lizhi Xu <lizhi.xu@windriver.com>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/inode.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c
+index 3e2957a1e3605..0f0d27d4644a9 100644
+--- a/fs/ntfs3/inode.c
++++ b/fs/ntfs3/inode.c
+@@ -805,6 +805,10 @@ static ssize_t ntfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
+               ret = 0;
+               goto out;
+       }
++      if (is_compressed(ni)) {
++              ret = 0;
++              goto out;
++      }
+       ret = blockdev_direct_IO(iocb, inode, iter,
+                                wr ? ntfs_get_block_direct_IO_W :
+@@ -2068,5 +2072,6 @@ const struct address_space_operations ntfs_aops_cmpr = {
+       .read_folio     = ntfs_read_folio,
+       .readahead      = ntfs_readahead,
+       .dirty_folio    = block_dirty_folio,
++      .direct_IO      = ntfs_direct_IO,
+ };
+ // clang-format on
+-- 
+2.39.5
+
diff --git a/queue-6.15/fs-ntfs3-handle-hdr_first_de-return-value.patch b/queue-6.15/fs-ntfs3-handle-hdr_first_de-return-value.patch
new file mode 100644 (file)
index 0000000..e395254
--- /dev/null
@@ -0,0 +1,56 @@
+From f7210118378f95488e9cea28707c401c7a4acfa3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Mar 2025 13:42:18 +0000
+Subject: fs/ntfs3: handle hdr_first_de() return value
+
+From: Andrey Vatoropin <a.vatoropin@crpt.ru>
+
+[ Upstream commit af5cab0e5b6f8edb0be51a9f47f3f620e0b4fd70 ]
+
+The hdr_first_de() function returns a pointer to a struct NTFS_DE. This
+pointer may be NULL. To handle the NULL error effectively, it is important
+to implement an error handler. This will help manage potential errors
+consistently.
+
+Additionally, error handling for the return value already exists at other
+points where this function is called.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: 82cae269cfa9 ("fs/ntfs3: Add initialization of super block")
+Signed-off-by: Andrey Vatoropin <a.vatoropin@crpt.ru>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/index.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/fs/ntfs3/index.c b/fs/ntfs3/index.c
+index 78d20e4baa2c9..1bf2a6593dec6 100644
+--- a/fs/ntfs3/index.c
++++ b/fs/ntfs3/index.c
+@@ -2182,6 +2182,10 @@ static int indx_get_entry_to_replace(struct ntfs_index *indx,
+               e = hdr_first_de(&n->index->ihdr);
+               fnd_push(fnd, n, e);
++              if (!e) {
++                      err = -EINVAL;
++                      goto out;
++              }
+               if (!de_is_last(e)) {
+                       /*
+@@ -2203,6 +2207,10 @@ static int indx_get_entry_to_replace(struct ntfs_index *indx,
+       n = fnd->nodes[level];
+       te = hdr_first_de(&n->index->ihdr);
++      if (!te) {
++              err = -EINVAL;
++              goto out;
++      }
+       /* Copy the candidate entry into the replacement entry buffer. */
+       re = kmalloc(le16_to_cpu(te->size) + sizeof(u64), GFP_NOFS);
+       if (!re) {
+-- 
+2.39.5
+
diff --git a/queue-6.15/genksyms-fix-enum-consts-from-a-reference-affecting-.patch b/queue-6.15/genksyms-fix-enum-consts-from-a-reference-affecting-.patch
new file mode 100644 (file)
index 0000000..abf0e28
--- /dev/null
@@ -0,0 +1,111 @@
+From b248ff036bfd802496cd170d52b9e314570d5491 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Jun 2025 15:02:09 +0200
+Subject: genksyms: Fix enum consts from a reference affecting new values
+
+From: Petr Pavlu <petr.pavlu@suse.com>
+
+[ Upstream commit c50a04f8f45c7f13972f9097622d1d929033ea8c ]
+
+Enumeration constants read from a symbol reference file can incorrectly
+affect new enumeration constants parsed from an actual input file.
+
+Example:
+
+ $ cat test.c
+ enum { E_A, E_B, E_MAX };
+ struct bar { int mem[E_MAX]; };
+ int foo(struct bar *a) {}
+ __GENKSYMS_EXPORT_SYMBOL(foo);
+
+ $ cat test.c | ./scripts/genksyms/genksyms -T test.0.symtypes
+ #SYMVER foo 0x070d854d
+
+ $ cat test.0.symtypes
+ E#E_MAX 2
+ s#bar struct bar { int mem [ E#E_MAX ] ; }
+ foo int foo ( s#bar * )
+
+ $ cat test.c | ./scripts/genksyms/genksyms -T test.1.symtypes -r test.0.symtypes
+ <stdin>:4: warning: foo: modversion changed because of changes in enum constant E_MAX
+ #SYMVER foo 0x9c9dfd81
+
+ $ cat test.1.symtypes
+ E#E_MAX ( 2 ) + 3
+ s#bar struct bar { int mem [ E#E_MAX ] ; }
+ foo int foo ( s#bar * )
+
+The __add_symbol() function includes logic to handle the incrementation of
+enumeration values, but this code is also invoked when reading a reference
+file. As a result, the variables last_enum_expr and enum_counter might be
+incorrectly set after reading the reference file, which later affects
+parsing of the actual input.
+
+Fix the problem by splitting the logic for the incrementation of
+enumeration values into a separate function process_enum() and call it from
+__add_symbol() only when processing non-reference data.
+
+Fixes: e37ddb825003 ("genksyms: Track changes to enum constants")
+Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/genksyms/genksyms.c | 27 ++++++++++++++++++++-------
+ 1 file changed, 20 insertions(+), 7 deletions(-)
+
+diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c
+index 8b0d7ac73dbb0..83e48670c2fcf 100644
+--- a/scripts/genksyms/genksyms.c
++++ b/scripts/genksyms/genksyms.c
+@@ -181,13 +181,9 @@ static int is_unknown_symbol(struct symbol *sym)
+                       strcmp(defn->string, "{") == 0);
+ }
+-static struct symbol *__add_symbol(const char *name, enum symbol_type type,
+-                          struct string_list *defn, int is_extern,
+-                          int is_reference)
++static struct string_list *process_enum(const char *name, enum symbol_type type,
++                                      struct string_list *defn)
+ {
+-      unsigned long h;
+-      struct symbol *sym;
+-      enum symbol_status status = STATUS_UNCHANGED;
+       /* The parser adds symbols in the order their declaration completes,
+        * so it is safe to store the value of the previous enum constant in
+        * a static variable.
+@@ -216,7 +212,7 @@ static struct symbol *__add_symbol(const char *name, enum symbol_type type,
+                               defn = mk_node(buf);
+                       }
+               }
+-      } else if (type == SYM_ENUM) {
++      } else {
+               free_list(last_enum_expr, NULL);
+               last_enum_expr = NULL;
+               enum_counter = 0;
+@@ -225,6 +221,23 @@ static struct symbol *__add_symbol(const char *name, enum symbol_type type,
+                       return NULL;
+       }
++      return defn;
++}
++
++static struct symbol *__add_symbol(const char *name, enum symbol_type type,
++                          struct string_list *defn, int is_extern,
++                          int is_reference)
++{
++      unsigned long h;
++      struct symbol *sym;
++      enum symbol_status status = STATUS_UNCHANGED;
++
++      if ((type == SYM_ENUM_CONST || type == SYM_ENUM) && !is_reference) {
++              defn = process_enum(name, type, defn);
++              if (defn == NULL)
++                      return NULL;
++      }
++
+       h = crc32(name);
+       hash_for_each_possible(symbol_hashtable, sym, hnode, h) {
+               if (map_to_ns(sym->type) != map_to_ns(type) ||
+-- 
+2.39.5
+
diff --git a/queue-6.15/gfs2-deallocate-inodes-in-gfs2_create_inode.patch b/queue-6.15/gfs2-deallocate-inodes-in-gfs2_create_inode.patch
new file mode 100644 (file)
index 0000000..9b009a5
--- /dev/null
@@ -0,0 +1,143 @@
+From 7feab78b21c40ee08ab5a04b261633280a492b0b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Apr 2025 16:41:52 +0200
+Subject: gfs2: deallocate inodes in gfs2_create_inode
+
+From: Andreas Gruenbacher <agruenba@redhat.com>
+
+[ Upstream commit 2c63986dd35fa9eb0d7d1530b5eb2244b7296e22 ]
+
+When creating and destroying inodes, we are relying on the inode hash
+table to make sure that for a given inode number, only a single inode
+will exist.  We then link that inode to its inode and iopen glock and
+let those glocks point back at the inode.  However, when iget_failed()
+is called, the inode is removed from the inode hash table before
+gfs_evict_inode() is called, and uniqueness is no longer guaranteed.
+
+Commit f1046a472b70 ("gfs2: gl_object races fix") was trying to work
+around that problem by detaching the inode glock from the inode before
+calling iget_failed(), but that broke the inode deallocation code in
+gfs_evict_inode().
+
+To fix that, deallocate partially created inodes in gfs2_create_inode()
+instead of relying on gfs_evict_inode() for doing that.
+
+This means that gfs2_evict_inode() and its helper functions will no
+longer see partially created inodes, and so some simplifications are
+possible there.
+
+Fixes: 9ffa18884cce ("gfs2: gl_object races fix")
+Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/gfs2/inode.c | 27 +++++++++++++++++++--------
+ fs/gfs2/super.c |  6 +-----
+ 2 files changed, 20 insertions(+), 13 deletions(-)
+
+diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
+index b2d38d09af7e8..8fd81444ffea0 100644
+--- a/fs/gfs2/inode.c
++++ b/fs/gfs2/inode.c
+@@ -697,10 +697,11 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
+       struct gfs2_inode *dip = GFS2_I(dir), *ip;
+       struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
+       struct gfs2_glock *io_gl;
+-      int error;
++      int error, dealloc_error;
+       u32 aflags = 0;
+       unsigned blocks = 1;
+       struct gfs2_diradd da = { .bh = NULL, .save_loc = 1, };
++      bool xattr_initialized = false;
+       if (!name->len || name->len > GFS2_FNAMESIZE)
+               return -ENAMETOOLONG;
+@@ -813,11 +814,11 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
+       error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl);
+       if (error)
+-              goto fail_free_inode;
++              goto fail_dealloc_inode;
+       error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_iopen_glops, CREATE, &io_gl);
+       if (error)
+-              goto fail_free_inode;
++              goto fail_dealloc_inode;
+       gfs2_cancel_delete_work(io_gl);
+       io_gl->gl_no_formal_ino = ip->i_no_formal_ino;
+@@ -841,8 +842,10 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
+       if (error)
+               goto fail_gunlock3;
+-      if (blocks > 1)
++      if (blocks > 1) {
+               gfs2_init_xattr(ip);
++              xattr_initialized = true;
++      }
+       init_dinode(dip, ip, symname);
+       gfs2_trans_end(sdp);
+@@ -897,6 +900,18 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
+       gfs2_glock_dq_uninit(&ip->i_iopen_gh);
+ fail_gunlock2:
+       gfs2_glock_put(io_gl);
++fail_dealloc_inode:
++      set_bit(GIF_ALLOC_FAILED, &ip->i_flags);
++      dealloc_error = 0;
++      if (ip->i_eattr)
++              dealloc_error = gfs2_ea_dealloc(ip, xattr_initialized);
++      clear_nlink(inode);
++      mark_inode_dirty(inode);
++      if (!dealloc_error)
++              dealloc_error = gfs2_dinode_dealloc(ip);
++      if (dealloc_error)
++              fs_warn(sdp, "%s: %d\n", __func__, dealloc_error);
++      ip->i_no_addr = 0;
+ fail_free_inode:
+       if (ip->i_gl) {
+               gfs2_glock_put(ip->i_gl);
+@@ -911,10 +926,6 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
+       gfs2_dir_no_add(&da);
+       gfs2_glock_dq_uninit(&d_gh);
+       if (!IS_ERR_OR_NULL(inode)) {
+-              set_bit(GIF_ALLOC_FAILED, &ip->i_flags);
+-              clear_nlink(inode);
+-              if (ip->i_no_addr)
+-                      mark_inode_dirty(inode);
+               if (inode->i_state & I_NEW)
+                       iget_failed(inode);
+               else
+diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
+index e25a24ae2197f..54f1efd47a3e5 100644
+--- a/fs/gfs2/super.c
++++ b/fs/gfs2/super.c
+@@ -1258,9 +1258,6 @@ static enum evict_behavior evict_should_delete(struct inode *inode,
+       struct gfs2_sbd *sdp = sb->s_fs_info;
+       int ret;
+-      if (unlikely(test_bit(GIF_ALLOC_FAILED, &ip->i_flags)))
+-              goto should_delete;
+-
+       if (gfs2_holder_initialized(&ip->i_iopen_gh) &&
+           test_bit(GLF_DEFER_DELETE, &ip->i_iopen_gh.gh_gl->gl_flags))
+               return EVICT_SHOULD_DEFER_DELETE;
+@@ -1290,7 +1287,6 @@ static enum evict_behavior evict_should_delete(struct inode *inode,
+       if (inode->i_nlink)
+               return EVICT_SHOULD_SKIP_DELETE;
+-should_delete:
+       if (gfs2_holder_initialized(&ip->i_iopen_gh) &&
+           test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags))
+               return gfs2_upgrade_iopen_glock(inode);
+@@ -1314,7 +1310,7 @@ static int evict_unlinked_inode(struct inode *inode)
+       }
+       if (ip->i_eattr) {
+-              ret = gfs2_ea_dealloc(ip, !test_bit(GIF_ALLOC_FAILED, &ip->i_flags));
++              ret = gfs2_ea_dealloc(ip, true);
+               if (ret)
+                       goto out;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/gfs2-don-t-start-unnecessary-transactions-during-log.patch b/queue-6.15/gfs2-don-t-start-unnecessary-transactions-during-log.patch
new file mode 100644 (file)
index 0000000..5f8f472
--- /dev/null
@@ -0,0 +1,110 @@
+From 633cf0112364087740eb07c55ac2a2ae7038deee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Mar 2025 22:47:02 +0100
+Subject: gfs2: Don't start unnecessary transactions during log flush
+
+From: Andreas Gruenbacher <agruenba@redhat.com>
+
+[ Upstream commit 5a90f8d499225512a385585ffe3e28f687263d47 ]
+
+Commit 8d391972ae2d ("gfs2: Remove __gfs2_writepage()") changed the log
+flush code in gfs2_ail1_start_one() to call aops->writepages() instead
+of aops->writepage().  For jdata inodes, this means that we will now try
+to reserve log space and start a transaction before we can determine
+that the pages in question have already been journaled.  When this
+happens in the context of gfs2_logd(), it can now appear that not enough
+log space is available for freeing up log space, and we will lock up.
+
+Fix that by issuing journal writes directly instead of going through
+aops->writepages() in the log flush code.
+
+Fixes: 8d391972ae2d ("gfs2: Remove __gfs2_writepage()")
+Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/gfs2/aops.c | 31 +++++++++++++++++++++++++++++++
+ fs/gfs2/aops.h |  1 +
+ fs/gfs2/log.c  |  7 ++++++-
+ 3 files changed, 38 insertions(+), 1 deletion(-)
+
+diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
+index ed2c708a215a4..eb4270e82ef8e 100644
+--- a/fs/gfs2/aops.c
++++ b/fs/gfs2/aops.c
+@@ -117,6 +117,37 @@ static int __gfs2_jdata_write_folio(struct folio *folio,
+       return gfs2_write_jdata_folio(folio, wbc);
+ }
++/**
++ * gfs2_jdata_writeback - Write jdata folios to the log
++ * @mapping: The mapping to write
++ * @wbc: The writeback control
++ *
++ * Returns: errno
++ */
++int gfs2_jdata_writeback(struct address_space *mapping, struct writeback_control *wbc)
++{
++      struct inode *inode = mapping->host;
++      struct gfs2_inode *ip = GFS2_I(inode);
++      struct gfs2_sbd *sdp = GFS2_SB(mapping->host);
++      struct folio *folio = NULL;
++      int error;
++
++      BUG_ON(current->journal_info);
++      if (gfs2_assert_withdraw(sdp, ip->i_gl->gl_state == LM_ST_EXCLUSIVE))
++              return 0;
++
++      while ((folio = writeback_iter(mapping, wbc, folio, &error))) {
++              if (folio_test_checked(folio)) {
++                      folio_redirty_for_writepage(wbc, folio);
++                      folio_unlock(folio);
++                      continue;
++              }
++              error = __gfs2_jdata_write_folio(folio, wbc);
++      }
++
++      return error;
++}
++
+ /**
+  * gfs2_writepages - Write a bunch of dirty pages back to disk
+  * @mapping: The mapping to write
+diff --git a/fs/gfs2/aops.h b/fs/gfs2/aops.h
+index f9fa41aaeaf41..bf002522a7822 100644
+--- a/fs/gfs2/aops.h
++++ b/fs/gfs2/aops.h
+@@ -9,5 +9,6 @@
+ #include "incore.h"
+ void adjust_fs_space(struct inode *inode);
++int gfs2_jdata_writeback(struct address_space *mapping, struct writeback_control *wbc);
+ #endif /* __AOPS_DOT_H__ */
+diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
+index f9c5089783d24..115c4ac457e90 100644
+--- a/fs/gfs2/log.c
++++ b/fs/gfs2/log.c
+@@ -31,6 +31,7 @@
+ #include "dir.h"
+ #include "trace_gfs2.h"
+ #include "trans.h"
++#include "aops.h"
+ static void gfs2_log_shutdown(struct gfs2_sbd *sdp);
+@@ -131,7 +132,11 @@ __acquires(&sdp->sd_ail_lock)
+               if (!mapping)
+                       continue;
+               spin_unlock(&sdp->sd_ail_lock);
+-              ret = mapping->a_ops->writepages(mapping, wbc);
++              BUG_ON(GFS2_SB(mapping->host) != sdp);
++              if (gfs2_is_jdata(GFS2_I(mapping->host)))
++                      ret = gfs2_jdata_writeback(mapping, wbc);
++              else
++                      ret = mapping->a_ops->writepages(mapping, wbc);
+               if (need_resched()) {
+                       blk_finish_plug(plug);
+                       cond_resched();
+-- 
+2.39.5
+
diff --git a/queue-6.15/gfs2-gfs2_create_inode-error-handling-fix.patch b/queue-6.15/gfs2-gfs2_create_inode-error-handling-fix.patch
new file mode 100644 (file)
index 0000000..be48284
--- /dev/null
@@ -0,0 +1,35 @@
+From 42013047d6cb49d78ee8165ac434431e23f90cea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Apr 2025 16:40:58 +0200
+Subject: gfs2: gfs2_create_inode error handling fix
+
+From: Andreas Gruenbacher <agruenba@redhat.com>
+
+[ Upstream commit af4044fd0b77e915736527dd83011e46e6415f01 ]
+
+When gfs2_create_inode() finds a directory, make sure to return -EISDIR.
+
+Fixes: 571a4b57975a ("GFS2: bugger off early if O_CREAT open finds a directory")
+Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/gfs2/inode.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
+index 198a8cbaf5e5a..9621680814b80 100644
+--- a/fs/gfs2/inode.c
++++ b/fs/gfs2/inode.c
+@@ -659,7 +659,8 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
+       if (!IS_ERR(inode)) {
+               if (S_ISDIR(inode->i_mode)) {
+                       iput(inode);
+-                      inode = ERR_PTR(-EISDIR);
++                      inode = NULL;
++                      error = -EISDIR;
+                       goto fail_gunlock;
+               }
+               d_instantiate(dentry, inode);
+-- 
+2.39.5
+
diff --git a/queue-6.15/gfs2-move-gfs2_dinode_dealloc.patch b/queue-6.15/gfs2-move-gfs2_dinode_dealloc.patch
new file mode 100644 (file)
index 0000000..9b0dec9
--- /dev/null
@@ -0,0 +1,194 @@
+From 2dd4ffcf6cff523c4292d2465d9cb60c7d069545 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Apr 2025 22:41:40 +0200
+Subject: gfs2: Move gfs2_dinode_dealloc
+
+From: Andreas Gruenbacher <agruenba@redhat.com>
+
+[ Upstream commit bcd18105fb34e27c097f222733dba9a3e79f191c ]
+
+Move gfs2_dinode_dealloc() and its helper gfs2_final_release_pages()
+from super.c to inode.c.
+
+Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
+Stable-dep-of: 2c63986dd35f ("gfs2: deallocate inodes in gfs2_create_inode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/gfs2/inode.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++
+ fs/gfs2/inode.h |  1 +
+ fs/gfs2/super.c | 68 -------------------------------------------------
+ 3 files changed, 69 insertions(+), 68 deletions(-)
+
+diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
+index 9621680814b80..b2d38d09af7e8 100644
+--- a/fs/gfs2/inode.c
++++ b/fs/gfs2/inode.c
+@@ -439,6 +439,74 @@ static int alloc_dinode(struct gfs2_inode *ip, u32 flags, unsigned *dblocks)
+       return error;
+ }
++static void gfs2_final_release_pages(struct gfs2_inode *ip)
++{
++      struct inode *inode = &ip->i_inode;
++      struct gfs2_glock *gl = ip->i_gl;
++
++      if (unlikely(!gl)) {
++              /* This can only happen during incomplete inode creation. */
++              BUG_ON(!test_bit(GIF_ALLOC_FAILED, &ip->i_flags));
++              return;
++      }
++
++      truncate_inode_pages(gfs2_glock2aspace(gl), 0);
++      truncate_inode_pages(&inode->i_data, 0);
++
++      if (atomic_read(&gl->gl_revokes) == 0) {
++              clear_bit(GLF_LFLUSH, &gl->gl_flags);
++              clear_bit(GLF_DIRTY, &gl->gl_flags);
++      }
++}
++
++int gfs2_dinode_dealloc(struct gfs2_inode *ip)
++{
++      struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
++      struct gfs2_rgrpd *rgd;
++      struct gfs2_holder gh;
++      int error;
++
++      if (gfs2_get_inode_blocks(&ip->i_inode) != 1) {
++              gfs2_consist_inode(ip);
++              return -EIO;
++      }
++
++      gfs2_rindex_update(sdp);
++
++      error = gfs2_quota_hold(ip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE);
++      if (error)
++              return error;
++
++      rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr, 1);
++      if (!rgd) {
++              gfs2_consist_inode(ip);
++              error = -EIO;
++              goto out_qs;
++      }
++
++      error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE,
++                                 LM_FLAG_NODE_SCOPE, &gh);
++      if (error)
++              goto out_qs;
++
++      error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_STATFS + RES_QUOTA,
++                               sdp->sd_jdesc->jd_blocks);
++      if (error)
++              goto out_rg_gunlock;
++
++      gfs2_free_di(rgd, ip);
++
++      gfs2_final_release_pages(ip);
++
++      gfs2_trans_end(sdp);
++
++out_rg_gunlock:
++      gfs2_glock_dq_uninit(&gh);
++out_qs:
++      gfs2_quota_unhold(ip);
++      return error;
++}
++
+ static void gfs2_init_dir(struct buffer_head *dibh,
+                         const struct gfs2_inode *parent)
+ {
+diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h
+index 9e5e1622d50a6..eafe123617e69 100644
+--- a/fs/gfs2/inode.h
++++ b/fs/gfs2/inode.h
+@@ -92,6 +92,7 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type,
+ struct inode *gfs2_lookup_by_inum(struct gfs2_sbd *sdp, u64 no_addr,
+                                 u64 no_formal_ino,
+                                 unsigned int blktype);
++int gfs2_dinode_dealloc(struct gfs2_inode *ip);
+ struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name,
+                          int is_root);
+diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
+index 4529b7dda8ca2..3f49f848c6b4e 100644
+--- a/fs/gfs2/super.c
++++ b/fs/gfs2/super.c
+@@ -1173,74 +1173,6 @@ static int gfs2_show_options(struct seq_file *s, struct dentry *root)
+       return 0;
+ }
+-static void gfs2_final_release_pages(struct gfs2_inode *ip)
+-{
+-      struct inode *inode = &ip->i_inode;
+-      struct gfs2_glock *gl = ip->i_gl;
+-
+-      if (unlikely(!gl)) {
+-              /* This can only happen during incomplete inode creation. */
+-              BUG_ON(!test_bit(GIF_ALLOC_FAILED, &ip->i_flags));
+-              return;
+-      }
+-
+-      truncate_inode_pages(gfs2_glock2aspace(gl), 0);
+-      truncate_inode_pages(&inode->i_data, 0);
+-
+-      if (atomic_read(&gl->gl_revokes) == 0) {
+-              clear_bit(GLF_LFLUSH, &gl->gl_flags);
+-              clear_bit(GLF_DIRTY, &gl->gl_flags);
+-      }
+-}
+-
+-static int gfs2_dinode_dealloc(struct gfs2_inode *ip)
+-{
+-      struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
+-      struct gfs2_rgrpd *rgd;
+-      struct gfs2_holder gh;
+-      int error;
+-
+-      if (gfs2_get_inode_blocks(&ip->i_inode) != 1) {
+-              gfs2_consist_inode(ip);
+-              return -EIO;
+-      }
+-
+-      gfs2_rindex_update(sdp);
+-
+-      error = gfs2_quota_hold(ip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE);
+-      if (error)
+-              return error;
+-
+-      rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr, 1);
+-      if (!rgd) {
+-              gfs2_consist_inode(ip);
+-              error = -EIO;
+-              goto out_qs;
+-      }
+-
+-      error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE,
+-                                 LM_FLAG_NODE_SCOPE, &gh);
+-      if (error)
+-              goto out_qs;
+-
+-      error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_STATFS + RES_QUOTA,
+-                               sdp->sd_jdesc->jd_blocks);
+-      if (error)
+-              goto out_rg_gunlock;
+-
+-      gfs2_free_di(rgd, ip);
+-
+-      gfs2_final_release_pages(ip);
+-
+-      gfs2_trans_end(sdp);
+-
+-out_rg_gunlock:
+-      gfs2_glock_dq_uninit(&gh);
+-out_qs:
+-      gfs2_quota_unhold(ip);
+-      return error;
+-}
+-
+ /**
+  * gfs2_glock_put_eventually
+  * @gl:       The glock to put
+-- 
+2.39.5
+
diff --git a/queue-6.15/gfs2-move-gfs2_trans_add_databufs.patch b/queue-6.15/gfs2-move-gfs2_trans_add_databufs.patch
new file mode 100644 (file)
index 0000000..da0a435
--- /dev/null
@@ -0,0 +1,138 @@
+From 249327515f25146606b524388b977d1849e6b9a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Mar 2025 22:21:08 +0100
+Subject: gfs2: Move gfs2_trans_add_databufs
+
+From: Andreas Gruenbacher <agruenba@redhat.com>
+
+[ Upstream commit d50a64e3c55e59e45e415c65531b0d76ad4cea36 ]
+
+Move gfs2_trans_add_databufs() to trans.c.  Pass in a glock instead of
+a gfs2_inode.
+
+Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
+Stable-dep-of: 5a90f8d49922 ("gfs2: Don't start unnecessary transactions during log flush")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/gfs2/aops.c  | 23 +----------------------
+ fs/gfs2/aops.h  |  2 --
+ fs/gfs2/bmap.c  |  3 ++-
+ fs/gfs2/trans.c | 21 +++++++++++++++++++++
+ fs/gfs2/trans.h |  2 ++
+ 5 files changed, 26 insertions(+), 25 deletions(-)
+
+diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
+index 68fc8af14700d..ed2c708a215a4 100644
+--- a/fs/gfs2/aops.c
++++ b/fs/gfs2/aops.c
+@@ -37,27 +37,6 @@
+ #include "aops.h"
+-void gfs2_trans_add_databufs(struct gfs2_inode *ip, struct folio *folio,
+-                           size_t from, size_t len)
+-{
+-      struct buffer_head *head = folio_buffers(folio);
+-      unsigned int bsize = head->b_size;
+-      struct buffer_head *bh;
+-      size_t to = from + len;
+-      size_t start, end;
+-
+-      for (bh = head, start = 0; bh != head || !start;
+-           bh = bh->b_this_page, start = end) {
+-              end = start + bsize;
+-              if (end <= from)
+-                      continue;
+-              if (start >= to)
+-                      break;
+-              set_buffer_uptodate(bh);
+-              gfs2_trans_add_data(ip->i_gl, bh);
+-      }
+-}
+-
+ /**
+  * gfs2_get_block_noalloc - Fills in a buffer head with details about a block
+  * @inode: The inode
+@@ -133,7 +112,7 @@ static int __gfs2_jdata_write_folio(struct folio *folio,
+                                       inode->i_sb->s_blocksize,
+                                       BIT(BH_Dirty)|BIT(BH_Uptodate));
+               }
+-              gfs2_trans_add_databufs(ip, folio, 0, folio_size(folio));
++              gfs2_trans_add_databufs(ip->i_gl, folio, 0, folio_size(folio));
+       }
+       return gfs2_write_jdata_folio(folio, wbc);
+ }
+diff --git a/fs/gfs2/aops.h b/fs/gfs2/aops.h
+index a10c4334d2489..f9fa41aaeaf41 100644
+--- a/fs/gfs2/aops.h
++++ b/fs/gfs2/aops.h
+@@ -9,7 +9,5 @@
+ #include "incore.h"
+ void adjust_fs_space(struct inode *inode);
+-void gfs2_trans_add_databufs(struct gfs2_inode *ip, struct folio *folio,
+-                           size_t from, size_t len);
+ #endif /* __AOPS_DOT_H__ */
+diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
+index 366516b98b3f3..b81984def58ec 100644
+--- a/fs/gfs2/bmap.c
++++ b/fs/gfs2/bmap.c
+@@ -988,7 +988,8 @@ static void gfs2_iomap_put_folio(struct inode *inode, loff_t pos,
+       struct gfs2_sbd *sdp = GFS2_SB(inode);
+       if (!gfs2_is_stuffed(ip))
+-              gfs2_trans_add_databufs(ip, folio, offset_in_folio(folio, pos),
++              gfs2_trans_add_databufs(ip->i_gl, folio,
++                                      offset_in_folio(folio, pos),
+                                       copied);
+       folio_unlock(folio);
+diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c
+index f8ae2c666fd60..075f7e9abe47c 100644
+--- a/fs/gfs2/trans.c
++++ b/fs/gfs2/trans.c
+@@ -226,6 +226,27 @@ void gfs2_trans_add_data(struct gfs2_glock *gl, struct buffer_head *bh)
+       unlock_buffer(bh);
+ }
++void gfs2_trans_add_databufs(struct gfs2_glock *gl, struct folio *folio,
++                           size_t from, size_t len)
++{
++      struct buffer_head *head = folio_buffers(folio);
++      unsigned int bsize = head->b_size;
++      struct buffer_head *bh;
++      size_t to = from + len;
++      size_t start, end;
++
++      for (bh = head, start = 0; bh != head || !start;
++           bh = bh->b_this_page, start = end) {
++              end = start + bsize;
++              if (end <= from)
++                      continue;
++              if (start >= to)
++                      break;
++              set_buffer_uptodate(bh);
++              gfs2_trans_add_data(gl, bh);
++      }
++}
++
+ void gfs2_trans_add_meta(struct gfs2_glock *gl, struct buffer_head *bh)
+ {
+diff --git a/fs/gfs2/trans.h b/fs/gfs2/trans.h
+index f8ce5302280d3..790c55f59e612 100644
+--- a/fs/gfs2/trans.h
++++ b/fs/gfs2/trans.h
+@@ -42,6 +42,8 @@ int gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int blocks,
+ void gfs2_trans_end(struct gfs2_sbd *sdp);
+ void gfs2_trans_add_data(struct gfs2_glock *gl, struct buffer_head *bh);
++void gfs2_trans_add_databufs(struct gfs2_glock *gl, struct folio *folio,
++                           size_t from, size_t len);
+ void gfs2_trans_add_meta(struct gfs2_glock *gl, struct buffer_head *bh);
+ void gfs2_trans_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd);
+ void gfs2_trans_remove_revoke(struct gfs2_sbd *sdp, u64 blkno, unsigned int len);
+-- 
+2.39.5
+
diff --git a/queue-6.15/gfs2-move-gif_alloc_failed-check-out-of-gfs2_ea_deal.patch b/queue-6.15/gfs2-move-gif_alloc_failed-check-out-of-gfs2_ea_deal.patch
new file mode 100644 (file)
index 0000000..f6364ad
--- /dev/null
@@ -0,0 +1,105 @@
+From 1259b68438ae92d7e0aecfe2975cdcf75623c678 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Apr 2025 01:09:32 +0200
+Subject: gfs2: Move GIF_ALLOC_FAILED check out of gfs2_ea_dealloc
+
+From: Andreas Gruenbacher <agruenba@redhat.com>
+
+[ Upstream commit 0cc617a54dfe6b44624c9a03e2e11a24eb9bc720 ]
+
+Don't check for the GIF_ALLOC_FAILED flag in gfs2_ea_dealloc() and pass
+that information explicitly instead.  This allows for a cleaner
+follow-up patch.
+
+Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
+Stable-dep-of: 2c63986dd35f ("gfs2: deallocate inodes in gfs2_create_inode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/gfs2/super.c |  2 +-
+ fs/gfs2/xattr.c | 11 ++++++-----
+ fs/gfs2/xattr.h |  2 +-
+ 3 files changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
+index 3f49f848c6b4e..e25a24ae2197f 100644
+--- a/fs/gfs2/super.c
++++ b/fs/gfs2/super.c
+@@ -1314,7 +1314,7 @@ static int evict_unlinked_inode(struct inode *inode)
+       }
+       if (ip->i_eattr) {
+-              ret = gfs2_ea_dealloc(ip);
++              ret = gfs2_ea_dealloc(ip, !test_bit(GIF_ALLOC_FAILED, &ip->i_flags));
+               if (ret)
+                       goto out;
+       }
+diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c
+index 17ae5070a90e6..df9c93de94c79 100644
+--- a/fs/gfs2/xattr.c
++++ b/fs/gfs2/xattr.c
+@@ -1383,7 +1383,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip)
+       return error;
+ }
+-static int ea_dealloc_block(struct gfs2_inode *ip)
++static int ea_dealloc_block(struct gfs2_inode *ip, bool initialized)
+ {
+       struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
+       struct gfs2_rgrpd *rgd;
+@@ -1416,7 +1416,7 @@ static int ea_dealloc_block(struct gfs2_inode *ip)
+       ip->i_eattr = 0;
+       gfs2_add_inode_blocks(&ip->i_inode, -1);
+-      if (likely(!test_bit(GIF_ALLOC_FAILED, &ip->i_flags))) {
++      if (initialized) {
+               error = gfs2_meta_inode_buffer(ip, &dibh);
+               if (!error) {
+                       gfs2_trans_add_meta(ip->i_gl, dibh);
+@@ -1435,11 +1435,12 @@ static int ea_dealloc_block(struct gfs2_inode *ip)
+ /**
+  * gfs2_ea_dealloc - deallocate the extended attribute fork
+  * @ip: the inode
++ * @initialized: xattrs have been initialized
+  *
+  * Returns: errno
+  */
+-int gfs2_ea_dealloc(struct gfs2_inode *ip)
++int gfs2_ea_dealloc(struct gfs2_inode *ip, bool initialized)
+ {
+       int error;
+@@ -1451,7 +1452,7 @@ int gfs2_ea_dealloc(struct gfs2_inode *ip)
+       if (error)
+               return error;
+-      if (likely(!test_bit(GIF_ALLOC_FAILED, &ip->i_flags))) {
++      if (initialized) {
+               error = ea_foreach(ip, ea_dealloc_unstuffed, NULL);
+               if (error)
+                       goto out_quota;
+@@ -1463,7 +1464,7 @@ int gfs2_ea_dealloc(struct gfs2_inode *ip)
+               }
+       }
+-      error = ea_dealloc_block(ip);
++      error = ea_dealloc_block(ip, initialized);
+ out_quota:
+       gfs2_quota_unhold(ip);
+diff --git a/fs/gfs2/xattr.h b/fs/gfs2/xattr.h
+index eb12eb7e37c19..3c9788e0e1375 100644
+--- a/fs/gfs2/xattr.h
++++ b/fs/gfs2/xattr.h
+@@ -54,7 +54,7 @@ int __gfs2_xattr_set(struct inode *inode, const char *name,
+                    const void *value, size_t size,
+                    int flags, int type);
+ ssize_t gfs2_listxattr(struct dentry *dentry, char *buffer, size_t size);
+-int gfs2_ea_dealloc(struct gfs2_inode *ip);
++int gfs2_ea_dealloc(struct gfs2_inode *ip, bool initialized);
+ /* Exported to acl.c */
+-- 
+2.39.5
+
diff --git a/queue-6.15/gfs2-replace-sd_aspace-with-sd_inode.patch b/queue-6.15/gfs2-replace-sd_aspace-with-sd_inode.patch
new file mode 100644 (file)
index 0000000..f8e28df
--- /dev/null
@@ -0,0 +1,237 @@
+From da1e6757be07b871d0ce6e64a82091ebd8660abd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 6 Apr 2025 00:31:37 +0200
+Subject: gfs2: replace sd_aspace with sd_inode
+
+From: Andreas Gruenbacher <agruenba@redhat.com>
+
+[ Upstream commit ae9f3bd8259a0a8f67be2420e66bb05fbb95af48 ]
+
+Currently, sdp->sd_aspace and the per-inode metadata address spaces use
+sb->s_bdev->bd_mapping->host as their ->host; folios in those address
+spaces will thus appear to be on bdev rather than on gfs2 filesystems.
+This is a problem because gfs2 doesn't support cgroup writeback
+(SB_I_CGROUPWB), but bdev does.
+
+Fix that by using a "dummy" gfs2 inode as ->host in those address
+spaces.  When coming from a folio, folio->mapping->host->i_sb will then
+be a gfs2 super block and the SB_I_CGROUPWB flag will not be set in
+sb->s_iflags.
+
+Based on a previous version from Bob Peterson from several years ago.
+Thanks to Tetsuo Handa, Jan Kara, and Rafael Aquini for helping figure
+this out.
+
+Fixes: aaa2cacf8184 ("writeback: add lockdep annotation to inode_to_wb()")
+Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/gfs2/glock.c      |  3 +--
+ fs/gfs2/glops.c      |  4 ++--
+ fs/gfs2/incore.h     |  9 ++++++++-
+ fs/gfs2/meta_io.c    |  2 +-
+ fs/gfs2/meta_io.h    |  4 +---
+ fs/gfs2/ops_fstype.c | 31 ++++++++++++++++++-------------
+ fs/gfs2/super.c      |  2 +-
+ 7 files changed, 32 insertions(+), 23 deletions(-)
+
+diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
+index d7220a6fe8f55..ba25b884169e5 100644
+--- a/fs/gfs2/glock.c
++++ b/fs/gfs2/glock.c
+@@ -1166,7 +1166,6 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
+                  const struct gfs2_glock_operations *glops, int create,
+                  struct gfs2_glock **glp)
+ {
+-      struct super_block *s = sdp->sd_vfs;
+       struct lm_lockname name = { .ln_number = number,
+                                   .ln_type = glops->go_type,
+                                   .ln_sbd = sdp };
+@@ -1229,7 +1228,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
+       mapping = gfs2_glock2aspace(gl);
+       if (mapping) {
+                 mapping->a_ops = &gfs2_meta_aops;
+-              mapping->host = s->s_bdev->bd_mapping->host;
++              mapping->host = sdp->sd_inode;
+               mapping->flags = 0;
+               mapping_set_gfp_mask(mapping, GFP_NOFS);
+               mapping->i_private_data = NULL;
+diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
+index eb4714f299efb..116efe335c321 100644
+--- a/fs/gfs2/glops.c
++++ b/fs/gfs2/glops.c
+@@ -168,7 +168,7 @@ void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync)
+ static int gfs2_rgrp_metasync(struct gfs2_glock *gl)
+ {
+       struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
+-      struct address_space *metamapping = &sdp->sd_aspace;
++      struct address_space *metamapping = gfs2_aspace(sdp);
+       struct gfs2_rgrpd *rgd = gfs2_glock2rgrp(gl);
+       const unsigned bsize = sdp->sd_sb.sb_bsize;
+       loff_t start = (rgd->rd_addr * bsize) & PAGE_MASK;
+@@ -225,7 +225,7 @@ static int rgrp_go_sync(struct gfs2_glock *gl)
+ static void rgrp_go_inval(struct gfs2_glock *gl, int flags)
+ {
+       struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
+-      struct address_space *mapping = &sdp->sd_aspace;
++      struct address_space *mapping = gfs2_aspace(sdp);
+       struct gfs2_rgrpd *rgd = gfs2_glock2rgrp(gl);
+       const unsigned bsize = sdp->sd_sb.sb_bsize;
+       loff_t start, end;
+diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
+index 74abbd4970f80..0a41c4e76b326 100644
+--- a/fs/gfs2/incore.h
++++ b/fs/gfs2/incore.h
+@@ -795,7 +795,7 @@ struct gfs2_sbd {
+       /* Log stuff */
+-      struct address_space sd_aspace;
++      struct inode *sd_inode;
+       spinlock_t sd_log_lock;
+@@ -851,6 +851,13 @@ struct gfs2_sbd {
+       unsigned long sd_glock_dqs_held;
+ };
++#define GFS2_BAD_INO 1
++
++static inline struct address_space *gfs2_aspace(struct gfs2_sbd *sdp)
++{
++      return sdp->sd_inode->i_mapping;
++}
++
+ static inline void gfs2_glstats_inc(struct gfs2_glock *gl, int which)
+ {
+       gl->gl_stats.stats[which]++;
+diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c
+index 198cc70566375..9dc8885c95d07 100644
+--- a/fs/gfs2/meta_io.c
++++ b/fs/gfs2/meta_io.c
+@@ -132,7 +132,7 @@ struct buffer_head *gfs2_getbuf(struct gfs2_glock *gl, u64 blkno, int create)
+       unsigned int bufnum;
+       if (mapping == NULL)
+-              mapping = &sdp->sd_aspace;
++              mapping = gfs2_aspace(sdp);
+       shift = PAGE_SHIFT - sdp->sd_sb.sb_bsize_shift;
+       index = blkno >> shift;             /* convert block to page */
+diff --git a/fs/gfs2/meta_io.h b/fs/gfs2/meta_io.h
+index 831d988c2ceb7..b7c8a6684d024 100644
+--- a/fs/gfs2/meta_io.h
++++ b/fs/gfs2/meta_io.h
+@@ -44,9 +44,7 @@ static inline struct gfs2_sbd *gfs2_mapping2sbd(struct address_space *mapping)
+               struct gfs2_glock_aspace *gla =
+                       container_of(mapping, struct gfs2_glock_aspace, mapping);
+               return gla->glock.gl_name.ln_sbd;
+-      } else if (mapping->a_ops == &gfs2_rgrp_aops)
+-              return container_of(mapping, struct gfs2_sbd, sd_aspace);
+-      else
++      } else
+               return inode->i_sb->s_fs_info;
+ }
+diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
+index e83d293c36142..6ce475e1c6d64 100644
+--- a/fs/gfs2/ops_fstype.c
++++ b/fs/gfs2/ops_fstype.c
+@@ -72,7 +72,6 @@ void free_sbd(struct gfs2_sbd *sdp)
+ static struct gfs2_sbd *init_sbd(struct super_block *sb)
+ {
+       struct gfs2_sbd *sdp;
+-      struct address_space *mapping;
+       sdp = kzalloc(sizeof(struct gfs2_sbd), GFP_KERNEL);
+       if (!sdp)
+@@ -109,16 +108,6 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
+       INIT_LIST_HEAD(&sdp->sd_sc_inodes_list);
+-      mapping = &sdp->sd_aspace;
+-
+-      address_space_init_once(mapping);
+-      mapping->a_ops = &gfs2_rgrp_aops;
+-      mapping->host = sb->s_bdev->bd_mapping->host;
+-      mapping->flags = 0;
+-      mapping_set_gfp_mask(mapping, GFP_NOFS);
+-      mapping->i_private_data = NULL;
+-      mapping->writeback_index = 0;
+-
+       spin_lock_init(&sdp->sd_log_lock);
+       atomic_set(&sdp->sd_log_pinned, 0);
+       INIT_LIST_HEAD(&sdp->sd_log_revokes);
+@@ -1135,6 +1124,7 @@ static int gfs2_fill_super(struct super_block *sb, struct fs_context *fc)
+       int silent = fc->sb_flags & SB_SILENT;
+       struct gfs2_sbd *sdp;
+       struct gfs2_holder mount_gh;
++      struct address_space *mapping;
+       int error;
+       sdp = init_sbd(sb);
+@@ -1156,6 +1146,7 @@ static int gfs2_fill_super(struct super_block *sb, struct fs_context *fc)
+       sb->s_flags |= SB_NOSEC;
+       sb->s_magic = GFS2_MAGIC;
+       sb->s_op = &gfs2_super_ops;
++
+       sb->s_d_op = &gfs2_dops;
+       sb->s_export_op = &gfs2_export_ops;
+       sb->s_qcop = &gfs2_quotactl_ops;
+@@ -1181,9 +1172,21 @@ static int gfs2_fill_super(struct super_block *sb, struct fs_context *fc)
+               sdp->sd_tune.gt_statfs_quantum = 30;
+       }
++      /* Set up an address space for metadata writes */
++      sdp->sd_inode = new_inode(sb);
++      error = -ENOMEM;
++      if (!sdp->sd_inode)
++              goto fail_free;
++      sdp->sd_inode->i_ino = GFS2_BAD_INO;
++      sdp->sd_inode->i_size = OFFSET_MAX;
++
++      mapping = gfs2_aspace(sdp);
++      mapping->a_ops = &gfs2_rgrp_aops;
++      mapping_set_gfp_mask(mapping, GFP_NOFS);
++
+       error = init_names(sdp, silent);
+       if (error)
+-              goto fail_free;
++              goto fail_iput;
+       snprintf(sdp->sd_fsname, sizeof(sdp->sd_fsname), "%s", sdp->sd_table_name);
+@@ -1192,7 +1195,7 @@ static int gfs2_fill_super(struct super_block *sb, struct fs_context *fc)
+                       WQ_MEM_RECLAIM | WQ_HIGHPRI | WQ_FREEZABLE, 0,
+                       sdp->sd_fsname);
+       if (!sdp->sd_glock_wq)
+-              goto fail_free;
++              goto fail_iput;
+       sdp->sd_delete_wq = alloc_workqueue("gfs2-delete/%s",
+                       WQ_MEM_RECLAIM | WQ_FREEZABLE, 0, sdp->sd_fsname);
+@@ -1309,6 +1312,8 @@ static int gfs2_fill_super(struct super_block *sb, struct fs_context *fc)
+ fail_glock_wq:
+       if (sdp->sd_glock_wq)
+               destroy_workqueue(sdp->sd_glock_wq);
++fail_iput:
++      iput(sdp->sd_inode);
+ fail_free:
+       free_sbd(sdp);
+       sb->s_fs_info = NULL;
+diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
+index 44e5658b896c8..4529b7dda8ca2 100644
+--- a/fs/gfs2/super.c
++++ b/fs/gfs2/super.c
+@@ -648,7 +648,7 @@ static void gfs2_put_super(struct super_block *sb)
+       gfs2_jindex_free(sdp);
+       /*  Take apart glock structures and buffer lists  */
+       gfs2_gl_hash_clear(sdp);
+-      truncate_inode_pages_final(&sdp->sd_aspace);
++      iput(sdp->sd_inode);
+       gfs2_delete_debugfs_file(sdp);
+       gfs2_sys_fs_del(sdp);
+-- 
+2.39.5
+
diff --git a/queue-6.15/gve-add-missing-null-check-for-gve_alloc_pending_pac.patch b/queue-6.15/gve-add-missing-null-check-for-gve_alloc_pending_pac.patch
new file mode 100644 (file)
index 0000000..0f6530b
--- /dev/null
@@ -0,0 +1,44 @@
+From c689aea4233fa7879e0ed71df89fded7fc082683 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Jun 2025 03:34:29 -0700
+Subject: gve: add missing NULL check for gve_alloc_pending_packet() in TX DQO
+
+From: Alok Tiwari <alok.a.tiwari@oracle.com>
+
+[ Upstream commit 12c331b29c7397ac3b03584e12902990693bc248 ]
+
+gve_alloc_pending_packet() can return NULL, but gve_tx_add_skb_dqo()
+did not check for this case before dereferencing the returned pointer.
+
+Add a missing NULL check to prevent a potential NULL pointer
+dereference when allocation fails.
+
+This improves robustness in low-memory scenarios.
+
+Fixes: a57e5de476be ("gve: DQO: Add TX path")
+Signed-off-by: Alok Tiwari <alok.a.tiwari@oracle.com>
+Reviewed-by: Mina Almasry <almasrymina@google.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/google/gve/gve_tx_dqo.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/google/gve/gve_tx_dqo.c b/drivers/net/ethernet/google/gve/gve_tx_dqo.c
+index 2eba868d80370..f7da7de23d672 100644
+--- a/drivers/net/ethernet/google/gve/gve_tx_dqo.c
++++ b/drivers/net/ethernet/google/gve/gve_tx_dqo.c
+@@ -763,6 +763,9 @@ static int gve_tx_add_skb_dqo(struct gve_tx_ring *tx,
+       s16 completion_tag;
+       pkt = gve_alloc_pending_packet(tx);
++      if (!pkt)
++              return -ENOMEM;
++
+       pkt->skb = skb;
+       completion_tag = pkt - tx->dqo.pending_packets;
+-- 
+2.39.5
+
diff --git a/queue-6.15/gve-fix-rx_buffers_posted-stat-to-report-per-queue-f.patch b/queue-6.15/gve-fix-rx_buffers_posted-stat-to-report-per-queue-f.patch
new file mode 100644 (file)
index 0000000..a13813e
--- /dev/null
@@ -0,0 +1,39 @@
+From 7b4b7287edcbd319804705e35e6f0a9d113b797a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 May 2025 06:08:16 -0700
+Subject: gve: Fix RX_BUFFERS_POSTED stat to report per-queue fill_cnt
+
+From: Alok Tiwari <alok.a.tiwari@oracle.com>
+
+[ Upstream commit f41a94aade120dc60322865f363cee7865f2df01 ]
+
+Previously, the RX_BUFFERS_POSTED stat incorrectly reported the
+fill_cnt from RX queue 0 for all queues, resulting in inaccurate
+per-queue statistics.
+Fix this by correctly indexing priv->rx[idx].fill_cnt for each RX queue.
+
+Fixes: 24aeb56f2d38 ("gve: Add Gvnic stats AQ command and ethtool show/set-priv-flags.")
+Signed-off-by: Alok Tiwari <alok.a.tiwari@oracle.com>
+Link: https://patch.msgid.link/20250527130830.1812903-1-alok.a.tiwari@oracle.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/google/gve/gve_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c
+index c3791cf23c876..d561d45021a58 100644
+--- a/drivers/net/ethernet/google/gve/gve_main.c
++++ b/drivers/net/ethernet/google/gve/gve_main.c
+@@ -2153,7 +2153,7 @@ void gve_handle_report_stats(struct gve_priv *priv)
+                       };
+                       stats[stats_idx++] = (struct stats) {
+                               .stat_name = cpu_to_be32(RX_BUFFERS_POSTED),
+-                              .value = cpu_to_be64(priv->rx[0].fill_cnt),
++                              .value = cpu_to_be64(priv->rx[idx].fill_cnt),
+                               .queue_id = cpu_to_be32(idx),
+                       };
+               }
+-- 
+2.39.5
+
diff --git a/queue-6.15/hid-hid_appletb_bl-should-depend-on-x86.patch b/queue-6.15/hid-hid_appletb_bl-should-depend-on-x86.patch
new file mode 100644 (file)
index 0000000..c918144
--- /dev/null
@@ -0,0 +1,37 @@
+From 769fce4eef653562b4fd9a592fa90f08fa5f97a7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Apr 2025 10:30:57 +0200
+Subject: HID: HID_APPLETB_BL should depend on X86
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit de7ad66b16b4d397593eafbbb09e9557b558a7e3 ]
+
+The Apple Touch Bar is only present on x86 MacBook Pros.  Hence add a
+dependency on X86, to prevent asking the user about this driver when
+configuring a kernel for a different architecture.
+
+Fixes: 1fd41e5e3d7cc556 ("HID: hid-appletb-bl: add driver for the backlight of Apple Touch Bars")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Aditya Garg <gargaditya08@live.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
+index 119e5190a2df7..43859fc757470 100644
+--- a/drivers/hid/Kconfig
++++ b/drivers/hid/Kconfig
+@@ -151,6 +151,7 @@ config HID_APPLEIR
+ config HID_APPLETB_BL
+       tristate "Apple Touch Bar Backlight"
+       depends on BACKLIGHT_CLASS_DEVICE
++      depends on X86 || COMPILE_TEST
+       help
+         Say Y here if you want support for the backlight of Touch Bars on x86
+         MacBook Pros.
+-- 
+2.39.5
+
diff --git a/queue-6.15/hid-hid_appletb_kbd-should-depend-on-x86.patch b/queue-6.15/hid-hid_appletb_kbd-should-depend-on-x86.patch
new file mode 100644 (file)
index 0000000..3fb65b4
--- /dev/null
@@ -0,0 +1,37 @@
+From ae70b4a226d521d9bc9a8eca75734c892d643910 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Apr 2025 10:30:56 +0200
+Subject: HID: HID_APPLETB_KBD should depend on X86
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 2a647d400afecdf12ba5905424e1337fbc2d6750 ]
+
+The Apple Touch Bar is only present on x86 MacBook Pros.  Hence add a
+dependency on X86, to prevent asking the user about this driver when
+configuring a kernel for a different architecture.
+
+Fixes: 8e9b9152cfbdc2a9 ("HID: hid-appletb-kbd: add driver for the keyboard mode of Apple Touch Bars")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Aditya Garg <gargaditya08@live.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
+index a503252702b7b..119e5190a2df7 100644
+--- a/drivers/hid/Kconfig
++++ b/drivers/hid/Kconfig
+@@ -163,6 +163,7 @@ config HID_APPLETB_KBD
+       depends on USB_HID
+       depends on BACKLIGHT_CLASS_DEVICE
+       depends on INPUT
++      depends on X86 || COMPILE_TEST
+       select INPUT_SPARSEKMAP
+       select HID_APPLETB_BL
+       help
+-- 
+2.39.5
+
diff --git a/queue-6.15/hid-intel-thc-hid-intel-quicki2c-pass-correct-argume.patch b/queue-6.15/hid-intel-thc-hid-intel-quicki2c-pass-correct-argume.patch
new file mode 100644 (file)
index 0000000..db150f0
--- /dev/null
@@ -0,0 +1,51 @@
+From 6a4199083b37c2bbb9f83ba19373a640da21e148 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Apr 2025 21:50:23 +0800
+Subject: HID: intel-thc-hid: intel-quicki2c: pass correct arguments to
+ acpi_evaluate_object
+
+From: Wentao Guan <guanwentao@uniontech.com>
+
+[ Upstream commit 37d66cf07871927ea682c491b9e9a12dd73e6b5b ]
+
+Delete unused argument, pass correct argument to acpi_evaluate_object.
+
+Log:
+  intel_quicki2c 0000:00:10.0: enabling device (0000 -> 0002)
+  ACPI: \_SB.PC00.THC0.ICRS: 1 arguments were passed to a non-method ACPI object (Buffer) (20230628/nsarguments-211)
+  ACPI: \_SB.PC00.THC0.ISUB: 1 arguments were passed to a non-method ACPI object (Buffer) (20230628/nsarguments-211)
+
+Fixes: 5282e45ccbfa ("HID: intel-thc-hid: intel-quicki2c: Add THC QuickI2C ACPI interfaces")
+Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
+Signed-off-by: WangYuli <wangyuli@uniontech.com>
+Reviewed-by: Even Xu <even.xu@intel.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+diff --git a/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c b/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c
+index fa51155ebe393..8a8c4a46f9270 100644
+--- a/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c
++++ b/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c
+@@ -82,15 +82,10 @@ static int quicki2c_acpi_get_dsd_property(struct acpi_device *adev, acpi_string
+ {
+       acpi_handle handle = acpi_device_handle(adev);
+       struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+-      union acpi_object obj = { .type = type };
+-      struct acpi_object_list arg_list = {
+-              .count = 1,
+-              .pointer = &obj,
+-      };
+       union acpi_object *ret_obj;
+       acpi_status status;
+-      status = acpi_evaluate_object(handle, dsd_method_name, &arg_list, &buffer);
++      status = acpi_evaluate_object(handle, dsd_method_name, NULL, &buffer);
+       if (ACPI_FAILURE(status)) {
+               acpi_handle_err(handle,
+                               "Can't evaluate %s method: %d\n", dsd_method_name, status);
+-- 
+2.39.5
+
diff --git a/queue-6.15/hisi_acc_vfio_pci-add-eq-and-aeq-interruption-restor.patch b/queue-6.15/hisi_acc_vfio_pci-add-eq-and-aeq-interruption-restor.patch
new file mode 100644 (file)
index 0000000..cf92aba
--- /dev/null
@@ -0,0 +1,65 @@
+From dc5f723f73e653b7e391343b0f41be2c2131f194 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 10 May 2025 16:11:51 +0800
+Subject: hisi_acc_vfio_pci: add eq and aeq interruption restore
+
+From: Longfang Liu <liulongfang@huawei.com>
+
+[ Upstream commit 3495cec0787721ba7a9d5c19d0bbb66d182de584 ]
+
+In order to ensure that the task packets of the accelerator
+device are not lost during the migration process, it is necessary
+to send an EQ and AEQ command to the device after the live migration
+is completed and to update the completion position of the task queue.
+
+Let the device recheck the completed tasks data and if there are
+uncollected packets, device resend a task completion interrupt
+to the software.
+
+Fixes: b0eed085903e ("hisi_acc_vfio_pci: Add support for VFIO live migration")
+Signed-off-by: Longfang Liu <liulongfang@huawei.com>
+Reviewed-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
+Link: https://lore.kernel.org/r/20250510081155.55840-3-liulongfang@huawei.com
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
+index 304dbdfa0e95a..80217aea54755 100644
+--- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
++++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
+@@ -470,6 +470,19 @@ static int vf_qm_get_match_data(struct hisi_acc_vf_core_device *hisi_acc_vdev,
+       return 0;
+ }
++static void vf_qm_xeqc_save(struct hisi_qm *qm,
++                          struct hisi_acc_vf_migration_file *migf)
++{
++      struct acc_vf_data *vf_data = &migf->vf_data;
++      u16 eq_head, aeq_head;
++
++      eq_head = vf_data->qm_eqc_dw[0] & 0xFFFF;
++      qm_db(qm, 0, QM_DOORBELL_CMD_EQ, eq_head, 0);
++
++      aeq_head = vf_data->qm_aeqc_dw[0] & 0xFFFF;
++      qm_db(qm, 0, QM_DOORBELL_CMD_AEQ, aeq_head, 0);
++}
++
+ static int vf_qm_load_data(struct hisi_acc_vf_core_device *hisi_acc_vdev,
+                          struct hisi_acc_vf_migration_file *migf)
+ {
+@@ -578,6 +591,9 @@ static int vf_qm_state_save(struct hisi_acc_vf_core_device *hisi_acc_vdev,
+               return -EINVAL;
+       migf->total_length = sizeof(struct acc_vf_data);
++      /* Save eqc and aeqc interrupt information */
++      vf_qm_xeqc_save(vf_qm, migf);
++
+       return 0;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/hisi_acc_vfio_pci-bugfix-cache-write-back-issue.patch b/queue-6.15/hisi_acc_vfio_pci-bugfix-cache-write-back-issue.patch
new file mode 100644 (file)
index 0000000..d6a4668
--- /dev/null
@@ -0,0 +1,70 @@
+From e6db07311bf763fdd7b07cfef9fc5f33e0abd71d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 10 May 2025 16:11:52 +0800
+Subject: hisi_acc_vfio_pci: bugfix cache write-back issue
+
+From: Longfang Liu <liulongfang@huawei.com>
+
+[ Upstream commit e63c466398731bb7867f42f44b76fa984de59db2 ]
+
+At present, cache write-back is placed in the device data
+copy stage after stopping the device operation.
+Writing back to the cache at this stage will cause the data
+obtained by the cache to be written back to be empty.
+
+In order to ensure that the cache data is written back
+successfully, the data needs to be written back into the
+stop device stage.
+
+Fixes: b0eed085903e ("hisi_acc_vfio_pci: Add support for VFIO live migration")
+Signed-off-by: Longfang Liu <liulongfang@huawei.com>
+Reviewed-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
+Link: https://lore.kernel.org/r/20250510081155.55840-4-liulongfang@huawei.com
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
+index 80217aea54755..d96446f499ed0 100644
+--- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
++++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
+@@ -566,7 +566,6 @@ static int vf_qm_state_save(struct hisi_acc_vf_core_device *hisi_acc_vdev,
+ {
+       struct acc_vf_data *vf_data = &migf->vf_data;
+       struct hisi_qm *vf_qm = &hisi_acc_vdev->vf_qm;
+-      struct device *dev = &vf_qm->pdev->dev;
+       int ret;
+       if (unlikely(qm_wait_dev_not_ready(vf_qm))) {
+@@ -580,12 +579,6 @@ static int vf_qm_state_save(struct hisi_acc_vf_core_device *hisi_acc_vdev,
+       vf_data->vf_qm_state = QM_READY;
+       hisi_acc_vdev->vf_qm_state = vf_data->vf_qm_state;
+-      ret = vf_qm_cache_wb(vf_qm);
+-      if (ret) {
+-              dev_err(dev, "failed to writeback QM Cache!\n");
+-              return ret;
+-      }
+-
+       ret = vf_qm_read_data(vf_qm, vf_data);
+       if (ret)
+               return -EINVAL;
+@@ -1012,6 +1005,13 @@ static int hisi_acc_vf_stop_device(struct hisi_acc_vf_core_device *hisi_acc_vdev
+               dev_err(dev, "failed to check QM INT state!\n");
+               return ret;
+       }
++
++      ret = vf_qm_cache_wb(vf_qm);
++      if (ret) {
++              dev_err(dev, "failed to writeback QM cache!\n");
++              return ret;
++      }
++
+       return 0;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/hisi_acc_vfio_pci-bugfix-live-migration-function-wit.patch b/queue-6.15/hisi_acc_vfio_pci-bugfix-live-migration-function-wit.patch
new file mode 100644 (file)
index 0000000..50f2f24
--- /dev/null
@@ -0,0 +1,81 @@
+From 88df8e350206e9b040d7fd8510afde40e8df1896 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 10 May 2025 16:11:54 +0800
+Subject: hisi_acc_vfio_pci: bugfix live migration function without VF device
+ driver
+
+From: Longfang Liu <liulongfang@huawei.com>
+
+[ Upstream commit 2777a40998deb36f96b6afc48bd397cf58a4edf0 ]
+
+If the VF device driver is not loaded in the Guest OS and we attempt to
+perform device data migration, the address of the migrated data will
+be NULL.
+The live migration recovery operation on the destination side will
+access a null address value, which will cause access errors.
+
+Therefore, live migration of VMs without added VF device drivers
+does not require device data migration.
+In addition, when the queue address data obtained by the destination
+is empty, device queue recovery processing will not be performed.
+
+Fixes: b0eed085903e ("hisi_acc_vfio_pci: Add support for VFIO live migration")
+Signed-off-by: Longfang Liu <liulongfang@huawei.com>
+Reviewed-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
+Link: https://lore.kernel.org/r/20250510081155.55840-6-liulongfang@huawei.com
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../vfio/pci/hisilicon/hisi_acc_vfio_pci.c    | 22 +++++++++++++------
+ 1 file changed, 15 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
+index cadc82419dca2..d12a350440d3c 100644
+--- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
++++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
+@@ -426,13 +426,6 @@ static int vf_qm_check_match(struct hisi_acc_vf_core_device *hisi_acc_vdev,
+               return -EINVAL;
+       }
+-      ret = qm_write_regs(vf_qm, QM_VF_STATE, &vf_data->vf_qm_state, 1);
+-      if (ret) {
+-              dev_err(dev, "failed to write QM_VF_STATE\n");
+-              return ret;
+-      }
+-
+-      hisi_acc_vdev->vf_qm_state = vf_data->vf_qm_state;
+       hisi_acc_vdev->match_done = true;
+       return 0;
+ }
+@@ -498,6 +491,20 @@ static int vf_qm_load_data(struct hisi_acc_vf_core_device *hisi_acc_vdev,
+       if (migf->total_length < sizeof(struct acc_vf_data))
+               return -EINVAL;
++      if (!vf_data->eqe_dma || !vf_data->aeqe_dma ||
++          !vf_data->sqc_dma || !vf_data->cqc_dma) {
++              dev_info(dev, "resume dma addr is NULL!\n");
++              hisi_acc_vdev->vf_qm_state = QM_NOT_READY;
++              return 0;
++      }
++
++      ret = qm_write_regs(qm, QM_VF_STATE, &vf_data->vf_qm_state, 1);
++      if (ret) {
++              dev_err(dev, "failed to write QM_VF_STATE\n");
++              return -EINVAL;
++      }
++      hisi_acc_vdev->vf_qm_state = vf_data->vf_qm_state;
++
+       qm->eqe_dma = vf_data->eqe_dma;
+       qm->aeqe_dma = vf_data->aeqe_dma;
+       qm->sqc_dma = vf_data->sqc_dma;
+@@ -1531,6 +1538,7 @@ static int hisi_acc_vfio_pci_migrn_init_dev(struct vfio_device *core_vdev)
+       hisi_acc_vdev->vf_id = pci_iov_vf_id(pdev) + 1;
+       hisi_acc_vdev->pf_qm = pf_qm;
+       hisi_acc_vdev->vf_dev = pdev;
++      hisi_acc_vdev->vf_qm_state = QM_NOT_READY;
+       mutex_init(&hisi_acc_vdev->state_mutex);
+       mutex_init(&hisi_acc_vdev->open_mutex);
+-- 
+2.39.5
+
diff --git a/queue-6.15/hisi_acc_vfio_pci-bugfix-the-problem-of-uninstalling.patch b/queue-6.15/hisi_acc_vfio_pci-bugfix-the-problem-of-uninstalling.patch
new file mode 100644 (file)
index 0000000..c7c9411
--- /dev/null
@@ -0,0 +1,46 @@
+From 8ad72b794b48342473f675fe4a118fd73d71a05f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 10 May 2025 16:11:53 +0800
+Subject: hisi_acc_vfio_pci: bugfix the problem of uninstalling driver
+
+From: Longfang Liu <liulongfang@huawei.com>
+
+[ Upstream commit db6525a8573957faea28850392f4744e5f8f7a53 ]
+
+In a live migration scenario. If the number of VFs at the
+destination is greater than the source, the recovery operation
+will fail and qemu will not be able to complete the process and
+exit after shutting down the device FD.
+
+This will cause the driver to be unable to be unloaded normally due
+to abnormal reference counting of the live migration driver caused
+by the abnormal closing operation of fd.
+
+Therefore, make sure the migration file descriptor references are
+always released when the device is closed.
+
+Fixes: b0eed085903e ("hisi_acc_vfio_pci: Add support for VFIO live migration")
+Signed-off-by: Longfang Liu <liulongfang@huawei.com>
+Reviewed-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
+Link: https://lore.kernel.org/r/20250510081155.55840-5-liulongfang@huawei.com
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
+index d96446f499ed0..cadc82419dca2 100644
+--- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
++++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
+@@ -1508,6 +1508,7 @@ static void hisi_acc_vfio_pci_close_device(struct vfio_device *core_vdev)
+       struct hisi_acc_vf_core_device *hisi_acc_vdev = hisi_acc_get_vf_dev(core_vdev);
+       struct hisi_qm *vf_qm = &hisi_acc_vdev->vf_qm;
++      hisi_acc_vf_disable_fds(hisi_acc_vdev);
+       mutex_lock(&hisi_acc_vdev->open_mutex);
+       hisi_acc_vdev->dev_opened = false;
+       iounmap(vf_qm->io_base);
+-- 
+2.39.5
+
diff --git a/queue-6.15/hisi_acc_vfio_pci-fix-xqe-dma-address-error.patch b/queue-6.15/hisi_acc_vfio_pci-fix-xqe-dma-address-error.patch
new file mode 100644 (file)
index 0000000..739eb57
--- /dev/null
@@ -0,0 +1,155 @@
+From a6aaa63a34b2bf8411dcf278dcd5ba6681979f8e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 10 May 2025 16:11:50 +0800
+Subject: hisi_acc_vfio_pci: fix XQE dma address error
+
+From: Longfang Liu <liulongfang@huawei.com>
+
+[ Upstream commit 8bb7170c5a055ea17c6857c256ee73c10ff872eb ]
+
+The dma addresses of EQE and AEQE are wrong after migration and
+results in guest kernel-mode encryption services  failure.
+Comparing the definition of hardware registers, we found that
+there was an error when the data read from the register was
+combined into an address. Therefore, the address combination
+sequence needs to be corrected.
+
+Even after fixing the above problem, we still have an issue
+where the Guest from an old kernel can get migrated to
+new kernel and may result in wrong data.
+
+In order to ensure that the address is correct after migration,
+if an old magic number is detected, the dma address needs to be
+updated.
+
+Fixes: b0eed085903e ("hisi_acc_vfio_pci: Add support for VFIO live migration")
+Signed-off-by: Longfang Liu <liulongfang@huawei.com>
+Reviewed-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
+Link: https://lore.kernel.org/r/20250510081155.55840-2-liulongfang@huawei.com
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../vfio/pci/hisilicon/hisi_acc_vfio_pci.c    | 41 ++++++++++++++++---
+ .../vfio/pci/hisilicon/hisi_acc_vfio_pci.h    | 14 ++++++-
+ 2 files changed, 47 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
+index 451c639299eb3..304dbdfa0e95a 100644
+--- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
++++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
+@@ -350,6 +350,32 @@ static int vf_qm_func_stop(struct hisi_qm *qm)
+       return hisi_qm_mb(qm, QM_MB_CMD_PAUSE_QM, 0, 0, 0);
+ }
++static int vf_qm_version_check(struct acc_vf_data *vf_data, struct device *dev)
++{
++      switch (vf_data->acc_magic) {
++      case ACC_DEV_MAGIC_V2:
++              if (vf_data->major_ver != ACC_DRV_MAJOR_VER) {
++                      dev_info(dev, "migration driver version<%u.%u> not match!\n",
++                               vf_data->major_ver, vf_data->minor_ver);
++                      return -EINVAL;
++              }
++              break;
++      case ACC_DEV_MAGIC_V1:
++              /* Correct dma address */
++              vf_data->eqe_dma = vf_data->qm_eqc_dw[QM_XQC_ADDR_HIGH];
++              vf_data->eqe_dma <<= QM_XQC_ADDR_OFFSET;
++              vf_data->eqe_dma |= vf_data->qm_eqc_dw[QM_XQC_ADDR_LOW];
++              vf_data->aeqe_dma = vf_data->qm_aeqc_dw[QM_XQC_ADDR_HIGH];
++              vf_data->aeqe_dma <<= QM_XQC_ADDR_OFFSET;
++              vf_data->aeqe_dma |= vf_data->qm_aeqc_dw[QM_XQC_ADDR_LOW];
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      return 0;
++}
++
+ static int vf_qm_check_match(struct hisi_acc_vf_core_device *hisi_acc_vdev,
+                            struct hisi_acc_vf_migration_file *migf)
+ {
+@@ -363,7 +389,8 @@ static int vf_qm_check_match(struct hisi_acc_vf_core_device *hisi_acc_vdev,
+       if (migf->total_length < QM_MATCH_SIZE || hisi_acc_vdev->match_done)
+               return 0;
+-      if (vf_data->acc_magic != ACC_DEV_MAGIC) {
++      ret = vf_qm_version_check(vf_data, dev);
++      if (ret) {
+               dev_err(dev, "failed to match ACC_DEV_MAGIC\n");
+               return -EINVAL;
+       }
+@@ -418,7 +445,9 @@ static int vf_qm_get_match_data(struct hisi_acc_vf_core_device *hisi_acc_vdev,
+       int vf_id = hisi_acc_vdev->vf_id;
+       int ret;
+-      vf_data->acc_magic = ACC_DEV_MAGIC;
++      vf_data->acc_magic = ACC_DEV_MAGIC_V2;
++      vf_data->major_ver = ACC_DRV_MAJOR_VER;
++      vf_data->minor_ver = ACC_DRV_MINOR_VER;
+       /* Save device id */
+       vf_data->dev_id = hisi_acc_vdev->vf_dev->device;
+@@ -496,12 +525,12 @@ static int vf_qm_read_data(struct hisi_qm *vf_qm, struct acc_vf_data *vf_data)
+               return -EINVAL;
+       /* Every reg is 32 bit, the dma address is 64 bit. */
+-      vf_data->eqe_dma = vf_data->qm_eqc_dw[1];
++      vf_data->eqe_dma = vf_data->qm_eqc_dw[QM_XQC_ADDR_HIGH];
+       vf_data->eqe_dma <<= QM_XQC_ADDR_OFFSET;
+-      vf_data->eqe_dma |= vf_data->qm_eqc_dw[0];
+-      vf_data->aeqe_dma = vf_data->qm_aeqc_dw[1];
++      vf_data->eqe_dma |= vf_data->qm_eqc_dw[QM_XQC_ADDR_LOW];
++      vf_data->aeqe_dma = vf_data->qm_aeqc_dw[QM_XQC_ADDR_HIGH];
+       vf_data->aeqe_dma <<= QM_XQC_ADDR_OFFSET;
+-      vf_data->aeqe_dma |= vf_data->qm_aeqc_dw[0];
++      vf_data->aeqe_dma |= vf_data->qm_aeqc_dw[QM_XQC_ADDR_LOW];
+       /* Through SQC_BT/CQC_BT to get sqc and cqc address */
+       ret = qm_get_sqc(vf_qm, &vf_data->sqc_dma);
+diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.h b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.h
+index 245d7537b2bcd..91002ceeebc18 100644
+--- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.h
++++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.h
+@@ -39,6 +39,9 @@
+ #define QM_REG_ADDR_OFFSET    0x0004
+ #define QM_XQC_ADDR_OFFSET    32U
++#define QM_XQC_ADDR_LOW       0x1
++#define QM_XQC_ADDR_HIGH      0x2
++
+ #define QM_VF_AEQ_INT_MASK    0x0004
+ #define QM_VF_EQ_INT_MASK     0x000c
+ #define QM_IFC_INT_SOURCE_V   0x0020
+@@ -50,10 +53,15 @@
+ #define QM_EQC_DW0            0X8000
+ #define QM_AEQC_DW0           0X8020
++#define ACC_DRV_MAJOR_VER 1
++#define ACC_DRV_MINOR_VER 0
++
++#define ACC_DEV_MAGIC_V1      0XCDCDCDCDFEEDAACC
++#define ACC_DEV_MAGIC_V2      0xAACCFEEDDECADEDE
++
+ struct acc_vf_data {
+ #define QM_MATCH_SIZE offsetofend(struct acc_vf_data, qm_rsv_state)
+       /* QM match information */
+-#define ACC_DEV_MAGIC 0XCDCDCDCDFEEDAACC
+       u64 acc_magic;
+       u32 qp_num;
+       u32 dev_id;
+@@ -61,7 +69,9 @@ struct acc_vf_data {
+       u32 qp_base;
+       u32 vf_qm_state;
+       /* QM reserved match information */
+-      u32 qm_rsv_state[3];
++      u16 major_ver;
++      u16 minor_ver;
++      u32 qm_rsv_state[2];
+       /* QM RW regs */
+       u32 aeq_int_mask;
+-- 
+2.39.5
+
diff --git a/queue-6.15/hwmon-asus-ec-sensors-check-sensor-index-in-read_str.patch b/queue-6.15/hwmon-asus-ec-sensors-check-sensor-index-in-read_str.patch
new file mode 100644 (file)
index 0000000..b79c979
--- /dev/null
@@ -0,0 +1,48 @@
+From f2e92b55c3a3ca5bca17329b29f2b4737d7ec5fa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Apr 2025 23:26:54 +0300
+Subject: hwmon: (asus-ec-sensors) check sensor index in read_string()
+
+From: Alexei Safin <a.safin@rosa.ru>
+
+[ Upstream commit 25be318324563c63cbd9cb53186203a08d2f83a1 ]
+
+Prevent a potential invalid memory access when the requested sensor
+is not found.
+
+find_ec_sensor_index() may return a negative value (e.g. -ENOENT),
+but its result was used without checking, which could lead to
+undefined behavior when passed to get_sensor_info().
+
+Add a proper check to return -EINVAL if sensor_index is negative.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: d0ddfd241e57 ("hwmon: (asus-ec-sensors) add driver for ASUS EC")
+Signed-off-by: Alexei Safin <a.safin@rosa.ru>
+Link: https://lore.kernel.org/r/20250424202654.5902-1-a.safin@rosa.ru
+[groeck: Return error code returned from find_ec_sensor_index]
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/asus-ec-sensors.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/hwmon/asus-ec-sensors.c b/drivers/hwmon/asus-ec-sensors.c
+index 006ced5ab6e6a..c7c02a1f55d45 100644
+--- a/drivers/hwmon/asus-ec-sensors.c
++++ b/drivers/hwmon/asus-ec-sensors.c
+@@ -933,6 +933,10 @@ static int asus_ec_hwmon_read_string(struct device *dev,
+ {
+       struct ec_sensors_data *state = dev_get_drvdata(dev);
+       int sensor_index = find_ec_sensor_index(state, type, channel);
++
++      if (sensor_index < 0)
++              return sensor_index;
++
+       *str = get_sensor_info(state, sensor_index)->label;
+       return 0;
+-- 
+2.39.5
+
diff --git a/queue-6.15/iavf-centralize-watchdog-requeueing-itself.patch b/queue-6.15/iavf-centralize-watchdog-requeueing-itself.patch
new file mode 100644 (file)
index 0000000..cf8c2f1
--- /dev/null
@@ -0,0 +1,216 @@
+From f344b9230fc0767ec1fdd91ae78653b198eb4141 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Apr 2025 12:23:17 +0200
+Subject: iavf: centralize watchdog requeueing itself
+
+From: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+
+[ Upstream commit 099418da91b7d3d46ddcccbb03075cc4f1ba2d44 ]
+
+Centralize the unlock(critlock); unlock(netdev); queue_delayed_work(watchog_task);
+pattern to one place.
+
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Stable-dep-of: 120f28a6f314 ("iavf: get rid of the crit lock")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/iavf/iavf_main.c | 103 ++++++++------------
+ 1 file changed, 41 insertions(+), 62 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index a77c726435281..2c6e033c73419 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -2911,6 +2911,8 @@ static void iavf_init_config_adapter(struct iavf_adapter *adapter)
+       iavf_change_state(adapter, __IAVF_INIT_FAILED);
+ }
++static const int IAVF_NO_RESCHED = -1;
++
+ /**
+  * iavf_watchdog_task - Periodic call-back task
+  * @work: pointer to work_struct
+@@ -2922,6 +2924,7 @@ static void iavf_watchdog_task(struct work_struct *work)
+                                                   watchdog_task.work);
+       struct net_device *netdev = adapter->netdev;
+       struct iavf_hw *hw = &adapter->hw;
++      int msec_delay;
+       u32 reg_val;
+       netdev_lock(netdev);
+@@ -2940,39 +2943,24 @@ static void iavf_watchdog_task(struct work_struct *work)
+       switch (adapter->state) {
+       case __IAVF_STARTUP:
+               iavf_startup(adapter);
+-              mutex_unlock(&adapter->crit_lock);
+-              netdev_unlock(netdev);
+-              queue_delayed_work(adapter->wq, &adapter->watchdog_task,
+-                                 msecs_to_jiffies(30));
+-              return;
++              msec_delay = 30;
++              goto watchdog_done;
+       case __IAVF_INIT_VERSION_CHECK:
+               iavf_init_version_check(adapter);
+-              mutex_unlock(&adapter->crit_lock);
+-              netdev_unlock(netdev);
+-              queue_delayed_work(adapter->wq, &adapter->watchdog_task,
+-                                 msecs_to_jiffies(30));
+-              return;
++              msec_delay = 30;
++              goto watchdog_done;
+       case __IAVF_INIT_GET_RESOURCES:
+               iavf_init_get_resources(adapter);
+-              mutex_unlock(&adapter->crit_lock);
+-              netdev_unlock(netdev);
+-              queue_delayed_work(adapter->wq, &adapter->watchdog_task,
+-                                 msecs_to_jiffies(1));
+-              return;
++              msec_delay = 1;
++              goto watchdog_done;
+       case __IAVF_INIT_EXTENDED_CAPS:
+               iavf_init_process_extended_caps(adapter);
+-              mutex_unlock(&adapter->crit_lock);
+-              netdev_unlock(netdev);
+-              queue_delayed_work(adapter->wq, &adapter->watchdog_task,
+-                                 msecs_to_jiffies(1));
+-              return;
++              msec_delay = 1;
++              goto watchdog_done;
+       case __IAVF_INIT_CONFIG_ADAPTER:
+               iavf_init_config_adapter(adapter);
+-              mutex_unlock(&adapter->crit_lock);
+-              netdev_unlock(netdev);
+-              queue_delayed_work(adapter->wq, &adapter->watchdog_task,
+-                                 msecs_to_jiffies(1));
+-              return;
++              msec_delay = 1;
++              goto watchdog_done;
+       case __IAVF_INIT_FAILED:
+               if (test_bit(__IAVF_IN_REMOVE_TASK,
+                            &adapter->crit_section)) {
+@@ -2980,27 +2968,21 @@ static void iavf_watchdog_task(struct work_struct *work)
+                        * watchdog task, iavf_remove should handle this state
+                        * as it can loop forever
+                        */
+-                      mutex_unlock(&adapter->crit_lock);
+-                      netdev_unlock(netdev);
+-                      return;
++                      msec_delay = IAVF_NO_RESCHED;
++                      goto watchdog_done;
+               }
+               if (++adapter->aq_wait_count > IAVF_AQ_MAX_ERR) {
+                       dev_err(&adapter->pdev->dev,
+                               "Failed to communicate with PF; waiting before retry\n");
+                       adapter->flags |= IAVF_FLAG_PF_COMMS_FAILED;
+                       iavf_shutdown_adminq(hw);
+-                      mutex_unlock(&adapter->crit_lock);
+-                      netdev_unlock(netdev);
+-                      queue_delayed_work(adapter->wq,
+-                                         &adapter->watchdog_task, (5 * HZ));
+-                      return;
++                      msec_delay = 5000;
++                      goto watchdog_done;
+               }
+               /* Try again from failed step*/
+               iavf_change_state(adapter, adapter->last_state);
+-              mutex_unlock(&adapter->crit_lock);
+-              netdev_unlock(netdev);
+-              queue_delayed_work(adapter->wq, &adapter->watchdog_task, HZ);
+-              return;
++              msec_delay = 1000;
++              goto watchdog_done;
+       case __IAVF_COMM_FAILED:
+               if (test_bit(__IAVF_IN_REMOVE_TASK,
+                            &adapter->crit_section)) {
+@@ -3010,9 +2992,8 @@ static void iavf_watchdog_task(struct work_struct *work)
+                        */
+                       iavf_change_state(adapter, __IAVF_INIT_FAILED);
+                       adapter->flags &= ~IAVF_FLAG_PF_COMMS_FAILED;
+-                      mutex_unlock(&adapter->crit_lock);
+-                      netdev_unlock(netdev);
+-                      return;
++                      msec_delay = IAVF_NO_RESCHED;
++                      goto watchdog_done;
+               }
+               reg_val = rd32(hw, IAVF_VFGEN_RSTAT) &
+                         IAVF_VFGEN_RSTAT_VFR_STATE_MASK;
+@@ -3030,18 +3011,11 @@ static void iavf_watchdog_task(struct work_struct *work)
+               }
+               adapter->aq_required = 0;
+               adapter->current_op = VIRTCHNL_OP_UNKNOWN;
+-              mutex_unlock(&adapter->crit_lock);
+-              netdev_unlock(netdev);
+-              queue_delayed_work(adapter->wq,
+-                                 &adapter->watchdog_task,
+-                                 msecs_to_jiffies(10));
+-              return;
++              msec_delay = 10;
++              goto watchdog_done;
+       case __IAVF_RESETTING:
+-              mutex_unlock(&adapter->crit_lock);
+-              netdev_unlock(netdev);
+-              queue_delayed_work(adapter->wq, &adapter->watchdog_task,
+-                                 HZ * 2);
+-              return;
++              msec_delay = 2000;
++              goto watchdog_done;
+       case __IAVF_DOWN:
+       case __IAVF_DOWN_PENDING:
+       case __IAVF_TESTING:
+@@ -3068,9 +3042,8 @@ static void iavf_watchdog_task(struct work_struct *work)
+               break;
+       case __IAVF_REMOVE:
+       default:
+-              mutex_unlock(&adapter->crit_lock);
+-              netdev_unlock(netdev);
+-              return;
++              msec_delay = IAVF_NO_RESCHED;
++              goto watchdog_done;
+       }
+       /* check for hw reset */
+@@ -3080,24 +3053,30 @@ static void iavf_watchdog_task(struct work_struct *work)
+               adapter->current_op = VIRTCHNL_OP_UNKNOWN;
+               dev_err(&adapter->pdev->dev, "Hardware reset detected\n");
+               iavf_schedule_reset(adapter, IAVF_FLAG_RESET_PENDING);
+-              mutex_unlock(&adapter->crit_lock);
+-              netdev_unlock(netdev);
+-              queue_delayed_work(adapter->wq,
+-                                 &adapter->watchdog_task, HZ * 2);
+-              return;
++              msec_delay = 2000;
++              goto watchdog_done;
+       }
+       mutex_unlock(&adapter->crit_lock);
+ restart_watchdog:
+       netdev_unlock(netdev);
++
++      /* note that we schedule a different task */
+       if (adapter->state >= __IAVF_DOWN)
+               queue_work(adapter->wq, &adapter->adminq_task);
+       if (adapter->aq_required)
+-              queue_delayed_work(adapter->wq, &adapter->watchdog_task,
+-                                 msecs_to_jiffies(20));
++              msec_delay = 20;
+       else
++              msec_delay = 2000;
++      goto skip_unlock;
++watchdog_done:
++      mutex_unlock(&adapter->crit_lock);
++      netdev_unlock(netdev);
++skip_unlock:
++
++      if (msec_delay != IAVF_NO_RESCHED)
+               queue_delayed_work(adapter->wq, &adapter->watchdog_task,
+-                                 HZ * 2);
++                                 msecs_to_jiffies(msec_delay));
+ }
+ /**
+-- 
+2.39.5
+
diff --git a/queue-6.15/iavf-extract-iavf_watchdog_step-out-of-iavf_watchdog.patch b/queue-6.15/iavf-extract-iavf_watchdog_step-out-of-iavf_watchdog.patch
new file mode 100644 (file)
index 0000000..65bac20
--- /dev/null
@@ -0,0 +1,189 @@
+From b3f763b6f29a67136503d9bceb4e2ef4023333a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Apr 2025 12:23:19 +0200
+Subject: iavf: extract iavf_watchdog_step() out of iavf_watchdog_task()
+
+From: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+
+[ Upstream commit 257a8241ad7f4dc312494f69e3bc79a5598b4514 ]
+
+Finish up easy refactor of watchdog_task, total for this + prev two
+commits is:
+ 1 file changed, 47 insertions(+), 82 deletions(-)
+
+Signed-off-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Stable-dep-of: 120f28a6f314 ("iavf: get rid of the crit lock")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/iavf/iavf_main.c | 87 +++++++++------------
+ 1 file changed, 39 insertions(+), 48 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index 5efe44724d112..4b6963ffaba5f 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -2913,30 +2913,14 @@ static void iavf_init_config_adapter(struct iavf_adapter *adapter)
+ static const int IAVF_NO_RESCHED = -1;
+-/**
+- * iavf_watchdog_task - Periodic call-back task
+- * @work: pointer to work_struct
+- **/
+-static void iavf_watchdog_task(struct work_struct *work)
++/* return: msec delay for requeueing itself */
++static int iavf_watchdog_step(struct iavf_adapter *adapter)
+ {
+-      struct iavf_adapter *adapter = container_of(work,
+-                                                  struct iavf_adapter,
+-                                                  watchdog_task.work);
+-      struct net_device *netdev = adapter->netdev;
+       struct iavf_hw *hw = &adapter->hw;
+-      int msec_delay;
+       u32 reg_val;
+-      netdev_lock(netdev);
+-      if (!mutex_trylock(&adapter->crit_lock)) {
+-              if (adapter->state == __IAVF_REMOVE) {
+-                      netdev_unlock(netdev);
+-                      return;
+-              }
+-
+-              msec_delay = 20;
+-              goto restart_watchdog;
+-      }
++      netdev_assert_locked(adapter->netdev);
++      lockdep_assert_held(&adapter->crit_lock);
+       if (adapter->flags & IAVF_FLAG_PF_COMMS_FAILED)
+               iavf_change_state(adapter, __IAVF_COMM_FAILED);
+@@ -2944,24 +2928,19 @@ static void iavf_watchdog_task(struct work_struct *work)
+       switch (adapter->state) {
+       case __IAVF_STARTUP:
+               iavf_startup(adapter);
+-              msec_delay = 30;
+-              goto watchdog_done;
++              return 30;
+       case __IAVF_INIT_VERSION_CHECK:
+               iavf_init_version_check(adapter);
+-              msec_delay = 30;
+-              goto watchdog_done;
++              return 30;
+       case __IAVF_INIT_GET_RESOURCES:
+               iavf_init_get_resources(adapter);
+-              msec_delay = 1;
+-              goto watchdog_done;
++              return 1;
+       case __IAVF_INIT_EXTENDED_CAPS:
+               iavf_init_process_extended_caps(adapter);
+-              msec_delay = 1;
+-              goto watchdog_done;
++              return 1;
+       case __IAVF_INIT_CONFIG_ADAPTER:
+               iavf_init_config_adapter(adapter);
+-              msec_delay = 1;
+-              goto watchdog_done;
++              return 1;
+       case __IAVF_INIT_FAILED:
+               if (test_bit(__IAVF_IN_REMOVE_TASK,
+                            &adapter->crit_section)) {
+@@ -2969,21 +2948,18 @@ static void iavf_watchdog_task(struct work_struct *work)
+                        * watchdog task, iavf_remove should handle this state
+                        * as it can loop forever
+                        */
+-                      msec_delay = IAVF_NO_RESCHED;
+-                      goto watchdog_done;
++                      return IAVF_NO_RESCHED;
+               }
+               if (++adapter->aq_wait_count > IAVF_AQ_MAX_ERR) {
+                       dev_err(&adapter->pdev->dev,
+                               "Failed to communicate with PF; waiting before retry\n");
+                       adapter->flags |= IAVF_FLAG_PF_COMMS_FAILED;
+                       iavf_shutdown_adminq(hw);
+-                      msec_delay = 5000;
+-                      goto watchdog_done;
++                      return 5000;
+               }
+               /* Try again from failed step*/
+               iavf_change_state(adapter, adapter->last_state);
+-              msec_delay = 1000;
+-              goto watchdog_done;
++              return 1000;
+       case __IAVF_COMM_FAILED:
+               if (test_bit(__IAVF_IN_REMOVE_TASK,
+                            &adapter->crit_section)) {
+@@ -2993,8 +2969,7 @@ static void iavf_watchdog_task(struct work_struct *work)
+                        */
+                       iavf_change_state(adapter, __IAVF_INIT_FAILED);
+                       adapter->flags &= ~IAVF_FLAG_PF_COMMS_FAILED;
+-                      msec_delay = IAVF_NO_RESCHED;
+-                      goto watchdog_done;
++                      return IAVF_NO_RESCHED;
+               }
+               reg_val = rd32(hw, IAVF_VFGEN_RSTAT) &
+                         IAVF_VFGEN_RSTAT_VFR_STATE_MASK;
+@@ -3012,11 +2987,9 @@ static void iavf_watchdog_task(struct work_struct *work)
+               }
+               adapter->aq_required = 0;
+               adapter->current_op = VIRTCHNL_OP_UNKNOWN;
+-              msec_delay = 10;
+-              goto watchdog_done;
++              return 10;
+       case __IAVF_RESETTING:
+-              msec_delay = 2000;
+-              goto watchdog_done;
++              return 2000;
+       case __IAVF_DOWN:
+       case __IAVF_DOWN_PENDING:
+       case __IAVF_TESTING:
+@@ -3043,8 +3016,7 @@ static void iavf_watchdog_task(struct work_struct *work)
+               break;
+       case __IAVF_REMOVE:
+       default:
+-              msec_delay = IAVF_NO_RESCHED;
+-              goto watchdog_done;
++              return IAVF_NO_RESCHED;
+       }
+       /* check for hw reset */
+@@ -3055,12 +3027,31 @@ static void iavf_watchdog_task(struct work_struct *work)
+               dev_err(&adapter->pdev->dev, "Hardware reset detected\n");
+               iavf_schedule_reset(adapter, IAVF_FLAG_RESET_PENDING);
+       }
+-      if (adapter->aq_required)
++
++      return adapter->aq_required ? 20 : 2000;
++}
++
++static void iavf_watchdog_task(struct work_struct *work)
++{
++      struct iavf_adapter *adapter = container_of(work,
++                                                  struct iavf_adapter,
++                                                  watchdog_task.work);
++      struct net_device *netdev = adapter->netdev;
++      int msec_delay;
++
++      netdev_lock(netdev);
++      if (!mutex_trylock(&adapter->crit_lock)) {
++              if (adapter->state == __IAVF_REMOVE) {
++                      netdev_unlock(netdev);
++                      return;
++              }
++
+               msec_delay = 20;
+-      else
+-              msec_delay = 2000;
++              goto restart_watchdog;
++      }
++
++      msec_delay = iavf_watchdog_step(adapter);
+-watchdog_done:
+       mutex_unlock(&adapter->crit_lock);
+ restart_watchdog:
+       netdev_unlock(netdev);
+-- 
+2.39.5
+
diff --git a/queue-6.15/iavf-get-rid-of-the-crit-lock.patch b/queue-6.15/iavf-get-rid-of-the-crit-lock.patch
new file mode 100644 (file)
index 0000000..82dda3e
--- /dev/null
@@ -0,0 +1,637 @@
+From 34bab7d76728f229f9b6e63aa69560596035189e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Apr 2025 12:23:21 +0200
+Subject: iavf: get rid of the crit lock
+
+From: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+
+[ Upstream commit 120f28a6f314fef7f282c99f196923fe44081cad ]
+
+Get rid of the crit lock.
+That frees us from the error prone logic of try_locks.
+
+Thanks to netdev_lock() by Jakub it is now easy, and in most cases we were
+protected by it already - replace crit lock by netdev lock when it was not
+the case.
+
+Lockdep reports that we should cancel the work under crit_lock [splat1],
+and that was the scheme we have mostly followed since [1] by Slawomir.
+But when that is done we still got into deadlocks [splat2]. So instead
+we should look at the bigger problem, namely "weird locking/scheduling"
+of the iavf. The first step to fix that is to remove the crit lock.
+I will followup with a -next series that simplifies scheduling/tasks.
+
+Cancel the work without netdev lock (weird unlock+lock scheme),
+to fix the [splat2] (which would be totally ugly if we would kept
+the crit lock).
+
+Extend protected part of iavf_watchdog_task() to include scheduling
+more work.
+
+Note that the removed comment in iavf_reset_task() was misplaced,
+it belonged to inside of the removed if condition, so it's gone now.
+
+[splat1] - w/o this patch - The deadlock during VF removal:
+     WARNING: possible circular locking dependency detected
+     sh/3825 is trying to acquire lock:
+      ((work_completion)(&(&adapter->watchdog_task)->work)){+.+.}-{0:0}, at: start_flush_work+0x1a1/0x470
+          but task is already holding lock:
+      (&adapter->crit_lock){+.+.}-{4:4}, at: iavf_remove+0xd1/0x690 [iavf]
+          which lock already depends on the new lock.
+
+[splat2] - when cancelling work under crit lock, w/o this series,
+          see [2] for the band aid attempt
+    WARNING: possible circular locking dependency detected
+    sh/3550 is trying to acquire lock:
+    ((wq_completion)iavf){+.+.}-{0:0}, at: touch_wq_lockdep_map+0x26/0x90
+        but task is already holding lock:
+    (&dev->lock){+.+.}-{4:4}, at: iavf_remove+0xa6/0x6e0 [iavf]
+        which lock already depends on the new lock.
+
+[1] fc2e6b3b132a ("iavf: Rework mutexes for better synchronisation")
+[2] https://github.com/pkitszel/linux/commit/52dddbfc2bb60294083f5711a158a
+
+Fixes: d1639a17319b ("iavf: fix a deadlock caused by rtnl and driver's lock circular dependencies")
+Signed-off-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/iavf/iavf.h        |   1 -
+ .../net/ethernet/intel/iavf/iavf_ethtool.c    |  23 +--
+ drivers/net/ethernet/intel/iavf/iavf_main.c   | 165 ++++--------------
+ 3 files changed, 38 insertions(+), 151 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h
+index 9de3e0ba37316..f7a98ff43a57f 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf.h
++++ b/drivers/net/ethernet/intel/iavf/iavf.h
+@@ -268,7 +268,6 @@ struct iavf_adapter {
+       struct list_head vlan_filter_list;
+       int num_vlan_filters;
+       struct list_head mac_filter_list;
+-      struct mutex crit_lock;
+       /* Lock to protect accesses to MAC and VLAN lists */
+       spinlock_t mac_vlan_list_lock;
+       char misc_vector_name[IFNAMSIZ + 9];
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
+index 03d86fe80ad91..2b2b315205b5e 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
+@@ -1258,7 +1258,6 @@ static int iavf_add_fdir_ethtool(struct iavf_adapter *adapter, struct ethtool_rx
+ {
+       struct ethtool_rx_flow_spec *fsp = &cmd->fs;
+       struct iavf_fdir_fltr *fltr;
+-      int count = 50;
+       int err;
+       netdev_assert_locked(adapter->netdev);
+@@ -1281,14 +1280,6 @@ static int iavf_add_fdir_ethtool(struct iavf_adapter *adapter, struct ethtool_rx
+       if (!fltr)
+               return -ENOMEM;
+-      while (!mutex_trylock(&adapter->crit_lock)) {
+-              if (--count == 0) {
+-                      kfree(fltr);
+-                      return -EINVAL;
+-              }
+-              udelay(1);
+-      }
+-
+       err = iavf_add_fdir_fltr_info(adapter, fsp, fltr);
+       if (!err)
+               err = iavf_fdir_add_fltr(adapter, fltr);
+@@ -1296,7 +1287,6 @@ static int iavf_add_fdir_ethtool(struct iavf_adapter *adapter, struct ethtool_rx
+       if (err)
+               kfree(fltr);
+-      mutex_unlock(&adapter->crit_lock);
+       return err;
+ }
+@@ -1439,9 +1429,9 @@ iavf_set_adv_rss_hash_opt(struct iavf_adapter *adapter,
+ {
+       struct iavf_adv_rss *rss_old, *rss_new;
+       bool rss_new_add = false;
+-      int count = 50, err = 0;
+       bool symm = false;
+       u64 hash_flds;
++      int err = 0;
+       u32 hdrs;
+       netdev_assert_locked(adapter->netdev);
+@@ -1469,15 +1459,6 @@ iavf_set_adv_rss_hash_opt(struct iavf_adapter *adapter,
+               return -EINVAL;
+       }
+-      while (!mutex_trylock(&adapter->crit_lock)) {
+-              if (--count == 0) {
+-                      kfree(rss_new);
+-                      return -EINVAL;
+-              }
+-
+-              udelay(1);
+-      }
+-
+       spin_lock_bh(&adapter->adv_rss_lock);
+       rss_old = iavf_find_adv_rss_cfg_by_hdrs(adapter, hdrs);
+       if (rss_old) {
+@@ -1506,8 +1487,6 @@ iavf_set_adv_rss_hash_opt(struct iavf_adapter *adapter,
+       if (!err)
+               iavf_schedule_aq_request(adapter, IAVF_FLAG_AQ_ADD_ADV_RSS_CFG);
+-      mutex_unlock(&adapter->crit_lock);
+-
+       if (!rss_new_add)
+               kfree(rss_new);
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index bf8c7baf2ab8a..2c0bb41809a41 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -1287,9 +1287,7 @@ static void iavf_configure(struct iavf_adapter *adapter)
+ /**
+  * iavf_up_complete - Finish the last steps of bringing up a connection
+  * @adapter: board private structure
+- *
+- * Expects to be called while holding crit_lock.
+- **/
++ */
+ static void iavf_up_complete(struct iavf_adapter *adapter)
+ {
+       netdev_assert_locked(adapter->netdev);
+@@ -1412,9 +1410,7 @@ static void iavf_clear_adv_rss_conf(struct iavf_adapter *adapter)
+ /**
+  * iavf_down - Shutdown the connection processing
+  * @adapter: board private structure
+- *
+- * Expects to be called while holding crit_lock.
+- **/
++ */
+ void iavf_down(struct iavf_adapter *adapter)
+ {
+       struct net_device *netdev = adapter->netdev;
+@@ -2029,22 +2025,21 @@ static int iavf_reinit_interrupt_scheme(struct iavf_adapter *adapter, bool runni
+  * iavf_finish_config - do all netdev work that needs RTNL
+  * @work: our work_struct
+  *
+- * Do work that needs both RTNL and crit_lock.
+- **/
++ * Do work that needs RTNL.
++ */
+ static void iavf_finish_config(struct work_struct *work)
+ {
+       struct iavf_adapter *adapter;
+-      bool locks_released = false;
++      bool netdev_released = false;
+       int pairs, err;
+       adapter = container_of(work, struct iavf_adapter, finish_config);
+       /* Always take RTNL first to prevent circular lock dependency;
+-       * The dev->lock is needed to update the queue number
++       * the dev->lock (== netdev lock) is needed to update the queue number.
+        */
+       rtnl_lock();
+       netdev_lock(adapter->netdev);
+-      mutex_lock(&adapter->crit_lock);
+       if ((adapter->flags & IAVF_FLAG_SETUP_NETDEV_FEATURES) &&
+           adapter->netdev->reg_state == NETREG_REGISTERED &&
+@@ -2063,22 +2058,21 @@ static void iavf_finish_config(struct work_struct *work)
+               netif_set_real_num_tx_queues(adapter->netdev, pairs);
+               if (adapter->netdev->reg_state != NETREG_REGISTERED) {
+-                      mutex_unlock(&adapter->crit_lock);
+                       netdev_unlock(adapter->netdev);
+-                      locks_released = true;
++                      netdev_released = true;
+                       err = register_netdevice(adapter->netdev);
+                       if (err) {
+                               dev_err(&adapter->pdev->dev, "Unable to register netdev (%d)\n",
+                                       err);
+                               /* go back and try again.*/
+-                              mutex_lock(&adapter->crit_lock);
++                              netdev_lock(adapter->netdev);
+                               iavf_free_rss(adapter);
+                               iavf_free_misc_irq(adapter);
+                               iavf_reset_interrupt_capability(adapter);
+                               iavf_change_state(adapter,
+                                                 __IAVF_INIT_CONFIG_ADAPTER);
+-                              mutex_unlock(&adapter->crit_lock);
++                              netdev_unlock(adapter->netdev);
+                               goto out;
+                       }
+               }
+@@ -2094,10 +2088,8 @@ static void iavf_finish_config(struct work_struct *work)
+       }
+ out:
+-      if (!locks_released) {
+-              mutex_unlock(&adapter->crit_lock);
++      if (!netdev_released)
+               netdev_unlock(adapter->netdev);
+-      }
+       rtnl_unlock();
+ }
+@@ -2924,7 +2916,6 @@ static int iavf_watchdog_step(struct iavf_adapter *adapter)
+       u32 reg_val;
+       netdev_assert_locked(adapter->netdev);
+-      lockdep_assert_held(&adapter->crit_lock);
+       if (adapter->flags & IAVF_FLAG_PF_COMMS_FAILED)
+               iavf_change_state(adapter, __IAVF_COMM_FAILED);
+@@ -3044,22 +3035,7 @@ static void iavf_watchdog_task(struct work_struct *work)
+       int msec_delay;
+       netdev_lock(netdev);
+-      if (!mutex_trylock(&adapter->crit_lock)) {
+-              if (adapter->state == __IAVF_REMOVE) {
+-                      netdev_unlock(netdev);
+-                      return;
+-              }
+-
+-              msec_delay = 20;
+-              goto restart_watchdog;
+-      }
+-
+       msec_delay = iavf_watchdog_step(adapter);
+-
+-      mutex_unlock(&adapter->crit_lock);
+-restart_watchdog:
+-      netdev_unlock(netdev);
+-
+       /* note that we schedule a different task */
+       if (adapter->state >= __IAVF_DOWN)
+               queue_work(adapter->wq, &adapter->adminq_task);
+@@ -3067,6 +3043,7 @@ static void iavf_watchdog_task(struct work_struct *work)
+       if (msec_delay != IAVF_NO_RESCHED)
+               queue_delayed_work(adapter->wq, &adapter->watchdog_task,
+                                  msecs_to_jiffies(msec_delay));
++      netdev_unlock(netdev);
+ }
+ /**
+@@ -3074,8 +3051,7 @@ static void iavf_watchdog_task(struct work_struct *work)
+  * @adapter: board private structure
+  *
+  * Set communication failed flag and free all resources.
+- * NOTE: This function is expected to be called with crit_lock being held.
+- **/
++ */
+ static void iavf_disable_vf(struct iavf_adapter *adapter)
+ {
+       struct iavf_mac_filter *f, *ftmp;
+@@ -3183,17 +3159,7 @@ static void iavf_reset_task(struct work_struct *work)
+       int i = 0, err;
+       bool running;
+-      /* When device is being removed it doesn't make sense to run the reset
+-       * task, just return in such a case.
+-       */
+       netdev_lock(netdev);
+-      if (!mutex_trylock(&adapter->crit_lock)) {
+-              if (adapter->state != __IAVF_REMOVE)
+-                      queue_work(adapter->wq, &adapter->reset_task);
+-
+-              netdev_unlock(netdev);
+-              return;
+-      }
+       iavf_misc_irq_disable(adapter);
+       if (adapter->flags & IAVF_FLAG_RESET_NEEDED) {
+@@ -3238,7 +3204,6 @@ static void iavf_reset_task(struct work_struct *work)
+               dev_err(&adapter->pdev->dev, "Reset never finished (%x)\n",
+                       reg_val);
+               iavf_disable_vf(adapter);
+-              mutex_unlock(&adapter->crit_lock);
+               netdev_unlock(netdev);
+               return; /* Do not attempt to reinit. It's dead, Jim. */
+       }
+@@ -3382,7 +3347,6 @@ static void iavf_reset_task(struct work_struct *work)
+       adapter->flags &= ~IAVF_FLAG_REINIT_ITR_NEEDED;
+       wake_up(&adapter->reset_waitqueue);
+-      mutex_unlock(&adapter->crit_lock);
+       netdev_unlock(netdev);
+       return;
+@@ -3393,7 +3357,6 @@ static void iavf_reset_task(struct work_struct *work)
+       }
+       iavf_disable_vf(adapter);
+-      mutex_unlock(&adapter->crit_lock);
+       netdev_unlock(netdev);
+       dev_err(&adapter->pdev->dev, "failed to allocate resources during reinit\n");
+ }
+@@ -3406,6 +3369,7 @@ static void iavf_adminq_task(struct work_struct *work)
+ {
+       struct iavf_adapter *adapter =
+               container_of(work, struct iavf_adapter, adminq_task);
++      struct net_device *netdev = adapter->netdev;
+       struct iavf_hw *hw = &adapter->hw;
+       struct iavf_arq_event_info event;
+       enum virtchnl_ops v_op;
+@@ -3413,13 +3377,7 @@ static void iavf_adminq_task(struct work_struct *work)
+       u32 val, oldval;
+       u16 pending;
+-      if (!mutex_trylock(&adapter->crit_lock)) {
+-              if (adapter->state == __IAVF_REMOVE)
+-                      return;
+-
+-              queue_work(adapter->wq, &adapter->adminq_task);
+-              goto out;
+-      }
++      netdev_lock(netdev);
+       if (adapter->flags & IAVF_FLAG_PF_COMMS_FAILED)
+               goto unlock;
+@@ -3486,8 +3444,7 @@ static void iavf_adminq_task(struct work_struct *work)
+ freedom:
+       kfree(event.msg_buf);
+ unlock:
+-      mutex_unlock(&adapter->crit_lock);
+-out:
++      netdev_unlock(netdev);
+       /* re-enable Admin queue interrupt cause */
+       iavf_misc_irq_enable(adapter);
+ }
+@@ -4180,8 +4137,8 @@ static int iavf_configure_clsflower(struct iavf_adapter *adapter,
+                                   struct flow_cls_offload *cls_flower)
+ {
+       int tc = tc_classid_to_hwtc(adapter->netdev, cls_flower->classid);
+-      struct iavf_cloud_filter *filter = NULL;
+-      int err = -EINVAL, count = 50;
++      struct iavf_cloud_filter *filter;
++      int err;
+       if (tc < 0) {
+               dev_err(&adapter->pdev->dev, "Invalid traffic class\n");
+@@ -4191,17 +4148,10 @@ static int iavf_configure_clsflower(struct iavf_adapter *adapter,
+       filter = kzalloc(sizeof(*filter), GFP_KERNEL);
+       if (!filter)
+               return -ENOMEM;
+-
+-      while (!mutex_trylock(&adapter->crit_lock)) {
+-              if (--count == 0) {
+-                      kfree(filter);
+-                      return err;
+-              }
+-              udelay(1);
+-      }
+-
+       filter->cookie = cls_flower->cookie;
++      netdev_lock(adapter->netdev);
++
+       /* bail out here if filter already exists */
+       spin_lock_bh(&adapter->cloud_filter_list_lock);
+       if (iavf_find_cf(adapter, &cls_flower->cookie)) {
+@@ -4235,7 +4185,7 @@ static int iavf_configure_clsflower(struct iavf_adapter *adapter,
+       if (err)
+               kfree(filter);
+-      mutex_unlock(&adapter->crit_lock);
++      netdev_unlock(adapter->netdev);
+       return err;
+ }
+@@ -4539,28 +4489,13 @@ static int iavf_open(struct net_device *netdev)
+               return -EIO;
+       }
+-      while (!mutex_trylock(&adapter->crit_lock)) {
+-              /* If we are in __IAVF_INIT_CONFIG_ADAPTER state the crit_lock
+-               * is already taken and iavf_open is called from an upper
+-               * device's notifier reacting on NETDEV_REGISTER event.
+-               * We have to leave here to avoid dead lock.
+-               */
+-              if (adapter->state == __IAVF_INIT_CONFIG_ADAPTER)
+-                      return -EBUSY;
+-
+-              usleep_range(500, 1000);
+-      }
+-
+-      if (adapter->state != __IAVF_DOWN) {
+-              err = -EBUSY;
+-              goto err_unlock;
+-      }
++      if (adapter->state != __IAVF_DOWN)
++              return -EBUSY;
+       if (adapter->state == __IAVF_RUNNING &&
+           !test_bit(__IAVF_VSI_DOWN, adapter->vsi.state)) {
+               dev_dbg(&adapter->pdev->dev, "VF is already open.\n");
+-              err = 0;
+-              goto err_unlock;
++              return 0;
+       }
+       /* allocate transmit descriptors */
+@@ -4579,9 +4514,7 @@ static int iavf_open(struct net_device *netdev)
+               goto err_req_irq;
+       spin_lock_bh(&adapter->mac_vlan_list_lock);
+-
+       iavf_add_filter(adapter, adapter->hw.mac.addr);
+-
+       spin_unlock_bh(&adapter->mac_vlan_list_lock);
+       /* Restore filters that were removed with IFF_DOWN */
+@@ -4594,8 +4527,6 @@ static int iavf_open(struct net_device *netdev)
+       iavf_irq_enable(adapter, true);
+-      mutex_unlock(&adapter->crit_lock);
+-
+       return 0;
+ err_req_irq:
+@@ -4605,8 +4536,6 @@ static int iavf_open(struct net_device *netdev)
+       iavf_free_all_rx_resources(adapter);
+ err_setup_tx:
+       iavf_free_all_tx_resources(adapter);
+-err_unlock:
+-      mutex_unlock(&adapter->crit_lock);
+       return err;
+ }
+@@ -4630,12 +4559,8 @@ static int iavf_close(struct net_device *netdev)
+       netdev_assert_locked(netdev);
+-      mutex_lock(&adapter->crit_lock);
+-
+-      if (adapter->state <= __IAVF_DOWN_PENDING) {
+-              mutex_unlock(&adapter->crit_lock);
++      if (adapter->state <= __IAVF_DOWN_PENDING)
+               return 0;
+-      }
+       set_bit(__IAVF_VSI_DOWN, adapter->vsi.state);
+       /* We cannot send IAVF_FLAG_AQ_GET_OFFLOAD_VLAN_V2_CAPS before
+@@ -4666,7 +4591,6 @@ static int iavf_close(struct net_device *netdev)
+       iavf_change_state(adapter, __IAVF_DOWN_PENDING);
+       iavf_free_traffic_irqs(adapter);
+-      mutex_unlock(&adapter->crit_lock);
+       netdev_unlock(netdev);
+       /* We explicitly don't free resources here because the hardware is
+@@ -4685,11 +4609,10 @@ static int iavf_close(struct net_device *netdev)
+                                   msecs_to_jiffies(500));
+       if (!status)
+               netdev_warn(netdev, "Device resources not yet released\n");
+-
+       netdev_lock(netdev);
+-      mutex_lock(&adapter->crit_lock);
++
+       adapter->aq_required |= aq_to_restore;
+-      mutex_unlock(&adapter->crit_lock);
++
+       return 0;
+ }
+@@ -5198,17 +5121,16 @@ iavf_shaper_set(struct net_shaper_binding *binding,
+       struct iavf_adapter *adapter = netdev_priv(binding->netdev);
+       const struct net_shaper_handle *handle = &shaper->handle;
+       struct iavf_ring *tx_ring;
+-      int ret = 0;
++      int ret;
+       netdev_assert_locked(adapter->netdev);
+-      mutex_lock(&adapter->crit_lock);
+       if (handle->id >= adapter->num_active_queues)
+-              goto unlock;
++              return 0;
+       ret = iavf_verify_shaper(binding, shaper, extack);
+       if (ret)
+-              goto unlock;
++              return ret;
+       tx_ring = &adapter->tx_rings[handle->id];
+@@ -5218,9 +5140,7 @@ iavf_shaper_set(struct net_shaper_binding *binding,
+       adapter->aq_required |= IAVF_FLAG_AQ_CONFIGURE_QUEUES_BW;
+-unlock:
+-      mutex_unlock(&adapter->crit_lock);
+-      return ret;
++      return 0;
+ }
+ static int iavf_shaper_del(struct net_shaper_binding *binding,
+@@ -5232,9 +5152,8 @@ static int iavf_shaper_del(struct net_shaper_binding *binding,
+       netdev_assert_locked(adapter->netdev);
+-      mutex_lock(&adapter->crit_lock);
+       if (handle->id >= adapter->num_active_queues)
+-              goto unlock;
++              return 0;
+       tx_ring = &adapter->tx_rings[handle->id];
+       tx_ring->q_shaper.bw_min = 0;
+@@ -5243,8 +5162,6 @@ static int iavf_shaper_del(struct net_shaper_binding *binding,
+       adapter->aq_required |= IAVF_FLAG_AQ_CONFIGURE_QUEUES_BW;
+-unlock:
+-      mutex_unlock(&adapter->crit_lock);
+       return 0;
+ }
+@@ -5505,10 +5422,6 @@ static int iavf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+               goto err_alloc_qos_cap;
+       }
+-      /* set up the locks for the AQ, do this only once in probe
+-       * and destroy them only once in remove
+-       */
+-      mutex_init(&adapter->crit_lock);
+       mutex_init(&hw->aq.asq_mutex);
+       mutex_init(&hw->aq.arq_mutex);
+@@ -5578,9 +5491,7 @@ static int iavf_suspend(struct device *dev_d)
+       running = netif_running(netdev);
+       if (running)
+               rtnl_lock();
+-
+       netdev_lock(netdev);
+-      mutex_lock(&adapter->crit_lock);
+       if (running)
+               iavf_down(adapter);
+@@ -5588,7 +5499,6 @@ static int iavf_suspend(struct device *dev_d)
+       iavf_free_misc_irq(adapter);
+       iavf_reset_interrupt_capability(adapter);
+-      mutex_unlock(&adapter->crit_lock);
+       netdev_unlock(netdev);
+       if (running)
+               rtnl_unlock();
+@@ -5668,20 +5578,20 @@ static void iavf_remove(struct pci_dev *pdev)
+        * There are flows where register/unregister netdev may race.
+        */
+       while (1) {
+-              mutex_lock(&adapter->crit_lock);
++              netdev_lock(netdev);
+               if (adapter->state == __IAVF_RUNNING ||
+                   adapter->state == __IAVF_DOWN ||
+                   adapter->state == __IAVF_INIT_FAILED) {
+-                      mutex_unlock(&adapter->crit_lock);
++                      netdev_unlock(netdev);
+                       break;
+               }
+               /* Simply return if we already went through iavf_shutdown */
+               if (adapter->state == __IAVF_REMOVE) {
+-                      mutex_unlock(&adapter->crit_lock);
++                      netdev_unlock(netdev);
+                       return;
+               }
+-              mutex_unlock(&adapter->crit_lock);
++              netdev_unlock(netdev);
+               usleep_range(500, 1000);
+       }
+       cancel_delayed_work_sync(&adapter->watchdog_task);
+@@ -5691,7 +5601,6 @@ static void iavf_remove(struct pci_dev *pdev)
+               unregister_netdev(netdev);
+       netdev_lock(netdev);
+-      mutex_lock(&adapter->crit_lock);
+       dev_info(&adapter->pdev->dev, "Removing device\n");
+       iavf_change_state(adapter, __IAVF_REMOVE);
+@@ -5707,9 +5616,11 @@ static void iavf_remove(struct pci_dev *pdev)
+       iavf_misc_irq_disable(adapter);
+       /* Shut down all the garbage mashers on the detention level */
++      netdev_unlock(netdev);
+       cancel_work_sync(&adapter->reset_task);
+       cancel_delayed_work_sync(&adapter->watchdog_task);
+       cancel_work_sync(&adapter->adminq_task);
++      netdev_lock(netdev);
+       adapter->aq_required = 0;
+       adapter->flags &= ~IAVF_FLAG_REINIT_ITR_NEEDED;
+@@ -5727,8 +5638,6 @@ static void iavf_remove(struct pci_dev *pdev)
+       /* destroy the locks only once, here */
+       mutex_destroy(&hw->aq.arq_mutex);
+       mutex_destroy(&hw->aq.asq_mutex);
+-      mutex_unlock(&adapter->crit_lock);
+-      mutex_destroy(&adapter->crit_lock);
+       netdev_unlock(netdev);
+       iounmap(hw->hw_addr);
+-- 
+2.39.5
+
diff --git a/queue-6.15/iavf-iavf_suspend-take-rtnl-before-netdev_lock.patch b/queue-6.15/iavf-iavf_suspend-take-rtnl-before-netdev_lock.patch
new file mode 100644 (file)
index 0000000..fa8c57a
--- /dev/null
@@ -0,0 +1,68 @@
+From 88d248f131e20a8040a7b4620cbe44ca2e4c7a63 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Apr 2025 12:23:16 +0200
+Subject: iavf: iavf_suspend(): take RTNL before netdev_lock()
+
+From: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+
+[ Upstream commit dba35a4bb4a3da5696f2a179b7d695dc3ea25fb8 ]
+
+Fix an obvious violation of lock ordering.
+Jakub's [1] added netdev_lock() call that is wrong ordered wrt RTNL,
+but the Fixes tag points to crit_lock being wrongly placed (by lockdep
+standards).
+
+Actual reason we got it wrong is dated back to critical section managed by
+pure flag checks, which is with us since the very beginning.
+
+[1] afc664987ab3 ("eth: iavf: extend the netdev_lock usage")
+
+Fixes: 5ac49f3c2702 ("iavf: use mutexes for locking of critical sections")
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/iavf/iavf_main.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index 6d7ba4d67a193..a77c726435281 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -5596,22 +5596,27 @@ static int iavf_suspend(struct device *dev_d)
+ {
+       struct net_device *netdev = dev_get_drvdata(dev_d);
+       struct iavf_adapter *adapter = netdev_priv(netdev);
++      bool running;
+       netif_device_detach(netdev);
++      running = netif_running(netdev);
++      if (running)
++              rtnl_lock();
++
+       netdev_lock(netdev);
+       mutex_lock(&adapter->crit_lock);
+-      if (netif_running(netdev)) {
+-              rtnl_lock();
++      if (running)
+               iavf_down(adapter);
+-              rtnl_unlock();
+-      }
++
+       iavf_free_misc_irq(adapter);
+       iavf_reset_interrupt_capability(adapter);
+       mutex_unlock(&adapter->crit_lock);
+       netdev_unlock(netdev);
++      if (running)
++              rtnl_unlock();
+       return 0;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/iavf-simplify-watchdog_task-in-terms-of-adminq-task-.patch b/queue-6.15/iavf-simplify-watchdog_task-in-terms-of-adminq-task-.patch
new file mode 100644 (file)
index 0000000..1ee7293
--- /dev/null
@@ -0,0 +1,72 @@
+From f0af4d754027a4b75a27c5a67e9d1313997fdec4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Apr 2025 12:23:18 +0200
+Subject: iavf: simplify watchdog_task in terms of adminq task scheduling
+
+From: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+
+[ Upstream commit ecb4cd0461accc446d20a7a167f39ed2fd5e9b0e ]
+
+Simplify the decision whether to schedule adminq task. The condition is
+the same, but it is executed in more scenarios.
+
+Note that movement of watchdog_done label makes this commit a bit
+surprising. (Hence not squashing it to anything bigger).
+
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Stable-dep-of: 120f28a6f314 ("iavf: get rid of the crit lock")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/iavf/iavf_main.c | 17 ++++++-----------
+ 1 file changed, 6 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index 2c6e033c73419..5efe44724d112 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -2934,6 +2934,7 @@ static void iavf_watchdog_task(struct work_struct *work)
+                       return;
+               }
++              msec_delay = 20;
+               goto restart_watchdog;
+       }
+@@ -3053,10 +3054,13 @@ static void iavf_watchdog_task(struct work_struct *work)
+               adapter->current_op = VIRTCHNL_OP_UNKNOWN;
+               dev_err(&adapter->pdev->dev, "Hardware reset detected\n");
+               iavf_schedule_reset(adapter, IAVF_FLAG_RESET_PENDING);
+-              msec_delay = 2000;
+-              goto watchdog_done;
+       }
++      if (adapter->aq_required)
++              msec_delay = 20;
++      else
++              msec_delay = 2000;
++watchdog_done:
+       mutex_unlock(&adapter->crit_lock);
+ restart_watchdog:
+       netdev_unlock(netdev);
+@@ -3064,15 +3068,6 @@ static void iavf_watchdog_task(struct work_struct *work)
+       /* note that we schedule a different task */
+       if (adapter->state >= __IAVF_DOWN)
+               queue_work(adapter->wq, &adapter->adminq_task);
+-      if (adapter->aq_required)
+-              msec_delay = 20;
+-      else
+-              msec_delay = 2000;
+-      goto skip_unlock;
+-watchdog_done:
+-      mutex_unlock(&adapter->crit_lock);
+-      netdev_unlock(netdev);
+-skip_unlock:
+       if (msec_delay != IAVF_NO_RESCHED)
+               queue_delayed_work(adapter->wq, &adapter->watchdog_task,
+-- 
+2.39.5
+
diff --git a/queue-6.15/iavf-sprinkle-netdev_assert_locked-annotations.patch b/queue-6.15/iavf-sprinkle-netdev_assert_locked-annotations.patch
new file mode 100644 (file)
index 0000000..e2a5bd1
--- /dev/null
@@ -0,0 +1,106 @@
+From 59da9057acaa50f19d321f4b7d5c3b818464f7cb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Apr 2025 12:23:20 +0200
+Subject: iavf: sprinkle netdev_assert_locked() annotations
+
+From: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+
+[ Upstream commit 05702b5c949bd46243181833d4726f4c5e95f5e3 ]
+
+Lockdep annotations help in general, but here it is extra good, as next
+commit will remove crit lock.
+
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Stable-dep-of: 120f28a6f314 ("iavf: get rid of the crit lock")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/iavf/iavf_ethtool.c |  6 ++++++
+ drivers/net/ethernet/intel/iavf/iavf_main.c    | 10 ++++++++++
+ 2 files changed, 16 insertions(+)
+
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
+index 288bb5b2e72ef..03d86fe80ad91 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
+@@ -4,6 +4,8 @@
+ #include <linux/bitfield.h>
+ #include <linux/uaccess.h>
++#include <net/netdev_lock.h>
++
+ /* ethtool support for iavf */
+ #include "iavf.h"
+@@ -1259,6 +1261,8 @@ static int iavf_add_fdir_ethtool(struct iavf_adapter *adapter, struct ethtool_rx
+       int count = 50;
+       int err;
++      netdev_assert_locked(adapter->netdev);
++
+       if (!(adapter->flags & IAVF_FLAG_FDIR_ENABLED))
+               return -EOPNOTSUPP;
+@@ -1440,6 +1444,8 @@ iavf_set_adv_rss_hash_opt(struct iavf_adapter *adapter,
+       u64 hash_flds;
+       u32 hdrs;
++      netdev_assert_locked(adapter->netdev);
++
+       if (!ADV_RSS_SUPPORT(adapter))
+               return -EOPNOTSUPP;
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index 4b6963ffaba5f..bf8c7baf2ab8a 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -1292,6 +1292,8 @@ static void iavf_configure(struct iavf_adapter *adapter)
+  **/
+ static void iavf_up_complete(struct iavf_adapter *adapter)
+ {
++      netdev_assert_locked(adapter->netdev);
++
+       iavf_change_state(adapter, __IAVF_RUNNING);
+       clear_bit(__IAVF_VSI_DOWN, adapter->vsi.state);
+@@ -1417,6 +1419,8 @@ void iavf_down(struct iavf_adapter *adapter)
+ {
+       struct net_device *netdev = adapter->netdev;
++      netdev_assert_locked(netdev);
++
+       if (adapter->state <= __IAVF_DOWN_PENDING)
+               return;
+@@ -3078,6 +3082,8 @@ static void iavf_disable_vf(struct iavf_adapter *adapter)
+       struct iavf_vlan_filter *fv, *fvtmp;
+       struct iavf_cloud_filter *cf, *cftmp;
++      netdev_assert_locked(adapter->netdev);
++
+       adapter->flags |= IAVF_FLAG_PF_COMMS_FAILED;
+       /* We don't use netif_running() because it may be true prior to
+@@ -5194,6 +5200,8 @@ iavf_shaper_set(struct net_shaper_binding *binding,
+       struct iavf_ring *tx_ring;
+       int ret = 0;
++      netdev_assert_locked(adapter->netdev);
++
+       mutex_lock(&adapter->crit_lock);
+       if (handle->id >= adapter->num_active_queues)
+               goto unlock;
+@@ -5222,6 +5230,8 @@ static int iavf_shaper_del(struct net_shaper_binding *binding,
+       struct iavf_adapter *adapter = netdev_priv(binding->netdev);
+       struct iavf_ring *tx_ring;
++      netdev_assert_locked(adapter->netdev);
++
+       mutex_lock(&adapter->crit_lock);
+       if (handle->id >= adapter->num_active_queues)
+               goto unlock;
+-- 
+2.39.5
+
diff --git a/queue-6.15/ib-cm-drop-lockdep-assert-and-warn-when-freeing-old-.patch b/queue-6.15/ib-cm-drop-lockdep-assert-and-warn-when-freeing-old-.patch
new file mode 100644 (file)
index 0000000..0972283
--- /dev/null
@@ -0,0 +1,42 @@
+From 45abb11e33423dfb9e03f440b0e511bcaf4b120e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Apr 2025 14:30:18 +0300
+Subject: IB/cm: Drop lockdep assert and WARN when freeing old msg
+
+From: Vlad Dumitrescu <vdumitrescu@nvidia.com>
+
+[ Upstream commit 7590649ee7af381a9d1153143026dec124c5798e ]
+
+The send completion handler can run after cm_id has advanced to another
+message.  The cm_id lock is not needed in this case, but a recent change
+re-used cm_free_priv_msg(), which asserts that the lock is held and
+WARNs if the cm_id's currently outstanding msg is different than the one
+being freed.
+
+Fixes: 1e5159219076 ("IB/cm: Do not hold reference on cm_id unless needed")
+Signed-off-by: Vlad Dumitrescu <vdumitrescu@nvidia.com>
+Reviewed-by: Sean Hefty <shefty@nvidia.com>
+Link: https://patch.msgid.link/0c364c29142f72b7875fdeba51f3c9bd6ca863ee.1745839788.git.leon@kernel.org
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/cm.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
+index effa53dd68002..e64cbd034a2a1 100644
+--- a/drivers/infiniband/core/cm.c
++++ b/drivers/infiniband/core/cm.c
+@@ -3786,7 +3786,8 @@ static void cm_process_send_error(struct cm_id_private *cm_id_priv,
+       spin_lock_irq(&cm_id_priv->lock);
+       if (msg != cm_id_priv->msg) {
+               spin_unlock_irq(&cm_id_priv->lock);
+-              cm_free_priv_msg(msg);
++              cm_free_msg(msg);
++              cm_deref_id(cm_id_priv);
+               return;
+       }
+       cm_free_priv_msg(msg);
+-- 
+2.39.5
+
diff --git a/queue-6.15/ib-cm-use-rwlock-for-mad-agent-lock.patch b/queue-6.15/ib-cm-use-rwlock-for-mad-agent-lock.patch
new file mode 100644 (file)
index 0000000..c579eb6
--- /dev/null
@@ -0,0 +1,117 @@
+From f3ffc71e67599639f45a8a40709df6542b4e6d87 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Feb 2025 17:56:12 +0000
+Subject: IB/cm: use rwlock for MAD agent lock
+
+From: Jacob Moroni <jmoroni@google.com>
+
+[ Upstream commit 4dab26bed543584577b64b36aadb8b5b165bf44f ]
+
+In workloads where there are many processes establishing connections using
+RDMA CM in parallel (large scale MPI), there can be heavy contention for
+mad_agent_lock in cm_alloc_msg.
+
+This contention can occur while inside of a spin_lock_irq region, leading
+to interrupts being disabled for extended durations on many
+cores. Furthermore, it leads to the serialization of rdma_create_ah calls,
+which has negative performance impacts for NICs which are capable of
+processing multiple address handle creations in parallel.
+
+The end result is the machine becoming unresponsive, hung task warnings,
+netdev TX timeouts, etc.
+
+Since the lock appears to be only for protection from cm_remove_one, it
+can be changed to a rwlock to resolve these issues.
+
+Reproducer:
+
+Server:
+  for i in $(seq 1 512); do
+    ucmatose -c 32 -p $((i + 5000)) &
+  done
+
+Client:
+  for i in $(seq 1 512); do
+    ucmatose -c 32 -p $((i + 5000)) -s 10.2.0.52 &
+  done
+
+Fixes: 76039ac9095f ("IB/cm: Protect cm_dev, cm_ports and mad_agent with kref and lock")
+Link: https://patch.msgid.link/r/20250220175612.2763122-1-jmoroni@google.com
+Signed-off-by: Jacob Moroni <jmoroni@google.com>
+Acked-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Zhu Yanjun <yanjun.zhu@linux.dev>
+Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/cm.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
+index 142170473e753..effa53dd68002 100644
+--- a/drivers/infiniband/core/cm.c
++++ b/drivers/infiniband/core/cm.c
+@@ -167,7 +167,7 @@ struct cm_port {
+ struct cm_device {
+       struct kref kref;
+       struct list_head list;
+-      spinlock_t mad_agent_lock;
++      rwlock_t mad_agent_lock;
+       struct ib_device *ib_device;
+       u8 ack_delay;
+       int going_down;
+@@ -285,7 +285,7 @@ static struct ib_mad_send_buf *cm_alloc_msg(struct cm_id_private *cm_id_priv)
+       if (!cm_id_priv->av.port)
+               return ERR_PTR(-EINVAL);
+-      spin_lock(&cm_id_priv->av.port->cm_dev->mad_agent_lock);
++      read_lock(&cm_id_priv->av.port->cm_dev->mad_agent_lock);
+       mad_agent = cm_id_priv->av.port->mad_agent;
+       if (!mad_agent) {
+               m = ERR_PTR(-EINVAL);
+@@ -311,7 +311,7 @@ static struct ib_mad_send_buf *cm_alloc_msg(struct cm_id_private *cm_id_priv)
+       m->ah = ah;
+ out:
+-      spin_unlock(&cm_id_priv->av.port->cm_dev->mad_agent_lock);
++      read_unlock(&cm_id_priv->av.port->cm_dev->mad_agent_lock);
+       return m;
+ }
+@@ -1297,10 +1297,10 @@ static __be64 cm_form_tid(struct cm_id_private *cm_id_priv)
+       if (!cm_id_priv->av.port)
+               return cpu_to_be64(low_tid);
+-      spin_lock(&cm_id_priv->av.port->cm_dev->mad_agent_lock);
++      read_lock(&cm_id_priv->av.port->cm_dev->mad_agent_lock);
+       if (cm_id_priv->av.port->mad_agent)
+               hi_tid = ((u64)cm_id_priv->av.port->mad_agent->hi_tid) << 32;
+-      spin_unlock(&cm_id_priv->av.port->cm_dev->mad_agent_lock);
++      read_unlock(&cm_id_priv->av.port->cm_dev->mad_agent_lock);
+       return cpu_to_be64(hi_tid | low_tid);
+ }
+@@ -4378,7 +4378,7 @@ static int cm_add_one(struct ib_device *ib_device)
+               return -ENOMEM;
+       kref_init(&cm_dev->kref);
+-      spin_lock_init(&cm_dev->mad_agent_lock);
++      rwlock_init(&cm_dev->mad_agent_lock);
+       cm_dev->ib_device = ib_device;
+       cm_dev->ack_delay = ib_device->attrs.local_ca_ack_delay;
+       cm_dev->going_down = 0;
+@@ -4494,9 +4494,9 @@ static void cm_remove_one(struct ib_device *ib_device, void *client_data)
+                * The above ensures no call paths from the work are running,
+                * the remaining paths all take the mad_agent_lock.
+                */
+-              spin_lock(&cm_dev->mad_agent_lock);
++              write_lock(&cm_dev->mad_agent_lock);
+               port->mad_agent = NULL;
+-              spin_unlock(&cm_dev->mad_agent_lock);
++              write_unlock(&cm_dev->mad_agent_lock);
+               ib_unregister_mad_agent(mad_agent);
+               ib_port_unregister_client_groups(ib_device, i,
+                                                cm_counter_groups);
+-- 
+2.39.5
+
diff --git a/queue-6.15/ice-create-new-tx-scheduler-nodes-for-new-queues-onl.patch b/queue-6.15/ice-create-new-tx-scheduler-nodes-for-new-queues-onl.patch
new file mode 100644 (file)
index 0000000..377e3dd
--- /dev/null
@@ -0,0 +1,72 @@
+From e274892d3d9db1cb1e6e657cd9ef0bc463331e6e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 May 2025 12:55:28 +0200
+Subject: ice: create new Tx scheduler nodes for new queues only
+
+From: Michal Kubiak <michal.kubiak@intel.com>
+
+[ Upstream commit 6fa2942578472c9cab13a8fc1dae0d830193e0a1 ]
+
+The current implementation of the Tx scheduler tree attempts
+to create nodes for all Tx queues, ignoring the fact that some
+queues may already exist in the tree. For example, if the VSI
+already has 128 Tx queues and the user requests for 16 new queues,
+the Tx scheduler will compute the tree for 272 queues (128 existing
+queues + 144 new queues), instead of 144 queues (128 existing queues
+and 16 new queues).
+Fix that by modifying the node count calculation algorithm to skip
+the queues that already exist in the tree.
+
+Fixes: 5513b920a4f7 ("ice: Update Tx scheduler tree for VSI multi-Tx queue support")
+Reviewed-by: Dawid Osuchowski <dawid.osuchowski@linux.intel.com>
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Michal Kubiak <michal.kubiak@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Tested-by: Jesse Brandeburg <jbrandeburg@cloudflare.com>
+Tested-by: Saritha Sanigani <sarithax.sanigani@intel.com> (A Contingent Worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_sched.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_sched.c b/drivers/net/ethernet/intel/ice/ice_sched.c
+index 6ca13c5dcb14e..6524875b34d39 100644
+--- a/drivers/net/ethernet/intel/ice/ice_sched.c
++++ b/drivers/net/ethernet/intel/ice/ice_sched.c
+@@ -1604,16 +1604,16 @@ ice_sched_get_agg_node(struct ice_port_info *pi, struct ice_sched_node *tc_node,
+ /**
+  * ice_sched_calc_vsi_child_nodes - calculate number of VSI child nodes
+  * @hw: pointer to the HW struct
+- * @num_qs: number of queues
++ * @num_new_qs: number of new queues that will be added to the tree
+  * @num_nodes: num nodes array
+  *
+  * This function calculates the number of VSI child nodes based on the
+  * number of queues.
+  */
+ static void
+-ice_sched_calc_vsi_child_nodes(struct ice_hw *hw, u16 num_qs, u16 *num_nodes)
++ice_sched_calc_vsi_child_nodes(struct ice_hw *hw, u16 num_new_qs, u16 *num_nodes)
+ {
+-      u16 num = num_qs;
++      u16 num = num_new_qs;
+       u8 i, qgl, vsil;
+       qgl = ice_sched_get_qgrp_layer(hw);
+@@ -1863,8 +1863,9 @@ ice_sched_update_vsi_child_nodes(struct ice_port_info *pi, u16 vsi_handle,
+                       return status;
+       }
+-      if (new_numqs)
+-              ice_sched_calc_vsi_child_nodes(hw, new_numqs, new_num_nodes);
++      ice_sched_calc_vsi_child_nodes(hw, new_numqs - prev_numqs,
++                                     new_num_nodes);
++
+       /* Keep the max number of queue configuration all the time. Update the
+        * tree only if number of queues > previous number of queues. This may
+        * leave some extra nodes in the tree if number of queues < previous
+-- 
+2.39.5
+
diff --git a/queue-6.15/ice-fix-rebuilding-the-tx-scheduler-tree-for-large-q.patch b/queue-6.15/ice-fix-rebuilding-the-tx-scheduler-tree-for-large-q.patch
new file mode 100644 (file)
index 0000000..8c8b438
--- /dev/null
@@ -0,0 +1,313 @@
+From f473fee289808c715d69d58232e3884448fdac38 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 May 2025 12:55:29 +0200
+Subject: ice: fix rebuilding the Tx scheduler tree for large queue counts
+
+From: Michal Kubiak <michal.kubiak@intel.com>
+
+[ Upstream commit 73145e6d81070d34a21431c9e0d7aaf2f29ca048 ]
+
+The current implementation of the Tx scheduler allows the tree to be
+rebuilt as the user adds more Tx queues to the VSI. In such a case,
+additional child nodes are added to the tree to support the new number
+of queues.
+Unfortunately, this algorithm does not take into account that the limit
+of the VSI support node may be exceeded, so an additional node in the
+VSI layer may be required to handle all the requested queues.
+
+Such a scenario occurs when adding XDP Tx queues on machines with many
+CPUs. Although the driver still respects the queue limit returned by
+the FW, the Tx scheduler was unable to add those queues to its tree
+and returned one of the errors below.
+
+Such a scenario occurs when adding XDP Tx queues on machines with many
+CPUs (e.g. at least 321 CPUs, if there is already 128 Tx/Rx queue pairs).
+Although the driver still respects the queue limit returned by the FW,
+the Tx scheduler was unable to add those queues to its tree and returned
+the following errors:
+
+     Failed VSI LAN queue config for XDP, error: -5
+or:
+     Failed to set LAN Tx queue context, error: -22
+
+Fix this problem by extending the tree rebuild algorithm to check if the
+current VSI node can support the requested number of queues. If it
+cannot, create as many additional VSI support nodes as necessary to
+handle all the required Tx queues. Symmetrically, adjust the VSI node
+removal algorithm to remove all nodes associated with the given VSI.
+Also, make the search for the next free VSI node more restrictive. That is,
+add queue group nodes only to the VSI support nodes that have a matching
+VSI handle.
+Finally, fix the comment describing the tree update algorithm to better
+reflect the current scenario.
+
+Fixes: b0153fdd7e8a ("ice: update VSI config dynamically")
+Reviewed-by: Dawid Osuchowski <dawid.osuchowski@linux.intel.com>
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Signed-off-by: Michal Kubiak <michal.kubiak@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Tested-by: Jesse Brandeburg <jbrandeburg@cloudflare.com>
+Tested-by: Saritha Sanigani <sarithax.sanigani@intel.com> (A Contingent Worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_sched.c | 170 +++++++++++++++++----
+ 1 file changed, 142 insertions(+), 28 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_sched.c b/drivers/net/ethernet/intel/ice/ice_sched.c
+index 6524875b34d39..d9d09296d1d48 100644
+--- a/drivers/net/ethernet/intel/ice/ice_sched.c
++++ b/drivers/net/ethernet/intel/ice/ice_sched.c
+@@ -84,6 +84,27 @@ ice_sched_find_node_by_teid(struct ice_sched_node *start_node, u32 teid)
+       return NULL;
+ }
++/**
++ * ice_sched_find_next_vsi_node - find the next node for a given VSI
++ * @vsi_node: VSI support node to start search with
++ *
++ * Return: Next VSI support node, or NULL.
++ *
++ * The function returns a pointer to the next node from the VSI layer
++ * assigned to the given VSI, or NULL if there is no such a node.
++ */
++static struct ice_sched_node *
++ice_sched_find_next_vsi_node(struct ice_sched_node *vsi_node)
++{
++      unsigned int vsi_handle = vsi_node->vsi_handle;
++
++      while ((vsi_node = vsi_node->sibling) != NULL)
++              if (vsi_node->vsi_handle == vsi_handle)
++                      break;
++
++      return vsi_node;
++}
++
+ /**
+  * ice_aqc_send_sched_elem_cmd - send scheduling elements cmd
+  * @hw: pointer to the HW struct
+@@ -1084,8 +1105,10 @@ ice_sched_add_nodes_to_layer(struct ice_port_info *pi,
+               if (parent->num_children < max_child_nodes) {
+                       new_num_nodes = max_child_nodes - parent->num_children;
+               } else {
+-                      /* This parent is full, try the next sibling */
+-                      parent = parent->sibling;
++                      /* This parent is full,
++                       * try the next available sibling.
++                       */
++                      parent = ice_sched_find_next_vsi_node(parent);
+                       /* Don't modify the first node TEID memory if the
+                        * first node was added already in the above call.
+                        * Instead send some temp memory for all other
+@@ -1528,12 +1551,23 @@ ice_sched_get_free_qparent(struct ice_port_info *pi, u16 vsi_handle, u8 tc,
+       /* get the first queue group node from VSI sub-tree */
+       qgrp_node = ice_sched_get_first_node(pi, vsi_node, qgrp_layer);
+       while (qgrp_node) {
++              struct ice_sched_node *next_vsi_node;
++
+               /* make sure the qgroup node is part of the VSI subtree */
+               if (ice_sched_find_node_in_subtree(pi->hw, vsi_node, qgrp_node))
+                       if (qgrp_node->num_children < max_children &&
+                           qgrp_node->owner == owner)
+                               break;
+               qgrp_node = qgrp_node->sibling;
++              if (qgrp_node)
++                      continue;
++
++              next_vsi_node = ice_sched_find_next_vsi_node(vsi_node);
++              if (!next_vsi_node)
++                      break;
++
++              vsi_node = next_vsi_node;
++              qgrp_node = ice_sched_get_first_node(pi, vsi_node, qgrp_layer);
+       }
+       /* Select the best queue group */
+@@ -1779,7 +1813,11 @@ ice_sched_add_vsi_support_nodes(struct ice_port_info *pi, u16 vsi_handle,
+               if (!parent)
+                       return -EIO;
+-              if (i == vsil)
++              /* Do not modify the VSI handle for already existing VSI nodes,
++               * (if no new VSI node was added to the tree).
++               * Assign the VSI handle only to newly added VSI nodes.
++               */
++              if (i == vsil && num_added)
+                       parent->vsi_handle = vsi_handle;
+       }
+@@ -1812,6 +1850,41 @@ ice_sched_add_vsi_to_topo(struct ice_port_info *pi, u16 vsi_handle, u8 tc)
+                                              num_nodes);
+ }
++/**
++ * ice_sched_recalc_vsi_support_nodes - recalculate VSI support nodes count
++ * @hw: pointer to the HW struct
++ * @vsi_node: pointer to the leftmost VSI node that needs to be extended
++ * @new_numqs: new number of queues that has to be handled by the VSI
++ * @new_num_nodes: pointer to nodes count table to modify the VSI layer entry
++ *
++ * This function recalculates the number of supported nodes that need to
++ * be added after adding more Tx queues for a given VSI.
++ * The number of new VSI support nodes that shall be added will be saved
++ * to the @new_num_nodes table for the VSI layer.
++ */
++static void
++ice_sched_recalc_vsi_support_nodes(struct ice_hw *hw,
++                                 struct ice_sched_node *vsi_node,
++                                 unsigned int new_numqs, u16 *new_num_nodes)
++{
++      u32 vsi_nodes_cnt = 1;
++      u32 max_queue_cnt = 1;
++      u32 qgl, vsil;
++
++      qgl = ice_sched_get_qgrp_layer(hw);
++      vsil = ice_sched_get_vsi_layer(hw);
++
++      for (u32 i = vsil; i <= qgl; i++)
++              max_queue_cnt *= hw->max_children[i];
++
++      while ((vsi_node = ice_sched_find_next_vsi_node(vsi_node)) != NULL)
++              vsi_nodes_cnt++;
++
++      if (new_numqs > (max_queue_cnt * vsi_nodes_cnt))
++              new_num_nodes[vsil] = DIV_ROUND_UP(new_numqs, max_queue_cnt) -
++                                    vsi_nodes_cnt;
++}
++
+ /**
+  * ice_sched_update_vsi_child_nodes - update VSI child nodes
+  * @pi: port information structure
+@@ -1863,16 +1936,25 @@ ice_sched_update_vsi_child_nodes(struct ice_port_info *pi, u16 vsi_handle,
+                       return status;
+       }
++      ice_sched_recalc_vsi_support_nodes(hw, vsi_node,
++                                         new_numqs, new_num_nodes);
+       ice_sched_calc_vsi_child_nodes(hw, new_numqs - prev_numqs,
+                                      new_num_nodes);
+-      /* Keep the max number of queue configuration all the time. Update the
+-       * tree only if number of queues > previous number of queues. This may
++      /* Never decrease the number of queues in the tree. Update the tree
++       * only if number of queues > previous number of queues. This may
+        * leave some extra nodes in the tree if number of queues < previous
+        * number but that wouldn't harm anything. Removing those extra nodes
+        * may complicate the code if those nodes are part of SRL or
+        * individually rate limited.
++       * Also, add the required VSI support nodes if the existing ones cannot
++       * handle the requested new number of queues.
+        */
++      status = ice_sched_add_vsi_support_nodes(pi, vsi_handle, tc_node,
++                                               new_num_nodes);
++      if (status)
++              return status;
++
+       status = ice_sched_add_vsi_child_nodes(pi, vsi_handle, tc_node,
+                                              new_num_nodes, owner);
+       if (status)
+@@ -2013,6 +2095,58 @@ static bool ice_sched_is_leaf_node_present(struct ice_sched_node *node)
+       return (node->info.data.elem_type == ICE_AQC_ELEM_TYPE_LEAF);
+ }
++/**
++ * ice_sched_rm_vsi_subtree - remove all nodes assigned to a given VSI
++ * @pi: port information structure
++ * @vsi_node: pointer to the leftmost node of the VSI to be removed
++ * @owner: LAN or RDMA
++ * @tc: TC number
++ *
++ * Return: Zero in case of success, or -EBUSY if the VSI has leaf nodes in TC.
++ *
++ * This function removes all the VSI support nodes associated with a given VSI
++ * and its LAN or RDMA children nodes from the scheduler tree.
++ */
++static int
++ice_sched_rm_vsi_subtree(struct ice_port_info *pi,
++                       struct ice_sched_node *vsi_node, u8 owner, u8 tc)
++{
++      u16 vsi_handle = vsi_node->vsi_handle;
++      bool all_vsi_nodes_removed = true;
++      int j = 0;
++
++      while (vsi_node) {
++              struct ice_sched_node *next_vsi_node;
++
++              if (ice_sched_is_leaf_node_present(vsi_node)) {
++                      ice_debug(pi->hw, ICE_DBG_SCHED, "VSI has leaf nodes in TC %d\n", tc);
++                      return -EBUSY;
++              }
++              while (j < vsi_node->num_children) {
++                      if (vsi_node->children[j]->owner == owner)
++                              ice_free_sched_node(pi, vsi_node->children[j]);
++                      else
++                              j++;
++              }
++
++              next_vsi_node = ice_sched_find_next_vsi_node(vsi_node);
++
++              /* remove the VSI if it has no children */
++              if (!vsi_node->num_children)
++                      ice_free_sched_node(pi, vsi_node);
++              else
++                      all_vsi_nodes_removed = false;
++
++              vsi_node = next_vsi_node;
++      }
++
++      /* clean up aggregator related VSI info if any */
++      if (all_vsi_nodes_removed)
++              ice_sched_rm_agg_vsi_info(pi, vsi_handle);
++
++      return 0;
++}
++
+ /**
+  * ice_sched_rm_vsi_cfg - remove the VSI and its children nodes
+  * @pi: port information structure
+@@ -2039,7 +2173,6 @@ ice_sched_rm_vsi_cfg(struct ice_port_info *pi, u16 vsi_handle, u8 owner)
+       ice_for_each_traffic_class(i) {
+               struct ice_sched_node *vsi_node, *tc_node;
+-              u8 j = 0;
+               tc_node = ice_sched_get_tc_node(pi, i);
+               if (!tc_node)
+@@ -2049,31 +2182,12 @@ ice_sched_rm_vsi_cfg(struct ice_port_info *pi, u16 vsi_handle, u8 owner)
+               if (!vsi_node)
+                       continue;
+-              if (ice_sched_is_leaf_node_present(vsi_node)) {
+-                      ice_debug(pi->hw, ICE_DBG_SCHED, "VSI has leaf nodes in TC %d\n", i);
+-                      status = -EBUSY;
++              status = ice_sched_rm_vsi_subtree(pi, vsi_node, owner, i);
++              if (status)
+                       goto exit_sched_rm_vsi_cfg;
+-              }
+-              while (j < vsi_node->num_children) {
+-                      if (vsi_node->children[j]->owner == owner) {
+-                              ice_free_sched_node(pi, vsi_node->children[j]);
+-                              /* reset the counter again since the num
+-                               * children will be updated after node removal
+-                               */
+-                              j = 0;
+-                      } else {
+-                              j++;
+-                      }
+-              }
+-              /* remove the VSI if it has no children */
+-              if (!vsi_node->num_children) {
+-                      ice_free_sched_node(pi, vsi_node);
+-                      vsi_ctx->sched.vsi_node[i] = NULL;
++              vsi_ctx->sched.vsi_node[i] = NULL;
+-                      /* clean up aggregator related VSI info if any */
+-                      ice_sched_rm_agg_vsi_info(pi, vsi_handle);
+-              }
+               if (owner == ICE_SCHED_NODE_OWNER_LAN)
+                       vsi_ctx->sched.max_lanq[i] = 0;
+               else
+-- 
+2.39.5
+
diff --git a/queue-6.15/ice-fix-tx-scheduler-error-handling-in-xdp-callback.patch b/queue-6.15/ice-fix-tx-scheduler-error-handling-in-xdp-callback.patch
new file mode 100644 (file)
index 0000000..2a207f4
--- /dev/null
@@ -0,0 +1,182 @@
+From aa8802d998061f96041226f40b373ff9376a0fde Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 May 2025 12:55:27 +0200
+Subject: ice: fix Tx scheduler error handling in XDP callback
+
+From: Michal Kubiak <michal.kubiak@intel.com>
+
+[ Upstream commit 0153f36041b8e52019ebfa8629c13bf8f9b0a951 ]
+
+When the XDP program is loaded, the XDP callback adds new Tx queues.
+This means that the callback must update the Tx scheduler with the new
+queue number. In the event of a Tx scheduler failure, the XDP callback
+should also fail and roll back any changes previously made for XDP
+preparation.
+
+The previous implementation had a bug that not all changes made by the
+XDP callback were rolled back. This caused the crash with the following
+call trace:
+
+[  +9.549584] ice 0000:ca:00.0: Failed VSI LAN queue config for XDP, error: -5
+[  +0.382335] Oops: general protection fault, probably for non-canonical address 0x50a2250a90495525: 0000 [#1] SMP NOPTI
+[  +0.010710] CPU: 103 UID: 0 PID: 0 Comm: swapper/103 Not tainted 6.14.0-net-next-mar-31+ #14 PREEMPT(voluntary)
+[  +0.010175] Hardware name: Intel Corporation M50CYP2SBSTD/M50CYP2SBSTD, BIOS SE5C620.86B.01.01.0005.2202160810 02/16/2022
+[  +0.010946] RIP: 0010:__ice_update_sample+0x39/0xe0 [ice]
+
+[...]
+
+[  +0.002715] Call Trace:
+[  +0.002452]  <IRQ>
+[  +0.002021]  ? __die_body.cold+0x19/0x29
+[  +0.003922]  ? die_addr+0x3c/0x60
+[  +0.003319]  ? exc_general_protection+0x17c/0x400
+[  +0.004707]  ? asm_exc_general_protection+0x26/0x30
+[  +0.004879]  ? __ice_update_sample+0x39/0xe0 [ice]
+[  +0.004835]  ice_napi_poll+0x665/0x680 [ice]
+[  +0.004320]  __napi_poll+0x28/0x190
+[  +0.003500]  net_rx_action+0x198/0x360
+[  +0.003752]  ? update_rq_clock+0x39/0x220
+[  +0.004013]  handle_softirqs+0xf1/0x340
+[  +0.003840]  ? sched_clock_cpu+0xf/0x1f0
+[  +0.003925]  __irq_exit_rcu+0xc2/0xe0
+[  +0.003665]  common_interrupt+0x85/0xa0
+[  +0.003839]  </IRQ>
+[  +0.002098]  <TASK>
+[  +0.002106]  asm_common_interrupt+0x26/0x40
+[  +0.004184] RIP: 0010:cpuidle_enter_state+0xd3/0x690
+
+Fix this by performing the missing unmapping of XDP queues from
+q_vectors and setting the XDP rings pointer back to NULL after all those
+queues are released.
+Also, add an immediate exit from the XDP callback in case of ring
+preparation failure.
+
+Fixes: efc2214b6047 ("ice: Add support for XDP")
+Reviewed-by: Dawid Osuchowski <dawid.osuchowski@linux.intel.com>
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Michal Kubiak <michal.kubiak@intel.com>
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Tested-by: Jesse Brandeburg <jbrandeburg@cloudflare.com>
+Tested-by: Saritha Sanigani <sarithax.sanigani@intel.com> (A Contingent Worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_main.c | 47 ++++++++++++++++-------
+ 1 file changed, 33 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
+index d390157b59fe1..82d472f1d781a 100644
+--- a/drivers/net/ethernet/intel/ice/ice_main.c
++++ b/drivers/net/ethernet/intel/ice/ice_main.c
+@@ -2740,6 +2740,27 @@ void ice_map_xdp_rings(struct ice_vsi *vsi)
+       }
+ }
++/**
++ * ice_unmap_xdp_rings - Unmap XDP rings from interrupt vectors
++ * @vsi: the VSI with XDP rings being unmapped
++ */
++static void ice_unmap_xdp_rings(struct ice_vsi *vsi)
++{
++      int v_idx;
++
++      ice_for_each_q_vector(vsi, v_idx) {
++              struct ice_q_vector *q_vector = vsi->q_vectors[v_idx];
++              struct ice_tx_ring *ring;
++
++              ice_for_each_tx_ring(ring, q_vector->tx)
++                      if (!ring->tx_buf || !ice_ring_is_xdp(ring))
++                              break;
++
++              /* restore the value of last node prior to XDP setup */
++              q_vector->tx.tx_ring = ring;
++      }
++}
++
+ /**
+  * ice_prepare_xdp_rings - Allocate, configure and setup Tx rings for XDP
+  * @vsi: VSI to bring up Tx rings used by XDP
+@@ -2803,7 +2824,7 @@ int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog,
+       if (status) {
+               dev_err(dev, "Failed VSI LAN queue config for XDP, error: %d\n",
+                       status);
+-              goto clear_xdp_rings;
++              goto unmap_xdp_rings;
+       }
+       /* assign the prog only when it's not already present on VSI;
+@@ -2819,6 +2840,8 @@ int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog,
+               ice_vsi_assign_bpf_prog(vsi, prog);
+       return 0;
++unmap_xdp_rings:
++      ice_unmap_xdp_rings(vsi);
+ clear_xdp_rings:
+       ice_for_each_xdp_txq(vsi, i)
+               if (vsi->xdp_rings[i]) {
+@@ -2835,6 +2858,8 @@ int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog,
+       mutex_unlock(&pf->avail_q_mutex);
+       devm_kfree(dev, vsi->xdp_rings);
++      vsi->xdp_rings = NULL;
++
+       return -ENOMEM;
+ }
+@@ -2850,7 +2875,7 @@ int ice_destroy_xdp_rings(struct ice_vsi *vsi, enum ice_xdp_cfg cfg_type)
+ {
+       u16 max_txqs[ICE_MAX_TRAFFIC_CLASS] = { 0 };
+       struct ice_pf *pf = vsi->back;
+-      int i, v_idx;
++      int i;
+       /* q_vectors are freed in reset path so there's no point in detaching
+        * rings
+@@ -2858,17 +2883,7 @@ int ice_destroy_xdp_rings(struct ice_vsi *vsi, enum ice_xdp_cfg cfg_type)
+       if (cfg_type == ICE_XDP_CFG_PART)
+               goto free_qmap;
+-      ice_for_each_q_vector(vsi, v_idx) {
+-              struct ice_q_vector *q_vector = vsi->q_vectors[v_idx];
+-              struct ice_tx_ring *ring;
+-
+-              ice_for_each_tx_ring(ring, q_vector->tx)
+-                      if (!ring->tx_buf || !ice_ring_is_xdp(ring))
+-                              break;
+-
+-              /* restore the value of last node prior to XDP setup */
+-              q_vector->tx.tx_ring = ring;
+-      }
++      ice_unmap_xdp_rings(vsi);
+ free_qmap:
+       mutex_lock(&pf->avail_q_mutex);
+@@ -3013,11 +3028,14 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog,
+               xdp_ring_err = ice_vsi_determine_xdp_res(vsi);
+               if (xdp_ring_err) {
+                       NL_SET_ERR_MSG_MOD(extack, "Not enough Tx resources for XDP");
++                      goto resume_if;
+               } else {
+                       xdp_ring_err = ice_prepare_xdp_rings(vsi, prog,
+                                                            ICE_XDP_CFG_FULL);
+-                      if (xdp_ring_err)
++                      if (xdp_ring_err) {
+                               NL_SET_ERR_MSG_MOD(extack, "Setting up XDP Tx resources failed");
++                              goto resume_if;
++                      }
+               }
+               xdp_features_set_redirect_target(vsi->netdev, true);
+               /* reallocate Rx queues that are used for zero-copy */
+@@ -3035,6 +3053,7 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog,
+                       NL_SET_ERR_MSG_MOD(extack, "Freeing XDP Rx resources failed");
+       }
++resume_if:
+       if (if_running)
+               ret = ice_up(vsi);
+-- 
+2.39.5
+
diff --git a/queue-6.15/idpf-avoid-mailbox-timeout-delays-during-reset.patch b/queue-6.15/idpf-avoid-mailbox-timeout-delays-during-reset.patch
new file mode 100644 (file)
index 0000000..a63f9c8
--- /dev/null
@@ -0,0 +1,101 @@
+From 72d61fd7a8880dcfac8f0a586e34f015aa8cb80f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 May 2025 11:47:15 -0700
+Subject: idpf: avoid mailbox timeout delays during reset
+
+From: Emil Tantilov <emil.s.tantilov@intel.com>
+
+[ Upstream commit 9dc63d8ff182150d7d7b318ab9389702a2c0a292 ]
+
+Mailbox operations are not possible while the driver is in reset.
+Operations that require MBX exchange with the control plane will result
+in long delays if executed while a reset is in progress:
+
+ethtool -L <inf> combined 8& echo 1 > /sys/class/net/<inf>/device/reset
+idpf 0000:83:00.0: HW reset detected
+idpf 0000:83:00.0: Device HW Reset initiated
+idpf 0000:83:00.0: Transaction timed-out (op:504 cookie:be00 vc_op:504 salt:be timeout:2000ms)
+idpf 0000:83:00.0: Transaction timed-out (op:508 cookie:bf00 vc_op:508 salt:bf timeout:2000ms)
+idpf 0000:83:00.0: Transaction timed-out (op:512 cookie:c000 vc_op:512 salt:c0 timeout:2000ms)
+idpf 0000:83:00.0: Transaction timed-out (op:510 cookie:c100 vc_op:510 salt:c1 timeout:2000ms)
+idpf 0000:83:00.0: Transaction timed-out (op:509 cookie:c200 vc_op:509 salt:c2 timeout:60000ms)
+idpf 0000:83:00.0: Transaction timed-out (op:509 cookie:c300 vc_op:509 salt:c3 timeout:60000ms)
+idpf 0000:83:00.0: Transaction timed-out (op:505 cookie:c400 vc_op:505 salt:c4 timeout:60000ms)
+idpf 0000:83:00.0: Failed to configure queues for vport 0, -62
+
+Disable mailbox communication in case of a reset, unless it's done during
+a driver load, where the virtchnl operations are needed to configure the
+device.
+
+Fixes: 8077c727561aa ("idpf: add controlq init and reset checks")
+Co-developed-by: Joshua Hay <joshua.a.hay@intel.com>
+Signed-off-by: Joshua Hay <joshua.a.hay@intel.com>
+Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
+Reviewed-by: Ahmed Zaki <ahmed.zaki@intel.com>
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Tested-by: Samuel Salin <Samuel.salin@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/idpf/idpf_lib.c     | 18 +++++++++++++-----
+ .../net/ethernet/intel/idpf/idpf_virtchnl.c    |  2 +-
+ .../net/ethernet/intel/idpf/idpf_virtchnl.h    |  1 +
+ 3 files changed, 15 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_lib.c b/drivers/net/ethernet/intel/idpf/idpf_lib.c
+index 3a033ce19cda2..2ed801398971c 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_lib.c
++++ b/drivers/net/ethernet/intel/idpf/idpf_lib.c
+@@ -1816,11 +1816,19 @@ void idpf_vc_event_task(struct work_struct *work)
+       if (test_bit(IDPF_REMOVE_IN_PROG, adapter->flags))
+               return;
+-      if (test_bit(IDPF_HR_FUNC_RESET, adapter->flags) ||
+-          test_bit(IDPF_HR_DRV_LOAD, adapter->flags)) {
+-              set_bit(IDPF_HR_RESET_IN_PROG, adapter->flags);
+-              idpf_init_hard_reset(adapter);
+-      }
++      if (test_bit(IDPF_HR_FUNC_RESET, adapter->flags))
++              goto func_reset;
++
++      if (test_bit(IDPF_HR_DRV_LOAD, adapter->flags))
++              goto drv_load;
++
++      return;
++
++func_reset:
++      idpf_vc_xn_shutdown(adapter->vcxn_mngr);
++drv_load:
++      set_bit(IDPF_HR_RESET_IN_PROG, adapter->flags);
++      idpf_init_hard_reset(adapter);
+ }
+ /**
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
+index 3d2413b8684fc..5d2ca007f6828 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
++++ b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
+@@ -376,7 +376,7 @@ static void idpf_vc_xn_init(struct idpf_vc_xn_manager *vcxn_mngr)
+  * All waiting threads will be woken-up and their transaction aborted. Further
+  * operations on that object will fail.
+  */
+-static void idpf_vc_xn_shutdown(struct idpf_vc_xn_manager *vcxn_mngr)
++void idpf_vc_xn_shutdown(struct idpf_vc_xn_manager *vcxn_mngr)
+ {
+       int i;
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.h b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.h
+index 83da5d8da56bf..23271cf0a2160 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.h
++++ b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.h
+@@ -66,5 +66,6 @@ int idpf_send_get_stats_msg(struct idpf_vport *vport);
+ int idpf_send_set_sriov_vfs_msg(struct idpf_adapter *adapter, u16 num_vfs);
+ int idpf_send_get_set_rss_key_msg(struct idpf_vport *vport, bool get);
+ int idpf_send_get_set_rss_lut_msg(struct idpf_vport *vport, bool get);
++void idpf_vc_xn_shutdown(struct idpf_vc_xn_manager *vcxn_mngr);
+ #endif /* _IDPF_VIRTCHNL_H_ */
+-- 
+2.39.5
+
diff --git a/queue-6.15/idpf-fix-a-race-in-txq-wakeup.patch b/queue-6.15/idpf-fix-a-race-in-txq-wakeup.patch
new file mode 100644 (file)
index 0000000..0f23dcc
--- /dev/null
@@ -0,0 +1,183 @@
+From a027ef4584ad8b0cd06ca8d87d7519ce31f1a372 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 May 2025 17:06:17 +0000
+Subject: idpf: fix a race in txq wakeup
+
+From: Brian Vazquez <brianvv@google.com>
+
+[ Upstream commit 7292af042bcf22e2c18b96ed250f78498a5b28ab ]
+
+Add a helper function to correctly handle the lockless
+synchronization when the sender needs to block. The paradigm is
+
+        if (no_resources()) {
+                stop_queue();
+                barrier();
+                if (!no_resources())
+                        restart_queue();
+        }
+
+netif_subqueue_maybe_stop already handles the paradigm correctly, but
+the code split the check for resources in three parts, the first one
+(descriptors) followed the protocol, but the other two (completions and
+tx_buf) were only doing the first part and so race prone.
+
+Luckily netif_subqueue_maybe_stop macro already allows you to use a
+function to evaluate the start/stop conditions so the fix only requires
+the right helper function to evaluate all the conditions at once.
+
+The patch removes idpf_tx_maybe_stop_common since it's no longer needed
+and instead adjusts separately the conditions for singleq and splitq.
+
+Note that idpf_tx_buf_hw_update doesn't need to check for resources
+since that will be covered in idpf_tx_splitq_frame.
+
+To reproduce:
+
+Reduce the threshold for pending completions to increase the chances of
+hitting this pause by changing your kernel:
+
+drivers/net/ethernet/intel/idpf/idpf_txrx.h
+
+-#define IDPF_TX_COMPLQ_OVERFLOW_THRESH(txcq)   ((txcq)->desc_count >> 1)
++#define IDPF_TX_COMPLQ_OVERFLOW_THRESH(txcq)   ((txcq)->desc_count >> 4)
+
+Use pktgen to force the host to push small pkts very aggressively:
+
+./pktgen_sample02_multiqueue.sh -i eth1 -s 100 -6 -d $IP -m $MAC \
+  -p 10000-10000 -t 16 -n 0 -v -x -c 64
+
+Fixes: 6818c4d5b3c2 ("idpf: add splitq start_xmit")
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Madhu Chittim <madhu.chittim@intel.com>
+Signed-off-by: Josh Hay <joshua.a.hay@intel.com>
+Signed-off-by: Brian Vazquez <brianvv@google.com>
+Signed-off-by: Luigi Rizzo <lrizzo@google.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Tested-by: Samuel Salin <Samuel.salin@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/intel/idpf/idpf_singleq_txrx.c   |  9 ++--
+ drivers/net/ethernet/intel/idpf/idpf_txrx.c   | 45 +++++++------------
+ drivers/net/ethernet/intel/idpf/idpf_txrx.h   |  8 ----
+ 3 files changed, 22 insertions(+), 40 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c b/drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c
+index eae1b6f474e62..6ade54e213259 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c
++++ b/drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c
+@@ -362,17 +362,18 @@ netdev_tx_t idpf_tx_singleq_frame(struct sk_buff *skb,
+ {
+       struct idpf_tx_offload_params offload = { };
+       struct idpf_tx_buf *first;
++      int csum, tso, needed;
+       unsigned int count;
+       __be16 protocol;
+-      int csum, tso;
+       count = idpf_tx_desc_count_required(tx_q, skb);
+       if (unlikely(!count))
+               return idpf_tx_drop_skb(tx_q, skb);
+-      if (idpf_tx_maybe_stop_common(tx_q,
+-                                    count + IDPF_TX_DESCS_PER_CACHE_LINE +
+-                                    IDPF_TX_DESCS_FOR_CTX)) {
++      needed = count + IDPF_TX_DESCS_PER_CACHE_LINE + IDPF_TX_DESCS_FOR_CTX;
++      if (!netif_subqueue_maybe_stop(tx_q->netdev, tx_q->idx,
++                                     IDPF_DESC_UNUSED(tx_q),
++                                     needed, needed)) {
+               idpf_tx_buf_hw_update(tx_q, tx_q->next_to_use, false);
+               u64_stats_update_begin(&tx_q->stats_sync);
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.c b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+index 2d5f5c9f91ce1..aa16e4c1edbb8 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c
++++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+@@ -2132,6 +2132,19 @@ void idpf_tx_splitq_build_flow_desc(union idpf_tx_flex_desc *desc,
+       desc->flow.qw1.compl_tag = cpu_to_le16(params->compl_tag);
+ }
++/* Global conditions to tell whether the txq (and related resources)
++ * has room to allow the use of "size" descriptors.
++ */
++static int idpf_txq_has_room(struct idpf_tx_queue *tx_q, u32 size)
++{
++      if (IDPF_DESC_UNUSED(tx_q) < size ||
++          IDPF_TX_COMPLQ_PENDING(tx_q->txq_grp) >
++              IDPF_TX_COMPLQ_OVERFLOW_THRESH(tx_q->txq_grp->complq) ||
++          IDPF_TX_BUF_RSV_LOW(tx_q))
++              return 0;
++      return 1;
++}
++
+ /**
+  * idpf_tx_maybe_stop_splitq - 1st level check for Tx splitq stop conditions
+  * @tx_q: the queue to be checked
+@@ -2142,29 +2155,11 @@ void idpf_tx_splitq_build_flow_desc(union idpf_tx_flex_desc *desc,
+ static int idpf_tx_maybe_stop_splitq(struct idpf_tx_queue *tx_q,
+                                    unsigned int descs_needed)
+ {
+-      if (idpf_tx_maybe_stop_common(tx_q, descs_needed))
+-              goto out;
+-
+-      /* If there are too many outstanding completions expected on the
+-       * completion queue, stop the TX queue to give the device some time to
+-       * catch up
+-       */
+-      if (unlikely(IDPF_TX_COMPLQ_PENDING(tx_q->txq_grp) >
+-                   IDPF_TX_COMPLQ_OVERFLOW_THRESH(tx_q->txq_grp->complq)))
+-              goto splitq_stop;
+-
+-      /* Also check for available book keeping buffers; if we are low, stop
+-       * the queue to wait for more completions
+-       */
+-      if (unlikely(IDPF_TX_BUF_RSV_LOW(tx_q)))
+-              goto splitq_stop;
+-
+-      return 0;
+-
+-splitq_stop:
+-      netif_stop_subqueue(tx_q->netdev, tx_q->idx);
++      if (netif_subqueue_maybe_stop(tx_q->netdev, tx_q->idx,
++                                    idpf_txq_has_room(tx_q, descs_needed),
++                                    1, 1))
++              return 0;
+-out:
+       u64_stats_update_begin(&tx_q->stats_sync);
+       u64_stats_inc(&tx_q->q_stats.q_busy);
+       u64_stats_update_end(&tx_q->stats_sync);
+@@ -2190,12 +2185,6 @@ void idpf_tx_buf_hw_update(struct idpf_tx_queue *tx_q, u32 val,
+       nq = netdev_get_tx_queue(tx_q->netdev, tx_q->idx);
+       tx_q->next_to_use = val;
+-      if (idpf_tx_maybe_stop_common(tx_q, IDPF_TX_DESC_NEEDED)) {
+-              u64_stats_update_begin(&tx_q->stats_sync);
+-              u64_stats_inc(&tx_q->q_stats.q_busy);
+-              u64_stats_update_end(&tx_q->stats_sync);
+-      }
+-
+       /* Force memory writes to complete before letting h/w
+        * know there are new descriptors to fetch.  (Only
+        * applicable for weak-ordered memory model archs,
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.h b/drivers/net/ethernet/intel/idpf/idpf_txrx.h
+index b029f566e57cd..c192a6c547dd3 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.h
++++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.h
+@@ -1037,12 +1037,4 @@ bool idpf_rx_singleq_buf_hw_alloc_all(struct idpf_rx_queue *rxq,
+                                     u16 cleaned_count);
+ int idpf_tso(struct sk_buff *skb, struct idpf_tx_offload_params *off);
+-static inline bool idpf_tx_maybe_stop_common(struct idpf_tx_queue *tx_q,
+-                                           u32 needed)
+-{
+-      return !netif_subqueue_maybe_stop(tx_q->netdev, tx_q->idx,
+-                                        IDPF_DESC_UNUSED(tx_q),
+-                                        needed, needed);
+-}
+-
+ #endif /* !_IDPF_TXRX_H_ */
+-- 
+2.39.5
+
diff --git a/queue-6.15/iio-adc-ad4851-fix-ad4858-chan-pointer-handling.patch b/queue-6.15/iio-adc-ad4851-fix-ad4858-chan-pointer-handling.patch
new file mode 100644 (file)
index 0000000..d9abbf7
--- /dev/null
@@ -0,0 +1,71 @@
+From c2e28447face6c615b92680c09f4baf637c08465 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 May 2025 13:16:57 +0300
+Subject: iio: adc: ad4851: fix ad4858 chan pointer handling
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Antoniu Miclaus <antoniu.miclaus@analog.com>
+
+[ Upstream commit 499a8cee812588905cc940837e69918c1649a19e ]
+
+The pointer returned from ad4851_parse_channels_common() is incremented
+internally as each channel is populated. In ad4858_parse_channels(),
+the same pointer was further incremented while setting ext_scan_type
+fields for each channel. This resulted in indio_dev->channels being set
+to a pointer past the end of the allocated array, potentially causing
+memory corruption or undefined behavior.
+
+Fix this by iterating over the channels using an explicit index instead
+of incrementing the pointer. This preserves the original base pointer
+and ensures all channel metadata is set correctly.
+
+Fixes: 6250803fe2ec ("iio: adc: ad4851: add ad485x driver")
+Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
+Reviewed-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://patch.msgid.link/20250509101657.6742-1-antoniu.miclaus@analog.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad4851.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/iio/adc/ad4851.c b/drivers/iio/adc/ad4851.c
+index 98ebc853db796..f1d2e2896f2a2 100644
+--- a/drivers/iio/adc/ad4851.c
++++ b/drivers/iio/adc/ad4851.c
+@@ -1034,7 +1034,7 @@ static int ad4858_parse_channels(struct iio_dev *indio_dev)
+       struct device *dev = &st->spi->dev;
+       struct iio_chan_spec *ad4851_channels;
+       const struct iio_chan_spec ad4851_chan = AD4858_IIO_CHANNEL;
+-      int ret;
++      int ret, i = 0;
+       ret = ad4851_parse_channels_common(indio_dev, &ad4851_channels,
+                                          ad4851_chan);
+@@ -1042,15 +1042,15 @@ static int ad4858_parse_channels(struct iio_dev *indio_dev)
+               return ret;
+       device_for_each_child_node_scoped(dev, child) {
+-              ad4851_channels->has_ext_scan_type = 1;
++              ad4851_channels[i].has_ext_scan_type = 1;
+               if (fwnode_property_read_bool(child, "bipolar")) {
+-                      ad4851_channels->ext_scan_type = ad4851_scan_type_20_b;
+-                      ad4851_channels->num_ext_scan_type = ARRAY_SIZE(ad4851_scan_type_20_b);
++                      ad4851_channels[i].ext_scan_type = ad4851_scan_type_20_b;
++                      ad4851_channels[i].num_ext_scan_type = ARRAY_SIZE(ad4851_scan_type_20_b);
+               } else {
+-                      ad4851_channels->ext_scan_type = ad4851_scan_type_20_u;
+-                      ad4851_channels->num_ext_scan_type = ARRAY_SIZE(ad4851_scan_type_20_u);
++                      ad4851_channels[i].ext_scan_type = ad4851_scan_type_20_u;
++                      ad4851_channels[i].num_ext_scan_type = ARRAY_SIZE(ad4851_scan_type_20_u);
+               }
+-              ad4851_channels++;
++              i++;
+       }
+       indio_dev->channels = ad4851_channels;
+-- 
+2.39.5
+
diff --git a/queue-6.15/iio-adc-ad7124-fix-3db-filter-frequency-reading.patch b/queue-6.15/iio-adc-ad7124-fix-3db-filter-frequency-reading.patch
new file mode 100644 (file)
index 0000000..f5f6762
--- /dev/null
@@ -0,0 +1,45 @@
+From 224f2c1b1467a783e41fd23f31ad7bdfc405b54f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Mar 2025 12:52:47 +0100
+Subject: iio: adc: ad7124: Fix 3dB filter frequency reading
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
+
+[ Upstream commit 8712e4986e7ce42a14c762c4c350f290989986a5 ]
+
+The sinc4 filter has a factor 0.23 between Output Data Rate and f_{3dB}
+and for sinc3 the factor is 0.272 according to the data sheets for
+ad7124-4 (Rev. E.) and ad7124-8 (Rev. F).
+
+Fixes: cef2760954cf ("iio: adc: ad7124: add 3db filter")
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
+Reviewed-by: Marcelo Schmitt <marcelo.schmitt@analog.com>
+Link: https://patch.msgid.link/20250317115247.3735016-6-u.kleine-koenig@baylibre.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad7124.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/adc/ad7124.c b/drivers/iio/adc/ad7124.c
+index 3ea81a98e4553..7d5d84a07cae1 100644
+--- a/drivers/iio/adc/ad7124.c
++++ b/drivers/iio/adc/ad7124.c
+@@ -301,9 +301,9 @@ static int ad7124_get_3db_filter_freq(struct ad7124_state *st,
+       switch (st->channels[channel].cfg.filter_type) {
+       case AD7124_SINC3_FILTER:
+-              return DIV_ROUND_CLOSEST(fadc * 230, 1000);
++              return DIV_ROUND_CLOSEST(fadc * 272, 1000);
+       case AD7124_SINC4_FILTER:
+-              return DIV_ROUND_CLOSEST(fadc * 262, 1000);
++              return DIV_ROUND_CLOSEST(fadc * 230, 1000);
+       default:
+               return -EINVAL;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/iio-adc-mcp3911-fix-device-dependent-mappings-for-co.patch b/queue-6.15/iio-adc-mcp3911-fix-device-dependent-mappings-for-co.patch
new file mode 100644 (file)
index 0000000..61e1b9b
--- /dev/null
@@ -0,0 +1,171 @@
+From 4e74b3e822baa65542e84962195b8b73596d51c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Apr 2025 08:54:11 +0200
+Subject: iio: adc: mcp3911: fix device dependent mappings for conversion
+ result registers
+
+From: Marcus Folkesson <marcus.folkesson@gmail.com>
+
+[ Upstream commit f62c49d8f32d6ce8871b01795498352775aa61db ]
+
+The conversion result registers differs between devices. Make sure the
+mapping is correct by using a device dependent .get_raw() callback function.
+
+Fixes: 732ad34260d3 ("iio: adc: mcp3911: add support for the whole MCP39xx family")
+Co-developed-by: Lukas Rauber <lukas.rauber@janitza.de>
+Signed-off-by: Lukas Rauber <lukas.rauber@janitza.de>
+Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://patch.msgid.link/20250428-mcp3911-fixes-v2-1-406e39330c3d@gmail.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/mcp3911.c | 39 ++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 34 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/iio/adc/mcp3911.c b/drivers/iio/adc/mcp3911.c
+index 6748b44d568db..60a19c35807ab 100644
+--- a/drivers/iio/adc/mcp3911.c
++++ b/drivers/iio/adc/mcp3911.c
+@@ -6,7 +6,7 @@
+  * Copyright (C) 2018 Kent Gustavsson <kent@minoris.se>
+  */
+ #include <linux/bitfield.h>
+-#include <linux/bits.h>
++#include <linux/bitops.h>
+ #include <linux/cleanup.h>
+ #include <linux/clk.h>
+ #include <linux/delay.h>
+@@ -79,6 +79,8 @@
+ #define MCP3910_CONFIG1_CLKEXT                BIT(6)
+ #define MCP3910_CONFIG1_VREFEXT               BIT(7)
++#define MCP3910_CHANNEL(ch)           (MCP3911_REG_CHANNEL0 + (ch))
++
+ #define MCP3910_REG_OFFCAL_CH0                0x0f
+ #define MCP3910_OFFCAL(ch)            (MCP3910_REG_OFFCAL_CH0 + (ch) * 6)
+@@ -110,6 +112,7 @@ struct mcp3911_chip_info {
+       int (*get_offset)(struct mcp3911 *adc, int channel, int *val);
+       int (*set_offset)(struct mcp3911 *adc, int channel, int val);
+       int (*set_scale)(struct mcp3911 *adc, int channel, u32 val);
++      int (*get_raw)(struct mcp3911 *adc, int channel, int *val);
+ };
+ struct mcp3911 {
+@@ -170,6 +173,18 @@ static int mcp3911_update(struct mcp3911 *adc, u8 reg, u32 mask, u32 val, u8 len
+       return mcp3911_write(adc, reg, val, len);
+ }
++static int mcp3911_read_s24(struct mcp3911 *const adc, u8 const reg, s32 *const val)
++{
++      u32 uval;
++      int const ret = mcp3911_read(adc, reg, &uval, 3);
++
++      if (ret)
++              return ret;
++
++      *val = sign_extend32(uval, 23);
++      return ret;
++}
++
+ static int mcp3910_enable_offset(struct mcp3911 *adc, bool enable)
+ {
+       unsigned int mask = MCP3910_CONFIG0_EN_OFFCAL;
+@@ -194,6 +209,11 @@ static int mcp3910_set_offset(struct mcp3911 *adc, int channel, int val)
+       return adc->chip->enable_offset(adc, 1);
+ }
++static int mcp3910_get_raw(struct mcp3911 *adc, int channel, s32 *val)
++{
++      return mcp3911_read_s24(adc, MCP3910_CHANNEL(channel), val);
++}
++
+ static int mcp3911_enable_offset(struct mcp3911 *adc, bool enable)
+ {
+       unsigned int mask = MCP3911_STATUSCOM_EN_OFFCAL;
+@@ -218,6 +238,11 @@ static int mcp3911_set_offset(struct mcp3911 *adc, int channel, int val)
+       return adc->chip->enable_offset(adc, 1);
+ }
++static int mcp3911_get_raw(struct mcp3911 *adc, int channel, s32 *val)
++{
++      return mcp3911_read_s24(adc, MCP3911_CHANNEL(channel), val);
++}
++
+ static int mcp3910_get_osr(struct mcp3911 *adc, u32 *val)
+ {
+       int ret;
+@@ -321,12 +346,9 @@ static int mcp3911_read_raw(struct iio_dev *indio_dev,
+       guard(mutex)(&adc->lock);
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+-              ret = mcp3911_read(adc,
+-                                 MCP3911_CHANNEL(channel->channel), val, 3);
++              ret = adc->chip->get_raw(adc, channel->channel, val);
+               if (ret)
+                       return ret;
+-
+-              *val = sign_extend32(*val, 23);
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_OFFSET:
+               ret = adc->chip->get_offset(adc, channel->channel, val);
+@@ -799,6 +821,7 @@ static const struct mcp3911_chip_info mcp3911_chip_info[] = {
+               .get_offset = mcp3910_get_offset,
+               .set_offset = mcp3910_set_offset,
+               .set_scale = mcp3910_set_scale,
++              .get_raw = mcp3910_get_raw,
+       },
+       [MCP3911] = {
+               .channels = mcp3911_channels,
+@@ -810,6 +833,7 @@ static const struct mcp3911_chip_info mcp3911_chip_info[] = {
+               .get_offset = mcp3911_get_offset,
+               .set_offset = mcp3911_set_offset,
+               .set_scale = mcp3911_set_scale,
++              .get_raw = mcp3911_get_raw,
+       },
+       [MCP3912] = {
+               .channels = mcp3912_channels,
+@@ -821,6 +845,7 @@ static const struct mcp3911_chip_info mcp3911_chip_info[] = {
+               .get_offset = mcp3910_get_offset,
+               .set_offset = mcp3910_set_offset,
+               .set_scale = mcp3910_set_scale,
++              .get_raw = mcp3910_get_raw,
+       },
+       [MCP3913] = {
+               .channels = mcp3913_channels,
+@@ -832,6 +857,7 @@ static const struct mcp3911_chip_info mcp3911_chip_info[] = {
+               .get_offset = mcp3910_get_offset,
+               .set_offset = mcp3910_set_offset,
+               .set_scale = mcp3910_set_scale,
++              .get_raw = mcp3910_get_raw,
+       },
+       [MCP3914] = {
+               .channels = mcp3914_channels,
+@@ -843,6 +869,7 @@ static const struct mcp3911_chip_info mcp3911_chip_info[] = {
+               .get_offset = mcp3910_get_offset,
+               .set_offset = mcp3910_set_offset,
+               .set_scale = mcp3910_set_scale,
++              .get_raw = mcp3910_get_raw,
+       },
+       [MCP3918] = {
+               .channels = mcp3918_channels,
+@@ -854,6 +881,7 @@ static const struct mcp3911_chip_info mcp3911_chip_info[] = {
+               .get_offset = mcp3910_get_offset,
+               .set_offset = mcp3910_set_offset,
+               .set_scale = mcp3910_set_scale,
++              .get_raw = mcp3910_get_raw,
+       },
+       [MCP3919] = {
+               .channels = mcp3919_channels,
+@@ -865,6 +893,7 @@ static const struct mcp3911_chip_info mcp3911_chip_info[] = {
+               .get_offset = mcp3910_get_offset,
+               .set_offset = mcp3910_set_offset,
+               .set_scale = mcp3910_set_scale,
++              .get_raw = mcp3910_get_raw,
+       },
+ };
+ static const struct of_device_id mcp3911_dt_ids[] = {
+-- 
+2.39.5
+
diff --git a/queue-6.15/iio-adc-pac1934-fix-typo-in-documentation-link.patch b/queue-6.15/iio-adc-pac1934-fix-typo-in-documentation-link.patch
new file mode 100644 (file)
index 0000000..68b6e0f
--- /dev/null
@@ -0,0 +1,40 @@
+From 2470fdf1bcff84e86eca55e9b40a07bc68bd646e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Apr 2025 11:06:33 +0300
+Subject: iio: adc: PAC1934: fix typo in documentation link
+
+From: Marius Cristea <marius.cristea@microchip.com>
+
+[ Upstream commit 52c43d80fa8370eb877fc63b1fc1eec67e1b1410 ]
+
+Fix a typo,(PAC1934 -> PAC193X), into the link from an application note
+related to the ACPI device definition.
+
+Fixes: 0fb528c8255b ("iio: adc: adding support for PAC193x")
+Reported-by: Matteo Martelli <matteomartelli3@gmail.com>
+Closes: https://patch.msgid.link/172794015844.2520.11909797050797595912@njaxe.localdomain
+Signed-off-by: Marius Cristea <marius.cristea@microchip.com>
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+Link: https://patch.msgid.link/20250424-pac1934-doc_link-v1-1-9832445cb270@microchip.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/pac1934.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/adc/pac1934.c b/drivers/iio/adc/pac1934.c
+index 20802b7f49ea8..09fe88eb3fb04 100644
+--- a/drivers/iio/adc/pac1934.c
++++ b/drivers/iio/adc/pac1934.c
+@@ -1081,7 +1081,7 @@ static int pac1934_chip_identify(struct pac1934_chip_info *info)
+ /*
+  * documentation related to the ACPI device definition
+- * https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ApplicationNotes/ApplicationNotes/PAC1934-Integration-Notes-for-Microsoft-Windows-10-and-Windows-11-Driver-Support-DS00002534.pdf
++ * https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ApplicationNotes/ApplicationNotes/PAC193X-Integration-Notes-for-Microsoft-Windows-10-and-Windows-11-Driver-Support-DS00002534.pdf
+  */
+ static int pac1934_acpi_parse_channel_config(struct i2c_client *client,
+                                            struct pac1934_chip_info *info)
+-- 
+2.39.5
+
diff --git a/queue-6.15/iio-dac-adi-axi-dac-fix-bus-read.patch b/queue-6.15/iio-dac-adi-axi-dac-fix-bus-read.patch
new file mode 100644 (file)
index 0000000..5905523
--- /dev/null
@@ -0,0 +1,58 @@
+From 911801fd0914012fb89d86325e3a9310768b7c7c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Apr 2025 11:16:54 +0200
+Subject: iio: dac: adi-axi-dac: fix bus read
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Angelo Dureghello <adureghello@baylibre.com>
+
+[ Upstream commit 921fece3268c3bf2e8c20dd17ff9e5454fa16fda ]
+
+Fix bus read function.
+
+Testing the driver, on a random basis, wrong reads was detected, mainly
+by a wrong DAC chip ID read at first boot.
+Before reading the expected value from the AXI regmap, need always to
+wait for busy flag to be cleared.
+
+Fixes: e61d7178429a ("iio: dac: adi-axi-dac: extend features")
+Signed-off-by: Angelo Dureghello <adureghello@baylibre.com>
+Reviewed-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://patch.msgid.link/20250409-ad3552r-fix-bus-read-v2-1-34d3b21e8ca0@baylibre.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/dac/adi-axi-dac.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/iio/dac/adi-axi-dac.c b/drivers/iio/dac/adi-axi-dac.c
+index 892d770aec69c..05b374e137d35 100644
+--- a/drivers/iio/dac/adi-axi-dac.c
++++ b/drivers/iio/dac/adi-axi-dac.c
+@@ -707,6 +707,7 @@ static int axi_dac_bus_reg_read(struct iio_backend *back, u32 reg, u32 *val,
+ {
+       struct axi_dac_state *st = iio_backend_get_priv(back);
+       int ret;
++      u32 ival;
+       guard(mutex)(&st->lock);
+@@ -719,6 +720,13 @@ static int axi_dac_bus_reg_read(struct iio_backend *back, u32 reg, u32 *val,
+       if (ret)
+               return ret;
++      ret = regmap_read_poll_timeout(st->regmap,
++                              AXI_DAC_UI_STATUS_REG, ival,
++                              FIELD_GET(AXI_DAC_UI_STATUS_IF_BUSY, ival) == 0,
++                              10, 100 * KILO);
++      if (ret)
++              return ret;
++
+       return regmap_read(st->regmap, AXI_DAC_CUSTOM_RD_REG, val);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/iio-filter-admv8818-fix-band-4-state-15.patch b/queue-6.15/iio-filter-admv8818-fix-band-4-state-15.patch
new file mode 100644 (file)
index 0000000..9cd2823
--- /dev/null
@@ -0,0 +1,37 @@
+From 65805740d92737ae362e863713def3260895b514 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Mar 2025 13:48:27 -0400
+Subject: iio: filter: admv8818: fix band 4, state 15
+
+From: Sam Winchenbach <swinchenbach@arka.org>
+
+[ Upstream commit ef0ce24f590ac075d5eda11f2d6434b303333ed6 ]
+
+Corrects the upper range of LPF Band 4 from 18.5 GHz to 18.85 GHz per
+the ADMV8818 datasheet
+
+Fixes: f34fe888ad05 ("iio:filter:admv8818: add support for ADMV8818")
+Signed-off-by: Sam Winchenbach <swinchenbach@arka.org>
+Link: https://patch.msgid.link/20250328174831.227202-3-sam.winchenbach@framepointer.org
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/filter/admv8818.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/filter/admv8818.c b/drivers/iio/filter/admv8818.c
+index d85b7d3de8660..3d8740caa1455 100644
+--- a/drivers/iio/filter/admv8818.c
++++ b/drivers/iio/filter/admv8818.c
+@@ -103,7 +103,7 @@ static const unsigned long long freq_range_lpf[4][2] = {
+       {2050000000ULL, 3850000000ULL},
+       {3350000000ULL, 7250000000ULL},
+       {7000000000, 13000000000},
+-      {12550000000, 18500000000}
++      {12550000000, 18850000000}
+ };
+ static const struct regmap_config admv8818_regmap_config = {
+-- 
+2.39.5
+
diff --git a/queue-6.15/iio-filter-admv8818-fix-integer-overflow.patch b/queue-6.15/iio-filter-admv8818-fix-integer-overflow.patch
new file mode 100644 (file)
index 0000000..1e29a84
--- /dev/null
@@ -0,0 +1,37 @@
+From f21c02fc8e194bea11a3a23eb5b0ce4cf3809532 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Mar 2025 13:48:28 -0400
+Subject: iio: filter: admv8818: fix integer overflow
+
+From: Sam Winchenbach <swinchenbach@arka.org>
+
+[ Upstream commit fb6009a28d77edec4eb548b5875dae8c79b88467 ]
+
+HZ_PER_MHZ is only unsigned long. This math overflows, leading to
+incorrect results.
+
+Fixes: f34fe888ad05 ("iio:filter:admv8818: add support for ADMV8818")
+Signed-off-by: Sam Winchenbach <swinchenbach@arka.org>
+Link: https://patch.msgid.link/20250328174831.227202-4-sam.winchenbach@framepointer.org
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/filter/admv8818.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/filter/admv8818.c b/drivers/iio/filter/admv8818.c
+index 3d8740caa1455..cd3aff9a2f7bf 100644
+--- a/drivers/iio/filter/admv8818.c
++++ b/drivers/iio/filter/admv8818.c
+@@ -154,7 +154,7 @@ static int __admv8818_hpf_select(struct admv8818_state *st, u64 freq)
+       }
+       /* Close HPF frequency gap between 12 and 12.5 GHz */
+-      if (freq >= 12000 * HZ_PER_MHZ && freq <= 12500 * HZ_PER_MHZ) {
++      if (freq >= 12000ULL * HZ_PER_MHZ && freq < 12500ULL * HZ_PER_MHZ) {
+               hpf_band = 3;
+               hpf_step = 15;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/iio-filter-admv8818-fix-range-calculation.patch b/queue-6.15/iio-filter-admv8818-fix-range-calculation.patch
new file mode 100644 (file)
index 0000000..8cee9e0
--- /dev/null
@@ -0,0 +1,550 @@
+From 082f84bfd5b088d70eb9bd6faccdb8d81b8f2b0c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Mar 2025 13:48:29 -0400
+Subject: iio: filter: admv8818: fix range calculation
+
+From: Sam Winchenbach <swinchenbach@arka.org>
+
+[ Upstream commit d542db7095d322bfcdc8e306db6f8c48358c9619 ]
+
+Search for the minimum error while ensuring that the LPF corner
+frequency is greater than the target, and the HPF corner frequency
+is lower than the target
+
+This fixes issues where the range calculations were suboptimal.
+
+Add two new DTS properties to set the margin between the input frequency
+and the calculated corner frequency
+
+Below is a generated table of the differences between the old algorithm
+and the new. This is a sweep from 0 to 20 GHz in 10 MHz steps.
+=== HPF ===
+freq = 1750 MHz, 3db: bypass => 1750 MHz
+freq = 3400 MHz, 3db: 3310 => 3400 MHz
+freq = 3410 MHz, 3db: 3310 => 3400 MHz
+freq = 3420 MHz, 3db: 3310 => 3400 MHz
+freq = 3660 MHz, 3db: 3550 => 3656 MHz
+freq = 6600 MHz, 3db: 6479 => 6600 MHz
+freq = 6610 MHz, 3db: 6479 => 6600 MHz
+freq = 6620 MHz, 3db: 6479 => 6600 MHz
+freq = 6630 MHz, 3db: 6479 => 6600 MHz
+freq = 6640 MHz, 3db: 6479 => 6600 MHz
+freq = 6650 MHz, 3db: 6479 => 6600 MHz
+freq = 6660 MHz, 3db: 6479 => 6600 MHz
+freq = 6670 MHz, 3db: 6479 => 6600 MHz
+freq = 6680 MHz, 3db: 6479 => 6600 MHz
+freq = 6690 MHz, 3db: 6479 => 6600 MHz
+freq = 6700 MHz, 3db: 6479 => 6600 MHz
+freq = 6710 MHz, 3db: 6479 => 6600 MHz
+freq = 6720 MHz, 3db: 6479 => 6600 MHz
+freq = 6730 MHz, 3db: 6479 => 6600 MHz
+freq = 6960 MHz, 3db: 6736 => 6960 MHz
+freq = 6970 MHz, 3db: 6736 => 6960 MHz
+freq = 6980 MHz, 3db: 6736 => 6960 MHz
+freq = 6990 MHz, 3db: 6736 => 6960 MHz
+freq = 7320 MHz, 3db: 7249 => 7320 MHz
+freq = 7330 MHz, 3db: 7249 => 7320 MHz
+freq = 7340 MHz, 3db: 7249 => 7320 MHz
+freq = 7350 MHz, 3db: 7249 => 7320 MHz
+freq = 7360 MHz, 3db: 7249 => 7320 MHz
+freq = 7370 MHz, 3db: 7249 => 7320 MHz
+freq = 7380 MHz, 3db: 7249 => 7320 MHz
+freq = 7390 MHz, 3db: 7249 => 7320 MHz
+freq = 7400 MHz, 3db: 7249 => 7320 MHz
+freq = 7410 MHz, 3db: 7249 => 7320 MHz
+freq = 7420 MHz, 3db: 7249 => 7320 MHz
+freq = 7430 MHz, 3db: 7249 => 7320 MHz
+freq = 7440 MHz, 3db: 7249 => 7320 MHz
+freq = 7450 MHz, 3db: 7249 => 7320 MHz
+freq = 7460 MHz, 3db: 7249 => 7320 MHz
+freq = 7470 MHz, 3db: 7249 => 7320 MHz
+freq = 7480 MHz, 3db: 7249 => 7320 MHz
+freq = 7490 MHz, 3db: 7249 => 7320 MHz
+freq = 7500 MHz, 3db: 7249 => 7320 MHz
+freq = 12500 MHz, 3db: 12000 => 12500 MHz
+
+=== LPF ===
+freq = 2050 MHz, 3db: bypass => 2050 MHz
+freq = 2170 MHz, 3db: 2290 => 2170 MHz
+freq = 2290 MHz, 3db: 2410 => 2290 MHz
+freq = 2410 MHz, 3db: 2530 => 2410 MHz
+freq = 2530 MHz, 3db: 2650 => 2530 MHz
+freq = 2650 MHz, 3db: 2770 => 2650 MHz
+freq = 2770 MHz, 3db: 2890 => 2770 MHz
+freq = 2890 MHz, 3db: 3010 => 2890 MHz
+freq = 3010 MHz, 3db: 3130 => 3010 MHz
+freq = 3130 MHz, 3db: 3250 => 3130 MHz
+freq = 3250 MHz, 3db: 3370 => 3250 MHz
+freq = 3260 MHz, 3db: 3370 => 3350 MHz
+freq = 3270 MHz, 3db: 3370 => 3350 MHz
+freq = 3280 MHz, 3db: 3370 => 3350 MHz
+freq = 3290 MHz, 3db: 3370 => 3350 MHz
+freq = 3300 MHz, 3db: 3370 => 3350 MHz
+freq = 3310 MHz, 3db: 3370 => 3350 MHz
+freq = 3320 MHz, 3db: 3370 => 3350 MHz
+freq = 3330 MHz, 3db: 3370 => 3350 MHz
+freq = 3340 MHz, 3db: 3370 => 3350 MHz
+freq = 3350 MHz, 3db: 3370 => 3350 MHz
+freq = 3370 MHz, 3db: 3490 => 3370 MHz
+freq = 3490 MHz, 3db: 3610 => 3490 MHz
+freq = 3610 MHz, 3db: 3730 => 3610 MHz
+freq = 3730 MHz, 3db: 3850 => 3730 MHz
+freq = 3850 MHz, 3db: 3870 => 3850 MHz
+freq = 3870 MHz, 3db: 4130 => 3870 MHz
+freq = 4130 MHz, 3db: 4390 => 4130 MHz
+freq = 4390 MHz, 3db: 4650 => 4390 MHz
+freq = 4650 MHz, 3db: 4910 => 4650 MHz
+freq = 4910 MHz, 3db: 5170 => 4910 MHz
+freq = 5170 MHz, 3db: 5430 => 5170 MHz
+freq = 5430 MHz, 3db: 5690 => 5430 MHz
+freq = 5690 MHz, 3db: 5950 => 5690 MHz
+freq = 5950 MHz, 3db: 6210 => 5950 MHz
+freq = 6210 MHz, 3db: 6470 => 6210 MHz
+freq = 6470 MHz, 3db: 6730 => 6470 MHz
+freq = 6730 MHz, 3db: 6990 => 6730 MHz
+freq = 6990 MHz, 3db: 7250 => 6990 MHz
+freq = 7000 MHz, 3db: 7250 => 7000 MHz
+freq = 7250 MHz, 3db: 7400 => 7250 MHz
+freq = 7400 MHz, 3db: 7800 => 7400 MHz
+freq = 7800 MHz, 3db: 8200 => 7800 MHz
+freq = 8200 MHz, 3db: 8600 => 8200 MHz
+freq = 8600 MHz, 3db: 9000 => 8600 MHz
+freq = 9000 MHz, 3db: 9400 => 9000 MHz
+freq = 9400 MHz, 3db: 9800 => 9400 MHz
+freq = 9800 MHz, 3db: 10200 => 9800 MHz
+freq = 10200 MHz, 3db: 10600 => 10200 MHz
+freq = 10600 MHz, 3db: 11000 => 10600 MHz
+freq = 11000 MHz, 3db: 11400 => 11000 MHz
+freq = 11400 MHz, 3db: 11800 => 11400 MHz
+freq = 11800 MHz, 3db: 12200 => 11800 MHz
+freq = 12200 MHz, 3db: 12600 => 12200 MHz
+freq = 12210 MHz, 3db: 12600 => 12550 MHz
+freq = 12220 MHz, 3db: 12600 => 12550 MHz
+freq = 12230 MHz, 3db: 12600 => 12550 MHz
+freq = 12240 MHz, 3db: 12600 => 12550 MHz
+freq = 12250 MHz, 3db: 12600 => 12550 MHz
+freq = 12260 MHz, 3db: 12600 => 12550 MHz
+freq = 12270 MHz, 3db: 12600 => 12550 MHz
+freq = 12280 MHz, 3db: 12600 => 12550 MHz
+freq = 12290 MHz, 3db: 12600 => 12550 MHz
+freq = 12300 MHz, 3db: 12600 => 12550 MHz
+freq = 12310 MHz, 3db: 12600 => 12550 MHz
+freq = 12320 MHz, 3db: 12600 => 12550 MHz
+freq = 12330 MHz, 3db: 12600 => 12550 MHz
+freq = 12340 MHz, 3db: 12600 => 12550 MHz
+freq = 12350 MHz, 3db: 12600 => 12550 MHz
+freq = 12360 MHz, 3db: 12600 => 12550 MHz
+freq = 12370 MHz, 3db: 12600 => 12550 MHz
+freq = 12380 MHz, 3db: 12600 => 12550 MHz
+freq = 12390 MHz, 3db: 12600 => 12550 MHz
+freq = 12400 MHz, 3db: 12600 => 12550 MHz
+freq = 12410 MHz, 3db: 12600 => 12550 MHz
+freq = 12420 MHz, 3db: 12600 => 12550 MHz
+freq = 12430 MHz, 3db: 12600 => 12550 MHz
+freq = 12440 MHz, 3db: 12600 => 12550 MHz
+freq = 12450 MHz, 3db: 12600 => 12550 MHz
+freq = 12460 MHz, 3db: 12600 => 12550 MHz
+freq = 12470 MHz, 3db: 12600 => 12550 MHz
+freq = 12480 MHz, 3db: 12600 => 12550 MHz
+freq = 12490 MHz, 3db: 12600 => 12550 MHz
+freq = 12500 MHz, 3db: 12600 => 12550 MHz
+freq = 12510 MHz, 3db: 12600 => 12550 MHz
+freq = 12520 MHz, 3db: 12600 => 12550 MHz
+freq = 12530 MHz, 3db: 12600 => 12550 MHz
+freq = 12540 MHz, 3db: 12600 => 12550 MHz
+freq = 12550 MHz, 3db: 12600 => 12550 MHz
+freq = 12600 MHz, 3db: 13000 => 12600 MHz
+freq = 12610 MHz, 3db: 13000 => 12970 MHz
+freq = 12620 MHz, 3db: 13000 => 12970 MHz
+freq = 12630 MHz, 3db: 13000 => 12970 MHz
+freq = 12640 MHz, 3db: 13000 => 12970 MHz
+freq = 12650 MHz, 3db: 13000 => 12970 MHz
+freq = 12660 MHz, 3db: 13000 => 12970 MHz
+freq = 12670 MHz, 3db: 13000 => 12970 MHz
+freq = 12680 MHz, 3db: 13000 => 12970 MHz
+freq = 12690 MHz, 3db: 13000 => 12970 MHz
+freq = 12700 MHz, 3db: 13000 => 12970 MHz
+freq = 12710 MHz, 3db: 13000 => 12970 MHz
+freq = 12720 MHz, 3db: 13000 => 12970 MHz
+freq = 12730 MHz, 3db: 13000 => 12970 MHz
+freq = 12740 MHz, 3db: 13000 => 12970 MHz
+freq = 12750 MHz, 3db: 13000 => 12970 MHz
+freq = 12760 MHz, 3db: 13000 => 12970 MHz
+freq = 12770 MHz, 3db: 13000 => 12970 MHz
+freq = 12780 MHz, 3db: 13000 => 12970 MHz
+freq = 12790 MHz, 3db: 13000 => 12970 MHz
+freq = 12800 MHz, 3db: 13000 => 12970 MHz
+freq = 12810 MHz, 3db: 13000 => 12970 MHz
+freq = 12820 MHz, 3db: 13000 => 12970 MHz
+freq = 12830 MHz, 3db: 13000 => 12970 MHz
+freq = 12840 MHz, 3db: 13000 => 12970 MHz
+freq = 12850 MHz, 3db: 13000 => 12970 MHz
+freq = 12860 MHz, 3db: 13000 => 12970 MHz
+freq = 12870 MHz, 3db: 13000 => 12970 MHz
+freq = 12880 MHz, 3db: 13000 => 12970 MHz
+freq = 12890 MHz, 3db: 13000 => 12970 MHz
+freq = 12900 MHz, 3db: 13000 => 12970 MHz
+freq = 12910 MHz, 3db: 13000 => 12970 MHz
+freq = 12920 MHz, 3db: 13000 => 12970 MHz
+freq = 12930 MHz, 3db: 13000 => 12970 MHz
+freq = 12940 MHz, 3db: 13000 => 12970 MHz
+freq = 12950 MHz, 3db: 13000 => 12970 MHz
+freq = 12960 MHz, 3db: 13000 => 12970 MHz
+freq = 12970 MHz, 3db: 13000 => 12970 MHz
+freq = 13000 MHz, 3db: 13390 => 13000 MHz
+freq = 13390 MHz, 3db: 13810 => 13390 MHz
+freq = 13810 MHz, 3db: 14230 => 13810 MHz
+freq = 14230 MHz, 3db: 14650 => 14230 MHz
+freq = 14650 MHz, 3db: 15070 => 14650 MHz
+freq = 15070 MHz, 3db: 15490 => 15070 MHz
+freq = 15490 MHz, 3db: 15910 => 15490 MHz
+freq = 15910 MHz, 3db: 16330 => 15910 MHz
+freq = 16330 MHz, 3db: 16750 => 16330 MHz
+freq = 16750 MHz, 3db: 17170 => 16750 MHz
+freq = 17170 MHz, 3db: 17590 => 17170 MHz
+freq = 17590 MHz, 3db: 18010 => 17590 MHz
+freq = 18010 MHz, 3db: 18430 => 18010 MHz
+freq = 18430 MHz, 3db: 18850 => 18430 MHz
+freq = 18850 MHz, 3db: bypass => 18850 MHz
+
+Fixes: f34fe888ad05 ("iio:filter:admv8818: add support for ADMV8818")
+Signed-off-by: Sam Winchenbach <swinchenbach@arka.org>
+Link: https://patch.msgid.link/20250328174831.227202-5-sam.winchenbach@framepointer.org
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/filter/admv8818.c | 205 +++++++++++++++++++++++++---------
+ 1 file changed, 152 insertions(+), 53 deletions(-)
+
+diff --git a/drivers/iio/filter/admv8818.c b/drivers/iio/filter/admv8818.c
+index cd3aff9a2f7bf..380e119b3cf54 100644
+--- a/drivers/iio/filter/admv8818.c
++++ b/drivers/iio/filter/admv8818.c
+@@ -14,6 +14,7 @@
+ #include <linux/mod_devicetable.h>
+ #include <linux/mutex.h>
+ #include <linux/notifier.h>
++#include <linux/property.h>
+ #include <linux/regmap.h>
+ #include <linux/spi/spi.h>
+ #include <linux/units.h>
+@@ -70,6 +71,16 @@
+ #define ADMV8818_HPF_WR0_MSK                  GENMASK(7, 4)
+ #define ADMV8818_LPF_WR0_MSK                  GENMASK(3, 0)
++#define ADMV8818_BAND_BYPASS       0
++#define ADMV8818_BAND_MIN          1
++#define ADMV8818_BAND_MAX          4
++#define ADMV8818_BAND_CORNER_LOW   0
++#define ADMV8818_BAND_CORNER_HIGH  1
++
++#define ADMV8818_STATE_MIN   0
++#define ADMV8818_STATE_MAX   15
++#define ADMV8818_NUM_STATES  16
++
+ enum {
+       ADMV8818_BW_FREQ,
+       ADMV8818_CENTER_FREQ
+@@ -90,16 +101,20 @@ struct admv8818_state {
+       struct mutex            lock;
+       unsigned int            filter_mode;
+       u64                     cf_hz;
++      u64                     lpf_margin_hz;
++      u64                     hpf_margin_hz;
+ };
+-static const unsigned long long freq_range_hpf[4][2] = {
++static const unsigned long long freq_range_hpf[5][2] = {
++      {0ULL, 0ULL}, /* bypass */
+       {1750000000ULL, 3550000000ULL},
+       {3400000000ULL, 7250000000ULL},
+       {6600000000, 12000000000},
+       {12500000000, 19900000000}
+ };
+-static const unsigned long long freq_range_lpf[4][2] = {
++static const unsigned long long freq_range_lpf[5][2] = {
++      {U64_MAX, U64_MAX}, /* bypass */
+       {2050000000ULL, 3850000000ULL},
+       {3350000000ULL, 7250000000ULL},
+       {7000000000, 13000000000},
+@@ -121,44 +136,59 @@ static const char * const admv8818_modes[] = {
+ static int __admv8818_hpf_select(struct admv8818_state *st, u64 freq)
+ {
+-      unsigned int hpf_step = 0, hpf_band = 0, i, j;
+-      u64 freq_step;
+-      int ret;
++      int band, state, ret;
++      unsigned int hpf_state = ADMV8818_STATE_MIN, hpf_band = ADMV8818_BAND_BYPASS;
++      u64 freq_error, min_freq_error, freq_corner, freq_step;
+-      if (freq < freq_range_hpf[0][0])
++      if (freq < freq_range_hpf[ADMV8818_BAND_MIN][ADMV8818_BAND_CORNER_LOW])
+               goto hpf_write;
+-      if (freq > freq_range_hpf[3][1]) {
+-              hpf_step = 15;
+-              hpf_band = 4;
+-
++      if (freq >= freq_range_hpf[ADMV8818_BAND_MAX][ADMV8818_BAND_CORNER_HIGH]) {
++              hpf_state = ADMV8818_STATE_MAX;
++              hpf_band = ADMV8818_BAND_MAX;
+               goto hpf_write;
+       }
+-      for (i = 0; i < 4; i++) {
+-              freq_step = div_u64((freq_range_hpf[i][1] -
+-                      freq_range_hpf[i][0]), 15);
++      /* Close HPF frequency gap between 12 and 12.5 GHz */
++      if (freq >= 12000ULL * HZ_PER_MHZ && freq < 12500ULL * HZ_PER_MHZ) {
++              hpf_state = ADMV8818_STATE_MAX;
++              hpf_band = 3;
++              goto hpf_write;
++      }
+-              if (freq > freq_range_hpf[i][0] &&
+-                  (freq < freq_range_hpf[i][1] + freq_step)) {
+-                      hpf_band = i + 1;
++      min_freq_error = U64_MAX;
++      for (band = ADMV8818_BAND_MIN; band <= ADMV8818_BAND_MAX; band++) {
++              /*
++               * This (and therefore all other ranges) have a corner
++               * frequency higher than the target frequency.
++               */
++              if (freq_range_hpf[band][ADMV8818_BAND_CORNER_LOW] > freq)
++                      break;
+-                      for (j = 1; j <= 16; j++) {
+-                              if (freq < (freq_range_hpf[i][0] + (freq_step * j))) {
+-                                      hpf_step = j - 1;
+-                                      break;
+-                              }
++              freq_step = freq_range_hpf[band][ADMV8818_BAND_CORNER_HIGH] -
++                          freq_range_hpf[band][ADMV8818_BAND_CORNER_LOW];
++              freq_step = div_u64(freq_step, ADMV8818_NUM_STATES - 1);
++
++              for (state = ADMV8818_STATE_MIN; state <= ADMV8818_STATE_MAX; state++) {
++                      freq_corner = freq_range_hpf[band][ADMV8818_BAND_CORNER_LOW] +
++                                    freq_step * state;
++
++                      /*
++                       * This (and therefore all other states) have a corner
++                       * frequency higher than the target frequency.
++                       */
++                      if (freq_corner > freq)
++                              break;
++
++                      freq_error = freq - freq_corner;
++                      if (freq_error < min_freq_error) {
++                              min_freq_error = freq_error;
++                              hpf_state = state;
++                              hpf_band = band;
+                       }
+-                      break;
+               }
+       }
+-      /* Close HPF frequency gap between 12 and 12.5 GHz */
+-      if (freq >= 12000ULL * HZ_PER_MHZ && freq < 12500ULL * HZ_PER_MHZ) {
+-              hpf_band = 3;
+-              hpf_step = 15;
+-      }
+-
+ hpf_write:
+       ret = regmap_update_bits(st->regmap, ADMV8818_REG_WR0_SW,
+                                ADMV8818_SW_IN_SET_WR0_MSK |
+@@ -170,7 +200,7 @@ static int __admv8818_hpf_select(struct admv8818_state *st, u64 freq)
+       return regmap_update_bits(st->regmap, ADMV8818_REG_WR0_FILTER,
+                                 ADMV8818_HPF_WR0_MSK,
+-                                FIELD_PREP(ADMV8818_HPF_WR0_MSK, hpf_step));
++                                FIELD_PREP(ADMV8818_HPF_WR0_MSK, hpf_state));
+ }
+ static int admv8818_hpf_select(struct admv8818_state *st, u64 freq)
+@@ -186,31 +216,52 @@ static int admv8818_hpf_select(struct admv8818_state *st, u64 freq)
+ static int __admv8818_lpf_select(struct admv8818_state *st, u64 freq)
+ {
+-      unsigned int lpf_step = 0, lpf_band = 0, i, j;
+-      u64 freq_step;
+-      int ret;
++      int band, state, ret;
++      unsigned int lpf_state = ADMV8818_STATE_MIN, lpf_band = ADMV8818_BAND_BYPASS;
++      u64 freq_error, min_freq_error, freq_corner, freq_step;
+-      if (freq > freq_range_lpf[3][1])
++      if (freq > freq_range_lpf[ADMV8818_BAND_MAX][ADMV8818_BAND_CORNER_HIGH])
+               goto lpf_write;
+-      if (freq < freq_range_lpf[0][0]) {
+-              lpf_band = 1;
+-
++      if (freq < freq_range_lpf[ADMV8818_BAND_MIN][ADMV8818_BAND_CORNER_LOW]) {
++              lpf_state = ADMV8818_STATE_MIN;
++              lpf_band = ADMV8818_BAND_MIN;
+               goto lpf_write;
+       }
+-      for (i = 0; i < 4; i++) {
+-              if (freq > freq_range_lpf[i][0] && freq < freq_range_lpf[i][1]) {
+-                      lpf_band = i + 1;
+-                      freq_step = div_u64((freq_range_lpf[i][1] - freq_range_lpf[i][0]), 15);
++      min_freq_error = U64_MAX;
++      for (band = ADMV8818_BAND_MAX; band >= ADMV8818_BAND_MIN; --band) {
++              /*
++               * At this point the highest corner frequency of
++               * all remaining ranges is below the target.
++               * LPF corner should be >= the target.
++               */
++              if (freq > freq_range_lpf[band][ADMV8818_BAND_CORNER_HIGH])
++                      break;
++
++              freq_step = freq_range_lpf[band][ADMV8818_BAND_CORNER_HIGH] -
++                          freq_range_lpf[band][ADMV8818_BAND_CORNER_LOW];
++              freq_step = div_u64(freq_step, ADMV8818_NUM_STATES - 1);
++
++              for (state = ADMV8818_STATE_MAX; state >= ADMV8818_STATE_MIN; --state) {
+-                      for (j = 0; j <= 15; j++) {
+-                              if (freq < (freq_range_lpf[i][0] + (freq_step * j))) {
+-                                      lpf_step = j;
+-                                      break;
+-                              }
++                      freq_corner = freq_range_lpf[band][ADMV8818_BAND_CORNER_LOW] +
++                                    state * freq_step;
++
++                      /*
++                       * At this point all other states in range will
++                       * place the corner frequency below the target
++                       * LPF corner should >= the target.
++                       */
++                      if (freq > freq_corner)
++                              break;
++
++                      freq_error = freq_corner - freq;
++                      if (freq_error < min_freq_error) {
++                              min_freq_error = freq_error;
++                              lpf_state = state;
++                              lpf_band = band;
+                       }
+-                      break;
+               }
+       }
+@@ -225,7 +276,7 @@ static int __admv8818_lpf_select(struct admv8818_state *st, u64 freq)
+       return regmap_update_bits(st->regmap, ADMV8818_REG_WR0_FILTER,
+                                 ADMV8818_LPF_WR0_MSK,
+-                                FIELD_PREP(ADMV8818_LPF_WR0_MSK, lpf_step));
++                                FIELD_PREP(ADMV8818_LPF_WR0_MSK, lpf_state));
+ }
+ static int admv8818_lpf_select(struct admv8818_state *st, u64 freq)
+@@ -242,16 +293,28 @@ static int admv8818_lpf_select(struct admv8818_state *st, u64 freq)
+ static int admv8818_rfin_band_select(struct admv8818_state *st)
+ {
+       int ret;
++      u64 hpf_corner_target, lpf_corner_target;
+       st->cf_hz = clk_get_rate(st->clkin);
++      /* Check for underflow */
++      if (st->cf_hz > st->hpf_margin_hz)
++              hpf_corner_target = st->cf_hz - st->hpf_margin_hz;
++      else
++              hpf_corner_target = 0;
++
++      /* Check for overflow */
++      lpf_corner_target = st->cf_hz + st->lpf_margin_hz;
++      if (lpf_corner_target < st->cf_hz)
++              lpf_corner_target = U64_MAX;
++
+       mutex_lock(&st->lock);
+-      ret = __admv8818_hpf_select(st, st->cf_hz);
++      ret = __admv8818_hpf_select(st, hpf_corner_target);
+       if (ret)
+               goto exit;
+-      ret = __admv8818_lpf_select(st, st->cf_hz);
++      ret = __admv8818_lpf_select(st, lpf_corner_target);
+ exit:
+       mutex_unlock(&st->lock);
+       return ret;
+@@ -278,8 +341,11 @@ static int __admv8818_read_hpf_freq(struct admv8818_state *st, u64 *hpf_freq)
+       hpf_state = FIELD_GET(ADMV8818_HPF_WR0_MSK, data);
+-      *hpf_freq = div_u64(freq_range_hpf[hpf_band - 1][1] - freq_range_hpf[hpf_band - 1][0], 15);
+-      *hpf_freq = freq_range_hpf[hpf_band - 1][0] + (*hpf_freq * hpf_state);
++      *hpf_freq = freq_range_hpf[hpf_band][ADMV8818_BAND_CORNER_HIGH] -
++                  freq_range_hpf[hpf_band][ADMV8818_BAND_CORNER_LOW];
++      *hpf_freq = div_u64(*hpf_freq, ADMV8818_NUM_STATES - 1);
++      *hpf_freq = freq_range_hpf[hpf_band][ADMV8818_BAND_CORNER_LOW] +
++                  (*hpf_freq * hpf_state);
+       return ret;
+ }
+@@ -316,8 +382,11 @@ static int __admv8818_read_lpf_freq(struct admv8818_state *st, u64 *lpf_freq)
+       lpf_state = FIELD_GET(ADMV8818_LPF_WR0_MSK, data);
+-      *lpf_freq = div_u64(freq_range_lpf[lpf_band - 1][1] - freq_range_lpf[lpf_band - 1][0], 15);
+-      *lpf_freq = freq_range_lpf[lpf_band - 1][0] + (*lpf_freq * lpf_state);
++      *lpf_freq = freq_range_lpf[lpf_band][ADMV8818_BAND_CORNER_HIGH] -
++                  freq_range_lpf[lpf_band][ADMV8818_BAND_CORNER_LOW];
++      *lpf_freq = div_u64(*lpf_freq, ADMV8818_NUM_STATES - 1);
++      *lpf_freq = freq_range_lpf[lpf_band][ADMV8818_BAND_CORNER_LOW] +
++                  (*lpf_freq * lpf_state);
+       return ret;
+ }
+@@ -641,6 +710,32 @@ static int admv8818_clk_setup(struct admv8818_state *st)
+       return devm_add_action_or_reset(&spi->dev, admv8818_clk_notifier_unreg, st);
+ }
++static int admv8818_read_properties(struct admv8818_state *st)
++{
++      struct spi_device *spi = st->spi;
++      u32 mhz;
++      int ret;
++
++      ret = device_property_read_u32(&spi->dev, "adi,lpf-margin-mhz", &mhz);
++      if (ret == 0)
++              st->lpf_margin_hz = (u64)mhz * HZ_PER_MHZ;
++      else if (ret == -EINVAL)
++              st->lpf_margin_hz = 0;
++      else
++              return ret;
++
++
++      ret = device_property_read_u32(&spi->dev, "adi,hpf-margin-mhz", &mhz);
++      if (ret == 0)
++              st->hpf_margin_hz = (u64)mhz * HZ_PER_MHZ;
++      else if (ret == -EINVAL)
++              st->hpf_margin_hz = 0;
++      else if (ret < 0)
++              return ret;
++
++      return 0;
++}
++
+ static int admv8818_probe(struct spi_device *spi)
+ {
+       struct iio_dev *indio_dev;
+@@ -672,6 +767,10 @@ static int admv8818_probe(struct spi_device *spi)
+       mutex_init(&st->lock);
++      ret = admv8818_read_properties(st);
++      if (ret)
++              return ret;
++
+       ret = admv8818_init(st);
+       if (ret)
+               return ret;
+-- 
+2.39.5
+
diff --git a/queue-6.15/iio-filter-admv8818-support-frequencies-2-32.patch b/queue-6.15/iio-filter-admv8818-support-frequencies-2-32.patch
new file mode 100644 (file)
index 0000000..fd426a8
--- /dev/null
@@ -0,0 +1,71 @@
+From b5bafa8451270f1c94645606845b5ebc669704e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Mar 2025 13:48:31 -0400
+Subject: iio: filter: admv8818: Support frequencies >= 2^32
+
+From: Brian Pellegrino <bpellegrino@arka.org>
+
+[ Upstream commit 9016776f1301627de78a633bda7c898425a56572 ]
+
+This patch allows writing u64 values to the ADMV8818's high and low-pass
+filter frequencies. It includes the following changes:
+
+- Rejects negative frequencies in admv8818_write_raw.
+- Adds a write_raw_get_fmt function to admv8818's iio_info, returning
+  IIO_VAL_INT_64 for the high and low-pass filter 3dB frequency channels.
+
+Fixes: f34fe888ad05 ("iio:filter:admv8818: add support for ADMV8818")
+Signed-off-by: Brian Pellegrino <bpellegrino@arka.org>
+Signed-off-by: Sam Winchenbach <swinchenbach@arka.org>
+Link: https://patch.msgid.link/20250328174831.227202-7-sam.winchenbach@framepointer.org
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/filter/admv8818.c | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+diff --git a/drivers/iio/filter/admv8818.c b/drivers/iio/filter/admv8818.c
+index 380e119b3cf54..cc8ce0fe74e7c 100644
+--- a/drivers/iio/filter/admv8818.c
++++ b/drivers/iio/filter/admv8818.c
+@@ -402,6 +402,19 @@ static int admv8818_read_lpf_freq(struct admv8818_state *st, u64 *lpf_freq)
+       return ret;
+ }
++static int admv8818_write_raw_get_fmt(struct iio_dev *indio_dev,
++                                                              struct iio_chan_spec const *chan,
++                                                              long mask)
++{
++      switch (mask) {
++      case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
++      case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY:
++              return IIO_VAL_INT_64;
++      default:
++              return -EINVAL;
++      }
++}
++
+ static int admv8818_write_raw(struct iio_dev *indio_dev,
+                             struct iio_chan_spec const *chan,
+                             int val, int val2, long info)
+@@ -410,6 +423,9 @@ static int admv8818_write_raw(struct iio_dev *indio_dev,
+       u64 freq = ((u64)val2 << 32 | (u32)val);
++      if ((s64)freq < 0)
++              return -EINVAL;
++
+       switch (info) {
+       case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
+               return admv8818_lpf_select(st, freq);
+@@ -571,6 +587,7 @@ static int admv8818_set_mode(struct iio_dev *indio_dev,
+ static const struct iio_info admv8818_info = {
+       .write_raw = admv8818_write_raw,
++      .write_raw_get_fmt = admv8818_write_raw_get_fmt,
+       .read_raw = admv8818_read_raw,
+       .debugfs_reg_access = &admv8818_reg_access,
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.15/iomap-don-t-lose-folio-dropbehind-state-for-overwrit.patch b/queue-6.15/iomap-don-t-lose-folio-dropbehind-state-for-overwrit.patch
new file mode 100644 (file)
index 0000000..a7292ff
--- /dev/null
@@ -0,0 +1,120 @@
+From d604669415e2d7635d5e31370cd4428dfb51c996 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 May 2025 17:01:31 -0600
+Subject: iomap: don't lose folio dropbehind state for overwrites
+
+From: Jens Axboe <axboe@kernel.dk>
+
+[ Upstream commit 34ecde3c56066ba79e5ec3d93c5b14ea83e3603e ]
+
+DONTCACHE I/O must have the completion punted to a workqueue, just like
+what is done for unwritten extents, as the completion needs task context
+to perform the invalidation of the folio(s). However, if writeback is
+started off filemap_fdatawrite_range() off generic_sync() and it's an
+overwrite, then the DONTCACHE marking gets lost as iomap_add_to_ioend()
+don't look at the folio being added and no further state is passed down
+to help it know that this is a dropbehind/DONTCACHE write.
+
+Check if the folio being added is marked as dropbehind, and set
+IOMAP_IOEND_DONTCACHE if that is the case. Then XFS can factor this into
+the decision making of completion context in xfs_submit_ioend().
+Additionally include this ioend flag in the NOMERGE flags, to avoid
+mixing it with unrelated IO.
+
+Since this is the 3rd flag that will cause XFS to punt the completion to
+a workqueue, add a helper so that each one of them can get appropriately
+commented.
+
+This fixes extra page cache being instantiated when the write performed
+is an overwrite, rather than newly instantiated blocks.
+
+Fixes: b2cd5ae693a3 ("iomap: make buffered writes work with RWF_DONTCACHE")
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Link: https://lore.kernel.org/5153f6e8-274d-4546-bf55-30a5018e0d03@kernel.dk
+Reviewed-by: Dave Chinner <dchinner@redhat.com>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/iomap/buffered-io.c |  2 ++
+ fs/xfs/xfs_aops.c      | 22 ++++++++++++++++++++--
+ include/linux/iomap.h  |  5 ++++-
+ 3 files changed, 26 insertions(+), 3 deletions(-)
+
+diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c
+index 5b08bd417b287..0ac474888a02e 100644
+--- a/fs/iomap/buffered-io.c
++++ b/fs/iomap/buffered-io.c
+@@ -1675,6 +1675,8 @@ static int iomap_add_to_ioend(struct iomap_writepage_ctx *wpc,
+               ioend_flags |= IOMAP_IOEND_UNWRITTEN;
+       if (wpc->iomap.flags & IOMAP_F_SHARED)
+               ioend_flags |= IOMAP_IOEND_SHARED;
++      if (folio_test_dropbehind(folio))
++              ioend_flags |= IOMAP_IOEND_DONTCACHE;
+       if (pos == wpc->iomap.offset && (wpc->iomap.flags & IOMAP_F_BOUNDARY))
+               ioend_flags |= IOMAP_IOEND_BOUNDARY;
+diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
+index 26a04a7834896..63151feb9c3fd 100644
+--- a/fs/xfs/xfs_aops.c
++++ b/fs/xfs/xfs_aops.c
+@@ -436,6 +436,25 @@ xfs_map_blocks(
+       return 0;
+ }
++static bool
++xfs_ioend_needs_wq_completion(
++      struct iomap_ioend      *ioend)
++{
++      /* Changing inode size requires a transaction. */
++      if (xfs_ioend_is_append(ioend))
++              return true;
++
++      /* Extent manipulation requires a transaction. */
++      if (ioend->io_flags & (IOMAP_IOEND_UNWRITTEN | IOMAP_IOEND_SHARED))
++              return true;
++
++      /* Page cache invalidation cannot be done in irq context. */
++      if (ioend->io_flags & IOMAP_IOEND_DONTCACHE)
++              return true;
++
++      return false;
++}
++
+ static int
+ xfs_submit_ioend(
+       struct iomap_writepage_ctx *wpc,
+@@ -460,8 +479,7 @@ xfs_submit_ioend(
+       memalloc_nofs_restore(nofs_flag);
+       /* send ioends that might require a transaction to the completion wq */
+-      if (xfs_ioend_is_append(ioend) ||
+-          (ioend->io_flags & (IOMAP_IOEND_UNWRITTEN | IOMAP_IOEND_SHARED)))
++      if (xfs_ioend_needs_wq_completion(ioend))
+               ioend->io_bio.bi_end_io = xfs_end_bio;
+       if (status)
+diff --git a/include/linux/iomap.h b/include/linux/iomap.h
+index 68416b135151d..522644d62f30f 100644
+--- a/include/linux/iomap.h
++++ b/include/linux/iomap.h
+@@ -377,13 +377,16 @@ sector_t iomap_bmap(struct address_space *mapping, sector_t bno,
+ #define IOMAP_IOEND_BOUNDARY          (1U << 2)
+ /* is direct I/O */
+ #define IOMAP_IOEND_DIRECT            (1U << 3)
++/* is DONTCACHE I/O */
++#define IOMAP_IOEND_DONTCACHE         (1U << 4)
+ /*
+  * Flags that if set on either ioend prevent the merge of two ioends.
+  * (IOMAP_IOEND_BOUNDARY also prevents merges, but only one-way)
+  */
+ #define IOMAP_IOEND_NOMERGE_FLAGS \
+-      (IOMAP_IOEND_SHARED | IOMAP_IOEND_UNWRITTEN | IOMAP_IOEND_DIRECT)
++      (IOMAP_IOEND_SHARED | IOMAP_IOEND_UNWRITTEN | IOMAP_IOEND_DIRECT | \
++       IOMAP_IOEND_DONTCACHE)
+ /*
+  * Structure for writeback I/O completions.
+-- 
+2.39.5
+
diff --git a/queue-6.15/iommu-arm-smmu-v3-fix-incorrect-return-in-arm_smmu_a.patch b/queue-6.15/iommu-arm-smmu-v3-fix-incorrect-return-in-arm_smmu_a.patch
new file mode 100644 (file)
index 0000000..fd6ac70
--- /dev/null
@@ -0,0 +1,44 @@
+From 87f690f7dedc39f49491bf9de173e99f5333c041 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Apr 2025 19:29:51 +0800
+Subject: iommu/arm-smmu-v3: Fix incorrect return in arm_smmu_attach_dev
+
+From: Qinxin Xia <xiaqinxin@huawei.com>
+
+[ Upstream commit be5a2d3f8f9738ea1426e7d2243707164ed5bac2 ]
+
+After commit 48e7b8e284e5 ("iommu/arm-smmu-v3: Remove
+arm_smmu_domain_finalise() during attach"), an error code is not
+returned on the attach path when the smmu does not match with the
+domain. This causes problems with VFIO because
+vfio_iommu_type1_attach_group() relies on this check to determine domain
+compatability.
+
+Re-instate the -EINVAL return value when the SMMU doesn't match on the
+device attach path.
+
+Fixes: 48e7b8e284e5 ("iommu/arm-smmu-v3: Remove arm_smmu_domain_finalise() during attach")
+Signed-off-by: Qinxin Xia <xiaqinxin@huawei.com>
+Link: https://lore.kernel.org/r/20250422112951.2027969-1-xiaqinxin@huawei.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+index 48d910399a1ba..be8d0f7db617d 100644
+--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
++++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+@@ -2953,7 +2953,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
+       smmu = master->smmu;
+       if (smmu_domain->smmu != smmu)
+-              return ret;
++              return -EINVAL;
+       if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) {
+               cdptr = arm_smmu_alloc_cd_ptr(master, IOMMU_NO_PASID);
+-- 
+2.39.5
+
diff --git a/queue-6.15/iommu-io-pgtable-arm-dynamically-allocate-selftest-d.patch b/queue-6.15/iommu-io-pgtable-arm-dynamically-allocate-selftest-d.patch
new file mode 100644 (file)
index 0000000..3fcd94f
--- /dev/null
@@ -0,0 +1,78 @@
+From b3c97300cd2c93d113d10da8fa0249379a366cdd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Apr 2025 18:48:16 +0200
+Subject: iommu/io-pgtable-arm: dynamically allocate selftest device struct
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit fa26198d30f3cdd7627ce47362057848219de765 ]
+
+In general a 'struct device' is way too large to be put on the kernel
+stack. Apparently something just caused it to grow a slightly larger,
+which pushed the arm_lpae_do_selftests() function over the warning
+limit in some configurations:
+
+drivers/iommu/io-pgtable-arm.c:1423:19: error: stack frame size (1032) exceeds limit (1024) in 'arm_lpae_do_selftests' [-Werror,-Wframe-larger-than]
+ 1423 | static int __init arm_lpae_do_selftests(void)
+      |                   ^
+
+Change the function to use a dynamically allocated faux_device
+instead of the on-stack device structure.
+
+Fixes: ca25ec247aad ("iommu/io-pgtable-arm: Remove iommu_dev==NULL special case")
+Link: https://lore.kernel.org/all/ab75a444-22a1-47f5-b3c0-253660395b5a@arm.com/
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Robin Murphy <robin.murphy@arm.com>
+Link: https://lore.kernel.org/r/20250423164826.2931382-1-arnd@kernel.org
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/io-pgtable-arm.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
+index 7632c80edea63..396c4f6f5a5bd 100644
+--- a/drivers/iommu/io-pgtable-arm.c
++++ b/drivers/iommu/io-pgtable-arm.c
+@@ -13,6 +13,7 @@
+ #include <linux/bitops.h>
+ #include <linux/io-pgtable.h>
+ #include <linux/kernel.h>
++#include <linux/device/faux.h>
+ #include <linux/sizes.h>
+ #include <linux/slab.h>
+ #include <linux/types.h>
+@@ -1433,15 +1434,17 @@ static int __init arm_lpae_do_selftests(void)
+       };
+       int i, j, k, pass = 0, fail = 0;
+-      struct device dev;
++      struct faux_device *dev;
+       struct io_pgtable_cfg cfg = {
+               .tlb = &dummy_tlb_ops,
+               .coherent_walk = true,
+-              .iommu_dev = &dev,
+       };
+-      /* __arm_lpae_alloc_pages() merely needs dev_to_node() to work */
+-      set_dev_node(&dev, NUMA_NO_NODE);
++      dev = faux_device_create("io-pgtable-test", NULL, 0);
++      if (!dev)
++              return -ENOMEM;
++
++      cfg.iommu_dev = &dev->dev;
+       for (i = 0; i < ARRAY_SIZE(pgsize); ++i) {
+               for (j = 0; j < ARRAY_SIZE(address_size); ++j) {
+@@ -1461,6 +1464,8 @@ static int __init arm_lpae_do_selftests(void)
+       }
+       pr_info("selftest: completed with %d PASS %d FAIL\n", pass, fail);
++      faux_device_destroy(dev);
++
+       return fail ? -EFAULT : 0;
+ }
+ subsys_initcall(arm_lpae_do_selftests);
+-- 
+2.39.5
+
diff --git a/queue-6.15/iommu-ipmmu-vmsa-avoid-wformat-security-warning.patch b/queue-6.15/iommu-ipmmu-vmsa-avoid-wformat-security-warning.patch
new file mode 100644 (file)
index 0000000..3d42cad
--- /dev/null
@@ -0,0 +1,51 @@
+From d076fd70876a7044890f0157a78b3d4f7ab4f92e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Apr 2025 18:40:02 +0200
+Subject: iommu: ipmmu-vmsa: avoid Wformat-security warning
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 33647d0be323f9e2f27cd1e86de5cfd965cec654 ]
+
+iommu_device_sysfs_add() requires a constant format string, otherwise
+a W=1 build produces a warning:
+
+drivers/iommu/ipmmu-vmsa.c:1093:62: error: format string is not a string literal (potentially insecure) [-Werror,-Wformat-security]
+ 1093 |         ret = iommu_device_sysfs_add(&mmu->iommu, &pdev->dev, NULL, dev_name(&pdev->dev));
+      |                                                                     ^~~~~~~~~~~~~~~~~~~~
+drivers/iommu/ipmmu-vmsa.c:1093:62: note: treat the string as an argument to avoid this
+ 1093 |         ret = iommu_device_sysfs_add(&mmu->iommu, &pdev->dev, NULL, dev_name(&pdev->dev));
+      |                                                                     ^
+      |                                                                     "%s",
+
+This was an old bug but I saw it now because the code was changed as part
+of commit d9d3cede4167 ("iommu/ipmmu-vmsa: Register in a sensible order").
+
+Fixes: 7af9a5fdb9e0 ("iommu/ipmmu-vmsa: Use iommu_device_sysfs_add()/remove()")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
+Link: https://lore.kernel.org/r/20250423164006.2661372-1-arnd@kernel.org
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/ipmmu-vmsa.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
+index e424b279a8cd9..90341b24a8115 100644
+--- a/drivers/iommu/ipmmu-vmsa.c
++++ b/drivers/iommu/ipmmu-vmsa.c
+@@ -1090,7 +1090,8 @@ static int ipmmu_probe(struct platform_device *pdev)
+       if (mmu->features->has_cache_leaf_nodes && ipmmu_is_root(mmu))
+               return 0;
+-      ret = iommu_device_sysfs_add(&mmu->iommu, &pdev->dev, NULL, dev_name(&pdev->dev));
++      ret = iommu_device_sysfs_add(&mmu->iommu, &pdev->dev, NULL, "%s",
++                                   dev_name(&pdev->dev));
+       if (ret)
+               return ret;
+-- 
+2.39.5
+
diff --git a/queue-6.15/iommu-protect-against-overflow-in-iommu_pgsize.patch b/queue-6.15/iommu-protect-against-overflow-in-iommu_pgsize.patch
new file mode 100644 (file)
index 0000000..2a53ddb
--- /dev/null
@@ -0,0 +1,56 @@
+From 9fb6d7aecb7f6564a55ad888a8abe7aff3fb9545 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 10:08:37 -0300
+Subject: iommu: Protect against overflow in iommu_pgsize()
+
+From: Jason Gunthorpe <jgg@nvidia.com>
+
+[ Upstream commit e586e22974d2b7acbef3c6c3e01b2d5ce69efe33 ]
+
+On a 32 bit system calling:
+ iommu_map(0, 0x40000000)
+
+When using the AMD V1 page table type with a domain->pgsize of 0xfffff000
+causes iommu_pgsize() to miscalculate a result of:
+  size=0x40000000 count=2
+
+count should be 1. This completely corrupts the mapping process.
+
+This is because the final test to adjust the pagesize malfunctions when
+the addition overflows. Use check_add_overflow() to prevent this.
+
+Fixes: b1d99dc5f983 ("iommu: Hook up '->unmap_pages' driver callback")
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
+Link: https://lore.kernel.org/r/0-v1-3ad28fc2e3a3+163327-iommu_overflow_pgsize_jgg@nvidia.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/iommu.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
+index 5bc2fc969494f..e4628d9621610 100644
+--- a/drivers/iommu/iommu.c
++++ b/drivers/iommu/iommu.c
+@@ -2399,6 +2399,7 @@ static size_t iommu_pgsize(struct iommu_domain *domain, unsigned long iova,
+       unsigned int pgsize_idx, pgsize_idx_next;
+       unsigned long pgsizes;
+       size_t offset, pgsize, pgsize_next;
++      size_t offset_end;
+       unsigned long addr_merge = paddr | iova;
+       /* Page sizes supported by the hardware and small enough for @size */
+@@ -2439,7 +2440,8 @@ static size_t iommu_pgsize(struct iommu_domain *domain, unsigned long iova,
+        * If size is big enough to accommodate the larger page, reduce
+        * the number of smaller pages.
+        */
+-      if (offset + pgsize_next <= size)
++      if (!check_add_overflow(offset, pgsize_next, &offset_end) &&
++          offset_end <= size)
+               size = offset;
+ out_set_count:
+-- 
+2.39.5
+
diff --git a/queue-6.15/iommu-remove-duplicate-selection-of-dmar_table.patch b/queue-6.15/iommu-remove-duplicate-selection-of-dmar_table.patch
new file mode 100644 (file)
index 0000000..1c7907f
--- /dev/null
@@ -0,0 +1,36 @@
+From d4badca3ff815d657b416f66eb42a86a229fd610 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 May 2025 15:10:44 +0200
+Subject: iommu: remove duplicate selection of DMAR_TABLE
+
+From: Rolf Eike Beer <eb@emlix.com>
+
+[ Upstream commit 9548feff840a05d61783e6316d08ed37e115f3b1 ]
+
+This is already done in intel/Kconfig.
+
+Fixes: 70bad345e622 ("iommu: Fix compilation without CONFIG_IOMMU_INTEL")
+Signed-off-by: Rolf Eike Beer <eb@emlix.com>
+Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
+Link: https://lore.kernel.org/r/2232605.Mh6RI2rZIc@devpool92.emlix.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/Kconfig | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
+index cd750f512deee..bad585b45a31d 100644
+--- a/drivers/iommu/Kconfig
++++ b/drivers/iommu/Kconfig
+@@ -199,7 +199,6 @@ source "drivers/iommu/riscv/Kconfig"
+ config IRQ_REMAP
+       bool "Support for Interrupt Remapping"
+       depends on X86_64 && X86_IO_APIC && PCI_MSI && ACPI
+-      select DMAR_TABLE if INTEL_IOMMU
+       help
+         Supports Interrupt remapping for IO-APIC and MSI devices.
+         To use x2apic mode in the CPU's which support x2APIC enhancements or
+-- 
+2.39.5
+
diff --git a/queue-6.15/iov_iter-use-iov_offset-for-length-calculation-in-io.patch b/queue-6.15/iov_iter-use-iov_offset-for-length-calculation-in-io.patch
new file mode 100644 (file)
index 0000000..5ede380
--- /dev/null
@@ -0,0 +1,89 @@
+From 47092a013607bc0e45b3b504f80a2264d329c95a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Apr 2025 15:28:48 +0530
+Subject: iov_iter: use iov_offset for length calculation in
+ iov_iter_aligned_bvec
+
+From: Nitesh Shetty <nj.shetty@samsung.com>
+
+[ Upstream commit 334d7c4fb60cf21e0abac134d92fe49e9b04377e ]
+
+If iov_offset is non-zero, then we need to consider iov_offset in length
+calculation, otherwise we might pass smaller IOs such as 512 bytes, in
+below scenario [1].
+
+This issue is reproducible using lib-uring test/fixed-seg.c application
+with fixed buffer on a 512 LBA formatted device.
+
+[1]
+
+At present we pass the alignment check, for 512 LBA formatted devices,
+len_mask = 511 when IO is smaller, i->count = 512 has an offset,
+i->io_offset = 3584 with bvec values, bvec->bv_offset = 256,
+bvec->bv_len = 3840.  In short, the first 256 bytes are in the current
+page, next 256 bytes are in the another page.  Ideally we expect to
+fail the IO.
+
+I can think of 2 userspace scenarios where we experience this.
+
+a: From userspace, we observe a different behaviour when device LBA
+   size is 512 vs 4096 bytes.  For 4096 LBA formatted device, I see the
+   same liburing test [2] failing, whereas 512 the test passes without
+   this.  This is reproducible everytime.
+
+   [2] https://github.com/axboe/liburing/
+
+b: Although I was not able to reproduce the below condition, but I
+   suspect below case should be possible from user space for devices
+   with 512 LBA formatted device.  Lets say from userspace while
+   allocating a virtually single chunk of memory, if we get 2 physical
+   chunk of memory, and IO happens to be at the boundary of first
+   physical chunk with length crossing first chunk, then we allow IOs
+   to proceed and hence we might map wrong physical address length and
+   proceed with IO rather than failing.
+
+: --- a/test/fixed-seg.c
+: +++ b/test/fixed-seg.c
+: @@ -64,7 +64,7 @@ static int test(struct io_uring *ring, int fd, int
+: vec_off)
+:              return T_EXIT_FAIL;
+:      }
+:
+: -       ret = read_it(ring, fd, 4096, vec_off);
+: +       ret = read_it(ring, fd, 4096, 7*512 + 256);
+:      if (ret) {
+:              fprintf(stderr, "4096 0 failed\n");
+:              return T_EXIT_FAIL;
+
+Effectively this is a write crossing the page boundary.
+
+Link: https://lkml.kernel.org/r/20250428095849.11709-1-nj.shetty@samsung.com
+Fixes: 2263639f96f2 ("iov_iter: streamline iovec/bvec alignment iteration")
+Reviewed-by: Jens Axboe <axboe@kernel.dk>
+Reviewed-by: Anuj Gupta <anuj20.g@samsung.com>
+Signed-off-by: Nitesh Shetty <nj.shetty@samsung.com>
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Cc: Christian Brauner <brauner@kernel.org>
+Cc: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/iov_iter.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/iov_iter.c b/lib/iov_iter.c
+index bc9391e55d57e..9ce83ab71bacd 100644
+--- a/lib/iov_iter.c
++++ b/lib/iov_iter.c
+@@ -820,7 +820,7 @@ static bool iov_iter_aligned_bvec(const struct iov_iter *i, unsigned addr_mask,
+       size_t size = i->count;
+       do {
+-              size_t len = bvec->bv_len;
++              size_t len = bvec->bv_len - skip;
+               if (len > size)
+                       len = size;
+-- 
+2.39.5
+
diff --git a/queue-6.15/kernfs-relax-constraint-in-draining-guard.patch b/queue-6.15/kernfs-relax-constraint-in-draining-guard.patch
new file mode 100644 (file)
index 0000000..bd59c7a
--- /dev/null
@@ -0,0 +1,88 @@
+From ef0af5ba2e094f751b3bde5bbf24795e31330704 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 May 2025 14:12:00 +0200
+Subject: kernfs: Relax constraint in draining guard
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Michal Koutný <mkoutny@suse.com>
+
+[ Upstream commit 071d8e4c2a3b0999a9b822e2eb8854784a350f8a ]
+
+The active reference lifecycle provides the break/unbreak mechanism but
+the active reference is not truly active after unbreak -- callers don't
+use it afterwards but it's important for proper pairing of kn->active
+counting. Assuming this mechanism is in place, the WARN check in
+kernfs_should_drain_open_files() is too sensitive -- it may transiently
+catch those (rightful) callers between
+kernfs_unbreak_active_protection() and kernfs_put_active() as found out by Chen
+Ridong:
+
+       kernfs_remove_by_name_ns        kernfs_get_active // active=1
+       __kernfs_remove                                   // active=0x80000002
+       kernfs_drain                    ...
+       wait_event
+       //waiting (active == 0x80000001)
+                                       kernfs_break_active_protection
+                                       // active = 0x80000001
+       // continue
+                                       kernfs_unbreak_active_protection
+                                       // active = 0x80000002
+       ...
+       kernfs_should_drain_open_files
+       // warning occurs
+                                       kernfs_put_active
+
+To avoid the false positives (mind panic_on_warn) remove the check altogether.
+(This is meant as quick fix, I think active reference break/unbreak may be
+simplified with larger rework.)
+
+Fixes: bdb2fd7fc56e1 ("kernfs: Skip kernfs_drain_open_files() more aggressively")
+Link: https://lore.kernel.org/r/kmmrseckjctb4gxcx2rdminrjnq2b4ipf7562nvfd432ld5v5m@2byj5eedkb2o/
+
+Cc: Chen Ridong <chenridong@huawei.com>
+Signed-off-by: Michal Koutný <mkoutny@suse.com>
+Acked-by: Tejun Heo <tj@kernel.org>
+Link: https://lore.kernel.org/r/20250505121201.879823-1-mkoutny@suse.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/kernfs/dir.c  | 5 +++--
+ fs/kernfs/file.c | 3 ++-
+ 2 files changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
+index fc70d72c3fe80..43487fa83eaea 100644
+--- a/fs/kernfs/dir.c
++++ b/fs/kernfs/dir.c
+@@ -1580,8 +1580,9 @@ void kernfs_break_active_protection(struct kernfs_node *kn)
+  * invoked before finishing the kernfs operation.  Note that while this
+  * function restores the active reference, it doesn't and can't actually
+  * restore the active protection - @kn may already or be in the process of
+- * being removed.  Once kernfs_break_active_protection() is invoked, that
+- * protection is irreversibly gone for the kernfs operation instance.
++ * being drained and removed.  Once kernfs_break_active_protection() is
++ * invoked, that protection is irreversibly gone for the kernfs operation
++ * instance.
+  *
+  * While this function may be called at any point after
+  * kernfs_break_active_protection() is invoked, its most useful location
+diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c
+index 66fe8fe41f060..a6c692cac6165 100644
+--- a/fs/kernfs/file.c
++++ b/fs/kernfs/file.c
+@@ -778,8 +778,9 @@ bool kernfs_should_drain_open_files(struct kernfs_node *kn)
+       /*
+        * @kn being deactivated guarantees that @kn->attr.open can't change
+        * beneath us making the lockless test below safe.
++       * Callers post kernfs_unbreak_active_protection may be counted in
++       * kn->active by now, do not WARN_ON because of them.
+        */
+-      WARN_ON_ONCE(atomic_read(&kn->active) != KN_DEACTIVATED_BIAS);
+       rcu_read_lock();
+       on = rcu_dereference(kn->attr.open);
+-- 
+2.39.5
+
diff --git a/queue-6.15/kselftest-arm64-fp-ptrace-fix-expected-fpmr-value-wh.patch b/queue-6.15/kselftest-arm64-fp-ptrace-fix-expected-fpmr-value-wh.patch
new file mode 100644 (file)
index 0000000..d9310ea
--- /dev/null
@@ -0,0 +1,103 @@
+From 2204efb500ac882fb317cdcd03b72d8d528daa53 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 May 2025 14:26:41 +0100
+Subject: kselftest/arm64: fp-ptrace: Fix expected FPMR value when PSTATE.SM is
+ changed
+
+From: Mark Rutland <mark.rutland@arm.com>
+
+[ Upstream commit 78b23877dbba7dbcda2b89383d17bed82ce8f663 ]
+
+The fp-ptrace test suite expects that FPMR is set to zero when PSTATE.SM
+is changed via ptrace, but ptrace has never altered FPMR in this way,
+and the test logic erroneously relies upon (and has concealed) a bug
+where task_fpsimd_load() would unexpectedly and non-deterministically
+clobber FPMR.
+
+Using ptrace, FPMR can only be altered by writing to the NT_ARM_FPMR
+regset. The value of PSTATE.SM can be altered by writing to the
+NT_ARM_SVE or NT_ARM_SSVE regsets, and/or by changing the SME vector
+length (when writing to the NT_ARM_SVE, NT_ARM_SSVE, or NT_ARM_ZA
+regsets), but none of these writes will change the value of FPMR.
+
+The task_fpsimd_load() bug was introduced with the initial FPMR support
+in commit:
+
+  203f2b95a882 ("arm64/fpsimd: Support FEAT_FPMR")
+
+The incorrect FPMR test code was introduced in commit:
+
+  7dbd26d0b22d ("kselftest/arm64: Add FPMR coverage to fp-ptrace")
+
+Subsequently, the task_fpsimd_load() bug was fixed in commit:
+
+  e5fa85fce08b ("arm64/fpsimd: Don't corrupt FPMR when streaming mode changes")
+
+... whereupon the fp-ptrace FPMR tests started failing reliably, e.g.
+
+| # # Mismatch in saved FPMR: 915058000 != 0
+| # not ok 25 SVE write, SVE 64->64, SME 64/0->64/1
+
+Fix this by changing the test to expect that FPMR is *NOT* changed when
+PSTATE.SM is changed via ptrace, matching the extant behaviour.
+
+I've chosen to update the test code rather than modifying ptrace to zero
+FPMR when PSTATE.SM changes. Not zeroing FPMR is simpler overall, and
+allows the NT_ARM_FPMR regset to be handled independently from other
+regsets, leaving less scope for error.
+
+Fixes: 7dbd26d0b22d ("kselftest/arm64: Add FPMR coverage to fp-ptrace")
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: David Spickett <david.spickett@arm.com>
+Cc: Luis Machado <luis.machado@arm.com>
+Cc: Marc Zyngier <maz@kernel.org>
+Cc: Mark Brown <broonie@kernel.org>
+Cc: Will Deacon <will@kernel.org>
+Link: https://lore.kernel.org/r/20250508132644.1395904-22-mark.rutland@arm.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/arm64/fp/fp-ptrace.c | 14 +-------------
+ 1 file changed, 1 insertion(+), 13 deletions(-)
+
+diff --git a/tools/testing/selftests/arm64/fp/fp-ptrace.c b/tools/testing/selftests/arm64/fp/fp-ptrace.c
+index 4930e03a7b990..762048eb354ff 100644
+--- a/tools/testing/selftests/arm64/fp/fp-ptrace.c
++++ b/tools/testing/selftests/arm64/fp/fp-ptrace.c
+@@ -891,18 +891,11 @@ static void set_initial_values(struct test_config *config)
+ {
+       int vq = __sve_vq_from_vl(vl_in(config));
+       int sme_vq = __sve_vq_from_vl(config->sme_vl_in);
+-      bool sm_change;
+       svcr_in = config->svcr_in;
+       svcr_expected = config->svcr_expected;
+       svcr_out = 0;
+-      if (sme_supported() &&
+-          (svcr_in & SVCR_SM) != (svcr_expected & SVCR_SM))
+-              sm_change = true;
+-      else
+-              sm_change = false;
+-
+       fill_random(&v_in, sizeof(v_in));
+       memcpy(v_expected, v_in, sizeof(v_in));
+       memset(v_out, 0, sizeof(v_out));
+@@ -953,12 +946,7 @@ static void set_initial_values(struct test_config *config)
+       if (fpmr_supported()) {
+               fill_random(&fpmr_in, sizeof(fpmr_in));
+               fpmr_in &= FPMR_SAFE_BITS;
+-
+-              /* Entering or exiting streaming mode clears FPMR */
+-              if (sm_change)
+-                      fpmr_expected = 0;
+-              else
+-                      fpmr_expected = fpmr_in;
++              fpmr_expected = fpmr_in;
+       } else {
+               fpmr_in = 0;
+               fpmr_expected = 0;
+-- 
+2.39.5
+
diff --git a/queue-6.15/kselftest-cpufreq-get-rid-of-double-suspend-in-rtcwa.patch b/queue-6.15/kselftest-cpufreq-get-rid-of-double-suspend-in-rtcwa.patch
new file mode 100644 (file)
index 0000000..a69f47d
--- /dev/null
@@ -0,0 +1,52 @@
+From b6a3c39f2f45cabfeae6f5b1f57599c20c3a303c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Apr 2025 10:55:49 -0400
+Subject: kselftest: cpufreq: Get rid of double suspend in rtcwake case
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+
+[ Upstream commit 23b88515a318680337f21d0a2fceee8038ccffc8 ]
+
+Commit 0b631ed3ce92 ("kselftest: cpufreq: Add RTC wakeup alarm") added
+support for automatic wakeup in the suspend routine of the cpufreq
+kselftest by using rtcwake, however it left the manual power state
+change in the common path. The end result is that when running the
+cpufreq kselftest with '-t suspend_rtc' or '-t hibernate_rtc', the
+system will go to sleep and be woken up by the RTC, but then immediately
+go to sleep again with no wakeup programmed, so it will sleep forever in
+an automated testing setup.
+
+Fix this by moving the manual power state change so that it only happens
+when not using rtcwake.
+
+Link: https://lore.kernel.org/r/20250430-ksft-cpufreq-suspend-rtc-double-fix-v1-1-dc17a729c5a7@collabora.com
+Fixes: 0b631ed3ce92 ("kselftest: cpufreq: Add RTC wakeup alarm")
+Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/cpufreq/cpufreq.sh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/cpufreq/cpufreq.sh b/tools/testing/selftests/cpufreq/cpufreq.sh
+index e350c521b4675..3aad9db921b53 100755
+--- a/tools/testing/selftests/cpufreq/cpufreq.sh
++++ b/tools/testing/selftests/cpufreq/cpufreq.sh
+@@ -244,9 +244,10 @@ do_suspend()
+                                       printf "Failed to suspend using RTC wake alarm\n"
+                                       return 1
+                               fi
++                      else
++                              echo $filename > $SYSFS/power/state
+                       fi
+-                      echo $filename > $SYSFS/power/state
+                       printf "Came out of $1\n"
+                       printf "Do basic tests after finishing $1 to verify cpufreq state\n\n"
+-- 
+2.39.5
+
diff --git a/queue-6.15/ktls-sockmap-fix-missing-uncharge-operation.patch b/queue-6.15/ktls-sockmap-fix-missing-uncharge-operation.patch
new file mode 100644 (file)
index 0000000..7fc7a09
--- /dev/null
@@ -0,0 +1,59 @@
+From dd35661091db189a2abf807fd315c583e13df915 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 13:59:57 +0800
+Subject: ktls, sockmap: Fix missing uncharge operation
+
+From: Jiayuan Chen <jiayuan.chen@linux.dev>
+
+[ Upstream commit 79f0c39ae7d3dc628c01b02f23ca5d01f9875040 ]
+
+When we specify apply_bytes, we divide the msg into multiple segments,
+each with a length of 'send', and every time we send this part of the data
+using tcp_bpf_sendmsg_redir(), we use sk_msg_return_zero() to uncharge the
+memory of the specified 'send' size.
+
+However, if the first segment of data fails to send, for example, the
+peer's buffer is full, we need to release all of the msg. When releasing
+the msg, we haven't uncharged the memory of the subsequent segments.
+
+This modification does not make significant logical changes, but only
+fills in the missing uncharge places.
+
+This issue has existed all along, until it was exposed after we added the
+apply test in test_sockmap:
+commit 3448ad23b34e ("selftests/bpf: Add apply_bytes test to test_txmsg_redir_wait_sndmem in test_sockmap")
+
+Fixes: d3b18ad31f93 ("tls: add bpf support to sk_msg handling")
+Reported-by: Cong Wang <xiyou.wangcong@gmail.com>
+Closes: https://lore.kernel.org/bpf/aAmIi0vlycHtbXeb@pop-os.localdomain/T/#t
+Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Acked-by: John Fastabend <john.fastabend@gmail.com>
+Reviewed-by: Cong Wang <xiyou.wangcong@gmail.com>
+Link: https://lore.kernel.org/r/20250425060015.6968-2-jiayuan.chen@linux.dev
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tls/tls_sw.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
+index f3d7d19482da9..fc88e34b7f33f 100644
+--- a/net/tls/tls_sw.c
++++ b/net/tls/tls_sw.c
+@@ -908,6 +908,13 @@ static int bpf_exec_tx_verdict(struct sk_msg *msg, struct sock *sk,
+                                           &msg_redir, send, flags);
+               lock_sock(sk);
+               if (err < 0) {
++                      /* Regardless of whether the data represented by
++                       * msg_redir is sent successfully, we have already
++                       * uncharged it via sk_msg_return_zero(). The
++                       * msg->sg.size represents the remaining unprocessed
++                       * data, which needs to be uncharged here.
++                       */
++                      sk_mem_uncharge(sk, msg->sg.size);
+                       *copied -= sk_msg_free_nocharge(sk, &msg_redir);
+                       msg->sg.size = 0;
+               }
+-- 
+2.39.5
+
diff --git a/queue-6.15/kunit-fix-wrong-parameter-to-kunit_deactivate_static.patch b/queue-6.15/kunit-fix-wrong-parameter-to-kunit_deactivate_static.patch
new file mode 100644 (file)
index 0000000..d3abde8
--- /dev/null
@@ -0,0 +1,41 @@
+From 7777af76c346fe55ffbb97ba6f9a414474e66fda Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 May 2025 08:20:49 +0000
+Subject: kunit: Fix wrong parameter to kunit_deactivate_static_stub()
+
+From: Tzung-Bi Shih <tzungbi@kernel.org>
+
+[ Upstream commit 772e50a76ee664e75581624f512df4e45582605a ]
+
+kunit_deactivate_static_stub() accepts real_fn_addr instead of
+replacement_addr.  In the case, it always passes NULL to
+kunit_deactivate_static_stub().
+
+Fix it.
+
+Link: https://lore.kernel.org/r/20250520082050.2254875-1-tzungbi@kernel.org
+Fixes: e047c5eaa763 ("kunit: Expose 'static stub' API to redirect functions")
+Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
+Reviewed-by: David Gow <davidgow@google.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/kunit/static_stub.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/kunit/static_stub.c b/lib/kunit/static_stub.c
+index 92b2cccd5e763..484fd85251b41 100644
+--- a/lib/kunit/static_stub.c
++++ b/lib/kunit/static_stub.c
+@@ -96,7 +96,7 @@ void __kunit_activate_static_stub(struct kunit *test,
+       /* If the replacement address is NULL, deactivate the stub. */
+       if (!replacement_addr) {
+-              kunit_deactivate_static_stub(test, replacement_addr);
++              kunit_deactivate_static_stub(test, real_fn_addr);
+               return;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/kunit-qemu_configs-disable-faulting-tests-on-32-bit-.patch b/queue-6.15/kunit-qemu_configs-disable-faulting-tests-on-32-bit-.patch
new file mode 100644 (file)
index 0000000..299229d
--- /dev/null
@@ -0,0 +1,46 @@
+From f0b446a605cabd365656856b9da91cb1168c9caf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Apr 2025 17:38:25 +0800
+Subject: kunit: qemu_configs: Disable faulting tests on 32-bit SPARC
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: David Gow <davidgow@google.com>
+
+[ Upstream commit 1d31d536871fe8b16c8c0de58d201c78e21eb3a2 ]
+
+The 32-bit sparc configuration (--arch sparc) crashes on
+the kunit_fault_test. It's known that some architectures don't handle
+deliberate segfaults in kernel mode well, so there's a config switch to
+disable tests which rely upon it by default.
+
+Use this for the sparc config, making sure the default config for it
+passes.
+
+Link: https://lore.kernel.org/r/20250416093826.1550040-1-davidgow@google.com
+Fixes: 87c9c1631788 ("kunit: tool: add support for QEMU")
+Signed-off-by: David Gow <davidgow@google.com>
+Reviewed-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
+Tested-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/kunit/qemu_configs/sparc.py | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tools/testing/kunit/qemu_configs/sparc.py b/tools/testing/kunit/qemu_configs/sparc.py
+index 3131dd299a6e3..2019550a1b692 100644
+--- a/tools/testing/kunit/qemu_configs/sparc.py
++++ b/tools/testing/kunit/qemu_configs/sparc.py
+@@ -2,6 +2,7 @@ from ..qemu_config import QemuArchParams
+ QEMU_ARCH = QemuArchParams(linux_arch='sparc',
+                          kconfig='''
++CONFIG_KUNIT_FAULT_TEST=n
+ CONFIG_SPARC32=y
+ CONFIG_SERIAL_SUNZILOG=y
+ CONFIG_SERIAL_SUNZILOG_CONSOLE=y
+-- 
+2.39.5
+
diff --git a/queue-6.15/kunit-qemu_configs-sparc-explicitly-enable-config_sp.patch b/queue-6.15/kunit-qemu_configs-sparc-explicitly-enable-config_sp.patch
new file mode 100644 (file)
index 0000000..f35b199
--- /dev/null
@@ -0,0 +1,42 @@
+From 877b34bc3be117ca903d2750382e2c21002c7883 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Apr 2025 15:38:05 +0200
+Subject: kunit: qemu_configs: sparc: Explicitly enable CONFIG_SPARC32=y
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
+
+[ Upstream commit d16b3d0fb43cb0f9eb21b35c2d2c870b3f38ab1d ]
+
+The configuration generated by kunit ends up with a 32bit configuration.
+A new kunit configuration for 64bit is to be added.
+To make the difference clearer spell out the variant in the kunit
+reference config.
+
+Link: https://lore.kernel.org/r/20250415-kunit-qemu-sparc64-v1-1-253906f61102@linutronix.de
+Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
+Reviewed-by: David Gow <davidgow@google.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Stable-dep-of: 1d31d536871f ("kunit: qemu_configs: Disable faulting tests on 32-bit SPARC")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/kunit/qemu_configs/sparc.py | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tools/testing/kunit/qemu_configs/sparc.py b/tools/testing/kunit/qemu_configs/sparc.py
+index 256d9573b4464..3131dd299a6e3 100644
+--- a/tools/testing/kunit/qemu_configs/sparc.py
++++ b/tools/testing/kunit/qemu_configs/sparc.py
+@@ -2,6 +2,7 @@ from ..qemu_config import QemuArchParams
+ QEMU_ARCH = QemuArchParams(linux_arch='sparc',
+                          kconfig='''
++CONFIG_SPARC32=y
+ CONFIG_SERIAL_SUNZILOG=y
+ CONFIG_SERIAL_SUNZILOG_CONSOLE=y
+ ''',
+-- 
+2.39.5
+
diff --git a/queue-6.15/kunit-usercopy-disable-u64-test-on-32-bit-sparc.patch b/queue-6.15/kunit-usercopy-disable-u64-test-on-32-bit-sparc.patch
new file mode 100644 (file)
index 0000000..ddc50fc
--- /dev/null
@@ -0,0 +1,45 @@
+From 64532866f168a9c66a560bd0690cdb3db388c824 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Apr 2025 14:44:19 +0200
+Subject: kunit/usercopy: Disable u64 test on 32-bit SPARC
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
+
+[ Upstream commit 0d6efa20e384a41a7f4afdcd8a0aec442c19d33e ]
+
+usercopy of 64 bit values does not work on 32-bit SPARC:
+
+    # usercopy_test_valid: EXPECTATION FAILED at lib/tests/usercopy_kunit.c:209
+    Expected val_u64 == 0x5a5b5c5d6a6b6c6d, but
+        val_u64 == 1515936861 (0x5a5b5c5d)
+        0x5a5b5c5d6a6b6c6d == 6510899242581322861 (0x5a5b5c5d6a6b6c6d)
+
+Disable the test.
+
+Fixes: 4c5d7bc63775 ("usercopy: Add tests for all get_user() sizes")
+Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
+Link: https://lore.kernel.org/r/20250416-kunit-sparc-usercopy-v1-1-a772054db3af@linutronix.de
+Signed-off-by: Kees Cook <kees@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/tests/usercopy_kunit.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/lib/tests/usercopy_kunit.c b/lib/tests/usercopy_kunit.c
+index 77fa00a13df77..80f8abe10968c 100644
+--- a/lib/tests/usercopy_kunit.c
++++ b/lib/tests/usercopy_kunit.c
+@@ -27,6 +27,7 @@
+                           !defined(CONFIG_MICROBLAZE) &&      \
+                           !defined(CONFIG_NIOS2) &&           \
+                           !defined(CONFIG_PPC32) &&           \
++                          !defined(CONFIG_SPARC32) &&         \
+                           !defined(CONFIG_SUPERH))
+ # define TEST_U64
+ #endif
+-- 
+2.39.5
+
diff --git a/queue-6.15/libbpf-fix-buffer-overflow-in-bpf_object__init_prog.patch b/queue-6.15/libbpf-fix-buffer-overflow-in-bpf_object__init_prog.patch
new file mode 100644 (file)
index 0000000..12da861
--- /dev/null
@@ -0,0 +1,106 @@
+From 27a994029c518ccbb18c1db4b969a1bb238b2610 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Apr 2025 17:50:14 +0200
+Subject: libbpf: Fix buffer overflow in bpf_object__init_prog
+
+From: Viktor Malik <vmalik@redhat.com>
+
+[ Upstream commit ee684de5c1b0ac01821320826baec7da93f3615b ]
+
+As shown in [1], it is possible to corrupt a BPF ELF file such that
+arbitrary BPF instructions are loaded by libbpf. This can be done by
+setting a symbol (BPF program) section offset to a large (unsigned)
+number such that <section start + symbol offset> overflows and points
+before the section data in the memory.
+
+Consider the situation below where:
+- prog_start = sec_start + symbol_offset    <-- size_t overflow here
+- prog_end   = prog_start + prog_size
+
+    prog_start        sec_start        prog_end        sec_end
+        |                |                 |              |
+        v                v                 v              v
+    .....................|################################|............
+
+The report in [1] also provides a corrupted BPF ELF which can be used as
+a reproducer:
+
+    $ readelf -S crash
+    Section Headers:
+      [Nr] Name              Type             Address           Offset
+           Size              EntSize          Flags  Link  Info  Align
+    ...
+      [ 2] uretprobe.mu[...] PROGBITS         0000000000000000  00000040
+           0000000000000068  0000000000000000  AX       0     0     8
+
+    $ readelf -s crash
+    Symbol table '.symtab' contains 8 entries:
+       Num:    Value          Size Type    Bind   Vis      Ndx Name
+    ...
+         6: ffffffffffffffb8   104 FUNC    GLOBAL DEFAULT    2 handle_tp
+
+Here, the handle_tp prog has section offset ffffffffffffffb8, i.e. will
+point before the actual memory where section 2 is allocated.
+
+This is also reported by AddressSanitizer:
+
+    =================================================================
+    ==1232==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7c7302fe0000 at pc 0x7fc3046e4b77 bp 0x7ffe64677cd0 sp 0x7ffe64677490
+    READ of size 104 at 0x7c7302fe0000 thread T0
+        #0 0x7fc3046e4b76 in memcpy (/lib64/libasan.so.8+0xe4b76)
+        #1 0x00000040df3e in bpf_object__init_prog /src/libbpf/src/libbpf.c:856
+        #2 0x00000040df3e in bpf_object__add_programs /src/libbpf/src/libbpf.c:928
+        #3 0x00000040df3e in bpf_object__elf_collect /src/libbpf/src/libbpf.c:3930
+        #4 0x00000040df3e in bpf_object_open /src/libbpf/src/libbpf.c:8067
+        #5 0x00000040f176 in bpf_object__open_file /src/libbpf/src/libbpf.c:8090
+        #6 0x000000400c16 in main /poc/poc.c:8
+        #7 0x7fc3043d25b4 in __libc_start_call_main (/lib64/libc.so.6+0x35b4)
+        #8 0x7fc3043d2667 in __libc_start_main@@GLIBC_2.34 (/lib64/libc.so.6+0x3667)
+        #9 0x000000400b34 in _start (/poc/poc+0x400b34)
+
+    0x7c7302fe0000 is located 64 bytes before 104-byte region [0x7c7302fe0040,0x7c7302fe00a8)
+    allocated by thread T0 here:
+        #0 0x7fc3046e716b in malloc (/lib64/libasan.so.8+0xe716b)
+        #1 0x7fc3045ee600 in __libelf_set_rawdata_wrlock (/lib64/libelf.so.1+0xb600)
+        #2 0x7fc3045ef018 in __elf_getdata_rdlock (/lib64/libelf.so.1+0xc018)
+        #3 0x00000040642f in elf_sec_data /src/libbpf/src/libbpf.c:3740
+
+The problem here is that currently, libbpf only checks that the program
+end is within the section bounds. There used to be a check
+`while (sec_off < sec_sz)` in bpf_object__add_programs, however, it was
+removed by commit 6245947c1b3c ("libbpf: Allow gaps in BPF program
+sections to support overriden weak functions").
+
+Add a check for detecting the overflow of `sec_off + prog_sz` to
+bpf_object__init_prog to fix this issue.
+
+[1] https://github.com/lmarch2/poc/blob/main/libbpf/libbpf.md
+
+Fixes: 6245947c1b3c ("libbpf: Allow gaps in BPF program sections to support overriden weak functions")
+Reported-by: lmarch2 <2524158037@qq.com>
+Signed-off-by: Viktor Malik <vmalik@redhat.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Reviewed-by: Shung-Hsi Yu <shung-hsi.yu@suse.com>
+Link: https://github.com/lmarch2/poc/blob/main/libbpf/libbpf.md
+Link: https://lore.kernel.org/bpf/20250415155014.397603-1-vmalik@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/libbpf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
+index 37d563e140515..cfb952d7002f6 100644
+--- a/tools/lib/bpf/libbpf.c
++++ b/tools/lib/bpf/libbpf.c
+@@ -896,7 +896,7 @@ bpf_object__add_programs(struct bpf_object *obj, Elf_Data *sec_data,
+                       return -LIBBPF_ERRNO__FORMAT;
+               }
+-              if (sec_off + prog_sz > sec_sz) {
++              if (sec_off + prog_sz > sec_sz || sec_off + prog_sz < sec_off) {
+                       pr_warn("sec '%s': program at offset %zu crosses section boundary\n",
+                               sec_name, sec_off);
+                       return -LIBBPF_ERRNO__FORMAT;
+-- 
+2.39.5
+
diff --git a/queue-6.15/libbpf-fix-event-name-too-long-error.patch b/queue-6.15/libbpf-fix-event-name-too-long-error.patch
new file mode 100644 (file)
index 0000000..b9985d5
--- /dev/null
@@ -0,0 +1,160 @@
+From 71b5a1af3337cd336206a9009f57ddb680da335c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Apr 2025 09:48:46 +0800
+Subject: libbpf: Fix event name too long error
+
+From: Feng Yang <yangfeng@kylinos.cn>
+
+[ Upstream commit 4dde20b1aa85d69c4281eaac9a7cfa7d2b62ecf0 ]
+
+When the binary path is excessively long, the generated probe_name in libbpf
+exceeds the kernel's MAX_EVENT_NAME_LEN limit (64 bytes).
+This causes legacy uprobe event attachment to fail with error code -22.
+
+The fix reorders the fields to place the unique ID before the name.
+This ensures that even if truncation occurs via snprintf, the unique ID
+remains intact, preserving event name uniqueness. Additionally, explicit
+checks with MAX_EVENT_NAME_LEN are added to enforce length constraints.
+
+Before Fix:
+       ./test_progs -t attach_probe/kprobe-long_name
+       ......
+       libbpf: failed to add legacy kprobe event for 'bpf_testmod_looooooooooooooooooooooooooooooong_name+0x0': -EINVAL
+       libbpf: prog 'handle_kprobe': failed to create kprobe 'bpf_testmod_looooooooooooooooooooooooooooooong_name+0x0' perf event: -EINVAL
+       test_attach_kprobe_long_event_name:FAIL:attach_kprobe_long_event_name unexpected error: -22
+       test_attach_probe:PASS:uprobe_ref_ctr_cleanup 0 nsec
+       #13/11   attach_probe/kprobe-long_name:FAIL
+       #13      attach_probe:FAIL
+
+       ./test_progs -t attach_probe/uprobe-long_name
+       ......
+       libbpf: failed to add legacy uprobe event for /root/linux-bpf/bpf-next/tools/testing/selftests/bpf/test_progs:0x13efd9: -EINVAL
+       libbpf: prog 'handle_uprobe': failed to create uprobe '/root/linux-bpf/bpf-next/tools/testing/selftests/bpf/test_progs:0x13efd9' perf event: -EINVAL
+       test_attach_uprobe_long_event_name:FAIL:attach_uprobe_long_event_name unexpected error: -22
+       #13/10   attach_probe/uprobe-long_name:FAIL
+       #13      attach_probe:FAIL
+After Fix:
+       ./test_progs -t attach_probe/uprobe-long_name
+       #13/10   attach_probe/uprobe-long_name:OK
+       #13      attach_probe:OK
+       Summary: 1/1 PASSED, 0 SKIPPED, 0 FAILED
+
+       ./test_progs -t attach_probe/kprobe-long_name
+       #13/11   attach_probe/kprobe-long_name:OK
+       #13      attach_probe:OK
+       Summary: 1/1 PASSED, 0 SKIPPED, 0 FAILED
+
+Fixes: 46ed5fc33db9 ("libbpf: Refactor and simplify legacy kprobe code")
+Fixes: cc10623c6810 ("libbpf: Add legacy uprobe attaching support")
+Signed-off-by: Hengqi Chen <hengqi.chen@gmail.com>
+Signed-off-by: Feng Yang <yangfeng@kylinos.cn>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20250417014848.59321-2-yangfeng59949@163.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/libbpf.c | 43 ++++++++++++++++--------------------------
+ 1 file changed, 16 insertions(+), 27 deletions(-)
+
+diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
+index cfb952d7002f6..087bb8daa46b5 100644
+--- a/tools/lib/bpf/libbpf.c
++++ b/tools/lib/bpf/libbpf.c
+@@ -60,6 +60,8 @@
+ #define BPF_FS_MAGIC          0xcafe4a11
+ #endif
++#define MAX_EVENT_NAME_LEN    64
++
+ #define BPF_FS_DEFAULT_PATH "/sys/fs/bpf"
+ #define BPF_INSN_SZ (sizeof(struct bpf_insn))
+@@ -11112,16 +11114,16 @@ static const char *tracefs_available_filter_functions_addrs(void)
+                            : TRACEFS"/available_filter_functions_addrs";
+ }
+-static void gen_kprobe_legacy_event_name(char *buf, size_t buf_sz,
+-                                       const char *kfunc_name, size_t offset)
++static void gen_probe_legacy_event_name(char *buf, size_t buf_sz,
++                                      const char *name, size_t offset)
+ {
+       static int index = 0;
+       int i;
+-      snprintf(buf, buf_sz, "libbpf_%u_%s_0x%zx_%d", getpid(), kfunc_name, offset,
+-               __sync_fetch_and_add(&index, 1));
++      snprintf(buf, buf_sz, "libbpf_%u_%d_%s_0x%zx", getpid(),
++               __sync_fetch_and_add(&index, 1), name, offset);
+-      /* sanitize binary_path in the probe name */
++      /* sanitize name in the probe name */
+       for (i = 0; buf[i]; i++) {
+               if (!isalnum(buf[i]))
+                       buf[i] = '_';
+@@ -11246,9 +11248,9 @@ int probe_kern_syscall_wrapper(int token_fd)
+               return pfd >= 0 ? 1 : 0;
+       } else { /* legacy mode */
+-              char probe_name[128];
++              char probe_name[MAX_EVENT_NAME_LEN];
+-              gen_kprobe_legacy_event_name(probe_name, sizeof(probe_name), syscall_name, 0);
++              gen_probe_legacy_event_name(probe_name, sizeof(probe_name), syscall_name, 0);
+               if (add_kprobe_event_legacy(probe_name, false, syscall_name, 0) < 0)
+                       return 0;
+@@ -11304,10 +11306,10 @@ bpf_program__attach_kprobe_opts(const struct bpf_program *prog,
+                                           func_name, offset,
+                                           -1 /* pid */, 0 /* ref_ctr_off */);
+       } else {
+-              char probe_name[256];
++              char probe_name[MAX_EVENT_NAME_LEN];
+-              gen_kprobe_legacy_event_name(probe_name, sizeof(probe_name),
+-                                           func_name, offset);
++              gen_probe_legacy_event_name(probe_name, sizeof(probe_name),
++                                          func_name, offset);
+               legacy_probe = strdup(probe_name);
+               if (!legacy_probe)
+@@ -11851,20 +11853,6 @@ static int attach_uprobe_multi(const struct bpf_program *prog, long cookie, stru
+       return ret;
+ }
+-static void gen_uprobe_legacy_event_name(char *buf, size_t buf_sz,
+-                                       const char *binary_path, uint64_t offset)
+-{
+-      int i;
+-
+-      snprintf(buf, buf_sz, "libbpf_%u_%s_0x%zx", getpid(), binary_path, (size_t)offset);
+-
+-      /* sanitize binary_path in the probe name */
+-      for (i = 0; buf[i]; i++) {
+-              if (!isalnum(buf[i]))
+-                      buf[i] = '_';
+-      }
+-}
+-
+ static inline int add_uprobe_event_legacy(const char *probe_name, bool retprobe,
+                                         const char *binary_path, size_t offset)
+ {
+@@ -12288,13 +12276,14 @@ bpf_program__attach_uprobe_opts(const struct bpf_program *prog, pid_t pid,
+               pfd = perf_event_open_probe(true /* uprobe */, retprobe, binary_path,
+                                           func_offset, pid, ref_ctr_off);
+       } else {
+-              char probe_name[PATH_MAX + 64];
++              char probe_name[MAX_EVENT_NAME_LEN];
+               if (ref_ctr_off)
+                       return libbpf_err_ptr(-EINVAL);
+-              gen_uprobe_legacy_event_name(probe_name, sizeof(probe_name),
+-                                           binary_path, func_offset);
++              gen_probe_legacy_event_name(probe_name, sizeof(probe_name),
++                                          strrchr(binary_path, '/') ? : binary_path,
++                                          func_offset);
+               legacy_probe = strdup(probe_name);
+               if (!legacy_probe)
+-- 
+2.39.5
+
diff --git a/queue-6.15/libbpf-fix-implicit-memfd_create-for-bionic.patch b/queue-6.15/libbpf-fix-implicit-memfd_create-for-bionic.patch
new file mode 100644 (file)
index 0000000..3715b8f
--- /dev/null
@@ -0,0 +1,88 @@
+From c6f6f2daf22436250e1ca97c3e80475b3b79a13d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 30 Mar 2025 21:13:23 +0000
+Subject: libbpf: Fix implicit memfd_create() for bionic
+
+From: Carlos Llamas <cmllamas@google.com>
+
+[ Upstream commit 75011ad69bc54396703867b5434f1622343a848e ]
+
+Since memfd_create() is not consistently available across different
+bionic libc implementations, using memfd_create() directly can break
+some Android builds:
+
+  tools/lib/bpf/linker.c:576:7: error: implicit declaration of function 'memfd_create' [-Werror,-Wimplicit-function-declaration]
+    576 |         fd = memfd_create(filename, 0);
+        |              ^
+
+To fix this, relocate and inline the sys_memfd_create() helper so that
+it can be used in "linker.c". Similar issues were previously fixed by
+commit 9fa5e1a180aa ("libbpf: Call memfd_create() syscall directly").
+
+Fixes: 6d5e5e5d7ce1 ("libbpf: Extend linker API to support in-memory ELF files")
+Signed-off-by: Carlos Llamas <cmllamas@google.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20250330211325.530677-1-cmllamas@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/libbpf.c          | 9 ---------
+ tools/lib/bpf/libbpf_internal.h | 9 +++++++++
+ tools/lib/bpf/linker.c          | 2 +-
+ 3 files changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
+index 6b85060f07b3b..37d563e140515 100644
+--- a/tools/lib/bpf/libbpf.c
++++ b/tools/lib/bpf/libbpf.c
+@@ -1725,15 +1725,6 @@ static Elf64_Sym *find_elf_var_sym(const struct bpf_object *obj, const char *nam
+       return ERR_PTR(-ENOENT);
+ }
+-/* Some versions of Android don't provide memfd_create() in their libc
+- * implementation, so avoid complications and just go straight to Linux
+- * syscall.
+- */
+-static int sys_memfd_create(const char *name, unsigned flags)
+-{
+-      return syscall(__NR_memfd_create, name, flags);
+-}
+-
+ #ifndef MFD_CLOEXEC
+ #define MFD_CLOEXEC 0x0001U
+ #endif
+diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_internal.h
+index 76669c73dcd16..477a3b3389a09 100644
+--- a/tools/lib/bpf/libbpf_internal.h
++++ b/tools/lib/bpf/libbpf_internal.h
+@@ -667,6 +667,15 @@ static inline int sys_dup3(int oldfd, int newfd, int flags)
+       return syscall(__NR_dup3, oldfd, newfd, flags);
+ }
++/* Some versions of Android don't provide memfd_create() in their libc
++ * implementation, so avoid complications and just go straight to Linux
++ * syscall.
++ */
++static inline int sys_memfd_create(const char *name, unsigned flags)
++{
++      return syscall(__NR_memfd_create, name, flags);
++}
++
+ /* Point *fixed_fd* to the same file that *tmp_fd* points to.
+  * Regardless of success, *tmp_fd* is closed.
+  * Whatever *fixed_fd* pointed to is closed silently.
+diff --git a/tools/lib/bpf/linker.c b/tools/lib/bpf/linker.c
+index 800e0ef09c378..56f5068e2ebab 100644
+--- a/tools/lib/bpf/linker.c
++++ b/tools/lib/bpf/linker.c
+@@ -573,7 +573,7 @@ int bpf_linker__add_buf(struct bpf_linker *linker, void *buf, size_t buf_sz,
+       snprintf(filename, sizeof(filename), "mem:%p+%zu", buf, buf_sz);
+-      fd = memfd_create(filename, 0);
++      fd = sys_memfd_create(filename, 0);
+       if (fd < 0) {
+               ret = -errno;
+               pr_warn("failed to create memfd '%s': %s\n", filename, errstr(ret));
+-- 
+2.39.5
+
diff --git a/queue-6.15/libbpf-remove-sample_period-init-in-perf_buffer.patch b/queue-6.15/libbpf-remove-sample_period-init-in-perf_buffer.patch
new file mode 100644 (file)
index 0000000..a368e0a
--- /dev/null
@@ -0,0 +1,39 @@
+From 4d96a4417fd49ab9731e7baf5bff49885d8e71f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Apr 2025 00:39:01 +0800
+Subject: libbpf: Remove sample_period init in perf_buffer
+
+From: Tao Chen <chen.dylane@linux.dev>
+
+[ Upstream commit 64821d25f05ac468d435e61669ae745ce5a633ea ]
+
+It seems that sample_period is not used in perf buffer. Actually, only
+wakeup_events are meaningful to enable events aggregation for wakeup notification.
+Remove sample_period setting code to avoid confusion.
+
+Fixes: fb84b8224655 ("libbpf: add perf buffer API")
+Signed-off-by: Tao Chen <chen.dylane@linux.dev>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Acked-by: Jiri Olsa <jolsa@kernel.org>
+Acked-by: Namhyung Kim <namhyung@kernel.org>
+Link: https://lore.kernel.org/bpf/20250423163901.2983689-1-chen.dylane@linux.dev
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/libbpf.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
+index 087bb8daa46b5..2bc0e3bfdd491 100644
+--- a/tools/lib/bpf/libbpf.c
++++ b/tools/lib/bpf/libbpf.c
+@@ -13351,7 +13351,6 @@ struct perf_buffer *perf_buffer__new(int map_fd, size_t page_cnt,
+       attr.config = PERF_COUNT_SW_BPF_OUTPUT;
+       attr.type = PERF_TYPE_SOFTWARE;
+       attr.sample_type = PERF_SAMPLE_RAW;
+-      attr.sample_period = sample_period;
+       attr.wakeup_events = sample_period;
+       p.attr = &attr;
+-- 
+2.39.5
+
diff --git a/queue-6.15/libbpf-use-proper-errno-value-in-linker.patch b/queue-6.15/libbpf-use-proper-errno-value-in-linker.patch
new file mode 100644 (file)
index 0000000..568be6c
--- /dev/null
@@ -0,0 +1,49 @@
+From 0e7c75a409d865dd17231e99a4a946e6a293ec01 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Apr 2025 12:08:20 +0000
+Subject: libbpf: Use proper errno value in linker
+
+From: Anton Protopopov <a.s.protopopov@gmail.com>
+
+[ Upstream commit 358b1c0f56ebb6996fcec7dcdcf6bae5dcbc8b6c ]
+
+Return values of the linker_append_sec_data() and the
+linker_append_elf_relos() functions are propagated all the
+way up to users of libbpf API. In some error cases these
+functions return -1 which will be seen as -EPERM from user's
+point of view. Instead, return a more reasonable -EINVAL.
+
+Fixes: faf6ed321cf6 ("libbpf: Add BPF static linker APIs")
+Signed-off-by: Anton Protopopov <a.s.protopopov@gmail.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20250430120820.2262053-1-a.s.protopopov@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/linker.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/lib/bpf/linker.c b/tools/lib/bpf/linker.c
+index 56f5068e2ebab..a469e5d4fee70 100644
+--- a/tools/lib/bpf/linker.c
++++ b/tools/lib/bpf/linker.c
+@@ -1376,7 +1376,7 @@ static int linker_append_sec_data(struct bpf_linker *linker, struct src_obj *obj
+               } else {
+                       if (!secs_match(dst_sec, src_sec)) {
+                               pr_warn("ELF sections %s are incompatible\n", src_sec->sec_name);
+-                              return -1;
++                              return -EINVAL;
+                       }
+                       /* "license" and "version" sections are deduped */
+@@ -2223,7 +2223,7 @@ static int linker_append_elf_relos(struct bpf_linker *linker, struct src_obj *ob
+                       }
+               } else if (!secs_match(dst_sec, src_sec)) {
+                       pr_warn("sections %s are not compatible\n", src_sec->sec_name);
+-                      return -1;
++                      return -EINVAL;
+               }
+               /* shdr->sh_link points to SYMTAB */
+-- 
+2.39.5
+
diff --git a/queue-6.15/libbpf-use-proper-errno-value-in-nlattr.patch b/queue-6.15/libbpf-use-proper-errno-value-in-nlattr.patch
new file mode 100644 (file)
index 0000000..7d568e7
--- /dev/null
@@ -0,0 +1,75 @@
+From a1d7326f1c0a2d135f4925ee3220fe7d13064501 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 10 May 2025 18:20:11 +0000
+Subject: libbpf: Use proper errno value in nlattr
+
+From: Anton Protopopov <a.s.protopopov@gmail.com>
+
+[ Upstream commit fd5fd538a1f4b34cee6823ba0ddda2f7a55aca96 ]
+
+Return value of the validate_nla() function can be propagated all the
+way up to users of libbpf API. In case of error this libbpf version
+of validate_nla returns -1 which will be seen as -EPERM from user's
+point of view. Instead, return a more reasonable -EINVAL.
+
+Fixes: bbf48c18ee0c ("libbpf: add error reporting in XDP")
+Suggested-by: Andrii Nakryiko <andrii@kernel.org>
+Signed-off-by: Anton Protopopov <a.s.protopopov@gmail.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20250510182011.2246631-1-a.s.protopopov@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/nlattr.c | 15 +++++++--------
+ 1 file changed, 7 insertions(+), 8 deletions(-)
+
+diff --git a/tools/lib/bpf/nlattr.c b/tools/lib/bpf/nlattr.c
+index 975e265eab3bf..06663f9ea581f 100644
+--- a/tools/lib/bpf/nlattr.c
++++ b/tools/lib/bpf/nlattr.c
+@@ -63,16 +63,16 @@ static int validate_nla(struct nlattr *nla, int maxtype,
+               minlen = nla_attr_minlen[pt->type];
+       if (libbpf_nla_len(nla) < minlen)
+-              return -1;
++              return -EINVAL;
+       if (pt->maxlen && libbpf_nla_len(nla) > pt->maxlen)
+-              return -1;
++              return -EINVAL;
+       if (pt->type == LIBBPF_NLA_STRING) {
+               char *data = libbpf_nla_data(nla);
+               if (data[libbpf_nla_len(nla) - 1] != '\0')
+-                      return -1;
++                      return -EINVAL;
+       }
+       return 0;
+@@ -118,19 +118,18 @@ int libbpf_nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head,
+               if (policy) {
+                       err = validate_nla(nla, maxtype, policy);
+                       if (err < 0)
+-                              goto errout;
++                              return err;
+               }
+-              if (tb[type])
++              if (tb[type]) {
+                       pr_warn("Attribute of type %#x found multiple times in message, "
+                               "previous attribute is being ignored.\n", type);
++              }
+               tb[type] = nla;
+       }
+-      err = 0;
+-errout:
+-      return err;
++      return 0;
+ }
+ /**
+-- 
+2.39.5
+
diff --git a/queue-6.15/loop-add-file_start_write-and-file_end_write.patch b/queue-6.15/loop-add-file_start_write-and-file_end_write.patch
new file mode 100644 (file)
index 0000000..e5dc01c
--- /dev/null
@@ -0,0 +1,63 @@
+From 0b1d33d06b2f5bc3abfc2f073b53267214d1a0ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 May 2025 23:34:05 +0800
+Subject: loop: add file_start_write() and file_end_write()
+
+From: Ming Lei <ming.lei@redhat.com>
+
+[ Upstream commit 39d86db34e41b96bd86f1955cd0ce6cd9c5fca4c ]
+
+file_start_write() and file_end_write() should be added around ->write_iter().
+
+Recently we switch to ->write_iter() from vfs_iter_write(), and the
+implied file_start_write() and file_end_write() are lost.
+
+Also we never add them for dio code path, so add them back for covering
+both.
+
+Cc: Jeff Moyer <jmoyer@redhat.com>
+Fixes: f2fed441c69b ("loop: stop using vfs_iter_{read,write} for buffered I/O")
+Fixes: bc07c10a3603 ("block: loop: support DIO & AIO")
+Signed-off-by: Ming Lei <ming.lei@redhat.com>
+Link: https://lore.kernel.org/r/20250527153405.837216-1-ming.lei@redhat.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/loop.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/block/loop.c b/drivers/block/loop.c
+index e2b1f377f5856..f8d136684109a 100644
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -308,11 +308,14 @@ static void lo_complete_rq(struct request *rq)
+ static void lo_rw_aio_do_completion(struct loop_cmd *cmd)
+ {
+       struct request *rq = blk_mq_rq_from_pdu(cmd);
++      struct loop_device *lo = rq->q->queuedata;
+       if (!atomic_dec_and_test(&cmd->ref))
+               return;
+       kfree(cmd->bvec);
+       cmd->bvec = NULL;
++      if (req_op(rq) == REQ_OP_WRITE)
++              file_end_write(lo->lo_backing_file);
+       if (likely(!blk_should_fake_timeout(rq->q)))
+               blk_mq_complete_request(rq);
+ }
+@@ -387,9 +390,10 @@ static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd,
+               cmd->iocb.ki_flags = 0;
+       }
+-      if (rw == ITER_SOURCE)
++      if (rw == ITER_SOURCE) {
++              file_start_write(lo->lo_backing_file);
+               ret = file->f_op->write_iter(&cmd->iocb, &iter);
+-      else
++      } else
+               ret = file->f_op->read_iter(&cmd->iocb, &iter);
+       lo_rw_aio_do_completion(cmd);
+-- 
+2.39.5
+
diff --git a/queue-6.15/m68k-mac-fix-macintosh_config-for-mac-ii.patch b/queue-6.15/m68k-mac-fix-macintosh_config-for-mac-ii.patch
new file mode 100644 (file)
index 0000000..7c1b69e
--- /dev/null
@@ -0,0 +1,46 @@
+From eb8b717f7b588b106ab6abcf426a81a0a7f8c08b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Apr 2025 10:07:26 +1000
+Subject: m68k: mac: Fix macintosh_config for Mac II
+
+From: Finn Thain <fthain@linux-m68k.org>
+
+[ Upstream commit 52ae3f5da7e5adbe3d1319573b55dac470abb83c ]
+
+When booted on my Mac II, the kernel prints this:
+
+    Detected Macintosh model: 6
+    Apple Macintosh Unknown
+
+The catch-all entry ("Unknown") is mac_data_table[0] which is only needed
+in the unlikely event that the bootinfo model ID can't be matched.
+When model ID is 6, the search should begin and end at mac_data_table[1].
+Fix the off-by-one error that causes this problem.
+
+Cc: Joshua Thompson <funaho@jurai.org>
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Finn Thain <fthain@linux-m68k.org>
+Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Link: https://lore.kernel.org/d0f30a551064ca4810b1c48d5a90954be80634a9.1745453246.git.fthain@linux-m68k.org
+Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/m68k/mac/config.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c
+index e324410ef239c..d26c7f4f8c360 100644
+--- a/arch/m68k/mac/config.c
++++ b/arch/m68k/mac/config.c
+@@ -793,7 +793,7 @@ static void __init mac_identify(void)
+       }
+       macintosh_config = mac_data_table;
+-      for (m = macintosh_config; m->ident != -1; m++) {
++      for (m = &mac_data_table[1]; m->ident != -1; m++) {
+               if (m->ident == model) {
+                       macintosh_config = m;
+                       break;
+-- 
+2.39.5
+
diff --git a/queue-6.15/mailbox-imx-fix-txdb_v2-sending.patch b/queue-6.15/mailbox-imx-fix-txdb_v2-sending.patch
new file mode 100644 (file)
index 0000000..26d3d84
--- /dev/null
@@ -0,0 +1,73 @@
+From 3dd8987c057a362c274643c1ac809b0e37a21b10 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 25 May 2025 16:47:24 +0800
+Subject: mailbox: imx: Fix TXDB_V2 sending
+
+From: Peng Fan <peng.fan@nxp.com>
+
+[ Upstream commit f5cb07ec6aabd1bb56adbdeb5f0d70cb524db2cd ]
+
+i.MX95 features several processing domains, Cortex-M7, Cortex-A55
+secure, Cortex-A55 non-secure. Each domain could communicate with
+SCMI firmware with a dedicated MU. But the current NXP SCMI firmware
+is not a RTOS, all processing logic codes are in interrupt context.
+So if high priority Cortex-M7 is communicating with SCMI firmware and
+requires a bit more time to handle the SCMI call, Linux MU TXDB_V2
+will be timeout with high possiblity in 1000us(the current value in
+imx-mailbox.c). Per NXP SCMI firmware design, if timeout, there is
+no recover logic, so SCMI agents should never timeout and always
+wait until the check condition met.
+
+Based on the upper reason, enlarge the timeout value to 10ms which
+is less chance to timeout, and retry if timeout really happends.
+
+Fixes: 5bfe4067d350 ("mailbox: imx: support channel type tx doorbell v2")
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mailbox/imx-mailbox.c | 21 +++++++++++++++------
+ 1 file changed, 15 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c
+index 6ef8338add0d6..6778afc64a048 100644
+--- a/drivers/mailbox/imx-mailbox.c
++++ b/drivers/mailbox/imx-mailbox.c
+@@ -226,7 +226,7 @@ static int imx_mu_generic_tx(struct imx_mu_priv *priv,
+ {
+       u32 *arg = data;
+       u32 val;
+-      int ret;
++      int ret, count;
+       switch (cp->type) {
+       case IMX_MU_TYPE_TX:
+@@ -240,11 +240,20 @@ static int imx_mu_generic_tx(struct imx_mu_priv *priv,
+       case IMX_MU_TYPE_TXDB_V2:
+               imx_mu_write(priv, IMX_MU_xCR_GIRn(priv->dcfg->type, cp->idx),
+                            priv->dcfg->xCR[IMX_MU_GCR]);
+-              ret = readl_poll_timeout(priv->base + priv->dcfg->xCR[IMX_MU_GCR], val,
+-                                       !(val & IMX_MU_xCR_GIRn(priv->dcfg->type, cp->idx)),
+-                                       0, 1000);
+-              if (ret)
+-                      dev_warn_ratelimited(priv->dev, "channel type: %d failure\n", cp->type);
++              ret = -ETIMEDOUT;
++              count = 0;
++              while (ret && (count < 10)) {
++                      ret =
++                      readl_poll_timeout(priv->base + priv->dcfg->xCR[IMX_MU_GCR], val,
++                                         !(val & IMX_MU_xCR_GIRn(priv->dcfg->type, cp->idx)),
++                                         0, 10000);
++
++                      if (ret) {
++                              dev_warn_ratelimited(priv->dev,
++                                                   "channel type: %d timeout, %d times, retry\n",
++                                                   cp->type, ++count);
++                      }
++              }
+               break;
+       default:
+               dev_warn_ratelimited(priv->dev, "Send data on wrong channel type: %d\n", cp->type);
+-- 
+2.39.5
+
diff --git a/queue-6.15/mailbox-mchp-ipc-sbi-fix-compile_test-build-error.patch b/queue-6.15/mailbox-mchp-ipc-sbi-fix-compile_test-build-error.patch
new file mode 100644 (file)
index 0000000..c25a66e
--- /dev/null
@@ -0,0 +1,48 @@
+From 32cc6cb982f3c8727116077f42d81d6400483298 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Apr 2025 15:57:47 +0800
+Subject: mailbox: mchp-ipc-sbi: Fix COMPILE_TEST build error
+
+From: Yue Haibing <yuehaibing@huawei.com>
+
+[ Upstream commit d635ba4207c31940398c41caa0cedd80f3b9c9c7 ]
+
+If COMPILE_TEST is y but RISCV_SBI is n, build fails:
+
+drivers/mailbox/mailbox-mchp-ipc-sbi.c: In function 'mchp_ipc_sbi_chan_send':
+drivers/mailbox/mailbox-mchp-ipc-sbi.c:119:23: error: storage size of 'ret' isn't known
+       struct sbiret ret;
+                     ^~~
+  CC      drivers/nvmem/lpc18xx_otp.o
+drivers/mailbox/mailbox-mchp-ipc-sbi.c:121:15: error: implicit declaration of function 'sbi_ecall' [-Werror=implicit-function-declaration]
+       ret = sbi_ecall(SBI_EXT_MICROCHIP_TECHNOLOGY, command, channel,
+             ^~~~~~~~~
+
+move COMPILE_TEST to ARCH_MICROCHIP dependency as other drivers.
+
+Fixes: e4b1d67e7141 ("mailbox: add Microchip IPC support")
+Signed-off-by: Yue Haibing <yuehaibing@huawei.com>
+Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mailbox/Kconfig | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
+index ed52db272f4d0..e8445cda7c618 100644
+--- a/drivers/mailbox/Kconfig
++++ b/drivers/mailbox/Kconfig
+@@ -191,8 +191,8 @@ config POLARFIRE_SOC_MAILBOX
+ config MCHP_SBI_IPC_MBOX
+       tristate "Microchip Inter-processor Communication (IPC) SBI driver"
+-      depends on RISCV_SBI || COMPILE_TEST
+-      depends on ARCH_MICROCHIP
++      depends on RISCV_SBI
++      depends on ARCH_MICROCHIP || COMPILE_TEST
+       help
+         Mailbox implementation for Microchip devices with an
+         Inter-process communication (IPC) controller.
+-- 
+2.39.5
+
diff --git a/queue-6.15/mailbox-mtk-cmdq-refine-gce_gctl_value-setting.patch b/queue-6.15/mailbox-mtk-cmdq-refine-gce_gctl_value-setting.patch
new file mode 100644 (file)
index 0000000..7da7747
--- /dev/null
@@ -0,0 +1,144 @@
+From 5a53163d04713c2fc23b9f333de6d8529357f56c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Apr 2025 11:55:47 +0800
+Subject: mailbox: mtk-cmdq: Refine GCE_GCTL_VALUE setting
+
+From: Jason-JH Lin <jason-jh.lin@mediatek.com>
+
+[ Upstream commit 9fcebcb37c3e0a4b6eb40768cc5a5faebf166fbe ]
+
+Add cmdq_gctl_value_toggle() to configure GCE_CTRL_BY_SW and GCE_DDR_EN
+together in the same GCE_GCTL_VALUE register.
+
+For the SoCs whose GCE is located in MMINFRA and uses MMINFRA_AO power,
+this allows it to be written without enabling the clocks. Otherwise, all
+GCE registers should be written after the GCE clocks are enabled.
+Move this function into cmdq_runtime_resume() and cmdq_runtime_suspend()
+to ensure it is called when the GCE clock is enabled.
+
+Fixes: 7abd037aa581 ("mailbox: mtk-cmdq: add gce ddr enable support flow")
+Signed-off-by: Jason-JH Lin <jason-jh.lin@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mailbox/mtk-cmdq-mailbox.c | 51 +++++++++++++-----------------
+ 1 file changed, 22 insertions(+), 29 deletions(-)
+
+diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c
+index d186865b8dce6..ab4e8d1954a16 100644
+--- a/drivers/mailbox/mtk-cmdq-mailbox.c
++++ b/drivers/mailbox/mtk-cmdq-mailbox.c
+@@ -92,18 +92,6 @@ struct gce_plat {
+       u32 gce_num;
+ };
+-static void cmdq_sw_ddr_enable(struct cmdq *cmdq, bool enable)
+-{
+-      WARN_ON(clk_bulk_enable(cmdq->pdata->gce_num, cmdq->clocks));
+-
+-      if (enable)
+-              writel(GCE_DDR_EN | GCE_CTRL_BY_SW, cmdq->base + GCE_GCTL_VALUE);
+-      else
+-              writel(GCE_CTRL_BY_SW, cmdq->base + GCE_GCTL_VALUE);
+-
+-      clk_bulk_disable(cmdq->pdata->gce_num, cmdq->clocks);
+-}
+-
+ u8 cmdq_get_shift_pa(struct mbox_chan *chan)
+ {
+       struct cmdq *cmdq = container_of(chan->mbox, struct cmdq, mbox);
+@@ -112,6 +100,19 @@ u8 cmdq_get_shift_pa(struct mbox_chan *chan)
+ }
+ EXPORT_SYMBOL(cmdq_get_shift_pa);
++static void cmdq_gctl_value_toggle(struct cmdq *cmdq, bool ddr_enable)
++{
++      u32 val = cmdq->pdata->control_by_sw ? GCE_CTRL_BY_SW : 0;
++
++      if (!cmdq->pdata->control_by_sw && !cmdq->pdata->sw_ddr_en)
++              return;
++
++      if (cmdq->pdata->sw_ddr_en && ddr_enable)
++              val |= GCE_DDR_EN;
++
++      writel(val, cmdq->base + GCE_GCTL_VALUE);
++}
++
+ static int cmdq_thread_suspend(struct cmdq *cmdq, struct cmdq_thread *thread)
+ {
+       u32 status;
+@@ -140,16 +141,10 @@ static void cmdq_thread_resume(struct cmdq_thread *thread)
+ static void cmdq_init(struct cmdq *cmdq)
+ {
+       int i;
+-      u32 gctl_regval = 0;
+       WARN_ON(clk_bulk_enable(cmdq->pdata->gce_num, cmdq->clocks));
+-      if (cmdq->pdata->control_by_sw)
+-              gctl_regval = GCE_CTRL_BY_SW;
+-      if (cmdq->pdata->sw_ddr_en)
+-              gctl_regval |= GCE_DDR_EN;
+-      if (gctl_regval)
+-              writel(gctl_regval, cmdq->base + GCE_GCTL_VALUE);
++      cmdq_gctl_value_toggle(cmdq, true);
+       writel(CMDQ_THR_ACTIVE_SLOT_CYCLES, cmdq->base + CMDQ_THR_SLOT_CYCLES);
+       for (i = 0; i <= CMDQ_MAX_EVENT; i++)
+@@ -315,14 +310,21 @@ static irqreturn_t cmdq_irq_handler(int irq, void *dev)
+ static int cmdq_runtime_resume(struct device *dev)
+ {
+       struct cmdq *cmdq = dev_get_drvdata(dev);
++      int ret;
+-      return clk_bulk_enable(cmdq->pdata->gce_num, cmdq->clocks);
++      ret = clk_bulk_enable(cmdq->pdata->gce_num, cmdq->clocks);
++      if (ret)
++              return ret;
++
++      cmdq_gctl_value_toggle(cmdq, true);
++      return 0;
+ }
+ static int cmdq_runtime_suspend(struct device *dev)
+ {
+       struct cmdq *cmdq = dev_get_drvdata(dev);
++      cmdq_gctl_value_toggle(cmdq, false);
+       clk_bulk_disable(cmdq->pdata->gce_num, cmdq->clocks);
+       return 0;
+ }
+@@ -347,9 +349,6 @@ static int cmdq_suspend(struct device *dev)
+       if (task_running)
+               dev_warn(dev, "exist running task(s) in suspend\n");
+-      if (cmdq->pdata->sw_ddr_en)
+-              cmdq_sw_ddr_enable(cmdq, false);
+-
+       return pm_runtime_force_suspend(dev);
+ }
+@@ -360,9 +359,6 @@ static int cmdq_resume(struct device *dev)
+       WARN_ON(pm_runtime_force_resume(dev));
+       cmdq->suspended = false;
+-      if (cmdq->pdata->sw_ddr_en)
+-              cmdq_sw_ddr_enable(cmdq, true);
+-
+       return 0;
+ }
+@@ -370,9 +366,6 @@ static void cmdq_remove(struct platform_device *pdev)
+ {
+       struct cmdq *cmdq = platform_get_drvdata(pdev);
+-      if (cmdq->pdata->sw_ddr_en)
+-              cmdq_sw_ddr_enable(cmdq, false);
+-
+       if (!IS_ENABLED(CONFIG_PM))
+               cmdq_runtime_suspend(&pdev->dev);
+-- 
+2.39.5
+
diff --git a/queue-6.15/md-raid1-raid10-don-t-handle-io-error-for-req_rahead.patch b/queue-6.15/md-raid1-raid10-don-t-handle-io-error-for-req_rahead.patch
new file mode 100644 (file)
index 0000000..d8af0c4
--- /dev/null
@@ -0,0 +1,146 @@
+From f000a2f93059c1c05674939a2683cc8f5e7e7c46 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 May 2025 16:14:07 +0800
+Subject: md/raid1,raid10: don't handle IO error for REQ_RAHEAD and REQ_NOWAIT
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit 9f346f7d4ea73692b82f5102ca8698e4040469ea ]
+
+IO with REQ_RAHEAD or REQ_NOWAIT can fail early, even if the storage medium
+is fine, hence record badblocks or remove the disk from array does not
+make sense.
+
+This problem if found by lvm2 test lvcreate-large-raid, where dm-zero
+will fail read ahead IO directly.
+
+Fixes: e879a0d9cb08 ("md/raid1,raid10: don't ignore IO flags")
+Reported-and-tested-by: Mikulas Patocka <mpatocka@redhat.com>
+Closes: https://lore.kernel.org/all/34fa755d-62c8-4588-8ee1-33cb1249bdf2@redhat.com/
+Link: https://lore.kernel.org/linux-raid/20250527081407.3004055-1-yukuai1@huaweicloud.com
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/raid1-10.c | 10 ++++++++++
+ drivers/md/raid1.c    | 19 ++++++++++---------
+ drivers/md/raid10.c   | 11 ++++++-----
+ 3 files changed, 26 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/md/raid1-10.c b/drivers/md/raid1-10.c
+index c7efd8aab675c..b8b3a90697012 100644
+--- a/drivers/md/raid1-10.c
++++ b/drivers/md/raid1-10.c
+@@ -293,3 +293,13 @@ static inline bool raid1_should_read_first(struct mddev *mddev,
+       return false;
+ }
++
++/*
++ * bio with REQ_RAHEAD or REQ_NOWAIT can fail at anytime, before such IO is
++ * submitted to the underlying disks, hence don't record badblocks or retry
++ * in this case.
++ */
++static inline bool raid1_should_handle_error(struct bio *bio)
++{
++      return !(bio->bi_opf & (REQ_RAHEAD | REQ_NOWAIT));
++}
+diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
+index de9bccbe7337b..1fe645e630012 100644
+--- a/drivers/md/raid1.c
++++ b/drivers/md/raid1.c
+@@ -373,14 +373,16 @@ static void raid1_end_read_request(struct bio *bio)
+        */
+       update_head_pos(r1_bio->read_disk, r1_bio);
+-      if (uptodate)
++      if (uptodate) {
+               set_bit(R1BIO_Uptodate, &r1_bio->state);
+-      else if (test_bit(FailFast, &rdev->flags) &&
+-               test_bit(R1BIO_FailFast, &r1_bio->state))
++      } else if (test_bit(FailFast, &rdev->flags) &&
++               test_bit(R1BIO_FailFast, &r1_bio->state)) {
+               /* This was a fail-fast read so we definitely
+                * want to retry */
+               ;
+-      else {
++      } else if (!raid1_should_handle_error(bio)) {
++              uptodate = 1;
++      } else {
+               /* If all other devices have failed, we want to return
+                * the error upwards rather than fail the last device.
+                * Here we redefine "uptodate" to mean "Don't want to retry"
+@@ -451,16 +453,15 @@ static void raid1_end_write_request(struct bio *bio)
+       struct bio *to_put = NULL;
+       int mirror = find_bio_disk(r1_bio, bio);
+       struct md_rdev *rdev = conf->mirrors[mirror].rdev;
+-      bool discard_error;
+       sector_t lo = r1_bio->sector;
+       sector_t hi = r1_bio->sector + r1_bio->sectors;
+-
+-      discard_error = bio->bi_status && bio_op(bio) == REQ_OP_DISCARD;
++      bool ignore_error = !raid1_should_handle_error(bio) ||
++              (bio->bi_status && bio_op(bio) == REQ_OP_DISCARD);
+       /*
+        * 'one mirror IO has finished' event handler:
+        */
+-      if (bio->bi_status && !discard_error) {
++      if (bio->bi_status && !ignore_error) {
+               set_bit(WriteErrorSeen, &rdev->flags);
+               if (!test_and_set_bit(WantReplacement, &rdev->flags))
+                       set_bit(MD_RECOVERY_NEEDED, &
+@@ -511,7 +512,7 @@ static void raid1_end_write_request(struct bio *bio)
+               /* Maybe we can clear some bad blocks. */
+               if (rdev_has_badblock(rdev, r1_bio->sector, r1_bio->sectors) &&
+-                  !discard_error) {
++                  !ignore_error) {
+                       r1_bio->bios[mirror] = IO_MADE_GOOD;
+                       set_bit(R1BIO_MadeGood, &r1_bio->state);
+               }
+diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
+index ba32bac975b8d..54320a887ecc5 100644
+--- a/drivers/md/raid10.c
++++ b/drivers/md/raid10.c
+@@ -399,6 +399,8 @@ static void raid10_end_read_request(struct bio *bio)
+                * wait for the 'master' bio.
+                */
+               set_bit(R10BIO_Uptodate, &r10_bio->state);
++      } else if (!raid1_should_handle_error(bio)) {
++              uptodate = 1;
+       } else {
+               /* If all other devices that store this block have
+                * failed, we want to return the error upwards rather
+@@ -456,9 +458,8 @@ static void raid10_end_write_request(struct bio *bio)
+       int slot, repl;
+       struct md_rdev *rdev = NULL;
+       struct bio *to_put = NULL;
+-      bool discard_error;
+-
+-      discard_error = bio->bi_status && bio_op(bio) == REQ_OP_DISCARD;
++      bool ignore_error = !raid1_should_handle_error(bio) ||
++              (bio->bi_status && bio_op(bio) == REQ_OP_DISCARD);
+       dev = find_bio_disk(conf, r10_bio, bio, &slot, &repl);
+@@ -472,7 +473,7 @@ static void raid10_end_write_request(struct bio *bio)
+       /*
+        * this branch is our 'one mirror IO has finished' event handler:
+        */
+-      if (bio->bi_status && !discard_error) {
++      if (bio->bi_status && !ignore_error) {
+               if (repl)
+                       /* Never record new bad blocks to replacement,
+                        * just fail it.
+@@ -527,7 +528,7 @@ static void raid10_end_write_request(struct bio *bio)
+               /* Maybe we can clear some bad blocks. */
+               if (rdev_has_badblock(rdev, r10_bio->devs[slot].addr,
+                                     r10_bio->sectors) &&
+-                  !discard_error) {
++                  !ignore_error) {
+                       bio_put(bio);
+                       if (repl)
+                               r10_bio->devs[slot].repl_bio = IO_MADE_GOOD;
+-- 
+2.39.5
+
diff --git a/queue-6.15/media-rkvdec-fix-frame-size-enumeration.patch b/queue-6.15/media-rkvdec-fix-frame-size-enumeration.patch
new file mode 100644 (file)
index 0000000..b371629
--- /dev/null
@@ -0,0 +1,56 @@
+From ffc92b5f5fe7b1edb65b535c8162ffba2083eeeb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Feb 2025 10:40:33 +0100
+Subject: media: rkvdec: Fix frame size enumeration
+
+From: Jonas Karlman <jonas@kwiboo.se>
+
+[ Upstream commit f270005b99fa19fee9a6b4006e8dee37c10f1944 ]
+
+The VIDIOC_ENUM_FRAMESIZES ioctl should return all frame sizes (i.e.
+width and height in pixels) that the device supports for the given pixel
+format.
+
+It doesn't make a lot of sense to return the frame-sizes in a stepwise
+manner, which is used to enforce hardware alignments requirements for
+CAPTURE buffers, for coded formats.
+
+Instead, applications should receive an indication, about the maximum
+supported frame size for that hardware decoder, via a continuous
+frame-size enumeration.
+
+Fixes: cd33c830448b ("media: rkvdec: Add the rkvdec driver")
+Suggested-by: Alex Bee <knaerzche@gmail.com>
+Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
+Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/media/rkvdec/rkvdec.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c
+index f9bef5173bf25..a9bfd5305410c 100644
+--- a/drivers/staging/media/rkvdec/rkvdec.c
++++ b/drivers/staging/media/rkvdec/rkvdec.c
+@@ -213,8 +213,14 @@ static int rkvdec_enum_framesizes(struct file *file, void *priv,
+       if (!fmt)
+               return -EINVAL;
+-      fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
+-      fsize->stepwise = fmt->frmsize;
++      fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
++      fsize->stepwise.min_width = 1;
++      fsize->stepwise.max_width = fmt->frmsize.max_width;
++      fsize->stepwise.step_width = 1;
++      fsize->stepwise.min_height = 1;
++      fsize->stepwise.max_height = fmt->frmsize.max_height;
++      fsize->stepwise.step_height = 1;
++
+       return 0;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/media-synopsys-hdmirx-count-dropped-frames.patch b/queue-6.15/media-synopsys-hdmirx-count-dropped-frames.patch
new file mode 100644 (file)
index 0000000..f76a544
--- /dev/null
@@ -0,0 +1,51 @@
+From b1d546af9e5a5fc9739dd488219177cdda11d591 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Apr 2025 16:43:47 -0400
+Subject: media: synopsys: hdmirx: Count dropped frames
+
+From: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+
+[ Upstream commit 57c8d79adf05244b171964d1d6c7e6fabbe5f5fd ]
+
+The sequence number communicate the lost frames to userspace. For this
+reason, it must be incremented even when a frame is skipped. This allows
+userspace such as GStreamer to report the loss.
+
+Fixes: 7b59b132ad439 ("media: platform: synopsys: Add support for HDMI input driver")
+Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Reviewed-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
+Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c b/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c
+index f5b3f5010ede5..7af6765532e33 100644
+--- a/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c
++++ b/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c
+@@ -1956,10 +1956,6 @@ static void dma_idle_int_handler(struct snps_hdmirx_dev *hdmirx_dev,
+                                       vb_done->field = V4L2_FIELD_NONE;
+                               hdmirx_vb_done(stream, vb_done);
+-                              stream->sequence++;
+-                              if (stream->sequence == 30)
+-                                      v4l2_dbg(1, debug, v4l2_dev,
+-                                               "rcv frames\n");
+                       }
+                       stream->curr_buf = NULL;
+@@ -1971,6 +1967,10 @@ static void dma_idle_int_handler(struct snps_hdmirx_dev *hdmirx_dev,
+                       v4l2_dbg(3, debug, v4l2_dev,
+                                "%s: next_buf NULL, skip vb_done\n", __func__);
+               }
++
++              stream->sequence++;
++              if (stream->sequence == 30)
++                      v4l2_dbg(1, debug, v4l2_dev, "rcv frames\n");
+       }
+ DMA_IDLE_OUT:
+-- 
+2.39.5
+
diff --git a/queue-6.15/media-synopsys-hdmirx-renamed-frame_idx-to-sequence.patch b/queue-6.15/media-synopsys-hdmirx-renamed-frame_idx-to-sequence.patch
new file mode 100644 (file)
index 0000000..02668e4
--- /dev/null
@@ -0,0 +1,68 @@
+From a732f9fb5a0b7054c5e1c69336eea5fa3dc8e974 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Apr 2025 16:43:46 -0400
+Subject: media: synopsys: hdmirx: Renamed frame_idx to sequence
+
+From: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+
+[ Upstream commit 0400bee67f49753b878c2576c02c1bc454f091ed ]
+
+This variable is used to fill the v4l2_buffer.sequence, let's name it
+the exact same way to reduce confusion.
+
+No functional changes.
+
+Fixes: 7b59b132ad439 ("media: platform: synopsys: Add support for HDMI input driver")
+Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Reviewed-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
+Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c b/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c
+index 3d2913de9a86c..f5b3f5010ede5 100644
+--- a/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c
++++ b/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c
+@@ -114,7 +114,7 @@ struct hdmirx_stream {
+       spinlock_t vbq_lock; /* to lock video buffer queue */
+       bool stopping;
+       wait_queue_head_t wq_stopped;
+-      u32 frame_idx;
++      u32 sequence;
+       u32 line_flag_int_cnt;
+       u32 irq_stat;
+ };
+@@ -1540,7 +1540,7 @@ static int hdmirx_start_streaming(struct vb2_queue *queue, unsigned int count)
+       int line_flag;
+       mutex_lock(&hdmirx_dev->stream_lock);
+-      stream->frame_idx = 0;
++      stream->sequence = 0;
+       stream->line_flag_int_cnt = 0;
+       stream->curr_buf = NULL;
+       stream->next_buf = NULL;
+@@ -1948,7 +1948,7 @@ static void dma_idle_int_handler(struct snps_hdmirx_dev *hdmirx_dev,
+                       if (vb_done) {
+                               vb_done->vb2_buf.timestamp = ktime_get_ns();
+-                              vb_done->sequence = stream->frame_idx;
++                              vb_done->sequence = stream->sequence;
+                               if (bt->interlaced)
+                                       vb_done->field = V4L2_FIELD_INTERLACED_TB;
+@@ -1956,8 +1956,8 @@ static void dma_idle_int_handler(struct snps_hdmirx_dev *hdmirx_dev,
+                                       vb_done->field = V4L2_FIELD_NONE;
+                               hdmirx_vb_done(stream, vb_done);
+-                              stream->frame_idx++;
+-                              if (stream->frame_idx == 30)
++                              stream->sequence++;
++                              if (stream->sequence == 30)
+                                       v4l2_dbg(1, debug, v4l2_dev,
+                                                "rcv frames\n");
+                       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/media-verisilicon-free-post-processor-buffers-on-err.patch b/queue-6.15/media-verisilicon-free-post-processor-buffers-on-err.patch
new file mode 100644 (file)
index 0000000..4c680b4
--- /dev/null
@@ -0,0 +1,47 @@
+From 13d78a7ba8e2f37b8ce87056d1278b6cd2650be3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 15:24:47 -0400
+Subject: media: verisilicon: Free post processor buffers on error
+
+From: Detlev Casanova <detlev.casanova@collabora.com>
+
+[ Upstream commit 11beb0fc346e00c412b3bfd19013206f6b655604 ]
+
+During initialization, the post processor allocates the same number of
+buffers as the buf queue.
+As the init function is called in streamon(), if an allocation fails,
+streamon will return an error and streamoff() will not be called, keeping
+all post processor buffers allocated.
+
+To avoid that, all post proc buffers are freed in case of an allocation
+error.
+
+Fixes: 26711491a807 ("media: verisilicon: Refactor postprocessor to store more buffers")
+Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
+Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/verisilicon/hantro_postproc.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/platform/verisilicon/hantro_postproc.c b/drivers/media/platform/verisilicon/hantro_postproc.c
+index c435a393e0cb7..9f559a13d409b 100644
+--- a/drivers/media/platform/verisilicon/hantro_postproc.c
++++ b/drivers/media/platform/verisilicon/hantro_postproc.c
+@@ -250,8 +250,10 @@ int hantro_postproc_init(struct hantro_ctx *ctx)
+       for (i = 0; i < num_buffers; i++) {
+               ret = hantro_postproc_alloc(ctx, i);
+-              if (ret)
++              if (ret) {
++                      hantro_postproc_free(ctx);
+                       return ret;
++              }
+       }
+       return 0;
+-- 
+2.39.5
+
diff --git a/queue-6.15/mei-vsc-cast-tx_buf-to-__be32-when-passed-to-cpu_to_.patch b/queue-6.15/mei-vsc-cast-tx_buf-to-__be32-when-passed-to-cpu_to_.patch
new file mode 100644 (file)
index 0000000..8395b86
--- /dev/null
@@ -0,0 +1,68 @@
+From 7e415b93515cba178b551d1e49caeff5e1910e33 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 May 2025 11:07:28 +0200
+Subject: mei: vsc: Cast tx_buf to (__be32 *) when passed to
+ cpu_to_be32_array()
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 97ce0fe2b7240d47d9124daa92217e478c21a3ba ]
+
+Commit f88c0c72ffb0 ("mei: vsc: Use struct vsc_tp_packet as vsc-tp tx_buf
+and rx_buf type") changed the type of tx_buf from "void *" to "struct
+vsc_tp_packet *" and added a cast to (u32 *) when passing it to
+cpu_to_be32_array() and the same change was made for rx_buf.
+
+This triggers the type-check warning in sparse:
+
+vsc-tp.c:327:28: sparse: expected restricted __be32 [usertype] *dst
+vsc-tp.c:327:28: sparse: got unsigned int [usertype] *
+
+vsc-tp.c:343:42: sparse: expected restricted __be32 const [usertype] *src
+vsc-tp.c:343:42: sparse: got unsigned int [usertype] *
+
+Fix this by casting to (__be32 *) instead.
+
+Note actually changing the type of the buffers to "be32 *" is not an option
+this buffer does actually contain a "struct vsc_tp_packet" and is used
+as such most of the time. vsc_tp_rom_xfer() re-uses the buffers as just
+dumb arrays of 32 bit words to talk to the device before the firmware has
+booted, to avoid needing to allocate a separate buffer.
+
+Fixes: f88c0c72ffb0 ("mei: vsc: Use struct vsc_tp_packet as vsc-tp tx_buf and rx_buf type")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202505071634.kZ0I7Va6-lkp@intel.com/
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Reviewed-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Link: https://lore.kernel.org/r/20250507090728.115910-1-hdegoede@redhat.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/mei/vsc-tp.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/misc/mei/vsc-tp.c b/drivers/misc/mei/vsc-tp.c
+index da26a080916c5..267d0de5fade8 100644
+--- a/drivers/misc/mei/vsc-tp.c
++++ b/drivers/misc/mei/vsc-tp.c
+@@ -324,7 +324,7 @@ int vsc_tp_rom_xfer(struct vsc_tp *tp, const void *obuf, void *ibuf, size_t len)
+       guard(mutex)(&tp->mutex);
+       /* rom xfer is big endian */
+-      cpu_to_be32_array((u32 *)tp->tx_buf, obuf, words);
++      cpu_to_be32_array((__be32 *)tp->tx_buf, obuf, words);
+       ret = read_poll_timeout(gpiod_get_value_cansleep, ret,
+                               !ret, VSC_TP_ROM_XFER_POLL_DELAY_US,
+@@ -340,7 +340,7 @@ int vsc_tp_rom_xfer(struct vsc_tp *tp, const void *obuf, void *ibuf, size_t len)
+               return ret;
+       if (ibuf)
+-              be32_to_cpu_array(ibuf, (u32 *)tp->rx_buf, words);
++              be32_to_cpu_array(ibuf, (__be32 *)tp->rx_buf, words);
+       return ret;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/mfd-exynos-lpass-avoid-calling-exynos_lpass_disable-.patch b/queue-6.15/mfd-exynos-lpass-avoid-calling-exynos_lpass_disable-.patch
new file mode 100644 (file)
index 0000000..53e711c
--- /dev/null
@@ -0,0 +1,38 @@
+From 63f74fc4a308b3bcb8ded360c57c5d52067ab8f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Apr 2025 17:00:34 +0200
+Subject: mfd: exynos-lpass: Avoid calling exynos_lpass_disable() twice in
+ exynos_lpass_remove()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit b70b84556eeca5262d290e8619fe0af5b7664a52 ]
+
+exynos_lpass_disable() is called twice in the remove function. Remove
+one of these calls.
+
+Fixes: 90f447170c6f ("mfd: exynos-lpass: Add runtime PM support")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/74d69e8de10308c9855db6d54155a3de4b11abfd.1745247209.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/exynos-lpass.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/mfd/exynos-lpass.c b/drivers/mfd/exynos-lpass.c
+index 6b95927e99be7..a2785ceea8bfc 100644
+--- a/drivers/mfd/exynos-lpass.c
++++ b/drivers/mfd/exynos-lpass.c
+@@ -141,7 +141,6 @@ static void exynos_lpass_remove(struct platform_device *pdev)
+ {
+       struct exynos_lpass *lpass = platform_get_drvdata(pdev);
+-      exynos_lpass_disable(lpass);
+       pm_runtime_disable(&pdev->dev);
+       if (!pm_runtime_status_suspended(&pdev->dev))
+               exynos_lpass_disable(lpass);
+-- 
+2.39.5
+
diff --git a/queue-6.15/mfd-exynos-lpass-fix-an-error-handling-path-in-exyno.patch b/queue-6.15/mfd-exynos-lpass-fix-an-error-handling-path-in-exyno.patch
new file mode 100644 (file)
index 0000000..9f3b80e
--- /dev/null
@@ -0,0 +1,51 @@
+From cdcdd28b50dc44d2fcfb724ac259a38892fe73e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Apr 2025 17:00:33 +0200
+Subject: mfd: exynos-lpass: Fix an error handling path in exynos_lpass_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 484f0f59f09edd1f6fa63703c12eb30d72a519ac ]
+
+If an error occurs after a successful regmap_init_mmio(), regmap_exit()
+should be called as already done in the .remove() function.
+
+Switch to devm_regmap_init_mmio() to avoid the leak and simplify the
+.remove() function.
+
+Fixes: c414df12bdf7 ("mfd: exynos-lpass: Add missing remove() function")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/38414eecb1096840946756ae86887aea2a489c1b.1745247209.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/exynos-lpass.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/mfd/exynos-lpass.c b/drivers/mfd/exynos-lpass.c
+index 6a585173230b1..6b95927e99be7 100644
+--- a/drivers/mfd/exynos-lpass.c
++++ b/drivers/mfd/exynos-lpass.c
+@@ -122,8 +122,8 @@ static int exynos_lpass_probe(struct platform_device *pdev)
+       if (IS_ERR(lpass->sfr0_clk))
+               return PTR_ERR(lpass->sfr0_clk);
+-      lpass->top = regmap_init_mmio(dev, base_top,
+-                                      &exynos_lpass_reg_conf);
++      lpass->top = devm_regmap_init_mmio(dev, base_top,
++                                         &exynos_lpass_reg_conf);
+       if (IS_ERR(lpass->top)) {
+               dev_err(dev, "LPASS top regmap initialization failed\n");
+               return PTR_ERR(lpass->top);
+@@ -145,7 +145,6 @@ static void exynos_lpass_remove(struct platform_device *pdev)
+       pm_runtime_disable(&pdev->dev);
+       if (!pm_runtime_status_suspended(&pdev->dev))
+               exynos_lpass_disable(lpass);
+-      regmap_exit(lpass->top);
+ }
+ static int __maybe_unused exynos_lpass_suspend(struct device *dev)
+-- 
+2.39.5
+
diff --git a/queue-6.15/mfd-exynos-lpass-fix-another-error-handling-path-in-.patch b/queue-6.15/mfd-exynos-lpass-fix-another-error-handling-path-in-.patch
new file mode 100644 (file)
index 0000000..6ae9f67
--- /dev/null
@@ -0,0 +1,85 @@
+From 125aaad28dbcee6cbcb465c4419f03033fa9c664 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Apr 2025 17:00:35 +0200
+Subject: mfd: exynos-lpass: Fix another error handling path in
+ exynos_lpass_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit f41cc37f4bc0e8cd424697bf6e26586cadcf4b9b ]
+
+If devm_of_platform_populate() fails, some clean-up needs to be done, as
+already done in the remove function.
+
+Add a new devm_add_action_or_reset() to fix the leak in the probe and
+remove the need of a remove function.
+
+Fixes: c695abab2429 ("mfd: Add Samsung Exynos Low Power Audio Subsystem driver")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/69471e839efc0249a504492a8de3497fcdb6a009.1745247209.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/exynos-lpass.c | 25 +++++++++++++++----------
+ 1 file changed, 15 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/mfd/exynos-lpass.c b/drivers/mfd/exynos-lpass.c
+index a2785ceea8bfc..44797001a4322 100644
+--- a/drivers/mfd/exynos-lpass.c
++++ b/drivers/mfd/exynos-lpass.c
+@@ -104,11 +104,22 @@ static const struct regmap_config exynos_lpass_reg_conf = {
+       .fast_io        = true,
+ };
++static void exynos_lpass_disable_lpass(void *data)
++{
++      struct platform_device *pdev = data;
++      struct exynos_lpass *lpass = platform_get_drvdata(pdev);
++
++      pm_runtime_disable(&pdev->dev);
++      if (!pm_runtime_status_suspended(&pdev->dev))
++              exynos_lpass_disable(lpass);
++}
++
+ static int exynos_lpass_probe(struct platform_device *pdev)
+ {
+       struct device *dev = &pdev->dev;
+       struct exynos_lpass *lpass;
+       void __iomem *base_top;
++      int ret;
+       lpass = devm_kzalloc(dev, sizeof(*lpass), GFP_KERNEL);
+       if (!lpass)
+@@ -134,16 +145,11 @@ static int exynos_lpass_probe(struct platform_device *pdev)
+       pm_runtime_enable(dev);
+       exynos_lpass_enable(lpass);
+-      return devm_of_platform_populate(dev);
+-}
+-
+-static void exynos_lpass_remove(struct platform_device *pdev)
+-{
+-      struct exynos_lpass *lpass = platform_get_drvdata(pdev);
++      ret = devm_add_action_or_reset(dev, exynos_lpass_disable_lpass, pdev);
++      if (ret)
++              return ret;
+-      pm_runtime_disable(&pdev->dev);
+-      if (!pm_runtime_status_suspended(&pdev->dev))
+-              exynos_lpass_disable(lpass);
++      return devm_of_platform_populate(dev);
+ }
+ static int __maybe_unused exynos_lpass_suspend(struct device *dev)
+@@ -183,7 +189,6 @@ static struct platform_driver exynos_lpass_driver = {
+               .of_match_table = exynos_lpass_of_match,
+       },
+       .probe  = exynos_lpass_probe,
+-      .remove = exynos_lpass_remove,
+ };
+ module_platform_driver(exynos_lpass_driver);
+-- 
+2.39.5
+
diff --git a/queue-6.15/mfd-stmpe-spi-correct-the-name-used-in-module_device.patch b/queue-6.15/mfd-stmpe-spi-correct-the-name-used-in-module_device.patch
new file mode 100644 (file)
index 0000000..8d78836
--- /dev/null
@@ -0,0 +1,40 @@
+From 9378219c947583303df4ade79b7e224fe176fe6f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 26 Apr 2025 18:16:32 +0200
+Subject: mfd: stmpe-spi: Correct the name used in MODULE_DEVICE_TABLE
+
+From: Alexey Gladkov <legion@kernel.org>
+
+[ Upstream commit 59d60c16ed41475f3b5f7b605e75fbf8e3628720 ]
+
+The name used in the macro does not exist.
+
+drivers/mfd/stmpe-spi.c:132:26: error: use of undeclared identifier 'stmpe_id'
+  132 | MODULE_DEVICE_TABLE(spi, stmpe_id);
+
+Fixes: e789995d5c61 ("mfd: Add support for STMPE SPI interface")
+Signed-off-by: Alexey Gladkov <legion@kernel.org>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/79d5a847303e45a46098f2d827d3d8a249a32be3.1745591072.git.legion@kernel.org
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/stmpe-spi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mfd/stmpe-spi.c b/drivers/mfd/stmpe-spi.c
+index 792236f56399a..b9cc85ea2c401 100644
+--- a/drivers/mfd/stmpe-spi.c
++++ b/drivers/mfd/stmpe-spi.c
+@@ -129,7 +129,7 @@ static const struct spi_device_id stmpe_spi_id[] = {
+       { "stmpe2403", STMPE2403 },
+       { }
+ };
+-MODULE_DEVICE_TABLE(spi, stmpe_id);
++MODULE_DEVICE_TABLE(spi, stmpe_spi_id);
+ static struct spi_driver stmpe_spi_driver = {
+       .driver = {
+-- 
+2.39.5
+
diff --git a/queue-6.15/mips-loongson64-add-missing-interrupt-cells-for-loon.patch b/queue-6.15/mips-loongson64-add-missing-interrupt-cells-for-loon.patch
new file mode 100644 (file)
index 0000000..cc8ab49
--- /dev/null
@@ -0,0 +1,43 @@
+From b00cd523f415e1b3b16dcccf545c0b44bc98dc8f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Apr 2025 11:45:48 +0800
+Subject: MIPS: Loongson64: Add missing '#interrupt-cells' for loongson64c_ls7a
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: WangYuli <wangyuli@uniontech.com>
+
+[ Upstream commit 6d223b8ffcd1593d032b71875def2daa71c53111 ]
+
+Similar to commit 98a9e2ac3755 ("MIPS: Loongson64: DTS: Fix msi node for ls7a").
+
+Fix follow warnings:
+  arch/mips/boot/dts/loongson/loongson64c_4core_ls7a.dts:28.31-36.4: Warning (interrupt_provider): /bus@10000000/msi-controller@2ff00000: Missing '#interrupt-cells' in interrupt provider
+  arch/mips/boot/dts/loongson/loongson64c_4core_ls7a.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'
+
+Fixes: 24af105962c8 ("MIPS: Loongson64: DeviceTree for LS7A PCH")
+Tested-by: WangYuli <wangyuli@uniontech.com>
+Signed-off-by: WangYuli <wangyuli@uniontech.com>
+Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/boot/dts/loongson/loongson64c_4core_ls7a.dts | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/mips/boot/dts/loongson/loongson64c_4core_ls7a.dts b/arch/mips/boot/dts/loongson/loongson64c_4core_ls7a.dts
+index c7ea4f1c0bb21..6c277ab83d4b9 100644
+--- a/arch/mips/boot/dts/loongson/loongson64c_4core_ls7a.dts
++++ b/arch/mips/boot/dts/loongson/loongson64c_4core_ls7a.dts
+@@ -29,6 +29,7 @@
+               compatible = "loongson,pch-msi-1.0";
+               reg = <0 0x2ff00000 0 0x8>;
+               interrupt-controller;
++              #interrupt-cells = <1>;
+               msi-controller;
+               loongson,msi-base-vec = <64>;
+               loongson,msi-num-vecs = <64>;
+-- 
+2.39.5
+
diff --git a/queue-6.15/misc-lis3lv02d-fix-correct-sysfs-directory-path-for-.patch b/queue-6.15/misc-lis3lv02d-fix-correct-sysfs-directory-path-for-.patch
new file mode 100644 (file)
index 0000000..8a69bc9
--- /dev/null
@@ -0,0 +1,75 @@
+From 08b4610ed82d62a5f3e335b2079d4be101178296 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 May 2025 11:00:07 +0000
+Subject: misc: lis3lv02d: Fix correct sysfs directory path for lis3lv02d
+
+From: Roxana Nicolescu <nicolescu.roxana@protonmail.com>
+
+[ Upstream commit 7b386d7454b610534026b279aa150e5a9e584082 ]
+
+The lis3lv02d driver does not create a platform device anymore. It was
+recently changed to use a faux device instead. Therefore the sysfs path
+has changed from /sys/devices/platform/lis3lv02d to
+/sys/devices/faux/lis3lv02d.
+
+Fixes: 3b18ccb5472b ("misc: lis3lv02d: convert to use faux_device")
+Signed-off-by: Roxana Nicolescu <nicolescu.roxana@protonmail.com>
+Link: https://lore.kernel.org/r/20250506110002.36477-1-nicolescu.roxana@protonmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/misc-devices/lis3lv02d.rst | 6 +++---
+ drivers/misc/lis3lv02d/Kconfig           | 4 ++--
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/Documentation/misc-devices/lis3lv02d.rst b/Documentation/misc-devices/lis3lv02d.rst
+index 959bd2b822cfa..6b3b7405ebdf6 100644
+--- a/Documentation/misc-devices/lis3lv02d.rst
++++ b/Documentation/misc-devices/lis3lv02d.rst
+@@ -22,10 +22,10 @@ sporting the feature officially called "HP Mobile Data Protection System 3D" or
+ models (full list can be found in drivers/platform/x86/hp_accel.c) will have
+ their axis automatically oriented on standard way (eg: you can directly play
+ neverball). The accelerometer data is readable via
+-/sys/devices/platform/lis3lv02d. Reported values are scaled
++/sys/devices/faux/lis3lv02d. Reported values are scaled
+ to mg values (1/1000th of earth gravity).
+-Sysfs attributes under /sys/devices/platform/lis3lv02d/:
++Sysfs attributes under /sys/devices/faux/lis3lv02d/:
+ position
+       - 3D position that the accelerometer reports. Format: "(x,y,z)"
+@@ -85,7 +85,7 @@ the accelerometer are converted into a "standard" organisation of the axes
+ If your laptop model is not recognized (cf "dmesg"), you can send an
+ email to the maintainer to add it to the database.  When reporting a new
+ laptop, please include the output of "dmidecode" plus the value of
+-/sys/devices/platform/lis3lv02d/position in these four cases.
++/sys/devices/faux/lis3lv02d/position in these four cases.
+ Q&A
+ ---
+diff --git a/drivers/misc/lis3lv02d/Kconfig b/drivers/misc/lis3lv02d/Kconfig
+index bb2fec4b5880b..56005243a230d 100644
+--- a/drivers/misc/lis3lv02d/Kconfig
++++ b/drivers/misc/lis3lv02d/Kconfig
+@@ -10,7 +10,7 @@ config SENSORS_LIS3_SPI
+       help
+         This driver provides support for the LIS3LV02Dx accelerometer connected
+         via SPI. The accelerometer data is readable via
+-        /sys/devices/platform/lis3lv02d.
++        /sys/devices/faux/lis3lv02d.
+         This driver also provides an absolute input class device, allowing
+         the laptop to act as a pinball machine-esque joystick.
+@@ -26,7 +26,7 @@ config SENSORS_LIS3_I2C
+       help
+         This driver provides support for the LIS3LV02Dx accelerometer connected
+         via I2C. The accelerometer data is readable via
+-        /sys/devices/platform/lis3lv02d.
++        /sys/devices/faux/lis3lv02d.
+         This driver also provides an absolute input class device, allowing
+         the device to act as a pinball machine-esque joystick.
+-- 
+2.39.5
+
diff --git a/queue-6.15/mtd-nand-ecc-mxic-fix-use-of-uninitialized-variable-.patch b/queue-6.15/mtd-nand-ecc-mxic-fix-use-of-uninitialized-variable-.patch
new file mode 100644 (file)
index 0000000..e9eecf1
--- /dev/null
@@ -0,0 +1,47 @@
+From 636094c7452f45469e914ac5ba49a11fceb40aa1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Apr 2025 00:39:06 +0300
+Subject: mtd: nand: ecc-mxic: Fix use of uninitialized variable ret
+
+From: Mikhail Arkhipov <m.arhipov@rosa.ru>
+
+[ Upstream commit d95846350aac72303036a70c4cdc69ae314aa26d ]
+
+If ctx->steps is zero, the loop processing ECC steps is skipped,
+and the variable ret remains uninitialized. It is later checked
+and returned, which leads to undefined behavior and may cause
+unpredictable results in user space or kernel crashes.
+
+This scenario can be triggered in edge cases such as misconfigured
+geometry, ECC engine misuse, or if ctx->steps is not validated
+after initialization.
+
+Initialize ret to zero before the loop to ensure correct and safe
+behavior regardless of the ctx->steps value.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: 48e6633a9fa2 ("mtd: nand: mxic-ecc: Add Macronix external ECC engine support")
+Signed-off-by: Mikhail Arkhipov <m.arhipov@rosa.ru>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/nand/ecc-mxic.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/nand/ecc-mxic.c b/drivers/mtd/nand/ecc-mxic.c
+index 56b56f726b998..1bf9a5a64b87a 100644
+--- a/drivers/mtd/nand/ecc-mxic.c
++++ b/drivers/mtd/nand/ecc-mxic.c
+@@ -614,7 +614,7 @@ static int mxic_ecc_finish_io_req_external(struct nand_device *nand,
+ {
+       struct mxic_ecc_engine *mxic = nand_to_mxic(nand);
+       struct mxic_ecc_ctx *ctx = nand_to_ecc_ctx(nand);
+-      int nents, step, ret;
++      int nents, step, ret = 0;
+       if (req->mode == MTD_OPS_RAW)
+               return 0;
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-airoha-add-the-capability-to-allocate-hfwd-descr.patch b/queue-6.15/net-airoha-add-the-capability-to-allocate-hfwd-descr.patch
new file mode 100644 (file)
index 0000000..5ce5174
--- /dev/null
@@ -0,0 +1,96 @@
+From 1edd66f118c7bc19f6b076ee945320d753174843 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 May 2025 09:16:39 +0200
+Subject: net: airoha: Add the capability to allocate hfwd descriptors in SRAM
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit c683e378c0907e66cee939145edf936c254ff1e3 ]
+
+In order to improve packet processing and packet forwarding
+performances, EN7581 SoC supports consuming SRAM instead of DRAM for
+hw forwarding descriptors queue.
+For downlink hw accelerated traffic request to consume SRAM memory
+for hw forwarding descriptors queue.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250521-airopha-desc-sram-v3-4-a6e9b085b4f0@kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: a869d3a5eb01 ("net: airoha: Initialize PPE UPDMEM source-mac table")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/airoha/airoha_eth.c | 11 +----------
+ drivers/net/ethernet/airoha/airoha_eth.h |  9 +++++++++
+ drivers/net/ethernet/airoha/airoha_ppe.c |  6 ++++++
+ 3 files changed, 16 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
+index c169b8b411b4f..c8664840f3fc2 100644
+--- a/drivers/net/ethernet/airoha/airoha_eth.c
++++ b/drivers/net/ethernet/airoha/airoha_eth.c
+@@ -67,15 +67,6 @@ static void airoha_qdma_irq_disable(struct airoha_qdma *qdma, int index,
+       airoha_qdma_set_irqmask(qdma, index, mask, 0);
+ }
+-static bool airhoa_is_lan_gdm_port(struct airoha_gdm_port *port)
+-{
+-      /* GDM1 port on EN7581 SoC is connected to the lan dsa switch.
+-       * GDM{2,3,4} can be used as wan port connected to an external
+-       * phy module.
+-       */
+-      return port->id == 1;
+-}
+-
+ static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr)
+ {
+       struct airoha_eth *eth = port->qdma->eth;
+@@ -1068,7 +1059,7 @@ static int airoha_qdma_init_hfwd_queues(struct airoha_qdma *qdma)
+                       LMGR_INIT_START | LMGR_SRAM_MODE_MASK |
+                       HW_FWD_DESC_NUM_MASK,
+                       FIELD_PREP(HW_FWD_DESC_NUM_MASK, HW_DSCP_NUM) |
+-                      LMGR_INIT_START);
++                      LMGR_INIT_START | LMGR_SRAM_MODE_MASK);
+       return read_poll_timeout(airoha_qdma_rr, status,
+                                !(status & LMGR_INIT_START), USEC_PER_MSEC,
+diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
+index ec8908f904c61..0204ea030c31a 100644
+--- a/drivers/net/ethernet/airoha/airoha_eth.h
++++ b/drivers/net/ethernet/airoha/airoha_eth.h
+@@ -532,6 +532,15 @@ u32 airoha_rmw(void __iomem *base, u32 offset, u32 mask, u32 val);
+ #define airoha_qdma_clear(qdma, offset, val)                  \
+       airoha_rmw((qdma)->regs, (offset), (val), 0)
++static inline bool airhoa_is_lan_gdm_port(struct airoha_gdm_port *port)
++{
++      /* GDM1 port on EN7581 SoC is connected to the lan dsa switch.
++       * GDM{2,3,4} can be used as wan port connected to an external
++       * phy module.
++       */
++      return port->id == 1;
++}
++
+ bool airoha_is_valid_gdm_port(struct airoha_eth *eth,
+                             struct airoha_gdm_port *port);
+diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
+index f10dab935cab6..843fe7bd1446e 100644
+--- a/drivers/net/ethernet/airoha/airoha_ppe.c
++++ b/drivers/net/ethernet/airoha/airoha_ppe.c
+@@ -234,6 +234,12 @@ static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth,
+               else
+                       pse_port = 2; /* uplink relies on GDM2 loopback */
+               val |= FIELD_PREP(AIROHA_FOE_IB2_PSE_PORT, pse_port);
++
++              /* For downlink traffic consume SRAM memory for hw forwarding
++               * descriptors queue.
++               */
++              if (airhoa_is_lan_gdm_port(port))
++                      val |= AIROHA_FOE_IB2_FAST_PATH;
+       }
+       if (is_multicast_ether_addr(data->eth.h_dest))
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-airoha-fix-an-error-handling-path-in-airoha_allo.patch b/queue-6.15/net-airoha-fix-an-error-handling-path-in-airoha_allo.patch
new file mode 100644 (file)
index 0000000..b2eab65
--- /dev/null
@@ -0,0 +1,51 @@
+From cdfffe5fa53259690e732893b0abc2323ca52126 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 24 May 2025 09:29:11 +0200
+Subject: net: airoha: Fix an error handling path in airoha_alloc_gdm_port()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit c59783780c8ad66f6076a9a7c74df3e006e29519 ]
+
+If register_netdev() fails, the error handling path of the probe will not
+free the memory allocated by the previous airoha_metadata_dst_alloc() call
+because port->dev->reg_state will not be NETREG_REGISTERED.
+
+So, an explicit airoha_metadata_dst_free() call is needed in this case to
+avoid a memory leak.
+
+Fixes: af3cf757d5c9 ("net: airoha: Move DSA tag in DMA descriptor")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/1b94b91345017429ed653e2f05d25620dc2823f9.1746715755.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/airoha/airoha_eth.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
+index 1e9ab65218ff1..c169b8b411b4f 100644
+--- a/drivers/net/ethernet/airoha/airoha_eth.c
++++ b/drivers/net/ethernet/airoha/airoha_eth.c
+@@ -2541,7 +2541,15 @@ static int airoha_alloc_gdm_port(struct airoha_eth *eth,
+       if (err)
+               return err;
+-      return register_netdev(dev);
++      err = register_netdev(dev);
++      if (err)
++              goto free_metadata_dst;
++
++      return 0;
++
++free_metadata_dst:
++      airoha_metadata_dst_free(port);
++      return err;
+ }
+ static int airoha_probe(struct platform_device *pdev)
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-airoha-initialize-ppe-updmem-source-mac-table.patch b/queue-6.15/net-airoha-initialize-ppe-updmem-source-mac-table.patch
new file mode 100644 (file)
index 0000000..2eae8b6
--- /dev/null
@@ -0,0 +1,138 @@
+From a2bc90a5d8abc9a94fc418701de1fd756e5cad31 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Jun 2025 12:55:37 +0200
+Subject: net: airoha: Initialize PPE UPDMEM source-mac table
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit a869d3a5eb011a9cf9bd864f31f5cf27362de8c7 ]
+
+UPDMEM source-mac table is a key-value map used to store devices mac
+addresses according to the port identifier. UPDMEM source mac table is
+used during IPv6 traffic hw acceleration since PPE entries, for space
+constraints, do not contain the full source mac address but just the
+identifier in the UPDMEM source-mac table.
+Configure UPDMEM source-mac table with device mac addresses and set
+the source-mac ID field for PPE IPv6 entries in order to select the
+proper device mac address as source mac for L3 IPv6 hw accelerated traffic.
+
+Fixes: 00a7678310fe ("net: airoha: Introduce flowtable offload support")
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250602-airoha-flowtable-ipv6-fix-v2-1-3287f8b55214@kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/airoha/airoha_eth.c  |  2 ++
+ drivers/net/ethernet/airoha/airoha_eth.h  |  1 +
+ drivers/net/ethernet/airoha/airoha_ppe.c  | 26 ++++++++++++++++++++++-
+ drivers/net/ethernet/airoha/airoha_regs.h | 10 +++++++++
+ 4 files changed, 38 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
+index c8664840f3fc2..af28a9300a15c 100644
+--- a/drivers/net/ethernet/airoha/airoha_eth.c
++++ b/drivers/net/ethernet/airoha/airoha_eth.c
+@@ -80,6 +80,8 @@ static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr)
+       val = (addr[3] << 16) | (addr[4] << 8) | addr[5];
+       airoha_fe_wr(eth, REG_FE_MAC_LMIN(reg), val);
+       airoha_fe_wr(eth, REG_FE_MAC_LMAX(reg), val);
++
++      airoha_ppe_init_upd_mem(port);
+ }
+ static void airoha_set_gdm_port_fwd_cfg(struct airoha_eth *eth, u32 addr,
+diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
+index 0204ea030c31a..2bf6b1a2dd9b0 100644
+--- a/drivers/net/ethernet/airoha/airoha_eth.h
++++ b/drivers/net/ethernet/airoha/airoha_eth.h
+@@ -549,6 +549,7 @@ int airoha_ppe_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
+                                void *cb_priv);
+ int airoha_ppe_init(struct airoha_eth *eth);
+ void airoha_ppe_deinit(struct airoha_eth *eth);
++void airoha_ppe_init_upd_mem(struct airoha_gdm_port *port);
+ struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe,
+                                                 u32 hash);
+diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
+index 843fe7bd1446e..1b8f21f808890 100644
+--- a/drivers/net/ethernet/airoha/airoha_ppe.c
++++ b/drivers/net/ethernet/airoha/airoha_ppe.c
+@@ -206,6 +206,7 @@ static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth,
+       int dsa_port = airoha_get_dsa_port(&dev);
+       struct airoha_foe_mac_info_common *l2;
+       u32 qdata, ports_pad, val;
++      u8 smac_id = 0xf;
+       memset(hwe, 0, sizeof(*hwe));
+@@ -240,6 +241,8 @@ static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth,
+                */
+               if (airhoa_is_lan_gdm_port(port))
+                       val |= AIROHA_FOE_IB2_FAST_PATH;
++
++              smac_id = port->id;
+       }
+       if (is_multicast_ether_addr(data->eth.h_dest))
+@@ -280,7 +283,7 @@ static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth,
+               hwe->ipv4.l2.src_mac_lo =
+                       get_unaligned_be16(data->eth.h_source + 4);
+       } else {
+-              l2->src_mac_hi = FIELD_PREP(AIROHA_FOE_MAC_SMAC_ID, 0xf);
++              l2->src_mac_hi = FIELD_PREP(AIROHA_FOE_MAC_SMAC_ID, smac_id);
+       }
+       if (data->vlan.num) {
+@@ -868,6 +871,27 @@ void airoha_ppe_check_skb(struct airoha_ppe *ppe, u16 hash)
+       airoha_ppe_foe_insert_entry(ppe, hash);
+ }
++void airoha_ppe_init_upd_mem(struct airoha_gdm_port *port)
++{
++      struct airoha_eth *eth = port->qdma->eth;
++      struct net_device *dev = port->dev;
++      const u8 *addr = dev->dev_addr;
++      u32 val;
++
++      val = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | addr[5];
++      airoha_fe_wr(eth, REG_UPDMEM_DATA(0), val);
++      airoha_fe_wr(eth, REG_UPDMEM_CTRL(0),
++                   FIELD_PREP(PPE_UPDMEM_ADDR_MASK, port->id) |
++                   PPE_UPDMEM_WR_MASK | PPE_UPDMEM_REQ_MASK);
++
++      val = (addr[0] << 8) | addr[1];
++      airoha_fe_wr(eth, REG_UPDMEM_DATA(0), val);
++      airoha_fe_wr(eth, REG_UPDMEM_CTRL(0),
++                   FIELD_PREP(PPE_UPDMEM_ADDR_MASK, port->id) |
++                   FIELD_PREP(PPE_UPDMEM_OFFSET_MASK, 1) |
++                   PPE_UPDMEM_WR_MASK | PPE_UPDMEM_REQ_MASK);
++}
++
+ int airoha_ppe_init(struct airoha_eth *eth)
+ {
+       struct airoha_ppe *ppe;
+diff --git a/drivers/net/ethernet/airoha/airoha_regs.h b/drivers/net/ethernet/airoha/airoha_regs.h
+index 8146cde4e8ba3..57bff8d2de276 100644
+--- a/drivers/net/ethernet/airoha/airoha_regs.h
++++ b/drivers/net/ethernet/airoha/airoha_regs.h
+@@ -312,6 +312,16 @@
+ #define REG_PPE_RAM_BASE(_n)                  (((_n) ? PPE2_BASE : PPE1_BASE) + 0x320)
+ #define REG_PPE_RAM_ENTRY(_m, _n)             (REG_PPE_RAM_BASE(_m) + ((_n) << 2))
++#define REG_UPDMEM_CTRL(_n)                   (((_n) ? PPE2_BASE : PPE1_BASE) + 0x370)
++#define PPE_UPDMEM_ACK_MASK                   BIT(31)
++#define PPE_UPDMEM_ADDR_MASK                  GENMASK(11, 8)
++#define PPE_UPDMEM_OFFSET_MASK                        GENMASK(7, 4)
++#define PPE_UPDMEM_SEL_MASK                   GENMASK(3, 2)
++#define PPE_UPDMEM_WR_MASK                    BIT(1)
++#define PPE_UPDMEM_REQ_MASK                   BIT(0)
++
++#define REG_UPDMEM_DATA(_n)                   (((_n) ? PPE2_BASE : PPE1_BASE) + 0x374)
++
+ #define REG_FE_GDM_TX_OK_PKT_CNT_H(_n)                (GDM_BASE(_n) + 0x280)
+ #define REG_FE_GDM_TX_OK_BYTE_CNT_H(_n)               (GDM_BASE(_n) + 0x284)
+ #define REG_FE_GDM_TX_ETH_PKT_CNT_H(_n)               (GDM_BASE(_n) + 0x288)
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-annotate-data-races-around-cleanup_net_task.patch b/queue-6.15/net-annotate-data-races-around-cleanup_net_task.patch
new file mode 100644 (file)
index 0000000..05bd394
--- /dev/null
@@ -0,0 +1,63 @@
+From cc518bc6442588a62050087ea8b70e8ca85e081b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Jun 2025 09:39:28 +0000
+Subject: net: annotate data-races around cleanup_net_task
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 535caaca921c653b1f9838fbd5c4e9494cafc3d9 ]
+
+from_cleanup_net() reads cleanup_net_task locklessly.
+
+Add READ_ONCE()/WRITE_ONCE() annotations to avoid
+a potential KCSAN warning, even if the race is harmless.
+
+Fixes: 0734d7c3d93c ("net: expedite synchronize_net() for cleanup_net()")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Jason Xing <kerneljasonxing@gmail.com>
+Link: https://patch.msgid.link/20250604093928.1323333-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/dev.c           | 2 +-
+ net/core/net_namespace.c | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/net/core/dev.c b/net/core/dev.c
+index 0d891634c6927..2b20aadaf9268 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -10393,7 +10393,7 @@ static void dev_index_release(struct net *net, int ifindex)
+ static bool from_cleanup_net(void)
+ {
+ #ifdef CONFIG_NET_NS
+-      return current == cleanup_net_task;
++      return current == READ_ONCE(cleanup_net_task);
+ #else
+       return false;
+ #endif
+diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
+index b0dfdf791ece5..599f6a89ae581 100644
+--- a/net/core/net_namespace.c
++++ b/net/core/net_namespace.c
+@@ -600,7 +600,7 @@ static void cleanup_net(struct work_struct *work)
+       LIST_HEAD(net_exit_list);
+       LIST_HEAD(dev_kill_list);
+-      cleanup_net_task = current;
++      WRITE_ONCE(cleanup_net_task, current);
+       /* Atomically snapshot the list of namespaces to cleanup */
+       net_kill_list = llist_del_all(&cleanup_list);
+@@ -676,7 +676,7 @@ static void cleanup_net(struct work_struct *work)
+               put_user_ns(net->user_ns);
+               net_passive_dec(net);
+       }
+-      cleanup_net_task = NULL;
++      WRITE_ONCE(cleanup_net_task, NULL);
+ }
+ /**
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-dsa-b53-allow-rgmii-for-bcm63xx-rgmii-ports.patch b/queue-6.15/net-dsa-b53-allow-rgmii-for-bcm63xx-rgmii-ports.patch
new file mode 100644 (file)
index 0000000..4d20402
--- /dev/null
@@ -0,0 +1,46 @@
+From 74b143ec34d1ecc1931caa7bb330ecbc1c6e5fd7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Jun 2025 21:39:52 +0200
+Subject: net: dsa: b53: allow RGMII for bcm63xx RGMII ports
+
+From: Jonas Gorski <jonas.gorski@gmail.com>
+
+[ Upstream commit 5ea0d42c1980e6d10e5cb56a78021db5bfcebaaf ]
+
+Add RGMII to supported interfaces for BCM63xx RGMII ports so they can be
+actually used in RGMII mode.
+
+Without this, phylink will fail to configure them:
+
+[    3.580000] b53-switch 10700000.switch GbE3 (uninitialized): validation of rgmii with support 0000000,00000000,00000000,000062ff and advertisement 0000000,00000000,00000000,000062ff failed: -EINVAL
+[    3.600000] b53-switch 10700000.switch GbE3 (uninitialized): failed to connect to PHY: -EINVAL
+[    3.610000] b53-switch 10700000.switch GbE3 (uninitialized): error -22 setting up PHY for tree 0, switch 0, port 4
+
+Fixes: ce3bf94871f7 ("net: dsa: b53: add support for BCM63xx RGMIIs")
+Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+Link: https://patch.msgid.link/20250602193953.1010487-5-jonas.gorski@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/b53/b53_common.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
+index 3f4934f974c81..be4493b769f44 100644
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -1439,6 +1439,10 @@ static void b53_phylink_get_caps(struct dsa_switch *ds, int port,
+       __set_bit(PHY_INTERFACE_MODE_MII, config->supported_interfaces);
+       __set_bit(PHY_INTERFACE_MODE_REVMII, config->supported_interfaces);
++      /* BCM63xx RGMII ports support RGMII */
++      if (is63xx(dev) && in_range(port, B53_63XX_RGMII0, 4))
++              phy_interface_set_rgmii(config->supported_interfaces);
++
+       config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
+               MAC_10 | MAC_100;
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-dsa-b53-do-not-configure-bcm63xx-s-imp-port-inte.patch b/queue-6.15/net-dsa-b53-do-not-configure-bcm63xx-s-imp-port-inte.patch
new file mode 100644 (file)
index 0000000..c1f9896
--- /dev/null
@@ -0,0 +1,80 @@
+From d855f607d56612545a16348c643b6703aa720dfa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Jun 2025 21:39:51 +0200
+Subject: net: dsa: b53: do not configure bcm63xx's IMP port interface
+
+From: Jonas Gorski <jonas.gorski@gmail.com>
+
+[ Upstream commit 75f4f7b2b13008803f84768ff90396f9d7553221 ]
+
+The IMP port is not a valid RGMII interface, but hard wired to internal,
+so we shouldn't touch the undefined register B53_RGMII_CTRL_IMP.
+
+While this does not seem to have any side effects, let's not touch it at
+all, so limit RGMII configuration on bcm63xx to the actual RGMII ports.
+
+Fixes: ce3bf94871f7 ("net: dsa: b53: add support for BCM63xx RGMIIs")
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Link: https://patch.msgid.link/20250602193953.1010487-4-jonas.gorski@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/b53/b53_common.c | 22 ++++++++--------------
+ 1 file changed, 8 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
+index c186ee3fb28df..3f4934f974c81 100644
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -22,6 +22,7 @@
+ #include <linux/gpio.h>
+ #include <linux/kernel.h>
+ #include <linux/math.h>
++#include <linux/minmax.h>
+ #include <linux/module.h>
+ #include <linux/platform_data/b53.h>
+ #include <linux/phy.h>
+@@ -1322,24 +1323,17 @@ static void b53_adjust_63xx_rgmii(struct dsa_switch *ds, int port,
+                                 phy_interface_t interface)
+ {
+       struct b53_device *dev = ds->priv;
+-      u8 rgmii_ctrl = 0, off;
++      u8 rgmii_ctrl = 0;
+-      if (port == dev->imp_port)
+-              off = B53_RGMII_CTRL_IMP;
+-      else
+-              off = B53_RGMII_CTRL_P(port);
+-
+-      b53_read8(dev, B53_CTRL_PAGE, off, &rgmii_ctrl);
++      b53_read8(dev, B53_CTRL_PAGE, B53_RGMII_CTRL_P(port), &rgmii_ctrl);
+       rgmii_ctrl &= ~(RGMII_CTRL_DLL_RXC | RGMII_CTRL_DLL_TXC);
+-      if (port != dev->imp_port) {
+-              if (is63268(dev))
+-                      rgmii_ctrl |= RGMII_CTRL_MII_OVERRIDE;
++      if (is63268(dev))
++              rgmii_ctrl |= RGMII_CTRL_MII_OVERRIDE;
+-              rgmii_ctrl |= RGMII_CTRL_ENABLE_GMII;
+-      }
++      rgmii_ctrl |= RGMII_CTRL_ENABLE_GMII;
+-      b53_write8(dev, B53_CTRL_PAGE, off, rgmii_ctrl);
++      b53_write8(dev, B53_CTRL_PAGE, B53_RGMII_CTRL_P(port), rgmii_ctrl);
+       dev_dbg(ds->dev, "Configured port %d for %s\n", port,
+               phy_modes(interface));
+@@ -1484,7 +1478,7 @@ static void b53_phylink_mac_config(struct phylink_config *config,
+       struct b53_device *dev = ds->priv;
+       int port = dp->index;
+-      if (is63xx(dev) && port >= B53_63XX_RGMII0)
++      if (is63xx(dev) && in_range(port, B53_63XX_RGMII0, 4))
+               b53_adjust_63xx_rgmii(ds, port, interface);
+       if (mode == MLO_AN_FIXED) {
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-dsa-b53-do-not-enable-eee-on-bcm63xx.patch b/queue-6.15/net-dsa-b53-do-not-enable-eee-on-bcm63xx.patch
new file mode 100644 (file)
index 0000000..816e889
--- /dev/null
@@ -0,0 +1,57 @@
+From a0265bd489fd41c748b0cf4fbf67b84e8de779ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Jun 2025 21:39:49 +0200
+Subject: net: dsa: b53: do not enable EEE on bcm63xx
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonas Gorski <jonas.gorski@gmail.com>
+
+[ Upstream commit 1237c2d4a8db79dfd4369bff6930b0e385ed7d5c ]
+
+BCM63xx internal switches do not support EEE, but provide multiple RGMII
+ports where external PHYs may be connected. If one of these PHYs are EEE
+capable, we may try to enable EEE for the MACs, which then hangs the
+system on access of the (non-existent) EEE registers.
+
+Fix this by checking if the switch actually supports EEE before
+attempting to configure it.
+
+Fixes: 22256b0afb12 ("net: dsa: b53: Move EEE functions to b53")
+Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Tested-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+Link: https://patch.msgid.link/20250602193953.1010487-2-jonas.gorski@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/b53/b53_common.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
+index 7216eb8f94936..a316f8c01d0a9 100644
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -2348,6 +2348,9 @@ int b53_eee_init(struct dsa_switch *ds, int port, struct phy_device *phy)
+ {
+       int ret;
++      if (!b53_support_eee(ds, port))
++              return 0;
++
+       ret = phy_init_eee(phy, false);
+       if (ret)
+               return 0;
+@@ -2362,7 +2365,7 @@ bool b53_support_eee(struct dsa_switch *ds, int port)
+ {
+       struct b53_device *dev = ds->priv;
+-      return !is5325(dev) && !is5365(dev);
++      return !is5325(dev) && !is5365(dev) && !is63xx(dev);
+ }
+ EXPORT_SYMBOL(b53_support_eee);
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-dsa-b53-do-not-enable-rgmii-delay-on-bcm63xx.patch b/queue-6.15/net-dsa-b53-do-not-enable-rgmii-delay-on-bcm63xx.patch
new file mode 100644 (file)
index 0000000..0680dfb
--- /dev/null
@@ -0,0 +1,59 @@
+From 47eb9fd2dc5b3d744fa2ebbac5fe79dd9d380663 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Jun 2025 21:39:50 +0200
+Subject: net: dsa: b53: do not enable RGMII delay on bcm63xx
+
+From: Jonas Gorski <jonas.gorski@gmail.com>
+
+[ Upstream commit 4af523551d876ab8b8057d1e5303a860fd736fcb ]
+
+bcm63xx's RGMII ports are always in MAC mode, never in PHY mode, so we
+shouldn't enable any delays and let the PHY handle any delays as
+necessary.
+
+This fixes using RGMII ports with normal PHYs like BCM54612E, which will
+handle the delay in the PHY.
+
+Fixes: ce3bf94871f7 ("net: dsa: b53: add support for BCM63xx RGMIIs")
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Link: https://patch.msgid.link/20250602193953.1010487-3-jonas.gorski@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/b53/b53_common.c | 19 +------------------
+ 1 file changed, 1 insertion(+), 18 deletions(-)
+
+diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
+index a316f8c01d0a9..ba70fbcc0f8bc 100644
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -1325,24 +1325,7 @@ static void b53_adjust_63xx_rgmii(struct dsa_switch *ds, int port,
+               off = B53_RGMII_CTRL_P(port);
+       b53_read8(dev, B53_CTRL_PAGE, off, &rgmii_ctrl);
+-
+-      switch (interface) {
+-      case PHY_INTERFACE_MODE_RGMII_ID:
+-              rgmii_ctrl |= (RGMII_CTRL_DLL_RXC | RGMII_CTRL_DLL_TXC);
+-              break;
+-      case PHY_INTERFACE_MODE_RGMII_RXID:
+-              rgmii_ctrl &= ~(RGMII_CTRL_DLL_TXC);
+-              rgmii_ctrl |= RGMII_CTRL_DLL_RXC;
+-              break;
+-      case PHY_INTERFACE_MODE_RGMII_TXID:
+-              rgmii_ctrl &= ~(RGMII_CTRL_DLL_RXC);
+-              rgmii_ctrl |= RGMII_CTRL_DLL_TXC;
+-              break;
+-      case PHY_INTERFACE_MODE_RGMII:
+-      default:
+-              rgmii_ctrl &= ~(RGMII_CTRL_DLL_RXC | RGMII_CTRL_DLL_TXC);
+-              break;
+-      }
++      rgmii_ctrl &= ~(RGMII_CTRL_DLL_RXC | RGMII_CTRL_DLL_TXC);
+       if (port != dev->imp_port) {
+               if (is63268(dev))
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-dsa-b53-do-not-touch-dll_iqqd-on-bcm53115.patch b/queue-6.15/net-dsa-b53-do-not-touch-dll_iqqd-on-bcm53115.patch
new file mode 100644 (file)
index 0000000..b7115b0
--- /dev/null
@@ -0,0 +1,69 @@
+From f56e9e2c4812e430dfe559c3c73271869b398dae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Jun 2025 21:39:53 +0200
+Subject: net: dsa: b53: do not touch DLL_IQQD on bcm53115
+
+From: Jonas Gorski <jonas.gorski@gmail.com>
+
+[ Upstream commit bc1a65eb81a21e2aa3c3dca058ee8adf687b6ef5 ]
+
+According to OpenMDK, bit 2 of the RGMII register has a different
+meaning for BCM53115 [1]:
+
+"DLL_IQQD         1: In the IDDQ mode, power is down0: Normal function
+                  mode"
+
+Configuring RGMII delay works without setting this bit, so let's keep it
+at the default. For other chips, we always set it, so not clearing it
+is not an issue.
+
+One would assume BCM53118 works the same, but OpenMDK is not quite sure
+what this bit actually means [2]:
+
+"BYPASS_IMP_2NS_DEL #1: In the IDDQ mode, power is down#0: Normal
+                    function mode1: Bypass dll65_2ns_del IP0: Use
+                    dll65_2ns_del IP"
+
+So lets keep setting it for now.
+
+[1] https://github.com/Broadcom-Network-Switching-Software/OpenMDK/blob/master/cdk/PKG/chip/bcm53115/bcm53115_a0_defs.h#L19871
+[2] https://github.com/Broadcom-Network-Switching-Software/OpenMDK/blob/master/cdk/PKG/chip/bcm53118/bcm53118_a0_defs.h#L14392
+
+Fixes: 967dd82ffc52 ("net: dsa: b53: Add support for Broadcom RoboSwitch")
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+Link: https://patch.msgid.link/20250602193953.1010487-6-jonas.gorski@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/b53/b53_common.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
+index be4493b769f44..862bdccb74397 100644
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -1354,8 +1354,7 @@ static void b53_adjust_531x5_rgmii(struct dsa_switch *ds, int port,
+        * tx_clk aligned timing (restoring to reset defaults)
+        */
+       b53_read8(dev, B53_CTRL_PAGE, off, &rgmii_ctrl);
+-      rgmii_ctrl &= ~(RGMII_CTRL_DLL_RXC | RGMII_CTRL_DLL_TXC |
+-                      RGMII_CTRL_TIMING_SEL);
++      rgmii_ctrl &= ~(RGMII_CTRL_DLL_RXC | RGMII_CTRL_DLL_TXC);
+       /* PHY_INTERFACE_MODE_RGMII_TXID means TX internal delay, make
+        * sure that we enable the port TX clock internal delay to
+@@ -1375,7 +1374,10 @@ static void b53_adjust_531x5_rgmii(struct dsa_switch *ds, int port,
+               rgmii_ctrl |= RGMII_CTRL_DLL_TXC;
+       if (interface == PHY_INTERFACE_MODE_RGMII)
+               rgmii_ctrl |= RGMII_CTRL_DLL_TXC | RGMII_CTRL_DLL_RXC;
+-      rgmii_ctrl |= RGMII_CTRL_TIMING_SEL;
++
++      if (dev->chip_id != BCM53115_DEVICE_ID)
++              rgmii_ctrl |= RGMII_CTRL_TIMING_SEL;
++
+       b53_write8(dev, B53_CTRL_PAGE, off, rgmii_ctrl);
+       dev_info(ds->dev, "Configured port %d for %s\n", port,
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-dsa-b53-implement-setting-ageing-time.patch b/queue-6.15/net-dsa-b53-implement-setting-ageing-time.patch
new file mode 100644 (file)
index 0000000..a18ad71
--- /dev/null
@@ -0,0 +1,133 @@
+From 2b3666b0fe32e27c9057eddcb77e8395a3d6bb7b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 10 May 2025 11:22:11 +0200
+Subject: net: dsa: b53: implement setting ageing time
+
+From: Jonas Gorski <jonas.gorski@gmail.com>
+
+[ Upstream commit e39d14a760c039af0653e3df967e7525413924a0 ]
+
+b53 supported switches support configuring ageing time between 1 and
+1,048,575 seconds, so add an appropriate setter.
+
+This allows b53 to pass the FDB learning test for both vlan aware and
+vlan unaware bridges.
+
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Link: https://patch.msgid.link/20250510092211.276541-1-jonas.gorski@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 75f4f7b2b130 ("net: dsa: b53: do not configure bcm63xx's IMP port interface")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/b53/b53_common.c | 28 ++++++++++++++++++++++++++++
+ drivers/net/dsa/b53/b53_priv.h   |  1 +
+ drivers/net/dsa/b53/b53_regs.h   |  7 +++++++
+ drivers/net/dsa/bcm_sf2.c        |  1 +
+ 4 files changed, 37 insertions(+)
+
+diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
+index ba70fbcc0f8bc..c186ee3fb28df 100644
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -21,6 +21,7 @@
+ #include <linux/export.h>
+ #include <linux/gpio.h>
+ #include <linux/kernel.h>
++#include <linux/math.h>
+ #include <linux/module.h>
+ #include <linux/platform_data/b53.h>
+ #include <linux/phy.h>
+@@ -1202,6 +1203,10 @@ static int b53_setup(struct dsa_switch *ds)
+        */
+       ds->untag_vlan_aware_bridge_pvid = true;
++      /* Ageing time is set in seconds */
++      ds->ageing_time_min = 1 * 1000;
++      ds->ageing_time_max = AGE_TIME_MAX * 1000;
++
+       ret = b53_reset_switch(dev);
+       if (ret) {
+               dev_err(ds->dev, "failed to reset switch\n");
+@@ -2392,6 +2397,28 @@ static int b53_get_max_mtu(struct dsa_switch *ds, int port)
+       return B53_MAX_MTU;
+ }
++int b53_set_ageing_time(struct dsa_switch *ds, unsigned int msecs)
++{
++      struct b53_device *dev = ds->priv;
++      u32 atc;
++      int reg;
++
++      if (is63xx(dev))
++              reg = B53_AGING_TIME_CONTROL_63XX;
++      else
++              reg = B53_AGING_TIME_CONTROL;
++
++      atc = DIV_ROUND_CLOSEST(msecs, 1000);
++
++      if (!is5325(dev) && !is5365(dev))
++              atc |= AGE_CHANGE;
++
++      b53_write32(dev, B53_MGMT_PAGE, reg, atc);
++
++      return 0;
++}
++EXPORT_SYMBOL_GPL(b53_set_ageing_time);
++
+ static const struct phylink_mac_ops b53_phylink_mac_ops = {
+       .mac_select_pcs = b53_phylink_mac_select_pcs,
+       .mac_config     = b53_phylink_mac_config,
+@@ -2415,6 +2442,7 @@ static const struct dsa_switch_ops b53_switch_ops = {
+       .port_disable           = b53_disable_port,
+       .support_eee            = b53_support_eee,
+       .set_mac_eee            = b53_set_mac_eee,
++      .set_ageing_time        = b53_set_ageing_time,
+       .port_bridge_join       = b53_br_join,
+       .port_bridge_leave      = b53_br_leave,
+       .port_pre_bridge_flags  = b53_br_flags_pre,
+diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h
+index 2cf3e6a81e378..a5ef7071ba07b 100644
+--- a/drivers/net/dsa/b53/b53_priv.h
++++ b/drivers/net/dsa/b53/b53_priv.h
+@@ -343,6 +343,7 @@ void b53_get_strings(struct dsa_switch *ds, int port, u32 stringset,
+ void b53_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data);
+ int b53_get_sset_count(struct dsa_switch *ds, int port, int sset);
+ void b53_get_ethtool_phy_stats(struct dsa_switch *ds, int port, uint64_t *data);
++int b53_set_ageing_time(struct dsa_switch *ds, unsigned int msecs);
+ int b53_br_join(struct dsa_switch *ds, int port, struct dsa_bridge bridge,
+               bool *tx_fwd_offload, struct netlink_ext_ack *extack);
+ void b53_br_leave(struct dsa_switch *ds, int port, struct dsa_bridge bridge);
+diff --git a/drivers/net/dsa/b53/b53_regs.h b/drivers/net/dsa/b53/b53_regs.h
+index 5f7a0e5c5709d..1fbc5a204bc72 100644
+--- a/drivers/net/dsa/b53/b53_regs.h
++++ b/drivers/net/dsa/b53/b53_regs.h
+@@ -220,6 +220,13 @@
+ #define   BRCM_HDR_P5_EN              BIT(1) /* Enable tagging on port 5 */
+ #define   BRCM_HDR_P7_EN              BIT(2) /* Enable tagging on port 7 */
++/* Aging Time control register (32 bit) */
++#define B53_AGING_TIME_CONTROL                0x06
++#define B53_AGING_TIME_CONTROL_63XX   0x08
++#define  AGE_CHANGE                   BIT(20)
++#define  AGE_TIME_MASK                        0x7ffff
++#define  AGE_TIME_MAX                 1048575
++
+ /* Mirror capture control register (16 bit) */
+ #define B53_MIR_CAP_CTL                       0x10
+ #define  CAP_PORT_MASK                        0xf
+diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c
+index 454a8c7fd7eea..960685596093b 100644
+--- a/drivers/net/dsa/bcm_sf2.c
++++ b/drivers/net/dsa/bcm_sf2.c
+@@ -1235,6 +1235,7 @@ static const struct dsa_switch_ops bcm_sf2_ops = {
+       .port_disable           = bcm_sf2_port_disable,
+       .support_eee            = b53_support_eee,
+       .set_mac_eee            = b53_set_mac_eee,
++      .set_ageing_time        = b53_set_ageing_time,
+       .port_bridge_join       = b53_br_join,
+       .port_bridge_leave      = b53_br_leave,
+       .port_pre_bridge_flags  = b53_br_flags_pre,
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-dsa-tag_brcm-legacy-fix-pskb_may_pull-length.patch b/queue-6.15/net-dsa-tag_brcm-legacy-fix-pskb_may_pull-length.patch
new file mode 100644 (file)
index 0000000..a96acc3
--- /dev/null
@@ -0,0 +1,41 @@
+From 0863fc69640a21e1d6fee0e030f5e1de425dda46 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 May 2025 14:44:06 +0200
+Subject: net: dsa: tag_brcm: legacy: fix pskb_may_pull length
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Álvaro Fernández Rojas <noltari@gmail.com>
+
+[ Upstream commit efdddc4484859082da6c7877ed144c8121c8ea55 ]
+
+BRCM_LEG_PORT_ID was incorrectly used for pskb_may_pull length.
+The correct check is BRCM_LEG_TAG_LEN + VLAN_HLEN, or 10 bytes.
+
+Fixes: 964dbf186eaa ("net: dsa: tag_brcm: add support for legacy tags")
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Link: https://patch.msgid.link/20250529124406.2513779-1-noltari@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/dsa/tag_brcm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/dsa/tag_brcm.c b/net/dsa/tag_brcm.c
+index 8c3c068728e51..fe75821623a4f 100644
+--- a/net/dsa/tag_brcm.c
++++ b/net/dsa/tag_brcm.c
+@@ -257,7 +257,7 @@ static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb,
+       int source_port;
+       u8 *brcm_tag;
+-      if (unlikely(!pskb_may_pull(skb, BRCM_LEG_PORT_ID)))
++      if (unlikely(!pskb_may_pull(skb, BRCM_LEG_TAG_LEN + VLAN_HLEN)))
+               return NULL;
+       brcm_tag = dsa_etype_header_pos_rx(skb);
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-fix-checksum-update-for-ila-adj-transport.patch b/queue-6.15/net-fix-checksum-update-for-ila-adj-transport.patch
new file mode 100644 (file)
index 0000000..4681b7f
--- /dev/null
@@ -0,0 +1,167 @@
+From df158fd596810b7138fbf510858d6db515bbad67 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 May 2025 12:28:05 +0200
+Subject: net: Fix checksum update for ILA adj-transport
+
+From: Paul Chaignon <paul.chaignon@gmail.com>
+
+[ Upstream commit 6043b794c7668c19dabc4a93c75b924a19474d59 ]
+
+During ILA address translations, the L4 checksums can be handled in
+different ways. One of them, adj-transport, consist in parsing the
+transport layer and updating any found checksum. This logic relies on
+inet_proto_csum_replace_by_diff and produces an incorrect skb->csum when
+in state CHECKSUM_COMPLETE.
+
+This bug can be reproduced with a simple ILA to SIR mapping, assuming
+packets are received with CHECKSUM_COMPLETE:
+
+  $ ip a show dev eth0
+  14: eth0@if15: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
+      link/ether 62:ae:35:9e:0f:8d brd ff:ff:ff:ff:ff:ff link-netnsid 0
+      inet6 3333:0:0:1::c078/64 scope global
+         valid_lft forever preferred_lft forever
+      inet6 fd00:10:244:1::c078/128 scope global nodad
+         valid_lft forever preferred_lft forever
+      inet6 fe80::60ae:35ff:fe9e:f8d/64 scope link proto kernel_ll
+         valid_lft forever preferred_lft forever
+  $ ip ila add loc_match fd00:10:244:1 loc 3333:0:0:1 \
+      csum-mode adj-transport ident-type luid dev eth0
+
+Then I hit [fd00:10:244:1::c078]:8000 with a server listening only on
+[3333:0:0:1::c078]:8000. With the bug, the SYN packet is dropped with
+SKB_DROP_REASON_TCP_CSUM after inet_proto_csum_replace_by_diff changed
+skb->csum. The translation and drop are visible on pwru [1] traces:
+
+  IFACE   TUPLE                                                        FUNC
+  eth0:9  [fd00:10:244:3::3d8]:51420->[fd00:10:244:1::c078]:8000(tcp)  ipv6_rcv
+  eth0:9  [fd00:10:244:3::3d8]:51420->[fd00:10:244:1::c078]:8000(tcp)  ip6_rcv_core
+  eth0:9  [fd00:10:244:3::3d8]:51420->[fd00:10:244:1::c078]:8000(tcp)  nf_hook_slow
+  eth0:9  [fd00:10:244:3::3d8]:51420->[fd00:10:244:1::c078]:8000(tcp)  inet_proto_csum_replace_by_diff
+  eth0:9  [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp)     tcp_v6_early_demux
+  eth0:9  [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp)     ip6_route_input
+  eth0:9  [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp)     ip6_input
+  eth0:9  [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp)     ip6_input_finish
+  eth0:9  [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp)     ip6_protocol_deliver_rcu
+  eth0:9  [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp)     raw6_local_deliver
+  eth0:9  [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp)     ipv6_raw_deliver
+  eth0:9  [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp)     tcp_v6_rcv
+  eth0:9  [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp)     __skb_checksum_complete
+  eth0:9  [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp)     kfree_skb_reason(SKB_DROP_REASON_TCP_CSUM)
+  eth0:9  [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp)     skb_release_head_state
+  eth0:9  [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp)     skb_release_data
+  eth0:9  [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp)     skb_free_head
+  eth0:9  [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp)     kfree_skbmem
+
+This is happening because inet_proto_csum_replace_by_diff is updating
+skb->csum when it shouldn't. The L4 checksum is updated such that it
+"cancels" the IPv6 address change in terms of checksum computation, so
+the impact on skb->csum is null.
+
+Note this would be different for an IPv4 packet since three fields
+would be updated: the IPv4 address, the IP checksum, and the L4
+checksum. Two would cancel each other and skb->csum would still need
+to be updated to take the L4 checksum change into account.
+
+This patch fixes it by passing an ipv6 flag to
+inet_proto_csum_replace_by_diff, to skip the skb->csum update if we're
+in the IPv6 case. Note the behavior of the only other user of
+inet_proto_csum_replace_by_diff, the BPF subsystem, is left as is in
+this patch and fixed in the subsequent patch.
+
+With the fix, using the reproduction from above, I can confirm
+skb->csum is not touched by inet_proto_csum_replace_by_diff and the TCP
+SYN proceeds to the application after the ILA translation.
+
+Link: https://github.com/cilium/pwru [1]
+Fixes: 65d7ab8de582 ("net: Identifier Locator Addressing module")
+Signed-off-by: Paul Chaignon <paul.chaignon@gmail.com>
+Acked-by: Daniel Borkmann <daniel@iogearbox.net>
+Link: https://patch.msgid.link/b5539869e3550d46068504feb02d37653d939c0b.1748509484.git.paul.chaignon@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/checksum.h    | 2 +-
+ net/core/filter.c         | 2 +-
+ net/core/utils.c          | 4 ++--
+ net/ipv6/ila/ila_common.c | 6 +++---
+ 4 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/include/net/checksum.h b/include/net/checksum.h
+index 243f972267b8d..be9356d4b67a1 100644
+--- a/include/net/checksum.h
++++ b/include/net/checksum.h
+@@ -164,7 +164,7 @@ void inet_proto_csum_replace16(__sum16 *sum, struct sk_buff *skb,
+                              const __be32 *from, const __be32 *to,
+                              bool pseudohdr);
+ void inet_proto_csum_replace_by_diff(__sum16 *sum, struct sk_buff *skb,
+-                                   __wsum diff, bool pseudohdr);
++                                   __wsum diff, bool pseudohdr, bool ipv6);
+ static __always_inline
+ void inet_proto_csum_replace2(__sum16 *sum, struct sk_buff *skb,
+diff --git a/net/core/filter.c b/net/core/filter.c
+index 577a4504e26fa..3c93765742c9c 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -1987,7 +1987,7 @@ BPF_CALL_5(bpf_l4_csum_replace, struct sk_buff *, skb, u32, offset,
+               if (unlikely(from != 0))
+                       return -EINVAL;
+-              inet_proto_csum_replace_by_diff(ptr, skb, to, is_pseudo);
++              inet_proto_csum_replace_by_diff(ptr, skb, to, is_pseudo, false);
+               break;
+       case 2:
+               inet_proto_csum_replace2(ptr, skb, from, to, is_pseudo);
+diff --git a/net/core/utils.c b/net/core/utils.c
+index 27f4cffaae05d..b8c21a859e27b 100644
+--- a/net/core/utils.c
++++ b/net/core/utils.c
+@@ -473,11 +473,11 @@ void inet_proto_csum_replace16(__sum16 *sum, struct sk_buff *skb,
+ EXPORT_SYMBOL(inet_proto_csum_replace16);
+ void inet_proto_csum_replace_by_diff(__sum16 *sum, struct sk_buff *skb,
+-                                   __wsum diff, bool pseudohdr)
++                                   __wsum diff, bool pseudohdr, bool ipv6)
+ {
+       if (skb->ip_summed != CHECKSUM_PARTIAL) {
+               csum_replace_by_diff(sum, diff);
+-              if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr)
++              if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr && !ipv6)
+                       skb->csum = ~csum_sub(diff, skb->csum);
+       } else if (pseudohdr) {
+               *sum = ~csum_fold(csum_add(diff, csum_unfold(*sum)));
+diff --git a/net/ipv6/ila/ila_common.c b/net/ipv6/ila/ila_common.c
+index 95e9146918cc6..b8d43ed4689db 100644
+--- a/net/ipv6/ila/ila_common.c
++++ b/net/ipv6/ila/ila_common.c
+@@ -86,7 +86,7 @@ static void ila_csum_adjust_transport(struct sk_buff *skb,
+                       diff = get_csum_diff(ip6h, p);
+                       inet_proto_csum_replace_by_diff(&th->check, skb,
+-                                                      diff, true);
++                                                      diff, true, true);
+               }
+               break;
+       case NEXTHDR_UDP:
+@@ -97,7 +97,7 @@ static void ila_csum_adjust_transport(struct sk_buff *skb,
+                       if (uh->check || skb->ip_summed == CHECKSUM_PARTIAL) {
+                               diff = get_csum_diff(ip6h, p);
+                               inet_proto_csum_replace_by_diff(&uh->check, skb,
+-                                                              diff, true);
++                                                              diff, true, true);
+                               if (!uh->check)
+                                       uh->check = CSUM_MANGLED_0;
+                       }
+@@ -111,7 +111,7 @@ static void ila_csum_adjust_transport(struct sk_buff *skb,
+                       diff = get_csum_diff(ip6h, p);
+                       inet_proto_csum_replace_by_diff(&ih->icmp6_cksum, skb,
+-                                                      diff, true);
++                                                      diff, true, true);
+               }
+               break;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-fix-udp-gso-skb_segment-after-pull-from-frag_lis.patch b/queue-6.15/net-fix-udp-gso-skb_segment-after-pull-from-frag_lis.patch
new file mode 100644 (file)
index 0000000..9995735
--- /dev/null
@@ -0,0 +1,107 @@
+From b6e3eb5c3b9314247942e8378ccf2fe26a474880 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 May 2025 09:26:08 +0800
+Subject: net: fix udp gso skb_segment after pull from frag_list
+
+From: Shiming Cheng <shiming.cheng@mediatek.com>
+
+[ Upstream commit 3382a1ed7f778db841063f5d7e317ac55f9e7f72 ]
+
+Commit a1e40ac5b5e9 ("net: gso: fix udp gso fraglist segmentation after
+pull from frag_list") detected invalid geometry in frag_list skbs and
+redirects them from skb_segment_list to more robust skb_segment. But some
+packets with modified geometry can also hit bugs in that code. We don't
+know how many such cases exist. Addressing each one by one also requires
+touching the complex skb_segment code, which risks introducing bugs for
+other types of skbs. Instead, linearize all these packets that fail the
+basic invariants on gso fraglist skbs. That is more robust.
+
+If only part of the fraglist payload is pulled into head_skb, it will
+always cause exception when splitting skbs by skb_segment. For detailed
+call stack information, see below.
+
+Valid SKB_GSO_FRAGLIST skbs
+- consist of two or more segments
+- the head_skb holds the protocol headers plus first gso_size
+- one or more frag_list skbs hold exactly one segment
+- all but the last must be gso_size
+
+Optional datapath hooks such as NAT and BPF (bpf_skb_pull_data) can
+modify fraglist skbs, breaking these invariants.
+
+In extreme cases they pull one part of data into skb linear. For UDP,
+this  causes three payloads with lengths of (11,11,10) bytes were
+pulled tail to become (12,10,10) bytes.
+
+The skbs no longer meets the above SKB_GSO_FRAGLIST conditions because
+payload was pulled into head_skb, it needs to be linearized before pass
+to regular skb_segment.
+
+    skb_segment+0xcd0/0xd14
+    __udp_gso_segment+0x334/0x5f4
+    udp4_ufo_fragment+0x118/0x15c
+    inet_gso_segment+0x164/0x338
+    skb_mac_gso_segment+0xc4/0x13c
+    __skb_gso_segment+0xc4/0x124
+    validate_xmit_skb+0x9c/0x2c0
+    validate_xmit_skb_list+0x4c/0x80
+    sch_direct_xmit+0x70/0x404
+    __dev_queue_xmit+0x64c/0xe5c
+    neigh_resolve_output+0x178/0x1c4
+    ip_finish_output2+0x37c/0x47c
+    __ip_finish_output+0x194/0x240
+    ip_finish_output+0x20/0xf4
+    ip_output+0x100/0x1a0
+    NF_HOOK+0xc4/0x16c
+    ip_forward+0x314/0x32c
+    ip_rcv+0x90/0x118
+    __netif_receive_skb+0x74/0x124
+    process_backlog+0xe8/0x1a4
+    __napi_poll+0x5c/0x1f8
+    net_rx_action+0x154/0x314
+    handle_softirqs+0x154/0x4b8
+
+    [118.376811] [C201134] rxq0_pus: [name:bug&]kernel BUG at net/core/skbuff.c:4278!
+    [118.376829] [C201134] rxq0_pus: [name:traps&]Internal error: Oops - BUG: 00000000f2000800 [#1] PREEMPT SMP
+    [118.470774] [C201134] rxq0_pus: [name:mrdump&]Kernel Offset: 0x178cc00000 from 0xffffffc008000000
+    [118.470810] [C201134] rxq0_pus: [name:mrdump&]PHYS_OFFSET: 0x40000000
+    [118.470827] [C201134] rxq0_pus: [name:mrdump&]pstate: 60400005 (nZCv daif +PAN -UAO)
+    [118.470848] [C201134] rxq0_pus: [name:mrdump&]pc : [0xffffffd79598aefc] skb_segment+0xcd0/0xd14
+    [118.470900] [C201134] rxq0_pus: [name:mrdump&]lr : [0xffffffd79598a5e8] skb_segment+0x3bc/0xd14
+    [118.470928] [C201134] rxq0_pus: [name:mrdump&]sp : ffffffc008013770
+
+Fixes: a1e40ac5b5e9 ("gso: fix udp gso fraglist segmentation after pull from frag_list")
+Signed-off-by: Shiming Cheng <shiming.cheng@mediatek.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/udp_offload.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
+index 9c775f8aa4385..85b5aa82d7d74 100644
+--- a/net/ipv4/udp_offload.c
++++ b/net/ipv4/udp_offload.c
+@@ -495,6 +495,7 @@ struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb,
+       bool copy_dtor;
+       __sum16 check;
+       __be16 newlen;
++      int ret = 0;
+       mss = skb_shinfo(gso_skb)->gso_size;
+       if (gso_skb->len <= sizeof(*uh) + mss)
+@@ -523,6 +524,10 @@ struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb,
+               if (skb_pagelen(gso_skb) - sizeof(*uh) == skb_shinfo(gso_skb)->gso_size)
+                       return __udp_gso_segment_list(gso_skb, features, is_ipv6);
++              ret = __skb_linearize(gso_skb);
++              if (ret)
++                      return ERR_PTR(ret);
++
+                /* Setup csum, as fraglist skips this in udp4_gro_receive. */
+               gso_skb->csum_start = skb_transport_header(gso_skb) - gso_skb->head;
+               gso_skb->csum_offset = offsetof(struct udphdr, check);
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-lan743x-fix-phy-reset-handling-during-initializa.patch b/queue-6.15/net-lan743x-fix-phy-reset-handling-during-initializa.patch
new file mode 100644 (file)
index 0000000..f21eab6
--- /dev/null
@@ -0,0 +1,65 @@
+From b8537def60800d2e5b93b568ac91bab3c3aa2ba1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 May 2025 11:00:48 +0530
+Subject: net: lan743x: Fix PHY reset handling during initialization and WOL
+
+From: Thangaraj Samynathan <thangaraj.s@microchip.com>
+
+[ Upstream commit 82d1096ca8b5dbb3158d707e6fb3ad21c3403a49 ]
+
+Remove lan743x_phy_init from lan743x_hardware_init as it resets the PHY
+registers, causing WOL to fail on subsequent attempts. Add a call to
+lan743x_hw_reset_phy in the probe function to ensure the PHY is reset
+during device initialization.
+
+Fixes: 23f0703c125be ("lan743x: Add main source files for new lan743x driver")
+Signed-off-by: Thangaraj Samynathan <thangaraj.s@microchip.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250526053048.287095-3-thangaraj.s@microchip.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/microchip/lan743x_main.c | 13 ++++---------
+ 1 file changed, 4 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c
+index da5bd54208dd5..7f36443832ada 100644
+--- a/drivers/net/ethernet/microchip/lan743x_main.c
++++ b/drivers/net/ethernet/microchip/lan743x_main.c
+@@ -1346,11 +1346,6 @@ static int lan743x_hw_reset_phy(struct lan743x_adapter *adapter)
+                                 50000, 1000000);
+ }
+-static int lan743x_phy_init(struct lan743x_adapter *adapter)
+-{
+-      return lan743x_hw_reset_phy(adapter);
+-}
+-
+ static void lan743x_phy_interface_select(struct lan743x_adapter *adapter)
+ {
+       u32 id_rev;
+@@ -3534,10 +3529,6 @@ static int lan743x_hardware_init(struct lan743x_adapter *adapter,
+       if (ret)
+               return ret;
+-      ret = lan743x_phy_init(adapter);
+-      if (ret)
+-              return ret;
+-
+       ret = lan743x_ptp_init(adapter);
+       if (ret)
+               return ret;
+@@ -3674,6 +3665,10 @@ static int lan743x_pcidev_probe(struct pci_dev *pdev,
+       if (ret)
+               goto cleanup_pci;
++      ret = lan743x_hw_reset_phy(adapter);
++      if (ret)
++              goto cleanup_pci;
++
+       ret = lan743x_hardware_init(adapter, pdev);
+       if (ret)
+               goto cleanup_pci;
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-lan743x-rename-lan743x_reset_phy-to-lan743x_hw_r.patch b/queue-6.15/net-lan743x-rename-lan743x_reset_phy-to-lan743x_hw_r.patch
new file mode 100644 (file)
index 0000000..c95ba38
--- /dev/null
@@ -0,0 +1,47 @@
+From 8a27c6c1fdd5a1cb943bb38075324ee379132854 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 May 2025 11:00:47 +0530
+Subject: net: lan743x: rename lan743x_reset_phy to lan743x_hw_reset_phy
+
+From: Thangaraj Samynathan <thangaraj.s@microchip.com>
+
+[ Upstream commit 68927eb52d0af04863584930db06075d2610e194 ]
+
+rename the function to lan743x_hw_reset_phy to better describe it
+operation.
+
+Fixes: 23f0703c125be ("lan743x: Add main source files for new lan743x driver")
+Signed-off-by: Thangaraj Samynathan <thangaraj.s@microchip.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250526053048.287095-2-thangaraj.s@microchip.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/microchip/lan743x_main.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c
+index a70b88037a208..da5bd54208dd5 100644
+--- a/drivers/net/ethernet/microchip/lan743x_main.c
++++ b/drivers/net/ethernet/microchip/lan743x_main.c
+@@ -1330,7 +1330,7 @@ static int lan743x_mac_set_mtu(struct lan743x_adapter *adapter, int new_mtu)
+ }
+ /* PHY */
+-static int lan743x_phy_reset(struct lan743x_adapter *adapter)
++static int lan743x_hw_reset_phy(struct lan743x_adapter *adapter)
+ {
+       u32 data;
+@@ -1348,7 +1348,7 @@ static int lan743x_phy_reset(struct lan743x_adapter *adapter)
+ static int lan743x_phy_init(struct lan743x_adapter *adapter)
+ {
+-      return lan743x_phy_reset(adapter);
++      return lan743x_hw_reset_phy(adapter);
+ }
+ static void lan743x_phy_interface_select(struct lan743x_adapter *adapter)
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-lan966x-fix-1-step-timestamping-over-ipv4-or-ipv.patch b/queue-6.15/net-lan966x-fix-1-step-timestamping-over-ipv4-or-ipv.patch
new file mode 100644 (file)
index 0000000..03ad5f1
--- /dev/null
@@ -0,0 +1,168 @@
+From 1a57c7dcd09ab34f99fdc00011c0b120b6251803 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 May 2025 14:41:59 +0200
+Subject: net: lan966x: Fix 1-step timestamping over ipv4 or ipv6
+
+From: Horatiu Vultur <horatiu.vultur@microchip.com>
+
+[ Upstream commit 57ee9584fd8606deef66d7b65fa4dcf94f6843aa ]
+
+When enabling 1-step timestamping for ptp frames that are over udpv4 or
+udpv6 then the inserted timestamp is added at the wrong offset in the
+frame, meaning that will modify the frame at the wrong place, so the
+frame will be malformed.
+To fix this, the HW needs to know which kind of frame it is to know
+where to insert the timestamp. For that there is a field in the IFH that
+says the PDU_TYPE, which can be NONE  which is the default value,
+IPV4 or IPV6. Therefore make sure to set the PDU_TYPE so the HW knows
+where to insert the timestamp.
+Like I mention before the issue is not seen with L2 frames because by
+default the PDU_TYPE has a value of 0, which represents the L2 frames.
+
+Fixes: 77eecf25bd9d2f ("net: lan966x: Update extraction/injection for timestamping")
+Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Link: https://patch.msgid.link/20250521124159.2713525-1-horatiu.vultur@microchip.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/microchip/lan966x/lan966x_main.c |  6 +++
+ .../ethernet/microchip/lan966x/lan966x_main.h |  5 ++
+ .../ethernet/microchip/lan966x/lan966x_ptp.c  | 49 ++++++++++++++-----
+ 3 files changed, 47 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
+index 0af143ec0f869..427bdc0e4908c 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
+@@ -353,6 +353,11 @@ static void lan966x_ifh_set_rew_op(void *ifh, u64 rew_op)
+       lan966x_ifh_set(ifh, rew_op, IFH_POS_REW_CMD, IFH_WID_REW_CMD);
+ }
++static void lan966x_ifh_set_oam_type(void *ifh, u64 oam_type)
++{
++      lan966x_ifh_set(ifh, oam_type, IFH_POS_PDU_TYPE, IFH_WID_PDU_TYPE);
++}
++
+ static void lan966x_ifh_set_timestamp(void *ifh, u64 timestamp)
+ {
+       lan966x_ifh_set(ifh, timestamp, IFH_POS_TIMESTAMP, IFH_WID_TIMESTAMP);
+@@ -380,6 +385,7 @@ static netdev_tx_t lan966x_port_xmit(struct sk_buff *skb,
+                       return err;
+               lan966x_ifh_set_rew_op(ifh, LAN966X_SKB_CB(skb)->rew_op);
++              lan966x_ifh_set_oam_type(ifh, LAN966X_SKB_CB(skb)->pdu_type);
+               lan966x_ifh_set_timestamp(ifh, LAN966X_SKB_CB(skb)->ts_id);
+       }
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
+index 1efa584e71077..1f9df67f05044 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
+@@ -75,6 +75,10 @@
+ #define IFH_REW_OP_ONE_STEP_PTP               0x3
+ #define IFH_REW_OP_TWO_STEP_PTP               0x4
++#define IFH_PDU_TYPE_NONE             0
++#define IFH_PDU_TYPE_IPV4             7
++#define IFH_PDU_TYPE_IPV6             8
++
+ #define FDMA_RX_DCB_MAX_DBS           1
+ #define FDMA_TX_DCB_MAX_DBS           1
+@@ -254,6 +258,7 @@ struct lan966x_phc {
+ struct lan966x_skb_cb {
+       u8 rew_op;
++      u8 pdu_type;
+       u16 ts_id;
+       unsigned long jiffies;
+ };
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c b/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
+index 63905bb5a63a8..87e5e81d40dc6 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
+@@ -322,34 +322,55 @@ void lan966x_ptp_hwtstamp_get(struct lan966x_port *port,
+       *cfg = phc->hwtstamp_config;
+ }
+-static int lan966x_ptp_classify(struct lan966x_port *port, struct sk_buff *skb)
++static void lan966x_ptp_classify(struct lan966x_port *port, struct sk_buff *skb,
++                               u8 *rew_op, u8 *pdu_type)
+ {
+       struct ptp_header *header;
+       u8 msgtype;
+       int type;
+-      if (port->ptp_tx_cmd == IFH_REW_OP_NOOP)
+-              return IFH_REW_OP_NOOP;
++      if (port->ptp_tx_cmd == IFH_REW_OP_NOOP) {
++              *rew_op = IFH_REW_OP_NOOP;
++              *pdu_type = IFH_PDU_TYPE_NONE;
++              return;
++      }
+       type = ptp_classify_raw(skb);
+-      if (type == PTP_CLASS_NONE)
+-              return IFH_REW_OP_NOOP;
++      if (type == PTP_CLASS_NONE) {
++              *rew_op = IFH_REW_OP_NOOP;
++              *pdu_type = IFH_PDU_TYPE_NONE;
++              return;
++      }
+       header = ptp_parse_header(skb, type);
+-      if (!header)
+-              return IFH_REW_OP_NOOP;
++      if (!header) {
++              *rew_op = IFH_REW_OP_NOOP;
++              *pdu_type = IFH_PDU_TYPE_NONE;
++              return;
++      }
+-      if (port->ptp_tx_cmd == IFH_REW_OP_TWO_STEP_PTP)
+-              return IFH_REW_OP_TWO_STEP_PTP;
++      if (type & PTP_CLASS_L2)
++              *pdu_type = IFH_PDU_TYPE_NONE;
++      if (type & PTP_CLASS_IPV4)
++              *pdu_type = IFH_PDU_TYPE_IPV4;
++      if (type & PTP_CLASS_IPV6)
++              *pdu_type = IFH_PDU_TYPE_IPV6;
++
++      if (port->ptp_tx_cmd == IFH_REW_OP_TWO_STEP_PTP) {
++              *rew_op = IFH_REW_OP_TWO_STEP_PTP;
++              return;
++      }
+       /* If it is sync and run 1 step then set the correct operation,
+        * otherwise run as 2 step
+        */
+       msgtype = ptp_get_msgtype(header, type);
+-      if ((msgtype & 0xf) == 0)
+-              return IFH_REW_OP_ONE_STEP_PTP;
++      if ((msgtype & 0xf) == 0) {
++              *rew_op = IFH_REW_OP_ONE_STEP_PTP;
++              return;
++      }
+-      return IFH_REW_OP_TWO_STEP_PTP;
++      *rew_op = IFH_REW_OP_TWO_STEP_PTP;
+ }
+ static void lan966x_ptp_txtstamp_old_release(struct lan966x_port *port)
+@@ -374,10 +395,12 @@ int lan966x_ptp_txtstamp_request(struct lan966x_port *port,
+ {
+       struct lan966x *lan966x = port->lan966x;
+       unsigned long flags;
++      u8 pdu_type;
+       u8 rew_op;
+-      rew_op = lan966x_ptp_classify(port, skb);
++      lan966x_ptp_classify(port, skb, &rew_op, &pdu_type);
+       LAN966X_SKB_CB(skb)->rew_op = rew_op;
++      LAN966X_SKB_CB(skb)->pdu_type = pdu_type;
+       if (rew_op != IFH_REW_OP_TWO_STEP_PTP)
+               return 0;
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-lan966x-make-sure-to-insert-the-vlan-tags-also-i.patch b/queue-6.15/net-lan966x-make-sure-to-insert-the-vlan-tags-also-i.patch
new file mode 100644 (file)
index 0000000..0141e41
--- /dev/null
@@ -0,0 +1,112 @@
+From 42b3a781554431d383de46d162cf07336130071e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 May 2025 11:36:19 +0200
+Subject: net: lan966x: Make sure to insert the vlan tags also in host mode
+
+From: Horatiu Vultur <horatiu.vultur@microchip.com>
+
+[ Upstream commit 27eab4c644236a9324084a70fe79e511cbd07393 ]
+
+When running these commands on DUT (and similar at the other end)
+ip link set dev eth0 up
+ip link add link eth0 name eth0.10 type vlan id 10
+ip addr add 10.0.0.1/24 dev eth0.10
+ip link set dev eth0.10 up
+ping 10.0.0.2
+
+The ping will fail.
+
+The reason why is failing is because, the network interfaces for lan966x
+have a flag saying that the HW can insert the vlan tags into the
+frames(NETIF_F_HW_VLAN_CTAG_TX). Meaning that the frames that are
+transmitted don't have the vlan tag inside the skb data, but they have
+it inside the skb. We already get that vlan tag and put it in the IFH
+but the problem is that we don't configure the HW to rewrite the frame
+when the interface is in host mode.
+The fix consists in actually configuring the HW to insert the vlan tag
+if it is different than 0.
+
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Fixes: 6d2c186afa5d ("net: lan966x: Add vlan support.")
+Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Link: https://patch.msgid.link/20250528093619.3738998-1-horatiu.vultur@microchip.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/microchip/lan966x/lan966x_main.c |  1 +
+ .../ethernet/microchip/lan966x/lan966x_main.h |  1 +
+ .../microchip/lan966x/lan966x_switchdev.c     |  1 +
+ .../ethernet/microchip/lan966x/lan966x_vlan.c | 21 +++++++++++++++++++
+ 4 files changed, 24 insertions(+)
+
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
+index 427bdc0e4908c..7001584f1b7a6 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
+@@ -879,6 +879,7 @@ static int lan966x_probe_port(struct lan966x *lan966x, u32 p,
+       lan966x_vlan_port_set_vlan_aware(port, 0);
+       lan966x_vlan_port_set_vid(port, HOST_PVID, false, false);
+       lan966x_vlan_port_apply(port);
++      lan966x_vlan_port_rew_host(port);
+       return 0;
+ }
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
+index 1f9df67f05044..4f75f06883693 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
+@@ -497,6 +497,7 @@ void lan966x_vlan_port_apply(struct lan966x_port *port);
+ bool lan966x_vlan_cpu_member_cpu_vlan_mask(struct lan966x *lan966x, u16 vid);
+ void lan966x_vlan_port_set_vlan_aware(struct lan966x_port *port,
+                                     bool vlan_aware);
++void lan966x_vlan_port_rew_host(struct lan966x_port *port);
+ int lan966x_vlan_port_set_vid(struct lan966x_port *port,
+                             u16 vid,
+                             bool pvid,
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_switchdev.c b/drivers/net/ethernet/microchip/lan966x/lan966x_switchdev.c
+index 1c88120eb291a..bcb4db76b75cd 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_switchdev.c
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_switchdev.c
+@@ -297,6 +297,7 @@ static void lan966x_port_bridge_leave(struct lan966x_port *port,
+       lan966x_vlan_port_set_vlan_aware(port, false);
+       lan966x_vlan_port_set_vid(port, HOST_PVID, false, false);
+       lan966x_vlan_port_apply(port);
++      lan966x_vlan_port_rew_host(port);
+ }
+ int lan966x_port_changeupper(struct net_device *dev,
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_vlan.c b/drivers/net/ethernet/microchip/lan966x/lan966x_vlan.c
+index fa34a739c748e..7da22520724ce 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_vlan.c
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_vlan.c
+@@ -149,6 +149,27 @@ void lan966x_vlan_port_set_vlan_aware(struct lan966x_port *port,
+       port->vlan_aware = vlan_aware;
+ }
++/* When the interface is in host mode, the interface should not be vlan aware
++ * but it should insert all the tags that it gets from the network stack.
++ * The tags are not in the data of the frame but actually in the skb and the ifh
++ * is configured already to get this tag. So what we need to do is to update the
++ * rewriter to insert the vlan tag for all frames which have a vlan tag
++ * different than 0.
++ */
++void lan966x_vlan_port_rew_host(struct lan966x_port *port)
++{
++      struct lan966x *lan966x = port->lan966x;
++      u32 val;
++
++      /* Tag all frames except when VID=0*/
++      val = REW_TAG_CFG_TAG_CFG_SET(2);
++
++      /* Update only some bits in the register */
++      lan_rmw(val,
++              REW_TAG_CFG_TAG_CFG,
++              lan966x, REW_TAG_CFG(port->chip_port));
++}
++
+ void lan966x_vlan_port_apply(struct lan966x_port *port)
+ {
+       struct lan966x *lan966x = port->lan966x;
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-mctp-start-tx-queue-on-netdev-open.patch b/queue-6.15/net-mctp-start-tx-queue-on-netdev-open.patch
new file mode 100644 (file)
index 0000000..fad14ec
--- /dev/null
@@ -0,0 +1,38 @@
+From b7e4b2e3356713b12c730ec7e96bbcdab0c17668 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 May 2025 10:44:33 +0800
+Subject: net: mctp: start tx queue on netdev open
+
+From: Jeremy Kerr <jk@codeconstruct.com.au>
+
+[ Upstream commit 126cd7852a62c6fab11a4a4cb6fa96421929ab69 ]
+
+We stop queues in ndo_stop, so they need to be restarted in ndo_open.
+This allows us to resume tx after a link down/up cycle.
+
+Suggested-by: Nitin Singh <nitsingh@nvidia.com>
+Fixes: 0791c0327a6e ("net: mctp: Add MCTP USB transport driver")
+Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
+Link: https://patch.msgid.link/20250526-dev-mctp-usb-v1-1-c7bd6cb75aa0@codeconstruct.com.au
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/mctp/mctp-usb.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/mctp/mctp-usb.c b/drivers/net/mctp/mctp-usb.c
+index e8d4b01c3f345..775a386d0aca1 100644
+--- a/drivers/net/mctp/mctp-usb.c
++++ b/drivers/net/mctp/mctp-usb.c
+@@ -257,6 +257,8 @@ static int mctp_usb_open(struct net_device *dev)
+       WRITE_ONCE(mctp_usb->stopped, false);
++      netif_start_queue(dev);
++
+       return mctp_usb_rx_queue(mctp_usb, GFP_KERNEL);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-mlx4_en-prevent-potential-integer-overflow-calcu.patch b/queue-6.15/net-mlx4_en-prevent-potential-integer-overflow-calcu.patch
new file mode 100644 (file)
index 0000000..68a694a
--- /dev/null
@@ -0,0 +1,41 @@
+From a7fb31a3b06830796a946d620552581dbdbef0fd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 May 2025 11:11:09 +0300
+Subject: net/mlx4_en: Prevent potential integer overflow calculating Hz
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 54d34165b4f786d7fea8412a18fb4a54c1eab623 ]
+
+The "freq" variable is in terms of MHz and "max_val_cycles" is in terms
+of Hz.  The fact that "max_val_cycles" is a u64 suggests that support
+for high frequency is intended but the "freq_khz * 1000" would overflow
+the u32 type if we went above 4GHz.  Use unsigned long long type for the
+mutliplication to prevent that.
+
+Fixes: 31c128b66e5b ("net/mlx4_en: Choose time-stamping shift value according to HW frequency")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/aDbFHe19juIJKjsb@stanley.mountain
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx4/en_clock.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx4/en_clock.c b/drivers/net/ethernet/mellanox/mlx4/en_clock.c
+index cd754cd76bde1..d73a2044dc266 100644
+--- a/drivers/net/ethernet/mellanox/mlx4/en_clock.c
++++ b/drivers/net/ethernet/mellanox/mlx4/en_clock.c
+@@ -249,7 +249,7 @@ static const struct ptp_clock_info mlx4_en_ptp_clock_info = {
+ static u32 freq_to_shift(u16 freq)
+ {
+       u32 freq_khz = freq * 1000;
+-      u64 max_val_cycles = freq_khz * 1000 * MLX4_EN_WRAP_AROUND_SEC;
++      u64 max_val_cycles = freq_khz * 1000ULL * MLX4_EN_WRAP_AROUND_SEC;
+       u64 max_val_cycles_rounded = 1ULL << fls64(max_val_cycles - 1);
+       /* calculate max possible multiplier in order to fit in 64bit */
+       u64 max_mul = div64_u64(ULLONG_MAX, max_val_cycles_rounded);
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-mlx5-avoid-using-xso.real_dev-unnecessarily.patch b/queue-6.15/net-mlx5-avoid-using-xso.real_dev-unnecessarily.patch
new file mode 100644 (file)
index 0000000..04d3b0f
--- /dev/null
@@ -0,0 +1,116 @@
+From cb403dc3012874c3a64eda2803506c843fa86ab6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Apr 2025 10:49:53 +0300
+Subject: net/mlx5: Avoid using xso.real_dev unnecessarily
+
+From: Cosmin Ratiu <cratiu@nvidia.com>
+
+[ Upstream commit d79444e8c3d40b11f5e155e5591d53bd1e512e1f ]
+
+xso.real_dev is the active device of an offloaded xfrm state and is
+managed by bonding. As such, it's subject to change when states are
+migrated to a new device. Using it in places other than
+offloading/unoffloading the states is risky.
+
+This commit saves the device into the driver-specific struct
+mlx5e_ipsec_sa_entry and switches mlx5e_ipsec_init_macs() and
+mlx5e_ipsec_netevent_event() to make use of it.
+
+Additionally, mlx5e_xfrm_update_stats() used xso.real_dev to validate
+that correct net locks are held. But in a bonding config, the net of the
+master device is the same as the underlying devices, and the net is
+already a local var, so use that instead.
+
+The only remaining references to xso.real_dev are now in the
+.xdo_dev_state_add() / .xdo_dev_state_delete() path.
+
+Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Stable-dep-of: fd4e41ebf66c ("bonding: Mark active offloaded xfrm_states")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/mellanox/mlx5/core/en_accel/ipsec.c | 16 +++++-----------
+ .../ethernet/mellanox/mlx5/core/en_accel/ipsec.h |  1 +
+ 2 files changed, 6 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
+index 2dd842aac6fc4..626e525c0f0d7 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
+@@ -259,8 +259,7 @@ static void mlx5e_ipsec_init_macs(struct mlx5e_ipsec_sa_entry *sa_entry,
+                                 struct mlx5_accel_esp_xfrm_attrs *attrs)
+ {
+       struct mlx5_core_dev *mdev = mlx5e_ipsec_sa2dev(sa_entry);
+-      struct xfrm_state *x = sa_entry->x;
+-      struct net_device *netdev;
++      struct net_device *netdev = sa_entry->dev;
+       struct neighbour *n;
+       u8 addr[ETH_ALEN];
+       const void *pkey;
+@@ -270,8 +269,6 @@ static void mlx5e_ipsec_init_macs(struct mlx5e_ipsec_sa_entry *sa_entry,
+           attrs->type != XFRM_DEV_OFFLOAD_PACKET)
+               return;
+-      netdev = x->xso.real_dev;
+-
+       mlx5_query_mac_address(mdev, addr);
+       switch (attrs->dir) {
+       case XFRM_DEV_OFFLOAD_IN:
+@@ -713,6 +710,7 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x,
+               return -ENOMEM;
+       sa_entry->x = x;
++      sa_entry->dev = netdev;
+       sa_entry->ipsec = ipsec;
+       /* Check if this SA is originated from acquire flow temporary SA */
+       if (x->xso.flags & XFRM_DEV_OFFLOAD_FLAG_ACQ)
+@@ -855,8 +853,6 @@ static int mlx5e_ipsec_netevent_event(struct notifier_block *nb,
+       struct mlx5e_ipsec_sa_entry *sa_entry;
+       struct mlx5e_ipsec *ipsec;
+       struct neighbour *n = ptr;
+-      struct net_device *netdev;
+-      struct xfrm_state *x;
+       unsigned long idx;
+       if (event != NETEVENT_NEIGH_UPDATE || !(n->nud_state & NUD_VALID))
+@@ -876,11 +872,9 @@ static int mlx5e_ipsec_netevent_event(struct notifier_block *nb,
+                               continue;
+               }
+-              x = sa_entry->x;
+-              netdev = x->xso.real_dev;
+               data = sa_entry->work->data;
+-              neigh_ha_snapshot(data->addr, n, netdev);
++              neigh_ha_snapshot(data->addr, n, sa_entry->dev);
+               queue_work(ipsec->wq, &sa_entry->work->work);
+       }
+@@ -996,8 +990,8 @@ static void mlx5e_xfrm_update_stats(struct xfrm_state *x)
+       size_t headers;
+       lockdep_assert(lockdep_is_held(&x->lock) ||
+-                     lockdep_is_held(&dev_net(x->xso.real_dev)->xfrm.xfrm_cfg_mutex) ||
+-                     lockdep_is_held(&dev_net(x->xso.real_dev)->xfrm.xfrm_state_lock));
++                     lockdep_is_held(&net->xfrm.xfrm_cfg_mutex) ||
++                     lockdep_is_held(&net->xfrm.xfrm_state_lock));
+       if (x->xso.flags & XFRM_DEV_OFFLOAD_FLAG_ACQ)
+               return;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h
+index a63c2289f8af9..ffcd0cdeb7754 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h
+@@ -274,6 +274,7 @@ struct mlx5e_ipsec_limits {
+ struct mlx5e_ipsec_sa_entry {
+       struct mlx5e_ipsec_esn_state esn_state;
+       struct xfrm_state *x;
++      struct net_device *dev;
+       struct mlx5e_ipsec *ipsec;
+       struct mlx5_accel_esp_xfrm_attrs attrs;
+       void (*set_iv_op)(struct sk_buff *skb, struct xfrm_state *x,
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-mlx5-hws-fix-matcher-action-template-attach.patch b/queue-6.15/net-mlx5-hws-fix-matcher-action-template-attach.patch
new file mode 100644 (file)
index 0000000..0477795
--- /dev/null
@@ -0,0 +1,325 @@
+From f571ed4e7ddabbdbc45c52b23cb6920c7dd2783e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Apr 2025 22:17:31 +0300
+Subject: net/mlx5: HWS, Fix matcher action template attach
+
+From: Vlad Dogaru <vdogaru@nvidia.com>
+
+[ Upstream commit 36ef2575e78d1a3c699dc3f1c9dee9be742c9bdd ]
+
+The procedure of attaching an action template to an existing matcher had
+a few issues:
+
+1. Attaching accidentally overran the `at` array in bwc_matcher, which
+   would result in memory corruption. This bug wasn't triggered, but it
+   is possible to trigger it by attaching action templates beyond the
+   initial buffer size of 8. Fix this by converting to a dynamically
+   sized buffer and reallocating if needed.
+
+2. Similarly, the `at` array inside the native matcher was never
+   reallocated. Fix this the same as above.
+
+3. The bwc layer treated any error in action template attach as a signal
+   that the matcher should be rehashed to account for a larger number of
+   action STEs. In reality, there are other unrelated errors that can
+   arise and they should be propagated upstack. Fix this by adding a
+   `need_rehash` output parameter that's orthogonal to error codes.
+
+Fixes: 2111bb970c78 ("net/mlx5: HWS, added backward-compatible API handling")
+Signed-off-by: Vlad Dogaru <vdogaru@nvidia.com>
+Reviewed-by: Yevgeny Kliteynik <kliteyn@nvidia.com>
+Reviewed-by: Mark Bloch <mbloch@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Michal Kubiak <michal.kubiak@intel.com>
+Link: https://patch.msgid.link/1744312662-356571-2-git-send-email-tariqt@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/steering/hws/bwc.c     | 55 ++++++++++++++++---
+ .../mellanox/mlx5/core/steering/hws/bwc.h     |  9 ++-
+ .../mellanox/mlx5/core/steering/hws/matcher.c | 48 +++++++++++++---
+ .../mellanox/mlx5/core/steering/hws/matcher.h |  4 ++
+ .../mellanox/mlx5/core/steering/hws/mlx5hws.h |  5 +-
+ 5 files changed, 97 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.c
+index 19dce1ba512d4..32de8bfc7644f 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.c
+@@ -90,13 +90,19 @@ int mlx5hws_bwc_matcher_create_simple(struct mlx5hws_bwc_matcher *bwc_matcher,
+       bwc_matcher->priority = priority;
+       bwc_matcher->size_log = MLX5HWS_BWC_MATCHER_INIT_SIZE_LOG;
++      bwc_matcher->size_of_at_array = MLX5HWS_BWC_MATCHER_ATTACH_AT_NUM;
++      bwc_matcher->at = kcalloc(bwc_matcher->size_of_at_array,
++                                sizeof(*bwc_matcher->at), GFP_KERNEL);
++      if (!bwc_matcher->at)
++              goto free_bwc_matcher_rules;
++
+       /* create dummy action template */
+       bwc_matcher->at[0] =
+               mlx5hws_action_template_create(action_types ?
+                                              action_types : init_action_types);
+       if (!bwc_matcher->at[0]) {
+               mlx5hws_err(table->ctx, "BWC matcher: failed creating action template\n");
+-              goto free_bwc_matcher_rules;
++              goto free_bwc_matcher_at_array;
+       }
+       bwc_matcher->num_of_at = 1;
+@@ -126,6 +132,8 @@ int mlx5hws_bwc_matcher_create_simple(struct mlx5hws_bwc_matcher *bwc_matcher,
+       mlx5hws_match_template_destroy(bwc_matcher->mt);
+ free_at:
+       mlx5hws_action_template_destroy(bwc_matcher->at[0]);
++free_bwc_matcher_at_array:
++      kfree(bwc_matcher->at);
+ free_bwc_matcher_rules:
+       kfree(bwc_matcher->rules);
+ err:
+@@ -192,6 +200,7 @@ int mlx5hws_bwc_matcher_destroy_simple(struct mlx5hws_bwc_matcher *bwc_matcher)
+       for (i = 0; i < bwc_matcher->num_of_at; i++)
+               mlx5hws_action_template_destroy(bwc_matcher->at[i]);
++      kfree(bwc_matcher->at);
+       mlx5hws_match_template_destroy(bwc_matcher->mt);
+       kfree(bwc_matcher->rules);
+@@ -520,6 +529,23 @@ hws_bwc_matcher_extend_at(struct mlx5hws_bwc_matcher *bwc_matcher,
+                         struct mlx5hws_rule_action rule_actions[])
+ {
+       enum mlx5hws_action_type action_types[MLX5HWS_BWC_MAX_ACTS];
++      void *p;
++
++      if (unlikely(bwc_matcher->num_of_at >= bwc_matcher->size_of_at_array)) {
++              if (bwc_matcher->size_of_at_array >= MLX5HWS_MATCHER_MAX_AT)
++                      return -ENOMEM;
++              bwc_matcher->size_of_at_array *= 2;
++              p = krealloc(bwc_matcher->at,
++                           bwc_matcher->size_of_at_array *
++                                   sizeof(*bwc_matcher->at),
++                           __GFP_ZERO | GFP_KERNEL);
++              if (!p) {
++                      bwc_matcher->size_of_at_array /= 2;
++                      return -ENOMEM;
++              }
++
++              bwc_matcher->at = p;
++      }
+       hws_bwc_rule_actions_to_action_types(rule_actions, action_types);
+@@ -777,6 +803,7 @@ int mlx5hws_bwc_rule_create_simple(struct mlx5hws_bwc_rule *bwc_rule,
+       struct mlx5hws_rule_attr rule_attr;
+       struct mutex *queue_lock; /* Protect the queue */
+       u32 num_of_rules;
++      bool need_rehash;
+       int ret = 0;
+       int at_idx;
+@@ -803,10 +830,14 @@ int mlx5hws_bwc_rule_create_simple(struct mlx5hws_bwc_rule *bwc_rule,
+               at_idx = bwc_matcher->num_of_at - 1;
+               ret = mlx5hws_matcher_attach_at(bwc_matcher->matcher,
+-                                              bwc_matcher->at[at_idx]);
++                                              bwc_matcher->at[at_idx],
++                                              &need_rehash);
+               if (unlikely(ret)) {
+-                      /* Action template attach failed, possibly due to
+-                       * requiring more action STEs.
++                      hws_bwc_unlock_all_queues(ctx);
++                      return ret;
++              }
++              if (unlikely(need_rehash)) {
++                      /* The new action template requires more action STEs.
+                        * Need to attempt creating new matcher with all
+                        * the action templates, including the new one.
+                        */
+@@ -942,6 +973,7 @@ hws_bwc_rule_action_update(struct mlx5hws_bwc_rule *bwc_rule,
+       struct mlx5hws_context *ctx = bwc_matcher->matcher->tbl->ctx;
+       struct mlx5hws_rule_attr rule_attr;
+       struct mutex *queue_lock; /* Protect the queue */
++      bool need_rehash;
+       int at_idx, ret;
+       u16 idx;
+@@ -973,12 +1005,17 @@ hws_bwc_rule_action_update(struct mlx5hws_bwc_rule *bwc_rule,
+                       at_idx = bwc_matcher->num_of_at - 1;
+                       ret = mlx5hws_matcher_attach_at(bwc_matcher->matcher,
+-                                                      bwc_matcher->at[at_idx]);
++                                                      bwc_matcher->at[at_idx],
++                                                      &need_rehash);
+                       if (unlikely(ret)) {
+-                              /* Action template attach failed, possibly due to
+-                               * requiring more action STEs.
+-                               * Need to attempt creating new matcher with all
+-                               * the action templates, including the new one.
++                              hws_bwc_unlock_all_queues(ctx);
++                              return ret;
++                      }
++                      if (unlikely(need_rehash)) {
++                              /* The new action template requires more action
++                               * STEs. Need to attempt creating new matcher
++                               * with all the action templates, including the
++                               * new one.
+                                */
+                               ret = hws_bwc_matcher_rehash_at(bwc_matcher);
+                               if (unlikely(ret)) {
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.h b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.h
+index 47f7ed1415535..bb0cf4b922ceb 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.h
+@@ -10,9 +10,7 @@
+ #define MLX5HWS_BWC_MATCHER_REHASH_BURST_TH 32
+ /* Max number of AT attach operations for the same matcher.
+- * When the limit is reached, next attempt to attach new AT
+- * will result in creation of a new matcher and moving all
+- * the rules to this matcher.
++ * When the limit is reached, a larger buffer is allocated for the ATs.
+  */
+ #define MLX5HWS_BWC_MATCHER_ATTACH_AT_NUM 8
+@@ -23,10 +21,11 @@
+ struct mlx5hws_bwc_matcher {
+       struct mlx5hws_matcher *matcher;
+       struct mlx5hws_match_template *mt;
+-      struct mlx5hws_action_template *at[MLX5HWS_BWC_MATCHER_ATTACH_AT_NUM];
+-      u32 priority;
++      struct mlx5hws_action_template **at;
+       u8 num_of_at;
++      u8 size_of_at_array;
+       u8 size_log;
++      u32 priority;
+       atomic_t num_of_rules;
+       struct list_head *rules;
+ };
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/matcher.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/matcher.c
+index b61864b320536..37a4497048a6f 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/matcher.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/matcher.c
+@@ -905,18 +905,48 @@ static int hws_matcher_uninit(struct mlx5hws_matcher *matcher)
+       return 0;
+ }
++static int hws_matcher_grow_at_array(struct mlx5hws_matcher *matcher)
++{
++      void *p;
++
++      if (matcher->size_of_at_array >= MLX5HWS_MATCHER_MAX_AT)
++              return -ENOMEM;
++
++      matcher->size_of_at_array *= 2;
++      p = krealloc(matcher->at,
++                   matcher->size_of_at_array * sizeof(*matcher->at),
++                   __GFP_ZERO | GFP_KERNEL);
++      if (!p) {
++              matcher->size_of_at_array /= 2;
++              return -ENOMEM;
++      }
++
++      matcher->at = p;
++
++      return 0;
++}
++
+ int mlx5hws_matcher_attach_at(struct mlx5hws_matcher *matcher,
+-                            struct mlx5hws_action_template *at)
++                            struct mlx5hws_action_template *at,
++                            bool *need_rehash)
+ {
+       bool is_jumbo = mlx5hws_matcher_mt_is_jumbo(matcher->mt);
+       struct mlx5hws_context *ctx = matcher->tbl->ctx;
+       u32 required_stes;
+       int ret;
+-      if (!matcher->attr.max_num_of_at_attach) {
+-              mlx5hws_dbg(ctx, "Num of current at (%d) exceed allowed value\n",
+-                          matcher->num_of_at);
+-              return -EOPNOTSUPP;
++      *need_rehash = false;
++
++      if (unlikely(matcher->num_of_at >= matcher->size_of_at_array)) {
++              ret = hws_matcher_grow_at_array(matcher);
++              if (ret)
++                      return ret;
++
++              if (matcher->col_matcher) {
++                      ret = hws_matcher_grow_at_array(matcher->col_matcher);
++                      if (ret)
++                              return ret;
++              }
+       }
+       ret = hws_matcher_check_and_process_at(matcher, at);
+@@ -927,12 +957,11 @@ int mlx5hws_matcher_attach_at(struct mlx5hws_matcher *matcher,
+       if (matcher->action_ste.max_stes < required_stes) {
+               mlx5hws_dbg(ctx, "Required STEs [%d] exceeds initial action template STE [%d]\n",
+                           required_stes, matcher->action_ste.max_stes);
+-              return -ENOMEM;
++              *need_rehash = true;
+       }
+       matcher->at[matcher->num_of_at] = *at;
+       matcher->num_of_at += 1;
+-      matcher->attr.max_num_of_at_attach -= 1;
+       if (matcher->col_matcher)
+               matcher->col_matcher->num_of_at = matcher->num_of_at;
+@@ -960,8 +989,9 @@ hws_matcher_set_templates(struct mlx5hws_matcher *matcher,
+       if (!matcher->mt)
+               return -ENOMEM;
+-      matcher->at = kvcalloc(num_of_at + matcher->attr.max_num_of_at_attach,
+-                             sizeof(*matcher->at),
++      matcher->size_of_at_array =
++              num_of_at + matcher->attr.max_num_of_at_attach;
++      matcher->at = kvcalloc(matcher->size_of_at_array, sizeof(*matcher->at),
+                              GFP_KERNEL);
+       if (!matcher->at) {
+               mlx5hws_err(ctx, "Failed to allocate action template array\n");
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/matcher.h b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/matcher.h
+index 020de70270c50..20b32012c418b 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/matcher.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/matcher.h
+@@ -23,6 +23,9 @@
+  */
+ #define MLX5HWS_MATCHER_ACTION_RTC_UPDATE_MULT 1
++/* Maximum number of action templates that can be attached to a matcher. */
++#define MLX5HWS_MATCHER_MAX_AT 128
++
+ enum mlx5hws_matcher_offset {
+       MLX5HWS_MATCHER_OFFSET_TAG_DW1 = 12,
+       MLX5HWS_MATCHER_OFFSET_TAG_DW0 = 13,
+@@ -72,6 +75,7 @@ struct mlx5hws_matcher {
+       struct mlx5hws_match_template *mt;
+       struct mlx5hws_action_template *at;
+       u8 num_of_at;
++      u8 size_of_at_array;
+       u8 num_of_mt;
+       /* enum mlx5hws_matcher_flags */
+       u8 flags;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/mlx5hws.h b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/mlx5hws.h
+index 5121951f2778a..8ed8a715a2eb2 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/mlx5hws.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/mlx5hws.h
+@@ -399,11 +399,14 @@ int mlx5hws_matcher_destroy(struct mlx5hws_matcher *matcher);
+  *
+  * @matcher: Matcher to attach the action template to.
+  * @at: Action template to be attached to the matcher.
++ * @need_rehash: Output parameter that tells callers if the matcher needs to be
++ * rehashed.
+  *
+  * Return: Zero on success, non-zero otherwise.
+  */
+ int mlx5hws_matcher_attach_at(struct mlx5hws_matcher *matcher,
+-                            struct mlx5hws_action_template *at);
++                            struct mlx5hws_action_template *at,
++                            bool *need_rehash);
+ /**
+  * mlx5hws_matcher_resize_set_target - Link two matchers and enable moving rules.
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-ncsi-fix-gcps-64-bit-member-variables.patch b/queue-6.15/net-ncsi-fix-gcps-64-bit-member-variables.patch
new file mode 100644 (file)
index 0000000..3bffb73
--- /dev/null
@@ -0,0 +1,161 @@
+From 9ef5779399c677ef8e6782d5b7ee58c824619348 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Apr 2025 18:23:08 -0700
+Subject: net: ncsi: Fix GCPS 64-bit member variables
+
+From: Hari Kalavakunta <kalavakunta.hari.prasad@gmail.com>
+
+[ Upstream commit e8a1bd8344054ce27bebf59f48e3f6bc10bc419b ]
+
+Correct Get Controller Packet Statistics (GCPS) 64-bit wide member
+variables, as per DSP0222 v1.0.0 and forward specs. The Driver currently
+collects these stats, but they are yet to be exposed to the user.
+Therefore, no user impact.
+
+Statistics fixes:
+Total Bytes Received (byte range 28..35)
+Total Bytes Transmitted (byte range 36..43)
+Total Unicast Packets Received (byte range 44..51)
+Total Multicast Packets Received (byte range 52..59)
+Total Broadcast Packets Received (byte range 60..67)
+Total Unicast Packets Transmitted (byte range 68..75)
+Total Multicast Packets Transmitted (byte range 76..83)
+Total Broadcast Packets Transmitted (byte range 84..91)
+Valid Bytes Received (byte range 204..11)
+
+Signed-off-by: Hari Kalavakunta <kalavakunta.hari.prasad@gmail.com>
+Reviewed-by: Paul Fertser <fercerpav@gmail.com>
+Link: https://patch.msgid.link/20250410012309.1343-1-kalavakunta.hari.prasad@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ncsi/internal.h | 21 ++++++++++-----------
+ net/ncsi/ncsi-pkt.h | 23 +++++++++++------------
+ net/ncsi/ncsi-rsp.c | 21 ++++++++++-----------
+ 3 files changed, 31 insertions(+), 34 deletions(-)
+
+diff --git a/net/ncsi/internal.h b/net/ncsi/internal.h
+index 4e0842df5234e..2c260f33b55cc 100644
+--- a/net/ncsi/internal.h
++++ b/net/ncsi/internal.h
+@@ -143,16 +143,15 @@ struct ncsi_channel_vlan_filter {
+ };
+ struct ncsi_channel_stats {
+-      u32 hnc_cnt_hi;         /* Counter cleared            */
+-      u32 hnc_cnt_lo;         /* Counter cleared            */
+-      u32 hnc_rx_bytes;       /* Rx bytes                   */
+-      u32 hnc_tx_bytes;       /* Tx bytes                   */
+-      u32 hnc_rx_uc_pkts;     /* Rx UC packets              */
+-      u32 hnc_rx_mc_pkts;     /* Rx MC packets              */
+-      u32 hnc_rx_bc_pkts;     /* Rx BC packets              */
+-      u32 hnc_tx_uc_pkts;     /* Tx UC packets              */
+-      u32 hnc_tx_mc_pkts;     /* Tx MC packets              */
+-      u32 hnc_tx_bc_pkts;     /* Tx BC packets              */
++      u64 hnc_cnt;            /* Counter cleared            */
++      u64 hnc_rx_bytes;       /* Rx bytes                   */
++      u64 hnc_tx_bytes;       /* Tx bytes                   */
++      u64 hnc_rx_uc_pkts;     /* Rx UC packets              */
++      u64 hnc_rx_mc_pkts;     /* Rx MC packets              */
++      u64 hnc_rx_bc_pkts;     /* Rx BC packets              */
++      u64 hnc_tx_uc_pkts;     /* Tx UC packets              */
++      u64 hnc_tx_mc_pkts;     /* Tx MC packets              */
++      u64 hnc_tx_bc_pkts;     /* Tx BC packets              */
+       u32 hnc_fcs_err;        /* FCS errors                 */
+       u32 hnc_align_err;      /* Alignment errors           */
+       u32 hnc_false_carrier;  /* False carrier detection    */
+@@ -181,7 +180,7 @@ struct ncsi_channel_stats {
+       u32 hnc_tx_1023_frames; /* Tx 512-1023 bytes frames   */
+       u32 hnc_tx_1522_frames; /* Tx 1024-1522 bytes frames  */
+       u32 hnc_tx_9022_frames; /* Tx 1523-9022 bytes frames  */
+-      u32 hnc_rx_valid_bytes; /* Rx valid bytes             */
++      u64 hnc_rx_valid_bytes; /* Rx valid bytes             */
+       u32 hnc_rx_runt_pkts;   /* Rx error runt packets      */
+       u32 hnc_rx_jabber_pkts; /* Rx error jabber packets    */
+       u32 ncsi_rx_cmds;       /* Rx NCSI commands           */
+diff --git a/net/ncsi/ncsi-pkt.h b/net/ncsi/ncsi-pkt.h
+index f2f3b5c1b9412..24edb27379724 100644
+--- a/net/ncsi/ncsi-pkt.h
++++ b/net/ncsi/ncsi-pkt.h
+@@ -252,16 +252,15 @@ struct ncsi_rsp_gp_pkt {
+ /* Get Controller Packet Statistics */
+ struct ncsi_rsp_gcps_pkt {
+       struct ncsi_rsp_pkt_hdr rsp;            /* Response header            */
+-      __be32                  cnt_hi;         /* Counter cleared            */
+-      __be32                  cnt_lo;         /* Counter cleared            */
+-      __be32                  rx_bytes;       /* Rx bytes                   */
+-      __be32                  tx_bytes;       /* Tx bytes                   */
+-      __be32                  rx_uc_pkts;     /* Rx UC packets              */
+-      __be32                  rx_mc_pkts;     /* Rx MC packets              */
+-      __be32                  rx_bc_pkts;     /* Rx BC packets              */
+-      __be32                  tx_uc_pkts;     /* Tx UC packets              */
+-      __be32                  tx_mc_pkts;     /* Tx MC packets              */
+-      __be32                  tx_bc_pkts;     /* Tx BC packets              */
++      __be64                  cnt;            /* Counter cleared            */
++      __be64                  rx_bytes;       /* Rx bytes                   */
++      __be64                  tx_bytes;       /* Tx bytes                   */
++      __be64                  rx_uc_pkts;     /* Rx UC packets              */
++      __be64                  rx_mc_pkts;     /* Rx MC packets              */
++      __be64                  rx_bc_pkts;     /* Rx BC packets              */
++      __be64                  tx_uc_pkts;     /* Tx UC packets              */
++      __be64                  tx_mc_pkts;     /* Tx MC packets              */
++      __be64                  tx_bc_pkts;     /* Tx BC packets              */
+       __be32                  fcs_err;        /* FCS errors                 */
+       __be32                  align_err;      /* Alignment errors           */
+       __be32                  false_carrier;  /* False carrier detection    */
+@@ -290,11 +289,11 @@ struct ncsi_rsp_gcps_pkt {
+       __be32                  tx_1023_frames; /* Tx 512-1023 bytes frames   */
+       __be32                  tx_1522_frames; /* Tx 1024-1522 bytes frames  */
+       __be32                  tx_9022_frames; /* Tx 1523-9022 bytes frames  */
+-      __be32                  rx_valid_bytes; /* Rx valid bytes             */
++      __be64                  rx_valid_bytes; /* Rx valid bytes             */
+       __be32                  rx_runt_pkts;   /* Rx error runt packets      */
+       __be32                  rx_jabber_pkts; /* Rx error jabber packets    */
+       __be32                  checksum;       /* Checksum                   */
+-};
++}  __packed __aligned(4);
+ /* Get NCSI Statistics */
+ struct ncsi_rsp_gns_pkt {
+diff --git a/net/ncsi/ncsi-rsp.c b/net/ncsi/ncsi-rsp.c
+index 4a8ce2949faea..8668888c5a2f9 100644
+--- a/net/ncsi/ncsi-rsp.c
++++ b/net/ncsi/ncsi-rsp.c
+@@ -926,16 +926,15 @@ static int ncsi_rsp_handler_gcps(struct ncsi_request *nr)
+       /* Update HNC's statistics */
+       ncs = &nc->stats;
+-      ncs->hnc_cnt_hi         = ntohl(rsp->cnt_hi);
+-      ncs->hnc_cnt_lo         = ntohl(rsp->cnt_lo);
+-      ncs->hnc_rx_bytes       = ntohl(rsp->rx_bytes);
+-      ncs->hnc_tx_bytes       = ntohl(rsp->tx_bytes);
+-      ncs->hnc_rx_uc_pkts     = ntohl(rsp->rx_uc_pkts);
+-      ncs->hnc_rx_mc_pkts     = ntohl(rsp->rx_mc_pkts);
+-      ncs->hnc_rx_bc_pkts     = ntohl(rsp->rx_bc_pkts);
+-      ncs->hnc_tx_uc_pkts     = ntohl(rsp->tx_uc_pkts);
+-      ncs->hnc_tx_mc_pkts     = ntohl(rsp->tx_mc_pkts);
+-      ncs->hnc_tx_bc_pkts     = ntohl(rsp->tx_bc_pkts);
++      ncs->hnc_cnt            = be64_to_cpu(rsp->cnt);
++      ncs->hnc_rx_bytes       = be64_to_cpu(rsp->rx_bytes);
++      ncs->hnc_tx_bytes       = be64_to_cpu(rsp->tx_bytes);
++      ncs->hnc_rx_uc_pkts     = be64_to_cpu(rsp->rx_uc_pkts);
++      ncs->hnc_rx_mc_pkts     = be64_to_cpu(rsp->rx_mc_pkts);
++      ncs->hnc_rx_bc_pkts     = be64_to_cpu(rsp->rx_bc_pkts);
++      ncs->hnc_tx_uc_pkts     = be64_to_cpu(rsp->tx_uc_pkts);
++      ncs->hnc_tx_mc_pkts     = be64_to_cpu(rsp->tx_mc_pkts);
++      ncs->hnc_tx_bc_pkts     = be64_to_cpu(rsp->tx_bc_pkts);
+       ncs->hnc_fcs_err        = ntohl(rsp->fcs_err);
+       ncs->hnc_align_err      = ntohl(rsp->align_err);
+       ncs->hnc_false_carrier  = ntohl(rsp->false_carrier);
+@@ -964,7 +963,7 @@ static int ncsi_rsp_handler_gcps(struct ncsi_request *nr)
+       ncs->hnc_tx_1023_frames = ntohl(rsp->tx_1023_frames);
+       ncs->hnc_tx_1522_frames = ntohl(rsp->tx_1522_frames);
+       ncs->hnc_tx_9022_frames = ntohl(rsp->tx_9022_frames);
+-      ncs->hnc_rx_valid_bytes = ntohl(rsp->rx_valid_bytes);
++      ncs->hnc_rx_valid_bytes = be64_to_cpu(rsp->rx_valid_bytes);
+       ncs->hnc_rx_runt_pkts   = ntohl(rsp->rx_runt_pkts);
+       ncs->hnc_rx_jabber_pkts = ntohl(rsp->rx_jabber_pkts);
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-openvswitch-fix-the-dead-loop-of-mpls-parse.patch b/queue-6.15/net-openvswitch-fix-the-dead-loop-of-mpls-parse.patch
new file mode 100644 (file)
index 0000000..5301ff9
--- /dev/null
@@ -0,0 +1,75 @@
+From 4577ff7f5567285a3104cb7636bc3de2a72db35a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 May 2025 03:41:43 +0000
+Subject: net: openvswitch: Fix the dead loop of MPLS parse
+
+From: Faicker Mo <faicker.mo@zenlayer.com>
+
+[ Upstream commit 0bdc924bfb319fb10d1113cbf091fc26fb7b1f99 ]
+
+The unexpected MPLS packet may not end with the bottom label stack.
+When there are many stacks, The label count value has wrapped around.
+A dead loop occurs, soft lockup/CPU stuck finally.
+
+stack backtrace:
+UBSAN: array-index-out-of-bounds in /build/linux-0Pa0xK/linux-5.15.0/net/openvswitch/flow.c:662:26
+index -1 is out of range for type '__be32 [3]'
+CPU: 34 PID: 0 Comm: swapper/34 Kdump: loaded Tainted: G           OE   5.15.0-121-generic #131-Ubuntu
+Hardware name: Dell Inc. PowerEdge C6420/0JP9TF, BIOS 2.12.2 07/14/2021
+Call Trace:
+ <IRQ>
+ show_stack+0x52/0x5c
+ dump_stack_lvl+0x4a/0x63
+ dump_stack+0x10/0x16
+ ubsan_epilogue+0x9/0x36
+ __ubsan_handle_out_of_bounds.cold+0x44/0x49
+ key_extract_l3l4+0x82a/0x840 [openvswitch]
+ ? kfree_skbmem+0x52/0xa0
+ key_extract+0x9c/0x2b0 [openvswitch]
+ ovs_flow_key_extract+0x124/0x350 [openvswitch]
+ ovs_vport_receive+0x61/0xd0 [openvswitch]
+ ? kernel_init_free_pages.part.0+0x4a/0x70
+ ? get_page_from_freelist+0x353/0x540
+ netdev_port_receive+0xc4/0x180 [openvswitch]
+ ? netdev_port_receive+0x180/0x180 [openvswitch]
+ netdev_frame_hook+0x1f/0x40 [openvswitch]
+ __netif_receive_skb_core.constprop.0+0x23a/0xf00
+ __netif_receive_skb_list_core+0xfa/0x240
+ netif_receive_skb_list_internal+0x18e/0x2a0
+ napi_complete_done+0x7a/0x1c0
+ bnxt_poll+0x155/0x1c0 [bnxt_en]
+ __napi_poll+0x30/0x180
+ net_rx_action+0x126/0x280
+ ? bnxt_msix+0x67/0x80 [bnxt_en]
+ handle_softirqs+0xda/0x2d0
+ irq_exit_rcu+0x96/0xc0
+ common_interrupt+0x8e/0xa0
+ </IRQ>
+
+Fixes: fbdcdd78da7c ("Change in Openvswitch to support MPLS label depth of 3 in ingress direction")
+Signed-off-by: Faicker Mo <faicker.mo@zenlayer.com>
+Acked-by: Ilya Maximets <i.maximets@ovn.org>
+Reviewed-by: Aaron Conole <aconole@redhat.com>
+Link: https://patch.msgid.link/259D3404-575D-4A6D-B263-1DF59A67CF89@zenlayer.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/openvswitch/flow.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
+index 8a848ce72e291..b80bd3a907739 100644
+--- a/net/openvswitch/flow.c
++++ b/net/openvswitch/flow.c
+@@ -788,7 +788,7 @@ static int key_extract_l3l4(struct sk_buff *skb, struct sw_flow_key *key)
+                       memset(&key->ipv4, 0, sizeof(key->ipv4));
+               }
+       } else if (eth_p_mpls(key->eth.type)) {
+-              u8 label_count = 1;
++              size_t label_count = 1;
+               memset(&key->mpls, 0, sizeof(key->mpls));
+               skb_set_inner_network_header(skb, skb->mac_len);
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-phy-clear-phydev-devlink-when-the-link-is-delete.patch b/queue-6.15/net-phy-clear-phydev-devlink-when-the-link-is-delete.patch
new file mode 100644 (file)
index 0000000..d5a9fb1
--- /dev/null
@@ -0,0 +1,61 @@
+From ea59a7d9bdfe61be263cdee51bca6aa0907c62f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 May 2025 16:37:59 +0800
+Subject: net: phy: clear phydev->devlink when the link is deleted
+
+From: Wei Fang <wei.fang@nxp.com>
+
+[ Upstream commit 0795b05a59b1371b18ffbf09d385296b12e9f5d5 ]
+
+There is a potential crash issue when disabling and re-enabling the
+network port. When disabling the network port, phy_detach() calls
+device_link_del() to remove the device link, but it does not clear
+phydev->devlink, so phydev->devlink is not a NULL pointer. Then the
+network port is re-enabled, but if phy_attach_direct() fails before
+calling device_link_add(), the code jumps to the "error" label and
+calls phy_detach(). Since phydev->devlink retains the old value from
+the previous attach/detach cycle, device_link_del() uses the old value,
+which accesses a NULL pointer and causes a crash. The simplified crash
+log is as follows.
+
+[   24.702421] Call trace:
+[   24.704856]  device_link_put_kref+0x20/0x120
+[   24.709124]  device_link_del+0x30/0x48
+[   24.712864]  phy_detach+0x24/0x168
+[   24.716261]  phy_attach_direct+0x168/0x3a4
+[   24.720352]  phylink_fwnode_phy_connect+0xc8/0x14c
+[   24.725140]  phylink_of_phy_connect+0x1c/0x34
+
+Therefore, phydev->devlink needs to be cleared when the device link is
+deleted.
+
+Fixes: bc66fa87d4fd ("net: phy: Add link between phy dev and mac dev")
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Link: https://patch.msgid.link/20250523083759.3741168-1-wei.fang@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/phy_device.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
+index cc1bfd22fb812..7d5e76a3db0e9 100644
+--- a/drivers/net/phy/phy_device.c
++++ b/drivers/net/phy/phy_device.c
+@@ -1727,8 +1727,10 @@ void phy_detach(struct phy_device *phydev)
+       struct module *ndev_owner = NULL;
+       struct mii_bus *bus;
+-      if (phydev->devlink)
++      if (phydev->devlink) {
+               device_link_del(phydev->devlink);
++              phydev->devlink = NULL;
++      }
+       if (phydev->sysfs_links) {
+               if (dev)
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-phy-fix-up-const-issues-in-to_mdio_device-and-to.patch b/queue-6.15/net-phy-fix-up-const-issues-in-to_mdio_device-and-to.patch
new file mode 100644 (file)
index 0000000..322892d
--- /dev/null
@@ -0,0 +1,63 @@
+From 43f2e281a4b334b2aa73202bcbc4eaf7fdb14bc9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 May 2025 13:21:47 +0200
+Subject: net: phy: fix up const issues in to_mdio_device() and to_phy_device()
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+[ Upstream commit e9cb929670a1e98b592b30f03f06e9e20110f318 ]
+
+Both to_mdio_device() and to_phy_device() "throw away" the const pointer
+attribute passed to them and return a non-const pointer, which generally
+is not a good thing overall.  Fix this up by using container_of_const()
+which was designed for this very problem.
+
+Cc: Alexander Lobakin <alobakin@pm.me>
+Cc: Andrew Lunn <andrew@lunn.ch>
+Cc: Heiner Kallweit <hkallweit1@gmail.com>
+Cc: Russell King <linux@armlinux.org.uk>
+Fixes: 7eab14de73a8 ("mdio, phy: fix -Wshadow warnings triggered by nested container_of()")
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Link: https://patch.msgid.link/2025052246-conduit-glory-8fc9@gregkh
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/mdio.h | 5 +----
+ include/linux/phy.h  | 5 +----
+ 2 files changed, 2 insertions(+), 8 deletions(-)
+
+diff --git a/include/linux/mdio.h b/include/linux/mdio.h
+index 3c3deac57894e..e43ff9f980a46 100644
+--- a/include/linux/mdio.h
++++ b/include/linux/mdio.h
+@@ -45,10 +45,7 @@ struct mdio_device {
+       unsigned int reset_deassert_delay;
+ };
+-static inline struct mdio_device *to_mdio_device(const struct device *dev)
+-{
+-      return container_of(dev, struct mdio_device, dev);
+-}
++#define to_mdio_device(__dev) container_of_const(__dev, struct mdio_device, dev)
+ /* struct mdio_driver_common: Common to all MDIO drivers */
+ struct mdio_driver_common {
+diff --git a/include/linux/phy.h b/include/linux/phy.h
+index a2bfae80c4497..bef68f6af99a9 100644
+--- a/include/linux/phy.h
++++ b/include/linux/phy.h
+@@ -744,10 +744,7 @@ struct phy_device {
+ #define PHY_F_NO_IRQ          0x80000000
+ #define PHY_F_RXC_ALWAYS_ON   0x40000000
+-static inline struct phy_device *to_phy_device(const struct device *dev)
+-{
+-      return container_of(to_mdio_device(dev), struct phy_device, mdio);
+-}
++#define to_phy_device(__dev)  container_of_const(to_mdio_device(__dev), struct phy_device, mdio)
+ /**
+  * struct phy_tdr_config - Configuration of a TDR raw test
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-phy-mediatek-permit-to-compile-test-ge-soc-phy-d.patch b/queue-6.15/net-phy-mediatek-permit-to-compile-test-ge-soc-phy-d.patch
new file mode 100644 (file)
index 0000000..05a0247
--- /dev/null
@@ -0,0 +1,47 @@
+From 7a99305c0c7d0db5ab2f8ce1cb3be23acdf80d06 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Apr 2025 12:04:03 +0200
+Subject: net: phy: mediatek: permit to compile test GE SOC PHY driver
+
+From: Christian Marangi <ansuelsmth@gmail.com>
+
+[ Upstream commit e5566162af8b9690e096d2e6089e4ed955a0d13d ]
+
+When commit 462a3daad679 ("net: phy: mediatek: fix compile-test
+dependencies") fixed the dependency, it should have also introduced
+an or on COMPILE_TEST to permit this driver to be compile-tested even if
+NVMEM_MTK_EFUSE wasn't selected. The driver makes use of NVMEM API that
+are always compiled (return error) so the driver can actually be
+compiled even without that config.
+
+Fix and simplify the dependency condition of this kernel config.
+
+Fixes: 462a3daad679 ("net: phy: mediatek: fix compile-test dependencies")
+Acked-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+Acked-by: Arnd Bergmann <arnd@arndb.de>
+Link: https://patch.msgid.link/20250410100410.348-1-ansuelsmth@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/mediatek/Kconfig | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/net/phy/mediatek/Kconfig b/drivers/net/phy/mediatek/Kconfig
+index 2a8ac5aed0f89..6a4c2b328c418 100644
+--- a/drivers/net/phy/mediatek/Kconfig
++++ b/drivers/net/phy/mediatek/Kconfig
+@@ -15,8 +15,7 @@ config MEDIATEK_GE_PHY
+ config MEDIATEK_GE_SOC_PHY
+       tristate "MediaTek SoC Ethernet PHYs"
+-      depends on (ARM64 && ARCH_MEDIATEK) || COMPILE_TEST
+-      depends on NVMEM_MTK_EFUSE
++      depends on (ARM64 && ARCH_MEDIATEK && NVMEM_MTK_EFUSE) || COMPILE_TEST
+       select MTK_NET_PHYLIB
+       help
+         Supports MediaTek SoC built-in Gigabit Ethernet PHYs.
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-phy-mscc-fix-memory-leak-when-using-one-step-tim.patch b/queue-6.15/net-phy-mscc-fix-memory-leak-when-using-one-step-tim.patch
new file mode 100644 (file)
index 0000000..81c3572
--- /dev/null
@@ -0,0 +1,62 @@
+From 177295a0d27b41e55d081f7c1c9340a9f3f851c4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 May 2025 13:57:22 +0200
+Subject: net: phy: mscc: Fix memory leak when using one step timestamping
+
+From: Horatiu Vultur <horatiu.vultur@microchip.com>
+
+[ Upstream commit 846992645b25ec4253167e3f931e4597eb84af56 ]
+
+Fix memory leak when running one-step timestamping. When running
+one-step sync timestamping, the HW is configured to insert the TX time
+into the frame, so there is no reason to keep the skb anymore. As in
+this case the HW will never generate an interrupt to say that the frame
+was timestamped, then the frame will never released.
+Fix this by freeing the frame in case of one-step timestamping.
+
+Fixes: 7d272e63e0979d ("net: phy: mscc: timestamping and PHC support")
+Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Link: https://patch.msgid.link/20250522115722.2827199-1-horatiu.vultur@microchip.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/mscc/mscc_ptp.c | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/phy/mscc/mscc_ptp.c b/drivers/net/phy/mscc/mscc_ptp.c
+index ed8fb14a7f215..6f96f2679f0bf 100644
+--- a/drivers/net/phy/mscc/mscc_ptp.c
++++ b/drivers/net/phy/mscc/mscc_ptp.c
+@@ -1166,18 +1166,24 @@ static void vsc85xx_txtstamp(struct mii_timestamper *mii_ts,
+               container_of(mii_ts, struct vsc8531_private, mii_ts);
+       if (!vsc8531->ptp->configured)
+-              return;
++              goto out;
+-      if (vsc8531->ptp->tx_type == HWTSTAMP_TX_OFF) {
+-              kfree_skb(skb);
+-              return;
+-      }
++      if (vsc8531->ptp->tx_type == HWTSTAMP_TX_OFF)
++              goto out;
++
++      if (vsc8531->ptp->tx_type == HWTSTAMP_TX_ONESTEP_SYNC)
++              if (ptp_msg_is_sync(skb, type))
++                      goto out;
+       skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
+       mutex_lock(&vsc8531->ts_lock);
+       __skb_queue_tail(&vsc8531->ptp->tx_queue, skb);
+       mutex_unlock(&vsc8531->ts_lock);
++      return;
++
++out:
++      kfree_skb(skb);
+ }
+ static bool vsc85xx_rxtstamp(struct mii_timestamper *mii_ts,
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-phy-mscc-stop-clearing-the-the-udpv4-checksum-fo.patch b/queue-6.15/net-phy-mscc-stop-clearing-the-the-udpv4-checksum-fo.patch
new file mode 100644 (file)
index 0000000..1292d9c
--- /dev/null
@@ -0,0 +1,47 @@
+From 227086760c1bcf728b6b7fad80905832557b0334 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 May 2025 10:27:16 +0200
+Subject: net: phy: mscc: Stop clearing the the UDPv4 checksum for L2 frames
+
+From: Horatiu Vultur <horatiu.vultur@microchip.com>
+
+[ Upstream commit 57a92d14659df3e7e7e0052358c8cc68bbbc3b5e ]
+
+We have noticed that when PHY timestamping is enabled, L2 frames seems
+to be modified by changing two 2 bytes with a value of 0. The place were
+these 2 bytes seems to be random(or I couldn't find a pattern).  In most
+of the cases the userspace can ignore these frames but if for example
+those 2 bytes are in the correction field there is nothing to do.  This
+seems to happen when configuring the HW for IPv4 even that the flow is
+not enabled.
+These 2 bytes correspond to the UDPv4 checksum and once we don't enable
+clearing the checksum when using L2 frames then the frame doesn't seem
+to be changed anymore.
+
+Fixes: 7d272e63e0979d ("net: phy: mscc: timestamping and PHC support")
+Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Link: https://patch.msgid.link/20250523082716.2935895-1-horatiu.vultur@microchip.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/mscc/mscc_ptp.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/phy/mscc/mscc_ptp.c b/drivers/net/phy/mscc/mscc_ptp.c
+index 6f96f2679f0bf..6b800081eed52 100644
+--- a/drivers/net/phy/mscc/mscc_ptp.c
++++ b/drivers/net/phy/mscc/mscc_ptp.c
+@@ -946,7 +946,9 @@ static int vsc85xx_ip1_conf(struct phy_device *phydev, enum ts_blk blk,
+       /* UDP checksum offset in IPv4 packet
+        * according to: https://tools.ietf.org/html/rfc768
+        */
+-      val |= IP1_NXT_PROT_UDP_CHKSUM_OFF(26) | IP1_NXT_PROT_UDP_CHKSUM_CLEAR;
++      val |= IP1_NXT_PROT_UDP_CHKSUM_OFF(26);
++      if (enable)
++              val |= IP1_NXT_PROT_UDP_CHKSUM_CLEAR;
+       vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_IP1_NXT_PROT_UDP_CHKSUM,
+                            val);
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-prevent-a-null-deref-in-rtnl_create_link.patch b/queue-6.15/net-prevent-a-null-deref-in-rtnl_create_link.patch
new file mode 100644 (file)
index 0000000..b6e1965
--- /dev/null
@@ -0,0 +1,59 @@
+From 470aa3cdf28343b2ab67c50b7eb3d264148d211e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Jun 2025 10:58:15 +0000
+Subject: net: prevent a NULL deref in rtnl_create_link()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit feafc73f3e6ae73371777a037d41d2e31c929636 ]
+
+At the time rtnl_create_link() is running, dev->netdev_ops is NULL,
+we must not use netdev_lock_ops() or risk a NULL deref if
+CONFIG_NET_SHAPER is defined.
+
+Use netif_set_group() instead of dev_set_group().
+
+ RIP: 0010:netdev_need_ops_lock include/net/netdev_lock.h:33 [inline]
+ RIP: 0010:netdev_lock_ops include/net/netdev_lock.h:41 [inline]
+ RIP: 0010:dev_set_group+0xc0/0x230 net/core/dev_api.c:82
+Call Trace:
+ <TASK>
+  rtnl_create_link+0x748/0xd10 net/core/rtnetlink.c:3674
+  rtnl_newlink_create+0x25c/0xb00 net/core/rtnetlink.c:3813
+  __rtnl_newlink net/core/rtnetlink.c:3940 [inline]
+  rtnl_newlink+0x16d6/0x1c70 net/core/rtnetlink.c:4055
+  rtnetlink_rcv_msg+0x7cf/0xb70 net/core/rtnetlink.c:6944
+  netlink_rcv_skb+0x208/0x470 net/netlink/af_netlink.c:2534
+  netlink_unicast_kernel net/netlink/af_netlink.c:1313 [inline]
+  netlink_unicast+0x75b/0x8d0 net/netlink/af_netlink.c:1339
+  netlink_sendmsg+0x805/0xb30 net/netlink/af_netlink.c:1883
+  sock_sendmsg_nosec net/socket.c:712 [inline]
+
+Reported-by: syzbot+9fc858ba0312b42b577e@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/6840265f.a00a0220.d4325.0009.GAE@google.com/T/#u
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Fixes: 7e4d784f5810 ("net: hold netdev instance lock during rtnetlink operations")
+Acked-by: Stanislav Fomichev <sdf@fomichev.me>
+Link: https://patch.msgid.link/20250604105815.1516973-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/rtnetlink.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
+index c5a7f41982a57..fc6815ad78266 100644
+--- a/net/core/rtnetlink.c
++++ b/net/core/rtnetlink.c
+@@ -3681,7 +3681,7 @@ struct net_device *rtnl_create_link(struct net *net, const char *ifname,
+       if (tb[IFLA_LINKMODE])
+               dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]);
+       if (tb[IFLA_GROUP])
+-              dev_set_group(dev, nla_get_u32(tb[IFLA_GROUP]));
++              netif_set_group(dev, nla_get_u32(tb[IFLA_GROUP]));
+       if (tb[IFLA_GSO_MAX_SIZE])
+               netif_set_gso_max_size(dev, nla_get_u32(tb[IFLA_GSO_MAX_SIZE]));
+       if (tb[IFLA_GSO_MAX_SEGS])
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-stmmac-make-sure-that-ptp_rate-is-not-0-before-c.patch b/queue-6.15/net-stmmac-make-sure-that-ptp_rate-is-not-0-before-c.patch
new file mode 100644 (file)
index 0000000..2f46802
--- /dev/null
@@ -0,0 +1,88 @@
+From 035a21420a8e8d9ab180ad09ef5a7e0b3df46d86 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 May 2025 11:07:23 +0200
+Subject: net: stmmac: make sure that ptp_rate is not 0 before configuring
+ timestamping
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Alexis Lothoré <alexis.lothore@bootlin.com>
+
+[ Upstream commit 030ce919e114a111e83b7976ecb3597cefd33f26 ]
+
+The stmmac platform drivers that do not open-code the clk_ptp_rate value
+after having retrieved the default one from the device-tree can end up
+with 0 in clk_ptp_rate (as clk_get_rate can return 0). It will
+eventually propagate up to PTP initialization when bringing up the
+interface, leading to a divide by 0:
+
+ Division by zero in kernel.
+ CPU: 1 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.12.30-00001-g48313bd5768a #22
+ Hardware name: STM32 (Device Tree Support)
+ Call trace:
+  unwind_backtrace from show_stack+0x18/0x1c
+  show_stack from dump_stack_lvl+0x6c/0x8c
+  dump_stack_lvl from Ldiv0_64+0x8/0x18
+  Ldiv0_64 from stmmac_init_tstamp_counter+0x190/0x1a4
+  stmmac_init_tstamp_counter from stmmac_hw_setup+0xc1c/0x111c
+  stmmac_hw_setup from __stmmac_open+0x18c/0x434
+  __stmmac_open from stmmac_open+0x3c/0xbc
+  stmmac_open from __dev_open+0xf4/0x1ac
+  __dev_open from __dev_change_flags+0x1cc/0x224
+  __dev_change_flags from dev_change_flags+0x24/0x60
+  dev_change_flags from ip_auto_config+0x2e8/0x11a0
+  ip_auto_config from do_one_initcall+0x84/0x33c
+  do_one_initcall from kernel_init_freeable+0x1b8/0x214
+  kernel_init_freeable from kernel_init+0x24/0x140
+  kernel_init from ret_from_fork+0x14/0x28
+ Exception stack(0xe0815fb0 to 0xe0815ff8)
+
+Prevent this division by 0 by adding an explicit check and error log
+about the actual issue. While at it, remove the same check from
+stmmac_ptp_register, which then becomes duplicate
+
+Fixes: 19d857c9038e ("stmmac: Fix calculations for ptp counters when clock input = 50Mhz.")
+Signed-off-by: Alexis Lothoré <alexis.lothore@bootlin.com>
+Reviewed-by: Yanteng Si <si.yanteng@linux.dev>
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20250529-stmmac_tstamp_div-v4-1-d73340a794d5@bootlin.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 5 +++++
+ drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c  | 2 +-
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index 59d07d0d3369d..3a049a158ea11 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -803,6 +803,11 @@ int stmmac_init_tstamp_counter(struct stmmac_priv *priv, u32 systime_flags)
+       if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp))
+               return -EOPNOTSUPP;
++      if (!priv->plat->clk_ptp_rate) {
++              netdev_err(priv->dev, "Invalid PTP clock rate");
++              return -EINVAL;
++      }
++
+       stmmac_config_hw_tstamping(priv, priv->ptpaddr, systime_flags);
+       priv->systime_flags = systime_flags;
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
+index 429b2d357813c..3767ba495e78d 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
+@@ -317,7 +317,7 @@ void stmmac_ptp_register(struct stmmac_priv *priv)
+       /* Calculate the clock domain crossing (CDC) error if necessary */
+       priv->plat->cdc_error_adj = 0;
+-      if (priv->plat->has_gmac4 && priv->plat->clk_ptp_rate)
++      if (priv->plat->has_gmac4)
+               priv->plat->cdc_error_adj = (2 * NSEC_PER_SEC) / priv->plat->clk_ptp_rate;
+       /* Update the ptp clock parameters based on feature discovery, when
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-stmmac-make-sure-that-ptp_rate-is-not-0-before-c.patch-22075 b/queue-6.15/net-stmmac-make-sure-that-ptp_rate-is-not-0-before-c.patch-22075
new file mode 100644 (file)
index 0000000..73799cb
--- /dev/null
@@ -0,0 +1,48 @@
+From 1fe0580056244910fdc6f61cbdca58c1081966f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 May 2025 11:07:24 +0200
+Subject: net: stmmac: make sure that ptp_rate is not 0 before configuring EST
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Alexis Lothoré <alexis.lothore@bootlin.com>
+
+[ Upstream commit cbefe2ffa7784525ec5d008ba87c7add19ec631a ]
+
+If the ptp_rate recorded earlier in the driver happens to be 0, this
+bogus value will propagate up to EST configuration, where it will
+trigger a division by 0.
+
+Prevent this division by 0 by adding the corresponding check and error
+code.
+
+Suggested-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Signed-off-by: Alexis Lothoré <alexis.lothore@bootlin.com>
+Fixes: 8572aec3d0dc ("net: stmmac: Add basic EST support for XGMAC")
+Link: https://patch.msgid.link/20250529-stmmac_tstamp_div-v4-2-d73340a794d5@bootlin.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_est.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_est.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_est.c
+index c9693f77e1f61..ac6f2e3a3fcd2 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_est.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_est.c
+@@ -32,6 +32,11 @@ static int est_configure(struct stmmac_priv *priv, struct stmmac_est *cfg,
+       int i, ret = 0;
+       u32 ctrl;
++      if (!ptp_rate) {
++              netdev_warn(priv->dev, "Invalid PTP rate");
++              return -EINVAL;
++      }
++
+       ret |= est_write(est_addr, EST_BTR_LOW, cfg->btr[0], false);
+       ret |= est_write(est_addr, EST_BTR_HIGH, cfg->btr[1], false);
+       ret |= est_write(est_addr, EST_TER, cfg->ter, false);
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-stmmac-platform-guarantee-uniqueness-of-bus_id.patch b/queue-6.15/net-stmmac-platform-guarantee-uniqueness-of-bus_id.patch
new file mode 100644 (file)
index 0000000..3755ac7
--- /dev/null
@@ -0,0 +1,68 @@
+From 7c0831c04f3d568bfe2fe8c4d9c32a91b6a80627 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 May 2025 13:56:23 +0200
+Subject: net: stmmac: platform: guarantee uniqueness of bus_id
+
+From: Quentin Schulz <quentin.schulz@cherry.de>
+
+[ Upstream commit eb7fd7aa35bfcc1e1fda4ecc42ccfcb526cdc780 ]
+
+bus_id is currently derived from the ethernetX alias. If one is missing
+for the device, 0 is used. If ethernet0 points to another stmmac device
+or if there are 2+ stmmac devices without an ethernet alias, then bus_id
+will be 0 for all of those.
+
+This is an issue because the bus_id is used to generate the mdio bus id
+(new_bus->id in drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+stmmac_mdio_register) and this needs to be unique.
+
+This allows to avoid needing to define ethernet aliases for devices with
+multiple stmmac controllers (such as the Rockchip RK3588) for multiple
+stmmac devices to probe properly.
+
+Obviously, the bus_id isn't guaranteed to be stable across reboots if no
+alias is set for the device but that is easily fixed by simply adding an
+alias if this is desired.
+
+Fixes: 25c83b5c2e82 ("dt:net:stmmac: Add support to dwmac version 3.610 and 3.710")
+Signed-off-by: Quentin Schulz <quentin.schulz@cherry.de>
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20250527-stmmac-mdio-bus_id-v2-1-a5ca78454e3c@cherry.de
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+index c73eff6a56b87..15205a47cafc2 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+@@ -430,6 +430,7 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
+       struct device_node *np = pdev->dev.of_node;
+       struct plat_stmmacenet_data *plat;
+       struct stmmac_dma_cfg *dma_cfg;
++      static int bus_id = -ENODEV;
+       int phy_mode;
+       void *ret;
+       int rc;
+@@ -465,8 +466,14 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
+       of_property_read_u32(np, "max-speed", &plat->max_speed);
+       plat->bus_id = of_alias_get_id(np, "ethernet");
+-      if (plat->bus_id < 0)
+-              plat->bus_id = 0;
++      if (plat->bus_id < 0) {
++              if (bus_id < 0)
++                      bus_id = of_alias_get_highest_id("ethernet");
++              /* No ethernet alias found, init at -1 so first bus_id is 0 */
++              if (bus_id < 0)
++                      bus_id = -1;
++              plat->bus_id = ++bus_id;
++      }
+       /* Default to phy auto-detection */
+       plat->phy_addr = -1;
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-ti-icssg-prueth-fix-swapped-tx-stats-for-mii-int.patch b/queue-6.15/net-ti-icssg-prueth-fix-swapped-tx-stats-for-mii-int.patch
new file mode 100644 (file)
index 0000000..e37d20d
--- /dev/null
@@ -0,0 +1,47 @@
+From 29c82d2ffac8ff1c704e39bbe335bdc156b74d8a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Jun 2025 10:59:04 +0530
+Subject: net: ti: icssg-prueth: Fix swapped TX stats for MII interfaces.
+
+From: Meghana Malladi <m-malladi@ti.com>
+
+[ Upstream commit 919d763d609428c2680ec8159257d9655f002f89 ]
+
+In MII mode, Tx lines are swapped for port0 and port1, which means
+Tx port0 receives data from PRU1 and the Tx port1 receives data from
+PRU0. This is an expected hardware behavior and reading the Tx stats
+needs to be handled accordingly in the driver. Update the driver to
+read Tx stats from the PRU1 for port0 and PRU0 for port1.
+
+Fixes: c1e10d5dc7a1 ("net: ti: icssg-prueth: Add ICSSG Stats")
+Signed-off-by: Meghana Malladi <m-malladi@ti.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250603052904.431203-1-m-malladi@ti.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ti/icssg/icssg_stats.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/net/ethernet/ti/icssg/icssg_stats.c b/drivers/net/ethernet/ti/icssg/icssg_stats.c
+index 6f0edae38ea24..172ae38381b45 100644
+--- a/drivers/net/ethernet/ti/icssg/icssg_stats.c
++++ b/drivers/net/ethernet/ti/icssg/icssg_stats.c
+@@ -29,6 +29,14 @@ void emac_update_hardware_stats(struct prueth_emac *emac)
+       spin_lock(&prueth->stats_lock);
+       for (i = 0; i < ARRAY_SIZE(icssg_all_miig_stats); i++) {
++              /* In MII mode TX lines are swapped inside ICSSG, so read Tx stats
++               * from slice1 for port0 and slice0 for port1 to get accurate Tx
++               * stats for a given port
++               */
++              if (emac->phy_if == PHY_INTERFACE_MODE_MII &&
++                  icssg_all_miig_stats[i].offset >= ICSSG_TX_PACKET_OFFSET &&
++                  icssg_all_miig_stats[i].offset <= ICSSG_TX_BYTE_OFFSET)
++                      base = stats_base[slice ^ 1];
+               regmap_read(prueth->miig_rt,
+                           base + icssg_all_miig_stats[i].offset,
+                           &val);
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-tipc-fix-refcount-warning-in-tipc_aead_encrypt.patch b/queue-6.15/net-tipc-fix-refcount-warning-in-tipc_aead_encrypt.patch
new file mode 100644 (file)
index 0000000..57fdd06
--- /dev/null
@@ -0,0 +1,57 @@
+From 8392dbc56df0d08ef5fda4a14951cfad9e786acf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 May 2025 16:35:44 +0000
+Subject: net: tipc: fix refcount warning in tipc_aead_encrypt
+
+From: Charalampos Mitrodimas <charmitro@posteo.net>
+
+[ Upstream commit f29ccaa07cf3d35990f4d25028cc55470d29372b ]
+
+syzbot reported a refcount warning [1] caused by calling get_net() on
+a network namespace that is being destroyed (refcount=0). This happens
+when a TIPC discovery timer fires during network namespace cleanup.
+
+The recently added get_net() call in commit e279024617134 ("net/tipc:
+fix slab-use-after-free Read in tipc_aead_encrypt_done") attempts to
+hold a reference to the network namespace. However, if the namespace
+is already being destroyed, its refcount might be zero, leading to the
+use-after-free warning.
+
+Replace get_net() with maybe_get_net(), which safely checks if the
+refcount is non-zero before incrementing it. If the namespace is being
+destroyed, return -ENODEV early, after releasing the bearer reference.
+
+[1]: https://lore.kernel.org/all/68342b55.a70a0220.253bc2.0091.GAE@google.com/T/#m12019cf9ae77e1954f666914640efa36d52704a2
+
+Reported-by: syzbot+f0c4a4aba757549ae26c@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/all/68342b55.a70a0220.253bc2.0091.GAE@google.com/T/#m12019cf9ae77e1954f666914640efa36d52704a2
+Fixes: e27902461713 ("net/tipc: fix slab-use-after-free Read in tipc_aead_encrypt_done")
+Signed-off-by: Charalampos Mitrodimas <charmitro@posteo.net>
+Reviewed-by: Tung Nguyen <tung.quang.nguyen@est.tech>
+Link: https://patch.msgid.link/20250527-net-tipc-warning-v2-1-df3dc398a047@posteo.net
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tipc/crypto.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/net/tipc/crypto.c b/net/tipc/crypto.c
+index 8584893b47851..79f91b6ca8c84 100644
+--- a/net/tipc/crypto.c
++++ b/net/tipc/crypto.c
+@@ -818,7 +818,11 @@ static int tipc_aead_encrypt(struct tipc_aead *aead, struct sk_buff *skb,
+       }
+       /* Get net to avoid freed tipc_crypto when delete namespace */
+-      get_net(aead->crypto->net);
++      if (!maybe_get_net(aead->crypto->net)) {
++              tipc_bearer_put(b);
++              rc = -ENODEV;
++              goto exit;
++      }
+       /* Now, do encrypt */
+       rc = crypto_aead_encrypt(req);
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-usb-aqc111-fix-error-handling-of-usbnet-read-cal.patch b/queue-6.15/net-usb-aqc111-fix-error-handling-of-usbnet-read-cal.patch
new file mode 100644 (file)
index 0000000..9aa811f
--- /dev/null
@@ -0,0 +1,106 @@
+From 902510a272c079ee37fd307ee21eb112f7492843 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 May 2025 14:32:39 +0300
+Subject: net: usb: aqc111: fix error handling of usbnet read calls
+
+From: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+
+[ Upstream commit 405b0d610745fb5e84fc2961d9b960abb9f3d107 ]
+
+Syzkaller, courtesy of syzbot, identified an error (see report [1]) in
+aqc111 driver, caused by incomplete sanitation of usb read calls'
+results. This problem is quite similar to the one fixed in commit
+920a9fa27e78 ("net: asix: add proper error handling of usb read errors").
+
+For instance, usbnet_read_cmd() may read fewer than 'size' bytes,
+even if the caller expected the full amount, and aqc111_read_cmd()
+will not check its result properly. As [1] shows, this may lead
+to MAC address in aqc111_bind() being only partly initialized,
+triggering KMSAN warnings.
+
+Fix the issue by verifying that the number of bytes read is
+as expected and not less.
+
+[1] Partial syzbot report:
+BUG: KMSAN: uninit-value in is_valid_ether_addr include/linux/etherdevice.h:208 [inline]
+BUG: KMSAN: uninit-value in usbnet_probe+0x2e57/0x4390 drivers/net/usb/usbnet.c:1830
+ is_valid_ether_addr include/linux/etherdevice.h:208 [inline]
+ usbnet_probe+0x2e57/0x4390 drivers/net/usb/usbnet.c:1830
+ usb_probe_interface+0xd01/0x1310 drivers/usb/core/driver.c:396
+ call_driver_probe drivers/base/dd.c:-1 [inline]
+ really_probe+0x4d1/0xd90 drivers/base/dd.c:658
+ __driver_probe_device+0x268/0x380 drivers/base/dd.c:800
+...
+
+Uninit was stored to memory at:
+ dev_addr_mod+0xb0/0x550 net/core/dev_addr_lists.c:582
+ __dev_addr_set include/linux/netdevice.h:4874 [inline]
+ eth_hw_addr_set include/linux/etherdevice.h:325 [inline]
+ aqc111_bind+0x35f/0x1150 drivers/net/usb/aqc111.c:717
+ usbnet_probe+0xbe6/0x4390 drivers/net/usb/usbnet.c:1772
+ usb_probe_interface+0xd01/0x1310 drivers/usb/core/driver.c:396
+...
+
+Uninit was stored to memory at:
+ ether_addr_copy include/linux/etherdevice.h:305 [inline]
+ aqc111_read_perm_mac drivers/net/usb/aqc111.c:663 [inline]
+ aqc111_bind+0x794/0x1150 drivers/net/usb/aqc111.c:713
+ usbnet_probe+0xbe6/0x4390 drivers/net/usb/usbnet.c:1772
+ usb_probe_interface+0xd01/0x1310 drivers/usb/core/driver.c:396
+ call_driver_probe drivers/base/dd.c:-1 [inline]
+...
+
+Local variable buf.i created at:
+ aqc111_read_perm_mac drivers/net/usb/aqc111.c:656 [inline]
+ aqc111_bind+0x221/0x1150 drivers/net/usb/aqc111.c:713
+ usbnet_probe+0xbe6/0x4390 drivers/net/usb/usbnet.c:1772
+
+Reported-by: syzbot+3b6b9ff7b80430020c7b@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=3b6b9ff7b80430020c7b
+Tested-by: syzbot+3b6b9ff7b80430020c7b@syzkaller.appspotmail.com
+Fixes: df2d59a2ab6c ("net: usb: aqc111: Add support for getting and setting of MAC address")
+Signed-off-by: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+Link: https://patch.msgid.link/20250520113240.2369438-1-n.zhandarovich@fintech.ru
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/aqc111.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c
+index ff5be2cbf17b9..453a2cf82753f 100644
+--- a/drivers/net/usb/aqc111.c
++++ b/drivers/net/usb/aqc111.c
+@@ -30,10 +30,13 @@ static int aqc111_read_cmd_nopm(struct usbnet *dev, u8 cmd, u16 value,
+       ret = usbnet_read_cmd_nopm(dev, cmd, USB_DIR_IN | USB_TYPE_VENDOR |
+                                  USB_RECIP_DEVICE, value, index, data, size);
+-      if (unlikely(ret < 0))
++      if (unlikely(ret < size)) {
++              ret = ret < 0 ? ret : -ENODATA;
++
+               netdev_warn(dev->net,
+                           "Failed to read(0x%x) reg index 0x%04x: %d\n",
+                           cmd, index, ret);
++      }
+       return ret;
+ }
+@@ -46,10 +49,13 @@ static int aqc111_read_cmd(struct usbnet *dev, u8 cmd, u16 value,
+       ret = usbnet_read_cmd(dev, cmd, USB_DIR_IN | USB_TYPE_VENDOR |
+                             USB_RECIP_DEVICE, value, index, data, size);
+-      if (unlikely(ret < 0))
++      if (unlikely(ret < size)) {
++              ret = ret < 0 ? ret : -ENODATA;
++
+               netdev_warn(dev->net,
+                           "Failed to read(0x%x) reg index 0x%04x: %d\n",
+                           cmd, index, ret);
++      }
+       return ret;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-wwan-mhi_wwan_mbim-use-correct-mux_id-for-multip.patch b/queue-6.15/net-wwan-mhi_wwan_mbim-use-correct-mux_id-for-multip.patch
new file mode 100644 (file)
index 0000000..13679d2
--- /dev/null
@@ -0,0 +1,69 @@
+From 8f154fe53eae684e524764db2e09bf5c89962f0f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Jun 2025 11:12:04 +0200
+Subject: net: wwan: mhi_wwan_mbim: use correct mux_id for multiplexing
+
+From: Daniele Palmas <dnlplm@gmail.com>
+
+[ Upstream commit 501fe52aa908c96f2c9b8d54767938a1a5960354 ]
+
+Recent Qualcomm chipsets like SDX72/75 require MBIM sessionId mapping
+to muxId in the range (0x70-0x8F) for the PCIe tethered use.
+
+This has been partially addressed by the referenced commit, mapping
+the default data call to muxId = 112, but the multiplexed data calls
+scenario was not properly considered, mapping sessionId = 1 to muxId
+1, while it should have been 113.
+
+Fix this by moving the session_id assignment logic to mhi_mbim_newlink,
+in order to map sessionId = n to muxId = n + WDS_BIND_MUX_DATA_PORT_MUX_ID.
+
+Fixes: 65bc58c3dcad ("net: wwan: mhi: make default data link id configurable")
+Signed-off-by: Daniele Palmas <dnlplm@gmail.com>
+Reviewed-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
+Link: https://patch.msgid.link/20250603091204.2802840-1-dnlplm@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wwan/mhi_wwan_mbim.c | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/wwan/mhi_wwan_mbim.c b/drivers/net/wwan/mhi_wwan_mbim.c
+index 8755c5e6a65b3..c814fbd756a1e 100644
+--- a/drivers/net/wwan/mhi_wwan_mbim.c
++++ b/drivers/net/wwan/mhi_wwan_mbim.c
+@@ -550,8 +550,8 @@ static int mhi_mbim_newlink(void *ctxt, struct net_device *ndev, u32 if_id,
+       struct mhi_mbim_link *link = wwan_netdev_drvpriv(ndev);
+       struct mhi_mbim_context *mbim = ctxt;
+-      link->session = if_id;
+       link->mbim = mbim;
++      link->session = mhi_mbim_get_link_mux_id(link->mbim->mdev->mhi_cntrl) + if_id;
+       link->ndev = ndev;
+       u64_stats_init(&link->rx_syncp);
+       u64_stats_init(&link->tx_syncp);
+@@ -607,7 +607,7 @@ static int mhi_mbim_probe(struct mhi_device *mhi_dev, const struct mhi_device_id
+ {
+       struct mhi_controller *cntrl = mhi_dev->mhi_cntrl;
+       struct mhi_mbim_context *mbim;
+-      int err, link_id;
++      int err;
+       mbim = devm_kzalloc(&mhi_dev->dev, sizeof(*mbim), GFP_KERNEL);
+       if (!mbim)
+@@ -628,11 +628,8 @@ static int mhi_mbim_probe(struct mhi_device *mhi_dev, const struct mhi_device_id
+       /* Number of transfer descriptors determines size of the queue */
+       mbim->rx_queue_sz = mhi_get_free_desc_count(mhi_dev, DMA_FROM_DEVICE);
+-      /* Get the corresponding mux_id from mhi */
+-      link_id = mhi_mbim_get_link_mux_id(cntrl);
+-
+       /* Register wwan link ops with MHI controller representing WWAN instance */
+-      return wwan_register_ops(&cntrl->mhi_dev->dev, &mhi_mbim_wwan_ops, mbim, link_id);
++      return wwan_register_ops(&cntrl->mhi_dev->dev, &mhi_mbim_wwan_ops, mbim, 0);
+ }
+ static void mhi_mbim_remove(struct mhi_device *mhi_dev)
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-wwan-t7xx-fix-napi-rx-poll-issue.patch b/queue-6.15/net-wwan-t7xx-fix-napi-rx-poll-issue.patch
new file mode 100644 (file)
index 0000000..e1ec7ca
--- /dev/null
@@ -0,0 +1,103 @@
+From c8259261e1632df91c7f1662e0e47a0b3ce96c30 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 May 2025 11:16:48 +0800
+Subject: net: wwan: t7xx: Fix napi rx poll issue
+
+From: Jinjian Song <jinjian.song@fibocom.com>
+
+[ Upstream commit 905fe0845bb27e4eed2ca27ea06e6c4847f1b2b1 ]
+
+When driver handles the napi rx polling requests, the netdev might
+have been released by the dellink logic triggered by the disconnect
+operation on user plane. However, in the logic of processing skb in
+polling, an invalid netdev is still being used, which causes a panic.
+
+BUG: kernel NULL pointer dereference, address: 00000000000000f1
+Oops: 0000 [#1] PREEMPT SMP NOPTI
+RIP: 0010:dev_gro_receive+0x3a/0x620
+[...]
+Call Trace:
+ <IRQ>
+ ? __die_body+0x68/0xb0
+ ? page_fault_oops+0x379/0x3e0
+ ? exc_page_fault+0x4f/0xa0
+ ? asm_exc_page_fault+0x22/0x30
+ ? __pfx_t7xx_ccmni_recv_skb+0x10/0x10 [mtk_t7xx (HASH:1400 7)]
+ ? dev_gro_receive+0x3a/0x620
+ napi_gro_receive+0xad/0x170
+ t7xx_ccmni_recv_skb+0x48/0x70 [mtk_t7xx (HASH:1400 7)]
+ t7xx_dpmaif_napi_rx_poll+0x590/0x800 [mtk_t7xx (HASH:1400 7)]
+ net_rx_action+0x103/0x470
+ irq_exit_rcu+0x13a/0x310
+ sysvec_apic_timer_interrupt+0x56/0x90
+ </IRQ>
+
+Fixes: 5545b7b9f294 ("net: wwan: t7xx: Add NAPI support")
+Signed-off-by: Jinjian Song <jinjian.song@fibocom.com>
+Link: https://patch.msgid.link/20250530031648.5592-1-jinjian.song@fibocom.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wwan/t7xx/t7xx_netdev.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/wwan/t7xx/t7xx_netdev.c b/drivers/net/wwan/t7xx/t7xx_netdev.c
+index 91fa082e9cab8..fc0a7cb181df2 100644
+--- a/drivers/net/wwan/t7xx/t7xx_netdev.c
++++ b/drivers/net/wwan/t7xx/t7xx_netdev.c
+@@ -302,7 +302,7 @@ static int t7xx_ccmni_wwan_newlink(void *ctxt, struct net_device *dev, u32 if_id
+       ccmni->ctlb = ctlb;
+       ccmni->dev = dev;
+       atomic_set(&ccmni->usage, 0);
+-      ctlb->ccmni_inst[if_id] = ccmni;
++      WRITE_ONCE(ctlb->ccmni_inst[if_id], ccmni);
+       ret = register_netdevice(dev);
+       if (ret)
+@@ -324,6 +324,7 @@ static void t7xx_ccmni_wwan_dellink(void *ctxt, struct net_device *dev, struct l
+       if (WARN_ON(ctlb->ccmni_inst[if_id] != ccmni))
+               return;
++      WRITE_ONCE(ctlb->ccmni_inst[if_id], NULL);
+       unregister_netdevice(dev);
+ }
+@@ -419,7 +420,7 @@ static void t7xx_ccmni_recv_skb(struct t7xx_ccmni_ctrl *ccmni_ctlb, struct sk_bu
+       skb_cb = T7XX_SKB_CB(skb);
+       netif_id = skb_cb->netif_idx;
+-      ccmni = ccmni_ctlb->ccmni_inst[netif_id];
++      ccmni = READ_ONCE(ccmni_ctlb->ccmni_inst[netif_id]);
+       if (!ccmni) {
+               dev_kfree_skb(skb);
+               return;
+@@ -441,7 +442,7 @@ static void t7xx_ccmni_recv_skb(struct t7xx_ccmni_ctrl *ccmni_ctlb, struct sk_bu
+ static void t7xx_ccmni_queue_tx_irq_notify(struct t7xx_ccmni_ctrl *ctlb, int qno)
+ {
+-      struct t7xx_ccmni *ccmni = ctlb->ccmni_inst[0];
++      struct t7xx_ccmni *ccmni = READ_ONCE(ctlb->ccmni_inst[0]);
+       struct netdev_queue *net_queue;
+       if (netif_running(ccmni->dev) && atomic_read(&ccmni->usage) > 0) {
+@@ -453,7 +454,7 @@ static void t7xx_ccmni_queue_tx_irq_notify(struct t7xx_ccmni_ctrl *ctlb, int qno
+ static void t7xx_ccmni_queue_tx_full_notify(struct t7xx_ccmni_ctrl *ctlb, int qno)
+ {
+-      struct t7xx_ccmni *ccmni = ctlb->ccmni_inst[0];
++      struct t7xx_ccmni *ccmni = READ_ONCE(ctlb->ccmni_inst[0]);
+       struct netdev_queue *net_queue;
+       if (atomic_read(&ccmni->usage) > 0) {
+@@ -471,7 +472,7 @@ static void t7xx_ccmni_queue_state_notify(struct t7xx_pci_dev *t7xx_dev,
+       if (ctlb->md_sta != MD_STATE_READY)
+               return;
+-      if (!ctlb->ccmni_inst[0]) {
++      if (!READ_ONCE(ctlb->ccmni_inst[0])) {
+               dev_warn(&t7xx_dev->pdev->dev, "No netdev registered yet\n");
+               return;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/net-xilinx-axienet-fix-tx-skb-circular-buffer-occupa.patch b/queue-6.15/net-xilinx-axienet-fix-tx-skb-circular-buffer-occupa.patch
new file mode 100644 (file)
index 0000000..23df5ec
--- /dev/null
@@ -0,0 +1,60 @@
+From 125753dd83d37e9e6d2be5a03503e371a711bc83 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 May 2025 23:46:08 +0530
+Subject: net: xilinx: axienet: Fix Tx skb circular buffer occupancy check in
+ dmaengine xmit
+
+From: Suraj Gupta <suraj.gupta2@amd.com>
+
+[ Upstream commit 32374234ab0101881e7d0c6a8ef7ebce566c46c9 ]
+
+In Dmaengine flow, driver maintains struct skbuf_dma_descriptor rings each
+element of which corresponds to a skb. In Tx datapath, compare available
+space in skb ring with number of skbs instead of skb fragments.
+Replace x * (MAX_SKB_FRAGS) in netif_txq_completed_wake() and
+netif_txq_maybe_stop() with x * (1 skb) to fix the comparison.
+
+Fixes: 6a91b846af85 ("net: axienet: Introduce dmaengine support")
+Signed-off-by: Suraj Gupta <suraj.gupta2@amd.com>
+Reviewed-by: Sean Anderson <sean.anderson@linux.dev>
+Link: https://patch.msgid.link/20250521181608.669554-1-suraj.gupta2@amd.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+index 054abf283ab33..5f912b27bfd7f 100644
+--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+@@ -880,7 +880,7 @@ static void axienet_dma_tx_cb(void *data, const struct dmaengine_result *result)
+       dev_consume_skb_any(skbuf_dma->skb);
+       netif_txq_completed_wake(txq, 1, len,
+                                CIRC_SPACE(lp->tx_ring_head, lp->tx_ring_tail, TX_BD_NUM_MAX),
+-                               2 * MAX_SKB_FRAGS);
++                               2);
+ }
+ /**
+@@ -914,7 +914,7 @@ axienet_start_xmit_dmaengine(struct sk_buff *skb, struct net_device *ndev)
+       dma_dev = lp->tx_chan->device;
+       sg_len = skb_shinfo(skb)->nr_frags + 1;
+-      if (CIRC_SPACE(lp->tx_ring_head, lp->tx_ring_tail, TX_BD_NUM_MAX) <= sg_len) {
++      if (CIRC_SPACE(lp->tx_ring_head, lp->tx_ring_tail, TX_BD_NUM_MAX) <= 1) {
+               netif_stop_queue(ndev);
+               if (net_ratelimit())
+                       netdev_warn(ndev, "TX ring unexpectedly full\n");
+@@ -964,7 +964,7 @@ axienet_start_xmit_dmaengine(struct sk_buff *skb, struct net_device *ndev)
+       txq = skb_get_tx_queue(lp->ndev, skb);
+       netdev_tx_sent_queue(txq, skb->len);
+       netif_txq_maybe_stop(txq, CIRC_SPACE(lp->tx_ring_head, lp->tx_ring_tail, TX_BD_NUM_MAX),
+-                           MAX_SKB_FRAGS + 1, 2 * MAX_SKB_FRAGS);
++                           1, 2);
+       dmaengine_submit(dma_tx_desc);
+       dma_async_issue_pending(lp->tx_chan);
+-- 
+2.39.5
+
diff --git a/queue-6.15/netfilter-bridge-move-specific-fragmented-packet-to-.patch b/queue-6.15/netfilter-bridge-move-specific-fragmented-packet-to-.patch
new file mode 100644 (file)
index 0000000..8bd7f6e
--- /dev/null
@@ -0,0 +1,96 @@
+From 3d35e216a9f5b5d14a7b75d0defc33da3bace68f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Apr 2025 17:29:53 +0800
+Subject: netfilter: bridge: Move specific fragmented packet to slow_path
+ instead of dropping it
+
+From: Huajian Yang <huajianyang@asrmicro.com>
+
+[ Upstream commit aa04c6f45b9224b949aa35d4fa5f8d0ba07b23d4 ]
+
+The config NF_CONNTRACK_BRIDGE will change the bridge forwarding for
+fragmented packets.
+
+The original bridge does not know that it is a fragmented packet and
+forwards it directly, after NF_CONNTRACK_BRIDGE is enabled, function
+nf_br_ip_fragment and br_ip6_fragment will check the headroom.
+
+In original br_forward, insufficient headroom of skb may indeed exist,
+but there's still a way to save the skb in the device driver after
+dev_queue_xmit.So droping the skb will change the original bridge
+forwarding in some cases.
+
+Fixes: 3c171f496ef5 ("netfilter: bridge: add connection tracking system")
+Signed-off-by: Huajian Yang <huajianyang@asrmicro.com>
+Reviewed-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bridge/netfilter/nf_conntrack_bridge.c | 12 ++++++------
+ net/ipv6/netfilter.c                       | 12 ++++++------
+ 2 files changed, 12 insertions(+), 12 deletions(-)
+
+diff --git a/net/bridge/netfilter/nf_conntrack_bridge.c b/net/bridge/netfilter/nf_conntrack_bridge.c
+index 816bb0fde718e..6482de4d87509 100644
+--- a/net/bridge/netfilter/nf_conntrack_bridge.c
++++ b/net/bridge/netfilter/nf_conntrack_bridge.c
+@@ -60,19 +60,19 @@ static int nf_br_ip_fragment(struct net *net, struct sock *sk,
+               struct ip_fraglist_iter iter;
+               struct sk_buff *frag;
+-              if (first_len - hlen > mtu ||
+-                  skb_headroom(skb) < ll_rs)
++              if (first_len - hlen > mtu)
+                       goto blackhole;
+-              if (skb_cloned(skb))
++              if (skb_cloned(skb) ||
++                  skb_headroom(skb) < ll_rs)
+                       goto slow_path;
+               skb_walk_frags(skb, frag) {
+-                      if (frag->len > mtu ||
+-                          skb_headroom(frag) < hlen + ll_rs)
++                      if (frag->len > mtu)
+                               goto blackhole;
+-                      if (skb_shared(frag))
++                      if (skb_shared(frag) ||
++                          skb_headroom(frag) < hlen + ll_rs)
+                               goto slow_path;
+               }
+diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
+index 581ce055bf520..4541836ee3da2 100644
+--- a/net/ipv6/netfilter.c
++++ b/net/ipv6/netfilter.c
+@@ -164,20 +164,20 @@ int br_ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
+               struct ip6_fraglist_iter iter;
+               struct sk_buff *frag2;
+-              if (first_len - hlen > mtu ||
+-                  skb_headroom(skb) < (hroom + sizeof(struct frag_hdr)))
++              if (first_len - hlen > mtu)
+                       goto blackhole;
+-              if (skb_cloned(skb))
++              if (skb_cloned(skb) ||
++                  skb_headroom(skb) < (hroom + sizeof(struct frag_hdr)))
+                       goto slow_path;
+               skb_walk_frags(skb, frag2) {
+-                      if (frag2->len > mtu ||
+-                          skb_headroom(frag2) < (hlen + hroom + sizeof(struct frag_hdr)))
++                      if (frag2->len > mtu)
+                               goto blackhole;
+                       /* Partially cloned skb? */
+-                      if (skb_shared(frag2))
++                      if (skb_shared(frag2) ||
++                          skb_headroom(frag2) < (hlen + hroom + sizeof(struct frag_hdr)))
+                               goto slow_path;
+               }
+-- 
+2.39.5
+
diff --git a/queue-6.15/netfilter-nf_nat-also-check-reverse-tuple-to-obtain-.patch b/queue-6.15/netfilter-nf_nat-also-check-reverse-tuple-to-obtain-.patch
new file mode 100644 (file)
index 0000000..88e44ff
--- /dev/null
@@ -0,0 +1,103 @@
+From fcb2baf43374166b243a89e92b7835373eb5f39c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 May 2025 12:34:02 +0200
+Subject: netfilter: nf_nat: also check reverse tuple to obtain clashing entry
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit 50d9ce9679dd50df2dc51ada717fa875bc248fad ]
+
+The logic added in the blamed commit was supposed to only omit nat source
+port allocation if neither the existing nor the new entry are subject to
+NAT.
+
+However, its not enough to lookup the conntrack based on the proposed
+tuple, we must also check the reverse direction.
+
+Otherwise there are esoteric cases where the collision is in the reverse
+direction because that colliding connection has a port rewrite, but the
+new entry doesn't.  In this case, we only check the new entry and then
+erronously conclude that no clash exists anymore.
+
+ The existing (udp) tuple is:
+  a:p -> b:P, with nat translation to s:P, i.e. pure daddr rewrite,
+  reverse tuple in conntrack table is s:P -> a:p.
+
+When another UDP packet is sent directly to s, i.e. a:p->s:P, this is
+correctly detected as a colliding entry: tuple is taken by existing reply
+tuple in reverse direction.
+
+But the colliding conntrack is only searched for with unreversed
+direction, and we can't find such entry matching a:p->s:P.
+
+The incorrect conclusion is that the clashing entry has timed out and
+that no port address translation is required.
+
+Such conntrack will then be discarded at nf_confirm time because the
+proposed reverse direction clashes with an existing mapping in the
+conntrack table.
+
+Search for the reverse tuple too, this will then check the NAT bits of
+the colliding entry and triggers port reallocation.
+
+Followp patch extends nft_nat.sh selftest to cover this scenario.
+
+The IPS_SEQ_ADJUST change is also a bug fix:
+Instead of checking for SEQ_ADJ this tested for SEEN_REPLY and ASSURED
+by accident -- _BIT is only for use with the test_bit() API.
+
+This bug has little consequence in practice, because the sequence number
+adjustments are only useful for TCP which doesn't support clash resolution.
+
+The existing test case (conntrack_reverse_clash.sh) exercise a race
+condition path (parallel conntrack creation on different CPUs), so
+the colliding entries have neither SEEN_REPLY nor ASSURED set.
+
+Thanks to Yafang Shao and Shaun Brady for an initial investigation
+of this bug.
+
+Fixes: d8f84a9bc7c4 ("netfilter: nf_nat: don't try nat source port reallocation for reverse dir clash")
+Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1795
+Reported-by: Yafang Shao <laoar.shao@gmail.com>
+Reported-by: Shaun Brady <brady.1345@gmail.com>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Tested-by: Yafang Shao <laoar.shao@gmail.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_nat_core.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
+index aad84aabd7f1d..f391cd267922b 100644
+--- a/net/netfilter/nf_nat_core.c
++++ b/net/netfilter/nf_nat_core.c
+@@ -248,7 +248,7 @@ static noinline bool
+ nf_nat_used_tuple_new(const struct nf_conntrack_tuple *tuple,
+                     const struct nf_conn *ignored_ct)
+ {
+-      static const unsigned long uses_nat = IPS_NAT_MASK | IPS_SEQ_ADJUST_BIT;
++      static const unsigned long uses_nat = IPS_NAT_MASK | IPS_SEQ_ADJUST;
+       const struct nf_conntrack_tuple_hash *thash;
+       const struct nf_conntrack_zone *zone;
+       struct nf_conn *ct;
+@@ -287,8 +287,14 @@ nf_nat_used_tuple_new(const struct nf_conntrack_tuple *tuple,
+       zone = nf_ct_zone(ignored_ct);
+       thash = nf_conntrack_find_get(net, zone, tuple);
+-      if (unlikely(!thash)) /* clashing entry went away */
+-              return false;
++      if (unlikely(!thash)) {
++              struct nf_conntrack_tuple reply;
++
++              nf_ct_invert_tuple(&reply, tuple);
++              thash = nf_conntrack_find_get(net, zone, &reply);
++              if (!thash) /* clashing entry went away */
++                      return false;
++      }
+       ct = nf_ct_tuplehash_to_ctrack(thash);
+-- 
+2.39.5
+
diff --git a/queue-6.15/netfilter-nf_set_pipapo_avx2-fix-initial-map-fill.patch b/queue-6.15/netfilter-nf_set_pipapo_avx2-fix-initial-map-fill.patch
new file mode 100644 (file)
index 0000000..974a2e5
--- /dev/null
@@ -0,0 +1,68 @@
+From 365f97bb0ca2e386b4bb0e33512752de64a9aadd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 May 2025 14:20:44 +0200
+Subject: netfilter: nf_set_pipapo_avx2: fix initial map fill
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit ea77c397bff8b6d59f6d83dae1425b08f465e8b5 ]
+
+If the first field doesn't cover the entire start map, then we must zero
+out the remainder, else we leak those bits into the next match round map.
+
+The early fix was incomplete and did only fix up the generic C
+implementation.
+
+A followup patch adds a test case to nft_concat_range.sh.
+
+Fixes: 791a615b7ad2 ("netfilter: nf_set_pipapo: fix initial map fill")
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_set_pipapo_avx2.c | 21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
+
+diff --git a/net/netfilter/nft_set_pipapo_avx2.c b/net/netfilter/nft_set_pipapo_avx2.c
+index c15db28c5ebc4..be7c16c79f711 100644
+--- a/net/netfilter/nft_set_pipapo_avx2.c
++++ b/net/netfilter/nft_set_pipapo_avx2.c
+@@ -1113,6 +1113,25 @@ bool nft_pipapo_avx2_estimate(const struct nft_set_desc *desc, u32 features,
+       return true;
+ }
++/**
++ * pipapo_resmap_init_avx2() - Initialise result map before first use
++ * @m:                Matching data, including mapping table
++ * @res_map:  Result map
++ *
++ * Like pipapo_resmap_init() but do not set start map bits covered by the first field.
++ */
++static inline void pipapo_resmap_init_avx2(const struct nft_pipapo_match *m, unsigned long *res_map)
++{
++      const struct nft_pipapo_field *f = m->f;
++      int i;
++
++      /* Starting map doesn't need to be set to all-ones for this implementation,
++       * but we do need to zero the remaining bits, if any.
++       */
++      for (i = f->bsize; i < m->bsize_max; i++)
++              res_map[i] = 0ul;
++}
++
+ /**
+  * nft_pipapo_avx2_lookup() - Lookup function for AVX2 implementation
+  * @net:      Network namespace
+@@ -1171,7 +1190,7 @@ bool nft_pipapo_avx2_lookup(const struct net *net, const struct nft_set *set,
+       res  = scratch->map + (map_index ? m->bsize_max : 0);
+       fill = scratch->map + (map_index ? 0 : m->bsize_max);
+-      /* Starting map doesn't need to be set for this implementation */
++      pipapo_resmap_init_avx2(m, res);
+       nft_pipapo_avx2_prepare();
+-- 
+2.39.5
+
diff --git a/queue-6.15/netfilter-nf_tables-nft_fib-consistent-l3mdev-handli.patch b/queue-6.15/netfilter-nf_tables-nft_fib-consistent-l3mdev-handli.patch
new file mode 100644 (file)
index 0000000..7fcf25f
--- /dev/null
@@ -0,0 +1,167 @@
+From 7572176b85a2c73ce63496ac57a8aaa5713095a9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 May 2025 11:38:48 +0200
+Subject: netfilter: nf_tables: nft_fib: consistent l3mdev handling
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit 9a119669fb1924cd9658c16da39a5a585e129e50 ]
+
+fib has two modes:
+1. Obtain output device according to source or destination address
+2. Obtain the type of the address, e.g. local, unicast, multicast.
+
+'fib daddr type' should return 'local' if the address is configured
+in this netns or unicast otherwise.
+
+'fib daddr . iif type' should return 'local' if the address is configured
+on the input interface or unicast otherwise, i.e. more restrictive.
+
+However, if the interface is part of a VRF, then 'fib daddr type'
+returns unicast even if the address is configured on the incoming
+interface.
+
+This is broken for both ipv4 and ipv6.
+
+In the ipv4 case, inet_dev_addr_type must only be used if the
+'iif' or 'oif' (strict mode) was requested.
+
+Else inet_addr_type_dev_table() needs to be used and the correct
+dev argument must be passed as well so the correct fib (vrf) table
+is used.
+
+In the ipv6 case, the bug is similar, without strict mode, dev is NULL
+so .flowi6_l3mdev will be set to 0.
+
+Add a new 'nft_fib_l3mdev_master_ifindex_rcu()' helper and use that
+to init the .l3mdev structure member.
+
+For ipv6, use it from nft_fib6_flowi_init() which gets called from
+both the 'type' and the 'route' mode eval functions.
+
+This provides consistent behaviour for all modes for both ipv4 and ipv6:
+If strict matching is requested, the input respectively output device
+of the netfilter hooks is used.
+
+Otherwise, use skb->dev to obtain the l3mdev ifindex.
+
+Without this, most type checks in updated nft_fib.sh selftest fail:
+
+  FAIL: did not find veth0 . 10.9.9.1 . local in fibtype4
+  FAIL: did not find veth0 . dead:1::1 . local in fibtype6
+  FAIL: did not find veth0 . dead:9::1 . local in fibtype6
+  FAIL: did not find tvrf . 10.0.1.1 . local in fibtype4
+  FAIL: did not find tvrf . 10.9.9.1 . local in fibtype4
+  FAIL: did not find tvrf . dead:1::1 . local in fibtype6
+  FAIL: did not find tvrf . dead:9::1 . local in fibtype6
+  FAIL: fib expression address types match (iif in vrf)
+
+(fib errounously returns 'unicast' for all of them, even
+ though all of these addresses are local to the vrf).
+
+Fixes: f6d0cbcf09c5 ("netfilter: nf_tables: add fib expression")
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/netfilter/nft_fib.h   |  9 +++++++++
+ net/ipv4/netfilter/nft_fib_ipv4.c | 11 +++++++++--
+ net/ipv6/netfilter/nft_fib_ipv6.c |  4 +---
+ 3 files changed, 19 insertions(+), 5 deletions(-)
+
+diff --git a/include/net/netfilter/nft_fib.h b/include/net/netfilter/nft_fib.h
+index 6e202ed5e63f3..7370fba844efc 100644
+--- a/include/net/netfilter/nft_fib.h
++++ b/include/net/netfilter/nft_fib.h
+@@ -2,6 +2,7 @@
+ #ifndef _NFT_FIB_H_
+ #define _NFT_FIB_H_
++#include <net/l3mdev.h>
+ #include <net/netfilter/nf_tables.h>
+ struct nft_fib {
+@@ -39,6 +40,14 @@ static inline bool nft_fib_can_skip(const struct nft_pktinfo *pkt)
+       return nft_fib_is_loopback(pkt->skb, indev);
+ }
++static inline int nft_fib_l3mdev_master_ifindex_rcu(const struct nft_pktinfo *pkt,
++                                                  const struct net_device *iif)
++{
++      const struct net_device *dev = iif ? iif : pkt->skb->dev;
++
++      return l3mdev_master_ifindex_rcu(dev);
++}
++
+ int nft_fib_dump(struct sk_buff *skb, const struct nft_expr *expr, bool reset);
+ int nft_fib_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
+                const struct nlattr * const tb[]);
+diff --git a/net/ipv4/netfilter/nft_fib_ipv4.c b/net/ipv4/netfilter/nft_fib_ipv4.c
+index 9082ca17e845c..7e7c49535e3f5 100644
+--- a/net/ipv4/netfilter/nft_fib_ipv4.c
++++ b/net/ipv4/netfilter/nft_fib_ipv4.c
+@@ -50,7 +50,12 @@ void nft_fib4_eval_type(const struct nft_expr *expr, struct nft_regs *regs,
+       else
+               addr = iph->saddr;
+-      *dst = inet_dev_addr_type(nft_net(pkt), dev, addr);
++      if (priv->flags & (NFTA_FIB_F_IIF | NFTA_FIB_F_OIF)) {
++              *dst = inet_dev_addr_type(nft_net(pkt), dev, addr);
++              return;
++      }
++
++      *dst = inet_addr_type_dev_table(nft_net(pkt), pkt->skb->dev, addr);
+ }
+ EXPORT_SYMBOL_GPL(nft_fib4_eval_type);
+@@ -65,8 +70,8 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs,
+       struct flowi4 fl4 = {
+               .flowi4_scope = RT_SCOPE_UNIVERSE,
+               .flowi4_iif = LOOPBACK_IFINDEX,
++              .flowi4_proto = pkt->tprot,
+               .flowi4_uid = sock_net_uid(nft_net(pkt), NULL),
+-              .flowi4_l3mdev = l3mdev_master_ifindex_rcu(nft_in(pkt)),
+       };
+       const struct net_device *oif;
+       const struct net_device *found;
+@@ -90,6 +95,8 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs,
+       else
+               oif = NULL;
++      fl4.flowi4_l3mdev = nft_fib_l3mdev_master_ifindex_rcu(pkt, oif);
++
+       iph = skb_header_pointer(pkt->skb, noff, sizeof(_iph), &_iph);
+       if (!iph) {
+               regs->verdict.code = NFT_BREAK;
+diff --git a/net/ipv6/netfilter/nft_fib_ipv6.c b/net/ipv6/netfilter/nft_fib_ipv6.c
+index f1f5640da6728..421036a3605b4 100644
+--- a/net/ipv6/netfilter/nft_fib_ipv6.c
++++ b/net/ipv6/netfilter/nft_fib_ipv6.c
+@@ -50,6 +50,7 @@ static int nft_fib6_flowi_init(struct flowi6 *fl6, const struct nft_fib *priv,
+               fl6->flowi6_mark = pkt->skb->mark;
+       fl6->flowlabel = (*(__be32 *)iph) & IPV6_FLOWINFO_MASK;
++      fl6->flowi6_l3mdev = nft_fib_l3mdev_master_ifindex_rcu(pkt, dev);
+       return lookup_flags;
+ }
+@@ -73,8 +74,6 @@ static u32 __nft_fib6_eval_type(const struct nft_fib *priv,
+       else if (priv->flags & NFTA_FIB_F_OIF)
+               dev = nft_out(pkt);
+-      fl6.flowi6_l3mdev = l3mdev_master_ifindex_rcu(dev);
+-
+       nft_fib6_flowi_init(&fl6, priv, pkt, dev, iph);
+       if (dev && nf_ipv6_chk_addr(nft_net(pkt), &fl6.daddr, dev, true))
+@@ -166,7 +165,6 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs,
+               .flowi6_iif = LOOPBACK_IFINDEX,
+               .flowi6_proto = pkt->tprot,
+               .flowi6_uid = sock_net_uid(nft_net(pkt), NULL),
+-              .flowi6_l3mdev = l3mdev_master_ifindex_rcu(nft_in(pkt)),
+       };
+       struct rt6_info *rt;
+       int lookup_flags;
+-- 
+2.39.5
+
diff --git a/queue-6.15/netfilter-nf_tables-nft_fib_ipv6-fix-vrf-ipv4-ipv6-r.patch b/queue-6.15/netfilter-nf_tables-nft_fib_ipv6-fix-vrf-ipv4-ipv6-r.patch
new file mode 100644 (file)
index 0000000..7527200
--- /dev/null
@@ -0,0 +1,80 @@
+From f456f26312c9e5b9040bb1bd6252a9192421ed23 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 May 2025 11:38:47 +0200
+Subject: netfilter: nf_tables: nft_fib_ipv6: fix VRF ipv4/ipv6 result
+ discrepancy
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit 8b53f46eb430fe5b42d485873b85331d2de2c469 ]
+
+With a VRF, ipv4 and ipv6 FIB expression behave differently.
+
+   fib daddr . iif oif
+
+Will return the input interface name for ipv4, but the real device
+for ipv6.  Example:
+
+If VRF device name is tvrf and real (incoming) device is veth0.
+First round is ok, both ipv4 and ipv6 will yield 'veth0'.
+
+But in the second round (incoming device will be set to "tvrf"), ipv4
+will yield "tvrf" whereas ipv6 returns "veth0" for the second round too.
+
+This makes ipv6 behave like ipv4.
+
+A followup patch will add a test case for this, without this change
+it will fail with:
+  get element inet t fibif6iif { tvrf . dead:1::99 . tvrf }
+  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+  FAIL: did not find tvrf . dead:1::99 . tvrf in fibif6iif
+
+Alternatively we could either not do anything at all or change
+ipv4 to also return the lower/real device, however, nft (userspace)
+doc says "iif: if fib lookup provides a route then check its output
+interface is identical to the packets input interface." which is what
+the nft fib ipv4 behaviour is.
+
+Fixes: f6d0cbcf09c5 ("netfilter: nf_tables: add fib expression")
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/netfilter/nft_fib_ipv6.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/net/ipv6/netfilter/nft_fib_ipv6.c b/net/ipv6/netfilter/nft_fib_ipv6.c
+index 7fd9d7b21cd42..f1f5640da6728 100644
+--- a/net/ipv6/netfilter/nft_fib_ipv6.c
++++ b/net/ipv6/netfilter/nft_fib_ipv6.c
+@@ -158,6 +158,7 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs,
+ {
+       const struct nft_fib *priv = nft_expr_priv(expr);
+       int noff = skb_network_offset(pkt->skb);
++      const struct net_device *found = NULL;
+       const struct net_device *oif = NULL;
+       u32 *dest = &regs->data[priv->dreg];
+       struct ipv6hdr *iph, _iph;
+@@ -203,11 +204,15 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs,
+       if (rt->rt6i_flags & (RTF_REJECT | RTF_ANYCAST | RTF_LOCAL))
+               goto put_rt_err;
+-      if (oif && oif != rt->rt6i_idev->dev &&
+-          l3mdev_master_ifindex_rcu(rt->rt6i_idev->dev) != oif->ifindex)
+-              goto put_rt_err;
++      if (!oif) {
++              found = rt->rt6i_idev->dev;
++      } else {
++              if (oif == rt->rt6i_idev->dev ||
++                  l3mdev_master_ifindex_rcu(rt->rt6i_idev->dev) == oif->ifindex)
++                      found = oif;
++      }
+-      nft_fib_store_result(dest, priv, rt->rt6i_idev->dev);
++      nft_fib_store_result(dest, priv, found);
+  put_rt_err:
+       ip6_rt_put(rt);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/netfilter-nft_quota-match-correctly-when-the-quota-j.patch b/queue-6.15/netfilter-nft_quota-match-correctly-when-the-quota-j.patch
new file mode 100644 (file)
index 0000000..4b7d546
--- /dev/null
@@ -0,0 +1,78 @@
+From b2a8bbfc8c550eb88c319ca2d2e3778134a8ae7c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Apr 2025 15:49:30 +0000
+Subject: netfilter: nft_quota: match correctly when the quota just depleted
+
+From: Zhongqiu Duan <dzq.aishenghu0@gmail.com>
+
+[ Upstream commit bfe7cfb65c753952735c3eed703eba9a8b96a18d ]
+
+The xt_quota compares skb length with remaining quota, but the nft_quota
+compares it with consumed bytes.
+
+The xt_quota can match consumed bytes up to quota at maximum. But the
+nft_quota break match when consumed bytes equal to quota.
+
+i.e., nft_quota match consumed bytes in [0, quota - 1], not [0, quota].
+
+Fixes: 795595f68d6c ("netfilter: nft_quota: dump consumed quota")
+Signed-off-by: Zhongqiu Duan <dzq.aishenghu0@gmail.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_quota.c | 20 +++++++++++++-------
+ 1 file changed, 13 insertions(+), 7 deletions(-)
+
+diff --git a/net/netfilter/nft_quota.c b/net/netfilter/nft_quota.c
+index 9b2d7463d3d32..df0798da2329b 100644
+--- a/net/netfilter/nft_quota.c
++++ b/net/netfilter/nft_quota.c
+@@ -19,10 +19,16 @@ struct nft_quota {
+ };
+ static inline bool nft_overquota(struct nft_quota *priv,
+-                               const struct sk_buff *skb)
++                               const struct sk_buff *skb,
++                               bool *report)
+ {
+-      return atomic64_add_return(skb->len, priv->consumed) >=
+-             atomic64_read(&priv->quota);
++      u64 consumed = atomic64_add_return(skb->len, priv->consumed);
++      u64 quota = atomic64_read(&priv->quota);
++
++      if (report)
++              *report = consumed >= quota;
++
++      return consumed > quota;
+ }
+ static inline bool nft_quota_invert(struct nft_quota *priv)
+@@ -34,7 +40,7 @@ static inline void nft_quota_do_eval(struct nft_quota *priv,
+                                    struct nft_regs *regs,
+                                    const struct nft_pktinfo *pkt)
+ {
+-      if (nft_overquota(priv, pkt->skb) ^ nft_quota_invert(priv))
++      if (nft_overquota(priv, pkt->skb, NULL) ^ nft_quota_invert(priv))
+               regs->verdict.code = NFT_BREAK;
+ }
+@@ -51,13 +57,13 @@ static void nft_quota_obj_eval(struct nft_object *obj,
+                              const struct nft_pktinfo *pkt)
+ {
+       struct nft_quota *priv = nft_obj_data(obj);
+-      bool overquota;
++      bool overquota, report;
+-      overquota = nft_overquota(priv, pkt->skb);
++      overquota = nft_overquota(priv, pkt->skb, &report);
+       if (overquota ^ nft_quota_invert(priv))
+               regs->verdict.code = NFT_BREAK;
+-      if (overquota &&
++      if (report &&
+           !test_and_set_bit(NFT_QUOTA_DEPLETED_BIT, &priv->flags))
+               nft_obj_notify(nft_net(pkt), obj->key.table, obj, 0, 0,
+                              NFT_MSG_NEWOBJ, 0, nft_pf(pkt), 0, GFP_ATOMIC);
+-- 
+2.39.5
+
diff --git a/queue-6.15/netfilter-nft_set_pipapo-prevent-overflow-in-lookup-.patch b/queue-6.15/netfilter-nft_set_pipapo-prevent-overflow-in-lookup-.patch
new file mode 100644 (file)
index 0000000..5fa8112
--- /dev/null
@@ -0,0 +1,157 @@
+From f6c354c990f3ad82d87537456bd217c0cb1d9012 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Apr 2025 21:52:43 +0200
+Subject: netfilter: nft_set_pipapo: prevent overflow in lookup table
+ allocation
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 4c5c6aa9967dbe55bd017bb509885928d0f31206 ]
+
+When calculating the lookup table size, ensure the following
+multiplication does not overflow:
+
+- desc->field_len[] maximum value is U8_MAX multiplied by
+  NFT_PIPAPO_GROUPS_PER_BYTE(f) that can be 2, worst case.
+- NFT_PIPAPO_BUCKETS(f->bb) is 2^8, worst case.
+- sizeof(unsigned long), from sizeof(*f->lt), lt in
+  struct nft_pipapo_field.
+
+Then, use check_mul_overflow() to multiply by bucket size and then use
+check_add_overflow() to the alignment for avx2 (if needed). Finally, add
+lt_size_check_overflow() helper and use it to consolidate this.
+
+While at it, replace leftover allocation using the GFP_KERNEL to
+GFP_KERNEL_ACCOUNT for consistency, in pipapo_resize().
+
+Fixes: 3c4287f62044 ("nf_tables: Add set type for arbitrary concatenation of ranges")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_set_pipapo.c | 58 ++++++++++++++++++++++++++--------
+ 1 file changed, 44 insertions(+), 14 deletions(-)
+
+diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c
+index 7be342b495f5f..0529e4ef75207 100644
+--- a/net/netfilter/nft_set_pipapo.c
++++ b/net/netfilter/nft_set_pipapo.c
+@@ -683,6 +683,30 @@ static int pipapo_realloc_mt(struct nft_pipapo_field *f,
+       return 0;
+ }
++
++/**
++ * lt_calculate_size() - Get storage size for lookup table with overflow check
++ * @groups:   Amount of bit groups
++ * @bb:               Number of bits grouped together in lookup table buckets
++ * @bsize:    Size of each bucket in lookup table, in longs
++ *
++ * Return: allocation size including alignment overhead, negative on overflow
++ */
++static ssize_t lt_calculate_size(unsigned int groups, unsigned int bb,
++                               unsigned int bsize)
++{
++      ssize_t ret = groups * NFT_PIPAPO_BUCKETS(bb) * sizeof(long);
++
++      if (check_mul_overflow(ret, bsize, &ret))
++              return -1;
++      if (check_add_overflow(ret, NFT_PIPAPO_ALIGN_HEADROOM, &ret))
++              return -1;
++      if (ret > INT_MAX)
++              return -1;
++
++      return ret;
++}
++
+ /**
+  * pipapo_resize() - Resize lookup or mapping table, or both
+  * @f:                Field containing lookup and mapping tables
+@@ -701,6 +725,7 @@ static int pipapo_resize(struct nft_pipapo_field *f,
+       long *new_lt = NULL, *new_p, *old_lt = f->lt, *old_p;
+       unsigned int new_bucket_size, copy;
+       int group, bucket, err;
++      ssize_t lt_size;
+       if (rules >= NFT_PIPAPO_RULE0_MAX)
+               return -ENOSPC;
+@@ -719,10 +744,11 @@ static int pipapo_resize(struct nft_pipapo_field *f,
+       else
+               copy = new_bucket_size;
+-      new_lt = kvzalloc(f->groups * NFT_PIPAPO_BUCKETS(f->bb) *
+-                        new_bucket_size * sizeof(*new_lt) +
+-                        NFT_PIPAPO_ALIGN_HEADROOM,
+-                        GFP_KERNEL);
++      lt_size = lt_calculate_size(f->groups, f->bb, new_bucket_size);
++      if (lt_size < 0)
++              return -ENOMEM;
++
++      new_lt = kvzalloc(lt_size, GFP_KERNEL_ACCOUNT);
+       if (!new_lt)
+               return -ENOMEM;
+@@ -907,7 +933,7 @@ static void pipapo_lt_bits_adjust(struct nft_pipapo_field *f)
+ {
+       unsigned int groups, bb;
+       unsigned long *new_lt;
+-      size_t lt_size;
++      ssize_t lt_size;
+       lt_size = f->groups * NFT_PIPAPO_BUCKETS(f->bb) * f->bsize *
+                 sizeof(*f->lt);
+@@ -917,15 +943,17 @@ static void pipapo_lt_bits_adjust(struct nft_pipapo_field *f)
+               groups = f->groups * 2;
+               bb = NFT_PIPAPO_GROUP_BITS_LARGE_SET;
+-              lt_size = groups * NFT_PIPAPO_BUCKETS(bb) * f->bsize *
+-                        sizeof(*f->lt);
++              lt_size = lt_calculate_size(groups, bb, f->bsize);
++              if (lt_size < 0)
++                      return;
+       } else if (f->bb == NFT_PIPAPO_GROUP_BITS_LARGE_SET &&
+                  lt_size < NFT_PIPAPO_LT_SIZE_LOW) {
+               groups = f->groups / 2;
+               bb = NFT_PIPAPO_GROUP_BITS_SMALL_SET;
+-              lt_size = groups * NFT_PIPAPO_BUCKETS(bb) * f->bsize *
+-                        sizeof(*f->lt);
++              lt_size = lt_calculate_size(groups, bb, f->bsize);
++              if (lt_size < 0)
++                      return;
+               /* Don't increase group width if the resulting lookup table size
+                * would exceed the upper size threshold for a "small" set.
+@@ -936,7 +964,7 @@ static void pipapo_lt_bits_adjust(struct nft_pipapo_field *f)
+               return;
+       }
+-      new_lt = kvzalloc(lt_size + NFT_PIPAPO_ALIGN_HEADROOM, GFP_KERNEL_ACCOUNT);
++      new_lt = kvzalloc(lt_size, GFP_KERNEL_ACCOUNT);
+       if (!new_lt)
+               return;
+@@ -1451,13 +1479,15 @@ static struct nft_pipapo_match *pipapo_clone(struct nft_pipapo_match *old)
+       for (i = 0; i < old->field_count; i++) {
+               unsigned long *new_lt;
++              ssize_t lt_size;
+               memcpy(dst, src, offsetof(struct nft_pipapo_field, lt));
+-              new_lt = kvzalloc(src->groups * NFT_PIPAPO_BUCKETS(src->bb) *
+-                                src->bsize * sizeof(*dst->lt) +
+-                                NFT_PIPAPO_ALIGN_HEADROOM,
+-                                GFP_KERNEL_ACCOUNT);
++              lt_size = lt_calculate_size(src->groups, src->bb, src->bsize);
++              if (lt_size < 0)
++                      goto out_lt;
++
++              new_lt = kvzalloc(lt_size, GFP_KERNEL_ACCOUNT);
+               if (!new_lt)
+                       goto out_lt;
+-- 
+2.39.5
+
diff --git a/queue-6.15/netfilter-nft_tunnel-fix-geneve_opt-dump.patch b/queue-6.15/netfilter-nft_tunnel-fix-geneve_opt-dump.patch
new file mode 100644 (file)
index 0000000..98c8902
--- /dev/null
@@ -0,0 +1,71 @@
+From 85f35a0037656bc0f85028eb7d7fea93b51fc985 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 May 2025 11:41:08 +0200
+Subject: netfilter: nft_tunnel: fix geneve_opt dump
+
+From: Fernando Fernandez Mancera <fmancera@suse.de>
+
+[ Upstream commit 22a9613de4c29d7d0770bfb8a5a9d73eb8df7dad ]
+
+When dumping a nft_tunnel with more than one geneve_opt configured the
+netlink attribute hierarchy should be as follow:
+
+ NFTA_TUNNEL_KEY_OPTS
+ |
+ |--NFTA_TUNNEL_KEY_OPTS_GENEVE
+ |  |
+ |  |--NFTA_TUNNEL_KEY_GENEVE_CLASS
+ |  |--NFTA_TUNNEL_KEY_GENEVE_TYPE
+ |  |--NFTA_TUNNEL_KEY_GENEVE_DATA
+ |
+ |--NFTA_TUNNEL_KEY_OPTS_GENEVE
+ |  |
+ |  |--NFTA_TUNNEL_KEY_GENEVE_CLASS
+ |  |--NFTA_TUNNEL_KEY_GENEVE_TYPE
+ |  |--NFTA_TUNNEL_KEY_GENEVE_DATA
+ |
+ |--NFTA_TUNNEL_KEY_OPTS_GENEVE
+ ...
+
+Otherwise, userspace tools won't be able to fetch the geneve options
+configured correctly.
+
+Fixes: 925d844696d9 ("netfilter: nft_tunnel: add support for geneve opts")
+Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_tunnel.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/net/netfilter/nft_tunnel.c b/net/netfilter/nft_tunnel.c
+index 0c63d1367cf7a..a12486ae089d6 100644
+--- a/net/netfilter/nft_tunnel.c
++++ b/net/netfilter/nft_tunnel.c
+@@ -621,10 +621,10 @@ static int nft_tunnel_opts_dump(struct sk_buff *skb,
+               struct geneve_opt *opt;
+               int offset = 0;
+-              inner = nla_nest_start_noflag(skb, NFTA_TUNNEL_KEY_OPTS_GENEVE);
+-              if (!inner)
+-                      goto failure;
+               while (opts->len > offset) {
++                      inner = nla_nest_start_noflag(skb, NFTA_TUNNEL_KEY_OPTS_GENEVE);
++                      if (!inner)
++                              goto failure;
+                       opt = (struct geneve_opt *)(opts->u.data + offset);
+                       if (nla_put_be16(skb, NFTA_TUNNEL_KEY_GENEVE_CLASS,
+                                        opt->opt_class) ||
+@@ -634,8 +634,8 @@ static int nft_tunnel_opts_dump(struct sk_buff *skb,
+                                   opt->length * 4, opt->opt_data))
+                               goto inner_failure;
+                       offset += sizeof(*opt) + opt->length * 4;
++                      nla_nest_end(skb, inner);
+               }
+-              nla_nest_end(skb, inner);
+       }
+       nla_nest_end(skb, nest);
+       return 0;
+-- 
+2.39.5
+
diff --git a/queue-6.15/netfilter-xtables-support-arpt_mark-and-ipv6-optstri.patch b/queue-6.15/netfilter-xtables-support-arpt_mark-and-ipv6-optstri.patch
new file mode 100644 (file)
index 0000000..b356272
--- /dev/null
@@ -0,0 +1,67 @@
+From 8e7a4724a7bf163d608d5e024943b6c006775cab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 May 2025 16:12:13 +0200
+Subject: netfilter: xtables: support arpt_mark and ipv6 optstrip for
+ iptables-nft only builds
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit c38eb2973c18d34a8081d173a6ad298461f4a37c ]
+
+Its now possible to build a kernel that has no support for the classic
+xtables get/setsockopt interfaces and builtin tables.
+
+In this case, we have CONFIG_IP6_NF_MANGLE=n and
+CONFIG_IP_NF_ARPTABLES=n.
+
+For optstript, the ipv6 code is so small that we can enable it if
+netfilter ipv6 support exists. For mark, check if either classic
+arptables or NFT_ARP_COMPAT is set.
+
+Fixes: a9525c7f6219 ("netfilter: xtables: allow xtables-nft only builds")
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/xt_TCPOPTSTRIP.c | 4 ++--
+ net/netfilter/xt_mark.c        | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/net/netfilter/xt_TCPOPTSTRIP.c b/net/netfilter/xt_TCPOPTSTRIP.c
+index 30e99464171b7..93f064306901c 100644
+--- a/net/netfilter/xt_TCPOPTSTRIP.c
++++ b/net/netfilter/xt_TCPOPTSTRIP.c
+@@ -91,7 +91,7 @@ tcpoptstrip_tg4(struct sk_buff *skb, const struct xt_action_param *par)
+       return tcpoptstrip_mangle_packet(skb, par, ip_hdrlen(skb));
+ }
+-#if IS_ENABLED(CONFIG_IP6_NF_MANGLE)
++#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
+ static unsigned int
+ tcpoptstrip_tg6(struct sk_buff *skb, const struct xt_action_param *par)
+ {
+@@ -119,7 +119,7 @@ static struct xt_target tcpoptstrip_tg_reg[] __read_mostly = {
+               .targetsize = sizeof(struct xt_tcpoptstrip_target_info),
+               .me         = THIS_MODULE,
+       },
+-#if IS_ENABLED(CONFIG_IP6_NF_MANGLE)
++#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
+       {
+               .name       = "TCPOPTSTRIP",
+               .family     = NFPROTO_IPV6,
+diff --git a/net/netfilter/xt_mark.c b/net/netfilter/xt_mark.c
+index 65b965ca40ea7..59b9d04400cac 100644
+--- a/net/netfilter/xt_mark.c
++++ b/net/netfilter/xt_mark.c
+@@ -48,7 +48,7 @@ static struct xt_target mark_tg_reg[] __read_mostly = {
+               .targetsize     = sizeof(struct xt_mark_tginfo2),
+               .me             = THIS_MODULE,
+       },
+-#if IS_ENABLED(CONFIG_IP_NF_ARPTABLES)
++#if IS_ENABLED(CONFIG_IP_NF_ARPTABLES) || IS_ENABLED(CONFIG_NFT_COMPAT_ARP)
+       {
+               .name           = "MARK",
+               .revision       = 2,
+-- 
+2.39.5
+
diff --git a/queue-6.15/netfs-fix-oops-in-write-retry-from-mis-resetting-the.patch b/queue-6.15/netfs-fix-oops-in-write-retry-from-mis-resetting-the.patch
new file mode 100644 (file)
index 0000000..8f17248
--- /dev/null
@@ -0,0 +1,80 @@
+From bb211a014f7c6d356930e64cb241131d9ed4c6cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 May 2025 10:07:01 +0100
+Subject: netfs: Fix oops in write-retry from mis-resetting the subreq iterator
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 4481f7f2b3df123ec77e828c849138f75cff2bf2 ]
+
+Fix the resetting of the subrequest iterator in netfs_retry_write_stream()
+to use the iterator-reset function as the iterator may have been shortened
+by a previous retry.  In such a case, the amount of data to be written by
+the subrequest is not "subreq->len" but "subreq->len -
+subreq->transferred".
+
+Without this, KASAN may see an error in iov_iter_revert():
+
+   BUG: KASAN: slab-out-of-bounds in iov_iter_revert lib/iov_iter.c:633 [inline]
+   BUG: KASAN: slab-out-of-bounds in iov_iter_revert+0x443/0x5a0 lib/iov_iter.c:611
+   Read of size 4 at addr ffff88802912a0b8 by task kworker/u32:7/1147
+
+   CPU: 1 UID: 0 PID: 1147 Comm: kworker/u32:7 Not tainted 6.15.0-rc6-syzkaller-00052-g9f35e33144ae #0 PREEMPT(full)
+   Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014
+   Workqueue: events_unbound netfs_write_collection_worker
+   Call Trace:
+    <TASK>
+    __dump_stack lib/dump_stack.c:94 [inline]
+    dump_stack_lvl+0x116/0x1f0 lib/dump_stack.c:120
+    print_address_description mm/kasan/report.c:408 [inline]
+    print_report+0xc3/0x670 mm/kasan/report.c:521
+    kasan_report+0xe0/0x110 mm/kasan/report.c:634
+    iov_iter_revert lib/iov_iter.c:633 [inline]
+    iov_iter_revert+0x443/0x5a0 lib/iov_iter.c:611
+    netfs_retry_write_stream fs/netfs/write_retry.c:44 [inline]
+    netfs_retry_writes+0x166d/0x1a50 fs/netfs/write_retry.c:231
+    netfs_collect_write_results fs/netfs/write_collect.c:352 [inline]
+    netfs_write_collection_worker+0x23fd/0x3830 fs/netfs/write_collect.c:374
+    process_one_work+0x9cf/0x1b70 kernel/workqueue.c:3238
+    process_scheduled_works kernel/workqueue.c:3319 [inline]
+    worker_thread+0x6c8/0xf10 kernel/workqueue.c:3400
+    kthread+0x3c2/0x780 kernel/kthread.c:464
+    ret_from_fork+0x45/0x80 arch/x86/kernel/process.c:153
+    ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
+    </TASK>
+
+Fixes: cd0277ed0c18 ("netfs: Use new folio_queue data type and iterator instead of xarray iter")
+Reported-by: syzbot+25b83a6f2c702075fcbc@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=25b83a6f2c702075fcbc
+Signed-off-by: David Howells <dhowells@redhat.com>
+Link: https://lore.kernel.org/20250519090707.2848510-2-dhowells@redhat.com
+Tested-by: syzbot+25b83a6f2c702075fcbc@syzkaller.appspotmail.com
+cc: Paulo Alcantara <pc@manguebit.com>
+cc: netfs@lists.linux.dev
+cc: linux-fsdevel@vger.kernel.org
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/netfs/write_retry.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/fs/netfs/write_retry.c b/fs/netfs/write_retry.c
+index 545d33079a77d..9b1ca8b0f4dd6 100644
+--- a/fs/netfs/write_retry.c
++++ b/fs/netfs/write_retry.c
+@@ -39,9 +39,10 @@ static void netfs_retry_write_stream(struct netfs_io_request *wreq,
+                       if (test_bit(NETFS_SREQ_FAILED, &subreq->flags))
+                               break;
+                       if (__test_and_clear_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags)) {
+-                              struct iov_iter source = subreq->io_iter;
++                              struct iov_iter source;
+-                              iov_iter_revert(&source, subreq->len - source.count);
++                              netfs_reset_iter(subreq);
++                              source = subreq->io_iter;
+                               netfs_get_subrequest(subreq, netfs_sreq_trace_get_resubmit);
+                               netfs_reissue_write(stream, subreq, &source);
+                       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/netfs-fix-setting-of-transferred-bytes-with-short-di.patch b/queue-6.15/netfs-fix-setting-of-transferred-bytes-with-short-di.patch
new file mode 100644 (file)
index 0000000..0c7dd49
--- /dev/null
@@ -0,0 +1,117 @@
+From b5436a3a7a416dce6d43cf6df0ce6c81aa5b6a1a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 May 2025 10:07:02 +0100
+Subject: netfs: Fix setting of transferred bytes with short DIO reads
+
+From: Paulo Alcantara <pc@manguebit.com>
+
+[ Upstream commit 34eb98c6598c4057640ca56dd1fad6555187473a ]
+
+A netfslib request comprises an ordered stream of subrequests that, when
+doing an unbuffered/DIO read, are contiguous.  The subrequests may be
+performed in parallel, but may not be fully completed.
+
+For instance, if we try and make a 256KiB DIO read from a 3-byte file with
+a 64KiB rsize and 256KiB bsize, netfslib will attempt to make a read of
+256KiB, broken up into four 64KiB subreads, with the expectation that the
+first will be short and the subsequent three be completely devoid - but we
+do all four on the basis that the file may have been changed by a third
+party.
+
+The read-collection code, however, walks through all the subreqs and
+advances the notion of how much data has been read in the stream to the
+start of each subreq plus its amount transferred (which are 3, 0, 0, 0 for
+the example above) - which gives an amount apparently read of 3*64KiB -
+which is incorrect.
+
+Fix the collection code to cut short the calculation of the transferred
+amount with the first short subrequest in an unbuffered read; everything
+beyond that must be ignored as there's a hole that cannot be filled.  This
+applies both to shortness due to hitting the EOF and shortness due to an
+error.
+
+This is achieved by setting a flag on the request when we collect the first
+short subrequest (collection is done in ascending order).
+
+This can be tested by mounting a cifs volume with rsize=65536,bsize=262144
+and doing a 256k DIO read of a very small file (e.g. 3 bytes).  read()
+should return 3, not >3.
+
+This problem came in when netfs_read_collection() set rreq->transferred to
+stream->transferred, even for DIO.  Prior to that, netfs_rreq_assess_dio()
+just went over the list and added up the subreqs till it met a short one -
+but now the subreqs are discarded earlier.
+
+Fixes: e2d46f2ec332 ("netfs: Change the read result collector to only use one work item")
+Reported-by: Nicolas Baranger <nicolas.baranger@3xo.fr>
+Closes: https://lore.kernel.org/all/10bec2430ed4df68bde10ed95295d093@3xo.fr/
+Signed-off-by: "Paulo Alcantara (Red Hat)" <pc@manguebit.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Link: https://lore.kernel.org/20250519090707.2848510-3-dhowells@redhat.com
+cc: netfs@lists.linux.dev
+cc: linux-fsdevel@vger.kernel.org
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/netfs/read_collect.c | 21 +++++----------------
+ include/linux/netfs.h   |  1 +
+ 2 files changed, 6 insertions(+), 16 deletions(-)
+
+diff --git a/fs/netfs/read_collect.c b/fs/netfs/read_collect.c
+index 23c75755ad4ed..d3cf27b2697c3 100644
+--- a/fs/netfs/read_collect.c
++++ b/fs/netfs/read_collect.c
+@@ -280,9 +280,13 @@ static void netfs_collect_read_results(struct netfs_io_request *rreq)
+                       stream->need_retry = true;
+                       notes |= NEED_RETRY | MADE_PROGRESS;
+                       break;
++              } else if (test_bit(NETFS_RREQ_SHORT_TRANSFER, &rreq->flags)) {
++                      notes |= MADE_PROGRESS;
+               } else {
+                       if (!stream->failed)
+-                              stream->transferred = stream->collected_to - rreq->start;
++                              stream->transferred += transferred;
++                      if (front->transferred < front->len)
++                              set_bit(NETFS_RREQ_SHORT_TRANSFER, &rreq->flags);
+                       notes |= MADE_PROGRESS;
+               }
+@@ -342,23 +346,8 @@ static void netfs_collect_read_results(struct netfs_io_request *rreq)
+  */
+ static void netfs_rreq_assess_dio(struct netfs_io_request *rreq)
+ {
+-      struct netfs_io_subrequest *subreq;
+-      struct netfs_io_stream *stream = &rreq->io_streams[0];
+       unsigned int i;
+-      /* Collect unbuffered reads and direct reads, adding up the transfer
+-       * sizes until we find the first short or failed subrequest.
+-       */
+-      list_for_each_entry(subreq, &stream->subrequests, rreq_link) {
+-              rreq->transferred += subreq->transferred;
+-
+-              if (subreq->transferred < subreq->len ||
+-                  test_bit(NETFS_SREQ_FAILED, &subreq->flags)) {
+-                      rreq->error = subreq->error;
+-                      break;
+-              }
+-      }
+-
+       if (rreq->origin == NETFS_DIO_READ) {
+               for (i = 0; i < rreq->direct_bv_count; i++) {
+                       flush_dcache_page(rreq->direct_bv[i].bv_page);
+diff --git a/include/linux/netfs.h b/include/linux/netfs.h
+index c86a11cfc4a36..497c4f4698f6e 100644
+--- a/include/linux/netfs.h
++++ b/include/linux/netfs.h
+@@ -279,6 +279,7 @@ struct netfs_io_request {
+ #define NETFS_RREQ_USE_IO_ITER                12      /* Use ->io_iter rather than ->i_pages */
+ #define NETFS_RREQ_ALL_QUEUED         13      /* All subreqs are now queued */
+ #define NETFS_RREQ_RETRYING           14      /* Set if we're in the retry path */
++#define NETFS_RREQ_SHORT_TRANSFER     15      /* Set if we have a short transfer */
+ #define NETFS_RREQ_USE_PGPRIV2                31      /* [DEPRECATED] Use PG_private_2 to mark
+                                                * write to cache on read */
+       const struct netfs_request_ops *netfs_ops;
+-- 
+2.39.5
+
diff --git a/queue-6.15/netfs-fix-the-request-s-work-item-to-not-require-a-r.patch b/queue-6.15/netfs-fix-the-request-s-work-item-to-not-require-a-r.patch
new file mode 100644 (file)
index 0000000..2e7246d
--- /dev/null
@@ -0,0 +1,1248 @@
+From 058b55547c02df0370ef88257c7ae9106f3bedb9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 May 2025 10:07:03 +0100
+Subject: netfs: Fix the request's work item to not require a ref
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 20d72b00ca814d748f5663484e5c53bb2bf37a3a ]
+
+When the netfs_io_request struct's work item is queued, it must be supplied
+with a ref to the work item struct to prevent it being deallocated whilst
+on the queue or whilst it is being processed.  This is tricky to manage as
+we have to get a ref before we try and queue it and then we may find it's
+already queued and is thus already holding a ref - in which case we have to
+try and get rid of the ref again.
+
+The problem comes if we're in BH or IRQ context and need to drop the ref:
+if netfs_put_request() reduces the count to 0, we have to do the cleanup -
+but the cleanup may need to wait.
+
+Fix this by adding a new work item to the request, ->cleanup_work, and
+dispatching that when the refcount hits zero.  That can then synchronously
+cancel any outstanding work on the main work item before doing the cleanup.
+
+Adding a new work item also deals with another problem upstream where it's
+sometimes changing the work func in the put function and requeuing it -
+which has occasionally in the past caused the cleanup to happen
+incorrectly.
+
+As a bonus, this allows us to get rid of the 'was_async' parameter from a
+bunch of functions.  This indicated whether the put function might not be
+permitted to sleep.
+
+Fixes: 3d3c95046742 ("netfs: Provide readahead and readpage netfs helpers")
+Signed-off-by: David Howells <dhowells@redhat.com>
+Link: https://lore.kernel.org/20250519090707.2848510-4-dhowells@redhat.com
+cc: Paulo Alcantara <pc@manguebit.com>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: Steve French <stfrench@microsoft.com>
+cc: linux-cifs@vger.kernel.org
+cc: netfs@lists.linux.dev
+cc: linux-fsdevel@vger.kernel.org
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/9p/vfs_addr.c             |  2 +-
+ fs/afs/write.c               |  8 ++---
+ fs/cachefiles/io.c           | 16 +++++-----
+ fs/ceph/addr.c               |  2 +-
+ fs/erofs/fscache.c           |  6 ++--
+ fs/netfs/buffered_read.c     | 30 +++++++++---------
+ fs/netfs/direct_read.c       |  6 ++--
+ fs/netfs/direct_write.c      |  2 +-
+ fs/netfs/fscache_io.c        | 10 +++---
+ fs/netfs/internal.h          | 11 +++----
+ fs/netfs/objects.c           | 47 +++++++++++++--------------
+ fs/netfs/read_collect.c      | 44 ++++++++++++++++----------
+ fs/netfs/read_pgpriv2.c      |  4 +--
+ fs/netfs/read_retry.c        |  2 +-
+ fs/netfs/read_single.c       |  6 ++--
+ fs/netfs/write_collect.c     | 61 +++++++++++++++++-------------------
+ fs/netfs/write_issue.c       | 16 +++++-----
+ fs/netfs/write_retry.c       |  2 +-
+ fs/smb/client/cifsproto.h    |  3 +-
+ fs/smb/client/cifssmb.c      |  4 +--
+ fs/smb/client/file.c         |  7 ++---
+ fs/smb/client/smb2pdu.c      |  4 +--
+ include/linux/fscache.h      |  2 +-
+ include/linux/netfs.h        | 13 ++++----
+ include/trace/events/netfs.h |  7 ++---
+ net/9p/client.c              |  6 ++--
+ 26 files changed, 159 insertions(+), 162 deletions(-)
+
+diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c
+index 32619d146cbc1..b5a4a28e0fe79 100644
+--- a/fs/9p/vfs_addr.c
++++ b/fs/9p/vfs_addr.c
+@@ -59,7 +59,7 @@ static void v9fs_issue_write(struct netfs_io_subrequest *subreq)
+       len = p9_client_write(fid, subreq->start, &subreq->io_iter, &err);
+       if (len > 0)
+               __set_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags);
+-      netfs_write_subrequest_terminated(subreq, len ?: err, false);
++      netfs_write_subrequest_terminated(subreq, len ?: err);
+ }
+ /**
+diff --git a/fs/afs/write.c b/fs/afs/write.c
+index 18b0a9f1615e4..7df7b2f5e7b29 100644
+--- a/fs/afs/write.c
++++ b/fs/afs/write.c
+@@ -120,17 +120,17 @@ static void afs_issue_write_worker(struct work_struct *work)
+ #if 0 // Error injection
+       if (subreq->debug_index == 3)
+-              return netfs_write_subrequest_terminated(subreq, -ENOANO, false);
++              return netfs_write_subrequest_terminated(subreq, -ENOANO);
+       if (!subreq->retry_count) {
+               set_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags);
+-              return netfs_write_subrequest_terminated(subreq, -EAGAIN, false);
++              return netfs_write_subrequest_terminated(subreq, -EAGAIN);
+       }
+ #endif
+       op = afs_alloc_operation(wreq->netfs_priv, vnode->volume);
+       if (IS_ERR(op))
+-              return netfs_write_subrequest_terminated(subreq, -EAGAIN, false);
++              return netfs_write_subrequest_terminated(subreq, -EAGAIN);
+       afs_op_set_vnode(op, 0, vnode);
+       op->file[0].dv_delta    = 1;
+@@ -166,7 +166,7 @@ static void afs_issue_write_worker(struct work_struct *work)
+               break;
+       }
+-      netfs_write_subrequest_terminated(subreq, ret < 0 ? ret : subreq->len, false);
++      netfs_write_subrequest_terminated(subreq, ret < 0 ? ret : subreq->len);
+ }
+ void afs_issue_write(struct netfs_io_subrequest *subreq)
+diff --git a/fs/cachefiles/io.c b/fs/cachefiles/io.c
+index 92058ae434882..c08e4a66ac07a 100644
+--- a/fs/cachefiles/io.c
++++ b/fs/cachefiles/io.c
+@@ -63,7 +63,7 @@ static void cachefiles_read_complete(struct kiocb *iocb, long ret)
+                               ret = -ESTALE;
+               }
+-              ki->term_func(ki->term_func_priv, ret, ki->was_async);
++              ki->term_func(ki->term_func_priv, ret);
+       }
+       cachefiles_put_kiocb(ki);
+@@ -188,7 +188,7 @@ static int cachefiles_read(struct netfs_cache_resources *cres,
+ presubmission_error:
+       if (term_func)
+-              term_func(term_func_priv, ret < 0 ? ret : skipped, false);
++              term_func(term_func_priv, ret < 0 ? ret : skipped);
+       return ret;
+ }
+@@ -271,7 +271,7 @@ static void cachefiles_write_complete(struct kiocb *iocb, long ret)
+       atomic_long_sub(ki->b_writing, &object->volume->cache->b_writing);
+       set_bit(FSCACHE_COOKIE_HAVE_DATA, &object->cookie->flags);
+       if (ki->term_func)
+-              ki->term_func(ki->term_func_priv, ret, ki->was_async);
++              ki->term_func(ki->term_func_priv, ret);
+       cachefiles_put_kiocb(ki);
+ }
+@@ -301,7 +301,7 @@ int __cachefiles_write(struct cachefiles_object *object,
+       ki = kzalloc(sizeof(struct cachefiles_kiocb), GFP_KERNEL);
+       if (!ki) {
+               if (term_func)
+-                      term_func(term_func_priv, -ENOMEM, false);
++                      term_func(term_func_priv, -ENOMEM);
+               return -ENOMEM;
+       }
+@@ -366,7 +366,7 @@ static int cachefiles_write(struct netfs_cache_resources *cres,
+ {
+       if (!fscache_wait_for_operation(cres, FSCACHE_WANT_WRITE)) {
+               if (term_func)
+-                      term_func(term_func_priv, -ENOBUFS, false);
++                      term_func(term_func_priv, -ENOBUFS);
+               trace_netfs_sreq(term_func_priv, netfs_sreq_trace_cache_nowrite);
+               return -ENOBUFS;
+       }
+@@ -665,7 +665,7 @@ static void cachefiles_issue_write(struct netfs_io_subrequest *subreq)
+               pre = CACHEFILES_DIO_BLOCK_SIZE - off;
+               if (pre >= len) {
+                       fscache_count_dio_misfit();
+-                      netfs_write_subrequest_terminated(subreq, len, false);
++                      netfs_write_subrequest_terminated(subreq, len);
+                       return;
+               }
+               subreq->transferred += pre;
+@@ -691,7 +691,7 @@ static void cachefiles_issue_write(struct netfs_io_subrequest *subreq)
+               len -= post;
+               if (len == 0) {
+                       fscache_count_dio_misfit();
+-                      netfs_write_subrequest_terminated(subreq, post, false);
++                      netfs_write_subrequest_terminated(subreq, post);
+                       return;
+               }
+               iov_iter_truncate(&subreq->io_iter, len);
+@@ -703,7 +703,7 @@ static void cachefiles_issue_write(struct netfs_io_subrequest *subreq)
+                                        &start, &len, len, true);
+       cachefiles_end_secure(cache, saved_cred);
+       if (ret < 0) {
+-              netfs_write_subrequest_terminated(subreq, ret, false);
++              netfs_write_subrequest_terminated(subreq, ret);
+               return;
+       }
+diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
+index 29be367905a16..557c326561fdc 100644
+--- a/fs/ceph/addr.c
++++ b/fs/ceph/addr.c
+@@ -539,7 +539,7 @@ static void ceph_set_page_fscache(struct page *page)
+       folio_start_private_2(page_folio(page)); /* [DEPRECATED] */
+ }
+-static void ceph_fscache_write_terminated(void *priv, ssize_t error, bool was_async)
++static void ceph_fscache_write_terminated(void *priv, ssize_t error)
+ {
+       struct inode *inode = priv;
+diff --git a/fs/erofs/fscache.c b/fs/erofs/fscache.c
+index 9c9129bca3460..34517ca9df915 100644
+--- a/fs/erofs/fscache.c
++++ b/fs/erofs/fscache.c
+@@ -102,8 +102,7 @@ static void erofs_fscache_req_io_put(struct erofs_fscache_io *io)
+               erofs_fscache_req_put(req);
+ }
+-static void erofs_fscache_req_end_io(void *priv,
+-              ssize_t transferred_or_error, bool was_async)
++static void erofs_fscache_req_end_io(void *priv, ssize_t transferred_or_error)
+ {
+       struct erofs_fscache_io *io = priv;
+       struct erofs_fscache_rq *req = io->private;
+@@ -180,8 +179,7 @@ struct erofs_fscache_bio {
+       struct bio_vec bvecs[BIO_MAX_VECS];
+ };
+-static void erofs_fscache_bio_endio(void *priv,
+-              ssize_t transferred_or_error, bool was_async)
++static void erofs_fscache_bio_endio(void *priv, ssize_t transferred_or_error)
+ {
+       struct erofs_fscache_bio *io = priv;
+diff --git a/fs/netfs/buffered_read.c b/fs/netfs/buffered_read.c
+index 0d1b6d35ff3b8..cb6202efc4668 100644
+--- a/fs/netfs/buffered_read.c
++++ b/fs/netfs/buffered_read.c
+@@ -262,9 +262,9 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq)
+                               if (ret < 0) {
+                                       subreq->error = ret;
+                                       /* Not queued - release both refs. */
+-                                      netfs_put_subrequest(subreq, false,
++                                      netfs_put_subrequest(subreq,
+                                                            netfs_sreq_trace_put_cancel);
+-                                      netfs_put_subrequest(subreq, false,
++                                      netfs_put_subrequest(subreq,
+                                                            netfs_sreq_trace_put_cancel);
+                                       break;
+                               }
+@@ -297,8 +297,8 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq)
+                       subreq->error = ret;
+                       trace_netfs_sreq(subreq, netfs_sreq_trace_cancel);
+                       /* Not queued - release both refs. */
+-                      netfs_put_subrequest(subreq, false, netfs_sreq_trace_put_cancel);
+-                      netfs_put_subrequest(subreq, false, netfs_sreq_trace_put_cancel);
++                      netfs_put_subrequest(subreq, netfs_sreq_trace_put_cancel);
++                      netfs_put_subrequest(subreq, netfs_sreq_trace_put_cancel);
+                       break;
+               }
+               size -= slice;
+@@ -365,12 +365,10 @@ void netfs_readahead(struct readahead_control *ractl)
+               goto cleanup_free;
+       netfs_read_to_pagecache(rreq);
+-      netfs_put_request(rreq, true, netfs_rreq_trace_put_return);
+-      return;
++      return netfs_put_request(rreq, netfs_rreq_trace_put_return);
+ cleanup_free:
+-      netfs_put_request(rreq, false, netfs_rreq_trace_put_failed);
+-      return;
++      return netfs_put_request(rreq, netfs_rreq_trace_put_failed);
+ }
+ EXPORT_SYMBOL(netfs_readahead);
+@@ -470,11 +468,11 @@ static int netfs_read_gaps(struct file *file, struct folio *folio)
+               folio_mark_uptodate(folio);
+       }
+       folio_unlock(folio);
+-      netfs_put_request(rreq, false, netfs_rreq_trace_put_return);
++      netfs_put_request(rreq, netfs_rreq_trace_put_return);
+       return ret < 0 ? ret : 0;
+ discard:
+-      netfs_put_request(rreq, false, netfs_rreq_trace_put_discard);
++      netfs_put_request(rreq, netfs_rreq_trace_put_discard);
+ alloc_error:
+       folio_unlock(folio);
+       return ret;
+@@ -530,11 +528,11 @@ int netfs_read_folio(struct file *file, struct folio *folio)
+       netfs_read_to_pagecache(rreq);
+       ret = netfs_wait_for_read(rreq);
+-      netfs_put_request(rreq, false, netfs_rreq_trace_put_return);
++      netfs_put_request(rreq, netfs_rreq_trace_put_return);
+       return ret < 0 ? ret : 0;
+ discard:
+-      netfs_put_request(rreq, false, netfs_rreq_trace_put_discard);
++      netfs_put_request(rreq, netfs_rreq_trace_put_discard);
+ alloc_error:
+       folio_unlock(folio);
+       return ret;
+@@ -689,7 +687,7 @@ int netfs_write_begin(struct netfs_inode *ctx,
+       ret = netfs_wait_for_read(rreq);
+       if (ret < 0)
+               goto error;
+-      netfs_put_request(rreq, false, netfs_rreq_trace_put_return);
++      netfs_put_request(rreq, netfs_rreq_trace_put_return);
+ have_folio:
+       ret = folio_wait_private_2_killable(folio);
+@@ -701,7 +699,7 @@ int netfs_write_begin(struct netfs_inode *ctx,
+       return 0;
+ error_put:
+-      netfs_put_request(rreq, false, netfs_rreq_trace_put_failed);
++      netfs_put_request(rreq, netfs_rreq_trace_put_failed);
+ error:
+       if (folio) {
+               folio_unlock(folio);
+@@ -752,11 +750,11 @@ int netfs_prefetch_for_write(struct file *file, struct folio *folio,
+       netfs_read_to_pagecache(rreq);
+       ret = netfs_wait_for_read(rreq);
+-      netfs_put_request(rreq, false, netfs_rreq_trace_put_return);
++      netfs_put_request(rreq, netfs_rreq_trace_put_return);
+       return ret < 0 ? ret : 0;
+ error_put:
+-      netfs_put_request(rreq, false, netfs_rreq_trace_put_discard);
++      netfs_put_request(rreq, netfs_rreq_trace_put_discard);
+ error:
+       _leave(" = %d", ret);
+       return ret;
+diff --git a/fs/netfs/direct_read.c b/fs/netfs/direct_read.c
+index 5e3f0aeb51f31..cb3c6dc0b1654 100644
+--- a/fs/netfs/direct_read.c
++++ b/fs/netfs/direct_read.c
+@@ -85,7 +85,7 @@ static int netfs_dispatch_unbuffered_reads(struct netfs_io_request *rreq)
+               if (rreq->netfs_ops->prepare_read) {
+                       ret = rreq->netfs_ops->prepare_read(subreq);
+                       if (ret < 0) {
+-                              netfs_put_subrequest(subreq, false, netfs_sreq_trace_put_cancel);
++                              netfs_put_subrequest(subreq, netfs_sreq_trace_put_cancel);
+                               break;
+                       }
+               }
+@@ -144,7 +144,7 @@ static ssize_t netfs_unbuffered_read(struct netfs_io_request *rreq, bool sync)
+       ret = netfs_dispatch_unbuffered_reads(rreq);
+       if (!rreq->submitted) {
+-              netfs_put_request(rreq, false, netfs_rreq_trace_put_no_submit);
++              netfs_put_request(rreq, netfs_rreq_trace_put_no_submit);
+               inode_dio_end(rreq->inode);
+               ret = 0;
+               goto out;
+@@ -236,7 +236,7 @@ ssize_t netfs_unbuffered_read_iter_locked(struct kiocb *iocb, struct iov_iter *i
+       }
+ out:
+-      netfs_put_request(rreq, false, netfs_rreq_trace_put_return);
++      netfs_put_request(rreq, netfs_rreq_trace_put_return);
+       if (ret > 0)
+               orig_count -= ret;
+       return ret;
+diff --git a/fs/netfs/direct_write.c b/fs/netfs/direct_write.c
+index 42ce53cc216e9..c98f1676f86df 100644
+--- a/fs/netfs/direct_write.c
++++ b/fs/netfs/direct_write.c
+@@ -117,7 +117,7 @@ ssize_t netfs_unbuffered_write_iter_locked(struct kiocb *iocb, struct iov_iter *
+       }
+ out:
+-      netfs_put_request(wreq, false, netfs_rreq_trace_put_return);
++      netfs_put_request(wreq, netfs_rreq_trace_put_return);
+       return ret;
+ }
+ EXPORT_SYMBOL(netfs_unbuffered_write_iter_locked);
+diff --git a/fs/netfs/fscache_io.c b/fs/netfs/fscache_io.c
+index b1722a82c03d3..e4308457633ca 100644
+--- a/fs/netfs/fscache_io.c
++++ b/fs/netfs/fscache_io.c
+@@ -192,8 +192,7 @@ EXPORT_SYMBOL(__fscache_clear_page_bits);
+ /*
+  * Deal with the completion of writing the data to the cache.
+  */
+-static void fscache_wreq_done(void *priv, ssize_t transferred_or_error,
+-                            bool was_async)
++static void fscache_wreq_done(void *priv, ssize_t transferred_or_error)
+ {
+       struct fscache_write_request *wreq = priv;
+@@ -202,8 +201,7 @@ static void fscache_wreq_done(void *priv, ssize_t transferred_or_error,
+                                       wreq->set_bits);
+       if (wreq->term_func)
+-              wreq->term_func(wreq->term_func_priv, transferred_or_error,
+-                              was_async);
++              wreq->term_func(wreq->term_func_priv, transferred_or_error);
+       fscache_end_operation(&wreq->cache_resources);
+       kfree(wreq);
+ }
+@@ -255,14 +253,14 @@ void __fscache_write_to_cache(struct fscache_cookie *cookie,
+       return;
+ abandon_end:
+-      return fscache_wreq_done(wreq, ret, false);
++      return fscache_wreq_done(wreq, ret);
+ abandon_free:
+       kfree(wreq);
+ abandon:
+       if (using_pgpriv2)
+               fscache_clear_page_bits(mapping, start, len, cond);
+       if (term_func)
+-              term_func(term_func_priv, ret, false);
++              term_func(term_func_priv, ret);
+ }
+ EXPORT_SYMBOL(__fscache_write_to_cache);
+diff --git a/fs/netfs/internal.h b/fs/netfs/internal.h
+index 1c4f953c3d683..b6500a7cda81d 100644
+--- a/fs/netfs/internal.h
++++ b/fs/netfs/internal.h
+@@ -23,7 +23,7 @@
+ /*
+  * buffered_read.c
+  */
+-void netfs_cache_read_terminated(void *priv, ssize_t transferred_or_error, bool was_async);
++void netfs_cache_read_terminated(void *priv, ssize_t transferred_or_error);
+ int netfs_prefetch_for_write(struct file *file, struct folio *folio,
+                            size_t offset, size_t len);
+@@ -71,9 +71,8 @@ struct netfs_io_request *netfs_alloc_request(struct address_space *mapping,
+                                            loff_t start, size_t len,
+                                            enum netfs_io_origin origin);
+ void netfs_get_request(struct netfs_io_request *rreq, enum netfs_rreq_ref_trace what);
+-void netfs_clear_subrequests(struct netfs_io_request *rreq, bool was_async);
+-void netfs_put_request(struct netfs_io_request *rreq, bool was_async,
+-                     enum netfs_rreq_ref_trace what);
++void netfs_clear_subrequests(struct netfs_io_request *rreq);
++void netfs_put_request(struct netfs_io_request *rreq, enum netfs_rreq_ref_trace what);
+ struct netfs_io_subrequest *netfs_alloc_subrequest(struct netfs_io_request *rreq);
+ static inline void netfs_see_request(struct netfs_io_request *rreq,
+@@ -94,7 +93,7 @@ static inline void netfs_see_subrequest(struct netfs_io_subrequest *subreq,
+  */
+ void netfs_read_collection_worker(struct work_struct *work);
+ void netfs_wake_read_collector(struct netfs_io_request *rreq);
+-void netfs_cache_read_terminated(void *priv, ssize_t transferred_or_error, bool was_async);
++void netfs_cache_read_terminated(void *priv, ssize_t transferred_or_error);
+ ssize_t netfs_wait_for_read(struct netfs_io_request *rreq);
+ void netfs_wait_for_pause(struct netfs_io_request *rreq);
+@@ -177,7 +176,7 @@ static inline void netfs_stat_d(atomic_t *stat)
+  */
+ int netfs_folio_written_back(struct folio *folio);
+ void netfs_write_collection_worker(struct work_struct *work);
+-void netfs_wake_write_collector(struct netfs_io_request *wreq, bool was_async);
++void netfs_wake_write_collector(struct netfs_io_request *wreq);
+ /*
+  * write_issue.c
+diff --git a/fs/netfs/objects.c b/fs/netfs/objects.c
+index dc6b41ef18b09..d3eb9ba3013a7 100644
+--- a/fs/netfs/objects.c
++++ b/fs/netfs/objects.c
+@@ -10,6 +10,8 @@
+ #include <linux/delay.h>
+ #include "internal.h"
++static void netfs_free_request(struct work_struct *work);
++
+ /*
+  * Allocate an I/O request and initialise it.
+  */
+@@ -34,6 +36,7 @@ struct netfs_io_request *netfs_alloc_request(struct address_space *mapping,
+       }
+       memset(rreq, 0, kmem_cache_size(cache));
++      INIT_WORK(&rreq->cleanup_work, netfs_free_request);
+       rreq->start     = start;
+       rreq->len       = len;
+       rreq->origin    = origin;
+@@ -49,7 +52,7 @@ struct netfs_io_request *netfs_alloc_request(struct address_space *mapping,
+       INIT_LIST_HEAD(&rreq->io_streams[0].subrequests);
+       INIT_LIST_HEAD(&rreq->io_streams[1].subrequests);
+       init_waitqueue_head(&rreq->waitq);
+-      refcount_set(&rreq->ref, 1);
++      refcount_set(&rreq->ref, 2);
+       if (origin == NETFS_READAHEAD ||
+           origin == NETFS_READPAGE ||
+@@ -63,7 +66,9 @@ struct netfs_io_request *netfs_alloc_request(struct address_space *mapping,
+               INIT_WORK(&rreq->work, netfs_write_collection_worker);
+       }
++      /* The IN_PROGRESS flag comes with a ref. */
+       __set_bit(NETFS_RREQ_IN_PROGRESS, &rreq->flags);
++
+       if (file && file->f_flags & O_NONBLOCK)
+               __set_bit(NETFS_RREQ_NONBLOCK, &rreq->flags);
+       if (rreq->netfs_ops->init_request) {
+@@ -75,7 +80,7 @@ struct netfs_io_request *netfs_alloc_request(struct address_space *mapping,
+       }
+       atomic_inc(&ctx->io_count);
+-      trace_netfs_rreq_ref(rreq->debug_id, 1, netfs_rreq_trace_new);
++      trace_netfs_rreq_ref(rreq->debug_id, refcount_read(&rreq->ref), netfs_rreq_trace_new);
+       netfs_proc_add_rreq(rreq);
+       netfs_stat(&netfs_n_rh_rreq);
+       return rreq;
+@@ -89,7 +94,7 @@ void netfs_get_request(struct netfs_io_request *rreq, enum netfs_rreq_ref_trace
+       trace_netfs_rreq_ref(rreq->debug_id, r + 1, what);
+ }
+-void netfs_clear_subrequests(struct netfs_io_request *rreq, bool was_async)
++void netfs_clear_subrequests(struct netfs_io_request *rreq)
+ {
+       struct netfs_io_subrequest *subreq;
+       struct netfs_io_stream *stream;
+@@ -101,8 +106,7 @@ void netfs_clear_subrequests(struct netfs_io_request *rreq, bool was_async)
+                       subreq = list_first_entry(&stream->subrequests,
+                                                 struct netfs_io_subrequest, rreq_link);
+                       list_del(&subreq->rreq_link);
+-                      netfs_put_subrequest(subreq, was_async,
+-                                           netfs_sreq_trace_put_clear);
++                      netfs_put_subrequest(subreq, netfs_sreq_trace_put_clear);
+               }
+       }
+ }
+@@ -118,13 +122,19 @@ static void netfs_free_request_rcu(struct rcu_head *rcu)
+ static void netfs_free_request(struct work_struct *work)
+ {
+       struct netfs_io_request *rreq =
+-              container_of(work, struct netfs_io_request, work);
++              container_of(work, struct netfs_io_request, cleanup_work);
+       struct netfs_inode *ictx = netfs_inode(rreq->inode);
+       unsigned int i;
+       trace_netfs_rreq(rreq, netfs_rreq_trace_free);
++
++      /* Cancel/flush the result collection worker.  That does not carry a
++       * ref of its own, so we must wait for it somewhere.
++       */
++      cancel_work_sync(&rreq->work);
++
+       netfs_proc_del_rreq(rreq);
+-      netfs_clear_subrequests(rreq, false);
++      netfs_clear_subrequests(rreq);
+       if (rreq->netfs_ops->free_request)
+               rreq->netfs_ops->free_request(rreq);
+       if (rreq->cache_resources.ops)
+@@ -145,8 +155,7 @@ static void netfs_free_request(struct work_struct *work)
+       call_rcu(&rreq->rcu, netfs_free_request_rcu);
+ }
+-void netfs_put_request(struct netfs_io_request *rreq, bool was_async,
+-                     enum netfs_rreq_ref_trace what)
++void netfs_put_request(struct netfs_io_request *rreq, enum netfs_rreq_ref_trace what)
+ {
+       unsigned int debug_id;
+       bool dead;
+@@ -156,15 +165,8 @@ void netfs_put_request(struct netfs_io_request *rreq, bool was_async,
+               debug_id = rreq->debug_id;
+               dead = __refcount_dec_and_test(&rreq->ref, &r);
+               trace_netfs_rreq_ref(debug_id, r - 1, what);
+-              if (dead) {
+-                      if (was_async) {
+-                              rreq->work.func = netfs_free_request;
+-                              if (!queue_work(system_unbound_wq, &rreq->work))
+-                                      WARN_ON(1);
+-                      } else {
+-                              netfs_free_request(&rreq->work);
+-                      }
+-              }
++              if (dead)
++                      WARN_ON(!queue_work(system_unbound_wq, &rreq->cleanup_work));
+       }
+ }
+@@ -206,8 +208,7 @@ void netfs_get_subrequest(struct netfs_io_subrequest *subreq,
+                            what);
+ }
+-static void netfs_free_subrequest(struct netfs_io_subrequest *subreq,
+-                                bool was_async)
++static void netfs_free_subrequest(struct netfs_io_subrequest *subreq)
+ {
+       struct netfs_io_request *rreq = subreq->rreq;
+@@ -216,10 +217,10 @@ static void netfs_free_subrequest(struct netfs_io_subrequest *subreq,
+               rreq->netfs_ops->free_subrequest(subreq);
+       mempool_free(subreq, rreq->netfs_ops->subrequest_pool ?: &netfs_subrequest_pool);
+       netfs_stat_d(&netfs_n_rh_sreq);
+-      netfs_put_request(rreq, was_async, netfs_rreq_trace_put_subreq);
++      netfs_put_request(rreq, netfs_rreq_trace_put_subreq);
+ }
+-void netfs_put_subrequest(struct netfs_io_subrequest *subreq, bool was_async,
++void netfs_put_subrequest(struct netfs_io_subrequest *subreq,
+                         enum netfs_sreq_ref_trace what)
+ {
+       unsigned int debug_index = subreq->debug_index;
+@@ -230,5 +231,5 @@ void netfs_put_subrequest(struct netfs_io_subrequest *subreq, bool was_async,
+       dead = __refcount_dec_and_test(&subreq->ref, &r);
+       trace_netfs_sreq_ref(debug_id, debug_index, r - 1, what);
+       if (dead)
+-              netfs_free_subrequest(subreq, was_async);
++              netfs_free_subrequest(subreq);
+ }
+diff --git a/fs/netfs/read_collect.c b/fs/netfs/read_collect.c
+index d3cf27b2697c3..1197ebce56757 100644
+--- a/fs/netfs/read_collect.c
++++ b/fs/netfs/read_collect.c
+@@ -301,7 +301,7 @@ static void netfs_collect_read_results(struct netfs_io_request *rreq)
+                                                struct netfs_io_subrequest, rreq_link);
+               stream->front = front;
+               spin_unlock(&rreq->lock);
+-              netfs_put_subrequest(remove, false,
++              netfs_put_subrequest(remove,
+                                    notes & ABANDON_SREQ ?
+                                    netfs_sreq_trace_put_abandon :
+                                    netfs_sreq_trace_put_done);
+@@ -399,7 +399,7 @@ static void netfs_rreq_assess_single(struct netfs_io_request *rreq)
+  * Note that we're in normal kernel thread context at this point, possibly
+  * running on a workqueue.
+  */
+-static void netfs_read_collection(struct netfs_io_request *rreq)
++static bool netfs_read_collection(struct netfs_io_request *rreq)
+ {
+       struct netfs_io_stream *stream = &rreq->io_streams[0];
+@@ -409,11 +409,11 @@ static void netfs_read_collection(struct netfs_io_request *rreq)
+        * queue is empty.
+        */
+       if (!test_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags))
+-              return;
++              return false;
+       smp_rmb(); /* Read ALL_QUEUED before subreq lists. */
+       if (!list_empty(&stream->subrequests))
+-              return;
++              return false;
+       /* Okay, declare that all I/O is complete. */
+       rreq->transferred = stream->transferred;
+@@ -436,12 +436,14 @@ static void netfs_read_collection(struct netfs_io_request *rreq)
+       trace_netfs_rreq(rreq, netfs_rreq_trace_wake_ip);
+       clear_and_wake_up_bit(NETFS_RREQ_IN_PROGRESS, &rreq->flags);
++      /* As we cleared NETFS_RREQ_IN_PROGRESS, we acquired its ref. */
+       trace_netfs_rreq(rreq, netfs_rreq_trace_done);
+-      netfs_clear_subrequests(rreq, false);
++      netfs_clear_subrequests(rreq);
+       netfs_unlock_abandoned_read_pages(rreq);
+       if (unlikely(rreq->copy_to_cache))
+               netfs_pgpriv2_end_copy_to_cache(rreq);
++      return true;
+ }
+ void netfs_read_collection_worker(struct work_struct *work)
+@@ -449,9 +451,13 @@ void netfs_read_collection_worker(struct work_struct *work)
+       struct netfs_io_request *rreq = container_of(work, struct netfs_io_request, work);
+       netfs_see_request(rreq, netfs_rreq_trace_see_work);
+-      if (test_bit(NETFS_RREQ_IN_PROGRESS, &rreq->flags))
+-              netfs_read_collection(rreq);
+-      netfs_put_request(rreq, false, netfs_rreq_trace_put_work);
++      if (test_bit(NETFS_RREQ_IN_PROGRESS, &rreq->flags)) {
++              if (netfs_read_collection(rreq))
++                      /* Drop the ref from the IN_PROGRESS flag. */
++                      netfs_put_request(rreq, netfs_rreq_trace_put_work_ip);
++              else
++                      netfs_see_request(rreq, netfs_rreq_trace_see_work_complete);
++      }
+ }
+ /*
+@@ -461,11 +467,7 @@ void netfs_wake_read_collector(struct netfs_io_request *rreq)
+ {
+       if (test_bit(NETFS_RREQ_OFFLOAD_COLLECTION, &rreq->flags) &&
+           !test_bit(NETFS_RREQ_RETRYING, &rreq->flags)) {
+-              if (!work_pending(&rreq->work)) {
+-                      netfs_get_request(rreq, netfs_rreq_trace_get_work);
+-                      if (!queue_work(system_unbound_wq, &rreq->work))
+-                              netfs_put_request(rreq, true, netfs_rreq_trace_put_work_nq);
+-              }
++              queue_work(system_unbound_wq, &rreq->work);
+       } else {
+               trace_netfs_rreq(rreq, netfs_rreq_trace_wake_queue);
+               wake_up(&rreq->waitq);
+@@ -580,14 +582,14 @@ void netfs_read_subreq_terminated(struct netfs_io_subrequest *subreq)
+           test_bit(NETFS_RREQ_RETRYING, &rreq->flags))
+               netfs_wake_read_collector(rreq);
+-      netfs_put_subrequest(subreq, true, netfs_sreq_trace_put_terminated);
++      netfs_put_subrequest(subreq, netfs_sreq_trace_put_terminated);
+ }
+ EXPORT_SYMBOL(netfs_read_subreq_terminated);
+ /*
+  * Handle termination of a read from the cache.
+  */
+-void netfs_cache_read_terminated(void *priv, ssize_t transferred_or_error, bool was_async)
++void netfs_cache_read_terminated(void *priv, ssize_t transferred_or_error)
+ {
+       struct netfs_io_subrequest *subreq = priv;
+@@ -623,7 +625,11 @@ ssize_t netfs_wait_for_read(struct netfs_io_request *rreq)
+                   (!test_bit(NETFS_SREQ_IN_PROGRESS, &subreq->flags) ||
+                    test_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags))) {
+                       __set_current_state(TASK_RUNNING);
+-                      netfs_read_collection(rreq);
++                      if (netfs_read_collection(rreq)) {
++                              /* Drop the ref from the NETFS_RREQ_IN_PROGRESS flag. */
++                              netfs_put_request(rreq, netfs_rreq_trace_put_work_ip);
++                              break;
++                      }
+                       continue;
+               }
+@@ -678,7 +684,11 @@ void netfs_wait_for_pause(struct netfs_io_request *rreq)
+                           (!test_bit(NETFS_SREQ_IN_PROGRESS, &subreq->flags) ||
+                            test_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags))) {
+                               __set_current_state(TASK_RUNNING);
+-                              netfs_read_collection(rreq);
++                              if (netfs_read_collection(rreq)) {
++                                      /* Drop the ref from the NETFS_RREQ_IN_PROGRESS flag. */
++                                      netfs_put_request(rreq, netfs_rreq_trace_put_work_ip);
++                                      break;
++                              }
+                               continue;
+                       }
+               }
+diff --git a/fs/netfs/read_pgpriv2.c b/fs/netfs/read_pgpriv2.c
+index cf7727060215a..5bbe906a551d5 100644
+--- a/fs/netfs/read_pgpriv2.c
++++ b/fs/netfs/read_pgpriv2.c
+@@ -116,7 +116,7 @@ static struct netfs_io_request *netfs_pgpriv2_begin_copy_to_cache(
+       return creq;
+ cancel_put:
+-      netfs_put_request(creq, false, netfs_rreq_trace_put_return);
++      netfs_put_request(creq, netfs_rreq_trace_put_return);
+ cancel:
+       rreq->copy_to_cache = ERR_PTR(-ENOBUFS);
+       clear_bit(NETFS_RREQ_FOLIO_COPY_TO_CACHE, &rreq->flags);
+@@ -155,7 +155,7 @@ void netfs_pgpriv2_end_copy_to_cache(struct netfs_io_request *rreq)
+       smp_wmb(); /* Write lists before ALL_QUEUED. */
+       set_bit(NETFS_RREQ_ALL_QUEUED, &creq->flags);
+-      netfs_put_request(creq, false, netfs_rreq_trace_put_return);
++      netfs_put_request(creq, netfs_rreq_trace_put_return);
+       creq->copy_to_cache = NULL;
+ }
+diff --git a/fs/netfs/read_retry.c b/fs/netfs/read_retry.c
+index 0f294b26e08c9..1378dc7fa2ccd 100644
+--- a/fs/netfs/read_retry.c
++++ b/fs/netfs/read_retry.c
+@@ -173,7 +173,7 @@ static void netfs_retry_read_subrequests(struct netfs_io_request *rreq)
+                                                     &stream->subrequests, rreq_link) {
+                               trace_netfs_sreq(subreq, netfs_sreq_trace_superfluous);
+                               list_del(&subreq->rreq_link);
+-                              netfs_put_subrequest(subreq, false, netfs_sreq_trace_put_done);
++                              netfs_put_subrequest(subreq, netfs_sreq_trace_put_done);
+                               if (subreq == to)
+                                       break;
+                       }
+diff --git a/fs/netfs/read_single.c b/fs/netfs/read_single.c
+index fea0ecdecc539..fa622a6cd56da 100644
+--- a/fs/netfs/read_single.c
++++ b/fs/netfs/read_single.c
+@@ -142,7 +142,7 @@ static int netfs_single_dispatch_read(struct netfs_io_request *rreq)
+       set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
+       return ret;
+ cancel:
+-      netfs_put_subrequest(subreq, false, netfs_sreq_trace_put_cancel);
++      netfs_put_subrequest(subreq, netfs_sreq_trace_put_cancel);
+       return ret;
+ }
+@@ -185,11 +185,11 @@ ssize_t netfs_read_single(struct inode *inode, struct file *file, struct iov_ite
+       netfs_single_dispatch_read(rreq);
+       ret = netfs_wait_for_read(rreq);
+-      netfs_put_request(rreq, true, netfs_rreq_trace_put_return);
++      netfs_put_request(rreq, netfs_rreq_trace_put_return);
+       return ret;
+ cleanup_free:
+-      netfs_put_request(rreq, false, netfs_rreq_trace_put_failed);
++      netfs_put_request(rreq, netfs_rreq_trace_put_failed);
+       return ret;
+ }
+ EXPORT_SYMBOL(netfs_read_single);
+diff --git a/fs/netfs/write_collect.c b/fs/netfs/write_collect.c
+index 3fca59e6475d1..7241d1fd2c14a 100644
+--- a/fs/netfs/write_collect.c
++++ b/fs/netfs/write_collect.c
+@@ -280,7 +280,7 @@ static void netfs_collect_write_results(struct netfs_io_request *wreq)
+                                                        struct netfs_io_subrequest, rreq_link);
+                       stream->front = front;
+                       spin_unlock(&wreq->lock);
+-                      netfs_put_subrequest(remove, false,
++                      netfs_put_subrequest(remove,
+                                            notes & SAW_FAILURE ?
+                                            netfs_sreq_trace_put_cancel :
+                                            netfs_sreq_trace_put_done);
+@@ -356,30 +356,21 @@ static void netfs_collect_write_results(struct netfs_io_request *wreq)
+ /*
+  * Perform the collection of subrequests, folios and encryption buffers.
+  */
+-void netfs_write_collection_worker(struct work_struct *work)
++static bool netfs_write_collection(struct netfs_io_request *wreq)
+ {
+-      struct netfs_io_request *wreq = container_of(work, struct netfs_io_request, work);
+       struct netfs_inode *ictx = netfs_inode(wreq->inode);
+       size_t transferred;
+       int s;
+       _enter("R=%x", wreq->debug_id);
+-      netfs_see_request(wreq, netfs_rreq_trace_see_work);
+-      if (!test_bit(NETFS_RREQ_IN_PROGRESS, &wreq->flags)) {
+-              netfs_put_request(wreq, false, netfs_rreq_trace_put_work);
+-              return;
+-      }
+-
+       netfs_collect_write_results(wreq);
+       /* We're done when the app thread has finished posting subreqs and all
+        * the queues in all the streams are empty.
+        */
+-      if (!test_bit(NETFS_RREQ_ALL_QUEUED, &wreq->flags)) {
+-              netfs_put_request(wreq, false, netfs_rreq_trace_put_work);
+-              return;
+-      }
++      if (!test_bit(NETFS_RREQ_ALL_QUEUED, &wreq->flags))
++              return false;
+       smp_rmb(); /* Read ALL_QUEUED before lists. */
+       transferred = LONG_MAX;
+@@ -387,10 +378,8 @@ void netfs_write_collection_worker(struct work_struct *work)
+               struct netfs_io_stream *stream = &wreq->io_streams[s];
+               if (!stream->active)
+                       continue;
+-              if (!list_empty(&stream->subrequests)) {
+-                      netfs_put_request(wreq, false, netfs_rreq_trace_put_work);
+-                      return;
+-              }
++              if (!list_empty(&stream->subrequests))
++                      return false;
+               if (stream->transferred < transferred)
+                       transferred = stream->transferred;
+       }
+@@ -430,6 +419,7 @@ void netfs_write_collection_worker(struct work_struct *work)
+       _debug("finished");
+       trace_netfs_rreq(wreq, netfs_rreq_trace_wake_ip);
+       clear_and_wake_up_bit(NETFS_RREQ_IN_PROGRESS, &wreq->flags);
++      /* As we cleared NETFS_RREQ_IN_PROGRESS, we acquired its ref. */
+       if (wreq->iocb) {
+               size_t written = min(wreq->transferred, wreq->len);
+@@ -440,27 +430,36 @@ void netfs_write_collection_worker(struct work_struct *work)
+               wreq->iocb = VFS_PTR_POISON;
+       }
+-      netfs_clear_subrequests(wreq, false);
+-      netfs_put_request(wreq, false, netfs_rreq_trace_put_work_complete);
++      netfs_clear_subrequests(wreq);
++      return true;
++}
++
++void netfs_write_collection_worker(struct work_struct *work)
++{
++      struct netfs_io_request *rreq = container_of(work, struct netfs_io_request, work);
++
++      netfs_see_request(rreq, netfs_rreq_trace_see_work);
++      if (test_bit(NETFS_RREQ_IN_PROGRESS, &rreq->flags)) {
++              if (netfs_write_collection(rreq))
++                      /* Drop the ref from the IN_PROGRESS flag. */
++                      netfs_put_request(rreq, netfs_rreq_trace_put_work_ip);
++              else
++                      netfs_see_request(rreq, netfs_rreq_trace_see_work_complete);
++      }
+ }
+ /*
+  * Wake the collection work item.
+  */
+-void netfs_wake_write_collector(struct netfs_io_request *wreq, bool was_async)
++void netfs_wake_write_collector(struct netfs_io_request *wreq)
+ {
+-      if (!work_pending(&wreq->work)) {
+-              netfs_get_request(wreq, netfs_rreq_trace_get_work);
+-              if (!queue_work(system_unbound_wq, &wreq->work))
+-                      netfs_put_request(wreq, was_async, netfs_rreq_trace_put_work_nq);
+-      }
++      queue_work(system_unbound_wq, &wreq->work);
+ }
+ /**
+  * netfs_write_subrequest_terminated - Note the termination of a write operation.
+  * @_op: The I/O request that has terminated.
+  * @transferred_or_error: The amount of data transferred or an error code.
+- * @was_async: The termination was asynchronous
+  *
+  * This tells the library that a contributory write I/O operation has
+  * terminated, one way or another, and that it should collect the results.
+@@ -470,17 +469,13 @@ void netfs_wake_write_collector(struct netfs_io_request *wreq, bool was_async)
+  * negative error code.  The library will look after reissuing I/O operations
+  * as appropriate and writing downloaded data to the cache.
+  *
+- * If @was_async is true, the caller might be running in softirq or interrupt
+- * context and we can't sleep.
+- *
+  * When this is called, ownership of the subrequest is transferred back to the
+  * library, along with a ref.
+  *
+  * Note that %_op is a void* so that the function can be passed to
+  * kiocb::term_func without the need for a casting wrapper.
+  */
+-void netfs_write_subrequest_terminated(void *_op, ssize_t transferred_or_error,
+-                                     bool was_async)
++void netfs_write_subrequest_terminated(void *_op, ssize_t transferred_or_error)
+ {
+       struct netfs_io_subrequest *subreq = _op;
+       struct netfs_io_request *wreq = subreq->rreq;
+@@ -543,8 +538,8 @@ void netfs_write_subrequest_terminated(void *_op, ssize_t transferred_or_error,
+        * transferring a ref to it if we were the ones to do so.
+        */
+       if (list_is_first(&subreq->rreq_link, &stream->subrequests))
+-              netfs_wake_write_collector(wreq, was_async);
++              netfs_wake_write_collector(wreq);
+-      netfs_put_subrequest(subreq, was_async, netfs_sreq_trace_put_terminated);
++      netfs_put_subrequest(subreq, netfs_sreq_trace_put_terminated);
+ }
+ EXPORT_SYMBOL(netfs_write_subrequest_terminated);
+diff --git a/fs/netfs/write_issue.c b/fs/netfs/write_issue.c
+index 77279fc5b5a7c..8744ed3faf29b 100644
+--- a/fs/netfs/write_issue.c
++++ b/fs/netfs/write_issue.c
+@@ -134,7 +134,7 @@ struct netfs_io_request *netfs_create_write_req(struct address_space *mapping,
+       return wreq;
+ nomem:
+       wreq->error = -ENOMEM;
+-      netfs_put_request(wreq, false, netfs_rreq_trace_put_failed);
++      netfs_put_request(wreq, netfs_rreq_trace_put_failed);
+       return ERR_PTR(-ENOMEM);
+ }
+@@ -233,7 +233,7 @@ static void netfs_do_issue_write(struct netfs_io_stream *stream,
+       _enter("R=%x[%x],%zx", wreq->debug_id, subreq->debug_index, subreq->len);
+       if (test_bit(NETFS_SREQ_FAILED, &subreq->flags))
+-              return netfs_write_subrequest_terminated(subreq, subreq->error, false);
++              return netfs_write_subrequest_terminated(subreq, subreq->error);
+       trace_netfs_sreq(subreq, netfs_sreq_trace_submit);
+       stream->issue_write(subreq);
+@@ -542,7 +542,7 @@ static void netfs_end_issue_write(struct netfs_io_request *wreq)
+       }
+       if (needs_poke)
+-              netfs_wake_write_collector(wreq, false);
++              netfs_wake_write_collector(wreq);
+ }
+ /*
+@@ -599,8 +599,9 @@ int netfs_writepages(struct address_space *mapping,
+       netfs_end_issue_write(wreq);
+       mutex_unlock(&ictx->wb_lock);
++      netfs_wake_write_collector(wreq);
+-      netfs_put_request(wreq, false, netfs_rreq_trace_put_return);
++      netfs_put_request(wreq, netfs_rreq_trace_put_return);
+       _leave(" = %d", error);
+       return error;
+@@ -694,7 +695,7 @@ int netfs_end_writethrough(struct netfs_io_request *wreq, struct writeback_contr
+               wait_on_bit(&wreq->flags, NETFS_RREQ_IN_PROGRESS, TASK_UNINTERRUPTIBLE);
+               ret = wreq->error;
+       }
+-      netfs_put_request(wreq, false, netfs_rreq_trace_put_return);
++      netfs_put_request(wreq, netfs_rreq_trace_put_return);
+       return ret;
+ }
+@@ -885,7 +886,7 @@ int netfs_writeback_single(struct address_space *mapping,
+               goto couldnt_start;
+       }
+-      trace_netfs_write(wreq, netfs_write_trace_writeback);
++      trace_netfs_write(wreq, netfs_write_trace_writeback_single);
+       netfs_stat(&netfs_n_wh_writepages);
+       if (__test_and_set_bit(NETFS_RREQ_UPLOAD_TO_SERVER, &wreq->flags))
+@@ -914,8 +915,9 @@ int netfs_writeback_single(struct address_space *mapping,
+       set_bit(NETFS_RREQ_ALL_QUEUED, &wreq->flags);
+       mutex_unlock(&ictx->wb_lock);
++      netfs_wake_write_collector(wreq);
+-      netfs_put_request(wreq, false, netfs_rreq_trace_put_return);
++      netfs_put_request(wreq, netfs_rreq_trace_put_return);
+       _leave(" = %d", ret);
+       return ret;
+diff --git a/fs/netfs/write_retry.c b/fs/netfs/write_retry.c
+index 9b1ca8b0f4dd6..7408f6bb8e42e 100644
+--- a/fs/netfs/write_retry.c
++++ b/fs/netfs/write_retry.c
+@@ -132,7 +132,7 @@ static void netfs_retry_write_stream(struct netfs_io_request *wreq,
+                                                     &stream->subrequests, rreq_link) {
+                               trace_netfs_sreq(subreq, netfs_sreq_trace_discard);
+                               list_del(&subreq->rreq_link);
+-                              netfs_put_subrequest(subreq, false, netfs_sreq_trace_put_done);
++                              netfs_put_subrequest(subreq, netfs_sreq_trace_put_done);
+                               if (subreq == to)
+                                       break;
+                       }
+diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h
+index ecf774a8f1ca0..66093fa78aed7 100644
+--- a/fs/smb/client/cifsproto.h
++++ b/fs/smb/client/cifsproto.h
+@@ -151,8 +151,7 @@ extern bool is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 eof,
+                                  bool from_readdir);
+ extern void cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
+                           unsigned int bytes_written);
+-void cifs_write_subrequest_terminated(struct cifs_io_subrequest *wdata, ssize_t result,
+-                                    bool was_async);
++void cifs_write_subrequest_terminated(struct cifs_io_subrequest *wdata, ssize_t result);
+ extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, int);
+ extern int cifs_get_writable_file(struct cifsInodeInfo *cifs_inode,
+                                 int flags,
+diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c
+index f55457b4b82e3..477792c07d458 100644
+--- a/fs/smb/client/cifssmb.c
++++ b/fs/smb/client/cifssmb.c
+@@ -1725,7 +1725,7 @@ cifs_writev_callback(struct mid_q_entry *mid)
+                             server->credits, server->in_flight,
+                             0, cifs_trace_rw_credits_write_response_clear);
+       wdata->credits.value = 0;
+-      cifs_write_subrequest_terminated(wdata, result, true);
++      cifs_write_subrequest_terminated(wdata, result);
+       release_mid(mid);
+       trace_smb3_rw_credits(credits.rreq_debug_id, credits.rreq_debug_index, 0,
+                             server->credits, server->in_flight,
+@@ -1813,7 +1813,7 @@ cifs_async_writev(struct cifs_io_subrequest *wdata)
+ out:
+       if (rc) {
+               add_credits_and_wake_if(wdata->server, &wdata->credits, 0);
+-              cifs_write_subrequest_terminated(wdata, rc, false);
++              cifs_write_subrequest_terminated(wdata, rc);
+       }
+ }
+diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c
+index 950aa4f912f5c..3000c8a9d3ea5 100644
+--- a/fs/smb/client/file.c
++++ b/fs/smb/client/file.c
+@@ -130,7 +130,7 @@ static void cifs_issue_write(struct netfs_io_subrequest *subreq)
+       else
+               trace_netfs_sreq(subreq, netfs_sreq_trace_fail);
+       add_credits_and_wake_if(wdata->server, &wdata->credits, 0);
+-      cifs_write_subrequest_terminated(wdata, rc, false);
++      cifs_write_subrequest_terminated(wdata, rc);
+       goto out;
+ }
+@@ -2423,8 +2423,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *flock)
+       return rc;
+ }
+-void cifs_write_subrequest_terminated(struct cifs_io_subrequest *wdata, ssize_t result,
+-                                    bool was_async)
++void cifs_write_subrequest_terminated(struct cifs_io_subrequest *wdata, ssize_t result)
+ {
+       struct netfs_io_request *wreq = wdata->rreq;
+       struct netfs_inode *ictx = netfs_inode(wreq->inode);
+@@ -2441,7 +2440,7 @@ void cifs_write_subrequest_terminated(struct cifs_io_subrequest *wdata, ssize_t
+                       netfs_resize_file(ictx, wrend, true);
+       }
+-      netfs_write_subrequest_terminated(&wdata->subreq, result, was_async);
++      netfs_write_subrequest_terminated(&wdata->subreq, result);
+ }
+ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
+diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
+index 4e28632b5fd66..399185ca7cacb 100644
+--- a/fs/smb/client/smb2pdu.c
++++ b/fs/smb/client/smb2pdu.c
+@@ -4888,7 +4888,7 @@ smb2_writev_callback(struct mid_q_entry *mid)
+                             0, cifs_trace_rw_credits_write_response_clear);
+       wdata->credits.value = 0;
+       trace_netfs_sreq(&wdata->subreq, netfs_sreq_trace_io_progress);
+-      cifs_write_subrequest_terminated(wdata, result ?: written, true);
++      cifs_write_subrequest_terminated(wdata, result ?: written);
+       release_mid(mid);
+       trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, 0,
+                             server->credits, server->in_flight,
+@@ -5061,7 +5061,7 @@ smb2_async_writev(struct cifs_io_subrequest *wdata)
+                                     -(int)wdata->credits.value,
+                                     cifs_trace_rw_credits_write_response_clear);
+               add_credits_and_wake_if(wdata->server, &wdata->credits, 0);
+-              cifs_write_subrequest_terminated(wdata, rc, true);
++              cifs_write_subrequest_terminated(wdata, rc);
+       }
+ }
+diff --git a/include/linux/fscache.h b/include/linux/fscache.h
+index 9de27643607fb..266e6c9e6f83a 100644
+--- a/include/linux/fscache.h
++++ b/include/linux/fscache.h
+@@ -628,7 +628,7 @@ static inline void fscache_write_to_cache(struct fscache_cookie *cookie,
+                                        term_func, term_func_priv,
+                                        using_pgpriv2, caching);
+       else if (term_func)
+-              term_func(term_func_priv, -ENOBUFS, false);
++              term_func(term_func_priv, -ENOBUFS);
+ }
+diff --git a/include/linux/netfs.h b/include/linux/netfs.h
+index 497c4f4698f6e..c3f230732f51d 100644
+--- a/include/linux/netfs.h
++++ b/include/linux/netfs.h
+@@ -51,8 +51,7 @@ enum netfs_io_source {
+       NETFS_INVALID_WRITE,
+ } __mode(byte);
+-typedef void (*netfs_io_terminated_t)(void *priv, ssize_t transferred_or_error,
+-                                    bool was_async);
++typedef void (*netfs_io_terminated_t)(void *priv, ssize_t transferred_or_error);
+ /*
+  * Per-inode context.  This wraps the VFS inode.
+@@ -223,9 +222,10 @@ enum netfs_io_origin {
+  */
+ struct netfs_io_request {
+       union {
+-              struct work_struct work;
++              struct work_struct cleanup_work; /* Deferred cleanup work */
+               struct rcu_head rcu;
+       };
++      struct work_struct      work;           /* Result collector work */
+       struct inode            *inode;         /* The file being accessed */
+       struct address_space    *mapping;       /* The mapping being accessed */
+       struct kiocb            *iocb;          /* AIO completion vector */
+@@ -270,7 +270,7 @@ struct netfs_io_request {
+ #define NETFS_RREQ_NO_UNLOCK_FOLIO    2       /* Don't unlock no_unlock_folio on completion */
+ #define NETFS_RREQ_DONT_UNLOCK_FOLIOS 3       /* Don't unlock the folios on completion */
+ #define NETFS_RREQ_FAILED             4       /* The request failed */
+-#define NETFS_RREQ_IN_PROGRESS                5       /* Unlocked when the request completes */
++#define NETFS_RREQ_IN_PROGRESS                5       /* Unlocked when the request completes (has ref) */
+ #define NETFS_RREQ_FOLIO_COPY_TO_CACHE        6       /* Copy current folio to cache from read */
+ #define NETFS_RREQ_UPLOAD_TO_SERVER   8       /* Need to write to the server */
+ #define NETFS_RREQ_NONBLOCK           9       /* Don't block if possible (O_NONBLOCK) */
+@@ -440,15 +440,14 @@ void netfs_read_subreq_terminated(struct netfs_io_subrequest *subreq);
+ void netfs_get_subrequest(struct netfs_io_subrequest *subreq,
+                         enum netfs_sreq_ref_trace what);
+ void netfs_put_subrequest(struct netfs_io_subrequest *subreq,
+-                        bool was_async, enum netfs_sreq_ref_trace what);
++                        enum netfs_sreq_ref_trace what);
+ ssize_t netfs_extract_user_iter(struct iov_iter *orig, size_t orig_len,
+                               struct iov_iter *new,
+                               iov_iter_extraction_t extraction_flags);
+ size_t netfs_limit_iter(const struct iov_iter *iter, size_t start_offset,
+                       size_t max_size, size_t max_segs);
+ void netfs_prepare_write_failed(struct netfs_io_subrequest *subreq);
+-void netfs_write_subrequest_terminated(void *_op, ssize_t transferred_or_error,
+-                                     bool was_async);
++void netfs_write_subrequest_terminated(void *_op, ssize_t transferred_or_error);
+ void netfs_queue_write_request(struct netfs_io_subrequest *subreq);
+ int netfs_start_io_read(struct inode *inode);
+diff --git a/include/trace/events/netfs.h b/include/trace/events/netfs.h
+index f880835f7695e..402c5e82e7b8d 100644
+--- a/include/trace/events/netfs.h
++++ b/include/trace/events/netfs.h
+@@ -30,6 +30,7 @@
+       EM(netfs_write_trace_dio_write,         "DIO-WRITE")    \
+       EM(netfs_write_trace_unbuffered_write,  "UNB-WRITE")    \
+       EM(netfs_write_trace_writeback,         "WRITEBACK")    \
++      EM(netfs_write_trace_writeback_single,  "WB-SINGLE") \
+       E_(netfs_write_trace_writethrough,      "WRITETHRU")
+ #define netfs_rreq_origins                                    \
+@@ -128,17 +129,15 @@
+ #define netfs_rreq_ref_traces                                 \
+       EM(netfs_rreq_trace_get_for_outstanding,"GET OUTSTND")  \
+       EM(netfs_rreq_trace_get_subreq,         "GET SUBREQ ")  \
+-      EM(netfs_rreq_trace_get_work,           "GET WORK   ")  \
+       EM(netfs_rreq_trace_put_complete,       "PUT COMPLT ")  \
+       EM(netfs_rreq_trace_put_discard,        "PUT DISCARD")  \
+       EM(netfs_rreq_trace_put_failed,         "PUT FAILED ")  \
+       EM(netfs_rreq_trace_put_no_submit,      "PUT NO-SUBM")  \
+       EM(netfs_rreq_trace_put_return,         "PUT RETURN ")  \
+       EM(netfs_rreq_trace_put_subreq,         "PUT SUBREQ ")  \
+-      EM(netfs_rreq_trace_put_work,           "PUT WORK   ")  \
+-      EM(netfs_rreq_trace_put_work_complete,  "PUT WORK CP")  \
+-      EM(netfs_rreq_trace_put_work_nq,        "PUT WORK NQ")  \
++      EM(netfs_rreq_trace_put_work_ip,        "PUT WORK IP ") \
+       EM(netfs_rreq_trace_see_work,           "SEE WORK   ")  \
++      EM(netfs_rreq_trace_see_work_complete,  "SEE WORK CP")  \
+       E_(netfs_rreq_trace_new,                "NEW        ")
+ #define netfs_sreq_ref_traces                                 \
+diff --git a/net/9p/client.c b/net/9p/client.c
+index 61461b9fa1343..5c1ca57ccd285 100644
+--- a/net/9p/client.c
++++ b/net/9p/client.c
+@@ -1704,7 +1704,7 @@ p9_client_write_subreq(struct netfs_io_subrequest *subreq)
+                                   start, len, &subreq->io_iter);
+       }
+       if (IS_ERR(req)) {
+-              netfs_write_subrequest_terminated(subreq, PTR_ERR(req), false);
++              netfs_write_subrequest_terminated(subreq, PTR_ERR(req));
+               return;
+       }
+@@ -1712,7 +1712,7 @@ p9_client_write_subreq(struct netfs_io_subrequest *subreq)
+       if (err) {
+               trace_9p_protocol_dump(clnt, &req->rc);
+               p9_req_put(clnt, req);
+-              netfs_write_subrequest_terminated(subreq, err, false);
++              netfs_write_subrequest_terminated(subreq, err);
+               return;
+       }
+@@ -1724,7 +1724,7 @@ p9_client_write_subreq(struct netfs_io_subrequest *subreq)
+       p9_debug(P9_DEBUG_9P, "<<< RWRITE count %d\n", len);
+       p9_req_put(clnt, req);
+-      netfs_write_subrequest_terminated(subreq, written, false);
++      netfs_write_subrequest_terminated(subreq, written);
+ }
+ EXPORT_SYMBOL(p9_client_write_subreq);
+-- 
+2.39.5
+
diff --git a/queue-6.15/netfs-fix-undifferentiation-of-dio-reads-from-unbuff.patch b/queue-6.15/netfs-fix-undifferentiation-of-dio-reads-from-unbuff.patch
new file mode 100644 (file)
index 0000000..6ada501
--- /dev/null
@@ -0,0 +1,232 @@
+From db49be1c02e1afe2c5c0211e93bb077b72c96436 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 May 2025 08:57:52 +0100
+Subject: netfs: Fix undifferentiation of DIO reads from unbuffered reads
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit db26d62d79e4068934ad0dccdb92715df36352b9 ]
+
+On cifs, "DIO reads" (specified by O_DIRECT) need to be differentiated from
+"unbuffered reads" (specified by cache=none in the mount parameters).  The
+difference is flagged in the protocol and the server may behave
+differently: Windows Server will, for example, mandate that DIO reads are
+block aligned.
+
+Fix this by adding a NETFS_UNBUFFERED_READ to differentiate this from
+NETFS_DIO_READ, parallelling the write differentiation that already exists.
+cifs will then do the right thing.
+
+Fixes: 016dc8516aec ("netfs: Implement unbuffered/DIO read support")
+Signed-off-by: David Howells <dhowells@redhat.com>
+Link: https://lore.kernel.org/3444961.1747987072@warthog.procyon.org.uk
+Reviewed-by: "Paulo Alcantara (Red Hat)" <pc@manguebit.com>
+Reviewed-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
+cc: Steve French <sfrench@samba.org>
+cc: netfs@lists.linux.dev
+cc: v9fs@lists.linux.dev
+cc: linux-afs@lists.infradead.org
+cc: linux-cifs@vger.kernel.org
+cc: ceph-devel@vger.kernel.org
+cc: linux-nfs@vger.kernel.org
+cc: linux-fsdevel@vger.kernel.org
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/9p/vfs_addr.c             | 3 ++-
+ fs/afs/write.c               | 1 +
+ fs/ceph/addr.c               | 4 +++-
+ fs/netfs/direct_read.c       | 3 ++-
+ fs/netfs/main.c              | 1 +
+ fs/netfs/misc.c              | 1 +
+ fs/netfs/objects.c           | 1 +
+ fs/netfs/read_collect.c      | 7 +++++--
+ fs/nfs/fscache.c             | 1 +
+ fs/smb/client/file.c         | 3 ++-
+ include/linux/netfs.h        | 1 +
+ include/trace/events/netfs.h | 1 +
+ 12 files changed, 21 insertions(+), 6 deletions(-)
+
+diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c
+index b5a4a28e0fe79..e4420591cf354 100644
+--- a/fs/9p/vfs_addr.c
++++ b/fs/9p/vfs_addr.c
+@@ -77,7 +77,8 @@ static void v9fs_issue_read(struct netfs_io_subrequest *subreq)
+       /* if we just extended the file size, any portion not in
+        * cache won't be on server and is zeroes */
+-      if (subreq->rreq->origin != NETFS_DIO_READ)
++      if (subreq->rreq->origin != NETFS_UNBUFFERED_READ &&
++          subreq->rreq->origin != NETFS_DIO_READ)
+               __set_bit(NETFS_SREQ_CLEAR_TAIL, &subreq->flags);
+       if (pos + total >= i_size_read(rreq->inode))
+               __set_bit(NETFS_SREQ_HIT_EOF, &subreq->flags);
+diff --git a/fs/afs/write.c b/fs/afs/write.c
+index 7df7b2f5e7b29..2e7526ea883ae 100644
+--- a/fs/afs/write.c
++++ b/fs/afs/write.c
+@@ -202,6 +202,7 @@ void afs_retry_request(struct netfs_io_request *wreq, struct netfs_io_stream *st
+       case NETFS_READ_GAPS:
+       case NETFS_READ_SINGLE:
+       case NETFS_READ_FOR_WRITE:
++      case NETFS_UNBUFFERED_READ:
+       case NETFS_DIO_READ:
+               return;
+       default:
+diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
+index 557c326561fdc..b95c4cb21c13f 100644
+--- a/fs/ceph/addr.c
++++ b/fs/ceph/addr.c
+@@ -238,6 +238,7 @@ static void finish_netfs_read(struct ceph_osd_request *req)
+               if (sparse && err > 0)
+                       err = ceph_sparse_ext_map_end(op);
+               if (err < subreq->len &&
++                  subreq->rreq->origin != NETFS_UNBUFFERED_READ &&
+                   subreq->rreq->origin != NETFS_DIO_READ)
+                       __set_bit(NETFS_SREQ_CLEAR_TAIL, &subreq->flags);
+               if (IS_ENCRYPTED(inode) && err > 0) {
+@@ -281,7 +282,8 @@ static bool ceph_netfs_issue_op_inline(struct netfs_io_subrequest *subreq)
+       size_t len;
+       int mode;
+-      if (rreq->origin != NETFS_DIO_READ)
++      if (rreq->origin != NETFS_UNBUFFERED_READ &&
++          rreq->origin != NETFS_DIO_READ)
+               __set_bit(NETFS_SREQ_CLEAR_TAIL, &subreq->flags);
+       __clear_bit(NETFS_SREQ_COPY_TO_CACHE, &subreq->flags);
+diff --git a/fs/netfs/direct_read.c b/fs/netfs/direct_read.c
+index a24e63d2c8186..9902766195d7b 100644
+--- a/fs/netfs/direct_read.c
++++ b/fs/netfs/direct_read.c
+@@ -188,7 +188,8 @@ ssize_t netfs_unbuffered_read_iter_locked(struct kiocb *iocb, struct iov_iter *i
+       rreq = netfs_alloc_request(iocb->ki_filp->f_mapping, iocb->ki_filp,
+                                  iocb->ki_pos, orig_count,
+-                                 NETFS_DIO_READ);
++                                 iocb->ki_flags & IOCB_DIRECT ?
++                                 NETFS_DIO_READ : NETFS_UNBUFFERED_READ);
+       if (IS_ERR(rreq))
+               return PTR_ERR(rreq);
+diff --git a/fs/netfs/main.c b/fs/netfs/main.c
+index 70ecc8f5f2103..3db401d269e7b 100644
+--- a/fs/netfs/main.c
++++ b/fs/netfs/main.c
+@@ -39,6 +39,7 @@ static const char *netfs_origins[nr__netfs_io_origin] = {
+       [NETFS_READ_GAPS]               = "RG",
+       [NETFS_READ_SINGLE]             = "R1",
+       [NETFS_READ_FOR_WRITE]          = "RW",
++      [NETFS_UNBUFFERED_READ]         = "UR",
+       [NETFS_DIO_READ]                = "DR",
+       [NETFS_WRITEBACK]               = "WB",
+       [NETFS_WRITEBACK_SINGLE]        = "W1",
+diff --git a/fs/netfs/misc.c b/fs/netfs/misc.c
+index 77e7f7c79d27c..43b67a28a8fa0 100644
+--- a/fs/netfs/misc.c
++++ b/fs/netfs/misc.c
+@@ -461,6 +461,7 @@ static ssize_t netfs_wait_for_request(struct netfs_io_request *rreq,
+               case NETFS_DIO_READ:
+               case NETFS_DIO_WRITE:
+               case NETFS_READ_SINGLE:
++              case NETFS_UNBUFFERED_READ:
+               case NETFS_UNBUFFERED_WRITE:
+                       break;
+               default:
+diff --git a/fs/netfs/objects.c b/fs/netfs/objects.c
+index d3eb9ba3013a7..31fa0c81e2a43 100644
+--- a/fs/netfs/objects.c
++++ b/fs/netfs/objects.c
+@@ -59,6 +59,7 @@ struct netfs_io_request *netfs_alloc_request(struct address_space *mapping,
+           origin == NETFS_READ_GAPS ||
+           origin == NETFS_READ_SINGLE ||
+           origin == NETFS_READ_FOR_WRITE ||
++          origin == NETFS_UNBUFFERED_READ ||
+           origin == NETFS_DIO_READ) {
+               INIT_WORK(&rreq->work, netfs_read_collection_worker);
+               rreq->io_streams[0].avail = true;
+diff --git a/fs/netfs/read_collect.c b/fs/netfs/read_collect.c
+index 900dd51c3b941..bad677e58a423 100644
+--- a/fs/netfs/read_collect.c
++++ b/fs/netfs/read_collect.c
+@@ -342,7 +342,8 @@ static void netfs_rreq_assess_dio(struct netfs_io_request *rreq)
+ {
+       unsigned int i;
+-      if (rreq->origin == NETFS_DIO_READ) {
++      if (rreq->origin == NETFS_UNBUFFERED_READ ||
++          rreq->origin == NETFS_DIO_READ) {
+               for (i = 0; i < rreq->direct_bv_count; i++) {
+                       flush_dcache_page(rreq->direct_bv[i].bv_page);
+                       // TODO: cifs marks pages in the destination buffer
+@@ -360,7 +361,8 @@ static void netfs_rreq_assess_dio(struct netfs_io_request *rreq)
+       }
+       if (rreq->netfs_ops->done)
+               rreq->netfs_ops->done(rreq);
+-      if (rreq->origin == NETFS_DIO_READ)
++      if (rreq->origin == NETFS_UNBUFFERED_READ ||
++          rreq->origin == NETFS_DIO_READ)
+               inode_dio_end(rreq->inode);
+ }
+@@ -416,6 +418,7 @@ bool netfs_read_collection(struct netfs_io_request *rreq)
+       //netfs_rreq_is_still_valid(rreq);
+       switch (rreq->origin) {
++      case NETFS_UNBUFFERED_READ:
+       case NETFS_DIO_READ:
+       case NETFS_READ_GAPS:
+               netfs_rreq_assess_dio(rreq);
+diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c
+index e278a1ad1ca3e..8b07851787312 100644
+--- a/fs/nfs/fscache.c
++++ b/fs/nfs/fscache.c
+@@ -367,6 +367,7 @@ void nfs_netfs_read_completion(struct nfs_pgio_header *hdr)
+       sreq = netfs->sreq;
+       if (test_bit(NFS_IOHDR_EOF, &hdr->flags) &&
++          sreq->rreq->origin != NETFS_UNBUFFERED_READ &&
+           sreq->rreq->origin != NETFS_DIO_READ)
+               __set_bit(NETFS_SREQ_CLEAR_TAIL, &sreq->flags);
+diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c
+index 3000c8a9d3ea5..d2df10b8e6fd8 100644
+--- a/fs/smb/client/file.c
++++ b/fs/smb/client/file.c
+@@ -219,7 +219,8 @@ static void cifs_issue_read(struct netfs_io_subrequest *subreq)
+                       goto failed;
+       }
+-      if (subreq->rreq->origin != NETFS_DIO_READ)
++      if (subreq->rreq->origin != NETFS_UNBUFFERED_READ &&
++          subreq->rreq->origin != NETFS_DIO_READ)
+               __set_bit(NETFS_SREQ_CLEAR_TAIL, &subreq->flags);
+       trace_netfs_sreq(subreq, netfs_sreq_trace_submit);
+diff --git a/include/linux/netfs.h b/include/linux/netfs.h
+index c3f230732f51d..1464b3a104989 100644
+--- a/include/linux/netfs.h
++++ b/include/linux/netfs.h
+@@ -206,6 +206,7 @@ enum netfs_io_origin {
+       NETFS_READ_GAPS,                /* This read is a synchronous read to fill gaps */
+       NETFS_READ_SINGLE,              /* This read should be treated as a single object */
+       NETFS_READ_FOR_WRITE,           /* This read is to prepare a write */
++      NETFS_UNBUFFERED_READ,          /* This is an unbuffered read */
+       NETFS_DIO_READ,                 /* This is a direct I/O read */
+       NETFS_WRITEBACK,                /* This write was triggered by writepages */
+       NETFS_WRITEBACK_SINGLE,         /* This monolithic write was triggered by writepages */
+diff --git a/include/trace/events/netfs.h b/include/trace/events/netfs.h
+index 402c5e82e7b8d..4175eec40048a 100644
+--- a/include/trace/events/netfs.h
++++ b/include/trace/events/netfs.h
+@@ -39,6 +39,7 @@
+       EM(NETFS_READ_GAPS,                     "RG")           \
+       EM(NETFS_READ_SINGLE,                   "R1")           \
+       EM(NETFS_READ_FOR_WRITE,                "RW")           \
++      EM(NETFS_UNBUFFERED_READ,               "UR")           \
+       EM(NETFS_DIO_READ,                      "DR")           \
+       EM(NETFS_WRITEBACK,                     "WB")           \
+       EM(NETFS_WRITEBACK_SINGLE,              "W1")           \
+-- 
+2.39.5
+
diff --git a/queue-6.15/netfs-fix-wait-wake-to-be-consistent-about-the-waitq.patch b/queue-6.15/netfs-fix-wait-wake-to-be-consistent-about-the-waitq.patch
new file mode 100644 (file)
index 0000000..7cf9f41
--- /dev/null
@@ -0,0 +1,881 @@
+From 5f76f3c36c7e925a483c836c2a6b38d5bd1eb0dc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 May 2025 10:07:04 +0100
+Subject: netfs: Fix wait/wake to be consistent about the waitqueue used
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 2b1424cd131cfaba4cf7040473133d26cddac088 ]
+
+Fix further inconsistencies in the use of waitqueues
+(clear_and_wake_up_bit() vs private waitqueue).
+
+Move some of this stuff from the read and write sides into common code so
+that it can be done in fewer places.
+
+To make this work, async I/O needs to set NETFS_RREQ_OFFLOAD_COLLECTION to
+indicate that a workqueue will do the collecting and places that call the
+wait function need to deal with it returning the amount transferred.
+
+Fixes: e2d46f2ec332 ("netfs: Change the read result collector to only use one work item")
+Signed-off-by: David Howells <dhowells@redhat.com>
+Link: https://lore.kernel.org/20250519090707.2848510-5-dhowells@redhat.com
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: Steve French <stfrench@microsoft.com>
+cc: Ihor Solodrai <ihor.solodrai@pm.me>
+cc: Eric Van Hensbergen <ericvh@kernel.org>
+cc: Latchesar Ionkov <lucho@ionkov.net>
+cc: Dominique Martinet <asmadeus@codewreck.org>
+cc: Christian Schoenebeck <linux_oss@crudebyte.com>
+cc: Paulo Alcantara <pc@manguebit.com>
+cc: Jeff Layton <jlayton@kernel.org>
+cc: v9fs@lists.linux.dev
+cc: linux-cifs@vger.kernel.org
+cc: netfs@lists.linux.dev
+cc: linux-fsdevel@vger.kernel.org
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/netfs/buffered_read.c  |   2 +-
+ fs/netfs/buffered_write.c |   2 +-
+ fs/netfs/direct_read.c    |   4 +-
+ fs/netfs/direct_write.c   |  10 +-
+ fs/netfs/internal.h       |  33 ++++--
+ fs/netfs/misc.c           | 218 ++++++++++++++++++++++++++++++++++++++
+ fs/netfs/read_collect.c   | 139 +-----------------------
+ fs/netfs/read_retry.c     |  24 +----
+ fs/netfs/write_collect.c  |  36 ++-----
+ fs/netfs/write_issue.c    |  28 +++--
+ fs/netfs/write_retry.c    |  12 +--
+ 11 files changed, 284 insertions(+), 224 deletions(-)
+
+diff --git a/fs/netfs/buffered_read.c b/fs/netfs/buffered_read.c
+index cb6202efc4668..fd4619275801b 100644
+--- a/fs/netfs/buffered_read.c
++++ b/fs/netfs/buffered_read.c
+@@ -312,7 +312,7 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq)
+       if (unlikely(size > 0)) {
+               smp_wmb(); /* Write lists before ALL_QUEUED. */
+               set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
+-              netfs_wake_read_collector(rreq);
++              netfs_wake_collector(rreq);
+       }
+       /* Defer error return as we may need to wait for outstanding I/O. */
+diff --git a/fs/netfs/buffered_write.c b/fs/netfs/buffered_write.c
+index b4826360a4111..dbb544e183d13 100644
+--- a/fs/netfs/buffered_write.c
++++ b/fs/netfs/buffered_write.c
+@@ -386,7 +386,7 @@ ssize_t netfs_perform_write(struct kiocb *iocb, struct iov_iter *iter,
+               wbc_detach_inode(&wbc);
+               if (ret2 == -EIOCBQUEUED)
+                       return ret2;
+-              if (ret == 0)
++              if (ret == 0 && ret2 < 0)
+                       ret = ret2;
+       }
+diff --git a/fs/netfs/direct_read.c b/fs/netfs/direct_read.c
+index cb3c6dc0b1654..a24e63d2c8186 100644
+--- a/fs/netfs/direct_read.c
++++ b/fs/netfs/direct_read.c
+@@ -103,7 +103,7 @@ static int netfs_dispatch_unbuffered_reads(struct netfs_io_request *rreq)
+               rreq->netfs_ops->issue_read(subreq);
+               if (test_bit(NETFS_RREQ_PAUSE, &rreq->flags))
+-                      netfs_wait_for_pause(rreq);
++                      netfs_wait_for_paused_read(rreq);
+               if (test_bit(NETFS_RREQ_FAILED, &rreq->flags))
+                       break;
+               if (test_bit(NETFS_RREQ_BLOCKED, &rreq->flags) &&
+@@ -115,7 +115,7 @@ static int netfs_dispatch_unbuffered_reads(struct netfs_io_request *rreq)
+       if (unlikely(size > 0)) {
+               smp_wmb(); /* Write lists before ALL_QUEUED. */
+               set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
+-              netfs_wake_read_collector(rreq);
++              netfs_wake_collector(rreq);
+       }
+       return ret;
+diff --git a/fs/netfs/direct_write.c b/fs/netfs/direct_write.c
+index c98f1676f86df..fa9a5bf3c6d51 100644
+--- a/fs/netfs/direct_write.c
++++ b/fs/netfs/direct_write.c
+@@ -87,6 +87,8 @@ ssize_t netfs_unbuffered_write_iter_locked(struct kiocb *iocb, struct iov_iter *
+       }
+       __set_bit(NETFS_RREQ_USE_IO_ITER, &wreq->flags);
++      if (async)
++              __set_bit(NETFS_RREQ_OFFLOAD_COLLECTION, &wreq->flags);
+       /* Copy the data into the bounce buffer and encrypt it. */
+       // TODO
+@@ -105,13 +107,9 @@ ssize_t netfs_unbuffered_write_iter_locked(struct kiocb *iocb, struct iov_iter *
+       if (!async) {
+               trace_netfs_rreq(wreq, netfs_rreq_trace_wait_ip);
+-              wait_on_bit(&wreq->flags, NETFS_RREQ_IN_PROGRESS,
+-                          TASK_UNINTERRUPTIBLE);
+-              ret = wreq->error;
+-              if (ret == 0) {
+-                      ret = wreq->transferred;
++              ret = netfs_wait_for_write(wreq);
++              if (ret > 0)
+                       iocb->ki_pos += ret;
+-              }
+       } else {
+               ret = -EIOCBQUEUED;
+       }
+diff --git a/fs/netfs/internal.h b/fs/netfs/internal.h
+index b6500a7cda81d..e2ee9183392b9 100644
+--- a/fs/netfs/internal.h
++++ b/fs/netfs/internal.h
+@@ -62,6 +62,14 @@ static inline void netfs_proc_del_rreq(struct netfs_io_request *rreq) {}
+ struct folio_queue *netfs_buffer_make_space(struct netfs_io_request *rreq,
+                                           enum netfs_folioq_trace trace);
+ void netfs_reset_iter(struct netfs_io_subrequest *subreq);
++void netfs_wake_collector(struct netfs_io_request *rreq);
++void netfs_subreq_clear_in_progress(struct netfs_io_subrequest *subreq);
++void netfs_wait_for_in_progress_stream(struct netfs_io_request *rreq,
++                                     struct netfs_io_stream *stream);
++ssize_t netfs_wait_for_read(struct netfs_io_request *rreq);
++ssize_t netfs_wait_for_write(struct netfs_io_request *rreq);
++void netfs_wait_for_paused_read(struct netfs_io_request *rreq);
++void netfs_wait_for_paused_write(struct netfs_io_request *rreq);
+ /*
+  * objects.c
+@@ -91,11 +99,9 @@ static inline void netfs_see_subrequest(struct netfs_io_subrequest *subreq,
+ /*
+  * read_collect.c
+  */
++bool netfs_read_collection(struct netfs_io_request *rreq);
+ void netfs_read_collection_worker(struct work_struct *work);
+-void netfs_wake_read_collector(struct netfs_io_request *rreq);
+ void netfs_cache_read_terminated(void *priv, ssize_t transferred_or_error);
+-ssize_t netfs_wait_for_read(struct netfs_io_request *rreq);
+-void netfs_wait_for_pause(struct netfs_io_request *rreq);
+ /*
+  * read_pgpriv2.c
+@@ -175,8 +181,8 @@ static inline void netfs_stat_d(atomic_t *stat)
+  * write_collect.c
+  */
+ int netfs_folio_written_back(struct folio *folio);
++bool netfs_write_collection(struct netfs_io_request *wreq);
+ void netfs_write_collection_worker(struct work_struct *work);
+-void netfs_wake_write_collector(struct netfs_io_request *wreq);
+ /*
+  * write_issue.c
+@@ -197,8 +203,8 @@ struct netfs_io_request *netfs_begin_writethrough(struct kiocb *iocb, size_t len
+ int netfs_advance_writethrough(struct netfs_io_request *wreq, struct writeback_control *wbc,
+                              struct folio *folio, size_t copied, bool to_page_end,
+                              struct folio **writethrough_cache);
+-int netfs_end_writethrough(struct netfs_io_request *wreq, struct writeback_control *wbc,
+-                         struct folio *writethrough_cache);
++ssize_t netfs_end_writethrough(struct netfs_io_request *wreq, struct writeback_control *wbc,
++                             struct folio *writethrough_cache);
+ int netfs_unbuffered_write(struct netfs_io_request *wreq, bool may_wait, size_t len);
+ /*
+@@ -253,6 +259,21 @@ static inline void netfs_put_group_many(struct netfs_group *netfs_group, int nr)
+               netfs_group->free(netfs_group);
+ }
++/*
++ * Clear and wake up a NETFS_RREQ_* flag bit on a request.
++ */
++static inline void netfs_wake_rreq_flag(struct netfs_io_request *rreq,
++                                      unsigned int rreq_flag,
++                                      enum netfs_rreq_trace trace)
++{
++      if (test_bit(rreq_flag, &rreq->flags)) {
++              trace_netfs_rreq(rreq, trace);
++              clear_bit_unlock(rreq_flag, &rreq->flags);
++              smp_mb__after_atomic(); /* Set flag before task state */
++              wake_up(&rreq->waitq);
++      }
++}
++
+ /*
+  * fscache-cache.c
+  */
+diff --git a/fs/netfs/misc.c b/fs/netfs/misc.c
+index 7099aa07737ac..77e7f7c79d27c 100644
+--- a/fs/netfs/misc.c
++++ b/fs/netfs/misc.c
+@@ -313,3 +313,221 @@ bool netfs_release_folio(struct folio *folio, gfp_t gfp)
+       return true;
+ }
+ EXPORT_SYMBOL(netfs_release_folio);
++
++/*
++ * Wake the collection work item.
++ */
++void netfs_wake_collector(struct netfs_io_request *rreq)
++{
++      if (test_bit(NETFS_RREQ_OFFLOAD_COLLECTION, &rreq->flags) &&
++          !test_bit(NETFS_RREQ_RETRYING, &rreq->flags)) {
++              queue_work(system_unbound_wq, &rreq->work);
++      } else {
++              trace_netfs_rreq(rreq, netfs_rreq_trace_wake_queue);
++              wake_up(&rreq->waitq);
++      }
++}
++
++/*
++ * Mark a subrequest as no longer being in progress and, if need be, wake the
++ * collector.
++ */
++void netfs_subreq_clear_in_progress(struct netfs_io_subrequest *subreq)
++{
++      struct netfs_io_request *rreq = subreq->rreq;
++      struct netfs_io_stream *stream = &rreq->io_streams[subreq->stream_nr];
++
++      clear_bit_unlock(NETFS_SREQ_IN_PROGRESS, &subreq->flags);
++      smp_mb__after_atomic(); /* Clear IN_PROGRESS before task state */
++
++      /* If we are at the head of the queue, wake up the collector. */
++      if (list_is_first(&subreq->rreq_link, &stream->subrequests) ||
++          test_bit(NETFS_RREQ_RETRYING, &rreq->flags))
++              netfs_wake_collector(rreq);
++}
++
++/*
++ * Wait for all outstanding I/O in a stream to quiesce.
++ */
++void netfs_wait_for_in_progress_stream(struct netfs_io_request *rreq,
++                                     struct netfs_io_stream *stream)
++{
++      struct netfs_io_subrequest *subreq;
++      DEFINE_WAIT(myself);
++
++      list_for_each_entry(subreq, &stream->subrequests, rreq_link) {
++              if (!test_bit(NETFS_SREQ_IN_PROGRESS, &subreq->flags))
++                      continue;
++
++              trace_netfs_rreq(rreq, netfs_rreq_trace_wait_queue);
++              for (;;) {
++                      prepare_to_wait(&rreq->waitq, &myself, TASK_UNINTERRUPTIBLE);
++
++                      if (!test_bit(NETFS_SREQ_IN_PROGRESS, &subreq->flags))
++                              break;
++
++                      trace_netfs_sreq(subreq, netfs_sreq_trace_wait_for);
++                      schedule();
++                      trace_netfs_rreq(rreq, netfs_rreq_trace_woke_queue);
++              }
++      }
++
++      finish_wait(&rreq->waitq, &myself);
++}
++
++/*
++ * Perform collection in app thread if not offloaded to workqueue.
++ */
++static int netfs_collect_in_app(struct netfs_io_request *rreq,
++                              bool (*collector)(struct netfs_io_request *rreq))
++{
++      bool need_collect = false, inactive = true;
++
++      for (int i = 0; i < NR_IO_STREAMS; i++) {
++              struct netfs_io_subrequest *subreq;
++              struct netfs_io_stream *stream = &rreq->io_streams[i];
++
++              if (!stream->active)
++                      continue;
++              inactive = false;
++              trace_netfs_collect_stream(rreq, stream);
++              subreq = list_first_entry_or_null(&stream->subrequests,
++                                                struct netfs_io_subrequest,
++                                                rreq_link);
++              if (subreq &&
++                  (!test_bit(NETFS_SREQ_IN_PROGRESS, &subreq->flags) ||
++                   test_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags))) {
++                      need_collect = true;
++                      break;
++              }
++      }
++
++      if (!need_collect && !inactive)
++              return 0; /* Sleep */
++
++      __set_current_state(TASK_RUNNING);
++      if (collector(rreq)) {
++              /* Drop the ref from the NETFS_RREQ_IN_PROGRESS flag. */
++              netfs_put_request(rreq, netfs_rreq_trace_put_work_ip);
++              return 1; /* Done */
++      }
++
++      if (inactive) {
++              WARN(true, "Failed to collect inactive req R=%08x\n",
++                   rreq->debug_id);
++              cond_resched();
++      }
++      return 2; /* Again */
++}
++
++/*
++ * Wait for a request to complete, successfully or otherwise.
++ */
++static ssize_t netfs_wait_for_request(struct netfs_io_request *rreq,
++                                    bool (*collector)(struct netfs_io_request *rreq))
++{
++      DEFINE_WAIT(myself);
++      ssize_t ret;
++
++      for (;;) {
++              trace_netfs_rreq(rreq, netfs_rreq_trace_wait_queue);
++              prepare_to_wait(&rreq->waitq, &myself, TASK_UNINTERRUPTIBLE);
++
++              if (!test_bit(NETFS_RREQ_OFFLOAD_COLLECTION, &rreq->flags)) {
++                      switch (netfs_collect_in_app(rreq, collector)) {
++                      case 0:
++                              break;
++                      case 1:
++                              goto all_collected;
++                      case 2:
++                              continue;
++                      }
++              }
++
++              if (!test_bit(NETFS_RREQ_IN_PROGRESS, &rreq->flags))
++                      break;
++
++              schedule();
++              trace_netfs_rreq(rreq, netfs_rreq_trace_woke_queue);
++      }
++
++all_collected:
++      finish_wait(&rreq->waitq, &myself);
++
++      ret = rreq->error;
++      if (ret == 0) {
++              ret = rreq->transferred;
++              switch (rreq->origin) {
++              case NETFS_DIO_READ:
++              case NETFS_DIO_WRITE:
++              case NETFS_READ_SINGLE:
++              case NETFS_UNBUFFERED_WRITE:
++                      break;
++              default:
++                      if (rreq->submitted < rreq->len) {
++                              trace_netfs_failure(rreq, NULL, ret, netfs_fail_short_read);
++                              ret = -EIO;
++                      }
++                      break;
++              }
++      }
++
++      return ret;
++}
++
++ssize_t netfs_wait_for_read(struct netfs_io_request *rreq)
++{
++      return netfs_wait_for_request(rreq, netfs_read_collection);
++}
++
++ssize_t netfs_wait_for_write(struct netfs_io_request *rreq)
++{
++      return netfs_wait_for_request(rreq, netfs_write_collection);
++}
++
++/*
++ * Wait for a paused operation to unpause or complete in some manner.
++ */
++static void netfs_wait_for_pause(struct netfs_io_request *rreq,
++                               bool (*collector)(struct netfs_io_request *rreq))
++{
++      DEFINE_WAIT(myself);
++
++      trace_netfs_rreq(rreq, netfs_rreq_trace_wait_pause);
++
++      for (;;) {
++              trace_netfs_rreq(rreq, netfs_rreq_trace_wait_queue);
++              prepare_to_wait(&rreq->waitq, &myself, TASK_UNINTERRUPTIBLE);
++
++              if (!test_bit(NETFS_RREQ_OFFLOAD_COLLECTION, &rreq->flags)) {
++                      switch (netfs_collect_in_app(rreq, collector)) {
++                      case 0:
++                              break;
++                      case 1:
++                              goto all_collected;
++                      case 2:
++                              continue;
++                      }
++              }
++
++              if (!test_bit(NETFS_RREQ_IN_PROGRESS, &rreq->flags) ||
++                  !test_bit(NETFS_RREQ_PAUSE, &rreq->flags))
++                      break;
++
++              schedule();
++              trace_netfs_rreq(rreq, netfs_rreq_trace_woke_queue);
++      }
++
++all_collected:
++      finish_wait(&rreq->waitq, &myself);
++}
++
++void netfs_wait_for_paused_read(struct netfs_io_request *rreq)
++{
++      return netfs_wait_for_pause(rreq, netfs_read_collection);
++}
++
++void netfs_wait_for_paused_write(struct netfs_io_request *rreq)
++{
++      return netfs_wait_for_pause(rreq, netfs_write_collection);
++}
+diff --git a/fs/netfs/read_collect.c b/fs/netfs/read_collect.c
+index 1197ebce56757..900dd51c3b941 100644
+--- a/fs/netfs/read_collect.c
++++ b/fs/netfs/read_collect.c
+@@ -315,14 +315,8 @@ static void netfs_collect_read_results(struct netfs_io_request *rreq)
+       if (notes & NEED_RETRY)
+               goto need_retry;
+-      if ((notes & MADE_PROGRESS) && test_bit(NETFS_RREQ_PAUSE, &rreq->flags)) {
+-              trace_netfs_rreq(rreq, netfs_rreq_trace_unpause);
+-              clear_bit_unlock(NETFS_RREQ_PAUSE, &rreq->flags);
+-              smp_mb__after_atomic(); /* Set PAUSE before task state */
+-              wake_up(&rreq->waitq);
+-      }
+-
+       if (notes & MADE_PROGRESS) {
++              netfs_wake_rreq_flag(rreq, NETFS_RREQ_PAUSE, netfs_rreq_trace_unpause);
+               //cond_resched();
+               goto reassess;
+       }
+@@ -399,7 +393,7 @@ static void netfs_rreq_assess_single(struct netfs_io_request *rreq)
+  * Note that we're in normal kernel thread context at this point, possibly
+  * running on a workqueue.
+  */
+-static bool netfs_read_collection(struct netfs_io_request *rreq)
++bool netfs_read_collection(struct netfs_io_request *rreq)
+ {
+       struct netfs_io_stream *stream = &rreq->io_streams[0];
+@@ -434,8 +428,7 @@ static bool netfs_read_collection(struct netfs_io_request *rreq)
+       }
+       task_io_account_read(rreq->transferred);
+-      trace_netfs_rreq(rreq, netfs_rreq_trace_wake_ip);
+-      clear_and_wake_up_bit(NETFS_RREQ_IN_PROGRESS, &rreq->flags);
++      netfs_wake_rreq_flag(rreq, NETFS_RREQ_IN_PROGRESS, netfs_rreq_trace_wake_ip);
+       /* As we cleared NETFS_RREQ_IN_PROGRESS, we acquired its ref. */
+       trace_netfs_rreq(rreq, netfs_rreq_trace_done);
+@@ -460,20 +453,6 @@ void netfs_read_collection_worker(struct work_struct *work)
+       }
+ }
+-/*
+- * Wake the collection work item.
+- */
+-void netfs_wake_read_collector(struct netfs_io_request *rreq)
+-{
+-      if (test_bit(NETFS_RREQ_OFFLOAD_COLLECTION, &rreq->flags) &&
+-          !test_bit(NETFS_RREQ_RETRYING, &rreq->flags)) {
+-              queue_work(system_unbound_wq, &rreq->work);
+-      } else {
+-              trace_netfs_rreq(rreq, netfs_rreq_trace_wake_queue);
+-              wake_up(&rreq->waitq);
+-      }
+-}
+-
+ /**
+  * netfs_read_subreq_progress - Note progress of a read operation.
+  * @subreq: The read request that has terminated.
+@@ -502,7 +481,7 @@ void netfs_read_subreq_progress(struct netfs_io_subrequest *subreq)
+           list_is_first(&subreq->rreq_link, &stream->subrequests)
+           ) {
+               __set_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags);
+-              netfs_wake_read_collector(rreq);
++              netfs_wake_collector(rreq);
+       }
+ }
+ EXPORT_SYMBOL(netfs_read_subreq_progress);
+@@ -526,7 +505,6 @@ EXPORT_SYMBOL(netfs_read_subreq_progress);
+ void netfs_read_subreq_terminated(struct netfs_io_subrequest *subreq)
+ {
+       struct netfs_io_request *rreq = subreq->rreq;
+-      struct netfs_io_stream *stream = &rreq->io_streams[0];
+       switch (subreq->source) {
+       case NETFS_READ_FROM_CACHE:
+@@ -573,15 +551,7 @@ void netfs_read_subreq_terminated(struct netfs_io_subrequest *subreq)
+       }
+       trace_netfs_sreq(subreq, netfs_sreq_trace_terminated);
+-
+-      clear_bit_unlock(NETFS_SREQ_IN_PROGRESS, &subreq->flags);
+-      smp_mb__after_atomic(); /* Clear IN_PROGRESS before task state */
+-
+-      /* If we are at the head of the queue, wake up the collector. */
+-      if (list_is_first(&subreq->rreq_link, &stream->subrequests) ||
+-          test_bit(NETFS_RREQ_RETRYING, &rreq->flags))
+-              netfs_wake_read_collector(rreq);
+-
++      netfs_subreq_clear_in_progress(subreq);
+       netfs_put_subrequest(subreq, netfs_sreq_trace_put_terminated);
+ }
+ EXPORT_SYMBOL(netfs_read_subreq_terminated);
+@@ -604,102 +574,3 @@ void netfs_cache_read_terminated(void *priv, ssize_t transferred_or_error)
+       }
+       netfs_read_subreq_terminated(subreq);
+ }
+-
+-/*
+- * Wait for the read operation to complete, successfully or otherwise.
+- */
+-ssize_t netfs_wait_for_read(struct netfs_io_request *rreq)
+-{
+-      struct netfs_io_subrequest *subreq;
+-      struct netfs_io_stream *stream = &rreq->io_streams[0];
+-      DEFINE_WAIT(myself);
+-      ssize_t ret;
+-
+-      for (;;) {
+-              trace_netfs_rreq(rreq, netfs_rreq_trace_wait_queue);
+-              prepare_to_wait(&rreq->waitq, &myself, TASK_UNINTERRUPTIBLE);
+-
+-              subreq = list_first_entry_or_null(&stream->subrequests,
+-                                                struct netfs_io_subrequest, rreq_link);
+-              if (subreq &&
+-                  (!test_bit(NETFS_SREQ_IN_PROGRESS, &subreq->flags) ||
+-                   test_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags))) {
+-                      __set_current_state(TASK_RUNNING);
+-                      if (netfs_read_collection(rreq)) {
+-                              /* Drop the ref from the NETFS_RREQ_IN_PROGRESS flag. */
+-                              netfs_put_request(rreq, netfs_rreq_trace_put_work_ip);
+-                              break;
+-                      }
+-                      continue;
+-              }
+-
+-              if (!test_bit(NETFS_RREQ_IN_PROGRESS, &rreq->flags))
+-                      break;
+-
+-              schedule();
+-              trace_netfs_rreq(rreq, netfs_rreq_trace_woke_queue);
+-      }
+-
+-      finish_wait(&rreq->waitq, &myself);
+-
+-      ret = rreq->error;
+-      if (ret == 0) {
+-              ret = rreq->transferred;
+-              switch (rreq->origin) {
+-              case NETFS_DIO_READ:
+-              case NETFS_READ_SINGLE:
+-                      ret = rreq->transferred;
+-                      break;
+-              default:
+-                      if (rreq->submitted < rreq->len) {
+-                              trace_netfs_failure(rreq, NULL, ret, netfs_fail_short_read);
+-                              ret = -EIO;
+-                      }
+-                      break;
+-              }
+-      }
+-
+-      return ret;
+-}
+-
+-/*
+- * Wait for a paused read operation to unpause or complete in some manner.
+- */
+-void netfs_wait_for_pause(struct netfs_io_request *rreq)
+-{
+-      struct netfs_io_subrequest *subreq;
+-      struct netfs_io_stream *stream = &rreq->io_streams[0];
+-      DEFINE_WAIT(myself);
+-
+-      trace_netfs_rreq(rreq, netfs_rreq_trace_wait_pause);
+-
+-      for (;;) {
+-              trace_netfs_rreq(rreq, netfs_rreq_trace_wait_queue);
+-              prepare_to_wait(&rreq->waitq, &myself, TASK_UNINTERRUPTIBLE);
+-
+-              if (!test_bit(NETFS_RREQ_OFFLOAD_COLLECTION, &rreq->flags)) {
+-                      subreq = list_first_entry_or_null(&stream->subrequests,
+-                                                        struct netfs_io_subrequest, rreq_link);
+-                      if (subreq &&
+-                          (!test_bit(NETFS_SREQ_IN_PROGRESS, &subreq->flags) ||
+-                           test_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags))) {
+-                              __set_current_state(TASK_RUNNING);
+-                              if (netfs_read_collection(rreq)) {
+-                                      /* Drop the ref from the NETFS_RREQ_IN_PROGRESS flag. */
+-                                      netfs_put_request(rreq, netfs_rreq_trace_put_work_ip);
+-                                      break;
+-                              }
+-                              continue;
+-                      }
+-              }
+-
+-              if (!test_bit(NETFS_RREQ_IN_PROGRESS, &rreq->flags) ||
+-                  !test_bit(NETFS_RREQ_PAUSE, &rreq->flags))
+-                      break;
+-
+-              schedule();
+-              trace_netfs_rreq(rreq, netfs_rreq_trace_woke_queue);
+-      }
+-
+-      finish_wait(&rreq->waitq, &myself);
+-}
+diff --git a/fs/netfs/read_retry.c b/fs/netfs/read_retry.c
+index 1378dc7fa2ccd..b99e84a8170af 100644
+--- a/fs/netfs/read_retry.c
++++ b/fs/netfs/read_retry.c
+@@ -257,35 +257,15 @@ static void netfs_retry_read_subrequests(struct netfs_io_request *rreq)
+  */
+ void netfs_retry_reads(struct netfs_io_request *rreq)
+ {
+-      struct netfs_io_subrequest *subreq;
+       struct netfs_io_stream *stream = &rreq->io_streams[0];
+-      DEFINE_WAIT(myself);
+       netfs_stat(&netfs_n_rh_retry_read_req);
+-      set_bit(NETFS_RREQ_RETRYING, &rreq->flags);
+-
+       /* Wait for all outstanding I/O to quiesce before performing retries as
+        * we may need to renegotiate the I/O sizes.
+        */
+-      list_for_each_entry(subreq, &stream->subrequests, rreq_link) {
+-              if (!test_bit(NETFS_SREQ_IN_PROGRESS, &subreq->flags))
+-                      continue;
+-
+-              trace_netfs_rreq(rreq, netfs_rreq_trace_wait_queue);
+-              for (;;) {
+-                      prepare_to_wait(&rreq->waitq, &myself, TASK_UNINTERRUPTIBLE);
+-
+-                      if (!test_bit(NETFS_SREQ_IN_PROGRESS, &subreq->flags))
+-                              break;
+-
+-                      trace_netfs_sreq(subreq, netfs_sreq_trace_wait_for);
+-                      schedule();
+-                      trace_netfs_rreq(rreq, netfs_rreq_trace_woke_queue);
+-              }
+-
+-              finish_wait(&rreq->waitq, &myself);
+-      }
++      set_bit(NETFS_RREQ_RETRYING, &rreq->flags);
++      netfs_wait_for_in_progress_stream(rreq, stream);
+       clear_bit(NETFS_RREQ_RETRYING, &rreq->flags);
+       trace_netfs_rreq(rreq, netfs_rreq_trace_resubmit);
+diff --git a/fs/netfs/write_collect.c b/fs/netfs/write_collect.c
+index 7241d1fd2c14a..0ce7b53e7fe83 100644
+--- a/fs/netfs/write_collect.c
++++ b/fs/netfs/write_collect.c
+@@ -321,18 +321,14 @@ static void netfs_collect_write_results(struct netfs_io_request *wreq)
+       if (notes & NEED_RETRY)
+               goto need_retry;
+-      if ((notes & MADE_PROGRESS) && test_bit(NETFS_RREQ_PAUSE, &wreq->flags)) {
+-              trace_netfs_rreq(wreq, netfs_rreq_trace_unpause);
+-              clear_bit_unlock(NETFS_RREQ_PAUSE, &wreq->flags);
+-              smp_mb__after_atomic(); /* Set PAUSE before task state */
+-              wake_up(&wreq->waitq);
+-      }
+-      if (notes & NEED_REASSESS) {
++      if (notes & MADE_PROGRESS) {
++              netfs_wake_rreq_flag(wreq, NETFS_RREQ_PAUSE, netfs_rreq_trace_unpause);
+               //cond_resched();
+               goto reassess_streams;
+       }
+-      if (notes & MADE_PROGRESS) {
++
++      if (notes & NEED_REASSESS) {
+               //cond_resched();
+               goto reassess_streams;
+       }
+@@ -356,7 +352,7 @@ static void netfs_collect_write_results(struct netfs_io_request *wreq)
+ /*
+  * Perform the collection of subrequests, folios and encryption buffers.
+  */
+-static bool netfs_write_collection(struct netfs_io_request *wreq)
++bool netfs_write_collection(struct netfs_io_request *wreq)
+ {
+       struct netfs_inode *ictx = netfs_inode(wreq->inode);
+       size_t transferred;
+@@ -417,8 +413,7 @@ static bool netfs_write_collection(struct netfs_io_request *wreq)
+               inode_dio_end(wreq->inode);
+       _debug("finished");
+-      trace_netfs_rreq(wreq, netfs_rreq_trace_wake_ip);
+-      clear_and_wake_up_bit(NETFS_RREQ_IN_PROGRESS, &wreq->flags);
++      netfs_wake_rreq_flag(wreq, NETFS_RREQ_IN_PROGRESS, netfs_rreq_trace_wake_ip);
+       /* As we cleared NETFS_RREQ_IN_PROGRESS, we acquired its ref. */
+       if (wreq->iocb) {
+@@ -448,14 +443,6 @@ void netfs_write_collection_worker(struct work_struct *work)
+       }
+ }
+-/*
+- * Wake the collection work item.
+- */
+-void netfs_wake_write_collector(struct netfs_io_request *wreq)
+-{
+-      queue_work(system_unbound_wq, &wreq->work);
+-}
+-
+ /**
+  * netfs_write_subrequest_terminated - Note the termination of a write operation.
+  * @_op: The I/O request that has terminated.
+@@ -479,7 +466,6 @@ void netfs_write_subrequest_terminated(void *_op, ssize_t transferred_or_error)
+ {
+       struct netfs_io_subrequest *subreq = _op;
+       struct netfs_io_request *wreq = subreq->rreq;
+-      struct netfs_io_stream *stream = &wreq->io_streams[subreq->stream_nr];
+       _enter("%x[%x] %zd", wreq->debug_id, subreq->debug_index, transferred_or_error);
+@@ -531,15 +517,7 @@ void netfs_write_subrequest_terminated(void *_op, ssize_t transferred_or_error)
+       }
+       trace_netfs_sreq(subreq, netfs_sreq_trace_terminated);
+-
+-      clear_and_wake_up_bit(NETFS_SREQ_IN_PROGRESS, &subreq->flags);
+-
+-      /* If we are at the head of the queue, wake up the collector,
+-       * transferring a ref to it if we were the ones to do so.
+-       */
+-      if (list_is_first(&subreq->rreq_link, &stream->subrequests))
+-              netfs_wake_write_collector(wreq);
+-
++      netfs_subreq_clear_in_progress(subreq);
+       netfs_put_subrequest(subreq, netfs_sreq_trace_put_terminated);
+ }
+ EXPORT_SYMBOL(netfs_write_subrequest_terminated);
+diff --git a/fs/netfs/write_issue.c b/fs/netfs/write_issue.c
+index 8744ed3faf29b..50bee2c4130d1 100644
+--- a/fs/netfs/write_issue.c
++++ b/fs/netfs/write_issue.c
+@@ -542,7 +542,7 @@ static void netfs_end_issue_write(struct netfs_io_request *wreq)
+       }
+       if (needs_poke)
+-              netfs_wake_write_collector(wreq);
++              netfs_wake_collector(wreq);
+ }
+ /*
+@@ -576,6 +576,7 @@ int netfs_writepages(struct address_space *mapping,
+               goto couldnt_start;
+       }
++      __set_bit(NETFS_RREQ_OFFLOAD_COLLECTION, &wreq->flags);
+       trace_netfs_write(wreq, netfs_write_trace_writeback);
+       netfs_stat(&netfs_n_wh_writepages);
+@@ -599,7 +600,7 @@ int netfs_writepages(struct address_space *mapping,
+       netfs_end_issue_write(wreq);
+       mutex_unlock(&ictx->wb_lock);
+-      netfs_wake_write_collector(wreq);
++      netfs_wake_collector(wreq);
+       netfs_put_request(wreq, netfs_rreq_trace_put_return);
+       _leave(" = %d", error);
+@@ -674,11 +675,11 @@ int netfs_advance_writethrough(struct netfs_io_request *wreq, struct writeback_c
+ /*
+  * End a write operation used when writing through the pagecache.
+  */
+-int netfs_end_writethrough(struct netfs_io_request *wreq, struct writeback_control *wbc,
+-                         struct folio *writethrough_cache)
++ssize_t netfs_end_writethrough(struct netfs_io_request *wreq, struct writeback_control *wbc,
++                             struct folio *writethrough_cache)
+ {
+       struct netfs_inode *ictx = netfs_inode(wreq->inode);
+-      int ret;
++      ssize_t ret;
+       _enter("R=%x", wreq->debug_id);
+@@ -689,12 +690,10 @@ int netfs_end_writethrough(struct netfs_io_request *wreq, struct writeback_contr
+       mutex_unlock(&ictx->wb_lock);
+-      if (wreq->iocb) {
++      if (wreq->iocb)
+               ret = -EIOCBQUEUED;
+-      } else {
+-              wait_on_bit(&wreq->flags, NETFS_RREQ_IN_PROGRESS, TASK_UNINTERRUPTIBLE);
+-              ret = wreq->error;
+-      }
++      else
++              ret = netfs_wait_for_write(wreq);
+       netfs_put_request(wreq, netfs_rreq_trace_put_return);
+       return ret;
+ }
+@@ -723,10 +722,8 @@ int netfs_unbuffered_write(struct netfs_io_request *wreq, bool may_wait, size_t
+               start += part;
+               len -= part;
+               rolling_buffer_advance(&wreq->buffer, part);
+-              if (test_bit(NETFS_RREQ_PAUSE, &wreq->flags)) {
+-                      trace_netfs_rreq(wreq, netfs_rreq_trace_wait_pause);
+-                      wait_event(wreq->waitq, !test_bit(NETFS_RREQ_PAUSE, &wreq->flags));
+-              }
++              if (test_bit(NETFS_RREQ_PAUSE, &wreq->flags))
++                      netfs_wait_for_paused_write(wreq);
+               if (test_bit(NETFS_RREQ_FAILED, &wreq->flags))
+                       break;
+       }
+@@ -886,6 +883,7 @@ int netfs_writeback_single(struct address_space *mapping,
+               goto couldnt_start;
+       }
++      __set_bit(NETFS_RREQ_OFFLOAD_COLLECTION, &wreq->flags);
+       trace_netfs_write(wreq, netfs_write_trace_writeback_single);
+       netfs_stat(&netfs_n_wh_writepages);
+@@ -915,7 +913,7 @@ int netfs_writeback_single(struct address_space *mapping,
+       set_bit(NETFS_RREQ_ALL_QUEUED, &wreq->flags);
+       mutex_unlock(&ictx->wb_lock);
+-      netfs_wake_write_collector(wreq);
++      netfs_wake_collector(wreq);
+       netfs_put_request(wreq, netfs_rreq_trace_put_return);
+       _leave(" = %d", ret);
+diff --git a/fs/netfs/write_retry.c b/fs/netfs/write_retry.c
+index 7408f6bb8e42e..9d1d8a8bab726 100644
+--- a/fs/netfs/write_retry.c
++++ b/fs/netfs/write_retry.c
+@@ -200,7 +200,6 @@ static void netfs_retry_write_stream(struct netfs_io_request *wreq,
+  */
+ void netfs_retry_writes(struct netfs_io_request *wreq)
+ {
+-      struct netfs_io_subrequest *subreq;
+       struct netfs_io_stream *stream;
+       int s;
+@@ -209,16 +208,13 @@ void netfs_retry_writes(struct netfs_io_request *wreq)
+       /* Wait for all outstanding I/O to quiesce before performing retries as
+        * we may need to renegotiate the I/O sizes.
+        */
++      set_bit(NETFS_RREQ_RETRYING, &wreq->flags);
+       for (s = 0; s < NR_IO_STREAMS; s++) {
+               stream = &wreq->io_streams[s];
+-              if (!stream->active)
+-                      continue;
+-
+-              list_for_each_entry(subreq, &stream->subrequests, rreq_link) {
+-                      wait_on_bit(&subreq->flags, NETFS_SREQ_IN_PROGRESS,
+-                                  TASK_UNINTERRUPTIBLE);
+-              }
++              if (stream->active)
++                      netfs_wait_for_in_progress_stream(wreq, stream);
+       }
++      clear_bit(NETFS_RREQ_RETRYING, &wreq->flags);
+       // TODO: Enc: Fetch changed partial pages
+       // TODO: Enc: Reencrypt content if needed.
+-- 
+2.39.5
+
diff --git a/queue-6.15/netlink-specs-rt-link-add-missing-byte-order-propert.patch b/queue-6.15/netlink-specs-rt-link-add-missing-byte-order-propert.patch
new file mode 100644 (file)
index 0000000..aea9c31
--- /dev/null
@@ -0,0 +1,123 @@
+From df033d7343b82f0148c584ff5460487993ffac38 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Jun 2025 06:53:56 -0700
+Subject: netlink: specs: rt-link: add missing byte-order properties
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit de92258e3b22bd4ce920715cc91f09d788e5badf ]
+
+A number of fields in the ip tunnels are lacking the big-endian
+designation. I suspect this is not intentional, as decoding
+the ports with the right endian seems objectively beneficial.
+
+Fixes: 6ffdbb93a59c ("netlink: specs: rt_link: decode ip6tnl, vti and vti6 link attrs")
+Fixes: 077b6022d24b ("doc/netlink/specs: Add sub-message type to rt_link family")
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Reviewed-by: Donald Hunter <donald.hunter@gmail.com>
+Link: https://patch.msgid.link/20250603135357.502626-2-kuba@kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/netlink/specs/rt_link.yaml | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/Documentation/netlink/specs/rt_link.yaml b/Documentation/netlink/specs/rt_link.yaml
+index 6b9d5ee87d93a..ba767c42e8792 100644
+--- a/Documentation/netlink/specs/rt_link.yaml
++++ b/Documentation/netlink/specs/rt_link.yaml
+@@ -1778,15 +1778,19 @@ attribute-sets:
+       -
+         name: iflags
+         type: u16
++        byte-order: big-endian
+       -
+         name: oflags
+         type: u16
++        byte-order: big-endian
+       -
+         name: ikey
+         type: u32
++        byte-order: big-endian
+       -
+         name: okey
+         type: u32
++        byte-order: big-endian
+       -
+         name: local
+         type: binary
+@@ -1810,6 +1814,7 @@ attribute-sets:
+       -
+         name: flowinfo
+         type: u32
++        byte-order: big-endian
+       -
+         name: flags
+         type: u32
+@@ -1822,9 +1827,11 @@ attribute-sets:
+       -
+         name: encap-sport
+         type: u16
++        byte-order: big-endian
+       -
+         name: encap-dport
+         type: u16
++        byte-order: big-endian
+       -
+         name: collect-metadata
+         type: flag
+@@ -1856,9 +1863,11 @@ attribute-sets:
+       -
+         name: ikey
+         type: u32
++        byte-order: big-endian
+       -
+         name: okey
+         type: u32
++        byte-order: big-endian
+       -
+         name: local
+         type: binary
+@@ -1908,6 +1917,7 @@ attribute-sets:
+       -
+         name: port
+         type: u16
++        byte-order: big-endian
+       -
+         name: collect-metadata
+         type: flag
+@@ -1927,6 +1937,7 @@ attribute-sets:
+       -
+         name: label
+         type: u32
++        byte-order: big-endian
+       -
+         name: ttl-inherit
+         type: u8
+@@ -1967,9 +1978,11 @@ attribute-sets:
+       -
+         name: flowinfo
+         type: u32
++        byte-order: big-endian
+       -
+         name: flags
+         type: u16
++        byte-order: big-endian
+       -
+         name: proto
+         type: u8
+@@ -1999,9 +2012,11 @@ attribute-sets:
+       -
+         name: encap-sport
+         type: u16
++        byte-order: big-endian
+       -
+         name: encap-dport
+         type: u16
++        byte-order: big-endian
+       -
+         name: collect-metadata
+         type: flag
+-- 
+2.39.5
+
diff --git a/queue-6.15/netlink-specs-rt-link-decode-ip6gre.patch b/queue-6.15/netlink-specs-rt-link-decode-ip6gre.patch
new file mode 100644 (file)
index 0000000..c734226
--- /dev/null
@@ -0,0 +1,108 @@
+From 9012682ef34e6d9f02f0cdf4af72a0459e6cf788 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Jun 2025 06:53:57 -0700
+Subject: netlink: specs: rt-link: decode ip6gre
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 8af7a919c52f02514a145f995cbdf0deadb8075a ]
+
+Driver tests now require GRE tunnels, while we don't configure
+them with YNL, YNL will complain when it sees link types it
+doesn't recognize. Teach it decoding ip6gre tunnels. The attrs
+are largely the same as IPv4 GRE.
+
+Correct the type of encap-limit, but note that this attr is
+only used in ip6gre, so the mistake didn't matter until now.
+
+Fixes: 0d0f4174f6c8 ("selftests: drv-net: add a simple TSO test")
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Reviewed-by: Donald Hunter <donald.hunter@gmail.com>
+Link: https://patch.msgid.link/20250603135357.502626-3-kuba@kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/netlink/specs/rt_link.yaml | 53 +++++++++++++++++++++++-
+ 1 file changed, 52 insertions(+), 1 deletion(-)
+
+diff --git a/Documentation/netlink/specs/rt_link.yaml b/Documentation/netlink/specs/rt_link.yaml
+index ba767c42e8792..2ac0e9fda1582 100644
+--- a/Documentation/netlink/specs/rt_link.yaml
++++ b/Documentation/netlink/specs/rt_link.yaml
+@@ -1810,7 +1810,7 @@ attribute-sets:
+         type: u8
+       -
+         name: encap-limit
+-        type: u32
++        type: u8
+       -
+         name: flowinfo
+         type: u32
+@@ -1853,6 +1853,54 @@ attribute-sets:
+       -
+         name: erspan-hwid
+         type: u16
++  -
++    name: linkinfo-gre6-attrs
++    subset-of: linkinfo-gre-attrs
++    attributes:
++      -
++        name: link
++      -
++        name: iflags
++      -
++        name: oflags
++      -
++        name: ikey
++      -
++        name: okey
++      -
++        name: local
++        display-hint: ipv6
++      -
++        name: remote
++        display-hint: ipv6
++      -
++        name: ttl
++      -
++        name: encap-limit
++      -
++        name: flowinfo
++      -
++        name: flags
++      -
++        name: encap-type
++      -
++        name: encap-flags
++      -
++        name: encap-sport
++      -
++        name: encap-dport
++      -
++        name: collect-metadata
++      -
++        name: fwmark
++      -
++        name: erspan-index
++      -
++        name: erspan-ver
++      -
++        name: erspan-dir
++      -
++        name: erspan-hwid
+   -
+     name: linkinfo-vti-attrs
+     name-prefix: ifla-vti-
+@@ -2314,6 +2362,9 @@ sub-messages:
+       -
+         value: gretap
+         attribute-set: linkinfo-gre-attrs
++      -
++        value: ip6gre
++        attribute-set: linkinfo-gre6-attrs
+       -
+         value: geneve
+         attribute-set: linkinfo-geneve-attrs
+-- 
+2.39.5
+
diff --git a/queue-6.15/nfs-clear-sb_rdonly-before-getting-superblock.patch b/queue-6.15/nfs-clear-sb_rdonly-before-getting-superblock.patch
new file mode 100644 (file)
index 0000000..66480f7
--- /dev/null
@@ -0,0 +1,68 @@
+From 6c511c6eb29b6dc050caa6ffb4994e59f2646d25 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Mar 2025 21:05:32 +0800
+Subject: nfs: clear SB_RDONLY before getting superblock
+
+From: Li Lingfeng <lilingfeng3@huawei.com>
+
+[ Upstream commit 8cd9b785943c57a136536250da80ba1eb6f8eb18 ]
+
+As described in the link, commit 52cb7f8f1778 ("nfs: ignore SB_RDONLY when
+mounting nfs") removed the check for the ro flag when determining whether
+to share the superblock, which caused issues when mounting different
+subdirectories under the same export directory via NFSv3. However, this
+change did not affect NFSv4.
+
+For NFSv3:
+1) A single superblock is created for the initial mount.
+2) When mounted read-only, this superblock carries the SB_RDONLY flag.
+3) Before commit 52cb7f8f1778 ("nfs: ignore SB_RDONLY when mounting nfs"):
+Subsequent rw mounts would not share the existing ro superblock due to
+flag mismatch, creating a new superblock without SB_RDONLY.
+After the commit:
+  The SB_RDONLY flag is ignored during superblock comparison, and this leads
+  to sharing the existing superblock even for rw mounts.
+  Ultimately results in write operations being rejected at the VFS layer.
+
+For NFSv4:
+1) Multiple superblocks are created and the last one will be kept.
+2) The actually used superblock for ro mounts doesn't carry SB_RDONLY flag.
+Therefore, commit 52cb7f8f1778 doesn't affect NFSv4 mounts.
+
+Clear SB_RDONLY before getting superblock when NFS_MOUNT_UNSHARED is not
+set to fix it.
+
+Fixes: 52cb7f8f1778 ("nfs: ignore SB_RDONLY when mounting nfs")
+Closes: https://lore.kernel.org/all/12d7ea53-1202-4e21-a7ef-431c94758ce5@app.fastmail.com/T/
+Signed-off-by: Li Lingfeng <lilingfeng3@huawei.com>
+Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/super.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/fs/nfs/super.c b/fs/nfs/super.c
+index 9eea9e62afc9c..1a609471e85ef 100644
+--- a/fs/nfs/super.c
++++ b/fs/nfs/super.c
+@@ -1308,8 +1308,17 @@ int nfs_get_tree_common(struct fs_context *fc)
+       if (IS_ERR(server))
+               return PTR_ERR(server);
++      /*
++       * When NFS_MOUNT_UNSHARED is not set, NFS forces the sharing of a
++       * superblock among each filesystem that mounts sub-directories
++       * belonging to a single exported root path.
++       * To prevent interference between different filesystems, the
++       * SB_RDONLY flag should be removed from the superblock.
++       */
+       if (server->flags & NFS_MOUNT_UNSHARED)
+               compare_super = NULL;
++      else
++              fc->sb_flags &= ~SB_RDONLY;
+       /* -o noac implies -o sync */
+       if (server->flags & NFS_MOUNT_NOAC)
+-- 
+2.39.5
+
diff --git a/queue-6.15/nfs-fix-incorrect-handling-of-large-number-nfs-error.patch b/queue-6.15/nfs-fix-incorrect-handling-of-large-number-nfs-error.patch
new file mode 100644 (file)
index 0000000..90e6681
--- /dev/null
@@ -0,0 +1,121 @@
+From 010c1a0cd4198f403d24084f28447d0b0ce10d2c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 May 2025 14:08:25 +1000
+Subject: nfs: fix incorrect handling of large-number NFS errors in
+ nfs4_do_mkdir()
+
+From: NeilBrown <neil@brown.name>
+
+[ Upstream commit dd862da61e91123ca745e06c03ba39ce71a929d9 ]
+
+A recent commit introduced nfs4_do_mkdir() which reports an error from
+nfs4_call_sync() by returning it with ERR_PTR().
+
+This is a problem as nfs4_call_sync() can return negative NFS-specific
+errors with values larger than MAX_ERRNO (4095).  One example is
+NFS4ERR_DELAY which has value 10008.
+
+This "pointer" gets to PTR_ERR_OR_ZERO() in nfs4_proc_mkdir() which
+chooses ZERO because it isn't in the range of value errors.  Ultimately
+the pointer is dereferenced.
+
+This patch changes nfs4_do_mkdir() to report the dentry pointer and
+status separately - pointer as a return value, status in an "int *"
+parameter.
+
+The same separation is used for _nfs4_proc_mkdir() and the two are
+combined only in nfs4_proc_mkdir() after the status has passed through
+nfs4_handle_exception(), which ensures the error code does not exceed
+MAX_ERRNO.
+
+It also fixes a problem in the even when nfs4_handle_exception() updated
+the error value, the original 'alias' was still returned.
+
+Reported-by: Anna Schumaker <anna@kernel.org>
+Fixes: 8376583b84a1 ("nfs: change mkdir inode_operation to return alternate dentry if needed.")
+Signed-off-by: NeilBrown <neil@brown.name>
+Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/nfs4proc.c | 32 ++++++++++++++++++++------------
+ 1 file changed, 20 insertions(+), 12 deletions(-)
+
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index b1d2122bd5a74..4b123bca65e12 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -5164,13 +5164,15 @@ static int nfs4_do_create(struct inode *dir, struct dentry *dentry, struct nfs4_
+ }
+ static struct dentry *nfs4_do_mkdir(struct inode *dir, struct dentry *dentry,
+-                                  struct nfs4_createdata *data)
++                                  struct nfs4_createdata *data, int *statusp)
+ {
+-      int status = nfs4_call_sync(NFS_SERVER(dir)->client, NFS_SERVER(dir), &data->msg,
++      struct dentry *ret;
++
++      *statusp = nfs4_call_sync(NFS_SERVER(dir)->client, NFS_SERVER(dir), &data->msg,
+                                   &data->arg.seq_args, &data->res.seq_res, 1);
+-      if (status)
+-              return ERR_PTR(status);
++      if (*statusp)
++              return NULL;
+       spin_lock(&dir->i_lock);
+       /* Creating a directory bumps nlink in the parent */
+@@ -5179,7 +5181,11 @@ static struct dentry *nfs4_do_mkdir(struct inode *dir, struct dentry *dentry,
+                                     data->res.fattr->time_start,
+                                     NFS_INO_INVALID_DATA);
+       spin_unlock(&dir->i_lock);
+-      return nfs_add_or_obtain(dentry, data->res.fh, data->res.fattr);
++      ret = nfs_add_or_obtain(dentry, data->res.fh, data->res.fattr);
++      if (!IS_ERR(ret))
++              return ret;
++      *statusp = PTR_ERR(ret);
++      return NULL;
+ }
+ static void nfs4_free_createdata(struct nfs4_createdata *data)
+@@ -5240,17 +5246,18 @@ static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
+ static struct dentry *_nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
+                                      struct iattr *sattr,
+-                                     struct nfs4_label *label)
++                                     struct nfs4_label *label, int *statusp)
+ {
+       struct nfs4_createdata *data;
+-      struct dentry *ret = ERR_PTR(-ENOMEM);
++      struct dentry *ret = NULL;
++      *statusp = -ENOMEM;
+       data = nfs4_alloc_createdata(dir, &dentry->d_name, sattr, NF4DIR);
+       if (data == NULL)
+               goto out;
+       data->arg.label = label;
+-      ret = nfs4_do_mkdir(dir, dentry, data);
++      ret = nfs4_do_mkdir(dir, dentry, data, statusp);
+       nfs4_free_createdata(data);
+ out:
+@@ -5273,11 +5280,12 @@ static struct dentry *nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
+       if (!(server->attr_bitmask[2] & FATTR4_WORD2_MODE_UMASK))
+               sattr->ia_mode &= ~current_umask();
+       do {
+-              alias = _nfs4_proc_mkdir(dir, dentry, sattr, label);
+-              err = PTR_ERR_OR_ZERO(alias);
++              alias = _nfs4_proc_mkdir(dir, dentry, sattr, label, &err);
+               trace_nfs4_mkdir(dir, &dentry->d_name, err);
+-              err = nfs4_handle_exception(NFS_SERVER(dir), err,
+-                              &exception);
++              if (err)
++                      alias = ERR_PTR(nfs4_handle_exception(NFS_SERVER(dir),
++                                                            err,
++                                                            &exception));
+       } while (exception.retry);
+       nfs4_label_release_security(label);
+-- 
+2.39.5
+
diff --git a/queue-6.15/nfs-ignore-sb_rdonly-when-remounting-nfs.patch b/queue-6.15/nfs-ignore-sb_rdonly-when-remounting-nfs.patch
new file mode 100644 (file)
index 0000000..510d3d7
--- /dev/null
@@ -0,0 +1,72 @@
+From 2065df0278b98382dce6d921a1c6e5127fb045f0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Mar 2025 21:05:33 +0800
+Subject: nfs: ignore SB_RDONLY when remounting nfs
+
+From: Li Lingfeng <lilingfeng3@huawei.com>
+
+[ Upstream commit 80c4de6ab44c14e910117a02f2f8241ffc6ec54a ]
+
+In some scenarios, when mounting NFS, more than one superblock may be
+created. The final superblock used is the last one created, but only the
+first superblock carries the ro flag passed from user space. If a ro flag
+is added to the superblock via remount, it will trigger the issue
+described in Link[1].
+
+Link[2] attempted to address this by marking the superblock as ro during
+the initial mount. However, this introduced a new problem in scenarios
+where multiple mount points share the same superblock:
+[root@a ~]# mount /dev/sdb /mnt/sdb
+[root@a ~]# echo "/mnt/sdb *(rw,no_root_squash)" > /etc/exports
+[root@a ~]# echo "/mnt/sdb/test_dir2 *(ro,no_root_squash)" >> /etc/exports
+[root@a ~]# systemctl restart nfs-server
+[root@a ~]# mount -t nfs -o rw 127.0.0.1:/mnt/sdb/test_dir1 /mnt/test_mp1
+[root@a ~]# mount | grep nfs4
+127.0.0.1:/mnt/sdb/test_dir1 on /mnt/test_mp1 type nfs4 (rw,relatime,...
+[root@a ~]# mount -t nfs -o ro 127.0.0.1:/mnt/sdb/test_dir2 /mnt/test_mp2
+[root@a ~]# mount | grep nfs4
+127.0.0.1:/mnt/sdb/test_dir1 on /mnt/test_mp1 type nfs4 (ro,relatime,...
+127.0.0.1:/mnt/sdb/test_dir2 on /mnt/test_mp2 type nfs4 (ro,relatime,...
+[root@a ~]#
+
+When mounting the second NFS, the shared superblock is marked as ro,
+causing the previous NFS mount to become read-only.
+
+To resolve both issues, the ro flag is no longer applied to the superblock
+during remount. Instead, the ro flag on the mount is used to control
+whether the mount point is read-only.
+
+Fixes: 281cad46b34d ("NFS: Create a submount rpc_op")
+Link[1]: https://lore.kernel.org/all/20240604112636.236517-3-lilingfeng@huaweicloud.com/
+Link[2]: https://lore.kernel.org/all/20241130035818.1459775-1-lilingfeng3@huawei.com/
+Signed-off-by: Li Lingfeng <lilingfeng3@huawei.com>
+Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/super.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/fs/nfs/super.c b/fs/nfs/super.c
+index 1a609471e85ef..91b5503b6f74d 100644
+--- a/fs/nfs/super.c
++++ b/fs/nfs/super.c
+@@ -1051,6 +1051,16 @@ int nfs_reconfigure(struct fs_context *fc)
+       sync_filesystem(sb);
++      /*
++       * The SB_RDONLY flag has been removed from the superblock during
++       * mounts to prevent interference between different filesystems.
++       * Similarly, it is also necessary to ignore the SB_RDONLY flag
++       * during reconfiguration; otherwise, it may also result in the
++       * creation of redundant superblocks when mounting a directory with
++       * different rw and ro flags multiple times.
++       */
++      fc->sb_flags_mask &= ~SB_RDONLY;
++
+       /*
+        * Userspace mount programs that send binary options generally send
+        * them populated with default values. We have no way to know which
+-- 
+2.39.5
+
diff --git a/queue-6.15/nfs_localio-always-hold-nfsd-net-ref-with-nfsd_file-.patch b/queue-6.15/nfs_localio-always-hold-nfsd-net-ref-with-nfsd_file-.patch
new file mode 100644 (file)
index 0000000..15ee274
--- /dev/null
@@ -0,0 +1,180 @@
+From 106272c1d61c4f56398c3f3c7f0bb8515e0ac213 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 May 2025 10:46:39 +1000
+Subject: nfs_localio: always hold nfsd net ref with nfsd_file ref
+
+From: NeilBrown <neil@brown.name>
+
+[ Upstream commit 77e82fb2c6c27c122e785f543ae0062f7783c886 ]
+
+Having separate nfsd_file_put and nfsd_file_put_local in struct
+nfsd_localio_operations doesn't make much sense.  The difference is that
+nfsd_file_put doesn't drop a reference to the nfs_net which is what
+keeps nfsd from shutting down.
+
+Currently, if nfsd tries to shutdown it will invalidate the files stored
+in the list from the nfs_uuid and this will drop all references to the
+nfsd net that the client holds.  But the client could still hold some
+references to nfsd_files for active IO.  So nfsd might think is has
+completely shut down local IO, but hasn't and has no way to wait for
+those active IO requests to complete.
+
+So this patch changes nfsd_file_get to nfsd_file_get_local and has it
+increase the ref count on the nfsd net and it replaces all calls to
+->nfsd_put_file to ->nfsd_put_file_local.
+
+It also changes ->nfsd_open_local_fh to return with the refcount on the
+net elevated precisely when a valid nfsd_file is returned.
+
+This means that whenever the client holds a valid nfsd_file, there will
+be an associated count on the nfsd net, and so the count can only reach
+zero when all nfsd_files have been returned.
+
+nfs_local_file_put() is changed to call nfs_to_nfsd_file_put_local()
+instead of replacing calls to one with calls to the other because this
+will help a later patch which changes nfs_to_nfsd_file_put_local() to
+take an __rcu pointer while nfs_local_file_put() doesn't.
+
+Fixes: 86e00412254a ("nfs: cache all open LOCALIO nfsd_file(s) in client")
+Signed-off-by: NeilBrown <neil@brown.name>
+Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/localio.c           |  4 ++--
+ fs/nfs_common/nfslocalio.c |  5 ++---
+ fs/nfsd/filecache.c        | 21 +++++++++++++++++++++
+ fs/nfsd/filecache.h        |  1 +
+ fs/nfsd/localio.c          |  9 +++++++--
+ include/linux/nfslocalio.h |  3 +--
+ 6 files changed, 34 insertions(+), 9 deletions(-)
+
+diff --git a/fs/nfs/localio.c b/fs/nfs/localio.c
+index 595903c215235..8fb08c3ad563b 100644
+--- a/fs/nfs/localio.c
++++ b/fs/nfs/localio.c
+@@ -209,12 +209,12 @@ EXPORT_SYMBOL_GPL(nfs_local_probe_async);
+ static inline struct nfsd_file *nfs_local_file_get(struct nfsd_file *nf)
+ {
+-      return nfs_to->nfsd_file_get(nf);
++      return nfs_to->nfsd_file_get_local(nf);
+ }
+ static inline void nfs_local_file_put(struct nfsd_file *nf)
+ {
+-      nfs_to->nfsd_file_put(nf);
++      nfs_to_nfsd_file_put_local(nf);
+ }
+ /*
+diff --git a/fs/nfs_common/nfslocalio.c b/fs/nfs_common/nfslocalio.c
+index bdf251332b6b8..f6821b2c87a2f 100644
+--- a/fs/nfs_common/nfslocalio.c
++++ b/fs/nfs_common/nfslocalio.c
+@@ -262,9 +262,8 @@ struct nfsd_file *nfs_open_local_fh(nfs_uuid_t *uuid,
+       /* We have an implied reference to net thanks to nfsd_net_try_get */
+       localio = nfs_to->nfsd_open_local_fh(net, uuid->dom, rpc_clnt,
+                                            cred, nfs_fh, fmode);
+-      if (IS_ERR(localio))
+-              nfs_to_nfsd_net_put(net);
+-      else
++      nfs_to_nfsd_net_put(net);
++      if (!IS_ERR(localio))
+               nfs_uuid_add_file(uuid, nfl);
+       return localio;
+diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c
+index ab85e6a2454f4..eedf2af8ee6ec 100644
+--- a/fs/nfsd/filecache.c
++++ b/fs/nfsd/filecache.c
+@@ -386,6 +386,27 @@ nfsd_file_put_local(struct nfsd_file *nf)
+       return net;
+ }
++/**
++ * nfsd_file_get_local - get nfsd_file reference and reference to net
++ * @nf: nfsd_file of which to put the reference
++ *
++ * Get reference to both the nfsd_file and nf->nf_net.
++ */
++struct nfsd_file *
++nfsd_file_get_local(struct nfsd_file *nf)
++{
++      struct net *net = nf->nf_net;
++
++      if (nfsd_net_try_get(net)) {
++              nf = nfsd_file_get(nf);
++              if (!nf)
++                      nfsd_net_put(net);
++      } else {
++              nf = NULL;
++      }
++      return nf;
++}
++
+ /**
+  * nfsd_file_file - get the backing file of an nfsd_file
+  * @nf: nfsd_file of which to access the backing file.
+diff --git a/fs/nfsd/filecache.h b/fs/nfsd/filecache.h
+index 5865f9c727121..cd02f91aaef13 100644
+--- a/fs/nfsd/filecache.h
++++ b/fs/nfsd/filecache.h
+@@ -63,6 +63,7 @@ int nfsd_file_cache_start_net(struct net *net);
+ void nfsd_file_cache_shutdown_net(struct net *net);
+ void nfsd_file_put(struct nfsd_file *nf);
+ struct net *nfsd_file_put_local(struct nfsd_file *nf);
++struct nfsd_file *nfsd_file_get_local(struct nfsd_file *nf);
+ struct nfsd_file *nfsd_file_get(struct nfsd_file *nf);
+ struct file *nfsd_file_file(struct nfsd_file *nf);
+ void nfsd_file_close_inode_sync(struct inode *inode);
+diff --git a/fs/nfsd/localio.c b/fs/nfsd/localio.c
+index 238647fa379e3..2c0afd1067ea6 100644
+--- a/fs/nfsd/localio.c
++++ b/fs/nfsd/localio.c
+@@ -29,8 +29,7 @@ static const struct nfsd_localio_operations nfsd_localio_ops = {
+       .nfsd_net_put  = nfsd_net_put,
+       .nfsd_open_local_fh = nfsd_open_local_fh,
+       .nfsd_file_put_local = nfsd_file_put_local,
+-      .nfsd_file_get = nfsd_file_get,
+-      .nfsd_file_put = nfsd_file_put,
++      .nfsd_file_get_local = nfsd_file_get_local,
+       .nfsd_file_file = nfsd_file_file,
+ };
+@@ -71,6 +70,9 @@ nfsd_open_local_fh(struct net *net, struct auth_domain *dom,
+       if (nfs_fh->size > NFS4_FHSIZE)
+               return ERR_PTR(-EINVAL);
++      if (!nfsd_net_try_get(net))
++              return ERR_PTR(-ENXIO);
++
+       /* nfs_fh -> svc_fh */
+       fh_init(&fh, NFS4_FHSIZE);
+       fh.fh_handle.fh_size = nfs_fh->size;
+@@ -92,6 +94,9 @@ nfsd_open_local_fh(struct net *net, struct auth_domain *dom,
+       if (rq_cred.cr_group_info)
+               put_group_info(rq_cred.cr_group_info);
++      if (IS_ERR(localio))
++              nfsd_net_put(net);
++
+       return localio;
+ }
+ EXPORT_SYMBOL_GPL(nfsd_open_local_fh);
+diff --git a/include/linux/nfslocalio.h b/include/linux/nfslocalio.h
+index 9aa8a43843d71..c3f34bae60e13 100644
+--- a/include/linux/nfslocalio.h
++++ b/include/linux/nfslocalio.h
+@@ -66,8 +66,7 @@ struct nfsd_localio_operations {
+                                               const struct nfs_fh *,
+                                               const fmode_t);
+       struct net *(*nfsd_file_put_local)(struct nfsd_file *);
+-      struct nfsd_file *(*nfsd_file_get)(struct nfsd_file *);
+-      void (*nfsd_file_put)(struct nfsd_file *);
++      struct nfsd_file *(*nfsd_file_get_local)(struct nfsd_file *);
+       struct file *(*nfsd_file_file)(struct nfsd_file *);
+ } ____cacheline_aligned;
+-- 
+2.39.5
+
diff --git a/queue-6.15/nfs_localio-change-nfsd_file_put_local-to-take-a-poi.patch b/queue-6.15/nfs_localio-change-nfsd_file_put_local-to-take-a-poi.patch
new file mode 100644 (file)
index 0000000..43973e8
--- /dev/null
@@ -0,0 +1,227 @@
+From 07278c23470b09e7b265609bacaad09708e7b334 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 May 2025 10:46:43 +1000
+Subject: nfs_localio: change nfsd_file_put_local() to take a pointer to __rcu
+ pointer
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: NeilBrown <neil@brown.name>
+
+[ Upstream commit c25a89770d1f216dcedfc2d25d56b604f62ce0bd ]
+
+Instead of calling xchg() and unrcu_pointer() before
+nfsd_file_put_local(), we now pass pointer to the __rcu pointer and call
+xchg() and unrcu_pointer() inside that function.
+
+Where unrcu_pointer() is currently called the internals of "struct
+nfsd_file" are not known and that causes older compilers such as gcc-8
+to complain.
+
+In some cases we have a __kernel (aka normal) pointer not an __rcu
+pointer so we need to cast it to __rcu first.  This is strictly a
+weakening so no information is lost.  Somewhat surprisingly, this cast
+is accepted by gcc-8.
+
+This has the pleasing result that the cmpxchg() which sets ro_file and
+rw_file, and also the xchg() which clears them, are both now in the nfsd
+code.
+
+Reported-by: Pali Rohár <pali@kernel.org>
+Reported-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Fixes: 86e00412254a ("nfs: cache all open LOCALIO nfsd_file(s) in client")
+Signed-off-by: NeilBrown <neil@brown.name>
+Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/localio.c           | 11 +++++++++--
+ fs/nfs_common/nfslocalio.c | 24 ++++++------------------
+ fs/nfsd/filecache.c        | 11 ++++++++---
+ fs/nfsd/filecache.h        |  2 +-
+ include/linux/nfslocalio.h | 23 ++++++++++++-----------
+ 5 files changed, 36 insertions(+), 35 deletions(-)
+
+diff --git a/fs/nfs/localio.c b/fs/nfs/localio.c
+index 030a54c8c9d8b..e6d36b3d3fc05 100644
+--- a/fs/nfs/localio.c
++++ b/fs/nfs/localio.c
+@@ -207,9 +207,16 @@ void nfs_local_probe_async(struct nfs_client *clp)
+ }
+ EXPORT_SYMBOL_GPL(nfs_local_probe_async);
+-static inline void nfs_local_file_put(struct nfsd_file *nf)
++static inline void nfs_local_file_put(struct nfsd_file *localio)
+ {
+-      nfs_to_nfsd_file_put_local(nf);
++      /* nfs_to_nfsd_file_put_local() expects an __rcu pointer
++       * but we have a __kernel pointer.  It is always safe
++       * to cast a __kernel pointer to an __rcu pointer
++       * because the cast only weakens what is known about the pointer.
++       */
++      struct nfsd_file __rcu *nf = (struct nfsd_file __rcu*) localio;
++
++      nfs_to_nfsd_file_put_local(&nf);
+ }
+ /*
+diff --git a/fs/nfs_common/nfslocalio.c b/fs/nfs_common/nfslocalio.c
+index 1dd5a8cca064d..05c7c16e37ab4 100644
+--- a/fs/nfs_common/nfslocalio.c
++++ b/fs/nfs_common/nfslocalio.c
+@@ -170,9 +170,6 @@ static bool nfs_uuid_put(nfs_uuid_t *nfs_uuid)
+       while ((nfl = list_first_entry_or_null(&nfs_uuid->files,
+                                              struct nfs_file_localio,
+                                              list)) != NULL) {
+-              struct nfsd_file *ro_nf;
+-              struct nfsd_file *rw_nf;
+-
+               /* If nfs_uuid is already NULL, nfs_close_local_fh is
+                * closing and we must wait, else we unlink and close.
+                */
+@@ -189,17 +186,14 @@ static bool nfs_uuid_put(nfs_uuid_t *nfs_uuid)
+                       continue;
+               }
+-              ro_nf = unrcu_pointer(xchg(&nfl->ro_file, NULL));
+-              rw_nf = unrcu_pointer(xchg(&nfl->rw_file, NULL));
+-
+               /* Remove nfl from nfs_uuid->files list */
+               list_del_init(&nfl->list);
+               spin_unlock(&nfs_uuid->lock);
+-              if (ro_nf)
+-                      nfs_to_nfsd_file_put_local(ro_nf);
+-              if (rw_nf)
+-                      nfs_to_nfsd_file_put_local(rw_nf);
++
++              nfs_to_nfsd_file_put_local(&nfl->ro_file);
++              nfs_to_nfsd_file_put_local(&nfl->rw_file);
+               cond_resched();
++
+               spin_lock(&nfs_uuid->lock);
+               /* Now we can allow racing nfs_close_local_fh() to
+                * skip the locking.
+@@ -303,8 +297,6 @@ EXPORT_SYMBOL_GPL(nfs_open_local_fh);
+ void nfs_close_local_fh(struct nfs_file_localio *nfl)
+ {
+-      struct nfsd_file *ro_nf;
+-      struct nfsd_file *rw_nf;
+       nfs_uuid_t *nfs_uuid;
+       rcu_read_lock();
+@@ -337,12 +329,8 @@ void nfs_close_local_fh(struct nfs_file_localio *nfl)
+       spin_unlock(&nfs_uuid->lock);
+       rcu_read_unlock();
+-      ro_nf = unrcu_pointer(xchg(&nfl->ro_file, NULL));
+-      rw_nf = unrcu_pointer(xchg(&nfl->rw_file, NULL));
+-      if (ro_nf)
+-              nfs_to_nfsd_file_put_local(ro_nf);
+-      if (rw_nf)
+-              nfs_to_nfsd_file_put_local(rw_nf);
++      nfs_to_nfsd_file_put_local(&nfl->ro_file);
++      nfs_to_nfsd_file_put_local(&nfl->rw_file);
+       /* Remove nfl from nfs_uuid->files list and signal nfs_uuid_put()
+        * that we are done.  The moment we drop the spinlock the
+diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c
+index eedf2af8ee6ec..e108b6c705b45 100644
+--- a/fs/nfsd/filecache.c
++++ b/fs/nfsd/filecache.c
+@@ -378,11 +378,16 @@ nfsd_file_put(struct nfsd_file *nf)
+  * the reference of the nfsd_file.
+  */
+ struct net *
+-nfsd_file_put_local(struct nfsd_file *nf)
++nfsd_file_put_local(struct nfsd_file __rcu **pnf)
+ {
+-      struct net *net = nf->nf_net;
++      struct nfsd_file *nf;
++      struct net *net = NULL;
+-      nfsd_file_put(nf);
++      nf = unrcu_pointer(xchg(pnf, NULL));
++      if (nf) {
++              net = nf->nf_net;
++              nfsd_file_put(nf);
++      }
+       return net;
+ }
+diff --git a/fs/nfsd/filecache.h b/fs/nfsd/filecache.h
+index cd02f91aaef13..722b26c71e454 100644
+--- a/fs/nfsd/filecache.h
++++ b/fs/nfsd/filecache.h
+@@ -62,7 +62,7 @@ void nfsd_file_cache_shutdown(void);
+ int nfsd_file_cache_start_net(struct net *net);
+ void nfsd_file_cache_shutdown_net(struct net *net);
+ void nfsd_file_put(struct nfsd_file *nf);
+-struct net *nfsd_file_put_local(struct nfsd_file *nf);
++struct net *nfsd_file_put_local(struct nfsd_file __rcu **nf);
+ struct nfsd_file *nfsd_file_get_local(struct nfsd_file *nf);
+ struct nfsd_file *nfsd_file_get(struct nfsd_file *nf);
+ struct file *nfsd_file_file(struct nfsd_file *nf);
+diff --git a/include/linux/nfslocalio.h b/include/linux/nfslocalio.h
+index c3f34bae60e13..5c7c92659e736 100644
+--- a/include/linux/nfslocalio.h
++++ b/include/linux/nfslocalio.h
+@@ -50,10 +50,6 @@ void nfs_localio_invalidate_clients(struct list_head *nn_local_clients,
+                                   spinlock_t *nn_local_clients_lock);
+ /* localio needs to map filehandle -> struct nfsd_file */
+-extern struct nfsd_file *
+-nfsd_open_local_fh(struct net *, struct auth_domain *, struct rpc_clnt *,
+-                 const struct cred *, const struct nfs_fh *,
+-                 const fmode_t) __must_hold(rcu);
+ void nfs_close_local_fh(struct nfs_file_localio *);
+ struct nfsd_localio_operations {
+@@ -64,8 +60,9 @@ struct nfsd_localio_operations {
+                                               struct rpc_clnt *,
+                                               const struct cred *,
+                                               const struct nfs_fh *,
++                                              struct nfsd_file __rcu **pnf,
+                                               const fmode_t);
+-      struct net *(*nfsd_file_put_local)(struct nfsd_file *);
++      struct net *(*nfsd_file_put_local)(struct nfsd_file __rcu **);
+       struct nfsd_file *(*nfsd_file_get_local)(struct nfsd_file *);
+       struct file *(*nfsd_file_file)(struct nfsd_file *);
+ } ____cacheline_aligned;
+@@ -76,6 +73,7 @@ extern const struct nfsd_localio_operations *nfs_to;
+ struct nfsd_file *nfs_open_local_fh(nfs_uuid_t *,
+                  struct rpc_clnt *, const struct cred *,
+                  const struct nfs_fh *, struct nfs_file_localio *,
++                 struct nfsd_file __rcu **pnf,
+                  const fmode_t);
+ static inline void nfs_to_nfsd_net_put(struct net *net)
+@@ -90,16 +88,19 @@ static inline void nfs_to_nfsd_net_put(struct net *net)
+       rcu_read_unlock();
+ }
+-static inline void nfs_to_nfsd_file_put_local(struct nfsd_file *localio)
++static inline void nfs_to_nfsd_file_put_local(struct nfsd_file __rcu **localio)
+ {
+       /*
+-       * Must not hold RCU otherwise nfsd_file_put() can easily trigger:
+-       * "Voluntary context switch within RCU read-side critical section!"
+-       * by scheduling deep in underlying filesystem (e.g. XFS).
++       * Either *localio must be guaranteed to be non-NULL, or caller
++       * must prevent nfsd shutdown from completing as nfs_close_local_fh()
++       * does by blocking the nfs_uuid from being finally put.
+        */
+-      struct net *net = nfs_to->nfsd_file_put_local(localio);
++      struct net *net;
+-      nfs_to_nfsd_net_put(net);
++      net = nfs_to->nfsd_file_put_local(localio);
++
++      if (net)
++              nfs_to_nfsd_net_put(net);
+ }
+ #else   /* CONFIG_NFS_LOCALIO */
+-- 
+2.39.5
+
diff --git a/queue-6.15/nfs_localio-duplicate-nfs_close_local_fh.patch b/queue-6.15/nfs_localio-duplicate-nfs_close_local_fh.patch
new file mode 100644 (file)
index 0000000..7291bbb
--- /dev/null
@@ -0,0 +1,69 @@
+From e516a45046f9874b048ccdc8a44ca4d162e6d0d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 May 2025 10:46:41 +1000
+Subject: nfs_localio: duplicate nfs_close_local_fh()
+
+From: NeilBrown <neil@brown.name>
+
+[ Upstream commit 74fc55ab2a6a0c71628fcf3b9783aae7119b5199 ]
+
+nfs_close_local_fh() is called from two different places for quite
+different use case.
+
+It is called from nfs_uuid_put() when the nfs_uuid is being detached -
+possibly because the nfs server is not longer serving that filesystem.
+In this case there will always be an nfs_uuid and so rcu_read_lock() is
+not needed.
+
+It is also called when the nfs_file_localio is no longer needed.  In
+this case there may not be an active nfs_uuid.
+
+These two can race, and handling the race properly while avoiding
+excessive locking will require different handling on each side.
+
+This patch prepares the way by opencoding nfs_close_local_fh() into
+nfs_uuid_put(), then simplifying the code there as befits the context.
+
+Fixes: 86e00412254a ("nfs: cache all open LOCALIO nfsd_file(s) in client")
+Signed-off-by: NeilBrown <neil@brown.name>
+Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs_common/nfslocalio.c | 21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
+
+diff --git a/fs/nfs_common/nfslocalio.c b/fs/nfs_common/nfslocalio.c
+index 503f85f64b760..49c59f0c78c62 100644
+--- a/fs/nfs_common/nfslocalio.c
++++ b/fs/nfs_common/nfslocalio.c
+@@ -171,7 +171,26 @@ static bool nfs_uuid_put(nfs_uuid_t *nfs_uuid)
+       /* Walk list of files and ensure their last references dropped */
+       list_for_each_entry_safe(nfl, tmp, &local_files, list) {
+-              nfs_close_local_fh(nfl);
++              struct nfsd_file *ro_nf;
++              struct nfsd_file *rw_nf;
++
++              ro_nf = unrcu_pointer(xchg(&nfl->ro_file, NULL));
++              rw_nf = unrcu_pointer(xchg(&nfl->rw_file, NULL));
++
++              spin_lock(&nfs_uuid->lock);
++              /* Remove nfl from nfs_uuid->files list */
++              list_del_init(&nfl->list);
++              spin_unlock(&nfs_uuid->lock);
++              /* Now we can allow racing nfs_close_local_fh() to
++               * skip the locking.
++               */
++              RCU_INIT_POINTER(nfl->nfs_uuid, NULL);
++
++              if (ro_nf)
++                      nfs_to_nfsd_file_put_local(ro_nf);
++              if (rw_nf)
++                      nfs_to_nfsd_file_put_local(rw_nf);
++
+               cond_resched();
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/nfs_localio-protect-race-between-nfs_uuid_put-and-nf.patch b/queue-6.15/nfs_localio-protect-race-between-nfs_uuid_put-and-nf.patch
new file mode 100644 (file)
index 0000000..2ae4b3f
--- /dev/null
@@ -0,0 +1,193 @@
+From 9f57671309d3183cda8f38d9ca129d895d6fa28c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 May 2025 10:46:42 +1000
+Subject: nfs_localio: protect race between nfs_uuid_put() and
+ nfs_close_local_fh()
+
+From: NeilBrown <neil@brown.name>
+
+[ Upstream commit 21fb44034695185f1dcbcb37354c842cabfe83c1 ]
+
+nfs_uuid_put() and nfs_close_local_fh() can race if a "struct
+nfs_file_localio" is released at the same time that nfsd calls
+nfs_localio_invalidate_clients().
+
+It is important that neither of these functions completes after the
+other has started looking at a given nfs_file_localio and before it
+finishes.
+
+If nfs_uuid_put() exits while nfs_close_local_fh() is closing ro_file
+and rw_file it could return to __nfd_file_cache_purge() while some files
+are still referenced so the purge may not succeed.
+
+If nfs_close_local_fh() exits while nfsd_uuid_put() is still closing the
+files then the "struct nfs_file_localio" could be freed while
+nfsd_uuid_put() is still looking at it.  This side is currently handled
+by copying the pointers out of ro_file and rw_file before deleting from
+the list in nfsd_uuid.  We need to preserve this while ensuring that
+nfsd_uuid_put() does wait for nfs_close_local_fh().
+
+This patch use nfl->uuid and nfl->list to provide the required
+interlock.
+
+nfs_uuid_put() removes the nfs_file_localio from the list, then drops
+locks and puts the two files, then reclaims the spinlock and sets
+->nfs_uuid to NULL.
+
+nfs_close_local_fh() operates in the reverse order, setting ->nfs_uuid
+to NULL, then closing the files, then unlinking from the list.
+
+If nfs_uuid_put() finds that ->nfs_uuid is already NULL, it waits for
+the nfs_file_localio to be removed from the list.  If
+nfs_close_local_fh() find that it has already been unlinked it waits for
+->nfs_uuid to become NULL.  This ensure that one of the two tries to
+close the files, but they each waits for the other.
+
+As nfs_uuid_put() is making the list empty, change from a
+list_for_each_safe loop to a while that always takes the first entry.
+This makes the intent more clear.
+Also don't move the list to a temporary local list as this would defeat
+the guarantees required for the interlock.
+
+Fixes: 86e00412254a ("nfs: cache all open LOCALIO nfsd_file(s) in client")
+Signed-off-by: NeilBrown <neil@brown.name>
+Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs_common/nfslocalio.c | 81 ++++++++++++++++++++++++++------------
+ 1 file changed, 56 insertions(+), 25 deletions(-)
+
+diff --git a/fs/nfs_common/nfslocalio.c b/fs/nfs_common/nfslocalio.c
+index 49c59f0c78c62..1dd5a8cca064d 100644
+--- a/fs/nfs_common/nfslocalio.c
++++ b/fs/nfs_common/nfslocalio.c
+@@ -151,8 +151,7 @@ EXPORT_SYMBOL_GPL(nfs_localio_enable_client);
+  */
+ static bool nfs_uuid_put(nfs_uuid_t *nfs_uuid)
+ {
+-      LIST_HEAD(local_files);
+-      struct nfs_file_localio *nfl, *tmp;
++      struct nfs_file_localio *nfl;
+       spin_lock(&nfs_uuid->lock);
+       if (unlikely(!rcu_access_pointer(nfs_uuid->net))) {
+@@ -166,37 +165,49 @@ static bool nfs_uuid_put(nfs_uuid_t *nfs_uuid)
+               nfs_uuid->dom = NULL;
+       }
+-      list_splice_init(&nfs_uuid->files, &local_files);
+-      spin_unlock(&nfs_uuid->lock);
+-
+       /* Walk list of files and ensure their last references dropped */
+-      list_for_each_entry_safe(nfl, tmp, &local_files, list) {
++
++      while ((nfl = list_first_entry_or_null(&nfs_uuid->files,
++                                             struct nfs_file_localio,
++                                             list)) != NULL) {
+               struct nfsd_file *ro_nf;
+               struct nfsd_file *rw_nf;
++              /* If nfs_uuid is already NULL, nfs_close_local_fh is
++               * closing and we must wait, else we unlink and close.
++               */
++              if (rcu_access_pointer(nfl->nfs_uuid) == NULL) {
++                      /* nfs_close_local_fh() is doing the
++                       * close and we must wait. until it unlinks
++                       */
++                      wait_var_event_spinlock(nfl,
++                                              list_first_entry_or_null(
++                                                      &nfs_uuid->files,
++                                                      struct nfs_file_localio,
++                                                      list) != nfl,
++                                              &nfs_uuid->lock);
++                      continue;
++              }
++
+               ro_nf = unrcu_pointer(xchg(&nfl->ro_file, NULL));
+               rw_nf = unrcu_pointer(xchg(&nfl->rw_file, NULL));
+-              spin_lock(&nfs_uuid->lock);
+               /* Remove nfl from nfs_uuid->files list */
+               list_del_init(&nfl->list);
+               spin_unlock(&nfs_uuid->lock);
+-              /* Now we can allow racing nfs_close_local_fh() to
+-               * skip the locking.
+-               */
+-              RCU_INIT_POINTER(nfl->nfs_uuid, NULL);
+-
+               if (ro_nf)
+                       nfs_to_nfsd_file_put_local(ro_nf);
+               if (rw_nf)
+                       nfs_to_nfsd_file_put_local(rw_nf);
+-
+               cond_resched();
++              spin_lock(&nfs_uuid->lock);
++              /* Now we can allow racing nfs_close_local_fh() to
++               * skip the locking.
++               */
++              RCU_INIT_POINTER(nfl->nfs_uuid, NULL);
++              wake_up_var_locked(&nfl->nfs_uuid, &nfs_uuid->lock);
+       }
+-      spin_lock(&nfs_uuid->lock);
+-      BUG_ON(!list_empty(&nfs_uuid->files));
+-
+       /* Remove client from nn->local_clients */
+       if (nfs_uuid->list_lock) {
+               spin_lock(nfs_uuid->list_lock);
+@@ -304,23 +315,43 @@ void nfs_close_local_fh(struct nfs_file_localio *nfl)
+               return;
+       }
+-      ro_nf = unrcu_pointer(xchg(&nfl->ro_file, NULL));
+-      rw_nf = unrcu_pointer(xchg(&nfl->rw_file, NULL));
+-
+       spin_lock(&nfs_uuid->lock);
+-      /* Remove nfl from nfs_uuid->files list */
+-      list_del_init(&nfl->list);
++      if (!rcu_access_pointer(nfl->nfs_uuid)) {
++              /* nfs_uuid_put has finished here */
++              spin_unlock(&nfs_uuid->lock);
++              rcu_read_unlock();
++              return;
++      }
++      if (list_empty(&nfs_uuid->files)) {
++              /* nfs_uuid_put() has started closing files, wait for it
++               * to finished
++               */
++              spin_unlock(&nfs_uuid->lock);
++              rcu_read_unlock();
++              wait_var_event(&nfl->nfs_uuid,
++                             rcu_access_pointer(nfl->nfs_uuid) == NULL);
++              return;
++      }
++      /* tell nfs_uuid_put() to wait for us */
++      RCU_INIT_POINTER(nfl->nfs_uuid, NULL);
+       spin_unlock(&nfs_uuid->lock);
+       rcu_read_unlock();
+-      /* Now we can allow racing nfs_close_local_fh() to
+-       * skip the locking.
+-       */
+-      RCU_INIT_POINTER(nfl->nfs_uuid, NULL);
++      ro_nf = unrcu_pointer(xchg(&nfl->ro_file, NULL));
++      rw_nf = unrcu_pointer(xchg(&nfl->rw_file, NULL));
+       if (ro_nf)
+               nfs_to_nfsd_file_put_local(ro_nf);
+       if (rw_nf)
+               nfs_to_nfsd_file_put_local(rw_nf);
++
++      /* Remove nfl from nfs_uuid->files list and signal nfs_uuid_put()
++       * that we are done.  The moment we drop the spinlock the
++       * nfs_uuid could be freed.
++       */
++      spin_lock(&nfs_uuid->lock);
++      list_del_init(&nfl->list);
++      wake_up_var_locked(&nfl->nfs_uuid, &nfs_uuid->lock);
++      spin_unlock(&nfs_uuid->lock);
+ }
+ EXPORT_SYMBOL_GPL(nfs_close_local_fh);
+-- 
+2.39.5
+
diff --git a/queue-6.15/nfs_localio-simplify-interface-to-nfsd-for-getting-n.patch b/queue-6.15/nfs_localio-simplify-interface-to-nfsd-for-getting-n.patch
new file mode 100644 (file)
index 0000000..e7cd0a6
--- /dev/null
@@ -0,0 +1,249 @@
+From ddee075897d80a478f4de76169590cc8e345c04e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 May 2025 10:46:40 +1000
+Subject: nfs_localio: simplify interface to nfsd for getting nfsd_file
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: NeilBrown <neil@brown.name>
+
+[ Upstream commit e6f7e1487ab528a6c653bd0d42812ff2942846cd ]
+
+The nfsd_localio_operations structure contains nfsd_file_get() to get a
+reference to an nfsd_file.  This is only used in one place, where
+nfsd_open_local_fh() is also used.
+
+This patch combines the two, calling nfsd_open_local_fh() passing a
+pointer to where the nfsd_file pointer might be stored.  If there is a
+pointer there an nfsd_file_get() can get a reference, that reference is
+returned.  If not a new nfsd_file is acquired, stored at the pointer,
+and returned.  When we store a reference we also increase the refcount
+on the net, as that refcount is decrements when we clear the stored
+pointer.
+
+We now get an extra reference *before* storing the new nfsd_file at the
+given location.  This avoids possible races with the nfsd_file being
+freed before the final reference can be taken.
+
+This patch moves the rcu_dereference() needed after fetching from
+ro_file or rw_file into the nfsd code where the 'struct nfs_file' is
+fully defined.  This avoids an error reported by older versions of gcc
+such as gcc-8 which complain about rcu_dereference() use in contexts
+where the structure (which will supposedly be accessed) is not fully
+defined.
+
+Reported-by: Pali Rohár <pali@kernel.org>
+Reported-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Fixes: 86e00412254a ("nfs: cache all open LOCALIO nfsd_file(s) in client")
+Signed-off-by: NeilBrown <neil@brown.name>
+Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/localio.c           | 31 ++++--------------
+ fs/nfs_common/nfslocalio.c |  3 +-
+ fs/nfsd/localio.c          | 65 +++++++++++++++++++++++++++-----------
+ 3 files changed, 55 insertions(+), 44 deletions(-)
+
+diff --git a/fs/nfs/localio.c b/fs/nfs/localio.c
+index 8fb08c3ad563b..030a54c8c9d8b 100644
+--- a/fs/nfs/localio.c
++++ b/fs/nfs/localio.c
+@@ -207,11 +207,6 @@ void nfs_local_probe_async(struct nfs_client *clp)
+ }
+ EXPORT_SYMBOL_GPL(nfs_local_probe_async);
+-static inline struct nfsd_file *nfs_local_file_get(struct nfsd_file *nf)
+-{
+-      return nfs_to->nfsd_file_get_local(nf);
+-}
+-
+ static inline void nfs_local_file_put(struct nfsd_file *nf)
+ {
+       nfs_to_nfsd_file_put_local(nf);
+@@ -226,12 +221,13 @@ static inline void nfs_local_file_put(struct nfsd_file *nf)
+ static struct nfsd_file *
+ __nfs_local_open_fh(struct nfs_client *clp, const struct cred *cred,
+                   struct nfs_fh *fh, struct nfs_file_localio *nfl,
++                  struct nfsd_file __rcu **pnf,
+                   const fmode_t mode)
+ {
+       struct nfsd_file *localio;
+       localio = nfs_open_local_fh(&clp->cl_uuid, clp->cl_rpcclient,
+-                                  cred, fh, nfl, mode);
++                                  cred, fh, nfl, pnf, mode);
+       if (IS_ERR(localio)) {
+               int status = PTR_ERR(localio);
+               trace_nfs_local_open_fh(fh, mode, status);
+@@ -258,7 +254,7 @@ nfs_local_open_fh(struct nfs_client *clp, const struct cred *cred,
+                 struct nfs_fh *fh, struct nfs_file_localio *nfl,
+                 const fmode_t mode)
+ {
+-      struct nfsd_file *nf, *new, __rcu **pnf;
++      struct nfsd_file *nf, __rcu **pnf;
+       if (!nfs_server_is_local(clp))
+               return NULL;
+@@ -270,24 +266,9 @@ nfs_local_open_fh(struct nfs_client *clp, const struct cred *cred,
+       else
+               pnf = &nfl->ro_file;
+-      new = NULL;
+-      rcu_read_lock();
+-      nf = rcu_dereference(*pnf);
+-      if (!nf) {
+-              rcu_read_unlock();
+-              new = __nfs_local_open_fh(clp, cred, fh, nfl, mode);
+-              if (IS_ERR(new))
+-                      return NULL;
+-              rcu_read_lock();
+-              /* try to swap in the pointer */
+-              nf = unrcu_pointer(cmpxchg(pnf, NULL, RCU_INITIALIZER(new)));
+-              if (!nf)
+-                      swap(nf, new);
+-      }
+-      nf = nfs_local_file_get(nf);
+-      rcu_read_unlock();
+-      if (new)
+-              nfs_to_nfsd_file_put_local(new);
++      nf = __nfs_local_open_fh(clp, cred, fh, nfl, pnf, mode);
++      if (IS_ERR(nf))
++              return NULL;
+       return nf;
+ }
+ EXPORT_SYMBOL_GPL(nfs_local_open_fh);
+diff --git a/fs/nfs_common/nfslocalio.c b/fs/nfs_common/nfslocalio.c
+index f6821b2c87a2f..503f85f64b760 100644
+--- a/fs/nfs_common/nfslocalio.c
++++ b/fs/nfs_common/nfslocalio.c
+@@ -237,6 +237,7 @@ static void nfs_uuid_add_file(nfs_uuid_t *nfs_uuid, struct nfs_file_localio *nfl
+ struct nfsd_file *nfs_open_local_fh(nfs_uuid_t *uuid,
+                  struct rpc_clnt *rpc_clnt, const struct cred *cred,
+                  const struct nfs_fh *nfs_fh, struct nfs_file_localio *nfl,
++                 struct nfsd_file __rcu **pnf,
+                  const fmode_t fmode)
+ {
+       struct net *net;
+@@ -261,7 +262,7 @@ struct nfsd_file *nfs_open_local_fh(nfs_uuid_t *uuid,
+       rcu_read_unlock();
+       /* We have an implied reference to net thanks to nfsd_net_try_get */
+       localio = nfs_to->nfsd_open_local_fh(net, uuid->dom, rpc_clnt,
+-                                           cred, nfs_fh, fmode);
++                                           cred, nfs_fh, pnf, fmode);
+       nfs_to_nfsd_net_put(net);
+       if (!IS_ERR(localio))
+               nfs_uuid_add_file(uuid, nfl);
+diff --git a/fs/nfsd/localio.c b/fs/nfsd/localio.c
+index 2c0afd1067ea6..80d9ff6608a7b 100644
+--- a/fs/nfsd/localio.c
++++ b/fs/nfsd/localio.c
+@@ -24,20 +24,6 @@
+ #include "filecache.h"
+ #include "cache.h"
+-static const struct nfsd_localio_operations nfsd_localio_ops = {
+-      .nfsd_net_try_get  = nfsd_net_try_get,
+-      .nfsd_net_put  = nfsd_net_put,
+-      .nfsd_open_local_fh = nfsd_open_local_fh,
+-      .nfsd_file_put_local = nfsd_file_put_local,
+-      .nfsd_file_get_local = nfsd_file_get_local,
+-      .nfsd_file_file = nfsd_file_file,
+-};
+-
+-void nfsd_localio_ops_init(void)
+-{
+-      nfs_to = &nfsd_localio_ops;
+-}
+-
+ /**
+  * nfsd_open_local_fh - lookup a local filehandle @nfs_fh and map to nfsd_file
+  *
+@@ -46,6 +32,7 @@ void nfsd_localio_ops_init(void)
+  * @rpc_clnt: rpc_clnt that the client established
+  * @cred: cred that the client established
+  * @nfs_fh: filehandle to lookup
++ * @nfp: place to find the nfsd_file, or store it if it was non-NULL
+  * @fmode: fmode_t to use for open
+  *
+  * This function maps a local fh to a path on a local filesystem.
+@@ -56,10 +43,11 @@ void nfsd_localio_ops_init(void)
+  * set. Caller (NFS client) is responsible for calling nfsd_net_put and
+  * nfsd_file_put (via nfs_to_nfsd_file_put_local).
+  */
+-struct nfsd_file *
++static struct nfsd_file *
+ nfsd_open_local_fh(struct net *net, struct auth_domain *dom,
+                  struct rpc_clnt *rpc_clnt, const struct cred *cred,
+-                 const struct nfs_fh *nfs_fh, const fmode_t fmode)
++                 const struct nfs_fh *nfs_fh, struct nfsd_file __rcu **pnf,
++                 const fmode_t fmode)
+ {
+       int mayflags = NFSD_MAY_LOCALIO;
+       struct svc_cred rq_cred;
+@@ -73,6 +61,12 @@ nfsd_open_local_fh(struct net *net, struct auth_domain *dom,
+       if (!nfsd_net_try_get(net))
+               return ERR_PTR(-ENXIO);
++      rcu_read_lock();
++      localio = nfsd_file_get(rcu_dereference(*pnf));
++      rcu_read_unlock();
++      if (localio)
++              return localio;
++
+       /* nfs_fh -> svc_fh */
+       fh_init(&fh, NFS4_FHSIZE);
+       fh.fh_handle.fh_size = nfs_fh->size;
+@@ -94,12 +88,47 @@ nfsd_open_local_fh(struct net *net, struct auth_domain *dom,
+       if (rq_cred.cr_group_info)
+               put_group_info(rq_cred.cr_group_info);
+-      if (IS_ERR(localio))
++      if (!IS_ERR(localio)) {
++              struct nfsd_file *new;
++              if (!nfsd_net_try_get(net)) {
++                      nfsd_file_put(localio);
++                      nfsd_net_put(net);
++                      return ERR_PTR(-ENXIO);
++              }
++              nfsd_file_get(localio);
++      again:
++              new = unrcu_pointer(cmpxchg(pnf, NULL, RCU_INITIALIZER(localio)));
++              if (new) {
++                      /* Some other thread installed an nfsd_file */
++                      if (nfsd_file_get(new) == NULL)
++                              goto again;
++                      /*
++                       * Drop the ref we were going to install and the
++                       * one we were going to return.
++                       */
++                      nfsd_file_put(localio);
++                      nfsd_file_put(localio);
++                      localio = new;
++              }
++      } else
+               nfsd_net_put(net);
+       return localio;
+ }
+-EXPORT_SYMBOL_GPL(nfsd_open_local_fh);
++
++static const struct nfsd_localio_operations nfsd_localio_ops = {
++      .nfsd_net_try_get  = nfsd_net_try_get,
++      .nfsd_net_put  = nfsd_net_put,
++      .nfsd_open_local_fh = nfsd_open_local_fh,
++      .nfsd_file_put_local = nfsd_file_put_local,
++      .nfsd_file_get_local = nfsd_file_get_local,
++      .nfsd_file_file = nfsd_file_file,
++};
++
++void nfsd_localio_ops_init(void)
++{
++      nfs_to = &nfsd_localio_ops;
++}
+ /*
+  * UUID_IS_LOCAL XDR functions
+-- 
+2.39.5
+
diff --git a/queue-6.15/nfs_localio-use-cmpxchg-to-install-new-nfs_file_loca.patch b/queue-6.15/nfs_localio-use-cmpxchg-to-install-new-nfs_file_loca.patch
new file mode 100644 (file)
index 0000000..d04b999
--- /dev/null
@@ -0,0 +1,120 @@
+From bc9d95ab4826de18fb379b9a7115410cebe0c732 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 May 2025 10:46:38 +1000
+Subject: nfs_localio: use cmpxchg() to install new nfs_file_localio
+
+From: NeilBrown <neil@brown.name>
+
+[ Upstream commit ed9be317330c7390df7db9e1d046698c02001bd2 ]
+
+Rather than using nfs_uuid.lock to protect installing
+a new ro_file or rw_file, change to use cmpxchg().
+Removing the file already uses xchg() so this improves symmetry
+and also makes the code a little simpler.
+
+Also remove the optimisation of not taking the lock, and not removing
+the nfs_file_localio from the linked list, when both ->ro_file and
+->rw_file are already NULL.  Given that ->nfs_uuid was not NULL, it is
+extremely unlikely that neither ->ro_file or ->rw_file is NULL so
+this optimisation can be of little value and it complicates
+understanding of the code - why can the list_del_init() be skipped?
+
+Finally, move the assignment of NULL to ->nfs_uuid until after
+the last action on the nfs_file_localio (the list_del_init).  As soon as
+this is NULL a racing nfs_close_local_fh() can bypass all the locking
+and go on to free the nfs_file_localio, so we must be certain to be
+finished with it first.
+
+Fixes: 86e00412254a ("nfs: cache all open LOCALIO nfsd_file(s) in client")
+Signed-off-by: NeilBrown <neil@brown.name>
+Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/localio.c           | 11 +++--------
+ fs/nfs_common/nfslocalio.c | 39 +++++++++++++++++---------------------
+ 2 files changed, 20 insertions(+), 30 deletions(-)
+
+diff --git a/fs/nfs/localio.c b/fs/nfs/localio.c
+index 4ec952f9f47dd..595903c215235 100644
+--- a/fs/nfs/localio.c
++++ b/fs/nfs/localio.c
+@@ -280,14 +280,9 @@ nfs_local_open_fh(struct nfs_client *clp, const struct cred *cred,
+                       return NULL;
+               rcu_read_lock();
+               /* try to swap in the pointer */
+-              spin_lock(&clp->cl_uuid.lock);
+-              nf = rcu_dereference_protected(*pnf, 1);
+-              if (!nf) {
+-                      nf = new;
+-                      new = NULL;
+-                      rcu_assign_pointer(*pnf, nf);
+-              }
+-              spin_unlock(&clp->cl_uuid.lock);
++              nf = unrcu_pointer(cmpxchg(pnf, NULL, RCU_INITIALIZER(new)));
++              if (!nf)
++                      swap(nf, new);
+       }
+       nf = nfs_local_file_get(nf);
+       rcu_read_unlock();
+diff --git a/fs/nfs_common/nfslocalio.c b/fs/nfs_common/nfslocalio.c
+index 6a0bdea6d6449..bdf251332b6b8 100644
+--- a/fs/nfs_common/nfslocalio.c
++++ b/fs/nfs_common/nfslocalio.c
+@@ -273,8 +273,8 @@ EXPORT_SYMBOL_GPL(nfs_open_local_fh);
+ void nfs_close_local_fh(struct nfs_file_localio *nfl)
+ {
+-      struct nfsd_file *ro_nf = NULL;
+-      struct nfsd_file *rw_nf = NULL;
++      struct nfsd_file *ro_nf;
++      struct nfsd_file *rw_nf;
+       nfs_uuid_t *nfs_uuid;
+       rcu_read_lock();
+@@ -285,28 +285,23 @@ void nfs_close_local_fh(struct nfs_file_localio *nfl)
+               return;
+       }
+-      ro_nf = rcu_access_pointer(nfl->ro_file);
+-      rw_nf = rcu_access_pointer(nfl->rw_file);
+-      if (ro_nf || rw_nf) {
+-              spin_lock(&nfs_uuid->lock);
+-              if (ro_nf)
+-                      ro_nf = rcu_dereference_protected(xchg(&nfl->ro_file, NULL), 1);
+-              if (rw_nf)
+-                      rw_nf = rcu_dereference_protected(xchg(&nfl->rw_file, NULL), 1);
+-
+-              /* Remove nfl from nfs_uuid->files list */
+-              RCU_INIT_POINTER(nfl->nfs_uuid, NULL);
+-              list_del_init(&nfl->list);
+-              spin_unlock(&nfs_uuid->lock);
+-              rcu_read_unlock();
++      ro_nf = unrcu_pointer(xchg(&nfl->ro_file, NULL));
++      rw_nf = unrcu_pointer(xchg(&nfl->rw_file, NULL));
+-              if (ro_nf)
+-                      nfs_to_nfsd_file_put_local(ro_nf);
+-              if (rw_nf)
+-                      nfs_to_nfsd_file_put_local(rw_nf);
+-              return;
+-      }
++      spin_lock(&nfs_uuid->lock);
++      /* Remove nfl from nfs_uuid->files list */
++      list_del_init(&nfl->list);
++      spin_unlock(&nfs_uuid->lock);
+       rcu_read_unlock();
++      /* Now we can allow racing nfs_close_local_fh() to
++       * skip the locking.
++       */
++      RCU_INIT_POINTER(nfl->nfs_uuid, NULL);
++
++      if (ro_nf)
++              nfs_to_nfsd_file_put_local(ro_nf);
++      if (rw_nf)
++              nfs_to_nfsd_file_put_local(rw_nf);
+ }
+ EXPORT_SYMBOL_GPL(nfs_close_local_fh);
+-- 
+2.39.5
+
diff --git a/queue-6.15/nilfs2-add-pointer-check-for-nilfs_direct_propagate.patch b/queue-6.15/nilfs2-add-pointer-check-for-nilfs_direct_propagate.patch
new file mode 100644 (file)
index 0000000..f7fc925
--- /dev/null
@@ -0,0 +1,56 @@
+From 2c05906bf51a9db29511d7e15cb71c94dee2751b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Apr 2025 02:37:07 +0900
+Subject: nilfs2: add pointer check for nilfs_direct_propagate()
+
+From: Wentao Liang <vulab@iscas.ac.cn>
+
+[ Upstream commit f43f02429295486059605997bc43803527d69791 ]
+
+Patch series "nilfs2: improve sanity checks in dirty state propagation".
+
+This fixes one missed check for block mapping anomalies and one improper
+return of an error code during a preparation step for log writing, thereby
+improving checking for filesystem corruption on writeback.
+
+This patch (of 2):
+
+In nilfs_direct_propagate(), the printer get from nilfs_direct_get_ptr()
+need to be checked to ensure it is not an invalid pointer.
+
+If the pointer value obtained by nilfs_direct_get_ptr() is
+NILFS_BMAP_INVALID_PTR, means that the metadata (in this case, i_bmap in
+the nilfs_inode_info struct) that should point to the data block at the
+buffer head of the argument is corrupted and the data block is orphaned,
+meaning that the file system has lost consistency.
+
+Add a value check and return -EINVAL when it is an invalid pointer.
+
+Link: https://lkml.kernel.org/r/20250428173808.6452-1-konishi.ryusuke@gmail.com
+Link: https://lkml.kernel.org/r/20250428173808.6452-2-konishi.ryusuke@gmail.com
+Fixes: 36a580eb489f ("nilfs2: direct block mapping")
+Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
+Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nilfs2/direct.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/fs/nilfs2/direct.c b/fs/nilfs2/direct.c
+index 893ab36824cc2..2d8dc6b35b547 100644
+--- a/fs/nilfs2/direct.c
++++ b/fs/nilfs2/direct.c
+@@ -273,6 +273,9 @@ static int nilfs_direct_propagate(struct nilfs_bmap *bmap,
+       dat = nilfs_bmap_get_dat(bmap);
+       key = nilfs_bmap_data_get_key(bmap, bh);
+       ptr = nilfs_direct_get_ptr(bmap, key);
++      if (ptr == NILFS_BMAP_INVALID_PTR)
++              return -EINVAL;
++
+       if (!buffer_nilfs_volatile(bh)) {
+               oldreq.pr_entry_nr = ptr;
+               newreq.pr_entry_nr = ptr;
+-- 
+2.39.5
+
diff --git a/queue-6.15/nilfs2-do-not-propagate-enoent-error-from-nilfs_btre.patch b/queue-6.15/nilfs2-do-not-propagate-enoent-error-from-nilfs_btre.patch
new file mode 100644 (file)
index 0000000..5a96e9a
--- /dev/null
@@ -0,0 +1,55 @@
+From c850e258ee73124391a3ccfc4bd6eea593831668 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Apr 2025 02:37:08 +0900
+Subject: nilfs2: do not propagate ENOENT error from nilfs_btree_propagate()
+
+From: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+
+[ Upstream commit 8e39fbb1edbb4ec9d7c1124f403877fc167fcecd ]
+
+In preparation for writing logs, in nilfs_btree_propagate(), which makes
+parent and ancestor node blocks dirty starting from a modified data block
+or b-tree node block, if the starting block does not belong to the b-tree,
+i.e.  is isolated, nilfs_btree_do_lookup() called within the function
+fails with -ENOENT.
+
+In this case, even though -ENOENT is an internal code, it is propagated to
+the log writer via nilfs_bmap_propagate() and may be erroneously returned
+to system calls such as fsync().
+
+Fix this issue by changing the error code to -EINVAL in this case, and
+having the bmap layer detect metadata corruption and convert the error
+code appropriately.
+
+Link: https://lkml.kernel.org/r/20250428173808.6452-3-konishi.ryusuke@gmail.com
+Fixes: 1f5abe7e7dbc ("nilfs2: replace BUG_ON and BUG calls triggerable from ioctl")
+Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Cc: Wentao Liang <vulab@iscas.ac.cn>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nilfs2/btree.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c
+index 0d8f7fb15c2e5..dd0c8e560ef6a 100644
+--- a/fs/nilfs2/btree.c
++++ b/fs/nilfs2/btree.c
+@@ -2102,11 +2102,13 @@ static int nilfs_btree_propagate(struct nilfs_bmap *btree,
+       ret = nilfs_btree_do_lookup(btree, path, key, NULL, level + 1, 0);
+       if (ret < 0) {
+-              if (unlikely(ret == -ENOENT))
++              if (unlikely(ret == -ENOENT)) {
+                       nilfs_crit(btree->b_inode->i_sb,
+                                  "writing node/leaf block does not appear in b-tree (ino=%lu) at key=%llu, level=%d",
+                                  btree->b_inode->i_ino,
+                                  (unsigned long long)key, level);
++                      ret = -EINVAL;
++              }
+               goto out;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/nvme-fix-command-limits-status-code.patch b/queue-6.15/nvme-fix-command-limits-status-code.patch
new file mode 100644 (file)
index 0000000..4262531
--- /dev/null
@@ -0,0 +1,124 @@
+From e355d2a77926764cc20a5b2c46d7c8af5a78903c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 May 2025 13:20:37 -0700
+Subject: nvme: fix command limits status code
+
+From: Keith Busch <kbusch@kernel.org>
+
+[ Upstream commit 10f4a7cd724e34b7a6ff96e57ac49dc0cadececc ]
+
+The command specific status code, 0x183, was introduced in the NVMe 2.0
+specification defined to "Command Size Limits Exceeded" and only ever
+applied to DSM and Copy commands.  Fix the name and, remove the
+incorrect translation to error codes and special treatment in the
+target code for it.
+
+Fixes: 3b7c33b28a44d4 ("nvme.h: add Write Zeroes definitions")
+Cc: Chaitanya Kulkarni <chaitanyak@nvidia.com>
+Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/constants.c     | 2 +-
+ drivers/nvme/host/core.c          | 1 -
+ drivers/nvme/host/pr.c            | 2 --
+ drivers/nvme/target/core.c        | 9 +--------
+ drivers/nvme/target/io-cmd-bdev.c | 9 +--------
+ include/linux/nvme.h              | 2 +-
+ 6 files changed, 4 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/nvme/host/constants.c b/drivers/nvme/host/constants.c
+index 2b9e6cfaf2a80..1a0058be58210 100644
+--- a/drivers/nvme/host/constants.c
++++ b/drivers/nvme/host/constants.c
+@@ -145,7 +145,7 @@ static const char * const nvme_statuses[] = {
+       [NVME_SC_BAD_ATTRIBUTES] = "Conflicting Attributes",
+       [NVME_SC_INVALID_PI] = "Invalid Protection Information",
+       [NVME_SC_READ_ONLY] = "Attempted Write to Read Only Range",
+-      [NVME_SC_ONCS_NOT_SUPPORTED] = "ONCS Not Supported",
++      [NVME_SC_CMD_SIZE_LIM_EXCEEDED  ] = "Command Size Limits Exceeded",
+       [NVME_SC_ZONE_BOUNDARY_ERROR] = "Zoned Boundary Error",
+       [NVME_SC_ZONE_FULL] = "Zone Is Full",
+       [NVME_SC_ZONE_READ_ONLY] = "Zone Is Read Only",
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index 6b04473c0ab73..93a8119ad5ca6 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -286,7 +286,6 @@ static blk_status_t nvme_error_status(u16 status)
+       case NVME_SC_NS_NOT_READY:
+               return BLK_STS_TARGET;
+       case NVME_SC_BAD_ATTRIBUTES:
+-      case NVME_SC_ONCS_NOT_SUPPORTED:
+       case NVME_SC_INVALID_OPCODE:
+       case NVME_SC_INVALID_FIELD:
+       case NVME_SC_INVALID_NS:
+diff --git a/drivers/nvme/host/pr.c b/drivers/nvme/host/pr.c
+index cf2d2c5039ddb..ca6a74607b139 100644
+--- a/drivers/nvme/host/pr.c
++++ b/drivers/nvme/host/pr.c
+@@ -82,8 +82,6 @@ static int nvme_status_to_pr_err(int status)
+               return PR_STS_SUCCESS;
+       case NVME_SC_RESERVATION_CONFLICT:
+               return PR_STS_RESERVATION_CONFLICT;
+-      case NVME_SC_ONCS_NOT_SUPPORTED:
+-              return -EOPNOTSUPP;
+       case NVME_SC_BAD_ATTRIBUTES:
+       case NVME_SC_INVALID_OPCODE:
+       case NVME_SC_INVALID_FIELD:
+diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
+index 245475c43127f..69b1ddff6731f 100644
+--- a/drivers/nvme/target/core.c
++++ b/drivers/nvme/target/core.c
+@@ -62,14 +62,7 @@ inline u16 errno_to_nvme_status(struct nvmet_req *req, int errno)
+               return  NVME_SC_LBA_RANGE | NVME_STATUS_DNR;
+       case -EOPNOTSUPP:
+               req->error_loc = offsetof(struct nvme_common_command, opcode);
+-              switch (req->cmd->common.opcode) {
+-              case nvme_cmd_dsm:
+-              case nvme_cmd_write_zeroes:
+-                      return NVME_SC_ONCS_NOT_SUPPORTED | NVME_STATUS_DNR;
+-              default:
+-                      return NVME_SC_INVALID_OPCODE | NVME_STATUS_DNR;
+-              }
+-              break;
++              return NVME_SC_INVALID_OPCODE | NVME_STATUS_DNR;
+       case -ENODATA:
+               req->error_loc = offsetof(struct nvme_rw_command, nsid);
+               return NVME_SC_ACCESS_DENIED;
+diff --git a/drivers/nvme/target/io-cmd-bdev.c b/drivers/nvme/target/io-cmd-bdev.c
+index 83be0657e6df4..1cfa13d029bfa 100644
+--- a/drivers/nvme/target/io-cmd-bdev.c
++++ b/drivers/nvme/target/io-cmd-bdev.c
+@@ -145,15 +145,8 @@ u16 blk_to_nvme_status(struct nvmet_req *req, blk_status_t blk_sts)
+               req->error_loc = offsetof(struct nvme_rw_command, slba);
+               break;
+       case BLK_STS_NOTSUPP:
++              status = NVME_SC_INVALID_OPCODE | NVME_STATUS_DNR;
+               req->error_loc = offsetof(struct nvme_common_command, opcode);
+-              switch (req->cmd->common.opcode) {
+-              case nvme_cmd_dsm:
+-              case nvme_cmd_write_zeroes:
+-                      status = NVME_SC_ONCS_NOT_SUPPORTED | NVME_STATUS_DNR;
+-                      break;
+-              default:
+-                      status = NVME_SC_INVALID_OPCODE | NVME_STATUS_DNR;
+-              }
+               break;
+       case BLK_STS_MEDIUM:
+               status = NVME_SC_ACCESS_DENIED;
+diff --git a/include/linux/nvme.h b/include/linux/nvme.h
+index 2479ed10f53e3..5d7afb6079f1d 100644
+--- a/include/linux/nvme.h
++++ b/include/linux/nvme.h
+@@ -2094,7 +2094,7 @@ enum {
+       NVME_SC_BAD_ATTRIBUTES          = 0x180,
+       NVME_SC_INVALID_PI              = 0x181,
+       NVME_SC_READ_ONLY               = 0x182,
+-      NVME_SC_ONCS_NOT_SUPPORTED      = 0x183,
++      NVME_SC_CMD_SIZE_LIM_EXCEEDED   = 0x183,
+       /*
+        * I/O Command Set Specific - Fabrics commands:
+-- 
+2.39.5
+
diff --git a/queue-6.15/nvme-fix-implicit-bool-to-flags-conversion.patch b/queue-6.15/nvme-fix-implicit-bool-to-flags-conversion.patch
new file mode 100644 (file)
index 0000000..75d64a0
--- /dev/null
@@ -0,0 +1,44 @@
+From 01b9a7c07dd972912655a5ad18e46586e7c3650b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 May 2025 16:14:49 +0100
+Subject: nvme: fix implicit bool to flags conversion
+
+From: Pavel Begunkov <asml.silence@gmail.com>
+
+[ Upstream commit c4b680ac2863821e19d360fca62f78b68b1c8ece ]
+
+nvme_map_user_request() takes flags as the last argument, but
+nvme_uring_cmd_io() shoves a bool "vec" into it. It behaves as
+expected because bool is converted to 0/1 and NVME_IOCTL_VEC is
+defined as 1, but it's better to pass flags explicitly.
+
+Fixes: 7b7fdb8e2dbc1 ("nvme: replace the "bool vec" arguments with flags in the ioctl path")
+Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
+Reviewed-by: Jens Axboe <axboe@kernel.dk>
+Reviewed-by: Keith Busch <kbusch@kernel.org>
+Reviewed-by: Anuj Gupta <anuj20.g@samsung.com>
+Reviewed-by: Kanchan Joshi <joshi.k@samsung.com>
+Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
+Reviewed-by: Caleb Sander Mateos <csander@purestorage.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/ioctl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c
+index ca86d3bf7ea49..f29107d95ff26 100644
+--- a/drivers/nvme/host/ioctl.c
++++ b/drivers/nvme/host/ioctl.c
+@@ -521,7 +521,7 @@ static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
+       if (d.data_len) {
+               ret = nvme_map_user_request(req, d.addr, d.data_len,
+                       nvme_to_user_ptr(d.metadata), d.metadata_len,
+-                      map_iter, vec);
++                      map_iter, vec ? NVME_IOCTL_VEC : 0);
+               if (ret)
+                       goto out_free_req;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/ocfs2-fix-possible-memory-leak-in-ocfs2_finish_quota.patch b/queue-6.15/ocfs2-fix-possible-memory-leak-in-ocfs2_finish_quota.patch
new file mode 100644 (file)
index 0000000..6f08764
--- /dev/null
@@ -0,0 +1,50 @@
+From 21ca8285b35349e86c85aafb05b9cb16be144e60 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Apr 2025 09:56:27 +0300
+Subject: ocfs2: fix possible memory leak in ocfs2_finish_quota_recovery
+
+From: Murad Masimov <m.masimov@mt-integration.ru>
+
+[ Upstream commit cdc3ed3035d0fe934aa1d9b78ce256752fd3bb7d ]
+
+If ocfs2_finish_quota_recovery() exits due to an error before passing all
+rc_list elements to ocfs2_recover_local_quota_file() then it can lead to a
+memory leak as rc_list may still contain elements that have to be freed.
+
+Release all memory allocated by ocfs2_add_recovery_chunk() using
+ocfs2_free_quota_recovery() instead of kfree().
+
+Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
+
+Link: https://lkml.kernel.org/r/20250402065628.706359-2-m.masimov@mt-integration.ru
+Fixes: 2205363dce74 ("ocfs2: Implement quota recovery")
+Signed-off-by: Murad Masimov <m.masimov@mt-integration.ru>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Jun Piao <piaojun@huawei.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ocfs2/quota_local.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/ocfs2/quota_local.c b/fs/ocfs2/quota_local.c
+index e272429da3db3..de7f12858729a 100644
+--- a/fs/ocfs2/quota_local.c
++++ b/fs/ocfs2/quota_local.c
+@@ -674,7 +674,7 @@ int ocfs2_finish_quota_recovery(struct ocfs2_super *osb,
+                       break;
+       }
+ out:
+-      kfree(rec);
++      ocfs2_free_quota_recovery(rec);
+       return status;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/octeontx2-af-send-link-events-one-by-one.patch b/queue-6.15/octeontx2-af-send-link-events-one-by-one.patch
new file mode 100644 (file)
index 0000000..42a5bfa
--- /dev/null
@@ -0,0 +1,67 @@
+From 93e158d78714e3551814d6f9678751f2b00555a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 May 2025 16:00:43 +0530
+Subject: octeontx2-af: Send Link events one by one
+
+From: Subbaraya Sundeep <sbhatta@marvell.com>
+
+[ Upstream commit ba5cb47b56e5d89f0a5eb5163ffbfda1e3e7cef0 ]
+
+Send link events one after another otherwise new message
+is overwriting the message which is being processed by PF.
+
+Fixes: a88e0f936ba9 ("octeontx2: Detect the mbox up or down message via register")
+Signed-off-by: Subbaraya Sundeep <sbhatta@marvell.com>
+Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/1747823443-404-1-git-send-email-sbhatta@marvell.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/octeontx2/af/mcs_rvu_if.c | 2 ++
+ drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c    | 2 ++
+ drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c    | 2 ++
+ 3 files changed, 6 insertions(+)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mcs_rvu_if.c b/drivers/net/ethernet/marvell/octeontx2/af/mcs_rvu_if.c
+index 655dd4726d36e..0277d226293e9 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/mcs_rvu_if.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/mcs_rvu_if.c
+@@ -143,6 +143,8 @@ static int mcs_notify_pfvf(struct mcs_intr_event *event, struct rvu *rvu)
+       otx2_mbox_msg_send_up(&rvu->afpf_wq_info.mbox_up, pf);
++      otx2_mbox_wait_for_rsp(&rvu->afpf_wq_info.mbox_up, pf);
++
+       mutex_unlock(&rvu->mbox_lock);
+       return 0;
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
+index 992fa0b82e8d2..ebb56eb0d18cf 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
+@@ -272,6 +272,8 @@ static void cgx_notify_pfs(struct cgx_link_event *event, struct rvu *rvu)
+               otx2_mbox_msg_send_up(&rvu->afpf_wq_info.mbox_up, pfid);
++              otx2_mbox_wait_for_rsp(&rvu->afpf_wq_info.mbox_up, pfid);
++
+               mutex_unlock(&rvu->mbox_lock);
+       } while (pfmap);
+ }
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c
+index 052ae5923e3a8..32953cca108c8 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c
+@@ -60,6 +60,8 @@ static int rvu_rep_up_notify(struct rvu *rvu, struct rep_event *event)
+       otx2_mbox_msg_send_up(&rvu->afpf_wq_info.mbox_up, pf);
++      otx2_mbox_wait_for_rsp(&rvu->afpf_wq_info.mbox_up, pf);
++
+       mutex_unlock(&rvu->mbox_lock);
+       return 0;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/octeontx2-pf-qos-perform-cache-sync-on-send-queue-te.patch b/queue-6.15/octeontx2-pf-qos-perform-cache-sync-on-send-queue-te.patch
new file mode 100644 (file)
index 0000000..eb39a84
--- /dev/null
@@ -0,0 +1,70 @@
+From b60e4fe13fe38c69951172696613a11d948bcfa6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 May 2025 15:17:41 +0530
+Subject: octeontx2-pf: QOS: Perform cache sync on send queue teardown
+
+From: Hariprasad Kelam <hkelam@marvell.com>
+
+[ Upstream commit 479c58016099d19686e36f6c50f912360839a7fa ]
+
+QOS is designed to create a new send queue whenever  a class
+is created, ensuring proper shaping and scheduling. However,
+when multiple send queues are created and deleted in a loop,
+SMMU errors are observed.
+
+This patch addresses the issue by performing an data cache sync
+during the teardown of QOS send queues.
+
+Fixes: ab6dddd2a669 ("octeontx2-pf: qos send queues management")
+Signed-off-by: Hariprasad Kelam <hkelam@marvell.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250522094742.1498295-1-hkelam@marvell.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/marvell/octeontx2/nic/qos_sq.c   | 22 +++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/qos_sq.c b/drivers/net/ethernet/marvell/octeontx2/nic/qos_sq.c
+index c5dbae0e513b6..58d572ce08eff 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/qos_sq.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/qos_sq.c
+@@ -256,6 +256,26 @@ int otx2_qos_enable_sq(struct otx2_nic *pfvf, int qidx)
+       return err;
+ }
++static int otx2_qos_nix_npa_ndc_sync(struct otx2_nic *pfvf)
++{
++      struct ndc_sync_op *req;
++      int rc;
++
++      mutex_lock(&pfvf->mbox.lock);
++
++      req = otx2_mbox_alloc_msg_ndc_sync_op(&pfvf->mbox);
++      if (!req) {
++              mutex_unlock(&pfvf->mbox.lock);
++              return -ENOMEM;
++      }
++
++      req->nix_lf_tx_sync = true;
++      req->npa_lf_sync = true;
++      rc = otx2_sync_mbox_msg(&pfvf->mbox);
++      mutex_unlock(&pfvf->mbox.lock);
++      return rc;
++}
++
+ void otx2_qos_disable_sq(struct otx2_nic *pfvf, int qidx)
+ {
+       struct otx2_qset *qset = &pfvf->qset;
+@@ -285,6 +305,8 @@ void otx2_qos_disable_sq(struct otx2_nic *pfvf, int qidx)
+       otx2_qos_sqb_flush(pfvf, sq_idx);
+       otx2_smq_flush(pfvf, otx2_get_smq_idx(pfvf, sq_idx));
++      /* NIX/NPA NDC sync */
++      otx2_qos_nix_npa_ndc_sync(pfvf);
+       otx2_cleanup_tx_cqes(pfvf, cq);
+       mutex_lock(&pfvf->mbox.lock);
+-- 
+2.39.5
+
diff --git a/queue-6.15/octeontx2-pf-qos-refactor-tc_htb_leaf_del_last-callb.patch b/queue-6.15/octeontx2-pf-qos-refactor-tc_htb_leaf_del_last-callb.patch
new file mode 100644 (file)
index 0000000..d6b9882
--- /dev/null
@@ -0,0 +1,60 @@
+From bbc14a001af9d6dfb9d1e818c529f1790b125e59 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 May 2025 17:28:42 +0530
+Subject: octeontx2-pf: QOS: Refactor TC_HTB_LEAF_DEL_LAST callback
+
+From: Hariprasad Kelam <hkelam@marvell.com>
+
+[ Upstream commit 67af4ec948e8ce3ea53a9cf614d01fddf172e56d ]
+
+This patch addresses below issues,
+
+1. Active traffic on the leaf node must be stopped before its send queue
+   is reassigned to the parent. This patch resolves the issue by marking
+   the node as 'Inner'.
+
+2. During a system reboot, the interface receives TC_HTB_LEAF_DEL
+   and TC_HTB_LEAF_DEL_LAST callbacks to delete its HTB queues.
+   In the case of TC_HTB_LEAF_DEL_LAST, although the same send queue
+   is reassigned to the parent, the current logic still attempts to update
+   the real number of queues, leadning to below warnings
+
+        New queues can't be registered after device unregistration.
+        WARNING: CPU: 0 PID: 6475 at net/core/net-sysfs.c:1714
+        netdev_queue_update_kobjects+0x1e4/0x200
+
+Fixes: 5e6808b4c68d ("octeontx2-pf: Add support for HTB offload")
+Signed-off-by: Hariprasad Kelam <hkelam@marvell.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250522115842.1499666-1-hkelam@marvell.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/octeontx2/nic/qos.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/qos.c b/drivers/net/ethernet/marvell/octeontx2/nic/qos.c
+index 35acc07bd9648..5765bac119f0e 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/qos.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/qos.c
+@@ -1638,6 +1638,7 @@ static int otx2_qos_leaf_del_last(struct otx2_nic *pfvf, u16 classid, bool force
+       if (!node->is_static)
+               dwrr_del_node = true;
++      WRITE_ONCE(node->qid, OTX2_QOS_QID_INNER);
+       /* destroy the leaf node */
+       otx2_qos_disable_sq(pfvf, qid);
+       otx2_qos_destroy_node(pfvf, node);
+@@ -1682,9 +1683,6 @@ static int otx2_qos_leaf_del_last(struct otx2_nic *pfvf, u16 classid, bool force
+       }
+       kfree(new_cfg);
+-      /* update tx_real_queues */
+-      otx2_qos_update_tx_netdev_queues(pfvf);
+-
+       return 0;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/of-unittest-unlock-on-error-in-unittest_data_add.patch b/queue-6.15/of-unittest-unlock-on-error-in-unittest_data_add.patch
new file mode 100644 (file)
index 0000000..887a54d
--- /dev/null
@@ -0,0 +1,61 @@
+From 058f2a1964fa81dcbd274770e25c292f6d847558 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Apr 2025 11:05:40 +0300
+Subject: of: unittest: Unlock on error in unittest_data_add()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 493e6cb63a21e9f009dc4c209fd311f2bb777656 ]
+
+The of_overlay_mutex_unlock() was accidentally deleted if "of_root" is
+NULL.  Change this to a goto unlock.
+
+Fixes: d1eabd218ede ("of: unittest: treat missing of_root as error instead of fixing up")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Reviewed-by: Stephen Boyd <sboyd@kernel.org>
+Link: https://lore.kernel.org/r/aBHZ1DvXiBcZkWmk@stanley.mountain
+Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/unittest.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c
+index 64d301893af7b..eeb370e0f5077 100644
+--- a/drivers/of/unittest.c
++++ b/drivers/of/unittest.c
+@@ -2029,15 +2029,16 @@ static int __init unittest_data_add(void)
+       rc = of_resolve_phandles(unittest_data_node);
+       if (rc) {
+               pr_err("%s: Failed to resolve phandles (rc=%i)\n", __func__, rc);
+-              of_overlay_mutex_unlock();
+-              return -EINVAL;
++              rc = -EINVAL;
++              goto unlock;
+       }
+       /* attach the sub-tree to live tree */
+       if (!of_root) {
+               pr_warn("%s: no live tree to attach sub-tree\n", __func__);
+               kfree(unittest_data);
+-              return -ENODEV;
++              rc = -ENODEV;
++              goto unlock;
+       }
+       EXPECT_BEGIN(KERN_INFO,
+@@ -2056,9 +2057,10 @@ static int __init unittest_data_add(void)
+       EXPECT_END(KERN_INFO,
+                  "Duplicate name in testcase-data, renamed to \"duplicate-name#1\"");
++unlock:
+       of_overlay_mutex_unlock();
+-      return 0;
++      return rc;
+ }
+ #ifdef CONFIG_OF_OVERLAY
+-- 
+2.39.5
+
diff --git a/queue-6.15/overflow-fix-direct-struct-member-initialization-in-.patch b/queue-6.15/overflow-fix-direct-struct-member-initialization-in-.patch
new file mode 100644 (file)
index 0000000..464c7ce
--- /dev/null
@@ -0,0 +1,85 @@
+From 6410baf5c75cb80ae9a9eb3dd188e13dd4bc50ca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 May 2025 18:44:43 -0600
+Subject: overflow: Fix direct struct member initialization in _DEFINE_FLEX()
+
+From: Gustavo A. R. Silva <gustavoars@kernel.org>
+
+[ Upstream commit 47e36ed7840661a9f7fb53554a1b04a5f8daffea ]
+
+Currently, to statically initialize the struct members of the `type`
+object created by _DEFINE_FLEX(), the internal `obj` member must be
+explicitly referenced at the call site. See:
+
+struct flex {
+        int a;
+        int b;
+        struct foo flex_array[];
+};
+
+_DEFINE_FLEX(struct flex, instance, flex_array,
+                 FIXED_SIZE, = {
+                        .obj = {
+                                .a = 0,
+                                .b = 1,
+                        },
+                });
+
+This leaks _DEFINE_FLEX() internal implementation details and make
+the helper harder to use and read.
+
+Fix this and allow for a more natural and intuitive C99 init-style:
+
+_DEFINE_FLEX(struct flex, instance, flex_array,
+                 FIXED_SIZE, = {
+                        .a = 0,
+                        .b = 1,
+                });
+
+Note that before these changes, the `initializer` argument was optional,
+but now it's required.
+
+Also, update "counter" member initialization in DEFINE_FLEX().
+
+Fixes: 26dd68d293fd ("overflow: add DEFINE_FLEX() for on-stack allocs")
+Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
+Link: https://lore.kernel.org/r/aBQVeyKfLOkO9Yss@kspp
+Signed-off-by: Kees Cook <kees@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/overflow.h | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/include/linux/overflow.h b/include/linux/overflow.h
+index 0c7e3dcfe8670..823a53cd9a193 100644
+--- a/include/linux/overflow.h
++++ b/include/linux/overflow.h
+@@ -396,7 +396,7 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend)
+  * @name: Name for a variable to define.
+  * @member: Name of the array member.
+  * @count: Number of elements in the array; must be compile-time const.
+- * @initializer: initializer expression (could be empty for no init).
++ * @initializer: Initializer expression (e.g., pass `= { }` at minimum).
+  */
+ #define _DEFINE_FLEX(type, name, member, count, initializer...)                       \
+       _Static_assert(__builtin_constant_p(count),                             \
+@@ -404,7 +404,7 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend)
+       union {                                                                 \
+               u8 bytes[struct_size_t(type, member, count)];                   \
+               type obj;                                                       \
+-      } name##_u initializer;                                                 \
++      } name##_u = { .obj initializer };                                      \
+       type *name = (type *)&name##_u
+ /**
+@@ -438,6 +438,6 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend)
+  * Use __struct_size(@NAME) to get compile-time size of it afterwards.
+  */
+ #define DEFINE_FLEX(TYPE, NAME, MEMBER, COUNTER, COUNT)       \
+-      _DEFINE_FLEX(TYPE, NAME, MEMBER, COUNT, = { .obj.COUNTER = COUNT, })
++      _DEFINE_FLEX(TYPE, NAME, MEMBER, COUNT, = { .COUNTER = COUNT, })
+ #endif /* __LINUX_OVERFLOW_H */
+-- 
+2.39.5
+
diff --git a/queue-6.15/page_pool-fix-use-after-free-in-page_pool_recycle_in.patch b/queue-6.15/page_pool-fix-use-after-free-in-page_pool_recycle_in.patch
new file mode 100644 (file)
index 0000000..3ece5b4
--- /dev/null
@@ -0,0 +1,149 @@
+From 9ca40a24adb347752e898cffa9bb23931c907793 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 May 2025 19:41:52 +0800
+Subject: page_pool: Fix use-after-free in page_pool_recycle_in_ring
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Dong Chenchen <dongchenchen2@huawei.com>
+
+[ Upstream commit 271683bb2cf32e5126c592b5d5e6a756fa374fd9 ]
+
+syzbot reported a uaf in page_pool_recycle_in_ring:
+
+BUG: KASAN: slab-use-after-free in lock_release+0x151/0xa30 kernel/locking/lockdep.c:5862
+Read of size 8 at addr ffff8880286045a0 by task syz.0.284/6943
+
+CPU: 0 UID: 0 PID: 6943 Comm: syz.0.284 Not tainted 6.13.0-rc3-syzkaller-gdfa94ce54f41 #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024
+Call Trace:
+ <TASK>
+ __dump_stack lib/dump_stack.c:94 [inline]
+ dump_stack_lvl+0x241/0x360 lib/dump_stack.c:120
+ print_address_description mm/kasan/report.c:378 [inline]
+ print_report+0x169/0x550 mm/kasan/report.c:489
+ kasan_report+0x143/0x180 mm/kasan/report.c:602
+ lock_release+0x151/0xa30 kernel/locking/lockdep.c:5862
+ __raw_spin_unlock_bh include/linux/spinlock_api_smp.h:165 [inline]
+ _raw_spin_unlock_bh+0x1b/0x40 kernel/locking/spinlock.c:210
+ spin_unlock_bh include/linux/spinlock.h:396 [inline]
+ ptr_ring_produce_bh include/linux/ptr_ring.h:164 [inline]
+ page_pool_recycle_in_ring net/core/page_pool.c:707 [inline]
+ page_pool_put_unrefed_netmem+0x748/0xb00 net/core/page_pool.c:826
+ page_pool_put_netmem include/net/page_pool/helpers.h:323 [inline]
+ page_pool_put_full_netmem include/net/page_pool/helpers.h:353 [inline]
+ napi_pp_put_page+0x149/0x2b0 net/core/skbuff.c:1036
+ skb_pp_recycle net/core/skbuff.c:1047 [inline]
+ skb_free_head net/core/skbuff.c:1094 [inline]
+ skb_release_data+0x6c4/0x8a0 net/core/skbuff.c:1125
+ skb_release_all net/core/skbuff.c:1190 [inline]
+ __kfree_skb net/core/skbuff.c:1204 [inline]
+ sk_skb_reason_drop+0x1c9/0x380 net/core/skbuff.c:1242
+ kfree_skb_reason include/linux/skbuff.h:1263 [inline]
+ __skb_queue_purge_reason include/linux/skbuff.h:3343 [inline]
+
+root cause is:
+
+page_pool_recycle_in_ring
+  ptr_ring_produce
+    spin_lock(&r->producer_lock);
+    WRITE_ONCE(r->queue[r->producer++], ptr)
+      //recycle last page to pool
+                               page_pool_release
+                                 page_pool_scrub
+                                   page_pool_empty_ring
+                                     ptr_ring_consume
+                                     page_pool_return_page  //release all page
+                                 __page_pool_destroy
+                                    free_percpu(pool->recycle_stats);
+                                    free(pool) //free
+
+     spin_unlock(&r->producer_lock); //pool->ring uaf read
+  recycle_stat_inc(pool, ring);
+
+page_pool can be free while page pool recycle the last page in ring.
+Add producer-lock barrier to page_pool_release to prevent the page
+pool from being free before all pages have been recycled.
+
+recycle_stat_inc() is empty when CONFIG_PAGE_POOL_STATS is not
+enabled, which will trigger Wempty-body build warning. Add definition
+for pool stat macro to fix warning.
+
+Suggested-by: Jakub Kicinski <kuba@kernel.org>
+Link: https://lore.kernel.org/netdev/20250513083123.3514193-1-dongchenchen2@huawei.com
+Fixes: ff7d6b27f894 ("page_pool: refurbish version of page_pool code")
+Reported-by: syzbot+204a4382fcb3311f3858@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=204a4382fcb3311f3858
+Signed-off-by: Dong Chenchen <dongchenchen2@huawei.com>
+Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
+Reviewed-by: Mina Almasry <almasrymina@google.com>
+Link: https://patch.msgid.link/20250527114152.3119109-1-dongchenchen2@huawei.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/page_pool.c | 27 ++++++++++++++-------------
+ 1 file changed, 14 insertions(+), 13 deletions(-)
+
+diff --git a/net/core/page_pool.c b/net/core/page_pool.c
+index 2b76848659418..2d9c51f480fb5 100644
+--- a/net/core/page_pool.c
++++ b/net/core/page_pool.c
+@@ -153,9 +153,9 @@ u64 *page_pool_ethtool_stats_get(u64 *data, const void *stats)
+ EXPORT_SYMBOL(page_pool_ethtool_stats_get);
+ #else
+-#define alloc_stat_inc(pool, __stat)
+-#define recycle_stat_inc(pool, __stat)
+-#define recycle_stat_add(pool, __stat, val)
++#define alloc_stat_inc(...)   do { } while (0)
++#define recycle_stat_inc(...) do { } while (0)
++#define recycle_stat_add(...) do { } while (0)
+ #endif
+ static bool page_pool_producer_lock(struct page_pool *pool)
+@@ -741,19 +741,16 @@ void page_pool_return_page(struct page_pool *pool, netmem_ref netmem)
+ static bool page_pool_recycle_in_ring(struct page_pool *pool, netmem_ref netmem)
+ {
+-      int ret;
+-      /* BH protection not needed if current is softirq */
+-      if (in_softirq())
+-              ret = ptr_ring_produce(&pool->ring, (__force void *)netmem);
+-      else
+-              ret = ptr_ring_produce_bh(&pool->ring, (__force void *)netmem);
++      bool in_softirq, ret;
+-      if (!ret) {
++      /* BH protection not needed if current is softirq */
++      in_softirq = page_pool_producer_lock(pool);
++      ret = !__ptr_ring_produce(&pool->ring, (__force void *)netmem);
++      if (ret)
+               recycle_stat_inc(pool, ring);
+-              return true;
+-      }
++      page_pool_producer_unlock(pool, in_softirq);
+-      return false;
++      return ret;
+ }
+ /* Only allow direct recycling in special circumstances, into the
+@@ -1146,10 +1143,14 @@ static void page_pool_scrub(struct page_pool *pool)
+ static int page_pool_release(struct page_pool *pool)
+ {
++      bool in_softirq;
+       int inflight;
+       page_pool_scrub(pool);
+       inflight = page_pool_inflight(pool, true);
++      /* Acquire producer lock to make sure producers have exited. */
++      in_softirq = page_pool_producer_lock(pool);
++      page_pool_producer_unlock(pool, in_softirq);
+       if (!inflight)
+               __page_pool_destroy(pool);
+-- 
+2.39.5
+
diff --git a/queue-6.15/page_pool-move-pp_magic-check-into-helper-functions.patch b/queue-6.15/page_pool-move-pp_magic-check-into-helper-functions.patch
new file mode 100644 (file)
index 0000000..c1d178c
--- /dev/null
@@ -0,0 +1,180 @@
+From b63763501fee913ebc1ee45be6cb1809be8dcca1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Apr 2025 12:41:36 +0200
+Subject: page_pool: Move pp_magic check into helper functions
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Toke Høiland-Jørgensen <toke@redhat.com>
+
+[ Upstream commit cd3c93167da0e760b5819246eae7a4ea30fd014b ]
+
+Since we are about to stash some more information into the pp_magic
+field, let's move the magic signature checks into a pair of helper
+functions so it can be changed in one place.
+
+Reviewed-by: Mina Almasry <almasrymina@google.com>
+Tested-by: Yonglong Liu <liuyonglong@huawei.com>
+Acked-by: Jesper Dangaard Brouer <hawk@kernel.org>
+Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
+Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
+Link: https://patch.msgid.link/20250409-page-pool-track-dma-v9-1-6a9ef2e0cba8@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: ee62ce7a1d90 ("page_pool: Track DMA-mapped pages and unmap them when destroying the pool")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/mellanox/mlx5/core/en/xdp.c  |  4 ++--
+ include/linux/mm.h                            | 20 +++++++++++++++++++
+ mm/page_alloc.c                               |  8 ++------
+ net/core/netmem_priv.h                        |  5 +++++
+ net/core/skbuff.c                             | 16 ++-------------
+ net/core/xdp.c                                |  4 ++--
+ 6 files changed, 33 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c b/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c
+index f803e1c935900..5ce1b463b7a8d 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c
+@@ -707,8 +707,8 @@ static void mlx5e_free_xdpsq_desc(struct mlx5e_xdpsq *sq,
+                               xdpi = mlx5e_xdpi_fifo_pop(xdpi_fifo);
+                               page = xdpi.page.page;
+-                              /* No need to check ((page->pp_magic & ~0x3UL) == PP_SIGNATURE)
+-                               * as we know this is a page_pool page.
++                              /* No need to check page_pool_page_is_pp() as we
++                               * know this is a page_pool page.
+                                */
+                               page_pool_recycle_direct(page->pp, page);
+                       } while (++n < num);
+diff --git a/include/linux/mm.h b/include/linux/mm.h
+index fdda6b16263b3..af2f551668e9e 100644
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -4265,4 +4265,24 @@ int arch_lock_shadow_stack_status(struct task_struct *t, unsigned long status);
+ #define VM_SEALED_SYSMAP      VM_NONE
+ #endif
++/* Mask used for checking in page_pool_page_is_pp() below. page->pp_magic is
++ * OR'ed with PP_SIGNATURE after the allocation in order to preserve bit 0 for
++ * the head page of compound page and bit 1 for pfmemalloc page.
++ * page_is_pfmemalloc() is checked in __page_pool_put_page() to avoid recycling
++ * the pfmemalloc page.
++ */
++#define PP_MAGIC_MASK ~0x3UL
++
++#ifdef CONFIG_PAGE_POOL
++static inline bool page_pool_page_is_pp(struct page *page)
++{
++      return (page->pp_magic & PP_MAGIC_MASK) == PP_SIGNATURE;
++}
++#else
++static inline bool page_pool_page_is_pp(struct page *page)
++{
++      return false;
++}
++#endif
++
+ #endif /* _LINUX_MM_H */
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index 47fa713ccb4d8..4f29e393f6af1 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -898,9 +898,7 @@ static inline bool page_expected_state(struct page *page,
+ #ifdef CONFIG_MEMCG
+                       page->memcg_data |
+ #endif
+-#ifdef CONFIG_PAGE_POOL
+-                      ((page->pp_magic & ~0x3UL) == PP_SIGNATURE) |
+-#endif
++                      page_pool_page_is_pp(page) |
+                       (page->flags & check_flags)))
+               return false;
+@@ -927,10 +925,8 @@ static const char *page_bad_reason(struct page *page, unsigned long flags)
+       if (unlikely(page->memcg_data))
+               bad_reason = "page still charged to cgroup";
+ #endif
+-#ifdef CONFIG_PAGE_POOL
+-      if (unlikely((page->pp_magic & ~0x3UL) == PP_SIGNATURE))
++      if (unlikely(page_pool_page_is_pp(page)))
+               bad_reason = "page_pool leak";
+-#endif
+       return bad_reason;
+ }
+diff --git a/net/core/netmem_priv.h b/net/core/netmem_priv.h
+index 7eadb8393e002..f33162fd281c2 100644
+--- a/net/core/netmem_priv.h
++++ b/net/core/netmem_priv.h
+@@ -18,6 +18,11 @@ static inline void netmem_clear_pp_magic(netmem_ref netmem)
+       __netmem_clear_lsb(netmem)->pp_magic = 0;
+ }
++static inline bool netmem_is_pp(netmem_ref netmem)
++{
++      return (netmem_get_pp_magic(netmem) & PP_MAGIC_MASK) == PP_SIGNATURE;
++}
++
+ static inline void netmem_set_pp(netmem_ref netmem, struct page_pool *pool)
+ {
+       __netmem_clear_lsb(netmem)->pp = pool;
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index 6cbf77bc61fce..74a2d886a35b5 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -893,11 +893,6 @@ static void skb_clone_fraglist(struct sk_buff *skb)
+               skb_get(list);
+ }
+-static bool is_pp_netmem(netmem_ref netmem)
+-{
+-      return (netmem_get_pp_magic(netmem) & ~0x3UL) == PP_SIGNATURE;
+-}
+-
+ int skb_pp_cow_data(struct page_pool *pool, struct sk_buff **pskb,
+                   unsigned int headroom)
+ {
+@@ -995,14 +990,7 @@ bool napi_pp_put_page(netmem_ref netmem)
+ {
+       netmem = netmem_compound_head(netmem);
+-      /* page->pp_magic is OR'ed with PP_SIGNATURE after the allocation
+-       * in order to preserve any existing bits, such as bit 0 for the
+-       * head page of compound page and bit 1 for pfmemalloc page, so
+-       * mask those bits for freeing side when doing below checking,
+-       * and page_is_pfmemalloc() is checked in __page_pool_put_page()
+-       * to avoid recycling the pfmemalloc page.
+-       */
+-      if (unlikely(!is_pp_netmem(netmem)))
++      if (unlikely(!netmem_is_pp(netmem)))
+               return false;
+       page_pool_put_full_netmem(netmem_get_pp(netmem), netmem, false);
+@@ -1042,7 +1030,7 @@ static int skb_pp_frag_ref(struct sk_buff *skb)
+       for (i = 0; i < shinfo->nr_frags; i++) {
+               head_netmem = netmem_compound_head(shinfo->frags[i].netmem);
+-              if (likely(is_pp_netmem(head_netmem)))
++              if (likely(netmem_is_pp(head_netmem)))
+                       page_pool_ref_netmem(head_netmem);
+               else
+                       page_ref_inc(netmem_to_page(head_netmem));
+diff --git a/net/core/xdp.c b/net/core/xdp.c
+index f86eedad586a7..0ba73943c6eed 100644
+--- a/net/core/xdp.c
++++ b/net/core/xdp.c
+@@ -437,8 +437,8 @@ void __xdp_return(netmem_ref netmem, enum xdp_mem_type mem_type,
+               netmem = netmem_compound_head(netmem);
+               if (napi_direct && xdp_return_frame_no_direct())
+                       napi_direct = false;
+-              /* No need to check ((page->pp_magic & ~0x3UL) == PP_SIGNATURE)
+-               * as mem->type knows this a page_pool page
++              /* No need to check netmem_is_pp() as mem->type knows this a
++               * page_pool page
+                */
+               page_pool_put_full_netmem(netmem_get_pp(netmem), netmem,
+                                         napi_direct);
+-- 
+2.39.5
+
diff --git a/queue-6.15/page_pool-track-dma-mapped-pages-and-unmap-them-when.patch b/queue-6.15/page_pool-track-dma-mapped-pages-and-unmap-them-when.patch
new file mode 100644 (file)
index 0000000..f8608c8
--- /dev/null
@@ -0,0 +1,427 @@
+From 3acd83352ca332840510e8d575d7abbc16654904 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Apr 2025 12:41:37 +0200
+Subject: page_pool: Track DMA-mapped pages and unmap them when destroying the
+ pool
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Toke Høiland-Jørgensen <toke@redhat.com>
+
+[ Upstream commit ee62ce7a1d909ccba0399680a03c2dee83bcae95 ]
+
+When enabling DMA mapping in page_pool, pages are kept DMA mapped until
+they are released from the pool, to avoid the overhead of re-mapping the
+pages every time they are used. This causes resource leaks and/or
+crashes when there are pages still outstanding while the device is torn
+down, because page_pool will attempt an unmap through a non-existent DMA
+device on the subsequent page return.
+
+To fix this, implement a simple tracking of outstanding DMA-mapped pages
+in page pool using an xarray. This was first suggested by Mina[0], and
+turns out to be fairly straight forward: We simply store pointers to
+pages directly in the xarray with xa_alloc() when they are first DMA
+mapped, and remove them from the array on unmap. Then, when a page pool
+is torn down, it can simply walk the xarray and unmap all pages still
+present there before returning, which also allows us to get rid of the
+get/put_device() calls in page_pool. Using xa_cmpxchg(), no additional
+synchronisation is needed, as a page will only ever be unmapped once.
+
+To avoid having to walk the entire xarray on unmap to find the page
+reference, we stash the ID assigned by xa_alloc() into the page
+structure itself, using the upper bits of the pp_magic field. This
+requires a couple of defines to avoid conflicting with the
+POINTER_POISON_DELTA define, but this is all evaluated at compile-time,
+so does not affect run-time performance. The bitmap calculations in this
+patch gives the following number of bits for different architectures:
+
+- 23 bits on 32-bit architectures
+- 21 bits on PPC64 (because of the definition of ILLEGAL_POINTER_VALUE)
+- 32 bits on other 64-bit architectures
+
+Stashing a value into the unused bits of pp_magic does have the effect
+that it can make the value stored there lie outside the unmappable
+range (as governed by the mmap_min_addr sysctl), for architectures that
+don't define ILLEGAL_POINTER_VALUE. This means that if one of the
+pointers that is aliased to the pp_magic field (such as page->lru.next)
+is dereferenced while the page is owned by page_pool, that could lead to
+a dereference into userspace, which is a security concern. The risk of
+this is mitigated by the fact that (a) we always clear pp_magic before
+releasing a page from page_pool, and (b) this would need a
+use-after-free bug for struct page, which can have many other risks
+since page->lru.next is used as a generic list pointer in multiple
+places in the kernel. As such, with this patch we take the position that
+this risk is negligible in practice. For more discussion, see[1].
+
+Since all the tracking added in this patch is performed on DMA
+map/unmap, no additional code is needed in the fast path, meaning the
+performance overhead of this tracking is negligible there. A
+micro-benchmark shows that the total overhead of the tracking itself is
+about 400 ns (39 cycles(tsc) 395.218 ns; sum for both map and unmap[2]).
+Since this cost is only paid on DMA map and unmap, it seems like an
+acceptable cost to fix the late unmap issue. Further optimisation can
+narrow the cases where this cost is paid (for instance by eliding the
+tracking when DMA map/unmap is a no-op).
+
+The extra memory needed to track the pages is neatly encapsulated inside
+xarray, which uses the 'struct xa_node' structure to track items. This
+structure is 576 bytes long, with slots for 64 items, meaning that a
+full node occurs only 9 bytes of overhead per slot it tracks (in
+practice, it probably won't be this efficient, but in any case it should
+be an acceptable overhead).
+
+[0] https://lore.kernel.org/all/CAHS8izPg7B5DwKfSuzz-iOop_YRbk3Sd6Y4rX7KBG9DcVJcyWg@mail.gmail.com/
+[1] https://lore.kernel.org/r/20250320023202.GA25514@openwall.com
+[2] https://lore.kernel.org/r/ae07144c-9295-4c9d-a400-153bb689fe9e@huawei.com
+
+Reported-by: Yonglong Liu <liuyonglong@huawei.com>
+Closes: https://lore.kernel.org/r/8743264a-9700-4227-a556-5f931c720211@huawei.com
+Fixes: ff7d6b27f894 ("page_pool: refurbish version of page_pool code")
+Suggested-by: Mina Almasry <almasrymina@google.com>
+Reviewed-by: Mina Almasry <almasrymina@google.com>
+Reviewed-by: Jesper Dangaard Brouer <hawk@kernel.org>
+Tested-by: Jesper Dangaard Brouer <hawk@kernel.org>
+Tested-by: Qiuling Ren <qren@redhat.com>
+Tested-by: Yuying Ma <yuma@redhat.com>
+Tested-by: Yonglong Liu <liuyonglong@huawei.com>
+Acked-by: Jesper Dangaard Brouer <hawk@kernel.org>
+Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
+Link: https://patch.msgid.link/20250409-page-pool-track-dma-v9-2-6a9ef2e0cba8@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/mm.h            | 46 ++++++++++++++++++--
+ include/linux/poison.h        |  4 ++
+ include/net/page_pool/types.h |  6 +++
+ net/core/netmem_priv.h        | 28 +++++++++++-
+ net/core/page_pool.c          | 81 +++++++++++++++++++++++++++++------
+ 5 files changed, 147 insertions(+), 18 deletions(-)
+
+diff --git a/include/linux/mm.h b/include/linux/mm.h
+index af2f551668e9e..e51dba8398f74 100644
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -4265,13 +4265,51 @@ int arch_lock_shadow_stack_status(struct task_struct *t, unsigned long status);
+ #define VM_SEALED_SYSMAP      VM_NONE
+ #endif
++/*
++ * DMA mapping IDs for page_pool
++ *
++ * When DMA-mapping a page, page_pool allocates an ID (from an xarray) and
++ * stashes it in the upper bits of page->pp_magic. We always want to be able to
++ * unambiguously identify page pool pages (using page_pool_page_is_pp()). Non-PP
++ * pages can have arbitrary kernel pointers stored in the same field as pp_magic
++ * (since it overlaps with page->lru.next), so we must ensure that we cannot
++ * mistake a valid kernel pointer with any of the values we write into this
++ * field.
++ *
++ * On architectures that set POISON_POINTER_DELTA, this is already ensured,
++ * since this value becomes part of PP_SIGNATURE; meaning we can just use the
++ * space between the PP_SIGNATURE value (without POISON_POINTER_DELTA), and the
++ * lowest bits of POISON_POINTER_DELTA. On arches where POISON_POINTER_DELTA is
++ * 0, we make sure that we leave the two topmost bits empty, as that guarantees
++ * we won't mistake a valid kernel pointer for a value we set, regardless of the
++ * VMSPLIT setting.
++ *
++ * Altogether, this means that the number of bits available is constrained by
++ * the size of an unsigned long (at the upper end, subtracting two bits per the
++ * above), and the definition of PP_SIGNATURE (with or without
++ * POISON_POINTER_DELTA).
++ */
++#define PP_DMA_INDEX_SHIFT (1 + __fls(PP_SIGNATURE - POISON_POINTER_DELTA))
++#if POISON_POINTER_DELTA > 0
++/* PP_SIGNATURE includes POISON_POINTER_DELTA, so limit the size of the DMA
++ * index to not overlap with that if set
++ */
++#define PP_DMA_INDEX_BITS MIN(32, __ffs(POISON_POINTER_DELTA) - PP_DMA_INDEX_SHIFT)
++#else
++/* Always leave out the topmost two; see above. */
++#define PP_DMA_INDEX_BITS MIN(32, BITS_PER_LONG - PP_DMA_INDEX_SHIFT - 2)
++#endif
++
++#define PP_DMA_INDEX_MASK GENMASK(PP_DMA_INDEX_BITS + PP_DMA_INDEX_SHIFT - 1, \
++                                PP_DMA_INDEX_SHIFT)
++
+ /* Mask used for checking in page_pool_page_is_pp() below. page->pp_magic is
+  * OR'ed with PP_SIGNATURE after the allocation in order to preserve bit 0 for
+- * the head page of compound page and bit 1 for pfmemalloc page.
+- * page_is_pfmemalloc() is checked in __page_pool_put_page() to avoid recycling
+- * the pfmemalloc page.
++ * the head page of compound page and bit 1 for pfmemalloc page, as well as the
++ * bits used for the DMA index. page_is_pfmemalloc() is checked in
++ * __page_pool_put_page() to avoid recycling the pfmemalloc page.
+  */
+-#define PP_MAGIC_MASK ~0x3UL
++#define PP_MAGIC_MASK ~(PP_DMA_INDEX_MASK | 0x3UL)
+ #ifdef CONFIG_PAGE_POOL
+ static inline bool page_pool_page_is_pp(struct page *page)
+diff --git a/include/linux/poison.h b/include/linux/poison.h
+index 331a9a996fa87..8ca2235f78d5d 100644
+--- a/include/linux/poison.h
++++ b/include/linux/poison.h
+@@ -70,6 +70,10 @@
+ #define KEY_DESTROY           0xbd
+ /********** net/core/page_pool.c **********/
++/*
++ * page_pool uses additional free bits within this value to store data, see the
++ * definition of PP_DMA_INDEX_MASK in mm.h
++ */
+ #define PP_SIGNATURE          (0x40 + POISON_POINTER_DELTA)
+ /********** net/core/skbuff.c **********/
+diff --git a/include/net/page_pool/types.h b/include/net/page_pool/types.h
+index 36eb57d73abc6..431b593de7093 100644
+--- a/include/net/page_pool/types.h
++++ b/include/net/page_pool/types.h
+@@ -6,6 +6,7 @@
+ #include <linux/dma-direction.h>
+ #include <linux/ptr_ring.h>
+ #include <linux/types.h>
++#include <linux/xarray.h>
+ #include <net/netmem.h>
+ #define PP_FLAG_DMA_MAP               BIT(0) /* Should page_pool do the DMA
+@@ -33,6 +34,9 @@
+ #define PP_FLAG_ALL           (PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV | \
+                                PP_FLAG_SYSTEM_POOL | PP_FLAG_ALLOW_UNREADABLE_NETMEM)
++/* Index limit to stay within PP_DMA_INDEX_BITS for DMA indices */
++#define PP_DMA_INDEX_LIMIT XA_LIMIT(1, BIT(PP_DMA_INDEX_BITS) - 1)
++
+ /*
+  * Fast allocation side cache array/stack
+  *
+@@ -221,6 +225,8 @@ struct page_pool {
+       void *mp_priv;
+       const struct memory_provider_ops *mp_ops;
++      struct xarray dma_mapped;
++
+ #ifdef CONFIG_PAGE_POOL_STATS
+       /* recycle stats are per-cpu to avoid locking */
+       struct page_pool_recycle_stats __percpu *recycle_stats;
+diff --git a/net/core/netmem_priv.h b/net/core/netmem_priv.h
+index f33162fd281c2..cd95394399b40 100644
+--- a/net/core/netmem_priv.h
++++ b/net/core/netmem_priv.h
+@@ -5,7 +5,7 @@
+ static inline unsigned long netmem_get_pp_magic(netmem_ref netmem)
+ {
+-      return __netmem_clear_lsb(netmem)->pp_magic;
++      return __netmem_clear_lsb(netmem)->pp_magic & ~PP_DMA_INDEX_MASK;
+ }
+ static inline void netmem_or_pp_magic(netmem_ref netmem, unsigned long pp_magic)
+@@ -15,6 +15,8 @@ static inline void netmem_or_pp_magic(netmem_ref netmem, unsigned long pp_magic)
+ static inline void netmem_clear_pp_magic(netmem_ref netmem)
+ {
++      WARN_ON_ONCE(__netmem_clear_lsb(netmem)->pp_magic & PP_DMA_INDEX_MASK);
++
+       __netmem_clear_lsb(netmem)->pp_magic = 0;
+ }
+@@ -33,4 +35,28 @@ static inline void netmem_set_dma_addr(netmem_ref netmem,
+ {
+       __netmem_clear_lsb(netmem)->dma_addr = dma_addr;
+ }
++
++static inline unsigned long netmem_get_dma_index(netmem_ref netmem)
++{
++      unsigned long magic;
++
++      if (WARN_ON_ONCE(netmem_is_net_iov(netmem)))
++              return 0;
++
++      magic = __netmem_clear_lsb(netmem)->pp_magic;
++
++      return (magic & PP_DMA_INDEX_MASK) >> PP_DMA_INDEX_SHIFT;
++}
++
++static inline void netmem_set_dma_index(netmem_ref netmem,
++                                      unsigned long id)
++{
++      unsigned long magic;
++
++      if (WARN_ON_ONCE(netmem_is_net_iov(netmem)))
++              return;
++
++      magic = netmem_get_pp_magic(netmem) | (id << PP_DMA_INDEX_SHIFT);
++      __netmem_clear_lsb(netmem)->pp_magic = magic;
++}
+ #endif
+diff --git a/net/core/page_pool.c b/net/core/page_pool.c
+index 7745ad924ae2d..2b76848659418 100644
+--- a/net/core/page_pool.c
++++ b/net/core/page_pool.c
+@@ -276,8 +276,7 @@ static int page_pool_init(struct page_pool *pool,
+       /* Driver calling page_pool_create() also call page_pool_destroy() */
+       refcount_set(&pool->user_cnt, 1);
+-      if (pool->dma_map)
+-              get_device(pool->p.dev);
++      xa_init_flags(&pool->dma_mapped, XA_FLAGS_ALLOC1);
+       if (pool->slow.flags & PP_FLAG_ALLOW_UNREADABLE_NETMEM) {
+               netdev_assert_locked(pool->slow.netdev);
+@@ -320,9 +319,7 @@ static int page_pool_init(struct page_pool *pool,
+ static void page_pool_uninit(struct page_pool *pool)
+ {
+       ptr_ring_cleanup(&pool->ring, NULL);
+-
+-      if (pool->dma_map)
+-              put_device(pool->p.dev);
++      xa_destroy(&pool->dma_mapped);
+ #ifdef CONFIG_PAGE_POOL_STATS
+       if (!pool->system)
+@@ -463,13 +460,21 @@ page_pool_dma_sync_for_device(const struct page_pool *pool,
+                             netmem_ref netmem,
+                             u32 dma_sync_size)
+ {
+-      if (pool->dma_sync && dma_dev_need_sync(pool->p.dev))
+-              __page_pool_dma_sync_for_device(pool, netmem, dma_sync_size);
++      if (pool->dma_sync && dma_dev_need_sync(pool->p.dev)) {
++              rcu_read_lock();
++              /* re-check under rcu_read_lock() to sync with page_pool_scrub() */
++              if (pool->dma_sync)
++                      __page_pool_dma_sync_for_device(pool, netmem,
++                                                      dma_sync_size);
++              rcu_read_unlock();
++      }
+ }
+-static bool page_pool_dma_map(struct page_pool *pool, netmem_ref netmem)
++static bool page_pool_dma_map(struct page_pool *pool, netmem_ref netmem, gfp_t gfp)
+ {
+       dma_addr_t dma;
++      int err;
++      u32 id;
+       /* Setup DMA mapping: use 'struct page' area for storing DMA-addr
+        * since dma_addr_t can be either 32 or 64 bits and does not always fit
+@@ -483,15 +488,30 @@ static bool page_pool_dma_map(struct page_pool *pool, netmem_ref netmem)
+       if (dma_mapping_error(pool->p.dev, dma))
+               return false;
+-      if (page_pool_set_dma_addr_netmem(netmem, dma))
++      if (page_pool_set_dma_addr_netmem(netmem, dma)) {
++              WARN_ONCE(1, "unexpected DMA address, please report to netdev@");
+               goto unmap_failed;
++      }
++
++      if (in_softirq())
++              err = xa_alloc(&pool->dma_mapped, &id, netmem_to_page(netmem),
++                             PP_DMA_INDEX_LIMIT, gfp);
++      else
++              err = xa_alloc_bh(&pool->dma_mapped, &id, netmem_to_page(netmem),
++                                PP_DMA_INDEX_LIMIT, gfp);
++      if (err) {
++              WARN_ONCE(err != -ENOMEM, "couldn't track DMA mapping, please report to netdev@");
++              goto unset_failed;
++      }
++      netmem_set_dma_index(netmem, id);
+       page_pool_dma_sync_for_device(pool, netmem, pool->p.max_len);
+       return true;
++unset_failed:
++      page_pool_set_dma_addr_netmem(netmem, 0);
+ unmap_failed:
+-      WARN_ONCE(1, "unexpected DMA address, please report to netdev@");
+       dma_unmap_page_attrs(pool->p.dev, dma,
+                            PAGE_SIZE << pool->p.order, pool->p.dma_dir,
+                            DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_WEAK_ORDERING);
+@@ -508,7 +528,7 @@ static struct page *__page_pool_alloc_page_order(struct page_pool *pool,
+       if (unlikely(!page))
+               return NULL;
+-      if (pool->dma_map && unlikely(!page_pool_dma_map(pool, page_to_netmem(page)))) {
++      if (pool->dma_map && unlikely(!page_pool_dma_map(pool, page_to_netmem(page), gfp))) {
+               put_page(page);
+               return NULL;
+       }
+@@ -554,7 +574,7 @@ static noinline netmem_ref __page_pool_alloc_pages_slow(struct page_pool *pool,
+        */
+       for (i = 0; i < nr_pages; i++) {
+               netmem = pool->alloc.cache[i];
+-              if (dma_map && unlikely(!page_pool_dma_map(pool, netmem))) {
++              if (dma_map && unlikely(!page_pool_dma_map(pool, netmem, gfp))) {
+                       put_page(netmem_to_page(netmem));
+                       continue;
+               }
+@@ -656,6 +676,8 @@ void page_pool_clear_pp_info(netmem_ref netmem)
+ static __always_inline void __page_pool_release_page_dma(struct page_pool *pool,
+                                                        netmem_ref netmem)
+ {
++      struct page *old, *page = netmem_to_page(netmem);
++      unsigned long id;
+       dma_addr_t dma;
+       if (!pool->dma_map)
+@@ -664,6 +686,17 @@ static __always_inline void __page_pool_release_page_dma(struct page_pool *pool,
+                */
+               return;
++      id = netmem_get_dma_index(netmem);
++      if (!id)
++              return;
++
++      if (in_softirq())
++              old = xa_cmpxchg(&pool->dma_mapped, id, page, NULL, 0);
++      else
++              old = xa_cmpxchg_bh(&pool->dma_mapped, id, page, NULL, 0);
++      if (old != page)
++              return;
++
+       dma = page_pool_get_dma_addr_netmem(netmem);
+       /* When page is unmapped, it cannot be returned to our pool */
+@@ -671,6 +704,7 @@ static __always_inline void __page_pool_release_page_dma(struct page_pool *pool,
+                            PAGE_SIZE << pool->p.order, pool->p.dma_dir,
+                            DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_WEAK_ORDERING);
+       page_pool_set_dma_addr_netmem(netmem, 0);
++      netmem_set_dma_index(netmem, 0);
+ }
+ /* Disconnects a page (from a page_pool).  API users can have a need
+@@ -1080,8 +1114,29 @@ static void page_pool_empty_alloc_cache_once(struct page_pool *pool)
+ static void page_pool_scrub(struct page_pool *pool)
+ {
++      unsigned long id;
++      void *ptr;
++
+       page_pool_empty_alloc_cache_once(pool);
+-      pool->destroy_cnt++;
++      if (!pool->destroy_cnt++ && pool->dma_map) {
++              if (pool->dma_sync) {
++                      /* Disable page_pool_dma_sync_for_device() */
++                      pool->dma_sync = false;
++
++                      /* Make sure all concurrent returns that may see the old
++                       * value of dma_sync (and thus perform a sync) have
++                       * finished before doing the unmapping below. Skip the
++                       * wait if the device doesn't actually need syncing, or
++                       * if there are no outstanding mapped pages.
++                       */
++                      if (dma_dev_need_sync(pool->p.dev) &&
++                          !xa_empty(&pool->dma_mapped))
++                              synchronize_net();
++              }
++
++              xa_for_each(&pool->dma_mapped, id, ptr)
++                      __page_pool_release_page_dma(pool, page_to_netmem(ptr));
++      }
+       /* No more consumers should exist, but producers could still
+        * be in-flight.
+-- 
+2.39.5
+
diff --git a/queue-6.15/path_overmount-avoid-false-negatives.patch b/queue-6.15/path_overmount-avoid-false-negatives.patch
new file mode 100644 (file)
index 0000000..958d7d7
--- /dev/null
@@ -0,0 +1,68 @@
+From 003acd7ea4b1ae86feac8498a34cc42883699e72 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 1 Jun 2025 14:02:26 -0400
+Subject: path_overmount(): avoid false negatives
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+[ Upstream commit 5f31c549382bcddbbd754c72c5433b19420d485d ]
+
+Holding namespace_sem is enough to make sure that result remains valid.
+It is *not* enough to avoid false negatives from __lookup_mnt().  Mounts
+can be unhashed outside of namespace_sem (stuck children getting detached
+on final mntput() of lazy-umounted mount) and having an unrelated mount
+removed from the hash chain while we traverse it may end up with false
+negative from __lookup_mnt().  We need to sample and recheck the seqlock
+component of mount_lock...
+
+Bug predates the introduction of path_overmount() - it had come from
+the code in finish_automount() that got abstracted into that helper.
+
+Reviewed-by: Christian Brauner <brauner@kernel.org>
+Fixes: 26df6034fdb2 ("fix automount/automount race properly")
+Fixes: 6ac392815628 ("fs: allow to mount beneath top mount")
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/namespace.c | 19 +++++++++++++------
+ 1 file changed, 13 insertions(+), 6 deletions(-)
+
+diff --git a/fs/namespace.c b/fs/namespace.c
+index 216807f772cd2..cb5126b06dcb9 100644
+--- a/fs/namespace.c
++++ b/fs/namespace.c
+@@ -3477,18 +3477,25 @@ static int do_set_group(struct path *from_path, struct path *to_path)
+  * Check if path is overmounted, i.e., if there's a mount on top of
+  * @path->mnt with @path->dentry as mountpoint.
+  *
+- * Context: This function expects namespace_lock() to be held.
++ * Context: namespace_sem must be held at least shared.
++ * MUST NOT be called under lock_mount_hash() (there one should just
++ * call __lookup_mnt() and check if it returns NULL).
+  * Return: If path is overmounted true is returned, false if not.
+  */
+ static inline bool path_overmounted(const struct path *path)
+ {
++      unsigned seq = read_seqbegin(&mount_lock);
++      bool no_child;
++
+       rcu_read_lock();
+-      if (unlikely(__lookup_mnt(path->mnt, path->dentry))) {
+-              rcu_read_unlock();
+-              return true;
+-      }
++      no_child = !__lookup_mnt(path->mnt, path->dentry);
+       rcu_read_unlock();
+-      return false;
++      if (need_seqretry(&mount_lock, seq)) {
++              read_seqlock_excl(&mount_lock);
++              no_child = !__lookup_mnt(path->mnt, path->dentry);
++              read_sequnlock_excl(&mount_lock);
++      }
++      return unlikely(!no_child);
+ }
+ /**
+-- 
+2.39.5
+
diff --git a/queue-6.15/pci-acpi-fix-allocated-memory-release-on-error-in-pc.patch b/queue-6.15/pci-acpi-fix-allocated-memory-release-on-error-in-pc.patch
new file mode 100644 (file)
index 0000000..8ae627b
--- /dev/null
@@ -0,0 +1,80 @@
+From bbc968ae5d72df3863582b73ecf4868dae7ff023 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Apr 2025 14:06:03 +0800
+Subject: PCI/ACPI: Fix allocated memory release on error in
+ pci_acpi_scan_root()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Zhe Qiao <qiaozhe@iscas.ac.cn>
+
+[ Upstream commit 631b2af2f35737750af284be22e63da56bf20139 ]
+
+In the pci_acpi_scan_root() function, when creating a PCI bus fails,
+we need to free up the previously allocated memory, which can avoid
+invalid memory usage and save resources.
+
+Fixes: 789befdfa389 ("arm64: PCI: Migrate ACPI related functions to pci-acpi.c")
+Signed-off-by: Zhe Qiao <qiaozhe@iscas.ac.cn>
+[kwilczynski: commit log]
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Link: https://lore.kernel.org/r/20250430060603.381504-1-qiaozhe@iscas.ac.cn
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pci-acpi.c | 23 +++++++++++++----------
+ 1 file changed, 13 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
+index af370628e5839..b78e0e4173244 100644
+--- a/drivers/pci/pci-acpi.c
++++ b/drivers/pci/pci-acpi.c
+@@ -1676,24 +1676,19 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
+               return NULL;
+       root_ops = kzalloc(sizeof(*root_ops), GFP_KERNEL);
+-      if (!root_ops) {
+-              kfree(ri);
+-              return NULL;
+-      }
++      if (!root_ops)
++              goto free_ri;
+       ri->cfg = pci_acpi_setup_ecam_mapping(root);
+-      if (!ri->cfg) {
+-              kfree(ri);
+-              kfree(root_ops);
+-              return NULL;
+-      }
++      if (!ri->cfg)
++              goto free_root_ops;
+       root_ops->release_info = pci_acpi_generic_release_info;
+       root_ops->prepare_resources = pci_acpi_root_prepare_resources;
+       root_ops->pci_ops = (struct pci_ops *)&ri->cfg->ops->pci_ops;
+       bus = acpi_pci_root_create(root, root_ops, &ri->common, ri->cfg);
+       if (!bus)
+-              return NULL;
++              goto free_cfg;
+       /* If we must preserve the resource configuration, claim now */
+       host = pci_find_host_bridge(bus);
+@@ -1710,6 +1705,14 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
+               pcie_bus_configure_settings(child);
+       return bus;
++
++free_cfg:
++      pci_ecam_free(ri->cfg);
++free_root_ops:
++      kfree(root_ops);
++free_ri:
++      kfree(ri);
++      return NULL;
+ }
+ void pcibios_add_bus(struct pci_bus *bus)
+-- 
+2.39.5
+
diff --git a/queue-6.15/pci-apple-use-gpiod_set_value_cansleep-in-probe-flow.patch b/queue-6.15/pci-apple-use-gpiod_set_value_cansleep-in-probe-flow.patch
new file mode 100644 (file)
index 0000000..4237d6a
--- /dev/null
@@ -0,0 +1,52 @@
+From b1f64c12740363a7ef5b93c9e348b537e8b72f8c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 10:17:11 +0100
+Subject: PCI: apple: Use gpiod_set_value_cansleep in probe flow
+
+From: Hector Martin <marcan@marcan.st>
+
+[ Upstream commit 7334364f9de79a9a236dd0243ba574b8d2876e89 ]
+
+We're allowed to sleep here, so tell the GPIO core by using
+gpiod_set_value_cansleep instead of gpiod_set_value.
+
+Fixes: 1e33888fbe44 ("PCI: apple: Add initial hardware bring-up")
+Signed-off-by: Hector Martin <marcan@marcan.st>
+Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Tested-by: Janne Grunau <j@jannau.net>
+Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Acked-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
+Link: https://patch.msgid.link/20250401091713.2765724-12-maz@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/pcie-apple.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c
+index 18e11b9a7f464..3d778d8b01875 100644
+--- a/drivers/pci/controller/pcie-apple.c
++++ b/drivers/pci/controller/pcie-apple.c
+@@ -540,7 +540,7 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
+       rmw_set(PORT_APPCLK_EN, port->base + PORT_APPCLK);
+       /* Assert PERST# before setting up the clock */
+-      gpiod_set_value(reset, 1);
++      gpiod_set_value_cansleep(reset, 1);
+       ret = apple_pcie_setup_refclk(pcie, port);
+       if (ret < 0)
+@@ -551,7 +551,7 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
+       /* Deassert PERST# */
+       rmw_set(PORT_PERST_OFF, port->base + PORT_PERST);
+-      gpiod_set_value(reset, 0);
++      gpiod_set_value_cansleep(reset, 0);
+       /* Wait for 100ms after PERST# deassertion (PCIe r5.0, 6.6.1) */
+       msleep(100);
+-- 
+2.39.5
+
diff --git a/queue-6.15/pci-cadence-fix-runtime-atomic-count-underflow.patch b/queue-6.15/pci-cadence-fix-runtime-atomic-count-underflow.patch
new file mode 100644 (file)
index 0000000..23ae986
--- /dev/null
@@ -0,0 +1,53 @@
+From 3f45c23bdbaae3dfc8f95bdecb6cfb87185e84d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Apr 2025 21:30:58 +0800
+Subject: PCI: cadence: Fix runtime atomic count underflow
+
+From: Hans Zhang <18255117159@163.com>
+
+[ Upstream commit 8805f32a96d3b97cef07999fa6f52112678f7e65 ]
+
+If the call to pci_host_probe() in cdns_pcie_host_setup() fails, PM
+runtime count is decremented in the error path using pm_runtime_put_sync().
+But the runtime count is not incremented by this driver, but only by the
+callers (cdns_plat_pcie_probe/j721e_pcie_probe). And the callers also
+decrement the runtime PM count in their error path. So this leads to the
+below warning from the PM core:
+
+       "runtime PM usage count underflow!"
+
+So fix it by getting rid of pm_runtime_put_sync() in the error path and
+directly return the errno.
+
+Fixes: 49e427e6bdd1 ("Merge branch 'pci/host-probe-refactor'")
+Signed-off-by: Hans Zhang <18255117159@163.com>
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://patch.msgid.link/20250419133058.162048-1-18255117159@163.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/cadence/pcie-cadence-host.c | 11 +----------
+ 1 file changed, 1 insertion(+), 10 deletions(-)
+
+diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c
+index 8af95e9da7cec..741e10a575ec7 100644
+--- a/drivers/pci/controller/cadence/pcie-cadence-host.c
++++ b/drivers/pci/controller/cadence/pcie-cadence-host.c
+@@ -570,14 +570,5 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
+       if (!bridge->ops)
+               bridge->ops = &cdns_pcie_host_ops;
+-      ret = pci_host_probe(bridge);
+-      if (ret < 0)
+-              goto err_init;
+-
+-      return 0;
+-
+- err_init:
+-      pm_runtime_put_sync(dev);
+-
+-      return ret;
++      return pci_host_probe(bridge);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/pci-dpc-initialize-aer_err_info-before-using-it.patch b/queue-6.15/pci-dpc-initialize-aer_err_info-before-using-it.patch
new file mode 100644 (file)
index 0000000..d8eb119
--- /dev/null
@@ -0,0 +1,46 @@
+From a9d883562dbdac55cc68f75b60a7836e869dd6a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 May 2025 18:21:07 -0500
+Subject: PCI/DPC: Initialize aer_err_info before using it
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Bjorn Helgaas <bhelgaas@google.com>
+
+[ Upstream commit a424b598e6a6c1e69a2bb801d6fd16e805ab2c38 ]
+
+Previously the struct aer_err_info "info" was allocated on the stack
+without being initialized, so it contained junk except for the fields we
+explicitly set later.
+
+Initialize "info" at declaration so it starts as all zeros.
+
+Fixes: 8aefa9b0d910 ("PCI/DPC: Print AER status in DPC event handling")
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Tested-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Link: https://patch.msgid.link/20250522232339.1525671-2-helgaas@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pcie/dpc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c
+index df42f15c98295..3daaf61c79c9f 100644
+--- a/drivers/pci/pcie/dpc.c
++++ b/drivers/pci/pcie/dpc.c
+@@ -258,7 +258,7 @@ static int dpc_get_aer_uncorrect_severity(struct pci_dev *dev,
+ void dpc_process_error(struct pci_dev *pdev)
+ {
+       u16 cap = pdev->dpc_cap, status, source, reason, ext_reason;
+-      struct aer_err_info info;
++      struct aer_err_info info = {};
+       pci_read_config_word(pdev, cap + PCI_EXP_DPC_STATUS, &status);
+       pci_read_config_word(pdev, cap + PCI_EXP_DPC_SOURCE_ID, &source);
+-- 
+2.39.5
+
diff --git a/queue-6.15/pci-dpc-log-error-source-id-only-when-valid.patch b/queue-6.15/pci-dpc-log-error-source-id-only-when-valid.patch
new file mode 100644 (file)
index 0000000..6b2493e
--- /dev/null
@@ -0,0 +1,133 @@
+From f1a60baf31c16b85e16afda6d4fb9bcbe070cdf7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 May 2025 18:21:08 -0500
+Subject: PCI/DPC: Log Error Source ID only when valid
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Bjorn Helgaas <bhelgaas@google.com>
+
+[ Upstream commit a0b62cc310239c7f1323fb20bd3789f21bdd8615 ]
+
+DPC Error Source ID is only valid when the DPC Trigger Reason indicates
+that DPC was triggered due to reception of an ERR_NONFATAL or ERR_FATAL
+Message (PCIe r6.0, sec 7.9.14.5).
+
+When DPC was triggered by ERR_NONFATAL (PCI_EXP_DPC_STATUS_TRIGGER_RSN_NFE)
+or ERR_FATAL (PCI_EXP_DPC_STATUS_TRIGGER_RSN_FE) from a downstream device,
+log the Error Source ID (decoded into domain/bus/device/function).  Don't
+print the source otherwise, since it's not valid.
+
+For DPC trigger due to reception of ERR_NONFATAL or ERR_FATAL, the dmesg
+logging changes:
+
+  - pci 0000:00:01.0: DPC: containment event, status:0x000d source:0x0200
+  - pci 0000:00:01.0: DPC: ERR_FATAL detected
+  + pci 0000:00:01.0: DPC: containment event, status:0x000d, ERR_FATAL received from 0000:02:00.0
+
+and when DPC triggered for other reasons, where DPC Error Source ID is
+undefined, e.g., unmasked uncorrectable error:
+
+  - pci 0000:00:01.0: DPC: containment event, status:0x0009 source:0x0200
+  - pci 0000:00:01.0: DPC: unmasked uncorrectable error detected
+  + pci 0000:00:01.0: DPC: containment event, status:0x0009: unmasked uncorrectable error detected
+
+Previously the "containment event" message was at KERN_INFO and the
+"%s detected" message was at KERN_WARNING.  Now the single message is at
+KERN_WARNING.
+
+Fixes: 26e515713342 ("PCI: Add Downstream Port Containment driver")
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Tested-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Link: https://patch.msgid.link/20250522232339.1525671-3-helgaas@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pcie/dpc.c | 66 +++++++++++++++++++++++-------------------
+ 1 file changed, 37 insertions(+), 29 deletions(-)
+
+diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c
+index 3daaf61c79c9f..9d85f1b3b7611 100644
+--- a/drivers/pci/pcie/dpc.c
++++ b/drivers/pci/pcie/dpc.c
+@@ -261,37 +261,45 @@ void dpc_process_error(struct pci_dev *pdev)
+       struct aer_err_info info = {};
+       pci_read_config_word(pdev, cap + PCI_EXP_DPC_STATUS, &status);
+-      pci_read_config_word(pdev, cap + PCI_EXP_DPC_SOURCE_ID, &source);
+-
+-      pci_info(pdev, "containment event, status:%#06x source:%#06x\n",
+-               status, source);
+       reason = status & PCI_EXP_DPC_STATUS_TRIGGER_RSN;
+-      ext_reason = status & PCI_EXP_DPC_STATUS_TRIGGER_RSN_EXT;
+-      pci_warn(pdev, "%s detected\n",
+-               (reason == PCI_EXP_DPC_STATUS_TRIGGER_RSN_UNCOR) ?
+-               "unmasked uncorrectable error" :
+-               (reason == PCI_EXP_DPC_STATUS_TRIGGER_RSN_NFE) ?
+-               "ERR_NONFATAL" :
+-               (reason == PCI_EXP_DPC_STATUS_TRIGGER_RSN_FE) ?
+-               "ERR_FATAL" :
+-               (ext_reason == PCI_EXP_DPC_STATUS_TRIGGER_RSN_RP_PIO) ?
+-               "RP PIO error" :
+-               (ext_reason == PCI_EXP_DPC_STATUS_TRIGGER_RSN_SW_TRIGGER) ?
+-               "software trigger" :
+-               "reserved error");
+-
+-      /* show RP PIO error detail information */
+-      if (pdev->dpc_rp_extensions &&
+-          reason == PCI_EXP_DPC_STATUS_TRIGGER_RSN_IN_EXT &&
+-          ext_reason == PCI_EXP_DPC_STATUS_TRIGGER_RSN_RP_PIO)
+-              dpc_process_rp_pio_error(pdev);
+-      else if (reason == PCI_EXP_DPC_STATUS_TRIGGER_RSN_UNCOR &&
+-               dpc_get_aer_uncorrect_severity(pdev, &info) &&
+-               aer_get_device_error_info(pdev, &info)) {
+-              aer_print_error(pdev, &info);
+-              pci_aer_clear_nonfatal_status(pdev);
+-              pci_aer_clear_fatal_status(pdev);
++
++      switch (reason) {
++      case PCI_EXP_DPC_STATUS_TRIGGER_RSN_UNCOR:
++              pci_warn(pdev, "containment event, status:%#06x: unmasked uncorrectable error detected\n",
++                       status);
++              if (dpc_get_aer_uncorrect_severity(pdev, &info) &&
++                  aer_get_device_error_info(pdev, &info)) {
++                      aer_print_error(pdev, &info);
++                      pci_aer_clear_nonfatal_status(pdev);
++                      pci_aer_clear_fatal_status(pdev);
++              }
++              break;
++      case PCI_EXP_DPC_STATUS_TRIGGER_RSN_NFE:
++      case PCI_EXP_DPC_STATUS_TRIGGER_RSN_FE:
++              pci_read_config_word(pdev, cap + PCI_EXP_DPC_SOURCE_ID,
++                                   &source);
++              pci_warn(pdev, "containment event, status:%#06x, %s received from %04x:%02x:%02x.%d\n",
++                       status,
++                       (reason == PCI_EXP_DPC_STATUS_TRIGGER_RSN_FE) ?
++                              "ERR_FATAL" : "ERR_NONFATAL",
++                       pci_domain_nr(pdev->bus), PCI_BUS_NUM(source),
++                       PCI_SLOT(source), PCI_FUNC(source));
++              break;
++      case PCI_EXP_DPC_STATUS_TRIGGER_RSN_IN_EXT:
++              ext_reason = status & PCI_EXP_DPC_STATUS_TRIGGER_RSN_EXT;
++              pci_warn(pdev, "containment event, status:%#06x: %s detected\n",
++                       status,
++                       (ext_reason == PCI_EXP_DPC_STATUS_TRIGGER_RSN_RP_PIO) ?
++                       "RP PIO error" :
++                       (ext_reason == PCI_EXP_DPC_STATUS_TRIGGER_RSN_SW_TRIGGER) ?
++                       "software trigger" :
++                       "reserved error");
++              /* show RP PIO error detail information */
++              if (ext_reason == PCI_EXP_DPC_STATUS_TRIGGER_RSN_RP_PIO &&
++                  pdev->dpc_rp_extensions)
++                      dpc_process_rp_pio_error(pdev);
++              break;
+       }
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/pci-endpoint-retain-fixed-size-bar-size-as-well-as-a.patch b/queue-6.15/pci-endpoint-retain-fixed-size-bar-size-as-well-as-a.patch
new file mode 100644 (file)
index 0000000..3b1ebfc
--- /dev/null
@@ -0,0 +1,126 @@
+From ca9428037866fedc7547922efece4ddb8c308720 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Apr 2025 10:34:04 +0200
+Subject: PCI: endpoint: Retain fixed-size BAR size as well as aligned size
+
+From: Jerome Brunet <jbrunet@baylibre.com>
+
+[ Upstream commit 793908d60b8745c386b9f4e29eb702f74ceb0886 ]
+
+When allocating space for an endpoint function on a BAR with a fixed size,
+the size saved in 'struct pci_epf_bar.size' should be the fixed size as
+expected by pci_epc_set_bar().
+
+However, if pci_epf_alloc_space() increased the allocation size to
+accommodate iATU alignment requirements, it previously saved the larger
+aligned size in .size, which broke pci_epc_set_bar().
+
+To solve this, keep the fixed BAR size in .size and save the aligned size
+in a new .aligned_size for use when deallocating it.
+
+Fixes: 2a9a801620ef ("PCI: endpoint: Add support to specify alignment for buffers allocated to BARs")
+Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
+[mani: commit message fixup]
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+[bhelgaas: more specific subject, commit log, wrap comment to match file]
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Niklas Cassel <cassel@kernel.org>
+Link: https://patch.msgid.link/20250424-pci-ep-size-alignment-v5-1-2d4ec2af23f5@baylibre.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/endpoint/pci-epf-core.c | 22 +++++++++++++++-------
+ include/linux/pci-epf.h             |  3 +++
+ 2 files changed, 18 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c
+index 394395c7f8dec..577a9e490115c 100644
+--- a/drivers/pci/endpoint/pci-epf-core.c
++++ b/drivers/pci/endpoint/pci-epf-core.c
+@@ -236,12 +236,13 @@ void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar,
+       }
+       dev = epc->dev.parent;
+-      dma_free_coherent(dev, epf_bar[bar].size, addr,
++      dma_free_coherent(dev, epf_bar[bar].aligned_size, addr,
+                         epf_bar[bar].phys_addr);
+       epf_bar[bar].phys_addr = 0;
+       epf_bar[bar].addr = NULL;
+       epf_bar[bar].size = 0;
++      epf_bar[bar].aligned_size = 0;
+       epf_bar[bar].barno = 0;
+       epf_bar[bar].flags = 0;
+ }
+@@ -264,7 +265,7 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar,
+                         enum pci_epc_interface_type type)
+ {
+       u64 bar_fixed_size = epc_features->bar[bar].fixed_size;
+-      size_t align = epc_features->align;
++      size_t aligned_size, align = epc_features->align;
+       struct pci_epf_bar *epf_bar;
+       dma_addr_t phys_addr;
+       struct pci_epc *epc;
+@@ -285,12 +286,18 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar,
+                       return NULL;
+               }
+               size = bar_fixed_size;
++      } else {
++              /* BAR size must be power of two */
++              size = roundup_pow_of_two(size);
+       }
+-      if (align)
+-              size = ALIGN(size, align);
+-      else
+-              size = roundup_pow_of_two(size);
++      /*
++       * Allocate enough memory to accommodate the iATU alignment
++       * requirement.  In most cases, this will be the same as .size but
++       * it might be different if, for example, the fixed size of a BAR
++       * is smaller than align.
++       */
++      aligned_size = align ? ALIGN(size, align) : size;
+       if (type == PRIMARY_INTERFACE) {
+               epc = epf->epc;
+@@ -301,7 +308,7 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar,
+       }
+       dev = epc->dev.parent;
+-      space = dma_alloc_coherent(dev, size, &phys_addr, GFP_KERNEL);
++      space = dma_alloc_coherent(dev, aligned_size, &phys_addr, GFP_KERNEL);
+       if (!space) {
+               dev_err(dev, "failed to allocate mem space\n");
+               return NULL;
+@@ -310,6 +317,7 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar,
+       epf_bar[bar].phys_addr = phys_addr;
+       epf_bar[bar].addr = space;
+       epf_bar[bar].size = size;
++      epf_bar[bar].aligned_size = aligned_size;
+       epf_bar[bar].barno = bar;
+       if (upper_32_bits(size) || epc_features->bar[bar].only_64bit)
+               epf_bar[bar].flags |= PCI_BASE_ADDRESS_MEM_TYPE_64;
+diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h
+index 879d19cebd4fc..749cee0bcf2cc 100644
+--- a/include/linux/pci-epf.h
++++ b/include/linux/pci-epf.h
+@@ -114,6 +114,8 @@ struct pci_epf_driver {
+  * @phys_addr: physical address that should be mapped to the BAR
+  * @addr: virtual address corresponding to the @phys_addr
+  * @size: the size of the address space present in BAR
++ * @aligned_size: the size actually allocated to accommodate the iATU alignment
++ *                requirement
+  * @barno: BAR number
+  * @flags: flags that are set for the BAR
+  */
+@@ -121,6 +123,7 @@ struct pci_epf_bar {
+       dma_addr_t      phys_addr;
+       void            *addr;
+       size_t          size;
++      size_t          aligned_size;
+       enum pci_barno  barno;
+       int             flags;
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.15/pci-explicitly-put-devices-into-d0-when-initializing.patch b/queue-6.15/pci-explicitly-put-devices-into-d0-when-initializing.patch
new file mode 100644 (file)
index 0000000..6e6ab5f
--- /dev/null
@@ -0,0 +1,108 @@
+From 564ca755d404028eb49dccfd10e359674636c609 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Apr 2025 23:31:32 -0500
+Subject: PCI: Explicitly put devices into D0 when initializing
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+[ Upstream commit 4d4c10f763d7808fbade28d83d237411603bca05 ]
+
+AMD BIOS team has root caused an issue that NVMe storage failed to come
+back from suspend to a lack of a call to _REG when NVMe device was probed.
+
+112a7f9c8edbf ("PCI/ACPI: Call _REG when transitioning D-states") added
+support for calling _REG when transitioning D-states, but this only works
+if the device actually "transitions" D-states.
+
+967577b062417 ("PCI/PM: Keep runtime PM enabled for unbound PCI devices")
+added support for runtime PM on PCI devices, but never actually
+'explicitly' sets the device to D0.
+
+To make sure that devices are in D0 and that platform methods such as
+_REG are called, explicitly set all devices into D0 during initialization.
+
+Fixes: 967577b062417 ("PCI/PM: Keep runtime PM enabled for unbound PCI devices")
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Tested-by: Denis Benato <benato.denis96@gmail.com>
+Tested-By: Yijun Shen <Yijun_Shen@Dell.com>
+Tested-By: David Perry <david.perry@amd.com>
+Reviewed-by: Rafael J. Wysocki <rafael@kernel.org>
+Link: https://patch.msgid.link/20250424043232.1848107-1-superm1@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pci-driver.c |  6 ------
+ drivers/pci/pci.c        | 13 ++++++++++---
+ drivers/pci/pci.h        |  1 +
+ 3 files changed, 11 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
+index c8bd71a739f72..082918ce03d8a 100644
+--- a/drivers/pci/pci-driver.c
++++ b/drivers/pci/pci-driver.c
+@@ -555,12 +555,6 @@ static void pci_pm_default_resume(struct pci_dev *pci_dev)
+       pci_enable_wake(pci_dev, PCI_D0, false);
+ }
+-static void pci_pm_power_up_and_verify_state(struct pci_dev *pci_dev)
+-{
+-      pci_power_up(pci_dev);
+-      pci_update_current_state(pci_dev, PCI_D0);
+-}
+-
+ static void pci_pm_default_resume_early(struct pci_dev *pci_dev)
+ {
+       pci_pm_power_up_and_verify_state(pci_dev);
+diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
+index 4d84ed4124844..f1a8f05a61054 100644
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -3192,6 +3192,12 @@ void pci_d3cold_disable(struct pci_dev *dev)
+ }
+ EXPORT_SYMBOL_GPL(pci_d3cold_disable);
++void pci_pm_power_up_and_verify_state(struct pci_dev *pci_dev)
++{
++      pci_power_up(pci_dev);
++      pci_update_current_state(pci_dev, PCI_D0);
++}
++
+ /**
+  * pci_pm_init - Initialize PM functions of given PCI device
+  * @dev: PCI device to handle.
+@@ -3202,9 +3208,6 @@ void pci_pm_init(struct pci_dev *dev)
+       u16 status;
+       u16 pmc;
+-      pm_runtime_forbid(&dev->dev);
+-      pm_runtime_set_active(&dev->dev);
+-      pm_runtime_enable(&dev->dev);
+       device_enable_async_suspend(&dev->dev);
+       dev->wakeup_prepared = false;
+@@ -3266,6 +3269,10 @@ void pci_pm_init(struct pci_dev *dev)
+       pci_read_config_word(dev, PCI_STATUS, &status);
+       if (status & PCI_STATUS_IMM_READY)
+               dev->imm_ready = 1;
++      pci_pm_power_up_and_verify_state(dev);
++      pm_runtime_forbid(&dev->dev);
++      pm_runtime_set_active(&dev->dev);
++      pm_runtime_enable(&dev->dev);
+ }
+ static unsigned long pci_ea_flags(struct pci_dev *dev, u8 prop)
+diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
+index 7db798bdcaaae..7e206c173599f 100644
+--- a/drivers/pci/pci.h
++++ b/drivers/pci/pci.h
+@@ -148,6 +148,7 @@ void pci_dev_adjust_pme(struct pci_dev *dev);
+ void pci_dev_complete_resume(struct pci_dev *pci_dev);
+ void pci_config_pm_runtime_get(struct pci_dev *dev);
+ void pci_config_pm_runtime_put(struct pci_dev *dev);
++void pci_pm_power_up_and_verify_state(struct pci_dev *pci_dev);
+ void pci_pm_init(struct pci_dev *dev);
+ void pci_ea_init(struct pci_dev *dev);
+ void pci_msi_init(struct pci_dev *dev);
+-- 
+2.39.5
+
diff --git a/queue-6.15/pci-imx6-save-and-restore-the-lut-setting-during-sus.patch b/queue-6.15/pci-imx6-save-and-restore-the-lut-setting-during-sus.patch
new file mode 100644 (file)
index 0000000..67deddc
--- /dev/null
@@ -0,0 +1,115 @@
+From ed506d13e71d73b01d7edda01e69a2a7fb9f0749 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Apr 2025 16:13:14 +0800
+Subject: PCI: imx6: Save and restore the LUT setting during suspend/resume for
+ i.MX95 SoC
+
+From: Richard Zhu <hongxing.zhu@nxp.com>
+
+[ Upstream commit e4d66131caaf18d7c3c69914513f4be0519ddaaf ]
+
+The look up table (LUT) setting would be lost during the PCIe suspend on
+i.MX95 SoC. So to ensure proper functionality after resume, save it during
+suspend and restore it while resuming.
+
+Fixes: 9d6b1bd6b3c8 ("PCI: imx6: Add i.MX8MQ, i.MX8Q and i.MX95 PM support")
+Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
+[mani: subject and description rewording]
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://patch.msgid.link/20250416081314.3929794-8-hongxing.zhu@nxp.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pci-imx6.c | 47 +++++++++++++++++++++++++++
+ 1 file changed, 47 insertions(+)
+
+diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
+index 5f267dd261b51..ea5c06371171f 100644
+--- a/drivers/pci/controller/dwc/pci-imx6.c
++++ b/drivers/pci/controller/dwc/pci-imx6.c
+@@ -129,6 +129,11 @@ struct imx_pcie_drvdata {
+       const struct dw_pcie_host_ops *ops;
+ };
++struct imx_lut_data {
++      u32 data1;
++      u32 data2;
++};
++
+ struct imx_pcie {
+       struct dw_pcie          *pci;
+       struct gpio_desc        *reset_gpiod;
+@@ -148,6 +153,8 @@ struct imx_pcie {
+       struct regulator        *vph;
+       void __iomem            *phy_base;
++      /* LUT data for pcie */
++      struct imx_lut_data     luts[IMX95_MAX_LUT];
+       /* power domain for pcie */
+       struct device           *pd_pcie;
+       /* power domain for pcie phy */
+@@ -1386,6 +1393,42 @@ static void imx_pcie_msi_save_restore(struct imx_pcie *imx_pcie, bool save)
+       }
+ }
++static void imx_pcie_lut_save(struct imx_pcie *imx_pcie)
++{
++      u32 data1, data2;
++      int i;
++
++      for (i = 0; i < IMX95_MAX_LUT; i++) {
++              regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_ACSCTRL,
++                           IMX95_PEO_LUT_RWA | i);
++              regmap_read(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA1, &data1);
++              regmap_read(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA2, &data2);
++              if (data1 & IMX95_PE0_LUT_VLD) {
++                      imx_pcie->luts[i].data1 = data1;
++                      imx_pcie->luts[i].data2 = data2;
++              } else {
++                      imx_pcie->luts[i].data1 = 0;
++                      imx_pcie->luts[i].data2 = 0;
++              }
++      }
++}
++
++static void imx_pcie_lut_restore(struct imx_pcie *imx_pcie)
++{
++      int i;
++
++      for (i = 0; i < IMX95_MAX_LUT; i++) {
++              if ((imx_pcie->luts[i].data1 & IMX95_PE0_LUT_VLD) == 0)
++                      continue;
++
++              regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA1,
++                           imx_pcie->luts[i].data1);
++              regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA2,
++                           imx_pcie->luts[i].data2);
++              regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_ACSCTRL, i);
++      }
++}
++
+ static int imx_pcie_suspend_noirq(struct device *dev)
+ {
+       struct imx_pcie *imx_pcie = dev_get_drvdata(dev);
+@@ -1394,6 +1437,8 @@ static int imx_pcie_suspend_noirq(struct device *dev)
+               return 0;
+       imx_pcie_msi_save_restore(imx_pcie, true);
++      if (imx_check_flag(imx_pcie, IMX_PCIE_FLAG_HAS_LUT))
++              imx_pcie_lut_save(imx_pcie);
+       if (imx_check_flag(imx_pcie, IMX_PCIE_FLAG_BROKEN_SUSPEND)) {
+               /*
+                * The minimum for a workaround would be to set PERST# and to
+@@ -1438,6 +1483,8 @@ static int imx_pcie_resume_noirq(struct device *dev)
+               if (ret)
+                       return ret;
+       }
++      if (imx_check_flag(imx_pcie, IMX_PCIE_FLAG_HAS_LUT))
++              imx_pcie_lut_restore(imx_pcie);
+       imx_pcie_msi_save_restore(imx_pcie, false);
+       return 0;
+-- 
+2.39.5
+
diff --git a/queue-6.15/pci-pciehp-ignore-link-down-up-caused-by-secondary-b.patch b/queue-6.15/pci-pciehp-ignore-link-down-up-caused-by-secondary-b.patch
new file mode 100644 (file)
index 0000000..aa3f8d1
--- /dev/null
@@ -0,0 +1,322 @@
+From 161a7237de69f65ccfe68da318343f3719149480 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Apr 2025 17:27:12 +0200
+Subject: PCI: pciehp: Ignore Link Down/Up caused by Secondary Bus Reset
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Lukas Wunner <lukas@wunner.de>
+
+[ Upstream commit 2af781a9edc4ef5f6684c0710cc3542d9be48b31 ]
+
+When a Secondary Bus Reset is issued at a hotplug port, it causes a Data
+Link Layer State Changed event as a side effect.  On hotplug ports using
+in-band presence detect, it additionally causes a Presence Detect Changed
+event.
+
+These spurious events should not result in teardown and re-enumeration of
+the device in the slot.  Hence commit 2e35afaefe64 ("PCI: pciehp: Add
+reset_slot() method") masked the Presence Detect Changed Enable bit in the
+Slot Control register during a Secondary Bus Reset.  Commit 06a8d89af551
+("PCI: pciehp: Disable link notification across slot reset") additionally
+masked the Data Link Layer State Changed Enable bit.
+
+However masking those bits only disables interrupt generation (PCIe r6.2
+sec 6.7.3.1).  The events are still visible in the Slot Status register
+and picked up by the IRQ handler if it runs during a Secondary Bus Reset.
+This can happen if the interrupt is shared or if an unmasked hotplug event
+occurs, e.g. Attention Button Pressed or Power Fault Detected.
+
+The likelihood of this happening used to be small, so it wasn't much of a
+problem in practice.  That has changed with the recent introduction of
+bandwidth control in v6.13-rc1 with commit 665745f27487 ("PCI/bwctrl:
+Re-add BW notification portdrv as PCIe BW controller"):
+
+Bandwidth control shares the interrupt with PCIe hotplug.  A Secondary Bus
+Reset causes a Link Bandwidth Notification, so the hotplug IRQ handler
+runs, picks up the masked events and tears down the device in the slot.
+
+As a result, Joel reports VFIO passthrough failure of a GPU, which Ilpo
+root-caused to the incorrect handling of masked hotplug events.
+
+Clearly, a more reliable way is needed to ignore spurious hotplug events.
+
+For Downstream Port Containment, a new ignore mechanism was introduced by
+commit a97396c6eb13 ("PCI: pciehp: Ignore Link Down/Up caused by DPC").
+It has been working reliably for the past four years.
+
+Adapt it for Secondary Bus Resets.
+
+Introduce two helpers to annotate code sections which cause spurious link
+changes:  pci_hp_ignore_link_change() and pci_hp_unignore_link_change()
+Use those helpers in lieu of masking interrupts in the Slot Control
+register.
+
+Introduce a helper to check whether such a code section is executing
+concurrently and if so, await it:  pci_hp_spurious_link_change()
+Invoke the helper in the hotplug IRQ thread pciehp_ist().  Re-use the
+IRQ thread's existing code which ignores DPC-induced link changes unless
+the link is unexpectedly down after reset recovery or the device was
+replaced during the bus reset.
+
+That code block in pciehp_ist() was previously only executed if a Data
+Link Layer State Changed event has occurred.  Additionally execute it for
+Presence Detect Changed events.  That's necessary for compatibility with
+PCIe r1.0 hotplug ports because Data Link Layer State Changed didn't exist
+before PCIe r1.1.  DPC was added with PCIe r3.1 and thus DPC-capable
+hotplug ports always support Data Link Layer State Changed events.
+But the same cannot be assumed for Secondary Bus Reset, which already
+existed in PCIe r1.0.
+
+Secondary Bus Reset is only one of many causes of spurious link changes.
+Others include runtime suspend to D3cold, firmware updates or FPGA
+reconfiguration.  The new pci_hp_{,un}ignore_link_change() helpers may be
+used by all kinds of drivers to annotate such code sections, hence their
+declarations are publicly visible in <linux/pci.h>.  A case in point is
+the Mellanox Ethernet driver which disables a firmware reset feature if
+the Ethernet card is attached to a hotplug port, see commit 3d7a3f2612d7
+("net/mlx5: Nack sync reset request when HotPlug is enabled").  Going
+forward, PCIe hotplug will be able to cope gracefully with all such use
+cases once the code sections are properly annotated.
+
+The new helpers internally use two bits in struct pci_dev's priv_flags as
+well as a wait_queue.  This mirrors what was done for DPC by commit
+a97396c6eb13 ("PCI: pciehp: Ignore Link Down/Up caused by DPC").  That may
+be insufficient if spurious link changes are caused by multiple sources
+simultaneously.  An example might be a Secondary Bus Reset issued by AER
+during FPGA reconfiguration.  If this turns out to happen in real life,
+support for it can easily be added by replacing the PCI_LINK_CHANGING flag
+with an atomic_t counter incremented by pci_hp_ignore_link_change() and
+decremented by pci_hp_unignore_link_change().  Instead of awaiting a zero
+PCI_LINK_CHANGING flag, the pci_hp_spurious_link_change() helper would
+then simply await a zero counter.
+
+Fixes: 665745f27487 ("PCI/bwctrl: Re-add BW notification portdrv as PCIe BW controller")
+Reported-by: Joel Mathew Thomas <proxy0@tutamail.com>
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219765
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Tested-by: Joel Mathew Thomas <proxy0@tutamail.com>
+Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Link: https://patch.msgid.link/d04deaf49d634a2edf42bf3c06ed81b4ca54d17b.1744298239.git.lukas@wunner.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/hotplug/pci_hotplug_core.c | 69 ++++++++++++++++++++++++++
+ drivers/pci/hotplug/pciehp_hpc.c       | 35 +++++--------
+ drivers/pci/pci.h                      |  3 ++
+ include/linux/pci.h                    |  8 +++
+ 4 files changed, 92 insertions(+), 23 deletions(-)
+
+diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c
+index d30f1316c98e2..d7fc3bc039643 100644
+--- a/drivers/pci/hotplug/pci_hotplug_core.c
++++ b/drivers/pci/hotplug/pci_hotplug_core.c
+@@ -492,6 +492,75 @@ void pci_hp_destroy(struct hotplug_slot *slot)
+ }
+ EXPORT_SYMBOL_GPL(pci_hp_destroy);
++static DECLARE_WAIT_QUEUE_HEAD(pci_hp_link_change_wq);
++
++/**
++ * pci_hp_ignore_link_change - begin code section causing spurious link changes
++ * @pdev: PCI hotplug bridge
++ *
++ * Mark the beginning of a code section causing spurious link changes on the
++ * Secondary Bus of @pdev, e.g. as a side effect of a Secondary Bus Reset,
++ * D3cold transition, firmware update or FPGA reconfiguration.
++ *
++ * Hotplug drivers can thus check whether such a code section is executing
++ * concurrently, await it with pci_hp_spurious_link_change() and ignore the
++ * resulting link change events.
++ *
++ * Must be paired with pci_hp_unignore_link_change().  May be called both
++ * from the PCI core and from Endpoint drivers.  May be called for bridges
++ * which are not hotplug-capable, in which case it has no effect because
++ * no hotplug driver is bound to the bridge.
++ */
++void pci_hp_ignore_link_change(struct pci_dev *pdev)
++{
++      set_bit(PCI_LINK_CHANGING, &pdev->priv_flags);
++      smp_mb__after_atomic(); /* pairs with implied barrier of wait_event() */
++}
++
++/**
++ * pci_hp_unignore_link_change - end code section causing spurious link changes
++ * @pdev: PCI hotplug bridge
++ *
++ * Mark the end of a code section causing spurious link changes on the
++ * Secondary Bus of @pdev.  Must be paired with pci_hp_ignore_link_change().
++ */
++void pci_hp_unignore_link_change(struct pci_dev *pdev)
++{
++      set_bit(PCI_LINK_CHANGED, &pdev->priv_flags);
++      mb(); /* ensure pci_hp_spurious_link_change() sees either bit set */
++      clear_bit(PCI_LINK_CHANGING, &pdev->priv_flags);
++      wake_up_all(&pci_hp_link_change_wq);
++}
++
++/**
++ * pci_hp_spurious_link_change - check for spurious link changes
++ * @pdev: PCI hotplug bridge
++ *
++ * Check whether a code section is executing concurrently which is causing
++ * spurious link changes on the Secondary Bus of @pdev.  Await the end of the
++ * code section if so.
++ *
++ * May be called by hotplug drivers to check whether a link change is spurious
++ * and can be ignored.
++ *
++ * Because a genuine link change may have occurred in-between a spurious link
++ * change and the invocation of this function, hotplug drivers should perform
++ * sanity checks such as retrieving the current link state and bringing down
++ * the slot if the link is down.
++ *
++ * Return: %true if such a code section has been executing concurrently,
++ * otherwise %false.  Also return %true if such a code section has not been
++ * executing concurrently, but at least once since the last invocation of this
++ * function.
++ */
++bool pci_hp_spurious_link_change(struct pci_dev *pdev)
++{
++      wait_event(pci_hp_link_change_wq,
++                 !test_bit(PCI_LINK_CHANGING, &pdev->priv_flags));
++
++      return test_and_clear_bit(PCI_LINK_CHANGED, &pdev->priv_flags);
++}
++
+ static int __init pci_hotplug_init(void)
+ {
+       int result;
+diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
+index 388fbed25402b..ebd342bda235d 100644
+--- a/drivers/pci/hotplug/pciehp_hpc.c
++++ b/drivers/pci/hotplug/pciehp_hpc.c
+@@ -592,21 +592,21 @@ bool pciehp_device_replaced(struct controller *ctrl)
+       return false;
+ }
+-static void pciehp_ignore_dpc_link_change(struct controller *ctrl,
+-                                        struct pci_dev *pdev, int irq,
+-                                        u16 ignored_events)
++static void pciehp_ignore_link_change(struct controller *ctrl,
++                                    struct pci_dev *pdev, int irq,
++                                    u16 ignored_events)
+ {
+       /*
+        * Ignore link changes which occurred while waiting for DPC recovery.
+        * Could be several if DPC triggered multiple times consecutively.
++       * Also ignore link changes caused by Secondary Bus Reset, etc.
+        */
+       synchronize_hardirq(irq);
+       atomic_and(~ignored_events, &ctrl->pending_events);
+       if (pciehp_poll_mode)
+               pcie_capability_write_word(pdev, PCI_EXP_SLTSTA,
+                                          ignored_events);
+-      ctrl_info(ctrl, "Slot(%s): Link Down/Up ignored (recovered by DPC)\n",
+-                slot_name(ctrl));
++      ctrl_info(ctrl, "Slot(%s): Link Down/Up ignored\n", slot_name(ctrl));
+       /*
+        * If the link is unexpectedly down after successful recovery,
+@@ -762,9 +762,11 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id)
+       /*
+        * Ignore Link Down/Up events caused by Downstream Port Containment
+-       * if recovery from the error succeeded.
++       * if recovery succeeded, or caused by Secondary Bus Reset,
++       * suspend to D3cold, firmware update, FPGA reconfiguration, etc.
+        */
+-      if ((events & PCI_EXP_SLTSTA_DLLSC) && pci_dpc_recovered(pdev) &&
++      if ((events & (PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC)) &&
++          (pci_dpc_recovered(pdev) || pci_hp_spurious_link_change(pdev)) &&
+           ctrl->state == ON_STATE) {
+               u16 ignored_events = PCI_EXP_SLTSTA_DLLSC;
+@@ -772,7 +774,7 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id)
+                       ignored_events |= events & PCI_EXP_SLTSTA_PDC;
+               events &= ~ignored_events;
+-              pciehp_ignore_dpc_link_change(ctrl, pdev, irq, ignored_events);
++              pciehp_ignore_link_change(ctrl, pdev, irq, ignored_events);
+       }
+       /*
+@@ -937,7 +939,6 @@ int pciehp_reset_slot(struct hotplug_slot *hotplug_slot, bool probe)
+ {
+       struct controller *ctrl = to_ctrl(hotplug_slot);
+       struct pci_dev *pdev = ctrl_dev(ctrl);
+-      u16 stat_mask = 0, ctrl_mask = 0;
+       int rc;
+       if (probe)
+@@ -945,23 +946,11 @@ int pciehp_reset_slot(struct hotplug_slot *hotplug_slot, bool probe)
+       down_write_nested(&ctrl->reset_lock, ctrl->depth);
+-      if (!ATTN_BUTTN(ctrl)) {
+-              ctrl_mask |= PCI_EXP_SLTCTL_PDCE;
+-              stat_mask |= PCI_EXP_SLTSTA_PDC;
+-      }
+-      ctrl_mask |= PCI_EXP_SLTCTL_DLLSCE;
+-      stat_mask |= PCI_EXP_SLTSTA_DLLSC;
+-
+-      pcie_write_cmd(ctrl, 0, ctrl_mask);
+-      ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
+-               pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, 0);
++      pci_hp_ignore_link_change(pdev);
+       rc = pci_bridge_secondary_bus_reset(ctrl->pcie->port);
+-      pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, stat_mask);
+-      pcie_write_cmd_nowait(ctrl, ctrl_mask, ctrl_mask);
+-      ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
+-               pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, ctrl_mask);
++      pci_hp_unignore_link_change(pdev);
+       up_write(&ctrl->reset_lock);
+       return rc;
+diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
+index b81e99cd4b62a..7db798bdcaaae 100644
+--- a/drivers/pci/pci.h
++++ b/drivers/pci/pci.h
+@@ -227,6 +227,7 @@ static inline int pci_proc_detach_bus(struct pci_bus *bus) { return 0; }
+ /* Functions for PCI Hotplug drivers to use */
+ int pci_hp_add_bridge(struct pci_dev *dev);
++bool pci_hp_spurious_link_change(struct pci_dev *pdev);
+ #if defined(CONFIG_SYSFS) && defined(HAVE_PCI_LEGACY)
+ void pci_create_legacy_files(struct pci_bus *bus);
+@@ -557,6 +558,8 @@ static inline int pci_dev_set_disconnected(struct pci_dev *dev, void *unused)
+ #define PCI_DPC_RECOVERED 1
+ #define PCI_DPC_RECOVERING 2
+ #define PCI_DEV_REMOVED 3
++#define PCI_LINK_CHANGED 4
++#define PCI_LINK_CHANGING 5
+ static inline void pci_dev_assign_added(struct pci_dev *dev)
+ {
+diff --git a/include/linux/pci.h b/include/linux/pci.h
+index 51e2bd6405cda..081e5c0a3ddf4 100644
+--- a/include/linux/pci.h
++++ b/include/linux/pci.h
+@@ -1850,6 +1850,14 @@ static inline bool pcie_aspm_support_enabled(void) { return false; }
+ static inline bool pcie_aspm_enabled(struct pci_dev *pdev) { return false; }
+ #endif
++#ifdef CONFIG_HOTPLUG_PCI
++void pci_hp_ignore_link_change(struct pci_dev *pdev);
++void pci_hp_unignore_link_change(struct pci_dev *pdev);
++#else
++static inline void pci_hp_ignore_link_change(struct pci_dev *pdev) { }
++static inline void pci_hp_unignore_link_change(struct pci_dev *pdev) { }
++#endif
++
+ #ifdef CONFIG_PCIEAER
+ bool pci_aer_available(void);
+ #else
+-- 
+2.39.5
+
diff --git a/queue-6.15/pci-pciehp-ignore-presence-detect-changed-caused-by-.patch b/queue-6.15/pci-pciehp-ignore-presence-detect-changed-caused-by-.patch
new file mode 100644 (file)
index 0000000..462a463
--- /dev/null
@@ -0,0 +1,191 @@
+From 501aa25a7341b71afed9394b4b3c1c3129cc7e24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Apr 2025 17:27:11 +0200
+Subject: PCI: pciehp: Ignore Presence Detect Changed caused by DPC
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Lukas Wunner <lukas@wunner.de>
+
+[ Upstream commit c3be50f7547ccb533284b22f74baf37d3379843e ]
+
+Commit a97396c6eb13 ("PCI: pciehp: Ignore Link Down/Up caused by DPC")
+amended PCIe hotplug to not bring down the slot upon Data Link Layer State
+Changed events caused by Downstream Port Containment.
+
+However Keith reports off-list that if the slot uses in-band presence
+detect (i.e. Presence Detect State is derived from Data Link Layer Link
+Active), DPC also causes a spurious Presence Detect Changed event.
+
+This needs to be ignored as well.
+
+Unfortunately there's no register indicating that in-band presence detect
+is used.  PCIe r5.0 sec 7.5.3.10 introduced the In-Band PD Disable bit in
+the Slot Control Register.  The PCIe hotplug driver sets this bit on
+ports supporting it.  But older ports may still use in-band presence
+detect.
+
+If in-band presence detect can be disabled, Presence Detect Changed events
+occurring during DPC must not be ignored because they signal device
+replacement.  On all other ports, device replacement cannot be detected
+reliably because the Presence Detect Changed event could be a side effect
+of DPC.  On those (older) ports, perform a best-effort device replacement
+check by comparing the Vendor ID, Device ID and other data in Config Space
+with the values cached in struct pci_dev.  Use the existing helper
+pciehp_device_replaced() to accomplish this.  It is currently #ifdef'ed to
+CONFIG_PM_SLEEP in pciehp_core.c, so move it to pciehp_hpc.c where most
+other functions accessing config space reside.
+
+Reported-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Link: https://patch.msgid.link/fa264ff71952915c4e35a53c89eb0cde8455a5c5.1744298239.git.lukas@wunner.de
+Stable-dep-of: 2af781a9edc4 ("PCI: pciehp: Ignore Link Down/Up caused by Secondary Bus Reset")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/hotplug/pciehp.h      |  1 +
+ drivers/pci/hotplug/pciehp_core.c | 29 ------------------
+ drivers/pci/hotplug/pciehp_hpc.c  | 49 ++++++++++++++++++++++++++-----
+ 3 files changed, 43 insertions(+), 36 deletions(-)
+
+diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
+index 273dd8c66f4ef..debc79b0adfb2 100644
+--- a/drivers/pci/hotplug/pciehp.h
++++ b/drivers/pci/hotplug/pciehp.h
+@@ -187,6 +187,7 @@ int pciehp_card_present(struct controller *ctrl);
+ int pciehp_card_present_or_link_active(struct controller *ctrl);
+ int pciehp_check_link_status(struct controller *ctrl);
+ int pciehp_check_link_active(struct controller *ctrl);
++bool pciehp_device_replaced(struct controller *ctrl);
+ void pciehp_release_ctrl(struct controller *ctrl);
+ int pciehp_sysfs_enable_slot(struct hotplug_slot *hotplug_slot);
+diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
+index 997841c698935..f59baa9129709 100644
+--- a/drivers/pci/hotplug/pciehp_core.c
++++ b/drivers/pci/hotplug/pciehp_core.c
+@@ -284,35 +284,6 @@ static int pciehp_suspend(struct pcie_device *dev)
+       return 0;
+ }
+-static bool pciehp_device_replaced(struct controller *ctrl)
+-{
+-      struct pci_dev *pdev __free(pci_dev_put) = NULL;
+-      u32 reg;
+-
+-      if (pci_dev_is_disconnected(ctrl->pcie->port))
+-              return false;
+-
+-      pdev = pci_get_slot(ctrl->pcie->port->subordinate, PCI_DEVFN(0, 0));
+-      if (!pdev)
+-              return true;
+-
+-      if (pci_read_config_dword(pdev, PCI_VENDOR_ID, &reg) ||
+-          reg != (pdev->vendor | (pdev->device << 16)) ||
+-          pci_read_config_dword(pdev, PCI_CLASS_REVISION, &reg) ||
+-          reg != (pdev->revision | (pdev->class << 8)))
+-              return true;
+-
+-      if (pdev->hdr_type == PCI_HEADER_TYPE_NORMAL &&
+-          (pci_read_config_dword(pdev, PCI_SUBSYSTEM_VENDOR_ID, &reg) ||
+-           reg != (pdev->subsystem_vendor | (pdev->subsystem_device << 16))))
+-              return true;
+-
+-      if (pci_get_dsn(pdev) != ctrl->dsn)
+-              return true;
+-
+-      return false;
+-}
+-
+ static int pciehp_resume_noirq(struct pcie_device *dev)
+ {
+       struct controller *ctrl = get_service_data(dev);
+diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
+index 8a09fb6083e27..388fbed25402b 100644
+--- a/drivers/pci/hotplug/pciehp_hpc.c
++++ b/drivers/pci/hotplug/pciehp_hpc.c
+@@ -563,18 +563,48 @@ void pciehp_power_off_slot(struct controller *ctrl)
+                PCI_EXP_SLTCTL_PWR_OFF);
+ }
++bool pciehp_device_replaced(struct controller *ctrl)
++{
++      struct pci_dev *pdev __free(pci_dev_put) = NULL;
++      u32 reg;
++
++      if (pci_dev_is_disconnected(ctrl->pcie->port))
++              return false;
++
++      pdev = pci_get_slot(ctrl->pcie->port->subordinate, PCI_DEVFN(0, 0));
++      if (!pdev)
++              return true;
++
++      if (pci_read_config_dword(pdev, PCI_VENDOR_ID, &reg) ||
++          reg != (pdev->vendor | (pdev->device << 16)) ||
++          pci_read_config_dword(pdev, PCI_CLASS_REVISION, &reg) ||
++          reg != (pdev->revision | (pdev->class << 8)))
++              return true;
++
++      if (pdev->hdr_type == PCI_HEADER_TYPE_NORMAL &&
++          (pci_read_config_dword(pdev, PCI_SUBSYSTEM_VENDOR_ID, &reg) ||
++           reg != (pdev->subsystem_vendor | (pdev->subsystem_device << 16))))
++              return true;
++
++      if (pci_get_dsn(pdev) != ctrl->dsn)
++              return true;
++
++      return false;
++}
++
+ static void pciehp_ignore_dpc_link_change(struct controller *ctrl,
+-                                        struct pci_dev *pdev, int irq)
++                                        struct pci_dev *pdev, int irq,
++                                        u16 ignored_events)
+ {
+       /*
+        * Ignore link changes which occurred while waiting for DPC recovery.
+        * Could be several if DPC triggered multiple times consecutively.
+        */
+       synchronize_hardirq(irq);
+-      atomic_and(~PCI_EXP_SLTSTA_DLLSC, &ctrl->pending_events);
++      atomic_and(~ignored_events, &ctrl->pending_events);
+       if (pciehp_poll_mode)
+               pcie_capability_write_word(pdev, PCI_EXP_SLTSTA,
+-                                         PCI_EXP_SLTSTA_DLLSC);
++                                         ignored_events);
+       ctrl_info(ctrl, "Slot(%s): Link Down/Up ignored (recovered by DPC)\n",
+                 slot_name(ctrl));
+@@ -584,8 +614,8 @@ static void pciehp_ignore_dpc_link_change(struct controller *ctrl,
+        * Synthesize it to ensure that it is acted on.
+        */
+       down_read_nested(&ctrl->reset_lock, ctrl->depth);
+-      if (!pciehp_check_link_active(ctrl))
+-              pciehp_request(ctrl, PCI_EXP_SLTSTA_DLLSC);
++      if (!pciehp_check_link_active(ctrl) || pciehp_device_replaced(ctrl))
++              pciehp_request(ctrl, ignored_events);
+       up_read(&ctrl->reset_lock);
+ }
+@@ -736,8 +766,13 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id)
+        */
+       if ((events & PCI_EXP_SLTSTA_DLLSC) && pci_dpc_recovered(pdev) &&
+           ctrl->state == ON_STATE) {
+-              events &= ~PCI_EXP_SLTSTA_DLLSC;
+-              pciehp_ignore_dpc_link_change(ctrl, pdev, irq);
++              u16 ignored_events = PCI_EXP_SLTSTA_DLLSC;
++
++              if (!ctrl->inband_presence_disabled)
++                      ignored_events |= events & PCI_EXP_SLTSTA_PDC;
++
++              events &= ~ignored_events;
++              pciehp_ignore_dpc_link_change(ctrl, pdev, irq, ignored_events);
+       }
+       /*
+-- 
+2.39.5
+
diff --git a/queue-6.15/pci-print-the-actual-delay-time-in-pci_bridge_wait_f.patch b/queue-6.15/pci-print-the-actual-delay-time-in-pci_bridge_wait_f.patch
new file mode 100644 (file)
index 0000000..32badec
--- /dev/null
@@ -0,0 +1,45 @@
+From 134390dc8f71ed16f2ed84dd478b7ebab4ada996 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Apr 2025 10:15:06 +1000
+Subject: PCI: Print the actual delay time in
+ pci_bridge_wait_for_secondary_bus()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
+
+[ Upstream commit d24eba726aadf8778f2907dd42281c6380b0ccaa ]
+
+Print the delay amount that pcie_wait_for_link_delay() is invoked with
+instead of the hardcoded 1000ms value in the debug info print.
+
+Fixes: 7b3ba09febf4 ("PCI/PM: Shorten pci_bridge_wait_for_secondary_bus() wait time for slow links")
+Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
+Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
+Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Link: https://patch.msgid.link/20250414001505.21243-2-wilfred.opensource@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pci.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
+index e77d5b53c0cec..4d84ed4124844 100644
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -4954,7 +4954,7 @@ int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type)
+               delay);
+       if (!pcie_wait_for_link_delay(dev, true, delay)) {
+               /* Did not train, no need to wait any further */
+-              pci_info(dev, "Data Link Layer Link Active not set in 1000 msec\n");
++              pci_info(dev, "Data Link Layer Link Active not set in %d msec\n", delay);
+               return -ENOTTY;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/pci-pwrctrl-cancel-outstanding-rescan-work-when-unre.patch b/queue-6.15/pci-pwrctrl-cancel-outstanding-rescan-work-when-unre.patch
new file mode 100644 (file)
index 0000000..bbcf567
--- /dev/null
@@ -0,0 +1,51 @@
+From e08c57b688adb296f9d0079482b1bef980189d6e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Apr 2025 11:53:13 -0700
+Subject: PCI/pwrctrl: Cancel outstanding rescan work when unregistering
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Brian Norris <briannorris@google.com>
+
+[ Upstream commit 8b926f237743f020518162c62b93cb7107a2b5eb ]
+
+It's possible to trigger use-after-free here by:
+
+  (a) forcing rescan_work_func() to take a long time and
+  (b) utilizing a pwrctrl driver that may be unloaded for some reason
+
+Cancel outstanding work to ensure it is finished before we allow our data
+structures to be cleaned up.
+
+[bhelgaas: tidy commit log]
+Fixes: 8f62819aaace ("PCI/pwrctl: Rescan bus on a separate thread")
+Signed-off-by: Brian Norris <briannorris@google.com>
+Signed-off-by: Brian Norris <briannorris@chromium.org>
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Acked-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Cc: Konrad Dybcio <konradybcio@kernel.org>
+Link: https://patch.msgid.link/20250409115313.1.Ia319526ed4ef06bec3180378c9a008340cec9658@changeid
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pwrctrl/core.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/pci/pwrctrl/core.c b/drivers/pci/pwrctrl/core.c
+index 9cc7e2b7f2b56..6bdbfed584d6d 100644
+--- a/drivers/pci/pwrctrl/core.c
++++ b/drivers/pci/pwrctrl/core.c
+@@ -101,6 +101,8 @@ EXPORT_SYMBOL_GPL(pci_pwrctrl_device_set_ready);
+  */
+ void pci_pwrctrl_device_unset_ready(struct pci_pwrctrl *pwrctrl)
+ {
++      cancel_work_sync(&pwrctrl->work);
++
+       /*
+        * We don't have to delete the link here. Typically, this function
+        * is only called when the power control device is being detached. If
+-- 
+2.39.5
+
diff --git a/queue-6.15/pci-rcar-gen4-set-ep-bar4-fixed-size.patch b/queue-6.15/pci-rcar-gen4-set-ep-bar4-fixed-size.patch
new file mode 100644 (file)
index 0000000..733d128
--- /dev/null
@@ -0,0 +1,37 @@
+From 4a518f55951cb3b76cf138f8f0d6fb2aead342dc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Mar 2025 15:30:44 +0100
+Subject: PCI: rcar-gen4: set ep BAR4 fixed size
+
+From: Jerome Brunet <jbrunet@baylibre.com>
+
+[ Upstream commit b584ab12d59f646b9254b2b16ff197d612fd4935 ]
+
+On rcar-gen4, the ep BAR4 has a fixed size of 256B. Document this
+constraint in the epc features of the platform.
+
+Fixes: e311b3834dfa ("PCI: rcar-gen4: Add endpoint mode support")
+Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://patch.msgid.link/20250328-rcar-gen4-bar4-v1-1-10bb6ce9ee7f@baylibre.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pcie-rcar-gen4.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
+index fc872dd35029c..02638ec442e70 100644
+--- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
++++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
+@@ -403,6 +403,7 @@ static const struct pci_epc_features rcar_gen4_pcie_epc_features = {
+       .msix_capable = false,
+       .bar[BAR_1] = { .type = BAR_RESERVED, },
+       .bar[BAR_3] = { .type = BAR_RESERVED, },
++      .bar[BAR_4] = { .type = BAR_FIXED, .fixed_size = 256 },
+       .bar[BAR_5] = { .type = BAR_RESERVED, },
+       .align = SZ_1M,
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.15/pci-rockchip-fix-order-of-rockchip_pci_core_rsts.patch b/queue-6.15/pci-rockchip-fix-order-of-rockchip_pci_core_rsts.patch
new file mode 100644 (file)
index 0000000..989b540
--- /dev/null
@@ -0,0 +1,55 @@
+From afbe305e70ba2ce89ef4347e66676371a9a51ae7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Mar 2025 18:58:22 +0800
+Subject: PCI: rockchip: Fix order of rockchip_pci_core_rsts
+
+From: Jensen Huang <jensenhuang@friendlyarm.com>
+
+[ Upstream commit c7540e5423d7f588c7210a9941ceb6a836963ccc ]
+
+The order of rockchip_pci_core_rsts introduced in the offending commit
+followed the previous comment that warned not to reorder them. But the
+commit failed to take into account that reset_control_bulk_deassert()
+deasserts the resets in reverse order. So this leads to the link getting
+downgraded to 2.5 GT/s.
+
+Hence, restore the deassert order and also add back the comments for
+rockchip_pci_core_rsts.
+
+Tested on NanoPC-T4 with Samsung 970 Pro.
+
+Fixes: 18715931a5c0 ("PCI: rockchip: Simplify reset control handling by using reset_control_bulk*() function")
+Signed-off-by: Jensen Huang <jensenhuang@friendlyarm.com>
+[mani: reworded the commit message and the comment above rockchip_pci_core_rsts]
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Acked-by: Shawn Lin <shawn.lin@rock-chips.com>
+Link: https://patch.msgid.link/20250328105822.3946767-1-jensenhuang@friendlyarm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/pcie-rockchip.h | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/pci/controller/pcie-rockchip.h b/drivers/pci/controller/pcie-rockchip.h
+index 14954f43e5e9a..5864a20323f21 100644
+--- a/drivers/pci/controller/pcie-rockchip.h
++++ b/drivers/pci/controller/pcie-rockchip.h
+@@ -319,11 +319,12 @@ static const char * const rockchip_pci_pm_rsts[] = {
+       "aclk",
+ };
++/* NOTE: Do not reorder the deassert sequence of the following reset pins */
+ static const char * const rockchip_pci_core_rsts[] = {
+-      "mgmt-sticky",
+-      "core",
+-      "mgmt",
+       "pipe",
++      "mgmt",
++      "core",
++      "mgmt-sticky",
+ };
+ struct rockchip_pcie {
+-- 
+2.39.5
+
diff --git a/queue-6.15/perf-amlogic-replace-smp_processor_id-with-raw_smp_p.patch b/queue-6.15/perf-amlogic-replace-smp_processor_id-with-raw_smp_p.patch
new file mode 100644 (file)
index 0000000..6221897
--- /dev/null
@@ -0,0 +1,80 @@
+From ae3264049b393a9fde9dc9cbb62bc688108c2184 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Apr 2025 12:02:03 +0530
+Subject: perf/amlogic: Replace smp_processor_id() with raw_smp_processor_id()
+ in meson_ddr_pmu_create()
+
+From: Anand Moon <linux.amoon@gmail.com>
+
+[ Upstream commit 097469a2b0f12b91b4f27b9e9e4f2c46484cde30 ]
+
+The Amlogic DDR PMU driver meson_ddr_pmu_create() function incorrectly uses
+smp_processor_id(), which assumes disabled preemption. This leads to kernel
+warnings during module loading because meson_ddr_pmu_create() can be called
+in a preemptible context.
+
+Following kernel warning and stack trace:
+[   31.745138] [   T2289] BUG: using smp_processor_id() in preemptible [00000000] code: (udev-worker)/2289
+[   31.745154] [   T2289] caller is debug_smp_processor_id+0x28/0x38
+[   31.745172] [   T2289] CPU: 4 UID: 0 PID: 2289 Comm: (udev-worker) Tainted: GW 6.14.0-0-MANJARO-ARM #1 59519addcbca6ba8de735e151fd7b9e97aac7ff0
+[   31.745181] [   T2289] Tainted: [W]=WARN
+[   31.745183] [   T2289] Hardware name: Hardkernel ODROID-N2Plus (DT)
+[   31.745188] [   T2289] Call trace:
+[   31.745191] [   T2289]  show_stack+0x28/0x40 (C)
+[   31.745199] [   T2289]  dump_stack_lvl+0x4c/0x198
+[   31.745205] [   T2289]  dump_stack+0x20/0x50
+[   31.745209] [   T2289]  check_preemption_disabled+0xec/0xf0
+[   31.745213] [   T2289]  debug_smp_processor_id+0x28/0x38
+[   31.745216] [   T2289]  meson_ddr_pmu_create+0x200/0x560 [meson_ddr_pmu_g12 8095101c49676ad138d9961e3eddaee10acca7bd]
+[   31.745237] [   T2289]  g12_ddr_pmu_probe+0x20/0x38 [meson_ddr_pmu_g12 8095101c49676ad138d9961e3eddaee10acca7bd]
+[   31.745246] [   T2289]  platform_probe+0x98/0xe0
+[   31.745254] [   T2289]  really_probe+0x144/0x3f8
+[   31.745258] [   T2289]  __driver_probe_device+0xb8/0x180
+[   31.745261] [   T2289]  driver_probe_device+0x54/0x268
+[   31.745264] [   T2289]  __driver_attach+0x11c/0x288
+[   31.745267] [   T2289]  bus_for_each_dev+0xfc/0x160
+[   31.745274] [   T2289]  driver_attach+0x34/0x50
+[   31.745277] [   T2289]  bus_add_driver+0x160/0x2b0
+[   31.745281] [   T2289]  driver_register+0x78/0x120
+[   31.745285] [   T2289]  __platform_driver_register+0x30/0x48
+[   31.745288] [   T2289]  init_module+0x30/0xfe0 [meson_ddr_pmu_g12 8095101c49676ad138d9961e3eddaee10acca7bd]
+[   31.745298] [   T2289]  do_one_initcall+0x11c/0x438
+[   31.745303] [   T2289]  do_init_module+0x68/0x228
+[   31.745311] [   T2289]  load_module+0x118c/0x13a8
+[   31.745315] [   T2289]  __arm64_sys_finit_module+0x274/0x390
+[   31.745320] [   T2289]  invoke_syscall+0x74/0x108
+[   31.745326] [   T2289]  el0_svc_common+0x90/0xf8
+[   31.745330] [   T2289]  do_el0_svc+0x2c/0x48
+[   31.745333] [   T2289]  el0_svc+0x60/0x150
+[   31.745337] [   T2289]  el0t_64_sync_handler+0x80/0x118
+[   31.745341] [   T2289]  el0t_64_sync+0x1b8/0x1c0
+
+Changes replaces smp_processor_id() with raw_smp_processor_id() to
+ensure safe CPU ID retrieval in preemptible contexts.
+
+Cc: Jiucheng Xu <jiucheng.xu@amlogic.com>
+Fixes: 2016e2113d35 ("perf/amlogic: Add support for Amlogic meson G12 SoC DDR PMU driver")
+Signed-off-by: Anand Moon <linux.amoon@gmail.com>
+Link: https://lore.kernel.org/r/20250407063206.5211-1-linux.amoon@gmail.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/perf/amlogic/meson_ddr_pmu_core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/perf/amlogic/meson_ddr_pmu_core.c b/drivers/perf/amlogic/meson_ddr_pmu_core.c
+index 07446d784a1a6..c1e755c356a33 100644
+--- a/drivers/perf/amlogic/meson_ddr_pmu_core.c
++++ b/drivers/perf/amlogic/meson_ddr_pmu_core.c
+@@ -511,7 +511,7 @@ int meson_ddr_pmu_create(struct platform_device *pdev)
+       fmt_attr_fill(pmu->info.hw_info->fmt_attr);
+-      pmu->cpu = smp_processor_id();
++      pmu->cpu = raw_smp_processor_id();
+       name = devm_kasprintf(&pdev->dev, GFP_KERNEL, DDR_PERF_DEV_NAME);
+       if (!name)
+-- 
+2.39.5
+
diff --git a/queue-6.15/perf-arm-ni-fix-missing-platform_set_drvdata.patch b/queue-6.15/perf-arm-ni-fix-missing-platform_set_drvdata.patch
new file mode 100644 (file)
index 0000000..6b60897
--- /dev/null
@@ -0,0 +1,37 @@
+From 8ab101a4c1e107991a96318c15f5ba2e3e500769 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 13:42:48 +0800
+Subject: perf: arm-ni: Fix missing platform_set_drvdata()
+
+From: Hongbo Yao <andy.xu@hj-micro.com>
+
+[ Upstream commit fc5106088d6db75df61308ef6de314d1f7959646 ]
+
+Add missing platform_set_drvdata in arm_ni_probe(), otherwise
+calling platform_get_drvdata() in remove returns NULL.
+
+Fixes: 4d5a7680f2b4 ("perf: Add driver for Arm NI-700 interconnect PMU")
+Signed-off-by: Hongbo Yao <andy.xu@hj-micro.com>
+Reviewed-by: Robin Murphy <robin.murphy@arm.com>
+Link: https://lore.kernel.org/r/20250401054248.3985814-1-andy.xu@hj-micro.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/perf/arm-ni.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/perf/arm-ni.c b/drivers/perf/arm-ni.c
+index 0c418a7ee10f3..de7b6cce4d68a 100644
+--- a/drivers/perf/arm-ni.c
++++ b/drivers/perf/arm-ni.c
+@@ -660,6 +660,7 @@ static int arm_ni_probe(struct platform_device *pdev)
+       ni->num_cds = num_cds;
+       ni->part = part;
+       ni->id = atomic_fetch_inc(&id);
++      platform_set_drvdata(pdev, ni);
+       for (int v = 0; v < cfg.num_components; v++) {
+               reg = readl_relaxed(cfg.base + NI_CHILD_PTR(v));
+-- 
+2.39.5
+
diff --git a/queue-6.15/perf-arm-ni-unregister-pmus-on-probe-failure.patch b/queue-6.15/perf-arm-ni-unregister-pmus-on-probe-failure.patch
new file mode 100644 (file)
index 0000000..96fb3ab
--- /dev/null
@@ -0,0 +1,119 @@
+From 3e33206b05bb03644e394e1ad73a84c5c0d2ea44 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Apr 2025 15:09:18 +0800
+Subject: perf: arm-ni: Unregister PMUs on probe failure
+
+From: Hongbo Yao <andy.xu@hj-micro.com>
+
+[ Upstream commit 7f57afde6a44d9e044885e1125034edd4fda02e8 ]
+
+When a resource allocation fails in one clock domain of an NI device,
+we need to properly roll back all previously registered perf PMUs in
+other clock domains of the same device.
+
+Otherwise, it can lead to kernel panics.
+
+Calling arm_ni_init+0x0/0xff8 [arm_ni] @ 2374
+arm-ni ARMHCB70:00: Failed to request PMU region 0x1f3c13000
+arm-ni ARMHCB70:00: probe with driver arm-ni failed with error -16
+list_add corruption: next->prev should be prev (fffffd01e9698a18),
+but was 0000000000000000. (next=ffff10001a0decc8).
+pstate: 6340009 (nZCv daif +PAN -UAO +TCO +DIT -SSBS BTYPE=--)
+pc : list_add_valid_or_report+0x7c/0xb8
+lr : list_add_valid_or_report+0x7c/0xb8
+Call trace:
+ __list_add_valid_or_report+0x7c/0xb8
+ perf_pmu_register+0x22c/0x3a0
+ arm_ni_probe+0x554/0x70c [arm_ni]
+ platform_probe+0x70/0xe8
+ really_probe+0xc6/0x4d8
+ driver_probe_device+0x48/0x170
+ __driver_attach+0x8e/0x1c0
+ bus_for_each_dev+0x64/0xf0
+ driver_add+0x138/0x260
+ bus_add_driver+0x68/0x138
+ __platform_driver_register+0x2c/0x40
+ arm_ni_init+0x14/0x2a [arm_ni]
+ do_init_module+0x36/0x298
+---[ end trace 0000000000000000 ]---
+Kernel panic - not syncing: Oops - BUG: Fatal exception
+SMP: stopping secondary CPUs
+
+Fixes: 4d5a7680f2b4 ("perf: Add driver for Arm NI-700 interconnect PMU")
+Signed-off-by: Hongbo Yao <andy.xu@hj-micro.com>
+Reviewed-by: Robin Murphy <robin.murphy@arm.com>
+Link: https://lore.kernel.org/r/20250403070918.4153839-1-andy.xu@hj-micro.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/perf/arm-ni.c | 39 +++++++++++++++++++++------------------
+ 1 file changed, 21 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/perf/arm-ni.c b/drivers/perf/arm-ni.c
+index fd7a5e60e9630..0c418a7ee10f3 100644
+--- a/drivers/perf/arm-ni.c
++++ b/drivers/perf/arm-ni.c
+@@ -575,6 +575,23 @@ static int arm_ni_init_cd(struct arm_ni *ni, struct arm_ni_node *node, u64 res_s
+       return err;
+ }
++static void arm_ni_remove(struct platform_device *pdev)
++{
++      struct arm_ni *ni = platform_get_drvdata(pdev);
++
++      for (int i = 0; i < ni->num_cds; i++) {
++              struct arm_ni_cd *cd = ni->cds + i;
++
++              if (!cd->pmu_base)
++                      continue;
++
++              writel_relaxed(0, cd->pmu_base + NI_PMCR);
++              writel_relaxed(U32_MAX, cd->pmu_base + NI_PMINTENCLR);
++              perf_pmu_unregister(&cd->pmu);
++              cpuhp_state_remove_instance_nocalls(arm_ni_hp_state, &cd->cpuhp_node);
++      }
++}
++
+ static void arm_ni_probe_domain(void __iomem *base, struct arm_ni_node *node)
+ {
+       u32 reg = readl_relaxed(base + NI_NODE_TYPE);
+@@ -656,8 +673,11 @@ static int arm_ni_probe(struct platform_device *pdev)
+                               reg = readl_relaxed(pd.base + NI_CHILD_PTR(c));
+                               arm_ni_probe_domain(base + reg, &cd);
+                               ret = arm_ni_init_cd(ni, &cd, res->start);
+-                              if (ret)
++                              if (ret) {
++                                      ni->cds[cd.id].pmu_base = NULL;
++                                      arm_ni_remove(pdev);
+                                       return ret;
++                              }
+                       }
+               }
+       }
+@@ -665,23 +685,6 @@ static int arm_ni_probe(struct platform_device *pdev)
+       return 0;
+ }
+-static void arm_ni_remove(struct platform_device *pdev)
+-{
+-      struct arm_ni *ni = platform_get_drvdata(pdev);
+-
+-      for (int i = 0; i < ni->num_cds; i++) {
+-              struct arm_ni_cd *cd = ni->cds + i;
+-
+-              if (!cd->pmu_base)
+-                      continue;
+-
+-              writel_relaxed(0, cd->pmu_base + NI_PMCR);
+-              writel_relaxed(U32_MAX, cd->pmu_base + NI_PMINTENCLR);
+-              perf_pmu_unregister(&cd->pmu);
+-              cpuhp_state_remove_instance_nocalls(arm_ni_hp_state, &cd->cpuhp_node);
+-      }
+-}
+-
+ #ifdef CONFIG_OF
+ static const struct of_device_id arm_ni_of_match[] = {
+       { .compatible = "arm,ni-700" },
+-- 
+2.39.5
+
diff --git a/queue-6.15/perf-build-warn-when-libdebuginfod-devel-files-are-n.patch b/queue-6.15/perf-build-warn-when-libdebuginfod-devel-files-are-n.patch
new file mode 100644 (file)
index 0000000..aa7d362
--- /dev/null
@@ -0,0 +1,111 @@
+From 32c94a589c18d101125f369f55bdbcd889fb08e5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Apr 2025 11:37:20 -0300
+Subject: perf build: Warn when libdebuginfod devel files are not available
+
+From: Arnaldo Carvalho de Melo <acme@redhat.com>
+
+[ Upstream commit 4fce4b91fd1aabb326c46e237eb4b19ab72598f8 ]
+
+While working on 'perf version --build-options' I noticed that:
+
+  $ perf version --build-options
+  perf version 6.15.rc1.g312a07a00d31
+                   aio: [ on  ]  # HAVE_AIO_SUPPORT
+                   bpf: [ on  ]  # HAVE_LIBBPF_SUPPORT
+         bpf_skeletons: [ on  ]  # HAVE_BPF_SKEL
+            debuginfod: [ OFF ]  # HAVE_DEBUGINFOD_SUPPORT
+  <SNIP>
+
+And looking at tools/perf/Makefile.config I also noticed that it is not
+opt-in, meaning we will attempt to build with it in all normal cases.
+
+So add the usual warning at build time to let the user know that
+something recommended is missing, now we see:
+
+  Makefile.config:563: No elfutils/debuginfod.h found, no debuginfo server support, please install elfutils-debuginfod-client-devel or equivalent
+
+And after following the recommendation:
+
+  $ perf check feature debuginfod
+            debuginfod: [ on  ]  # HAVE_DEBUGINFOD_SUPPORT
+  $ ldd ~/bin/perf | grep debuginfo
+       libdebuginfod.so.1 => /lib64/libdebuginfod.so.1 (0x00007fee5cf5f000)
+  $
+
+With this feature on several perf tools will fetch what is needed and
+not require all the contents of the debuginfo packages, for instance:
+
+  # rpm -qa | grep kernel-debuginfo
+  # pahole --running_kernel_vmlinux
+  pahole: couldn't find a vmlinux that matches the running kernel
+  HINT: Maybe you're inside a container or missing a debuginfo package?
+  #
+  # perf trace -e open* perf probe --vars icmp_rcv
+      0.000 ( 0.005 ms): perf/97391 openat(dfd: CWD, filename: "/etc/ld.so.cache", flags: RDONLY|CLOEXEC) = 3
+      0.014 ( 0.004 ms): perf/97391 openat(dfd: CWD, filename: "/lib64/libm.so.6", flags: RDONLY|CLOEXEC) = 3
+  <SNIP>
+  32130.100 ( 0.008 ms): perf/97391 openat(dfd: CWD, filename: "/root/.cache/debuginfod_client/aa3c82b4a13f9c0e0301bebb20fe958c4db6f362/debuginfo") = 3
+  <SNIP>
+  Available variables at icmp_rcv
+        @<icmp_rcv+0>
+                struct sk_buff* skb
+  <SNIP>
+  #
+  # pahole --running_kernel_vmlinux
+  /root/.cache/debuginfod_client/aa3c82b4a13f9c0e0301bebb20fe958c4db6f362/debuginfo
+  # file /root/.cache/debuginfod_client/aa3c82b4a13f9c0e0301bebb20fe958c4db6f362/debuginfo
+  /root/.cache/debuginfod_client/aa3c82b4a13f9c0e0301bebb20fe958c4db6f362/debuginfo: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=aa3c82b4a13f9c0e0301bebb20fe958c4db6f362, with debug_info, not stripped
+  # ls -la /root/.cache/debuginfod_client/aa3c82b4a13f9c0e0301bebb20fe958c4db6f362/debuginfo
+  -r--------. 1 root root 475401512 Mar 27 21:00 /root/.cache/debuginfod_client/aa3c82b4a13f9c0e0301bebb20fe958c4db6f362/debuginfo
+  #
+
+Then, cached:
+
+  # perf stat --null perf probe --vars icmp_rcv
+  Available variables at icmp_rcv
+        @<icmp_rcv+0>
+                struct sk_buff* skb
+
+   Performance counter stats for 'perf probe --vars icmp_rcv':
+
+       0.671389041 seconds time elapsed
+
+       0.519176000 seconds user
+       0.150860000 seconds sys
+
+Fixes: c7a14fdcb3fa7736 ("perf build-ids: Fall back to debuginfod query if debuginfo not found")
+Tested-by: Ingo Molnar <mingo@kernel.org>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Dmitriy Vyukov <dvyukov@google.com>
+Cc: Howard Chu <howardchu95@gmail.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Frank Ch. Eigler <fche@redhat.com>
+Link: https://lore.kernel.org/r/Z_dkNDj9EPFwPqq1@gmail.com
+[ Folded patch from Ingo to have the debian/ubuntu devel package added build warning message ]
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/Makefile.config | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
+index e0c20a5c19cfe..d1ea7bf449647 100644
+--- a/tools/perf/Makefile.config
++++ b/tools/perf/Makefile.config
+@@ -560,6 +560,8 @@ ifndef NO_LIBELF
+     ifeq ($(feature-libdebuginfod), 1)
+       CFLAGS += -DHAVE_DEBUGINFOD_SUPPORT
+       EXTLIBS += -ldebuginfod
++    else
++      $(warning No elfutils/debuginfod.h found, no debuginfo server support, please install libdebuginfod-dev/elfutils-debuginfod-client-devel or equivalent)
+     endif
+   endif
+-- 
+2.39.5
+
diff --git a/queue-6.15/perf-callchain-always-populate-the-addr_location-map.patch b/queue-6.15/perf-callchain-always-populate-the-addr_location-map.patch
new file mode 100644 (file)
index 0000000..25f5041
--- /dev/null
@@ -0,0 +1,147 @@
+From 27a0786919b06b2c3e600d6e5b75f37bad8e0331 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 May 2025 21:39:37 -0700
+Subject: perf callchain: Always populate the addr_location map when adding IP
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit a913ef6fd883c05bd6538ed21ee1e773f0d750b7 ]
+
+Dropping symbols also meant the callchain maps wasn't populated, but
+the callchain map is needed to find the DSO.
+
+Plumb the symbols option better, falling back to thread__find_map()
+rather than thread__find_symbol() when symbols are disabled.
+
+Fixes: 02b2705017d2e5ad ("perf callchain: Allow symbols to be optional when resolving a callchain")
+Signed-off-by: Ian Rogers <irogers@google.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: Athira Rajeev <atrajeev@linux.ibm.com>
+Cc: Ben Gainey <ben.gainey@arm.com>
+Cc: Chaitanya S Prakash <chaitanyas.prakash@arm.com>
+Cc: Charlie Jenkins <charlie@rivosinc.com>
+Cc: Chun-Tse Shao <ctshao@google.com>
+Cc: Colin Ian King <colin.i.king@gmail.com>
+Cc: Dmitriy Vyukov <dvyukov@google.com>
+Cc: Dr. David Alan Gilbert <linux@treblig.org>
+Cc: Graham Woodward <graham.woodward@arm.com>
+Cc: Howard Chu <howardchu95@gmail.com>
+Cc: Ilkka Koskinen <ilkka@os.amperecomputing.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: James Clark <james.clark@linaro.org>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: John Garry <john.g.garry@oracle.com>
+Cc: Kajol Jain <kjain@linux.ibm.com>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Krzysztof Łopatowski <krzysztof.m.lopatowski@gmail.com>
+Cc: Leo Yan <leo.yan@linux.dev>
+Cc: Levi Yun <yeoreum.yun@arm.com>
+Cc: Li Huafei <lihuafei1@huawei.com>
+Cc: linux-arm-kernel@lists.infradead.org
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Martin Liška <martin.liska@hey.com>
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Matt Fleming <matt@readmodwrite.com>
+Cc: Mike Leach <mike.leach@linaro.org>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Ravi Bangoria <ravi.bangoria@amd.com>
+Cc: Song Liu <song@kernel.org>
+Cc: Steinar H. Gunderson <sesse@google.com>
+Cc: Stephen Brennan <stephen.s.brennan@oracle.com>
+Cc: Steve Clevenger <scclevenger@os.amperecomputing.com>
+Cc: Thomas Falcon <thomas.falcon@intel.com>
+Cc: Veronika Molnarova <vmolnaro@redhat.com>
+Cc: Weilin Wang <weilin.wang@intel.com>
+Cc: Will Deacon <will@kernel.org>
+Cc: Yicong Yang <yangyicong@hisilicon.com>
+Cc: Yujie Liu <yujie.liu@intel.com>
+Cc: Zhongqiu Han <quic_zhonhan@quicinc.com>
+Cc: Zixian Cai <fzczx123@gmail.com>
+Link: https://lore.kernel.org/r/20250529044000.759937-2-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/machine.c | 6 ++++--
+ tools/perf/util/thread.c  | 8 ++++++--
+ tools/perf/util/thread.h  | 2 +-
+ 3 files changed, 11 insertions(+), 5 deletions(-)
+
+diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
+index 2531b373f2cf7..b048165b10c14 100644
+--- a/tools/perf/util/machine.c
++++ b/tools/perf/util/machine.c
+@@ -1976,7 +1976,7 @@ static void ip__resolve_ams(struct thread *thread,
+        * Thus, we have to try consecutively until we find a match
+        * or else, the symbol is unknown
+        */
+-      thread__find_cpumode_addr_location(thread, ip, &al);
++      thread__find_cpumode_addr_location(thread, ip, /*symbols=*/true, &al);
+       ams->addr = ip;
+       ams->al_addr = al.addr;
+@@ -2078,7 +2078,7 @@ static int add_callchain_ip(struct thread *thread,
+       al.sym = NULL;
+       al.srcline = NULL;
+       if (!cpumode) {
+-              thread__find_cpumode_addr_location(thread, ip, &al);
++              thread__find_cpumode_addr_location(thread, ip, symbols, &al);
+       } else {
+               if (ip >= PERF_CONTEXT_MAX) {
+                       switch (ip) {
+@@ -2106,6 +2106,8 @@ static int add_callchain_ip(struct thread *thread,
+               }
+               if (symbols)
+                       thread__find_symbol(thread, *cpumode, ip, &al);
++              else
++                      thread__find_map(thread, *cpumode, ip, &al);
+       }
+       if (al.sym != NULL) {
+diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
+index 89585f53c1d5c..10a01f8fbd400 100644
+--- a/tools/perf/util/thread.c
++++ b/tools/perf/util/thread.c
+@@ -410,7 +410,7 @@ int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp, bo
+ }
+ void thread__find_cpumode_addr_location(struct thread *thread, u64 addr,
+-                                      struct addr_location *al)
++                                      bool symbols, struct addr_location *al)
+ {
+       size_t i;
+       const u8 cpumodes[] = {
+@@ -421,7 +421,11 @@ void thread__find_cpumode_addr_location(struct thread *thread, u64 addr,
+       };
+       for (i = 0; i < ARRAY_SIZE(cpumodes); i++) {
+-              thread__find_symbol(thread, cpumodes[i], addr, al);
++              if (symbols)
++                      thread__find_symbol(thread, cpumodes[i], addr, al);
++              else
++                      thread__find_map(thread, cpumodes[i], addr, al);
++
+               if (al->map)
+                       break;
+       }
+diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
+index cd574a896418a..2b90bbed7a612 100644
+--- a/tools/perf/util/thread.h
++++ b/tools/perf/util/thread.h
+@@ -126,7 +126,7 @@ struct symbol *thread__find_symbol_fb(struct thread *thread, u8 cpumode,
+                                     u64 addr, struct addr_location *al);
+ void thread__find_cpumode_addr_location(struct thread *thread, u64 addr,
+-                                      struct addr_location *al);
++                                      bool symbols, struct addr_location *al);
+ int thread__memcpy(struct thread *thread, struct machine *machine,
+                  void *buf, u64 ip, int len, bool *is64bit);
+-- 
+2.39.5
+
diff --git a/queue-6.15/perf-core-fix-broken-throttling-when-max_samples_per.patch b/queue-6.15/perf-core-fix-broken-throttling-when-max_samples_per.patch
new file mode 100644 (file)
index 0000000..9be3dab
--- /dev/null
@@ -0,0 +1,64 @@
+From baf2e731396087e685df4e3cbd4161dcb46405a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 5 Apr 2025 22:16:35 +0800
+Subject: perf/core: Fix broken throttling when max_samples_per_tick=1
+
+From: Qing Wang <wangqing7171@gmail.com>
+
+[ Upstream commit f51972e6f8b9a737b2b3eb588069acb538fa72de ]
+
+According to the throttling mechanism, the pmu interrupts number can not
+exceed the max_samples_per_tick in one tick. But this mechanism is
+ineffective when max_samples_per_tick=1, because the throttling check is
+skipped during the first interrupt and only performed when the second
+interrupt arrives.
+
+Perhaps this bug may cause little influence in one tick, but if in a
+larger time scale, the problem can not be underestimated.
+
+When max_samples_per_tick = 1:
+Allowed-interrupts-per-second max-samples-per-second  default-HZ  ARCH
+200                           100                     100         X86
+500                           250                     250         ARM64
+...
+Obviously, the pmu interrupt number far exceed the user's expect.
+
+Fixes: e050e3f0a71b ("perf: Fix broken interrupt rate throttling")
+Signed-off-by: Qing Wang <wangqing7171@gmail.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/20250405141635.243786-3-wangqing7171@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/events/core.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index 95e703891b24f..881d768e45564 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -10029,14 +10029,14 @@ __perf_event_account_interrupt(struct perf_event *event, int throttle)
+               hwc->interrupts = 1;
+       } else {
+               hwc->interrupts++;
+-              if (unlikely(throttle &&
+-                           hwc->interrupts > max_samples_per_tick)) {
+-                      __this_cpu_inc(perf_throttled_count);
+-                      tick_dep_set_cpu(smp_processor_id(), TICK_DEP_BIT_PERF_EVENTS);
+-                      hwc->interrupts = MAX_INTERRUPTS;
+-                      perf_log_throttle(event, 0);
+-                      ret = 1;
+-              }
++      }
++
++      if (unlikely(throttle && hwc->interrupts >= max_samples_per_tick)) {
++              __this_cpu_inc(perf_throttled_count);
++              tick_dep_set_cpu(smp_processor_id(), TICK_DEP_BIT_PERF_EVENTS);
++              hwc->interrupts = MAX_INTERRUPTS;
++              perf_log_throttle(event, 0);
++              ret = 1;
+       }
+       if (event->attr.freq) {
+-- 
+2.39.5
+
diff --git a/queue-6.15/perf-intel-pt-fix-pebs-via-pt-data_src.patch b/queue-6.15/perf-intel-pt-fix-pebs-via-pt-data_src.patch
new file mode 100644 (file)
index 0000000..57ed295
--- /dev/null
@@ -0,0 +1,334 @@
+From 43e31134abf8432d01beca72f1bcfdd6876fd6fa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 May 2025 12:39:30 +0300
+Subject: perf intel-pt: Fix PEBS-via-PT data_src
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+[ Upstream commit e00eac6b5b6d956f38d8880c44bf7fd9954063c3 ]
+
+The Fixes commit did not add support for decoding PEBS-via-PT data_src.
+Fix by adding support.
+
+PEBS-via-PT is a feature of some E-core processors, starting with
+processors based on Tremont microarchitecture. Because the kernel only
+supports Intel PT features that are on all processors, there is no support
+for PEBS-via-PT on hybrids.
+
+Currently that leaves processors based on Tremont, Gracemont and Crestmont,
+however there are no events on Tremont that produce data_src information,
+and for Gracemont and Crestmont there are only:
+
+       mem-loads       event=0xd0,umask=0x5,ldlat=3
+       mem-stores      event=0xd0,umask=0x6
+
+Affected processors include Alder Lake N (Gracemont), Sierra Forest
+(Crestmont) and Grand Ridge (Crestmont).
+
+Example:
+
+ # perf record -d -e intel_pt/branch=0/ -e mem-loads/aux-output/pp uname
+
+ Before:
+
+  # perf.before script --itrace=o -Fdata_src
+            0 |OP No|LVL N/A|SNP N/A|TLB N/A|LCK No|BLK  N/A
+            0 |OP No|LVL N/A|SNP N/A|TLB N/A|LCK No|BLK  N/A
+
+ After:
+
+  # perf script --itrace=o -Fdata_src
+  10268100142 |OP LOAD|LVL L1 hit|SNP None|TLB L1 or L2 hit|LCK No|BLK  N/A
+  10450100442 |OP LOAD|LVL L2 hit|SNP None|TLB L2 miss|LCK No|BLK  N/A
+
+Fixes: 975846eddf907297 ("perf intel-pt: Add memory information to synthesized PEBS sample")
+Reviewed-by: Kan Liang <kan.liang@linux.intel.com>
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Link: https://lore.kernel.org/r/20250512093932.79854-2-adrian.hunter@intel.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/intel-pt.c | 205 ++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 202 insertions(+), 3 deletions(-)
+
+diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c
+index 4e8a9b172fbcc..9b1011fe48267 100644
+--- a/tools/perf/util/intel-pt.c
++++ b/tools/perf/util/intel-pt.c
+@@ -127,6 +127,7 @@ struct intel_pt {
+       bool single_pebs;
+       bool sample_pebs;
++      int pebs_data_src_fmt;
+       struct evsel *pebs_evsel;
+       u64 evt_sample_type;
+@@ -175,6 +176,7 @@ enum switch_state {
+ struct intel_pt_pebs_event {
+       struct evsel *evsel;
+       u64 id;
++      int data_src_fmt;
+ };
+ struct intel_pt_queue {
+@@ -2272,7 +2274,146 @@ static void intel_pt_add_lbrs(struct branch_stack *br_stack,
+       }
+ }
+-static int intel_pt_do_synth_pebs_sample(struct intel_pt_queue *ptq, struct evsel *evsel, u64 id)
++#define P(a, b) PERF_MEM_S(a, b)
++#define OP_LH (P(OP, LOAD) | P(LVL, HIT))
++#define LEVEL(x) P(LVLNUM, x)
++#define REM P(REMOTE, REMOTE)
++#define SNOOP_NONE_MISS (P(SNOOP, NONE) | P(SNOOP, MISS))
++
++#define PERF_PEBS_DATA_SOURCE_GRT_MAX 0x10
++#define PERF_PEBS_DATA_SOURCE_GRT_MASK        (PERF_PEBS_DATA_SOURCE_GRT_MAX - 1)
++
++/* Based on kernel __intel_pmu_pebs_data_source_grt() and pebs_data_source */
++static const u64 pebs_data_source_grt[PERF_PEBS_DATA_SOURCE_GRT_MAX] = {
++      P(OP, LOAD) | P(LVL, MISS) | LEVEL(L3) | P(SNOOP, NA),         /* L3 miss|SNP N/A */
++      OP_LH | P(LVL, L1)  | LEVEL(L1)  | P(SNOOP, NONE),             /* L1 hit|SNP None */
++      OP_LH | P(LVL, LFB) | LEVEL(LFB) | P(SNOOP, NONE),             /* LFB/MAB hit|SNP None */
++      OP_LH | P(LVL, L2)  | LEVEL(L2)  | P(SNOOP, NONE),             /* L2 hit|SNP None */
++      OP_LH | P(LVL, L3)  | LEVEL(L3)  | P(SNOOP, NONE),             /* L3 hit|SNP None */
++      OP_LH | P(LVL, L3)  | LEVEL(L3)  | P(SNOOP, HIT),              /* L3 hit|SNP Hit */
++      OP_LH | P(LVL, L3)  | LEVEL(L3)  | P(SNOOP, HITM),             /* L3 hit|SNP HitM */
++      OP_LH | P(LVL, L3)  | LEVEL(L3)  | P(SNOOP, HITM),             /* L3 hit|SNP HitM */
++      OP_LH | P(LVL, L3)  | LEVEL(L3)  | P(SNOOPX, FWD),             /* L3 hit|SNP Fwd */
++      OP_LH | P(LVL, REM_CCE1) | REM | LEVEL(L3) | P(SNOOP, HITM),   /* Remote L3 hit|SNP HitM */
++      OP_LH | P(LVL, LOC_RAM)  | LEVEL(RAM) | P(SNOOP, HIT),         /* RAM hit|SNP Hit */
++      OP_LH | P(LVL, REM_RAM1) | REM | LEVEL(L3) | P(SNOOP, HIT),    /* Remote L3 hit|SNP Hit */
++      OP_LH | P(LVL, LOC_RAM)  | LEVEL(RAM) | SNOOP_NONE_MISS,       /* RAM hit|SNP None or Miss */
++      OP_LH | P(LVL, REM_RAM1) | LEVEL(RAM) | REM | SNOOP_NONE_MISS, /* Remote RAM hit|SNP None or Miss */
++      OP_LH | P(LVL, IO)  | LEVEL(NA) | P(SNOOP, NONE),              /* I/O hit|SNP None */
++      OP_LH | P(LVL, UNC) | LEVEL(NA) | P(SNOOP, NONE),              /* Uncached hit|SNP None */
++};
++
++/* Based on kernel __intel_pmu_pebs_data_source_cmt() and pebs_data_source */
++static const u64 pebs_data_source_cmt[PERF_PEBS_DATA_SOURCE_GRT_MAX] = {
++      P(OP, LOAD) | P(LVL, MISS) | LEVEL(L3) | P(SNOOP, NA),       /* L3 miss|SNP N/A */
++      OP_LH | P(LVL, L1)  | LEVEL(L1)  | P(SNOOP, NONE),           /* L1 hit|SNP None */
++      OP_LH | P(LVL, LFB) | LEVEL(LFB) | P(SNOOP, NONE),           /* LFB/MAB hit|SNP None */
++      OP_LH | P(LVL, L2)  | LEVEL(L2)  | P(SNOOP, NONE),           /* L2 hit|SNP None */
++      OP_LH | P(LVL, L3)  | LEVEL(L3)  | P(SNOOP, NONE),           /* L3 hit|SNP None */
++      OP_LH | P(LVL, L3)  | LEVEL(L3)  | P(SNOOP, MISS),           /* L3 hit|SNP Hit */
++      OP_LH | P(LVL, L3)  | LEVEL(L3)  | P(SNOOP, HIT),            /* L3 hit|SNP HitM */
++      OP_LH | P(LVL, L3)  | LEVEL(L3)  | P(SNOOPX, FWD),           /* L3 hit|SNP HitM */
++      OP_LH | P(LVL, L3)  | LEVEL(L3)  | P(SNOOP, HITM),           /* L3 hit|SNP Fwd */
++      OP_LH | P(LVL, REM_CCE1) | REM | LEVEL(L3) | P(SNOOP, HITM), /* Remote L3 hit|SNP HitM */
++      OP_LH | P(LVL, LOC_RAM)  | LEVEL(RAM) | P(SNOOP, NONE),      /* RAM hit|SNP Hit */
++      OP_LH | LEVEL(RAM) | REM | P(SNOOP, NONE),                   /* Remote L3 hit|SNP Hit */
++      OP_LH | LEVEL(RAM) | REM | P(SNOOPX, FWD),                   /* RAM hit|SNP None or Miss */
++      OP_LH | LEVEL(RAM) | REM | P(SNOOP, HITM),                   /* Remote RAM hit|SNP None or Miss */
++      OP_LH | P(LVL, IO)  | LEVEL(NA) | P(SNOOP, NONE),            /* I/O hit|SNP None */
++      OP_LH | P(LVL, UNC) | LEVEL(NA) | P(SNOOP, NONE),            /* Uncached hit|SNP None */
++};
++
++/* Based on kernel pebs_set_tlb_lock() */
++static inline void pebs_set_tlb_lock(u64 *val, bool tlb, bool lock)
++{
++      /*
++       * TLB access
++       * 0 = did not miss 2nd level TLB
++       * 1 = missed 2nd level TLB
++       */
++      if (tlb)
++              *val |= P(TLB, MISS) | P(TLB, L2);
++      else
++              *val |= P(TLB, HIT) | P(TLB, L1) | P(TLB, L2);
++
++      /* locked prefix */
++      if (lock)
++              *val |= P(LOCK, LOCKED);
++}
++
++/* Based on kernel __grt_latency_data() */
++static u64 intel_pt_grt_latency_data(u8 dse, bool tlb, bool lock, bool blk,
++                                   const u64 *pebs_data_source)
++{
++      u64 val;
++
++      dse &= PERF_PEBS_DATA_SOURCE_GRT_MASK;
++      val = pebs_data_source[dse];
++
++      pebs_set_tlb_lock(&val, tlb, lock);
++
++      if (blk)
++              val |= P(BLK, DATA);
++      else
++              val |= P(BLK, NA);
++
++      return val;
++}
++
++/* Default value for data source */
++#define PERF_MEM_NA (PERF_MEM_S(OP, NA)    |\
++                   PERF_MEM_S(LVL, NA)   |\
++                   PERF_MEM_S(SNOOP, NA) |\
++                   PERF_MEM_S(LOCK, NA)  |\
++                   PERF_MEM_S(TLB, NA)   |\
++                   PERF_MEM_S(LVLNUM, NA))
++
++enum DATA_SRC_FORMAT {
++      DATA_SRC_FORMAT_ERR  = -1,
++      DATA_SRC_FORMAT_NA   =  0,
++      DATA_SRC_FORMAT_GRT  =  1,
++      DATA_SRC_FORMAT_CMT  =  2,
++};
++
++/* Based on kernel grt_latency_data() and cmt_latency_data */
++static u64 intel_pt_get_data_src(u64 mem_aux_info, int data_src_fmt)
++{
++      switch (data_src_fmt) {
++      case DATA_SRC_FORMAT_GRT: {
++              union {
++                      u64 val;
++                      struct {
++                              unsigned int dse:4;
++                              unsigned int locked:1;
++                              unsigned int stlb_miss:1;
++                              unsigned int fwd_blk:1;
++                              unsigned int reserved:25;
++                      };
++              } x = {.val = mem_aux_info};
++              return intel_pt_grt_latency_data(x.dse, x.stlb_miss, x.locked, x.fwd_blk,
++                                               pebs_data_source_grt);
++      }
++      case DATA_SRC_FORMAT_CMT: {
++              union {
++                      u64 val;
++                      struct {
++                              unsigned int dse:5;
++                              unsigned int locked:1;
++                              unsigned int stlb_miss:1;
++                              unsigned int fwd_blk:1;
++                              unsigned int reserved:24;
++                      };
++              } x = {.val = mem_aux_info};
++              return intel_pt_grt_latency_data(x.dse, x.stlb_miss, x.locked, x.fwd_blk,
++                                               pebs_data_source_cmt);
++      }
++      default:
++              return PERF_MEM_NA;
++      }
++}
++
++static int intel_pt_do_synth_pebs_sample(struct intel_pt_queue *ptq, struct evsel *evsel,
++                                       u64 id, int data_src_fmt)
+ {
+       const struct intel_pt_blk_items *items = &ptq->state->items;
+       struct perf_sample sample;
+@@ -2393,6 +2534,18 @@ static int intel_pt_do_synth_pebs_sample(struct intel_pt_queue *ptq, struct evse
+               }
+       }
++      if (sample_type & PERF_SAMPLE_DATA_SRC) {
++              if (items->has_mem_aux_info && data_src_fmt) {
++                      if (data_src_fmt < 0) {
++                              pr_err("Intel PT missing data_src info\n");
++                              return -1;
++                      }
++                      sample.data_src = intel_pt_get_data_src(items->mem_aux_info, data_src_fmt);
++              } else {
++                      sample.data_src = PERF_MEM_NA;
++              }
++      }
++
+       if (sample_type & PERF_SAMPLE_TRANSACTION && items->has_tsx_aux_info) {
+               u64 ax = items->has_rax ? items->rax : 0;
+               /* Refer kernel's intel_hsw_transaction() */
+@@ -2413,9 +2566,10 @@ static int intel_pt_synth_single_pebs_sample(struct intel_pt_queue *ptq)
+ {
+       struct intel_pt *pt = ptq->pt;
+       struct evsel *evsel = pt->pebs_evsel;
++      int data_src_fmt = pt->pebs_data_src_fmt;
+       u64 id = evsel->core.id[0];
+-      return intel_pt_do_synth_pebs_sample(ptq, evsel, id);
++      return intel_pt_do_synth_pebs_sample(ptq, evsel, id, data_src_fmt);
+ }
+ static int intel_pt_synth_pebs_sample(struct intel_pt_queue *ptq)
+@@ -2440,7 +2594,7 @@ static int intel_pt_synth_pebs_sample(struct intel_pt_queue *ptq)
+                                      hw_id);
+                       return intel_pt_synth_single_pebs_sample(ptq);
+               }
+-              err = intel_pt_do_synth_pebs_sample(ptq, pe->evsel, pe->id);
++              err = intel_pt_do_synth_pebs_sample(ptq, pe->evsel, pe->id, pe->data_src_fmt);
+               if (err)
+                       return err;
+       }
+@@ -3407,6 +3561,49 @@ static int intel_pt_process_itrace_start(struct intel_pt *pt,
+                                       event->itrace_start.tid);
+ }
++/*
++ * Events with data_src are identified by L1_Hit_Indication
++ * refer https://github.com/intel/perfmon
++ */
++static int intel_pt_data_src_fmt(struct intel_pt *pt, struct evsel *evsel)
++{
++      struct perf_env *env = pt->machine->env;
++      int fmt = DATA_SRC_FORMAT_NA;
++
++      if (!env->cpuid)
++              return DATA_SRC_FORMAT_ERR;
++
++      /*
++       * PEBS-via-PT is only supported on E-core non-hybrid. Of those only
++       * Gracemont and Crestmont have data_src. Check for:
++       *      Alderlake N   (Gracemont)
++       *      Sierra Forest (Crestmont)
++       *      Grand Ridge   (Crestmont)
++       */
++
++      if (!strncmp(env->cpuid, "GenuineIntel,6,190,", 19))
++              fmt = DATA_SRC_FORMAT_GRT;
++
++      if (!strncmp(env->cpuid, "GenuineIntel,6,175,", 19) ||
++          !strncmp(env->cpuid, "GenuineIntel,6,182,", 19))
++              fmt = DATA_SRC_FORMAT_CMT;
++
++      if (fmt == DATA_SRC_FORMAT_NA)
++              return fmt;
++
++      /*
++       * Only data_src events are:
++       *      mem-loads       event=0xd0,umask=0x5
++       *      mem-stores      event=0xd0,umask=0x6
++       */
++      if (evsel->core.attr.type == PERF_TYPE_RAW &&
++          ((evsel->core.attr.config & 0xffff) == 0x5d0 ||
++           (evsel->core.attr.config & 0xffff) == 0x6d0))
++              return fmt;
++
++      return DATA_SRC_FORMAT_NA;
++}
++
+ static int intel_pt_process_aux_output_hw_id(struct intel_pt *pt,
+                                            union perf_event *event,
+                                            struct perf_sample *sample)
+@@ -3427,6 +3624,7 @@ static int intel_pt_process_aux_output_hw_id(struct intel_pt *pt,
+       ptq->pebs[hw_id].evsel = evsel;
+       ptq->pebs[hw_id].id = sample->id;
++      ptq->pebs[hw_id].data_src_fmt = intel_pt_data_src_fmt(pt, evsel);
+       return 0;
+ }
+@@ -3976,6 +4174,7 @@ static void intel_pt_setup_pebs_events(struct intel_pt *pt)
+                       }
+                       pt->single_pebs = true;
+                       pt->sample_pebs = true;
++                      pt->pebs_data_src_fmt = intel_pt_data_src_fmt(pt, evsel);
+                       pt->pebs_evsel = evsel;
+               }
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/perf-pmu-avoid-segv-for-missing-name-alias_name-in-w.patch b/queue-6.15/perf-pmu-avoid-segv-for-missing-name-alias_name-in-w.patch
new file mode 100644 (file)
index 0000000..cb5aa2a
--- /dev/null
@@ -0,0 +1,49 @@
+From b12f7a09b5593569439a88fda826bfae1112f481 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 May 2025 14:50:35 -0700
+Subject: perf pmu: Avoid segv for missing name/alias_name in wildcarding
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 2a2a7f5e7deffa363b438308812989ded126a48a ]
+
+The pmu name or alias_name fields may be NULL and should be skipped if
+so. This is done in all loops of perf_pmu___name_match except the
+final wildcard loop which was an oversight.
+
+Fixes: 63e287131cf0c59b ("perf pmu: Rename name matching for no suffix or wildcard variants")
+Signed-off-by: Ian Rogers <irogers@google.com>
+Acked-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: James Clark <james.clark@linaro.org>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20250527215035.187992-1-irogers@google.com
+[ Fixup the Fixes: tag to the right commit ]
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/pmu.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
+index b7ebac5ab1d11..e2e3969e12d36 100644
+--- a/tools/perf/util/pmu.c
++++ b/tools/perf/util/pmu.c
+@@ -2052,6 +2052,9 @@ static bool perf_pmu___name_match(const struct perf_pmu *pmu, const char *to_mat
+       for (size_t i = 0; i < ARRAY_SIZE(names); i++) {
+               const char *name = names[i];
++              if (!name)
++                      continue;
++
+               if (wildcard && perf_pmu__match_wildcard_uncore(name, to_match))
+                       return true;
+               if (!wildcard && perf_pmu__match_ignoring_suffix_uncore(name, to_match))
+-- 
+2.39.5
+
diff --git a/queue-6.15/perf-record-fix-incorrect-user-regs-comments.patch b/queue-6.15/perf-record-fix-incorrect-user-regs-comments.patch
new file mode 100644 (file)
index 0000000..bd37ad8
--- /dev/null
@@ -0,0 +1,46 @@
+From decc238969f1a62bb336533f964f6959bad68e98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Apr 2025 06:08:10 +0000
+Subject: perf record: Fix incorrect --user-regs comments
+
+From: Dapeng Mi <dapeng1.mi@linux.intel.com>
+
+[ Upstream commit a4a859eb6704a8aa46aa1cec5396c8d41383a26b ]
+
+The comment of "--user-regs" option is not correct, fix it.
+
+"on interrupt," -> "in user space,"
+
+Fixes: 84c417422798c897 ("perf record: Support direct --user-regs arguments")
+Reviewed-by: Ian Rogers <irogers@google.com>
+Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20250403060810.196028-1-dapeng1.mi@linux.intel.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-record.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
+index ba20bf7c011d7..d56273a0e241c 100644
+--- a/tools/perf/builtin-record.c
++++ b/tools/perf/builtin-record.c
+@@ -3480,7 +3480,7 @@ static struct option __record_options[] = {
+                   "sample selected machine registers on interrupt,"
+                   " use '-I?' to list register names", parse_intr_regs),
+       OPT_CALLBACK_OPTARG(0, "user-regs", &record.opts.sample_user_regs, NULL, "any register",
+-                  "sample selected machine registers on interrupt,"
++                  "sample selected machine registers in user space,"
+                   " use '--user-regs=?' to list register names", parse_user_regs),
+       OPT_BOOLEAN(0, "running-time", &record.opts.running_time,
+                   "Record running/enabled time of read (:S) events"),
+-- 
+2.39.5
+
diff --git a/queue-6.15/perf-scripts-python-exported-sql-viewer.py-fix-patte.patch b/queue-6.15/perf-scripts-python-exported-sql-viewer.py-fix-patte.patch
new file mode 100644 (file)
index 0000000..5f822e5
--- /dev/null
@@ -0,0 +1,53 @@
+From c96f125c4e15fa9463a0afc05d55f7794f492551 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 May 2025 12:39:32 +0300
+Subject: perf scripts python: exported-sql-viewer.py: Fix pattern matching
+ with Python 3
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+[ Upstream commit 17e548405a81665fd14cee960db7d093d1396400 ]
+
+The script allows the user to enter patterns to find symbols.
+
+The pattern matching characters are converted for use in SQL.
+
+For PostgreSQL the conversion involves using the Python maketrans()
+method which is slightly different in Python 3 compared with Python 2.
+
+Fix to work in Python 3.
+
+Fixes: beda0e725e5f06ac ("perf script python: Add Python3 support to exported-sql-viewer.py")
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Tony Jones <tonyj@suse.de>
+Link: https://lore.kernel.org/r/20250512093932.79854-4-adrian.hunter@intel.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/scripts/python/exported-sql-viewer.py | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/tools/perf/scripts/python/exported-sql-viewer.py b/tools/perf/scripts/python/exported-sql-viewer.py
+index 121cf61ba1b34..e0b2e7268ef68 100755
+--- a/tools/perf/scripts/python/exported-sql-viewer.py
++++ b/tools/perf/scripts/python/exported-sql-viewer.py
+@@ -680,7 +680,10 @@ class CallGraphModelBase(TreeModel):
+                               s = value.replace("%", "\\%")
+                               s = s.replace("_", "\\_")
+                               # Translate * and ? into SQL LIKE pattern characters % and _
+-                              trans = string.maketrans("*?", "%_")
++                              if sys.version_info[0] == 3:
++                                      trans = str.maketrans("*?", "%_")
++                              else:
++                                      trans = string.maketrans("*?", "%_")
+                               match = " LIKE '" + str(s).translate(trans) + "'"
+                       else:
+                               match = " GLOB '" + str(value) + "'"
+-- 
+2.39.5
+
diff --git a/queue-6.15/perf-symbol-fix-use-after-free-in-filename__read_bui.patch b/queue-6.15/perf-symbol-fix-use-after-free-in-filename__read_bui.patch
new file mode 100644 (file)
index 0000000..d69c0bd
--- /dev/null
@@ -0,0 +1,290 @@
+From 7df65b4fd136d22585d52034d2646f2111f5b115 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 May 2025 20:26:31 -0700
+Subject: perf symbol: Fix use-after-free in filename__read_build_id
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit fef8f648bb47726d96a5701fe31ed606268da73d ]
+
+The same buf is used for the program headers and reading notes. As the
+notes memory may be reallocated then this corrupts the memory pointed
+to by the phdr. Using the same buffer is in any case a logic
+error. Rather than deal with the duplicated code, introduce an elf32
+boolean and a union for either the elf32 or elf64 headers that are in
+use. Let the program headers have their own memory and grow the buffer
+for notes as necessary.
+
+Before `perf list -j` compiled with asan would crash with:
+```
+==4176189==ERROR: AddressSanitizer: heap-use-after-free on address 0x5160000070b8 at pc 0x555d3b15075b bp 0x7ffebb5a8090 sp 0x7ffebb5a8088
+READ of size 8 at 0x5160000070b8 thread T0
+    #0 0x555d3b15075a in filename__read_build_id tools/perf/util/symbol-minimal.c:212:25
+    #1 0x555d3ae43aff in filename__sprintf_build_id tools/perf/util/build-id.c:110:8
+...
+
+0x5160000070b8 is located 312 bytes inside of 560-byte region [0x516000006f80,0x5160000071b0)
+freed by thread T0 here:
+    #0 0x555d3ab21840 in realloc (perf+0x264840) (BuildId: 12dff2f6629f738e5012abdf0e90055518e70b5e)
+    #1 0x555d3b1506e7 in filename__read_build_id tools/perf/util/symbol-minimal.c:206:11
+...
+
+previously allocated by thread T0 here:
+    #0 0x555d3ab21423 in malloc (perf+0x264423) (BuildId: 12dff2f6629f738e5012abdf0e90055518e70b5e)
+    #1 0x555d3b1503a2 in filename__read_build_id tools/perf/util/symbol-minimal.c:182:9
+...
+```
+
+Note: this bug is long standing and not introduced by the other asan
+fix in commit fa9c4977fbfb ("perf symbol-minimal: Fix double free in
+filename__read_build_id").
+
+Fixes: b691f64360ecec49 ("perf symbols: Implement poor man's ELF parser")
+Signed-off-by: Ian Rogers <irogers@google.com>
+Link: https://lore.kernel.org/r/20250528032637.198960-2-irogers@google.com
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Gary Guo <gary@garyguo.net>
+Cc: Alex Gaynor <alex.gaynor@gmail.com>
+Cc: Boqun Feng <boqun.feng@gmail.com>
+Cc: Howard Chu <howardchu95@gmail.com>
+Cc: Alice Ryhl <aliceryhl@google.com>
+Cc: Dmitry Vyukov <dvyukov@google.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Weilin Wang <weilin.wang@intel.com>
+Cc: Andreas Hindborg <a.hindborg@kernel.org>
+Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
+Cc: Danilo Krummrich <dakr@kernel.org>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Miguel Ojeda <ojeda@kernel.org>
+Cc: James Clark <james.clark@linaro.org>
+Cc: Jiapeng Chong <jiapeng.chong@linux.alibaba.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Stephen Brennan <stephen.s.brennan@oracle.com>
+Cc: Benno Lossin <benno.lossin@proton.me>
+Cc: Björn Roy Baron <bjorn3_gh@protonmail.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Trevor Gross <tmgross@umich.edu>
+Cc: linux-kernel@vger.kernel.org
+Cc: linux-perf-users@vger.kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/symbol-minimal.c | 168 +++++++++++++------------------
+ 1 file changed, 70 insertions(+), 98 deletions(-)
+
+diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c
+index d8da3da01fe6b..36c1d3090689f 100644
+--- a/tools/perf/util/symbol-minimal.c
++++ b/tools/perf/util/symbol-minimal.c
+@@ -90,11 +90,23 @@ int filename__read_build_id(const char *filename, struct build_id *bid)
+ {
+       FILE *fp;
+       int ret = -1;
+-      bool need_swap = false;
++      bool need_swap = false, elf32;
+       u8 e_ident[EI_NIDENT];
+-      size_t buf_size;
+-      void *buf;
+       int i;
++      union {
++              struct {
++                      Elf32_Ehdr ehdr32;
++                      Elf32_Phdr *phdr32;
++              };
++              struct {
++                      Elf64_Ehdr ehdr64;
++                      Elf64_Phdr *phdr64;
++              };
++      } hdrs;
++      void *phdr;
++      size_t phdr_size;
++      void *buf = NULL;
++      size_t buf_size = 0;
+       fp = fopen(filename, "r");
+       if (fp == NULL)
+@@ -108,119 +120,79 @@ int filename__read_build_id(const char *filename, struct build_id *bid)
+               goto out;
+       need_swap = check_need_swap(e_ident[EI_DATA]);
++      elf32 = e_ident[EI_CLASS] == ELFCLASS32;
+-      /* for simplicity */
+-      fseek(fp, 0, SEEK_SET);
+-
+-      if (e_ident[EI_CLASS] == ELFCLASS32) {
+-              Elf32_Ehdr ehdr;
+-              Elf32_Phdr *phdr;
+-
+-              if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1)
+-                      goto out;
++      if (fread(elf32 ? (void *)&hdrs.ehdr32 : (void *)&hdrs.ehdr64,
++                elf32 ? sizeof(hdrs.ehdr32) : sizeof(hdrs.ehdr64),
++                1, fp) != 1)
++              goto out;
+-              if (need_swap) {
+-                      ehdr.e_phoff = bswap_32(ehdr.e_phoff);
+-                      ehdr.e_phentsize = bswap_16(ehdr.e_phentsize);
+-                      ehdr.e_phnum = bswap_16(ehdr.e_phnum);
++      if (need_swap) {
++              if (elf32) {
++                      hdrs.ehdr32.e_phoff = bswap_32(hdrs.ehdr32.e_phoff);
++                      hdrs.ehdr32.e_phentsize = bswap_16(hdrs.ehdr32.e_phentsize);
++                      hdrs.ehdr32.e_phnum = bswap_16(hdrs.ehdr32.e_phnum);
++              } else {
++                      hdrs.ehdr64.e_phoff = bswap_64(hdrs.ehdr64.e_phoff);
++                      hdrs.ehdr64.e_phentsize = bswap_16(hdrs.ehdr64.e_phentsize);
++                      hdrs.ehdr64.e_phnum = bswap_16(hdrs.ehdr64.e_phnum);
+               }
++      }
++      phdr_size = elf32 ? hdrs.ehdr32.e_phentsize * hdrs.ehdr32.e_phnum
++                        : hdrs.ehdr64.e_phentsize * hdrs.ehdr64.e_phnum;
++      phdr = malloc(phdr_size);
++      if (phdr == NULL)
++              goto out;
+-              buf_size = ehdr.e_phentsize * ehdr.e_phnum;
+-              buf = malloc(buf_size);
+-              if (buf == NULL)
+-                      goto out;
+-
+-              fseek(fp, ehdr.e_phoff, SEEK_SET);
+-              if (fread(buf, buf_size, 1, fp) != 1)
+-                      goto out_free;
+-
+-              for (i = 0, phdr = buf; i < ehdr.e_phnum; i++, phdr++) {
+-                      void *tmp;
+-                      long offset;
+-
+-                      if (need_swap) {
+-                              phdr->p_type = bswap_32(phdr->p_type);
+-                              phdr->p_offset = bswap_32(phdr->p_offset);
+-                              phdr->p_filesz = bswap_32(phdr->p_filesz);
+-                      }
+-
+-                      if (phdr->p_type != PT_NOTE)
+-                              continue;
+-
+-                      offset = phdr->p_offset;
+-                      if (phdr->p_filesz > buf_size) {
+-                              buf_size = phdr->p_filesz;
+-                              tmp = realloc(buf, buf_size);
+-                              if (tmp == NULL)
+-                                      goto out_free;
+-                              buf = tmp;
+-                      }
+-                      fseek(fp, offset, SEEK_SET);
+-                      if (fread(buf, phdr->p_filesz, 1, fp) != 1)
+-                              goto out_free;
++      fseek(fp, elf32 ? hdrs.ehdr32.e_phoff : hdrs.ehdr64.e_phoff, SEEK_SET);
++      if (fread(phdr, phdr_size, 1, fp) != 1)
++              goto out_free;
+-                      ret = read_build_id(buf, phdr->p_filesz, bid, need_swap);
+-                      if (ret == 0) {
+-                              ret = bid->size;
+-                              break;
+-                      }
+-              }
+-      } else {
+-              Elf64_Ehdr ehdr;
+-              Elf64_Phdr *phdr;
++      if (elf32)
++              hdrs.phdr32 = phdr;
++      else
++              hdrs.phdr64 = phdr;
+-              if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1)
+-                      goto out;
++      for (i = 0; i < elf32 ? hdrs.ehdr32.e_phnum : hdrs.ehdr64.e_phnum; i++) {
++              size_t p_filesz;
+               if (need_swap) {
+-                      ehdr.e_phoff = bswap_64(ehdr.e_phoff);
+-                      ehdr.e_phentsize = bswap_16(ehdr.e_phentsize);
+-                      ehdr.e_phnum = bswap_16(ehdr.e_phnum);
++                      if (elf32) {
++                              hdrs.phdr32[i].p_type = bswap_32(hdrs.phdr32[i].p_type);
++                              hdrs.phdr32[i].p_offset = bswap_32(hdrs.phdr32[i].p_offset);
++                              hdrs.phdr32[i].p_filesz = bswap_32(hdrs.phdr32[i].p_offset);
++                      } else {
++                              hdrs.phdr64[i].p_type = bswap_32(hdrs.phdr64[i].p_type);
++                              hdrs.phdr64[i].p_offset = bswap_64(hdrs.phdr64[i].p_offset);
++                              hdrs.phdr64[i].p_filesz = bswap_64(hdrs.phdr64[i].p_filesz);
++                      }
+               }
++              if ((elf32 ? hdrs.phdr32[i].p_type : hdrs.phdr64[i].p_type) != PT_NOTE)
++                      continue;
+-              buf_size = ehdr.e_phentsize * ehdr.e_phnum;
+-              buf = malloc(buf_size);
+-              if (buf == NULL)
+-                      goto out;
+-
+-              fseek(fp, ehdr.e_phoff, SEEK_SET);
+-              if (fread(buf, buf_size, 1, fp) != 1)
+-                      goto out_free;
+-
+-              for (i = 0, phdr = buf; i < ehdr.e_phnum; i++, phdr++) {
++              p_filesz = elf32 ? hdrs.phdr32[i].p_filesz : hdrs.phdr64[i].p_filesz;
++              if (p_filesz > buf_size) {
+                       void *tmp;
+-                      long offset;
+-
+-                      if (need_swap) {
+-                              phdr->p_type = bswap_32(phdr->p_type);
+-                              phdr->p_offset = bswap_64(phdr->p_offset);
+-                              phdr->p_filesz = bswap_64(phdr->p_filesz);
+-                      }
+-
+-                      if (phdr->p_type != PT_NOTE)
+-                              continue;
+-                      offset = phdr->p_offset;
+-                      if (phdr->p_filesz > buf_size) {
+-                              buf_size = phdr->p_filesz;
+-                              tmp = realloc(buf, buf_size);
+-                              if (tmp == NULL)
+-                                      goto out_free;
+-                              buf = tmp;
+-                      }
+-                      fseek(fp, offset, SEEK_SET);
+-                      if (fread(buf, phdr->p_filesz, 1, fp) != 1)
++                      buf_size = p_filesz;
++                      tmp = realloc(buf, buf_size);
++                      if (tmp == NULL)
+                               goto out_free;
++                      buf = tmp;
++              }
++              fseek(fp, elf32 ? hdrs.phdr32[i].p_offset : hdrs.phdr64[i].p_offset, SEEK_SET);
++              if (fread(buf, p_filesz, 1, fp) != 1)
++                      goto out_free;
+-                      ret = read_build_id(buf, phdr->p_filesz, bid, need_swap);
+-                      if (ret == 0) {
+-                              ret = bid->size;
+-                              break;
+-                      }
++              ret = read_build_id(buf, p_filesz, bid, need_swap);
++              if (ret == 0) {
++                      ret = bid->size;
++                      break;
+               }
+       }
+ out_free:
+       free(buf);
++      free(phdr);
+ out:
+       fclose(fp);
+       return ret;
+-- 
+2.39.5
+
diff --git a/queue-6.15/perf-symbol-minimal-fix-double-free-in-filename__rea.patch b/queue-6.15/perf-symbol-minimal-fix-double-free-in-filename__rea.patch
new file mode 100644 (file)
index 0000000..619cbe1
--- /dev/null
@@ -0,0 +1,123 @@
+From 004b42f303f71930124905e3e29f1e25b835525b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 May 2025 00:00:03 -0700
+Subject: perf symbol-minimal: Fix double free in filename__read_build_id
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit fa9c4977fbfbca182f9e410d57b3f98356a9d917 ]
+
+Running the "perf script task-analyzer tests" with address sanitizer
+showed a double free:
+```
+FAIL: "test_csv_extended_times" Error message: "Failed to find required string:'Out-Out;'."
+=================================================================
+==19190==ERROR: AddressSanitizer: attempting double-free on 0x50b000017b10 in thread T0:
+    #0 0x55da9601c78a in free (perf+0x26078a) (BuildId: e7ef50e08970f017a96fde6101c5e2491acc674a)
+    #1 0x55da96640c63 in filename__read_build_id tools/perf/util/symbol-minimal.c:221:2
+
+0x50b000017b10 is located 0 bytes inside of 112-byte region [0x50b000017b10,0x50b000017b80)
+freed by thread T0 here:
+    #0 0x55da9601ce40 in realloc (perf+0x260e40) (BuildId: e7ef50e08970f017a96fde6101c5e2491acc674a)
+    #1 0x55da96640ad6 in filename__read_build_id tools/perf/util/symbol-minimal.c:204:10
+
+previously allocated by thread T0 here:
+    #0 0x55da9601ca23 in malloc (perf+0x260a23) (BuildId: e7ef50e08970f017a96fde6101c5e2491acc674a)
+    #1 0x55da966407e7 in filename__read_build_id tools/perf/util/symbol-minimal.c:181:9
+
+SUMMARY: AddressSanitizer: double-free (perf+0x26078a) (BuildId: e7ef50e08970f017a96fde6101c5e2491acc674a) in free
+==19190==ABORTING
+FAIL: "invocation of perf script report task-analyzer --csv-summary csvsummary --summary-extended command failed" Error message: ""
+FAIL: "test_csvsummary_extended" Error message: "Failed to find required string:'Out-Out;'."
+---- end(-1) ----
+132: perf script task-analyzer tests                                 : FAILED!
+```
+
+The buf_size if always set to phdr->p_filesz, but that may be 0
+causing a free and realloc to return NULL. This is treated in
+filename__read_build_id like a failure and the buffer is freed again.
+
+To avoid this problem only grow buf, meaning the buf_size will never
+be 0. This also reduces the number of memory (re)allocations.
+
+Fixes: b691f64360ecec49 ("perf symbols: Implement poor man's ELF parser")
+Signed-off-by: Ian Rogers <irogers@google.com>
+Acked-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung.kim@lge.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20250501070003.22251-1-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/symbol-minimal.c | 34 +++++++++++++++++---------------
+ 1 file changed, 18 insertions(+), 16 deletions(-)
+
+diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c
+index c6f369b5d893f..d8da3da01fe6b 100644
+--- a/tools/perf/util/symbol-minimal.c
++++ b/tools/perf/util/symbol-minimal.c
+@@ -147,18 +147,19 @@ int filename__read_build_id(const char *filename, struct build_id *bid)
+                       if (phdr->p_type != PT_NOTE)
+                               continue;
+-                      buf_size = phdr->p_filesz;
+                       offset = phdr->p_offset;
+-                      tmp = realloc(buf, buf_size);
+-                      if (tmp == NULL)
+-                              goto out_free;
+-
+-                      buf = tmp;
++                      if (phdr->p_filesz > buf_size) {
++                              buf_size = phdr->p_filesz;
++                              tmp = realloc(buf, buf_size);
++                              if (tmp == NULL)
++                                      goto out_free;
++                              buf = tmp;
++                      }
+                       fseek(fp, offset, SEEK_SET);
+-                      if (fread(buf, buf_size, 1, fp) != 1)
++                      if (fread(buf, phdr->p_filesz, 1, fp) != 1)
+                               goto out_free;
+-                      ret = read_build_id(buf, buf_size, bid, need_swap);
++                      ret = read_build_id(buf, phdr->p_filesz, bid, need_swap);
+                       if (ret == 0) {
+                               ret = bid->size;
+                               break;
+@@ -199,18 +200,19 @@ int filename__read_build_id(const char *filename, struct build_id *bid)
+                       if (phdr->p_type != PT_NOTE)
+                               continue;
+-                      buf_size = phdr->p_filesz;
+                       offset = phdr->p_offset;
+-                      tmp = realloc(buf, buf_size);
+-                      if (tmp == NULL)
+-                              goto out_free;
+-
+-                      buf = tmp;
++                      if (phdr->p_filesz > buf_size) {
++                              buf_size = phdr->p_filesz;
++                              tmp = realloc(buf, buf_size);
++                              if (tmp == NULL)
++                                      goto out_free;
++                              buf = tmp;
++                      }
+                       fseek(fp, offset, SEEK_SET);
+-                      if (fread(buf, buf_size, 1, fp) != 1)
++                      if (fread(buf, phdr->p_filesz, 1, fp) != 1)
+                               goto out_free;
+-                      ret = read_build_id(buf, buf_size, bid, need_swap);
++                      ret = read_build_id(buf, phdr->p_filesz, bid, need_swap);
+                       if (ret == 0) {
+                               ret = bid->size;
+                               break;
+-- 
+2.39.5
+
diff --git a/queue-6.15/perf-tests-fix-perf-report-tests-installation.patch b/queue-6.15/perf-tests-fix-perf-report-tests-installation.patch
new file mode 100644 (file)
index 0000000..265509d
--- /dev/null
@@ -0,0 +1,44 @@
+From 7bc8fdccd1e93e71cdb529551efc694eb748df71 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jan 2025 19:26:00 +0100
+Subject: perf tests: Fix 'perf report' tests installation
+
+From: Michael Petlan <mpetlan@redhat.com>
+
+[ Upstream commit 4bfe27140edf8dd1322326c79f5ae8d29ff7e43d ]
+
+There was a copy-paste mistake in the installation commands.
+
+Also, we need to install stderr-whitelist.txt file, which contains
+allowed messages that are printed on stderr and should not cause test
+fail.
+
+Fixes: 097fe67df1aa9cc7 ("perf testsuite: Install perf-report tests in the 'make install-tests -C tools/perf' target")
+Signed-off-by: Michael Petlan <mpetlan@redhat.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Link: https://lore.kernel.org/r/20250113182605.130719-6-vmolnaro@redhat.com
+Signed-off-by: Veronika Molnarova <vmolnaro@redhat.com>
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/Makefile.perf | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
+index 979d4691221a0..a7ae5637dadee 100644
+--- a/tools/perf/Makefile.perf
++++ b/tools/perf/Makefile.perf
+@@ -1147,7 +1147,8 @@ install-tests: all install-gtk
+               $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/base_probe'; \
+               $(INSTALL) tests/shell/base_probe/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/base_probe'; \
+               $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/base_report'; \
+-              $(INSTALL) tests/shell/base_probe/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/base_report'; \
++              $(INSTALL) tests/shell/base_report/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/base_report'; \
++              $(INSTALL) tests/shell/base_report/*.txt '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/base_report'; \
+               $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/coresight' ; \
+               $(INSTALL) tests/shell/coresight/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/coresight'
+       $(Q)$(MAKE) -C tests/shell/coresight install-tests
+-- 
+2.39.5
+
diff --git a/queue-6.15/perf-tests-metric-only-perf-stat-fix-tests-84-and-86.patch b/queue-6.15/perf-tests-metric-only-perf-stat-fix-tests-84-and-86.patch
new file mode 100644 (file)
index 0000000..2f8ac6a
--- /dev/null
@@ -0,0 +1,84 @@
+From d3ed1e7359d6c82b6aa8fd633e76873c0879d603 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Apr 2025 15:33:10 +0200
+Subject: perf tests metric-only perf stat: Fix tests 84 and 86 s390
+
+From: Thomas Richter <tmricht@linux.ibm.com>
+
+[ Upstream commit ccd4b5cdf00f358acae9f396d13029e7ae78522e ]
+
+On s390x KVM and z/VM machines the CPU Measurement Facility is not
+available. Events cycles and instructions do not exist.  Running above
+tests on s390 KVM and z/VM guests always fail with this error:
+
+  # ./perf test 84 86
+  84: perf stat JSON output linter          : FAILED!
+  86: perf stat STD output linter           : FAILED!
+  #
+
+Root cause is command:
+
+  # perf stat -j --metric-only -e instructions,cycles -- true
+  {"metric-value" : "none"}
+  #
+
+Which fails due to unsupported events and returns "none".
+Do not execute this test case on s390 KVM and z/VM machines.
+
+Output after:
+  # ./perf test 84 86
+  84: perf stat JSON output linter          : Ok
+  86: perf stat STD output linter           : Ok
+  #
+
+Fixes: 45a86d017adf4d6c ("perf test: Add --metric-only to perf stat output tests")
+Suggested-by: Heiko Carstens <hca@linux.ibm.com>
+Suggested-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
+Reviewed-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
+Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
+Cc: Alexander Gordeev <agordeev@linux.ibm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Vasily Gorbik <gor@linux.ibm.com>
+Link: https://lore.kernel.org/r/20250424133310.37452-1-tmricht@linux.ibm.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/tests/shell/lib/stat_output.sh  | 5 +++++
+ tools/perf/tests/shell/stat+json_output.sh | 5 +++++
+ 2 files changed, 10 insertions(+)
+
+diff --git a/tools/perf/tests/shell/lib/stat_output.sh b/tools/perf/tests/shell/lib/stat_output.sh
+index 4d4aac547f010..c2ec7881ec1de 100644
+--- a/tools/perf/tests/shell/lib/stat_output.sh
++++ b/tools/perf/tests/shell/lib/stat_output.sh
+@@ -151,6 +151,11 @@ check_per_socket()
+ check_metric_only()
+ {
+       echo -n "Checking $1 output: metric only "
++      if [ "$(uname -m)" = "s390x" ] && ! grep '^facilities' /proc/cpuinfo  | grep -qw 67
++      then
++              echo "[Skip] CPU-measurement counter facility not installed"
++              return
++      fi
+       perf stat --metric-only $2 -e instructions,cycles true
+       commachecker --metric-only
+       echo "[Success]"
+diff --git a/tools/perf/tests/shell/stat+json_output.sh b/tools/perf/tests/shell/stat+json_output.sh
+index a4f257ea839e1..98fb65274ac4f 100755
+--- a/tools/perf/tests/shell/stat+json_output.sh
++++ b/tools/perf/tests/shell/stat+json_output.sh
+@@ -176,6 +176,11 @@ check_per_socket()
+ check_metric_only()
+ {
+       echo -n "Checking json output: metric only "
++      if [ "$(uname -m)" = "s390x" ] && ! grep '^facilities' /proc/cpuinfo  | grep -qw 67
++      then
++              echo "[Skip] CPU-measurement counter facility not installed"
++              return
++      fi
+       perf stat -j --metric-only -e instructions,cycles -o "${stat_output}" true
+       $PYTHON $pythonchecker --metric-only --file "${stat_output}"
+       echo "[Success]"
+-- 
+2.39.5
+
diff --git a/queue-6.15/perf-tests-switch-tracking-fix-timestamp-comparison.patch b/queue-6.15/perf-tests-switch-tracking-fix-timestamp-comparison.patch
new file mode 100644 (file)
index 0000000..6f529d5
--- /dev/null
@@ -0,0 +1,102 @@
+From 39a26615ef67a67aeb26bb116cb4790e10ec3d2c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Mar 2025 18:27:59 +0100
+Subject: perf tests switch-tracking: Fix timestamp comparison
+
+From: Leo Yan <leo.yan@arm.com>
+
+[ Upstream commit 628e124404b3db5e10e17228e680a2999018ab33 ]
+
+The test might fail on the Arm64 platform with the error:
+
+  # perf test -vvv "Track with sched_switch"
+  Missing sched_switch events
+  #
+
+The issue is caused by incorrect handling of timestamp comparisons. The
+comparison result, a signed 64-bit value, was being directly cast to an
+int, leading to incorrect sorting for sched events.
+
+The case does not fail everytime, usually I can trigger the failure
+after run 20 ~ 30 times:
+
+  # while true; do perf test "Track with sched_switch"; done
+  106: Track with sched_switch                                         : Ok
+  106: Track with sched_switch                                         : Ok
+  106: Track with sched_switch                                         : Ok
+  106: Track with sched_switch                                         : Ok
+  106: Track with sched_switch                                         : Ok
+  106: Track with sched_switch                                         : Ok
+  106: Track with sched_switch                                         : Ok
+  106: Track with sched_switch                                         : Ok
+  106: Track with sched_switch                                         : Ok
+  106: Track with sched_switch                                         : Ok
+  106: Track with sched_switch                                         : Ok
+  106: Track with sched_switch                                         : Ok
+  106: Track with sched_switch                                         : Ok
+  106: Track with sched_switch                                         : Ok
+  106: Track with sched_switch                                         : FAILED!
+  106: Track with sched_switch                                         : Ok
+  106: Track with sched_switch                                         : Ok
+  106: Track with sched_switch                                         : Ok
+  106: Track with sched_switch                                         : Ok
+  106: Track with sched_switch                                         : Ok
+  106: Track with sched_switch                                         : Ok
+  106: Track with sched_switch                                         : Ok
+  106: Track with sched_switch                                         : Ok
+  106: Track with sched_switch                                         : FAILED!
+  106: Track with sched_switch                                         : Ok
+  106: Track with sched_switch                                         : Ok
+
+I used cross compiler to build Perf tool on my host machine and tested on
+Debian / Juno board.  Generally, I think this issue is not very specific
+to GCC versions.  As both internal CI and my local env can reproduce the
+issue.
+
+My Host Build compiler:
+
+  # aarch64-linux-gnu-gcc --version
+  aarch64-linux-gnu-gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0
+
+Juno Board:
+
+  # lsb_release -a
+  No LSB modules are available.
+  Distributor ID: Debian
+  Description:    Debian GNU/Linux 12 (bookworm)
+  Release:        12
+  Codename:       bookworm
+
+Fix this by explicitly returning 0, 1, or -1 based on whether the result
+is zero, positive, or negative.
+
+Fixes: d44bc558297222d9 ("perf tests: Add a test for tracking with sched_switch")
+Reviewed-by: Ian Rogers <irogers@google.com>
+Signed-off-by: Leo Yan <leo.yan@arm.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: James Clark <james.clark@linaro.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Link: https://lore.kernel.org/r/20250331172759.115604-1-leo.yan@arm.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/tests/switch-tracking.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c
+index 8df3f9d9ffd2b..6b3aac283c371 100644
+--- a/tools/perf/tests/switch-tracking.c
++++ b/tools/perf/tests/switch-tracking.c
+@@ -264,7 +264,7 @@ static int compar(const void *a, const void *b)
+       const struct event_node *nodeb = b;
+       s64 cmp = nodea->event_time - nodeb->event_time;
+-      return cmp;
++      return cmp < 0 ? -1 : (cmp > 0 ? 1 : 0);
+ }
+ static int process_events(struct evlist *evlist,
+-- 
+2.39.5
+
diff --git a/queue-6.15/perf-tool_pmu-fix-aggregation-on-duration_time.patch b/queue-6.15/perf-tool_pmu-fix-aggregation-on-duration_time.patch
new file mode 100644 (file)
index 0000000..1ad098f
--- /dev/null
@@ -0,0 +1,85 @@
+From 9cb6aa97d5659d2b2659ff938369c246fe32f40d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Apr 2025 22:03:58 -0700
+Subject: perf tool_pmu: Fix aggregation on duration_time
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 68cb1567439fa325ba980f3b5b67f95d3953eafd ]
+
+evsel__count_has_error() fails counters when the enabled or running time
+are 0. The duration_time event reads 0 when the cpu_map_idx != 0 to
+avoid aggregating time over CPUs. Change the enable and running time
+to always have a ratio of 100% so that evsel__count_has_error won't
+fail.
+
+Before:
+```
+$ sudo /tmp/perf/perf stat --per-core -a -M UNCORE_FREQ sleep 1
+
+ Performance counter stats for 'system wide':
+
+S0-D0-C0              1      2,615,819,485      UNC_CLOCK.SOCKET                 #     2.61 UNCORE_FREQ
+S0-D0-C0              2      <not counted>      duration_time
+
+       1.002111784 seconds time elapsed
+```
+
+After:
+```
+$ perf stat --per-core -a -M UNCORE_FREQ sleep 1
+
+ Performance counter stats for 'system wide':
+
+S0-D0-C0              1        758,160,296      UNC_CLOCK.SOCKET                 #     0.76 UNCORE_FREQ
+S0-D0-C0              2      1,003,438,246      duration_time
+
+       1.002486017 seconds time elapsed
+```
+
+Note: the metric reads the value a different way and isn't impacted.
+
+Fixes: 240505b2d0adcdc8 ("perf tool_pmu: Factor tool events into their own PMU")
+Reported-by: Stephane Eranian <eranian@google.com>
+Reviewed-by: James Clark <james.clark@linaro.org>
+Signed-off-by: Ian Rogers <irogers@google.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Richter <tmricht@linux.ibm.com>
+Link: https://lore.kernel.org/r/20250423050358.94310-1-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/tool_pmu.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/tools/perf/util/tool_pmu.c b/tools/perf/util/tool_pmu.c
+index 97b327d1ce4a0..727a10e3f9900 100644
+--- a/tools/perf/util/tool_pmu.c
++++ b/tools/perf/util/tool_pmu.c
+@@ -486,8 +486,14 @@ int evsel__tool_pmu_read(struct evsel *evsel, int cpu_map_idx, int thread)
+               delta_start *= 1000000000 / ticks_per_sec;
+       }
+       count->val    = delta_start;
+-      count->ena    = count->run = delta_start;
+       count->lost   = 0;
++      /*
++       * The values of enabled and running must make a ratio of 100%. The
++       * exact values don't matter as long as they are non-zero to avoid
++       * issues with evsel__count_has_error.
++       */
++      count->ena++;
++      count->run++;
+       return 0;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/perf-tools-fix-arm64-source-package-build.patch b/queue-6.15/perf-tools-fix-arm64-source-package-build.patch
new file mode 100644 (file)
index 0000000..c7365f7
--- /dev/null
@@ -0,0 +1,60 @@
+From 3fc24f1eb05a62bc8f77b3d82d2d751f60d904ac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 May 2025 10:57:30 +0100
+Subject: perf tools: Fix arm64 source package build
+
+From: James Clark <james.clark@linaro.org>
+
+[ Upstream commit aea3496bbc7c20037ecc35411264de109d700fc7 ]
+
+Syscall tables are generated from rules in the kernel tree. Add the
+related files to the MANIFEST to fix the Perf source package build.
+
+Reported-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Fixes: bfb713ea53c746b0 ("perf tools: Fix arm64 build by generating unistd_64.h")
+Signed-off-by: James Clark <james.clark@linaro.org>
+Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20250513-james-perf-src-pkg-fix-v1-1-bcfd0486dbd6@linaro.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/MANIFEST | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST
+index 364b55b00b484..34af57b8ec2a9 100644
+--- a/tools/perf/MANIFEST
++++ b/tools/perf/MANIFEST
+@@ -1,8 +1,10 @@
+ COPYING
+ LICENSES/preferred/GPL-2.0
+ arch/arm64/tools/gen-sysreg.awk
++arch/arm64/tools/syscall_64.tbl
+ arch/arm64/tools/sysreg
+ arch/*/include/uapi/asm/bpf_perf_event.h
++include/uapi/asm-generic/Kbuild
+ tools/perf
+ tools/arch
+ tools/scripts
+@@ -25,6 +27,10 @@ tools/lib/str_error_r.c
+ tools/lib/vsprintf.c
+ tools/lib/zalloc.c
+ scripts/bpf_doc.py
++scripts/Kbuild.include
++scripts/Makefile.asm-headers
++scripts/syscall.tbl
++scripts/syscallhdr.sh
+ tools/bpf/bpftool
+ kernel/bpf/disasm.c
+ kernel/bpf/disasm.h
+-- 
+2.39.5
+
diff --git a/queue-6.15/perf-trace-always-print-return-value-for-syscalls-re.patch b/queue-6.15/perf-trace-always-print-return-value-for-syscalls-re.patch
new file mode 100644 (file)
index 0000000..3b3bae3
--- /dev/null
@@ -0,0 +1,67 @@
+From 8e6b48a1c30f2194a0ee1844a2e80fb77bf0c8d1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Apr 2025 12:04:12 -0400
+Subject: perf trace: Always print return value for syscalls returning a pid
+
+From: Anubhav Shelat <ashelat@redhat.com>
+
+[ Upstream commit c7a48ea9b919e2fa0e4a1d9938fdb03e9afe276c ]
+
+The syscalls that were consistently observed were set_robust_list and
+rseq. This is because perf cannot find their child process.
+
+This change ensures that the return value is always printed.
+
+Before:
+     0.256 ( 0.001 ms): set_robust_list(head: 0x7f09c77dba20, len: 24)                        =
+     0.259 ( 0.001 ms): rseq(rseq: 0x7f09c77dc0e0, rseq_len: 32, sig: 1392848979)             =
+After:
+     0.270 ( 0.002 ms): set_robust_list(head: 0x7f0bb14a6a20, len: 24)                        = 0
+     0.273 ( 0.002 ms): rseq(rseq: 0x7f0bb14a70e0, rseq_len: 32, sig: 1392848979)             = 0
+
+Committer notes:
+
+As discussed in the thread in the Link: tag below, these two don't
+return a pid, but for syscalls returning one, we need to print the
+result and if we manage to find the children in 'perf trace' data
+structures, then print its name as well.
+
+Fixes: 11c8e39f5133aed9 ("perf trace: Infrastructure to show COMM strings for syscalls returning PIDs")
+Reviewed-by: Howard Chu <howardchu95@gmail.com>
+Signed-off-by: Anubhav Shelat <ashelat@redhat.com>
+Acked-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Dapeng Mi <dapeng1.mi@linux.intel.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: James Clark <james.clark@linaro.org>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Michael Petlan <mpetlan@redhat.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20250403160411.159238-2-ashelat@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-trace.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
+index f98b5efb1f96c..7304e62b69fee 100644
+--- a/tools/perf/builtin-trace.c
++++ b/tools/perf/builtin-trace.c
+@@ -3005,8 +3005,8 @@ errno_print: {
+       else if (sc->fmt->errpid) {
+               struct thread *child = machine__find_thread(trace->host, ret, ret);
++              fprintf(trace->output, "%ld", ret);
+               if (child != NULL) {
+-                      fprintf(trace->output, "%ld", ret);
+                       if (thread__comm_set(child))
+                               fprintf(trace->output, " (%s)", thread__comm_str(child));
+                       thread__put(child);
+-- 
+2.39.5
+
diff --git a/queue-6.15/perf-trace-fix-leaks-of-struct-thread-in-fprintf_sys.patch b/queue-6.15/perf-trace-fix-leaks-of-struct-thread-in-fprintf_sys.patch
new file mode 100644 (file)
index 0000000..55e6e64
--- /dev/null
@@ -0,0 +1,46 @@
+From 93d1a87e38b60c0f8a6997b77e8f05a9221e7d57 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Apr 2025 22:42:13 -0700
+Subject: perf trace: Fix leaks of 'struct thread' in fprintf_sys_enter()
+
+From: Namhyung Kim <namhyung@kernel.org>
+
+[ Upstream commit bb3de7fa988c1b315ab8e87dc74e0d088284f142 ]
+
+I've found some leaks from 'perf trace -a'.
+
+It seems there are more leaks but this is what I can find for now.
+
+Fixes: 70351029b55677eb ("perf thread: Add support for reading the e_machine type for a thread")
+Reviewed-by: Howard Chu <howardchu95@gmail.com>
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20250403054213.7021-1-namhyung@kernel.org
+[ split from a larget patch ]
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-trace.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
+index 6ac51925ea424..f6b23319ea5f6 100644
+--- a/tools/perf/builtin-trace.c
++++ b/tools/perf/builtin-trace.c
+@@ -2842,7 +2842,7 @@ static int trace__fprintf_sys_enter(struct trace *trace, struct evsel *evsel,
+       e_machine = thread__e_machine(thread, trace->host);
+       sc = trace__syscall_info(trace, evsel, e_machine, id);
+       if (sc == NULL)
+-              return -1;
++              goto out_put;
+       ttrace = thread__trace(thread, trace);
+       /*
+        * We need to get ttrace just to make sure it is there when syscall__scnprintf_args()
+-- 
+2.39.5
+
diff --git a/queue-6.15/perf-trace-fix-leaks-of-struct-thread-in-set_filter_.patch b/queue-6.15/perf-trace-fix-leaks-of-struct-thread-in-set_filter_.patch
new file mode 100644 (file)
index 0000000..8c980dd
--- /dev/null
@@ -0,0 +1,51 @@
+From cf2e1cb053103b13ff0aa81c443fc8f7f52133a5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Apr 2025 22:42:13 -0700
+Subject: perf trace: Fix leaks of 'struct thread' in set_filter_loop_pids()
+
+From: Namhyung Kim <namhyung@kernel.org>
+
+[ Upstream commit 30d20fb1f84ad5c92706fe2c6cbb2d4cc293e671 ]
+
+I've found some leaks from 'perf trace -a'.
+
+It seems there are more leaks but this is what I can find for now.
+
+Fixes: 082ab9a18e532864 ("perf trace: Filter out 'sshd' in the tracer ancestry in syswide tracing")
+Reviewed-by: Howard Chu <howardchu95@gmail.com>
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20250403054213.7021-1-namhyung@kernel.org
+[ split from a larget patch ]
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-trace.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
+index f6b23319ea5f6..f98b5efb1f96c 100644
+--- a/tools/perf/builtin-trace.c
++++ b/tools/perf/builtin-trace.c
+@@ -4128,10 +4128,13 @@ static int trace__set_filter_loop_pids(struct trace *trace)
+               if (!strcmp(thread__comm_str(parent), "sshd") ||
+                   strstarts(thread__comm_str(parent), "gnome-terminal")) {
+                       pids[nr++] = thread__tid(parent);
++                      thread__put(parent);
+                       break;
+               }
++              thread__put(thread);
+               thread = parent;
+       }
++      thread__put(thread);
+       err = evlist__append_tp_filter_pids(trace->evlist, nr, pids);
+       if (!err && trace->filter_pids.map)
+-- 
+2.39.5
+
diff --git a/queue-6.15/perf-trace-set-errpid-to-false-for-rseq-and-set_robu.patch b/queue-6.15/perf-trace-set-errpid-to-false-for-rseq-and-set_robu.patch
new file mode 100644 (file)
index 0000000..0704b2b
--- /dev/null
@@ -0,0 +1,60 @@
+From d96b3213afc124cdc9198cf4d071fd0a35309458 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 May 2025 10:33:35 -0400
+Subject: perf trace: Set errpid to false for rseq and set_robust_list
+
+From: Anubhav Shelat <ashelat@redhat.com>
+
+[ Upstream commit 8c56bfe53bd881c7b598c54a3a06216743c57bbc ]
+
+The 'rseq' and 'set_robust_list' syscalls don't return a pid, so set
+errpid for both to false.
+
+Fixes: 0c1019e3463b263a ("perf trace: Mark the 'rseq' arg in the rseq syscall as coming from user space")
+Fixes: 1de5b5dcb8353f36 ("perf trace: Mark the 'head' arg in the set_robust_list syscall as coming from user space")
+Signed-off-by: Anubhav Shelat <ashelat@redhat.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Dapeng Mi <dapeng1.mi@linux.intel.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: James Clark <james.clark@linaro.org>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Michael Petlan <mpetlan@redhat.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20250529143334.1469669-2-ashelat@redhat.com
+[ Remove explicit .errpid = false, omitting its initialization zeroes it, as noted by Namhyung ]
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-trace.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
+index 7304e62b69fee..33cce59bdfbdb 100644
+--- a/tools/perf/builtin-trace.c
++++ b/tools/perf/builtin-trace.c
+@@ -1352,7 +1352,7 @@ static const struct syscall_fmt syscall_fmts[] = {
+         .arg = { [0] = { .scnprintf = SCA_FDAT, /* olddirfd */ },
+                  [2] = { .scnprintf = SCA_FDAT, /* newdirfd */ },
+                  [4] = { .scnprintf = SCA_RENAMEAT2_FLAGS, /* flags */ }, }, },
+-      { .name     = "rseq",       .errpid = true,
++      { .name     = "rseq",
+         .arg = { [0] = { .from_user = true /* rseq */, }, }, },
+       { .name     = "rt_sigaction",
+         .arg = { [0] = { .scnprintf = SCA_SIGNUM, /* sig */ }, }, },
+@@ -1376,7 +1376,7 @@ static const struct syscall_fmt syscall_fmts[] = {
+       { .name     = "sendto",
+         .arg = { [3] = { .scnprintf = SCA_MSG_FLAGS, /* flags */ },
+                  [4] = SCA_SOCKADDR_FROM_USER(addr), }, },
+-      { .name     = "set_robust_list",            .errpid = true,
++      { .name     = "set_robust_list",
+         .arg = { [0] = { .from_user = true /* head */, }, }, },
+       { .name     = "set_tid_address", .errpid = true, },
+       { .name     = "setitimer",
+-- 
+2.39.5
+
diff --git a/queue-6.15/perf-ui-browser-hists-set-actions-thread-before-call.patch b/queue-6.15/perf-ui-browser-hists-set-actions-thread-before-call.patch
new file mode 100644 (file)
index 0000000..f6d4fa5
--- /dev/null
@@ -0,0 +1,62 @@
+From 61ad52dfd488fab484bfb2a37def60c740433397 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Apr 2025 21:58:19 -0300
+Subject: perf ui browser hists: Set actions->thread before calling
+ do_zoom_thread()
+
+From: Arnaldo Carvalho de Melo <acme@redhat.com>
+
+[ Upstream commit 1741189d843a1d5ef38538bc52a3760e2e46cb2e ]
+
+In 7cecb7fe8388d5c3 ("perf hists: Move sort__has_comm into struct
+perf_hpp_list") it assumes that act->thread is set prior to calling
+do_zoom_thread().
+
+This doesn't happen when we use ESC or the Left arrow key to Zoom out of
+a specific thread, making this operation not to work and we get stuck
+into the thread zoom.
+
+In 6422184b087ff435 ("perf hists browser: Simplify zooming code using
+pstack_peek()") it says no need to set actions->thread, and at that
+point that was true, but in 7cecb7fe8388d5c3 a actions->thread == NULL
+check was added before the zoom out of thread could kick in.
+
+We can zoom out using the alternative 't' thread zoom toggle hotkey to
+finally set actions->thread before calling do_zoom_thread() and zoom
+out, but lets also fix the ESC/Zoom out of thread case.
+
+Fixes: 7cecb7fe8388d5c3 ("perf hists: Move sort__has_comm into struct perf_hpp_list")
+Reported-by: Ingo Molnar <mingo@kernel.org>
+Tested-by: Ingo Molnar <mingo@kernel.org>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: James Clark <james.clark@linaro.org>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Link: https://lore.kernel.org/r/Z_TYux5fUg2pW-pF@gmail.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/ui/browsers/hists.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
+index 35c10509b797f..992d1c822a97a 100644
+--- a/tools/perf/ui/browsers/hists.c
++++ b/tools/perf/ui/browsers/hists.c
+@@ -3274,10 +3274,10 @@ static int evsel__hists_browse(struct evsel *evsel, int nr_events, const char *h
+                               /*
+                                * No need to set actions->dso here since
+                                * it's just to remove the current filter.
+-                               * Ditto for thread below.
+                                */
+                               do_zoom_dso(browser, actions);
+                       } else if (top == &browser->hists->thread_filter) {
++                              actions->thread = thread;
+                               do_zoom_thread(browser, actions);
+                       } else if (top == &browser->hists->socket_filter) {
+                               do_zoom_socket(browser, actions);
+-- 
+2.39.5
+
diff --git a/queue-6.15/perf-x86-amd-uncore-prevent-umc-counters-from-satura.patch b/queue-6.15/perf-x86-amd-uncore-prevent-umc-counters-from-satura.patch
new file mode 100644 (file)
index 0000000..98c1834
--- /dev/null
@@ -0,0 +1,86 @@
+From 534c71b39066f0fb67b56bc32ea828d3555df182 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Apr 2025 09:13:03 +0530
+Subject: perf/x86/amd/uncore: Prevent UMC counters from saturating
+
+From: Sandipan Das <sandipan.das@amd.com>
+
+[ Upstream commit 2492e5aba2be064d0604ae23ae0770ecc0168192 ]
+
+Unlike L3 and DF counters, UMC counters (PERF_CTRs) set the Overflow bit
+(bit 48) and saturate on overflow. A subsequent pmu->read() of the event
+reports an incorrect accumulated count as there is no difference between
+the previous and the current values of the counter.
+
+To avoid this, inspect the current counter value and proactively reset
+the corresponding PERF_CTR register on every pmu->read(). Combined with
+the periodic reads initiated by the hrtimer, the counters never get a
+chance saturate but the resolution reduces to 47 bits.
+
+Fixes: 25e56847821f ("perf/x86/amd/uncore: Add memory controller support")
+Signed-off-by: Sandipan Das <sandipan.das@amd.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Reviewed-by: Song Liu <song@kernel.org>
+Acked-by: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/dee9c8af2c6d66814cf4c6224529c144c620cf2c.1744906694.git.sandipan.das@amd.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/events/amd/uncore.c | 35 ++++++++++++++++++++++++++++++++++-
+ 1 file changed, 34 insertions(+), 1 deletion(-)
+
+diff --git a/arch/x86/events/amd/uncore.c b/arch/x86/events/amd/uncore.c
+index 010024f09f2c4..a6fa01ef35a10 100644
+--- a/arch/x86/events/amd/uncore.c
++++ b/arch/x86/events/amd/uncore.c
+@@ -889,6 +889,39 @@ static void amd_uncore_umc_start(struct perf_event *event, int flags)
+       perf_event_update_userpage(event);
+ }
++static void amd_uncore_umc_read(struct perf_event *event)
++{
++      struct hw_perf_event *hwc = &event->hw;
++      u64 prev, new, shift;
++      s64 delta;
++
++      shift = COUNTER_SHIFT + 1;
++      prev = local64_read(&hwc->prev_count);
++
++      /*
++       * UMC counters do not have RDPMC assignments. Read counts directly
++       * from the corresponding PERF_CTR.
++       */
++      rdmsrl(hwc->event_base, new);
++
++      /*
++       * Unlike the other uncore counters, UMC counters saturate and set the
++       * Overflow bit (bit 48) on overflow. Since they do not roll over,
++       * proactively reset the corresponding PERF_CTR when bit 47 is set so
++       * that the counter never gets a chance to saturate.
++       */
++      if (new & BIT_ULL(63 - COUNTER_SHIFT)) {
++              wrmsrl(hwc->event_base, 0);
++              local64_set(&hwc->prev_count, 0);
++      } else {
++              local64_set(&hwc->prev_count, new);
++      }
++
++      delta = (new << shift) - (prev << shift);
++      delta >>= shift;
++      local64_add(delta, &event->count);
++}
++
+ static
+ void amd_uncore_umc_ctx_scan(struct amd_uncore *uncore, unsigned int cpu)
+ {
+@@ -967,7 +1000,7 @@ int amd_uncore_umc_ctx_init(struct amd_uncore *uncore, unsigned int cpu)
+                               .del            = amd_uncore_del,
+                               .start          = amd_uncore_umc_start,
+                               .stop           = amd_uncore_stop,
+-                              .read           = amd_uncore_read,
++                              .read           = amd_uncore_umc_read,
+                               .capabilities   = PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_INTERRUPT,
+                               .module         = THIS_MODULE,
+                       };
+-- 
+2.39.5
+
diff --git a/queue-6.15/perf-x86-amd-uncore-remove-unused-struct-amd_uncore_.patch b/queue-6.15/perf-x86-amd-uncore-remove-unused-struct-amd_uncore_.patch
new file mode 100644 (file)
index 0000000..20604c6
--- /dev/null
@@ -0,0 +1,35 @@
+From 15ad44bf6a7c68f8f2ed7cdb1ca0bd10873c5ac8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Apr 2025 09:12:59 +0530
+Subject: perf/x86/amd/uncore: Remove unused 'struct amd_uncore_ctx::node'
+ member
+
+From: Sandipan Das <sandipan.das@amd.com>
+
+[ Upstream commit 4f81cc2d1bf91a49d33eb6578b58db2518deef01 ]
+
+Fixes: d6389d3ccc13 ("perf/x86/amd/uncore: Refactor uncore management")
+Signed-off-by: Sandipan Das <sandipan.das@amd.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/30f9254c2de6c4318dd0809ef85a1677f68eef10.1744906694.git.sandipan.das@amd.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/events/amd/uncore.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/arch/x86/events/amd/uncore.c b/arch/x86/events/amd/uncore.c
+index 49c26ce2b1152..010024f09f2c4 100644
+--- a/arch/x86/events/amd/uncore.c
++++ b/arch/x86/events/amd/uncore.c
+@@ -38,7 +38,6 @@ struct amd_uncore_ctx {
+       int refcnt;
+       int cpu;
+       struct perf_event **events;
+-      struct hlist_node node;
+ };
+ struct amd_uncore_pmu {
+-- 
+2.39.5
+
diff --git a/queue-6.15/phy-qcom-qmp-usb-fix-an-null-vs-is_err-bug.patch b/queue-6.15/phy-qcom-qmp-usb-fix-an-null-vs-is_err-bug.patch
new file mode 100644 (file)
index 0000000..8bd69e0
--- /dev/null
@@ -0,0 +1,56 @@
+From 6346ebb0526dc6e63e2f1885d69fd2243bd003e7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Apr 2025 07:50:50 -0500
+Subject: phy: qcom-qmp-usb: Fix an NULL vs IS_ERR() bug
+
+From: Chenyuan Yang <chenyuan0y@gmail.com>
+
+[ Upstream commit d14402a38c2d868cacb1facaf9be908ca6558e59 ]
+
+The qmp_usb_iomap() helper function currently returns the raw result of
+devm_ioremap() for non-exclusive mappings. Since devm_ioremap() may return
+a NULL pointer and the caller only checks error pointers with IS_ERR(),
+NULL could bypass the check and lead to an invalid dereference.
+
+Fix the issue by checking if devm_ioremap() returns NULL. When it does,
+qmp_usb_iomap() now returns an error pointer via IOMEM_ERR_PTR(-ENOMEM),
+ensuring safe and consistent error handling.
+
+Signed-off-by: Chenyuan Yang <chenyuan0y@gmail.com>
+Fixes: a5d6b1ac56cb ("phy: qcom-qmp-usb: fix memleak on probe deferral")
+CC: Johan Hovold <johan@kernel.org>
+CC: Krzysztof Kozlowski <krzk@kernel.org>
+Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Link: https://lore.kernel.org/r/20250414125050.2118619-1-chenyuan0y@gmail.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/qualcomm/phy-qcom-qmp-usb.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
+index 7877215704575..ed646a7e705ba 100644
+--- a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
++++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
+@@ -2106,12 +2106,16 @@ static void __iomem *qmp_usb_iomap(struct device *dev, struct device_node *np,
+                                       int index, bool exclusive)
+ {
+       struct resource res;
++      void __iomem *mem;
+       if (!exclusive) {
+               if (of_address_to_resource(np, index, &res))
+                       return IOMEM_ERR_PTR(-EINVAL);
+-              return devm_ioremap(dev, res.start, resource_size(&res));
++              mem = devm_ioremap(dev, res.start, resource_size(&res));
++              if (!mem)
++                      return IOMEM_ERR_PTR(-ENOMEM);
++              return mem;
+       }
+       return devm_of_iomap(dev, np, index, NULL);
+-- 
+2.39.5
+
diff --git a/queue-6.15/phy-qcom-qusb2-reuse-the-ipq6018-settings-for-ipq542.patch b/queue-6.15/phy-qcom-qusb2-reuse-the-ipq6018-settings-for-ipq542.patch
new file mode 100644 (file)
index 0000000..af3d1fe
--- /dev/null
@@ -0,0 +1,44 @@
+From ebde27f15b2f58938fa4e4ba4ab79251dae380f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Apr 2025 09:52:51 +0530
+Subject: phy: qcom-qusb2: reuse the IPQ6018 settings for IPQ5424
+
+From: Kathiravan Thirumoorthy <kathiravan.thirumoorthy@oss.qualcomm.com>
+
+[ Upstream commit 25c36b54eafc98b3ef004e2037cea1328d9b8bc5 ]
+
+With the settings used in the commit 9c56a1de296e ("phy: qcom-qusb2: add
+QUSB2 support for IPQ5424"), compliance test cases especially
+eye-diagram (Host High-speed Signal Quality) tests are failing.
+
+Reuse the IPQ6018 settings for IPQ5424 as mentioned in the Hardware
+Design Document which helps to meet all the complaince requirement test
+cases.
+
+Fixes: 9c56a1de296e ("phy: qcom-qusb2: add QUSB2 support for IPQ5424")
+Signed-off-by: Kathiravan Thirumoorthy <kathiravan.thirumoorthy@oss.qualcomm.com>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Link: https://lore.kernel.org/r/20250415-revert_hs_phy_settings-v3-2-3a8f86211b59@oss.qualcomm.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/qualcomm/phy-qcom-qusb2.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c b/drivers/phy/qualcomm/phy-qcom-qusb2.c
+index 81b9e9349c3eb..49c37c53b38e7 100644
+--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
++++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
+@@ -929,6 +929,9 @@ static const struct phy_ops qusb2_phy_gen_ops = {
+ static const struct of_device_id qusb2_phy_of_match_table[] = {
+       {
++              .compatible     = "qcom,ipq5424-qusb2-phy",
++              .data           = &ipq6018_phy_cfg,
++      }, {
+               .compatible     = "qcom,ipq6018-qusb2-phy",
+               .data           = &ipq6018_phy_cfg,
+       }, {
+-- 
+2.39.5
+
diff --git a/queue-6.15/phy-rockchip-samsung-hdptx-do-no-set-rk_hdptx_phy-ra.patch b/queue-6.15/phy-rockchip-samsung-hdptx-do-no-set-rk_hdptx_phy-ra.patch
new file mode 100644 (file)
index 0000000..65f0983
--- /dev/null
@@ -0,0 +1,53 @@
+From 637c7e8d14c59f5c1f44379754e43124bc0f373d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Mar 2025 14:35:38 +0200
+Subject: phy: rockchip: samsung-hdptx: Do no set rk_hdptx_phy->rate in case of
+ errors
+
+From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
+
+[ Upstream commit 1f4d382769e3b38dfc498c806811dae856e40f31 ]
+
+Ensure rk_hdptx_ropll_tmds_cmn_config() updates hdptx->rate only after
+all the other operations have been successful.
+
+Fixes: c4b09c562086 ("phy: phy-rockchip-samsung-hdptx: Add clock provider support")
+Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
+Link: https://lore.kernel.org/r/20250318-phy-sam-hdptx-bpc-v6-4-8cb1678e7663@collabora.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+index 6cfed3fcd647b..61db514ce5cfb 100644
+--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
++++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+@@ -1008,9 +1008,7 @@ static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx,
+ {
+       const struct ropll_config *cfg = NULL;
+       struct ropll_config rc = {0};
+-      int i;
+-
+-      hdptx->rate = rate * 100;
++      int ret, i;
+       for (i = 0; i < ARRAY_SIZE(ropll_tmds_cfg); i++)
+               if (rate == ropll_tmds_cfg[i].bit_rate) {
+@@ -1065,7 +1063,11 @@ static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx,
+       regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_CLK_EN_MASK,
+                          FIELD_PREP(PLL_PCG_CLK_EN_MASK, 0x1));
+-      return rk_hdptx_post_enable_pll(hdptx);
++      ret = rk_hdptx_post_enable_pll(hdptx);
++      if (!ret)
++              hdptx->rate = rate * 100;
++
++      return ret;
+ }
+ static int rk_hdptx_ropll_tmds_mode_config(struct rk_hdptx_phy *hdptx,
+-- 
+2.39.5
+
diff --git a/queue-6.15/phy-rockchip-samsung-hdptx-fix-clock-ratio-setup.patch b/queue-6.15/phy-rockchip-samsung-hdptx-fix-clock-ratio-setup.patch
new file mode 100644 (file)
index 0000000..9e33f63
--- /dev/null
@@ -0,0 +1,51 @@
+From 28243a8f2944e89e4627dfb5d542d7795addeabe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Mar 2025 14:35:37 +0200
+Subject: phy: rockchip: samsung-hdptx: Fix clock ratio setup
+
+From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
+
+[ Upstream commit 0422253ac1919fea8292381c85f11a9decff1bb1 ]
+
+The switch from 1/10 to 1/40 clock ratio must happen when exceeding the
+340 MHz rate limit of HDMI 1.4, i.e. when entering the HDMI 2.0 domain,
+and not before.
+
+Therefore, use the correct comparison operator '>' instead of '>=' when
+checking the max rate.  While at it, introduce a define for this rate
+limit constant.
+
+Fixes: 553be2830c5f ("phy: rockchip: Add Samsung HDMI/eDP Combo PHY driver")
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
+Link: https://lore.kernel.org/r/20250318-phy-sam-hdptx-bpc-v6-3-8cb1678e7663@collabora.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+index 77236f012a1f7..6cfed3fcd647b 100644
+--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
++++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+@@ -320,6 +320,7 @@
+ #define LN3_TX_SER_RATE_SEL_HBR2_MASK BIT(3)
+ #define LN3_TX_SER_RATE_SEL_HBR3_MASK BIT(2)
++#define HDMI14_MAX_RATE                       340000000
+ #define HDMI20_MAX_RATE                       600000000
+ enum dp_link_rate {
+@@ -1074,7 +1075,7 @@ static int rk_hdptx_ropll_tmds_mode_config(struct rk_hdptx_phy *hdptx,
+       regmap_write(hdptx->regmap, LNTOP_REG(0200), 0x06);
+-      if (rate >= 3400000) {
++      if (rate > HDMI14_MAX_RATE / 100) {
+               /* For 1/40 bitrate clk */
+               rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_lntop_highbr_seq);
+       } else {
+-- 
+2.39.5
+
diff --git a/queue-6.15/pinctrl-at91-fix-possible-out-of-boundary-access.patch b/queue-6.15/pinctrl-at91-fix-possible-out-of-boundary-access.patch
new file mode 100644 (file)
index 0000000..3e285d0
--- /dev/null
@@ -0,0 +1,50 @@
+From 00b8c504816ccbd19d34398215b7236f565aeda9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 May 2025 23:08:07 +0300
+Subject: pinctrl: at91: Fix possible out-of-boundary access
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 762ef7d1e6eefad9896560bfcb9bcf7f1b6df9c1 ]
+
+at91_gpio_probe() doesn't check that given OF alias is not available or
+something went wrong when trying to get it. This might have consequences
+when accessing gpio_chips array with that value as an index. Note, that
+BUG() can be compiled out and hence won't actually perform the required
+checks.
+
+Fixes: 6732ae5cb47c ("ARM: at91: add pinctrl support")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Closes: https://lore.kernel.org/r/202505052343.UHF1Zo93-lkp@intel.com/
+Link: https://lore.kernel.org/20250508200807.1384558-1-andriy.shevchenko@linux.intel.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/pinctrl-at91.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
+index 93ab277d9943c..fbe74e4ef320c 100644
+--- a/drivers/pinctrl/pinctrl-at91.c
++++ b/drivers/pinctrl/pinctrl-at91.c
+@@ -1819,12 +1819,16 @@ static int at91_gpio_probe(struct platform_device *pdev)
+       struct at91_gpio_chip *at91_chip = NULL;
+       struct gpio_chip *chip;
+       struct pinctrl_gpio_range *range;
++      int alias_idx;
+       int ret = 0;
+       int irq, i;
+-      int alias_idx = of_alias_get_id(np, "gpio");
+       uint32_t ngpio;
+       char **names;
++      alias_idx = of_alias_get_id(np, "gpio");
++      if (alias_idx < 0)
++              return alias_idx;
++
+       BUG_ON(alias_idx >= ARRAY_SIZE(gpio_chips));
+       if (gpio_chips[alias_idx])
+               return dev_err_probe(dev, -EBUSY, "%d slot is occupied.\n", alias_idx);
+-- 
+2.39.5
+
diff --git a/queue-6.15/pinctrl-mediatek-fix-the-invalid-conditions.patch b/queue-6.15/pinctrl-mediatek-fix-the-invalid-conditions.patch
new file mode 100644 (file)
index 0000000..e775893
--- /dev/null
@@ -0,0 +1,84 @@
+From ca19b95df2e259927e6f10d8fbf7e5e82e4db85a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 29 Mar 2025 10:40:29 +0800
+Subject: pinctrl: mediatek: Fix the invalid conditions
+
+From: Hao Chang <ot_chhao.chang@mediatek.com>
+
+[ Upstream commit 86dee87f4b2e6ac119b03810e58723d0b27787a4 ]
+
+The variable count_reg_names is defined as an int type and cannot be
+directly compared to an unsigned int. To resolve this issue,
+first verify the correctness of count_reg_names.
+
+Link: https://lore.kernel.org/all/5ae93d42e4c4e70fb33bf35dcc37caebf324c8d3.camel@mediatek.com/T/
+Signed-off-by: Hao Chang <ot_chhao.chang@mediatek.com>
+Signed-off-by: Qingliang Li <qingliang.li@mediatek.com>
+Link: https://lore.kernel.org/20250329024533.5279-1-ot_chhao.chang@mediatek.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Stable-dep-of: 1c9977b26347 ("pinctrl: mediatek: eint: Fix invalid pointer dereference for v1 platforms")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/mediatek/mtk-eint.c              | 4 ++--
+ drivers/pinctrl/mediatek/mtk-eint.h              | 2 +-
+ drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 7 +++++--
+ 3 files changed, 8 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/pinctrl/mediatek/mtk-eint.c b/drivers/pinctrl/mediatek/mtk-eint.c
+index c516c34aaaf60..e235a98ae7ee5 100644
+--- a/drivers/pinctrl/mediatek/mtk-eint.c
++++ b/drivers/pinctrl/mediatek/mtk-eint.c
+@@ -506,7 +506,7 @@ EXPORT_SYMBOL_GPL(mtk_eint_find_irq);
+ int mtk_eint_do_init(struct mtk_eint *eint, struct mtk_eint_pin *eint_pin)
+ {
+-      unsigned int size, i, port, inst = 0;
++      unsigned int size, i, port, virq, inst = 0;
+       /* If clients don't assign a specific regs, let's use generic one */
+       if (!eint->regs)
+@@ -580,7 +580,7 @@ int mtk_eint_do_init(struct mtk_eint *eint, struct mtk_eint_pin *eint_pin)
+               if (inst >= eint->nbase)
+                       continue;
+               eint->pin_list[inst][eint->pins[i].index] = i;
+-              int virq = irq_create_mapping(eint->domain, i);
++              virq = irq_create_mapping(eint->domain, i);
+               irq_set_chip_and_handler(virq, &mtk_eint_irq_chip,
+                                        handle_level_irq);
+               irq_set_chip_data(virq, eint);
+diff --git a/drivers/pinctrl/mediatek/mtk-eint.h b/drivers/pinctrl/mediatek/mtk-eint.h
+index 23801d4b636f6..fc31a4c0c77bf 100644
+--- a/drivers/pinctrl/mediatek/mtk-eint.h
++++ b/drivers/pinctrl/mediatek/mtk-eint.h
+@@ -66,7 +66,7 @@ struct mtk_eint_xt {
+ struct mtk_eint {
+       struct device *dev;
+       void __iomem **base;
+-      u8 nbase;
++      int nbase;
+       u16 *base_pin_num;
+       struct irq_domain *domain;
+       int irq;
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+index ba13558bfcd7b..4918d38abfc29 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+@@ -381,10 +381,13 @@ int mtk_build_eint(struct mtk_pinctrl *hw, struct platform_device *pdev)
+               return -ENOMEM;
+       count_reg_names = of_property_count_strings(np, "reg-names");
+-      if (count_reg_names < hw->soc->nbase_names)
++      if (count_reg_names < 0)
++              return -EINVAL;
++
++      hw->eint->nbase = count_reg_names - (int)hw->soc->nbase_names;
++      if (hw->eint->nbase <= 0)
+               return -EINVAL;
+-      hw->eint->nbase = count_reg_names - hw->soc->nbase_names;
+       hw->eint->base = devm_kmalloc_array(&pdev->dev, hw->eint->nbase,
+                                           sizeof(*hw->eint->base), GFP_KERNEL | __GFP_ZERO);
+       if (!hw->eint->base) {
+-- 
+2.39.5
+
diff --git a/queue-6.15/pinctrl-qcom-correct-the-ngpios-entry-for-qcs615.patch b/queue-6.15/pinctrl-qcom-correct-the-ngpios-entry-for-qcs615.patch
new file mode 100644 (file)
index 0000000..f5091ba
--- /dev/null
@@ -0,0 +1,39 @@
+From ea5404a34ce8c206be9d36424ad192e24536e5fe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 May 2025 14:23:00 +0800
+Subject: pinctrl: qcom: correct the ngpios entry for QCS615
+
+From: Lijuan Gao <quic_lijuang@quicinc.com>
+
+[ Upstream commit d18cdb975ba8aad7046ff82df1a963fa21082a45 ]
+
+Correct the ngpios entry to account for the UFS_RESET pin being exported
+as a GPIO in addition to the real GPIOs, allowing the UFS driver to toggle
+it.
+
+Fixes: b698f36a9d40 ("pinctrl: qcom: add the tlmm driver for QCS615 platform")
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Signed-off-by: Lijuan Gao <quic_lijuang@quicinc.com>
+Link: https://lore.kernel.org/20250506-correct_gpio_ranges-v3-3-49a7d292befa@quicinc.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/qcom/pinctrl-qcs615.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pinctrl/qcom/pinctrl-qcs615.c b/drivers/pinctrl/qcom/pinctrl-qcs615.c
+index 23015b055f6a9..17ca743c2210f 100644
+--- a/drivers/pinctrl/qcom/pinctrl-qcs615.c
++++ b/drivers/pinctrl/qcom/pinctrl-qcs615.c
+@@ -1062,7 +1062,7 @@ static const struct msm_pinctrl_soc_data qcs615_tlmm = {
+       .nfunctions = ARRAY_SIZE(qcs615_functions),
+       .groups = qcs615_groups,
+       .ngroups = ARRAY_SIZE(qcs615_groups),
+-      .ngpios = 123,
++      .ngpios = 124,
+       .tiles = qcs615_tiles,
+       .ntiles = ARRAY_SIZE(qcs615_tiles),
+       .wakeirq_map = qcs615_pdc_map,
+-- 
+2.39.5
+
diff --git a/queue-6.15/pinctrl-qcom-correct-the-ngpios-entry-for-qcs8300.patch b/queue-6.15/pinctrl-qcom-correct-the-ngpios-entry-for-qcs8300.patch
new file mode 100644 (file)
index 0000000..0a4aa3c
--- /dev/null
@@ -0,0 +1,40 @@
+From 7138c5ad5fc0d49bf987b18d26463560551b8e58 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 May 2025 14:23:01 +0800
+Subject: pinctrl: qcom: correct the ngpios entry for QCS8300
+
+From: Lijuan Gao <quic_lijuang@quicinc.com>
+
+[ Upstream commit 32b5361a0d10627343b2ded76f05e5d591627fd6 ]
+
+Correct the ngpios entry to account for the UFS_RESET pin, which is
+expected to be wired to the reset pin of the primary UFS memory and is
+exported as GPIOs in addition to the real GPIOs, allowing the UFS driver
+to toggle it.
+
+Fixes: 0c4cd2cc87c8 ("pinctrl: qcom: add the tlmm driver for QCS8300 platforms")
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Signed-off-by: Lijuan Gao <quic_lijuang@quicinc.com>
+Link: https://lore.kernel.org/20250506-correct_gpio_ranges-v3-4-49a7d292befa@quicinc.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/qcom/pinctrl-qcs8300.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pinctrl/qcom/pinctrl-qcs8300.c b/drivers/pinctrl/qcom/pinctrl-qcs8300.c
+index ba6de944a859a..5f5f7c4ac644c 100644
+--- a/drivers/pinctrl/qcom/pinctrl-qcs8300.c
++++ b/drivers/pinctrl/qcom/pinctrl-qcs8300.c
+@@ -1204,7 +1204,7 @@ static const struct msm_pinctrl_soc_data qcs8300_pinctrl = {
+       .nfunctions = ARRAY_SIZE(qcs8300_functions),
+       .groups = qcs8300_groups,
+       .ngroups = ARRAY_SIZE(qcs8300_groups),
+-      .ngpios = 133,
++      .ngpios = 134,
+       .wakeirq_map = qcs8300_pdc_map,
+       .nwakeirq_map = ARRAY_SIZE(qcs8300_pdc_map),
+       .egpio_func = 11,
+-- 
+2.39.5
+
diff --git a/queue-6.15/pinctrl-qcom-tlmm-test-fix-potential-null-dereferenc.patch b/queue-6.15/pinctrl-qcom-tlmm-test-fix-potential-null-dereferenc.patch
new file mode 100644 (file)
index 0000000..044993b
--- /dev/null
@@ -0,0 +1,38 @@
+From 7e9ffd638bc8bd09b02a0377fc5563141b07c71d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Mar 2025 17:49:32 +0800
+Subject: pinctrl: qcom: tlmm-test: Fix potential null dereference in tlmm
+ kunit test
+
+From: Charles Han <hanchunchao@inspur.com>
+
+[ Upstream commit 1938be9fbad1bd87a1dcd9c3ca88e454565f0609 ]
+
+kunit_kzalloc() may return a NULL pointer, dereferencing it without
+NULL check may lead to NULL dereference.
+Add a NULL check for grp.
+
+Fixes: c7984dc0a2b9 ("pinctrl: qcom: Add test case for TLMM interrupt handling")
+Signed-off-by: Charles Han <hanchunchao@inspur.com>
+Link: https://lore.kernel.org/20250325094932.4733-1-hanchunchao@inspur.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/qcom/tlmm-test.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/pinctrl/qcom/tlmm-test.c b/drivers/pinctrl/qcom/tlmm-test.c
+index fd02bf3a76cbc..7b99e89e0f670 100644
+--- a/drivers/pinctrl/qcom/tlmm-test.c
++++ b/drivers/pinctrl/qcom/tlmm-test.c
+@@ -547,6 +547,7 @@ static int tlmm_test_init(struct kunit *test)
+       struct tlmm_test_priv *priv;
+       priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
++      KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
+       atomic_set(&priv->intr_count, 0);
+       atomic_set(&priv->thread_count, 0);
+-- 
+2.39.5
+
diff --git a/queue-6.15/platform-chrome-cros_ec_typec-set-pin-assignment-e-i.patch b/queue-6.15/platform-chrome-cros_ec_typec-set-pin-assignment-e-i.patch
new file mode 100644 (file)
index 0000000..0b79b65
--- /dev/null
@@ -0,0 +1,56 @@
+From 87f524b5aec5944ed5ad84bf9d87bf35b3c97a14 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Apr 2025 17:48:28 +0000
+Subject: platform/chrome: cros_ec_typec: Set Pin Assignment E in DP PORT VDO
+
+From: Benson Leung <bleung@chromium.org>
+
+[ Upstream commit a9635ef0ca12e7914f42bfa7ca6a019f606c2817 ]
+
+Pin C and D are used on C-to-C cable applications including docks,
+and for USB-C adapters that convert from DP over USB-C to other
+video standards.
+
+Pin Assignment E is intended to be used with adapter from USB-C to DP
+plugs or receptacles.
+
+All Chromebook USB-C DFPs support DisplayPort Alternate Mode as the DP
+Source with support for all 3 pin assignments. Pin Assignment E is required
+in order to support if the user attaches a Pin E C-to-DP cable.
+
+Without this, the displayport.c alt mode driver will error out of
+dp_altmode_probe with an -ENODEV, as it cannot find a compatible matching
+pin assignment between the DFP_D and UFP_D.
+
+Fixes: dbb3fc0ffa95 ("platform/chrome: cros_ec_typec: Displayport support")
+
+Signed-off-by: Benson Leung <bleung@chromium.org>
+Reviewed-by: Jameson Thies <jthies@google.com>
+Reviewed-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
+Link: https://lore.kernel.org/r/20250428174828.13939-1-bleung@chromium.org
+Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/chrome/cros_ec_typec.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chrome/cros_ec_typec.c
+index d2228720991ff..7678e3d05fd36 100644
+--- a/drivers/platform/chrome/cros_ec_typec.c
++++ b/drivers/platform/chrome/cros_ec_typec.c
+@@ -22,8 +22,10 @@
+ #define DRV_NAME "cros-ec-typec"
+-#define DP_PORT_VDO   (DP_CONF_SET_PIN_ASSIGN(BIT(DP_PIN_ASSIGN_C) | BIT(DP_PIN_ASSIGN_D)) | \
+-                              DP_CAP_DFP_D | DP_CAP_RECEPTACLE)
++#define DP_PORT_VDO   (DP_CAP_DFP_D | DP_CAP_RECEPTACLE | \
++                       DP_CONF_SET_PIN_ASSIGN(BIT(DP_PIN_ASSIGN_C) | \
++                                              BIT(DP_PIN_ASSIGN_D) | \
++                                              BIT(DP_PIN_ASSIGN_E)))
+ static void cros_typec_role_switch_quirk(struct fwnode_handle *fwnode)
+ {
+-- 
+2.39.5
+
diff --git a/queue-6.15/pm-em-fix-potential-division-by-zero-error-in-em_com.patch b/queue-6.15/pm-em-fix-potential-division-by-zero-error-in-em_com.patch
new file mode 100644 (file)
index 0000000..83fc293
--- /dev/null
@@ -0,0 +1,46 @@
+From 12f802862bf5fa410af0e9dd1994278e8609cc6d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Apr 2025 09:06:13 +0800
+Subject: PM: EM: Fix potential division-by-zero error in em_compute_costs()
+
+From: Yaxiong Tian <tianyaxiong@kylinos.cn>
+
+[ Upstream commit 179c0c7044a378198adb36f2a12410ab68cc730a ]
+
+When the device is of a non-CPU type, table[i].performance won't be
+initialized in the previous em_init_performance(), resulting in division
+by zero when calculating costs in em_compute_costs().
+
+Since the 'cost' algorithm is only used for EAS energy efficiency
+calculations and is currently not utilized by other device drivers, we
+should add the _is_cpu_device(dev) check to prevent this division-by-zero
+issue.
+
+Fixes: 1b600da51073 ("PM: EM: Optimize em_cpu_energy() and remove division")
+Signed-off-by: Yaxiong Tian <tianyaxiong@kylinos.cn>
+Reviewed-by: Lukasz Luba <lukasz.luba@arm.com>
+Link: https://patch.msgid.link/tencent_7F99ED4767C1AF7889D0D8AD50F34859CE06@qq.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/power/energy_model.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/kernel/power/energy_model.c b/kernel/power/energy_model.c
+index d9b7e2b38c7a9..41606247c2776 100644
+--- a/kernel/power/energy_model.c
++++ b/kernel/power/energy_model.c
+@@ -233,6 +233,10 @@ static int em_compute_costs(struct device *dev, struct em_perf_state *table,
+       unsigned long prev_cost = ULONG_MAX;
+       int i, ret;
++      /* This is needed only for CPUs and EAS skip other devices */
++      if (!_is_cpu_device(dev))
++              return 0;
++
+       /* Compute the cost of each performance state. */
+       for (i = nr_states - 1; i >= 0; i--) {
+               unsigned long power_res, cost;
+-- 
+2.39.5
+
diff --git a/queue-6.15/pm-runtime-add-new-devm-functions.patch b/queue-6.15/pm-runtime-add-new-devm-functions.patch
new file mode 100644 (file)
index 0000000..757fc74
--- /dev/null
@@ -0,0 +1,115 @@
+From dc5f27336f5caf268118e53e52c75cc49e82fe2e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Mar 2025 20:59:26 +0100
+Subject: PM: runtime: Add new devm functions
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Bence Csókás <csokas.bence@prolan.hu>
+
+[ Upstream commit 73db799bf5efc5a04654bb3ff6c9bf63a0dfa473 ]
+
+Add `devm_pm_runtime_set_active_enabled()` and
+`devm_pm_runtime_get_noresume()` for simplifying
+common cases in drivers.
+
+Signed-off-by: Bence Csókás <csokas.bence@prolan.hu>
+Link: https://patch.msgid.link/20250327195928.680771-3-csokas.bence@prolan.hu
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Stable-dep-of: 8856eafcc05e ("spi: atmel-quadspi: Fix unbalanced pm_runtime by using devm_ API")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/power/runtime.c | 44 ++++++++++++++++++++++++++++++++++++
+ include/linux/pm_runtime.h   |  4 ++++
+ 2 files changed, 48 insertions(+)
+
+diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
+index 0e127b0329c00..205a4f8828b0a 100644
+--- a/drivers/base/power/runtime.c
++++ b/drivers/base/power/runtime.c
+@@ -1568,6 +1568,32 @@ void pm_runtime_enable(struct device *dev)
+ }
+ EXPORT_SYMBOL_GPL(pm_runtime_enable);
++static void pm_runtime_set_suspended_action(void *data)
++{
++      pm_runtime_set_suspended(data);
++}
++
++/**
++ * devm_pm_runtime_set_active_enabled - set_active version of devm_pm_runtime_enable.
++ *
++ * @dev: Device to handle.
++ */
++int devm_pm_runtime_set_active_enabled(struct device *dev)
++{
++      int err;
++
++      err = pm_runtime_set_active(dev);
++      if (err)
++              return err;
++
++      err = devm_add_action_or_reset(dev, pm_runtime_set_suspended_action, dev);
++      if (err)
++              return err;
++
++      return devm_pm_runtime_enable(dev);
++}
++EXPORT_SYMBOL_GPL(devm_pm_runtime_set_active_enabled);
++
+ static void pm_runtime_disable_action(void *data)
+ {
+       pm_runtime_dont_use_autosuspend(data);
+@@ -1590,6 +1616,24 @@ int devm_pm_runtime_enable(struct device *dev)
+ }
+ EXPORT_SYMBOL_GPL(devm_pm_runtime_enable);
++static void pm_runtime_put_noidle_action(void *data)
++{
++      pm_runtime_put_noidle(data);
++}
++
++/**
++ * devm_pm_runtime_get_noresume - devres-enabled version of pm_runtime_get_noresume.
++ *
++ * @dev: Device to handle.
++ */
++int devm_pm_runtime_get_noresume(struct device *dev)
++{
++      pm_runtime_get_noresume(dev);
++
++      return devm_add_action_or_reset(dev, pm_runtime_put_noidle_action, dev);
++}
++EXPORT_SYMBOL_GPL(devm_pm_runtime_get_noresume);
++
+ /**
+  * pm_runtime_forbid - Block runtime PM of a device.
+  * @dev: Device to handle.
+diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h
+index 7fb5a459847ef..756b842dcd309 100644
+--- a/include/linux/pm_runtime.h
++++ b/include/linux/pm_runtime.h
+@@ -96,7 +96,9 @@ extern void pm_runtime_new_link(struct device *dev);
+ extern void pm_runtime_drop_link(struct device_link *link);
+ extern void pm_runtime_release_supplier(struct device_link *link);
++int devm_pm_runtime_set_active_enabled(struct device *dev);
+ extern int devm_pm_runtime_enable(struct device *dev);
++int devm_pm_runtime_get_noresume(struct device *dev);
+ /**
+  * pm_suspend_ignore_children - Set runtime PM behavior regarding children.
+@@ -294,7 +296,9 @@ static inline bool pm_runtime_blocked(struct device *dev) { return true; }
+ static inline void pm_runtime_allow(struct device *dev) {}
+ static inline void pm_runtime_forbid(struct device *dev) {}
++static inline int devm_pm_runtime_set_active_enabled(struct device *dev) { return 0; }
+ static inline int devm_pm_runtime_enable(struct device *dev) { return 0; }
++static inline int devm_pm_runtime_get_noresume(struct device *dev) { return 0; }
+ static inline void pm_suspend_ignore_children(struct device *dev, bool enable) {}
+ static inline void pm_runtime_get_noresume(struct device *dev) {}
+-- 
+2.39.5
+
diff --git a/queue-6.15/pm-sleep-fix-power.is_suspended-cleanup-for-direct-c.patch b/queue-6.15/pm-sleep-fix-power.is_suspended-cleanup-for-direct-c.patch
new file mode 100644 (file)
index 0000000..3571415
--- /dev/null
@@ -0,0 +1,60 @@
+From a3b74dc21d52849b10b48d8f051195f85d952748 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Jun 2025 18:19:27 +0200
+Subject: PM: sleep: Fix power.is_suspended cleanup for direct-complete devices
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit d46c4c839c20a599a0eb8d73708ce401f9c7d06d ]
+
+Commit 03f1444016b7 ("PM: sleep: Fix handling devices with direct_complete
+set on errors") caused power.is_suspended to be set for devices with
+power.direct_complete set, but it forgot to ensure the clearing of that
+flag for them in device_resume(), so power.is_suspended is still set for
+them during the next system suspend-resume cycle.
+
+If that cycle is aborted in dpm_suspend(), the subsequent invocation of
+dpm_resume() will trigger a device_resume() call for every device and
+because power.is_suspended is set for the devices in question, they will
+not be skipped by device_resume() as expected which causes scary error
+messages to be logged (as appropriate).
+
+To address this issue, move the clearing of power.is_suspended in
+device_resume() immediately after the power.is_suspended check so it
+will be always cleared for all devices processed by that function.
+
+Fixes: 03f1444016b7 ("PM: sleep: Fix handling devices with direct_complete set on errors")
+Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4280
+Reported-and-tested-by: Chris Bainbridge <chris.bainbridge@gmail.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
+Link: https://patch.msgid.link/4990586.GXAFRqVoOG@rjwysocki.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/power/main.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
+index c8b0a9e29ed84..1926454c7a7e8 100644
+--- a/drivers/base/power/main.c
++++ b/drivers/base/power/main.c
+@@ -941,6 +941,8 @@ static void device_resume(struct device *dev, pm_message_t state, bool async)
+       if (!dev->power.is_suspended)
+               goto Complete;
++      dev->power.is_suspended = false;
++
+       if (dev->power.direct_complete) {
+               /*
+                * Allow new children to be added under the device after this
+@@ -1003,7 +1005,6 @@ static void device_resume(struct device *dev, pm_message_t state, bool async)
+  End:
+       error = dpm_run_callback(callback, dev, state, info);
+-      dev->power.is_suspended = false;
+       device_unlock(dev);
+       dpm_watchdog_clear(&wd);
+-- 
+2.39.5
+
diff --git a/queue-6.15/pm-sleep-print-pm-debug-messages-during-hibernation.patch b/queue-6.15/pm-sleep-print-pm-debug-messages-during-hibernation.patch
new file mode 100644 (file)
index 0000000..b9bee08
--- /dev/null
@@ -0,0 +1,80 @@
+From 5a040f6e62059db5d8e0b8d19bf1b4b87f5007d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 May 2025 14:51:47 +0200
+Subject: PM: sleep: Print PM debug messages during hibernation
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 1b17d4525bca3916644c41e01522df8fa0f8b90b ]
+
+Commit cdb8c100d8a4 ("include/linux/suspend.h: Only show pm_pr_dbg
+messages at suspend/resume") caused PM debug messages to only be
+printed during system-wide suspend and resume in progress, but it
+forgot about hibernation.
+
+Address this by adding a check for hibernation in progress to
+pm_debug_messages_should_print().
+
+Fixes: cdb8c100d8a4 ("include/linux/suspend.h: Only show pm_pr_dbg messages at suspend/resume")
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
+Link: https://patch.msgid.link/4998903.GXAFRqVoOG@rjwysocki.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/power/hibernate.c | 5 +++++
+ kernel/power/main.c      | 3 ++-
+ kernel/power/power.h     | 4 ++++
+ 3 files changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
+index 23c0f4e6cb2ff..5af9c7ee98cd4 100644
+--- a/kernel/power/hibernate.c
++++ b/kernel/power/hibernate.c
+@@ -90,6 +90,11 @@ void hibernate_release(void)
+       atomic_inc(&hibernate_atomic);
+ }
++bool hibernation_in_progress(void)
++{
++      return !atomic_read(&hibernate_atomic);
++}
++
+ bool hibernation_available(void)
+ {
+       return nohibernate == 0 &&
+diff --git a/kernel/power/main.c b/kernel/power/main.c
+index 6254814d48171..0622e7dacf172 100644
+--- a/kernel/power/main.c
++++ b/kernel/power/main.c
+@@ -613,7 +613,8 @@ bool pm_debug_messages_on __read_mostly;
+ bool pm_debug_messages_should_print(void)
+ {
+-      return pm_debug_messages_on && pm_suspend_target_state != PM_SUSPEND_ON;
++      return pm_debug_messages_on && (hibernation_in_progress() ||
++              pm_suspend_target_state != PM_SUSPEND_ON);
+ }
+ EXPORT_SYMBOL_GPL(pm_debug_messages_should_print);
+diff --git a/kernel/power/power.h b/kernel/power/power.h
+index c352dea2f67b5..f8496f40b54fa 100644
+--- a/kernel/power/power.h
++++ b/kernel/power/power.h
+@@ -71,10 +71,14 @@ extern void enable_restore_image_protection(void);
+ static inline void enable_restore_image_protection(void) {}
+ #endif /* CONFIG_STRICT_KERNEL_RWX */
++extern bool hibernation_in_progress(void);
++
+ #else /* !CONFIG_HIBERNATION */
+ static inline void hibernate_reserved_size_init(void) {}
+ static inline void hibernate_image_size_init(void) {}
++
++static inline bool hibernation_in_progress(void) { return false; }
+ #endif /* !CONFIG_HIBERNATION */
+ #define power_attr(_name) \
+-- 
+2.39.5
+
diff --git a/queue-6.15/pm-wakeup-delete-space-in-the-end-of-string-shown-by.patch b/queue-6.15/pm-wakeup-delete-space-in-the-end-of-string-shown-by.patch
new file mode 100644 (file)
index 0000000..000b88e
--- /dev/null
@@ -0,0 +1,45 @@
+From d7a7b043b1cfcb24b5c0532751bd80a62c78537f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 May 2025 17:26:51 +0800
+Subject: PM: wakeup: Delete space in the end of string shown by
+ pm_show_wakelocks()
+
+From: Zijun Hu <quic_zijuhu@quicinc.com>
+
+[ Upstream commit f0050a3e214aa941b78ad4caf122a735a24d81a6 ]
+
+pm_show_wakelocks() is called to generate a string when showing
+attributes /sys/power/wake_(lock|unlock), but the string ends
+with an unwanted space that was added back by mistake by commit
+c9d967b2ce40 ("PM: wakeup: simplify the output logic of
+pm_show_wakelocks()").
+
+Remove the unwanted space.
+
+Fixes: c9d967b2ce40 ("PM: wakeup: simplify the output logic of pm_show_wakelocks()")
+Signed-off-by: Zijun Hu <quic_zijuhu@quicinc.com>
+Link: https://patch.msgid.link/20250505-fix_power-v1-1-0f7f2c2f338c@quicinc.com
+[ rjw: Changelog edits ]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/power/wakelock.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/kernel/power/wakelock.c b/kernel/power/wakelock.c
+index 52571dcad768b..4e941999a53ba 100644
+--- a/kernel/power/wakelock.c
++++ b/kernel/power/wakelock.c
+@@ -49,6 +49,9 @@ ssize_t pm_show_wakelocks(char *buf, bool show_active)
+                       len += sysfs_emit_at(buf, len, "%s ", wl->name);
+       }
++      if (len > 0)
++              --len;
++
+       len += sysfs_emit_at(buf, len, "\n");
+       mutex_unlock(&wakelocks_lock);
+-- 
+2.39.5
+
diff --git a/queue-6.15/power-reset-at91-reset-optimize-at91_reset.patch b/queue-6.15/power-reset-at91-reset-optimize-at91_reset.patch
new file mode 100644 (file)
index 0000000..82f8d2d
--- /dev/null
@@ -0,0 +1,56 @@
+From 2461ea4bf5a76ee5e0e27933fc5917108acb6328 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Mar 2025 08:38:09 +0300
+Subject: power: reset: at91-reset: Optimize at91_reset()
+
+From: Alexander Shiyan <eagle.alexander923@gmail.com>
+
+[ Upstream commit 62d48983f215bf1dd48665913318101fa3414dcf ]
+
+This patch adds a small optimization to the low-level at91_reset()
+function, which includes:
+- Removes the extra branch, since the following store operations
+  already have proper condition checks.
+- Removes the definition of the clobber register r4, since it is
+  no longer used in the code.
+
+Fixes: fcd0532fac2a ("power: reset: at91-reset: make at91sam9g45_restart() generic")
+Signed-off-by: Alexander Shiyan <eagle.alexander923@gmail.com>
+Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Link: https://lore.kernel.org/r/20250307053809.20245-1-eagle.alexander923@gmail.com
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/reset/at91-reset.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/power/reset/at91-reset.c b/drivers/power/reset/at91-reset.c
+index 036b18a1f90f8..511f5a8f8961c 100644
+--- a/drivers/power/reset/at91-reset.c
++++ b/drivers/power/reset/at91-reset.c
+@@ -129,12 +129,11 @@ static int at91_reset(struct notifier_block *this, unsigned long mode,
+               "       str     %4, [%0, %6]\n\t"
+               /* Disable SDRAM1 accesses */
+               "1:     tst     %1, #0\n\t"
+-              "       beq     2f\n\t"
+               "       strne   %3, [%1, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t"
+               /* Power down SDRAM1 */
+               "       strne   %4, [%1, %6]\n\t"
+               /* Reset CPU */
+-              "2:     str     %5, [%2, #" __stringify(AT91_RSTC_CR) "]\n\t"
++              "       str     %5, [%2, #" __stringify(AT91_RSTC_CR) "]\n\t"
+               "       b       .\n\t"
+               :
+@@ -145,7 +144,7 @@ static int at91_reset(struct notifier_block *this, unsigned long mode,
+                 "r" cpu_to_le32(AT91_DDRSDRC_LPCB_POWER_DOWN),
+                 "r" (reset->data->reset_args),
+                 "r" (reset->ramc_lpr)
+-              : "r4");
++      );
+       return NOTIFY_DONE;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/power-supply-max77705-fix-workqueue-error-handling-i.patch b/queue-6.15/power-supply-max77705-fix-workqueue-error-handling-i.patch
new file mode 100644 (file)
index 0000000..521a5ed
--- /dev/null
@@ -0,0 +1,64 @@
+From 2f35563520ba6f75a96b5998c6892cabe34d7290 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Mar 2025 17:34:06 +0300
+Subject: power: supply: max77705: Fix workqueue error handling in probe
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 11741b8e382d34b13277497ab91123d8b0b5c2db ]
+
+The create_singlethread_workqueue() doesn't return error pointers, it
+returns NULL.  Also cleanup the workqueue on the error paths.
+
+Fixes: a6a494c8e3ce ("power: supply: max77705: Add charger driver for Maxim 77705")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/547656e3-4a5f-4f2e-802b-4edcb7c576b0@stanley.mountain
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/max77705_charger.c | 20 ++++++++++++++------
+ 1 file changed, 14 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/power/supply/max77705_charger.c b/drivers/power/supply/max77705_charger.c
+index eec5e9ef795ef..329b430d0e506 100644
+--- a/drivers/power/supply/max77705_charger.c
++++ b/drivers/power/supply/max77705_charger.c
+@@ -545,20 +545,28 @@ static int max77705_charger_probe(struct i2c_client *i2c)
+               return dev_err_probe(dev, ret, "failed to add irq chip\n");
+       chg->wqueue = create_singlethread_workqueue(dev_name(dev));
+-      if (IS_ERR(chg->wqueue))
+-              return dev_err_probe(dev, PTR_ERR(chg->wqueue), "failed to create workqueue\n");
++      if (!chg->wqueue)
++              return dev_err_probe(dev, -ENOMEM, "failed to create workqueue\n");
+       ret = devm_work_autocancel(dev, &chg->chgin_work, max77705_chgin_isr_work);
+-      if (ret)
+-              return dev_err_probe(dev, ret, "failed to initialize interrupt work\n");
++      if (ret) {
++              dev_err_probe(dev, ret, "failed to initialize interrupt work\n");
++              goto destroy_wq;
++      }
+       max77705_charger_initialize(chg);
+       ret = max77705_charger_enable(chg);
+-      if (ret)
+-              return dev_err_probe(dev, ret, "failed to enable charge\n");
++      if (ret) {
++              dev_err_probe(dev, ret, "failed to enable charge\n");
++              goto destroy_wq;
++      }
+       return devm_add_action_or_reset(dev, max77705_charger_disable, chg);
++
++destroy_wq:
++      destroy_workqueue(chg->wqueue);
++      return ret;
+ }
+ static const struct of_device_id max77705_charger_of_match[] = {
+-- 
+2.39.5
+
diff --git a/queue-6.15/powerpc-crash-fix-non-smp-kexec-preparation.patch b/queue-6.15/powerpc-crash-fix-non-smp-kexec-preparation.patch
new file mode 100644 (file)
index 0000000..1ac6746
--- /dev/null
@@ -0,0 +1,43 @@
+From 00e290a37e217af177ef01a5176b65f162dc7818 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Feb 2025 10:20:54 -0600
+Subject: powerpc/crash: Fix non-smp kexec preparation
+
+From: Eddie James <eajames@linux.ibm.com>
+
+[ Upstream commit 882b25af265de8e05c66f72b9a29f6047102958f ]
+
+In non-smp configurations, crash_kexec_prepare is never called in
+the crash shutdown path. One result of this is that the crashing_cpu
+variable is never set, preventing crash_save_cpu from storing the
+NT_PRSTATUS elf note in the core dump.
+
+Fixes: c7255058b543 ("powerpc/crash: save cpu register data in crash_smp_send_stop()")
+Signed-off-by: Eddie James <eajames@linux.ibm.com>
+Reviewed-by: Hari Bathini <hbathini@linux.ibm.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20250211162054.857762-1-eajames@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kexec/crash.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/arch/powerpc/kexec/crash.c b/arch/powerpc/kexec/crash.c
+index 9ac3266e49652..a325c1c02f96d 100644
+--- a/arch/powerpc/kexec/crash.c
++++ b/arch/powerpc/kexec/crash.c
+@@ -359,7 +359,10 @@ void default_machine_crash_shutdown(struct pt_regs *regs)
+       if (TRAP(regs) == INTERRUPT_SYSTEM_RESET)
+               is_via_system_reset = 1;
+-      crash_smp_send_stop();
++      if (IS_ENABLED(CONFIG_SMP))
++              crash_smp_send_stop();
++      else
++              crash_kexec_prepare();
+       crash_save_cpu(regs, crashing_cpu);
+-- 
+2.39.5
+
diff --git a/queue-6.15/powerpc-do-not-build-ppc_save_regs.o-always.patch b/queue-6.15/powerpc-do-not-build-ppc_save_regs.o-always.patch
new file mode 100644 (file)
index 0000000..8ee24c0
--- /dev/null
@@ -0,0 +1,44 @@
+From 242c2ba3f16d92cd81c309725550f6c723833ae3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Apr 2025 12:53:05 +0200
+Subject: powerpc: do not build ppc_save_regs.o always
+
+From: Jiri Slaby (SUSE) <jirislaby@kernel.org>
+
+[ Upstream commit 497b7794aef03d525a5be05ae78dd7137c6861a5 ]
+
+The Fixes commit below tried to add CONFIG_PPC_BOOK3S to one of the
+conditions to enable the build of ppc_save_regs.o. But it failed to do
+so, in fact. The commit omitted to add a dollar sign.
+
+Therefore, ppc_save_regs.o is built always these days (as
+"(CONFIG_PPC_BOOK3S)" is never an empty string).
+
+Fix this by adding the missing dollar sign.
+
+Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
+Fixes: fc2a5a6161a2 ("powerpc/64s: ppc_save_regs is now needed for all 64s builds")
+Acked-by: Stephen Rothwell <sfr@canb.auug.org.au>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20250417105305.397128-1-jirislaby@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
+index 6ac621155ec3c..0c26b2412d173 100644
+--- a/arch/powerpc/kernel/Makefile
++++ b/arch/powerpc/kernel/Makefile
+@@ -160,7 +160,7 @@ endif
+ obj64-$(CONFIG_PPC_TRANSACTIONAL_MEM) += tm.o
+-ifneq ($(CONFIG_XMON)$(CONFIG_KEXEC_CORE)(CONFIG_PPC_BOOK3S),)
++ifneq ($(CONFIG_XMON)$(CONFIG_KEXEC_CORE)$(CONFIG_PPC_BOOK3S),)
+ obj-y                         += ppc_save_regs.o
+ endif
+-- 
+2.39.5
+
diff --git a/queue-6.15/powerpc-pseries-iommu-fix-kmemleak-in-tce-table-user.patch b/queue-6.15/powerpc-pseries-iommu-fix-kmemleak-in-tce-table-user.patch
new file mode 100644 (file)
index 0000000..e022ec9
--- /dev/null
@@ -0,0 +1,83 @@
+From 137539ea655d00910f6a03d5894dca0949312e6c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 May 2025 17:46:53 -0500
+Subject: powerpc/pseries/iommu: Fix kmemleak in TCE table userspace view
+
+From: Gaurav Batra <gbatra@linux.ibm.com>
+
+[ Upstream commit d36e3f11fe8b55b801bdbe84ad51f612b1bd84da ]
+
+When a device is opened by a userspace driver, via VFIO interface, DMA
+window is created. This DMA window has TCE Table and a corresponding
+data for userview of TCE table.
+
+When the userspace driver closes the device, all the above infrastructure
+is free'ed and the device control given back to kernel. Both DMA window
+and TCE table is getting free'ed. But due to a code bug, userview of the
+TCE table is not getting free'ed. This is resulting in a memory leak.
+
+Befow is the information from KMEMLEAK
+
+unreferenced object 0xc008000022af0000 (size 16777216):
+  comm "senlib_unit_tes", pid 9346, jiffies 4294983174
+  hex dump (first 32 bytes):
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
+  backtrace (crc 0):
+    kmemleak_vmalloc+0xc8/0x1a0
+    __vmalloc_node_range+0x284/0x340
+    vzalloc+0x58/0x70
+    spapr_tce_create_table+0x4b0/0x8d0
+    tce_iommu_create_table+0xcc/0x170 [vfio_iommu_spapr_tce]
+    tce_iommu_create_window+0x144/0x2f0 [vfio_iommu_spapr_tce]
+    tce_iommu_ioctl.part.0+0x59c/0xc90 [vfio_iommu_spapr_tce]
+    vfio_fops_unl_ioctl+0x88/0x280 [vfio]
+    sys_ioctl+0xf4/0x160
+    system_call_exception+0x164/0x310
+    system_call_vectored_common+0xe8/0x278
+unreferenced object 0xc008000023b00000 (size 4194304):
+  comm "senlib_unit_tes", pid 9351, jiffies 4294984116
+  hex dump (first 32 bytes):
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
+  backtrace (crc 0):
+    kmemleak_vmalloc+0xc8/0x1a0
+    __vmalloc_node_range+0x284/0x340
+    vzalloc+0x58/0x70
+    spapr_tce_create_table+0x4b0/0x8d0
+    tce_iommu_create_table+0xcc/0x170 [vfio_iommu_spapr_tce]
+    tce_iommu_create_window+0x144/0x2f0 [vfio_iommu_spapr_tce]
+    tce_iommu_create_default_window+0x88/0x120 [vfio_iommu_spapr_tce]
+    tce_iommu_ioctl.part.0+0x57c/0xc90 [vfio_iommu_spapr_tce]
+    vfio_fops_unl_ioctl+0x88/0x280 [vfio]
+    sys_ioctl+0xf4/0x160
+    system_call_exception+0x164/0x310
+    system_call_vectored_common+0xe8/0x278
+
+Fixes: f431a8cde7f1 ("powerpc/iommu: Reimplement the iommu_table_group_ops for pSeries")
+Signed-off-by: Gaurav Batra <gbatra@linux.ibm.com>
+Reviewed-by: Nilay Shroff <nilay@linux.ibm.com>
+Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20250512224653.35697-1-gbatra@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/pseries/iommu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
+index d6ebc19fb99c5..eec333dd2e598 100644
+--- a/arch/powerpc/platforms/pseries/iommu.c
++++ b/arch/powerpc/platforms/pseries/iommu.c
+@@ -197,7 +197,7 @@ static void tce_iommu_userspace_view_free(struct iommu_table *tbl)
+ static void tce_free_pSeries(struct iommu_table *tbl)
+ {
+-      if (!tbl->it_userspace)
++      if (tbl->it_userspace)
+               tce_iommu_userspace_view_free(tbl);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/randstruct-gcc-plugin-fix-attribute-addition.patch b/queue-6.15/randstruct-gcc-plugin-fix-attribute-addition.patch
new file mode 100644 (file)
index 0000000..972efd9
--- /dev/null
@@ -0,0 +1,134 @@
+From bef5cc30eca8ca32bcb6ca9d5b51472b8a674118 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 May 2025 15:18:28 -0700
+Subject: randstruct: gcc-plugin: Fix attribute addition
+
+From: Kees Cook <kees@kernel.org>
+
+[ Upstream commit f39f18f3c3531aa802b58a20d39d96e82eb96c14 ]
+
+Based on changes in the 2021 public version of the randstruct
+out-of-tree GCC plugin[1], more carefully update the attributes on
+resulting decls, to avoid tripping checks in GCC 15's
+comptypes_check_enum_int() when it has been configured with
+"--enable-checking=misc":
+
+arch/arm64/kernel/kexec_image.c:132:14: internal compiler error: in comptypes_check_enum_int, at c/c-typeck.cc:1519
+  132 | const struct kexec_file_ops kexec_image_ops = {
+      |              ^~~~~~~~~~~~~~
+ internal_error(char const*, ...), at gcc/gcc/diagnostic-global-context.cc:517
+ fancy_abort(char const*, int, char const*), at gcc/gcc/diagnostic.cc:1803
+ comptypes_check_enum_int(tree_node*, tree_node*, bool*), at gcc/gcc/c/c-typeck.cc:1519
+ ...
+
+Link: https://archive.org/download/grsecurity/grsecurity-3.1-5.10.41-202105280954.patch.gz [1]
+Reported-by: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
+Closes: https://github.com/KSPP/linux/issues/367
+Closes: https://lore.kernel.org/lkml/20250530000646.104457-1-thiago.bauermann@linaro.org/
+Reported-by: Ingo Saitz <ingo@hannover.ccc.de>
+Closes: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1104745
+Fixes: 313dd1b62921 ("gcc-plugins: Add the randstruct plugin")
+Tested-by: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
+Link: https://lore.kernel.org/r/20250530221824.work.623-kees@kernel.org
+Signed-off-by: Kees Cook <kees@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/gcc-plugins/gcc-common.h              | 32 +++++++++++++++++++
+ scripts/gcc-plugins/randomize_layout_plugin.c | 22 ++++++-------
+ 2 files changed, 43 insertions(+), 11 deletions(-)
+
+diff --git a/scripts/gcc-plugins/gcc-common.h b/scripts/gcc-plugins/gcc-common.h
+index 3222c1070444f..ef12c8f929eda 100644
+--- a/scripts/gcc-plugins/gcc-common.h
++++ b/scripts/gcc-plugins/gcc-common.h
+@@ -123,6 +123,38 @@ static inline tree build_const_char_string(int len, const char *str)
+       return cstr;
+ }
++static inline void __add_type_attr(tree type, const char *attr, tree args)
++{
++      tree oldattr;
++
++      if (type == NULL_TREE)
++              return;
++      oldattr = lookup_attribute(attr, TYPE_ATTRIBUTES(type));
++      if (oldattr != NULL_TREE) {
++              gcc_assert(TREE_VALUE(oldattr) == args || TREE_VALUE(TREE_VALUE(oldattr)) == TREE_VALUE(args));
++              return;
++      }
++
++      TYPE_ATTRIBUTES(type) = copy_list(TYPE_ATTRIBUTES(type));
++      TYPE_ATTRIBUTES(type) = tree_cons(get_identifier(attr), args, TYPE_ATTRIBUTES(type));
++}
++
++static inline void add_type_attr(tree type, const char *attr, tree args)
++{
++      tree main_variant = TYPE_MAIN_VARIANT(type);
++
++      __add_type_attr(TYPE_CANONICAL(type), attr, args);
++      __add_type_attr(TYPE_CANONICAL(main_variant), attr, args);
++      __add_type_attr(main_variant, attr, args);
++
++      for (type = TYPE_NEXT_VARIANT(main_variant); type; type = TYPE_NEXT_VARIANT(type)) {
++              if (!lookup_attribute(attr, TYPE_ATTRIBUTES(type)))
++                      TYPE_ATTRIBUTES(type) = TYPE_ATTRIBUTES(main_variant);
++
++              __add_type_attr(TYPE_CANONICAL(type), attr, args);
++      }
++}
++
+ #define PASS_INFO(NAME, REF, ID, POS)         \
+ struct register_pass_info NAME##_pass_info = {        \
+       .pass = make_##NAME##_pass(),           \
+diff --git a/scripts/gcc-plugins/randomize_layout_plugin.c b/scripts/gcc-plugins/randomize_layout_plugin.c
+index 971a1908a8cc4..ff65a4f87f240 100644
+--- a/scripts/gcc-plugins/randomize_layout_plugin.c
++++ b/scripts/gcc-plugins/randomize_layout_plugin.c
+@@ -73,6 +73,9 @@ static tree handle_randomize_layout_attr(tree *node, tree name, tree args, int f
+       if (TYPE_P(*node)) {
+               type = *node;
++      } else if (TREE_CODE(*node) == FIELD_DECL) {
++              *no_add_attrs = false;
++              return NULL_TREE;
+       } else {
+               gcc_assert(TREE_CODE(*node) == TYPE_DECL);
+               type = TREE_TYPE(*node);
+@@ -348,15 +351,14 @@ static int relayout_struct(tree type)
+               TREE_CHAIN(newtree[i]) = newtree[i+1];
+       TREE_CHAIN(newtree[num_fields - 1]) = NULL_TREE;
++      add_type_attr(type, "randomize_performed", NULL_TREE);
++      add_type_attr(type, "designated_init", NULL_TREE);
++      if (has_flexarray)
++              add_type_attr(type, "has_flexarray", NULL_TREE);
++
+       main_variant = TYPE_MAIN_VARIANT(type);
+-      for (variant = main_variant; variant; variant = TYPE_NEXT_VARIANT(variant)) {
++      for (variant = main_variant; variant; variant = TYPE_NEXT_VARIANT(variant))
+               TYPE_FIELDS(variant) = newtree[0];
+-              TYPE_ATTRIBUTES(variant) = copy_list(TYPE_ATTRIBUTES(variant));
+-              TYPE_ATTRIBUTES(variant) = tree_cons(get_identifier("randomize_performed"), NULL_TREE, TYPE_ATTRIBUTES(variant));
+-              TYPE_ATTRIBUTES(variant) = tree_cons(get_identifier("designated_init"), NULL_TREE, TYPE_ATTRIBUTES(variant));
+-              if (has_flexarray)
+-                      TYPE_ATTRIBUTES(type) = tree_cons(get_identifier("has_flexarray"), NULL_TREE, TYPE_ATTRIBUTES(type));
+-      }
+       /*
+        * force a re-layout of the main variant
+@@ -424,10 +426,8 @@ static void randomize_type(tree type)
+       if (lookup_attribute("randomize_layout", TYPE_ATTRIBUTES(TYPE_MAIN_VARIANT(type))) || is_pure_ops_struct(type))
+               relayout_struct(type);
+-      for (variant = TYPE_MAIN_VARIANT(type); variant; variant = TYPE_NEXT_VARIANT(variant)) {
+-              TYPE_ATTRIBUTES(type) = copy_list(TYPE_ATTRIBUTES(type));
+-              TYPE_ATTRIBUTES(type) = tree_cons(get_identifier("randomize_considered"), NULL_TREE, TYPE_ATTRIBUTES(type));
+-      }
++      add_type_attr(type, "randomize_considered", NULL_TREE);
++
+ #ifdef __DEBUG_PLUGIN
+       fprintf(stderr, "Marking randomize_considered on struct %s\n", ORIG_TYPE_NAME(type));
+ #ifdef __DEBUG_VERBOSE
+-- 
+2.39.5
+
diff --git a/queue-6.15/randstruct-gcc-plugin-remove-bogus-void-member.patch b/queue-6.15/randstruct-gcc-plugin-remove-bogus-void-member.patch
new file mode 100644 (file)
index 0000000..402837c
--- /dev/null
@@ -0,0 +1,120 @@
+From 425eb58c185f368ef73307560ac8792005d543de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 26 Apr 2025 00:37:52 -0700
+Subject: randstruct: gcc-plugin: Remove bogus void member
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Kees Cook <kees@kernel.org>
+
+[ Upstream commit e136a4062174a9a8d1c1447ca040ea81accfa6a8 ]
+
+When building the randomized replacement tree of struct members, the
+randstruct GCC plugin would insert, as the first member, a 0-sized void
+member. This appears as though it was done to catch non-designated
+("unnamed") static initializers, which wouldn't be stable since they
+depend on the original struct layout order.
+
+This was accomplished by having the side-effect of the "void member"
+tripping an assert in GCC internals (count_type_elements) if the member
+list ever needed to be counted (e.g. for figuring out the order of members
+during a non-designated initialization), which would catch impossible type
+(void) in the struct:
+
+security/landlock/fs.c: In function ‘hook_file_ioctl_common’:
+security/landlock/fs.c:1745:61: internal compiler error: in count_type_elements, at expr.cc:7075
+ 1745 |                         .u.op = &(struct lsm_ioctlop_audit) {
+      |                                                             ^
+
+static HOST_WIDE_INT
+count_type_elements (const_tree type, bool for_ctor_p)
+{
+  switch (TREE_CODE (type))
+...
+    case VOID_TYPE:
+    default:
+      gcc_unreachable ();
+    }
+}
+
+However this is a redundant safety measure since randstruct uses the
+__designated_initializer attribute both internally and within the
+__randomized_layout attribute macro so that this would be enforced
+by the compiler directly even when randstruct was not enabled (via
+-Wdesignated-init).
+
+A recent change in Landlock ended up tripping the same member counting
+routine when using a full-struct copy initializer as part of an anonymous
+initializer. This, however, is a false positive as the initializer is
+copying between identical structs (and hence identical layouts). The
+"path" member is "struct path", a randomized struct, and is being copied
+to from another "struct path", the "f_path" member:
+
+        landlock_log_denial(landlock_cred(file->f_cred), &(struct landlock_request) {
+                .type = LANDLOCK_REQUEST_FS_ACCESS,
+                .audit = {
+                        .type = LSM_AUDIT_DATA_IOCTL_OP,
+                        .u.op = &(struct lsm_ioctlop_audit) {
+                                .path = file->f_path,
+                                .cmd = cmd,
+                        },
+                },
+       ...
+
+As can be seen with the coming randstruct KUnit test, there appears to
+be no behavioral problems with this kind of initialization when the void
+member is removed from the randstruct GCC plugin, so remove it.
+
+Reported-by: "Dr. David Alan Gilbert" <linux@treblig.org>
+Closes: https://lore.kernel.org/lkml/Z_PRaKx7q70MKgCA@gallifrey/
+Reported-by: Mark Brown <broonie@kernel.org>
+Closes: https://lore.kernel.org/lkml/20250407-kbuild-disable-gcc-plugins-v1-1-5d46ae583f5e@kernel.org/
+Reported-by: WangYuli <wangyuli@uniontech.com>
+Closes: https://lore.kernel.org/lkml/337D5D4887277B27+3c677db3-a8b9-47f0-93a4-7809355f1381@uniontech.com/
+Fixes: 313dd1b62921 ("gcc-plugins: Add the randstruct plugin")
+Signed-off-by: Kees Cook <kees@kernel.org>
+Stable-dep-of: f39f18f3c353 ("randstruct: gcc-plugin: Fix attribute addition")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/gcc-plugins/randomize_layout_plugin.c | 18 +-----------------
+ 1 file changed, 1 insertion(+), 17 deletions(-)
+
+diff --git a/scripts/gcc-plugins/randomize_layout_plugin.c b/scripts/gcc-plugins/randomize_layout_plugin.c
+index 5694df3da2e95..971a1908a8cc4 100644
+--- a/scripts/gcc-plugins/randomize_layout_plugin.c
++++ b/scripts/gcc-plugins/randomize_layout_plugin.c
+@@ -344,29 +344,13 @@ static int relayout_struct(tree type)
+       shuffle(type, (tree *)newtree, shuffle_length);
+-      /*
+-       * set up a bogus anonymous struct field designed to error out on unnamed struct initializers
+-       * as gcc provides no other way to detect such code
+-       */
+-      list = make_node(FIELD_DECL);
+-      TREE_CHAIN(list) = newtree[0];
+-      TREE_TYPE(list) = void_type_node;
+-      DECL_SIZE(list) = bitsize_zero_node;
+-      DECL_NONADDRESSABLE_P(list) = 1;
+-      DECL_FIELD_BIT_OFFSET(list) = bitsize_zero_node;
+-      DECL_SIZE_UNIT(list) = size_zero_node;
+-      DECL_FIELD_OFFSET(list) = size_zero_node;
+-      DECL_CONTEXT(list) = type;
+-      // to satisfy the constify plugin
+-      TREE_READONLY(list) = 1;
+-
+       for (i = 0; i < num_fields - 1; i++)
+               TREE_CHAIN(newtree[i]) = newtree[i+1];
+       TREE_CHAIN(newtree[num_fields - 1]) = NULL_TREE;
+       main_variant = TYPE_MAIN_VARIANT(type);
+       for (variant = main_variant; variant; variant = TYPE_NEXT_VARIANT(variant)) {
+-              TYPE_FIELDS(variant) = list;
++              TYPE_FIELDS(variant) = newtree[0];
+               TYPE_ATTRIBUTES(variant) = copy_list(TYPE_ATTRIBUTES(variant));
+               TYPE_ATTRIBUTES(variant) = tree_cons(get_identifier("randomize_performed"), NULL_TREE, TYPE_ATTRIBUTES(variant));
+               TYPE_ATTRIBUTES(variant) = tree_cons(get_identifier("designated_init"), NULL_TREE, TYPE_ATTRIBUTES(variant));
+-- 
+2.39.5
+
diff --git a/queue-6.15/rcu-cpu_stall_cputime-fix-the-hardirq-count-for-x86-.patch b/queue-6.15/rcu-cpu_stall_cputime-fix-the-hardirq-count-for-x86-.patch
new file mode 100644 (file)
index 0000000..38c5240
--- /dev/null
@@ -0,0 +1,104 @@
+From 87f103ce7b6192cb8cccb8c9c03aa93db099173c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 16 Feb 2025 16:41:09 +0800
+Subject: rcu/cpu_stall_cputime: fix the hardirq count for x86 architecture
+
+From: Yongliang Gao <leonylgao@tencent.com>
+
+[ Upstream commit da6b85598af30e9fec34d82882d7e1e39f3da769 ]
+
+When counting the number of hardirqs in the x86 architecture,
+it is essential to add arch_irq_stat_cpu to ensure accuracy.
+
+For example, a CPU loop within the rcu_read_lock function.
+
+Before:
+[   70.910184] rcu: INFO: rcu_preempt self-detected stall on CPU
+[   70.910436] rcu:     3-....: (4999 ticks this GP) idle=***
+[   70.910711] rcu:              hardirqs   softirqs   csw/system
+[   70.910870] rcu:      number:        0        657            0
+[   70.911024] rcu:     cputime:        0          0         2498   ==> 2498(ms)
+[   70.911278] rcu:     (t=5001 jiffies g=3677 q=29 ncpus=8)
+
+After:
+[   68.046132] rcu: INFO: rcu_preempt self-detected stall on CPU
+[   68.046354] rcu:     2-....: (4999 ticks this GP) idle=***
+[   68.046628] rcu:              hardirqs   softirqs   csw/system
+[   68.046793] rcu:      number:     2498        663            0
+[   68.046951] rcu:     cputime:        0          0         2496   ==> 2496(ms)
+[   68.047244] rcu:     (t=5000 jiffies g=3825 q=4 ncpus=8)
+
+Fixes: be42f00b73a0 ("rcu: Add RCU stall diagnosis information")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202501090842.SfI6QPGS-lkp@intel.com/
+Signed-off-by: Yongliang Gao <leonylgao@tencent.com>
+Reviewed-by: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
+Link: https://lore.kernel.org/r/20250216084109.3109837-1-leonylgao@gmail.com
+Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
+Signed-off-by: Joel Fernandes <joelagnelf@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/rcu/tree.c       | 10 +++++++---
+ kernel/rcu/tree.h       |  2 +-
+ kernel/rcu/tree_stall.h |  4 ++--
+ 3 files changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
+index 659f83e710486..80b10893b5038 100644
+--- a/kernel/rcu/tree.c
++++ b/kernel/rcu/tree.c
+@@ -801,6 +801,10 @@ static int rcu_watching_snap_save(struct rcu_data *rdp)
+       return 0;
+ }
++#ifndef arch_irq_stat_cpu
++#define arch_irq_stat_cpu(cpu) 0
++#endif
++
+ /*
+  * Returns positive if the specified CPU has passed through a quiescent state
+  * by virtue of being in or having passed through an dynticks idle state since
+@@ -936,9 +940,9 @@ static int rcu_watching_snap_recheck(struct rcu_data *rdp)
+                       rsrp->cputime_irq     = kcpustat_field(kcsp, CPUTIME_IRQ, cpu);
+                       rsrp->cputime_softirq = kcpustat_field(kcsp, CPUTIME_SOFTIRQ, cpu);
+                       rsrp->cputime_system  = kcpustat_field(kcsp, CPUTIME_SYSTEM, cpu);
+-                      rsrp->nr_hardirqs = kstat_cpu_irqs_sum(rdp->cpu);
+-                      rsrp->nr_softirqs = kstat_cpu_softirqs_sum(rdp->cpu);
+-                      rsrp->nr_csw = nr_context_switches_cpu(rdp->cpu);
++                      rsrp->nr_hardirqs = kstat_cpu_irqs_sum(cpu) + arch_irq_stat_cpu(cpu);
++                      rsrp->nr_softirqs = kstat_cpu_softirqs_sum(cpu);
++                      rsrp->nr_csw = nr_context_switches_cpu(cpu);
+                       rsrp->jiffies = jiffies;
+                       rsrp->gp_seq = rdp->gp_seq;
+               }
+diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h
+index a9a811d9d7a37..1bba2225e7448 100644
+--- a/kernel/rcu/tree.h
++++ b/kernel/rcu/tree.h
+@@ -168,7 +168,7 @@ struct rcu_snap_record {
+       u64             cputime_irq;    /* Accumulated cputime of hard irqs */
+       u64             cputime_softirq;/* Accumulated cputime of soft irqs */
+       u64             cputime_system; /* Accumulated cputime of kernel tasks */
+-      unsigned long   nr_hardirqs;    /* Accumulated number of hard irqs */
++      u64             nr_hardirqs;    /* Accumulated number of hard irqs */
+       unsigned int    nr_softirqs;    /* Accumulated number of soft irqs */
+       unsigned long long nr_csw;      /* Accumulated number of task switches */
+       unsigned long   jiffies;        /* Track jiffies value */
+diff --git a/kernel/rcu/tree_stall.h b/kernel/rcu/tree_stall.h
+index 925fcdad5dea2..56b21219442b6 100644
+--- a/kernel/rcu/tree_stall.h
++++ b/kernel/rcu/tree_stall.h
+@@ -435,8 +435,8 @@ static void print_cpu_stat_info(int cpu)
+       rsr.cputime_system  = kcpustat_field(kcsp, CPUTIME_SYSTEM, cpu);
+       pr_err("\t         hardirqs   softirqs   csw/system\n");
+-      pr_err("\t number: %8ld %10d %12lld\n",
+-              kstat_cpu_irqs_sum(cpu) - rsrp->nr_hardirqs,
++      pr_err("\t number: %8lld %10d %12lld\n",
++              kstat_cpu_irqs_sum(cpu) + arch_irq_stat_cpu(cpu) - rsrp->nr_hardirqs,
+               kstat_cpu_softirqs_sum(cpu) - rsrp->nr_softirqs,
+               nr_context_switches_cpu(cpu) - rsrp->nr_csw);
+       pr_err("\tcputime: %8lld %10lld %12lld   ==> %d(ms)\n",
+-- 
+2.39.5
+
diff --git a/queue-6.15/rdma-bnxt_re-fix-incorrect-display-of-inactivity_cp-.patch b/queue-6.15/rdma-bnxt_re-fix-incorrect-display-of-inactivity_cp-.patch
new file mode 100644 (file)
index 0000000..a3cb5c5
--- /dev/null
@@ -0,0 +1,54 @@
+From 6f86b3dde4b89eb85466e1b81c711fb90e82fd46 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 May 2025 09:29:07 +0530
+Subject: RDMA/bnxt_re: Fix incorrect display of inactivity_cp in debugfs
+ output
+
+From: Gautam R A <gautam-r.a@broadcom.com>
+
+[ Upstream commit 58d7a965bb2b014d467445d38cdb07099b1f0f77 ]
+
+The inactivity_cp parameter in debugfs was not being read or
+written correctly, resulting in "Invalid argument" errors.
+
+Fixed this by ensuring proper mapping of inactivity_cp in
+both the map_cc_config_offset_gen0_ext0 and
+bnxt_re_fill_gen0_ext0() functions.
+
+Fixes: 656dff55da19 ("RDMA/bnxt_re: Congestion control settings using debugfs hook")
+Signed-off-by: Gautam R A <gautam-r.a@broadcom.com>
+Link: https://patch.msgid.link/20250520035910.1061918-2-kalesh-anakkur.purayil@broadcom.com
+Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/bnxt_re/debugfs.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/infiniband/hw/bnxt_re/debugfs.c b/drivers/infiniband/hw/bnxt_re/debugfs.c
+index af91d16c3c77f..a3aad6c3dbec1 100644
+--- a/drivers/infiniband/hw/bnxt_re/debugfs.c
++++ b/drivers/infiniband/hw/bnxt_re/debugfs.c
+@@ -170,6 +170,9 @@ static int map_cc_config_offset_gen0_ext0(u32 offset, struct bnxt_qplib_cc_param
+       case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TCP_CP:
+               *val =  ccparam->tcp_cp;
+               break;
++      case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_INACTIVITY_CP:
++              *val = ccparam->inact_th;
++              break;
+       default:
+               return -EINVAL;
+       }
+@@ -247,7 +250,9 @@ static void bnxt_re_fill_gen0_ext0(struct bnxt_qplib_cc_param *ccparam, u32 offs
+               ccparam->tcp_cp = val;
+               break;
+       case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TX_QUEUE:
++              break;
+       case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_INACTIVITY_CP:
++              ccparam->inact_th = val;
+               break;
+       case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TIME_PER_PHASE:
+               ccparam->time_pph = val;
+-- 
+2.39.5
+
diff --git a/queue-6.15/rdma-bnxt_re-fix-missing-error-handling-for-tx_queue.patch b/queue-6.15/rdma-bnxt_re-fix-missing-error-handling-for-tx_queue.patch
new file mode 100644 (file)
index 0000000..6feb46b
--- /dev/null
@@ -0,0 +1,77 @@
+From e30b53bbf84bae6b437143419c59000459953c49 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 May 2025 09:29:08 +0530
+Subject: RDMA/bnxt_re: Fix missing error handling for tx_queue
+
+From: Gautam R A <gautam-r.a@broadcom.com>
+
+[ Upstream commit e3d57a00d4d1f36689e9eab80b60d5024361efec ]
+
+bnxt_re_fill_gen0_ext0() did not return an error when
+attempting to modify CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TX_QUEUE,
+leading to silent failures.
+
+Fixed this by returning -EOPNOTSUPP for tx_queue modifications and
+ensuring proper error propagation in bnxt_re_configure_cc().
+
+Fixes: 656dff55da19 ("RDMA/bnxt_re: Congestion control settings using debugfs hook")
+Signed-off-by: Gautam R A <gautam-r.a@broadcom.com>
+Link: https://patch.msgid.link/20250520035910.1061918-3-kalesh-anakkur.purayil@broadcom.com
+Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/bnxt_re/debugfs.c | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/infiniband/hw/bnxt_re/debugfs.c b/drivers/infiniband/hw/bnxt_re/debugfs.c
+index a3aad6c3dbec1..9f6392155d915 100644
+--- a/drivers/infiniband/hw/bnxt_re/debugfs.c
++++ b/drivers/infiniband/hw/bnxt_re/debugfs.c
+@@ -206,7 +206,7 @@ static ssize_t bnxt_re_cc_config_get(struct file *filp, char __user *buffer,
+       return simple_read_from_buffer(buffer, usr_buf_len, ppos, (u8 *)(buf), rc);
+ }
+-static void bnxt_re_fill_gen0_ext0(struct bnxt_qplib_cc_param *ccparam, u32 offset, u32 val)
++static int bnxt_re_fill_gen0_ext0(struct bnxt_qplib_cc_param *ccparam, u32 offset, u32 val)
+ {
+       u32 modify_mask;
+@@ -250,7 +250,7 @@ static void bnxt_re_fill_gen0_ext0(struct bnxt_qplib_cc_param *ccparam, u32 offs
+               ccparam->tcp_cp = val;
+               break;
+       case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TX_QUEUE:
+-              break;
++              return -EOPNOTSUPP;
+       case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_INACTIVITY_CP:
+               ccparam->inact_th = val;
+               break;
+@@ -263,18 +263,21 @@ static void bnxt_re_fill_gen0_ext0(struct bnxt_qplib_cc_param *ccparam, u32 offs
+       }
+       ccparam->mask = modify_mask;
++      return 0;
+ }
+ static int bnxt_re_configure_cc(struct bnxt_re_dev *rdev, u32 gen_ext, u32 offset, u32 val)
+ {
+       struct bnxt_qplib_cc_param ccparam = { };
++      int rc;
+-      /* Supporting only Gen 0 now */
+-      if (gen_ext == CC_CONFIG_GEN0_EXT0)
+-              bnxt_re_fill_gen0_ext0(&ccparam, offset, val);
+-      else
++      if (gen_ext != CC_CONFIG_GEN0_EXT0)
+               return -EINVAL;
++      rc = bnxt_re_fill_gen0_ext0(&ccparam, offset, val);
++      if (rc)
++              return rc;
++
+       bnxt_qplib_modify_cc(&rdev->qplib_res, &ccparam);
+       return 0;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/rdma-bnxt_re-fix-return-code-of-bnxt_re_configure_cc.patch b/queue-6.15/rdma-bnxt_re-fix-return-code-of-bnxt_re_configure_cc.patch
new file mode 100644 (file)
index 0000000..60143c5
--- /dev/null
@@ -0,0 +1,40 @@
+From d596aebc0ae6e8262d045b3b1b05833f6e9e8911 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 May 2025 09:29:09 +0530
+Subject: RDMA/bnxt_re: Fix return code of bnxt_re_configure_cc
+
+From: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+
+[ Upstream commit 990b5c07f677a0b633b41130a70771337c18343e ]
+
+Driver currently supports modifying GEN0_EXT0 CC parameters
+through debugfs hook.
+
+Fixed to return -EOPNOTSUPP instead of -EINVAL in bnxt_re_configure_cc()
+when the user tries to modify any other CC parameters.
+
+Fixes: 656dff55da19 ("RDMA/bnxt_re: Congestion control settings using debugfs hook")
+Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Link: https://patch.msgid.link/20250520035910.1061918-4-kalesh-anakkur.purayil@broadcom.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/bnxt_re/debugfs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/bnxt_re/debugfs.c b/drivers/infiniband/hw/bnxt_re/debugfs.c
+index 9f6392155d915..e632f1661b929 100644
+--- a/drivers/infiniband/hw/bnxt_re/debugfs.c
++++ b/drivers/infiniband/hw/bnxt_re/debugfs.c
+@@ -272,7 +272,7 @@ static int bnxt_re_configure_cc(struct bnxt_re_dev *rdev, u32 gen_ext, u32 offse
+       int rc;
+       if (gen_ext != CC_CONFIG_GEN0_EXT0)
+-              return -EINVAL;
++              return -EOPNOTSUPP;
+       rc = bnxt_re_fill_gen0_ext0(&ccparam, offset, val);
+       if (rc)
+-- 
+2.39.5
+
diff --git a/queue-6.15/rdma-cma-fix-hang-when-cma_netevent_callback-fails-t.patch b/queue-6.15/rdma-cma-fix-hang-when-cma_netevent_callback-fails-t.patch
new file mode 100644 (file)
index 0000000..d02ce5e
--- /dev/null
@@ -0,0 +1,52 @@
+From 0451bdefac1529bb249bb867ba3661d227ed6a9c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 May 2025 14:36:02 +0300
+Subject: RDMA/cma: Fix hang when cma_netevent_callback fails to queue_work
+
+From: Jack Morgenstein <jackm@nvidia.com>
+
+[ Upstream commit 92a251c3df8ea1991cd9fe00f1ab0cfce18d7711 ]
+
+The cited commit fixed a crash when cma_netevent_callback was called for
+a cma_id while work on that id from a previous call had not yet started.
+The work item was re-initialized in the second call, which corrupted the
+work item currently in the work queue.
+
+However, it left a problem when queue_work fails (because the item is
+still pending in the work queue from a previous call). In this case,
+cma_id_put (which is called in the work handler) is therefore not
+called. This results in a userspace process hang (zombie process).
+
+Fix this by calling cma_id_put() if queue_work fails.
+
+Fixes: 45f5dcdd0497 ("RDMA/cma: Fix workqueue crash in cma_netevent_work_handler")
+Link: https://patch.msgid.link/r/4f3640b501e48d0166f312a64fdadf72b059bd04.1747827103.git.leon@kernel.org
+Signed-off-by: Jack Morgenstein <jackm@nvidia.com>
+Signed-off-by: Feng Liu <feliu@nvidia.com>
+Reviewed-by: Vlad Dumitrescu <vdumitrescu@nvidia.com>
+Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
+Reviewed-by: Sharath Srinivasan <sharath.srinivasan@oracle.com>
+Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/cma.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
+index ab31eefa916b3..274cfbd5aaba7 100644
+--- a/drivers/infiniband/core/cma.c
++++ b/drivers/infiniband/core/cma.c
+@@ -5245,7 +5245,8 @@ static int cma_netevent_callback(struct notifier_block *self,
+                          neigh->ha, ETH_ALEN))
+                       continue;
+               cma_id_get(current_id);
+-              queue_work(cma_wq, &current_id->id.net_work);
++              if (!queue_work(cma_wq, &current_id->id.net_work))
++                      cma_id_put(current_id);
+       }
+ out:
+       spin_unlock_irqrestore(&id_table_lock, flags);
+-- 
+2.39.5
+
diff --git a/queue-6.15/rdma-hns-include-hnae3.h-in-hns_roce_hw_v2.h.patch b/queue-6.15/rdma-hns-include-hnae3.h-in-hns_roce_hw_v2.h.patch
new file mode 100644 (file)
index 0000000..9948d3f
--- /dev/null
@@ -0,0 +1,93 @@
+From 1bc67fdeab1ab3a47ae2eb6585cc08bcf86f853d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Apr 2025 21:27:49 +0800
+Subject: RDMA/hns: Include hnae3.h in hns_roce_hw_v2.h
+
+From: Junxian Huang <huangjunxian6@hisilicon.com>
+
+[ Upstream commit 2b11d33de23262cb20d1dcb24b586dbb8f54d463 ]
+
+hns_roce_hw_v2.h has a direct dependency on hnae3.h due to the
+inline function hns_roce_write64(), but it doesn't include this
+header currently. This leads to that files including
+hns_roce_hw_v2.h must also include hnae3.h to avoid compilation
+errors, even if they themselves don't really rely on hnae3.h.
+This doesn't make sense, hns_roce_hw_v2.h should include hnae3.h
+directly.
+
+Fixes: d3743fa94ccd ("RDMA/hns: Fix the chip hanging caused by sending doorbell during reset")
+Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com>
+Link: https://patch.msgid.link/20250421132750.1363348-6-huangjunxian6@hisilicon.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_ah.c       | 1 -
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.c    | 1 -
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.h    | 1 +
+ drivers/infiniband/hw/hns/hns_roce_main.c     | 1 -
+ drivers/infiniband/hw/hns/hns_roce_restrack.c | 1 -
+ 5 files changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_ah.c b/drivers/infiniband/hw/hns/hns_roce_ah.c
+index 4fc5b9d5fea87..307c35888b300 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_ah.c
++++ b/drivers/infiniband/hw/hns/hns_roce_ah.c
+@@ -33,7 +33,6 @@
+ #include <linux/pci.h>
+ #include <rdma/ib_addr.h>
+ #include <rdma/ib_cache.h>
+-#include "hnae3.h"
+ #include "hns_roce_device.h"
+ #include "hns_roce_hw_v2.h"
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+index 160e8927d364e..59352d1b62099 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -43,7 +43,6 @@
+ #include <rdma/ib_umem.h>
+ #include <rdma/uverbs_ioctl.h>
+-#include "hnae3.h"
+ #include "hns_roce_common.h"
+ #include "hns_roce_device.h"
+ #include "hns_roce_cmd.h"
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
+index 91a5665465ffb..bc7466830eaf9 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
+@@ -34,6 +34,7 @@
+ #define _HNS_ROCE_HW_V2_H
+ #include <linux/bitops.h>
++#include "hnae3.h"
+ #define HNS_ROCE_V2_MAX_RC_INL_INN_SZ         32
+ #define HNS_ROCE_V2_MTT_ENTRY_SZ              64
+diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c
+index 8d0b63d4b50a6..e7a497cc125cc 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_main.c
++++ b/drivers/infiniband/hw/hns/hns_roce_main.c
+@@ -37,7 +37,6 @@
+ #include <rdma/ib_smi.h>
+ #include <rdma/ib_user_verbs.h>
+ #include <rdma/ib_cache.h>
+-#include "hnae3.h"
+ #include "hns_roce_common.h"
+ #include "hns_roce_device.h"
+ #include "hns_roce_hem.h"
+diff --git a/drivers/infiniband/hw/hns/hns_roce_restrack.c b/drivers/infiniband/hw/hns/hns_roce_restrack.c
+index 356d988169497..f637b73b946e4 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_restrack.c
++++ b/drivers/infiniband/hw/hns/hns_roce_restrack.c
+@@ -4,7 +4,6 @@
+ #include <rdma/rdma_cm.h>
+ #include <rdma/restrack.h>
+ #include <uapi/rdma/rdma_netlink.h>
+-#include "hnae3.h"
+ #include "hns_roce_common.h"
+ #include "hns_roce_device.h"
+ #include "hns_roce_hw_v2.h"
+-- 
+2.39.5
+
diff --git a/queue-6.15/rdma-mlx5-fix-error-flow-upon-firmware-failure-for-r.patch b/queue-6.15/rdma-mlx5-fix-error-flow-upon-firmware-failure-for-r.patch
new file mode 100644 (file)
index 0000000..8c1ccbe
--- /dev/null
@@ -0,0 +1,140 @@
+From a157c2a883eede85054ee8d2e842607ac16791c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Apr 2025 14:34:07 +0300
+Subject: RDMA/mlx5: Fix error flow upon firmware failure for RQ destruction
+
+From: Patrisious Haddad <phaddad@nvidia.com>
+
+[ Upstream commit 5d2ea5aebbb2f3ebde4403f9c55b2b057e5dd2d6 ]
+
+Upon RQ destruction if the firmware command fails which is the
+last resource to be destroyed some SW resources were already cleaned
+regardless of the failure.
+
+Now properly rollback the object to its original state upon such failure.
+
+In order to avoid a use-after free in case someone tries to destroy the
+object again, which results in the following kernel trace:
+refcount_t: underflow; use-after-free.
+WARNING: CPU: 0 PID: 37589 at lib/refcount.c:28 refcount_warn_saturate+0xf4/0x148
+Modules linked in: rdma_ucm(OE) rdma_cm(OE) iw_cm(OE) ib_ipoib(OE) ib_cm(OE) ib_umad(OE) mlx5_ib(OE) rfkill mlx5_core(OE) mlxdevm(OE) ib_uverbs(OE) ib_core(OE) psample mlxfw(OE) mlx_compat(OE) macsec tls pci_hyperv_intf sunrpc vfat fat virtio_net net_failover failover fuse loop nfnetlink vsock_loopback vmw_vsock_virtio_transport_common vmw_vsock_vmci_transport vmw_vmci vsock xfs crct10dif_ce ghash_ce sha2_ce sha256_arm64 sha1_ce virtio_console virtio_gpu virtio_blk virtio_dma_buf virtio_mmio dm_mirror dm_region_hash dm_log dm_mod xpmem(OE)
+CPU: 0 UID: 0 PID: 37589 Comm: python3 Kdump: loaded Tainted: G           OE     -------  ---  6.12.0-54.el10.aarch64 #1
+Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
+Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015
+pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+pc : refcount_warn_saturate+0xf4/0x148
+lr : refcount_warn_saturate+0xf4/0x148
+sp : ffff80008b81b7e0
+x29: ffff80008b81b7e0 x28: ffff000133d51600 x27: 0000000000000001
+x26: 0000000000000000 x25: 00000000ffffffea x24: ffff00010ae80f00
+x23: ffff00010ae80f80 x22: ffff0000c66e5d08 x21: 0000000000000000
+x20: ffff0000c66e0000 x19: ffff00010ae80340 x18: 0000000000000006
+x17: 0000000000000000 x16: 0000000000000020 x15: ffff80008b81b37f
+x14: 0000000000000000 x13: 2e656572662d7265 x12: ffff80008283ef78
+x11: ffff80008257efd0 x10: ffff80008283efd0 x9 : ffff80008021ed90
+x8 : 0000000000000001 x7 : 00000000000bffe8 x6 : c0000000ffff7fff
+x5 : ffff0001fb8e3408 x4 : 0000000000000000 x3 : ffff800179993000
+x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff000133d51600
+Call trace:
+ refcount_warn_saturate+0xf4/0x148
+ mlx5_core_put_rsc+0x88/0xa0 [mlx5_ib]
+ mlx5_core_destroy_rq_tracked+0x64/0x98 [mlx5_ib]
+ mlx5_ib_destroy_wq+0x34/0x80 [mlx5_ib]
+ ib_destroy_wq_user+0x30/0xc0 [ib_core]
+ uverbs_free_wq+0x28/0x58 [ib_uverbs]
+ destroy_hw_idr_uobject+0x34/0x78 [ib_uverbs]
+ uverbs_destroy_uobject+0x48/0x240 [ib_uverbs]
+ __uverbs_cleanup_ufile+0xd4/0x1a8 [ib_uverbs]
+ uverbs_destroy_ufile_hw+0x48/0x120 [ib_uverbs]
+ ib_uverbs_close+0x2c/0x100 [ib_uverbs]
+ __fput+0xd8/0x2f0
+ __fput_sync+0x50/0x70
+ __arm64_sys_close+0x40/0x90
+ invoke_syscall.constprop.0+0x74/0xd0
+ do_el0_svc+0x48/0xe8
+ el0_svc+0x44/0x1d0
+ el0t_64_sync_handler+0x120/0x130
+ el0t_64_sync+0x1a4/0x1a8
+
+Fixes: e2013b212f9f ("net/mlx5_core: Add RQ and SQ event handling")
+Signed-off-by: Patrisious Haddad <phaddad@nvidia.com>
+Link: https://patch.msgid.link/3181433ccdd695c63560eeeb3f0c990961732101.1745839855.git.leon@kernel.org
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/mlx5/qpc.c | 30 ++++++++++++++++++++++++++++--
+ include/linux/mlx5/driver.h      |  1 +
+ 2 files changed, 29 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/hw/mlx5/qpc.c b/drivers/infiniband/hw/mlx5/qpc.c
+index d3dcc272200af..146d03ae40bd9 100644
+--- a/drivers/infiniband/hw/mlx5/qpc.c
++++ b/drivers/infiniband/hw/mlx5/qpc.c
+@@ -21,8 +21,10 @@ mlx5_get_rsc(struct mlx5_qp_table *table, u32 rsn)
+       spin_lock_irqsave(&table->lock, flags);
+       common = radix_tree_lookup(&table->tree, rsn);
+-      if (common)
++      if (common && !common->invalid)
+               refcount_inc(&common->refcount);
++      else
++              common = NULL;
+       spin_unlock_irqrestore(&table->lock, flags);
+@@ -178,6 +180,18 @@ static int create_resource_common(struct mlx5_ib_dev *dev,
+       return 0;
+ }
++static void modify_resource_common_state(struct mlx5_ib_dev *dev,
++                                       struct mlx5_core_qp *qp,
++                                       bool invalid)
++{
++      struct mlx5_qp_table *table = &dev->qp_table;
++      unsigned long flags;
++
++      spin_lock_irqsave(&table->lock, flags);
++      qp->common.invalid = invalid;
++      spin_unlock_irqrestore(&table->lock, flags);
++}
++
+ static void destroy_resource_common(struct mlx5_ib_dev *dev,
+                                   struct mlx5_core_qp *qp)
+ {
+@@ -609,8 +623,20 @@ int mlx5_core_create_rq_tracked(struct mlx5_ib_dev *dev, u32 *in, int inlen,
+ int mlx5_core_destroy_rq_tracked(struct mlx5_ib_dev *dev,
+                                struct mlx5_core_qp *rq)
+ {
++      int ret;
++
++      /* The rq destruction can be called again in case it fails, hence we
++       * mark the common resource as invalid and only once FW destruction
++       * is completed successfully we actually destroy the resources.
++       */
++      modify_resource_common_state(dev, rq, true);
++      ret = destroy_rq_tracked(dev, rq->qpn, rq->uid);
++      if (ret) {
++              modify_resource_common_state(dev, rq, false);
++              return ret;
++      }
+       destroy_resource_common(dev, rq);
+-      return destroy_rq_tracked(dev, rq->qpn, rq->uid);
++      return 0;
+ }
+ static void destroy_sq_tracked(struct mlx5_ib_dev *dev, u32 sqn, u16 uid)
+diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
+index d1dfbad9a4473..e6ba8f4f4bd1f 100644
+--- a/include/linux/mlx5/driver.h
++++ b/include/linux/mlx5/driver.h
+@@ -398,6 +398,7 @@ struct mlx5_core_rsc_common {
+       enum mlx5_res_type      res;
+       refcount_t              refcount;
+       struct completion       free;
++      bool                    invalid;
+ };
+ struct mlx5_uars_page {
+-- 
+2.39.5
+
diff --git a/queue-6.15/rdma-rxe-fix-trying-to-register-non-static-key-in-rx.patch b/queue-6.15/rdma-rxe-fix-trying-to-register-non-static-key-in-rx.patch
new file mode 100644 (file)
index 0000000..24734c5
--- /dev/null
@@ -0,0 +1,90 @@
+From f6231eef244c546012b33725d93d26a0b0edf9ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Apr 2025 10:07:41 +0200
+Subject: RDMA/rxe: Fix "trying to register non-static key in
+ rxe_qp_do_cleanup" bug
+
+From: Zhu Yanjun <yanjun.zhu@linux.dev>
+
+[ Upstream commit 1c7eec4d5f3b39cdea2153abaebf1b7229a47072 ]
+
+Call Trace:
+ <TASK>
+ __dump_stack lib/dump_stack.c:94 [inline]
+ dump_stack_lvl+0x116/0x1f0 lib/dump_stack.c:120
+ assign_lock_key kernel/locking/lockdep.c:986 [inline]
+ register_lock_class+0x4a3/0x4c0 kernel/locking/lockdep.c:1300
+ __lock_acquire+0x99/0x1ba0 kernel/locking/lockdep.c:5110
+ lock_acquire kernel/locking/lockdep.c:5866 [inline]
+ lock_acquire+0x179/0x350 kernel/locking/lockdep.c:5823
+ __timer_delete_sync+0x152/0x1b0 kernel/time/timer.c:1644
+ rxe_qp_do_cleanup+0x5c3/0x7e0 drivers/infiniband/sw/rxe/rxe_qp.c:815
+ execute_in_process_context+0x3a/0x160 kernel/workqueue.c:4596
+ __rxe_cleanup+0x267/0x3c0 drivers/infiniband/sw/rxe/rxe_pool.c:232
+ rxe_create_qp+0x3f7/0x5f0 drivers/infiniband/sw/rxe/rxe_verbs.c:604
+ create_qp+0x62d/0xa80 drivers/infiniband/core/verbs.c:1250
+ ib_create_qp_kernel+0x9f/0x310 drivers/infiniband/core/verbs.c:1361
+ ib_create_qp include/rdma/ib_verbs.h:3803 [inline]
+ rdma_create_qp+0x10c/0x340 drivers/infiniband/core/cma.c:1144
+ rds_ib_setup_qp+0xc86/0x19a0 net/rds/ib_cm.c:600
+ rds_ib_cm_initiate_connect+0x1e8/0x3d0 net/rds/ib_cm.c:944
+ rds_rdma_cm_event_handler_cmn+0x61f/0x8c0 net/rds/rdma_transport.c:109
+ cma_cm_event_handler+0x94/0x300 drivers/infiniband/core/cma.c:2184
+ cma_work_handler+0x15b/0x230 drivers/infiniband/core/cma.c:3042
+ process_one_work+0x9cc/0x1b70 kernel/workqueue.c:3238
+ process_scheduled_works kernel/workqueue.c:3319 [inline]
+ worker_thread+0x6c8/0xf10 kernel/workqueue.c:3400
+ kthread+0x3c2/0x780 kernel/kthread.c:464
+ ret_from_fork+0x45/0x80 arch/x86/kernel/process.c:153
+ ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
+ </TASK>
+
+The root cause is as below:
+
+In the function rxe_create_qp, the function rxe_qp_from_init is called
+to create qp, if this function rxe_qp_from_init fails, rxe_cleanup will
+be called to handle all the allocated resources, including the timers:
+retrans_timer and rnr_nak_timer.
+
+The function rxe_qp_from_init calls the function rxe_qp_init_req to
+initialize the timers: retrans_timer and rnr_nak_timer.
+
+But these timers are initialized in the end of rxe_qp_init_req.
+If some errors occur before the initialization of these timers, this
+problem will occur.
+
+The solution is to check whether these timers are initialized or not.
+If these timers are not initialized, ignore these timers.
+
+Fixes: 8700e3e7c485 ("Soft RoCE driver")
+Reported-by: syzbot+4edb496c3cad6e953a31@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=4edb496c3cad6e953a31
+Signed-off-by: Zhu Yanjun <yanjun.zhu@linux.dev>
+Link: https://patch.msgid.link/20250419080741.1515231-1-yanjun.zhu@linux.dev
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/rxe/rxe_qp.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c
+index 7975fb0e2782f..f2af3e0aef35b 100644
+--- a/drivers/infiniband/sw/rxe/rxe_qp.c
++++ b/drivers/infiniband/sw/rxe/rxe_qp.c
+@@ -811,7 +811,12 @@ static void rxe_qp_do_cleanup(struct work_struct *work)
+       spin_unlock_irqrestore(&qp->state_lock, flags);
+       qp->qp_timeout_jiffies = 0;
+-      if (qp_type(qp) == IB_QPT_RC) {
++      /* In the function timer_setup, .function is initialized. If .function
++       * is NULL, it indicates the function timer_setup is not called, the
++       * timer is not initialized. Or else, the timer is initialized.
++       */
++      if (qp_type(qp) == IB_QPT_RC && qp->retrans_timer.function &&
++              qp->rnr_nak_timer.function) {
+               timer_delete_sync(&qp->retrans_timer);
+               timer_delete_sync(&qp->rnr_nak_timer);
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/remoteproc-k3-dsp-drop-check-performed-in-k3_dsp_rpr.patch b/queue-6.15/remoteproc-k3-dsp-drop-check-performed-in-k3_dsp_rpr.patch
new file mode 100644 (file)
index 0000000..4557c9a
--- /dev/null
@@ -0,0 +1,64 @@
+From 8cdbf348e9e56428a03226ad431791aa64c3a3dc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 May 2025 11:14:36 +0530
+Subject: remoteproc: k3-dsp: Drop check performed in
+ k3_dsp_rproc_{mbox_callback/kick}
+
+From: Siddharth Vadapalli <s-vadapalli@ti.com>
+
+[ Upstream commit 349d62ab207f55f039c3ddb40b36e95c2f0b3ed0 ]
+
+Commit ea1d6fb5b571 ("remoteproc: k3-dsp: Acquire mailbox handle during
+probe routine") introduced a check in the "k3_dsp_rproc_mbox_callback()"
+and "k3_dsp_rproc_kick()" callbacks, causing them to exit if the remote
+core's state is "RPROC_DETACHED". However, the "__rproc_attach()"
+function that is responsible for attaching to a remote core, updates the
+state of the remote core to "RPROC_ATTACHED" only after invoking
+"rproc_start_subdevices()".
+
+The "rproc_start_subdevices()" function triggers the probe of the Virtio
+RPMsg devices associated with the remote core, which require that the
+"k3_dsp_rproc_kick()" and "k3_dsp_rproc_mbox_callback()" callbacks are
+functional. Hence, drop the check in the callbacks.
+
+Fixes: ea1d6fb5b571 ("remoteproc: k3-dsp: Acquire mailbox handle during probe routine")
+Signed-off-by: Siddharth Vadapalli <s-vadapalli@ti.com>
+Signed-off-by: Beleswar Padhi <b-padhi@ti.com>
+Tested-by: Judith Mendez <jm@ti.com>
+Reviewed-by: Andrew Davis <afd@ti.com>
+Link: https://lore.kernel.org/r/20250513054510.3439842-3-b-padhi@ti.com
+Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/ti_k3_dsp_remoteproc.c | 8 --------
+ 1 file changed, 8 deletions(-)
+
+diff --git a/drivers/remoteproc/ti_k3_dsp_remoteproc.c b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
+index a695890254ff7..35e8c3cc313c3 100644
+--- a/drivers/remoteproc/ti_k3_dsp_remoteproc.c
++++ b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
+@@ -115,10 +115,6 @@ static void k3_dsp_rproc_mbox_callback(struct mbox_client *client, void *data)
+       const char *name = kproc->rproc->name;
+       u32 msg = omap_mbox_message(data);
+-      /* Do not forward messages from a detached core */
+-      if (kproc->rproc->state == RPROC_DETACHED)
+-              return;
+-
+       dev_dbg(dev, "mbox msg: 0x%x\n", msg);
+       switch (msg) {
+@@ -159,10 +155,6 @@ static void k3_dsp_rproc_kick(struct rproc *rproc, int vqid)
+       mbox_msg_t msg = (mbox_msg_t)vqid;
+       int ret;
+-      /* Do not forward messages to a detached core */
+-      if (kproc->rproc->state == RPROC_DETACHED)
+-              return;
+-
+       /* send the index of the triggered virtqueue in the mailbox payload */
+       ret = mbox_send_message(kproc->mbox, (void *)msg);
+       if (ret < 0)
+-- 
+2.39.5
+
diff --git a/queue-6.15/remoteproc-k3-r5-drop-check-performed-in-k3_r5_rproc.patch b/queue-6.15/remoteproc-k3-r5-drop-check-performed-in-k3_r5_rproc.patch
new file mode 100644 (file)
index 0000000..e3f756e
--- /dev/null
@@ -0,0 +1,64 @@
+From 340bee6d69661826652ece035f6712c7936202eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 May 2025 11:14:35 +0530
+Subject: remoteproc: k3-r5: Drop check performed in
+ k3_r5_rproc_{mbox_callback/kick}
+
+From: Siddharth Vadapalli <s-vadapalli@ti.com>
+
+[ Upstream commit 9995dbfc2235efabdb3759606d522e1a7ec3bdcb ]
+
+Commit f3f11cfe8907 ("remoteproc: k3-r5: Acquire mailbox handle during
+probe routine") introduced a check in the "k3_r5_rproc_mbox_callback()"
+and "k3_r5_rproc_kick()" callbacks, causing them to exit if the remote
+core's state is "RPROC_DETACHED". However, the "__rproc_attach()"
+function that is responsible for attaching to a remote core, updates
+the state of the remote core to "RPROC_ATTACHED" only after invoking
+"rproc_start_subdevices()".
+
+The "rproc_start_subdevices()" function triggers the probe of the Virtio
+RPMsg devices associated with the remote core, which require that the
+"k3_r5_rproc_kick()" and "k3_r5_rproc_mbox_callback()" callbacks are
+functional. Hence, drop the check in the callbacks.
+
+Fixes: f3f11cfe8907 ("remoteproc: k3-r5: Acquire mailbox handle during probe routine")
+Signed-off-by: Siddharth Vadapalli <s-vadapalli@ti.com>
+Signed-off-by: Beleswar Padhi <b-padhi@ti.com>
+Tested-by: Judith Mendez <jm@ti.com>
+Reviewed-by: Andrew Davis <afd@ti.com>
+Link: https://lore.kernel.org/r/20250513054510.3439842-2-b-padhi@ti.com
+Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/ti_k3_r5_remoteproc.c | 8 --------
+ 1 file changed, 8 deletions(-)
+
+diff --git a/drivers/remoteproc/ti_k3_r5_remoteproc.c b/drivers/remoteproc/ti_k3_r5_remoteproc.c
+index dbc513c5569cb..3fc0b97dec600 100644
+--- a/drivers/remoteproc/ti_k3_r5_remoteproc.c
++++ b/drivers/remoteproc/ti_k3_r5_remoteproc.c
+@@ -194,10 +194,6 @@ static void k3_r5_rproc_mbox_callback(struct mbox_client *client, void *data)
+       const char *name = kproc->rproc->name;
+       u32 msg = omap_mbox_message(data);
+-      /* Do not forward message from a detached core */
+-      if (kproc->rproc->state == RPROC_DETACHED)
+-              return;
+-
+       dev_dbg(dev, "mbox msg: 0x%x\n", msg);
+       switch (msg) {
+@@ -233,10 +229,6 @@ static void k3_r5_rproc_kick(struct rproc *rproc, int vqid)
+       mbox_msg_t msg = (mbox_msg_t)vqid;
+       int ret;
+-      /* Do not forward message to a detached core */
+-      if (kproc->rproc->state == RPROC_DETACHED)
+-              return;
+-
+       /* send the index of the triggered virtqueue in the mailbox payload */
+       ret = mbox_send_message(kproc->mbox, (void *)msg);
+       if (ret < 0)
+-- 
+2.39.5
+
diff --git a/queue-6.15/remoteproc-k3-r5-refactor-sequential-core-power-up-d.patch b/queue-6.15/remoteproc-k3-r5-refactor-sequential-core-power-up-d.patch
new file mode 100644 (file)
index 0000000..7640752
--- /dev/null
@@ -0,0 +1,231 @@
+From c98ed2b48a3ac4d135dc2a789f3d1cde80dbbe55 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 May 2025 11:14:37 +0530
+Subject: remoteproc: k3-r5: Refactor sequential core power up/down operations
+
+From: Beleswar Padhi <b-padhi@ti.com>
+
+[ Upstream commit 701177511abd295e0fc2499796e466d8ff12165c ]
+
+The existing implementation of the waiting mechanism in
+"k3_r5_cluster_rproc_init()" waits for the "released_from_reset" flag to
+be set as part of the firmware boot process in "k3_r5_rproc_start()".
+The "k3_r5_cluster_rproc_init()" function is invoked in the probe
+routine which causes unexpected failures in cases where the firmware is
+unavailable at boot time, resulting in probe failure and removal of the
+remoteproc handles in the sysfs paths.
+
+To address this, the waiting mechanism is refactored out of the probe
+routine into the appropriate "k3_r5_rproc_{prepare/unprepare}()"
+functions. This allows the probe routine to complete without depending
+on firmware booting, while still maintaining the required
+power-synchronization between cores.
+
+Further, this wait mechanism is dropped from
+"k3_r5_rproc_{start/stop}()" functions as they deal with Core Run/Halt
+operations, and as such, there is no constraint in Running or Halting
+the cores of a cluster in order.
+
+Fixes: 61f6f68447ab ("remoteproc: k3-r5: Wait for core0 power-up before powering up core1")
+Signed-off-by: Beleswar Padhi <b-padhi@ti.com>
+Tested-by: Judith Mendez <jm@ti.com>
+Reviewed-by: Andrew Davis <afd@ti.com>
+Link: https://lore.kernel.org/r/20250513054510.3439842-4-b-padhi@ti.com
+Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/ti_k3_r5_remoteproc.c | 110 +++++++++++++----------
+ 1 file changed, 63 insertions(+), 47 deletions(-)
+
+diff --git a/drivers/remoteproc/ti_k3_r5_remoteproc.c b/drivers/remoteproc/ti_k3_r5_remoteproc.c
+index 3fc0b97dec600..ba082ca13e750 100644
+--- a/drivers/remoteproc/ti_k3_r5_remoteproc.c
++++ b/drivers/remoteproc/ti_k3_r5_remoteproc.c
+@@ -440,13 +440,36 @@ static int k3_r5_rproc_prepare(struct rproc *rproc)
+ {
+       struct k3_r5_rproc *kproc = rproc->priv;
+       struct k3_r5_cluster *cluster = kproc->cluster;
+-      struct k3_r5_core *core = kproc->core;
++      struct k3_r5_core *core = kproc->core, *core0, *core1;
+       struct device *dev = kproc->dev;
+       u32 ctrl = 0, cfg = 0, stat = 0;
+       u64 boot_vec = 0;
+       bool mem_init_dis;
+       int ret;
++      /*
++       * R5 cores require to be powered on sequentially, core0 should be in
++       * higher power state than core1 in a cluster. So, wait for core0 to
++       * power up before proceeding to core1 and put timeout of 2sec. This
++       * waiting mechanism is necessary because rproc_auto_boot_callback() for
++       * core1 can be called before core0 due to thread execution order.
++       *
++       * By placing the wait mechanism here in .prepare() ops, this condition
++       * is enforced for rproc boot requests from sysfs as well.
++       */
++      core0 = list_first_entry(&cluster->cores, struct k3_r5_core, elem);
++      core1 = list_last_entry(&cluster->cores, struct k3_r5_core, elem);
++      if (cluster->mode == CLUSTER_MODE_SPLIT && core == core1 &&
++          !core0->released_from_reset) {
++              ret = wait_event_interruptible_timeout(cluster->core_transition,
++                                                     core0->released_from_reset,
++                                                     msecs_to_jiffies(2000));
++              if (ret <= 0) {
++                      dev_err(dev, "can not power up core1 before core0");
++                      return -EPERM;
++              }
++      }
++
+       ret = ti_sci_proc_get_status(core->tsp, &boot_vec, &cfg, &ctrl, &stat);
+       if (ret < 0)
+               return ret;
+@@ -462,6 +485,14 @@ static int k3_r5_rproc_prepare(struct rproc *rproc)
+               return ret;
+       }
++      /*
++       * Notify all threads in the wait queue when core0 state has changed so
++       * that threads waiting for this condition can be executed.
++       */
++      core->released_from_reset = true;
++      if (core == core0)
++              wake_up_interruptible(&cluster->core_transition);
++
+       /*
+        * Newer IP revisions like on J7200 SoCs support h/w auto-initialization
+        * of TCMs, so there is no need to perform the s/w memzero. This bit is
+@@ -507,10 +538,30 @@ static int k3_r5_rproc_unprepare(struct rproc *rproc)
+ {
+       struct k3_r5_rproc *kproc = rproc->priv;
+       struct k3_r5_cluster *cluster = kproc->cluster;
+-      struct k3_r5_core *core = kproc->core;
++      struct k3_r5_core *core = kproc->core, *core0, *core1;
+       struct device *dev = kproc->dev;
+       int ret;
++      /*
++       * Ensure power-down of cores is sequential in split mode. Core1 must
++       * power down before Core0 to maintain the expected state. By placing
++       * the wait mechanism here in .unprepare() ops, this condition is
++       * enforced for rproc stop or shutdown requests from sysfs and device
++       * removal as well.
++       */
++      core0 = list_first_entry(&cluster->cores, struct k3_r5_core, elem);
++      core1 = list_last_entry(&cluster->cores, struct k3_r5_core, elem);
++      if (cluster->mode == CLUSTER_MODE_SPLIT && core == core0 &&
++          core1->released_from_reset) {
++              ret = wait_event_interruptible_timeout(cluster->core_transition,
++                                                     !core1->released_from_reset,
++                                                     msecs_to_jiffies(2000));
++              if (ret <= 0) {
++                      dev_err(dev, "can not power down core0 before core1");
++                      return -EPERM;
++              }
++      }
++
+       /* Re-use LockStep-mode reset logic for Single-CPU mode */
+       ret = (cluster->mode == CLUSTER_MODE_LOCKSTEP ||
+              cluster->mode == CLUSTER_MODE_SINGLECPU) ?
+@@ -518,6 +569,14 @@ static int k3_r5_rproc_unprepare(struct rproc *rproc)
+       if (ret)
+               dev_err(dev, "unable to disable cores, ret = %d\n", ret);
++      /*
++       * Notify all threads in the wait queue when core1 state has changed so
++       * that threads waiting for this condition can be executed.
++       */
++      core->released_from_reset = false;
++      if (core == core1)
++              wake_up_interruptible(&cluster->core_transition);
++
+       return ret;
+ }
+@@ -543,7 +602,7 @@ static int k3_r5_rproc_start(struct rproc *rproc)
+       struct k3_r5_rproc *kproc = rproc->priv;
+       struct k3_r5_cluster *cluster = kproc->cluster;
+       struct device *dev = kproc->dev;
+-      struct k3_r5_core *core0, *core;
++      struct k3_r5_core *core;
+       u32 boot_addr;
+       int ret;
+@@ -565,21 +624,9 @@ static int k3_r5_rproc_start(struct rproc *rproc)
+                               goto unroll_core_run;
+               }
+       } else {
+-              /* do not allow core 1 to start before core 0 */
+-              core0 = list_first_entry(&cluster->cores, struct k3_r5_core,
+-                                       elem);
+-              if (core != core0 && core0->rproc->state == RPROC_OFFLINE) {
+-                      dev_err(dev, "%s: can not start core 1 before core 0\n",
+-                              __func__);
+-                      return -EPERM;
+-              }
+-
+               ret = k3_r5_core_run(core);
+               if (ret)
+                       return ret;
+-
+-              core->released_from_reset = true;
+-              wake_up_interruptible(&cluster->core_transition);
+       }
+       return 0;
+@@ -620,8 +667,7 @@ static int k3_r5_rproc_stop(struct rproc *rproc)
+ {
+       struct k3_r5_rproc *kproc = rproc->priv;
+       struct k3_r5_cluster *cluster = kproc->cluster;
+-      struct device *dev = kproc->dev;
+-      struct k3_r5_core *core1, *core = kproc->core;
++      struct k3_r5_core *core = kproc->core;
+       int ret;
+       /* halt all applicable cores */
+@@ -634,16 +680,6 @@ static int k3_r5_rproc_stop(struct rproc *rproc)
+                       }
+               }
+       } else {
+-              /* do not allow core 0 to stop before core 1 */
+-              core1 = list_last_entry(&cluster->cores, struct k3_r5_core,
+-                                      elem);
+-              if (core != core1 && core1->rproc->state != RPROC_OFFLINE) {
+-                      dev_err(dev, "%s: can not stop core 0 before core 1\n",
+-                              __func__);
+-                      ret = -EPERM;
+-                      goto out;
+-              }
+-
+               ret = k3_r5_core_halt(core);
+               if (ret)
+                       goto out;
+@@ -1271,26 +1307,6 @@ static int k3_r5_cluster_rproc_init(struct platform_device *pdev)
+                   cluster->mode == CLUSTER_MODE_SINGLECPU ||
+                   cluster->mode == CLUSTER_MODE_SINGLECORE)
+                       break;
+-
+-              /*
+-               * R5 cores require to be powered on sequentially, core0
+-               * should be in higher power state than core1 in a cluster
+-               * So, wait for current core to power up before proceeding
+-               * to next core and put timeout of 2sec for each core.
+-               *
+-               * This waiting mechanism is necessary because
+-               * rproc_auto_boot_callback() for core1 can be called before
+-               * core0 due to thread execution order.
+-               */
+-              ret = wait_event_interruptible_timeout(cluster->core_transition,
+-                                                     core->released_from_reset,
+-                                                     msecs_to_jiffies(2000));
+-              if (ret <= 0) {
+-                      dev_err(dev,
+-                              "Timed out waiting for %s core to power up!\n",
+-                              rproc->name);
+-                      goto out;
+-              }
+       }
+       return 0;
+-- 
+2.39.5
+
diff --git a/queue-6.15/remoteproc-qcom_wcnss_iris-add-missing-put_device-on.patch b/queue-6.15/remoteproc-qcom_wcnss_iris-add-missing-put_device-on.patch
new file mode 100644 (file)
index 0000000..ec77954
--- /dev/null
@@ -0,0 +1,44 @@
+From 6e54b4bb79d598dbff083b3a2a5c43f0cc70f7af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Apr 2025 13:59:51 +0300
+Subject: remoteproc: qcom_wcnss_iris: Add missing put_device() on error in
+ probe
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 0cb4b1b97041d8a1f773425208ded253c1cb5869 ]
+
+The device_del() call matches with the device_add() but we also need
+to call put_device() to trigger the qcom_iris_release().
+
+Fixes: 1fcef985c8bd ("remoteproc: qcom: wcnss: Fix race with iris probe")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Link: https://lore.kernel.org/r/4604f7e0-3217-4095-b28a-3ff8b5afad3a@stanley.mountain
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/qcom_wcnss_iris.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/remoteproc/qcom_wcnss_iris.c b/drivers/remoteproc/qcom_wcnss_iris.c
+index b989718776bdb..2b52b403eb3f7 100644
+--- a/drivers/remoteproc/qcom_wcnss_iris.c
++++ b/drivers/remoteproc/qcom_wcnss_iris.c
+@@ -196,6 +196,7 @@ struct qcom_iris *qcom_iris_probe(struct device *parent, bool *use_48mhz_xo)
+ err_device_del:
+       device_del(&iris->dev);
++      put_device(&iris->dev);
+       return ERR_PTR(ret);
+ }
+@@ -203,4 +204,5 @@ struct qcom_iris *qcom_iris_probe(struct device *parent, bool *use_48mhz_xo)
+ void qcom_iris_remove(struct qcom_iris *iris)
+ {
+       device_del(&iris->dev);
++      put_device(&iris->dev);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/revert-phy-qcom-qusb2-add-qusb2-support-for-ipq5424.patch b/queue-6.15/revert-phy-qcom-qusb2-add-qusb2-support-for-ipq5424.patch
new file mode 100644 (file)
index 0000000..ba7b516
--- /dev/null
@@ -0,0 +1,82 @@
+From fe4588fe7a6207d6319c7ade863b62e93422ec6a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Apr 2025 09:52:50 +0530
+Subject: Revert "phy: qcom-qusb2: add QUSB2 support for IPQ5424"
+
+From: Kathiravan Thirumoorthy <kathiravan.thirumoorthy@oss.qualcomm.com>
+
+[ Upstream commit 8a040e13afd94a1f91acaf8e0505769d4f7f5af4 ]
+
+With the current settings, compliance tests especially eye diagram
+(Host High-speed Signal Quality) tests are failing. Reuse the IPQ6018
+settings to overcome this issue, as mentioned in the Hardware Design
+Document.
+
+So revert the change which introduced the new settings and reuse the
+IPQ6018 settings in the subsequent patch.
+
+Fixes: 9c56a1de296e ("phy: qcom-qusb2: add QUSB2 support for IPQ5424")
+Signed-off-by: Kathiravan Thirumoorthy <kathiravan.thirumoorthy@oss.qualcomm.com>
+Link: https://lore.kernel.org/r/20250415-revert_hs_phy_settings-v3-1-3a8f86211b59@oss.qualcomm.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/qualcomm/phy-qcom-qusb2.c | 28 ---------------------------
+ 1 file changed, 28 deletions(-)
+
+diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c b/drivers/phy/qualcomm/phy-qcom-qusb2.c
+index 1f5f7df14d5a2..81b9e9349c3eb 100644
+--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
++++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
+@@ -151,21 +151,6 @@ static const struct qusb2_phy_init_tbl ipq6018_init_tbl[] = {
+       QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_AUTOPGM_CTL1, 0x9F),
+ };
+-static const struct qusb2_phy_init_tbl ipq5424_init_tbl[] = {
+-      QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL, 0x14),
+-      QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE1, 0x00),
+-      QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE2, 0x53),
+-      QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE4, 0xc3),
+-      QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_TUNE, 0x30),
+-      QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_USER_CTL1, 0x79),
+-      QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_USER_CTL2, 0x21),
+-      QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE5, 0x00),
+-      QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_PWR_CTRL, 0x00),
+-      QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TEST2, 0x14),
+-      QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_TEST, 0x80),
+-      QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_AUTOPGM_CTL1, 0x9f),
+-};
+-
+ static const struct qusb2_phy_init_tbl qcs615_init_tbl[] = {
+       QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE1, 0xc8),
+       QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE2, 0xb3),
+@@ -359,16 +344,6 @@ static const struct qusb2_phy_cfg ipq6018_phy_cfg = {
+       .autoresume_en   = BIT(0),
+ };
+-static const struct qusb2_phy_cfg ipq5424_phy_cfg = {
+-      .tbl            = ipq5424_init_tbl,
+-      .tbl_num        = ARRAY_SIZE(ipq5424_init_tbl),
+-      .regs           = ipq6018_regs_layout,
+-
+-      .disable_ctrl   = POWER_DOWN,
+-      .mask_core_ready = PLL_LOCKED,
+-      .autoresume_en   = BIT(0),
+-};
+-
+ static const struct qusb2_phy_cfg qcs615_phy_cfg = {
+       .tbl            = qcs615_init_tbl,
+       .tbl_num        = ARRAY_SIZE(qcs615_init_tbl),
+@@ -954,9 +929,6 @@ static const struct phy_ops qusb2_phy_gen_ops = {
+ static const struct of_device_id qusb2_phy_of_match_table[] = {
+       {
+-              .compatible     = "qcom,ipq5424-qusb2-phy",
+-              .data           = &ipq5424_phy_cfg,
+-      }, {
+               .compatible     = "qcom,ipq6018-qusb2-phy",
+               .data           = &ipq6018_phy_cfg,
+       }, {
+-- 
+2.39.5
+
diff --git a/queue-6.15/risc-v-kvm-lock-the-correct-mp_state-during-reset.patch b/queue-6.15/risc-v-kvm-lock-the-correct-mp_state-during-reset.patch
new file mode 100644 (file)
index 0000000..e2ec877
--- /dev/null
@@ -0,0 +1,45 @@
+From 01508e1113c40fc2df9ead4903ea201c6addb37d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 May 2025 12:47:28 +0200
+Subject: RISC-V: KVM: lock the correct mp_state during reset
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Radim Krčmář <rkrcmar@ventanamicro.com>
+
+[ Upstream commit 7917be170928189fefad490d1a1237fdfa6b856f ]
+
+Currently, the kvm_riscv_vcpu_sbi_system_reset() function locks
+vcpu->arch.mp_state_lock when updating tmp->arch.mp_state.mp_state
+which is incorrect hence fix it.
+
+Fixes: 2121cadec45a ("RISCV: KVM: Introduce mp_state_lock to avoid lock inversion")
+Signed-off-by: Radim Krčmář <rkrcmar@ventanamicro.com>
+Reviewed-by: Anup Patel <anup@brainfault.org>
+Link: https://lore.kernel.org/r/20250523104725.2894546-4-rkrcmar@ventanamicro.com
+Signed-off-by: Anup Patel <anup@brainfault.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kvm/vcpu_sbi.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c
+index d1c83a77735e0..0000ecf49b188 100644
+--- a/arch/riscv/kvm/vcpu_sbi.c
++++ b/arch/riscv/kvm/vcpu_sbi.c
+@@ -143,9 +143,9 @@ void kvm_riscv_vcpu_sbi_system_reset(struct kvm_vcpu *vcpu,
+       struct kvm_vcpu *tmp;
+       kvm_for_each_vcpu(i, tmp, vcpu->kvm) {
+-              spin_lock(&vcpu->arch.mp_state_lock);
++              spin_lock(&tmp->arch.mp_state_lock);
+               WRITE_ONCE(tmp->arch.mp_state.mp_state, KVM_MP_STATE_STOPPED);
+-              spin_unlock(&vcpu->arch.mp_state_lock);
++              spin_unlock(&tmp->arch.mp_state_lock);
+       }
+       kvm_make_all_cpus_request(vcpu->kvm, KVM_REQ_SLEEP);
+-- 
+2.39.5
+
diff --git a/queue-6.15/riscv-misaligned-fix-sleeping-function-called-during.patch b/queue-6.15/riscv-misaligned-fix-sleeping-function-called-during.patch
new file mode 100644 (file)
index 0000000..3e0fb7f
--- /dev/null
@@ -0,0 +1,71 @@
+From 0ab925b5dbec3dd389cf1867d7855869b00bd1e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Apr 2025 15:38:50 +0800
+Subject: riscv: misaligned: fix sleeping function called during misaligned
+ access handling
+
+From: Nylon Chen <nylon.chen@sifive.com>
+
+[ Upstream commit 61a74ad254628ccd9e88838c3c622885dfb6c588 ]
+
+Use copy_from_user_nofault() and copy_to_user_nofault() instead of
+copy_from/to_user functions in the misaligned access trap handlers.
+
+The following bug report was found when executing misaligned memory
+accesses:
+
+BUG: sleeping function called from invalid context at ./include/linux/uaccess.h:162
+in_atomic(): 0, irqs_disabled(): 1, non_block: 0, pid: 115, name: two
+preempt_count: 0, expected: 0
+CPU: 0 UID: 0 PID: 115 Comm: two Not tainted 6.14.0-rc5 #24
+Hardware name: riscv-virtio,qemu (DT)
+Call Trace:
+ [<ffffffff800160ea>] dump_backtrace+0x1c/0x24
+ [<ffffffff80002304>] show_stack+0x28/0x34
+ [<ffffffff80010fae>] dump_stack_lvl+0x4a/0x68
+ [<ffffffff80010fe0>] dump_stack+0x14/0x1c
+ [<ffffffff8004e44e>] __might_resched+0xfa/0x104
+ [<ffffffff8004e496>] __might_sleep+0x3e/0x62
+ [<ffffffff801963c4>] __might_fault+0x1c/0x24
+ [<ffffffff80425352>] _copy_from_user+0x28/0xaa
+ [<ffffffff8000296c>] handle_misaligned_store+0x204/0x254
+ [<ffffffff809eae82>] do_trap_store_misaligned+0x24/0xee
+ [<ffffffff809f4f1a>] handle_exception+0x146/0x152
+
+Fixes: b686ecdeacf6 ("riscv: misaligned: Restrict user access to kernel memory")
+Fixes: 441381506ba7 ("riscv: misaligned: remove CONFIG_RISCV_M_MODE specific code")
+
+Signed-off-by: Zong Li <zong.li@sifive.com>
+Signed-off-by: Nylon Chen <nylon.chen@sifive.com>
+Link: https://lore.kernel.org/r/20250411073850.3699180-3-nylon.chen@sifive.com
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/traps_misaligned.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/riscv/kernel/traps_misaligned.c b/arch/riscv/kernel/traps_misaligned.c
+index 77c788660223b..56f06a27d45fb 100644
+--- a/arch/riscv/kernel/traps_misaligned.c
++++ b/arch/riscv/kernel/traps_misaligned.c
+@@ -455,7 +455,7 @@ static int handle_scalar_misaligned_load(struct pt_regs *regs)
+       val.data_u64 = 0;
+       if (user_mode(regs)) {
+-              if (copy_from_user(&val, (u8 __user *)addr, len))
++              if (copy_from_user_nofault(&val, (u8 __user *)addr, len))
+                       return -1;
+       } else {
+               memcpy(&val, (u8 *)addr, len);
+@@ -556,7 +556,7 @@ static int handle_scalar_misaligned_store(struct pt_regs *regs)
+               return -EOPNOTSUPP;
+       if (user_mode(regs)) {
+-              if (copy_to_user((u8 __user *)addr, &val, len))
++              if (copy_to_user_nofault((u8 __user *)addr, &val, len))
+                       return -1;
+       } else {
+               memcpy((u8 *)addr, &val, len);
+-- 
+2.39.5
+
diff --git a/queue-6.15/rpmsg-qcom_smd-fix-uninitialized-return-variable-in-.patch b/queue-6.15/rpmsg-qcom_smd-fix-uninitialized-return-variable-in-.patch
new file mode 100644 (file)
index 0000000..acd1320
--- /dev/null
@@ -0,0 +1,38 @@
+From 14f00ca2a8696e7b5b6ede78fea2234f8deb0788 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Apr 2025 20:22:05 +0300
+Subject: rpmsg: qcom_smd: Fix uninitialized return variable in
+ __qcom_smd_send()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 5de775df3362090a6e90046d1f2d83fe62489aa0 ]
+
+The "ret" variable isn't initialized if we don't enter the loop.  For
+example,  if "channel->state" is not SMD_CHANNEL_OPENED.
+
+Fixes: 33e3820dda88 ("rpmsg: smd: Use spinlock in tx path")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://lore.kernel.org/r/aAkhvV0nSbrsef1P@stanley.mountain
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rpmsg/qcom_smd.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/rpmsg/qcom_smd.c b/drivers/rpmsg/qcom_smd.c
+index 40d386809d6b7..bb161def31753 100644
+--- a/drivers/rpmsg/qcom_smd.c
++++ b/drivers/rpmsg/qcom_smd.c
+@@ -746,7 +746,7 @@ static int __qcom_smd_send(struct qcom_smd_channel *channel, const void *data,
+       __le32 hdr[5] = { cpu_to_le32(len), };
+       int tlen = sizeof(hdr) + len;
+       unsigned long flags;
+-      int ret;
++      int ret = 0;
+       /* Word aligned channels only accept word size aligned data */
+       if (channel->info_word && len % 4)
+-- 
+2.39.5
+
diff --git a/queue-6.15/rtc-loongson-add-missing-alarm-notifications-for-acp.patch b/queue-6.15/rtc-loongson-add-missing-alarm-notifications-for-acp.patch
new file mode 100644 (file)
index 0000000..16499f5
--- /dev/null
@@ -0,0 +1,52 @@
+From 9ec0dd2f82bc0b09897b637344eaa7c744fb5ecf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 May 2025 16:44:16 +0800
+Subject: rtc: loongson: Add missing alarm notifications for ACPI RTC events
+
+From: Liu Dalin <liudalin@kylinsec.com.cn>
+
+[ Upstream commit 5af9f1fa576874b24627d4c05e3a84672204c200 ]
+
+When an application sets and enables an alarm on Loongson RTC devices,
+the alarm notification fails to propagate to userspace because the
+ACPI event handler omits calling rtc_update_irq().
+
+As a result, processes waiting via select() or poll() on RTC device
+files fail to receive alarm notifications.
+
+The ACPI interrupt is also triggered multiple times. In loongson_rtc_handler,
+we need to clear TOY_MATCH0_REG to resolve this issue.
+
+Fixes: 09471d8f5b39 ("rtc: loongson: clear TOY_MATCH0_REG in loongson_rtc_isr()")
+Fixes: 1b733a9ebc3d ("rtc: Add rtc driver for the Loongson family chips")
+Signed-off-by: Liu Dalin <liudalin@kylinsec.com.cn>
+Reviewed-by: Binbin Zhou <zhoubinbin@loongson.cn>
+Link: https://lore.kernel.org/r/20250509084416.7979-1-liudalin@kylinsec.com.cn
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rtc/rtc-loongson.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/rtc/rtc-loongson.c b/drivers/rtc/rtc-loongson.c
+index 97e5625c064ce..2ca7ffd5d7a92 100644
+--- a/drivers/rtc/rtc-loongson.c
++++ b/drivers/rtc/rtc-loongson.c
+@@ -129,6 +129,14 @@ static u32 loongson_rtc_handler(void *id)
+ {
+       struct loongson_rtc_priv *priv = (struct loongson_rtc_priv *)id;
++      rtc_update_irq(priv->rtcdev, 1, RTC_AF | RTC_IRQF);
++
++      /*
++       * The TOY_MATCH0_REG should be cleared 0 here,
++       * otherwise the interrupt cannot be cleared.
++       */
++      regmap_write(priv->regmap, TOY_MATCH0_REG, 0);
++
+       spin_lock(&priv->lock);
+       /* Disable RTC alarm wakeup and interrupt */
+       writel(readl(priv->pm_base + PM1_EN_REG) & ~RTC_EN,
+-- 
+2.39.5
+
diff --git a/queue-6.15/rtc-sh-assign-correct-interrupts-with-dt.patch b/queue-6.15/rtc-sh-assign-correct-interrupts-with-dt.patch
new file mode 100644 (file)
index 0000000..0e21fda
--- /dev/null
@@ -0,0 +1,51 @@
+From 3837455102655794ba155d68b92021f53491d94c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 14:42:56 +0100
+Subject: rtc: sh: assign correct interrupts with DT
+
+From: Wolfram Sang <wsa+renesas@sang-engineering.com>
+
+[ Upstream commit 8f2efdbc303fe7baa83843d3290dd6ea5ba3276c ]
+
+The DT bindings for this driver define the interrupts in the order as
+they are numbered in the interrupt controller. The old platform_data,
+however, listed them in a different order. So, for DT based platforms,
+they are mixed up. Assign them specifically for DT, so we can keep the
+bindings stable. After the fix, 'rtctest' passes again on the Renesas
+Genmai board (RZ-A1 / R7S72100).
+
+Fixes: dab5aec64bf5 ("rtc: sh: add support for rza series")
+Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Link: https://lore.kernel.org/r/20250227134256.9167-11-wsa+renesas@sang-engineering.com
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rtc/rtc-sh.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c
+index 9ea40f40188f3..3409f57642248 100644
+--- a/drivers/rtc/rtc-sh.c
++++ b/drivers/rtc/rtc-sh.c
+@@ -485,9 +485,15 @@ static int __init sh_rtc_probe(struct platform_device *pdev)
+               return -ENOENT;
+       }
+-      rtc->periodic_irq = ret;
+-      rtc->carry_irq = platform_get_irq(pdev, 1);
+-      rtc->alarm_irq = platform_get_irq(pdev, 2);
++      if (!pdev->dev.of_node) {
++              rtc->periodic_irq = ret;
++              rtc->carry_irq = platform_get_irq(pdev, 1);
++              rtc->alarm_irq = platform_get_irq(pdev, 2);
++      } else {
++              rtc->alarm_irq = ret;
++              rtc->periodic_irq = platform_get_irq(pdev, 1);
++              rtc->carry_irq = platform_get_irq(pdev, 2);
++      }
+       res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+       if (!res)
+-- 
+2.39.5
+
diff --git a/queue-6.15/rtla-define-_gnu_source-in-timerlat_bpf.c.patch b/queue-6.15/rtla-define-_gnu_source-in-timerlat_bpf.c.patch
new file mode 100644 (file)
index 0000000..23fd249
--- /dev/null
@@ -0,0 +1,55 @@
+From 474744acfeae7b412e3325d915c3be3176b27d48 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Apr 2025 16:46:51 +0200
+Subject: rtla: Define _GNU_SOURCE in timerlat_bpf.c
+
+From: Tomas Glozar <tglozar@redhat.com>
+
+[ Upstream commit 8020361d51eea5145402e450d91b083bccdcd874 ]
+
+Newer versions of glibc include a definition of struct sched_attr in
+bits/sched.h (included through sched.h which is included by rtla).
+Commit 0eecee340672 ("tools/rtla: fix collision with glibc
+sched_attr/sched_set_attr") has modified the definition of struct
+sched_attr in utils.h, so that it is only applied with older versions of
+glibc that do not define it, in order to prevent build failure.
+
+The definition in bits/sched.h depends on _GNU_SOURCE.
+timerlat_bpf.c does not define _GNU_SOURCE, making it fall back to the
+definition in utils.h. The latter has two fields less, leading to
+shifted offsets of struct timerlat_params in timerlat_bpf_init.
+
+Because of the shift, timerlat_bpf_init incorrectly reads
+params->entries as 0 for timerlat-hist and disables the creation of
+histogram maps, causing breakage in BPF sample collection mode:
+
+$ rtla timerlat hist -d 1s
+Error pulling BPF data
+
+Fix the issue by also defining _GNU_SOURCE in timerlat_bpf.c.
+
+Cc: John Kacur <jkacur@redhat.com>
+Cc: Luis Goncalves <lgoncalv@redhat.com>
+Link: https://lore.kernel.org/20250430144651.621766-1-tglozar@redhat.com
+Fixes: e34293ddcebd ("rtla/timerlat: Add BPF skeleton to collect samples")
+Signed-off-by: Tomas Glozar <tglozar@redhat.com>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/tracing/rtla/src/timerlat_bpf.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tools/tracing/rtla/src/timerlat_bpf.c b/tools/tracing/rtla/src/timerlat_bpf.c
+index 5abee884037ae..0bc44ce5d69bd 100644
+--- a/tools/tracing/rtla/src/timerlat_bpf.c
++++ b/tools/tracing/rtla/src/timerlat_bpf.c
+@@ -1,5 +1,6 @@
+ // SPDX-License-Identifier: GPL-2.0
+ #ifdef HAVE_BPF_SKEL
++#define _GNU_SOURCE
+ #include "timerlat.h"
+ #include "timerlat_bpf.h"
+ #include "timerlat.skel.h"
+-- 
+2.39.5
+
diff --git a/queue-6.15/rust-alloc-add-missing-invariant-in-vec-set_len.patch b/queue-6.15/rust-alloc-add-missing-invariant-in-vec-set_len.patch
new file mode 100644 (file)
index 0000000..e9896a4
--- /dev/null
@@ -0,0 +1,40 @@
+From 7356eb699592117147df4c4d8685f403947aae25 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 15 Mar 2025 16:43:02 +0100
+Subject: rust: alloc: add missing invariant in Vec::set_len()
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+[ Upstream commit fb1bf1067de979c89ae33589e0466d6ce0dde204 ]
+
+When setting a new length, we have to justify that the set length
+represents the exact number of elements stored in the vector.
+
+Reviewed-by: Benno Lossin <benno.lossin@proton.me>
+Reported-by: Alice Ryhl <aliceryhl@google.com>
+Closes: https://lore.kernel.org/rust-for-linux/20250311-iov-iter-v1-4-f6c9134ea824@google.com
+Fixes: 2aac4cd7dae3 ("rust: alloc: implement kernel `Vec` type")
+Link: https://lore.kernel.org/r/20250315154436.65065-2-dakr@kernel.org
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ rust/kernel/alloc/kvec.rs | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/rust/kernel/alloc/kvec.rs b/rust/kernel/alloc/kvec.rs
+index 87a71fd40c3ca..f62204fe563f5 100644
+--- a/rust/kernel/alloc/kvec.rs
++++ b/rust/kernel/alloc/kvec.rs
+@@ -196,6 +196,9 @@ where
+     #[inline]
+     pub unsafe fn set_len(&mut self, new_len: usize) {
+         debug_assert!(new_len <= self.capacity());
++
++        // INVARIANT: By the safety requirements of this method `new_len` represents the exact
++        // number of elements stored within `self`.
+         self.len = new_len;
+     }
+-- 
+2.39.5
+
diff --git a/queue-6.15/rust-file-mark-localfile-as-repr-transparent.patch b/queue-6.15/rust-file-mark-localfile-as-repr-transparent.patch
new file mode 100644 (file)
index 0000000..1bea6a0
--- /dev/null
@@ -0,0 +1,44 @@
+From 38f15d42fd85b986296bc8a5f602c030a17f660e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 May 2025 20:48:55 +0000
+Subject: rust: file: mark `LocalFile` as `repr(transparent)`
+
+From: Pekka Ristola <pekkarr@protonmail.com>
+
+[ Upstream commit 15ecd83dc06277385ad71dc7ea26911d9a79acaf ]
+
+Unsafe code in `LocalFile`'s methods assumes that the type has the same
+layout as the inner `bindings::file`. This is not guaranteed by the default
+struct representation in Rust, but requires specifying the `transparent`
+representation.
+
+The `File` struct (which also wraps `bindings::file`) is already marked as
+`repr(transparent)`, so this change makes their layouts equivalent.
+
+Fixes: 851849824bb5 ("rust: file: add Rust abstraction for `struct file`")
+Closes: https://github.com/Rust-for-Linux/linux/issues/1165
+Signed-off-by: Pekka Ristola <pekkarr@protonmail.com>
+Link: https://lore.kernel.org/20250527204636.12573-1-pekkarr@protonmail.com
+Reviewed-by: Benno Lossin <lossin@kernel.org>
+Reviewed-by: Alice Ryhl <aliceryhl@google.com>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ rust/kernel/fs/file.rs | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/rust/kernel/fs/file.rs b/rust/kernel/fs/file.rs
+index 13a0e44cd1aa8..138693bdeb3fd 100644
+--- a/rust/kernel/fs/file.rs
++++ b/rust/kernel/fs/file.rs
+@@ -219,6 +219,7 @@ unsafe impl AlwaysRefCounted for File {
+ ///   must be on the same thread as this file.
+ ///
+ /// [`assume_no_fdget_pos`]: LocalFile::assume_no_fdget_pos
++#[repr(transparent)]
+ pub struct LocalFile {
+     inner: Opaque<bindings::file>,
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/rust-miscdevice-fix-typo-in-miscdevice-ioctl-documen.patch b/queue-6.15/rust-miscdevice-fix-typo-in-miscdevice-ioctl-documen.patch
new file mode 100644 (file)
index 0000000..74f9a0f
--- /dev/null
@@ -0,0 +1,39 @@
+From 7807ceedf126383eec63a60c8c6b0fc24ee11c43 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 17 May 2025 13:06:15 +0200
+Subject: rust: miscdevice: fix typo in MiscDevice::ioctl documentation
+
+From: Christian Schrefl <chrisi.schrefl@gmail.com>
+
+[ Upstream commit 81e9edc1a8d657291409d70d93361d8277d226d8 ]
+
+Fixes one small typo (`utilties` to `utilities`) in the documentation of
+`MiscDevice::ioctl`.
+
+Fixes: f893691e7426 ("rust: miscdevice: add base miscdevice abstraction")
+Signed-off-by: Christian Schrefl <chrisi.schrefl@gmail.com>
+Reviewed-by: Benno Lossin <lossin@kernel.org>
+Reviewed-by: Alice Ryhl <aliceryhl@google.com>
+Link: https://lore.kernel.org/r/20250517-rust_miscdevice_fix_typo-v1-1-8c30a6237ba9@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ rust/kernel/miscdevice.rs | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/rust/kernel/miscdevice.rs b/rust/kernel/miscdevice.rs
+index fa9ecc42602a4..15d10e5c1db7d 100644
+--- a/rust/kernel/miscdevice.rs
++++ b/rust/kernel/miscdevice.rs
+@@ -121,7 +121,7 @@ pub trait MiscDevice: Sized {
+     /// Handler for ioctls.
+     ///
+-    /// The `cmd` argument is usually manipulated using the utilties in [`kernel::ioctl`].
++    /// The `cmd` argument is usually manipulated using the utilities in [`kernel::ioctl`].
+     ///
+     /// [`kernel::ioctl`]: mod@crate::ioctl
+     fn ioctl(
+-- 
+2.39.5
+
diff --git a/queue-6.15/rust-pci-fix-docs-related-to-missing-markdown-code-s.patch b/queue-6.15/rust-pci-fix-docs-related-to-missing-markdown-code-s.patch
new file mode 100644 (file)
index 0000000..1c2f18b
--- /dev/null
@@ -0,0 +1,76 @@
+From 98a0da5b4eb9cf000019f2d64d7c9c517a932ecd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Mar 2025 22:03:54 +0100
+Subject: rust: pci: fix docs related to missing Markdown code spans
+
+From: Miguel Ojeda <ojeda@kernel.org>
+
+[ Upstream commit 1dbaf8b1bafb8557904eb54b98bb323a3061dd2c ]
+
+In particular:
+
+  - Add missing Markdown code spans.
+
+  - Improve title for `DeviceId`, adding a link to the struct in the
+    C side, rather than referring to `bindings::`.
+
+  - Convert `TODO` from documentation to a normal comment, and put code
+    in block.
+
+This was found using the Clippy `doc_markdown` lint, which we may want
+to enable.
+
+Fixes: 1bd8b6b2c5d3 ("rust: pci: add basic PCI device / driver abstractions")
+Reviewed-by: Benno Lossin <benno.lossin@proton.me>
+Acked-by: Danilo Krummrich <dakr@kernel.org>
+Link: https://lore.kernel.org/r/20250324210359.1199574-8-ojeda@kernel.org
+[ Prefixed link text with `struct`. - Miguel ]
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ rust/kernel/pci.rs | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs
+index c97d6d470b282..bbc453c6d9ea8 100644
+--- a/rust/kernel/pci.rs
++++ b/rust/kernel/pci.rs
+@@ -118,7 +118,9 @@ macro_rules! module_pci_driver {
+ };
+ }
+-/// Abstraction for bindings::pci_device_id.
++/// Abstraction for the PCI device ID structure ([`struct pci_device_id`]).
++///
++/// [`struct pci_device_id`]: https://docs.kernel.org/PCI/pci.html#c.pci_device_id
+ #[repr(transparent)]
+ #[derive(Clone, Copy)]
+ pub struct DeviceId(bindings::pci_device_id);
+@@ -173,7 +175,7 @@ unsafe impl RawDeviceId for DeviceId {
+     }
+ }
+-/// IdTable type for PCI
++/// `IdTable` type for PCI.
+ pub type IdTable<T> = &'static dyn kernel::device_id::IdTable<DeviceId, T>;
+ /// Create a PCI `IdTable` with its alias for modpost.
+@@ -224,10 +226,11 @@ macro_rules! pci_device_table {
+ /// `Adapter` documentation for an example.
+ pub trait Driver: Send {
+     /// The type holding information about each device id supported by the driver.
+-    ///
+-    /// TODO: Use associated_type_defaults once stabilized:
+-    ///
+-    /// type IdInfo: 'static = ();
++    // TODO: Use `associated_type_defaults` once stabilized:
++    //
++    // ```
++    // type IdInfo: 'static = ();
++    // ```
+     type IdInfo: 'static;
+     /// The table of device ids supported by the driver.
+-- 
+2.39.5
+
diff --git a/queue-6.15/s390-bpf-store-backchain-even-for-leaf-progs.patch b/queue-6.15/s390-bpf-store-backchain-even-for-leaf-progs.patch
new file mode 100644 (file)
index 0000000..2c28018
--- /dev/null
@@ -0,0 +1,68 @@
+From 785fe85db16e41d62eb3035a24feaffce454fb26 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 May 2025 14:26:15 +0200
+Subject: s390/bpf: Store backchain even for leaf progs
+
+From: Ilya Leoshkevich <iii@linux.ibm.com>
+
+[ Upstream commit 5f55f2168432298f5a55294831ab6a76a10cb3c3 ]
+
+Currently a crash in a leaf prog (caused by a bug) produces the
+following call trace:
+
+     [<000003ff600ebf00>] bpf_prog_6df0139e1fbf2789_fentry+0x20/0x78
+     [<0000000000000000>] 0x0
+
+This is because leaf progs do not store backchain. Fix by making all
+progs do it. This is what GCC and Clang-generated code does as well.
+Now the call trace looks like this:
+
+     [<000003ff600eb0f2>] bpf_prog_6df0139e1fbf2789_fentry+0x2a/0x80
+     [<000003ff600ed096>] bpf_trampoline_201863462940+0x96/0xf4
+     [<000003ff600e3a40>] bpf_prog_05f379658fdd72f2_classifier_0+0x58/0xc0
+     [<000003ffe0aef070>] bpf_test_run+0x210/0x390
+     [<000003ffe0af0dc2>] bpf_prog_test_run_skb+0x25a/0x668
+     [<000003ffe038a90e>] __sys_bpf+0xa46/0xdb0
+     [<000003ffe038ad0c>] __s390x_sys_bpf+0x44/0x50
+     [<000003ffe0defea8>] __do_syscall+0x150/0x280
+     [<000003ffe0e01d5c>] system_call+0x74/0x98
+
+Fixes: 054623105728 ("s390/bpf: Add s390x eBPF JIT compiler backend")
+Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
+Link: https://lore.kernel.org/r/20250512122717.54878-1-iii@linux.ibm.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/net/bpf_jit_comp.c | 12 +++++-------
+ 1 file changed, 5 insertions(+), 7 deletions(-)
+
+diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c
+index 0776dfde2dba9..945106b5562db 100644
+--- a/arch/s390/net/bpf_jit_comp.c
++++ b/arch/s390/net/bpf_jit_comp.c
+@@ -605,17 +605,15 @@ static void bpf_jit_prologue(struct bpf_jit *jit, struct bpf_prog *fp,
+       }
+       /* Setup stack and backchain */
+       if (is_first_pass(jit) || (jit->seen & SEEN_STACK)) {
+-              if (is_first_pass(jit) || (jit->seen & SEEN_FUNC))
+-                      /* lgr %w1,%r15 (backchain) */
+-                      EMIT4(0xb9040000, REG_W1, REG_15);
++              /* lgr %w1,%r15 (backchain) */
++              EMIT4(0xb9040000, REG_W1, REG_15);
+               /* la %bfp,STK_160_UNUSED(%r15) (BPF frame pointer) */
+               EMIT4_DISP(0x41000000, BPF_REG_FP, REG_15, STK_160_UNUSED);
+               /* aghi %r15,-STK_OFF */
+               EMIT4_IMM(0xa70b0000, REG_15, -(STK_OFF + stack_depth));
+-              if (is_first_pass(jit) || (jit->seen & SEEN_FUNC))
+-                      /* stg %w1,152(%r15) (backchain) */
+-                      EMIT6_DISP_LH(0xe3000000, 0x0024, REG_W1, REG_0,
+-                                    REG_15, 152);
++              /* stg %w1,152(%r15) (backchain) */
++              EMIT6_DISP_LH(0xe3000000, 0x0024, REG_W1, REG_0,
++                            REG_15, 152);
+       }
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/s390-uv-always-return-0-from-s390_wiggle_split_folio.patch b/queue-6.15/s390-uv-always-return-0-from-s390_wiggle_split_folio.patch
new file mode 100644 (file)
index 0000000..1cf1245
--- /dev/null
@@ -0,0 +1,92 @@
+From 0acc491615f53f83af593205a3a29c834ea7adde Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 May 2025 14:39:45 +0200
+Subject: s390/uv: Always return 0 from s390_wiggle_split_folio() if successful
+
+From: David Hildenbrand <david@redhat.com>
+
+[ Upstream commit bd428b8c79ed8e8658570e70c62c0092500e2eac ]
+
+Let's consistently return 0 if the operation was successful, and just
+detect ourselves whether splitting is required -- folio_test_large() is
+a cheap operation.
+
+Update the documentation.
+
+Should we simply always return -EAGAIN instead of 0, so we don't have
+to handle it in the caller? Not sure, staring at the documentation, this
+way looks a bit cleaner.
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Link: https://lore.kernel.org/r/20250516123946.1648026-3-david@redhat.com
+Message-ID: <20250516123946.1648026-3-david@redhat.com>
+Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
+Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
+Stable-dep-of: ab73b29efd36 ("s390/uv: Improve splitting of large folios that cannot be split while dirty")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/kernel/uv.c | 22 ++++++++++++----------
+ 1 file changed, 12 insertions(+), 10 deletions(-)
+
+diff --git a/arch/s390/kernel/uv.c b/arch/s390/kernel/uv.c
+index 2cc3b599c7fe3..f6ddb2b54032e 100644
+--- a/arch/s390/kernel/uv.c
++++ b/arch/s390/kernel/uv.c
+@@ -324,34 +324,36 @@ static int make_folio_secure(struct mm_struct *mm, struct folio *folio, struct u
+ }
+ /**
+- * s390_wiggle_split_folio() - try to drain extra references to a folio and optionally split.
++ * s390_wiggle_split_folio() - try to drain extra references to a folio and
++ *                           split the folio if it is large.
+  * @mm:    the mm containing the folio to work on
+  * @folio: the folio
+- * @split: whether to split a large folio
+  *
+  * Context: Must be called while holding an extra reference to the folio;
+  *          the mm lock should not be held.
+- * Return: 0 if the folio was split successfully;
+- *         -EAGAIN if the folio was not split successfully but another attempt
+- *                 can be made, or if @split was set to false;
+- *         -EINVAL in case of other errors. See split_folio().
++ * Return: 0 if the operation was successful;
++ *       -EAGAIN if splitting the large folio was not successful,
++ *               but another attempt can be made;
++ *       -EINVAL in case of other folio splitting errors. See split_folio().
+  */
+-static int s390_wiggle_split_folio(struct mm_struct *mm, struct folio *folio, bool split)
++static int s390_wiggle_split_folio(struct mm_struct *mm, struct folio *folio)
+ {
+       int rc;
+       lockdep_assert_not_held(&mm->mmap_lock);
+       folio_wait_writeback(folio);
+       lru_add_drain_all();
+-      if (split) {
++
++      if (folio_test_large(folio)) {
+               folio_lock(folio);
+               rc = split_folio(folio);
+               folio_unlock(folio);
+               if (rc != -EBUSY)
+                       return rc;
++              return -EAGAIN;
+       }
+-      return -EAGAIN;
++      return 0;
+ }
+ int make_hva_secure(struct mm_struct *mm, unsigned long hva, struct uv_cb_header *uvcb)
+@@ -394,7 +396,7 @@ int make_hva_secure(struct mm_struct *mm, unsigned long hva, struct uv_cb_header
+       mmap_read_unlock(mm);
+       if (rc == -E2BIG || rc == -EBUSY) {
+-              rc = s390_wiggle_split_folio(mm, folio, rc == -E2BIG);
++              rc = s390_wiggle_split_folio(mm, folio);
+               if (!rc)
+                       rc = -EAGAIN;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/s390-uv-don-t-return-0-from-make_hva_secure-if-the-o.patch b/queue-6.15/s390-uv-don-t-return-0-from-make_hva_secure-if-the-o.patch
new file mode 100644 (file)
index 0000000..1ad837d
--- /dev/null
@@ -0,0 +1,59 @@
+From cf3005b70d170ec268e42b819b8df1391866cc9f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 May 2025 14:39:44 +0200
+Subject: s390/uv: Don't return 0 from make_hva_secure() if the operation was
+ not successful
+
+From: David Hildenbrand <david@redhat.com>
+
+[ Upstream commit 3ec8a8330a1aa846dffbf1d64479213366c55b54 ]
+
+If s390_wiggle_split_folio() returns 0 because splitting a large folio
+succeeded, we will return 0 from make_hva_secure() even though a retry
+is required. Return -EAGAIN in that case.
+
+Otherwise, we'll return 0 from gmap_make_secure(), and consequently from
+unpack_one(). In kvm_s390_pv_unpack(), we assume that unpacking
+succeeded and skip unpacking this page. Later on, we run into issues
+and fail booting the VM.
+
+So far, this issue was only observed with follow-up patches where we
+split large pagecache XFS folios. Maybe it can also be triggered with
+shmem?
+
+We'll cleanup s390_wiggle_split_folio() a bit next, to also return 0
+if no split was required.
+
+Fixes: d8dfda5af0be ("KVM: s390: pv: fix race when making a page secure")
+Cc: stable@vger.kernel.org
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Link: https://lore.kernel.org/r/20250516123946.1648026-2-david@redhat.com
+Message-ID: <20250516123946.1648026-2-david@redhat.com>
+Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
+Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
+Stable-dep-of: ab73b29efd36 ("s390/uv: Improve splitting of large folios that cannot be split while dirty")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/kernel/uv.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/arch/s390/kernel/uv.c b/arch/s390/kernel/uv.c
+index 9a5d5be8acf41..2cc3b599c7fe3 100644
+--- a/arch/s390/kernel/uv.c
++++ b/arch/s390/kernel/uv.c
+@@ -393,8 +393,11 @@ int make_hva_secure(struct mm_struct *mm, unsigned long hva, struct uv_cb_header
+       folio_walk_end(&fw, vma);
+       mmap_read_unlock(mm);
+-      if (rc == -E2BIG || rc == -EBUSY)
++      if (rc == -E2BIG || rc == -EBUSY) {
+               rc = s390_wiggle_split_folio(mm, folio, rc == -E2BIG);
++              if (!rc)
++                      rc = -EAGAIN;
++      }
+       folio_put(folio);
+       return rc;
+-- 
+2.39.5
+
diff --git a/queue-6.15/s390-uv-improve-splitting-of-large-folios-that-canno.patch b/queue-6.15/s390-uv-improve-splitting-of-large-folios-that-canno.patch
new file mode 100644 (file)
index 0000000..673cc47
--- /dev/null
@@ -0,0 +1,157 @@
+From 9e2d962b201d8b7ea9d8bf1356b28e62531b050f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 May 2025 14:39:46 +0200
+Subject: s390/uv: Improve splitting of large folios that cannot be split while
+ dirty
+
+From: David Hildenbrand <david@redhat.com>
+
+[ Upstream commit ab73b29efd36f8916c6cc9954e912c4723c9a1b0 ]
+
+Currently, starting a PV VM on an iomap-based filesystem with large
+folio support, such as XFS, will not work. We'll be stuck in
+unpack_one()->gmap_make_secure(), because we can't seem to make progress
+splitting the large folio.
+
+The problem is that we require a writable PTE but a writable PTE under such
+filesystems will imply a dirty folio.
+
+So whenever we have a writable PTE, we'll have a dirty folio, and dirty
+iomap folios cannot currently get split, because
+split_folio()->split_huge_page_to_list_to_order()->filemap_release_folio()
+will fail in iomap_release_folio().
+
+So we will not make any progress splitting such large folios.
+
+Until dirty folios can be split more reliably, let's manually trigger
+writeback of the problematic folio using
+filemap_write_and_wait_range(), and retry the split immediately
+afterwards exactly once, before looking up the folio again.
+
+Should this logic be part of split_folio()? Likely not; most split users
+don't have to split so eagerly to make any progress.
+
+For now, this seems to affect xfs, zonefs and erofs, and this patch
+makes it work again (tested on xfs only).
+
+While this could be considered a fix for commit 6795801366da ("xfs: Support
+large folios"), commit df2f9708ff1f ("zonefs: enable support for large
+folios") and commit ce529cc25b18 ("erofs: enable large folios for iomap
+mode"), before commit eef88fe45ac9 ("s390/uv: Split large folios in
+gmap_make_secure()"), we did not try splitting large folios at all. So it's
+all rather part of making SE compatible with file systems that support
+large folios. But to have some "Fixes:" tag, let's just use eef88fe45ac9.
+
+Not CCing stable, because there are a lot of dependencies, and it simply
+not working is not critical in stable kernels.
+
+Reported-by: Sebastian Mitterle <smitterl@redhat.com>
+Closes: https://issues.redhat.com/browse/RHEL-58218
+Fixes: eef88fe45ac9 ("s390/uv: Split large folios in gmap_make_secure()")
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Link: https://lore.kernel.org/r/20250516123946.1648026-4-david@redhat.com
+Message-ID: <20250516123946.1648026-4-david@redhat.com>
+Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
+Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/kernel/uv.c | 66 +++++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 60 insertions(+), 6 deletions(-)
+
+diff --git a/arch/s390/kernel/uv.c b/arch/s390/kernel/uv.c
+index f6ddb2b54032e..d278bf0c09d1b 100644
+--- a/arch/s390/kernel/uv.c
++++ b/arch/s390/kernel/uv.c
+@@ -15,6 +15,7 @@
+ #include <linux/pagemap.h>
+ #include <linux/swap.h>
+ #include <linux/pagewalk.h>
++#include <linux/backing-dev.h>
+ #include <asm/facility.h>
+ #include <asm/sections.h>
+ #include <asm/uv.h>
+@@ -338,22 +339,75 @@ static int make_folio_secure(struct mm_struct *mm, struct folio *folio, struct u
+  */
+ static int s390_wiggle_split_folio(struct mm_struct *mm, struct folio *folio)
+ {
+-      int rc;
++      int rc, tried_splits;
+       lockdep_assert_not_held(&mm->mmap_lock);
+       folio_wait_writeback(folio);
+       lru_add_drain_all();
+-      if (folio_test_large(folio)) {
++      if (!folio_test_large(folio))
++              return 0;
++
++      for (tried_splits = 0; tried_splits < 2; tried_splits++) {
++              struct address_space *mapping;
++              loff_t lstart, lend;
++              struct inode *inode;
++
+               folio_lock(folio);
+               rc = split_folio(folio);
++              if (rc != -EBUSY) {
++                      folio_unlock(folio);
++                      return rc;
++              }
++
++              /*
++               * Splitting with -EBUSY can fail for various reasons, but we
++               * have to handle one case explicitly for now: some mappings
++               * don't allow for splitting dirty folios; writeback will
++               * mark them clean again, including marking all page table
++               * entries mapping the folio read-only, to catch future write
++               * attempts.
++               *
++               * While the system should be writing back dirty folios in the
++               * background, we obtained this folio by looking up a writable
++               * page table entry. On these problematic mappings, writable
++               * page table entries imply dirty folios, preventing the
++               * split in the first place.
++               *
++               * To prevent a livelock when trigger writeback manually and
++               * letting the caller look up the folio again in the page
++               * table (turning it dirty), immediately try to split again.
++               *
++               * This is only a problem for some mappings (e.g., XFS);
++               * mappings that do not support writeback (e.g., shmem) do not
++               * apply.
++               */
++              if (!folio_test_dirty(folio) || folio_test_anon(folio) ||
++                  !folio->mapping || !mapping_can_writeback(folio->mapping)) {
++                      folio_unlock(folio);
++                      break;
++              }
++
++              /*
++               * Ideally, we'd only trigger writeback on this exact folio. But
++               * there is no easy way to do that, so we'll stabilize the
++               * mapping while we still hold the folio lock, so we can drop
++               * the folio lock to trigger writeback on the range currently
++               * covered by the folio instead.
++               */
++              mapping = folio->mapping;
++              lstart = folio_pos(folio);
++              lend = lstart + folio_size(folio) - 1;
++              inode = igrab(mapping->host);
+               folio_unlock(folio);
+-              if (rc != -EBUSY)
+-                      return rc;
+-              return -EAGAIN;
++              if (unlikely(!inode))
++                      break;
++
++              filemap_write_and_wait_range(mapping, lstart, lend);
++              iput(mapping->host);
+       }
+-      return 0;
++      return -EAGAIN;
+ }
+ int make_hva_secure(struct mm_struct *mm, unsigned long hva, struct uv_cb_header *uvcb)
+-- 
+2.39.5
+
diff --git a/queue-6.15/sched-core-tweak-wait_task_inactive-to-force-dequeue.patch b/queue-6.15/sched-core-tweak-wait_task_inactive-to-force-dequeue.patch
new file mode 100644 (file)
index 0000000..3945351
--- /dev/null
@@ -0,0 +1,65 @@
+From 8fff919f68322d4a573e83c4b37f740693a42805 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Apr 2025 08:07:26 -0700
+Subject: sched/core: Tweak wait_task_inactive() to force dequeue sched_delayed
+ tasks
+
+From: John Stultz <jstultz@google.com>
+
+[ Upstream commit b7ca5743a2604156d6083b88cefacef983f3a3a6 ]
+
+It was reported that in 6.12, smpboot_create_threads() was
+taking much longer then in 6.6.
+
+I narrowed down the call path to:
+ smpboot_create_threads()
+ -> kthread_create_on_cpu()
+    -> kthread_bind()
+       -> __kthread_bind_mask()
+          ->wait_task_inactive()
+
+Where in wait_task_inactive() we were regularly hitting the
+queued case, which sets a 1 tick timeout, which when called
+multiple times in a row, accumulates quickly into a long
+delay.
+
+I noticed disabling the DELAY_DEQUEUE sched feature recovered
+the performance, and it seems the newly create tasks are usually
+sched_delayed and left on the runqueue.
+
+So in wait_task_inactive() when we see the task
+p->se.sched_delayed, manually dequeue the sched_delayed task
+with DEQUEUE_DELAYED, so we don't have to constantly wait a
+tick.
+
+Fixes: 152e11f6df29 ("sched/fair: Implement delayed dequeue")
+Reported-by: peter-yc.chang@mediatek.com
+Signed-off-by: John Stultz <jstultz@google.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Tested-by: K Prateek Nayak <kprateek.nayak@amd.com>
+Link: https://lkml.kernel.org/r/20250429150736.3778580-1-jstultz@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/core.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index 36b34e6884587..d593d6612ba07 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -2283,6 +2283,12 @@ unsigned long wait_task_inactive(struct task_struct *p, unsigned int match_state
+                * just go back and repeat.
+                */
+               rq = task_rq_lock(p, &rf);
++              /*
++               * If task is sched_delayed, force dequeue it, to avoid always
++               * hitting the tick timeout in the queued case
++               */
++              if (p->se.sched_delayed)
++                      dequeue_task(rq, p, DEQUEUE_SLEEP | DEQUEUE_DELAYED);
+               trace_sched_wait_task(p);
+               running = task_on_cpu(rq, p);
+               queued = task_on_rq_queued(p);
+-- 
+2.39.5
+
diff --git a/queue-6.15/sched-fair-fixup-wake_up_sync-vs-delayed_dequeue.patch b/queue-6.15/sched-fair-fixup-wake_up_sync-vs-delayed_dequeue.patch
new file mode 100644 (file)
index 0000000..7f8df70
--- /dev/null
@@ -0,0 +1,61 @@
+From 455de0661c783e4d8664a42cd593d5253d6ffee7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Mar 2025 18:52:39 +0800
+Subject: sched/fair: Fixup wake_up_sync() vs DELAYED_DEQUEUE
+
+From: Xuewen Yan <xuewen.yan@unisoc.com>
+
+[ Upstream commit aa3ee4f0b7541382c9f6f43f7408d73a5d4f4042 ]
+
+Delayed dequeued feature keeps a sleeping task enqueued until its
+lag has elapsed. As a result, it stays also visible in rq->nr_running.
+So when in wake_affine_idle(), we should use the real running-tasks
+in rq to check whether we should place the wake-up task to
+current cpu.
+On the other hand, add a helper function to return the nr-delayed.
+
+Fixes: 152e11f6df29 ("sched/fair: Implement delayed dequeue")
+Signed-off-by: Xuewen Yan <xuewen.yan@unisoc.com>
+Reviewed-and-tested-by: Tianchen Ding <dtcccc@linux.alibaba.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Vincent Guittot <vincent.guittot@linaro.org>
+Link: https://lore.kernel.org/r/20250303105241.17251-2-xuewen.yan@unisoc.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/fair.c | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
+index 0fb9bf995a479..0c04ed4148525 100644
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -7196,6 +7196,11 @@ static bool dequeue_task_fair(struct rq *rq, struct task_struct *p, int flags)
+       return true;
+ }
++static inline unsigned int cfs_h_nr_delayed(struct rq *rq)
++{
++      return (rq->cfs.h_nr_queued - rq->cfs.h_nr_runnable);
++}
++
+ #ifdef CONFIG_SMP
+ /* Working cpumask for: sched_balance_rq(), sched_balance_newidle(). */
+@@ -7357,8 +7362,12 @@ wake_affine_idle(int this_cpu, int prev_cpu, int sync)
+       if (available_idle_cpu(this_cpu) && cpus_share_cache(this_cpu, prev_cpu))
+               return available_idle_cpu(prev_cpu) ? prev_cpu : this_cpu;
+-      if (sync && cpu_rq(this_cpu)->nr_running == 1)
+-              return this_cpu;
++      if (sync) {
++              struct rq *rq = cpu_rq(this_cpu);
++
++              if ((rq->nr_running - cfs_h_nr_delayed(rq)) == 1)
++                      return this_cpu;
++      }
+       if (available_idle_cpu(prev_cpu))
+               return prev_cpu;
+-- 
+2.39.5
+
diff --git a/queue-6.15/sched-fix-trace_sched_switch-.prev_state.patch b/queue-6.15/sched-fix-trace_sched_switch-.prev_state.patch
new file mode 100644 (file)
index 0000000..81e4e75
--- /dev/null
@@ -0,0 +1,53 @@
+From a2718c79d591ea4eca9d03f36032f3542d20b9f3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Mar 2025 22:23:23 +0100
+Subject: sched: Fix trace_sched_switch(.prev_state)
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+[ Upstream commit 8feb053d53194382fcfb68231296fdc220497ea6 ]
+
+Gabriele noted that in case of signal_pending_state(), the tracepoint
+sees a stale task-state.
+
+Fixes: fa2c3254d7cf ("sched/tracing: Don't re-read p->state when emitting sched_switch event")
+Reported-by: Gabriele Monaco <gmonaco@redhat.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: Valentin Schneider <vschneid@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/core.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index c81cf642dba05..36b34e6884587 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -6571,12 +6571,14 @@ pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
+  * Otherwise marks the task's __state as RUNNING
+  */
+ static bool try_to_block_task(struct rq *rq, struct task_struct *p,
+-                            unsigned long task_state)
++                            unsigned long *task_state_p)
+ {
++      unsigned long task_state = *task_state_p;
+       int flags = DEQUEUE_NOCLOCK;
+       if (signal_pending_state(task_state, p)) {
+               WRITE_ONCE(p->__state, TASK_RUNNING);
++              *task_state_p = TASK_RUNNING;
+               return false;
+       }
+@@ -6713,7 +6715,7 @@ static void __sched notrace __schedule(int sched_mode)
+                       goto picked;
+               }
+       } else if (!preempt && prev_state) {
+-              try_to_block_task(rq, prev, prev_state);
++              try_to_block_task(rq, prev, &prev_state);
+               switch_count = &prev->nvcsw;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/sched_ext-idle-skip-cross-node-search-with-config_nu.patch b/queue-6.15/sched_ext-idle-skip-cross-node-search-with-config_nu.patch
new file mode 100644 (file)
index 0000000..0fbe4b1
--- /dev/null
@@ -0,0 +1,52 @@
+From e7029fe0a05e0319e85fce1a559d73e455bbbbb3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Jun 2025 10:22:01 +0200
+Subject: sched_ext: idle: Skip cross-node search with !CONFIG_NUMA
+
+From: Andrea Righi <arighi@nvidia.com>
+
+[ Upstream commit 9960be72a54cf0e4d47abdd4cacd1278835a3bb4 ]
+
+In the idle CPU selection logic, attempting cross-node searches adds
+unnecessary complexity when CONFIG_NUMA is disabled.
+
+Since there's no meaningful concept of nodes in this case, simplify the
+logic by restricting the idle CPU search to the current node only.
+
+Fixes: 48849271e6611 ("sched_ext: idle: Per-node idle cpumasks")
+Signed-off-by: Andrea Righi <arighi@nvidia.com>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/ext_idle.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/kernel/sched/ext_idle.c b/kernel/sched/ext_idle.c
+index e67a19a071c11..50b9f3af810d9 100644
+--- a/kernel/sched/ext_idle.c
++++ b/kernel/sched/ext_idle.c
+@@ -131,6 +131,7 @@ static s32 pick_idle_cpu_in_node(const struct cpumask *cpus_allowed, int node, u
+               goto retry;
+ }
++#ifdef CONFIG_NUMA
+ /*
+  * Tracks nodes that have not yet been visited when searching for an idle
+  * CPU across all available nodes.
+@@ -179,6 +180,13 @@ static s32 pick_idle_cpu_from_online_nodes(const struct cpumask *cpus_allowed, i
+       return cpu;
+ }
++#else
++static inline s32
++pick_idle_cpu_from_online_nodes(const struct cpumask *cpus_allowed, int node, u64 flags)
++{
++      return -EBUSY;
++}
++#endif
+ /*
+  * Find an idle CPU in the system, starting from @node.
+-- 
+2.39.5
+
diff --git a/queue-6.15/scsi-hisi_sas-call-i_t_nexus-after-soft-reset-for-sa.patch b/queue-6.15/scsi-hisi_sas-call-i_t_nexus-after-soft-reset-for-sa.patch
new file mode 100644 (file)
index 0000000..b232226
--- /dev/null
@@ -0,0 +1,79 @@
+From ee6569bf10ee93b736b081ddde3e68d64beef843 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Apr 2025 16:08:44 +0800
+Subject: scsi: hisi_sas: Call I_T_nexus after soft reset for SATA disk
+
+From: Yihang Li <liyihang9@huawei.com>
+
+[ Upstream commit e4d953ca557e02edd3aed7390043e1b8ad1c9723 ]
+
+In commit 21c7e972475e ("scsi: hisi_sas: Disable SATA disk phy for severe
+I_T nexus reset failure"), if the softreset fails upon certain
+conditions, the PHY connected to the disk is disabled directly. Manual
+recovery is required, which is inconvenient for users in actual use.
+
+In addition, SATA disks do not support simultaneous connection of multiple
+hosts. Therefore, when multiple controllers are connected to a SATA disk
+at the same time, the controller which is connected later failed to issue
+an ATA softreset to the SATA disk. As a result, the PHY associated with
+the disk is disabled and cannot be automatically recovered.
+
+Now that, we will not focus on the execution result of softreset. No
+matter whether the execution is successful or not, we will directly carry
+out I_T_nexus_reset.
+
+Fixes: 21c7e972475e ("scsi: hisi_sas: Disable SATA disk phy for severe I_T nexus reset failure")
+Signed-off-by: Yihang Li <liyihang9@huawei.com>
+Link: https://lore.kernel.org/r/20250414080845.1220997-4-liyihang9@huawei.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 29 +++++----------------------
+ 1 file changed, 5 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 944cf2fb05617..d3981b6779316 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -1885,33 +1885,14 @@ static int hisi_sas_I_T_nexus_reset(struct domain_device *device)
+       }
+       hisi_sas_dereg_device(hisi_hba, device);
+-      rc = hisi_sas_debug_I_T_nexus_reset(device);
+-      if (rc == TMF_RESP_FUNC_COMPLETE && dev_is_sata(device)) {
+-              struct sas_phy *local_phy;
+-
++      if (dev_is_sata(device)) {
+               rc = hisi_sas_softreset_ata_disk(device);
+-              switch (rc) {
+-              case -ECOMM:
+-                      rc = -ENODEV;
+-                      break;
+-              case TMF_RESP_FUNC_FAILED:
+-              case -EMSGSIZE:
+-              case -EIO:
+-                      local_phy = sas_get_local_phy(device);
+-                      rc = sas_phy_enable(local_phy, 0);
+-                      if (!rc) {
+-                              local_phy->enabled = 0;
+-                              dev_err(dev, "Disabled local phy of ATA disk %016llx due to softreset fail (%d)\n",
+-                                      SAS_ADDR(device->sas_addr), rc);
+-                              rc = -ENODEV;
+-                      }
+-                      sas_put_local_phy(local_phy);
+-                      break;
+-              default:
+-                      break;
+-              }
++              if (rc == TMF_RESP_FUNC_FAILED)
++                      dev_err(dev, "ata disk %016llx reset (%d)\n",
++                              SAS_ADDR(device->sas_addr), rc);
+       }
++      rc = hisi_sas_debug_I_T_nexus_reset(device);
+       if ((rc == TMF_RESP_FUNC_COMPLETE) || (rc == -ENODEV))
+               hisi_sas_release_task(hisi_hba, device);
+-- 
+2.39.5
+
diff --git a/queue-6.15/scsi-lpfc-avoid-potential-ndlp-use-after-free-in-dev.patch b/queue-6.15/scsi-lpfc-avoid-potential-ndlp-use-after-free-in-dev.patch
new file mode 100644 (file)
index 0000000..5df576d
--- /dev/null
@@ -0,0 +1,97 @@
+From cb4969d3e724d64141082cf45fbfc14f9e3f928f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Apr 2025 12:48:03 -0700
+Subject: scsi: lpfc: Avoid potential ndlp use-after-free in
+ dev_loss_tmo_callbk
+
+From: Justin Tee <justin.tee@broadcom.com>
+
+[ Upstream commit b5162bb6aa1ec04dff4509b025883524b6d7e7ca ]
+
+Smatch detected a potential use-after-free of an ndlp oject in
+dev_loss_tmo_callbk during driver unload or fatal error handling.
+
+Fix by reordering code to avoid potential use-after-free if initial
+nodelist reference has been previously removed.
+
+Fixes: 4281f44ea8bf ("scsi: lpfc: Prevent NDLP reference count underflow in dev_loss_tmo callback")
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Closes: https://lore.kernel.org/linux-scsi/41c1d855-9eb5-416f-ac12-8b61929201a3@stanley.mountain/
+Signed-off-by: Justin Tee <justin.tee@broadcom.com>
+Link: https://lore.kernel.org/r/20250425194806.3585-6-justintee8345@gmail.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/lpfc/lpfc_hbadisc.c | 32 +++++++++++++++++---------------
+ 1 file changed, 17 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
+index 179be6c5a43e0..c2ec4db672869 100644
+--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
++++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
+@@ -161,7 +161,7 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
+       struct lpfc_hba   *phba;
+       struct lpfc_work_evt *evtp;
+       unsigned long iflags;
+-      bool nvme_reg = false;
++      bool drop_initial_node_ref = false;
+       ndlp = ((struct lpfc_rport_data *)rport->dd_data)->pnode;
+       if (!ndlp)
+@@ -188,8 +188,13 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
+               spin_lock_irqsave(&ndlp->lock, iflags);
+               ndlp->rport = NULL;
+-              if (ndlp->fc4_xpt_flags & NVME_XPT_REGD)
+-                      nvme_reg = true;
++              /* Only 1 thread can drop the initial node reference.
++               * If not registered for NVME and NLP_DROPPED flag is
++               * clear, remove the initial reference.
++               */
++              if (!(ndlp->fc4_xpt_flags & NVME_XPT_REGD))
++                      if (!test_and_set_bit(NLP_DROPPED, &ndlp->nlp_flag))
++                              drop_initial_node_ref = true;
+               /* The scsi_transport is done with the rport so lpfc cannot
+                * call to unregister.
+@@ -200,13 +205,16 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
+                       /* If NLP_XPT_REGD was cleared in lpfc_nlp_unreg_node,
+                        * unregister calls were made to the scsi and nvme
+                        * transports and refcnt was already decremented. Clear
+-                       * the NLP_XPT_REGD flag only if the NVME Rport is
++                       * the NLP_XPT_REGD flag only if the NVME nrport is
+                        * confirmed unregistered.
+                        */
+-                      if (!nvme_reg && ndlp->fc4_xpt_flags & NLP_XPT_REGD) {
+-                              ndlp->fc4_xpt_flags &= ~NLP_XPT_REGD;
++                      if (ndlp->fc4_xpt_flags & NLP_XPT_REGD) {
++                              if (!(ndlp->fc4_xpt_flags & NVME_XPT_REGD))
++                                      ndlp->fc4_xpt_flags &= ~NLP_XPT_REGD;
+                               spin_unlock_irqrestore(&ndlp->lock, iflags);
+-                              lpfc_nlp_put(ndlp); /* may free ndlp */
++
++                              /* Release scsi transport reference */
++                              lpfc_nlp_put(ndlp);
+                       } else {
+                               spin_unlock_irqrestore(&ndlp->lock, iflags);
+                       }
+@@ -214,14 +222,8 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
+                       spin_unlock_irqrestore(&ndlp->lock, iflags);
+               }
+-              /* Only 1 thread can drop the initial node reference.  If
+-               * another thread has set NLP_DROPPED, this thread is done.
+-               */
+-              if (nvme_reg || test_bit(NLP_DROPPED, &ndlp->nlp_flag))
+-                      return;
+-
+-              set_bit(NLP_DROPPED, &ndlp->nlp_flag);
+-              lpfc_nlp_put(ndlp);
++              if (drop_initial_node_ref)
++                      lpfc_nlp_put(ndlp);
+               return;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/scsi-mpt3sas-fix-_ctl_get_mpt_mctp_passthru_adapter-.patch b/queue-6.15/scsi-mpt3sas-fix-_ctl_get_mpt_mctp_passthru_adapter-.patch
new file mode 100644 (file)
index 0000000..0bad280
--- /dev/null
@@ -0,0 +1,40 @@
+From d3441df78c68a54f5e172f8ac6d62edb487200b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 May 2025 02:09:41 -0700
+Subject: scsi: mpt3sas: Fix _ctl_get_mpt_mctp_passthru_adapter() to return IOC
+ pointer
+
+From: Shivasharan S <shivasharan.srikanteshwara@broadcom.com>
+
+[ Upstream commit 9ad5249b37b59baaf2da1014f397c2e23b605075 ]
+
+Fix _ctl_get_mpt_mctp_passthru_adapter() to return the correct IOC
+pointer to caller based on dev_index.
+
+Signed-off-by: Shivasharan S <shivasharan.srikanteshwara@broadcom.com>
+Link: https://lore.kernel.org/r/1747213781-31545-1-git-send-email-shivasharan.srikanteshwara@broadcom.com
+Fixes: c72be4b5bb7c ("scsi: mpt3sas: Add support for MCTP Passthrough commands")
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/mpt3sas/mpt3sas_ctl.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+index 063b10dd82514..02fc204b9bf7b 100644
+--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c
++++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+@@ -2869,8 +2869,9 @@ _ctl_get_mpt_mctp_passthru_adapter(int dev_index)
+               if (ioc->facts.IOCCapabilities & MPI26_IOCFACTS_CAPABILITY_MCTP_PASSTHRU) {
+                       if (count == dev_index) {
+                               spin_unlock(&gioc_lock);
+-                              return 0;
++                              return ioc;
+                       }
++                      count++;
+               }
+       }
+       spin_unlock(&gioc_lock);
+-- 
+2.39.5
+
diff --git a/queue-6.15/scsi-qedf-use-designated-initializer-for-struct-qed_.patch b/queue-6.15/scsi-qedf-use-designated-initializer-for-struct-qed_.patch
new file mode 100644 (file)
index 0000000..40f34f9
--- /dev/null
@@ -0,0 +1,43 @@
+From 45d25c797c19d735cd5b561d739fc1b1f2cb2571 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 May 2025 15:41:57 -0700
+Subject: scsi: qedf: Use designated initializer for struct qed_fcoe_cb_ops
+
+From: Kees Cook <kees@kernel.org>
+
+[ Upstream commit d8720235d5b5cad86c1f07f65117ef2a96f8bec7 ]
+
+Recent fixes to the randstruct GCC plugin allowed it to notice
+that this structure is entirely function pointers and is therefore
+subject to randomization, but doing so requires that it always use
+designated initializers. Explicitly specify the "common" member as being
+initialized. Silences:
+
+drivers/scsi/qedf/qedf_main.c:702:9: error: positional initialization of field in 'struct' declared with 'designated_init' attribute [-Werror=designated-init]
+  702 |         {
+      |         ^
+
+Fixes: 035f7f87b729 ("randstruct: Enable Clang support")
+Link: https://lore.kernel.org/r/20250502224156.work.617-kees@kernel.org
+Signed-off-by: Kees Cook <kees@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qedf/qedf_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c
+index 436bd29d5ebae..6b1ebab36fa35 100644
+--- a/drivers/scsi/qedf/qedf_main.c
++++ b/drivers/scsi/qedf/qedf_main.c
+@@ -699,7 +699,7 @@ static u32 qedf_get_login_failures(void *cookie)
+ }
+ static struct qed_fcoe_cb_ops qedf_cb_ops = {
+-      {
++      .common = {
+               .link_update = qedf_link_update,
+               .bw_update = qedf_bw_update,
+               .schedule_recovery_handler = qedf_schedule_recovery_handler,
+-- 
+2.39.5
+
diff --git a/queue-6.15/scsi-smartpqi-fix-smp_processor_id-call-trace-for-pr.patch b/queue-6.15/scsi-smartpqi-fix-smp_processor_id-call-trace-for-pr.patch
new file mode 100644 (file)
index 0000000..6a63c20
--- /dev/null
@@ -0,0 +1,69 @@
+From fc63349e90af2bd600fcee9a9c965ba6fbaedf57 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Apr 2025 13:32:28 -0500
+Subject: scsi: smartpqi: Fix smp_processor_id() call trace for preemptible
+ kernels
+
+From: Yi Zhang <yi.zhang@redhat.com>
+
+[ Upstream commit 42d033cf4b517e91c187ad2fbd7b30fdc6d2d62c ]
+
+Correct kernel call trace when calling smp_processor_id() when called in
+preemptible kernels by using raw_smp_processor_id().
+
+smp_processor_id() checks to see if preemption is disabled and if not,
+issue an error message followed by a call to dump_stack().
+
+Brief example of call trace:
+kernel:  check_preemption_disabled: 436 callbacks suppressed
+kernel:  BUG: using smp_processor_id() in preemptible [00000000]
+         code: kworker/u1025:0/2354
+kernel:  caller is pqi_scsi_queue_command+0x183/0x310 [smartpqi]
+kernel:  CPU: 129 PID: 2354 Comm: kworker/u1025:0
+kernel:  ...
+kernel:  Workqueue: writeback wb_workfn (flush-253:0)
+kernel:  Call Trace:
+kernel:   <TASK>
+kernel:   dump_stack_lvl+0x34/0x48
+kernel:   check_preemption_disabled+0xdd/0xe0
+kernel:   pqi_scsi_queue_command+0x183/0x310 [smartpqi]
+kernel:  ...
+
+Fixes: 283dcc1b142e ("scsi: smartpqi: add counter for parity write stream requests")
+Reviewed-by: Scott Benesh <scott.benesh@microchip.com>
+Reviewed-by: Mike McGowen <mike.mcgowen@microchip.com>
+Tested-by: Don Brace <don.brace@microchip.com>
+Signed-off-by: Yi Zhang <yi.zhang@redhat.com>
+Signed-off-by: Don Brace <don.brace@microchip.com>
+Link: https://lore.kernel.org/r/20250423183229.538572-5-don.brace@microchip.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/smartpqi/smartpqi_init.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index 8a26eca4fdc9b..6c9dec7e3128f 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -5990,7 +5990,7 @@ static bool pqi_is_parity_write_stream(struct pqi_ctrl_info *ctrl_info,
+                       pqi_stream_data->next_lba = rmd.first_block +
+                               rmd.block_cnt;
+                       pqi_stream_data->last_accessed = jiffies;
+-                      per_cpu_ptr(device->raid_io_stats, smp_processor_id())->write_stream_cnt++;
++                              per_cpu_ptr(device->raid_io_stats, raw_smp_processor_id())->write_stream_cnt++;
+                       return true;
+               }
+@@ -6069,7 +6069,7 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scm
+                       rc = pqi_raid_bypass_submit_scsi_cmd(ctrl_info, device, scmd, queue_group);
+                       if (rc == 0 || rc == SCSI_MLQUEUE_HOST_BUSY) {
+                               raid_bypassed = true;
+-                              per_cpu_ptr(device->raid_io_stats, smp_processor_id())->raid_bypass_cnt++;
++                              per_cpu_ptr(device->raid_io_stats, raw_smp_processor_id())->raid_bypass_cnt++;
+                       }
+               }
+               if (!raid_bypassed)
+-- 
+2.39.5
+
diff --git a/queue-6.15/scsi-ufs-mcq-delete-ufshcd_release_scsi_cmd-in-ufshc.patch b/queue-6.15/scsi-ufs-mcq-delete-ufshcd_release_scsi_cmd-in-ufshc.patch
new file mode 100644 (file)
index 0000000..c68665f
--- /dev/null
@@ -0,0 +1,58 @@
+From d680cdcf04e3aa6795b0678b74eec9a3c541ed2a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 May 2025 16:38:12 +0800
+Subject: scsi: ufs: mcq: Delete ufshcd_release_scsi_cmd() in
+ ufshcd_mcq_abort()
+
+From: ping.gao <ping.gao@samsung.com>
+
+[ Upstream commit 53755903b9357e69b2dd6a02fafbb1e30c741895 ]
+
+After UFS_ABORT_TASK has been processed successfully, the host will
+generate MCQ IRQ for ABORT TAG with response OCS_ABORTED. This results in
+ufshcd_compl_one_cqe() calling ufshcd_release_scsi_cmd().
+
+But ufshcd_mcq_abort() already calls ufshcd_release_scsi_cmd(), resulting
+in __ufshcd_release() being called twice. This means
+hba->clk_gating.active_reqs will be decreased twice, making it go
+negative.
+
+Delete ufshcd_release_scsi_cmd() in ufshcd_mcq_abort().
+
+Fixes: f1304d442077 ("scsi: ufs: mcq: Added ufshcd_mcq_abort()")
+Signed-off-by: ping.gao <ping.gao@samsung.com>
+Link: https://lore.kernel.org/r/20250516083812.3894396-1-ping.gao@samsung.com
+Reviewed-by: Peter Wang <peter.wang@mediatek.com>
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ufs/core/ufs-mcq.c | 6 ------
+ 1 file changed, 6 deletions(-)
+
+diff --git a/drivers/ufs/core/ufs-mcq.c b/drivers/ufs/core/ufs-mcq.c
+index f1294c29f4849..1e50675772feb 100644
+--- a/drivers/ufs/core/ufs-mcq.c
++++ b/drivers/ufs/core/ufs-mcq.c
+@@ -674,7 +674,6 @@ int ufshcd_mcq_abort(struct scsi_cmnd *cmd)
+       int tag = scsi_cmd_to_rq(cmd)->tag;
+       struct ufshcd_lrb *lrbp = &hba->lrb[tag];
+       struct ufs_hw_queue *hwq;
+-      unsigned long flags;
+       int err;
+       /* Skip task abort in case previous aborts failed and report failure */
+@@ -713,10 +712,5 @@ int ufshcd_mcq_abort(struct scsi_cmnd *cmd)
+               return FAILED;
+       }
+-      spin_lock_irqsave(&hwq->cq_lock, flags);
+-      if (ufshcd_cmd_inflight(lrbp->cmd))
+-              ufshcd_release_scsi_cmd(hba, lrbp);
+-      spin_unlock_irqrestore(&hwq->cq_lock, flags);
+-
+       return SUCCESS;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/scsi-ufs-qcom-check-gear-against-max-gear-in-vop-fre.patch b/queue-6.15/scsi-ufs-qcom-check-gear-against-max-gear-in-vop-fre.patch
new file mode 100644 (file)
index 0000000..ab128c9
--- /dev/null
@@ -0,0 +1,58 @@
+From e4b90fef1f8fc43a1defdde3ebba5936c20ff505 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 May 2025 10:15:35 +0800
+Subject: scsi: ufs: qcom: Check gear against max gear in vop freq_to_gear()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ziqi Chen <quic_ziqichen@quicinc.com>
+
+[ Upstream commit 663d0c19f3acc0d697f623d34b8eb3b438bf2bda ]
+
+The vop freq_to_gear() may return a gear greater than the negotiated max
+gear. Return the negotiated max gear if the mapped gear is greater.
+
+Fixes: c02fe9e222d1 ("scsi: ufs: qcom: Implement the freq_to_gear_speed() vop")
+Signed-off-by: Ziqi Chen <quic_ziqichen@quicinc.com>
+Link: https://lore.kernel.org/r/20250522021537.999107-2-quic_ziqichen@quicinc.com
+Reported-by: Neil Armstrong <neil.armstrong@linaro.org>
+Closes: https://lore.kernel.org/all/c7f2476a-943a-4d73-ad80-802c91e5f880@linaro.org/
+Tested-by: Neil Armstrong <neil.armstrong@linaro.org>
+Reviewed-by: Bean Huo <beanhuo@micron.com>
+Tested-by: Loïc Minier <loic.minier@oss.qualcomm.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ufs/host/ufs-qcom.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c
+index c0761ccc1381e..28515f89ce798 100644
+--- a/drivers/ufs/host/ufs-qcom.c
++++ b/drivers/ufs/host/ufs-qcom.c
+@@ -1924,7 +1924,7 @@ static int ufs_qcom_config_esi(struct ufs_hba *hba)
+ static u32 ufs_qcom_freq_to_gear_speed(struct ufs_hba *hba, unsigned long freq)
+ {
+-      u32 gear = 0;
++      u32 gear = UFS_HS_DONT_CHANGE;
+       switch (freq) {
+       case 403000000:
+@@ -1946,10 +1946,10 @@ static u32 ufs_qcom_freq_to_gear_speed(struct ufs_hba *hba, unsigned long freq)
+               break;
+       default:
+               dev_err(hba->dev, "%s: Unsupported clock freq : %lu\n", __func__, freq);
+-              break;
++              return UFS_HS_DONT_CHANGE;
+       }
+-      return gear;
++      return min_t(u32, gear, hba->max_pwr_info.info.gear_rx);
+ }
+ /*
+-- 
+2.39.5
+
diff --git a/queue-6.15/scsi-ufs-qcom-map-devfreq-opp-freq-to-unipro-core-cl.patch b/queue-6.15/scsi-ufs-qcom-map-devfreq-opp-freq-to-unipro-core-cl.patch
new file mode 100644 (file)
index 0000000..3f946f4
--- /dev/null
@@ -0,0 +1,184 @@
+From f157af77be5ceb198a0ee7742fc13738036b544e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 May 2025 10:15:36 +0800
+Subject: scsi: ufs: qcom: Map devfreq OPP freq to UniPro Core Clock freq
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Can Guo <quic_cang@quicinc.com>
+
+[ Upstream commit 8c5bcb3daeef9bc54c9939c36dca9a626126eb59 ]
+
+On some platforms, the devfreq OPP freq may be different than the unipro
+core clock freq. Implement ufs_qcom_opp_freq_to_clk_freq() and use it to
+find the unipro core clk freq.
+
+Fixes: c02fe9e222d1 ("scsi: ufs: qcom: Implement the freq_to_gear_speed() vop")
+Signed-off-by: Can Guo <quic_cang@quicinc.com>
+Co-developed-by: Ziqi Chen <quic_ziqichen@quicinc.com>
+Signed-off-by: Ziqi Chen <quic_ziqichen@quicinc.com>
+Link: https://lore.kernel.org/r/20250522021537.999107-3-quic_ziqichen@quicinc.com
+Reported-by: Luca Weiss <luca.weiss@fairphone.com>
+Closes: https://lore.kernel.org/linux-arm-msm/D9FZ9U3AEXW4.1I12FX3YQ3JPW@fairphone.com/
+Tested-by: Luca Weiss <luca.weiss@fairphone.com>
+Reviewed-by: Bean Huo <beanhuo@micron.com>
+Tested-by: Loïc Minier <loic.minier@oss.qualcomm.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ufs/host/ufs-qcom.c | 81 ++++++++++++++++++++++++++++++++-----
+ 1 file changed, 71 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c
+index 28515f89ce798..2b000c1708ce4 100644
+--- a/drivers/ufs/host/ufs-qcom.c
++++ b/drivers/ufs/host/ufs-qcom.c
+@@ -103,7 +103,9 @@ static const struct __ufs_qcom_bw_table {
+ };
+ static void ufs_qcom_get_default_testbus_cfg(struct ufs_qcom_host *host);
+-static int ufs_qcom_set_core_clk_ctrl(struct ufs_hba *hba, unsigned long freq);
++static unsigned long ufs_qcom_opp_freq_to_clk_freq(struct ufs_hba *hba,
++                                                 unsigned long freq, char *name);
++static int ufs_qcom_set_core_clk_ctrl(struct ufs_hba *hba, bool is_scale_up, unsigned long freq);
+ static struct ufs_qcom_host *rcdev_to_ufs_host(struct reset_controller_dev *rcd)
+ {
+@@ -602,7 +604,7 @@ static int ufs_qcom_link_startup_notify(struct ufs_hba *hba,
+                       return -EINVAL;
+               }
+-              err = ufs_qcom_set_core_clk_ctrl(hba, ULONG_MAX);
++              err = ufs_qcom_set_core_clk_ctrl(hba, true, ULONG_MAX);
+               if (err)
+                       dev_err(hba->dev, "cfg core clk ctrl failed\n");
+               /*
+@@ -1360,29 +1362,46 @@ static int ufs_qcom_set_clk_40ns_cycles(struct ufs_hba *hba,
+       return ufshcd_dme_set(hba, UIC_ARG_MIB(PA_VS_CORE_CLK_40NS_CYCLES), reg);
+ }
+-static int ufs_qcom_set_core_clk_ctrl(struct ufs_hba *hba, unsigned long freq)
++static int ufs_qcom_set_core_clk_ctrl(struct ufs_hba *hba, bool is_scale_up, unsigned long freq)
+ {
+       struct ufs_qcom_host *host = ufshcd_get_variant(hba);
+       struct list_head *head = &hba->clk_list_head;
+       struct ufs_clk_info *clki;
+       u32 cycles_in_1us = 0;
+       u32 core_clk_ctrl_reg;
++      unsigned long clk_freq;
+       int err;
++      if (hba->use_pm_opp && freq != ULONG_MAX) {
++              clk_freq = ufs_qcom_opp_freq_to_clk_freq(hba, freq, "core_clk_unipro");
++              if (clk_freq) {
++                      cycles_in_1us = ceil(clk_freq, HZ_PER_MHZ);
++                      goto set_core_clk_ctrl;
++              }
++      }
++
+       list_for_each_entry(clki, head, list) {
+               if (!IS_ERR_OR_NULL(clki->clk) &&
+                   !strcmp(clki->name, "core_clk_unipro")) {
+-                      if (!clki->max_freq)
++                      if (!clki->max_freq) {
+                               cycles_in_1us = 150; /* default for backwards compatibility */
+-                      else if (freq == ULONG_MAX)
++                              break;
++                      }
++
++                      if (freq == ULONG_MAX) {
+                               cycles_in_1us = ceil(clki->max_freq, HZ_PER_MHZ);
+-                      else
+-                              cycles_in_1us = ceil(freq, HZ_PER_MHZ);
++                              break;
++                      }
++                      if (is_scale_up)
++                              cycles_in_1us = ceil(clki->max_freq, HZ_PER_MHZ);
++                      else
++                              cycles_in_1us = ceil(clk_get_rate(clki->clk), HZ_PER_MHZ);
+                       break;
+               }
+       }
++set_core_clk_ctrl:
+       err = ufshcd_dme_get(hba,
+                           UIC_ARG_MIB(DME_VS_CORE_CLK_CTRL),
+                           &core_clk_ctrl_reg);
+@@ -1425,7 +1444,7 @@ static int ufs_qcom_clk_scale_up_pre_change(struct ufs_hba *hba, unsigned long f
+               return ret;
+       }
+       /* set unipro core clock attributes and clear clock divider */
+-      return ufs_qcom_set_core_clk_ctrl(hba, freq);
++      return ufs_qcom_set_core_clk_ctrl(hba, true, freq);
+ }
+ static int ufs_qcom_clk_scale_up_post_change(struct ufs_hba *hba)
+@@ -1457,7 +1476,7 @@ static int ufs_qcom_clk_scale_down_pre_change(struct ufs_hba *hba)
+ static int ufs_qcom_clk_scale_down_post_change(struct ufs_hba *hba, unsigned long freq)
+ {
+       /* set unipro core clock attributes and clear clock divider */
+-      return ufs_qcom_set_core_clk_ctrl(hba, freq);
++      return ufs_qcom_set_core_clk_ctrl(hba, false, freq);
+ }
+ static int ufs_qcom_clk_scale_notify(struct ufs_hba *hba, bool scale_up,
+@@ -1922,11 +1941,53 @@ static int ufs_qcom_config_esi(struct ufs_hba *hba)
+       return ret;
+ }
++static unsigned long ufs_qcom_opp_freq_to_clk_freq(struct ufs_hba *hba,
++                                                 unsigned long freq, char *name)
++{
++      struct ufs_clk_info *clki;
++      struct dev_pm_opp *opp;
++      unsigned long clk_freq;
++      int idx = 0;
++      bool found = false;
++
++      opp = dev_pm_opp_find_freq_exact_indexed(hba->dev, freq, 0, true);
++      if (IS_ERR(opp)) {
++              dev_err(hba->dev, "Failed to find OPP for exact frequency %lu\n", freq);
++              return 0;
++      }
++
++      list_for_each_entry(clki, &hba->clk_list_head, list) {
++              if (!strcmp(clki->name, name)) {
++                      found = true;
++                      break;
++              }
++
++              idx++;
++      }
++
++      if (!found) {
++              dev_err(hba->dev, "Failed to find clock '%s' in clk list\n", name);
++              dev_pm_opp_put(opp);
++              return 0;
++      }
++
++      clk_freq = dev_pm_opp_get_freq_indexed(opp, idx);
++
++      dev_pm_opp_put(opp);
++
++      return clk_freq;
++}
++
+ static u32 ufs_qcom_freq_to_gear_speed(struct ufs_hba *hba, unsigned long freq)
+ {
+       u32 gear = UFS_HS_DONT_CHANGE;
++      unsigned long unipro_freq;
++
++      if (!hba->use_pm_opp)
++              return gear;
+-      switch (freq) {
++      unipro_freq = ufs_qcom_opp_freq_to_clk_freq(hba, freq, "core_clk_unipro");
++      switch (unipro_freq) {
+       case 403000000:
+               gear = UFS_HS_G5;
+               break;
+-- 
+2.39.5
+
diff --git a/queue-6.15/scsi-ufs-qcom-prevent-calling-phy_exit-before-phy_in.patch b/queue-6.15/scsi-ufs-qcom-prevent-calling-phy_exit-before-phy_in.patch
new file mode 100644 (file)
index 0000000..58210c8
--- /dev/null
@@ -0,0 +1,44 @@
+From 2a846d506c77621d8b4e851364a9d9747480468f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 May 2025 21:08:12 +0530
+Subject: scsi: ufs: qcom: Prevent calling phy_exit() before phy_init()
+
+From: Nitin Rawat <quic_nitirawa@quicinc.com>
+
+[ Upstream commit 7831003165d37ecb7b33843fcee05cada0359a82 ]
+
+Prevent calling phy_exit() before phy_init() to avoid abnormal power
+count and the following warning during boot up.
+
+[5.146763] phy phy-1d80000.phy.0: phy_power_on was called before phy_init
+
+Fixes: 7bac65687510 ("scsi: ufs: qcom: Power off the PHY if it was already powered on in ufs_qcom_power_up_sequence()")
+Signed-off-by: Nitin Rawat <quic_nitirawa@quicinc.com>
+Link: https://lore.kernel.org/r/20250526153821.7918-2-quic_nitirawa@quicinc.com
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ufs/host/ufs-qcom.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c
+index 2b000c1708ce4..31649f908dd46 100644
+--- a/drivers/ufs/host/ufs-qcom.c
++++ b/drivers/ufs/host/ufs-qcom.c
+@@ -454,10 +454,9 @@ static int ufs_qcom_power_up_sequence(struct ufs_hba *hba)
+       if (ret)
+               return ret;
+-      if (phy->power_count) {
++      if (phy->power_count)
+               phy_power_off(phy);
+-              phy_exit(phy);
+-      }
++
+       /* phy initialization - calibrate the phy */
+       ret = phy_init(phy);
+-- 
+2.39.5
+
diff --git a/queue-6.15/seg6-fix-validation-of-nexthop-addresses.patch b/queue-6.15/seg6-fix-validation-of-nexthop-addresses.patch
new file mode 100644 (file)
index 0000000..630191b
--- /dev/null
@@ -0,0 +1,48 @@
+From 62b38eee896416996f2b7c84a0806641c95f2a1e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Jun 2025 14:32:52 +0300
+Subject: seg6: Fix validation of nexthop addresses
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 7632fedb266d93ed0ed9f487133e6c6314a9b2d1 ]
+
+The kernel currently validates that the length of the provided nexthop
+address does not exceed the specified length. This can lead to the
+kernel reading uninitialized memory if user space provided a shorter
+length than the specified one.
+
+Fix by validating that the provided length exactly matches the specified
+one.
+
+Fixes: d1df6fd8a1d2 ("ipv6: sr: define core operations for seg6local lightweight tunnel")
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://patch.msgid.link/20250604113252.371528-1-idosch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/seg6_local.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/net/ipv6/seg6_local.c b/net/ipv6/seg6_local.c
+index ac1dbd492c22d..a11a02b4ba95b 100644
+--- a/net/ipv6/seg6_local.c
++++ b/net/ipv6/seg6_local.c
+@@ -1644,10 +1644,8 @@ static const struct nla_policy seg6_local_policy[SEG6_LOCAL_MAX + 1] = {
+       [SEG6_LOCAL_SRH]        = { .type = NLA_BINARY },
+       [SEG6_LOCAL_TABLE]      = { .type = NLA_U32 },
+       [SEG6_LOCAL_VRFTABLE]   = { .type = NLA_U32 },
+-      [SEG6_LOCAL_NH4]        = { .type = NLA_BINARY,
+-                                  .len = sizeof(struct in_addr) },
+-      [SEG6_LOCAL_NH6]        = { .type = NLA_BINARY,
+-                                  .len = sizeof(struct in6_addr) },
++      [SEG6_LOCAL_NH4]        = NLA_POLICY_EXACT_LEN(sizeof(struct in_addr)),
++      [SEG6_LOCAL_NH6]        = NLA_POLICY_EXACT_LEN(sizeof(struct in6_addr)),
+       [SEG6_LOCAL_IIF]        = { .type = NLA_U32 },
+       [SEG6_LOCAL_OIF]        = { .type = NLA_U32 },
+       [SEG6_LOCAL_BPF]        = { .type = NLA_NESTED },
+-- 
+2.39.5
+
diff --git a/queue-6.15/selftests-bpf-avoid-passing-out-of-range-values-to-_.patch b/queue-6.15/selftests-bpf-avoid-passing-out-of-range-values-to-_.patch
new file mode 100644 (file)
index 0000000..f11f356
--- /dev/null
@@ -0,0 +1,224 @@
+From e7229593a25860fdb9a0e976e583ce50e7f1785b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 May 2025 03:43:19 +0000
+Subject: selftests/bpf: Avoid passing out-of-range values to __retval()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Peilin Ye <yepeilin@google.com>
+
+[ Upstream commit 6e492ffcab6064cd7b317dc1f49fb9f92407aaa7 ]
+
+Currently, we pass 0x1234567890abcdef to __retval() for the following
+two tests:
+
+  verifier_load_acquire/load_acquire_64
+  verifier_store_release/store_release_64
+
+However, the upper 32 bits of that value are being ignored, since
+__retval() expects an int.  Actually, the tests would still pass even if
+I change '__retval(0x1234567890abcdef)' to e.g. '__retval(0x90abcdef)'.
+
+Restructure the tests a bit to test the entire 64-bit values properly.
+Do the same to their 8-, 16- and 32-bit variants as well to keep the
+style consistent.
+
+Fixes: ff3afe5da998 ("selftests/bpf: Add selftests for load-acquire and store-release instructions")
+Acked-by: Björn Töpel <bjorn@kernel.org>
+Reviewed-by: Pu Lehui <pulehui@huawei.com>
+Tested-by: Björn Töpel <bjorn@rivosinc.com> # QEMU/RVA23
+Signed-off-by: Peilin Ye <yepeilin@google.com>
+Link: https://lore.kernel.org/r/d67f4c6f6ee0d0388cbce1f4892ec4176ee2d604.1746588351.git.yepeilin@google.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../bpf/progs/verifier_load_acquire.c         | 40 +++++++++++++------
+ .../bpf/progs/verifier_store_release.c        | 32 +++++++++++----
+ 2 files changed, 52 insertions(+), 20 deletions(-)
+
+diff --git a/tools/testing/selftests/bpf/progs/verifier_load_acquire.c b/tools/testing/selftests/bpf/progs/verifier_load_acquire.c
+index 77698d5a19e44..a696ab84bfd66 100644
+--- a/tools/testing/selftests/bpf/progs/verifier_load_acquire.c
++++ b/tools/testing/selftests/bpf/progs/verifier_load_acquire.c
+@@ -10,65 +10,81 @@
+ SEC("socket")
+ __description("load-acquire, 8-bit")
+-__success __success_unpriv __retval(0x12)
++__success __success_unpriv __retval(0)
+ __naked void load_acquire_8(void)
+ {
+       asm volatile (
++      "r0 = 0;"
+       "w1 = 0x12;"
+       "*(u8 *)(r10 - 1) = w1;"
+-      ".8byte %[load_acquire_insn];" // w0 = load_acquire((u8 *)(r10 - 1));
++      ".8byte %[load_acquire_insn];" // w2 = load_acquire((u8 *)(r10 - 1));
++      "if r2 == r1 goto 1f;"
++      "r0 = 1;"
++"1:"
+       "exit;"
+       :
+       : __imm_insn(load_acquire_insn,
+-                   BPF_ATOMIC_OP(BPF_B, BPF_LOAD_ACQ, BPF_REG_0, BPF_REG_10, -1))
++                   BPF_ATOMIC_OP(BPF_B, BPF_LOAD_ACQ, BPF_REG_2, BPF_REG_10, -1))
+       : __clobber_all);
+ }
+ SEC("socket")
+ __description("load-acquire, 16-bit")
+-__success __success_unpriv __retval(0x1234)
++__success __success_unpriv __retval(0)
+ __naked void load_acquire_16(void)
+ {
+       asm volatile (
++      "r0 = 0;"
+       "w1 = 0x1234;"
+       "*(u16 *)(r10 - 2) = w1;"
+-      ".8byte %[load_acquire_insn];" // w0 = load_acquire((u16 *)(r10 - 2));
++      ".8byte %[load_acquire_insn];" // w2 = load_acquire((u16 *)(r10 - 2));
++      "if r2 == r1 goto 1f;"
++      "r0 = 1;"
++"1:"
+       "exit;"
+       :
+       : __imm_insn(load_acquire_insn,
+-                   BPF_ATOMIC_OP(BPF_H, BPF_LOAD_ACQ, BPF_REG_0, BPF_REG_10, -2))
++                   BPF_ATOMIC_OP(BPF_H, BPF_LOAD_ACQ, BPF_REG_2, BPF_REG_10, -2))
+       : __clobber_all);
+ }
+ SEC("socket")
+ __description("load-acquire, 32-bit")
+-__success __success_unpriv __retval(0x12345678)
++__success __success_unpriv __retval(0)
+ __naked void load_acquire_32(void)
+ {
+       asm volatile (
++      "r0 = 0;"
+       "w1 = 0x12345678;"
+       "*(u32 *)(r10 - 4) = w1;"
+-      ".8byte %[load_acquire_insn];" // w0 = load_acquire((u32 *)(r10 - 4));
++      ".8byte %[load_acquire_insn];" // w2 = load_acquire((u32 *)(r10 - 4));
++      "if r2 == r1 goto 1f;"
++      "r0 = 1;"
++"1:"
+       "exit;"
+       :
+       : __imm_insn(load_acquire_insn,
+-                   BPF_ATOMIC_OP(BPF_W, BPF_LOAD_ACQ, BPF_REG_0, BPF_REG_10, -4))
++                   BPF_ATOMIC_OP(BPF_W, BPF_LOAD_ACQ, BPF_REG_2, BPF_REG_10, -4))
+       : __clobber_all);
+ }
+ SEC("socket")
+ __description("load-acquire, 64-bit")
+-__success __success_unpriv __retval(0x1234567890abcdef)
++__success __success_unpriv __retval(0)
+ __naked void load_acquire_64(void)
+ {
+       asm volatile (
++      "r0 = 0;"
+       "r1 = 0x1234567890abcdef ll;"
+       "*(u64 *)(r10 - 8) = r1;"
+-      ".8byte %[load_acquire_insn];" // r0 = load_acquire((u64 *)(r10 - 8));
++      ".8byte %[load_acquire_insn];" // r2 = load_acquire((u64 *)(r10 - 8));
++      "if r2 == r1 goto 1f;"
++      "r0 = 1;"
++"1:"
+       "exit;"
+       :
+       : __imm_insn(load_acquire_insn,
+-                   BPF_ATOMIC_OP(BPF_DW, BPF_LOAD_ACQ, BPF_REG_0, BPF_REG_10, -8))
++                   BPF_ATOMIC_OP(BPF_DW, BPF_LOAD_ACQ, BPF_REG_2, BPF_REG_10, -8))
+       : __clobber_all);
+ }
+diff --git a/tools/testing/selftests/bpf/progs/verifier_store_release.c b/tools/testing/selftests/bpf/progs/verifier_store_release.c
+index c0442d5bb049d..022d03d983595 100644
+--- a/tools/testing/selftests/bpf/progs/verifier_store_release.c
++++ b/tools/testing/selftests/bpf/progs/verifier_store_release.c
+@@ -11,13 +11,17 @@
+ SEC("socket")
+ __description("store-release, 8-bit")
+-__success __success_unpriv __retval(0x12)
++__success __success_unpriv __retval(0)
+ __naked void store_release_8(void)
+ {
+       asm volatile (
++      "r0 = 0;"
+       "w1 = 0x12;"
+       ".8byte %[store_release_insn];" // store_release((u8 *)(r10 - 1), w1);
+-      "w0 = *(u8 *)(r10 - 1);"
++      "w2 = *(u8 *)(r10 - 1);"
++      "if r2 == r1 goto 1f;"
++      "r0 = 1;"
++"1:"
+       "exit;"
+       :
+       : __imm_insn(store_release_insn,
+@@ -27,13 +31,17 @@ __naked void store_release_8(void)
+ SEC("socket")
+ __description("store-release, 16-bit")
+-__success __success_unpriv __retval(0x1234)
++__success __success_unpriv __retval(0)
+ __naked void store_release_16(void)
+ {
+       asm volatile (
++      "r0 = 0;"
+       "w1 = 0x1234;"
+       ".8byte %[store_release_insn];" // store_release((u16 *)(r10 - 2), w1);
+-      "w0 = *(u16 *)(r10 - 2);"
++      "w2 = *(u16 *)(r10 - 2);"
++      "if r2 == r1 goto 1f;"
++      "r0 = 1;"
++"1:"
+       "exit;"
+       :
+       : __imm_insn(store_release_insn,
+@@ -43,13 +51,17 @@ __naked void store_release_16(void)
+ SEC("socket")
+ __description("store-release, 32-bit")
+-__success __success_unpriv __retval(0x12345678)
++__success __success_unpriv __retval(0)
+ __naked void store_release_32(void)
+ {
+       asm volatile (
++      "r0 = 0;"
+       "w1 = 0x12345678;"
+       ".8byte %[store_release_insn];" // store_release((u32 *)(r10 - 4), w1);
+-      "w0 = *(u32 *)(r10 - 4);"
++      "w2 = *(u32 *)(r10 - 4);"
++      "if r2 == r1 goto 1f;"
++      "r0 = 1;"
++"1:"
+       "exit;"
+       :
+       : __imm_insn(store_release_insn,
+@@ -59,13 +71,17 @@ __naked void store_release_32(void)
+ SEC("socket")
+ __description("store-release, 64-bit")
+-__success __success_unpriv __retval(0x1234567890abcdef)
++__success __success_unpriv __retval(0)
+ __naked void store_release_64(void)
+ {
+       asm volatile (
++      "r0 = 0;"
+       "r1 = 0x1234567890abcdef ll;"
+       ".8byte %[store_release_insn];" // store_release((u64 *)(r10 - 8), r1);
+-      "r0 = *(u64 *)(r10 - 8);"
++      "r2 = *(u64 *)(r10 - 8);"
++      "if r2 == r1 goto 1f;"
++      "r0 = 1;"
++"1:"
+       "exit;"
+       :
+       : __imm_insn(store_release_insn,
+-- 
+2.39.5
+
diff --git a/queue-6.15/selftests-bpf-fix-bpf_nf-selftest-failure.patch b/queue-6.15/selftests-bpf-fix-bpf_nf-selftest-failure.patch
new file mode 100644 (file)
index 0000000..d54718c
--- /dev/null
@@ -0,0 +1,43 @@
+From f074dba4f89bc4ab4838a6605bf453d158cdc03d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Apr 2025 15:26:33 +0530
+Subject: selftests/bpf: Fix bpf_nf selftest failure
+
+From: Saket Kumar Bhaskar <skb99@linux.ibm.com>
+
+[ Upstream commit 967e8def1100cb4b08c28a54d27ce69563fdf281 ]
+
+For systems with missing iptables-legacy tool this selftest fails.
+
+Add check to find if iptables-legacy tool is available and skip the
+test if the tool is missing.
+
+Fixes: de9c8d848d90 ("selftests/bpf: S/iptables/iptables-legacy/ in the bpf_nf and xdp_synproxy test")
+Signed-off-by: Saket Kumar Bhaskar <skb99@linux.ibm.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20250409095633.33653-1-skb99@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/prog_tests/bpf_nf.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_nf.c b/tools/testing/selftests/bpf/prog_tests/bpf_nf.c
+index dbd13f8e42a7a..dd6512fa652be 100644
+--- a/tools/testing/selftests/bpf/prog_tests/bpf_nf.c
++++ b/tools/testing/selftests/bpf/prog_tests/bpf_nf.c
+@@ -63,6 +63,12 @@ static void test_bpf_nf_ct(int mode)
+               .repeat = 1,
+       );
++      if (SYS_NOFAIL("iptables-legacy --version")) {
++              fprintf(stdout, "Missing required iptables-legacy tool\n");
++              test__skip();
++              return;
++      }
++
+       skel = test_bpf_nf__open_and_load();
+       if (!ASSERT_OK_PTR(skel, "test_bpf_nf__open_and_load"))
+               return;
+-- 
+2.39.5
+
diff --git a/queue-6.15/selftests-bpf-fix-caps-for-__xlated-jited_unpriv.patch b/queue-6.15/selftests-bpf-fix-caps-for-__xlated-jited_unpriv.patch
new file mode 100644 (file)
index 0000000..83272cc
--- /dev/null
@@ -0,0 +1,70 @@
+From 469323c5fe168909b9a521832e8bd9f365cffda3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 May 2025 09:35:52 +0200
+Subject: selftests/bpf: Fix caps for __xlated/jited_unpriv
+
+From: Luis Gerhorst <luis.gerhorst@fau.de>
+
+[ Upstream commit cf15cdc0f0f39a5c6315200808ec3e3995b0c2d2 ]
+
+Currently, __xlated_unpriv and __jited_unpriv do not work because the
+BPF syscall will overwrite info.jited_prog_len and info.xlated_prog_len
+with 0 if the process is not bpf_capable(). This bug was not noticed
+before, because there is no test that actually uses
+__xlated_unpriv/__jited_unpriv.
+
+To resolve this, simply restore the capabilities earlier (but still
+after loading the program). Adding this here unconditionally is fine
+because the function first checks that the capabilities were initialized
+before attempting to restore them.
+
+This will be important later when we add tests that check whether a
+speculation barrier was inserted in the correct location.
+
+Signed-off-by: Luis Gerhorst <luis.gerhorst@fau.de>
+Fixes: 9c9f73391310 ("selftests/bpf: allow checking xlated programs in verifier_* tests")
+Fixes: 7d743e4c759c ("selftests/bpf: __jited test tag to check disassembly after jit")
+Acked-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+Tested-by: Eduard Zingerman <eddyz87@gmail.com>
+Link: https://lore.kernel.org/r/20250501073603.1402960-2-luis.gerhorst@fau.de
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/test_loader.c | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/tools/testing/selftests/bpf/test_loader.c b/tools/testing/selftests/bpf/test_loader.c
+index 49f2fc61061f5..9551d8d5f8f9f 100644
+--- a/tools/testing/selftests/bpf/test_loader.c
++++ b/tools/testing/selftests/bpf/test_loader.c
+@@ -1042,6 +1042,14 @@ void run_subtest(struct test_loader *tester,
+       emit_verifier_log(tester->log_buf, false /*force*/);
+       validate_msgs(tester->log_buf, &subspec->expect_msgs, emit_verifier_log);
++      /* Restore capabilities because the kernel will silently ignore requests
++       * for program info (such as xlated program text) if we are not
++       * bpf-capable. Also, for some reason test_verifier executes programs
++       * with all capabilities restored. Do the same here.
++       */
++      if (restore_capabilities(&caps))
++              goto tobj_cleanup;
++
+       if (subspec->expect_xlated.cnt) {
+               err = get_xlated_program_text(bpf_program__fd(tprog),
+                                             tester->log_buf, tester->log_buf_sz);
+@@ -1067,12 +1075,6 @@ void run_subtest(struct test_loader *tester,
+       }
+       if (should_do_test_run(spec, subspec)) {
+-              /* For some reason test_verifier executes programs
+-               * with all capabilities restored. Do the same here.
+-               */
+-              if (restore_capabilities(&caps))
+-                      goto tobj_cleanup;
+-
+               /* Do bpf_map__attach_struct_ops() for each struct_ops map.
+                * This should trigger bpf_struct_ops->reg callback on kernel side.
+                */
+-- 
+2.39.5
+
diff --git a/queue-6.15/selftests-bpf-fix-kmem_cache-iterator-draining.patch b/queue-6.15/selftests-bpf-fix-kmem_cache-iterator-draining.patch
new file mode 100644 (file)
index 0000000..b127824
--- /dev/null
@@ -0,0 +1,48 @@
+From 3bb978af6411a73b07a10b877a10f363afb68c98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Apr 2025 18:02:54 +0000
+Subject: selftests/bpf: Fix kmem_cache iterator draining
+
+From: T.J. Mercier <tjmercier@google.com>
+
+[ Upstream commit 38d976c32d85ef12dcd2b8a231196f7049548477 ]
+
+The closing parentheses around the read syscall is misplaced, causing
+single byte reads from the iterator instead of buf sized reads. While
+the end result is the same, many more read calls than necessary are
+performed.
+
+$ tools/testing/selftests/bpf/vmtest.sh  "./test_progs -t kmem_cache_iter"
+145/1   kmem_cache_iter/check_task_struct:OK
+145/2   kmem_cache_iter/check_slabinfo:OK
+145/3   kmem_cache_iter/open_coded_iter:OK
+145     kmem_cache_iter:OK
+Summary: 1/3 PASSED, 0 SKIPPED, 0 FAILED
+
+Fixes: a496d0cdc84d ("selftests/bpf: Add a test for kmem_cache_iter")
+Signed-off-by: T.J. Mercier <tjmercier@google.com>
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Acked-by: Song Liu <song@kernel.org>
+Acked-by: Namhyung Kim <namhyung@kernel.org>
+Link: https://patch.msgid.link/20250428180256.1482899-1-tjmercier@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/prog_tests/kmem_cache_iter.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/kmem_cache_iter.c b/tools/testing/selftests/bpf/prog_tests/kmem_cache_iter.c
+index 8e13a3416a21d..1de14b111931a 100644
+--- a/tools/testing/selftests/bpf/prog_tests/kmem_cache_iter.c
++++ b/tools/testing/selftests/bpf/prog_tests/kmem_cache_iter.c
+@@ -104,7 +104,7 @@ void test_kmem_cache_iter(void)
+               goto destroy;
+       memset(buf, 0, sizeof(buf));
+-      while (read(iter_fd, buf, sizeof(buf) > 0)) {
++      while (read(iter_fd, buf, sizeof(buf)) > 0) {
+               /* Read out all contents */
+               printf("%s", buf);
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/selftests-coredump-fix-test-failure-for-slow-machine.patch b/queue-6.15/selftests-coredump-fix-test-failure-for-slow-machine.patch
new file mode 100644 (file)
index 0000000..32e6433
--- /dev/null
@@ -0,0 +1,53 @@
+From 784f4eeb69698131f9767363cd34fb9a8de4dc4d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Apr 2025 17:09:42 +0200
+Subject: selftests: coredump: Fix test failure for slow machines
+
+From: Nam Cao <namcao@linutronix.de>
+
+[ Upstream commit 6f5bf9f37f06668ead446e2997f2b431db8963ce ]
+
+The test waits for coredump to finish by busy-waiting for the stack_values
+file to be created. The maximum wait time is 10 seconds.
+
+This doesn't work for slow machine (qemu-system-riscv64), because coredump
+takes longer.
+
+Fix it by waiting for the crashing child process to finish first.
+
+Fixes: 15858da53542 ("selftests: coredump: Add stackdump test")
+Signed-off-by: Nam Cao <namcao@linutronix.de>
+Link: https://lore.kernel.org/ee657f3fc8e19657cf7aaa366552d6347728f371.1744383419.git.namcao@linutronix.de
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/coredump/stackdump_test.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/coredump/stackdump_test.c b/tools/testing/selftests/coredump/stackdump_test.c
+index c23cf95c3f6df..9da10fb5e597c 100644
+--- a/tools/testing/selftests/coredump/stackdump_test.c
++++ b/tools/testing/selftests/coredump/stackdump_test.c
+@@ -96,7 +96,7 @@ TEST_F(coredump, stackdump)
+       char *test_dir, *line;
+       size_t line_length;
+       char buf[PATH_MAX];
+-      int ret, i;
++      int ret, i, status;
+       FILE *file;
+       pid_t pid;
+@@ -129,6 +129,10 @@ TEST_F(coredump, stackdump)
+       /*
+        * Step 3: Wait for the stackdump script to write the stack pointers to the stackdump file
+        */
++      waitpid(pid, &status, 0);
++      ASSERT_TRUE(WIFSIGNALED(status));
++      ASSERT_TRUE(WCOREDUMP(status));
++
+       for (i = 0; i < 10; ++i) {
+               file = fopen(STACKDUMP_FILE, "r");
+               if (file)
+-- 
+2.39.5
+
diff --git a/queue-6.15/selftests-coredump-properly-initialize-pointer.patch b/queue-6.15/selftests-coredump-properly-initialize-pointer.patch
new file mode 100644 (file)
index 0000000..c5585c5
--- /dev/null
@@ -0,0 +1,49 @@
+From be1ed4199de3c8fa29c49f72392cc03715af6502 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Apr 2025 17:09:41 +0200
+Subject: selftests: coredump: Properly initialize pointer
+
+From: Nam Cao <namcao@linutronix.de>
+
+[ Upstream commit e194d2067c958827810a7a7282dff8773633ad8c ]
+
+The buffer pointer "line" is not initialized. This pointer is passed to
+getline().
+
+It can still work if the stack is zero-initialized, because getline() can
+work with a NULL pointer as buffer.
+
+But this is obviously broken. This bug shows up while running the test on a
+riscv64 machine.
+
+Fix it by properly initializing the pointer.
+
+Fixes: 15858da53542 ("selftests: coredump: Add stackdump test")
+Signed-off-by: Nam Cao <namcao@linutronix.de>
+Link: https://lore.kernel.org/4fb9b6fb3e0040481bacc258c44b4aab5c4df35d.1744383419.git.namcao@linutronix.de
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/coredump/stackdump_test.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/tools/testing/selftests/coredump/stackdump_test.c b/tools/testing/selftests/coredump/stackdump_test.c
+index 137b2364a0820..c23cf95c3f6df 100644
+--- a/tools/testing/selftests/coredump/stackdump_test.c
++++ b/tools/testing/selftests/coredump/stackdump_test.c
+@@ -138,10 +138,12 @@ TEST_F(coredump, stackdump)
+       ASSERT_NE(file, NULL);
+       /* Step 4: Make sure all stack pointer values are non-zero */
++      line = NULL;
+       for (i = 0; -1 != getline(&line, &line_length, file); ++i) {
+               stack = strtoull(line, NULL, 10);
+               ASSERT_NE(stack, 0);
+       }
++      free(line);
+       ASSERT_EQ(i, 1 + NUM_THREAD_SPAWN);
+-- 
+2.39.5
+
diff --git a/queue-6.15/selftests-coredump-raise-timeout-to-2-minutes.patch b/queue-6.15/selftests-coredump-raise-timeout-to-2-minutes.patch
new file mode 100644 (file)
index 0000000..98542cb
--- /dev/null
@@ -0,0 +1,45 @@
+From 9b92bfadf6db4ef5bc1412e2137c51adf92d4dfa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Apr 2025 17:09:43 +0200
+Subject: selftests: coredump: Raise timeout to 2 minutes
+
+From: Nam Cao <namcao@linutronix.de>
+
+[ Upstream commit c6e888d02d51d1e9f9abf1587e6a5618375cac9f ]
+
+The test's runtime (nearly 20s) is dangerously close to the limit (30s) on
+qemu-system-riscv64:
+
+$ time ./stackdump_test > /dev/null
+real   0m19.210s
+user   0m0.077s
+sys    0m0.359s
+
+There could be machines slower than qemu-system-riscv64. Therefore raise
+the test timeout to 2 minutes to be safe.
+
+Fixes: 15858da53542 ("selftests: coredump: Add stackdump test")
+Signed-off-by: Nam Cao <namcao@linutronix.de>
+Link: https://lore.kernel.org/dd636084d55e7828782728d087fa2298dcab1c8b.1744383419.git.namcao@linutronix.de
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/coredump/stackdump_test.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/coredump/stackdump_test.c b/tools/testing/selftests/coredump/stackdump_test.c
+index 9da10fb5e597c..fe3c728cd6be5 100644
+--- a/tools/testing/selftests/coredump/stackdump_test.c
++++ b/tools/testing/selftests/coredump/stackdump_test.c
+@@ -89,7 +89,7 @@ FIXTURE_TEARDOWN(coredump)
+       fprintf(stderr, "Failed to cleanup stackdump test: %s\n", reason);
+ }
+-TEST_F(coredump, stackdump)
++TEST_F_TIMEOUT(coredump, stackdump, 120)
+ {
+       struct sigaction action = {};
+       unsigned long long stack;
+-- 
+2.39.5
+
diff --git a/queue-6.15/selftests-drv-net-tso-fix-the-gre-device-name.patch b/queue-6.15/selftests-drv-net-tso-fix-the-gre-device-name.patch
new file mode 100644 (file)
index 0000000..4131852
--- /dev/null
@@ -0,0 +1,41 @@
+From c1657bd30565ce32633937b48538458acb9b3b09 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Jun 2025 18:20:31 -0700
+Subject: selftests: drv-net: tso: fix the GRE device name
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit c68804c934e3197e34560744854c57cf88dff8e7 ]
+
+The device type for IPv4 GRE is "gre" not "ipgre",
+unlike for IPv6 which uses "ip6gre".
+
+Not sure how I missed this when writing the test, perhaps
+because all HW I have access to is on an IPv6-only network.
+
+Fixes: 0d0f4174f6c8 ("selftests: drv-net: add a simple TSO test")
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20250604012031.891242-1-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/drivers/net/hw/tso.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/drivers/net/hw/tso.py b/tools/testing/selftests/drivers/net/hw/tso.py
+index e1ecb92f79d9b..eec647e7ec19c 100755
+--- a/tools/testing/selftests/drivers/net/hw/tso.py
++++ b/tools/testing/selftests/drivers/net/hw/tso.py
+@@ -216,7 +216,7 @@ def main() -> None:
+             ("",            "6", "tx-tcp6-segmentation",          None),
+             ("vxlan",        "", "tx-udp_tnl-segmentation",       ("vxlan",  True,  "id 100 dstport 4789 noudpcsum")),
+             ("vxlan_csum",   "", "tx-udp_tnl-csum-segmentation",  ("vxlan",  False, "id 100 dstport 4789 udpcsum")),
+-            ("gre",         "4", "tx-gre-segmentation",           ("ipgre",  False,  "")),
++            ("gre",         "4", "tx-gre-segmentation",           ("gre",    False,  "")),
+             ("gre",         "6", "tx-gre-segmentation",           ("ip6gre", False,  "")),
+         )
+-- 
+2.39.5
+
diff --git a/queue-6.15/selftests-drv-net-tso-make-bkg-wait-for-socat-to-qui.patch b/queue-6.15/selftests-drv-net-tso-make-bkg-wait-for-socat-to-qui.patch
new file mode 100644 (file)
index 0000000..c8ca6a7
--- /dev/null
@@ -0,0 +1,44 @@
+From c31d4953897de8917f331b2ad30b5d28e93f89fe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Jun 2025 18:20:55 -0700
+Subject: selftests: drv-net: tso: make bkg() wait for socat to quit
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit e6854be4d80ea266a7be64a65a0322bcdfa72807 ]
+
+Commit 846742f7e32f ("selftests: drv-net: add a warning for
+bkg + shell + terminate") added a warning for bkg() used
+with terminate=True. The tso test was missed as we didn't
+have it running anywhere in NIPA. Add exit_wait=True, to avoid:
+
+  # Warning: combining shell and terminate is risky!
+  #          SIGTERM may not reach the child on zsh/ksh!
+
+getting printed twice for every variant.
+
+Fixes: 0d0f4174f6c8 ("selftests: drv-net: add a simple TSO test")
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20250604012055.891431-1-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/drivers/net/hw/tso.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/drivers/net/hw/tso.py b/tools/testing/selftests/drivers/net/hw/tso.py
+index eec647e7ec19c..3370827409aa0 100755
+--- a/tools/testing/selftests/drivers/net/hw/tso.py
++++ b/tools/testing/selftests/drivers/net/hw/tso.py
+@@ -39,7 +39,7 @@ def run_one_stream(cfg, ipver, remote_v4, remote_v6, should_lso):
+     port = rand_port()
+     listen_cmd = f"socat -{ipver} -t 2 -u TCP-LISTEN:{port},reuseport /dev/null,ignoreeof"
+-    with bkg(listen_cmd, host=cfg.remote) as nc:
++    with bkg(listen_cmd, host=cfg.remote, exit_wait=True) as nc:
+         wait_port_listen(port, host=cfg.remote)
+         if ipver == "4":
+-- 
+2.39.5
+
diff --git a/queue-6.15/selftests-net-build-net-lib-dependency-in-all-target.patch b/queue-6.15/selftests-net-build-net-lib-dependency-in-all-target.patch
new file mode 100644 (file)
index 0000000..f37a368
--- /dev/null
@@ -0,0 +1,40 @@
+From 59b9db0e1003c419b1933fab5faea0c427f786fa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 1 Jun 2025 21:29:13 +0700
+Subject: selftests: net: build net/lib dependency in all target
+
+From: Bui Quang Minh <minhquangbui99@gmail.com>
+
+[ Upstream commit d3f2a9587ebe68f5067f9ff624f9a83dfb911f60 ]
+
+We have the logic to include net/lib automatically for net related
+selftests. However, currently, this logic is only in install target
+which means only `make install` will have net/lib included. This commit
+adds the logic to all target so that all `make`, `make run_tests` and
+`make install` will have net/lib included in net related selftests.
+
+Signed-off-by: Bui Quang Minh <minhquangbui99@gmail.com>
+Link: https://patch.msgid.link/20250601142914.13379-1-minhquangbui99@gmail.com
+Fixes: b86761ff6374 ("selftests: net: add scaffolding for Netlink tests in Python")
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
+index 80fb84fa3cfcb..9c477321a5b47 100644
+--- a/tools/testing/selftests/Makefile
++++ b/tools/testing/selftests/Makefile
+@@ -202,7 +202,7 @@ export KHDR_INCLUDES
+ all:
+       @ret=1;                                                 \
+-      for TARGET in $(TARGETS); do                            \
++      for TARGET in $(TARGETS) $(INSTALL_DEP_TARGETS); do     \
+               BUILD_TARGET=$$BUILD/$$TARGET;                  \
+               mkdir $$BUILD_TARGET  -p;                       \
+               $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET       \
+-- 
+2.39.5
+
diff --git a/queue-6.15/selftests-seccomp-fix-negative_enosys-tracer-tests-o.patch b/queue-6.15/selftests-seccomp-fix-negative_enosys-tracer-tests-o.patch
new file mode 100644 (file)
index 0000000..b3843f0
--- /dev/null
@@ -0,0 +1,50 @@
+From 628b0e22bd7092d2648b0465c69635cd66597fd0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 May 2025 12:56:22 +0100
+Subject: selftests/seccomp: fix negative_ENOSYS tracer tests on arm32
+
+From: Terry Tritton <terry.tritton@linaro.org>
+
+[ Upstream commit 73989c998814d82c71d523c104c398925470d59e ]
+
+TRACE_syscall.ptrace.negative_ENOSYS and TRACE_syscall.seccomp.negative_ENOSYS
+on arm32 are being reported as failures instead of skipping.
+
+The teardown_trace_fixture function sets the test to KSFT_FAIL in case of a
+non 0 return value from the tracer process.
+Due to _metadata now being shared between the forked processes the tracer is
+returning the KSFT_SKIP value set by the tracee which is non 0.
+
+Remove the setting of the _metadata.exit_code in teardown_trace_fixture.
+
+Fixes: 24cf65a62266 ("selftests/harness: Share _metadata between forked processes")
+Signed-off-by: Terry Tritton <terry.tritton@linaro.org>
+Link: https://lore.kernel.org/r/20250509115622.64775-1-terry.tritton@linaro.org
+Signed-off-by: Kees Cook <kees@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/seccomp/seccomp_bpf.c | 6 ------
+ 1 file changed, 6 deletions(-)
+
+diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c
+index 53bf6a9c801f8..61acbd45ffaaf 100644
+--- a/tools/testing/selftests/seccomp/seccomp_bpf.c
++++ b/tools/testing/selftests/seccomp/seccomp_bpf.c
+@@ -1629,14 +1629,8 @@ void teardown_trace_fixture(struct __test_metadata *_metadata,
+ {
+       if (tracer) {
+               int status;
+-              /*
+-               * Extract the exit code from the other process and
+-               * adopt it for ourselves in case its asserts failed.
+-               */
+               ASSERT_EQ(0, kill(tracer, SIGUSR1));
+               ASSERT_EQ(tracer, waitpid(tracer, &status, 0));
+-              if (WEXITSTATUS(status))
+-                      _metadata->exit_code = KSFT_FAIL;
+       }
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/selftests-seccomp-fix-syscall_restart-test-for-arm-c.patch b/queue-6.15/selftests-seccomp-fix-syscall_restart-test-for-arm-c.patch
new file mode 100644 (file)
index 0000000..89f295f
--- /dev/null
@@ -0,0 +1,53 @@
+From 39be7e4e7ff7f6e75de29ac2a55880cfed8f56ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 27 Apr 2025 09:40:58 +0000
+Subject: selftests/seccomp: fix syscall_restart test for arm compat
+
+From: Neill Kapron <nkapron@google.com>
+
+[ Upstream commit 797002deed03491215a352ace891749b39741b69 ]
+
+The inconsistencies in the systcall ABI between arm and arm-compat can
+can cause a failure in the syscall_restart test due to the logic
+attempting to work around the differences. The 'machine' field for an
+ARM64 device running in compat mode can report 'armv8l' or 'armv8b'
+which matches with the string 'arm' when only examining the first three
+characters of the string.
+
+This change adds additional validation to the workaround logic to make
+sure we only take the arm path when running natively, not in arm-compat.
+
+Fixes: 256d0afb11d6 ("selftests/seccomp: build and pass on arm64")
+Signed-off-by: Neill Kapron <nkapron@google.com>
+Link: https://lore.kernel.org/r/20250427094103.3488304-2-nkapron@google.com
+Signed-off-by: Kees Cook <kees@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/seccomp/seccomp_bpf.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c
+index b2f76a52215ad..53bf6a9c801f8 100644
+--- a/tools/testing/selftests/seccomp/seccomp_bpf.c
++++ b/tools/testing/selftests/seccomp/seccomp_bpf.c
+@@ -3166,12 +3166,15 @@ TEST(syscall_restart)
+       ret = get_syscall(_metadata, child_pid);
+ #if defined(__arm__)
+       /*
+-       * FIXME:
+        * - native ARM registers do NOT expose true syscall.
+        * - compat ARM registers on ARM64 DO expose true syscall.
++       * - values of utsbuf.machine include 'armv8l' or 'armb8b'
++       *   for ARM64 running in compat mode.
+        */
+       ASSERT_EQ(0, uname(&utsbuf));
+-      if (strncmp(utsbuf.machine, "arm", 3) == 0) {
++      if ((strncmp(utsbuf.machine, "arm", 3) == 0) &&
++          (strncmp(utsbuf.machine, "armv8l", 6) != 0) &&
++          (strncmp(utsbuf.machine, "armv8b", 6) != 0)) {
+               EXPECT_EQ(__NR_nanosleep, ret);
+       } else
+ #endif
+-- 
+2.39.5
+
diff --git a/queue-6.15/serial-fix-potential-null-ptr-deref-in-mlb_usio_prob.patch b/queue-6.15/serial-fix-potential-null-ptr-deref-in-mlb_usio_prob.patch
new file mode 100644 (file)
index 0000000..50042a1
--- /dev/null
@@ -0,0 +1,43 @@
+From 19aa8b904dbcb381d4e249ac8105e46273b1652a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Apr 2025 15:03:39 +0800
+Subject: serial: Fix potential null-ptr-deref in mlb_usio_probe()
+
+From: Henry Martin <bsdhenrymartin@gmail.com>
+
+[ Upstream commit 86bcae88c9209e334b2f8c252f4cc66beb261886 ]
+
+devm_ioremap() can return NULL on error. Currently, mlb_usio_probe()
+does not check for this case, which could result in a NULL pointer
+dereference.
+
+Add NULL check after devm_ioremap() to prevent this issue.
+
+Fixes: ba44dc043004 ("serial: Add Milbeaut serial control")
+Signed-off-by: Henry Martin <bsdhenrymartin@gmail.com>
+Link: https://lore.kernel.org/r/20250403070339.64990-1-bsdhenrymartin@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/milbeaut_usio.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/tty/serial/milbeaut_usio.c b/drivers/tty/serial/milbeaut_usio.c
+index 059bea18dbab5..4e47dca2c4ed9 100644
+--- a/drivers/tty/serial/milbeaut_usio.c
++++ b/drivers/tty/serial/milbeaut_usio.c
+@@ -523,7 +523,10 @@ static int mlb_usio_probe(struct platform_device *pdev)
+       }
+       port->membase = devm_ioremap(&pdev->dev, res->start,
+                               resource_size(res));
+-
++      if (!port->membase) {
++              ret = -ENOMEM;
++              goto failed;
++      }
+       ret = platform_get_irq_byname(pdev, "rx");
+       mlb_usio_irq[index][RX] = ret;
+-- 
+2.39.5
+
diff --git a/queue-6.15/series b/queue-6.15/series
new file mode 100644 (file)
index 0000000..93abb6e
--- /dev/null
@@ -0,0 +1,659 @@
+tools-x86-kcpuid-fix-error-handling.patch
+x86-idle-remove-mfences-for-x86_bug_clflush_monitor-.patch
+crypto-iaa-do-not-clobber-req-base.data.patch
+crypto-sun8i-ce-hash-fix-error-handling-in-sun8i_ce_.patch
+sched-fix-trace_sched_switch-.prev_state.patch
+crypto-ecdsa-fix-enc-dec-size-reported-by-keyctl_pke.patch
+crypto-ecdsa-fix-nist-p521-key-size-reported-by-keyc.patch
+crypto-zynqmp-sha-add-locking.patch
+kunit-qemu_configs-sparc-explicitly-enable-config_sp.patch
+kunit-qemu_configs-disable-faulting-tests-on-32-bit-.patch
+perf-x86-amd-uncore-remove-unused-struct-amd_uncore_.patch
+perf-x86-amd-uncore-prevent-umc-counters-from-satura.patch
+gfs2-replace-sd_aspace-with-sd_inode.patch
+gfs2-gfs2_create_inode-error-handling-fix.patch
+gfs2-move-gfs2_dinode_dealloc.patch
+gfs2-move-gif_alloc_failed-check-out-of-gfs2_ea_deal.patch
+gfs2-deallocate-inodes-in-gfs2_create_inode.patch
+perf-core-fix-broken-throttling-when-max_samples_per.patch
+crypto-sun8i-ce-cipher-fix-error-handling-in-sun8i_c.patch
+crypto-sun8i-ss-do-not-use-sg_dma_len-before-calling.patch
+powerpc-do-not-build-ppc_save_regs.o-always.patch
+powerpc-crash-fix-non-smp-kexec-preparation.patch
+sched-core-tweak-wait_task_inactive-to-force-dequeue.patch
+x86-microcode-amd-do-not-return-error-when-microcode.patch
+selftests-coredump-properly-initialize-pointer.patch
+selftests-coredump-fix-test-failure-for-slow-machine.patch
+selftests-coredump-raise-timeout-to-2-minutes.patch
+crypto-sun8i-ce-undo-runtime-pm-changes-during-drive.patch
+blk-throttle-fix-wrong-tg-bytes-io-_disp-update-in-_.patch
+x86-cpu-sanitize-cpuid-0x80000000-output.patch
+x86-insn-fix-opcode-map-rex2-superscript-tags.patch
+brd-fix-aligned_sector-from-brd_do_discard.patch
+brd-fix-discard-end-sector.patch
+kselftest-cpufreq-get-rid-of-double-suspend-in-rtcwa.patch
+crypto-marvell-cesa-handle-zero-length-skcipher-requ.patch
+crypto-marvell-cesa-avoid-empty-transfer-descriptor.patch
+erofs-fix-file-handle-encoding-for-64-bit-nids.patch
+erofs-avoid-using-multiple-devices-with-different-ty.patch
+powerpc-pseries-iommu-fix-kmemleak-in-tce-table-user.patch
+btrfs-scrub-update-device-stats-when-an-error-is-det.patch
+btrfs-scrub-fix-a-wrong-error-type-when-metadata-byt.patch
+btrfs-fix-invalid-data-space-release-when-truncating.patch
+btrfs-fix-wrong-start-offset-for-delalloc-space-rele.patch
+rcu-cpu_stall_cputime-fix-the-hardirq-count-for-x86-.patch
+crypto-lrw-only-add-ecb-if-it-is-not-already-there.patch
+crypto-xts-only-add-ecb-if-it-is-not-already-there.patch
+crypto-sun8i-ce-move-fallback-ahash_request-to-the-e.patch
+sched-fair-fixup-wake_up_sync-vs-delayed_dequeue.patch
+kunit-fix-wrong-parameter-to-kunit_deactivate_static.patch
+gfs2-move-gfs2_trans_add_databufs.patch
+gfs2-don-t-start-unnecessary-transactions-during-log.patch
+crypto-api-redo-lookup-on-eexist.patch
+acpica-exserial-don-t-forget-to-handle-ffixedhw-opre.patch
+tools-nolibc-types.h-fix-mismatched-parenthesis-in-m.patch
+asoc-tas2764-reinit-cache-on-part-reset.patch
+asoc-tas2764-enable-main-irqs.patch
+asoc-mediatek-mt8195-set-etdm1-2-in-out-to-comp_dumm.patch
+edac-skx_common-fix-general-protection-fault.patch
+edac-skx_common-i10nm-fix-the-loss-of-saved-rrl-for-.patch
+tools-nolibc-properly-align-dirent-buffer.patch
+tools-nolibc-fix-integer-overflow-in-i-64-toa_r-and.patch
+spi-tegra210-quad-fix-x1_x2_x4-encoding-and-support-.patch
+spi-tegra210-quad-remove-redundant-error-handling-co.patch
+spi-tegra210-quad-modify-chip-select-cs-deactivation.patch
+power-reset-at91-reset-optimize-at91_reset.patch
+pm-em-fix-potential-division-by-zero-error-in-em_com.patch
+power-supply-max77705-fix-workqueue-error-handling-i.patch
+platform-chrome-cros_ec_typec-set-pin-assignment-e-i.patch
+asoc-sof-ipc4-pcm-adjust-pipeline_list-pipelines-all.patch
+asoc-intel-avs-fix-kcalloc-sizes.patch
+asoc-sof-amd-add-missing-acp-descriptor-field.patch
+pm-wakeup-delete-space-in-the-end-of-string-shown-by.patch
+acpi-resource-fix-a-typo-for-mechrevo-in-irq1_edge_l.patch
+pm-runtime-add-new-devm-functions.patch
+spi-atmel-quadspi-fix-unbalanced-pm_runtime-by-using.patch
+x86-mtrr-check-if-fixed-range-mtrrs-exist-in-mtrr_sa.patch
+pm-sleep-print-pm-debug-messages-during-hibernation.patch
+spi-spi-qpic-snand-use-kmalloc-for-oob-buffer-alloca.patch
+spi-spi-qpic-snand-validate-user-chip-specific-ecc-p.patch
+thermal-drivers-mediatek-lvts-fix-debugfs-unregister.patch
+acpi-osi-stop-advertising-support-for-3.0-_scp-exten.patch
+acpi-thermal-execute-_scp-before-reading-trip-points.patch
+spi-sh-msiof-fix-maximum-dma-transfer-size.patch
+asoc-apple-mca-constrain-channels-according-to-tdm-m.patch
+edac-bluefield-don-t-use-bluefield_edac_readl-result.patch
+alsa-core-fix-up-bus-match-const-issues.patch
+acpi-platform_profile-avoid-initializing-on-non-acpi.patch
+drm-vmwgfx-add-seqno-waiter-for-sync_files.patch
+drm-vmwgfx-add-error-path-for-xa_store-in-vmw_bo_add.patch
+drm-xlnx-zynqmp_dpsub-fix-kconfig-dependencies-for-a.patch
+drm-ci-fix-merge-request-rules.patch
+drm-vmwgfx-fix-dumb-buffer-leak.patch
+drm-vc4-hdmi-call-hdmi-hotplug-helper-on-disconnect.patch
+drm-xe-d3cold-set-power-state-to-d3cold-during-s2idl.patch
+drm-vc4-tests-use-return-instead-of-assert.patch
+drm-vc4-tests-stop-allocating-the-state-in-test-init.patch
+drm-vc4-tests-retry-pv-muxing-tests-when-edeadlk.patch
+drm-amd-pp-fix-potential-null-pointer-dereference-in.patch
+media-rkvdec-fix-frame-size-enumeration.patch
+arm64-fpsimd-avoid-res0-bits-in-the-sme-trap-handler.patch
+arm64-fpsimd-discard-stale-cpu-state-when-handling-s.patch
+arm64-fpsimd-don-t-corrupt-fpmr-when-streaming-mode-.patch
+arm64-fpsimd-avoid-clobbering-kernel-fpsimd-state-wi.patch
+arm64-fpsimd-reset-fpmr-upon-exec.patch
+arm64-fpsimd-fix-merging-of-fpsimd-state-during-sign.patch
+drm-panthor-fix-gpu_coherency_ace-_lite-definitions.patch
+drm-panthor-call-panthor_gpu_coherency_init-after-pm.patch
+drm-panthor-update-panthor_mmu-irq-mask-when-needed.patch
+accel-amdxdna-fix-incorrect-size-of-ert_start_npu-co.patch
+drm-panthor-fix-the-panthor_gpu_coherency_init-error.patch
+perf-arm-ni-unregister-pmus-on-probe-failure.patch
+perf-arm-ni-fix-missing-platform_set_drvdata.patch
+drm-amdgpu-refine-cleaner-shader-mec-firmware-versio.patch
+drm-panel-samsung-sofef00-drop-s6e3fc2x01-support.patch
+drm-bridge-lt9611uxc-fix-an-error-handling-path-in-l.patch
+drm-v3d-associate-a-v3d-tech-revision-to-all-support.patch
+drm-v3d-fix-client-obtained-from-axi_ids-on-v3d-4.1.patch
+drm-v3d-client-ranges-from-axi_ids-are-different-wit.patch
+fs-ntfs3-handle-hdr_first_de-return-value.patch
+fs-ntfs3-add-missing-direct_io-in-ntfs_aops_cmpr.patch
+kunit-usercopy-disable-u64-test-on-32-bit-sparc.patch
+watchdog-exar-shorten-identity-name-to-fit-correctly.patch
+m68k-mac-fix-macintosh_config-for-mac-ii.patch
+firmware-psci-fix-refcount-leak-in-psci_dt_init.patch
+arm64-support-arm64_va_bits-52-when-setting-arch_mma.patch
+arm64-fpsimd-avoid-warning-when-sve_to_fpsimd-is-unu.patch
+selftests-seccomp-fix-syscall_restart-test-for-arm-c.patch
+drm-msm-dpu-enable-smartdma-on-sm8150.patch
+drm-msm-dpu-enable-smartdma-on-sc8180x.patch
+drm-msm-dpu-remove-dsc-feature-bit-for-pingpong-on-m.patch
+drm-msm-dpu-remove-dsc-feature-bit-for-pingpong-on-m.patch-13942
+drm-msm-dpu-remove-dsc-feature-bit-for-pingpong-on-m.patch-8756
+drm-rcar-du-fix-memory-leak-in-rcar_du_vsps_init.patch
+drm-vkms-adjust-vkms_state-active_planes-allocation-.patch
+drm-tegra-rgb-fix-the-unbound-reference-count.patch
+drm-amd-display-don-t-check-for-null-divisor-in-fixp.patch
+firmware-sdei-allow-sdei-initialization-without-acpi.patch
+kselftest-arm64-fp-ptrace-fix-expected-fpmr-value-wh.patch
+overflow-fix-direct-struct-member-initialization-in-.patch
+scsi-qedf-use-designated-initializer-for-struct-qed_.patch
+media-synopsys-hdmirx-renamed-frame_idx-to-sequence.patch
+media-synopsys-hdmirx-count-dropped-frames.patch
+perf-amlogic-replace-smp_processor_id-with-raw_smp_p.patch
+selftests-seccomp-fix-negative_enosys-tracer-tests-o.patch
+drm-msm-a6xx-disable-rgb565_predicator-on-adreno-7c3.patch
+drm-msm-dp-fix-support-of-lttpr-initialization.patch
+drm-msm-dp-account-for-lttprs-capabilities.patch
+drm-msm-dp-prepare-for-link-training-per-segment-for.patch
+drm-i915-dp_mst-use-the-correct-connector-while-comp.patch
+drm-mediatek-mtk_drm_drv-fix-kobject-put-for-mtk_mut.patch
+drm-mediatek-fix-kobject-put-for-component-sub-drive.patch
+drm-mediatek-mtk_drm_drv-unbind-secondary-mmsys-comp.patch
+media-verisilicon-free-post-processor-buffers-on-err.patch
+svcrdma-reduce-the-number-of-rdma_rw-contexts-per-qp.patch
+xen-x86-fix-initial-memory-balloon-target.patch
+drm-xe-guc-refactor-guc-debugfs-initialization.patch
+drm-xe-guc-don-t-expose-guc-privileged-debugfs-files.patch
+drm-xe-guc-make-creation-of-slpc-debugfs-files-condi.patch
+drm-panic-clean-clippy-warning.patch
+drm-panic-use-a-decimal-fifo-to-avoid-u64-by-u64-div.patch
+wifi-ath12k-fix-null-access-in-assign-channel-contex.patch
+wifi-ath11k-fix-node-corruption-in-ar-arvifs-list.patch
+libbpf-fix-implicit-memfd_create-for-bionic.patch
+wifi-ath12k-fix-memory-leak-during-vdev_id-mismatch.patch
+wifi-ath12k-fix-memory-corruption-during-mlo-multica.patch
+wifi-ath12k-fix-invalid-memory-access-while-forming-.patch
+ib-cm-use-rwlock-for-mad-agent-lock.patch
+bpf-check-link_create.flags-parameter-for-multi_kpro.patch
+bpf-check-link_create.flags-parameter-for-multi_upro.patch
+selftests-bpf-fix-bpf_nf-selftest-failure.patch
+bpf-fix-ktls-panic-with-sockmap.patch
+bpf-sockmap-fix-duplicated-data-transmission.patch
+bpf-sockmap-fix-panic-when-calling-skb_linearize.patch
+f2fs-zone-fix-to-avoid-inconsistence-in-between-sit-.patch
+net-phy-mediatek-permit-to-compile-test-ge-soc-phy-d.patch
+wifi-ath12k-fix-cleanup-path-after-mhi-init.patch
+wifi-ath12k-resolve-multicast-packet-drop-by-populat.patch
+wifi-ath12k-fix-wmi-tag-for-eht-rate-in-peer-assoc.patch
+wifi-ath12k-fix-buffer-overflow-in-debugfs.patch
+wifi-ath12k-fix-slub-bug-object-already-free-in-ath1.patch
+wifi-ath12k-fix-ath12k_flag_registered-flag-handling.patch
+f2fs-clean-up-unnecessary-indentation.patch
+f2fs-prevent-the-current-section-from-being-selected.patch
+f2fs-fix-to-do-sanity-check-on-sbi-total_valid_block.patch
+udp_tunnel-create-a-fastpath-gro-lookup.patch
+udp_tunnel-use-static-call-for-gro-hooks-when-possib.patch
+udp-properly-deal-with-xfrm-encap-and-addrform.patch
+page_pool-move-pp_magic-check-into-helper-functions.patch
+page_pool-track-dma-mapped-pages-and-unmap-them-when.patch
+net-mlx5-hws-fix-matcher-action-template-attach.patch
+pinctrl-qcom-tlmm-test-fix-potential-null-dereferenc.patch
+net-ncsi-fix-gcps-64-bit-member-variables.patch
+libbpf-fix-buffer-overflow-in-bpf_object__init_prog.patch
+net-mlx5-avoid-using-xso.real_dev-unnecessarily.patch
+xfrm-use-xdo.dev-instead-of-xdo.real_dev.patch
+xfrm-add-explicit-dev-to-.xdo_dev_state_-add-delete-.patch
+bonding-mark-active-offloaded-xfrm_states.patch
+bonding-fix-multiple-long-standing-offload-races.patch
+wifi-rtw88-sdio-map-mgmt-frames-to-queue-tx_desc_qse.patch
+wifi-rtw88-sdio-call-rtw_sdio_indicate_tx_status-unc.patch
+wifi-rtw88-do-not-ignore-hardware-read-error-during-.patch
+wifi-ath12k-handle-error-cases-during-extended-skb-a.patch
+wifi-ath12k-fix-invalid-access-to-memory.patch
+wifi-ath12k-add-msdu-length-validation-for-tkip-mic-.patch
+wifi-ath12k-fix-the-qos-control-field-offset-to-buil.patch
+wifi-ath12k-add-extra-tlv-tag-parsing-support-in-mon.patch
+wifi-ath12k-avoid-fetch-error-bitmap-and-decap-forma.patch
+wifi-ath12k-replace-band-define-g-with-ghz-where-app.patch
+wifi-ath12k-change-the-status-update-in-the-monitor-.patch
+wifi-ath12k-add-rx_info-to-capture-required-field-fr.patch
+wifi-ath12k-replace-the-usage-of-rx-desc-with-rx_inf.patch
+wifi-ath12k-fix-wrong-handling-of-ccmp256-and-gcmp-c.patch
+wifi-ath12k-prevent-sending-wmi-commands-to-firmware.patch
+wifi-ath12k-fix-node-corruption-in-ar-arvifs-list.patch
+rdma-rxe-fix-trying-to-register-non-static-key-in-rx.patch
+rdma-hns-include-hnae3.h-in-hns_roce_hw_v2.h.patch
+scsi-hisi_sas-call-i_t_nexus-after-soft-reset-for-sa.patch
+libbpf-fix-event-name-too-long-error.patch
+wifi-iwlwifi-re-add-iwl_amsdu_8k-case.patch
+libbpf-remove-sample_period-init-in-perf_buffer.patch
+use-thread-safe-function-pointer-in-libbpf_print.patch
+iommu-ipmmu-vmsa-avoid-wformat-security-warning.patch
+iommu-io-pgtable-arm-dynamically-allocate-selftest-d.patch
+iommu-protect-against-overflow-in-iommu_pgsize.patch
+bonding-assign-random-address-if-device-address-is-s.patch
+f2fs-clean-up-w-fscrypt_is_bounce_page.patch
+f2fs-fix-to-detect-gcing-page-in-f2fs_is_cp_guarante.patch
+f2fs-zone-fix-to-calculate-first_zoned_segno-correct.patch
+scsi-lpfc-avoid-potential-ndlp-use-after-free-in-dev.patch
+scsi-smartpqi-fix-smp_processor_id-call-trace-for-pr.patch
+crypto-krb5-fix-change-to-use-sg-miter-to-use-offset.patch
+selftests-bpf-fix-kmem_cache-iterator-draining.patch
+libbpf-use-proper-errno-value-in-linker.patch
+bpf-allow-xdp-dev-bound-programs-to-perform-xdp_redi.patch
+netfilter-bridge-move-specific-fragmented-packet-to-.patch
+netfilter-nft_quota-match-correctly-when-the-quota-j.patch
+netfilter-nft_set_pipapo-prevent-overflow-in-lookup-.patch
+ib-cm-drop-lockdep-assert-and-warn-when-freeing-old-.patch
+rdma-mlx5-fix-error-flow-upon-firmware-failure-for-r.patch
+bpf-fix-uninitialized-values-in-bpf_-core-probe-_rea.patch
+iommu-arm-smmu-v3-fix-incorrect-return-in-arm_smmu_a.patch
+tracing-move-histogram-trigger-variables-from-stack-.patch
+clk-qcom-camcc-sm6350-add-_wait_val-values-for-gdscs.patch
+clk-qcom-dispcc-sm6350-add-_wait_val-values-for-gdsc.patch
+clk-qcom-gcc-sm6350-add-_wait_val-values-for-gdscs.patch
+clk-qcom-gpucc-sm6350-add-_wait_val-values-for-gdscs.patch
+bpftool-fix-regression-of-bpftool-cgroup-tree-einval.patch
+clk-bcm-rpi-add-null-check-in-raspberrypi_clk_regist.patch
+clk-test-forward-declare-struct-of_phandle_args-in-k.patch
+wifi-iwlfiwi-mvm-fix-the-rate-reporting.patch
+rtla-define-_gnu_source-in-timerlat_bpf.c.patch
+efi-libstub-describe-missing-out-parameter-in-efi_lo.patch
+selftests-bpf-avoid-passing-out-of-range-values-to-_.patch
+selftests-bpf-fix-caps-for-__xlated-jited_unpriv.patch
+tracing-rename-event_trigger_alloc-to-trigger_data_a.patch
+tracing-fix-error-handling-in-event_trigger_parse.patch
+of-unittest-unlock-on-error-in-unittest_data_add.patch
+ktls-sockmap-fix-missing-uncharge-operation.patch
+libbpf-use-proper-errno-value-in-nlattr.patch
+pinctrl-qcom-correct-the-ngpios-entry-for-qcs615.patch
+pinctrl-qcom-correct-the-ngpios-entry-for-qcs8300.patch
+pinctrl-at91-fix-possible-out-of-boundary-access.patch
+bpf-fix-warn-in-get_bpf_raw_tp_regs.patch
+dt-bindings-soc-fsl-qman-fqd-fix-reserved-memory.yam.patch
+clk-qcom-gcc-msm8939-fix-mclk0-mclk1-for-24-mhz.patch
+s390-bpf-store-backchain-even-for-leaf-progs.patch
+wifi-rtw89-pci-configure-manual-dac-mode-via-pci-con.patch
+wifi-rtw89-pci-enlarge-retry-times-of-rx-tag-to-1000.patch
+wifi-rtw88-fix-the-para-buffer-size-to-avoid-reading.patch
+wifi-rtw89-fix-firmware-scan-delay-unit-for-wifi-6-c.patch
+iommu-remove-duplicate-selection-of-dmar_table.patch
+wifi-ath12k-fix-invalid-rssi-values-in-station-dump.patch
+wifi-ath12k-reorder-and-relocate-the-release-of-reso.patch
+wifi-ath12k-fix-memory-leak-in-ath12k_service_ready_.patch
+hisi_acc_vfio_pci-fix-xqe-dma-address-error.patch
+hisi_acc_vfio_pci-add-eq-and-aeq-interruption-restor.patch
+hisi_acc_vfio_pci-bugfix-cache-write-back-issue.patch
+hisi_acc_vfio_pci-bugfix-the-problem-of-uninstalling.patch
+hisi_acc_vfio_pci-bugfix-live-migration-function-wit.patch
+wifi-ath9k_htc-abort-software-beacon-handling-if-dis.patch
+pinctrl-mediatek-fix-the-invalid-conditions.patch
+scsi-ufs-mcq-delete-ufshcd_release_scsi_cmd-in-ufshc.patch
+scsi-mpt3sas-fix-_ctl_get_mpt_mctp_passthru_adapter-.patch
+rdma-bnxt_re-fix-incorrect-display-of-inactivity_cp-.patch
+rdma-bnxt_re-fix-missing-error-handling-for-tx_queue.patch
+rdma-bnxt_re-fix-return-code-of-bnxt_re_configure_cc.patch
+kernfs-relax-constraint-in-draining-guard.patch
+wifi-mt76-mt7925-fix-logical-vs-bitwise-typo.patch
+wifi-mt76-mt7996-add-null-check-in-mt7996_thermal_in.patch
+wifi-mt76-mt7996-prevent-uninit-return-in-mt7996_mac.patch
+wifi-mt76-mt7996-avoid-null-pointer-dereference-in-m.patch
+wifi-mt76-mt7996-avoid-null-deref-in-mt7996_stop_phy.patch
+bluetooth-iso-fix-not-using-sid-from-adv-report.patch
+bluetooth-separate-cis_link-and-bis_link-link-types.patch
+wifi-mt76-scan-fix-mlink-dereferenced-before-is_err_.patch
+wifi-mt76-mt7996-fix-null-ptr-deref-in-mt7996_mmio_w.patch
+wifi-mt76-mt7915-fix-null-ptr-deref-in-mt7915_mmio_w.patch
+wifi-mt76-mt7925-prevent-multiple-scan-commands.patch
+wifi-mt76-mt7925-refine-the-sniffer-commnad.patch
+wifi-mt76-mt7925-ensure-all-mcu-commands-wait-for-re.patch
+wifi-mt76-mt7996-fix-beamformee-ss-field.patch
+wifi-mt76-mt7996-set-eht-max-ampdu-length-capability.patch
+wifi-mt76-mt7996-fix-invalid-nss-setting-when-tx-pat.patch
+wifi-mt76-mt7996-fix-rx-buffer-size-of-mcu-event.patch
+wifi-mt76-fix-available_antennas-setting.patch
+bpf-revert-bpf-remove-unnecessary-rcu_read_-lock-unl.patch
+netfilter-xtables-support-arpt_mark-and-ipv6-optstri.patch
+netfilter-nf_tables-nft_fib_ipv6-fix-vrf-ipv4-ipv6-r.patch
+vfio-type1-fix-error-unwind-in-migration-dirty-bitma.patch
+bluetooth-mgmt-iterate-over-mesh-commands-in-mgmt_me.patch
+bluetooth-btintel-check-dsbr-size-from-efi-variable.patch
+bpf-sockmap-avoid-using-sk_socket-after-free-when-se.patch
+netfilter-nf_tables-nft_fib-consistent-l3mdev-handli.patch
+netfilter-nft_tunnel-fix-geneve_opt-dump.patch
+risc-v-kvm-lock-the-correct-mp_state-during-reset.patch
+net-usb-aqc111-fix-error-handling-of-usbnet-read-cal.patch
+octeontx2-af-send-link-events-one-by-one.patch
+vsock-virtio-fix-rx_bytes-accounting-for-stream-sock.patch
+rdma-cma-fix-hang-when-cma_netevent_callback-fails-t.patch
+net-lan966x-fix-1-step-timestamping-over-ipv4-or-ipv.patch
+net-xilinx-axienet-fix-tx-skb-circular-buffer-occupa.patch
+af_packet-move-notifier-s-packet_dev_mc-out-of-rcu-c.patch
+virtio-pci-fix-result-size-returned-for-the-admin-co.patch
+bpf-avoid-__bpf_prog_ret0_warn-when-jit-fails.patch
+bpf-do-not-include-stack-ptr-register-in-precision-b.patch
+net-phy-clear-phydev-devlink-when-the-link-is-delete.patch
+net-airoha-fix-an-error-handling-path-in-airoha_allo.patch
+net-mctp-start-tx-queue-on-netdev-open.patch
+net-phy-fix-up-const-issues-in-to_mdio_device-and-to.patch
+net-lan743x-rename-lan743x_reset_phy-to-lan743x_hw_r.patch
+net-lan743x-fix-phy-reset-handling-during-initializa.patch
+net-phy-mscc-fix-memory-leak-when-using-one-step-tim.patch
+octeontx2-pf-qos-perform-cache-sync-on-send-queue-te.patch
+octeontx2-pf-qos-refactor-tc_htb_leaf_del_last-callb.patch
+calipso-don-t-call-calipso-functions-for-af_inet-sk.patch
+net-openvswitch-fix-the-dead-loop-of-mpls-parse.patch
+net-phy-mscc-stop-clearing-the-the-udpv4-checksum-fo.patch
+f2fs-fix-to-skip-f2fs_balance_fs-if-checkpoint-is-di.patch
+f2fs-use-d_inode-dentry-cleanup-dentry-d_inode.patch
+f2fs-fix-to-correct-check-conditions-in-f2fs_cross_r.patch
+arm64-dts-qcom-x1e80100-mark-usb_2-as-dma-coherent.patch
+arm64-dts-qcom-sm8650-setup-gpu-thermal-with-higher-.patch
+arm64-dts-qcom-sa8775p-partially-revert-arm64-dts-qc.patch
+arm64-dts-qcom-qcs8300-partially-revert-arm64-dts-qc.patch
+arm64-dts-qcom-sm8550-use-icc-tag-for-all-interconne.patch
+arm64-dts-qcom-sm8550-add-missing-cpu-cfg-interconne.patch
+arm64-dts-qcom-sm8650-add-missing-cpu-cfg-interconne.patch
+arm64-dts-qcom-x1e80100-romulus-keep-l12b-and-l15b-a.patch
+arm64-dts-qcom-sdm845-starqltechn-remove-wifi.patch
+arm64-dts-qcom-sdm845-starqltechn-fix-usb-regulator-.patch
+arm64-dts-qcom-sdm845-starqltechn-refactor-node-orde.patch
+arm64-dts-qcom-sdm845-starqltechn-remove-excess-rese.patch
+arm64-dts-qcom-sm8350-reenable-crypto-cryptobam.patch
+arm64-dts-qcom-ipq9574-fix-the-msi-interrupt-numbers.patch
+arm64-dts-qcom-sm8750-fix-cluster-hierarchy-for-idle.patch
+arm64-dts-qcom-sm8250-fix-cpu7-opp-table.patch
+arm64-dts-qcom-sm8750-correct-clocks-property-for-ua.patch
+arm64-dts-qcom-sc8280xp-x13s-drop-duplicate-dmic-sup.patch
+arm64-dts-qcom-ipq9574-fix-usb-vdd-info.patch
+arm64-dts-qcom-qcs615-remove-disallowed-property-in-.patch
+arm64-dts-qcom-sm8650-fix-domain-idle-state-for-cpu2.patch
+arm64-dts-rockchip-add-missing-uart3-interrupt-for-r.patch
+arm64-dts-rockchip-move-shmem-memory-to-reserved-mem.patch
+arm-dts-at91-usb_a9263-fix-gpio-for-dataflash-chip-s.patch
+arm-dts-at91-at91sam9263-fix-nand-chip-selects.patch
+arm64-dts-mediatek-mt8188-fix-iommu-device-for-rdma0.patch
+arm64-dts-mediatek-mt8195-reparent-vdec1-2-and-venc1.patch
+arm64-dts-qcom-sdm660-xiaomi-lavender-add-missing-sd.patch
+firmware-exynos-acpm-fix-reading-longer-results.patch
+firmware-exynos-acpm-silence-eprobe_defer-error-on-b.patch
+arm64-dts-mt8183-add-port-node-to-mt8183.dtsi.patch
+arm64-dts-imx8mm-beacon-fix-rtc-capacitive-load.patch
+arm64-dts-imx8mn-beacon-fix-rtc-capacitive-load.patch
+arm64-dts-imx8mp-beacon-fix-rtc-capacitive-load.patch
+arm64-dts-imx8mm-beacon-set-sai5-mclk-direction-to-o.patch
+arm64-dts-imx8mn-beacon-set-sai5-mclk-direction-to-o.patch
+arm64-dts-mediatek-mt6357-drop-regulator-fixed-compa.patch
+arm64-dts-mediatek-mt8390-genio-common-set-ssusb2-de.patch
+arm64-dts-mt6359-add-missing-compatible-property-to-.patch
+arm64-dts-qcom-sdm660-lavender-add-missing-usb-phy-s.patch
+arm64-dts-qcom-sda660-ifc6560-fix-dt-validate-warnin.patch
+arm64-dts-qcom-x1e001de-devkit-describe-usb-retimers.patch
+arm64-dts-qcom-x1e001de-devkit-fix-pin-config-for-us.patch
+arm64-dts-rockchip-add-vcc-supply-to-spi-flash-on-rk.patch
+arm64-dts-allwinner-a100-set-maximum-mmc-frequency.patch
+arm64-dts-rockchip-update-emmc-for-nanopi-r5-series.patch
+arm64-dts-renesas-white-hawk-single-improve-ethernet.patch
+arm64-tegra-drop-remaining-serial-clock-names-and-re.patch
+arm64-tegra-add-uartd-serial-alias-for-jetson-tx1-mo.patch
+arm64-dts-ti-k3-j721e-common-proc-board-enable-ospi1.patch
+soc-qcom-smp2p-fix-fallback-to-qcom-ipc-parse.patch
+squashfs-check-return-result-of-sb_min_blocksize.patch
+ocfs2-fix-possible-memory-leak-in-ocfs2_finish_quota.patch
+nilfs2-add-pointer-check-for-nilfs_direct_propagate.patch
+nilfs2-do-not-propagate-enoent-error-from-nilfs_btre.patch
+bus-fsl-mc-fix-double-free-on-mc_dev.patch
+bus-fsl_mc-fix-driver_managed_dma-check.patch
+dt-bindings-vendor-prefixes-add-liontron-name.patch
+arm-dts-qcom-apq8064-add-missing-clocks-to-the-timer.patch
+arm-dts-qcom-apq8064-merge-hw-splinlock-into-corresp.patch
+arm-dts-qcom-apq8064-move-replicator-out-of-soc-node.patch
+arm64-defconfig-mediatek-enable-phy-drivers.patch
+arm64-dts-qcom-sm8650-add-the-missing-l2-cache-node.patch
+arm64-dts-rockchip-disable-unrouted-usb-controllers-.patch
+arm64-dts-rockchip-disable-unrouted-usb-controllers-.patch-25959
+arm64-dts-qcom-qcm2290-fix-some-of-qup-interconnects.patch
+arm64-dts-qcom-msm8998-use-the-header-with-dsi-phy-c.patch
+arm64-dts-qcom-msm8998-remove-mdss_hdmi_phy-phandle-.patch
+arm64-dts-qcom-qcs615-fix-up-ufs-clocks.patch
+arm64-dts-renesas-white-hawk-ard-audio-fix-tpu0-grou.patch
+arm64-dts-mt6359-rename-rtc-node-to-match-binding-ex.patch
+arm-aspeed-don-t-select-sram.patch
+soc-aspeed-lpc-fix-impossible-judgment-condition.patch
+soc-aspeed-add-null-check-in-aspeed_lpc_enable_snoop.patch
+ubsan-integer-overflow-depend-on-broken-to-keep-this.patch
+fbdev-core-fbcvt-avoid-division-by-0-in-fb_cvt_hperi.patch
+watchdog-lenovo_se30_wdt-fix-possible-devm_ioremap-n.patch
+randstruct-gcc-plugin-remove-bogus-void-member.patch
+randstruct-gcc-plugin-fix-attribute-addition.patch
+tools-build-don-t-set-libunwind-as-available-if-test.patch
+tools-build-don-t-show-libunwind-build-status-as-it-.patch
+perf-build-warn-when-libdebuginfod-devel-files-are-n.patch
+tools-build-don-t-show-libbfd-build-status-as-it-is-.patch
+perf-ui-browser-hists-set-actions-thread-before-call.patch
+dm-don-t-change-md-if-dm_table_set_restrictions-fail.patch
+dm-free-table-mempools-if-not-used-in-__bind.patch
+dm-handle-failures-in-dm_table_set_restrictions.patch
+backlight-pm8941-add-null-check-in-wled_configure.patch
+hid-intel-thc-hid-intel-quicki2c-pass-correct-argume.patch
+hid-hid_appletb_kbd-should-depend-on-x86.patch
+hid-hid_appletb_bl-should-depend-on-x86.patch
+x86-irq-ensure-initial-pir-loads-are-performed-exact.patch
+perf-tool_pmu-fix-aggregation-on-duration_time.patch
+perf-tests-metric-only-perf-stat-fix-tests-84-and-86.patch
+mtd-nand-ecc-mxic-fix-use-of-uninitialized-variable-.patch
+hwmon-asus-ec-sensors-check-sensor-index-in-read_str.patch
+perf-symbol-minimal-fix-double-free-in-filename__rea.patch
+dm-fix-dm_blk_report_zones.patch
+dm-limit-swapping-tables-for-devices-with-zone-write.patch
+dm-flakey-error-all-ios-when-num_features-is-absent.patch
+dm-flakey-make-corrupting-read-bios-work.patch
+perf-trace-fix-leaks-of-struct-thread-in-fprintf_sys.patch
+perf-trace-fix-leaks-of-struct-thread-in-set_filter_.patch
+perf-tests-fix-perf-report-tests-installation.patch
+perf-intel-pt-fix-pebs-via-pt-data_src.patch
+perf-scripts-python-exported-sql-viewer.py-fix-patte.patch
+remoteproc-qcom_wcnss_iris-add-missing-put_device-on.patch
+perf-tools-fix-arm64-source-package-build.patch
+remoteproc-k3-r5-drop-check-performed-in-k3_r5_rproc.patch
+remoteproc-k3-dsp-drop-check-performed-in-k3_dsp_rpr.patch
+remoteproc-k3-r5-refactor-sequential-core-power-up-d.patch
+rpmsg-qcom_smd-fix-uninitialized-return-variable-in-.patch
+netfs-fix-oops-in-write-retry-from-mis-resetting-the.patch
+netfs-fix-setting-of-transferred-bytes-with-short-di.patch
+netfs-fix-the-request-s-work-item-to-not-require-a-r.patch
+netfs-fix-wait-wake-to-be-consistent-about-the-waitq.patch
+mfd-exynos-lpass-fix-an-error-handling-path-in-exyno.patch
+mfd-exynos-lpass-avoid-calling-exynos_lpass_disable-.patch
+mfd-exynos-lpass-fix-another-error-handling-path-in-.patch
+mfd-stmpe-spi-correct-the-name-used-in-module_device.patch
+netfs-fix-undifferentiation-of-dio-reads-from-unbuff.patch
+drivers-hv-always-select-config_sysfb-for-hyper-v-gu.patch
+perf-tests-switch-tracking-fix-timestamp-comparison.patch
+mailbox-mchp-ipc-sbi-fix-compile_test-build-error.patch
+mailbox-imx-fix-txdb_v2-sending.patch
+mailbox-mtk-cmdq-refine-gce_gctl_value-setting.patch
+iomap-don-t-lose-folio-dropbehind-state-for-overwrit.patch
+perf-pmu-avoid-segv-for-missing-name-alias_name-in-w.patch
+perf-symbol-fix-use-after-free-in-filename__read_bui.patch
+s390-uv-don-t-return-0-from-make_hva_secure-if-the-o.patch
+s390-uv-always-return-0-from-s390_wiggle_split_folio.patch
+s390-uv-improve-splitting-of-large-folios-that-canno.patch
+perf-record-fix-incorrect-user-regs-comments.patch
+perf-trace-always-print-return-value-for-syscalls-re.patch
+nfs-clear-sb_rdonly-before-getting-superblock.patch
+nfs-ignore-sb_rdonly-when-remounting-nfs.patch
+nfs-fix-incorrect-handling-of-large-number-nfs-error.patch
+nfs_localio-use-cmpxchg-to-install-new-nfs_file_loca.patch
+nfs_localio-always-hold-nfsd-net-ref-with-nfsd_file-.patch
+nfs_localio-simplify-interface-to-nfsd-for-getting-n.patch
+nfs_localio-duplicate-nfs_close_local_fh.patch
+nfs_localio-protect-race-between-nfs_uuid_put-and-nf.patch
+nfs_localio-change-nfsd_file_put_local-to-take-a-poi.patch
+perf-trace-set-errpid-to-false-for-rseq-and-set_robu.patch
+fs-dax-fix-don-t-skip-locked-entries-when-scanning-e.patch
+rust-file-mark-localfile-as-repr-transparent.patch
+exportfs-require-fh_to_parent-to-encode-connectable-.patch
+perf-callchain-always-populate-the-addr_location-map.patch
+cifs-fix-validation-of-smb1-query-reparse-point-resp.patch
+rust-alloc-add-missing-invariant-in-vec-set_len.patch
+rtc-sh-assign-correct-interrupts-with-dt.patch
+phy-rockchip-samsung-hdptx-fix-clock-ratio-setup.patch
+phy-rockchip-samsung-hdptx-do-no-set-rk_hdptx_phy-ra.patch
+pci-pciehp-ignore-presence-detect-changed-caused-by-.patch
+pci-pciehp-ignore-link-down-up-caused-by-secondary-b.patch
+pci-print-the-actual-delay-time-in-pci_bridge_wait_f.patch
+pci-rockchip-fix-order-of-rockchip_pci_core_rsts.patch
+pci-rcar-gen4-set-ep-bar4-fixed-size.patch
+pci-cadence-fix-runtime-atomic-count-underflow.patch
+pci-apple-use-gpiod_set_value_cansleep-in-probe-flow.patch
+pci-imx6-save-and-restore-the-lut-setting-during-sus.patch
+pci-explicitly-put-devices-into-d0-when-initializing.patch
+phy-qcom-qmp-usb-fix-an-null-vs-is_err-bug.patch
+revert-phy-qcom-qusb2-add-qusb2-support-for-ipq5424.patch
+phy-qcom-qusb2-reuse-the-ipq6018-settings-for-ipq542.patch
+soundwire-only-compute-port-params-in-specific-strea.patch
+dmaengine-ti-add-null-check-in-udma_probe.patch
+pci-acpi-fix-allocated-memory-release-on-error-in-pc.patch
+pci-dpc-initialize-aer_err_info-before-using-it.patch
+pci-dpc-log-error-source-id-only-when-valid.patch
+pci-pwrctrl-cancel-outstanding-rescan-work-when-unre.patch
+rtc-loongson-add-missing-alarm-notifications-for-acp.patch
+rust-pci-fix-docs-related-to-missing-markdown-code-s.patch
+pci-endpoint-retain-fixed-size-bar-size-as-well-as-a.patch
+sched_ext-idle-skip-cross-node-search-with-config_nu.patch
+usb-renesas_usbhs-reorder-clock-handling-and-power-m.patch
+serial-fix-potential-null-ptr-deref-in-mlb_usio_prob.patch
+thunderbolt-fix-a-logic-error-in-wake-on-connect.patch
+iio-filter-admv8818-fix-band-4-state-15.patch
+iio-filter-admv8818-fix-integer-overflow.patch
+iio-filter-admv8818-fix-range-calculation.patch
+iio-filter-admv8818-support-frequencies-2-32.patch
+iio-adc-ad7124-fix-3db-filter-frequency-reading.patch
+usb-acpi-prevent-null-pointer-dereference-in-usb_acp.patch
+mips-loongson64-add-missing-interrupt-cells-for-loon.patch
+coresight-fixes-device-s-owner-field-for-registered-.patch
+coresight-catu-introduce-refcount-and-spinlock-for-e.patch
+coresight-core-disable-helpers-for-devices-that-fail.patch
+counter-interrupt-cnt-protect-enable-disable-ops-wit.patch
+fpga-fix-potential-null-pointer-deref-in-fpga_mgr_te.patch
+iio-dac-adi-axi-dac-fix-bus-read.patch
+iio-adc-ad4851-fix-ad4858-chan-pointer-handling.patch
+coresight-tmc-fix-failure-to-disable-enable-etf-afte.patch
+coresight-etm4x-fix-timestamp-bit-field-handling.patch
+coresight-etm4-fix-missing-disable-active-config.patch
+coresight-holding-cscfg_csdev_lock-while-removing-cs.patch
+coresight-prevent-deactivate-active-config-while-ena.patch
+vt-remove-vt_resize-and-vt_resizex-from-vt_compat_io.patch
+staging-gpib-fix-pcmcia-config-identifier.patch
+staging-gpib-fix-secondary-address-restriction.patch
+rust-miscdevice-fix-typo-in-miscdevice-ioctl-documen.patch
+misc-lis3lv02d-fix-correct-sysfs-directory-path-for-.patch
+char-tlclk-fix-correct-sysfs-directory-path-for-tlcl.patch
+mei-vsc-cast-tx_buf-to-__be32-when-passed-to-cpu_to_.patch
+iio-adc-pac1934-fix-typo-in-documentation-link.patch
+iio-adc-mcp3911-fix-device-dependent-mappings-for-co.patch
+usb-serial-bus-fix-const-issue-in-usb_serial_device_.patch
+usb-gadget-udc-fix-const-issue-in-gadget_match_drive.patch
+usb-typec-fix-const-issue-in-typec_match.patch
+loop-add-file_start_write-and-file_end_write.patch
+drm-connector-only-call-hdmi-audio-helper-plugged-cb.patch
+drm-bridge-analogix_dp-remove-the-unnecessary-calls-.patch
+accel-ivpu-reorder-doorbell-unregister-and-command-q.patch
+drm-bridge-analogix_dp-remove-config_pm-related-chec.patch
+drm-bridge-analogix_dp-add-support-to-get-panel-from.patch
+drm-bridge-analogix_dp-fix-clk-disable-removal.patch
+drm-xe-make-xe_gt_freq-part-of-the-documentation.patch
+drm-xe-add-missing-documentation-of-rpa_freq.patch
+fix-sock_exceed_buf_limit-not-being-triggered-in-__s.patch
+page_pool-fix-use-after-free-in-page_pool_recycle_in.patch
+net-stmmac-platform-guarantee-uniqueness-of-bus_id.patch
+gve-fix-rx_buffers_posted-stat-to-report-per-queue-f.patch
+net-tipc-fix-refcount-warning-in-tipc_aead_encrypt.patch
+driver-net-ethernet-mtk_star_emac-fix-suspend-resume.patch
+net-mlx4_en-prevent-potential-integer-overflow-calcu.patch
+net-lan966x-make-sure-to-insert-the-vlan-tags-also-i.patch
+md-raid1-raid10-don-t-handle-io-error-for-req_rahead.patch
+spi-bcm63xx-spi-fix-shared-reset.patch
+spi-bcm63xx-hsspi-fix-shared-reset.patch
+bluetooth-mgmt-reject-malformed-hci_cmd_sync-command.patch
+bluetooth-l2cap-fix-not-responding-with-l2cap_cr_le_.patch
+ice-fix-tx-scheduler-error-handling-in-xdp-callback.patch
+ice-create-new-tx-scheduler-nodes-for-new-queues-onl.patch
+ice-fix-rebuilding-the-tx-scheduler-tree-for-large-q.patch
+idpf-fix-a-race-in-txq-wakeup.patch
+idpf-avoid-mailbox-timeout-delays-during-reset.patch
+net-dsa-tag_brcm-legacy-fix-pskb_may_pull-length.patch
+net-stmmac-make-sure-that-ptp_rate-is-not-0-before-c.patch
+net-stmmac-make-sure-that-ptp_rate-is-not-0-before-c.patch-22075
+net-fix-checksum-update-for-ila-adj-transport.patch
+bpf-clarify-the-meaning-of-bpf_f_pseudo_hdr.patch
+bpf-fix-l4-csum-update-on-ipv6-in-checksum_complete.patch
+drm-i915-guc-check-if-expecting-reply-before-decreme.patch
+drm-i915-psr-fix-using-wrong-mask-in-reg_field_prep.patch
+drm-i915-guc-handle-race-condition-where-wakeref-cou.patch
+um-fix-tgkill-compile-error-on-old-host-oses.patch
+net-fix-udp-gso-skb_segment-after-pull-from-frag_lis.patch
+net-wwan-t7xx-fix-napi-rx-poll-issue.patch
+vmxnet3-correctly-report-gso-type-for-udp-tunnels.patch
+selftests-net-build-net-lib-dependency-in-all-target.patch
+net-airoha-add-the-capability-to-allocate-hfwd-descr.patch
+net-airoha-initialize-ppe-updmem-source-mac-table.patch
+iavf-iavf_suspend-take-rtnl-before-netdev_lock.patch
+iavf-centralize-watchdog-requeueing-itself.patch
+iavf-simplify-watchdog_task-in-terms-of-adminq-task-.patch
+iavf-extract-iavf_watchdog_step-out-of-iavf_watchdog.patch
+iavf-sprinkle-netdev_assert_locked-annotations.patch
+iavf-get-rid-of-the-crit-lock.patch
+drm-amdgpu-gfx10-refine-cleaner-shader-for-gfx10.1.1.patch
+pm-sleep-fix-power.is_suspended-cleanup-for-direct-c.patch
+block-flip-iter-directions-in-blk_rq_integrity_map_u.patch
+nvme-fix-command-limits-status-code.patch
+nvme-fix-implicit-bool-to-flags-conversion.patch
+gve-add-missing-null-check-for-gve_alloc_pending_pac.patch
+drm-i915-display-fix-u32-overflow-in-snps-phy-hdmi-p.patch
+wifi-iwlwifi-mld-avoid-panic-on-init-failure.patch
+drm-panel-simple-fix-the-warnings-for-the-evervision.patch
+netfilter-nf_set_pipapo_avx2-fix-initial-map-fill.patch
+netfilter-nf_nat-also-check-reverse-tuple-to-obtain-.patch
+net-ti-icssg-prueth-fix-swapped-tx-stats-for-mii-int.patch
+net-dsa-b53-do-not-enable-eee-on-bcm63xx.patch
+net-dsa-b53-do-not-enable-rgmii-delay-on-bcm63xx.patch
+net-dsa-b53-implement-setting-ageing-time.patch
+net-dsa-b53-do-not-configure-bcm63xx-s-imp-port-inte.patch
+net-dsa-b53-allow-rgmii-for-bcm63xx-rgmii-ports.patch
+net-dsa-b53-do-not-touch-dll_iqqd-on-bcm53115.patch
+wifi-cfg80211-mac80211-correctly-parse-s1g-beacon-op.patch
+net-wwan-mhi_wwan_mbim-use-correct-mux_id-for-multip.patch
+netlink-specs-rt-link-add-missing-byte-order-propert.patch
+netlink-specs-rt-link-decode-ip6gre.patch
+wireguard-device-enable-threaded-napi.patch
+selftests-drv-net-tso-fix-the-gre-device-name.patch
+selftests-drv-net-tso-make-bkg-wait-for-socat-to-qui.patch
+net-annotate-data-races-around-cleanup_net_task.patch
+net-prevent-a-null-deref-in-rtnl_create_link.patch
+seg6-fix-validation-of-nexthop-addresses.patch
+drm-xe-vm-move-xe_svm_init-earlier.patch
+drm-xe-vsec-fix-config_intel_vsec-dependency.patch
+drm-xe-rework-eviction-rejection-of-bound-external-b.patch
+drm-xe-pxp-use-the-correct-define-in-the-set_propert.patch
+drm-xe-pxp-clarify-pxp-queue-creation-behavior-if-px.patch
+riscv-misaligned-fix-sleeping-function-called-during.patch
+scsi-ufs-qcom-check-gear-against-max-gear-in-vop-fre.patch
+scsi-ufs-qcom-map-devfreq-opp-freq-to-unipro-core-cl.patch
+scsi-ufs-qcom-prevent-calling-phy_exit-before-phy_in.patch
+asoc-codecs-hda-fix-rpm-usage-count-underflow.patch
+asoc-intel-avs-fix-deadlock-when-the-failing-ipc-is-.patch
+alsa-hda-allow-to-fetch-hlink-by-id.patch
+asoc-intel-avs-pcm-operations-for-lnl-based-platform.patch
+asoc-intel-avs-fix-pplcxfmt-calculation.patch
+asoc-intel-avs-fix-possible-null-ptr-deref-when-init.patch
+asoc-intel-avs-ignore-vendor-space-manipulation-for-.patch
+asoc-intel-avs-read-hw-capabilities-when-possible.patch
+asoc-intel-avs-relocate-dsp-status-registers.patch
+asoc-intel-avs-fix-paths-in-module_firmware-hints.patch
+asoc-intel-avs-verify-kcalloc-status-when-setting-co.patch
+asoc-intel-avs-verify-content-returned-by-parse_int_.patch
+asoc-ti-omap-hdmi-re-add-dai_link-platform-to-fix-ca.patch
+iov_iter-use-iov_offset-for-length-calculation-in-io.patch
+fs-fhandle.c-fix-a-race-in-call-of-has_locked_childr.patch
+path_overmount-avoid-false-negatives.patch
+fs-convert-mount-flags-to-enum.patch
+finish_automount-don-t-leak-mnt_locked-from-parent-t.patch
+fix-propagation-graph-breakage-by-move_mount_set_gro.patch
+fs-allow-clone_private_mount-for-a-path-on-real-root.patch
+clone_private_mnt-make-sure-that-caller-has-cap_sys_.patch
+do_change_type-refuse-to-operate-on-unmounted-not-ou.patch
+genksyms-fix-enum-consts-from-a-reference-affecting-.patch
+tools-power-turbostat-fix-amd-package-energy-reporti.patch
diff --git a/queue-6.15/soc-aspeed-add-null-check-in-aspeed_lpc_enable_snoop.patch b/queue-6.15/soc-aspeed-add-null-check-in-aspeed_lpc_enable_snoop.patch
new file mode 100644 (file)
index 0000000..4329a59
--- /dev/null
@@ -0,0 +1,73 @@
+From 8e3eaba31de35e3ad028d9677447fad0db16e7a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 May 2025 16:00:44 +0930
+Subject: soc: aspeed: Add NULL check in aspeed_lpc_enable_snoop()
+
+From: Henry Martin <bsdhenrymartin@gmail.com>
+
+[ Upstream commit f1706e0e1a74b095cbc60375b9b1e6205f5f4c98 ]
+
+devm_kasprintf() returns NULL when memory allocation fails. Currently,
+aspeed_lpc_enable_snoop() does not check for this case, which results in a
+NULL pointer dereference.
+
+Add NULL check after devm_kasprintf() to prevent this issue.
+
+Fixes: 3772e5da4454 ("drivers/misc: Aspeed LPC snoop output using misc chardev")
+Signed-off-by: Henry Martin <bsdhenrymartin@gmail.com>
+Link: https://patch.msgid.link/20250401074647.21300-1-bsdhenrymartin@gmail.com
+[arj: Fix Fixes: tag to use subject from 3772e5da4454]
+Signed-off-by: Andrew Jeffery <andrew@codeconstruct.com.au>
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/aspeed/aspeed-lpc-snoop.c | 15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/soc/aspeed/aspeed-lpc-snoop.c b/drivers/soc/aspeed/aspeed-lpc-snoop.c
+index 57ba855f375d9..ef8f355589a58 100644
+--- a/drivers/soc/aspeed/aspeed-lpc-snoop.c
++++ b/drivers/soc/aspeed/aspeed-lpc-snoop.c
+@@ -200,11 +200,15 @@ static int aspeed_lpc_enable_snoop(struct aspeed_lpc_snoop *lpc_snoop,
+       lpc_snoop->chan[channel].miscdev.minor = MISC_DYNAMIC_MINOR;
+       lpc_snoop->chan[channel].miscdev.name =
+               devm_kasprintf(dev, GFP_KERNEL, "%s%d", DEVICE_NAME, channel);
++      if (!lpc_snoop->chan[channel].miscdev.name) {
++              rc = -ENOMEM;
++              goto err_free_fifo;
++      }
+       lpc_snoop->chan[channel].miscdev.fops = &snoop_fops;
+       lpc_snoop->chan[channel].miscdev.parent = dev;
+       rc = misc_register(&lpc_snoop->chan[channel].miscdev);
+       if (rc)
+-              return rc;
++              goto err_free_fifo;
+       /* Enable LPC snoop channel at requested port */
+       switch (channel) {
+@@ -221,7 +225,8 @@ static int aspeed_lpc_enable_snoop(struct aspeed_lpc_snoop *lpc_snoop,
+               hicrb_en = HICRB_ENSNP1D;
+               break;
+       default:
+-              return -EINVAL;
++              rc = -EINVAL;
++              goto err_misc_deregister;
+       }
+       regmap_update_bits(lpc_snoop->regmap, HICR5, hicr5_en, hicr5_en);
+@@ -231,6 +236,12 @@ static int aspeed_lpc_enable_snoop(struct aspeed_lpc_snoop *lpc_snoop,
+               regmap_update_bits(lpc_snoop->regmap, HICRB,
+                               hicrb_en, hicrb_en);
++      return 0;
++
++err_misc_deregister:
++      misc_deregister(&lpc_snoop->chan[channel].miscdev);
++err_free_fifo:
++      kfifo_free(&lpc_snoop->chan[channel].fifo);
+       return rc;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/soc-aspeed-lpc-fix-impossible-judgment-condition.patch b/queue-6.15/soc-aspeed-lpc-fix-impossible-judgment-condition.patch
new file mode 100644 (file)
index 0000000..6ecf66b
--- /dev/null
@@ -0,0 +1,46 @@
+From cda22bff053aab1a012cd67e6691ed9d49ae72d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 May 2025 16:00:43 +0930
+Subject: soc: aspeed: lpc: Fix impossible judgment condition
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Su Hui <suhui@nfschina.com>
+
+[ Upstream commit d9f0a97e859bdcef51f9c187b1eb712eb13fd3ff ]
+
+smatch error:
+drivers/soc/aspeed/aspeed-lpc-snoop.c:169
+aspeed_lpc_snoop_config_irq() warn: platform_get_irq() does not return zero
+
+platform_get_irq() return non-zero IRQ number or negative error code,
+change '!lpc_snoop->irq' to 'lpc_snoop->irq < 0' to fix this.
+
+Fixes: 9f4f9ae81d0a ("drivers/misc: add Aspeed LPC snoop driver")
+Signed-off-by: Su Hui <suhui@nfschina.com>
+Reviewed-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://lore.kernel.org/r/20231027020703.1231875-1-suhui@nfschina.com
+Signed-off-by: Andrew Jeffery <andrew@codeconstruct.com.au>
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/aspeed/aspeed-lpc-snoop.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/soc/aspeed/aspeed-lpc-snoop.c b/drivers/soc/aspeed/aspeed-lpc-snoop.c
+index 9ab5ba9cf1d61..57ba855f375d9 100644
+--- a/drivers/soc/aspeed/aspeed-lpc-snoop.c
++++ b/drivers/soc/aspeed/aspeed-lpc-snoop.c
+@@ -166,7 +166,7 @@ static int aspeed_lpc_snoop_config_irq(struct aspeed_lpc_snoop *lpc_snoop,
+       int rc;
+       lpc_snoop->irq = platform_get_irq(pdev, 0);
+-      if (!lpc_snoop->irq)
++      if (lpc_snoop->irq < 0)
+               return -ENODEV;
+       rc = devm_request_irq(dev, lpc_snoop->irq,
+-- 
+2.39.5
+
diff --git a/queue-6.15/soc-qcom-smp2p-fix-fallback-to-qcom-ipc-parse.patch b/queue-6.15/soc-qcom-smp2p-fix-fallback-to-qcom-ipc-parse.patch
new file mode 100644 (file)
index 0000000..63719c3
--- /dev/null
@@ -0,0 +1,44 @@
+From 532d080919965a400b176a0ed686894e27e21a18 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Apr 2025 04:04:17 +0200
+Subject: soc: qcom: smp2p: Fix fallback to qcom,ipc parse
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Barnabás Czémán <barnabas.czeman@mainlining.org>
+
+[ Upstream commit 421777a02bbd9cdabe0ae05a69ee06253150589d ]
+
+mbox_request_channel() returning value was changed in case of error.
+It uses returning value of of_parse_phandle_with_args().
+It is returning with -ENOENT instead of -ENODEV when no mboxes property
+exists.
+
+Fixes: 24fdd5074b20 ("mailbox: use error ret code of of_parse_phandle_with_args()")
+Signed-off-by: Barnabás Czémán <barnabas.czeman@mainlining.org>
+Reviewed-by: Stephan Gerhold <stephan.gerhold@linaro.org>
+Tested-by: Stephan Gerhold <stephan.gerhold@linaro.org> # msm8939
+Link: https://lore.kernel.org/r/20250421-fix-qcom-smd-v1-2-574d071d3f27@mainlining.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/qcom/smp2p.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/soc/qcom/smp2p.c b/drivers/soc/qcom/smp2p.c
+index a3e88ced328a9..c9199d6fbe26e 100644
+--- a/drivers/soc/qcom/smp2p.c
++++ b/drivers/soc/qcom/smp2p.c
+@@ -575,7 +575,7 @@ static int qcom_smp2p_probe(struct platform_device *pdev)
+       smp2p->mbox_client.knows_txdone = true;
+       smp2p->mbox_chan = mbox_request_channel(&smp2p->mbox_client, 0);
+       if (IS_ERR(smp2p->mbox_chan)) {
+-              if (PTR_ERR(smp2p->mbox_chan) != -ENODEV)
++              if (PTR_ERR(smp2p->mbox_chan) != -ENOENT)
+                       return PTR_ERR(smp2p->mbox_chan);
+               smp2p->mbox_chan = NULL;
+-- 
+2.39.5
+
diff --git a/queue-6.15/soundwire-only-compute-port-params-in-specific-strea.patch b/queue-6.15/soundwire-only-compute-port-params-in-specific-strea.patch
new file mode 100644 (file)
index 0000000..6b5ad4c
--- /dev/null
@@ -0,0 +1,49 @@
+From 4b2d7e98e0b2750c865d4a33ab7c84daf12912b6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 May 2025 14:20:29 +0800
+Subject: soundwire: only compute port params in specific stream states
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Bard Liao <yung-chuan.liao@linux.intel.com>
+
+[ Upstream commit 62ada17a6217a50fbd1b23f10899890f56effc97 ]
+
+Currently, sdw_compute_master_ports() is blindly called for every single
+Manager runtime. However, we should not take into account the stream's
+bandwidth if the stream is just allocated or already deprepared.
+
+Fixes: 25befdf32aa4 ("soundwire: generic_bandwidth_allocation: count the bandwidth of active streams only")
+Link: https://github.com/thesofproject/linux/issues/5398
+Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
+Link: https://lore.kernel.org/r/20250508062029.6596-1-yung-chuan.liao@linux.intel.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soundwire/generic_bandwidth_allocation.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/soundwire/generic_bandwidth_allocation.c b/drivers/soundwire/generic_bandwidth_allocation.c
+index 1cfaccf43eac5..c18f0c16f9297 100644
+--- a/drivers/soundwire/generic_bandwidth_allocation.c
++++ b/drivers/soundwire/generic_bandwidth_allocation.c
+@@ -204,6 +204,13 @@ static void _sdw_compute_port_params(struct sdw_bus *bus,
+                       port_bo = 1;
+                       list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) {
++                              /*
++                               * Only runtimes with CONFIGURED, PREPARED, ENABLED, and DISABLED
++                               * states should be included in the bandwidth calculation.
++                               */
++                              if (m_rt->stream->state > SDW_STREAM_DISABLED ||
++                                  m_rt->stream->state < SDW_STREAM_CONFIGURED)
++                                      continue;
+                               sdw_compute_master_ports(m_rt, &params[i], &port_bo, hstop);
+                       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/spi-atmel-quadspi-fix-unbalanced-pm_runtime-by-using.patch b/queue-6.15/spi-atmel-quadspi-fix-unbalanced-pm_runtime-by-using.patch
new file mode 100644 (file)
index 0000000..12444ef
--- /dev/null
@@ -0,0 +1,71 @@
+From a6883a8c31d80beba859bd7e48d1825ec760d6c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Mar 2025 20:59:27 +0100
+Subject: spi: atmel-quadspi: Fix unbalanced pm_runtime by using devm_ API
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Bence Csókás <csokas.bence@prolan.hu>
+
+[ Upstream commit 8856eafcc05ecf54d6dd2b6c67804fefd276472c ]
+
+Fix unbalanced PM in error path of `atmel_qspi_probe()`
+by using `devm_pm_runtime_*()` functions.
+
+Reported-by: Alexander Dahl <ada@thorsis.com>
+Closes: https://lore.kernel.org/linux-spi/20250110-paycheck-irregular-bcddab1276c7@thorsis.com/
+Fixes: 5af42209a4d2 ("spi: atmel-quadspi: Add support for sama7g5 QSPI")
+Signed-off-by: Bence Csókás <csokas.bence@prolan.hu>
+Link: https://patch.msgid.link/20250327195928.680771-4-csokas.bence@prolan.hu
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/atmel-quadspi.c | 17 ++++-------------
+ 1 file changed, 4 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/spi/atmel-quadspi.c b/drivers/spi/atmel-quadspi.c
+index 244ac01068629..e7b61dc4ce676 100644
+--- a/drivers/spi/atmel-quadspi.c
++++ b/drivers/spi/atmel-quadspi.c
+@@ -1436,22 +1436,17 @@ static int atmel_qspi_probe(struct platform_device *pdev)
+       pm_runtime_set_autosuspend_delay(&pdev->dev, 500);
+       pm_runtime_use_autosuspend(&pdev->dev);
+-      pm_runtime_set_active(&pdev->dev);
+-      pm_runtime_enable(&pdev->dev);
+-      pm_runtime_get_noresume(&pdev->dev);
++      devm_pm_runtime_set_active_enabled(&pdev->dev);
++      devm_pm_runtime_get_noresume(&pdev->dev);
+       err = atmel_qspi_init(aq);
+       if (err)
+               goto dma_release;
+       err = spi_register_controller(ctrl);
+-      if (err) {
+-              pm_runtime_put_noidle(&pdev->dev);
+-              pm_runtime_disable(&pdev->dev);
+-              pm_runtime_set_suspended(&pdev->dev);
+-              pm_runtime_dont_use_autosuspend(&pdev->dev);
++      if (err)
+               goto dma_release;
+-      }
++
+       pm_runtime_mark_last_busy(&pdev->dev);
+       pm_runtime_put_autosuspend(&pdev->dev);
+@@ -1530,10 +1525,6 @@ static void atmel_qspi_remove(struct platform_device *pdev)
+                */
+               dev_warn(&pdev->dev, "Failed to resume device on remove\n");
+       }
+-
+-      pm_runtime_disable(&pdev->dev);
+-      pm_runtime_dont_use_autosuspend(&pdev->dev);
+-      pm_runtime_put_noidle(&pdev->dev);
+ }
+ static int __maybe_unused atmel_qspi_suspend(struct device *dev)
+-- 
+2.39.5
+
diff --git a/queue-6.15/spi-bcm63xx-hsspi-fix-shared-reset.patch b/queue-6.15/spi-bcm63xx-hsspi-fix-shared-reset.patch
new file mode 100644 (file)
index 0000000..9bca605
--- /dev/null
@@ -0,0 +1,42 @@
+From 03b45666574d3f56441360929d37e880de7da1e7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 May 2025 15:09:15 +0200
+Subject: spi: bcm63xx-hsspi: fix shared reset
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Álvaro Fernández Rojas <noltari@gmail.com>
+
+[ Upstream commit 3d6d84c8f2f66d3fd6a43a1e2ce8e6b54c573960 ]
+
+Some bmips SoCs (bcm6362, bcm63268) share the same SPI reset for both SPI
+and HSSPI controllers, so reset shouldn't be exclusive.
+
+Fixes: 0eeadddbf09a ("spi: bcm63xx-hsspi: add reset support")
+Reported-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Link: https://patch.msgid.link/20250529130915.2519590-3-noltari@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-bcm63xx-hsspi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-bcm63xx-hsspi.c b/drivers/spi/spi-bcm63xx-hsspi.c
+index 644b44d2aef24..18261cbd413b4 100644
+--- a/drivers/spi/spi-bcm63xx-hsspi.c
++++ b/drivers/spi/spi-bcm63xx-hsspi.c
+@@ -745,7 +745,7 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev)
+       if (IS_ERR(clk))
+               return PTR_ERR(clk);
+-      reset = devm_reset_control_get_optional_exclusive(dev, NULL);
++      reset = devm_reset_control_get_optional_shared(dev, NULL);
+       if (IS_ERR(reset))
+               return PTR_ERR(reset);
+-- 
+2.39.5
+
diff --git a/queue-6.15/spi-bcm63xx-spi-fix-shared-reset.patch b/queue-6.15/spi-bcm63xx-spi-fix-shared-reset.patch
new file mode 100644 (file)
index 0000000..2867d90
--- /dev/null
@@ -0,0 +1,42 @@
+From 7f6d898a2c3a613740ecbec95d01b084b3bfa564 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 May 2025 15:09:14 +0200
+Subject: spi: bcm63xx-spi: fix shared reset
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Álvaro Fernández Rojas <noltari@gmail.com>
+
+[ Upstream commit 5ad20e3d8cfe3b2e42bbddc7e0ebaa74479bb589 ]
+
+Some bmips SoCs (bcm6362, bcm63268) share the same SPI reset for both SPI
+and HSSPI controllers, so reset shouldn't be exclusive.
+
+Fixes: 38807adeaf1e ("spi: bcm63xx-spi: add reset support")
+Reported-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Link: https://patch.msgid.link/20250529130915.2519590-2-noltari@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-bcm63xx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c
+index c8f64ec69344a..b56210734caaf 100644
+--- a/drivers/spi/spi-bcm63xx.c
++++ b/drivers/spi/spi-bcm63xx.c
+@@ -523,7 +523,7 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
+               return PTR_ERR(clk);
+       }
+-      reset = devm_reset_control_get_optional_exclusive(dev, NULL);
++      reset = devm_reset_control_get_optional_shared(dev, NULL);
+       if (IS_ERR(reset))
+               return PTR_ERR(reset);
+-- 
+2.39.5
+
diff --git a/queue-6.15/spi-sh-msiof-fix-maximum-dma-transfer-size.patch b/queue-6.15/spi-sh-msiof-fix-maximum-dma-transfer-size.patch
new file mode 100644 (file)
index 0000000..824022d
--- /dev/null
@@ -0,0 +1,71 @@
+From f81315920f57dcab37cf16a7cdbeacbae17139d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 May 2025 15:32:06 +0200
+Subject: spi: sh-msiof: Fix maximum DMA transfer size
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 0941d5166629cb766000530945e54b4e49680c68 ]
+
+The maximum amount of data to transfer in a single DMA request is
+calculated from the FIFO sizes (which is technically not 100% correct,
+but a simplification, as it is limited by the maximum word count values
+in the Transmit and Control Data Registers).  However, in case there is
+both data to transmit and to receive, the transmit limit is overwritten
+by the receive limit.
+
+Fix this by using the minimum applicable FIFO size instead.  Move the
+calculation outside the loop, so it is not repeated for each individual
+DMA transfer.
+
+As currently tx_fifo_size is always equal to rx_fifo_size, this bug had
+no real impact.
+
+Fixes: fe78d0b7691c0274 ("spi: sh-msiof: Fix FIFO size to 64 word from 256 word")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://patch.msgid.link/d9961767a97758b2614f2ee8afe1bd56dc900a60.1747401908.git.geert+renesas@glider.be
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-sh-msiof.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c
+index 8a98c313548e3..7d8a7998f8ae7 100644
+--- a/drivers/spi/spi-sh-msiof.c
++++ b/drivers/spi/spi-sh-msiof.c
+@@ -918,6 +918,7 @@ static int sh_msiof_transfer_one(struct spi_controller *ctlr,
+       void *rx_buf = t->rx_buf;
+       unsigned int len = t->len;
+       unsigned int bits = t->bits_per_word;
++      unsigned int max_wdlen = 256;
+       unsigned int bytes_per_word;
+       unsigned int words;
+       int n;
+@@ -931,17 +932,17 @@ static int sh_msiof_transfer_one(struct spi_controller *ctlr,
+       if (!spi_controller_is_target(p->ctlr))
+               sh_msiof_spi_set_clk_regs(p, t);
++      if (tx_buf)
++              max_wdlen = min(max_wdlen, p->tx_fifo_size);
++      if (rx_buf)
++              max_wdlen = min(max_wdlen, p->rx_fifo_size);
++
+       while (ctlr->dma_tx && len > 15) {
+               /*
+                *  DMA supports 32-bit words only, hence pack 8-bit and 16-bit
+                *  words, with byte resp. word swapping.
+                */
+-              unsigned int l = 0;
+-
+-              if (tx_buf)
+-                      l = min(round_down(len, 4), p->tx_fifo_size * 4);
+-              if (rx_buf)
+-                      l = min(round_down(len, 4), p->rx_fifo_size * 4);
++              unsigned int l = min(round_down(len, 4), max_wdlen * 4);
+               if (bits <= 8) {
+                       copy32 = copy_bswap32;
+-- 
+2.39.5
+
diff --git a/queue-6.15/spi-spi-qpic-snand-use-kmalloc-for-oob-buffer-alloca.patch b/queue-6.15/spi-spi-qpic-snand-use-kmalloc-for-oob-buffer-alloca.patch
new file mode 100644 (file)
index 0000000..fda81ee
--- /dev/null
@@ -0,0 +1,40 @@
+From 3e9354c0e7c0e319060045109ab0c3ce41483b63 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Mar 2025 19:11:59 +0100
+Subject: spi: spi-qpic-snand: use kmalloc() for OOB buffer allocation
+
+From: Gabor Juhos <j4g8y7@gmail.com>
+
+[ Upstream commit f48d80503504257682e493dc17408f2f0b47bcfa ]
+
+The qcom_spi_ecc_init_ctx_pipelined() function allocates zeroed
+memory for the OOB buffer, then it fills the buffer with '0xff'
+bytes right after the allocation. In this case zeroing the memory
+during allocation is superfluous, so use kmalloc() instead of
+kzalloc() to avoid that.
+
+Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
+Link: https://patch.msgid.link/20250320-qpic-snand-kmalloc-v1-1-94e267550675@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 65cb56d49f6e ("spi: spi-qpic-snand: validate user/chip specific ECC properties")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-qpic-snand.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-qpic-snand.c b/drivers/spi/spi-qpic-snand.c
+index 94948c8781e83..924aa8461963f 100644
+--- a/drivers/spi/spi-qpic-snand.c
++++ b/drivers/spi/spi-qpic-snand.c
+@@ -261,7 +261,7 @@ static int qcom_spi_ecc_init_ctx_pipelined(struct nand_device *nand)
+       ecc_cfg = kzalloc(sizeof(*ecc_cfg), GFP_KERNEL);
+       if (!ecc_cfg)
+               return -ENOMEM;
+-      snandc->qspi->oob_buf = kzalloc(mtd->writesize + mtd->oobsize,
++      snandc->qspi->oob_buf = kmalloc(mtd->writesize + mtd->oobsize,
+                                       GFP_KERNEL);
+       if (!snandc->qspi->oob_buf) {
+               kfree(ecc_cfg);
+-- 
+2.39.5
+
diff --git a/queue-6.15/spi-spi-qpic-snand-validate-user-chip-specific-ecc-p.patch b/queue-6.15/spi-spi-qpic-snand-validate-user-chip-specific-ecc-p.patch
new file mode 100644 (file)
index 0000000..0a30fca
--- /dev/null
@@ -0,0 +1,176 @@
+From becfe977fa94f28d27717e4b014bf9bb5736d1e3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 May 2025 18:19:16 +0200
+Subject: spi: spi-qpic-snand: validate user/chip specific ECC properties
+
+From: Gabor Juhos <j4g8y7@gmail.com>
+
+[ Upstream commit 65cb56d49f6edea409600a3c61effc70ee5d43d8 ]
+
+The driver only supports 512 bytes ECC step size and 4 bit ECC strength
+at the moment, however it does not reject unsupported step/strength
+configurations. Due to this, whenever the driver is used with a flash
+chip which needs stronger ECC protection, the following warning is shown
+in the kernel log:
+
+  [    0.574648] spi-nand spi0.0: GigaDevice SPI NAND was found.
+  [    0.635748] spi-nand spi0.0: 256 MiB, block size: 128 KiB, page size: 2048, OOB size: 128
+  [    0.649079] nand: WARNING: (null): the ECC used on your system is too weak compared to the one required by the NAND chip
+
+Although the message indicates that something is wrong, but it often gets
+unnoticed, which can cause serious problems. For example when the user
+writes something into the flash chip despite the warning, the written data
+may won't be readable by the bootloader or by the boot ROM. In the worst
+case, when the attached SPI NAND chip is the boot device, the board may not
+be able to boot anymore.
+
+Also, it is not even possible to create a backup of the flash, because
+reading its content results in bogus data. For example, dumping the first
+page of the flash gives this:
+
+  # hexdump -C -n 2048 /dev/mtd0
+  00000000  0f 0f 0f 0f 0f 0f 0f 0f  0f 0f 0f 0f 0f 0f 0f 0f  |................|
+  *
+  00000040  0f 0f 0f 0f 0f 0f 0f 0d  0f 0f 0f 0f 0f 0f 0f 0f  |................|
+  00000050  0f 0f 0f 0f 0f 0f 0f 0f  0f 0f 0f 0f 0f 0f 0f 0f  |................|
+  *
+  000001c0  0f 0f 0f 0f ff 0f 0f 0f  0f 0f 0f 0f 0f 0f 0f 0f  |................|
+  000001d0  0f 0f 0f 0f 0f 0f 0f 0f  0f 0f 0f 0f 0f 0f 0f 0f  |................|
+  *
+  00000200  0f 0f 0f 0f f5 5b ff ff  0f 0f 0f 0f 0f 0f 0f 0f  |.....[..........|
+  00000210  0f 0f 0f 0f 0f 0f 0f 0f  0f 0f 0f 0f 0f 0f 0f 0f  |................|
+  *
+  000002f0  0f 0f 0f 0f 0f 0f 0f 0f  0f 0f 0f 0f 0f 1f 0f 0f  |................|
+  00000300  0f 0f 0f 0f 0f 0f 0f 0f  0f 0f 0f 0f 0f 0f 0f 0f  |................|
+  *
+  000003c0  0f 0f 0f 0f 0f 0f 0f 0f  0f 0f 0f 0f ff 0f 0f 0f  |................|
+  000003d0  0f 0f 0f 0f 0f 0f 0f 0f  0f 0f 0f 0f 0f 0f 0f 0f  |................|
+  *
+  00000400  0f 0f 0f 0f 0f 0f 0f 0f  e9 74 c9 06 f5 5b ff ff  |.........t...[..|
+  00000410  0f 0f 0f 0f 0f 0f 0f 0f  0f 0f 0f 0f 0f 0f 0f 0f  |................|
+  *
+  000005d0  0f 0f 0f 0f ff 0f 0f 0f  0f 0f 0f 0f 0f 0f 0f 0f  |................|
+  000005e0  0f 0f 0f 0f 0f 0f 0f 0f  0f 0f 0f 0f 0f 0f 0f 0f  |................|
+  *
+  00000600  0f 0f 0f 0f 0f 0f 0f 0f  0f 0f 0f 0f c6 be 0f c3  |................|
+  00000610  e9 74 c9 06 f5 5b ff ff  0f 0f 0f 0f 0f 0f 0f 0f  |.t...[..........|
+  00000620  0f 0f 0f 0f 0f 0f 0f 0f  0f 0f 0f 0f 0f 0f 0f 0f  |................|
+  *
+  00000770  0f 0f 0f 0f 8f 0f 0f 0f  0f 0f 0f 0f 0f 0f 0f 0f  |................|
+  00000780  0f 0f 0f 0f 0f 0f 0f 0f  0f 0f 0f 0f 0f 0f 0f 0f  |................|
+  *
+  00000800
+  #
+
+Doing the same by using the downstream kernel results in different output:
+
+  # hexdump -C -n 2048 /dev/mtd0
+  00000000  0f 0f 0f 0f 0f 0f 0f 0f  0f 0f 0f 0f 0f 0f 0f 0f  |................|
+  *
+  00000800
+  #
+
+This patch adds some sanity checks to the code to prevent using the driver
+with unsupported ECC step/strength configurations. After the change, probing
+of the driver fails in such cases:
+
+  [    0.655038] spi-nand spi0.0: GigaDevice SPI NAND was found.
+  [    0.659159] spi-nand spi0.0: 256 MiB, block size: 128 KiB, page size: 2048, OOB size: 128
+  [    0.669138] qcom_snand 79b0000.spi: only 4 bits ECC strength is supported
+  [    0.677476] nand: No suitable ECC configuration
+  [    0.689909] spi-nand spi0.0: probe with driver spi-nand failed with error -95
+
+This helps to avoid the aforementioned hassles until support for 8 bit ECC
+strength gets implemented.
+
+Fixes: 7304d1909080 ("spi: spi-qpic: add driver for QCOM SPI NAND flash Interface")
+Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
+Link: https://patch.msgid.link/20250501-qpic-snand-validate-ecc-v1-1-532776581a66@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-qpic-snand.c | 42 +++++++++++++++++++++++++++++++-----
+ 1 file changed, 37 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/spi/spi-qpic-snand.c b/drivers/spi/spi-qpic-snand.c
+index 924aa8461963f..44a8f58e46fe1 100644
+--- a/drivers/spi/spi-qpic-snand.c
++++ b/drivers/spi/spi-qpic-snand.c
+@@ -250,9 +250,11 @@ static const struct mtd_ooblayout_ops qcom_spi_ooblayout = {
+ static int qcom_spi_ecc_init_ctx_pipelined(struct nand_device *nand)
+ {
+       struct qcom_nand_controller *snandc = nand_to_qcom_snand(nand);
++      struct nand_ecc_props *reqs = &nand->ecc.requirements;
++      struct nand_ecc_props *user = &nand->ecc.user_conf;
+       struct nand_ecc_props *conf = &nand->ecc.ctx.conf;
+       struct mtd_info *mtd = nanddev_to_mtd(nand);
+-      int cwperpage, bad_block_byte;
++      int cwperpage, bad_block_byte, ret;
+       struct qpic_ecc *ecc_cfg;
+       cwperpage = mtd->writesize / NANDC_STEP_SIZE;
+@@ -261,11 +263,39 @@ static int qcom_spi_ecc_init_ctx_pipelined(struct nand_device *nand)
+       ecc_cfg = kzalloc(sizeof(*ecc_cfg), GFP_KERNEL);
+       if (!ecc_cfg)
+               return -ENOMEM;
++
++      if (user->step_size && user->strength) {
++              ecc_cfg->step_size = user->step_size;
++              ecc_cfg->strength = user->strength;
++      } else if (reqs->step_size && reqs->strength) {
++              ecc_cfg->step_size = reqs->step_size;
++              ecc_cfg->strength = reqs->strength;
++      } else {
++              /* use defaults */
++              ecc_cfg->step_size = NANDC_STEP_SIZE;
++              ecc_cfg->strength = 4;
++      }
++
++      if (ecc_cfg->step_size != NANDC_STEP_SIZE) {
++              dev_err(snandc->dev,
++                      "only %u bytes ECC step size is supported\n",
++                      NANDC_STEP_SIZE);
++              ret = -EOPNOTSUPP;
++              goto err_free_ecc_cfg;
++      }
++
++      if (ecc_cfg->strength != 4) {
++              dev_err(snandc->dev,
++                      "only 4 bits ECC strength is supported\n");
++              ret = -EOPNOTSUPP;
++              goto err_free_ecc_cfg;
++      }
++
+       snandc->qspi->oob_buf = kmalloc(mtd->writesize + mtd->oobsize,
+                                       GFP_KERNEL);
+       if (!snandc->qspi->oob_buf) {
+-              kfree(ecc_cfg);
+-              return -ENOMEM;
++              ret = -ENOMEM;
++              goto err_free_ecc_cfg;
+       }
+       memset(snandc->qspi->oob_buf, 0xff, mtd->writesize + mtd->oobsize);
+@@ -280,8 +310,6 @@ static int qcom_spi_ecc_init_ctx_pipelined(struct nand_device *nand)
+       ecc_cfg->bytes = ecc_cfg->ecc_bytes_hw + ecc_cfg->spare_bytes + ecc_cfg->bbm_size;
+       ecc_cfg->steps = 4;
+-      ecc_cfg->strength = 4;
+-      ecc_cfg->step_size = 512;
+       ecc_cfg->cw_data = 516;
+       ecc_cfg->cw_size = ecc_cfg->cw_data + ecc_cfg->bytes;
+       bad_block_byte = mtd->writesize - ecc_cfg->cw_size * (cwperpage - 1) + 1;
+@@ -339,6 +367,10 @@ static int qcom_spi_ecc_init_ctx_pipelined(struct nand_device *nand)
+               ecc_cfg->strength, ecc_cfg->step_size);
+       return 0;
++
++err_free_ecc_cfg:
++      kfree(ecc_cfg);
++      return ret;
+ }
+ static void qcom_spi_ecc_cleanup_ctx_pipelined(struct nand_device *nand)
+-- 
+2.39.5
+
diff --git a/queue-6.15/spi-tegra210-quad-fix-x1_x2_x4-encoding-and-support-.patch b/queue-6.15/spi-tegra210-quad-fix-x1_x2_x4-encoding-and-support-.patch
new file mode 100644 (file)
index 0000000..c1b2572
--- /dev/null
@@ -0,0 +1,85 @@
+From 5d9e508d1380a14654f6ec586d6fbfa3f6f023b0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Apr 2025 11:06:01 +0000
+Subject: spi: tegra210-quad: Fix X1_X2_X4 encoding and support x4 transfers
+
+From: Vishwaroop A <va@nvidia.com>
+
+[ Upstream commit dcb06c638a1174008a985849fa30fc0da7d08904 ]
+
+This patch corrects the QSPI_COMMAND_X1_X2_X4 and QSPI_ADDRESS_X1_X2_X4
+macros to properly encode the bus width for x1, x2, and x4 transfers.
+Although these macros were previously incorrect, they were not being
+used in the driver, so no functionality was affected.
+
+The patch updates tegra_qspi_cmd_config() and tegra_qspi_addr_config()
+function calls to use the actual bus width from the transfer, instead of
+hardcoding it to 0 (which implied x1 mode). This change enables proper
+support for x1, x2, and x4 data transfers by correctly configuring the
+interface width for commands and addresses.
+
+These modifications improve the QSPI driver's flexibility and prepare it
+for future use cases that may require different bus widths for commands
+and addresses.
+
+Fixes: 1b8342cc4a38 ("spi: tegra210-quad: combined sequence mode")
+Signed-off-by: Vishwaroop A <va@nvidia.com>
+Link: https://patch.msgid.link/20250416110606.2737315-2-va@nvidia.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-tegra210-quad.c | 12 ++++--------
+ 1 file changed, 4 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c
+index 64e1b2f8a0001..3d9c5fb237825 100644
+--- a/drivers/spi/spi-tegra210-quad.c
++++ b/drivers/spi/spi-tegra210-quad.c
+@@ -134,7 +134,7 @@
+ #define QSPI_COMMAND_VALUE_SET(X)             (((x) & 0xFF) << 0)
+ #define QSPI_CMB_SEQ_CMD_CFG                  0x1a0
+-#define QSPI_COMMAND_X1_X2_X4(x)              (((x) & 0x3) << 13)
++#define QSPI_COMMAND_X1_X2_X4(x)              ((((x) >> 1) & 0x3) << 13)
+ #define QSPI_COMMAND_X1_X2_X4_MASK            (0x03 << 13)
+ #define QSPI_COMMAND_SDR_DDR                  BIT(12)
+ #define QSPI_COMMAND_SIZE_SET(x)              (((x) & 0xFF) << 0)
+@@ -147,7 +147,7 @@
+ #define QSPI_ADDRESS_VALUE_SET(X)             (((x) & 0xFFFF) << 0)
+ #define QSPI_CMB_SEQ_ADDR_CFG                 0x1ac
+-#define QSPI_ADDRESS_X1_X2_X4(x)              (((x) & 0x3) << 13)
++#define QSPI_ADDRESS_X1_X2_X4(x)              ((((x) >> 1) & 0x3) << 13)
+ #define QSPI_ADDRESS_X1_X2_X4_MASK            (0x03 << 13)
+ #define QSPI_ADDRESS_SDR_DDR                  BIT(12)
+ #define QSPI_ADDRESS_SIZE_SET(x)              (((x) & 0xFF) << 0)
+@@ -1036,10 +1036,6 @@ static u32 tegra_qspi_addr_config(bool is_ddr, u8 bus_width, u8 len)
+ {
+       u32 addr_config = 0;
+-      /* Extract Address configuration and value */
+-      is_ddr = 0; //Only SDR mode supported
+-      bus_width = 0; //X1 mode
+-
+       if (is_ddr)
+               addr_config |= QSPI_ADDRESS_SDR_DDR;
+       else
+@@ -1079,13 +1075,13 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi,
+               switch (transfer_phase) {
+               case CMD_TRANSFER:
+                       /* X1 SDR mode */
+-                      cmd_config = tegra_qspi_cmd_config(false, 0,
++                      cmd_config = tegra_qspi_cmd_config(false, xfer->tx_nbits,
+                                                          xfer->len);
+                       cmd_value = *((const u8 *)(xfer->tx_buf));
+                       break;
+               case ADDR_TRANSFER:
+                       /* X1 SDR mode */
+-                      addr_config = tegra_qspi_addr_config(false, 0,
++                      addr_config = tegra_qspi_addr_config(false, xfer->tx_nbits,
+                                                            xfer->len);
+                       address_value = *((const u32 *)(xfer->tx_buf));
+                       break;
+-- 
+2.39.5
+
diff --git a/queue-6.15/spi-tegra210-quad-modify-chip-select-cs-deactivation.patch b/queue-6.15/spi-tegra210-quad-modify-chip-select-cs-deactivation.patch
new file mode 100644 (file)
index 0000000..c178a3a
--- /dev/null
@@ -0,0 +1,51 @@
+From 0b9b0d16f3a75724e6b9146ad3045fb36a4764e4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Apr 2025 11:06:03 +0000
+Subject: spi: tegra210-quad: modify chip select (CS) deactivation
+
+From: Vishwaroop A <va@nvidia.com>
+
+[ Upstream commit d8966b65413390d1b5b706886987caac05fbe024 ]
+
+Modify the chip select (CS) deactivation and inter-transfer delay
+execution only during the DATA_TRANSFER phase when the cs_change
+flag is not set. This ensures proper CS handling and timing between
+transfers while eliminating redundant operations.
+
+Fixes: 1b8342cc4a38 ("spi: tegra210-quad: combined sequence mode")
+Signed-off-by: Vishwaroop A <va@nvidia.com>
+Link: https://patch.msgid.link/20250416110606.2737315-4-va@nvidia.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-tegra210-quad.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c
+index b2872853d6ed8..665c06e1473be 100644
+--- a/drivers/spi/spi-tegra210-quad.c
++++ b/drivers/spi/spi-tegra210-quad.c
+@@ -1159,16 +1159,16 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi,
+                               ret = -EIO;
+                               goto exit;
+                       }
+-                      if (!xfer->cs_change) {
+-                              tegra_qspi_transfer_end(spi);
+-                              spi_transfer_delay_exec(xfer);
+-                      }
+                       break;
+               default:
+                       ret = -EINVAL;
+                       goto exit;
+               }
+               msg->actual_length += xfer->len;
++              if (!xfer->cs_change && transfer_phase == DATA_TRANSFER) {
++                      tegra_qspi_transfer_end(spi);
++                      spi_transfer_delay_exec(xfer);
++              }
+               transfer_phase++;
+       }
+       ret = 0;
+-- 
+2.39.5
+
diff --git a/queue-6.15/spi-tegra210-quad-remove-redundant-error-handling-co.patch b/queue-6.15/spi-tegra210-quad-remove-redundant-error-handling-co.patch
new file mode 100644 (file)
index 0000000..0fe7c69
--- /dev/null
@@ -0,0 +1,40 @@
+From c16341478d0c963673d060723934bc67b4b1282d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Apr 2025 11:06:02 +0000
+Subject: spi: tegra210-quad: remove redundant error handling code
+
+From: Vishwaroop A <va@nvidia.com>
+
+[ Upstream commit 400d9f1a27cc2fceabdb1ed93eaf0b89b6d32ba5 ]
+
+Remove unnecessary error handling code that terminated transfers and
+executed delay on errors. This code was redundant as error handling is
+already done at a higher level in the SPI core.
+
+Fixes: 1b8342cc4a38 ("spi: tegra210-quad: combined sequence mode")
+Signed-off-by: Vishwaroop A <va@nvidia.com>
+Link: https://patch.msgid.link/20250416110606.2737315-3-va@nvidia.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-tegra210-quad.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c
+index 3d9c5fb237825..b2872853d6ed8 100644
+--- a/drivers/spi/spi-tegra210-quad.c
++++ b/drivers/spi/spi-tegra210-quad.c
+@@ -1175,10 +1175,6 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi,
+ exit:
+       msg->status = ret;
+-      if (ret < 0) {
+-              tegra_qspi_transfer_end(spi);
+-              spi_transfer_delay_exec(xfer);
+-      }
+       return ret;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/squashfs-check-return-result-of-sb_min_blocksize.patch b/queue-6.15/squashfs-check-return-result-of-sb_min_blocksize.patch
new file mode 100644 (file)
index 0000000..f262126
--- /dev/null
@@ -0,0 +1,66 @@
+From 0573f544923e55aa4c1a5ca9901f7d11d5a28662 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Apr 2025 03:47:47 +0100
+Subject: Squashfs: check return result of sb_min_blocksize
+
+From: Phillip Lougher <phillip@squashfs.org.uk>
+
+[ Upstream commit 734aa85390ea693bb7eaf2240623d41b03705c84 ]
+
+Syzkaller reports an "UBSAN: shift-out-of-bounds in squashfs_bio_read" bug.
+
+Syzkaller forks multiple processes which after mounting the Squashfs
+filesystem, issues an ioctl("/dev/loop0", LOOP_SET_BLOCK_SIZE, 0x8000).
+Now if this ioctl occurs at the same time another process is in the
+process of mounting a Squashfs filesystem on /dev/loop0, the failure
+occurs.  When this happens the following code in squashfs_fill_super()
+fails.
+
+----
+msblk->devblksize = sb_min_blocksize(sb, SQUASHFS_DEVBLK_SIZE);
+msblk->devblksize_log2 = ffz(~msblk->devblksize);
+----
+
+sb_min_blocksize() returns 0, which means msblk->devblksize is set to 0.
+
+As a result, ffz(~msblk->devblksize) returns 64, and msblk->devblksize_log2
+is set to 64.
+
+This subsequently causes the
+
+UBSAN: shift-out-of-bounds in fs/squashfs/block.c:195:36
+shift exponent 64 is too large for 64-bit type 'u64' (aka
+'unsigned long long')
+
+This commit adds a check for a 0 return by sb_min_blocksize().
+
+Link: https://lkml.kernel.org/r/20250409024747.876480-1-phillip@squashfs.org.uk
+Fixes: 0aa666190509 ("Squashfs: super block operations")
+Reported-by: syzbot+65761fc25a137b9c8c6e@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/all/67f0dd7a.050a0220.0a13.0230.GAE@google.com/
+Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/squashfs/super.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c
+index 67c55fe32ce88..992ea0e372572 100644
+--- a/fs/squashfs/super.c
++++ b/fs/squashfs/super.c
+@@ -202,6 +202,11 @@ static int squashfs_fill_super(struct super_block *sb, struct fs_context *fc)
+       msblk->panic_on_errors = (opts->errors == Opt_errors_panic);
+       msblk->devblksize = sb_min_blocksize(sb, SQUASHFS_DEVBLK_SIZE);
++      if (!msblk->devblksize) {
++              errorf(fc, "squashfs: unable to set blocksize\n");
++              return -EINVAL;
++      }
++
+       msblk->devblksize_log2 = ffz(~msblk->devblksize);
+       mutex_init(&msblk->meta_index_mutex);
+-- 
+2.39.5
+
diff --git a/queue-6.15/staging-gpib-fix-pcmcia-config-identifier.patch b/queue-6.15/staging-gpib-fix-pcmcia-config-identifier.patch
new file mode 100644 (file)
index 0000000..69d23ae
--- /dev/null
@@ -0,0 +1,40 @@
+From e5b35accc0e72af0deda4d651c9752880f707e26 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 May 2025 09:21:48 +0200
+Subject: staging: gpib: Fix PCMCIA config identifier
+
+From: Dave Penkler <dpenkler@gmail.com>
+
+[ Upstream commit 034a456869a071c635a9997e0bf3947a6cb20b25 ]
+
+The PCMCIA config identifier in the ines_exit_module function
+was never changed because it was misspelled in the original commit.
+
+Update the config parameter to use the correct identifier from
+gpib/Kconfig
+
+Fixes: bb1bd92fa0f2 ("staging: gpib: Add ines GPIB driver")
+Signed-off-by: Dave Penkler <dpenkler@gmail.com>
+Link: https://lore.kernel.org/r/20250502072150.32714-2-dpenkler@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/gpib/ines/ines_gpib.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/staging/gpib/ines/ines_gpib.c b/drivers/staging/gpib/ines/ines_gpib.c
+index d93eb05dab903..8e2375d8ddac2 100644
+--- a/drivers/staging/gpib/ines/ines_gpib.c
++++ b/drivers/staging/gpib/ines/ines_gpib.c
+@@ -1484,7 +1484,7 @@ static void __exit ines_exit_module(void)
+       gpib_unregister_driver(&ines_pci_unaccel_interface);
+       gpib_unregister_driver(&ines_pci_accel_interface);
+       gpib_unregister_driver(&ines_isa_interface);
+-#ifdef GPIB__PCMCIA
++#ifdef CONFIG_GPIB_PCMCIA
+       gpib_unregister_driver(&ines_pcmcia_interface);
+       gpib_unregister_driver(&ines_pcmcia_unaccel_interface);
+       gpib_unregister_driver(&ines_pcmcia_accel_interface);
+-- 
+2.39.5
+
diff --git a/queue-6.15/staging-gpib-fix-secondary-address-restriction.patch b/queue-6.15/staging-gpib-fix-secondary-address-restriction.patch
new file mode 100644 (file)
index 0000000..9667ffc
--- /dev/null
@@ -0,0 +1,42 @@
+From 3e828c09cc1732958feac5efa2f31f41823e2b3c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 May 2025 17:51:00 +0200
+Subject: staging: gpib: Fix secondary address restriction
+
+From: Dave Penkler <dpenkler@gmail.com>
+
+[ Upstream commit 5aac95320d0f17f1098960e903ce5e087f42bc70 ]
+
+GPIB secondary addresses have valid values between 0 and 31
+inclusive. The Make Secondary Address function MSA, used to form
+the protocol byte, was using the gpib_address_restrict function
+erroneously restricting the address range to 0 through 30.
+
+Remove the call to gpib_address_restrict and simply trim the
+address to 5 bits.
+
+Fixes: 2da03e7e31aa ("staging: gpib: Add user api include files")
+Signed-off-by: Dave Penkler <dpenkler@gmail.com>
+Link: https://lore.kernel.org/r/20250520155100.5808-1-dpenkler@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/gpib/uapi/gpib_user.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/staging/gpib/uapi/gpib_user.h b/drivers/staging/gpib/uapi/gpib_user.h
+index 5ff4588686fde..0fd32fb9e7a64 100644
+--- a/drivers/staging/gpib/uapi/gpib_user.h
++++ b/drivers/staging/gpib/uapi/gpib_user.h
+@@ -178,7 +178,7 @@ static inline uint8_t MTA(unsigned int addr)
+ static inline uint8_t MSA(unsigned int addr)
+ {
+-      return gpib_address_restrict(addr) | SAD;
++      return (addr & 0x1f) | SAD;
+ }
+ static inline uint8_t PPE_byte(unsigned int dio_line, int sense)
+-- 
+2.39.5
+
diff --git a/queue-6.15/svcrdma-reduce-the-number-of-rdma_rw-contexts-per-qp.patch b/queue-6.15/svcrdma-reduce-the-number-of-rdma_rw-contexts-per-qp.patch
new file mode 100644 (file)
index 0000000..88ecebf
--- /dev/null
@@ -0,0 +1,95 @@
+From 05f8363ec67d5053330d7d1f9e760346ac6f5b5a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Apr 2025 15:36:49 -0400
+Subject: svcrdma: Reduce the number of rdma_rw contexts per-QP
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+[ Upstream commit 59243315890578a040a2d50ae9e001a2ef2fcb62 ]
+
+There is an upper bound on the number of rdma_rw contexts that can
+be created per QP.
+
+This invisible upper bound is because rdma_create_qp() adds one or
+more additional SQEs for each ctxt that the ULP requests via
+qp_attr.cap.max_rdma_ctxs. The QP's actual Send Queue length is on
+the order of the sum of qp_attr.cap.max_send_wr and a factor times
+qp_attr.cap.max_rdma_ctxs. The factor can be up to three, depending
+on whether MR operations are required before RDMA Reads.
+
+This limit is not visible to RDMA consumers via dev->attrs. When the
+limit is surpassed, QP creation fails with -ENOMEM. For example:
+
+svcrdma's estimate of the number of rdma_rw contexts it needs is
+three times the number of pages in RPCSVC_MAXPAGES. When MAXPAGES
+is about 260, the internally-computed SQ length should be:
+
+64 credits + 10 backlog + 3 * (3 * 260) = 2414
+
+Which is well below the advertised qp_max_wr of 32768.
+
+If RPCSVC_MAXPAGES is increased to 4MB, that's 1040 pages:
+
+64 credits + 10 backlog + 3 * (3 * 1040) = 9434
+
+However, QP creation fails. Dynamic printk for mlx5 shows:
+
+calc_sq_size:618:(pid 1514): send queue size (9326 * 256 / 64 -> 65536) exceeds limits(32768)
+
+Although 9326 is still far below qp_max_wr, QP creation still
+fails.
+
+Because the total SQ length calculation is opaque to RDMA consumers,
+there doesn't seem to be much that can be done about this except for
+consumers to try to keep the requested rdma_rw ctxt count low.
+
+Fixes: 2da0f610e733 ("svcrdma: Increase the per-transport rw_ctx count")
+Reviewed-by: NeilBrown <neil@brown.name>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sunrpc/xprtrdma/svc_rdma_transport.c | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c
+index aca8bdf65d729..ca6172822b68a 100644
+--- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
++++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
+@@ -406,12 +406,12 @@ static void svc_rdma_xprt_done(struct rpcrdma_notification *rn)
+  */
+ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
+ {
++      unsigned int ctxts, rq_depth, maxpayload;
+       struct svcxprt_rdma *listen_rdma;
+       struct svcxprt_rdma *newxprt = NULL;
+       struct rdma_conn_param conn_param;
+       struct rpcrdma_connect_private pmsg;
+       struct ib_qp_init_attr qp_attr;
+-      unsigned int ctxts, rq_depth;
+       struct ib_device *dev;
+       int ret = 0;
+       RPC_IFDEBUG(struct sockaddr *sap);
+@@ -462,12 +462,14 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
+               newxprt->sc_max_bc_requests = 2;
+       }
+-      /* Arbitrarily estimate the number of rw_ctxs needed for
+-       * this transport. This is enough rw_ctxs to make forward
+-       * progress even if the client is using one rkey per page
+-       * in each Read chunk.
++      /* Arbitrary estimate of the needed number of rdma_rw contexts.
+        */
+-      ctxts = 3 * RPCSVC_MAXPAGES;
++      maxpayload = min(xprt->xpt_server->sv_max_payload,
++                       RPCSVC_MAXPAYLOAD_RDMA);
++      ctxts = newxprt->sc_max_requests * 3 *
++              rdma_rw_mr_factor(dev, newxprt->sc_port_num,
++                                maxpayload >> PAGE_SHIFT);
++
+       newxprt->sc_sq_depth = rq_depth + ctxts;
+       if (newxprt->sc_sq_depth > dev->attrs.max_qp_wr)
+               newxprt->sc_sq_depth = dev->attrs.max_qp_wr;
+-- 
+2.39.5
+
diff --git a/queue-6.15/thermal-drivers-mediatek-lvts-fix-debugfs-unregister.patch b/queue-6.15/thermal-drivers-mediatek-lvts-fix-debugfs-unregister.patch
new file mode 100644 (file)
index 0000000..b710813
--- /dev/null
@@ -0,0 +1,79 @@
+From 6fd6b108b6b2a9c34da5a8126a6e8690e5129e7c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Apr 2025 10:38:52 +0200
+Subject: thermal/drivers/mediatek/lvts: Fix debugfs unregister on failure
+
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+[ Upstream commit b49825661af93d9b8d7236f914803f136896f8fd ]
+
+When running the probe function for this driver, the function
+lvts_debugfs_init() gets called in lvts_domain_init() which, in
+turn, gets called in lvts_probe() before registering threaded
+interrupt handlers.
+
+Even though it's unlikely, the last call may fail and, if it does,
+there's nothing removing the already created debugfs folder and
+files.
+
+In order to fix that, instead of calling the lvts debugfs cleanup
+function upon failure, register a devm action that will take care
+of calling that upon failure or driver removal.
+
+Since devm was used, also delete the call to lvts_debugfs_exit()
+in the lvts_remove() callback, as now that's done automatically.
+
+Fixes: f5f633b18234 ("thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver")
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
+Link: https://lore.kernel.org/r/20250402083852.20624-1-angelogioacchino.delregno@collabora.com
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/mediatek/lvts_thermal.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c
+index 088481d91e6e2..c0be4ca55c7b8 100644
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -213,6 +213,13 @@ static const struct debugfs_reg32 lvts_regs[] = {
+       LVTS_DEBUG_FS_REGS(LVTS_CLKEN),
+ };
++static void lvts_debugfs_exit(void *data)
++{
++      struct lvts_domain *lvts_td = data;
++
++      debugfs_remove_recursive(lvts_td->dom_dentry);
++}
++
+ static int lvts_debugfs_init(struct device *dev, struct lvts_domain *lvts_td)
+ {
+       struct debugfs_regset32 *regset;
+@@ -245,12 +252,7 @@ static int lvts_debugfs_init(struct device *dev, struct lvts_domain *lvts_td)
+               debugfs_create_regset32("registers", 0400, dentry, regset);
+       }
+-      return 0;
+-}
+-
+-static void lvts_debugfs_exit(struct lvts_domain *lvts_td)
+-{
+-      debugfs_remove_recursive(lvts_td->dom_dentry);
++      return devm_add_action_or_reset(dev, lvts_debugfs_exit, lvts_td);
+ }
+ #else
+@@ -1374,8 +1376,6 @@ static void lvts_remove(struct platform_device *pdev)
+       for (i = 0; i < lvts_td->num_lvts_ctrl; i++)
+               lvts_ctrl_set_enable(&lvts_td->lvts_ctrl[i], false);
+-
+-      lvts_debugfs_exit(lvts_td);
+ }
+ static const struct lvts_ctrl_data mt7988_lvts_ap_data_ctrl[] = {
+-- 
+2.39.5
+
diff --git a/queue-6.15/thunderbolt-fix-a-logic-error-in-wake-on-connect.patch b/queue-6.15/thunderbolt-fix-a-logic-error-in-wake-on-connect.patch
new file mode 100644 (file)
index 0000000..9e8c1a1
--- /dev/null
@@ -0,0 +1,51 @@
+From 2e25205e7ee31ea3f26a2391a2b829cb88314d24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Apr 2025 10:14:44 -0500
+Subject: thunderbolt: Fix a logic error in wake on connect
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+[ Upstream commit 1a760d10ded372d113a0410c42be246315bbc2ff ]
+
+commit a5cfc9d65879c ("thunderbolt: Add wake on connect/disconnect
+on USB4 ports") introduced a sysfs file to control wake up policy
+for a given USB4 port that defaulted to disabled.
+
+However when testing commit 4bfeea6ec1c02 ("thunderbolt: Use wake
+on connect and disconnect over suspend") I found that it was working
+even without making changes to the power/wakeup file (which defaults
+to disabled). This is because of a logic error doing a bitwise or
+of the wake-on-connect flag with device_may_wakeup() which should
+have been a logical AND.
+
+Adjust the logic so that policy is only applied when wakeup is
+actually enabled.
+
+Fixes: a5cfc9d65879c ("thunderbolt: Add wake on connect/disconnect on USB4 ports")
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thunderbolt/usb4.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/thunderbolt/usb4.c b/drivers/thunderbolt/usb4.c
+index e51d01671d8e7..3e96f1afd4268 100644
+--- a/drivers/thunderbolt/usb4.c
++++ b/drivers/thunderbolt/usb4.c
+@@ -440,10 +440,10 @@ int usb4_switch_set_wake(struct tb_switch *sw, unsigned int flags)
+                       bool configured = val & PORT_CS_19_PC;
+                       usb4 = port->usb4;
+-                      if (((flags & TB_WAKE_ON_CONNECT) |
++                      if (((flags & TB_WAKE_ON_CONNECT) &&
+                             device_may_wakeup(&usb4->dev)) && !configured)
+                               val |= PORT_CS_19_WOC;
+-                      if (((flags & TB_WAKE_ON_DISCONNECT) |
++                      if (((flags & TB_WAKE_ON_DISCONNECT) &&
+                             device_may_wakeup(&usb4->dev)) && configured)
+                               val |= PORT_CS_19_WOD;
+                       if ((flags & TB_WAKE_ON_USB4) && configured)
+-- 
+2.39.5
+
diff --git a/queue-6.15/tools-build-don-t-set-libunwind-as-available-if-test.patch b/queue-6.15/tools-build-don-t-set-libunwind-as-available-if-test.patch
new file mode 100644 (file)
index 0000000..acb6654
--- /dev/null
@@ -0,0 +1,112 @@
+From 8625e45bd980a7b146102a624d9614ae28200670 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Apr 2025 15:37:45 -0300
+Subject: tools build: Don't set libunwind as available if test-all.c build
+ succeeds
+
+From: Arnaldo Carvalho de Melo <acme@redhat.com>
+
+[ Upstream commit 6559b83e4e71ba77461c8d6e6af7b89693c8e677 ]
+
+The tools/build/feature/test-all.c file tries to detect the expected,
+most common set of libraries/features we expect to have available to
+build perf with.
+
+At some point libunwind was deemed not to be part of that set of
+libries, but the patches making it to be opt-in ended up forgetting some
+details, fix one more.
+
+Testing it:
+
+  $ rm -rf /tmp/build/$(basename $PWD)/ ; mkdir -p /tmp/build/$(basename $PWD)/
+  $ rpm -q libunwind-devel
+  libunwind-devel-1.8.0-3.fc40.x86_64
+  $ make -k LIBUNWIND=1 CORESIGHT=1 O=/tmp/build/$(basename $PWD)/ -C tools/perf install-bin |& grep unwind && ldd ~/bin/perf | grep unwind
+  ...                               libunwind: [ on  ]
+    CC      /tmp/build/perf-tools-next/arch/x86/tests/dwarf-unwind.o
+    CC      /tmp/build/perf-tools-next/arch/x86/util/unwind-libunwind.o
+    CC      /tmp/build/perf-tools-next/util/arm64-frame-pointer-unwind-support.o
+    CC      /tmp/build/perf-tools-next/tests/dwarf-unwind.o
+    CC      /tmp/build/perf-tools-next/util/unwind-libunwind-local.o
+    CC      /tmp/build/perf-tools-next/util/unwind-libunwind.o
+         libunwind-x86_64.so.8 => /lib64/libunwind-x86_64.so.8 (0x00007f615a549000)
+         libunwind.so.8 => /lib64/libunwind.so.8 (0x00007f615a52f000)
+  $ sudo rpm -e libunwind-devel
+  $ rm -rf /tmp/build/$(basename $PWD)/ ; mkdir -p /tmp/build/$(basename $PWD)/
+  $ make -k LIBUNWIND=1 CORESIGHT=1 O=/tmp/build/$(basename $PWD)/ -C tools/perf install-bin |& grep unwind && ldd ~/bin/perf | grep unwind
+  Makefile.config:653: No libunwind found. Please install libunwind-dev[el] >= 1.1 and/or set LIBUNWIND_DIR
+  ...                               libunwind: [ OFF ]
+    CC      /tmp/build/perf-tools-next/arch/x86/tests/dwarf-unwind.o
+    CC      /tmp/build/perf-tools-next/arch/x86/util/unwind-libdw.o
+    CC      /tmp/build/perf-tools-next/util/arm64-frame-pointer-unwind-support.o
+    CC      /tmp/build/perf-tools-next/tests/dwarf-unwind.o
+    CC      /tmp/build/perf-tools-next/util/unwind-libdw.o
+  $
+
+Should be in a separate patch, but tired now, so also adding a message
+about the need to use LIBUNWIND=1 in the output when its not available,
+so done here as well.
+
+So, now when the devel files are not available we get:
+
+  $ make -k LIBUNWIND=1 CORESIGHT=1 O=/tmp/build/$(basename $PWD)/ -C tools/perf install-bin |& grep unwind && ldd ~/bin/perf | grep unwind
+  Makefile.config:653: No libunwind found. Please install libunwind-dev[el] >= 1.1 and/or set LIBUNWIND_DIR and set LIBUNWIND=1 in the make command line as it is opt-in now
+  ...                               libunwind: [ OFF ]
+  $
+
+Fixes: 13e17c9ff49119aa ("perf build: Make libunwind opt-in rather than opt-out")
+Reported-by: Ingo Molnar <mingo@kernel.org>
+Tested-by: Ingo Molnar <mingo@kernel.org>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Dmitriy Vyukov <dvyukov@google.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: James Clark <james.clark@linaro.org>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/Z_AnsW9oJzFbhIFC@x1
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/build/Makefile.feature | 1 -
+ tools/perf/Makefile.config   | 4 +++-
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature
+index 1f44ca677ad3d..48e3f124b98ac 100644
+--- a/tools/build/Makefile.feature
++++ b/tools/build/Makefile.feature
+@@ -87,7 +87,6 @@ FEATURE_TESTS_BASIC :=                  \
+         libtracefs                      \
+         libcpupower                     \
+         libcrypto                       \
+-        libunwind                       \
+         pthread-attr-setaffinity-np     \
+         pthread-barrier               \
+         reallocarray                    \
+diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
+index b7769a22fe1af..e0c20a5c19cfe 100644
+--- a/tools/perf/Makefile.config
++++ b/tools/perf/Makefile.config
+@@ -625,6 +625,8 @@ endif
+ ifndef NO_LIBUNWIND
+   have_libunwind :=
++  $(call feature_check,libunwind)
++
+   $(call feature_check,libunwind-x86)
+   ifeq ($(feature-libunwind-x86), 1)
+     $(call detected,CONFIG_LIBUNWIND_X86)
+@@ -649,7 +651,7 @@ ifndef NO_LIBUNWIND
+   endif
+   ifneq ($(feature-libunwind), 1)
+-    $(warning No libunwind found. Please install libunwind-dev[el] >= 1.1 and/or set LIBUNWIND_DIR)
++    $(warning No libunwind found. Please install libunwind-dev[el] >= 1.1 and/or set LIBUNWIND_DIR and set LIBUNWIND=1 in the make command line as it is opt-in now)
+     NO_LOCAL_LIBUNWIND := 1
+   else
+     have_libunwind := 1
+-- 
+2.39.5
+
diff --git a/queue-6.15/tools-build-don-t-show-libbfd-build-status-as-it-is-.patch b/queue-6.15/tools-build-don-t-show-libbfd-build-status-as-it-is-.patch
new file mode 100644 (file)
index 0000000..7577742
--- /dev/null
@@ -0,0 +1,54 @@
+From 4b7e1945443a56da1d645776b8d99a366bda06f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Apr 2025 15:03:11 -0300
+Subject: tools build: Don't show libbfd build status as it is opt-in
+
+From: Arnaldo Carvalho de Melo <acme@redhat.com>
+
+[ Upstream commit e0eb84cd518084582c0d1db5d904f31b16902fdc ]
+
+Since dd317df072071903 ("perf build: Make binutil libraries opt in")
+doesn't try to build with binutils libraries, so showing that it is OFF
+when building causes just distraction, remove it from FEATURES_DISPLAY.
+
+For people that for some reason notice that there is always 'perf -vv',
+a short hand for 'perf version --build-options' and 'perf check feature
+libbfd' that now explains why it is not built:
+
+  $ perf check feature libbfd
+  libbfd: [ OFF ]  # HAVE_LIBBFD_SUPPORT ( tip: Deprecated, license incompatibility, use BUILD_NONDISTRO=1 and install binutils-dev[el] )
+  $
+
+Fixes: dd317df072071903 ("perf build: Make binutil libraries opt in")
+Tested-by: Ingo Molnar <mingo@kernel.org>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Dmitriy Vyukov <dvyukov@google.com>
+Cc: Howard Chu <howardchu95@gmail.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/Z--pWmTHGb62_83e@gmail.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/build/Makefile.feature | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature
+index 357749701239f..57bd995ce6afa 100644
+--- a/tools/build/Makefile.feature
++++ b/tools/build/Makefile.feature
+@@ -147,8 +147,6 @@ endif
+ FEATURE_DISPLAY ?=              \
+          libdw                  \
+          glibc                  \
+-         libbfd                 \
+-         libbfd-buildid               \
+          libelf                 \
+          libnuma                \
+          numa_num_possible_cpus \
+-- 
+2.39.5
+
diff --git a/queue-6.15/tools-build-don-t-show-libunwind-build-status-as-it-.patch b/queue-6.15/tools-build-don-t-show-libunwind-build-status-as-it-.patch
new file mode 100644 (file)
index 0000000..561136a
--- /dev/null
@@ -0,0 +1,54 @@
+From a6352b4b868f34305233e7ead923fc2a49744656 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Apr 2025 15:03:11 -0300
+Subject: tools build: Don't show libunwind build status as it is opt-in
+
+From: Arnaldo Carvalho de Melo <acme@redhat.com>
+
+[ Upstream commit a3a40391292273cf78a7920c119cdc386d694c38 ]
+
+Since 13e17c9ff49119aa ("perf build: Make libunwind opt-in rather than
+opt-out") doesn't try to build with libunwind, so showing that it is OFF
+when building causes just distraction, remove it from FEATURES_DISPLAY.
+
+For people that for some reason notice that there is always 'perf -vv',
+a short hand for 'perf version --build-options' and 'perf check feature
+libunwind' that now explains why it is not built:
+
+  $ perf check feature libunwind
+             libunwind: [ OFF ]  # HAVE_LIBUNWIND_SUPPORT ( tip: Deprecated, use LIBUNWIND=1 and install libunwind-dev[el] to build with it )
+  $
+
+Fixes: 13e17c9ff49119aa ("perf build: Make libunwind opt-in rather than opt-out")
+Reported-by: Ingo Molnar <mingo@kernel.org>
+Tested-by: Ingo Molnar <mingo@kernel.org>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Dmitriy Vyukov <dvyukov@google.com>
+Cc: Howard Chu <howardchu95@gmail.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/Z--pWmTHGb62_83e@gmail.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/build/Makefile.feature | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature
+index 48e3f124b98ac..357749701239f 100644
+--- a/tools/build/Makefile.feature
++++ b/tools/build/Makefile.feature
+@@ -155,7 +155,6 @@ FEATURE_DISPLAY ?=              \
+          libperl                \
+          libpython              \
+          libcrypto              \
+-         libunwind              \
+          libcapstone            \
+          llvm-perf              \
+          zlib                   \
+-- 
+2.39.5
+
diff --git a/queue-6.15/tools-nolibc-fix-integer-overflow-in-i-64-toa_r-and.patch b/queue-6.15/tools-nolibc-fix-integer-overflow-in-i-64-toa_r-and.patch
new file mode 100644 (file)
index 0000000..8d2f72e
--- /dev/null
@@ -0,0 +1,49 @@
+From 75026185123fd95e74c3728af6e4bd3c0cfd0bea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Apr 2025 12:46:22 +0200
+Subject: tools/nolibc: fix integer overflow in i{64,}toa_r() and
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Thomas Weißschuh <linux@weissschuh.net>
+
+[ Upstream commit 4d231a7df1a85c7572b67a4666cb73adb977fbf6 ]
+
+In twos complement the most negative number can not be negated.
+
+Fixes: b1c21e7d99cd ("tools/nolibc/stdlib: add i64toa() and u64toa()")
+Fixes: 66c397c4d2e1 ("tools/nolibc/stdlib: replace the ltoa() function with more efficient ones")
+Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
+Acked-by: Willy Tarreau <w@1wt.eu>
+Link: https://lore.kernel.org/r/20250419-nolibc-ubsan-v2-5-060b8a016917@weissschuh.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/include/nolibc/stdlib.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/include/nolibc/stdlib.h b/tools/include/nolibc/stdlib.h
+index 86ad378ab1ea2..32b3038002c16 100644
+--- a/tools/include/nolibc/stdlib.h
++++ b/tools/include/nolibc/stdlib.h
+@@ -275,7 +275,7 @@ int itoa_r(long in, char *buffer)
+       int len = 0;
+       if (in < 0) {
+-              in = -in;
++              in = -(unsigned long)in;
+               *(ptr++) = '-';
+               len++;
+       }
+@@ -411,7 +411,7 @@ int i64toa_r(int64_t in, char *buffer)
+       int len = 0;
+       if (in < 0) {
+-              in = -in;
++              in = -(uint64_t)in;
+               *(ptr++) = '-';
+               len++;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/tools-nolibc-properly-align-dirent-buffer.patch b/queue-6.15/tools-nolibc-properly-align-dirent-buffer.patch
new file mode 100644 (file)
index 0000000..e9ec153
--- /dev/null
@@ -0,0 +1,48 @@
+From ee7908c69769df295b8a2ca40eacee387fd1fafc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Apr 2025 12:46:21 +0200
+Subject: tools/nolibc: properly align dirent buffer
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Thomas Weißschuh <linux@weissschuh.net>
+
+[ Upstream commit 0e75768ba24d669dbf76530e21fd51cfe2fbd2a9 ]
+
+As byte buffer is overlaid with a 'struct dirent64'.
+it has to satisfy the structs alignment requirements.
+
+Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
+Fixes: 665fa8dea90d ("tools/nolibc: add support for directory access")
+Acked-by: Willy Tarreau <w@1wt.eu>
+Link: https://lore.kernel.org/r/20250419-nolibc-ubsan-v2-4-060b8a016917@weissschuh.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/include/nolibc/dirent.h | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/tools/include/nolibc/dirent.h b/tools/include/nolibc/dirent.h
+index c5c30d0dd6806..946a697e98e4c 100644
+--- a/tools/include/nolibc/dirent.h
++++ b/tools/include/nolibc/dirent.h
+@@ -7,6 +7,7 @@
+ #ifndef _NOLIBC_DIRENT_H
+ #define _NOLIBC_DIRENT_H
++#include "compiler.h"
+ #include "stdint.h"
+ #include "types.h"
+@@ -58,7 +59,7 @@ int closedir(DIR *dirp)
+ static __attribute__((unused))
+ int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
+ {
+-      char buf[sizeof(struct linux_dirent64) + NAME_MAX + 1];
++      char buf[sizeof(struct linux_dirent64) + NAME_MAX + 1] __nolibc_aligned_as(struct linux_dirent64);
+       struct linux_dirent64 *ldir = (void *)buf;
+       intptr_t i = (intptr_t)dirp;
+       int fd, ret;
+-- 
+2.39.5
+
diff --git a/queue-6.15/tools-nolibc-types.h-fix-mismatched-parenthesis-in-m.patch b/queue-6.15/tools-nolibc-types.h-fix-mismatched-parenthesis-in-m.patch
new file mode 100644 (file)
index 0000000..a9cfd6e
--- /dev/null
@@ -0,0 +1,40 @@
+From 45379fa935ba1974a35a3b5e45b6526f71173140 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Apr 2025 15:36:24 +0800
+Subject: tools/nolibc/types.h: fix mismatched parenthesis in minor()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jemmy Wong <jemmywong512@gmail.com>
+
+[ Upstream commit 9c138ac9392228835b520fd4dbb07e636b34a867 ]
+
+Fix an imbalance where opening parentheses exceed closing ones.
+
+Fixes: eba6d00d38e7c ("tools/nolibc/types: move makedev to types.h and make it a macro")
+Signed-off-by: Jemmy Wong <jemmywong512@gmail.com>
+Acked-by: Willy Tarreau <w@1wt.eu>
+Link: https://lore.kernel.org/r/20250411073624.22153-1-jemmywong512@gmail.com
+Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/include/nolibc/types.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/include/nolibc/types.h b/tools/include/nolibc/types.h
+index b26a5d0c417c7..32d0929c633bb 100644
+--- a/tools/include/nolibc/types.h
++++ b/tools/include/nolibc/types.h
+@@ -201,7 +201,7 @@ struct stat {
+ /* WARNING, it only deals with the 4096 first majors and 256 first minors */
+ #define makedev(major, minor) ((dev_t)((((major) & 0xfff) << 8) | ((minor) & 0xff)))
+ #define major(dev) ((unsigned int)(((dev) >> 8) & 0xfff))
+-#define minor(dev) ((unsigned int)(((dev) & 0xff))
++#define minor(dev) ((unsigned int)((dev) & 0xff))
+ #ifndef offsetof
+ #define offsetof(TYPE, FIELD) ((size_t) &((TYPE *)0)->FIELD)
+-- 
+2.39.5
+
diff --git a/queue-6.15/tools-power-turbostat-fix-amd-package-energy-reporti.patch b/queue-6.15/tools-power-turbostat-fix-amd-package-energy-reporti.patch
new file mode 100644 (file)
index 0000000..f2de8fd
--- /dev/null
@@ -0,0 +1,126 @@
+From 965cd5f5772d4da744eff22e2e5bdefa34479530 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 May 2025 17:18:25 +0530
+Subject: tools/power turbostat: Fix AMD package-energy reporting
+
+From: Gautham R. Shenoy <gautham.shenoy@amd.com>
+
+[ Upstream commit adb49732c8c63665dd3476e8e6b7c67a0f851245 ]
+
+commit 05a2f07db888 ("tools/power turbostat: read RAPL counters via
+perf") that adds support to read RAPL counters via perf defines the
+notion of a RAPL domain_id which is set to physical_core_id on
+platforms which support per_core_rapl counters (Eg: AMD processors
+Family 17h onwards) and is set to the physical_package_id on all the
+other platforms.
+
+However, the physical_core_id is only unique within a package and on
+platforms with multiple packages more than one core can have the same
+physical_core_id and thus the same domain_id. (For eg, the first cores
+of each package have the physical_core_id = 0). This results in all
+these cores with the same physical_core_id using the same entry in the
+rapl_counter_info_perdomain[]. Since rapl_perf_init() skips the
+perf-initialization for cores whose domain_ids have already been
+visited, cores that have the same physical_core_id always read the
+perf file corresponding to the physical_core_id of the first package
+and thus the package-energy is incorrectly reported to be the same
+value for different packages.
+
+Note: This issue only arises when RAPL counters are read via perf and
+not when they are read via MSRs since in the latter case the MSRs are
+read separately on each core.
+
+Fix this issue by associating each CPU with rapl_core_id which is
+unique across all the packages in the system.
+
+Fixes: 05a2f07db888 ("tools/power turbostat: read RAPL counters via perf")
+Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
+Signed-off-by: Len Brown <len.brown@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/power/x86/turbostat/turbostat.c | 41 +++++++++++++++++++++++----
+ 1 file changed, 36 insertions(+), 5 deletions(-)
+
+diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
+index 0170d3cc68194..ab79854cb296e 100644
+--- a/tools/power/x86/turbostat/turbostat.c
++++ b/tools/power/x86/turbostat/turbostat.c
+@@ -4766,6 +4766,38 @@ unsigned long pmt_read_counter(struct pmt_counter *ppmt, unsigned int domain_id)
+       return (value & value_mask) >> value_shift;
+ }
++
++/* Rapl domain enumeration helpers */
++static inline int get_rapl_num_domains(void)
++{
++      int num_packages = topo.max_package_id + 1;
++      int num_cores_per_package;
++      int num_cores;
++
++      if (!platform->has_per_core_rapl)
++              return num_packages;
++
++      num_cores_per_package = topo.max_core_id + 1;
++      num_cores = num_cores_per_package * num_packages;
++
++      return num_cores;
++}
++
++static inline int get_rapl_domain_id(int cpu)
++{
++      int nr_cores_per_package = topo.max_core_id + 1;
++      int rapl_core_id;
++
++      if (!platform->has_per_core_rapl)
++              return cpus[cpu].physical_package_id;
++
++      /* Compute the system-wide unique core-id for @cpu */
++      rapl_core_id = cpus[cpu].physical_core_id;
++      rapl_core_id += cpus[cpu].physical_package_id * nr_cores_per_package;
++
++      return rapl_core_id;
++}
++
+ /*
+  * get_counters(...)
+  * migrate to cpu
+@@ -4821,7 +4853,7 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
+               goto done;
+       if (platform->has_per_core_rapl) {
+-              status = get_rapl_counters(cpu, c->core_id, c, p);
++              status = get_rapl_counters(cpu, get_rapl_domain_id(cpu), c, p);
+               if (status != 0)
+                       return status;
+       }
+@@ -4887,7 +4919,7 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
+               p->sys_lpi = cpuidle_cur_sys_lpi_us;
+       if (!platform->has_per_core_rapl) {
+-              status = get_rapl_counters(cpu, p->package_id, c, p);
++              status = get_rapl_counters(cpu, get_rapl_domain_id(cpu), c, p);
+               if (status != 0)
+                       return status;
+       }
+@@ -7863,7 +7895,7 @@ void linux_perf_init(void)
+ void rapl_perf_init(void)
+ {
+-      const unsigned int num_domains = (platform->has_per_core_rapl ? topo.max_core_id : topo.max_package_id) + 1;
++      const unsigned int num_domains = get_rapl_num_domains();
+       bool *domain_visited = calloc(num_domains, sizeof(bool));
+       rapl_counter_info_perdomain = calloc(num_domains, sizeof(*rapl_counter_info_perdomain));
+@@ -7904,8 +7936,7 @@ void rapl_perf_init(void)
+                               continue;
+                       /* Skip already seen and handled RAPL domains */
+-                      next_domain =
+-                          platform->has_per_core_rapl ? cpus[cpu].physical_core_id : cpus[cpu].physical_package_id;
++                      next_domain = get_rapl_domain_id(cpu);
+                       assert(next_domain < num_domains);
+-- 
+2.39.5
+
diff --git a/queue-6.15/tools-x86-kcpuid-fix-error-handling.patch b/queue-6.15/tools-x86-kcpuid-fix-error-handling.patch
new file mode 100644 (file)
index 0000000..68e3f3b
--- /dev/null
@@ -0,0 +1,168 @@
+From a400e3bdb1a75fb70ca683f91027381174486549 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Mar 2025 15:20:22 +0100
+Subject: tools/x86/kcpuid: Fix error handling
+
+From: Ahmed S. Darwish <darwi@linutronix.de>
+
+[ Upstream commit 116edfe173d0c59ec2aa87fb91f2f31d477b61b3 ]
+
+Error handling in kcpuid is unreliable.  On malloc() failures, the code
+prints an error then just goes on.  The error messages are also printed
+to standard output instead of standard error.
+
+Use err() and errx() from <err.h> to direct all error messages to
+standard error and automatically exit the program.  Use err() to include
+the errno information, and errx() otherwise.  Use warnx() for warnings.
+
+While at it, alphabetically reorder the header includes.
+
+[ mingo: Fix capitalization in the help text while at it. ]
+
+Fixes: c6b2f240bf8d ("tools/x86: Add a kcpuid tool to show raw CPU features")
+Reported-by: Remington Brasga <rbrasga@uci.edu>
+Signed-off-by: Ahmed S. Darwish <darwi@linutronix.de>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Cc: H. Peter Anvin <hpa@zytor.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Link: https://lore.kernel.org/r/20250324142042.29010-2-darwi@linutronix.de
+Closes: https://lkml.kernel.org/r/20240926223557.2048-1-rbrasga@uci.edu
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/arch/x86/kcpuid/kcpuid.c | 47 +++++++++++++++++-----------------
+ 1 file changed, 23 insertions(+), 24 deletions(-)
+
+diff --git a/tools/arch/x86/kcpuid/kcpuid.c b/tools/arch/x86/kcpuid/kcpuid.c
+index 1b25c0a95d3f9..40a9e59c2fd56 100644
+--- a/tools/arch/x86/kcpuid/kcpuid.c
++++ b/tools/arch/x86/kcpuid/kcpuid.c
+@@ -1,11 +1,12 @@
+ // SPDX-License-Identifier: GPL-2.0
+ #define _GNU_SOURCE
+-#include <stdio.h>
++#include <err.h>
++#include <getopt.h>
+ #include <stdbool.h>
++#include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+-#include <getopt.h>
+ #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+ #define min(a, b)     (((a) < (b)) ? (a) : (b))
+@@ -145,14 +146,14 @@ static bool cpuid_store(struct cpuid_range *range, u32 f, int subleaf,
+       if (!func->leafs) {
+               func->leafs = malloc(sizeof(struct subleaf));
+               if (!func->leafs)
+-                      perror("malloc func leaf");
++                      err(EXIT_FAILURE, NULL);
+               func->nr = 1;
+       } else {
+               s = func->nr;
+               func->leafs = realloc(func->leafs, (s + 1) * sizeof(*leaf));
+               if (!func->leafs)
+-                      perror("realloc f->leafs");
++                      err(EXIT_FAILURE, NULL);
+               func->nr++;
+       }
+@@ -211,7 +212,7 @@ struct cpuid_range *setup_cpuid_range(u32 input_eax)
+       range = malloc(sizeof(struct cpuid_range));
+       if (!range)
+-              perror("malloc range");
++              err(EXIT_FAILURE, NULL);
+       if (input_eax & 0x80000000)
+               range->is_ext = true;
+@@ -220,7 +221,7 @@ struct cpuid_range *setup_cpuid_range(u32 input_eax)
+       range->funcs = malloc(sizeof(struct cpuid_func) * idx_func);
+       if (!range->funcs)
+-              perror("malloc range->funcs");
++              err(EXIT_FAILURE, NULL);
+       range->nr = idx_func;
+       memset(range->funcs, 0, sizeof(struct cpuid_func) * idx_func);
+@@ -395,8 +396,8 @@ static int parse_line(char *line)
+       return 0;
+ err_exit:
+-      printf("Warning: wrong line format:\n");
+-      printf("\tline[%d]: %s\n", flines, line);
++      warnx("Wrong line format:\n"
++            "\tline[%d]: %s", flines, line);
+       return -1;
+ }
+@@ -418,10 +419,8 @@ static void parse_text(void)
+               file = fopen("./cpuid.csv", "r");
+       }
+-      if (!file) {
+-              printf("Fail to open '%s'\n", filename);
+-              return;
+-      }
++      if (!file)
++              err(EXIT_FAILURE, "%s", filename);
+       while (1) {
+               ret = getline(&line, &len, file);
+@@ -530,7 +529,7 @@ static inline struct cpuid_func *index_to_func(u32 index)
+       func_idx = index & 0xffff;
+       if ((func_idx + 1) > (u32)range->nr) {
+-              printf("ERR: invalid input index (0x%x)\n", index);
++              warnx("Invalid input index (0x%x)", index);
+               return NULL;
+       }
+       return &range->funcs[func_idx];
+@@ -562,7 +561,7 @@ static void show_info(void)
+                               return;
+                       }
+-                      printf("ERR: invalid input subleaf (0x%x)\n", user_sub);
++                      warnx("Invalid input subleaf (0x%x)", user_sub);
+               }
+               show_func(func);
+@@ -593,15 +592,15 @@ static void setup_platform_cpuid(void)
+ static void usage(void)
+ {
+-      printf("kcpuid [-abdfhr] [-l leaf] [-s subleaf]\n"
+-              "\t-a|--all             Show both bit flags and complex bit fields info\n"
+-              "\t-b|--bitflags        Show boolean flags only\n"
+-              "\t-d|--detail          Show details of the flag/fields (default)\n"
+-              "\t-f|--flags           Specify the cpuid csv file\n"
+-              "\t-h|--help            Show usage info\n"
+-              "\t-l|--leaf=index      Specify the leaf you want to check\n"
+-              "\t-r|--raw             Show raw cpuid data\n"
+-              "\t-s|--subleaf=sub     Specify the subleaf you want to check\n"
++      warnx("kcpuid [-abdfhr] [-l leaf] [-s subleaf]\n"
++            "\t-a|--all             Show both bit flags and complex bit fields info\n"
++            "\t-b|--bitflags        Show boolean flags only\n"
++            "\t-d|--detail          Show details of the flag/fields (default)\n"
++            "\t-f|--flags           Specify the CPUID CSV file\n"
++            "\t-h|--help            Show usage info\n"
++            "\t-l|--leaf=index      Specify the leaf you want to check\n"
++            "\t-r|--raw             Show raw CPUID data\n"
++            "\t-s|--subleaf=sub     Specify the subleaf you want to check"
+       );
+ }
+@@ -652,7 +651,7 @@ static int parse_options(int argc, char *argv[])
+                       user_sub = strtoul(optarg, NULL, 0);
+                       break;
+               default:
+-                      printf("%s: Invalid option '%c'\n", argv[0], optopt);
++                      warnx("Invalid option '%c'", optopt);
+                       return -1;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/tracing-fix-error-handling-in-event_trigger_parse.patch b/queue-6.15/tracing-fix-error-handling-in-event_trigger_parse.patch
new file mode 100644 (file)
index 0000000..e4ac214
--- /dev/null
@@ -0,0 +1,55 @@
+From 7a8b27bf2214b1a48133b12ac59df50cd94354a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 May 2025 10:53:07 -0400
+Subject: tracing: Fix error handling in event_trigger_parse()
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit c5dd28e7fb4f63475b50df4f58311df92939d011 ]
+
+According to trigger_data_alloc() doc, trigger_data_free() should be
+used to free an event_trigger_data object. This fixes a mismatch introduced
+when kzalloc was replaced with trigger_data_alloc without updating
+the corresponding deallocation calls.
+
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Tom Zanussi <zanussi@kernel.org>
+Link: https://lore.kernel.org/20250507145455.944453325@goodmis.org
+Link: https://lore.kernel.org/20250318112737.4174-1-linmq006@gmail.com
+Fixes: e1f187d09e11 ("tracing: Have existing event_command.parse() implementations use helpers")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+[ SDR: Changed event_trigger_alloc/free() to trigger_data_alloc/free() ]
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/trace_events_trigger.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c
+index 9f3f76405a28c..c443ed7649a89 100644
+--- a/kernel/trace/trace_events_trigger.c
++++ b/kernel/trace/trace_events_trigger.c
+@@ -995,7 +995,7 @@ event_trigger_parse(struct event_command *cmd_ops,
+       if (remove) {
+               event_trigger_unregister(cmd_ops, file, glob+1, trigger_data);
+-              kfree(trigger_data);
++              trigger_data_free(trigger_data);
+               ret = 0;
+               goto out;
+       }
+@@ -1022,7 +1022,7 @@ event_trigger_parse(struct event_command *cmd_ops,
+  out_free:
+       event_trigger_reset_filter(cmd_ops, trigger_data);
+-      kfree(trigger_data);
++      trigger_data_free(trigger_data);
+       goto out;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/tracing-move-histogram-trigger-variables-from-stack-.patch b/queue-6.15/tracing-move-histogram-trigger-variables-from-stack-.patch
new file mode 100644 (file)
index 0000000..d81591a
--- /dev/null
@@ -0,0 +1,239 @@
+From 9e9da67240e03cad5c62cd45c8e5899a23ceaeb0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Apr 2025 12:38:51 -0400
+Subject: tracing: Move histogram trigger variables from stack to per CPU
+ structure
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit 7ab0fc61ce73040f89b12d76a8279995ec283541 ]
+
+The histogram trigger has three somewhat large arrays on the kernel stack:
+
+       unsigned long entries[HIST_STACKTRACE_DEPTH];
+       u64 var_ref_vals[TRACING_MAP_VARS_MAX];
+       char compound_key[HIST_KEY_SIZE_MAX];
+
+Checking the function event_hist_trigger() stack frame size, it currently
+uses 816 bytes for its stack frame due to these variables!
+
+Instead, allocate a per CPU structure that holds these arrays for each
+context level (normal, softirq, irq and NMI). That is, each CPU will have
+4 of these structures. This will be allocated when the first histogram
+trigger is enabled and freed when the last is disabled. When the
+histogram callback triggers, it will request this structure. The request
+will disable preemption, get the per CPU structure at the index of the
+per CPU variable, and increment that variable.
+
+The callback will use the arrays in this structure to perform its work and
+then release the structure. That in turn will simply decrement the per CPU
+index and enable preemption.
+
+Moving the variables from the kernel stack to the per CPU structure brings
+the stack frame of event_hist_trigger() down to just 112 bytes.
+
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Tom Zanussi <zanussi@kernel.org>
+Link: https://lore.kernel.org/20250407123851.74ea8d58@gandalf.local.home
+Fixes: 067fe038e70f6 ("tracing: Add variable reference handling to hist triggers")
+Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/trace_events_hist.c | 120 +++++++++++++++++++++++++++----
+ 1 file changed, 105 insertions(+), 15 deletions(-)
+
+diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
+index 1260c23cfa5fc..0ec692f80aefc 100644
+--- a/kernel/trace/trace_events_hist.c
++++ b/kernel/trace/trace_events_hist.c
+@@ -5246,17 +5246,94 @@ hist_trigger_actions(struct hist_trigger_data *hist_data,
+       }
+ }
++/*
++ * The hist_pad structure is used to save information to create
++ * a histogram from the histogram trigger. It's too big to store
++ * on the stack, so when the histogram trigger is initialized
++ * a percpu array of 4 hist_pad structures is allocated.
++ * This will cover every context from normal, softirq, irq and NMI
++ * in the very unlikely event that a tigger happens at each of
++ * these contexts and interrupts a currently active trigger.
++ */
++struct hist_pad {
++      unsigned long           entries[HIST_STACKTRACE_DEPTH];
++      u64                     var_ref_vals[TRACING_MAP_VARS_MAX];
++      char                    compound_key[HIST_KEY_SIZE_MAX];
++};
++
++static struct hist_pad __percpu *hist_pads;
++static DEFINE_PER_CPU(int, hist_pad_cnt);
++static refcount_t hist_pad_ref;
++
++/* One hist_pad for every context (normal, softirq, irq, NMI) */
++#define MAX_HIST_CNT 4
++
++static int alloc_hist_pad(void)
++{
++      lockdep_assert_held(&event_mutex);
++
++      if (refcount_read(&hist_pad_ref)) {
++              refcount_inc(&hist_pad_ref);
++              return 0;
++      }
++
++      hist_pads = __alloc_percpu(sizeof(struct hist_pad) * MAX_HIST_CNT,
++                                 __alignof__(struct hist_pad));
++      if (!hist_pads)
++              return -ENOMEM;
++
++      refcount_set(&hist_pad_ref, 1);
++      return 0;
++}
++
++static void free_hist_pad(void)
++{
++      lockdep_assert_held(&event_mutex);
++
++      if (!refcount_dec_and_test(&hist_pad_ref))
++              return;
++
++      free_percpu(hist_pads);
++      hist_pads = NULL;
++}
++
++static struct hist_pad *get_hist_pad(void)
++{
++      struct hist_pad *hist_pad;
++      int cnt;
++
++      if (WARN_ON_ONCE(!hist_pads))
++              return NULL;
++
++      preempt_disable();
++
++      hist_pad = per_cpu_ptr(hist_pads, smp_processor_id());
++
++      if (this_cpu_read(hist_pad_cnt) == MAX_HIST_CNT) {
++              preempt_enable();
++              return NULL;
++      }
++
++      cnt = this_cpu_inc_return(hist_pad_cnt) - 1;
++
++      return &hist_pad[cnt];
++}
++
++static void put_hist_pad(void)
++{
++      this_cpu_dec(hist_pad_cnt);
++      preempt_enable();
++}
++
+ static void event_hist_trigger(struct event_trigger_data *data,
+                              struct trace_buffer *buffer, void *rec,
+                              struct ring_buffer_event *rbe)
+ {
+       struct hist_trigger_data *hist_data = data->private_data;
+       bool use_compound_key = (hist_data->n_keys > 1);
+-      unsigned long entries[HIST_STACKTRACE_DEPTH];
+-      u64 var_ref_vals[TRACING_MAP_VARS_MAX];
+-      char compound_key[HIST_KEY_SIZE_MAX];
+       struct tracing_map_elt *elt = NULL;
+       struct hist_field *key_field;
++      struct hist_pad *hist_pad;
+       u64 field_contents;
+       void *key = NULL;
+       unsigned int i;
+@@ -5264,12 +5341,18 @@ static void event_hist_trigger(struct event_trigger_data *data,
+       if (unlikely(!rbe))
+               return;
+-      memset(compound_key, 0, hist_data->key_size);
++      hist_pad = get_hist_pad();
++      if (!hist_pad)
++              return;
++
++      memset(hist_pad->compound_key, 0, hist_data->key_size);
+       for_each_hist_key_field(i, hist_data) {
+               key_field = hist_data->fields[i];
+               if (key_field->flags & HIST_FIELD_FL_STACKTRACE) {
++                      unsigned long *entries = hist_pad->entries;
++
+                       memset(entries, 0, HIST_STACKTRACE_SIZE);
+                       if (key_field->field) {
+                               unsigned long *stack, n_entries;
+@@ -5293,26 +5376,31 @@ static void event_hist_trigger(struct event_trigger_data *data,
+               }
+               if (use_compound_key)
+-                      add_to_key(compound_key, key, key_field, rec);
++                      add_to_key(hist_pad->compound_key, key, key_field, rec);
+       }
+       if (use_compound_key)
+-              key = compound_key;
++              key = hist_pad->compound_key;
+       if (hist_data->n_var_refs &&
+-          !resolve_var_refs(hist_data, key, var_ref_vals, false))
+-              return;
++          !resolve_var_refs(hist_data, key, hist_pad->var_ref_vals, false))
++              goto out;
+       elt = tracing_map_insert(hist_data->map, key);
+       if (!elt)
+-              return;
++              goto out;
+-      hist_trigger_elt_update(hist_data, elt, buffer, rec, rbe, var_ref_vals);
++      hist_trigger_elt_update(hist_data, elt, buffer, rec, rbe, hist_pad->var_ref_vals);
+-      if (resolve_var_refs(hist_data, key, var_ref_vals, true))
+-              hist_trigger_actions(hist_data, elt, buffer, rec, rbe, key, var_ref_vals);
++      if (resolve_var_refs(hist_data, key, hist_pad->var_ref_vals, true)) {
++              hist_trigger_actions(hist_data, elt, buffer, rec, rbe,
++                                   key, hist_pad->var_ref_vals);
++      }
+       hist_poll_wakeup();
++
++ out:
++      put_hist_pad();
+ }
+ static void hist_trigger_stacktrace_print(struct seq_file *m,
+@@ -6157,6 +6245,9 @@ static int event_hist_trigger_init(struct event_trigger_data *data)
+ {
+       struct hist_trigger_data *hist_data = data->private_data;
++      if (alloc_hist_pad() < 0)
++              return -ENOMEM;
++
+       if (!data->ref && hist_data->attrs->name)
+               save_named_trigger(hist_data->attrs->name, data);
+@@ -6201,6 +6292,7 @@ static void event_hist_trigger_free(struct event_trigger_data *data)
+               destroy_hist_data(hist_data);
+       }
++      free_hist_pad();
+ }
+ static const struct event_trigger_ops event_hist_trigger_ops = {
+@@ -6216,9 +6308,7 @@ static int event_hist_trigger_named_init(struct event_trigger_data *data)
+       save_named_trigger(data->named_data->name, data);
+-      event_hist_trigger_init(data->named_data);
+-
+-      return 0;
++      return event_hist_trigger_init(data->named_data);
+ }
+ static void event_hist_trigger_named_free(struct event_trigger_data *data)
+-- 
+2.39.5
+
diff --git a/queue-6.15/tracing-rename-event_trigger_alloc-to-trigger_data_a.patch b/queue-6.15/tracing-rename-event_trigger_alloc-to-trigger_data_a.patch
new file mode 100644 (file)
index 0000000..fa2909b
--- /dev/null
@@ -0,0 +1,126 @@
+From 61040ea3c28e6e3eda94920332bd94d07c3df652 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 May 2025 10:53:06 -0400
+Subject: tracing: Rename event_trigger_alloc() to trigger_data_alloc()
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit f2947c4b7d0f235621c5daf78aecfbd6e22c05e5 ]
+
+The function event_trigger_alloc() creates an event_trigger_data
+descriptor and states that it needs to be freed via event_trigger_free().
+This is incorrect, it needs to be freed by trigger_data_free() as
+event_trigger_free() adds ref counting.
+
+Rename event_trigger_alloc() to trigger_data_alloc() and state that it
+needs to be freed via trigger_data_free(). This naming convention
+was introducing bugs.
+
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Tom Zanussi <zanussi@kernel.org>
+Link: https://lore.kernel.org/20250507145455.776436410@goodmis.org
+Fixes: 86599dbe2c527 ("tracing: Add helper functions to simplify event_command.parse() callback handling")
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/trace.h                |  8 +++-----
+ kernel/trace/trace_events_hist.c    |  2 +-
+ kernel/trace/trace_events_trigger.c | 16 ++++++++--------
+ 3 files changed, 12 insertions(+), 14 deletions(-)
+
+diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
+index 79be1995db44c..10ee434a9b755 100644
+--- a/kernel/trace/trace.h
++++ b/kernel/trace/trace.h
+@@ -1772,6 +1772,9 @@ extern int event_enable_register_trigger(char *glob,
+ extern void event_enable_unregister_trigger(char *glob,
+                                           struct event_trigger_data *test,
+                                           struct trace_event_file *file);
++extern struct event_trigger_data *
++trigger_data_alloc(struct event_command *cmd_ops, char *cmd, char *param,
++                 void *private_data);
+ extern void trigger_data_free(struct event_trigger_data *data);
+ extern int event_trigger_init(struct event_trigger_data *data);
+ extern int trace_event_trigger_enable_disable(struct trace_event_file *file,
+@@ -1798,11 +1801,6 @@ extern bool event_trigger_check_remove(const char *glob);
+ extern bool event_trigger_empty_param(const char *param);
+ extern int event_trigger_separate_filter(char *param_and_filter, char **param,
+                                        char **filter, bool param_required);
+-extern struct event_trigger_data *
+-event_trigger_alloc(struct event_command *cmd_ops,
+-                  char *cmd,
+-                  char *param,
+-                  void *private_data);
+ extern int event_trigger_parse_num(char *trigger,
+                                  struct event_trigger_data *trigger_data);
+ extern int event_trigger_set_filter(struct event_command *cmd_ops,
+diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
+index 0ec692f80aefc..86fd06812cdab 100644
+--- a/kernel/trace/trace_events_hist.c
++++ b/kernel/trace/trace_events_hist.c
+@@ -6795,7 +6795,7 @@ static int event_hist_trigger_parse(struct event_command *cmd_ops,
+               return PTR_ERR(hist_data);
+       }
+-      trigger_data = event_trigger_alloc(cmd_ops, cmd, param, hist_data);
++      trigger_data = trigger_data_alloc(cmd_ops, cmd, param, hist_data);
+       if (!trigger_data) {
+               ret = -ENOMEM;
+               goto out_free;
+diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c
+index 6e87ae2a1a66b..9f3f76405a28c 100644
+--- a/kernel/trace/trace_events_trigger.c
++++ b/kernel/trace/trace_events_trigger.c
+@@ -804,7 +804,7 @@ int event_trigger_separate_filter(char *param_and_filter, char **param,
+ }
+ /**
+- * event_trigger_alloc - allocate and init event_trigger_data for a trigger
++ * trigger_data_alloc - allocate and init event_trigger_data for a trigger
+  * @cmd_ops: The event_command operations for the trigger
+  * @cmd: The cmd string
+  * @param: The param string
+@@ -815,14 +815,14 @@ int event_trigger_separate_filter(char *param_and_filter, char **param,
+  * trigger_ops to assign to the event_trigger_data.  @private_data can
+  * also be passed in and associated with the event_trigger_data.
+  *
+- * Use event_trigger_free() to free an event_trigger_data object.
++ * Use trigger_data_free() to free an event_trigger_data object.
+  *
+  * Return: The trigger_data object success, NULL otherwise
+  */
+-struct event_trigger_data *event_trigger_alloc(struct event_command *cmd_ops,
+-                                             char *cmd,
+-                                             char *param,
+-                                             void *private_data)
++struct event_trigger_data *trigger_data_alloc(struct event_command *cmd_ops,
++                                            char *cmd,
++                                            char *param,
++                                            void *private_data)
+ {
+       struct event_trigger_data *trigger_data;
+       const struct event_trigger_ops *trigger_ops;
+@@ -989,7 +989,7 @@ event_trigger_parse(struct event_command *cmd_ops,
+               return ret;
+       ret = -ENOMEM;
+-      trigger_data = event_trigger_alloc(cmd_ops, cmd, param, file);
++      trigger_data = trigger_data_alloc(cmd_ops, cmd, param, file);
+       if (!trigger_data)
+               goto out;
+@@ -1793,7 +1793,7 @@ int event_enable_trigger_parse(struct event_command *cmd_ops,
+       enable_data->enable = enable;
+       enable_data->file = event_enable_file;
+-      trigger_data = event_trigger_alloc(cmd_ops, cmd, param, enable_data);
++      trigger_data = trigger_data_alloc(cmd_ops, cmd, param, enable_data);
+       if (!trigger_data) {
+               kfree(enable_data);
+               goto out;
+-- 
+2.39.5
+
diff --git a/queue-6.15/ubsan-integer-overflow-depend-on-broken-to-keep-this.patch b/queue-6.15/ubsan-integer-overflow-depend-on-broken-to-keep-this.patch
new file mode 100644 (file)
index 0000000..a6693f8
--- /dev/null
@@ -0,0 +1,45 @@
+From b2a730a9b16618185f6254554d4872fc26e760fc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 May 2025 11:26:22 -0700
+Subject: ubsan: integer-overflow: depend on BROKEN to keep this out of CI
+
+From: Kees Cook <kees@kernel.org>
+
+[ Upstream commit d6a0e0bfecccdcecb08defe75a137c7262352102 ]
+
+Depending on !COMPILE_TEST isn't sufficient to keep this feature out of
+CI because we can't stop it from being included in randconfig builds.
+This feature is still highly experimental, and is developed in lock-step
+with Clang's Overflow Behavior Types[1]. Depend on BROKEN to keep it
+from being enabled by anyone not expecting it.
+
+Link: https://discourse.llvm.org/t/rfc-v2-clang-introduce-overflowbehaviortypes-for-wrapping-and-non-wrapping-arithmetic/86507 [1]
+Reported-by: kernel test robot <oliver.sang@intel.com>
+Closes: https://lore.kernel.org/oe-lkp/202505281024.f42beaa7-lkp@intel.com
+Fixes: 557f8c582a9b ("ubsan: Reintroduce signed overflow sanitizer")
+Acked-by: Eric Biggers <ebiggers@kernel.org>
+Link: https://lore.kernel.org/r/20250528182616.work.296-kees@kernel.org
+Reviewed-by: Nathan Chancellor <nathan@kernel.org>
+Acked-by: Marco Elver <elver@google.com>
+Signed-off-by: Kees Cook <kees@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/Kconfig.ubsan | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/lib/Kconfig.ubsan b/lib/Kconfig.ubsan
+index f6ea0c5b5da39..96cd896684676 100644
+--- a/lib/Kconfig.ubsan
++++ b/lib/Kconfig.ubsan
+@@ -118,6 +118,8 @@ config UBSAN_UNREACHABLE
+ config UBSAN_INTEGER_WRAP
+       bool "Perform checking for integer arithmetic wrap-around"
++      # This is very experimental so drop the next line if you really want it
++      depends on BROKEN
+       depends on !COMPILE_TEST
+       depends on $(cc-option,-fsanitize-undefined-ignore-overflow-pattern=all)
+       depends on $(cc-option,-fsanitize=signed-integer-overflow)
+-- 
+2.39.5
+
diff --git a/queue-6.15/udp-properly-deal-with-xfrm-encap-and-addrform.patch b/queue-6.15/udp-properly-deal-with-xfrm-encap-and-addrform.patch
new file mode 100644 (file)
index 0000000..3978af2
--- /dev/null
@@ -0,0 +1,190 @@
+From 7379d064b4e3a412604ed33592bdaee2468b6c95 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Apr 2025 22:00:56 +0200
+Subject: udp: properly deal with xfrm encap and ADDRFORM
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+[ Upstream commit c26c192c3d486a2a7d83d254bae294c2f8f50abf ]
+
+UDP GRO accounting assumes that the GRO receive callback is always
+set when the UDP tunnel is enabled, but syzkaller proved otherwise,
+leading tot the following splat:
+
+WARNING: CPU: 0 PID: 5837 at net/ipv4/udp_offload.c:123 udp_tunnel_update_gro_rcv+0x28d/0x4c0 net/ipv4/udp_offload.c:123
+Modules linked in:
+CPU: 0 UID: 0 PID: 5837 Comm: syz-executor850 Not tainted 6.14.0-syzkaller-13320-g420aabef3ab5 #0 PREEMPT(full)
+Hardware name: Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2025
+RIP: 0010:udp_tunnel_update_gro_rcv+0x28d/0x4c0 net/ipv4/udp_offload.c:123
+Code: 00 00 e8 c6 5a 2f f7 48 c1 e5 04 48 8d b5 20 53 c7 9a ba 10
+      00 00 00 4c 89 ff e8 ce 87 99 f7 e9 ce 00 00 00 e8 a4 5a 2f
+      f7 90 <0f> 0b 90 e9 de fd ff ff bf 01 00 00 00 89 ee e8 cf
+      5e 2f f7 85 ed
+RSP: 0018:ffffc90003effa88 EFLAGS: 00010293
+RAX: ffffffff8a93fc9c RBX: 0000000000000000 RCX: ffff8880306f9e00
+RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
+RBP: 0000000000000000 R08: ffffffff8a93fabe R09: 1ffffffff20bfb2e
+R10: dffffc0000000000 R11: fffffbfff20bfb2f R12: ffff88814ef21738
+R13: dffffc0000000000 R14: ffff88814ef21778 R15: 1ffff11029de42ef
+FS:  0000000000000000(0000) GS:ffff888124f96000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00007f04eec760d0 CR3: 000000000eb38000 CR4: 00000000003526f0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+Call Trace:
+ <TASK>
+ udp_tunnel_cleanup_gro include/net/udp_tunnel.h:205 [inline]
+ udpv6_destroy_sock+0x212/0x270 net/ipv6/udp.c:1829
+ sk_common_release+0x71/0x2e0 net/core/sock.c:3896
+ inet_release+0x17d/0x200 net/ipv4/af_inet.c:435
+ __sock_release net/socket.c:647 [inline]
+ sock_close+0xbc/0x240 net/socket.c:1391
+ __fput+0x3e9/0x9f0 fs/file_table.c:465
+ task_work_run+0x251/0x310 kernel/task_work.c:227
+ exit_task_work include/linux/task_work.h:40 [inline]
+ do_exit+0xa11/0x27f0 kernel/exit.c:953
+ do_group_exit+0x207/0x2c0 kernel/exit.c:1102
+ __do_sys_exit_group kernel/exit.c:1113 [inline]
+ __se_sys_exit_group kernel/exit.c:1111 [inline]
+ __x64_sys_exit_group+0x3f/0x40 kernel/exit.c:1111
+ x64_sys_call+0x26c3/0x26d0 arch/x86/include/generated/asm/syscalls_64.h:232
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xf3/0x230 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+RIP: 0033:0x7f04eebfac79
+Code: Unable to access opcode bytes at 0x7f04eebfac4f.
+RSP: 002b:00007fffdcaa34a8 EFLAGS: 00000246 ORIG_RAX: 00000000000000e7
+RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f04eebfac79
+RDX: 000000000000003c RSI: 00000000000000e7 RDI: 0000000000000000
+RBP: 00007f04eec75270 R08: ffffffffffffffb8 R09: 00007fffdcaa36c8
+R10: 0000200000000000 R11: 0000000000000246 R12: 00007f04eec75270
+R13: 0000000000000000 R14: 00007f04eec75cc0 R15: 00007f04eebcca70
+
+Address the issue moving the accounting hook into
+setup_udp_tunnel_sock() and set_xfrm_gro_udp_encap_rcv(), where
+the GRO callback is actually set.
+
+set_xfrm_gro_udp_encap_rcv() is prone to races with IPV6_ADDRFORM,
+run the relevant setsockopt under the socket lock to ensure using
+consistent values of sk_family and up->encap_type.
+
+Refactor the GRO callback selection code, to make it clear that
+the function pointer is always initialized.
+
+Reported-by: syzbot+8c469a2260132cd095c1@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=8c469a2260132cd095c1
+Fixes: 172bf009c18d ("xfrm: Support GRO for IPv4 ESP in UDP encapsulation")
+Fixes: 5d7f5b2f6b935 ("udp_tunnel: use static call for GRO hooks when possible")
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
+Link: https://patch.msgid.link/92bcdb6899145a9a387c8fa9e3ca656642a43634.1744228733.git.pabeni@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/udp_tunnel.h   |  1 -
+ net/ipv4/udp.c             | 31 ++++++++++++++++++++++++++-----
+ net/ipv4/udp_tunnel_core.c |  2 ++
+ 3 files changed, 28 insertions(+), 6 deletions(-)
+
+diff --git a/include/net/udp_tunnel.h b/include/net/udp_tunnel.h
+index 288f06f23a804..2df3b8344eb52 100644
+--- a/include/net/udp_tunnel.h
++++ b/include/net/udp_tunnel.h
+@@ -215,7 +215,6 @@ static inline void udp_tunnel_encap_enable(struct sock *sk)
+       if (READ_ONCE(sk->sk_family) == PF_INET6)
+               ipv6_stub->udpv6_encap_enable();
+ #endif
+-      udp_tunnel_update_gro_rcv(sk, true);
+       udp_encap_enable();
+ }
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index 04cd3353f1d46..af943b905804a 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -2904,15 +2904,33 @@ void udp_destroy_sock(struct sock *sk)
+       }
+ }
++typedef struct sk_buff *(*udp_gro_receive_t)(struct sock *sk,
++                                           struct list_head *head,
++                                           struct sk_buff *skb);
++
+ static void set_xfrm_gro_udp_encap_rcv(__u16 encap_type, unsigned short family,
+                                      struct sock *sk)
+ {
+ #ifdef CONFIG_XFRM
++      udp_gro_receive_t new_gro_receive;
++
+       if (udp_test_bit(GRO_ENABLED, sk) && encap_type == UDP_ENCAP_ESPINUDP) {
+-              if (family == AF_INET)
+-                      WRITE_ONCE(udp_sk(sk)->gro_receive, xfrm4_gro_udp_encap_rcv);
+-              else if (IS_ENABLED(CONFIG_IPV6) && family == AF_INET6)
+-                      WRITE_ONCE(udp_sk(sk)->gro_receive, ipv6_stub->xfrm6_gro_udp_encap_rcv);
++              if (IS_ENABLED(CONFIG_IPV6) && family == AF_INET6)
++                      new_gro_receive = ipv6_stub->xfrm6_gro_udp_encap_rcv;
++              else
++                      new_gro_receive = xfrm4_gro_udp_encap_rcv;
++
++              if (udp_sk(sk)->gro_receive != new_gro_receive) {
++                      /*
++                       * With IPV6_ADDRFORM the gro callback could change
++                       * after being set, unregister the old one, if valid.
++                       */
++                      if (udp_sk(sk)->gro_receive)
++                              udp_tunnel_update_gro_rcv(sk, false);
++
++                      WRITE_ONCE(udp_sk(sk)->gro_receive, new_gro_receive);
++                      udp_tunnel_update_gro_rcv(sk, true);
++              }
+       }
+ #endif
+ }
+@@ -2962,6 +2980,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
+               break;
+       case UDP_ENCAP:
++              sockopt_lock_sock(sk);
+               switch (val) {
+               case 0:
+ #ifdef CONFIG_XFRM
+@@ -2985,6 +3004,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
+                       err = -ENOPROTOOPT;
+                       break;
+               }
++              sockopt_release_sock(sk);
+               break;
+       case UDP_NO_CHECK6_TX:
+@@ -3002,13 +3022,14 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
+               break;
+       case UDP_GRO:
+-
++              sockopt_lock_sock(sk);
+               /* when enabling GRO, accept the related GSO packet type */
+               if (valbool)
+                       udp_tunnel_encap_enable(sk);
+               udp_assign_bit(GRO_ENABLED, sk, valbool);
+               udp_assign_bit(ACCEPT_L4, sk, valbool);
+               set_xfrm_gro_udp_encap_rcv(up->encap_type, sk->sk_family, sk);
++              sockopt_release_sock(sk);
+               break;
+       /*
+diff --git a/net/ipv4/udp_tunnel_core.c b/net/ipv4/udp_tunnel_core.c
+index 3d1214e6df0ea..2326548997d3f 100644
+--- a/net/ipv4/udp_tunnel_core.c
++++ b/net/ipv4/udp_tunnel_core.c
+@@ -90,6 +90,8 @@ void setup_udp_tunnel_sock(struct net *net, struct socket *sock,
+       udp_tunnel_encap_enable(sk);
++      udp_tunnel_update_gro_rcv(sk, true);
++
+       if (!sk->sk_dport && !sk->sk_bound_dev_if && sk_saddr_any(sk) &&
+           sk->sk_kern_sock)
+               udp_tunnel_update_gro_lookup(net, sk, true);
+-- 
+2.39.5
+
diff --git a/queue-6.15/udp_tunnel-create-a-fastpath-gro-lookup.patch b/queue-6.15/udp_tunnel-create-a-fastpath-gro-lookup.patch
new file mode 100644 (file)
index 0000000..8e2a770
--- /dev/null
@@ -0,0 +1,319 @@
+From 57f99d8615549a5172faf93150703db31f61f6eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Apr 2025 17:45:41 +0200
+Subject: udp_tunnel: create a fastpath GRO lookup.
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+[ Upstream commit a36283e2b683f172aa1760c77325e50b16c0f792 ]
+
+Most UDP tunnels bind a socket to a local port, with ANY address, no
+peer and no interface index specified.
+Additionally it's quite common to have a single tunnel device per
+namespace.
+
+Track in each namespace the UDP tunnel socket respecting the above.
+When only a single one is present, store a reference in the netns.
+
+When such reference is not NULL, UDP tunnel GRO lookup just need to
+match the incoming packet destination port vs the socket local port.
+
+The tunnel socket never sets the reuse[port] flag[s]. When bound to no
+address and interface, no other socket can exist in the same netns
+matching the specified local port.
+
+Matching packets with non-local destination addresses will be
+aggregated, and eventually segmented as needed - no behavior changes
+intended.
+
+Restrict the optimization to kernel sockets only: it covers all the
+relevant use-cases, and user-space owned sockets could be disconnected
+and rebound after setup_udp_tunnel_sock(), breaking the uniqueness
+assumption
+
+Note that the UDP tunnel socket reference is stored into struct
+netns_ipv4 for both IPv4 and IPv6 tunnels. That is intentional to keep
+all the fastpath-related netns fields in the same struct and allow
+cacheline-based optimization. Currently both the IPv4 and IPv6 socket
+pointer share the same cacheline as the `udp_table` field.
+
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/41d16bc8d1257d567f9344c445b4ae0b4a91ede4.1744040675.git.pabeni@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: c26c192c3d48 ("udp: properly deal with xfrm encap and ADDRFORM")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/udp.h        | 16 ++++++++++++++++
+ include/net/netns/ipv4.h   | 11 +++++++++++
+ include/net/udp.h          |  1 +
+ include/net/udp_tunnel.h   | 12 ++++++++++++
+ net/ipv4/udp.c             | 13 ++++++++++++-
+ net/ipv4/udp_offload.c     | 37 +++++++++++++++++++++++++++++++++++++
+ net/ipv4/udp_tunnel_core.c | 13 +++++++++++++
+ net/ipv6/udp.c             |  2 ++
+ net/ipv6/udp_offload.c     |  5 +++++
+ 9 files changed, 109 insertions(+), 1 deletion(-)
+
+diff --git a/include/linux/udp.h b/include/linux/udp.h
+index 0807e21cfec95..895240177f4f4 100644
+--- a/include/linux/udp.h
++++ b/include/linux/udp.h
+@@ -101,6 +101,13 @@ struct udp_sock {
+       /* Cache friendly copy of sk->sk_peek_off >= 0 */
+       bool            peeking_with_offset;
++
++      /*
++       * Accounting for the tunnel GRO fastpath.
++       * Unprotected by compilers guard, as it uses space available in
++       * the last UDP socket cacheline.
++       */
++      struct hlist_node       tunnel_list;
+ };
+ #define udp_test_bit(nr, sk)                  \
+@@ -219,4 +226,13 @@ static inline void udp_allow_gso(struct sock *sk)
+ #define IS_UDPLITE(__sk) (__sk->sk_protocol == IPPROTO_UDPLITE)
++static inline struct sock *udp_tunnel_sk(const struct net *net, bool is_ipv6)
++{
++#if IS_ENABLED(CONFIG_NET_UDP_TUNNEL)
++      return rcu_dereference(net->ipv4.udp_tunnel_gro[is_ipv6].sk);
++#else
++      return NULL;
++#endif
++}
++
+ #endif        /* _LINUX_UDP_H */
+diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
+index 650b2dc9199f4..6373e3f17da84 100644
+--- a/include/net/netns/ipv4.h
++++ b/include/net/netns/ipv4.h
+@@ -47,6 +47,11 @@ struct sysctl_fib_multipath_hash_seed {
+ };
+ #endif
++struct udp_tunnel_gro {
++      struct sock __rcu *sk;
++      struct hlist_head list;
++};
++
+ struct netns_ipv4 {
+       /* Cacheline organization can be found documented in
+        * Documentation/networking/net_cachelines/netns_ipv4_sysctl.rst.
+@@ -85,6 +90,11 @@ struct netns_ipv4 {
+       struct inet_timewait_death_row tcp_death_row;
+       struct udp_table *udp_table;
++#if IS_ENABLED(CONFIG_NET_UDP_TUNNEL)
++      /* Not in a pernet subsys because need to be available at GRO stage */
++      struct udp_tunnel_gro udp_tunnel_gro[2];
++#endif
++
+ #ifdef CONFIG_SYSCTL
+       struct ctl_table_header *forw_hdr;
+       struct ctl_table_header *frags_hdr;
+@@ -277,4 +287,5 @@ struct netns_ipv4 {
+       struct hlist_head       *inet_addr_lst;
+       struct delayed_work     addr_chk_work;
+ };
++
+ #endif
+diff --git a/include/net/udp.h b/include/net/udp.h
+index 6e89520e100dc..a772510b2aa58 100644
+--- a/include/net/udp.h
++++ b/include/net/udp.h
+@@ -290,6 +290,7 @@ static inline void udp_lib_init_sock(struct sock *sk)
+       struct udp_sock *up = udp_sk(sk);
+       skb_queue_head_init(&up->reader_queue);
++      INIT_HLIST_NODE(&up->tunnel_list);
+       up->forward_threshold = sk->sk_rcvbuf >> 2;
+       set_bit(SOCK_CUSTOM_SOCKOPT, &sk->sk_socket->flags);
+ }
+diff --git a/include/net/udp_tunnel.h b/include/net/udp_tunnel.h
+index a93dc51f6323e..1bb2b852e90eb 100644
+--- a/include/net/udp_tunnel.h
++++ b/include/net/udp_tunnel.h
+@@ -191,6 +191,18 @@ static inline int udp_tunnel_handle_offloads(struct sk_buff *skb, bool udp_csum)
+ }
+ #endif
++#if IS_ENABLED(CONFIG_NET_UDP_TUNNEL)
++void udp_tunnel_update_gro_lookup(struct net *net, struct sock *sk, bool add);
++#else
++static inline void udp_tunnel_update_gro_lookup(struct net *net,
++                                              struct sock *sk, bool add) {}
++#endif
++
++static inline void udp_tunnel_cleanup_gro(struct sock *sk)
++{
++      udp_tunnel_update_gro_lookup(sock_net(sk), sk, false);
++}
++
+ static inline void udp_tunnel_encap_enable(struct sock *sk)
+ {
+       if (udp_test_and_set_bit(ENCAP_ENABLED, sk))
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index 2742cc7602bb5..04cd3353f1d46 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -2897,8 +2897,10 @@ void udp_destroy_sock(struct sock *sk)
+                       if (encap_destroy)
+                               encap_destroy(sk);
+               }
+-              if (udp_test_bit(ENCAP_ENABLED, sk))
++              if (udp_test_bit(ENCAP_ENABLED, sk)) {
+                       static_branch_dec(&udp_encap_needed_key);
++                      udp_tunnel_cleanup_gro(sk);
++              }
+       }
+ }
+@@ -3810,6 +3812,15 @@ static void __net_init udp_set_table(struct net *net)
+ static int __net_init udp_pernet_init(struct net *net)
+ {
++#if IS_ENABLED(CONFIG_NET_UDP_TUNNEL)
++      int i;
++
++      /* No tunnel is configured */
++      for (i = 0; i < ARRAY_SIZE(net->ipv4.udp_tunnel_gro); ++i) {
++              INIT_HLIST_HEAD(&net->ipv4.udp_tunnel_gro[i].list);
++              RCU_INIT_POINTER(net->ipv4.udp_tunnel_gro[i].sk, NULL);
++      }
++#endif
+       udp_sysctl_init(net);
+       udp_set_table(net);
+diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
+index 9a8142ccbabe4..67641945ba3a3 100644
+--- a/net/ipv4/udp_offload.c
++++ b/net/ipv4/udp_offload.c
+@@ -12,6 +12,38 @@
+ #include <net/udp.h>
+ #include <net/protocol.h>
+ #include <net/inet_common.h>
++#include <net/udp_tunnel.h>
++
++#if IS_ENABLED(CONFIG_NET_UDP_TUNNEL)
++static DEFINE_SPINLOCK(udp_tunnel_gro_lock);
++
++void udp_tunnel_update_gro_lookup(struct net *net, struct sock *sk, bool add)
++{
++      bool is_ipv6 = sk->sk_family == AF_INET6;
++      struct udp_sock *tup, *up = udp_sk(sk);
++      struct udp_tunnel_gro *udp_tunnel_gro;
++
++      spin_lock(&udp_tunnel_gro_lock);
++      udp_tunnel_gro = &net->ipv4.udp_tunnel_gro[is_ipv6];
++      if (add)
++              hlist_add_head(&up->tunnel_list, &udp_tunnel_gro->list);
++      else if (up->tunnel_list.pprev)
++              hlist_del_init(&up->tunnel_list);
++
++      if (udp_tunnel_gro->list.first &&
++          !udp_tunnel_gro->list.first->next) {
++              tup = hlist_entry(udp_tunnel_gro->list.first, struct udp_sock,
++                                tunnel_list);
++
++              rcu_assign_pointer(udp_tunnel_gro->sk, (struct sock *)tup);
++      } else {
++              RCU_INIT_POINTER(udp_tunnel_gro->sk, NULL);
++      }
++
++      spin_unlock(&udp_tunnel_gro_lock);
++}
++EXPORT_SYMBOL_GPL(udp_tunnel_update_gro_lookup);
++#endif
+ static struct sk_buff *__skb_udp_tunnel_segment(struct sk_buff *skb,
+       netdev_features_t features,
+@@ -694,8 +726,13 @@ static struct sock *udp4_gro_lookup_skb(struct sk_buff *skb, __be16 sport,
+ {
+       const struct iphdr *iph = skb_gro_network_header(skb);
+       struct net *net = dev_net_rcu(skb->dev);
++      struct sock *sk;
+       int iif, sdif;
++      sk = udp_tunnel_sk(net, false);
++      if (sk && dport == htons(sk->sk_num))
++              return sk;
++
+       inet_get_iif_sdif(skb, &iif, &sdif);
+       return __udp4_lib_lookup(net, iph->saddr, sport,
+diff --git a/net/ipv4/udp_tunnel_core.c b/net/ipv4/udp_tunnel_core.c
+index 619a53eb672da..3d1214e6df0ea 100644
+--- a/net/ipv4/udp_tunnel_core.c
++++ b/net/ipv4/udp_tunnel_core.c
+@@ -58,6 +58,15 @@ int udp_sock_create4(struct net *net, struct udp_port_cfg *cfg,
+ }
+ EXPORT_SYMBOL(udp_sock_create4);
++static bool sk_saddr_any(struct sock *sk)
++{
++#if IS_ENABLED(CONFIG_IPV6)
++      return ipv6_addr_any(&sk->sk_v6_rcv_saddr);
++#else
++      return !sk->sk_rcv_saddr;
++#endif
++}
++
+ void setup_udp_tunnel_sock(struct net *net, struct socket *sock,
+                          struct udp_tunnel_sock_cfg *cfg)
+ {
+@@ -80,6 +89,10 @@ void setup_udp_tunnel_sock(struct net *net, struct socket *sock,
+       udp_sk(sk)->gro_complete = cfg->gro_complete;
+       udp_tunnel_encap_enable(sk);
++
++      if (!sk->sk_dport && !sk->sk_bound_dev_if && sk_saddr_any(sk) &&
++          sk->sk_kern_sock)
++              udp_tunnel_update_gro_lookup(net, sk, true);
+ }
+ EXPORT_SYMBOL_GPL(setup_udp_tunnel_sock);
+diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
+index 024458ef163c9..7317f8e053f1c 100644
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -46,6 +46,7 @@
+ #include <net/tcp_states.h>
+ #include <net/ip6_checksum.h>
+ #include <net/ip6_tunnel.h>
++#include <net/udp_tunnel.h>
+ #include <net/xfrm.h>
+ #include <net/inet_hashtables.h>
+ #include <net/inet6_hashtables.h>
+@@ -1825,6 +1826,7 @@ void udpv6_destroy_sock(struct sock *sk)
+               if (udp_test_bit(ENCAP_ENABLED, sk)) {
+                       static_branch_dec(&udpv6_encap_needed_key);
+                       udp_encap_disable();
++                      udp_tunnel_cleanup_gro(sk);
+               }
+       }
+ }
+diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c
+index 404212dfc99ab..d8445ac1b2e43 100644
+--- a/net/ipv6/udp_offload.c
++++ b/net/ipv6/udp_offload.c
+@@ -118,8 +118,13 @@ static struct sock *udp6_gro_lookup_skb(struct sk_buff *skb, __be16 sport,
+ {
+       const struct ipv6hdr *iph = skb_gro_network_header(skb);
+       struct net *net = dev_net_rcu(skb->dev);
++      struct sock *sk;
+       int iif, sdif;
++      sk = udp_tunnel_sk(net, true);
++      if (sk && dport == htons(sk->sk_num))
++              return sk;
++
+       inet6_get_iif_sdif(skb, &iif, &sdif);
+       return __udp6_lib_lookup(net, &iph->saddr, sport,
+-- 
+2.39.5
+
diff --git a/queue-6.15/udp_tunnel-use-static-call-for-gro-hooks-when-possib.patch b/queue-6.15/udp_tunnel-use-static-call-for-gro-hooks-when-possib.patch
new file mode 100644 (file)
index 0000000..a981a37
--- /dev/null
@@ -0,0 +1,232 @@
+From ad8d1ce2b68078680a685515600fbafbb35fa691 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Apr 2025 17:45:42 +0200
+Subject: udp_tunnel: use static call for GRO hooks when possible
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+[ Upstream commit 5d7f5b2f6b935517ee5fd8058dc32342a5cba3e1 ]
+
+It's quite common to have a single UDP tunnel type active in the
+whole system. In such a case we can replace the indirect call for
+the UDP tunnel GRO callback with a static call.
+
+Add the related accounting in the control path and switch to static
+call when possible. To keep the code simple use a static array for
+the registered tunnel types, and size such array based on the kernel
+config.
+
+Note that there are valid kernel configurations leading to
+UDP_MAX_TUNNEL_TYPES == 0 even with IS_ENABLED(CONFIG_NET_UDP_TUNNEL),
+Explicitly skip the accounting in such a case, to avoid compile warning
+when accessing "udp_tunnel_gro_types".
+
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/53d156cdfddcc9678449e873cc83e68fa1582653.1744040675.git.pabeni@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: c26c192c3d48 ("udp: properly deal with xfrm encap and ADDRFORM")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/udp_tunnel.h |   4 ++
+ net/ipv4/udp_offload.c   | 135 ++++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 138 insertions(+), 1 deletion(-)
+
+diff --git a/include/net/udp_tunnel.h b/include/net/udp_tunnel.h
+index 1bb2b852e90eb..288f06f23a804 100644
+--- a/include/net/udp_tunnel.h
++++ b/include/net/udp_tunnel.h
+@@ -193,13 +193,16 @@ static inline int udp_tunnel_handle_offloads(struct sk_buff *skb, bool udp_csum)
+ #if IS_ENABLED(CONFIG_NET_UDP_TUNNEL)
+ void udp_tunnel_update_gro_lookup(struct net *net, struct sock *sk, bool add);
++void udp_tunnel_update_gro_rcv(struct sock *sk, bool add);
+ #else
+ static inline void udp_tunnel_update_gro_lookup(struct net *net,
+                                               struct sock *sk, bool add) {}
++static inline void udp_tunnel_update_gro_rcv(struct sock *sk, bool add) {}
+ #endif
+ static inline void udp_tunnel_cleanup_gro(struct sock *sk)
+ {
++      udp_tunnel_update_gro_rcv(sk, false);
+       udp_tunnel_update_gro_lookup(sock_net(sk), sk, false);
+ }
+@@ -212,6 +215,7 @@ static inline void udp_tunnel_encap_enable(struct sock *sk)
+       if (READ_ONCE(sk->sk_family) == PF_INET6)
+               ipv6_stub->udpv6_encap_enable();
+ #endif
++      udp_tunnel_update_gro_rcv(sk, true);
+       udp_encap_enable();
+ }
+diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
+index 67641945ba3a3..9c775f8aa4385 100644
+--- a/net/ipv4/udp_offload.c
++++ b/net/ipv4/udp_offload.c
+@@ -15,6 +15,38 @@
+ #include <net/udp_tunnel.h>
+ #if IS_ENABLED(CONFIG_NET_UDP_TUNNEL)
++
++/*
++ * Dummy GRO tunnel callback, exists mainly to avoid dangling/NULL
++ * values for the udp tunnel static call.
++ */
++static struct sk_buff *dummy_gro_rcv(struct sock *sk,
++                                   struct list_head *head,
++                                   struct sk_buff *skb)
++{
++      NAPI_GRO_CB(skb)->flush = 1;
++      return NULL;
++}
++
++typedef struct sk_buff *(*udp_tunnel_gro_rcv_t)(struct sock *sk,
++                                              struct list_head *head,
++                                              struct sk_buff *skb);
++
++struct udp_tunnel_type_entry {
++      udp_tunnel_gro_rcv_t gro_receive;
++      refcount_t count;
++};
++
++#define UDP_MAX_TUNNEL_TYPES (IS_ENABLED(CONFIG_GENEVE) + \
++                            IS_ENABLED(CONFIG_VXLAN) * 2 + \
++                            IS_ENABLED(CONFIG_NET_FOU) * 2 + \
++                            IS_ENABLED(CONFIG_XFRM) * 2)
++
++DEFINE_STATIC_CALL(udp_tunnel_gro_rcv, dummy_gro_rcv);
++static DEFINE_STATIC_KEY_FALSE(udp_tunnel_static_call);
++static struct mutex udp_tunnel_gro_type_lock;
++static struct udp_tunnel_type_entry udp_tunnel_gro_types[UDP_MAX_TUNNEL_TYPES];
++static unsigned int udp_tunnel_gro_type_nr;
+ static DEFINE_SPINLOCK(udp_tunnel_gro_lock);
+ void udp_tunnel_update_gro_lookup(struct net *net, struct sock *sk, bool add)
+@@ -43,6 +75,105 @@ void udp_tunnel_update_gro_lookup(struct net *net, struct sock *sk, bool add)
+       spin_unlock(&udp_tunnel_gro_lock);
+ }
+ EXPORT_SYMBOL_GPL(udp_tunnel_update_gro_lookup);
++
++void udp_tunnel_update_gro_rcv(struct sock *sk, bool add)
++{
++      struct udp_tunnel_type_entry *cur = NULL;
++      struct udp_sock *up = udp_sk(sk);
++      int i, old_gro_type_nr;
++
++      if (!UDP_MAX_TUNNEL_TYPES || !up->gro_receive)
++              return;
++
++      mutex_lock(&udp_tunnel_gro_type_lock);
++
++      /* Check if the static call is permanently disabled. */
++      if (udp_tunnel_gro_type_nr > UDP_MAX_TUNNEL_TYPES)
++              goto out;
++
++      for (i = 0; i < udp_tunnel_gro_type_nr; i++)
++              if (udp_tunnel_gro_types[i].gro_receive == up->gro_receive)
++                      cur = &udp_tunnel_gro_types[i];
++
++      old_gro_type_nr = udp_tunnel_gro_type_nr;
++      if (add) {
++              /*
++               * Update the matching entry, if found, or add a new one
++               * if needed
++               */
++              if (cur) {
++                      refcount_inc(&cur->count);
++                      goto out;
++              }
++
++              if (unlikely(udp_tunnel_gro_type_nr == UDP_MAX_TUNNEL_TYPES)) {
++                      pr_err_once("Too many UDP tunnel types, please increase UDP_MAX_TUNNEL_TYPES\n");
++                      /* Ensure static call will never be enabled */
++                      udp_tunnel_gro_type_nr = UDP_MAX_TUNNEL_TYPES + 1;
++              } else {
++                      cur = &udp_tunnel_gro_types[udp_tunnel_gro_type_nr++];
++                      refcount_set(&cur->count, 1);
++                      cur->gro_receive = up->gro_receive;
++              }
++      } else {
++              /*
++               * The stack cleanups only successfully added tunnel, the
++               * lookup on removal should never fail.
++               */
++              if (WARN_ON_ONCE(!cur))
++                      goto out;
++
++              if (!refcount_dec_and_test(&cur->count))
++                      goto out;
++
++              /* Avoid gaps, so that the enable tunnel has always id 0 */
++              *cur = udp_tunnel_gro_types[--udp_tunnel_gro_type_nr];
++      }
++
++      if (udp_tunnel_gro_type_nr == 1) {
++              static_call_update(udp_tunnel_gro_rcv,
++                                 udp_tunnel_gro_types[0].gro_receive);
++              static_branch_enable(&udp_tunnel_static_call);
++      } else if (old_gro_type_nr == 1) {
++              static_branch_disable(&udp_tunnel_static_call);
++              static_call_update(udp_tunnel_gro_rcv, dummy_gro_rcv);
++      }
++
++out:
++      mutex_unlock(&udp_tunnel_gro_type_lock);
++}
++EXPORT_SYMBOL_GPL(udp_tunnel_update_gro_rcv);
++
++static void udp_tunnel_gro_init(void)
++{
++      mutex_init(&udp_tunnel_gro_type_lock);
++}
++
++static struct sk_buff *udp_tunnel_gro_rcv(struct sock *sk,
++                                        struct list_head *head,
++                                        struct sk_buff *skb)
++{
++      if (static_branch_likely(&udp_tunnel_static_call)) {
++              if (unlikely(gro_recursion_inc_test(skb))) {
++                      NAPI_GRO_CB(skb)->flush |= 1;
++                      return NULL;
++              }
++              return static_call(udp_tunnel_gro_rcv)(sk, head, skb);
++      }
++      return call_gro_receive_sk(udp_sk(sk)->gro_receive, sk, head, skb);
++}
++
++#else
++
++static void udp_tunnel_gro_init(void) {}
++
++static struct sk_buff *udp_tunnel_gro_rcv(struct sock *sk,
++                                        struct list_head *head,
++                                        struct sk_buff *skb)
++{
++      return call_gro_receive_sk(udp_sk(sk)->gro_receive, sk, head, skb);
++}
++
+ #endif
+ static struct sk_buff *__skb_udp_tunnel_segment(struct sk_buff *skb,
+@@ -713,7 +844,7 @@ struct sk_buff *udp_gro_receive(struct list_head *head, struct sk_buff *skb,
+       skb_gro_pull(skb, sizeof(struct udphdr)); /* pull encapsulating udp header */
+       skb_gro_postpull_rcsum(skb, uh, sizeof(struct udphdr));
+-      pp = call_gro_receive_sk(udp_sk(sk)->gro_receive, sk, head, skb);
++      pp = udp_tunnel_gro_rcv(sk, head, skb);
+ out:
+       skb_gro_flush_final(skb, pp, flush);
+@@ -863,5 +994,7 @@ int __init udpv4_offload_init(void)
+                       .gro_complete = udp4_gro_complete,
+               },
+       };
++
++      udp_tunnel_gro_init();
+       return inet_add_offload(&net_hotdata.udpv4_offload, IPPROTO_UDP);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/um-fix-tgkill-compile-error-on-old-host-oses.patch b/queue-6.15/um-fix-tgkill-compile-error-on-old-host-oses.patch
new file mode 100644 (file)
index 0000000..e763788
--- /dev/null
@@ -0,0 +1,66 @@
+From 3fa7fe3302712161d1eca1855a5c95bf9ffb4748 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 May 2025 23:12:22 +0800
+Subject: um: Fix tgkill compile error on old host OSes
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Yongting Lin <linyongting@gmail.com>
+
+[ Upstream commit fd054188999ff19746cc09f4e0f196a113964db9 ]
+
+tgkill is a quite old syscall since kernel 2.5.75, but unfortunately glibc
+doesn't support it before 2.30. Thus some systems fail to compile the
+latest UserMode Linux.
+
+Here is the compile error I encountered when I tried to compile UML in
+my system shipped with glibc-2.28.
+
+    CALL    scripts/checksyscalls.sh
+    CC      arch/um/os-Linux/sigio.o
+  In file included from arch/um/os-Linux/sigio.c:17:
+  arch/um/os-Linux/sigio.c: In function ‘write_sigio_thread’:
+  arch/um/os-Linux/sigio.c:49:19: error: implicit declaration of function ‘tgkill’; did you mean ‘kill’? [-Werror=implicit-function-declaration]
+     CATCH_EINTR(r = tgkill(pid, pid, SIGIO));
+                     ^~~~~~
+  ./arch/um/include/shared/os.h:21:48: note: in definition of macro ‘CATCH_EINTR’
+  #define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR))
+                                                ^~~~
+  cc1: some warnings being treated as errors
+
+Fix it by Replacing glibc call with raw syscall.
+
+Fixes: 33c9da5dfb18 ("um: Rewrite the sigio workaround based on epoll and tgkill")
+Signed-off-by: Yongting Lin <linyongting@gmail.com>
+Link: https://patch.msgid.link/20250527151222.40371-1-linyongting@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/um/os-Linux/sigio.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c
+index a05a6ecee7561..6de145f8fe3d9 100644
+--- a/arch/um/os-Linux/sigio.c
++++ b/arch/um/os-Linux/sigio.c
+@@ -12,6 +12,7 @@
+ #include <signal.h>
+ #include <string.h>
+ #include <sys/epoll.h>
++#include <asm/unistd.h>
+ #include <kern_util.h>
+ #include <init.h>
+ #include <os.h>
+@@ -46,7 +47,7 @@ static void *write_sigio_thread(void *unused)
+                              __func__, errno);
+               }
+-              CATCH_EINTR(r = tgkill(pid, pid, SIGIO));
++              CATCH_EINTR(r = syscall(__NR_tgkill, pid, pid, SIGIO));
+               if (r < 0)
+                       printk(UM_KERN_ERR "%s: tgkill failed, errno = %d\n",
+                              __func__, errno);
+-- 
+2.39.5
+
diff --git a/queue-6.15/usb-acpi-prevent-null-pointer-dereference-in-usb_acp.patch b/queue-6.15/usb-acpi-prevent-null-pointer-dereference-in-usb_acp.patch
new file mode 100644 (file)
index 0000000..6fca76d
--- /dev/null
@@ -0,0 +1,48 @@
+From f8f0357ac10593c22013a5c5318a034d3d1c4cec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Apr 2025 14:50:32 -0500
+Subject: usb: acpi: Prevent null pointer dereference in
+ usb_acpi_add_usb4_devlink()
+
+From: Chenyuan Yang <chenyuan0y@gmail.com>
+
+[ Upstream commit 73fb0ec9436ae87bcae067ce35d6cdd72bade86c ]
+
+As demonstrated by the fix for update_port_device_state,
+commit 12783c0b9e2c ("usb: core: Prevent null pointer dereference in update_port_device_state"),
+usb_hub_to_struct_hub() can return NULL in certain scenarios,
+such as during hub driver unbind or teardown race conditions,
+even if the underlying usb_device structure exists.
+
+Plus, all other places that call usb_hub_to_struct_hub() in the same file
+do check for NULL return values.
+
+If usb_hub_to_struct_hub() returns NULL, the subsequent access to
+hub->ports[udev->portnum - 1] will cause a null pointer dereference.
+
+Signed-off-by: Chenyuan Yang <chenyuan0y@gmail.com>
+Fixes: f1bfb4a6fed6 ("usb: acpi: add device link between tunneled USB3 device and USB4 Host Interface")
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Link: https://lore.kernel.org/r/20250417195032.1811338-1-chenyuan0y@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/core/usb-acpi.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c
+index 935c0efea0b64..ea1ce8beb0cbb 100644
+--- a/drivers/usb/core/usb-acpi.c
++++ b/drivers/usb/core/usb-acpi.c
+@@ -165,6 +165,8 @@ static int usb_acpi_add_usb4_devlink(struct usb_device *udev)
+               return 0;
+       hub = usb_hub_to_struct_hub(udev->parent);
++      if (!hub)
++              return 0;
+       port_dev = hub->ports[udev->portnum - 1];
+       struct fwnode_handle *nhi_fwnode __free(fwnode_handle) =
+-- 
+2.39.5
+
diff --git a/queue-6.15/usb-gadget-udc-fix-const-issue-in-gadget_match_drive.patch b/queue-6.15/usb-gadget-udc-fix-const-issue-in-gadget_match_drive.patch
new file mode 100644 (file)
index 0000000..dc04dff
--- /dev/null
@@ -0,0 +1,38 @@
+From 40ec52304cdef0ffa0cbfcd9715fd9f778d3c43f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 May 2025 15:41:40 +0200
+Subject: USB: gadget: udc: fix const issue in gadget_match_driver()
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+[ Upstream commit 5f5cc794fac605afd3bef8065e33096aeacf6257 ]
+
+gadget_match_driver() takes a const pointer, and then decides to cast it
+away into a non-const one, which is not a good thing to do overall.  Fix
+this up by properly setting the pointers to be const to preserve that
+attribute.
+
+Fixes: d69d80484598 ("driver core: have match() callback in struct bus_type take a const *")
+Link: https://lore.kernel.org/r/2025052139-rash-unsaddle-7c5e@gregkh
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/udc/core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
+index 4b3d5075621aa..d709e24c1fd42 100644
+--- a/drivers/usb/gadget/udc/core.c
++++ b/drivers/usb/gadget/udc/core.c
+@@ -1570,7 +1570,7 @@ static int gadget_match_driver(struct device *dev, const struct device_driver *d
+ {
+       struct usb_gadget *gadget = dev_to_usb_gadget(dev);
+       struct usb_udc *udc = gadget->udc;
+-      struct usb_gadget_driver *driver = container_of(drv,
++      const struct usb_gadget_driver *driver = container_of(drv,
+                       struct usb_gadget_driver, driver);
+       /* If the driver specifies a udc_name, it must match the UDC's name */
+-- 
+2.39.5
+
diff --git a/queue-6.15/usb-renesas_usbhs-reorder-clock-handling-and-power-m.patch b/queue-6.15/usb-renesas_usbhs-reorder-clock-handling-and-power-m.patch
new file mode 100644 (file)
index 0000000..0b59342
--- /dev/null
@@ -0,0 +1,192 @@
+From 9cb6103ff5d921006a4267dfc76d45793df7cc98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Apr 2025 11:50:02 +0100
+Subject: usb: renesas_usbhs: Reorder clock handling and power management in
+ probe
+
+From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+
+[ Upstream commit ffb34a60ce86656ba12d46e91f1ccc71dd221251 ]
+
+Reorder the initialization sequence in `usbhs_probe()` to enable runtime
+PM before accessing registers, preventing potential crashes due to
+uninitialized clocks.
+
+Currently, in the probe path, registers are accessed before enabling the
+clocks, leading to a synchronous external abort on the RZ/V2H SoC.
+The problematic call flow is as follows:
+
+    usbhs_probe()
+        usbhs_sys_clock_ctrl()
+            usbhs_bset()
+                usbhs_write()
+                    iowrite16()  <-- Register access before enabling clocks
+
+Since `iowrite16()` is performed without ensuring the required clocks are
+enabled, this can lead to access errors. To fix this, enable PM runtime
+early in the probe function and ensure clocks are acquired before register
+access, preventing crashes like the following on RZ/V2H:
+
+[13.272640] Internal error: synchronous external abort: 0000000096000010 [#1] PREEMPT SMP
+[13.280814] Modules linked in: cec renesas_usbhs(+) drm_kms_helper fuse drm backlight ipv6
+[13.289088] CPU: 1 UID: 0 PID: 195 Comm: (udev-worker) Not tainted 6.14.0-rc7+ #98
+[13.296640] Hardware name: Renesas RZ/V2H EVK Board based on r9a09g057h44 (DT)
+[13.303834] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+[13.310770] pc : usbhs_bset+0x14/0x4c [renesas_usbhs]
+[13.315831] lr : usbhs_probe+0x2e4/0x5ac [renesas_usbhs]
+[13.321138] sp : ffff8000827e3850
+[13.324438] x29: ffff8000827e3860 x28: 0000000000000000 x27: ffff8000827e3ca0
+[13.331554] x26: ffff8000827e3ba0 x25: ffff800081729668 x24: 0000000000000025
+[13.338670] x23: ffff0000c0f08000 x22: 0000000000000000 x21: ffff0000c0f08010
+[13.345783] x20: 0000000000000000 x19: ffff0000c3b52080 x18: 00000000ffffffff
+[13.352895] x17: 0000000000000000 x16: 0000000000000000 x15: ffff8000827e36ce
+[13.360009] x14: 00000000000003d7 x13: 00000000000003d7 x12: 0000000000000000
+[13.367122] x11: 0000000000000000 x10: 0000000000000aa0 x9 : ffff8000827e3750
+[13.374235] x8 : ffff0000c1850b00 x7 : 0000000003826060 x6 : 000000000000001c
+[13.381347] x5 : 000000030d5fcc00 x4 : ffff8000825c0000 x3 : 0000000000000000
+[13.388459] x2 : 0000000000000400 x1 : 0000000000000000 x0 : ffff0000c3b52080
+[13.395574] Call trace:
+[13.398013]  usbhs_bset+0x14/0x4c [renesas_usbhs] (P)
+[13.403076]  platform_probe+0x68/0xdc
+[13.406738]  really_probe+0xbc/0x2c0
+[13.410306]  __driver_probe_device+0x78/0x120
+[13.414653]  driver_probe_device+0x3c/0x154
+[13.418825]  __driver_attach+0x90/0x1a0
+[13.422647]  bus_for_each_dev+0x7c/0xe0
+[13.426470]  driver_attach+0x24/0x30
+[13.430032]  bus_add_driver+0xe4/0x208
+[13.433766]  driver_register+0x68/0x130
+[13.437587]  __platform_driver_register+0x24/0x30
+[13.442273]  renesas_usbhs_driver_init+0x20/0x1000 [renesas_usbhs]
+[13.448450]  do_one_initcall+0x60/0x1d4
+[13.452276]  do_init_module+0x54/0x1f8
+[13.456014]  load_module+0x1754/0x1c98
+[13.459750]  init_module_from_file+0x88/0xcc
+[13.464004]  __arm64_sys_finit_module+0x1c4/0x328
+[13.468689]  invoke_syscall+0x48/0x104
+[13.472426]  el0_svc_common.constprop.0+0xc0/0xe0
+[13.477113]  do_el0_svc+0x1c/0x28
+[13.480415]  el0_svc+0x30/0xcc
+[13.483460]  el0t_64_sync_handler+0x10c/0x138
+[13.487800]  el0t_64_sync+0x198/0x19c
+[13.491453] Code: 2a0103e1 12003c42 12003c63 8b010084 (79400084)
+[13.497522] ---[ end trace 0000000000000000 ]---
+
+Fixes: f1407d5c66240 ("usb: renesas_usbhs: Add Renesas USBHS common code")
+Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Tested-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Link: https://lore.kernel.org/r/20250407105002.107181-4-prabhakar.mahadev-lad.rj@bp.renesas.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/renesas_usbhs/common.c | 50 +++++++++++++++++++++++-------
+ 1 file changed, 38 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c
+index 4b35ef216125c..16692e72b7365 100644
+--- a/drivers/usb/renesas_usbhs/common.c
++++ b/drivers/usb/renesas_usbhs/common.c
+@@ -685,10 +685,29 @@ static int usbhs_probe(struct platform_device *pdev)
+       INIT_DELAYED_WORK(&priv->notify_hotplug_work, usbhsc_notify_hotplug);
+       spin_lock_init(usbhs_priv_to_lock(priv));
++      /*
++       * Acquire clocks and enable power management (PM) early in the
++       * probe process, as the driver accesses registers during
++       * initialization. Ensure the device is active before proceeding.
++       */
++      pm_runtime_enable(dev);
++
++      ret = usbhsc_clk_get(dev, priv);
++      if (ret)
++              goto probe_pm_disable;
++
++      ret = pm_runtime_resume_and_get(dev);
++      if (ret)
++              goto probe_clk_put;
++
++      ret = usbhsc_clk_prepare_enable(priv);
++      if (ret)
++              goto probe_pm_put;
++
+       /* call pipe and module init */
+       ret = usbhs_pipe_probe(priv);
+       if (ret < 0)
+-              return ret;
++              goto probe_clk_dis_unprepare;
+       ret = usbhs_fifo_probe(priv);
+       if (ret < 0)
+@@ -705,10 +724,6 @@ static int usbhs_probe(struct platform_device *pdev)
+       if (ret)
+               goto probe_fail_rst;
+-      ret = usbhsc_clk_get(dev, priv);
+-      if (ret)
+-              goto probe_fail_clks;
+-
+       /*
+        * deviece reset here because
+        * USB device might be used in boot loader.
+@@ -721,7 +736,7 @@ static int usbhs_probe(struct platform_device *pdev)
+               if (ret) {
+                       dev_warn(dev, "USB function not selected (GPIO)\n");
+                       ret = -ENOTSUPP;
+-                      goto probe_end_mod_exit;
++                      goto probe_assert_rest;
+               }
+       }
+@@ -735,14 +750,19 @@ static int usbhs_probe(struct platform_device *pdev)
+       ret = usbhs_platform_call(priv, hardware_init, pdev);
+       if (ret < 0) {
+               dev_err(dev, "platform init failed.\n");
+-              goto probe_end_mod_exit;
++              goto probe_assert_rest;
+       }
+       /* reset phy for connection */
+       usbhs_platform_call(priv, phy_reset, pdev);
+-      /* power control */
+-      pm_runtime_enable(dev);
++      /*
++       * Disable the clocks that were enabled earlier in the probe path,
++       * and let the driver handle the clocks beyond this point.
++       */
++      usbhsc_clk_disable_unprepare(priv);
++      pm_runtime_put(dev);
++
+       if (!usbhs_get_dparam(priv, runtime_pwctrl)) {
+               usbhsc_power_ctrl(priv, 1);
+               usbhs_mod_autonomy_mode(priv);
+@@ -759,9 +779,7 @@ static int usbhs_probe(struct platform_device *pdev)
+       return ret;
+-probe_end_mod_exit:
+-      usbhsc_clk_put(priv);
+-probe_fail_clks:
++probe_assert_rest:
+       reset_control_assert(priv->rsts);
+ probe_fail_rst:
+       usbhs_mod_remove(priv);
+@@ -769,6 +787,14 @@ static int usbhs_probe(struct platform_device *pdev)
+       usbhs_fifo_remove(priv);
+ probe_end_pipe_exit:
+       usbhs_pipe_remove(priv);
++probe_clk_dis_unprepare:
++      usbhsc_clk_disable_unprepare(priv);
++probe_pm_put:
++      pm_runtime_put(dev);
++probe_clk_put:
++      usbhsc_clk_put(priv);
++probe_pm_disable:
++      pm_runtime_disable(dev);
+       dev_info(dev, "probe failed (%d)\n", ret);
+-- 
+2.39.5
+
diff --git a/queue-6.15/usb-serial-bus-fix-const-issue-in-usb_serial_device_.patch b/queue-6.15/usb-serial-bus-fix-const-issue-in-usb_serial_device_.patch
new file mode 100644 (file)
index 0000000..723d718
--- /dev/null
@@ -0,0 +1,38 @@
+From 0e91be50efc1a26ec9047dadc980631d31ef8578 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 May 2025 15:41:34 +0200
+Subject: USB: serial: bus: fix const issue in usb_serial_device_match()
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+[ Upstream commit 92cd405b648605db4da866f3b9818b271ae84ef0 ]
+
+usb_serial_device_match() takes a const pointer, and then decides to
+cast it away into a non-const one, which is not a good thing to do
+overall.  Fix this up by properly setting the pointers to be const to
+preserve that attribute.
+
+Fixes: d69d80484598 ("driver core: have match() callback in struct bus_type take a const *")
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/serial/bus.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c
+index 2fea1b1db4a26..9e2a18c0b2183 100644
+--- a/drivers/usb/serial/bus.c
++++ b/drivers/usb/serial/bus.c
+@@ -17,7 +17,7 @@ static int usb_serial_device_match(struct device *dev,
+                                  const struct device_driver *drv)
+ {
+       const struct usb_serial_port *port = to_usb_serial_port(dev);
+-      struct usb_serial_driver *driver = to_usb_serial_driver(drv);
++      const struct usb_serial_driver *driver = to_usb_serial_driver(drv);
+       /*
+        * drivers are already assigned to ports in serial_probe so it's
+-- 
+2.39.5
+
diff --git a/queue-6.15/usb-typec-fix-const-issue-in-typec_match.patch b/queue-6.15/usb-typec-fix-const-issue-in-typec_match.patch
new file mode 100644 (file)
index 0000000..1bca775
--- /dev/null
@@ -0,0 +1,39 @@
+From 1024383786877cf7b213919ce63f2a4aca904312 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 May 2025 15:35:24 +0200
+Subject: USB: typec: fix const issue in typec_match()
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+[ Upstream commit ae4432e01dd967a64f6670a152d91d5328032726 ]
+
+typec_match() takes a const pointer, and then decides to cast it away
+into a non-const one, which is not a good thing to do overall.  Fix this
+up by properly setting the pointers to be const to preserve that
+attribute.
+
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/2025052126-scholar-stainless-ad55@gregkh
+Fixes: d69d80484598 ("driver core: have match() callback in struct bus_type take a const *")
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/typec/bus.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/typec/bus.c b/drivers/usb/typec/bus.c
+index ae90688d23e40..a884cec9ab7e8 100644
+--- a/drivers/usb/typec/bus.c
++++ b/drivers/usb/typec/bus.c
+@@ -449,7 +449,7 @@ ATTRIBUTE_GROUPS(typec);
+ static int typec_match(struct device *dev, const struct device_driver *driver)
+ {
+-      struct typec_altmode_driver *drv = to_altmode_driver(driver);
++      const struct typec_altmode_driver *drv = to_altmode_driver(driver);
+       struct typec_altmode *altmode = to_typec_altmode(dev);
+       const struct typec_device_id *id;
+-- 
+2.39.5
+
diff --git a/queue-6.15/use-thread-safe-function-pointer-in-libbpf_print.patch b/queue-6.15/use-thread-safe-function-pointer-in-libbpf_print.patch
new file mode 100644 (file)
index 0000000..00c6175
--- /dev/null
@@ -0,0 +1,39 @@
+From bc37232accdca78dd1c18663b85a304d8f4646bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Apr 2025 18:14:57 -0400
+Subject: Use thread-safe function pointer in libbpf_print
+
+From: Jonathan Wiepert <jonathan.wiepert@gmail.com>
+
+[ Upstream commit 91dbac4076537b464639953c055c460d2bdfc7ea ]
+
+This patch fixes a thread safety bug where libbpf_print uses the
+global variable storing the print function pointer rather than the local
+variable that had the print function set via __atomic_load_n.
+
+Fixes: f1cb927cdb62 ("libbpf: Ensure print callback usage is thread-safe")
+Signed-off-by: Jonathan Wiepert <jonathan.wiepert@gmail.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Acked-by: Mykyta Yatsenko <mykyta.yatsenko5@gmail.com>
+Link: https://lore.kernel.org/bpf/20250424221457.793068-1-jonathan.wiepert@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/libbpf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
+index 2bc0e3bfdd491..147964bb64c8f 100644
+--- a/tools/lib/bpf/libbpf.c
++++ b/tools/lib/bpf/libbpf.c
+@@ -286,7 +286,7 @@ void libbpf_print(enum libbpf_print_level level, const char *format, ...)
+       old_errno = errno;
+       va_start(args, format);
+-      __libbpf_pr(level, format, args);
++      print_fn(level, format, args);
+       va_end(args);
+       errno = old_errno;
+-- 
+2.39.5
+
diff --git a/queue-6.15/vfio-type1-fix-error-unwind-in-migration-dirty-bitma.patch b/queue-6.15/vfio-type1-fix-error-unwind-in-migration-dirty-bitma.patch
new file mode 100644 (file)
index 0000000..9b78127
--- /dev/null
@@ -0,0 +1,45 @@
+From 553bc9645cc20ec36147bd47904b7d6b3835ec79 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 May 2025 11:46:47 +0800
+Subject: vfio/type1: Fix error unwind in migration dirty bitmap allocation
+
+From: Li RongQing <lirongqing@baidu.com>
+
+[ Upstream commit 4518e5a60c7fbf0cdff393c2681db39d77b4f87e ]
+
+When setting up dirty page tracking at the vfio IOMMU backend for
+device migration, if an error is encountered allocating a tracking
+bitmap, the unwind loop fails to free previously allocated tracking
+bitmaps.  This occurs because the wrong loop index is used to
+generate the tracking object.  This results in unintended memory
+usage for the life of the current DMA mappings where bitmaps were
+successfully allocated.
+
+Use the correct loop index to derive the tracking object for
+freeing during unwind.
+
+Fixes: d6a4c185660c ("vfio iommu: Implementation of ioctl for dirty pages tracking")
+Signed-off-by: Li RongQing <lirongqing@baidu.com>
+Link: https://lore.kernel.org/r/20250521034647.2877-1-lirongqing@baidu.com
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/vfio/vfio_iommu_type1.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
+index 0ac56072af9f2..ba5d91e576af1 100644
+--- a/drivers/vfio/vfio_iommu_type1.c
++++ b/drivers/vfio/vfio_iommu_type1.c
+@@ -293,7 +293,7 @@ static int vfio_dma_bitmap_alloc_all(struct vfio_iommu *iommu, size_t pgsize)
+                       struct rb_node *p;
+                       for (p = rb_prev(n); p; p = rb_prev(p)) {
+-                              struct vfio_dma *dma = rb_entry(n,
++                              struct vfio_dma *dma = rb_entry(p,
+                                                       struct vfio_dma, node);
+                               vfio_dma_bitmap_free(dma);
+-- 
+2.39.5
+
diff --git a/queue-6.15/virtio-pci-fix-result-size-returned-for-the-admin-co.patch b/queue-6.15/virtio-pci-fix-result-size-returned-for-the-admin-co.patch
new file mode 100644 (file)
index 0000000..7f24edb
--- /dev/null
@@ -0,0 +1,72 @@
+From 95d23c1da2459ac7447f673079418ef2f8a0ac74 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Apr 2025 13:33:45 +0300
+Subject: virtio-pci: Fix result size returned for the admin command completion
+
+From: Israel Rukshin <israelr@nvidia.com>
+
+[ Upstream commit 9ef41ebf787fcbde99ac404ae473f8467641f983 ]
+
+The result size returned by virtio_pci_admin_dev_parts_get() is 8 bytes
+larger than the actual result data size. This occurs because the
+result_sg_size field of the command is filled with the result length
+from virtqueue_get_buf(), which includes both the data size and an
+additional 8 bytes of status.
+
+This oversized result size causes two issues:
+1. The state transferred to the destination includes 8 bytes of extra
+   data at the end.
+2. The allocated buffer in the kernel may be smaller than the returned
+   size, leading to failures when reading beyond the allocated size.
+
+The commit fixes this by subtracting the status size from the result of
+virtqueue_get_buf().
+
+This fix has been tested through live migrations with virtio-net,
+virtio-net-transitional, and virtio-blk devices.
+
+Fixes: 704806ca400e ("virtio: Extend the admin command to include the result size")
+Signed-off-by: Israel Rukshin <israelr@nvidia.com>
+Reviewed-by: Parav Pandit <parav@nvidia.com>
+Reviewed-by: Max Gurtovoy <mgurtovoy@nvidia.com>
+Message-Id: <1745318025-23103-1-git-send-email-israelr@nvidia.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/virtio/virtio_pci_modern.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/virtio/virtio_pci_modern.c b/drivers/virtio/virtio_pci_modern.c
+index d50fe030d8253..7182f43ed0551 100644
+--- a/drivers/virtio/virtio_pci_modern.c
++++ b/drivers/virtio/virtio_pci_modern.c
+@@ -48,6 +48,7 @@ void vp_modern_avq_done(struct virtqueue *vq)
+ {
+       struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev);
+       struct virtio_pci_admin_vq *admin_vq = &vp_dev->admin_vq;
++      unsigned int status_size = sizeof(struct virtio_admin_cmd_status);
+       struct virtio_admin_cmd *cmd;
+       unsigned long flags;
+       unsigned int len;
+@@ -56,7 +57,17 @@ void vp_modern_avq_done(struct virtqueue *vq)
+       do {
+               virtqueue_disable_cb(vq);
+               while ((cmd = virtqueue_get_buf(vq, &len))) {
+-                      cmd->result_sg_size = len;
++                      /* If the number of bytes written by the device is less
++                       * than the size of struct virtio_admin_cmd_status, the
++                       * remaining status bytes will remain zero-initialized,
++                       * since the buffer was zeroed during allocation.
++                       * In this case, set the size of command_specific_result
++                       * to 0.
++                       */
++                      if (len < status_size)
++                              cmd->result_sg_size = 0;
++                      else
++                              cmd->result_sg_size = len - status_size;
+                       complete(&cmd->completion);
+               }
+       } while (!virtqueue_enable_cb(vq));
+-- 
+2.39.5
+
diff --git a/queue-6.15/vmxnet3-correctly-report-gso-type-for-udp-tunnels.patch b/queue-6.15/vmxnet3-correctly-report-gso-type-for-udp-tunnels.patch
new file mode 100644 (file)
index 0000000..39a1866
--- /dev/null
@@ -0,0 +1,82 @@
+From a2bc2bd3b5896b2bd70e699cf04d4efb6196b2d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 May 2025 15:27:00 +0000
+Subject: vmxnet3: correctly report gso type for UDP tunnels
+
+From: Ronak Doshi <ronak.doshi@broadcom.com>
+
+[ Upstream commit 982d30c30eaa2ec723df42e3bf526c014c1dbb88 ]
+
+Commit 3d010c8031e3 ("udp: do not accept non-tunnel GSO skbs landing
+in a tunnel") added checks in linux stack to not accept non-tunnel
+GRO packets landing in a tunnel. This exposed an issue in vmxnet3
+which was not correctly reporting GRO packets for tunnel packets.
+
+This patch fixes this issue by setting correct GSO type for the
+tunnel packets.
+
+Currently, vmxnet3 does not support reporting inner fields for LRO
+tunnel packets. The issue is not seen for egress drivers that do not
+use skb inner fields. The workaround is to enable tnl-segmentation
+offload on the egress interfaces if the driver supports it. This
+problem pre-exists this patch fix and can be addressed as a separate
+future patch.
+
+Fixes: dacce2be3312 ("vmxnet3: add geneve and vxlan tunnel offload support")
+Signed-off-by: Ronak Doshi <ronak.doshi@broadcom.com>
+Acked-by: Guolin Yang <guolin.yang@broadcom.com>
+Link: https://patch.msgid.link/20250530152701.70354-1-ronak.doshi@broadcom.com
+[pabeni@redhat.com: dropped the changelog]
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/vmxnet3/vmxnet3_drv.c | 26 ++++++++++++++++++++++++++
+ 1 file changed, 26 insertions(+)
+
+diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
+index c676979c7ab94..287b7c20c0d6c 100644
+--- a/drivers/net/vmxnet3/vmxnet3_drv.c
++++ b/drivers/net/vmxnet3/vmxnet3_drv.c
+@@ -1568,6 +1568,30 @@ vmxnet3_get_hdr_len(struct vmxnet3_adapter *adapter, struct sk_buff *skb,
+       return (hlen + (hdr.tcp->doff << 2));
+ }
++static void
++vmxnet3_lro_tunnel(struct sk_buff *skb, __be16 ip_proto)
++{
++      struct udphdr *uh = NULL;
++
++      if (ip_proto == htons(ETH_P_IP)) {
++              struct iphdr *iph = (struct iphdr *)skb->data;
++
++              if (iph->protocol == IPPROTO_UDP)
++                      uh = (struct udphdr *)(iph + 1);
++      } else {
++              struct ipv6hdr *iph = (struct ipv6hdr *)skb->data;
++
++              if (iph->nexthdr == IPPROTO_UDP)
++                      uh = (struct udphdr *)(iph + 1);
++      }
++      if (uh) {
++              if (uh->check)
++                      skb_shinfo(skb)->gso_type |= SKB_GSO_UDP_TUNNEL_CSUM;
++              else
++                      skb_shinfo(skb)->gso_type |= SKB_GSO_UDP_TUNNEL;
++      }
++}
++
+ static int
+ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
+                      struct vmxnet3_adapter *adapter, int quota)
+@@ -1881,6 +1905,8 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
+                       if (segCnt != 0 && mss != 0) {
+                               skb_shinfo(skb)->gso_type = rcd->v4 ?
+                                       SKB_GSO_TCPV4 : SKB_GSO_TCPV6;
++                              if (encap_lro)
++                                      vmxnet3_lro_tunnel(skb, skb->protocol);
+                               skb_shinfo(skb)->gso_size = mss;
+                               skb_shinfo(skb)->gso_segs = segCnt;
+                       } else if ((segCnt != 0 || skb->len > mtu) && !encap_lro) {
+-- 
+2.39.5
+
diff --git a/queue-6.15/vsock-virtio-fix-rx_bytes-accounting-for-stream-sock.patch b/queue-6.15/vsock-virtio-fix-rx_bytes-accounting-for-stream-sock.patch
new file mode 100644 (file)
index 0000000..599bf94
--- /dev/null
@@ -0,0 +1,163 @@
+From e952627e1f30a482d5df8d883bb153a0bd4a2482 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 May 2025 14:17:05 +0200
+Subject: vsock/virtio: fix `rx_bytes` accounting for stream sockets
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Stefano Garzarella <sgarzare@redhat.com>
+
+[ Upstream commit 45ca7e9f0730ae36fc610e675b990e9cc9ca0714 ]
+
+In `struct virtio_vsock_sock`, we maintain two counters:
+- `rx_bytes`: used internally to track how many bytes have been read.
+  This supports mechanisms like .stream_has_data() and sock_rcvlowat().
+- `fwd_cnt`: used for the credit mechanism to inform available receive
+  buffer space to the remote peer.
+
+These counters are updated via virtio_transport_inc_rx_pkt() and
+virtio_transport_dec_rx_pkt().
+
+Since the beginning with commit 06a8fc78367d ("VSOCK: Introduce
+virtio_vsock_common.ko"), we call virtio_transport_dec_rx_pkt() in
+virtio_transport_stream_do_dequeue() only when we consume the entire
+packet, so partial reads, do not update `rx_bytes` and `fwd_cnt`.
+
+This is fine for `fwd_cnt`, because we still have space used for the
+entire packet, and we don't want to update the credit for the other
+peer until we free the space of the entire packet. However, this
+causes `rx_bytes` to be stale on partial reads.
+
+Previously, this didn’t cause issues because `rx_bytes` was used only by
+.stream_has_data(), and any unread portion of a packet implied data was
+still available. However, since commit 93b808876682
+("virtio/vsock: fix logic which reduces credit update messages"), we now
+rely on `rx_bytes` to determine if a credit update should be sent when
+the data in the RX queue drops below SO_RCVLOWAT value.
+
+This patch fixes the accounting by updating `rx_bytes` with the number
+of bytes actually read, even on partial reads, while leaving `fwd_cnt`
+untouched until the packet is fully consumed. Also introduce a new
+`buf_used` counter to check that the remote peer is honoring the given
+credit; this was previously done via `rx_bytes`.
+
+Fixes: 93b808876682 ("virtio/vsock: fix logic which reduces credit update messages")
+Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
+Link: https://patch.msgid.link/20250521121705.196379-1-sgarzare@redhat.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/virtio_vsock.h            |  1 +
+ net/vmw_vsock/virtio_transport_common.c | 26 +++++++++++++++----------
+ 2 files changed, 17 insertions(+), 10 deletions(-)
+
+diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h
+index 0387d64e2c66c..36fb3edfa403d 100644
+--- a/include/linux/virtio_vsock.h
++++ b/include/linux/virtio_vsock.h
+@@ -140,6 +140,7 @@ struct virtio_vsock_sock {
+       u32 last_fwd_cnt;
+       u32 rx_bytes;
+       u32 buf_alloc;
++      u32 buf_used;
+       struct sk_buff_head rx_queue;
+       u32 msg_count;
+ };
+diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
+index 7f7de6d880965..2c9b1011cdcc8 100644
+--- a/net/vmw_vsock/virtio_transport_common.c
++++ b/net/vmw_vsock/virtio_transport_common.c
+@@ -441,18 +441,20 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk,
+ static bool virtio_transport_inc_rx_pkt(struct virtio_vsock_sock *vvs,
+                                       u32 len)
+ {
+-      if (vvs->rx_bytes + len > vvs->buf_alloc)
++      if (vvs->buf_used + len > vvs->buf_alloc)
+               return false;
+       vvs->rx_bytes += len;
++      vvs->buf_used += len;
+       return true;
+ }
+ static void virtio_transport_dec_rx_pkt(struct virtio_vsock_sock *vvs,
+-                                      u32 len)
++                                      u32 bytes_read, u32 bytes_dequeued)
+ {
+-      vvs->rx_bytes -= len;
+-      vvs->fwd_cnt += len;
++      vvs->rx_bytes -= bytes_read;
++      vvs->buf_used -= bytes_dequeued;
++      vvs->fwd_cnt += bytes_dequeued;
+ }
+ void virtio_transport_inc_tx_pkt(struct virtio_vsock_sock *vvs, struct sk_buff *skb)
+@@ -581,11 +583,11 @@ virtio_transport_stream_do_dequeue(struct vsock_sock *vsk,
+                                  size_t len)
+ {
+       struct virtio_vsock_sock *vvs = vsk->trans;
+-      size_t bytes, total = 0;
+       struct sk_buff *skb;
+       u32 fwd_cnt_delta;
+       bool low_rx_bytes;
+       int err = -EFAULT;
++      size_t total = 0;
+       u32 free_space;
+       spin_lock_bh(&vvs->rx_lock);
+@@ -597,6 +599,8 @@ virtio_transport_stream_do_dequeue(struct vsock_sock *vsk,
+       }
+       while (total < len && !skb_queue_empty(&vvs->rx_queue)) {
++              size_t bytes, dequeued = 0;
++
+               skb = skb_peek(&vvs->rx_queue);
+               bytes = min_t(size_t, len - total,
+@@ -620,12 +624,12 @@ virtio_transport_stream_do_dequeue(struct vsock_sock *vsk,
+               VIRTIO_VSOCK_SKB_CB(skb)->offset += bytes;
+               if (skb->len == VIRTIO_VSOCK_SKB_CB(skb)->offset) {
+-                      u32 pkt_len = le32_to_cpu(virtio_vsock_hdr(skb)->len);
+-
+-                      virtio_transport_dec_rx_pkt(vvs, pkt_len);
++                      dequeued = le32_to_cpu(virtio_vsock_hdr(skb)->len);
+                       __skb_unlink(skb, &vvs->rx_queue);
+                       consume_skb(skb);
+               }
++
++              virtio_transport_dec_rx_pkt(vvs, bytes, dequeued);
+       }
+       fwd_cnt_delta = vvs->fwd_cnt - vvs->last_fwd_cnt;
+@@ -781,7 +785,7 @@ static int virtio_transport_seqpacket_do_dequeue(struct vsock_sock *vsk,
+                               msg->msg_flags |= MSG_EOR;
+               }
+-              virtio_transport_dec_rx_pkt(vvs, pkt_len);
++              virtio_transport_dec_rx_pkt(vvs, pkt_len, pkt_len);
+               kfree_skb(skb);
+       }
+@@ -1735,6 +1739,7 @@ int virtio_transport_read_skb(struct vsock_sock *vsk, skb_read_actor_t recv_acto
+       struct sock *sk = sk_vsock(vsk);
+       struct virtio_vsock_hdr *hdr;
+       struct sk_buff *skb;
++      u32 pkt_len;
+       int off = 0;
+       int err;
+@@ -1752,7 +1757,8 @@ int virtio_transport_read_skb(struct vsock_sock *vsk, skb_read_actor_t recv_acto
+       if (le32_to_cpu(hdr->flags) & VIRTIO_VSOCK_SEQ_EOM)
+               vvs->msg_count--;
+-      virtio_transport_dec_rx_pkt(vvs, le32_to_cpu(hdr->len));
++      pkt_len = le32_to_cpu(hdr->len);
++      virtio_transport_dec_rx_pkt(vvs, pkt_len, pkt_len);
+       spin_unlock_bh(&vvs->rx_lock);
+       virtio_transport_send_credit_update(vsk);
+-- 
+2.39.5
+
diff --git a/queue-6.15/vt-remove-vt_resize-and-vt_resizex-from-vt_compat_io.patch b/queue-6.15/vt-remove-vt_resize-and-vt_resizex-from-vt_compat_io.patch
new file mode 100644 (file)
index 0000000..3f1bbc7
--- /dev/null
@@ -0,0 +1,39 @@
+From 831f7b95037213b6a5bcd8578811d4966adaed73 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 May 2025 11:30:52 -0400
+Subject: vt: remove VT_RESIZE and VT_RESIZEX from vt_compat_ioctl()
+
+From: Nicolas Pitre <npitre@baylibre.com>
+
+[ Upstream commit c4c7ead7b86c1e7f11c64915b7e5bb6d2e242691 ]
+
+They are listed amon those cmd values that "treat 'arg' as an integer"
+which is wrong. They should instead fall into the default case. Probably
+nobody ever relied on that code since 2009 but still.
+
+Fixes: e92166517e3c ("tty: handle VT specific compat ioctls in vt driver")
+Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
+Reviewed-by: Jiri Slaby <jirislaby@kernel.org>
+Link: https://lore.kernel.org/r/pr214s15-36r8-6732-2pop-159nq85o48r7@syhkavp.arg
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/vt/vt_ioctl.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c
+index 4b91072f3a4e9..1f2bdd2e1cc59 100644
+--- a/drivers/tty/vt/vt_ioctl.c
++++ b/drivers/tty/vt/vt_ioctl.c
+@@ -1103,8 +1103,6 @@ long vt_compat_ioctl(struct tty_struct *tty,
+       case VT_WAITACTIVE:
+       case VT_RELDISP:
+       case VT_DISALLOCATE:
+-      case VT_RESIZE:
+-      case VT_RESIZEX:
+               return vt_ioctl(tty, cmd, arg);
+       /*
+-- 
+2.39.5
+
diff --git a/queue-6.15/watchdog-exar-shorten-identity-name-to-fit-correctly.patch b/queue-6.15/watchdog-exar-shorten-identity-name-to-fit-correctly.patch
new file mode 100644 (file)
index 0000000..10e50fb
--- /dev/null
@@ -0,0 +1,44 @@
+From 332d16f70462ce499a96e6a9f55177106105b705 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Apr 2025 15:52:49 -0700
+Subject: watchdog: exar: Shorten identity name to fit correctly
+
+From: Kees Cook <kees@kernel.org>
+
+[ Upstream commit 8e28276a569addb8a2324439ae473848ee52b056 ]
+
+The static initializer for struct watchdog_info::identity is too long
+and gets initialized without a trailing NUL byte. Since the length
+of "identity" is part of UAPI and tied to ioctls, just shorten
+the name of the device. Avoids the warning seen with GCC 15's
+-Wunterminated-string-initialization option:
+
+drivers/watchdog/exar_wdt.c:224:27: warning: initializer-string for array of 'unsigned char' truncates NUL terminator but destination lacks 'nonstring' attribute (33 chars into 32 available) [-Wunterminated-string-initialization]
+  224 |         .identity       = "Exar/MaxLinear XR28V38x Watchdog",
+      |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Fixes: 81126222bd3a ("watchdog: Exar/MaxLinear XR28V38x driver")
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/20250415225246.work.458-kees@kernel.org
+Signed-off-by: Kees Cook <kees@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/watchdog/exar_wdt.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/watchdog/exar_wdt.c b/drivers/watchdog/exar_wdt.c
+index 7c61ff3432711..c2e3bb08df899 100644
+--- a/drivers/watchdog/exar_wdt.c
++++ b/drivers/watchdog/exar_wdt.c
+@@ -221,7 +221,7 @@ static const struct watchdog_info exar_wdt_info = {
+       .options        = WDIOF_KEEPALIVEPING |
+                         WDIOF_SETTIMEOUT |
+                         WDIOF_MAGICCLOSE,
+-      .identity       = "Exar/MaxLinear XR28V38x Watchdog",
++      .identity       = "Exar XR28V38x Watchdog",
+ };
+ static const struct watchdog_ops exar_wdt_ops = {
+-- 
+2.39.5
+
diff --git a/queue-6.15/watchdog-lenovo_se30_wdt-fix-possible-devm_ioremap-n.patch b/queue-6.15/watchdog-lenovo_se30_wdt-fix-possible-devm_ioremap-n.patch
new file mode 100644 (file)
index 0000000..8ce7874
--- /dev/null
@@ -0,0 +1,43 @@
+From 2f404db31eb1fde41259e1ba3b0aab8102d0f7f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Apr 2025 15:16:48 +0800
+Subject: watchdog: lenovo_se30_wdt: Fix possible devm_ioremap() NULL pointer
+ dereference in lenovo_se30_wdt_probe()
+
+From: Henry Martin <bsdhenrymartin@gmail.com>
+
+[ Upstream commit a4e2401438a26131ecff9be6a3a1d4cbfea66f9a ]
+
+devm_ioremap() returns NULL on error. Currently, lenovo_se30_wdt_probe()
+does not check for this case, which results in a NULL pointer
+dereference.
+
+Add NULL check after devm_ioremap() to prevent this issue.
+
+Fixes: c284153a2c55 ("watchdog: lenovo_se30_wdt: Watchdog driver for Lenovo SE30 platform")
+Signed-off-by: Henry Martin <bsdhenrymartin@gmail.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/20250424071648.89016-1-bsdhenrymartin@gmail.com
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/watchdog/lenovo_se30_wdt.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/watchdog/lenovo_se30_wdt.c b/drivers/watchdog/lenovo_se30_wdt.c
+index 024b842499b36..1c73bb7eeeeed 100644
+--- a/drivers/watchdog/lenovo_se30_wdt.c
++++ b/drivers/watchdog/lenovo_se30_wdt.c
+@@ -271,6 +271,8 @@ static int lenovo_se30_wdt_probe(struct platform_device *pdev)
+               return -EBUSY;
+       priv->shm_base_addr = devm_ioremap(dev, base_phys, SHM_WIN_SIZE);
++      if (!priv->shm_base_addr)
++              return -ENOMEM;
+       priv->wdt_cfg.mod = WDT_MODULE;
+       priv->wdt_cfg.idx = WDT_CFG_INDEX;
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-ath11k-fix-node-corruption-in-ar-arvifs-list.patch b/queue-6.15/wifi-ath11k-fix-node-corruption-in-ar-arvifs-list.patch
new file mode 100644 (file)
index 0000000..7339e67
--- /dev/null
@@ -0,0 +1,83 @@
+From 91073089c6230f2523aa74ee102dffd90b9e7edd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Mar 2025 13:31:45 +0800
+Subject: wifi: ath11k: fix node corruption in ar->arvifs list
+
+From: Stone Zhang <quic_stonez@quicinc.com>
+
+[ Upstream commit 31e98e277ae47f56632e4d663b1d4fd12ba33ea8 ]
+
+In current WLAN recovery code flow, ath11k_core_halt() only
+reinitializes the "arvifs" list head. This will cause the
+list node immediately following the list head to become an
+invalid list node. Because the prev of that node still points
+to the list head "arvifs", but the next of the list head "arvifs"
+no longer points to that list node.
+
+When a WLAN recovery occurs during the execution of a vif
+removal, and it happens before the spin_lock_bh(&ar->data_lock)
+in ath11k_mac_op_remove_interface(), list_del() will detect the
+previously mentioned situation, thereby triggering a kernel panic.
+
+The fix is to remove and reinitialize all vif list nodes from the
+list head "arvifs" during WLAN halt. The reinitialization is to make
+the list nodes valid, ensuring that the list_del() in
+ath11k_mac_op_remove_interface() can execute normally.
+
+Call trace:
+__list_del_entry_valid_or_report+0xb8/0xd0
+ath11k_mac_op_remove_interface+0xb0/0x27c [ath11k]
+drv_remove_interface+0x48/0x194 [mac80211]
+ieee80211_do_stop+0x6e0/0x844 [mac80211]
+ieee80211_stop+0x44/0x17c [mac80211]
+__dev_close_many+0xac/0x150
+__dev_change_flags+0x194/0x234
+dev_change_flags+0x24/0x6c
+devinet_ioctl+0x3a0/0x670
+inet_ioctl+0x200/0x248
+sock_do_ioctl+0x60/0x118
+sock_ioctl+0x274/0x35c
+__arm64_sys_ioctl+0xac/0xf0
+invoke_syscall+0x48/0x114
+...
+
+Tested-on: QCA6698AQ hw2.1 PCI WLAN.HSP.1.1-04591-QCAHSPSWPL_V1_V2_SILICONZ_IOE-1
+
+Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
+Signed-off-by: Stone Zhang <quic_stonez@quicinc.com>
+Link: https://patch.msgid.link/20250320053145.3445187-1-quic_stonez@quicinc.com
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/core.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c
+index 3d39ff85ba94a..8d08dd47bde9c 100644
+--- a/drivers/net/wireless/ath/ath11k/core.c
++++ b/drivers/net/wireless/ath/ath11k/core.c
+@@ -2050,6 +2050,7 @@ static int ath11k_core_reconfigure_on_crash(struct ath11k_base *ab)
+ void ath11k_core_halt(struct ath11k *ar)
+ {
+       struct ath11k_base *ab = ar->ab;
++      struct list_head *pos, *n;
+       lockdep_assert_held(&ar->conf_mutex);
+@@ -2065,7 +2066,12 @@ void ath11k_core_halt(struct ath11k *ar)
+       rcu_assign_pointer(ab->pdevs_active[ar->pdev_idx], NULL);
+       synchronize_rcu();
+-      INIT_LIST_HEAD(&ar->arvifs);
++
++      spin_lock_bh(&ar->data_lock);
++      list_for_each_safe(pos, n, &ar->arvifs)
++              list_del_init(pos);
++      spin_unlock_bh(&ar->data_lock);
++
+       idr_init(&ar->txmgmt_idr);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-ath12k-add-extra-tlv-tag-parsing-support-in-mon.patch b/queue-6.15/wifi-ath12k-add-extra-tlv-tag-parsing-support-in-mon.patch
new file mode 100644 (file)
index 0000000..34b202d
--- /dev/null
@@ -0,0 +1,337 @@
+From 37ced12adf288f3aca539158fd4bc68c6be46e5b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Mar 2025 11:55:10 +0530
+Subject: wifi: ath12k: Add extra TLV tag parsing support in monitor Rx path
+
+From: P Praneesh <quic_ppranees@quicinc.com>
+
+[ Upstream commit 3973cda5ef496fd412fdec2c7c3403ac90e391b8 ]
+
+Currently, the monitor Rx parser handler is inherited from the ath11k.
+However, the ath12k 802.11be hardware does not report the Rx TLV header
+in the MSDU data. Instead, the hardware reports those TLVs under the
+following TLV tags:
+
+1. Buffer address
+2. MPDU start
+3. MPDU end
+4. MSDU end
+
+Therefore, add support for parsing the above TLVs in the Rx monitor path
+and use this information for MSDU buffer and status updates.
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1
+Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
+
+Signed-off-by: P Praneesh <quic_ppranees@quicinc.com>
+Tested-by: Nicolas Escande <nico.escande@gmail.com>
+Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
+Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
+Link: https://patch.msgid.link/20250324062518.2752822-3-quic_periyasa@quicinc.com
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Stable-dep-of: f5d6b15d9503 ("wifi: ath12k: fix wrong handling of CCMP256 and GCMP ciphers")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/dp.h     |   2 +
+ drivers/net/wireless/ath/ath12k/dp_mon.c | 157 ++++++++++++++++++++++-
+ drivers/net/wireless/ath/ath12k/dp_mon.h |   4 +-
+ drivers/net/wireless/ath/ath12k/dp_rx.c  |   2 +
+ drivers/net/wireless/ath/ath12k/hal_rx.h |  12 +-
+ 5 files changed, 170 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h
+index 75435a931548c..427a87b63dec3 100644
+--- a/drivers/net/wireless/ath/ath12k/dp.h
++++ b/drivers/net/wireless/ath/ath12k/dp.h
+@@ -106,6 +106,8 @@ struct dp_mon_mpdu {
+       struct list_head list;
+       struct sk_buff *head;
+       struct sk_buff *tail;
++      u32 err_bitmap;
++      u8 decap_format;
+ };
+ #define DP_MON_MAX_STATUS_BUF 32
+diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c
+index d22800e894850..8c78f601f70aa 100644
+--- a/drivers/net/wireless/ath/ath12k/dp_mon.c
++++ b/drivers/net/wireless/ath/ath12k/dp_mon.c
+@@ -1647,7 +1647,7 @@ ath12k_dp_mon_rx_parse_status_tlv(struct ath12k *ar,
+                               u32_get_bits(info[0], HAL_RX_MPDU_START_INFO0_PPDU_ID);
+               }
+-              break;
++              return HAL_RX_MON_STATUS_MPDU_START;
+       }
+       case HAL_RX_MSDU_START:
+               /* TODO: add msdu start parsing logic */
+@@ -2088,6 +2088,144 @@ static int ath12k_dp_mon_rx_deliver(struct ath12k *ar,
+       return -EINVAL;
+ }
++static int ath12k_dp_pkt_set_pktlen(struct sk_buff *skb, u32 len)
++{
++      if (skb->len > len) {
++              skb_trim(skb, len);
++      } else {
++              if (skb_tailroom(skb) < len - skb->len) {
++                      if ((pskb_expand_head(skb, 0,
++                                            len - skb->len - skb_tailroom(skb),
++                                            GFP_ATOMIC))) {
++                              return -ENOMEM;
++                      }
++              }
++              skb_put(skb, (len - skb->len));
++      }
++
++      return 0;
++}
++
++static void ath12k_dp_mon_parse_rx_msdu_end_err(u32 info, u32 *errmap)
++{
++      if (info & RX_MSDU_END_INFO13_FCS_ERR)
++              *errmap |= HAL_RX_MPDU_ERR_FCS;
++
++      if (info & RX_MSDU_END_INFO13_DECRYPT_ERR)
++              *errmap |= HAL_RX_MPDU_ERR_DECRYPT;
++
++      if (info & RX_MSDU_END_INFO13_TKIP_MIC_ERR)
++              *errmap |= HAL_RX_MPDU_ERR_TKIP_MIC;
++
++      if (info & RX_MSDU_END_INFO13_A_MSDU_ERROR)
++              *errmap |= HAL_RX_MPDU_ERR_AMSDU_ERR;
++
++      if (info & RX_MSDU_END_INFO13_OVERFLOW_ERR)
++              *errmap |= HAL_RX_MPDU_ERR_OVERFLOW;
++
++      if (info & RX_MSDU_END_INFO13_MSDU_LEN_ERR)
++              *errmap |= HAL_RX_MPDU_ERR_MSDU_LEN;
++
++      if (info & RX_MSDU_END_INFO13_MPDU_LEN_ERR)
++              *errmap |= HAL_RX_MPDU_ERR_MPDU_LEN;
++}
++
++static int
++ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon,
++                                  const struct hal_rx_msdu_end *msdu_end)
++{
++      struct dp_mon_mpdu *mon_mpdu = pmon->mon_mpdu;
++
++      ath12k_dp_mon_parse_rx_msdu_end_err(__le32_to_cpu(msdu_end->info2),
++                                          &mon_mpdu->err_bitmap);
++
++      mon_mpdu->decap_format = le32_get_bits(msdu_end->info1,
++                                             RX_MSDU_END_INFO11_DECAP_FORMAT);
++
++      return 0;
++}
++
++static int
++ath12k_dp_mon_parse_status_buf(struct ath12k *ar,
++                             struct ath12k_mon_data *pmon,
++                             const struct dp_mon_packet_info *packet_info)
++{
++      struct ath12k_base *ab = ar->ab;
++      struct dp_rxdma_mon_ring *buf_ring = &ab->dp.rxdma_mon_buf_ring;
++      struct sk_buff *msdu;
++      int buf_id;
++      u32 offset;
++
++      buf_id = u32_get_bits(packet_info->cookie, DP_RXDMA_BUF_COOKIE_BUF_ID);
++
++      spin_lock_bh(&buf_ring->idr_lock);
++      msdu = idr_remove(&buf_ring->bufs_idr, buf_id);
++      spin_unlock_bh(&buf_ring->idr_lock);
++
++      if (unlikely(!msdu)) {
++              ath12k_warn(ab, "mon dest desc with inval buf_id %d\n", buf_id);
++              return 0;
++      }
++
++      dma_unmap_single(ab->dev, ATH12K_SKB_RXCB(msdu)->paddr,
++                       msdu->len + skb_tailroom(msdu),
++                       DMA_FROM_DEVICE);
++
++      offset = packet_info->dma_length + ATH12K_MON_RX_DOT11_OFFSET;
++      if (ath12k_dp_pkt_set_pktlen(msdu, offset)) {
++              dev_kfree_skb_any(msdu);
++              goto dest_replenish;
++      }
++
++      if (!pmon->mon_mpdu->head)
++              pmon->mon_mpdu->head = msdu;
++      else
++              pmon->mon_mpdu->tail->next = msdu;
++
++      pmon->mon_mpdu->tail = msdu;
++
++dest_replenish:
++      ath12k_dp_mon_buf_replenish(ab, buf_ring, 1);
++
++      return 0;
++}
++
++static int
++ath12k_dp_mon_parse_rx_dest_tlv(struct ath12k *ar,
++                              struct ath12k_mon_data *pmon,
++                              enum hal_rx_mon_status hal_status,
++                              const void *tlv_data)
++{
++      switch (hal_status) {
++      case HAL_RX_MON_STATUS_MPDU_START:
++              if (WARN_ON_ONCE(pmon->mon_mpdu))
++                      break;
++
++              pmon->mon_mpdu = kzalloc(sizeof(*pmon->mon_mpdu), GFP_ATOMIC);
++              if (!pmon->mon_mpdu)
++                      return -ENOMEM;
++              break;
++      case HAL_RX_MON_STATUS_BUF_ADDR:
++              return ath12k_dp_mon_parse_status_buf(ar, pmon, tlv_data);
++      case HAL_RX_MON_STATUS_MPDU_END:
++              /* If no MSDU then free empty MPDU */
++              if (pmon->mon_mpdu->tail) {
++                      pmon->mon_mpdu->tail->next = NULL;
++                      list_add_tail(&pmon->mon_mpdu->list, &pmon->dp_rx_mon_mpdu_list);
++              } else {
++                      kfree(pmon->mon_mpdu);
++              }
++              pmon->mon_mpdu = NULL;
++              break;
++      case HAL_RX_MON_STATUS_MSDU_END:
++              return ath12k_dp_mon_parse_status_msdu_end(pmon, tlv_data);
++      default:
++              break;
++      }
++
++      return 0;
++}
++
+ static enum hal_rx_mon_status
+ ath12k_dp_mon_parse_rx_dest(struct ath12k *ar, struct ath12k_mon_data *pmon,
+                           struct sk_buff *skb)
+@@ -2114,14 +2252,20 @@ ath12k_dp_mon_parse_rx_dest(struct ath12k *ar, struct ath12k_mon_data *pmon,
+                       tlv_len = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_LEN);
+               hal_status = ath12k_dp_mon_rx_parse_status_tlv(ar, pmon, tlv);
++
++              if (ar->monitor_started &&
++                  ath12k_dp_mon_parse_rx_dest_tlv(ar, pmon, hal_status, tlv->value))
++                      return HAL_RX_MON_STATUS_PPDU_DONE;
++
+               ptr += sizeof(*tlv) + tlv_len;
+               ptr = PTR_ALIGN(ptr, HAL_TLV_64_ALIGN);
+-              if ((ptr - skb->data) >= DP_RX_BUFFER_SIZE)
++              if ((ptr - skb->data) > skb->len)
+                       break;
+       } while ((hal_status == HAL_RX_MON_STATUS_PPDU_NOT_DONE) ||
+                (hal_status == HAL_RX_MON_STATUS_BUF_ADDR) ||
++               (hal_status == HAL_RX_MON_STATUS_MPDU_START) ||
+                (hal_status == HAL_RX_MON_STATUS_MPDU_END) ||
+                (hal_status == HAL_RX_MON_STATUS_MSDU_END));
+@@ -2142,9 +2286,11 @@ ath12k_dp_mon_rx_parse_mon_status(struct ath12k *ar,
+       struct dp_mon_mpdu *tmp;
+       struct dp_mon_mpdu *mon_mpdu = pmon->mon_mpdu;
+       struct sk_buff *head_msdu, *tail_msdu;
+-      enum hal_rx_mon_status hal_status = HAL_RX_MON_STATUS_BUF_DONE;
++      enum hal_rx_mon_status hal_status;
+-      ath12k_dp_mon_parse_rx_dest(ar, pmon, skb);
++      hal_status = ath12k_dp_mon_parse_rx_dest(ar, pmon, skb);
++      if (hal_status != HAL_RX_MON_STATUS_PPDU_DONE)
++              return hal_status;
+       list_for_each_entry_safe(mon_mpdu, tmp, &pmon->dp_rx_mon_mpdu_list, list) {
+               list_del(&mon_mpdu->list);
+@@ -2158,6 +2304,7 @@ ath12k_dp_mon_rx_parse_mon_status(struct ath12k *ar,
+               kfree(mon_mpdu);
+       }
++
+       return hal_status;
+ }
+@@ -3346,7 +3493,7 @@ int ath12k_dp_mon_srng_process(struct ath12k *ar, int *budget,
+               ath12k_dp_mon_rx_memset_ppdu_info(ppdu_info);
+       while ((skb = __skb_dequeue(&skb_list))) {
+-              hal_status = ath12k_dp_mon_parse_rx_dest(ar, pmon, skb);
++              hal_status = ath12k_dp_mon_rx_parse_mon_status(ar, pmon, skb, napi);
+               if (hal_status != HAL_RX_MON_STATUS_PPDU_DONE) {
+                       ppdu_info->ppdu_continuation = true;
+                       dev_kfree_skb_any(skb);
+diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h
+index e4368eb42aca8..b039f6b9277c6 100644
+--- a/drivers/net/wireless/ath/ath12k/dp_mon.h
++++ b/drivers/net/wireless/ath/ath12k/dp_mon.h
+@@ -1,7 +1,7 @@
+ /* SPDX-License-Identifier: BSD-3-Clause-Clear */
+ /*
+  * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
+- * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
++ * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+  */
+ #ifndef ATH12K_DP_MON_H
+@@ -9,6 +9,8 @@
+ #include "core.h"
++#define ATH12K_MON_RX_DOT11_OFFSET    5
++
+ enum dp_monitor_mode {
+       ATH12K_DP_TX_MONITOR_MODE,
+       ATH12K_DP_RX_MONITOR_MODE
+diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
+index 125ccbd0532ce..d6794c753f3ae 100644
+--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
++++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
+@@ -4482,6 +4482,8 @@ int ath12k_dp_rx_pdev_mon_attach(struct ath12k *ar)
+       pmon->mon_last_linkdesc_paddr = 0;
+       pmon->mon_last_buf_cookie = DP_RX_DESC_COOKIE_MAX + 1;
++      INIT_LIST_HEAD(&pmon->dp_rx_mon_mpdu_list);
++      pmon->mon_mpdu = NULL;
+       spin_lock_init(&pmon->mon_lock);
+       return 0;
+diff --git a/drivers/net/wireless/ath/ath12k/hal_rx.h b/drivers/net/wireless/ath/ath12k/hal_rx.h
+index 6bdcd0867d86e..6f10e4222ba6e 100644
+--- a/drivers/net/wireless/ath/ath12k/hal_rx.h
++++ b/drivers/net/wireless/ath/ath12k/hal_rx.h
+@@ -108,11 +108,12 @@ enum hal_rx_mon_status {
+       HAL_RX_MON_STATUS_PPDU_DONE,
+       HAL_RX_MON_STATUS_BUF_DONE,
+       HAL_RX_MON_STATUS_BUF_ADDR,
++      HAL_RX_MON_STATUS_MPDU_START,
+       HAL_RX_MON_STATUS_MPDU_END,
+       HAL_RX_MON_STATUS_MSDU_END,
+ };
+-#define HAL_RX_MAX_MPDU               256
++#define HAL_RX_MAX_MPDU                               1024
+ #define HAL_RX_NUM_WORDS_PER_PPDU_BITMAP      (HAL_RX_MAX_MPDU >> 5)
+ struct hal_rx_user_status {
+@@ -506,6 +507,15 @@ struct hal_rx_mpdu_start {
+       __le32 rsvd2[16];
+ } __packed;
++struct hal_rx_msdu_end {
++      __le32 info0;
++      __le32 rsvd0[18];
++      __le32 info1;
++      __le32 rsvd1[10];
++      __le32 info2;
++      __le32 rsvd2;
++} __packed;
++
+ #define HAL_RX_PPDU_END_DURATION      GENMASK(23, 0)
+ struct hal_rx_ppdu_end_duration {
+       __le32 rsvd0[9];
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-ath12k-add-msdu-length-validation-for-tkip-mic-.patch b/queue-6.15/wifi-ath12k-add-msdu-length-validation-for-tkip-mic-.patch
new file mode 100644 (file)
index 0000000..64f4994
--- /dev/null
@@ -0,0 +1,55 @@
+From 0f008816bc15f9478ce765ad58d7620d0c33f379 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Apr 2025 07:49:03 +0530
+Subject: wifi: ath12k: Add MSDU length validation for TKIP MIC error
+
+From: P Praneesh <quic_ppranees@quicinc.com>
+
+[ Upstream commit 763216fe6c5df95d122c71ef34c342427c987820 ]
+
+In the WBM error path, while processing TKIP MIC errors, MSDU length
+is fetched from the hal_rx_desc's msdu_end. This MSDU length is
+directly passed to skb_put() without validation. In stress test
+scenarios, the WBM error ring may receive invalid descriptors, which
+could lead to an invalid MSDU length.
+
+To fix this, add a check to drop the skb when the calculated MSDU
+length is greater than the skb size.
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1
+Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
+
+Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices")
+Signed-off-by: P Praneesh <quic_ppranees@quicinc.com>
+Signed-off-by: Nithyanantham Paramasivam <nithyanantham.paramasivam@oss.qualcomm.com>
+Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
+Link: https://patch.msgid.link/20250416021903.3178962-1-nithyanantham.paramasivam@oss.qualcomm.com
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/dp_rx.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
+index 70afb3bd39202..317cc6e6e1f5b 100644
+--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
++++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
+@@ -3824,6 +3824,15 @@ static bool ath12k_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff *msdu,
+       l3pad_bytes = ath12k_dp_rx_h_l3pad(ab, desc);
+       msdu_len = ath12k_dp_rx_h_msdu_len(ab, desc);
++
++      if ((hal_rx_desc_sz + l3pad_bytes + msdu_len) > DP_RX_BUFFER_SIZE) {
++              ath12k_dbg(ab, ATH12K_DBG_DATA,
++                         "invalid msdu len in tkip mic err %u\n", msdu_len);
++              ath12k_dbg_dump(ab, ATH12K_DBG_DATA, NULL, "", desc,
++                              sizeof(*desc));
++              return true;
++      }
++
+       skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len);
+       skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes);
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-ath12k-add-rx_info-to-capture-required-field-fr.patch b/queue-6.15/wifi-ath12k-add-rx_info-to-capture-required-field-fr.patch
new file mode 100644 (file)
index 0000000..2fed92c
--- /dev/null
@@ -0,0 +1,282 @@
+From 0b9f413b8abb0798ce8800f1f4fd20d3d30a8e78 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Apr 2025 23:59:16 +0530
+Subject: wifi: ath12k: add rx_info to capture required field from rx
+ descriptor
+
+From: P Praneesh <praneesh.p@oss.qualcomm.com>
+
+[ Upstream commit e88e6e3c9ada84ceed3fa223ce11af94fcaf3ad3 ]
+
+In ath12k_dp_rx_h_mpdu(), as part of undecap to native wifi mode, the rx
+descriptor memory is getting overwritten. After this function call, all
+the rx descriptor related memory accesses give invalid values. To handle
+this scenario, introduce a new structure ath12k_dp_rx_info which
+pre-caches all the required fields from the rx descriptor before calling
+ath12k_dp_rx_h_ppdu(). This rx_info structure will be used in the next
+patch.
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
+Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
+
+Co-developed-by: Karthikeyan Periyasamy <karthikeyan.periyasamy@oss.qualcomm.com>
+Signed-off-by: Karthikeyan Periyasamy <karthikeyan.periyasamy@oss.qualcomm.com>
+Signed-off-by: P Praneesh <praneesh.p@oss.qualcomm.com>
+Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
+Link: https://patch.msgid.link/20250402182917.2715596-2-praneesh.p@oss.qualcomm.com
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Stable-dep-of: f5d6b15d9503 ("wifi: ath12k: fix wrong handling of CCMP256 and GCMP ciphers")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/dp_rx.c | 80 ++++++++++++++++++-------
+ drivers/net/wireless/ath/ath12k/dp_rx.h | 18 ++++++
+ 2 files changed, 78 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
+index eaba698267685..dcbd97975f642 100644
+--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
++++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
+@@ -2405,6 +2405,30 @@ static void ath12k_dp_rx_h_rate(struct ath12k *ar, struct hal_rx_desc *rx_desc,
+       }
+ }
++static void ath12k_dp_rx_h_fetch_info(struct ath12k_base *ab,
++                                    struct hal_rx_desc *rx_desc,
++                                    struct ath12k_dp_rx_info *rx_info)
++{
++      rx_info->ip_csum_fail = ath12k_dp_rx_h_ip_cksum_fail(ab, rx_desc);
++      rx_info->l4_csum_fail = ath12k_dp_rx_h_l4_cksum_fail(ab, rx_desc);
++      rx_info->is_mcbc = ath12k_dp_rx_h_is_da_mcbc(ab, rx_desc);
++      rx_info->decap_type = ath12k_dp_rx_h_decap_type(ab, rx_desc);
++      rx_info->pkt_type = ath12k_dp_rx_h_pkt_type(ab, rx_desc);
++      rx_info->sgi = ath12k_dp_rx_h_sgi(ab, rx_desc);
++      rx_info->rate_mcs = ath12k_dp_rx_h_rate_mcs(ab, rx_desc);
++      rx_info->bw = ath12k_dp_rx_h_rx_bw(ab, rx_desc);
++      rx_info->nss = ath12k_dp_rx_h_nss(ab, rx_desc);
++      rx_info->tid = ath12k_dp_rx_h_tid(ab, rx_desc);
++      rx_info->peer_id = ath12k_dp_rx_h_peer_id(ab, rx_desc);
++      rx_info->phy_meta_data = ath12k_dp_rx_h_freq(ab, rx_desc);
++
++      if (ath12k_dp_rxdesc_mac_addr2_valid(ab, rx_desc)) {
++              ether_addr_copy(rx_info->addr2,
++                              ath12k_dp_rxdesc_get_mpdu_start_addr2(ab, rx_desc));
++              rx_info->addr2_present = true;
++      }
++}
++
+ void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct hal_rx_desc *rx_desc,
+                        struct ieee80211_rx_status *rx_status)
+ {
+@@ -2567,7 +2591,7 @@ static bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab,
+ static int ath12k_dp_rx_process_msdu(struct ath12k *ar,
+                                    struct sk_buff *msdu,
+                                    struct sk_buff_head *msdu_list,
+-                                   struct ieee80211_rx_status *rx_status)
++                                   struct ath12k_dp_rx_info *rx_info)
+ {
+       struct ath12k_base *ab = ar->ab;
+       struct hal_rx_desc *rx_desc, *lrx_desc;
+@@ -2627,10 +2651,11 @@ static int ath12k_dp_rx_process_msdu(struct ath12k *ar,
+               goto free_out;
+       }
+-      ath12k_dp_rx_h_ppdu(ar, rx_desc, rx_status);
+-      ath12k_dp_rx_h_mpdu(ar, msdu, rx_desc, rx_status);
++      ath12k_dp_rx_h_fetch_info(ab, rx_desc, rx_info);
++      ath12k_dp_rx_h_ppdu(ar, rx_desc, rx_info->rx_status);
++      ath12k_dp_rx_h_mpdu(ar, msdu, rx_desc, rx_info->rx_status);
+-      rx_status->flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED;
++      rx_info->rx_status->flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED;
+       return 0;
+@@ -2650,12 +2675,16 @@ static void ath12k_dp_rx_process_received_packets(struct ath12k_base *ab,
+       struct ath12k *ar;
+       struct ath12k_hw_link *hw_links = ag->hw_links;
+       struct ath12k_base *partner_ab;
++      struct ath12k_dp_rx_info rx_info;
+       u8 hw_link_id, pdev_id;
+       int ret;
+       if (skb_queue_empty(msdu_list))
+               return;
++      rx_info.addr2_present = false;
++      rx_info.rx_status = &rx_status;
++
+       rcu_read_lock();
+       while ((msdu = __skb_dequeue(msdu_list))) {
+@@ -2676,7 +2705,7 @@ static void ath12k_dp_rx_process_received_packets(struct ath12k_base *ab,
+                       continue;
+               }
+-              ret = ath12k_dp_rx_process_msdu(ar, msdu, msdu_list, &rx_status);
++              ret = ath12k_dp_rx_process_msdu(ar, msdu, msdu_list, &rx_info);
+               if (ret) {
+                       ath12k_dbg(ab, ATH12K_DBG_DATA,
+                                  "Unable to process msdu %d", ret);
+@@ -2977,6 +3006,7 @@ static int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, struct ath12k_peer
+       struct ieee80211_rx_status *rxs = IEEE80211_SKB_RXCB(msdu);
+       struct ieee80211_key_conf *key_conf;
+       struct ieee80211_hdr *hdr;
++      struct ath12k_dp_rx_info rx_info;
+       u8 mic[IEEE80211_CCMP_MIC_LEN];
+       int head_len, tail_len, ret;
+       size_t data_len;
+@@ -2987,6 +3017,9 @@ static int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, struct ath12k_peer
+       if (ath12k_dp_rx_h_enctype(ab, rx_desc) != HAL_ENCRYPT_TYPE_TKIP_MIC)
+               return 0;
++      rx_info.addr2_present = false;
++      rx_info.rx_status = rxs;
++
+       hdr = (struct ieee80211_hdr *)(msdu->data + hal_rx_desc_sz);
+       hdr_len = ieee80211_hdrlen(hdr->frame_control);
+       head_len = hdr_len + hal_rx_desc_sz + IEEE80211_TKIP_IV_LEN;
+@@ -3013,6 +3046,8 @@ static int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, struct ath12k_peer
+       (ATH12K_SKB_RXCB(msdu))->is_first_msdu = true;
+       (ATH12K_SKB_RXCB(msdu))->is_last_msdu = true;
++      ath12k_dp_rx_h_fetch_info(ab, rx_desc, &rx_info);
++
+       rxs->flag |= RX_FLAG_MMIC_ERROR | RX_FLAG_MMIC_STRIPPED |
+                   RX_FLAG_IV_STRIPPED | RX_FLAG_DECRYPTED;
+       skb_pull(msdu, hal_rx_desc_sz);
+@@ -3709,7 +3744,7 @@ static void ath12k_dp_rx_null_q_desc_sg_drop(struct ath12k *ar,
+ }
+ static int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu,
+-                                    struct ieee80211_rx_status *status,
++                                    struct ath12k_dp_rx_info *rx_info,
+                                     struct sk_buff_head *msdu_list)
+ {
+       struct ath12k_base *ab = ar->ab;
+@@ -3765,9 +3800,9 @@ static int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu,
+       if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu)))
+               return -EINVAL;
+-      ath12k_dp_rx_h_ppdu(ar, desc, status);
+-
+-      ath12k_dp_rx_h_mpdu(ar, msdu, desc, status);
++      ath12k_dp_rx_h_fetch_info(ab, desc, rx_info);
++      ath12k_dp_rx_h_ppdu(ar, desc, rx_info->rx_status);
++      ath12k_dp_rx_h_mpdu(ar, msdu, desc, rx_info->rx_status);
+       rxcb->tid = ath12k_dp_rx_h_tid(ab, desc);
+@@ -3779,7 +3814,7 @@ static int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu,
+ }
+ static bool ath12k_dp_rx_h_reo_err(struct ath12k *ar, struct sk_buff *msdu,
+-                                 struct ieee80211_rx_status *status,
++                                 struct ath12k_dp_rx_info *rx_info,
+                                  struct sk_buff_head *msdu_list)
+ {
+       struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);
+@@ -3789,7 +3824,7 @@ static bool ath12k_dp_rx_h_reo_err(struct ath12k *ar, struct sk_buff *msdu,
+       switch (rxcb->err_code) {
+       case HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO:
+-              if (ath12k_dp_rx_h_null_q_desc(ar, msdu, status, msdu_list))
++              if (ath12k_dp_rx_h_null_q_desc(ar, msdu, rx_info, msdu_list))
+                       drop = true;
+               break;
+       case HAL_REO_DEST_RING_ERROR_CODE_PN_CHECK_FAILED:
+@@ -3810,7 +3845,7 @@ static bool ath12k_dp_rx_h_reo_err(struct ath12k *ar, struct sk_buff *msdu,
+ }
+ static bool ath12k_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff *msdu,
+-                                      struct ieee80211_rx_status *status)
++                                      struct ath12k_dp_rx_info *rx_info)
+ {
+       struct ath12k_base *ab = ar->ab;
+       u16 msdu_len;
+@@ -3839,18 +3874,18 @@ static bool ath12k_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff *msdu,
+       if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu)))
+               return true;
+-      ath12k_dp_rx_h_ppdu(ar, desc, status);
++      ath12k_dp_rx_h_ppdu(ar, desc, rx_info->rx_status);
+-      status->flag |= (RX_FLAG_MMIC_STRIPPED | RX_FLAG_MMIC_ERROR |
+-                       RX_FLAG_DECRYPTED);
++      rx_info->rx_status->flag |= (RX_FLAG_MMIC_STRIPPED | RX_FLAG_MMIC_ERROR |
++                                   RX_FLAG_DECRYPTED);
+       ath12k_dp_rx_h_undecap(ar, msdu, desc,
+-                             HAL_ENCRYPT_TYPE_TKIP_MIC, status, false);
++                             HAL_ENCRYPT_TYPE_TKIP_MIC, rx_info->rx_status, false);
+       return false;
+ }
+ static bool ath12k_dp_rx_h_rxdma_err(struct ath12k *ar,  struct sk_buff *msdu,
+-                                   struct ieee80211_rx_status *status)
++                                   struct ath12k_dp_rx_info *rx_info)
+ {
+       struct ath12k_base *ab = ar->ab;
+       struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);
+@@ -3865,7 +3900,8 @@ static bool ath12k_dp_rx_h_rxdma_err(struct ath12k *ar,  struct sk_buff *msdu,
+       case HAL_REO_ENTR_RING_RXDMA_ECODE_TKIP_MIC_ERR:
+               err_bitmap = ath12k_dp_rx_h_mpdu_err(ab, rx_desc);
+               if (err_bitmap & HAL_RX_MPDU_ERR_TKIP_MIC) {
+-                      drop = ath12k_dp_rx_h_tkip_mic_err(ar, msdu, status);
++                      ath12k_dp_rx_h_fetch_info(ab, rx_desc, rx_info);
++                      drop = ath12k_dp_rx_h_tkip_mic_err(ar, msdu, rx_info);
+                       break;
+               }
+               fallthrough;
+@@ -3887,14 +3923,18 @@ static void ath12k_dp_rx_wbm_err(struct ath12k *ar,
+ {
+       struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);
+       struct ieee80211_rx_status rxs = {0};
++      struct ath12k_dp_rx_info rx_info;
+       bool drop = true;
++      rx_info.addr2_present = false;
++      rx_info.rx_status = &rxs;
++
+       switch (rxcb->err_rel_src) {
+       case HAL_WBM_REL_SRC_MODULE_REO:
+-              drop = ath12k_dp_rx_h_reo_err(ar, msdu, &rxs, msdu_list);
++              drop = ath12k_dp_rx_h_reo_err(ar, msdu, &rx_info, msdu_list);
+               break;
+       case HAL_WBM_REL_SRC_MODULE_RXDMA:
+-              drop = ath12k_dp_rx_h_rxdma_err(ar, msdu, &rxs);
++              drop = ath12k_dp_rx_h_rxdma_err(ar, msdu, &rx_info);
+               break;
+       default:
+               /* msdu will get freed */
+diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h
+index 88e42365a9d8b..0e7cec42a8d13 100644
+--- a/drivers/net/wireless/ath/ath12k/dp_rx.h
++++ b/drivers/net/wireless/ath/ath12k/dp_rx.h
+@@ -65,6 +65,24 @@ struct ath12k_dp_rx_rfc1042_hdr {
+       __be16 snap_type;
+ } __packed;
++struct ath12k_dp_rx_info {
++      struct ieee80211_rx_status *rx_status;
++      u32 phy_meta_data;
++      u16 peer_id;
++      u8 decap_type;
++      u8 pkt_type;
++      u8 sgi;
++      u8 rate_mcs;
++      u8 bw;
++      u8 nss;
++      u8 addr2[ETH_ALEN];
++      u8 tid;
++      bool ip_csum_fail;
++      bool l4_csum_fail;
++      bool is_mcbc;
++      bool addr2_present;
++};
++
+ static inline u32 ath12k_he_gi_to_nl80211_he_gi(u8 sgi)
+ {
+       u32 ret = 0;
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-ath12k-avoid-fetch-error-bitmap-and-decap-forma.patch b/queue-6.15/wifi-ath12k-avoid-fetch-error-bitmap-and-decap-forma.patch
new file mode 100644 (file)
index 0000000..7f64e02
--- /dev/null
@@ -0,0 +1,200 @@
+From 93f2ef7f5ebade8f04fed3d820ee6204bdf903da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Mar 2025 11:55:11 +0530
+Subject: wifi: ath12k: Avoid fetch Error bitmap and decap format from Rx TLV
+
+From: P Praneesh <quic_ppranees@quicinc.com>
+
+[ Upstream commit a6621bf6397ae6981b5041ba0a127e7dbeade746 ]
+
+Currently, error bitmap and decap format information are fetched from the
+MSDU Rx TLV data. This logic is inherited from ath11k. However, for ath12k
+802.11be hardware, the Rx TLV will not be present in the MSDU data.
+Instead, this information is reported separately under the MSDU END TLV
+tag. Therefore, remove the existing fetch code, handle the MSDU END TLV
+tag and fetch the above information to store it in the mon_mpdu data
+structure for use in the merge MSDU procedure.
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1
+Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
+
+Signed-off-by: P Praneesh <quic_ppranees@quicinc.com>
+Tested-by: Nicolas Escande <nico.escande@gmail.com>
+Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
+Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
+Link: https://patch.msgid.link/20250324062518.2752822-4-quic_periyasa@quicinc.com
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Stable-dep-of: f5d6b15d9503 ("wifi: ath12k: fix wrong handling of CCMP256 and GCMP ciphers")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/dp_mon.c | 58 ++++++++++--------------
+ 1 file changed, 23 insertions(+), 35 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c
+index 8c78f601f70aa..6fc3b92117656 100644
+--- a/drivers/net/wireless/ath/ath12k/dp_mon.c
++++ b/drivers/net/wireless/ath/ath12k/dp_mon.c
+@@ -1702,30 +1702,26 @@ static void ath12k_dp_mon_rx_msdus_set_payload(struct ath12k *ar,
+ static struct sk_buff *
+ ath12k_dp_mon_rx_merg_msdus(struct ath12k *ar,
+-                          struct sk_buff *head_msdu, struct sk_buff *tail_msdu,
+-                          struct ieee80211_rx_status *rxs, bool *fcs_err)
++                          struct dp_mon_mpdu *mon_mpdu,
++                          struct ieee80211_rx_status *rxs)
+ {
+       struct ath12k_base *ab = ar->ab;
+       struct sk_buff *msdu, *mpdu_buf, *prev_buf, *head_frag_list;
++      struct sk_buff *head_msdu, *tail_msdu;
+       struct hal_rx_desc *rx_desc, *tail_rx_desc;
+-      u8 *hdr_desc, *dest, decap_format;
++      u8 *hdr_desc, *dest, decap_format = mon_mpdu->decap_format;
+       struct ieee80211_hdr_3addr *wh;
+-      u32 err_bitmap, frag_list_sum_len = 0;
++      u32 frag_list_sum_len = 0;
+       mpdu_buf = NULL;
++      head_msdu = mon_mpdu->head;
++      tail_msdu = mon_mpdu->tail;
+       if (!head_msdu)
+               goto err_merge_fail;
+-      rx_desc = (struct hal_rx_desc *)head_msdu->data;
+       tail_rx_desc = (struct hal_rx_desc *)tail_msdu->data;
+-      err_bitmap = ath12k_dp_rx_h_mpdu_err(ab, tail_rx_desc);
+-      if (err_bitmap & HAL_RX_MPDU_ERR_FCS)
+-              *fcs_err = true;
+-
+-      decap_format = ath12k_dp_rx_h_decap_type(ab, tail_rx_desc);
+-
+       ath12k_dp_rx_h_ppdu(ar, tail_rx_desc, rxs);
+       if (decap_format == DP_RX_DECAP_TYPE_RAW) {
+@@ -1954,7 +1950,8 @@ static void ath12k_dp_mon_update_radiotap(struct ath12k *ar,
+ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi,
+                                         struct sk_buff *msdu,
+-                                        struct ieee80211_rx_status *status)
++                                        struct ieee80211_rx_status *status,
++                                        u8 decap)
+ {
+       static const struct ieee80211_radiotap_he known = {
+               .data1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN |
+@@ -1966,7 +1963,6 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct
+       struct ieee80211_sta *pubsta = NULL;
+       struct ath12k_peer *peer;
+       struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);
+-      u8 decap = DP_RX_DECAP_TYPE_RAW;
+       bool is_mcbc = rxcb->is_mcbc;
+       bool is_eapol_tkip = rxcb->is_eapol;
+@@ -1977,8 +1973,6 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct
+               status->flag |= RX_FLAG_RADIOTAP_HE;
+       }
+-      if (!(status->flag & RX_FLAG_ONLY_MONITOR))
+-              decap = ath12k_dp_rx_h_decap_type(ar->ab, rxcb->rx_desc);
+       spin_lock_bh(&ar->ab->base_lock);
+       peer = ath12k_dp_rx_h_find_peer(ar->ab, msdu);
+       if (peer && peer->sta) {
+@@ -2035,25 +2029,23 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct
+ }
+ static int ath12k_dp_mon_rx_deliver(struct ath12k *ar,
+-                                  struct sk_buff *head_msdu, struct sk_buff *tail_msdu,
++                                  struct dp_mon_mpdu *mon_mpdu,
+                                   struct hal_rx_mon_ppdu_info *ppduinfo,
+                                   struct napi_struct *napi)
+ {
+       struct ath12k_pdev_dp *dp = &ar->dp;
+       struct sk_buff *mon_skb, *skb_next, *header;
+       struct ieee80211_rx_status *rxs = &dp->rx_status;
+-      bool fcs_err = false;
++      u8 decap = DP_RX_DECAP_TYPE_RAW;
+-      mon_skb = ath12k_dp_mon_rx_merg_msdus(ar,
+-                                            head_msdu, tail_msdu,
+-                                            rxs, &fcs_err);
++      mon_skb = ath12k_dp_mon_rx_merg_msdus(ar, mon_mpdu, rxs);
+       if (!mon_skb)
+               goto mon_deliver_fail;
+       header = mon_skb;
+       rxs->flag = 0;
+-      if (fcs_err)
++      if (mon_mpdu->err_bitmap & HAL_RX_MPDU_ERR_FCS)
+               rxs->flag = RX_FLAG_FAILED_FCS_CRC;
+       do {
+@@ -2070,8 +2062,12 @@ static int ath12k_dp_mon_rx_deliver(struct ath12k *ar,
+                       rxs->flag |= RX_FLAG_ALLOW_SAME_PN;
+               }
+               rxs->flag |= RX_FLAG_ONLY_MONITOR;
++
++              if (!(rxs->flag & RX_FLAG_ONLY_MONITOR))
++                      decap = mon_mpdu->decap_format;
++
+               ath12k_dp_mon_update_radiotap(ar, ppduinfo, mon_skb, rxs);
+-              ath12k_dp_mon_rx_deliver_msdu(ar, napi, mon_skb, rxs);
++              ath12k_dp_mon_rx_deliver_msdu(ar, napi, mon_skb, rxs, decap);
+               mon_skb = skb_next;
+       } while (mon_skb);
+       rxs->flag = 0;
+@@ -2079,7 +2075,7 @@ static int ath12k_dp_mon_rx_deliver(struct ath12k *ar,
+       return 0;
+ mon_deliver_fail:
+-      mon_skb = head_msdu;
++      mon_skb = mon_mpdu->head;
+       while (mon_skb) {
+               skb_next = mon_skb->next;
+               dev_kfree_skb_any(mon_skb);
+@@ -2285,7 +2281,6 @@ ath12k_dp_mon_rx_parse_mon_status(struct ath12k *ar,
+       struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info;
+       struct dp_mon_mpdu *tmp;
+       struct dp_mon_mpdu *mon_mpdu = pmon->mon_mpdu;
+-      struct sk_buff *head_msdu, *tail_msdu;
+       enum hal_rx_mon_status hal_status;
+       hal_status = ath12k_dp_mon_parse_rx_dest(ar, pmon, skb);
+@@ -2294,13 +2289,9 @@ ath12k_dp_mon_rx_parse_mon_status(struct ath12k *ar,
+       list_for_each_entry_safe(mon_mpdu, tmp, &pmon->dp_rx_mon_mpdu_list, list) {
+               list_del(&mon_mpdu->list);
+-              head_msdu = mon_mpdu->head;
+-              tail_msdu = mon_mpdu->tail;
+-              if (head_msdu && tail_msdu) {
+-                      ath12k_dp_mon_rx_deliver(ar, head_msdu,
+-                                               tail_msdu, ppdu_info, napi);
+-              }
++              if (mon_mpdu->head && mon_mpdu->tail)
++                      ath12k_dp_mon_rx_deliver(ar, mon_mpdu, ppdu_info, napi);
+               kfree(mon_mpdu);
+       }
+@@ -2985,16 +2976,13 @@ ath12k_dp_mon_tx_process_ppdu_info(struct ath12k *ar,
+                                  struct dp_mon_tx_ppdu_info *tx_ppdu_info)
+ {
+       struct dp_mon_mpdu *tmp, *mon_mpdu;
+-      struct sk_buff *head_msdu, *tail_msdu;
+       list_for_each_entry_safe(mon_mpdu, tmp,
+                                &tx_ppdu_info->dp_tx_mon_mpdu_list, list) {
+               list_del(&mon_mpdu->list);
+-              head_msdu = mon_mpdu->head;
+-              tail_msdu = mon_mpdu->tail;
+-              if (head_msdu)
+-                      ath12k_dp_mon_rx_deliver(ar, head_msdu, tail_msdu,
++              if (mon_mpdu->head)
++                      ath12k_dp_mon_rx_deliver(ar, mon_mpdu,
+                                                &tx_ppdu_info->rx_status, napi);
+               kfree(mon_mpdu);
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-ath12k-change-the-status-update-in-the-monitor-.patch b/queue-6.15/wifi-ath12k-change-the-status-update-in-the-monitor-.patch
new file mode 100644 (file)
index 0000000..475dcdd
--- /dev/null
@@ -0,0 +1,254 @@
+From 9cf3a35d4537411bd8fd85a0759a471a77b136b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Mar 2025 11:55:13 +0530
+Subject: wifi: ath12k: change the status update in the monitor Rx
+
+From: P Praneesh <quic_ppranees@quicinc.com>
+
+[ Upstream commit 5393dcb4520911f2b4a980e7e3c2c0de2bbf9ec7 ]
+
+Currently, in the monitor Rx path, status is filled from the RX TLV header
+present in the MSDU data. This logic is inherited from ath11k. However, in
+the ath12k 802.11be hardware, the Rx TLV header is not present in the MSDU
+data. This information is reported under various TLV tags. Therefore, avoid
+the existing status filling by accumulating the needed information in the
+PPDU information structure and fill the status.
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1
+Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
+
+Signed-off-by: P Praneesh <quic_ppranees@quicinc.com>
+Tested-by: Nicolas Escande <nico.escande@gmail.com>
+Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
+Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
+Link: https://patch.msgid.link/20250324062518.2752822-6-quic_periyasa@quicinc.com
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Stable-dep-of: f5d6b15d9503 ("wifi: ath12k: fix wrong handling of CCMP256 and GCMP ciphers")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/core.h   |  16 ++-
+ drivers/net/wireless/ath/ath12k/dp_mon.c | 138 ++++++++++++++++++++++-
+ drivers/net/wireless/ath/ath12k/hal_rx.h |   5 +-
+ 3 files changed, 151 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h
+index 2d91a6a4750ca..2ee83517eadc7 100644
+--- a/drivers/net/wireless/ath/ath12k/core.h
++++ b/drivers/net/wireless/ath/ath12k/core.h
+@@ -533,9 +533,19 @@ struct ath12k_sta {
+       enum ieee80211_sta_state state;
+ };
+-#define ATH12K_MIN_5GHZ_FREQ 4150
+-#define ATH12K_MIN_6GHZ_FREQ 5925
+-#define ATH12K_MAX_6GHZ_FREQ 7115
++#define ATH12K_HALF_20MHZ_BW  10
++#define ATH12K_2GHZ_MIN_CENTER        2412
++#define ATH12K_2GHZ_MAX_CENTER        2484
++#define ATH12K_5GHZ_MIN_CENTER        4900
++#define ATH12K_5GHZ_MAX_CENTER        5920
++#define ATH12K_6GHZ_MIN_CENTER        5935
++#define ATH12K_6GHZ_MAX_CENTER        7115
++#define ATH12K_MIN_2GHZ_FREQ  (ATH12K_2GHZ_MIN_CENTER - ATH12K_HALF_20MHZ_BW - 1)
++#define ATH12K_MAX_2GHZ_FREQ  (ATH12K_2GHZ_MAX_CENTER + ATH12K_HALF_20MHZ_BW + 1)
++#define ATH12K_MIN_5GHZ_FREQ  (ATH12K_5GHZ_MIN_CENTER - ATH12K_HALF_20MHZ_BW)
++#define ATH12K_MAX_5GHZ_FREQ  (ATH12K_5GHZ_MAX_CENTER + ATH12K_HALF_20MHZ_BW)
++#define ATH12K_MIN_6GHZ_FREQ  (ATH12K_6GHZ_MIN_CENTER - ATH12K_HALF_20MHZ_BW)
++#define ATH12K_MAX_6GHZ_FREQ  (ATH12K_6GHZ_MAX_CENTER + ATH12K_HALF_20MHZ_BW)
+ #define ATH12K_NUM_CHANS 101
+ #define ATH12K_MAX_5GHZ_CHAN 173
+diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c
+index 6fc3b92117656..9013c6ce94257 100644
+--- a/drivers/net/wireless/ath/ath12k/dp_mon.c
++++ b/drivers/net/wireless/ath/ath12k/dp_mon.c
+@@ -1700,18 +1700,128 @@ static void ath12k_dp_mon_rx_msdus_set_payload(struct ath12k *ar,
+       skb_pull(head_msdu, rx_pkt_offset + l2_hdr_offset);
+ }
++static void
++ath12k_dp_mon_fill_rx_stats_info(struct ath12k *ar,
++                               struct hal_rx_mon_ppdu_info *ppdu_info,
++                               struct ieee80211_rx_status *rx_status)
++{
++      u32 center_freq = ppdu_info->freq;
++
++      rx_status->freq = center_freq;
++      rx_status->bw = ath12k_mac_bw_to_mac80211_bw(ppdu_info->bw);
++      rx_status->nss = ppdu_info->nss;
++      rx_status->rate_idx = 0;
++      rx_status->encoding = RX_ENC_LEGACY;
++      rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
++
++      if (center_freq >= ATH12K_MIN_6GHZ_FREQ &&
++          center_freq <= ATH12K_MAX_6GHZ_FREQ) {
++              rx_status->band = NL80211_BAND_6GHZ;
++      } else if (center_freq >= ATH12K_MIN_2GHZ_FREQ &&
++                 center_freq <= ATH12K_MAX_2GHZ_FREQ) {
++              rx_status->band = NL80211_BAND_2GHZ;
++      } else if (center_freq >= ATH12K_MIN_5GHZ_FREQ &&
++                 center_freq <= ATH12K_MAX_5GHZ_FREQ) {
++              rx_status->band = NL80211_BAND_5GHZ;
++      } else {
++              rx_status->band = NUM_NL80211_BANDS;
++      }
++}
++
++static void
++ath12k_dp_mon_fill_rx_rate(struct ath12k *ar,
++                         struct hal_rx_mon_ppdu_info *ppdu_info,
++                         struct ieee80211_rx_status *rx_status)
++{
++      struct ieee80211_supported_band *sband;
++      enum rx_msdu_start_pkt_type pkt_type;
++      u8 rate_mcs, nss, sgi;
++      bool is_cck;
++
++      pkt_type = ppdu_info->preamble_type;
++      rate_mcs = ppdu_info->rate;
++      nss = ppdu_info->nss;
++      sgi = ppdu_info->gi;
++
++      switch (pkt_type) {
++      case RX_MSDU_START_PKT_TYPE_11A:
++      case RX_MSDU_START_PKT_TYPE_11B:
++              is_cck = (pkt_type == RX_MSDU_START_PKT_TYPE_11B);
++              if (rx_status->band < NUM_NL80211_BANDS) {
++                      sband = &ar->mac.sbands[rx_status->band];
++                      rx_status->rate_idx = ath12k_mac_hw_rate_to_idx(sband, rate_mcs,
++                                                                      is_cck);
++              }
++              break;
++      case RX_MSDU_START_PKT_TYPE_11N:
++              rx_status->encoding = RX_ENC_HT;
++              if (rate_mcs > ATH12K_HT_MCS_MAX) {
++                      ath12k_warn(ar->ab,
++                                  "Received with invalid mcs in HT mode %d\n",
++                                   rate_mcs);
++                      break;
++              }
++              rx_status->rate_idx = rate_mcs + (8 * (nss - 1));
++              if (sgi)
++                      rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
++              break;
++      case RX_MSDU_START_PKT_TYPE_11AC:
++              rx_status->encoding = RX_ENC_VHT;
++              rx_status->rate_idx = rate_mcs;
++              if (rate_mcs > ATH12K_VHT_MCS_MAX) {
++                      ath12k_warn(ar->ab,
++                                  "Received with invalid mcs in VHT mode %d\n",
++                                   rate_mcs);
++                      break;
++              }
++              if (sgi)
++                      rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
++              break;
++      case RX_MSDU_START_PKT_TYPE_11AX:
++              rx_status->rate_idx = rate_mcs;
++              if (rate_mcs > ATH12K_HE_MCS_MAX) {
++                      ath12k_warn(ar->ab,
++                                  "Received with invalid mcs in HE mode %d\n",
++                                  rate_mcs);
++                      break;
++              }
++              rx_status->encoding = RX_ENC_HE;
++              rx_status->he_gi = ath12k_he_gi_to_nl80211_he_gi(sgi);
++              break;
++      case RX_MSDU_START_PKT_TYPE_11BE:
++              rx_status->rate_idx = rate_mcs;
++              if (rate_mcs > ATH12K_EHT_MCS_MAX) {
++                      ath12k_warn(ar->ab,
++                                  "Received with invalid mcs in EHT mode %d\n",
++                                  rate_mcs);
++                      break;
++              }
++              rx_status->encoding = RX_ENC_EHT;
++              rx_status->he_gi = ath12k_he_gi_to_nl80211_he_gi(sgi);
++              break;
++      default:
++              ath12k_dbg(ar->ab, ATH12K_DBG_DATA,
++                         "monitor receives invalid preamble type %d",
++                          pkt_type);
++              break;
++      }
++}
++
+ static struct sk_buff *
+ ath12k_dp_mon_rx_merg_msdus(struct ath12k *ar,
+                           struct dp_mon_mpdu *mon_mpdu,
++                          struct hal_rx_mon_ppdu_info *ppdu_info,
+                           struct ieee80211_rx_status *rxs)
+ {
+       struct ath12k_base *ab = ar->ab;
+       struct sk_buff *msdu, *mpdu_buf, *prev_buf, *head_frag_list;
+       struct sk_buff *head_msdu, *tail_msdu;
+-      struct hal_rx_desc *rx_desc, *tail_rx_desc;
++      struct hal_rx_desc *rx_desc;
+       u8 *hdr_desc, *dest, decap_format = mon_mpdu->decap_format;
+       struct ieee80211_hdr_3addr *wh;
++      struct ieee80211_channel *channel;
+       u32 frag_list_sum_len = 0;
++      u8 channel_num = ppdu_info->chan_num;
+       mpdu_buf = NULL;
+       head_msdu = mon_mpdu->head;
+@@ -1720,9 +1830,29 @@ ath12k_dp_mon_rx_merg_msdus(struct ath12k *ar,
+       if (!head_msdu)
+               goto err_merge_fail;
+-      tail_rx_desc = (struct hal_rx_desc *)tail_msdu->data;
++      ath12k_dp_mon_fill_rx_stats_info(ar, ppdu_info, rxs);
++
++      if (unlikely(rxs->band == NUM_NL80211_BANDS ||
++                   !ath12k_ar_to_hw(ar)->wiphy->bands[rxs->band])) {
++              ath12k_dbg(ar->ab, ATH12K_DBG_DATA,
++                         "sband is NULL for status band %d channel_num %d center_freq %d pdev_id %d\n",
++                         rxs->band, channel_num, ppdu_info->freq, ar->pdev_idx);
++
++              spin_lock_bh(&ar->data_lock);
++              channel = ar->rx_channel;
++              if (channel) {
++                      rxs->band = channel->band;
++                      channel_num =
++                              ieee80211_frequency_to_channel(channel->center_freq);
++              }
++              spin_unlock_bh(&ar->data_lock);
++      }
++
++      if (rxs->band < NUM_NL80211_BANDS)
++              rxs->freq = ieee80211_channel_to_frequency(channel_num,
++                                                         rxs->band);
+-      ath12k_dp_rx_h_ppdu(ar, tail_rx_desc, rxs);
++      ath12k_dp_mon_fill_rx_rate(ar, ppdu_info, rxs);
+       if (decap_format == DP_RX_DECAP_TYPE_RAW) {
+               ath12k_dp_mon_rx_msdus_set_payload(ar, head_msdu, tail_msdu);
+@@ -2038,7 +2168,7 @@ static int ath12k_dp_mon_rx_deliver(struct ath12k *ar,
+       struct ieee80211_rx_status *rxs = &dp->rx_status;
+       u8 decap = DP_RX_DECAP_TYPE_RAW;
+-      mon_skb = ath12k_dp_mon_rx_merg_msdus(ar, mon_mpdu, rxs);
++      mon_skb = ath12k_dp_mon_rx_merg_msdus(ar, mon_mpdu, ppduinfo, rxs);
+       if (!mon_skb)
+               goto mon_deliver_fail;
+diff --git a/drivers/net/wireless/ath/ath12k/hal_rx.h b/drivers/net/wireless/ath/ath12k/hal_rx.h
+index 6f10e4222ba6e..c753eb2a03ad2 100644
+--- a/drivers/net/wireless/ath/ath12k/hal_rx.h
++++ b/drivers/net/wireless/ath/ath12k/hal_rx.h
+@@ -509,7 +509,10 @@ struct hal_rx_mpdu_start {
+ struct hal_rx_msdu_end {
+       __le32 info0;
+-      __le32 rsvd0[18];
++      __le32 rsvd0[9];
++      __le16 info00;
++      __le16 info01;
++      __le32 rsvd00[8];
+       __le32 info1;
+       __le32 rsvd1[10];
+       __le32 info2;
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-ath12k-fix-ath12k_flag_registered-flag-handling.patch b/queue-6.15/wifi-ath12k-fix-ath12k_flag_registered-flag-handling.patch
new file mode 100644 (file)
index 0000000..c0061bc
--- /dev/null
@@ -0,0 +1,96 @@
+From 7c8e6deae645a910ffe66cd08635897c70015c40 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Apr 2025 11:36:32 +0530
+Subject: wifi: ath12k: fix ATH12K_FLAG_REGISTERED flag handling
+
+From: Aditya Kumar Singh <aditya.kumar.singh@oss.qualcomm.com>
+
+[ Upstream commit 6af396942bf132a1a49523e8fe2f816dc1ebd913 ]
+
+Commit a5686ae820fa ("wifi: ath12k: move ATH12K_FLAG_REGISTERED handling to
+ath12k_mac_register()") relocated the setting of the ATH12K_FLAG_REGISTERED
+flag to the ath12k_mac_register() function. However, this function only
+accesses the first device (ab) via ag->ab[0], resulting in the flag being
+set only for the first device in the group. Similarly,
+ath12k_mac_unregister() only unsets the flag for the first device. The flag
+should actually be set for all devices in the group to avoid issues during
+recovery.
+
+Hence, move setting and clearing of this flag in the function
+ath12k_core_hw_group_start() and ath12k_core_hw_group_stop() respectively.
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
+Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
+
+Fixes: a5686ae820fa ("wifi: ath12k: move ATH12K_FLAG_REGISTERED handling to ath12k_mac_register()")
+Signed-off-by: Aditya Kumar Singh <aditya.kumar.singh@oss.qualcomm.com>
+Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
+Link: https://patch.msgid.link/20250408-fix_reboot_issues_with_hw_grouping-v4-4-95e7bf048595@oss.qualcomm.com
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/core.c | 5 +++++
+ drivers/net/wireless/ath/ath12k/mac.c  | 6 ------
+ 2 files changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
+index 0b2dec081c6ee..34eaa6b5bf772 100644
+--- a/drivers/net/wireless/ath/ath12k/core.c
++++ b/drivers/net/wireless/ath/ath12k/core.c
+@@ -891,6 +891,9 @@ static void ath12k_core_hw_group_stop(struct ath12k_hw_group *ag)
+               ab = ag->ab[i];
+               if (!ab)
+                       continue;
++
++              clear_bit(ATH12K_FLAG_REGISTERED, &ab->dev_flags);
++
+               ath12k_core_device_cleanup(ab);
+       }
+@@ -1026,6 +1029,8 @@ static int ath12k_core_hw_group_start(struct ath12k_hw_group *ag)
+               mutex_lock(&ab->core_lock);
++              set_bit(ATH12K_FLAG_REGISTERED, &ab->dev_flags);
++
+               ret = ath12k_core_pdev_create(ab);
+               if (ret) {
+                       ath12k_err(ab, "failed to create pdev core %d\n", ret);
+diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
+index 3883dab6771b8..bd67140688290 100644
+--- a/drivers/net/wireless/ath/ath12k/mac.c
++++ b/drivers/net/wireless/ath/ath12k/mac.c
+@@ -11569,7 +11569,6 @@ void ath12k_mac_mlo_teardown(struct ath12k_hw_group *ag)
+ int ath12k_mac_register(struct ath12k_hw_group *ag)
+ {
+-      struct ath12k_base *ab = ag->ab[0];
+       struct ath12k_hw *ah;
+       int i;
+       int ret;
+@@ -11582,8 +11581,6 @@ int ath12k_mac_register(struct ath12k_hw_group *ag)
+                       goto err;
+       }
+-      set_bit(ATH12K_FLAG_REGISTERED, &ab->dev_flags);
+-
+       return 0;
+ err:
+@@ -11600,12 +11597,9 @@ int ath12k_mac_register(struct ath12k_hw_group *ag)
+ void ath12k_mac_unregister(struct ath12k_hw_group *ag)
+ {
+-      struct ath12k_base *ab = ag->ab[0];
+       struct ath12k_hw *ah;
+       int i;
+-      clear_bit(ATH12K_FLAG_REGISTERED, &ab->dev_flags);
+-
+       for (i = ag->num_hw - 1; i >= 0; i--) {
+               ah = ath12k_ag_to_ah(ag, i);
+               if (!ah)
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-ath12k-fix-buffer-overflow-in-debugfs.patch b/queue-6.15/wifi-ath12k-fix-buffer-overflow-in-debugfs.patch
new file mode 100644 (file)
index 0000000..1904745
--- /dev/null
@@ -0,0 +1,39 @@
+From 09e90408927e4c4b69e058a048067e27d744df95 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Apr 2025 14:01:25 +0300
+Subject: wifi: ath12k: Fix buffer overflow in debugfs
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 8c7a5031a6b0d42e640fbd2d5d05f61f74e32dce ]
+
+If the user tries to write more than 32 bytes then it results in memory
+corruption.  Fortunately, this is debugfs so it's limited to root users.
+
+Fixes: 3f73c24f28b3 ("wifi: ath12k: Add support to enable debugfs_htt_stats")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
+Link: https://patch.msgid.link/35daefbd-d493-41d9-b192-96177d521b40@stanley.mountain
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/debugfs_htt_stats.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.c b/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.c
+index 1c0d5fa39a8dc..aeaf970339d4d 100644
+--- a/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.c
++++ b/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.c
+@@ -5377,6 +5377,9 @@ static ssize_t ath12k_write_htt_stats_type(struct file *file,
+       const int size = 32;
+       int num_args;
++      if (count > size)
++              return -EINVAL;
++
+       char *buf __free(kfree) = kzalloc(size, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-ath12k-fix-cleanup-path-after-mhi-init.patch b/queue-6.15/wifi-ath12k-fix-cleanup-path-after-mhi-init.patch
new file mode 100644 (file)
index 0000000..dc71956
--- /dev/null
@@ -0,0 +1,48 @@
+From 8d5f632bb958c25b378eca185250fbcca2d8421d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Apr 2025 15:34:29 +0530
+Subject: wifi: ath12k: fix cleanup path after mhi init
+
+From: Raj Kumar Bhagat <quic_rajkbhag@quicinc.com>
+
+[ Upstream commit 6177c97fb6f05bf0473a2806e3bece7e77693209 ]
+
+Currently, the 'err_pci_msi_free' label is misplaced, causing the cleanup
+sequence to be incorrect. Fix this by moving the 'err_pci_msi_free' label
+to the correct position after 'err_irq_affinity_cleanup'.
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00209-QCAHKSWPL_SILICONZ-1
+
+Fixes: a3012f206d07 ("wifi: ath12k: set IRQ affinity to CPU0 in case of one MSI vector")
+Signed-off-by: Raj Kumar Bhagat <quic_rajkbhag@quicinc.com>
+Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
+Link: https://patch.msgid.link/20250403-ath12k-cleanup-v1-1-ad8f67b0e9cf@quicinc.com
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/pci.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c
+index b474696ac6d8c..99b2c7927ec81 100644
+--- a/drivers/net/wireless/ath/ath12k/pci.c
++++ b/drivers/net/wireless/ath/ath12k/pci.c
+@@ -1710,12 +1710,12 @@ static int ath12k_pci_probe(struct pci_dev *pdev,
+ err_mhi_unregister:
+       ath12k_mhi_unregister(ab_pci);
+-err_pci_msi_free:
+-      ath12k_pci_msi_free(ab_pci);
+-
+ err_irq_affinity_cleanup:
+       ath12k_pci_set_irq_affinity_hint(ab_pci, NULL);
++err_pci_msi_free:
++      ath12k_pci_msi_free(ab_pci);
++
+ err_pci_free_region:
+       ath12k_pci_free_region(ab_pci);
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-ath12k-fix-invalid-access-to-memory.patch b/queue-6.15/wifi-ath12k-fix-invalid-access-to-memory.patch
new file mode 100644 (file)
index 0000000..47c6c5b
--- /dev/null
@@ -0,0 +1,64 @@
+From 3d45362404f3c8c66c510ec738790926e70ba9c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Apr 2025 10:23:27 +0530
+Subject: wifi: ath12k: fix invalid access to memory
+
+From: Sarika Sharma <quic_sarishar@quicinc.com>
+
+[ Upstream commit 9f17747fbda6fca934854463873c4abf8061491d ]
+
+In ath12k_dp_rx_msdu_coalesce(), rxcb is fetched from skb and boolean
+is_continuation is part of rxcb.
+Currently, after freeing the skb, the rxcb->is_continuation accessed
+again which is wrong since the memory is already freed.
+This might lead use-after-free error.
+
+Hence, fix by locally defining bool is_continuation from rxcb,
+so that after freeing skb, is_continuation can be used.
+
+Compile tested only.
+
+Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices")
+Signed-off-by: Sarika Sharma <quic_sarishar@quicinc.com>
+Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
+Link: https://patch.msgid.link/20250408045327.1632222-1-quic_sarishar@quicinc.com
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/dp_rx.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
+index 21d240cc3aee4..70afb3bd39202 100644
+--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
++++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
+@@ -1817,6 +1817,7 @@ static int ath12k_dp_rx_msdu_coalesce(struct ath12k *ar,
+       struct hal_rx_desc *ldesc;
+       int space_extra, rem_len, buf_len;
+       u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz;
++      bool is_continuation;
+       /* As the msdu is spread across multiple rx buffers,
+        * find the offset to the start of msdu for computing
+@@ -1865,7 +1866,8 @@ static int ath12k_dp_rx_msdu_coalesce(struct ath12k *ar,
+       rem_len = msdu_len - buf_first_len;
+       while ((skb = __skb_dequeue(msdu_list)) != NULL && rem_len > 0) {
+               rxcb = ATH12K_SKB_RXCB(skb);
+-              if (rxcb->is_continuation)
++              is_continuation = rxcb->is_continuation;
++              if (is_continuation)
+                       buf_len = DP_RX_BUFFER_SIZE - hal_rx_desc_sz;
+               else
+                       buf_len = rem_len;
+@@ -1883,7 +1885,7 @@ static int ath12k_dp_rx_msdu_coalesce(struct ath12k *ar,
+               dev_kfree_skb_any(skb);
+               rem_len -= buf_len;
+-              if (!rxcb->is_continuation)
++              if (!is_continuation)
+                       break;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-ath12k-fix-invalid-memory-access-while-forming-.patch b/queue-6.15/wifi-ath12k-fix-invalid-memory-access-while-forming-.patch
new file mode 100644 (file)
index 0000000..9496975
--- /dev/null
@@ -0,0 +1,185 @@
+From f3619d2f6fa057d0221b844f894a16991d4577bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Apr 2025 23:35:43 +0530
+Subject: wifi: ath12k: Fix invalid memory access while forming 802.11 header
+
+From: P Praneesh <praneesh.p@oss.qualcomm.com>
+
+[ Upstream commit be908d2360341f8bbc982fff5a5e4f8030c17f74 ]
+
+While forming the 802.11 header from the rx descriptor, skb_push() is
+performed for the 802.11 header length and then calls
+ath12k_dp_rx_desc_get_dot11_hdr(). Since skb_push() moves the skb->data
+pointer backwards by the 802.11 header length, the rx descriptor points to
+a different memory area than intended, causing invalid information to be
+fetched from the rx descriptor.
+
+Also, when IV and ICV are not stripped from the given MSDU, mac80211
+performs PN validation for these MSDUs, which requires the crypto header.
+Before forming the crypto header from the given rx descriptor, skb_push()
+is performed for the crypto header length, which overwrites the memory
+pointed to by the rx descriptor, causing invalid information to form the
+802.11 header.
+
+Fix these issues by moving all rx descriptor accesses before the skb_push()
+operation which ensures the proper 802.11 headers are generated from the
+given rx descriptor and removing ath12k_dp_rxdesc_get_mpdu_frame_ctrl()
+for filling frame control, as this information is already fetched by
+ath12k_dp_rx_desc_get_dot11_hdr().
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
+Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
+
+Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices")
+Co-developed-by: Karthikeyan Periyasamy <karthikeyan.periyasamy@oss.qualcomm.com>
+Signed-off-by: Karthikeyan Periyasamy <karthikeyan.periyasamy@oss.qualcomm.com>
+Signed-off-by: P Praneesh <praneesh.p@oss.qualcomm.com>
+Link: https://patch.msgid.link/20250402180543.2670947-1-praneesh.p@oss.qualcomm.com
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/dp_rx.c | 27 +++++++++----------------
+ drivers/net/wireless/ath/ath12k/hal.c   | 19 -----------------
+ drivers/net/wireless/ath/ath12k/hal.h   |  1 -
+ 3 files changed, 9 insertions(+), 38 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
+index 75bf4211ad422..21d240cc3aee4 100644
+--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
++++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
+@@ -228,12 +228,6 @@ static void ath12k_dp_rx_desc_get_crypto_header(struct ath12k_base *ab,
+       ab->hal_rx_ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype);
+ }
+-static u16 ath12k_dp_rxdesc_get_mpdu_frame_ctrl(struct ath12k_base *ab,
+-                                              struct hal_rx_desc *desc)
+-{
+-      return ab->hal_rx_ops->rx_desc_get_mpdu_frame_ctl(desc);
+-}
+-
+ static inline u8 ath12k_dp_rx_get_msdu_src_link(struct ath12k_base *ab,
+                                               struct hal_rx_desc *desc)
+ {
+@@ -2122,10 +2116,13 @@ static void ath12k_get_dot11_hdr_from_rx_desc(struct ath12k *ar,
+       struct hal_rx_desc *rx_desc = rxcb->rx_desc;
+       struct ath12k_base *ab = ar->ab;
+       size_t hdr_len, crypto_len;
+-      struct ieee80211_hdr *hdr;
++      struct ieee80211_hdr hdr;
+       u16 qos_ctl;
+-      __le16 fc;
+-      u8 *crypto_hdr;
++      u8 *crypto_hdr, mesh_ctrl;
++
++      ath12k_dp_rx_desc_get_dot11_hdr(ab, rx_desc, &hdr);
++      hdr_len = ieee80211_hdrlen(hdr.frame_control);
++      mesh_ctrl = ath12k_dp_rx_h_mesh_ctl_present(ab, rx_desc);
+       if (!(status->flag & RX_FLAG_IV_STRIPPED)) {
+               crypto_len = ath12k_dp_rx_crypto_param_len(ar, enctype);
+@@ -2133,22 +2130,16 @@ static void ath12k_get_dot11_hdr_from_rx_desc(struct ath12k *ar,
+               ath12k_dp_rx_desc_get_crypto_header(ab, rx_desc, crypto_hdr, enctype);
+       }
+-      fc = cpu_to_le16(ath12k_dp_rxdesc_get_mpdu_frame_ctrl(ab, rx_desc));
+-      hdr_len = ieee80211_hdrlen(fc);
+       skb_push(msdu, hdr_len);
+-      hdr = (struct ieee80211_hdr *)msdu->data;
+-      hdr->frame_control = fc;
+-
+-      /* Get wifi header from rx_desc */
+-      ath12k_dp_rx_desc_get_dot11_hdr(ab, rx_desc, hdr);
++      memcpy(msdu->data, &hdr, min(hdr_len, sizeof(hdr)));
+       if (rxcb->is_mcbc)
+               status->flag &= ~RX_FLAG_PN_VALIDATED;
+       /* Add QOS header */
+-      if (ieee80211_is_data_qos(hdr->frame_control)) {
++      if (ieee80211_is_data_qos(hdr.frame_control)) {
+               qos_ctl = rxcb->tid;
+-              if (ath12k_dp_rx_h_mesh_ctl_present(ab, rx_desc))
++              if (mesh_ctrl)
+                       qos_ctl |= IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT;
+               /* TODO: Add other QoS ctl fields when required */
+diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c
+index cd59ff8e6c7b0..178c242a840e3 100644
+--- a/drivers/net/wireless/ath/ath12k/hal.c
++++ b/drivers/net/wireless/ath/ath12k/hal.c
+@@ -511,11 +511,6 @@ static void ath12k_hw_qcn9274_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc,
+       crypto_hdr[7] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274.mpdu_start.pn[1]);
+ }
+-static u16 ath12k_hw_qcn9274_rx_desc_get_mpdu_frame_ctl(struct hal_rx_desc *desc)
+-{
+-      return __le16_to_cpu(desc->u.qcn9274.mpdu_start.frame_ctrl);
+-}
+-
+ static int ath12k_hal_srng_create_config_qcn9274(struct ath12k_base *ab)
+ {
+       struct ath12k_hal *hal = &ab->hal;
+@@ -736,7 +731,6 @@ const struct hal_rx_ops hal_rx_qcn9274_ops = {
+       .rx_desc_is_da_mcbc = ath12k_hw_qcn9274_rx_desc_is_da_mcbc,
+       .rx_desc_get_dot11_hdr = ath12k_hw_qcn9274_rx_desc_get_dot11_hdr,
+       .rx_desc_get_crypto_header = ath12k_hw_qcn9274_rx_desc_get_crypto_hdr,
+-      .rx_desc_get_mpdu_frame_ctl = ath12k_hw_qcn9274_rx_desc_get_mpdu_frame_ctl,
+       .dp_rx_h_msdu_done = ath12k_hw_qcn9274_dp_rx_h_msdu_done,
+       .dp_rx_h_l4_cksum_fail = ath12k_hw_qcn9274_dp_rx_h_l4_cksum_fail,
+       .dp_rx_h_ip_cksum_fail = ath12k_hw_qcn9274_dp_rx_h_ip_cksum_fail,
+@@ -975,11 +969,6 @@ ath12k_hw_qcn9274_compact_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc,
+               HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274_compact.mpdu_start.pn[1]);
+ }
+-static u16 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_frame_ctl(struct hal_rx_desc *desc)
+-{
+-      return __le16_to_cpu(desc->u.qcn9274_compact.mpdu_start.frame_ctrl);
+-}
+-
+ static bool ath12k_hw_qcn9274_compact_dp_rx_h_msdu_done(struct hal_rx_desc *desc)
+ {
+       return !!le32_get_bits(desc->u.qcn9274_compact.msdu_end.info14,
+@@ -1080,8 +1069,6 @@ const struct hal_rx_ops hal_rx_qcn9274_compact_ops = {
+       .rx_desc_is_da_mcbc = ath12k_hw_qcn9274_compact_rx_desc_is_da_mcbc,
+       .rx_desc_get_dot11_hdr = ath12k_hw_qcn9274_compact_rx_desc_get_dot11_hdr,
+       .rx_desc_get_crypto_header = ath12k_hw_qcn9274_compact_rx_desc_get_crypto_hdr,
+-      .rx_desc_get_mpdu_frame_ctl =
+-              ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_frame_ctl,
+       .dp_rx_h_msdu_done = ath12k_hw_qcn9274_compact_dp_rx_h_msdu_done,
+       .dp_rx_h_l4_cksum_fail = ath12k_hw_qcn9274_compact_dp_rx_h_l4_cksum_fail,
+       .dp_rx_h_ip_cksum_fail = ath12k_hw_qcn9274_compact_dp_rx_h_ip_cksum_fail,
+@@ -1330,11 +1317,6 @@ static void ath12k_hw_wcn7850_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc,
+       crypto_hdr[7] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.wcn7850.mpdu_start.pn[1]);
+ }
+-static u16 ath12k_hw_wcn7850_rx_desc_get_mpdu_frame_ctl(struct hal_rx_desc *desc)
+-{
+-      return __le16_to_cpu(desc->u.wcn7850.mpdu_start.frame_ctrl);
+-}
+-
+ static int ath12k_hal_srng_create_config_wcn7850(struct ath12k_base *ab)
+ {
+       struct ath12k_hal *hal = &ab->hal;
+@@ -1555,7 +1537,6 @@ const struct hal_rx_ops hal_rx_wcn7850_ops = {
+       .rx_desc_is_da_mcbc = ath12k_hw_wcn7850_rx_desc_is_da_mcbc,
+       .rx_desc_get_dot11_hdr = ath12k_hw_wcn7850_rx_desc_get_dot11_hdr,
+       .rx_desc_get_crypto_header = ath12k_hw_wcn7850_rx_desc_get_crypto_hdr,
+-      .rx_desc_get_mpdu_frame_ctl = ath12k_hw_wcn7850_rx_desc_get_mpdu_frame_ctl,
+       .dp_rx_h_msdu_done = ath12k_hw_wcn7850_dp_rx_h_msdu_done,
+       .dp_rx_h_l4_cksum_fail = ath12k_hw_wcn7850_dp_rx_h_l4_cksum_fail,
+       .dp_rx_h_ip_cksum_fail = ath12k_hw_wcn7850_dp_rx_h_ip_cksum_fail,
+diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h
+index 94e2e87359583..3156563c77e5b 100644
+--- a/drivers/net/wireless/ath/ath12k/hal.h
++++ b/drivers/net/wireless/ath/ath12k/hal.h
+@@ -1068,7 +1068,6 @@ struct hal_rx_ops {
+       bool (*rx_desc_is_da_mcbc)(struct hal_rx_desc *desc);
+       void (*rx_desc_get_dot11_hdr)(struct hal_rx_desc *desc,
+                                     struct ieee80211_hdr *hdr);
+-      u16 (*rx_desc_get_mpdu_frame_ctl)(struct hal_rx_desc *desc);
+       void (*rx_desc_get_crypto_header)(struct hal_rx_desc *desc,
+                                         u8 *crypto_hdr,
+                                         enum hal_encrypt_type enctype);
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-ath12k-fix-invalid-rssi-values-in-station-dump.patch b/queue-6.15/wifi-ath12k-fix-invalid-rssi-values-in-station-dump.patch
new file mode 100644 (file)
index 0000000..f8b29c3
--- /dev/null
@@ -0,0 +1,51 @@
+From 6bfbd576feb558c71aa5068e0a66f45141793cbe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Apr 2025 11:21:04 +0530
+Subject: wifi: ath12k: Fix invalid RSSI values in station dump
+
+From: P Praneesh <praneesh.p@oss.qualcomm.com>
+
+[ Upstream commit 3126f1c52af5bc8d40d2c984907daeb501f6b739 ]
+
+When processing a "station dump" command, the driver retrieves RSSI
+values from the HAL_PHYRX_RSSI_LEGACY TLV received from the monitor
+destination ring, and reports them to userspace. Currently, the RSSI
+values reported are improper because the hardware has not been
+configured to update them properly.
+
+To fix this, enable the HTT_RX_FILTER_TLV_FLAGS_PPDU_START_USER_INFO in
+the filter setup to ensure the correct RSSI values are returned in the
+HAL_PHYRX_RSSI_LEGACY TLV, resulting in correct RSSI values being
+reported to userspace.
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00218-QCAHKSWPL_SILICONZ-1
+Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
+
+Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices")
+Signed-off-by: P Praneesh <praneesh.p@oss.qualcomm.com>
+Signed-off-by: Sowjanya vardhineni <quic_svardhin@quicinc.com>
+Reviewed-by: Mahendran P <quic_mahep@quicinc.com>
+Link: https://patch.msgid.link/20250424055104.2503723-1-quic_svardhin@quicinc.com
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/mac.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
+index 65eb50bf03b24..331bcf5e6c4cc 100644
+--- a/drivers/net/wireless/ath/ath12k/mac.c
++++ b/drivers/net/wireless/ath/ath12k/mac.c
+@@ -229,7 +229,8 @@ ath12k_phymodes[NUM_NL80211_BANDS][ATH12K_CHAN_WIDTH_NUM] = {
+ const struct htt_rx_ring_tlv_filter ath12k_mac_mon_status_filter_default = {
+       .rx_filter = HTT_RX_FILTER_TLV_FLAGS_MPDU_START |
+                    HTT_RX_FILTER_TLV_FLAGS_PPDU_END |
+-                   HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE,
++                   HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE |
++                   HTT_RX_FILTER_TLV_FLAGS_PPDU_START_USER_INFO,
+       .pkt_filter_flags0 = HTT_RX_FP_MGMT_FILTER_FLAGS0,
+       .pkt_filter_flags1 = HTT_RX_FP_MGMT_FILTER_FLAGS1,
+       .pkt_filter_flags2 = HTT_RX_FP_CTRL_FILTER_FLASG2,
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-ath12k-fix-memory-corruption-during-mlo-multica.patch b/queue-6.15/wifi-ath12k-fix-memory-corruption-during-mlo-multica.patch
new file mode 100644 (file)
index 0000000..3a5a760
--- /dev/null
@@ -0,0 +1,56 @@
+From 10d65138721b0e6c4cb55f167d1f69e6c5afd553 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Apr 2025 23:27:14 +0530
+Subject: wifi: ath12k: Fix memory corruption during MLO multicast tx
+
+From: P Praneesh <praneesh.p@oss.qualcomm.com>
+
+[ Upstream commit 6f8a27a584b23e9dedefd6cb110dd2587b84a6d4 ]
+
+The struct sk_buff's control buffer is shared by mac80211's struct
+ieee80211_tx_info and ath12k's struct ath12k_skb_cb. When the driver wants
+to transmit an skb, it caches all the mac80211-specific information from
+struct ieee80211_tx_info, then performs a memset on the control buffer
+before writing the ath12k-specific information using struct ath12k_skb_cb.
+However, during multicast tx, the key is being filled into the driver data,
+which overwrites some crucial members like link_id and flags in struct
+ath12k_skb_cb. This causes invalid information retrieval when the driver
+accesses these fields during ath12k_dp_tx(). Fix this issue by removing
+the key filling logic during MLO multicast tx, as it is not used anywhere
+in the tx path.
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
+Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
+
+Fixes: 2f50de725677 ("wifi: ath12k: Add support for MLO Multicast handling in driver")
+Signed-off-by: P Praneesh <praneesh.p@oss.qualcomm.com>
+Link: https://patch.msgid.link/20250402175714.2667270-1-praneesh.p@oss.qualcomm.com
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/mac.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
+index c20fd92000dfe..a1fad297ca357 100644
+--- a/drivers/net/wireless/ath/ath12k/mac.c
++++ b/drivers/net/wireless/ath/ath12k/mac.c
+@@ -7429,7 +7429,6 @@ static void ath12k_mac_op_tx(struct ieee80211_hw *hw,
+                                                               info_flags);
+                       skb_cb = ATH12K_SKB_CB(msdu_copied);
+-                      info = IEEE80211_SKB_CB(msdu_copied);
+                       skb_cb->link_id = link_id;
+                       /* For open mode, skip peer find logic */
+@@ -7452,7 +7451,6 @@ static void ath12k_mac_op_tx(struct ieee80211_hw *hw,
+                       if (key) {
+                               skb_cb->cipher = key->cipher;
+                               skb_cb->flags |= ATH12K_SKB_CIPHER_SET;
+-                              info->control.hw_key = key;
+                               hdr = (struct ieee80211_hdr *)msdu_copied->data;
+                               if (!ieee80211_has_protected(hdr->frame_control))
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-ath12k-fix-memory-leak-during-vdev_id-mismatch.patch b/queue-6.15/wifi-ath12k-fix-memory-leak-during-vdev_id-mismatch.patch
new file mode 100644 (file)
index 0000000..eac99bd
--- /dev/null
@@ -0,0 +1,68 @@
+From 85ba384e1dd7136757d928771c4e10a7e091f5c4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Apr 2025 23:10:32 +0530
+Subject: wifi: ath12k: Fix memory leak during vdev_id mismatch
+
+From: P Praneesh <praneesh.p@oss.qualcomm.com>
+
+[ Upstream commit 75ec94db880b1e4b4f9182885d60db0db6e2ee56 ]
+
+Currently driver enables vdev_id check as part of the bank configuration
+in ath12k_dp_tx_get_vdev_bank_config(). This check ensures that the vdev_id
+configured in the bank register aligns with the vdev_id in the packet's
+address search table within the firmware. If there is a mismatch, the
+firmware forwards the packet with the HTT status
+HAL_WBM_REL_HTT_TX_COMP_STATUS_VDEVID_MISMATCH. Since driver does not
+handle this vdev_id mismatch HTT status, the corresponding buffers are not
+freed properly, causing a memory leak. Fix this issue by adding handling to
+free the buffers when a vdev_id mismatch HTT status is encountered.
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
+Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-
+
+Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices")
+Signed-off-by: P Praneesh <praneesh.p@oss.qualcomm.com>
+Link: https://patch.msgid.link/20250402174032.2651221-1-praneesh.p@oss.qualcomm.com
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/dp_tx.c    | 1 +
+ drivers/net/wireless/ath/ath12k/hal_desc.h | 3 ++-
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.c b/drivers/net/wireless/ath/ath12k/dp_tx.c
+index ced232bf4aed0..1e2788df476c2 100644
+--- a/drivers/net/wireless/ath/ath12k/dp_tx.c
++++ b/drivers/net/wireless/ath/ath12k/dp_tx.c
+@@ -585,6 +585,7 @@ ath12k_dp_tx_process_htt_tx_complete(struct ath12k_base *ab,
+       case HAL_WBM_REL_HTT_TX_COMP_STATUS_TTL:
+       case HAL_WBM_REL_HTT_TX_COMP_STATUS_REINJ:
+       case HAL_WBM_REL_HTT_TX_COMP_STATUS_INSPECT:
++      case HAL_WBM_REL_HTT_TX_COMP_STATUS_VDEVID_MISMATCH:
+               ath12k_dp_tx_free_txbuf(ab, msdu, mac_id, tx_ring);
+               break;
+       case HAL_WBM_REL_HTT_TX_COMP_STATUS_MEC_NOTIFY:
+diff --git a/drivers/net/wireless/ath/ath12k/hal_desc.h b/drivers/net/wireless/ath/ath12k/hal_desc.h
+index 3e8983b85de86..63d279fab3224 100644
+--- a/drivers/net/wireless/ath/ath12k/hal_desc.h
++++ b/drivers/net/wireless/ath/ath12k/hal_desc.h
+@@ -1,7 +1,7 @@
+ /* SPDX-License-Identifier: BSD-3-Clause-Clear */
+ /*
+  * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
+- * Copyright (c) 2021-2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
++ * Copyright (c) 2021-2022, 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+  */
+ #include "core.h"
+@@ -1298,6 +1298,7 @@ enum hal_wbm_htt_tx_comp_status {
+       HAL_WBM_REL_HTT_TX_COMP_STATUS_REINJ,
+       HAL_WBM_REL_HTT_TX_COMP_STATUS_INSPECT,
+       HAL_WBM_REL_HTT_TX_COMP_STATUS_MEC_NOTIFY,
++      HAL_WBM_REL_HTT_TX_COMP_STATUS_VDEVID_MISMATCH,
+       HAL_WBM_REL_HTT_TX_COMP_STATUS_MAX,
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-ath12k-fix-memory-leak-in-ath12k_service_ready_.patch b/queue-6.15/wifi-ath12k-fix-memory-leak-in-ath12k_service_ready_.patch
new file mode 100644 (file)
index 0000000..a0154ea
--- /dev/null
@@ -0,0 +1,65 @@
+From d9825315b30a5203e183726e337d6a5b3673149b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Apr 2025 10:25:38 +0530
+Subject: wifi: ath12k: fix memory leak in ath12k_service_ready_ext_event
+
+From: Rajat Soni <quic_rajson@quicinc.com>
+
+[ Upstream commit 89142d34d5602c7447827beb181fa06eb08b9d5c ]
+
+Currently, in ath12k_service_ready_ext_event(), svc_rdy_ext.mac_phy_caps
+is not freed in the failure case, causing a memory leak. The following
+trace is observed in kmemleak:
+
+unreferenced object 0xffff8b3eb5789c00 (size 1024):
+ comm "softirq", pid 0, jiffies 4294942577
+ hex dump (first 32 bytes):
+   00 00 00 00 01 00 00 00 00 00 00 00 7b 00 00 10  ............{...
+   01 00 00 00 00 00 00 00 01 00 00 00 1f 38 00 00  .............8..
+ backtrace (crc 44e1c357):
+   __kmalloc_noprof+0x30b/0x410
+   ath12k_wmi_mac_phy_caps_parse+0x84/0x100 [ath12k]
+   ath12k_wmi_tlv_iter+0x5e/0x140 [ath12k]
+   ath12k_wmi_svc_rdy_ext_parse+0x308/0x4c0 [ath12k]
+   ath12k_wmi_tlv_iter+0x5e/0x140 [ath12k]
+   ath12k_service_ready_ext_event.isra.0+0x44/0xd0 [ath12k]
+   ath12k_wmi_op_rx+0x2eb/0xd70 [ath12k]
+   ath12k_htc_rx_completion_handler+0x1f4/0x330 [ath12k]
+   ath12k_ce_recv_process_cb+0x218/0x300 [ath12k]
+   ath12k_pci_ce_workqueue+0x1b/0x30 [ath12k]
+   process_one_work+0x219/0x680
+   bh_worker+0x198/0x1f0
+   tasklet_action+0x13/0x30
+   handle_softirqs+0xca/0x460
+   __irq_exit_rcu+0xbe/0x110
+   irq_exit_rcu+0x9/0x30
+
+Free svc_rdy_ext.mac_phy_caps in the error case to fix this memory leak.
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
+
+Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices")
+Signed-off-by: Rajat Soni <quic_rajson@quicinc.com>
+Signed-off-by: Raj Kumar Bhagat <quic_rajkbhag@quicinc.com>
+Link: https://patch.msgid.link/20250430-wmi-mem-leak-v1-1-fcc9b49c2ddc@quicinc.com
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/wmi.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
+index d0705880cd3c9..fe50c3d3cb820 100644
+--- a/drivers/net/wireless/ath/ath12k/wmi.c
++++ b/drivers/net/wireless/ath/ath12k/wmi.c
+@@ -4601,6 +4601,7 @@ static int ath12k_service_ready_ext_event(struct ath12k_base *ab,
+       return 0;
+ err:
++      kfree(svc_rdy_ext.mac_phy_caps);
+       ath12k_wmi_free_dbring_caps(ab);
+       return ret;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-ath12k-fix-node-corruption-in-ar-arvifs-list.patch b/queue-6.15/wifi-ath12k-fix-node-corruption-in-ar-arvifs-list.patch
new file mode 100644 (file)
index 0000000..9e56200
--- /dev/null
@@ -0,0 +1,79 @@
+From 385a50e46ec8eefdc6288a85964da3d06509e415 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Apr 2025 07:47:24 +0530
+Subject: wifi: ath12k: fix node corruption in ar->arvifs list
+
+From: Maharaja Kennadyrajan <maharaja.kennadyrajan@oss.qualcomm.com>
+
+[ Upstream commit 823435bd23108d6f8be89ea2d025c0e2e3769c51 ]
+
+In current WLAN recovery code flow, ath12k_core_halt() only reinitializes
+the "arvifs" list head. This will cause the list node immediately following
+the list head to become an invalid list node. Because the prev of that node
+still points to the list head "arvifs", but the next of the list head
+"arvifs" no longer points to that list node.
+
+When a WLAN recovery occurs during the execution of a vif removal, and it
+happens before the spin_lock_bh(&ar->data_lock) in
+ath12k_mac_vdev_delete(), list_del() will detect the previously mentioned
+situation, thereby triggering a kernel panic.
+
+The fix is to remove and reinitialize all vif list nodes from the list head
+"arvifs" during WLAN halt. The reinitialization is to make the list nodes
+valid, ensuring that the list_del() in ath12k_mac_vdev_delete() can execute
+normally.
+
+Call trace:
+__list_del_entry_valid_or_report+0xd4/0x100 (P)
+ath12k_mac_remove_link_interface.isra.0+0xf8/0x2e4 [ath12k]
+ath12k_scan_vdev_clean_work+0x40/0x164 [ath12k]
+cfg80211_wiphy_work+0xfc/0x100
+process_one_work+0x164/0x2d0
+worker_thread+0x254/0x380
+kthread+0xfc/0x100
+ret_from_fork+0x10/0x20
+
+The change is mostly copied from the ath11k patch:
+https://lore.kernel.org/all/20250320053145.3445187-1-quic_stonez@quicinc.com/
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
+
+Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices")
+Signed-off-by: Maharaja Kennadyrajan <maharaja.kennadyrajan@oss.qualcomm.com>
+Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
+Link: https://patch.msgid.link/20250416021724.2162519-1-maharaja.kennadyrajan@oss.qualcomm.com
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/core.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
+index 34eaa6b5bf772..6b0c719be5434 100644
+--- a/drivers/net/wireless/ath/ath12k/core.c
++++ b/drivers/net/wireless/ath/ath12k/core.c
+@@ -1251,6 +1251,7 @@ static void ath12k_rfkill_work(struct work_struct *work)
+ void ath12k_core_halt(struct ath12k *ar)
+ {
++      struct list_head *pos, *n;
+       struct ath12k_base *ab = ar->ab;
+       lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
+@@ -1266,7 +1267,12 @@ void ath12k_core_halt(struct ath12k *ar)
+       rcu_assign_pointer(ab->pdevs_active[ar->pdev_idx], NULL);
+       synchronize_rcu();
+-      INIT_LIST_HEAD(&ar->arvifs);
++
++      spin_lock_bh(&ar->data_lock);
++      list_for_each_safe(pos, n, &ar->arvifs)
++              list_del_init(pos);
++      spin_unlock_bh(&ar->data_lock);
++
+       idr_init(&ar->txmgmt_idr);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-ath12k-fix-null-access-in-assign-channel-contex.patch b/queue-6.15/wifi-ath12k-fix-null-access-in-assign-channel-contex.patch
new file mode 100644 (file)
index 0000000..7ea0778
--- /dev/null
@@ -0,0 +1,46 @@
+From e1ca36f487ea6869d3060ae3bc292430236ef127 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Mar 2025 11:55:15 +0530
+Subject: wifi: ath12k: fix NULL access in assign channel context handler
+
+From: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
+
+[ Upstream commit ea24531d00f782f4e659e8c74578b7ac144720ca ]
+
+Currently, when ath12k_mac_assign_vif_to_vdev() fails, the radio handle
+(ar) gets accessed from the link VIF handle (arvif) for debug logging, This
+is incorrect. In the fail scenario, radio handle is NULL. Fix the NULL
+access, avoid radio handle access by moving to the hardware debug logging
+helper function (ath12k_hw_warn).
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1
+Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
+
+Fixes: 90570ba4610b ("wifi: ath12k: do not return invalid link id for scan link")
+Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
+Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
+Link: https://patch.msgid.link/20250324062518.2752822-8-quic_periyasa@quicinc.com
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/mac.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
+index dfa05f0ee6c9f..c20fd92000dfe 100644
+--- a/drivers/net/wireless/ath/ath12k/mac.c
++++ b/drivers/net/wireless/ath/ath12k/mac.c
+@@ -9462,8 +9462,8 @@ ath12k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
+       ar = ath12k_mac_assign_vif_to_vdev(hw, arvif, ctx);
+       if (!ar) {
+-              ath12k_warn(arvif->ar->ab, "failed to assign chanctx for vif %pM link id %u link vif is already started",
+-                          vif->addr, link_id);
++              ath12k_hw_warn(ah, "failed to assign chanctx for vif %pM link id %u link vif is already started",
++                             vif->addr, link_id);
+               return -EINVAL;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-ath12k-fix-slub-bug-object-already-free-in-ath1.patch b/queue-6.15/wifi-ath12k-fix-slub-bug-object-already-free-in-ath1.patch
new file mode 100644 (file)
index 0000000..c9f404c
--- /dev/null
@@ -0,0 +1,94 @@
+From 54e55d544367be27dbf9d99a6d8a3af03ab5fb4c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Apr 2025 11:36:29 +0530
+Subject: wifi: ath12k: fix SLUB BUG - Object already free in ath12k_reg_free()
+
+From: Aditya Kumar Singh <aditya.kumar.singh@oss.qualcomm.com>
+
+[ Upstream commit 6d019abc402f58b25a7cab30b2d9af2f3173e4df ]
+
+During rmmod of ath12k module with SLUB debug enabled, following print is
+seen -
+
+=============================================================================
+BUG kmalloc-1k (Not tainted): Object already free
+-----------------------------------------------------------------------------
+
+Allocated in ath12k_reg_build_regd+0x94/0xa20 [ath12k] age=10470 cpu=0 pid=0
+ __kmalloc_noprof+0xf4/0x368
+ ath12k_reg_build_regd+0x94/0xa20 [ath12k]
+ ath12k_wmi_op_rx+0x199c/0x2c14 [ath12k]
+ ath12k_htc_rx_completion_handler+0x398/0x554 [ath12k]
+ ath12k_ce_per_engine_service+0x248/0x368 [ath12k]
+ ath12k_pci_ce_workqueue+0x28/0x50 [ath12k]
+ process_one_work+0x14c/0x28c
+ bh_worker+0x22c/0x27c
+ workqueue_softirq_action+0x80/0x90
+ tasklet_action+0x14/0x3c
+ handle_softirqs+0x108/0x240
+ __do_softirq+0x14/0x20
+Freed in ath12k_reg_free+0x40/0x74 [ath12k] age=136 cpu=2 pid=166
+ kfree+0x148/0x248
+ ath12k_reg_free+0x40/0x74 [ath12k]
+ ath12k_core_hw_group_destroy+0x68/0xac [ath12k]
+ ath12k_core_deinit+0xd8/0x124 [ath12k]
+ ath12k_pci_remove+0x6c/0x130 [ath12k]
+ pci_device_remove+0x44/0xe8
+ device_remove+0x4c/0x80
+ device_release_driver_internal+0x1d0/0x22c
+ driver_detach+0x50/0x98
+ bus_remove_driver+0x70/0xf4
+ driver_unregister+0x30/0x60
+ pci_unregister_driver+0x24/0x9c
+ ath12k_pci_exit+0x18/0x24 [ath12k]
+ __arm64_sys_delete_module+0x1a0/0x2a8
+ invoke_syscall+0x48/0x110
+ el0_svc_common.constprop.0+0x40/0xe0
+Slab 0xfffffdffc0033600 objects=10 used=6 fp=0xffff000000cdcc00 flags=0x3fffe0000000240(workingset|head|node=0|zone=0|lastcpupid=0x1ffff)
+Object 0xffff000000cdcc00 @offset=19456 fp=0xffff000000cde400
+[...]
+
+This issue arises because in ath12k_core_hw_group_destroy(), each device
+calls ath12k_core_soc_destroy() for itself and all its partners within the
+same group. Since ath12k_core_hw_group_destroy() is invoked for each
+device, this results in a double free condition, eventually causing the
+SLUB bug.
+
+To resolve this, set the freed pointers to NULL. And since there could be
+a race condition to read these pointers, guard these with the available
+mutex lock.
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
+Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
+
+Fixes: 6f245ea0ec6c ("wifi: ath12k: introduce device group abstraction")
+Signed-off-by: Aditya Kumar Singh <aditya.kumar.singh@oss.qualcomm.com>
+Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
+Link: https://patch.msgid.link/20250408-fix_reboot_issues_with_hw_grouping-v4-1-95e7bf048595@oss.qualcomm.com
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/reg.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/net/wireless/ath/ath12k/reg.c b/drivers/net/wireless/ath/ath12k/reg.c
+index 439d61f284d89..7fa7cd301b757 100644
+--- a/drivers/net/wireless/ath/ath12k/reg.c
++++ b/drivers/net/wireless/ath/ath12k/reg.c
+@@ -777,8 +777,12 @@ void ath12k_reg_free(struct ath12k_base *ab)
+ {
+       int i;
++      mutex_lock(&ab->core_lock);
+       for (i = 0; i < ab->hw_params->max_radios; i++) {
+               kfree(ab->default_regd[i]);
+               kfree(ab->new_regd[i]);
++              ab->default_regd[i] = NULL;
++              ab->new_regd[i] = NULL;
+       }
++      mutex_unlock(&ab->core_lock);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-ath12k-fix-the-qos-control-field-offset-to-buil.patch b/queue-6.15/wifi-ath12k-fix-the-qos-control-field-offset-to-buil.patch
new file mode 100644 (file)
index 0000000..dcf3cb6
--- /dev/null
@@ -0,0 +1,68 @@
+From a124a7bc2db93b2ba0aa89245b19acb7d92ca398 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Apr 2025 00:11:02 +0530
+Subject: wifi: ath12k: Fix the QoS control field offset to build QoS header
+
+From: Ramasamy Kaliappan <quic_rkaliapp@quicinc.com>
+
+[ Upstream commit 8599d4cc4191c8c1af34207a8b9414acca4afb59 ]
+
+Currently, in the mac80211 layer, received EAPOL packets are dropped
+when the HT control field is present in the QoS header. This issue
+arises due to an incorrect QoS control field offset used to build
+the QoS header in the MSDU data, leading to a corrupted header in the
+mac80211 layer. This issue also applies to other frames that contain
+the QoS control field, such as QoS data or Null frames. To resolve
+this, use ieee80211_get_qos_ctl() to obtain the correct QoS control
+offset from the MSDU data. Additionally, ensure the QoS control header
+is copied in little-endian format within the MSDU data.
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
+Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
+
+Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices")
+Signed-off-by: Ramasamy Kaliappan <quic_rkaliapp@quicinc.com>
+Signed-off-by: Nithyanantham Paramasivam <nithyanantham.paramasivam@oss.qualcomm.com>
+Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
+Link: https://patch.msgid.link/20250415184102.2707300-1-nithyanantham.paramasivam@oss.qualcomm.com
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/dp_rx.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
+index 317cc6e6e1f5b..125ccbd0532ce 100644
+--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
++++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
+@@ -2119,7 +2119,7 @@ static void ath12k_get_dot11_hdr_from_rx_desc(struct ath12k *ar,
+       struct ath12k_base *ab = ar->ab;
+       size_t hdr_len, crypto_len;
+       struct ieee80211_hdr hdr;
+-      u16 qos_ctl;
++      __le16 qos_ctl;
+       u8 *crypto_hdr, mesh_ctrl;
+       ath12k_dp_rx_desc_get_dot11_hdr(ab, rx_desc, &hdr);
+@@ -2140,13 +2140,13 @@ static void ath12k_get_dot11_hdr_from_rx_desc(struct ath12k *ar,
+       /* Add QOS header */
+       if (ieee80211_is_data_qos(hdr.frame_control)) {
+-              qos_ctl = rxcb->tid;
++              struct ieee80211_hdr *qos_ptr = (struct ieee80211_hdr *)msdu->data;
++
++              qos_ctl = cpu_to_le16(rxcb->tid & IEEE80211_QOS_CTL_TID_MASK);
+               if (mesh_ctrl)
+-                      qos_ctl |= IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT;
++                      qos_ctl |= cpu_to_le16(IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT);
+-              /* TODO: Add other QoS ctl fields when required */
+-              memcpy(msdu->data + (hdr_len - IEEE80211_QOS_CTL_LEN),
+-                     &qos_ctl, IEEE80211_QOS_CTL_LEN);
++              memcpy(ieee80211_get_qos_ctl(qos_ptr), &qos_ctl, IEEE80211_QOS_CTL_LEN);
+       }
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-ath12k-fix-wmi-tag-for-eht-rate-in-peer-assoc.patch b/queue-6.15/wifi-ath12k-fix-wmi-tag-for-eht-rate-in-peer-assoc.patch
new file mode 100644 (file)
index 0000000..40b33a0
--- /dev/null
@@ -0,0 +1,42 @@
+From eea8cf3b056fe668c6671495ec289d445af5f0f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Apr 2025 20:53:41 +0530
+Subject: wifi: ath12k: Fix WMI tag for EHT rate in peer assoc
+
+From: Ramya Gnanasekar <ramya.gnanasekar@oss.qualcomm.com>
+
+[ Upstream commit 1a0e65750b55d2cf5de4a9bf7d6d55718784bdb7 ]
+
+Incorrect WMI tag is used for EHT rate update from host to firmware
+while encoding peer assoc WMI.
+
+Correct the WMI tag used for EHT rate update from WMI_TAG_HE_RATE_SET
+to the proper tag. This ensures firmware does not mistakenly update HE rate during parsing.
+
+Found during code review. Compile tested only.
+
+Fixes: 5b70ec6036c1 ("wifi: ath12k: add WMI support for EHT peer")
+Signed-off-by: Ramya Gnanasekar <ramya.gnanasekar@oss.qualcomm.com>
+Link: https://patch.msgid.link/20250409152341.944628-1-ramya.gnanasekar@oss.qualcomm.com
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/wmi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
+index 6d1ea5f3a791b..6374e86f89f3d 100644
+--- a/drivers/net/wireless/ath/ath12k/wmi.c
++++ b/drivers/net/wireless/ath/ath12k/wmi.c
+@@ -2351,7 +2351,7 @@ int ath12k_wmi_send_peer_assoc_cmd(struct ath12k *ar,
+       for (i = 0; i < arg->peer_eht_mcs_count; i++) {
+               eht_mcs = ptr;
+-              eht_mcs->tlv_header = ath12k_wmi_tlv_cmd_hdr(WMI_TAG_HE_RATE_SET,
++              eht_mcs->tlv_header = ath12k_wmi_tlv_cmd_hdr(WMI_TAG_EHT_RATE_SET,
+                                                            sizeof(*eht_mcs));
+               eht_mcs->rx_mcs_set = cpu_to_le32(arg->peer_eht_rx_mcs_set[i]);
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-ath12k-fix-wrong-handling-of-ccmp256-and-gcmp-c.patch b/queue-6.15/wifi-ath12k-fix-wrong-handling-of-ccmp256-and-gcmp-c.patch
new file mode 100644 (file)
index 0000000..3df0e16
--- /dev/null
@@ -0,0 +1,123 @@
+From b197b820a9daa6d1f27a15015272c43916b2ced4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Apr 2025 01:28:11 +0530
+Subject: wifi: ath12k: fix wrong handling of CCMP256 and GCMP ciphers
+
+From: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
+
+[ Upstream commit f5d6b15d9503263d9425dcde9cc2fd401a32b0f2 ]
+
+Currently for CCMP256, GCMP128 and GCMP256 ciphers, in
+ath12k_install_key() IEEE80211_KEY_FLAG_GENERATE_IV_MGMT is not set and
+in ath12k_mac_mgmt_tx_wmi() a length of IEEE80211_CCMP_MIC_LEN is reserved
+for all ciphers.
+
+This results in unexpected drop of protected management frames in case
+either of above 3 ciphers is used. The reason is, without
+IEEE80211_KEY_FLAG_GENERATE_IV_MGMT set, mac80211 will not generate
+CCMP/GCMP headers in TX frame for ath12k.
+Also MIC length reserved is wrong and such frames are dropped by hardware.
+
+Fix this by setting IEEE80211_KEY_FLAG_GENERATE_IV_MGMT flag for above
+ciphers and by reserving proper MIC length for those ciphers.
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1
+Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
+
+Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices")
+Signed-off-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
+Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
+Link: https://patch.msgid.link/20250415195812.2633923-2-rameshkumar.sundaram@oss.qualcomm.com
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/dp_rx.c |  3 +--
+ drivers/net/wireless/ath/ath12k/dp_rx.h |  3 +++
+ drivers/net/wireless/ath/ath12k/mac.c   | 16 ++++++++++------
+ 3 files changed, 14 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
+index f7e176e9c01a6..7fadd366ec13d 100644
+--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
++++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
+@@ -1917,8 +1917,7 @@ static void ath12k_dp_rx_h_csum_offload(struct sk_buff *msdu,
+                          CHECKSUM_NONE : CHECKSUM_UNNECESSARY;
+ }
+-static int ath12k_dp_rx_crypto_mic_len(struct ath12k *ar,
+-                                     enum hal_encrypt_type enctype)
++int ath12k_dp_rx_crypto_mic_len(struct ath12k *ar, enum hal_encrypt_type enctype)
+ {
+       switch (enctype) {
+       case HAL_ENCRYPT_TYPE_OPEN:
+diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h
+index eb4d2b60a035e..a4e179c6f2664 100644
+--- a/drivers/net/wireless/ath/ath12k/dp_rx.h
++++ b/drivers/net/wireless/ath/ath12k/dp_rx.h
+@@ -165,4 +165,7 @@ int ath12k_dp_htt_tlv_iter(struct ath12k_base *ab, const void *ptr, size_t len,
+                          void *data);
+ void ath12k_dp_rx_h_fetch_info(struct ath12k_base *ab,  struct hal_rx_desc *rx_desc,
+                              struct ath12k_dp_rx_info *rx_info);
++
++int ath12k_dp_rx_crypto_mic_len(struct ath12k *ar, enum hal_encrypt_type enctype);
++
+ #endif /* ATH12K_DP_RX_H */
+diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
+index 4134f9512d038..65eb50bf03b24 100644
+--- a/drivers/net/wireless/ath/ath12k/mac.c
++++ b/drivers/net/wireless/ath/ath12k/mac.c
+@@ -4623,8 +4623,8 @@ static int ath12k_install_key(struct ath12k_link_vif *arvif,
+       switch (key->cipher) {
+       case WLAN_CIPHER_SUITE_CCMP:
++      case WLAN_CIPHER_SUITE_CCMP_256:
+               arg.key_cipher = WMI_CIPHER_AES_CCM;
+-              /* TODO: Re-check if flag is valid */
+               key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT;
+               break;
+       case WLAN_CIPHER_SUITE_TKIP:
+@@ -4632,12 +4632,10 @@ static int ath12k_install_key(struct ath12k_link_vif *arvif,
+               arg.key_txmic_len = 8;
+               arg.key_rxmic_len = 8;
+               break;
+-      case WLAN_CIPHER_SUITE_CCMP_256:
+-              arg.key_cipher = WMI_CIPHER_AES_CCM;
+-              break;
+       case WLAN_CIPHER_SUITE_GCMP:
+       case WLAN_CIPHER_SUITE_GCMP_256:
+               arg.key_cipher = WMI_CIPHER_AES_GCM;
++              key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT;
+               break;
+       default:
+               ath12k_warn(ar->ab, "cipher %d is not supported\n", key->cipher);
+@@ -7041,6 +7039,8 @@ static int ath12k_mac_mgmt_tx_wmi(struct ath12k *ar, struct ath12k_link_vif *arv
+       struct ath12k_base *ab = ar->ab;
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+       struct ieee80211_tx_info *info;
++      enum hal_encrypt_type enctype;
++      unsigned int mic_len;
+       dma_addr_t paddr;
+       int buf_id;
+       int ret;
+@@ -7056,12 +7056,16 @@ static int ath12k_mac_mgmt_tx_wmi(struct ath12k *ar, struct ath12k_link_vif *arv
+               return -ENOSPC;
+       info = IEEE80211_SKB_CB(skb);
+-      if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)) {
++      if ((ATH12K_SKB_CB(skb)->flags & ATH12K_SKB_CIPHER_SET) &&
++          !(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)) {
+               if ((ieee80211_is_action(hdr->frame_control) ||
+                    ieee80211_is_deauth(hdr->frame_control) ||
+                    ieee80211_is_disassoc(hdr->frame_control)) &&
+                    ieee80211_has_protected(hdr->frame_control)) {
+-                      skb_put(skb, IEEE80211_CCMP_MIC_LEN);
++                      enctype =
++                          ath12k_dp_tx_get_encrypt_type(ATH12K_SKB_CB(skb)->cipher);
++                      mic_len = ath12k_dp_rx_crypto_mic_len(ar, enctype);
++                      skb_put(skb, mic_len);
+               }
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-ath12k-handle-error-cases-during-extended-skb-a.patch b/queue-6.15/wifi-ath12k-handle-error-cases-during-extended-skb-a.patch
new file mode 100644 (file)
index 0000000..a71d1c2
--- /dev/null
@@ -0,0 +1,96 @@
+From 47fa07747b451d692ee08dd98c3caf1ff7295dfa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Apr 2025 11:31:51 +0530
+Subject: wifi: ath12k: Handle error cases during extended skb allocation
+
+From: P Praneesh <praneesh.p@oss.qualcomm.com>
+
+[ Upstream commit 37a068fc9dc4feb8d76e8896bb33883d06c11a6b ]
+
+Currently, in the case of extended skb allocation, the buffer is freed
+before the DMA unmap operation. This premature deletion can result in
+skb->data corruption, as the memory region could be re-allocated for other
+purposes. Fix this issue by reordering the failure cases by calling
+dma_unmap_single() first, then followed by the corresponding kfree_skb().
+This helps avoid data corruption in case of failures in dp_tx().
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
+Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
+
+Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices")
+Signed-off-by: P Praneesh <praneesh.p@oss.qualcomm.com>
+Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
+Link: https://patch.msgid.link/20250411060154.1388159-2-praneesh.p@oss.qualcomm.com
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/dp_tx.c | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.c b/drivers/net/wireless/ath/ath12k/dp_tx.c
+index 1e2788df476c2..f82d2c58eff3f 100644
+--- a/drivers/net/wireless/ath/ath12k/dp_tx.c
++++ b/drivers/net/wireless/ath/ath12k/dp_tx.c
+@@ -229,7 +229,7 @@ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif,
+       struct ath12k_skb_cb *skb_cb = ATH12K_SKB_CB(skb);
+       struct hal_tcl_data_cmd *hal_tcl_desc;
+       struct hal_tx_msdu_ext_desc *msg;
+-      struct sk_buff *skb_ext_desc;
++      struct sk_buff *skb_ext_desc = NULL;
+       struct hal_srng *tcl_ring;
+       struct ieee80211_hdr *hdr = (void *)skb->data;
+       struct ath12k_vif *ahvif = arvif->ahvif;
+@@ -415,18 +415,15 @@ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif,
+                       if (ret < 0) {
+                               ath12k_dbg(ab, ATH12K_DBG_DP_TX,
+                                          "Failed to add HTT meta data, dropping packet\n");
+-                              kfree_skb(skb_ext_desc);
+-                              goto fail_unmap_dma;
++                              goto fail_free_ext_skb;
+                       }
+               }
+               ti.paddr = dma_map_single(ab->dev, skb_ext_desc->data,
+                                         skb_ext_desc->len, DMA_TO_DEVICE);
+               ret = dma_mapping_error(ab->dev, ti.paddr);
+-              if (ret) {
+-                      kfree_skb(skb_ext_desc);
+-                      goto fail_unmap_dma;
+-              }
++              if (ret)
++                      goto fail_free_ext_skb;
+               ti.data_len = skb_ext_desc->len;
+               ti.type = HAL_TCL_DESC_TYPE_EXT_DESC;
+@@ -462,7 +459,7 @@ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif,
+                       ring_selector++;
+               }
+-              goto fail_unmap_dma;
++              goto fail_unmap_dma_ext;
+       }
+       ath12k_hal_tx_cmd_desc_setup(ab, hal_tcl_desc, &ti);
+@@ -478,13 +475,16 @@ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif,
+       return 0;
+-fail_unmap_dma:
+-      dma_unmap_single(ab->dev, ti.paddr, ti.data_len, DMA_TO_DEVICE);
+-
++fail_unmap_dma_ext:
+       if (skb_cb->paddr_ext_desc)
+               dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc,
+                                sizeof(struct hal_tx_msdu_ext_desc),
+                                DMA_TO_DEVICE);
++fail_free_ext_skb:
++      kfree_skb(skb_ext_desc);
++
++fail_unmap_dma:
++      dma_unmap_single(ab->dev, ti.paddr, ti.data_len, DMA_TO_DEVICE);
+ fail_remove_tx_buf:
+       ath12k_dp_tx_release_txbuf(dp, tx_desc, pool_id);
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-ath12k-prevent-sending-wmi-commands-to-firmware.patch b/queue-6.15/wifi-ath12k-prevent-sending-wmi-commands-to-firmware.patch
new file mode 100644 (file)
index 0000000..75a1202
--- /dev/null
@@ -0,0 +1,103 @@
+From eb1f1db7778e6070b2fee1968c4e16137cbef798 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Apr 2025 07:34:14 +0530
+Subject: wifi: ath12k: Prevent sending WMI commands to firmware during
+ firmware crash
+
+From: Maharaja Kennadyrajan <maharaja.kennadyrajan@oss.qualcomm.com>
+
+[ Upstream commit e9e094a9734ea3bd4d4d117c915ccf129ac61ba1 ]
+
+Currently, we encounter the following kernel call trace when a firmware
+crash occurs. This happens because the host sends WMI commands to the
+firmware while it is in recovery, causing the commands to fail and
+resulting in the kernel call trace.
+
+Set the ATH12K_FLAG_CRASH_FLUSH and ATH12K_FLAG_RECOVERY flags when the
+host driver receives the firmware crash notification from MHI. This
+prevents sending WMI commands to the firmware during recovery.
+
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x75/0xc0
+ register_lock_class+0x6be/0x7a0
+ ? __lock_acquire+0x644/0x19a0
+ __lock_acquire+0x95/0x19a0
+ lock_acquire+0x265/0x310
+ ? ath12k_ce_send+0xa2/0x210 [ath12k]
+ ? find_held_lock+0x34/0xa0
+ ? ath12k_ce_send+0x56/0x210 [ath12k]
+ _raw_spin_lock_bh+0x33/0x70
+ ? ath12k_ce_send+0xa2/0x210 [ath12k]
+ ath12k_ce_send+0xa2/0x210 [ath12k]
+ ath12k_htc_send+0x178/0x390 [ath12k]
+ ath12k_wmi_cmd_send_nowait+0x76/0xa0 [ath12k]
+ ath12k_wmi_cmd_send+0x62/0x190 [ath12k]
+ ath12k_wmi_pdev_bss_chan_info_request+0x62/0xc0 [ath1
+ ath12k_mac_op_get_survey+0x2be/0x310 [ath12k]
+ ieee80211_dump_survey+0x99/0x240 [mac80211]
+ nl80211_dump_survey+0xe7/0x470 [cfg80211]
+ ? kmalloc_reserve+0x59/0xf0
+ genl_dumpit+0x24/0x70
+ netlink_dump+0x177/0x360
+ __netlink_dump_start+0x206/0x280
+ genl_family_rcv_msg_dumpit.isra.22+0x8a/0xe0
+ ? genl_family_rcv_msg_attrs_parse.isra.23+0xe0/0xe0
+ ? genl_op_lock.part.12+0x10/0x10
+ ? genl_dumpit+0x70/0x70
+ genl_rcv_msg+0x1d0/0x290
+ ? nl80211_del_station+0x330/0x330 [cfg80211]
+ ? genl_get_cmd_both+0x50/0x50
+ netlink_rcv_skb+0x4f/0x100
+ genl_rcv+0x1f/0x30
+ netlink_unicast+0x1b6/0x260
+ netlink_sendmsg+0x31a/0x450
+ __sock_sendmsg+0xa8/0xb0
+ ____sys_sendmsg+0x1e4/0x260
+ ___sys_sendmsg+0x89/0xe0
+ ? local_clock_noinstr+0xb/0xc0
+ ? rcu_is_watching+0xd/0x40
+ ? kfree+0x1de/0x370
+ ? __sys_sendmsg+0x7a/0xc0
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
+
+Fixes: a9b46dd2e483 ("wifi: ath12k: Add firmware coredump collection support")
+Signed-off-by: Maharaja Kennadyrajan <maharaja.kennadyrajan@oss.qualcomm.com>
+Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
+Link: https://patch.msgid.link/20250416020414.2161545-1-maharaja.kennadyrajan@oss.qualcomm.com
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/mhi.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath12k/mhi.c b/drivers/net/wireless/ath/ath12k/mhi.c
+index 2f6d14382ed70..4d40c4ec4b811 100644
+--- a/drivers/net/wireless/ath/ath12k/mhi.c
++++ b/drivers/net/wireless/ath/ath12k/mhi.c
+@@ -1,7 +1,7 @@
+ // SPDX-License-Identifier: BSD-3-Clause-Clear
+ /*
+  * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
+- * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
++ * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+  */
+ #include <linux/msi.h>
+@@ -285,8 +285,11 @@ static void ath12k_mhi_op_status_cb(struct mhi_controller *mhi_cntrl,
+                       break;
+               }
+-              if (!(test_bit(ATH12K_FLAG_UNREGISTERING, &ab->dev_flags)))
++              if (!(test_bit(ATH12K_FLAG_UNREGISTERING, &ab->dev_flags))) {
++                      set_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags);
++                      set_bit(ATH12K_FLAG_RECOVERY, &ab->dev_flags);
+                       queue_work(ab->workqueue_aux, &ab->reset_work);
++              }
+               break;
+       default:
+               break;
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-ath12k-reorder-and-relocate-the-release-of-reso.patch b/queue-6.15/wifi-ath12k-reorder-and-relocate-the-release-of-reso.patch
new file mode 100644 (file)
index 0000000..5d083aa
--- /dev/null
@@ -0,0 +1,123 @@
+From aad8d6d98ebb65445cd219b8d91b304a861bf291 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Apr 2025 11:26:49 +0530
+Subject: wifi: ath12k: Reorder and relocate the release of resources in
+ ath12k_core_deinit()
+
+From: Yingying Tang <quic_yintang@quicinc.com>
+
+[ Upstream commit aabd3be90579ed088aa34f0584ab6836c735c76f ]
+
+Ath12k panic notifier is registered in driver loading process. But it is not
+unregistered if ATH12K_FLAG_QMI_FAIL is set(e.g. load BDF failed) and unload
+driver. It causes a dirty node in panic notifier list since ath12k panic
+notifier is not unregistered from list but the buffer of this node is freed
+in driver unloading process. If load driver again there will be a page fault
+error due to this dirty node in panic notifier list.
+
+This issue is caused by asymmetry between ath12k_core_init() and
+ath12k_core_deinit(). Reorder and relocate the release of resources in
+ath12k_core_deinit() to avoid this asymmetry issue.
+
+Call Trace:
+<TASK>
+? show_regs+0x67/0x70
+? __die_body+0x20/0x70
+? __die+0x2b/0x40
+? page_fault_oops+0x15d/0x500
+? search_bpf_extables+0x63/0x90
+? notifier_chain_register+0x21/0xe0
+? search_exception_tables+0x5f/0x70
+? kernelmode_fixup_or_oops.isra.0+0x61/0x80
+? __bad_area_nosemaphore+0x179/0x240
+? bad_area_nosemaphore+0x16/0x20
+? do_user_addr_fault+0x312/0x7f0
+? prb_read_valid+0x1c/0x30
+? exc_page_fault+0x78/0x180
+? asm_exc_page_fault+0x27/0x30
+? notifier_chain_register+0x21/0xe0
+? notifier_chain_register+0x55/0xe0
+atomic_notifier_chain_register+0x2c/0x50
+ath12k_core_init+0x7e/0x110 [ath12k]
+ath12k_pci_probe+0xaba/0xba0 [ath12k]
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0-02903-QCAHKSWPL_SILICONZ-1
+Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
+
+Fixes: 809055628bce8 ("wifi: ath12k: add panic handler")
+Signed-off-by: Yingying Tang <quic_yintang@quicinc.com>
+Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
+Link: https://patch.msgid.link/20250423055650.16230-2-quic_yintang@quicinc.com
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/core.c | 5 ++---
+ drivers/net/wireless/ath/ath12k/core.h | 1 +
+ drivers/net/wireless/ath/ath12k/pci.c  | 5 ++---
+ 3 files changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
+index 6b0c719be5434..770156347ffad 100644
+--- a/drivers/net/wireless/ath/ath12k/core.c
++++ b/drivers/net/wireless/ath/ath12k/core.c
+@@ -1785,7 +1785,7 @@ static void ath12k_core_hw_group_destroy(struct ath12k_hw_group *ag)
+       }
+ }
+-static void ath12k_core_hw_group_cleanup(struct ath12k_hw_group *ag)
++void ath12k_core_hw_group_cleanup(struct ath12k_hw_group *ag)
+ {
+       struct ath12k_base *ab;
+       int i;
+@@ -1933,10 +1933,9 @@ int ath12k_core_init(struct ath12k_base *ab)
+ void ath12k_core_deinit(struct ath12k_base *ab)
+ {
+-      ath12k_core_panic_notifier_unregister(ab);
+-      ath12k_core_hw_group_cleanup(ab->ag);
+       ath12k_core_hw_group_destroy(ab->ag);
+       ath12k_core_hw_group_unassign(ab);
++      ath12k_core_panic_notifier_unregister(ab);
+ }
+ void ath12k_core_free(struct ath12k_base *ab)
+diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h
+index 2ee83517eadc7..f5f1ec796f7c5 100644
+--- a/drivers/net/wireless/ath/ath12k/core.h
++++ b/drivers/net/wireless/ath/ath12k/core.h
+@@ -1195,6 +1195,7 @@ struct ath12k_fw_stats_pdev {
+ };
+ int ath12k_core_qmi_firmware_ready(struct ath12k_base *ab);
++void ath12k_core_hw_group_cleanup(struct ath12k_hw_group *ag);
+ int ath12k_core_pre_init(struct ath12k_base *ab);
+ int ath12k_core_init(struct ath12k_base *ath12k);
+ void ath12k_core_deinit(struct ath12k_base *ath12k);
+diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c
+index 99b2c7927ec81..273f4bc260bfe 100644
+--- a/drivers/net/wireless/ath/ath12k/pci.c
++++ b/drivers/net/wireless/ath/ath12k/pci.c
+@@ -1734,8 +1734,6 @@ static void ath12k_pci_remove(struct pci_dev *pdev)
+       if (test_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags)) {
+               ath12k_pci_power_down(ab, false);
+-              ath12k_qmi_deinit_service(ab);
+-              ath12k_core_hw_group_unassign(ab);
+               goto qmi_fail;
+       }
+@@ -1743,9 +1741,10 @@ static void ath12k_pci_remove(struct pci_dev *pdev)
+       cancel_work_sync(&ab->reset_work);
+       cancel_work_sync(&ab->dump_work);
+-      ath12k_core_deinit(ab);
++      ath12k_core_hw_group_cleanup(ab->ag);
+ qmi_fail:
++      ath12k_core_deinit(ab);
+       ath12k_fw_unmap(ab);
+       ath12k_mhi_unregister(ab_pci);
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-ath12k-replace-band-define-g-with-ghz-where-app.patch b/queue-6.15/wifi-ath12k-replace-band-define-g-with-ghz-where-app.patch
new file mode 100644 (file)
index 0000000..a01beec
--- /dev/null
@@ -0,0 +1,459 @@
+From 344016a171ed8809c4d31a2153c17e2608634e3c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Mar 2025 11:55:12 +0530
+Subject: wifi: ath12k: Replace band define G with GHZ where appropriate
+
+From: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
+
+[ Upstream commit 6a88093f79ea0b131e5feab9cdc045a007fad26e ]
+
+Currently, band define and enum are with the word 'G'. Replace it with
+more appropriate 'GHZ' for clarity and correctness.
+
+No functional changes. Only compile tested.
+
+Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
+Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
+Link: https://patch.msgid.link/20250324062518.2752822-5-quic_periyasa@quicinc.com
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Stable-dep-of: f5d6b15d9503 ("wifi: ath12k: fix wrong handling of CCMP256 and GCMP ciphers")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/core.h    |  8 ++--
+ drivers/net/wireless/ath/ath12k/debugfs.c |  4 +-
+ drivers/net/wireless/ath/ath12k/dp_rx.c   |  4 +-
+ drivers/net/wireless/ath/ath12k/mac.c     | 52 +++++++++++------------
+ drivers/net/wireless/ath/ath12k/wmi.c     | 36 ++++++++--------
+ drivers/net/wireless/ath/ath12k/wmi.h     | 16 +++----
+ 6 files changed, 60 insertions(+), 60 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h
+index 3fac4f00d3832..2d91a6a4750ca 100644
+--- a/drivers/net/wireless/ath/ath12k/core.h
++++ b/drivers/net/wireless/ath/ath12k/core.h
+@@ -533,11 +533,11 @@ struct ath12k_sta {
+       enum ieee80211_sta_state state;
+ };
+-#define ATH12K_MIN_5G_FREQ 4150
+-#define ATH12K_MIN_6G_FREQ 5925
+-#define ATH12K_MAX_6G_FREQ 7115
++#define ATH12K_MIN_5GHZ_FREQ 4150
++#define ATH12K_MIN_6GHZ_FREQ 5925
++#define ATH12K_MAX_6GHZ_FREQ 7115
+ #define ATH12K_NUM_CHANS 101
+-#define ATH12K_MAX_5G_CHAN 173
++#define ATH12K_MAX_5GHZ_CHAN 173
+ enum ath12k_hw_state {
+       ATH12K_HW_STATE_OFF,
+diff --git a/drivers/net/wireless/ath/ath12k/debugfs.c b/drivers/net/wireless/ath/ath12k/debugfs.c
+index 57002215ddf16..5efe30cf77470 100644
+--- a/drivers/net/wireless/ath/ath12k/debugfs.c
++++ b/drivers/net/wireless/ath/ath12k/debugfs.c
+@@ -88,8 +88,8 @@ static int ath12k_get_tpc_ctl_mode_idx(struct wmi_tpc_stats_arg *tpc_stats,
+       u32 chan_freq = le32_to_cpu(tpc_stats->tpc_config.chan_freq);
+       u8 band;
+-      band = ((chan_freq > ATH12K_MIN_6G_FREQ) ? NL80211_BAND_6GHZ :
+-              ((chan_freq > ATH12K_MIN_5G_FREQ) ? NL80211_BAND_5GHZ :
++      band = ((chan_freq > ATH12K_MIN_6GHZ_FREQ) ? NL80211_BAND_6GHZ :
++              ((chan_freq > ATH12K_MIN_5GHZ_FREQ) ? NL80211_BAND_5GHZ :
+               NL80211_BAND_2GHZ));
+       if (band == NL80211_BAND_5GHZ || band == NL80211_BAND_6GHZ) {
+diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
+index d6794c753f3ae..eaba698267685 100644
+--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
++++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
+@@ -2426,8 +2426,8 @@ void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct hal_rx_desc *rx_desc,
+       channel_num = meta_data;
+       center_freq = meta_data >> 16;
+-      if (center_freq >= ATH12K_MIN_6G_FREQ &&
+-          center_freq <= ATH12K_MAX_6G_FREQ) {
++      if (center_freq >= ATH12K_MIN_6GHZ_FREQ &&
++          center_freq <= ATH12K_MAX_6GHZ_FREQ) {
+               rx_status->band = NL80211_BAND_6GHZ;
+               rx_status->freq = center_freq;
+       } else if (channel_num >= 1 && channel_num <= 14) {
+diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
+index bd67140688290..4134f9512d038 100644
+--- a/drivers/net/wireless/ath/ath12k/mac.c
++++ b/drivers/net/wireless/ath/ath12k/mac.c
+@@ -874,12 +874,12 @@ static bool ath12k_mac_band_match(enum nl80211_band band1, enum WMI_HOST_WLAN_BA
+ {
+       switch (band1) {
+       case NL80211_BAND_2GHZ:
+-              if (band2 & WMI_HOST_WLAN_2G_CAP)
++              if (band2 & WMI_HOST_WLAN_2GHZ_CAP)
+                       return true;
+               break;
+       case NL80211_BAND_5GHZ:
+       case NL80211_BAND_6GHZ:
+-              if (band2 & WMI_HOST_WLAN_5G_CAP)
++              if (band2 & WMI_HOST_WLAN_5GHZ_CAP)
+                       return true;
+               break;
+       default:
+@@ -980,7 +980,7 @@ static int ath12k_mac_txpower_recalc(struct ath12k *ar)
+       ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "txpower to set in hw %d\n",
+                  txpower / 2);
+-      if ((pdev->cap.supported_bands & WMI_HOST_WLAN_2G_CAP) &&
++      if ((pdev->cap.supported_bands & WMI_HOST_WLAN_2GHZ_CAP) &&
+           ar->txpower_limit_2g != txpower) {
+               param = WMI_PDEV_PARAM_TXPOWER_LIMIT2G;
+               ret = ath12k_wmi_pdev_set_param(ar, param,
+@@ -990,7 +990,7 @@ static int ath12k_mac_txpower_recalc(struct ath12k *ar)
+               ar->txpower_limit_2g = txpower;
+       }
+-      if ((pdev->cap.supported_bands & WMI_HOST_WLAN_5G_CAP) &&
++      if ((pdev->cap.supported_bands & WMI_HOST_WLAN_5GHZ_CAP) &&
+           ar->txpower_limit_5g != txpower) {
+               param = WMI_PDEV_PARAM_TXPOWER_LIMIT5G;
+               ret = ath12k_wmi_pdev_set_param(ar, param,
+@@ -1272,12 +1272,12 @@ static int ath12k_mac_monitor_vdev_create(struct ath12k *ar)
+       arg.pdev_id = pdev->pdev_id;
+       arg.if_stats_id = ATH12K_INVAL_VDEV_STATS_ID;
+-      if (pdev->cap.supported_bands & WMI_HOST_WLAN_2G_CAP) {
++      if (pdev->cap.supported_bands & WMI_HOST_WLAN_2GHZ_CAP) {
+               arg.chains[NL80211_BAND_2GHZ].tx = ar->num_tx_chains;
+               arg.chains[NL80211_BAND_2GHZ].rx = ar->num_rx_chains;
+       }
+-      if (pdev->cap.supported_bands & WMI_HOST_WLAN_5G_CAP) {
++      if (pdev->cap.supported_bands & WMI_HOST_WLAN_5GHZ_CAP) {
+               arg.chains[NL80211_BAND_5GHZ].tx = ar->num_tx_chains;
+               arg.chains[NL80211_BAND_5GHZ].rx = ar->num_rx_chains;
+       }
+@@ -3988,7 +3988,7 @@ static void ath12k_mac_bss_info_changed(struct ath12k *ar,
+               else
+                       rateidx = ffs(info->basic_rates) - 1;
+-              if (ar->pdev->cap.supported_bands & WMI_HOST_WLAN_5G_CAP)
++              if (ar->pdev->cap.supported_bands & WMI_HOST_WLAN_5GHZ_CAP)
+                       rateidx += ATH12K_MAC_FIRST_OFDM_RATE_IDX;
+               bitrate = ath12k_legacy_rates[rateidx].bitrate;
+@@ -4162,9 +4162,9 @@ ath12k_mac_select_scan_device(struct ieee80211_hw *hw,
+        * split the hw request and perform multiple scans
+        */
+-      if (center_freq < ATH12K_MIN_5G_FREQ)
++      if (center_freq < ATH12K_MIN_5GHZ_FREQ)
+               band = NL80211_BAND_2GHZ;
+-      else if (center_freq < ATH12K_MIN_6G_FREQ)
++      else if (center_freq < ATH12K_MIN_6GHZ_FREQ)
+               band = NL80211_BAND_5GHZ;
+       else
+               band = NL80211_BAND_6GHZ;
+@@ -6474,7 +6474,7 @@ static void ath12k_mac_setup_ht_vht_cap(struct ath12k *ar,
+       rate_cap_tx_chainmask = ar->cfg_tx_chainmask >> cap->tx_chain_mask_shift;
+       rate_cap_rx_chainmask = ar->cfg_rx_chainmask >> cap->rx_chain_mask_shift;
+-      if (cap->supported_bands & WMI_HOST_WLAN_2G_CAP) {
++      if (cap->supported_bands & WMI_HOST_WLAN_2GHZ_CAP) {
+               band = &ar->mac.sbands[NL80211_BAND_2GHZ];
+               ht_cap = cap->band[NL80211_BAND_2GHZ].ht_cap_info;
+               if (ht_cap_info)
+@@ -6483,7 +6483,7 @@ static void ath12k_mac_setup_ht_vht_cap(struct ath12k *ar,
+                                                   rate_cap_rx_chainmask);
+       }
+-      if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP &&
++      if (cap->supported_bands & WMI_HOST_WLAN_5GHZ_CAP &&
+           (ar->ab->hw_params->single_pdev_only ||
+            !ar->supports_6ghz)) {
+               band = &ar->mac.sbands[NL80211_BAND_5GHZ];
+@@ -6892,7 +6892,7 @@ static void ath12k_mac_setup_sband_iftype_data(struct ath12k *ar,
+       enum nl80211_band band;
+       int count;
+-      if (cap->supported_bands & WMI_HOST_WLAN_2G_CAP) {
++      if (cap->supported_bands & WMI_HOST_WLAN_2GHZ_CAP) {
+               band = NL80211_BAND_2GHZ;
+               count = ath12k_mac_copy_sband_iftype_data(ar, cap,
+                                                         ar->mac.iftype[band],
+@@ -6902,7 +6902,7 @@ static void ath12k_mac_setup_sband_iftype_data(struct ath12k *ar,
+                                                count);
+       }
+-      if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP) {
++      if (cap->supported_bands & WMI_HOST_WLAN_5GHZ_CAP) {
+               band = NL80211_BAND_5GHZ;
+               count = ath12k_mac_copy_sband_iftype_data(ar, cap,
+                                                         ar->mac.iftype[band],
+@@ -6912,7 +6912,7 @@ static void ath12k_mac_setup_sband_iftype_data(struct ath12k *ar,
+                                                count);
+       }
+-      if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP &&
++      if (cap->supported_bands & WMI_HOST_WLAN_5GHZ_CAP &&
+           ar->supports_6ghz) {
+               band = NL80211_BAND_6GHZ;
+               count = ath12k_mac_copy_sband_iftype_data(ar, cap,
+@@ -7900,15 +7900,15 @@ static int ath12k_mac_setup_vdev_create_arg(struct ath12k_link_vif *arvif,
+                       return ret;
+       }
+-      if (pdev->cap.supported_bands & WMI_HOST_WLAN_2G_CAP) {
++      if (pdev->cap.supported_bands & WMI_HOST_WLAN_2GHZ_CAP) {
+               arg->chains[NL80211_BAND_2GHZ].tx = ar->num_tx_chains;
+               arg->chains[NL80211_BAND_2GHZ].rx = ar->num_rx_chains;
+       }
+-      if (pdev->cap.supported_bands & WMI_HOST_WLAN_5G_CAP) {
++      if (pdev->cap.supported_bands & WMI_HOST_WLAN_5GHZ_CAP) {
+               arg->chains[NL80211_BAND_5GHZ].tx = ar->num_tx_chains;
+               arg->chains[NL80211_BAND_5GHZ].rx = ar->num_rx_chains;
+       }
+-      if (pdev->cap.supported_bands & WMI_HOST_WLAN_5G_CAP &&
++      if (pdev->cap.supported_bands & WMI_HOST_WLAN_5GHZ_CAP &&
+           ar->supports_6ghz) {
+               arg->chains[NL80211_BAND_6GHZ].tx = ar->num_tx_chains;
+               arg->chains[NL80211_BAND_6GHZ].rx = ar->num_rx_chains;
+@@ -7937,7 +7937,7 @@ ath12k_mac_prepare_he_mode(struct ath12k_pdev *pdev, u32 viftype)
+       u32 *hecap_phy_ptr = NULL;
+       u32 hemode;
+-      if (pdev->cap.supported_bands & WMI_HOST_WLAN_2G_CAP)
++      if (pdev->cap.supported_bands & WMI_HOST_WLAN_2GHZ_CAP)
+               cap_band = &pdev_cap->band[NL80211_BAND_2GHZ];
+       else
+               cap_band = &pdev_cap->band[NL80211_BAND_5GHZ];
+@@ -10637,10 +10637,10 @@ static u32 ath12k_get_phy_id(struct ath12k *ar, u32 band)
+       struct ath12k_pdev *pdev = ar->pdev;
+       struct ath12k_pdev_cap *pdev_cap = &pdev->cap;
+-      if (band == WMI_HOST_WLAN_2G_CAP)
++      if (band == WMI_HOST_WLAN_2GHZ_CAP)
+               return pdev_cap->band[NL80211_BAND_2GHZ].phy_id;
+-      if (band == WMI_HOST_WLAN_5G_CAP)
++      if (band == WMI_HOST_WLAN_5GHZ_CAP)
+               return pdev_cap->band[NL80211_BAND_5GHZ].phy_id;
+       ath12k_warn(ar->ab, "unsupported phy cap:%d\n", band);
+@@ -10665,7 +10665,7 @@ static int ath12k_mac_setup_channels_rates(struct ath12k *ar,
+       reg_cap = &ar->ab->hal_reg_cap[ar->pdev_idx];
+-      if (supported_bands & WMI_HOST_WLAN_2G_CAP) {
++      if (supported_bands & WMI_HOST_WLAN_2GHZ_CAP) {
+               channels = kmemdup(ath12k_2ghz_channels,
+                                  sizeof(ath12k_2ghz_channels),
+                                  GFP_KERNEL);
+@@ -10681,7 +10681,7 @@ static int ath12k_mac_setup_channels_rates(struct ath12k *ar,
+               bands[NL80211_BAND_2GHZ] = band;
+               if (ar->ab->hw_params->single_pdev_only) {
+-                      phy_id = ath12k_get_phy_id(ar, WMI_HOST_WLAN_2G_CAP);
++                      phy_id = ath12k_get_phy_id(ar, WMI_HOST_WLAN_2GHZ_CAP);
+                       reg_cap = &ar->ab->hal_reg_cap[phy_id];
+               }
+               ath12k_mac_update_ch_list(ar, band,
+@@ -10689,8 +10689,8 @@ static int ath12k_mac_setup_channels_rates(struct ath12k *ar,
+                                         reg_cap->high_2ghz_chan);
+       }
+-      if (supported_bands & WMI_HOST_WLAN_5G_CAP) {
+-              if (reg_cap->high_5ghz_chan >= ATH12K_MIN_6G_FREQ) {
++      if (supported_bands & WMI_HOST_WLAN_5GHZ_CAP) {
++              if (reg_cap->high_5ghz_chan >= ATH12K_MIN_6GHZ_FREQ) {
+                       channels = kmemdup(ath12k_6ghz_channels,
+                                          sizeof(ath12k_6ghz_channels), GFP_KERNEL);
+                       if (!channels) {
+@@ -10712,7 +10712,7 @@ static int ath12k_mac_setup_channels_rates(struct ath12k *ar,
+                       ah->use_6ghz_regd = true;
+               }
+-              if (reg_cap->low_5ghz_chan < ATH12K_MIN_6G_FREQ) {
++              if (reg_cap->low_5ghz_chan < ATH12K_MIN_6GHZ_FREQ) {
+                       channels = kmemdup(ath12k_5ghz_channels,
+                                          sizeof(ath12k_5ghz_channels),
+                                          GFP_KERNEL);
+@@ -10731,7 +10731,7 @@ static int ath12k_mac_setup_channels_rates(struct ath12k *ar,
+                       bands[NL80211_BAND_5GHZ] = band;
+                       if (ar->ab->hw_params->single_pdev_only) {
+-                              phy_id = ath12k_get_phy_id(ar, WMI_HOST_WLAN_5G_CAP);
++                              phy_id = ath12k_get_phy_id(ar, WMI_HOST_WLAN_5GHZ_CAP);
+                               reg_cap = &ar->ab->hal_reg_cap[phy_id];
+                       }
+diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
+index 6374e86f89f3d..d0705880cd3c9 100644
+--- a/drivers/net/wireless/ath/ath12k/wmi.c
++++ b/drivers/net/wireless/ath/ath12k/wmi.c
+@@ -520,10 +520,10 @@ ath12k_pull_mac_phy_cap_svc_ready_ext(struct ath12k_wmi_pdev *wmi_handle,
+        * band to band for a single radio, need to see how this should be
+        * handled.
+        */
+-      if (le32_to_cpu(mac_caps->supported_bands) & WMI_HOST_WLAN_2G_CAP) {
++      if (le32_to_cpu(mac_caps->supported_bands) & WMI_HOST_WLAN_2GHZ_CAP) {
+               pdev_cap->tx_chain_mask = le32_to_cpu(mac_caps->tx_chain_mask_2g);
+               pdev_cap->rx_chain_mask = le32_to_cpu(mac_caps->rx_chain_mask_2g);
+-      } else if (le32_to_cpu(mac_caps->supported_bands) & WMI_HOST_WLAN_5G_CAP) {
++      } else if (le32_to_cpu(mac_caps->supported_bands) & WMI_HOST_WLAN_5GHZ_CAP) {
+               pdev_cap->vht_cap = le32_to_cpu(mac_caps->vht_cap_info_5g);
+               pdev_cap->vht_mcs = le32_to_cpu(mac_caps->vht_supp_mcs_5g);
+               pdev_cap->he_mcs = le32_to_cpu(mac_caps->he_supp_mcs_5g);
+@@ -546,7 +546,7 @@ ath12k_pull_mac_phy_cap_svc_ready_ext(struct ath12k_wmi_pdev *wmi_handle,
+       pdev_cap->rx_chain_mask_shift =
+                       find_first_bit((unsigned long *)&pdev_cap->rx_chain_mask, 32);
+-      if (le32_to_cpu(mac_caps->supported_bands) & WMI_HOST_WLAN_2G_CAP) {
++      if (le32_to_cpu(mac_caps->supported_bands) & WMI_HOST_WLAN_2GHZ_CAP) {
+               cap_band = &pdev_cap->band[NL80211_BAND_2GHZ];
+               cap_band->phy_id = le32_to_cpu(mac_caps->phy_id);
+               cap_band->max_bw_supported = le32_to_cpu(mac_caps->max_bw_supported_2g);
+@@ -566,7 +566,7 @@ ath12k_pull_mac_phy_cap_svc_ready_ext(struct ath12k_wmi_pdev *wmi_handle,
+                               le32_to_cpu(mac_caps->he_ppet2g.ppet16_ppet8_ru3_ru0[i]);
+       }
+-      if (le32_to_cpu(mac_caps->supported_bands) & WMI_HOST_WLAN_5G_CAP) {
++      if (le32_to_cpu(mac_caps->supported_bands) & WMI_HOST_WLAN_5GHZ_CAP) {
+               cap_band = &pdev_cap->band[NL80211_BAND_5GHZ];
+               cap_band->phy_id = le32_to_cpu(mac_caps->phy_id);
+               cap_band->max_bw_supported =
+@@ -3646,15 +3646,15 @@ ath12k_fill_band_to_mac_param(struct ath12k_base  *soc,
+               arg[i].pdev_id = pdev->pdev_id;
+               switch (pdev->cap.supported_bands) {
+-              case WMI_HOST_WLAN_2G_5G_CAP:
++              case WMI_HOST_WLAN_2GHZ_5GHZ_CAP:
+                       arg[i].start_freq = hal_reg_cap->low_2ghz_chan;
+                       arg[i].end_freq = hal_reg_cap->high_5ghz_chan;
+                       break;
+-              case WMI_HOST_WLAN_2G_CAP:
++              case WMI_HOST_WLAN_2GHZ_CAP:
+                       arg[i].start_freq = hal_reg_cap->low_2ghz_chan;
+                       arg[i].end_freq = hal_reg_cap->high_2ghz_chan;
+                       break;
+-              case WMI_HOST_WLAN_5G_CAP:
++              case WMI_HOST_WLAN_5GHZ_CAP:
+                       arg[i].start_freq = hal_reg_cap->low_5ghz_chan;
+                       arg[i].end_freq = hal_reg_cap->high_5ghz_chan;
+                       break;
+@@ -4699,7 +4699,7 @@ ath12k_wmi_tlv_mac_phy_caps_ext_parse(struct ath12k_base *ab,
+               bands = pdev->cap.supported_bands;
+       }
+-      if (bands & WMI_HOST_WLAN_2G_CAP) {
++      if (bands & WMI_HOST_WLAN_2GHZ_CAP) {
+               ath12k_wmi_eht_caps_parse(pdev, NL80211_BAND_2GHZ,
+                                         caps->eht_cap_mac_info_2ghz,
+                                         caps->eht_cap_phy_info_2ghz,
+@@ -4708,7 +4708,7 @@ ath12k_wmi_tlv_mac_phy_caps_ext_parse(struct ath12k_base *ab,
+                                         caps->eht_cap_info_internal);
+       }
+-      if (bands & WMI_HOST_WLAN_5G_CAP) {
++      if (bands & WMI_HOST_WLAN_5GHZ_CAP) {
+               ath12k_wmi_eht_caps_parse(pdev, NL80211_BAND_5GHZ,
+                                         caps->eht_cap_mac_info_5ghz,
+                                         caps->eht_cap_phy_info_5ghz,
+@@ -4922,7 +4922,7 @@ static u8 ath12k_wmi_ignore_num_extra_rules(struct ath12k_wmi_reg_rule_ext_param
+       for (count = 0; count < num_reg_rules; count++) {
+               start_freq = le32_get_bits(rule[count].freq_info, REG_RULE_START_FREQ);
+-              if (start_freq >= ATH12K_MIN_6G_FREQ)
++              if (start_freq >= ATH12K_MIN_6GHZ_FREQ)
+                       num_invalid_5ghz_rules++;
+       }
+@@ -4992,9 +4992,9 @@ static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab,
+       for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++) {
+               num_6g_reg_rules_ap[i] = reg_info->num_6g_reg_rules_ap[i];
+-              if (num_6g_reg_rules_ap[i] > MAX_6G_REG_RULES) {
++              if (num_6g_reg_rules_ap[i] > MAX_6GHZ_REG_RULES) {
+                       ath12k_warn(ab, "Num 6G reg rules for AP mode(%d) exceeds max limit (num_6g_reg_rules_ap: %d, max_rules: %d)\n",
+-                                  i, num_6g_reg_rules_ap[i], MAX_6G_REG_RULES);
++                                  i, num_6g_reg_rules_ap[i], MAX_6GHZ_REG_RULES);
+                       kfree(tb);
+                       return -EINVAL;
+               }
+@@ -5015,9 +5015,9 @@ static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab,
+                               reg_info->num_6g_reg_rules_cl[WMI_REG_VLP_AP][i];
+               total_reg_rules += num_6g_reg_rules_cl[WMI_REG_VLP_AP][i];
+-              if (num_6g_reg_rules_cl[WMI_REG_INDOOR_AP][i] > MAX_6G_REG_RULES ||
+-                  num_6g_reg_rules_cl[WMI_REG_STD_POWER_AP][i] > MAX_6G_REG_RULES ||
+-                  num_6g_reg_rules_cl[WMI_REG_VLP_AP][i] >  MAX_6G_REG_RULES) {
++              if (num_6g_reg_rules_cl[WMI_REG_INDOOR_AP][i] > MAX_6GHZ_REG_RULES ||
++                  num_6g_reg_rules_cl[WMI_REG_STD_POWER_AP][i] > MAX_6GHZ_REG_RULES ||
++                  num_6g_reg_rules_cl[WMI_REG_VLP_AP][i] >  MAX_6GHZ_REG_RULES) {
+                       ath12k_warn(ab, "Num 6g client reg rules exceeds max limit, for client(type: %d)\n",
+                                   i);
+                       kfree(tb);
+@@ -6317,13 +6317,13 @@ static void ath12k_mgmt_rx_event(struct ath12k_base *ab, struct sk_buff *skb)
+       if (rx_ev.status & WMI_RX_STATUS_ERR_MIC)
+               status->flag |= RX_FLAG_MMIC_ERROR;
+-      if (rx_ev.chan_freq >= ATH12K_MIN_6G_FREQ &&
+-          rx_ev.chan_freq <= ATH12K_MAX_6G_FREQ) {
++      if (rx_ev.chan_freq >= ATH12K_MIN_6GHZ_FREQ &&
++          rx_ev.chan_freq <= ATH12K_MAX_6GHZ_FREQ) {
+               status->band = NL80211_BAND_6GHZ;
+               status->freq = rx_ev.chan_freq;
+       } else if (rx_ev.channel >= 1 && rx_ev.channel <= 14) {
+               status->band = NL80211_BAND_2GHZ;
+-      } else if (rx_ev.channel >= 36 && rx_ev.channel <= ATH12K_MAX_5G_CHAN) {
++      } else if (rx_ev.channel >= 36 && rx_ev.channel <= ATH12K_MAX_5GHZ_CHAN) {
+               status->band = NL80211_BAND_5GHZ;
+       } else {
+               /* Shouldn't happen unless list of advertised channels to
+diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h
+index 1ba33e30ddd27..be4ac91dd34f5 100644
+--- a/drivers/net/wireless/ath/ath12k/wmi.h
++++ b/drivers/net/wireless/ath/ath12k/wmi.h
+@@ -216,9 +216,9 @@ enum wmi_host_hw_mode_priority {
+ };
+ enum WMI_HOST_WLAN_BAND {
+-      WMI_HOST_WLAN_2G_CAP    = 1,
+-      WMI_HOST_WLAN_5G_CAP    = 2,
+-      WMI_HOST_WLAN_2G_5G_CAP = 3,
++      WMI_HOST_WLAN_2GHZ_CAP          = 1,
++      WMI_HOST_WLAN_5GHZ_CAP          = 2,
++      WMI_HOST_WLAN_2GHZ_5GHZ_CAP     = 3,
+ };
+ enum wmi_cmd_group {
+@@ -2690,8 +2690,8 @@ enum wmi_channel_width {
+  * 2 - index for 160 MHz, first 3 bytes valid
+  * 3 - index for 320 MHz, first 3 bytes valid
+  */
+-#define WMI_MAX_EHT_SUPP_MCS_2G_SIZE  2
+-#define WMI_MAX_EHT_SUPP_MCS_5G_SIZE  4
++#define WMI_MAX_EHT_SUPP_MCS_2GHZ_SIZE  2
++#define WMI_MAX_EHT_SUPP_MCS_5GHZ_SIZE  4
+ #define WMI_EHTCAP_TXRX_MCS_NSS_IDX_80    0
+ #define WMI_EHTCAP_TXRX_MCS_NSS_IDX_160   1
+@@ -2730,8 +2730,8 @@ struct ath12k_wmi_caps_ext_params {
+       struct ath12k_wmi_ppe_threshold_params eht_ppet_2ghz;
+       struct ath12k_wmi_ppe_threshold_params eht_ppet_5ghz;
+       __le32 eht_cap_info_internal;
+-      __le32 eht_supp_mcs_ext_2ghz[WMI_MAX_EHT_SUPP_MCS_2G_SIZE];
+-      __le32 eht_supp_mcs_ext_5ghz[WMI_MAX_EHT_SUPP_MCS_5G_SIZE];
++      __le32 eht_supp_mcs_ext_2ghz[WMI_MAX_EHT_SUPP_MCS_2GHZ_SIZE];
++      __le32 eht_supp_mcs_ext_5ghz[WMI_MAX_EHT_SUPP_MCS_5GHZ_SIZE];
+       __le32 eml_capability;
+       __le32 mld_capability;
+ } __packed;
+@@ -4108,7 +4108,7 @@ struct ath12k_wmi_eht_rate_set_params {
+ #define MAX_REG_RULES 10
+ #define REG_ALPHA2_LEN 2
+-#define MAX_6G_REG_RULES 5
++#define MAX_6GHZ_REG_RULES 5
+ enum wmi_start_event_param {
+       WMI_VDEV_START_RESP_EVENT = 0,
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-ath12k-replace-the-usage-of-rx-desc-with-rx_inf.patch b/queue-6.15/wifi-ath12k-replace-the-usage-of-rx-desc-with-rx_inf.patch
new file mode 100644 (file)
index 0000000..e7a18cf
--- /dev/null
@@ -0,0 +1,371 @@
+From 1321aa9e916afe49df471d13fc81a6a0c06f66f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Apr 2025 23:59:17 +0530
+Subject: wifi: ath12k: replace the usage of rx desc with rx_info
+
+From: P Praneesh <praneesh.p@oss.qualcomm.com>
+
+[ Upstream commit bd00cc7e8a4c1048d14c9a9e9790c582119785fb ]
+
+In ath12k_dp_rx_h_mpdu(), during the undecap to native wifi mode, the rx
+descriptor memory is overwritten. After this function call, any subsequent
+accesses to rx descriptor related memory yield invalid values. Fix this by
+replacing instances where rx_desc was used with the pre-cached information
+in rx_info. This ensures that the values populated from the rx descriptor
+are accurate and prevents invalid memory access.
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
+Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
+
+Co-developed-by: Karthikeyan Periyasamy <karthikeyan.periyasamy@oss.qualcomm.com>
+Signed-off-by: Karthikeyan Periyasamy <karthikeyan.periyasamy@oss.qualcomm.com>
+Signed-off-by: P Praneesh <praneesh.p@oss.qualcomm.com>
+Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
+Link: https://patch.msgid.link/20250402182917.2715596-3-praneesh.p@oss.qualcomm.com
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Stable-dep-of: f5d6b15d9503 ("wifi: ath12k: fix wrong handling of CCMP256 and GCMP ciphers")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/dp_mon.c |   4 +-
+ drivers/net/wireless/ath/ath12k/dp_rx.c  | 107 ++++++++++-------------
+ drivers/net/wireless/ath/ath12k/dp_rx.h  |   8 +-
+ 3 files changed, 52 insertions(+), 67 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c
+index 9013c6ce94257..600d97169f241 100644
+--- a/drivers/net/wireless/ath/ath12k/dp_mon.c
++++ b/drivers/net/wireless/ath/ath12k/dp_mon.c
+@@ -2093,6 +2093,7 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct
+       struct ieee80211_sta *pubsta = NULL;
+       struct ath12k_peer *peer;
+       struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);
++      struct ath12k_dp_rx_info rx_info;
+       bool is_mcbc = rxcb->is_mcbc;
+       bool is_eapol_tkip = rxcb->is_eapol;
+@@ -2104,7 +2105,8 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct
+       }
+       spin_lock_bh(&ar->ab->base_lock);
+-      peer = ath12k_dp_rx_h_find_peer(ar->ab, msdu);
++      rx_info.addr2_present = false;
++      peer = ath12k_dp_rx_h_find_peer(ar->ab, msdu, &rx_info);
+       if (peer && peer->sta) {
+               pubsta = peer->sta;
+               if (pubsta->valid_links) {
+diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
+index dcbd97975f642..f7e176e9c01a6 100644
+--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
++++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
+@@ -1910,17 +1910,11 @@ static struct sk_buff *ath12k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_
+       return NULL;
+ }
+-static void ath12k_dp_rx_h_csum_offload(struct ath12k *ar, struct sk_buff *msdu)
++static void ath12k_dp_rx_h_csum_offload(struct sk_buff *msdu,
++                                      struct ath12k_dp_rx_info *rx_info)
+ {
+-      struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);
+-      struct ath12k_base *ab = ar->ab;
+-      bool ip_csum_fail, l4_csum_fail;
+-
+-      ip_csum_fail = ath12k_dp_rx_h_ip_cksum_fail(ab, rxcb->rx_desc);
+-      l4_csum_fail = ath12k_dp_rx_h_l4_cksum_fail(ab, rxcb->rx_desc);
+-
+-      msdu->ip_summed = (ip_csum_fail || l4_csum_fail) ?
+-                        CHECKSUM_NONE : CHECKSUM_UNNECESSARY;
++      msdu->ip_summed = (rx_info->ip_csum_fail || rx_info->l4_csum_fail) ?
++                         CHECKSUM_NONE : CHECKSUM_UNNECESSARY;
+ }
+ static int ath12k_dp_rx_crypto_mic_len(struct ath12k *ar,
+@@ -2222,10 +2216,10 @@ static void ath12k_dp_rx_h_undecap(struct ath12k *ar, struct sk_buff *msdu,
+ }
+ struct ath12k_peer *
+-ath12k_dp_rx_h_find_peer(struct ath12k_base *ab, struct sk_buff *msdu)
++ath12k_dp_rx_h_find_peer(struct ath12k_base *ab, struct sk_buff *msdu,
++                       struct ath12k_dp_rx_info *rx_info)
+ {
+       struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);
+-      struct hal_rx_desc *rx_desc = rxcb->rx_desc;
+       struct ath12k_peer *peer = NULL;
+       lockdep_assert_held(&ab->base_lock);
+@@ -2236,39 +2230,35 @@ ath12k_dp_rx_h_find_peer(struct ath12k_base *ab, struct sk_buff *msdu)
+       if (peer)
+               return peer;
+-      if (!rx_desc || !(ath12k_dp_rxdesc_mac_addr2_valid(ab, rx_desc)))
+-              return NULL;
++      if (rx_info->addr2_present)
++              peer = ath12k_peer_find_by_addr(ab, rx_info->addr2);
+-      peer = ath12k_peer_find_by_addr(ab,
+-                                      ath12k_dp_rxdesc_get_mpdu_start_addr2(ab,
+-                                                                            rx_desc));
+       return peer;
+ }
+ static void ath12k_dp_rx_h_mpdu(struct ath12k *ar,
+                               struct sk_buff *msdu,
+                               struct hal_rx_desc *rx_desc,
+-                              struct ieee80211_rx_status *rx_status)
++                              struct ath12k_dp_rx_info *rx_info)
+ {
+-      bool  fill_crypto_hdr;
+       struct ath12k_base *ab = ar->ab;
+       struct ath12k_skb_rxcb *rxcb;
+       enum hal_encrypt_type enctype;
+       bool is_decrypted = false;
+       struct ieee80211_hdr *hdr;
+       struct ath12k_peer *peer;
++      struct ieee80211_rx_status *rx_status = rx_info->rx_status;
+       u32 err_bitmap;
+       /* PN for multicast packets will be checked in mac80211 */
+       rxcb = ATH12K_SKB_RXCB(msdu);
+-      fill_crypto_hdr = ath12k_dp_rx_h_is_da_mcbc(ar->ab, rx_desc);
+-      rxcb->is_mcbc = fill_crypto_hdr;
++      rxcb->is_mcbc = rx_info->is_mcbc;
+       if (rxcb->is_mcbc)
+-              rxcb->peer_id = ath12k_dp_rx_h_peer_id(ar->ab, rx_desc);
++              rxcb->peer_id = rx_info->peer_id;
+       spin_lock_bh(&ar->ab->base_lock);
+-      peer = ath12k_dp_rx_h_find_peer(ar->ab, msdu);
++      peer = ath12k_dp_rx_h_find_peer(ar->ab, msdu, rx_info);
+       if (peer) {
+               if (rxcb->is_mcbc)
+                       enctype = peer->sec_type_grp;
+@@ -2298,7 +2288,7 @@ static void ath12k_dp_rx_h_mpdu(struct ath12k *ar,
+       if (is_decrypted) {
+               rx_status->flag |= RX_FLAG_DECRYPTED | RX_FLAG_MMIC_STRIPPED;
+-              if (fill_crypto_hdr)
++              if (rx_info->is_mcbc)
+                       rx_status->flag |= RX_FLAG_MIC_STRIPPED |
+                                       RX_FLAG_ICV_STRIPPED;
+               else
+@@ -2306,37 +2296,28 @@ static void ath12k_dp_rx_h_mpdu(struct ath12k *ar,
+                                          RX_FLAG_PN_VALIDATED;
+       }
+-      ath12k_dp_rx_h_csum_offload(ar, msdu);
++      ath12k_dp_rx_h_csum_offload(msdu, rx_info);
+       ath12k_dp_rx_h_undecap(ar, msdu, rx_desc,
+                              enctype, rx_status, is_decrypted);
+-      if (!is_decrypted || fill_crypto_hdr)
++      if (!is_decrypted || rx_info->is_mcbc)
+               return;
+-      if (ath12k_dp_rx_h_decap_type(ar->ab, rx_desc) !=
+-          DP_RX_DECAP_TYPE_ETHERNET2_DIX) {
++      if (rx_info->decap_type != DP_RX_DECAP_TYPE_ETHERNET2_DIX) {
+               hdr = (void *)msdu->data;
+               hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED);
+       }
+ }
+-static void ath12k_dp_rx_h_rate(struct ath12k *ar, struct hal_rx_desc *rx_desc,
+-                              struct ieee80211_rx_status *rx_status)
++static void ath12k_dp_rx_h_rate(struct ath12k *ar, struct ath12k_dp_rx_info *rx_info)
+ {
+-      struct ath12k_base *ab = ar->ab;
+       struct ieee80211_supported_band *sband;
+-      enum rx_msdu_start_pkt_type pkt_type;
+-      u8 bw;
+-      u8 rate_mcs, nss;
+-      u8 sgi;
++      struct ieee80211_rx_status *rx_status = rx_info->rx_status;
++      enum rx_msdu_start_pkt_type pkt_type = rx_info->pkt_type;
++      u8 bw = rx_info->bw, sgi = rx_info->sgi;
++      u8 rate_mcs = rx_info->rate_mcs, nss = rx_info->nss;
+       bool is_cck;
+-      pkt_type = ath12k_dp_rx_h_pkt_type(ab, rx_desc);
+-      bw = ath12k_dp_rx_h_rx_bw(ab, rx_desc);
+-      rate_mcs = ath12k_dp_rx_h_rate_mcs(ab, rx_desc);
+-      nss = ath12k_dp_rx_h_nss(ab, rx_desc);
+-      sgi = ath12k_dp_rx_h_sgi(ab, rx_desc);
+-
+       switch (pkt_type) {
+       case RX_MSDU_START_PKT_TYPE_11A:
+       case RX_MSDU_START_PKT_TYPE_11B:
+@@ -2405,9 +2386,8 @@ static void ath12k_dp_rx_h_rate(struct ath12k *ar, struct hal_rx_desc *rx_desc,
+       }
+ }
+-static void ath12k_dp_rx_h_fetch_info(struct ath12k_base *ab,
+-                                    struct hal_rx_desc *rx_desc,
+-                                    struct ath12k_dp_rx_info *rx_info)
++void ath12k_dp_rx_h_fetch_info(struct ath12k_base *ab, struct hal_rx_desc *rx_desc,
++                             struct ath12k_dp_rx_info *rx_info)
+ {
+       rx_info->ip_csum_fail = ath12k_dp_rx_h_ip_cksum_fail(ab, rx_desc);
+       rx_info->l4_csum_fail = ath12k_dp_rx_h_l4_cksum_fail(ab, rx_desc);
+@@ -2427,12 +2407,14 @@ static void ath12k_dp_rx_h_fetch_info(struct ath12k_base *ab,
+                               ath12k_dp_rxdesc_get_mpdu_start_addr2(ab, rx_desc));
+               rx_info->addr2_present = true;
+       }
++
++      ath12k_dbg_dump(ab, ATH12K_DBG_DATA, NULL, "rx_desc: ",
++                      rx_desc, sizeof(*rx_desc));
+ }
+-void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct hal_rx_desc *rx_desc,
+-                       struct ieee80211_rx_status *rx_status)
++void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct ath12k_dp_rx_info *rx_info)
+ {
+-      struct ath12k_base *ab = ar->ab;
++      struct ieee80211_rx_status *rx_status = rx_info->rx_status;
+       u8 channel_num;
+       u32 center_freq, meta_data;
+       struct ieee80211_channel *channel;
+@@ -2446,7 +2428,7 @@ void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct hal_rx_desc *rx_desc,
+       rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
+-      meta_data = ath12k_dp_rx_h_freq(ab, rx_desc);
++      meta_data = rx_info->phy_meta_data;
+       channel_num = meta_data;
+       center_freq = meta_data >> 16;
+@@ -2467,20 +2449,18 @@ void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct hal_rx_desc *rx_desc,
+                               ieee80211_frequency_to_channel(channel->center_freq);
+               }
+               spin_unlock_bh(&ar->data_lock);
+-              ath12k_dbg_dump(ar->ab, ATH12K_DBG_DATA, NULL, "rx_desc: ",
+-                              rx_desc, sizeof(*rx_desc));
+       }
+       if (rx_status->band != NL80211_BAND_6GHZ)
+               rx_status->freq = ieee80211_channel_to_frequency(channel_num,
+                                                                rx_status->band);
+-      ath12k_dp_rx_h_rate(ar, rx_desc, rx_status);
++      ath12k_dp_rx_h_rate(ar, rx_info);
+ }
+ static void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi,
+                                     struct sk_buff *msdu,
+-                                    struct ieee80211_rx_status *status)
++                                    struct ath12k_dp_rx_info *rx_info)
+ {
+       struct ath12k_base *ab = ar->ab;
+       static const struct ieee80211_radiotap_he known = {
+@@ -2493,6 +2473,7 @@ static void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *nap
+       struct ieee80211_sta *pubsta;
+       struct ath12k_peer *peer;
+       struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);
++      struct ieee80211_rx_status *status = rx_info->rx_status;
+       u8 decap = DP_RX_DECAP_TYPE_RAW;
+       bool is_mcbc = rxcb->is_mcbc;
+       bool is_eapol = rxcb->is_eapol;
+@@ -2505,10 +2486,10 @@ static void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *nap
+       }
+       if (!(status->flag & RX_FLAG_ONLY_MONITOR))
+-              decap = ath12k_dp_rx_h_decap_type(ab, rxcb->rx_desc);
++              decap = rx_info->decap_type;
+       spin_lock_bh(&ab->base_lock);
+-      peer = ath12k_dp_rx_h_find_peer(ab, msdu);
++      peer = ath12k_dp_rx_h_find_peer(ab, msdu, rx_info);
+       pubsta = peer ? peer->sta : NULL;
+@@ -2652,8 +2633,8 @@ static int ath12k_dp_rx_process_msdu(struct ath12k *ar,
+       }
+       ath12k_dp_rx_h_fetch_info(ab, rx_desc, rx_info);
+-      ath12k_dp_rx_h_ppdu(ar, rx_desc, rx_info->rx_status);
+-      ath12k_dp_rx_h_mpdu(ar, msdu, rx_desc, rx_info->rx_status);
++      ath12k_dp_rx_h_ppdu(ar, rx_info);
++      ath12k_dp_rx_h_mpdu(ar, msdu, rx_desc, rx_info);
+       rx_info->rx_status->flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED;
+@@ -2713,7 +2694,7 @@ static void ath12k_dp_rx_process_received_packets(struct ath12k_base *ab,
+                       continue;
+               }
+-              ath12k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_status);
++              ath12k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_info);
+       }
+       rcu_read_unlock();
+@@ -3055,7 +3036,7 @@ static int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, struct ath12k_peer
+       if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, rx_desc, msdu)))
+               return -EINVAL;
+-      ath12k_dp_rx_h_ppdu(ar, rx_desc, rxs);
++      ath12k_dp_rx_h_ppdu(ar, &rx_info);
+       ath12k_dp_rx_h_undecap(ar, msdu, rx_desc,
+                              HAL_ENCRYPT_TYPE_TKIP_MIC, rxs, true);
+       ieee80211_rx(ath12k_ar_to_hw(ar), msdu);
+@@ -3801,10 +3782,10 @@ static int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu,
+               return -EINVAL;
+       ath12k_dp_rx_h_fetch_info(ab, desc, rx_info);
+-      ath12k_dp_rx_h_ppdu(ar, desc, rx_info->rx_status);
+-      ath12k_dp_rx_h_mpdu(ar, msdu, desc, rx_info->rx_status);
++      ath12k_dp_rx_h_ppdu(ar, rx_info);
++      ath12k_dp_rx_h_mpdu(ar, msdu, desc, rx_info);
+-      rxcb->tid = ath12k_dp_rx_h_tid(ab, desc);
++      rxcb->tid = rx_info->tid;
+       /* Please note that caller will having the access to msdu and completing
+        * rx with mac80211. Need not worry about cleaning up amsdu_list.
+@@ -3874,7 +3855,7 @@ static bool ath12k_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff *msdu,
+       if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu)))
+               return true;
+-      ath12k_dp_rx_h_ppdu(ar, desc, rx_info->rx_status);
++      ath12k_dp_rx_h_ppdu(ar, rx_info);
+       rx_info->rx_status->flag |= (RX_FLAG_MMIC_STRIPPED | RX_FLAG_MMIC_ERROR |
+                                    RX_FLAG_DECRYPTED);
+@@ -3946,7 +3927,7 @@ static void ath12k_dp_rx_wbm_err(struct ath12k *ar,
+               return;
+       }
+-      ath12k_dp_rx_deliver_msdu(ar, napi, msdu, &rxs);
++      ath12k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_info);
+ }
+ int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab,
+diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h
+index 0e7cec42a8d13..eb4d2b60a035e 100644
+--- a/drivers/net/wireless/ath/ath12k/dp_rx.h
++++ b/drivers/net/wireless/ath/ath12k/dp_rx.h
+@@ -149,13 +149,13 @@ int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev
+ u8 ath12k_dp_rx_h_l3pad(struct ath12k_base *ab,
+                       struct hal_rx_desc *desc);
+ struct ath12k_peer *
+-ath12k_dp_rx_h_find_peer(struct ath12k_base *ab, struct sk_buff *msdu);
++ath12k_dp_rx_h_find_peer(struct ath12k_base *ab, struct sk_buff *msdu,
++                       struct ath12k_dp_rx_info *rx_info);
+ u8 ath12k_dp_rx_h_decap_type(struct ath12k_base *ab,
+                            struct hal_rx_desc *desc);
+ u32 ath12k_dp_rx_h_mpdu_err(struct ath12k_base *ab,
+                           struct hal_rx_desc *desc);
+-void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct hal_rx_desc *rx_desc,
+-                       struct ieee80211_rx_status *rx_status);
++void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct ath12k_dp_rx_info *rx_info);
+ int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab);
+ int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab);
+@@ -163,4 +163,6 @@ int ath12k_dp_htt_tlv_iter(struct ath12k_base *ab, const void *ptr, size_t len,
+                          int (*iter)(struct ath12k_base *ar, u16 tag, u16 len,
+                                      const void *ptr, void *data),
+                          void *data);
++void ath12k_dp_rx_h_fetch_info(struct ath12k_base *ab,  struct hal_rx_desc *rx_desc,
++                             struct ath12k_dp_rx_info *rx_info);
+ #endif /* ATH12K_DP_RX_H */
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-ath12k-resolve-multicast-packet-drop-by-populat.patch b/queue-6.15/wifi-ath12k-resolve-multicast-packet-drop-by-populat.patch
new file mode 100644 (file)
index 0000000..ed0b8cd
--- /dev/null
@@ -0,0 +1,57 @@
+From 71696dd27231d79e97c08eb23c793484087dd26c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Apr 2025 13:52:06 +0530
+Subject: wifi: ath12k: Resolve multicast packet drop by populating key_cipher
+ in ath12k_install_key()
+
+From: Aaradhana Sahu <aaradhana.sahu@oss.qualcomm.com>
+
+[ Upstream commit d61c0b3c63462d17e63e5a2b4815e0f1ad17f57e ]
+
+Currently, the key_cipher in the ath12k_vif structure, which represents the
+group cipher of the MLD AP, is populated when the link address matches the
+ieee80211_vif address within ath12k_install_key().
+
+However, in MLD AP, the link address and ieee80211_vif address can differ.
+Due to this key_cipher is not populated and multicast packets don't get the
+correct cipher information and resulting multicast packets drop.
+
+To fix this, compare the link address with the arvif->bssid instead of the
+ieee80211_vif address.
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00209-QCAHKSWPL_SILICONZ-1
+
+Fixes: 3dd2c68f206ef ("wifi: ath12k: prepare vif data structure for MLO handling")
+Signed-off-by: Aaradhana Sahu <aaradhana.sahu@oss.qualcomm.com>
+Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
+Link: https://patch.msgid.link/20250403082207.3323938-2-aaradhana.sahu@oss.qualcomm.com
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/mac.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
+index a1fad297ca357..3883dab6771b8 100644
+--- a/drivers/net/wireless/ath/ath12k/mac.c
++++ b/drivers/net/wireless/ath/ath12k/mac.c
+@@ -4605,7 +4605,6 @@ static int ath12k_install_key(struct ath12k_link_vif *arvif,
+               .macaddr = macaddr,
+       };
+       struct ath12k_vif *ahvif = arvif->ahvif;
+-      struct ieee80211_vif *vif = ath12k_ahvif_to_vif(ahvif);
+       lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
+@@ -4658,7 +4657,7 @@ static int ath12k_install_key(struct ath12k_link_vif *arvif,
+       if (!wait_for_completion_timeout(&ar->install_key_done, 1 * HZ))
+               return -ETIMEDOUT;
+-      if (ether_addr_equal(macaddr, vif->addr))
++      if (ether_addr_equal(macaddr, arvif->bssid))
+               ahvif->key_cipher = key->cipher;
+       return ar->install_key_status ? -EINVAL : 0;
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-ath9k_htc-abort-software-beacon-handling-if-dis.patch b/queue-6.15/wifi-ath9k_htc-abort-software-beacon-handling-if-dis.patch
new file mode 100644 (file)
index 0000000..cc3822f
--- /dev/null
@@ -0,0 +1,48 @@
+From 0611f9093019e99344e477a7b73dd76643a600d5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Apr 2025 13:22:16 +0200
+Subject: wifi: ath9k_htc: Abort software beacon handling if disabled
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Toke Høiland-Jørgensen <toke@toke.dk>
+
+[ Upstream commit ac4e317a95a1092b5da5b9918b7118759342641c ]
+
+A malicious USB device can send a WMI_SWBA_EVENTID event from an
+ath9k_htc-managed device before beaconing has been enabled. This causes
+a device-by-zero error in the driver, leading to either a crash or an
+out of bounds read.
+
+Prevent this by aborting the handling in ath9k_htc_swba() if beacons are
+not enabled.
+
+Reported-by: Robert Morris <rtm@csail.mit.edu>
+Closes: https://lore.kernel.org/r/88967.1743099372@localhost
+Fixes: 832f6a18fc2a ("ath9k_htc: Add beacon slots")
+Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk>
+Link: https://patch.msgid.link/20250402112217.58533-1-toke@toke.dk
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
+index 547634f82183d..81fa7cbad8921 100644
+--- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
++++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
+@@ -290,6 +290,9 @@ void ath9k_htc_swba(struct ath9k_htc_priv *priv,
+       struct ath_common *common = ath9k_hw_common(priv->ah);
+       int slot;
++      if (!priv->cur_beacon_conf.enable_beacon)
++              return;
++
+       if (swba->beacon_pending != 0) {
+               priv->beacon.bmisscnt++;
+               if (priv->beacon.bmisscnt > BSTUCK_THRESHOLD) {
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-cfg80211-mac80211-correctly-parse-s1g-beacon-op.patch b/queue-6.15/wifi-cfg80211-mac80211-correctly-parse-s1g-beacon-op.patch
new file mode 100644 (file)
index 0000000..d9d9778
--- /dev/null
@@ -0,0 +1,245 @@
+From a50c49f0e3b564ca05a7a8cc4bd8810c129349c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Jun 2025 15:35:38 +1000
+Subject: wifi: cfg80211/mac80211: correctly parse S1G beacon optional elements
+
+From: Lachlan Hodges <lachlan.hodges@morsemicro.com>
+
+[ Upstream commit 1e1f706fc2ce90eaaf3480b3d5f27885960d751c ]
+
+S1G beacons are not traditional beacons but a type of extension frame.
+Extension frames contain the frame control and duration fields, followed
+by zero or more optional fields before the frame body. These optional
+fields are distinct from the variable length elements.
+
+The presence of optional fields is indicated in the frame control field.
+To correctly locate the elements offset, the frame control must be parsed
+to identify which optional fields are present. Currently, mac80211 parses
+S1G beacons based on fixed assumptions about the frame layout, without
+inspecting the frame control field. This can result in incorrect offsets
+to the "variable" portion of the frame.
+
+Properly parse S1G beacon frames by using the field lengths defined in
+IEEE 802.11-2024, section 9.3.4.3, ensuring that the elements offset is
+calculated accurately.
+
+Fixes: 9eaffe5078ca ("cfg80211: convert S1G beacon to scan results")
+Fixes: cd418ba63f0c ("mac80211: convert S1G beacon to scan results")
+Signed-off-by: Lachlan Hodges <lachlan.hodges@morsemicro.com>
+Link: https://patch.msgid.link/20250603053538.468562-1-lachlan.hodges@morsemicro.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/ieee80211.h | 79 ++++++++++++++++++++++++++++++++++-----
+ net/mac80211/mlme.c       |  7 +---
+ net/mac80211/scan.c       | 11 +++---
+ net/wireless/scan.c       | 18 ++++-----
+ 4 files changed, 83 insertions(+), 32 deletions(-)
+
+diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
+index 457b4fba88bd0..7edc3fb0641cb 100644
+--- a/include/linux/ieee80211.h
++++ b/include/linux/ieee80211.h
+@@ -111,6 +111,8 @@
+ /* bits unique to S1G beacon */
+ #define IEEE80211_S1G_BCN_NEXT_TBTT   0x100
++#define IEEE80211_S1G_BCN_CSSID               0x200
++#define IEEE80211_S1G_BCN_ANO         0x400
+ /* see 802.11ah-2016 9.9 NDP CMAC frames */
+ #define IEEE80211_S1G_1MHZ_NDP_BITS   25
+@@ -153,9 +155,6 @@
+ #define IEEE80211_ANO_NETTYPE_WILD              15
+-/* bits unique to S1G beacon */
+-#define IEEE80211_S1G_BCN_NEXT_TBTT    0x100
+-
+ /* control extension - for IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTL_EXT */
+ #define IEEE80211_CTL_EXT_POLL                0x2000
+ #define IEEE80211_CTL_EXT_SPR         0x3000
+@@ -627,6 +626,42 @@ static inline bool ieee80211_is_s1g_beacon(__le16 fc)
+              cpu_to_le16(IEEE80211_FTYPE_EXT | IEEE80211_STYPE_S1G_BEACON);
+ }
++/**
++ * ieee80211_s1g_has_next_tbtt - check if IEEE80211_S1G_BCN_NEXT_TBTT
++ * @fc: frame control bytes in little-endian byteorder
++ * Return: whether or not the frame contains the variable-length
++ *    next TBTT field
++ */
++static inline bool ieee80211_s1g_has_next_tbtt(__le16 fc)
++{
++      return ieee80211_is_s1g_beacon(fc) &&
++              (fc & cpu_to_le16(IEEE80211_S1G_BCN_NEXT_TBTT));
++}
++
++/**
++ * ieee80211_s1g_has_ano - check if IEEE80211_S1G_BCN_ANO
++ * @fc: frame control bytes in little-endian byteorder
++ * Return: whether or not the frame contains the variable-length
++ *    ANO field
++ */
++static inline bool ieee80211_s1g_has_ano(__le16 fc)
++{
++      return ieee80211_is_s1g_beacon(fc) &&
++              (fc & cpu_to_le16(IEEE80211_S1G_BCN_ANO));
++}
++
++/**
++ * ieee80211_s1g_has_cssid - check if IEEE80211_S1G_BCN_CSSID
++ * @fc: frame control bytes in little-endian byteorder
++ * Return: whether or not the frame contains the variable-length
++ *    compressed SSID field
++ */
++static inline bool ieee80211_s1g_has_cssid(__le16 fc)
++{
++      return ieee80211_is_s1g_beacon(fc) &&
++              (fc & cpu_to_le16(IEEE80211_S1G_BCN_CSSID));
++}
++
+ /**
+  * ieee80211_is_s1g_short_beacon - check if frame is an S1G short beacon
+  * @fc: frame control bytes in little-endian byteorder
+@@ -1245,16 +1280,40 @@ struct ieee80211_ext {
+                       u8 change_seq;
+                       u8 variable[0];
+               } __packed s1g_beacon;
+-              struct {
+-                      u8 sa[ETH_ALEN];
+-                      __le32 timestamp;
+-                      u8 change_seq;
+-                      u8 next_tbtt[3];
+-                      u8 variable[0];
+-              } __packed s1g_short_beacon;
+       } u;
+ } __packed __aligned(2);
++/**
++ * ieee80211_s1g_optional_len - determine length of optional S1G beacon fields
++ * @fc: frame control bytes in little-endian byteorder
++ * Return: total length in bytes of the optional fixed-length fields
++ *
++ * S1G beacons may contain up to three optional fixed-length fields that
++ * precede the variable-length elements. Whether these fields are present
++ * is indicated by flags in the frame control field.
++ *
++ * From IEEE 802.11-2024 section 9.3.4.3:
++ *  - Next TBTT field may be 0 or 3 bytes
++ *  - Short SSID field may be 0 or 4 bytes
++ *  - Access Network Options (ANO) field may be 0 or 1 byte
++ */
++static inline size_t
++ieee80211_s1g_optional_len(__le16 fc)
++{
++      size_t len = 0;
++
++      if (ieee80211_s1g_has_next_tbtt(fc))
++              len += 3;
++
++      if (ieee80211_s1g_has_cssid(fc))
++              len += 4;
++
++      if (ieee80211_s1g_has_ano(fc))
++              len += 1;
++
++      return len;
++}
++
+ #define IEEE80211_TWT_CONTROL_NDP                     BIT(0)
+ #define IEEE80211_TWT_CONTROL_RESP_MODE                       BIT(1)
+ #define IEEE80211_TWT_CONTROL_NEG_TYPE_BROADCAST      BIT(3)
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index 35eaf0812c5b2..53d5ffad87be8 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -7220,11 +7220,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_link_data *link,
+       bssid = ieee80211_get_bssid(hdr, len, sdata->vif.type);
+       if (ieee80211_is_s1g_beacon(mgmt->frame_control)) {
+               struct ieee80211_ext *ext = (void *) mgmt;
+-
+-              if (ieee80211_is_s1g_short_beacon(ext->frame_control))
+-                      variable = ext->u.s1g_short_beacon.variable;
+-              else
+-                      variable = ext->u.s1g_beacon.variable;
++              variable = ext->u.s1g_beacon.variable +
++                         ieee80211_s1g_optional_len(ext->frame_control);
+       }
+       baselen = (u8 *) variable - (u8 *) mgmt;
+diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
+index cb70790718858..5a56487dab69c 100644
+--- a/net/mac80211/scan.c
++++ b/net/mac80211/scan.c
+@@ -260,6 +260,7 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
+       struct ieee80211_mgmt *mgmt = (void *)skb->data;
+       struct ieee80211_bss *bss;
+       struct ieee80211_channel *channel;
++      struct ieee80211_ext *ext;
+       size_t min_hdr_len = offsetof(struct ieee80211_mgmt,
+                                     u.probe_resp.variable);
+@@ -269,12 +270,10 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
+               return;
+       if (ieee80211_is_s1g_beacon(mgmt->frame_control)) {
+-              if (ieee80211_is_s1g_short_beacon(mgmt->frame_control))
+-                      min_hdr_len = offsetof(struct ieee80211_ext,
+-                                             u.s1g_short_beacon.variable);
+-              else
+-                      min_hdr_len = offsetof(struct ieee80211_ext,
+-                                             u.s1g_beacon);
++              ext = (struct ieee80211_ext *)mgmt;
++              min_hdr_len =
++                      offsetof(struct ieee80211_ext, u.s1g_beacon.variable) +
++                      ieee80211_s1g_optional_len(ext->frame_control);
+       }
+       if (skb->len < min_hdr_len)
+diff --git a/net/wireless/scan.c b/net/wireless/scan.c
+index ddd3a97f6609d..e8a4fe44ec2d8 100644
+--- a/net/wireless/scan.c
++++ b/net/wireless/scan.c
+@@ -3250,6 +3250,7 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
+       const u8 *ie;
+       size_t ielen;
+       u64 tsf;
++      size_t s1g_optional_len;
+       if (WARN_ON(!mgmt))
+               return NULL;
+@@ -3264,12 +3265,11 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
+       if (ieee80211_is_s1g_beacon(mgmt->frame_control)) {
+               ext = (void *) mgmt;
+-              if (ieee80211_is_s1g_short_beacon(mgmt->frame_control))
+-                      min_hdr_len = offsetof(struct ieee80211_ext,
+-                                             u.s1g_short_beacon.variable);
+-              else
+-                      min_hdr_len = offsetof(struct ieee80211_ext,
+-                                             u.s1g_beacon.variable);
++              s1g_optional_len =
++                      ieee80211_s1g_optional_len(ext->frame_control);
++              min_hdr_len =
++                      offsetof(struct ieee80211_ext, u.s1g_beacon.variable) +
++                      s1g_optional_len;
+       } else {
+               /* same for beacons */
+               min_hdr_len = offsetof(struct ieee80211_mgmt,
+@@ -3285,11 +3285,7 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
+               const struct ieee80211_s1g_bcn_compat_ie *compat;
+               const struct element *elem;
+-              if (ieee80211_is_s1g_short_beacon(mgmt->frame_control))
+-                      ie = ext->u.s1g_short_beacon.variable;
+-              else
+-                      ie = ext->u.s1g_beacon.variable;
+-
++              ie = ext->u.s1g_beacon.variable + s1g_optional_len;
+               elem = cfg80211_find_elem(WLAN_EID_S1G_BCN_COMPAT, ie, ielen);
+               if (!elem)
+                       return NULL;
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-iwlfiwi-mvm-fix-the-rate-reporting.patch b/queue-6.15/wifi-iwlfiwi-mvm-fix-the-rate-reporting.patch
new file mode 100644 (file)
index 0000000..d3048f1
--- /dev/null
@@ -0,0 +1,49 @@
+From 70d9169068c3216141ac1e7c766cc290a0273079 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 3 May 2025 22:44:32 +0300
+Subject: wifi: iwlfiwi: mvm: Fix the rate reporting
+
+From: Ilan Peer <ilan.peer@intel.com>
+
+[ Upstream commit 8f7561209eda7d6998708f06376e8dd2dc52f3b8 ]
+
+The rate validation in mac80211 considers a rate to be valid iff both
+the rate index and the count are positive. When the rate scaling is
+managed in the driver and not enough traffic passed to set the actual
+rate, the driver set the rate to be the optimal rate. However, the rate
+count is not set and thus the rate is considered not valid. Fix it by
+setting the count to 1.
+
+Fixes: 3e99b4d28219 ("wifi: mac80211: Sanity check tx bitrate if not provided by driver")
+Signed-off-by: Ilan Peer <ilan.peer@intel.com>
+Reviewed-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Link: https://patch.msgid.link/20250503224232.0d1d1e022d63.I76833c14ba1d66f9bea5c32b25a54d8b36f229ba@changeid
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/mvm/rs.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
+index 068c58e9c1eb4..c2729dab8e79e 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
+@@ -2,6 +2,7 @@
+ /******************************************************************************
+  *
+  * Copyright(c) 2005 - 2014, 2018 - 2023 Intel Corporation. All rights reserved.
++ * Copyright(c) 2025 Intel Corporation
+  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
+  * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+  *****************************************************************************/
+@@ -2709,6 +2710,7 @@ static void rs_drv_get_rate(void *mvm_r, struct ieee80211_sta *sta,
+                                                         optimal_rate);
+               iwl_mvm_hwrate_to_tx_rate_v1(last_ucode_rate, info->band,
+                                            &txrc->reported_rate);
++              txrc->reported_rate.count = 1;
+       }
+       spin_unlock_bh(&lq_sta->pers.lock);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-iwlwifi-mld-avoid-panic-on-init-failure.patch b/queue-6.15/wifi-iwlwifi-mld-avoid-panic-on-init-failure.patch
new file mode 100644 (file)
index 0000000..7c906f2
--- /dev/null
@@ -0,0 +1,48 @@
+From f94c3e64b57464996fbcd492073b6591c24429f3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Jun 2025 06:13:19 +0300
+Subject: wifi: iwlwifi: mld: avoid panic on init failure
+
+From: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+
+[ Upstream commit 960c7e6d388034d219dafffa6da0a5c2ccd5ff30 ]
+
+In case of an error during init, in_hw_restart will be set, but it will
+never get cleared.
+Instead, we will retry to init again, and then we will act like we are in a
+restart when we are actually not.
+
+This causes (among others) to a NULL pointer dereference when canceling
+rx_omi::finished_work, that was not even initialized, because we thought
+that we are in hw_restart.
+
+Set in_hw_restart to true only if the fw is running, then we know that
+FW was loaded successfully and we are not going to the retry loop.
+
+Fixes: 7391b2a4f7db ("wifi: iwlwifi: rework firmware error handling")
+Reviewed-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Link: https://patch.msgid.link/20250604061200.e0040e0a4b09.Iae469a0abe6bfa3c26d8a88c066bad75c2e8f121@changeid
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/mld/mld.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mld.c b/drivers/net/wireless/intel/iwlwifi/mld/mld.c
+index 73d2166a4c257..7a098942dc802 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mld/mld.c
++++ b/drivers/net/wireless/intel/iwlwifi/mld/mld.c
+@@ -638,7 +638,8 @@ iwl_mld_nic_error(struct iwl_op_mode *op_mode,
+        * It might not actually be true that we'll restart, but the
+        * setting doesn't matter if we're going to be unbound either.
+        */
+-      if (type != IWL_ERR_TYPE_RESET_HS_TIMEOUT)
++      if (type != IWL_ERR_TYPE_RESET_HS_TIMEOUT &&
++          mld->fw_status.running)
+               mld->fw_status.in_hw_restart = true;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-iwlwifi-re-add-iwl_amsdu_8k-case.patch b/queue-6.15/wifi-iwlwifi-re-add-iwl_amsdu_8k-case.patch
new file mode 100644 (file)
index 0000000..af3eee3
--- /dev/null
@@ -0,0 +1,36 @@
+From dd963b66f6c0064676af264c5d2ee8e4da192591 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Apr 2025 09:16:29 +0300
+Subject: wifi: iwlwifi: re-add IWL_AMSDU_8K case
+
+From: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+
+[ Upstream commit bdd6d93d7a109ba1080336fe07d0b4eb815efaf9 ]
+
+This case in iwl_trans_get_rb_size_order was accidently combined with
+the IWL_AMSDU_12K case. Fix this.
+
+Fixes: 7391b2a4f7db ("wifi: iwlwifi: rework firmware error handling")
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Link: https://patch.msgid.link/20250423091408.ef19205aa358.Ifbf89e7b7391cd7070267b7360c53230b3b2c57c@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/iwl-trans.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+index ce4954b0d5246..44a249a753ecf 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+@@ -328,6 +328,7 @@ iwl_trans_get_rb_size_order(enum iwl_amsdu_size rb_size)
+       case IWL_AMSDU_4K:
+               return get_order(4 * 1024);
+       case IWL_AMSDU_8K:
++              return get_order(8 * 1024);
+       case IWL_AMSDU_12K:
+               return get_order(16 * 1024);
+       default:
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-mt76-fix-available_antennas-setting.patch b/queue-6.15/wifi-mt76-fix-available_antennas-setting.patch
new file mode 100644 (file)
index 0000000..a6a8524
--- /dev/null
@@ -0,0 +1,42 @@
+From 7f6d483700f7aca5ef8c15d5de385a5218040053 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 May 2025 11:29:51 +0800
+Subject: wifi: mt76: fix available_antennas setting
+
+From: Shayne Chen <shayne.chen@mediatek.com>
+
+[ Upstream commit 249173e94dd5edef9e704f89513de7d9715ddf22 ]
+
+Check if available_antennas_tx and available_antennas_rx are already set
+during the per-chip initialization phase; otherwise, they could be
+overwritten with incorrect values.
+
+Fixes: 69d54ce7491d ("wifi: mt76: mt7996: switch to single multi-radio wiphy")
+Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
+Link: https://patch.msgid.link/20250515032952.1653494-8-shayne.chen@mediatek.com
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mac80211.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c
+index b88d7e10742ee..e9605dc222910 100644
+--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
++++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
+@@ -449,8 +449,10 @@ mt76_phy_init(struct mt76_phy *phy, struct ieee80211_hw *hw)
+       wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_AIRTIME_FAIRNESS);
+       wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_AQL);
+-      wiphy->available_antennas_tx = phy->antenna_mask;
+-      wiphy->available_antennas_rx = phy->antenna_mask;
++      if (!wiphy->available_antennas_tx)
++              wiphy->available_antennas_tx = phy->antenna_mask;
++      if (!wiphy->available_antennas_rx)
++              wiphy->available_antennas_rx = phy->antenna_mask;
+       wiphy->sar_capa = &mt76_sar_capa;
+       phy->frp = devm_kcalloc(dev->dev, wiphy->sar_capa->num_freq_ranges,
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-mt76-mt7915-fix-null-ptr-deref-in-mt7915_mmio_w.patch b/queue-6.15/wifi-mt76-mt7915-fix-null-ptr-deref-in-mt7915_mmio_w.patch
new file mode 100644 (file)
index 0000000..1cda280
--- /dev/null
@@ -0,0 +1,51 @@
+From 39047dff7a0337796f5f9c90b19cb568011dac86 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Apr 2025 14:19:00 +0800
+Subject: wifi: mt76: mt7915: Fix null-ptr-deref in mt7915_mmio_wed_init()
+
+From: Henry Martin <bsdhenrymartin@gmail.com>
+
+[ Upstream commit efb95439c1477bbc955cacd0179c35e7861b437c ]
+
+devm_ioremap() returns NULL on error. Currently, mt7915_mmio_wed_init()
+does not check for this case, which results in a NULL pointer
+dereference.
+
+Prevent null pointer dereference in mt7915_mmio_wed_init().
+
+Fixes: 4f831d18d12d ("wifi: mt76: mt7915: enable WED RX support")
+Signed-off-by: Henry Martin <bsdhenrymartin@gmail.com>
+Link: https://patch.msgid.link/20250407061900.85317-1-bsdhenrymartin@gmail.com
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7915/mmio.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c
+index 876f0692850a2..9c4d5cea0c42e 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c
+@@ -651,6 +651,9 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
+               wed->wlan.base = devm_ioremap(dev->mt76.dev,
+                                             pci_resource_start(pci_dev, 0),
+                                             pci_resource_len(pci_dev, 0));
++              if (!wed->wlan.base)
++                      return -ENOMEM;
++
+               wed->wlan.phy_base = pci_resource_start(pci_dev, 0);
+               wed->wlan.wpdma_int = pci_resource_start(pci_dev, 0) +
+                                     MT_INT_WED_SOURCE_CSR;
+@@ -678,6 +681,9 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
+               wed->wlan.bus_type = MTK_WED_BUS_AXI;
+               wed->wlan.base = devm_ioremap(dev->mt76.dev, res->start,
+                                             resource_size(res));
++              if (!wed->wlan.base)
++                      return -ENOMEM;
++
+               wed->wlan.phy_base = res->start;
+               wed->wlan.wpdma_int = res->start + MT_INT_SOURCE_CSR;
+               wed->wlan.wpdma_mask = res->start + MT_INT_MASK_CSR;
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-mt76-mt7925-ensure-all-mcu-commands-wait-for-re.patch b/queue-6.15/wifi-mt76-mt7925-ensure-all-mcu-commands-wait-for-re.patch
new file mode 100644 (file)
index 0000000..96dfea7
--- /dev/null
@@ -0,0 +1,103 @@
+From 34ac215294d39fdfe008a6bb2bf817467a8abc4b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Apr 2025 09:39:54 +0800
+Subject: wifi: mt76: mt7925: ensure all MCU commands wait for response
+
+From: Michael Lo <michael.lo@mediatek.com>
+
+[ Upstream commit aa97ff5782cf01cf2163593e1f57bbde63a06047 ]
+
+Modify MCU command sending functions to wait for a response,
+ensuring consistent behavior across all commands and improves
+reliability by confirming that each command is processed
+successfully.
+
+Fixes: c948b5da6bbe ("wifi: mt76: mt7925: add Mediatek Wi-Fi7 driver for mt7925 chips")
+Signed-off-by: Michael Lo <michael.lo@mediatek.com>
+Signed-off-by: Ming Yen Hsieh <mingyen.hsieh@mediatek.com>
+Link: https://patch.msgid.link/20250414013954.1151774-3-mingyen.hsieh@mediatek.com
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7925/mcu.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
+index 2bd9fc38a27f4..dea5b9bcb3fdf 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
+@@ -783,7 +783,7 @@ int mt7925_mcu_fw_log_2_host(struct mt792x_dev *dev, u8 ctrl)
+       int ret;
+       ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_UNI_CMD(WSYS_CONFIG),
+-                                      &req, sizeof(req), false, NULL);
++                                      &req, sizeof(req), true, NULL);
+       return ret;
+ }
+@@ -1424,7 +1424,7 @@ int mt7925_mcu_set_eeprom(struct mt792x_dev *dev)
+       };
+       return mt76_mcu_send_and_get_msg(&dev->mt76, MCU_UNI_CMD(EFUSE_CTRL),
+-                                       &req, sizeof(req), false, NULL);
++                                       &req, sizeof(req), true, NULL);
+ }
+ EXPORT_SYMBOL_GPL(mt7925_mcu_set_eeprom);
+@@ -2762,7 +2762,7 @@ int mt7925_mcu_set_dbdc(struct mt76_phy *phy, bool enable)
+       conf->band = 0; /* unused */
+       err = mt76_mcu_skb_send_msg(mdev, skb, MCU_UNI_CMD(SET_DBDC_PARMS),
+-                                  false);
++                                  true);
+       return err;
+ }
+@@ -2870,7 +2870,7 @@ int mt7925_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif,
+       }
+       err = mt76_mcu_skb_send_msg(mdev, skb, MCU_UNI_CMD(SCAN_REQ),
+-                                  false);
++                                  true);
+       if (err < 0)
+               clear_bit(MT76_HW_SCANNING, &phy->state);
+@@ -2976,7 +2976,7 @@ int mt7925_mcu_sched_scan_req(struct mt76_phy *phy,
+       }
+       return mt76_mcu_skb_send_msg(mdev, skb, MCU_UNI_CMD(SCAN_REQ),
+-                                   false);
++                                   true);
+ }
+ EXPORT_SYMBOL_GPL(mt7925_mcu_sched_scan_req);
+@@ -3012,7 +3012,7 @@ mt7925_mcu_sched_scan_enable(struct mt76_phy *phy,
+               clear_bit(MT76_HW_SCHED_SCANNING, &phy->state);
+       return mt76_mcu_skb_send_msg(mdev, skb, MCU_UNI_CMD(SCAN_REQ),
+-                                   false);
++                                   true);
+ }
+ int mt7925_mcu_cancel_hw_scan(struct mt76_phy *phy,
+@@ -3051,7 +3051,7 @@ int mt7925_mcu_cancel_hw_scan(struct mt76_phy *phy,
+       }
+       return mt76_mcu_send_msg(phy->dev, MCU_UNI_CMD(SCAN_REQ),
+-                               &req, sizeof(req), false);
++                               &req, sizeof(req), true);
+ }
+ EXPORT_SYMBOL_GPL(mt7925_mcu_cancel_hw_scan);
+@@ -3156,7 +3156,7 @@ int mt7925_mcu_set_channel_domain(struct mt76_phy *phy)
+       memcpy(__skb_push(skb, sizeof(req)), &req, sizeof(req));
+       return mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD(SET_DOMAIN_INFO),
+-                                   false);
++                                   true);
+ }
+ EXPORT_SYMBOL_GPL(mt7925_mcu_set_channel_domain);
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-mt76-mt7925-fix-logical-vs-bitwise-typo.patch b/queue-6.15/wifi-mt76-mt7925-fix-logical-vs-bitwise-typo.patch
new file mode 100644 (file)
index 0000000..1b91c4d
--- /dev/null
@@ -0,0 +1,36 @@
+From 46f91bfae70f60790eda00f561f62e8a2f10f473 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Mar 2025 17:35:40 +0300
+Subject: wifi: mt76: mt7925: Fix logical vs bitwise typo
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 88224119863c39fa67581874e1ba218fa56113b4 ]
+
+This was supposed to be & instead of &&.
+
+Fixes: f0317215b367 ("wifi: mt76: mt7925: add EHT control support based on the CLC data")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://patch.msgid.link/d323a443-4e81-4064-8563-b62274b53ef4@stanley.mountain
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7925/init.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/init.c b/drivers/net/wireless/mediatek/mt76/mt7925/init.c
+index 63cb08f4d87cc..79639be0d29ac 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7925/init.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7925/init.c
+@@ -89,7 +89,7 @@ void mt7925_regd_be_ctrl(struct mt792x_dev *dev, u8 *alpha2)
+               }
+               /* Check the last one */
+-              if (rule->flag && BIT(0))
++              if (rule->flag & BIT(0))
+                       break;
+               pos += sizeof(*rule);
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-mt76-mt7925-prevent-multiple-scan-commands.patch b/queue-6.15/wifi-mt76-mt7925-prevent-multiple-scan-commands.patch
new file mode 100644 (file)
index 0000000..9623688
--- /dev/null
@@ -0,0 +1,38 @@
+From ce694f559ad6fe7f1f851043eda97b2f8056224d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Apr 2025 09:39:52 +0800
+Subject: wifi: mt76: mt7925: prevent multiple scan commands
+
+From: Ming Yen Hsieh <mingyen.hsieh@mediatek.com>
+
+[ Upstream commit 122f270aca2c86d7de264ab67161c845e0691d73 ]
+
+Add a check to ensure only one scan command is active at a time
+by testing the MT76_HW_SCANNING state.
+
+Fixes: c948b5da6bbe ("wifi: mt76: mt7925: add Mediatek Wi-Fi7 driver for mt7925 chips")
+Signed-off-by: Ming Yen Hsieh <mingyen.hsieh@mediatek.com>
+Link: https://patch.msgid.link/20250414013954.1151774-1-mingyen.hsieh@mediatek.com
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7925/mcu.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
+index 14b1f603fb622..8eaba8c07a62a 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
+@@ -2790,6 +2790,9 @@ int mt7925_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif,
+       struct tlv *tlv;
+       int max_len;
++      if (test_bit(MT76_HW_SCANNING, &phy->state))
++              return -EBUSY;
++
+       max_len = sizeof(*hdr) + sizeof(*req) + sizeof(*ssid) +
+                               sizeof(*bssid) + sizeof(*chan_info) +
+                               sizeof(*misc) + sizeof(*ie);
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-mt76-mt7925-refine-the-sniffer-commnad.patch b/queue-6.15/wifi-mt76-mt7925-refine-the-sniffer-commnad.patch
new file mode 100644 (file)
index 0000000..4824df4
--- /dev/null
@@ -0,0 +1,37 @@
+From 78f2d24c6f8793d1fa9af34826d0c1d017fa599f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Apr 2025 09:39:53 +0800
+Subject: wifi: mt76: mt7925: refine the sniffer commnad
+
+From: Ming Yen Hsieh <mingyen.hsieh@mediatek.com>
+
+[ Upstream commit bd02eebfc0b3502fe8322cf229b4c801416d1007 ]
+
+Remove a duplicate call to `mt76_mcu_send_msg` to fix redundant operations
+in the sniffer command handling.
+
+Fixes: c948b5da6bbe ("wifi: mt76: mt7925: add Mediatek Wi-Fi7 driver for mt7925 chips")
+Signed-off-by: Ming Yen Hsieh <mingyen.hsieh@mediatek.com>
+Link: https://patch.msgid.link/20250414013954.1151774-2-mingyen.hsieh@mediatek.com
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7925/mcu.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
+index 8eaba8c07a62a..2bd9fc38a27f4 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
+@@ -2046,8 +2046,6 @@ int mt7925_mcu_set_sniffer(struct mt792x_dev *dev, struct ieee80211_vif *vif,
+               },
+       };
+-      mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(SNIFFER), &req, sizeof(req), true);
+-
+       return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(SNIFFER), &req, sizeof(req),
+                                true);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-mt76-mt7996-add-null-check-in-mt7996_thermal_in.patch b/queue-6.15/wifi-mt76-mt7996-add-null-check-in-mt7996_thermal_in.patch
new file mode 100644 (file)
index 0000000..e354731
--- /dev/null
@@ -0,0 +1,40 @@
+From fdaa4d13a70e7d9db4ec8675db78d63f94eba42b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Apr 2025 17:55:51 +0800
+Subject: wifi: mt76: mt7996: Add NULL check in mt7996_thermal_init
+
+From: Charles Han <hanchunchao@inspur.com>
+
+[ Upstream commit caf4b347c5dc40fdd125793b5e82ba9fc4de5275 ]
+
+devm_kasprintf() can return a NULL pointer on failure,but this
+returned value in mt7996_thermal_init() is not checked.
+Add NULL check in mt7996_thermal_init(), to handle kernel NULL
+pointer dereference error.
+
+Fixes: 69d54ce7491d ("wifi: mt76: mt7996: switch to single multi-radio wiphy")
+Signed-off-by: Charles Han <hanchunchao@inspur.com>
+Link: https://patch.msgid.link/20250407095551.32127-1-hanchunchao@inspur.com
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7996/init.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/init.c b/drivers/net/wireless/mediatek/mt76/mt7996/init.c
+index 6b660424aedc3..5af52bd1f1f12 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7996/init.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7996/init.c
+@@ -217,6 +217,9 @@ static int mt7996_thermal_init(struct mt7996_phy *phy)
+       name = devm_kasprintf(&wiphy->dev, GFP_KERNEL, "mt7996_%s.%d",
+                             wiphy_name(wiphy), phy->mt76->band_idx);
++      if (!name)
++              return -ENOMEM;
++
+       snprintf(cname, sizeof(cname), "cooling_device%d", phy->mt76->band_idx);
+       cdev = thermal_cooling_device_register(name, phy, &mt7996_thermal_ops);
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-mt76-mt7996-avoid-null-deref-in-mt7996_stop_phy.patch b/queue-6.15/wifi-mt76-mt7996-avoid-null-deref-in-mt7996_stop_phy.patch
new file mode 100644 (file)
index 0000000..eed61d4
--- /dev/null
@@ -0,0 +1,47 @@
+From 6f5bde1a0dd4f65c2fad456f47fa9f43a6f6e468 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Apr 2025 12:13:44 +0100
+Subject: wifi: mt76: mt7996: avoid null deref in mt7996_stop_phy()
+
+From: Qasim Ijaz <qasdev00@gmail.com>
+
+[ Upstream commit a0bdd3d1b94d22dd9d255fd148eb9183ea0a822f ]
+
+In mt7996_stop_phy() the mt7996_phy structure is
+dereferenced before the null sanity check which could
+lead to a null deref.
+
+Fix by moving the dereference operation after the
+sanity check.
+
+Fixes: 69d54ce7491d ("wifi: mt76: mt7996: switch to single multi-radio wiphy")
+Signed-off-by: Qasim Ijaz <qasdev00@gmail.com>
+Link: https://patch.msgid.link/20250421111344.11484-1-qasdev00@gmail.com
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7996/main.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
+index 5ec4f97932865..8698c4345af0c 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
+@@ -68,11 +68,13 @@ static int mt7996_start(struct ieee80211_hw *hw)
+ static void mt7996_stop_phy(struct mt7996_phy *phy)
+ {
+-      struct mt7996_dev *dev = phy->dev;
++      struct mt7996_dev *dev;
+       if (!phy || !test_bit(MT76_STATE_RUNNING, &phy->mt76->state))
+               return;
++      dev = phy->dev;
++
+       cancel_delayed_work_sync(&phy->mt76->mac_work);
+       mutex_lock(&dev->mt76.mutex);
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-mt76-mt7996-avoid-null-pointer-dereference-in-m.patch b/queue-6.15/wifi-mt76-mt7996-avoid-null-pointer-dereference-in-m.patch
new file mode 100644 (file)
index 0000000..bd5d6c1
--- /dev/null
@@ -0,0 +1,47 @@
+From 1d29076cac62455f5ecb3691f7fc7587315afc35 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Apr 2025 12:25:44 +0100
+Subject: wifi: mt76: mt7996: avoid NULL pointer dereference in
+ mt7996_set_monitor()
+
+From: Qasim Ijaz <qasdev00@gmail.com>
+
+[ Upstream commit cb423ddad0f6e6f55b1700422ab777b25597cc83 ]
+
+The function mt7996_set_monitor() dereferences phy before
+the NULL sanity check.
+
+Fix this to avoid NULL pointer dereference by moving the
+dereference after the check.
+
+Fixes: 69d54ce7491d ("wifi: mt76: mt7996: switch to single multi-radio wiphy")
+Signed-off-by: Qasim Ijaz <qasdev00@gmail.com>
+Link: https://patch.msgid.link/20250421112544.13430-1-qasdev00@gmail.com
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7996/main.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
+index 70823bbb165c7..5ec4f97932865 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
+@@ -414,11 +414,13 @@ static void mt7996_phy_set_rxfilter(struct mt7996_phy *phy)
+ static void mt7996_set_monitor(struct mt7996_phy *phy, bool enabled)
+ {
+-      struct mt7996_dev *dev = phy->dev;
++      struct mt7996_dev *dev;
+       if (!phy)
+               return;
++      dev = phy->dev;
++
+       if (enabled == !(phy->rxfilter & MT_WF_RFCR_DROP_OTHER_UC))
+               return;
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-mt76-mt7996-fix-beamformee-ss-field.patch b/queue-6.15/wifi-mt76-mt7996-fix-beamformee-ss-field.patch
new file mode 100644 (file)
index 0000000..e558685
--- /dev/null
@@ -0,0 +1,47 @@
+From d13f70fd29d30dc4f13a07a3bbd04b0abe15c5d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 May 2025 11:29:45 +0800
+Subject: wifi: mt76: mt7996: fix beamformee SS field
+
+From: Howard Hsu <howard-yh.hsu@mediatek.com>
+
+[ Upstream commit 5c78949fc7cd772d483a8abe126fe90937c0f002 ]
+
+Fix the beamformee SS field for the mt7996, mt7992 and mt7990 chipsets.
+For the mt7992, this value shall be set to 0x4, while the others shall
+be set to 0x3.
+
+Fixes: 5b20557593d4 ("wifi: mt76: connac: adjust phy capabilities based on band constraints")
+Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
+Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
+Link: https://patch.msgid.link/20250515032952.1653494-2-shayne.chen@mediatek.com
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7996/init.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/init.c b/drivers/net/wireless/mediatek/mt76/mt7996/init.c
+index 5af52bd1f1f12..e99dfd1771d52 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7996/init.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7996/init.c
+@@ -1116,12 +1116,12 @@ mt7996_set_stream_he_txbf_caps(struct mt7996_phy *phy,
+       c = IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE;
+-      if (is_mt7996(phy->mt76->dev))
+-              c |= IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_4 |
+-                   (IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_4 * non_2g);
+-      else
++      if (is_mt7992(phy->mt76->dev))
+               c |= IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_5 |
+                    (IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_5 * non_2g);
++      else
++              c |= IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_4 |
++                   (IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_4 * non_2g);
+       elem->phy_cap_info[4] |= c;
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-mt76-mt7996-fix-invalid-nss-setting-when-tx-pat.patch b/queue-6.15/wifi-mt76-mt7996-fix-invalid-nss-setting-when-tx-pat.patch
new file mode 100644 (file)
index 0000000..10d66df
--- /dev/null
@@ -0,0 +1,68 @@
+From a9034aeb92b5984466c75b91b28c0d86e8aec140 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 May 2025 11:29:48 +0800
+Subject: wifi: mt76: mt7996: fix invalid NSS setting when TX path differs from
+ NSS
+
+From: Peter Chiu <chui-hao.chiu@mediatek.com>
+
+[ Upstream commit d5012734fc4bd5371e2e8dea8c2f3d28287573b8 ]
+
+The maximum TX path and NSS may differ on a band. For example, one variant
+of the MT7992 has 5 TX paths and 4 NSS on the 5 GHz band. To address this,
+add orig_antenna_mask to record the maximum NSS and prevent setting an
+invalid NSS in mt7996_set_antenna().
+
+Fixes: 69d54ce7491d ("wifi: mt76: mt7996: switch to single multi-radio wiphy")
+Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
+Link: https://patch.msgid.link/20250515032952.1653494-5-shayne.chen@mediatek.com
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7996/eeprom.c | 1 +
+ drivers/net/wireless/mediatek/mt76/mt7996/main.c   | 3 ++-
+ drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h | 1 +
+ 3 files changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7996/eeprom.c
+index 53dfac02f8af0..f0c76aac175df 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7996/eeprom.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7996/eeprom.c
+@@ -304,6 +304,7 @@ int mt7996_eeprom_parse_hw_cap(struct mt7996_dev *dev, struct mt7996_phy *phy)
+               phy->has_aux_rx = true;
+       mphy->antenna_mask = BIT(nss) - 1;
++      phy->orig_antenna_mask = mphy->antenna_mask;
+       mphy->chainmask = (BIT(path) - 1) << dev->chainshift[band_idx];
+       phy->orig_chainmask = mphy->chainmask;
+       dev->chainmask |= mphy->chainmask;
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
+index 8698c4345af0c..a3295b22523a6 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
+@@ -1528,7 +1528,8 @@ mt7996_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
+               u8 shift = dev->chainshift[band_idx];
+               phy->mt76->chainmask = tx_ant & phy->orig_chainmask;
+-              phy->mt76->antenna_mask = phy->mt76->chainmask >> shift;
++              phy->mt76->antenna_mask = (phy->mt76->chainmask >> shift) &
++                                        phy->orig_antenna_mask;
+               mt76_set_stream_caps(phy->mt76, true);
+               mt7996_set_stream_vht_txbf_caps(phy);
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
+index 43e646ed6094c..c393784436d4c 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
+@@ -293,6 +293,7 @@ struct mt7996_phy {
+       struct mt76_channel_state state_ts;
+       u16 orig_chainmask;
++      u16 orig_antenna_mask;
+       bool has_aux_rx;
+       bool counter_reset;
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-mt76-mt7996-fix-null-ptr-deref-in-mt7996_mmio_w.patch b/queue-6.15/wifi-mt76-mt7996-fix-null-ptr-deref-in-mt7996_mmio_w.patch
new file mode 100644 (file)
index 0000000..c8df80e
--- /dev/null
@@ -0,0 +1,41 @@
+From 8f93be32873f62299acdea8905163430d2bd468a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Apr 2025 11:23:49 +0800
+Subject: wifi: mt76: mt7996: Fix null-ptr-deref in mt7996_mmio_wed_init()
+
+From: Henry Martin <bsdhenrymartin@gmail.com>
+
+[ Upstream commit 8f30e2b059757d8711a823e4c9c023db62a1d171 ]
+
+devm_ioremap() returns NULL on error. Currently, mt7996_mmio_wed_init()
+does not check for this case, which results in a NULL pointer
+dereference.
+
+Prevent null pointer dereference in mt7996_mmio_wed_init()
+
+Fixes: 83eafc9251d6 ("wifi: mt76: mt7996: add wed tx support")
+Signed-off-by: Henry Martin <bsdhenrymartin@gmail.com>
+Link: https://patch.msgid.link/20250407032349.83360-1-bsdhenrymartin@gmail.com
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7996/mmio.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c b/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c
+index 13b188e281bdb..af9169030bad9 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c
+@@ -323,6 +323,9 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
+       wed->wlan.base = devm_ioremap(dev->mt76.dev,
+                                     pci_resource_start(pci_dev, 0),
+                                     pci_resource_len(pci_dev, 0));
++      if (!wed->wlan.base)
++              return -ENOMEM;
++
+       wed->wlan.phy_base = pci_resource_start(pci_dev, 0);
+       if (hif2) {
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-mt76-mt7996-fix-rx-buffer-size-of-mcu-event.patch b/queue-6.15/wifi-mt76-mt7996-fix-rx-buffer-size-of-mcu-event.patch
new file mode 100644 (file)
index 0000000..796de32
--- /dev/null
@@ -0,0 +1,71 @@
+From 30c6f3d7a29be3fb61d251f0bdf7a611f75b74a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 May 2025 11:29:50 +0800
+Subject: wifi: mt76: mt7996: fix RX buffer size of MCU event
+
+From: Shayne Chen <shayne.chen@mediatek.com>
+
+[ Upstream commit 42cb27af34de4acf680606fad2c1f2932110591f ]
+
+Some management frames are first processed by the firmware and then
+passed to the driver through the MCU event rings. In CONNAC3, event rings
+do not support scatter-gather and have a size limitation of 2048 bytes.
+If a packet sized between 1728 and 2048 bytes arrives from an event ring,
+the ring will hang because the driver attempts to use scatter-gather to
+process it.
+
+To fix this, include the size of struct skb_shared_info in the MCU RX
+buffer size to prevent scatter-gather from being used for event skb in
+mt76_dma_rx_fill_buf().
+
+Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
+Co-developed-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
+Link: https://patch.msgid.link/20250515032952.1653494-7-shayne.chen@mediatek.com
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7996/dma.c    | 4 ++--
+ drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h | 3 +++
+ 2 files changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/dma.c b/drivers/net/wireless/mediatek/mt76/mt7996/dma.c
+index 69a7d9b2e38bd..4b68d2fc5e094 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7996/dma.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7996/dma.c
+@@ -493,7 +493,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+       ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU],
+                              MT_RXQ_ID(MT_RXQ_MCU),
+                              MT7996_RX_MCU_RING_SIZE,
+-                             MT_RX_BUF_SIZE,
++                             MT7996_RX_MCU_BUF_SIZE,
+                              MT_RXQ_RING_BASE(MT_RXQ_MCU));
+       if (ret)
+               return ret;
+@@ -502,7 +502,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+       ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU_WA],
+                              MT_RXQ_ID(MT_RXQ_MCU_WA),
+                              MT7996_RX_MCU_RING_SIZE_WA,
+-                             MT_RX_BUF_SIZE,
++                             MT7996_RX_MCU_BUF_SIZE,
+                              MT_RXQ_RING_BASE(MT_RXQ_MCU_WA));
+       if (ret)
+               return ret;
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
+index c393784436d4c..77605403b3966 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
+@@ -29,6 +29,9 @@
+ #define MT7996_RX_RING_SIZE           1536
+ #define MT7996_RX_MCU_RING_SIZE               512
+ #define MT7996_RX_MCU_RING_SIZE_WA    1024
++/* scatter-gather of mcu event is not supported in connac3 */
++#define MT7996_RX_MCU_BUF_SIZE                (2048 + \
++                                       SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
+ #define MT7996_FIRMWARE_WA            "mediatek/mt7996/mt7996_wa.bin"
+ #define MT7996_FIRMWARE_WM            "mediatek/mt7996/mt7996_wm.bin"
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-mt76-mt7996-prevent-uninit-return-in-mt7996_mac.patch b/queue-6.15/wifi-mt76-mt7996-prevent-uninit-return-in-mt7996_mac.patch
new file mode 100644 (file)
index 0000000..5d03221
--- /dev/null
@@ -0,0 +1,58 @@
+From d52d8672fab698a781550de1c44086a649c012ca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Apr 2025 12:05:50 +0100
+Subject: wifi: mt76: mt7996: prevent uninit return in mt7996_mac_sta_add_links
+
+From: Qasim Ijaz <qasdev00@gmail.com>
+
+[ Upstream commit d9bc625861d490cb76ae8af86fac6f8ab0655a18 ]
+
+If link_conf_dereference_protected() or mt7996_vif_link()
+or link_sta_dereference_protected() fail the code jumps to
+the error_unlink label and returns ret which is uninitialised.
+
+Fix this by setting err before jumping to error_unlink.
+
+Fixes: c7e4fc362443 ("wifi: mt76: mt7996: Update mt7996_mcu_add_sta to MLO support")
+Fixes: dd82a9e02c05 ("wifi: mt76: mt7996: Rely on mt7996_sta_link in sta_add/sta_remove callbacks")
+Signed-off-by: Qasim Ijaz <qasdev00@gmail.com>
+Link: https://patch.msgid.link/20250421110550.9839-1-qasdev00@gmail.com
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7996/main.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
+index 91c64e3a0860f..70823bbb165c7 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
+@@ -998,16 +998,22 @@ mt7996_mac_sta_add_links(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+                       continue;
+               link_conf = link_conf_dereference_protected(vif, link_id);
+-              if (!link_conf)
++              if (!link_conf) {
++                      err = -EINVAL;
+                       goto error_unlink;
++              }
+               link = mt7996_vif_link(dev, vif, link_id);
+-              if (!link)
++              if (!link) {
++                      err = -EINVAL;
+                       goto error_unlink;
++              }
+               link_sta = link_sta_dereference_protected(sta, link_id);
+-              if (!link_sta)
++              if (!link_sta) {
++                      err = -EINVAL;
+                       goto error_unlink;
++              }
+               err = mt7996_mac_sta_init_link(dev, link_conf, link_sta, link,
+                                              link_id);
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-mt76-mt7996-set-eht-max-ampdu-length-capability.patch b/queue-6.15/wifi-mt76-mt7996-set-eht-max-ampdu-length-capability.patch
new file mode 100644 (file)
index 0000000..4fe7565
--- /dev/null
@@ -0,0 +1,40 @@
+From 42659bf911a5f416431dc1241a00c76cf060ea7a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 May 2025 11:29:46 +0800
+Subject: wifi: mt76: mt7996: set EHT max ampdu length capability
+
+From: Peter Chiu <chui-hao.chiu@mediatek.com>
+
+[ Upstream commit 8b2f574845e33d02e7fbad2d3192a8b717567afa ]
+
+Set the max AMPDU length in the EHT MAC CAP. Without this patch, the
+peer station cannot obtain the correct capability, which prevents
+achieving peak throughput on the 2 GHz band.
+
+Fixes: 1816ad9381e0 ("wifi: mt76: mt7996: add max mpdu len capability")
+Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
+Link: https://patch.msgid.link/20250515032952.1653494-3-shayne.chen@mediatek.com
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7996/init.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/init.c b/drivers/net/wireless/mediatek/mt76/mt7996/init.c
+index e99dfd1771d52..4906b0ecc73e0 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7996/init.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7996/init.c
+@@ -1321,6 +1321,9 @@ mt7996_init_eht_caps(struct mt7996_phy *phy, enum nl80211_band band,
+               u8_encode_bits(IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_11454,
+                              IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_MASK);
++      eht_cap_elem->mac_cap_info[1] |=
++              IEEE80211_EHT_MAC_CAP1_MAX_AMPDU_LEN_MASK;
++
+       eht_cap_elem->phy_cap_info[0] =
+               IEEE80211_EHT_PHY_CAP0_NDP_4_EHT_LFT_32_GI |
+               IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMER |
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-mt76-scan-fix-mlink-dereferenced-before-is_err_.patch b/queue-6.15/wifi-mt76-scan-fix-mlink-dereferenced-before-is_err_.patch
new file mode 100644 (file)
index 0000000..c17e6df
--- /dev/null
@@ -0,0 +1,44 @@
+From 1082e461fdb3a3703af0216103d3e3f11ad83b23 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Apr 2025 14:24:15 +0800
+Subject: wifi: mt76: scan: Fix 'mlink' dereferenced before IS_ERR_OR_NULL
+ check
+
+From: Feng Jiang <jiangfeng@kylinos.cn>
+
+[ Upstream commit 7e1fcf687c2fb22ad25cf3fae322a37452f5f560 ]
+
+Reported-by: kernel test robot <lkp@intel.com>
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Closes: https://lore.kernel.org/r/202504011739.HvUKtUUe-lkp@intel.com/
+Fixes: 3ba20af886d1 ("wifi: mt76: scan: set vif offchannel link for scanning/roc")
+Signed-off-by: Feng Jiang <jiangfeng@kylinos.cn>
+Link: https://patch.msgid.link/20250402062415.25434-1-jiangfeng@kylinos.cn
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/channel.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/channel.c b/drivers/net/wireless/mediatek/mt76/channel.c
+index e7b839e742903..cc2d888e3f17a 100644
+--- a/drivers/net/wireless/mediatek/mt76/channel.c
++++ b/drivers/net/wireless/mediatek/mt76/channel.c
+@@ -302,11 +302,13 @@ void mt76_put_vif_phy_link(struct mt76_phy *phy, struct ieee80211_vif *vif,
+                          struct mt76_vif_link *mlink)
+ {
+       struct mt76_dev *dev = phy->dev;
+-      struct mt76_vif_data *mvif = mlink->mvif;
++      struct mt76_vif_data *mvif;
+       if (IS_ERR_OR_NULL(mlink) || !mlink->offchannel)
+               return;
++      mvif = mlink->mvif;
++
+       rcu_assign_pointer(mvif->offchannel_link, NULL);
+       dev->drv->vif_link_remove(phy, vif, &vif->bss_conf, mlink);
+       kfree(mlink);
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-rtw88-do-not-ignore-hardware-read-error-during-.patch b/queue-6.15/wifi-rtw88-do-not-ignore-hardware-read-error-during-.patch
new file mode 100644 (file)
index 0000000..04a788e
--- /dev/null
@@ -0,0 +1,42 @@
+From 543354db68fb01bc2afe161d15be8a94520dbe04 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Apr 2025 12:07:20 +0300
+Subject: wifi: rtw88: do not ignore hardware read error during DPK
+
+From: Dmitry Antipov <dmantipov@yandex.ru>
+
+[ Upstream commit 20d3c19bd8f9b498173c198eadf54580c8caa336 ]
+
+In 'rtw8822c_dpk_cal_coef1()', do not ignore error returned
+by 'check_hw_ready()' but issue a warning to denote possible
+DPK issue. Compile tested only.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: 5227c2ee453d ("rtw88: 8822c: add SW DPK support")
+Suggested-by: Ping-Ke Shih <pkshih@realtek.com>
+Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
+Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
+Link: https://patch.msgid.link/20250415090720.194048-1-dmantipov@yandex.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtw88/rtw8822c.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
+index 5e53e0db177ef..8937a7b656edb 100644
+--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c
++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
+@@ -3951,7 +3951,8 @@ static void rtw8822c_dpk_cal_coef1(struct rtw_dev *rtwdev)
+       rtw_write32(rtwdev, REG_NCTL0, 0x00001148);
+       rtw_write32(rtwdev, REG_NCTL0, 0x00001149);
+-      check_hw_ready(rtwdev, 0x2d9c, MASKBYTE0, 0x55);
++      if (!check_hw_ready(rtwdev, 0x2d9c, MASKBYTE0, 0x55))
++              rtw_warn(rtwdev, "DPK stuck, performance may be suboptimal");
+       rtw_write8(rtwdev, 0x1b10, 0x0);
+       rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x0000000c);
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-rtw88-fix-the-para-buffer-size-to-avoid-reading.patch b/queue-6.15/wifi-rtw88-fix-the-para-buffer-size-to-avoid-reading.patch
new file mode 100644 (file)
index 0000000..45e3708
--- /dev/null
@@ -0,0 +1,48 @@
+From 088ef9a83354a3fd3cc4e5e0a9401e33c2430dc4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 May 2025 12:13:04 +0000
+Subject: wifi: rtw88: fix the 'para' buffer size to avoid reading out of
+ bounds
+
+From: Alexey Kodanev <aleksei.kodanev@bell-sw.com>
+
+[ Upstream commit 4c2c372de2e108319236203cce6de44d70ae15cd ]
+
+Set the size to 6 instead of 2, since 'para' array is passed to
+'rtw_fw_bt_wifi_control(rtwdev, para[0], &para[1])', which reads
+5 bytes:
+
+void rtw_fw_bt_wifi_control(struct rtw_dev *rtwdev, u8 op_code, u8 *data)
+{
+    ...
+    SET_BT_WIFI_CONTROL_DATA1(h2c_pkt, *data);
+    SET_BT_WIFI_CONTROL_DATA2(h2c_pkt, *(data + 1));
+    ...
+    SET_BT_WIFI_CONTROL_DATA5(h2c_pkt, *(data + 4));
+
+Detected using the static analysis tool - Svace.
+Fixes: 4136214f7c46 ("rtw88: add BT co-existence support")
+Signed-off-by: Alexey Kodanev <aleksei.kodanev@bell-sw.com>
+Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
+Link: https://patch.msgid.link/20250513121304.124141-1-aleksei.kodanev@bell-sw.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtw88/coex.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/realtek/rtw88/coex.c b/drivers/net/wireless/realtek/rtw88/coex.c
+index c929db1e53ca6..64904278ddad7 100644
+--- a/drivers/net/wireless/realtek/rtw88/coex.c
++++ b/drivers/net/wireless/realtek/rtw88/coex.c
+@@ -309,7 +309,7 @@ static void rtw_coex_tdma_timer_base(struct rtw_dev *rtwdev, u8 type)
+ {
+       struct rtw_coex *coex = &rtwdev->coex;
+       struct rtw_coex_stat *coex_stat = &coex->stat;
+-      u8 para[2] = {0};
++      u8 para[6] = {};
+       u8 times;
+       u16 tbtt_interval = coex_stat->wl_beacon_interval;
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-rtw88-sdio-call-rtw_sdio_indicate_tx_status-unc.patch b/queue-6.15/wifi-rtw88-sdio-call-rtw_sdio_indicate_tx_status-unc.patch
new file mode 100644 (file)
index 0000000..9443661
--- /dev/null
@@ -0,0 +1,46 @@
+From 380e1d1388059538573f04312dba704f25810fe7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Apr 2025 15:42:16 +0000
+Subject: wifi: rtw88: sdio: call rtw_sdio_indicate_tx_status unconditionally
+
+From: Zhen XIN <zhen.xin@nokia-sbell.com>
+
+[ Upstream commit fc5f5a0ec463ae6a07850428bd3082947e01d276 ]
+
+The rtw88-sdio do not work in AP mode due to the lack of TX status report
+for management frames.
+
+Make the invocation of rtw_sdio_indicate_tx_status unconditional and cover
+all packet queues
+
+Tested-on: rtl8723ds
+
+Fixes: 65371a3f14e7 ("wifi: rtw88: sdio: Add HCI implementation for SDIO based chipsets")
+Signed-off-by: Zhen XIN <zhen.xin@nokia-sbell.com>
+Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
+Link: https://patch.msgid.link/20250410154217.1849977-2-zhen.xin@nokia-sbell.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtw88/sdio.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c
+index ba600d40bba46..410f637b1add5 100644
+--- a/drivers/net/wireless/realtek/rtw88/sdio.c
++++ b/drivers/net/wireless/realtek/rtw88/sdio.c
+@@ -1224,10 +1224,7 @@ static void rtw_sdio_process_tx_queue(struct rtw_dev *rtwdev,
+               return;
+       }
+-      if (queue <= RTW_TX_QUEUE_VO)
+-              rtw_sdio_indicate_tx_status(rtwdev, skb);
+-      else
+-              dev_kfree_skb_any(skb);
++      rtw_sdio_indicate_tx_status(rtwdev, skb);
+ }
+ static void rtw_sdio_tx_handler(struct work_struct *work)
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-rtw88-sdio-map-mgmt-frames-to-queue-tx_desc_qse.patch b/queue-6.15/wifi-rtw88-sdio-map-mgmt-frames-to-queue-tx_desc_qse.patch
new file mode 100644 (file)
index 0000000..ea947cd
--- /dev/null
@@ -0,0 +1,46 @@
+From 22392516cb3d15a469513b6110a203238049f31e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Apr 2025 15:42:17 +0000
+Subject: wifi: rtw88: sdio: map mgmt frames to queue TX_DESC_QSEL_MGMT
+
+From: Zhen XIN <zhen.xin@nokia-sbell.com>
+
+[ Upstream commit b2effcdc237979dcc533d446a792fc54fd0e1213 ]
+
+The rtw88-sdio do not work in AP mode due to the lack of TX status report
+for management frames.
+
+Map the management frames to queue TX_DESC_QSEL_MGMT, which enables the
+chip to generate TX reports for these frames
+
+Tested-on: rtl8723ds
+
+Fixes: 65371a3f14e7 ("wifi: rtw88: sdio: Add HCI implementation for SDIO based chipsets")
+Signed-off-by: Zhen XIN <zhen.xin@nokia-sbell.com>
+Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
+Link: https://patch.msgid.link/20250410154217.1849977-3-zhen.xin@nokia-sbell.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtw88/sdio.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c
+index 6209a49312f17..ba600d40bba46 100644
+--- a/drivers/net/wireless/realtek/rtw88/sdio.c
++++ b/drivers/net/wireless/realtek/rtw88/sdio.c
+@@ -718,10 +718,7 @@ static u8 rtw_sdio_get_tx_qsel(struct rtw_dev *rtwdev, struct sk_buff *skb,
+       case RTW_TX_QUEUE_H2C:
+               return TX_DESC_QSEL_H2C;
+       case RTW_TX_QUEUE_MGMT:
+-              if (rtw_chip_wcpu_11n(rtwdev))
+-                      return TX_DESC_QSEL_HIGH;
+-              else
+-                      return TX_DESC_QSEL_MGMT;
++              return TX_DESC_QSEL_MGMT;
+       case RTW_TX_QUEUE_HI0:
+               return TX_DESC_QSEL_HIGH;
+       default:
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-rtw89-fix-firmware-scan-delay-unit-for-wifi-6-c.patch b/queue-6.15/wifi-rtw89-fix-firmware-scan-delay-unit-for-wifi-6-c.patch
new file mode 100644 (file)
index 0000000..d004ebc
--- /dev/null
@@ -0,0 +1,38 @@
+From f7308d1272122d320c56abacde219ac7deb0f88b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 May 2025 20:52:03 +0800
+Subject: wifi: rtw89: fix firmware scan delay unit for WiFi 6 chips
+
+From: Chin-Yen Lee <timlee@realtek.com>
+
+[ Upstream commit 3cc35394fac15d533639c9c9e42f28d28936a4a0 ]
+
+The scan delay unit of firmware command for WiFi 6 chips is
+microsecond, but is wrong set now and lead to abnormal work
+for net-detect. Correct the unit to avoid the error.
+
+Fixes: e99dd80c8a18 ("wifi: rtw89: wow: add delay option for net-detect")
+Signed-off-by: Chin-Yen Lee <timlee@realtek.com>
+Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
+Link: https://patch.msgid.link/20250513125203.6858-1-pkshih@realtek.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtw89/fw.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
+index 8643b17866f89..6c52b0425f2ea 100644
+--- a/drivers/net/wireless/realtek/rtw89/fw.c
++++ b/drivers/net/wireless/realtek/rtw89/fw.c
+@@ -5477,7 +5477,7 @@ int rtw89_fw_h2c_scan_list_offload_be(struct rtw89_dev *rtwdev, int ch_num,
+       return 0;
+ }
+-#define RTW89_SCAN_DELAY_TSF_UNIT 104800
++#define RTW89_SCAN_DELAY_TSF_UNIT 1000000
+ int rtw89_fw_h2c_scan_offload_ax(struct rtw89_dev *rtwdev,
+                                struct rtw89_scan_option *option,
+                                struct rtw89_vif_link *rtwvif_link,
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-rtw89-pci-configure-manual-dac-mode-via-pci-con.patch b/queue-6.15/wifi-rtw89-pci-configure-manual-dac-mode-via-pci-con.patch
new file mode 100644 (file)
index 0000000..8547cfc
--- /dev/null
@@ -0,0 +1,159 @@
+From 569b6c9d8f2bea0f2615a8c7991b2f7e0f93809e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 May 2025 09:53:56 +0800
+Subject: wifi: rtw89: pci: configure manual DAC mode via PCI config API only
+
+From: Ping-Ke Shih <pkshih@realtek.com>
+
+[ Upstream commit a70cf04b08f44f41bce14659aa7012674b15d9de ]
+
+To support 36-bit DMA, configure chip proprietary bit via PCI config API
+or chip DBI interface. However, the PCI device mmap isn't set yet and
+the DBI is also inaccessible via mmap, so only if the bit can be accessible
+via PCI config API, chip can support 36-bit DMA. Otherwise, fallback to
+32-bit DMA.
+
+With NULL mmap address, kernel throws trace:
+
+  BUG: unable to handle page fault for address: 0000000000001090
+  #PF: supervisor write access in kernel mode
+  #PF: error_code(0x0002) - not-present page
+  PGD 0 P4D 0
+  Oops: Oops: 0002 [#1] PREEMPT SMP PTI
+  CPU: 1 UID: 0 PID: 71 Comm: irq/26-pciehp Tainted: G           OE      6.14.2-061402-generic #202504101348
+  Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
+  RIP: 0010:rtw89_pci_ops_write16+0x12/0x30 [rtw89_pci]
+  RSP: 0018:ffffb0ffc0acf9d8 EFLAGS: 00010206
+  RAX: ffffffffc158f9c0 RBX: ffff94865e702020 RCX: 0000000000000000
+  RDX: 0000000000000718 RSI: 0000000000001090 RDI: ffff94865e702020
+  RBP: ffffb0ffc0acf9d8 R08: 0000000000000000 R09: 0000000000000000
+  R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000015
+  R13: 0000000000000719 R14: ffffb0ffc0acfa1f R15: ffffffffc1813060
+  FS:  0000000000000000(0000) GS:ffff9486f3480000(0000) knlGS:0000000000000000
+  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+  CR2: 0000000000001090 CR3: 0000000090440001 CR4: 00000000000626f0
+  Call Trace:
+   <TASK>
+   rtw89_pci_read_config_byte+0x6d/0x120 [rtw89_pci]
+   rtw89_pci_cfg_dac+0x5b/0xb0 [rtw89_pci]
+   rtw89_pci_probe+0xa96/0xbd0 [rtw89_pci]
+   ? __pfx___device_attach_driver+0x10/0x10
+   ? __pfx___device_attach_driver+0x10/0x10
+   local_pci_probe+0x47/0xa0
+   pci_call_probe+0x5d/0x190
+   pci_device_probe+0xa7/0x160
+   really_probe+0xf9/0x370
+   ? pm_runtime_barrier+0x55/0xa0
+   __driver_probe_device+0x8c/0x140
+   driver_probe_device+0x24/0xd0
+   __device_attach_driver+0xcd/0x170
+   bus_for_each_drv+0x99/0x100
+   __device_attach+0xb4/0x1d0
+   device_attach+0x10/0x20
+   pci_bus_add_device+0x59/0x90
+   pci_bus_add_devices+0x31/0x80
+   pciehp_configure_device+0xaa/0x170
+   pciehp_enable_slot+0xd6/0x240
+   pciehp_handle_presence_or_link_change+0xf1/0x180
+   pciehp_ist+0x162/0x1c0
+   irq_thread_fn+0x24/0x70
+   irq_thread+0xef/0x1c0
+   ? __pfx_irq_thread_fn+0x10/0x10
+   ? __pfx_irq_thread_dtor+0x10/0x10
+   ? __pfx_irq_thread+0x10/0x10
+   kthread+0xfc/0x230
+   ? __pfx_kthread+0x10/0x10
+   ret_from_fork+0x47/0x70
+   ? __pfx_kthread+0x10/0x10
+   ret_from_fork_asm+0x1a/0x30
+   </TASK>
+
+Fixes: 1fd4b3fe52ef ("wifi: rtw89: pci: support 36-bit PCI DMA address")
+Reported-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
+Closes: https://lore.kernel.org/linux-wireless/ccaf49b6-ff41-4917-90f1-f53cadaaa0da@gmail.com/T/#u
+Closes: https://github.com/openwrt/openwrt/issues/17025
+Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
+Link: https://patch.msgid.link/20250506015356.7995-1-pkshih@realtek.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtw89/pci.c | 34 ++++++++++++++++--------
+ 1 file changed, 23 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c
+index c2fe5a898dc71..b5cdc18f802a9 100644
+--- a/drivers/net/wireless/realtek/rtw89/pci.c
++++ b/drivers/net/wireless/realtek/rtw89/pci.c
+@@ -3105,17 +3105,26 @@ static bool rtw89_pci_is_dac_compatible_bridge(struct rtw89_dev *rtwdev)
+       return false;
+ }
+-static void rtw89_pci_cfg_dac(struct rtw89_dev *rtwdev)
++static int rtw89_pci_cfg_dac(struct rtw89_dev *rtwdev, bool force)
+ {
+       struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
++      struct pci_dev *pdev = rtwpci->pdev;
++      int ret;
++      u8 val;
+-      if (!rtwpci->enable_dac)
+-              return;
++      if (!rtwpci->enable_dac && !force)
++              return 0;
+       if (!rtw89_pci_chip_is_manual_dac(rtwdev))
+-              return;
++              return 0;
+-      rtw89_pci_config_byte_set(rtwdev, RTW89_PCIE_L1_CTRL, RTW89_PCIE_BIT_EN_64BITS);
++      /* Configure DAC only via PCI config API, not DBI interfaces */
++      ret = pci_read_config_byte(pdev, RTW89_PCIE_L1_CTRL, &val);
++      if (ret)
++              return ret;
++
++      val |= RTW89_PCIE_BIT_EN_64BITS;
++      return pci_write_config_byte(pdev, RTW89_PCIE_L1_CTRL, val);
+ }
+ static int rtw89_pci_setup_mapping(struct rtw89_dev *rtwdev,
+@@ -3133,13 +3142,16 @@ static int rtw89_pci_setup_mapping(struct rtw89_dev *rtwdev,
+       }
+       if (!rtw89_pci_is_dac_compatible_bridge(rtwdev))
+-              goto no_dac;
++              goto try_dac_done;
+       ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(36));
+       if (!ret) {
+-              rtwpci->enable_dac = true;
+-              rtw89_pci_cfg_dac(rtwdev);
+-      } else {
++              ret = rtw89_pci_cfg_dac(rtwdev, true);
++              if (!ret) {
++                      rtwpci->enable_dac = true;
++                      goto try_dac_done;
++              }
++
+               ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+               if (ret) {
+                       rtw89_err(rtwdev,
+@@ -3147,7 +3159,7 @@ static int rtw89_pci_setup_mapping(struct rtw89_dev *rtwdev,
+                       goto err_release_regions;
+               }
+       }
+-no_dac:
++try_dac_done:
+       resource_len = pci_resource_len(pdev, bar_id);
+       rtwpci->mmap = pci_iomap(pdev, bar_id, resource_len);
+@@ -4302,7 +4314,7 @@ static void rtw89_pci_l2_hci_ldo(struct rtw89_dev *rtwdev)
+ void rtw89_pci_basic_cfg(struct rtw89_dev *rtwdev, bool resume)
+ {
+       if (resume)
+-              rtw89_pci_cfg_dac(rtwdev);
++              rtw89_pci_cfg_dac(rtwdev, false);
+       rtw89_pci_disable_eq(rtwdev);
+       rtw89_pci_filter_out(rtwdev);
+-- 
+2.39.5
+
diff --git a/queue-6.15/wifi-rtw89-pci-enlarge-retry-times-of-rx-tag-to-1000.patch b/queue-6.15/wifi-rtw89-pci-enlarge-retry-times-of-rx-tag-to-1000.patch
new file mode 100644 (file)
index 0000000..6ad4dc7
--- /dev/null
@@ -0,0 +1,44 @@
+From adf4cc0fba23a114aab685a62744f9ff7ae80894 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 May 2025 09:34:33 +0800
+Subject: wifi: rtw89: pci: enlarge retry times of RX tag to 1000
+
+From: Ping-Ke Shih <pkshih@realtek.com>
+
+[ Upstream commit dda27a47c036d981ec664ac57e044a21035ffe12 ]
+
+RX tag is sequence number to ensure RX DMA is complete. On platform
+Gigabyte X870 AORUS ELITE WIFI7, sometimes it needs longer retry times
+to complete RX DMA, or driver throws warnings and connection drops:
+
+  rtw89_8922ae 0000:07:00.0: failed to update 162 RXBD info: -11
+  rtw89_8922ae 0000:07:00.0: failed to update 163 RXBD info: -11
+  rtw89_8922ae 0000:07:00.0: failed to update 32 RXBD info: -11
+  rtw89_8922ae 0000:07:00.0: failed to release TX skbs
+
+Fixes: 0bc7d1d4e63c ("wifi: rtw89: pci: validate RX tag for RXQ and RPQ")
+Reported-by: Samuel Reyes <zohrlaffz@gmail.com>
+Closes: https://lore.kernel.org/linux-wireless/f4355539f3ac46bbaf9c586d059a8cbb@realtek.com/T/#t
+Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
+Link: https://patch.msgid.link/20250509013433.7573-1-pkshih@realtek.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtw89/pci.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c
+index b5cdc18f802a9..064f6a9401073 100644
+--- a/drivers/net/wireless/realtek/rtw89/pci.c
++++ b/drivers/net/wireless/realtek/rtw89/pci.c
+@@ -228,7 +228,7 @@ int rtw89_pci_sync_skb_for_device_and_validate_rx_info(struct rtw89_dev *rtwdev,
+                                                      struct sk_buff *skb)
+ {
+       struct rtw89_pci_rx_info *rx_info = RTW89_PCI_RX_SKB_CB(skb);
+-      int rx_tag_retry = 100;
++      int rx_tag_retry = 1000;
+       int ret;
+       do {
+-- 
+2.39.5
+
diff --git a/queue-6.15/wireguard-device-enable-threaded-napi.patch b/queue-6.15/wireguard-device-enable-threaded-napi.patch
new file mode 100644 (file)
index 0000000..e82dd58
--- /dev/null
@@ -0,0 +1,79 @@
+From 939fe3d2a0d19e8c165d02ffdae4f7f6d5776b8d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Jun 2025 14:06:16 +0200
+Subject: wireguard: device: enable threaded NAPI
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Mirco Barone <mirco.barone@polito.it>
+
+[ Upstream commit db9ae3b6b43c79b1ba87eea849fd65efa05b4b2e ]
+
+Enable threaded NAPI by default for WireGuard devices in response to low
+performance behavior that we observed when multiple tunnels (and thus
+multiple wg devices) are deployed on a single host.  This affects any
+kind of multi-tunnel deployment, regardless of whether the tunnels share
+the same endpoints or not (i.e., a VPN concentrator type of gateway
+would also be affected).
+
+The problem is caused by the fact that, in case of a traffic surge that
+involves multiple tunnels at the same time, the polling of the NAPI
+instance of all these wg devices tends to converge onto the same core,
+causing underutilization of the CPU and bottlenecking performance.
+
+This happens because NAPI polling is hosted by default in softirq
+context, but the WireGuard driver only raises this softirq after the rx
+peer queue has been drained, which doesn't happen during high traffic.
+In this case, the softirq already active on a core is reused instead of
+raising a new one.
+
+As a result, once two or more tunnel softirqs have been scheduled on
+the same core, they remain pinned there until the surge ends.
+
+In our experiments, this almost always leads to all tunnel NAPIs being
+handled on a single core shortly after a surge begins, limiting
+scalability to less than 3× the performance of a single tunnel, despite
+plenty of unused CPU cores being available.
+
+The proposed mitigation is to enable threaded NAPI for all WireGuard
+devices. This moves the NAPI polling context to a dedicated per-device
+kernel thread, allowing the scheduler to balance the load across all
+available cores.
+
+On our 32-core gateways, enabling threaded NAPI yields a ~4× performance
+improvement with 16 tunnels, increasing throughput from ~13 Gbps to
+~48 Gbps. Meanwhile, CPU usage on the receiver (which is the bottleneck)
+jumps from 20% to 100%.
+
+We have found no performance regressions in any scenario we tested.
+Single-tunnel throughput remains unchanged.
+
+More details are available in our Netdev paper.
+
+Link: https://netdevconf.info/0x18/docs/netdev-0x18-paper23-talk-paper.pdf
+Signed-off-by: Mirco Barone <mirco.barone@polito.it>
+Fixes: e7096c131e51 ("net: WireGuard secure network tunnel")
+Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
+Link: https://patch.msgid.link/20250605120616.2808744-1-Jason@zx2c4.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireguard/device.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireguard/device.c b/drivers/net/wireguard/device.c
+index 3ffeeba5dccf4..4a529f1f9beab 100644
+--- a/drivers/net/wireguard/device.c
++++ b/drivers/net/wireguard/device.c
+@@ -366,6 +366,7 @@ static int wg_newlink(struct net_device *dev,
+       if (ret < 0)
+               goto err_free_handshake_queue;
++      dev_set_threaded(dev, true);
+       ret = register_netdevice(dev);
+       if (ret < 0)
+               goto err_uninit_ratelimiter;
+-- 
+2.39.5
+
diff --git a/queue-6.15/x86-cpu-sanitize-cpuid-0x80000000-output.patch b/queue-6.15/x86-cpu-sanitize-cpuid-0x80000000-output.patch
new file mode 100644 (file)
index 0000000..4f184e2
--- /dev/null
@@ -0,0 +1,92 @@
+From d285122f736214966b0d689111b01f54a20bdb5e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 May 2025 07:04:13 +0200
+Subject: x86/cpu: Sanitize CPUID(0x80000000) output
+
+From: Ahmed S. Darwish <darwi@linutronix.de>
+
+[ Upstream commit cc663ba3fe383a628a812f893cc98aafff39ab04 ]
+
+CPUID(0x80000000).EAX returns the max extended CPUID leaf available.  On
+x86-32 machines without an extended CPUID range, a CPUID(0x80000000)
+query will just repeat the output of the last valid standard CPUID leaf
+on the CPU; i.e., a garbage values.  Current tip:x86/cpu code protects against
+this by doing:
+
+       eax = cpuid_eax(0x80000000);
+       c->extended_cpuid_level = eax;
+
+       if ((eax & 0xffff0000) == 0x80000000) {
+               // CPU has an extended CPUID range. Check for 0x80000001
+               if (eax >= 0x80000001) {
+                       cpuid(0x80000001, ...);
+               }
+       }
+
+This is correct so far.  Afterwards though, the same possibly broken EAX
+value is used to check the availability of other extended CPUID leaves:
+
+       if (c->extended_cpuid_level >= 0x80000007)
+               ...
+       if (c->extended_cpuid_level >= 0x80000008)
+               ...
+       if (c->extended_cpuid_level >= 0x8000000a)
+               ...
+       if (c->extended_cpuid_level >= 0x8000001f)
+               ...
+
+which is invalid.  Fix this by immediately setting the CPU's max extended
+CPUID leaf to zero if CPUID(0x80000000).EAX doesn't indicate a valid
+CPUID extended range.
+
+While at it, add a comment, similar to kernel/head_32.S, clarifying the
+CPUID(0x80000000) sanity check.
+
+References: 8a50e5135af0 ("x86-32: Use symbolic constants, safer CPUID when enabling EFER.NX")
+Fixes: 3da99c977637 ("x86: make (early)_identify_cpu more the same between 32bit and 64 bit")
+Signed-off-by: Ahmed S. Darwish <darwi@linutronix.de>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Cc: Andrew Cooper <andrew.cooper3@citrix.com>
+Cc: H. Peter Anvin <hpa@zytor.com>
+Cc: John Ogness <john.ogness@linutronix.de>
+Cc: x86-cpuid@lists.linux.dev
+Link: https://lore.kernel.org/r/20250506050437.10264-3-darwi@linutronix.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/cpu/common.c | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
+index 0ff057ff11ce9..5de4a879232a6 100644
+--- a/arch/x86/kernel/cpu/common.c
++++ b/arch/x86/kernel/cpu/common.c
+@@ -1005,17 +1005,18 @@ void get_cpu_cap(struct cpuinfo_x86 *c)
+               c->x86_capability[CPUID_D_1_EAX] = eax;
+       }
+-      /* AMD-defined flags: level 0x80000001 */
++      /*
++       * Check if extended CPUID leaves are implemented: Max extended
++       * CPUID leaf must be in the 0x80000001-0x8000ffff range.
++       */
+       eax = cpuid_eax(0x80000000);
+-      c->extended_cpuid_level = eax;
++      c->extended_cpuid_level = ((eax & 0xffff0000) == 0x80000000) ? eax : 0;
+-      if ((eax & 0xffff0000) == 0x80000000) {
+-              if (eax >= 0x80000001) {
+-                      cpuid(0x80000001, &eax, &ebx, &ecx, &edx);
++      if (c->extended_cpuid_level >= 0x80000001) {
++              cpuid(0x80000001, &eax, &ebx, &ecx, &edx);
+-                      c->x86_capability[CPUID_8000_0001_ECX] = ecx;
+-                      c->x86_capability[CPUID_8000_0001_EDX] = edx;
+-              }
++              c->x86_capability[CPUID_8000_0001_ECX] = ecx;
++              c->x86_capability[CPUID_8000_0001_EDX] = edx;
+       }
+       if (c->extended_cpuid_level >= 0x80000007) {
+-- 
+2.39.5
+
diff --git a/queue-6.15/x86-idle-remove-mfences-for-x86_bug_clflush_monitor-.patch b/queue-6.15/x86-idle-remove-mfences-for-x86_bug_clflush_monitor-.patch
new file mode 100644 (file)
index 0000000..59142f0
--- /dev/null
@@ -0,0 +1,120 @@
+From af58351f6fe9fe3cd03c7e74bd2f267e01129dcf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Apr 2025 18:24:58 +0100
+Subject: x86/idle: Remove MFENCEs for X86_BUG_CLFLUSH_MONITOR in
+ mwait_idle_with_hints() and prefer_mwait_c1_over_halt()
+
+From: Andrew Cooper <andrew.cooper3@citrix.com>
+
+[ Upstream commit 1f13c60d84e880df6698441026e64f84c7110c49 ]
+
+The following commit, 12 years ago:
+
+  7e98b7192046 ("x86, idle: Use static_cpu_has() for CLFLUSH workaround, add barriers")
+
+added barriers around the CLFLUSH in mwait_idle_with_hints(), justified with:
+
+  ... and add memory barriers around it since the documentation is explicit
+  that CLFLUSH is only ordered with respect to MFENCE.
+
+This also triggered, 11 years ago, the same adjustment in:
+
+  f8e617f45829 ("sched/idle/x86: Optimize unnecessary mwait_idle() resched IPIs")
+
+during development, although it failed to get the static_cpu_has_bug() treatment.
+
+X86_BUG_CLFLUSH_MONITOR (a.k.a the AAI65 errata) is specific to Intel CPUs,
+and the SDM currently states:
+
+  Executions of the CLFLUSH instruction are ordered with respect to each
+  other and with respect to writes, locked read-modify-write instructions,
+  and fence instructions[1].
+
+With footnote 1 reading:
+
+  Earlier versions of this manual specified that executions of the CLFLUSH
+  instruction were ordered only by the MFENCE instruction.  All processors
+  implementing the CLFLUSH instruction also order it relative to the other
+  operations enumerated above.
+
+i.e. The SDM was incorrect at the time, and barriers should not have been
+inserted.  Double checking the original AAI65 errata (not available from
+intel.com any more) shows no mention of barriers either.
+
+Note: If this were a general codepath, the MFENCEs would be needed, because
+      AMD CPUs of the same vintage do sport otherwise-unordered CLFLUSHs.
+
+Remove the unnecessary barriers. Furthermore, use a plain alternative(),
+rather than static_cpu_has_bug() and/or no optimisation.  The workaround
+is a single instruction.
+
+Use an explicit %rax pointer rather than a general memory operand, because
+MONITOR takes the pointer implicitly in the same way.
+
+[ mingo: Cleaned up the commit a bit. ]
+
+Fixes: 7e98b7192046 ("x86, idle: Use static_cpu_has() for CLFLUSH workaround, add barriers")
+Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Dave Hansen <dave.hansen@intel.com>
+Acked-by: Borislav Petkov (AMD) <bp@alien8.de>
+Cc: "H. Peter Anvin" <hpa@zytor.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Rik van Riel <riel@surriel.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: Brian Gerst <brgerst@gmail.com>
+Cc: Juergen Gross <jgross@suse.com>
+Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Link: https://lore.kernel.org/r/20250402172458.1378112-1-andrew.cooper3@citrix.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/include/asm/mwait.h | 9 +++------
+ arch/x86/kernel/process.c    | 9 +++------
+ 2 files changed, 6 insertions(+), 12 deletions(-)
+
+diff --git a/arch/x86/include/asm/mwait.h b/arch/x86/include/asm/mwait.h
+index ce857ef54cf15..54dc313bcdf01 100644
+--- a/arch/x86/include/asm/mwait.h
++++ b/arch/x86/include/asm/mwait.h
+@@ -116,13 +116,10 @@ static __always_inline void __sti_mwait(unsigned long eax, unsigned long ecx)
+ static __always_inline void mwait_idle_with_hints(unsigned long eax, unsigned long ecx)
+ {
+       if (static_cpu_has_bug(X86_BUG_MONITOR) || !current_set_polling_and_test()) {
+-              if (static_cpu_has_bug(X86_BUG_CLFLUSH_MONITOR)) {
+-                      mb();
+-                      clflush((void *)&current_thread_info()->flags);
+-                      mb();
+-              }
++              const void *addr = &current_thread_info()->flags;
+-              __monitor((void *)&current_thread_info()->flags, 0, 0);
++              alternative_input("", "clflush (%[addr])", X86_BUG_CLFLUSH_MONITOR, [addr] "a" (addr));
++              __monitor(addr, 0, 0);
+               if (!need_resched()) {
+                       if (ecx & 1) {
+diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
+index 962c3ce39323e..12948380cdd06 100644
+--- a/arch/x86/kernel/process.c
++++ b/arch/x86/kernel/process.c
+@@ -907,13 +907,10 @@ static __init bool prefer_mwait_c1_over_halt(void)
+ static __cpuidle void mwait_idle(void)
+ {
+       if (!current_set_polling_and_test()) {
+-              if (this_cpu_has(X86_BUG_CLFLUSH_MONITOR)) {
+-                      mb(); /* quirk */
+-                      clflush((void *)&current_thread_info()->flags);
+-                      mb(); /* quirk */
+-              }
++              const void *addr = &current_thread_info()->flags;
+-              __monitor((void *)&current_thread_info()->flags, 0, 0);
++              alternative_input("", "clflush (%[addr])", X86_BUG_CLFLUSH_MONITOR, [addr] "a" (addr));
++              __monitor(addr, 0, 0);
+               if (!need_resched()) {
+                       __sti_mwait(0, 0);
+                       raw_local_irq_disable();
+-- 
+2.39.5
+
diff --git a/queue-6.15/x86-insn-fix-opcode-map-rex2-superscript-tags.patch b/queue-6.15/x86-insn-fix-opcode-map-rex2-superscript-tags.patch
new file mode 100644 (file)
index 0000000..663b969
--- /dev/null
@@ -0,0 +1,203 @@
+From 9aa2dda436244086ee2b0861449ed9b9ebb8a527 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Apr 2025 10:48:10 +0900
+Subject: x86/insn: Fix opcode map (!REX2) superscript tags
+
+From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+
+[ Upstream commit ca698ec2f07873a448d53c580795c4e023c75393 ]
+
+Commit:
+
+  159039af8c07 ("x86/insn: x86/insn: Add support for REX2 prefix to the instruction decoder opcode map")
+
+added (!REX2) superscript with a space, but the correct format requires ','
+for concatination with other superscript tags.
+
+Add ',' to generate correct insn attribute tables.
+
+I confirmed with following command:
+
+      arch/x86/lib/x86-opcode-map.txt | grep e8 | head -n 1
+  [0xe8] = INAT_MAKE_IMM(INAT_IMM_VWORD32) | INAT_FORCE64 | INAT_NO_REX2,
+
+Fixes: 159039af8c07 ("x86/insn: x86/insn: Add support for REX2 prefix to the instruction decoder opcode map")
+Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Cc: H. Peter Anvin <hpa@zytor.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/174580489027.388420.15539375184727726142.stgit@devnote2
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/lib/x86-opcode-map.txt       | 50 +++++++++++++--------------
+ tools/arch/x86/lib/x86-opcode-map.txt | 50 +++++++++++++--------------
+ 2 files changed, 50 insertions(+), 50 deletions(-)
+
+diff --git a/arch/x86/lib/x86-opcode-map.txt b/arch/x86/lib/x86-opcode-map.txt
+index f5dd84eb55dcd..cd3fd5155f6ec 100644
+--- a/arch/x86/lib/x86-opcode-map.txt
++++ b/arch/x86/lib/x86-opcode-map.txt
+@@ -35,7 +35,7 @@
+ #  - (!F3) : the last prefix is not 0xF3 (including non-last prefix case)
+ #  - (66&F2): Both 0x66 and 0xF2 prefixes are specified.
+ #
+-# REX2 Prefix
++# REX2 Prefix Superscripts
+ #  - (!REX2): REX2 is not allowed
+ #  - (REX2): REX2 variant e.g. JMPABS
+@@ -286,10 +286,10 @@ df: ESC
+ # Note: "forced64" is Intel CPU behavior: they ignore 0x66 prefix
+ # in 64-bit mode. AMD CPUs accept 0x66 prefix, it causes RIP truncation
+ # to 16 bits. In 32-bit mode, 0x66 is accepted by both Intel and AMD.
+-e0: LOOPNE/LOOPNZ Jb (f64) (!REX2)
+-e1: LOOPE/LOOPZ Jb (f64) (!REX2)
+-e2: LOOP Jb (f64) (!REX2)
+-e3: JrCXZ Jb (f64) (!REX2)
++e0: LOOPNE/LOOPNZ Jb (f64),(!REX2)
++e1: LOOPE/LOOPZ Jb (f64),(!REX2)
++e2: LOOP Jb (f64),(!REX2)
++e3: JrCXZ Jb (f64),(!REX2)
+ e4: IN AL,Ib (!REX2)
+ e5: IN eAX,Ib (!REX2)
+ e6: OUT Ib,AL (!REX2)
+@@ -298,10 +298,10 @@ e7: OUT Ib,eAX (!REX2)
+ # in "near" jumps and calls is 16-bit. For CALL,
+ # push of return address is 16-bit wide, RSP is decremented by 2
+ # but is not truncated to 16 bits, unlike RIP.
+-e8: CALL Jz (f64) (!REX2)
+-e9: JMP-near Jz (f64) (!REX2)
+-ea: JMP-far Ap (i64) (!REX2)
+-eb: JMP-short Jb (f64) (!REX2)
++e8: CALL Jz (f64),(!REX2)
++e9: JMP-near Jz (f64),(!REX2)
++ea: JMP-far Ap (i64),(!REX2)
++eb: JMP-short Jb (f64),(!REX2)
+ ec: IN AL,DX (!REX2)
+ ed: IN eAX,DX (!REX2)
+ ee: OUT DX,AL (!REX2)
+@@ -478,22 +478,22 @@ AVXcode: 1
+ 7f: movq Qq,Pq | vmovdqa Wx,Vx (66) | vmovdqa32/64 Wx,Vx (66),(evo) | vmovdqu Wx,Vx (F3) | vmovdqu32/64 Wx,Vx (F3),(evo) | vmovdqu8/16 Wx,Vx (F2),(ev)
+ # 0x0f 0x80-0x8f
+ # Note: "forced64" is Intel CPU behavior (see comment about CALL insn).
+-80: JO Jz (f64) (!REX2)
+-81: JNO Jz (f64) (!REX2)
+-82: JB/JC/JNAE Jz (f64) (!REX2)
+-83: JAE/JNB/JNC Jz (f64) (!REX2)
+-84: JE/JZ Jz (f64) (!REX2)
+-85: JNE/JNZ Jz (f64) (!REX2)
+-86: JBE/JNA Jz (f64) (!REX2)
+-87: JA/JNBE Jz (f64) (!REX2)
+-88: JS Jz (f64) (!REX2)
+-89: JNS Jz (f64) (!REX2)
+-8a: JP/JPE Jz (f64) (!REX2)
+-8b: JNP/JPO Jz (f64) (!REX2)
+-8c: JL/JNGE Jz (f64) (!REX2)
+-8d: JNL/JGE Jz (f64) (!REX2)
+-8e: JLE/JNG Jz (f64) (!REX2)
+-8f: JNLE/JG Jz (f64) (!REX2)
++80: JO Jz (f64),(!REX2)
++81: JNO Jz (f64),(!REX2)
++82: JB/JC/JNAE Jz (f64),(!REX2)
++83: JAE/JNB/JNC Jz (f64),(!REX2)
++84: JE/JZ Jz (f64),(!REX2)
++85: JNE/JNZ Jz (f64),(!REX2)
++86: JBE/JNA Jz (f64),(!REX2)
++87: JA/JNBE Jz (f64),(!REX2)
++88: JS Jz (f64),(!REX2)
++89: JNS Jz (f64),(!REX2)
++8a: JP/JPE Jz (f64),(!REX2)
++8b: JNP/JPO Jz (f64),(!REX2)
++8c: JL/JNGE Jz (f64),(!REX2)
++8d: JNL/JGE Jz (f64),(!REX2)
++8e: JLE/JNG Jz (f64),(!REX2)
++8f: JNLE/JG Jz (f64),(!REX2)
+ # 0x0f 0x90-0x9f
+ 90: SETO Eb | kmovw/q Vk,Wk | kmovb/d Vk,Wk (66)
+ 91: SETNO Eb | kmovw/q Mv,Vk | kmovb/d Mv,Vk (66)
+diff --git a/tools/arch/x86/lib/x86-opcode-map.txt b/tools/arch/x86/lib/x86-opcode-map.txt
+index f5dd84eb55dcd..cd3fd5155f6ec 100644
+--- a/tools/arch/x86/lib/x86-opcode-map.txt
++++ b/tools/arch/x86/lib/x86-opcode-map.txt
+@@ -35,7 +35,7 @@
+ #  - (!F3) : the last prefix is not 0xF3 (including non-last prefix case)
+ #  - (66&F2): Both 0x66 and 0xF2 prefixes are specified.
+ #
+-# REX2 Prefix
++# REX2 Prefix Superscripts
+ #  - (!REX2): REX2 is not allowed
+ #  - (REX2): REX2 variant e.g. JMPABS
+@@ -286,10 +286,10 @@ df: ESC
+ # Note: "forced64" is Intel CPU behavior: they ignore 0x66 prefix
+ # in 64-bit mode. AMD CPUs accept 0x66 prefix, it causes RIP truncation
+ # to 16 bits. In 32-bit mode, 0x66 is accepted by both Intel and AMD.
+-e0: LOOPNE/LOOPNZ Jb (f64) (!REX2)
+-e1: LOOPE/LOOPZ Jb (f64) (!REX2)
+-e2: LOOP Jb (f64) (!REX2)
+-e3: JrCXZ Jb (f64) (!REX2)
++e0: LOOPNE/LOOPNZ Jb (f64),(!REX2)
++e1: LOOPE/LOOPZ Jb (f64),(!REX2)
++e2: LOOP Jb (f64),(!REX2)
++e3: JrCXZ Jb (f64),(!REX2)
+ e4: IN AL,Ib (!REX2)
+ e5: IN eAX,Ib (!REX2)
+ e6: OUT Ib,AL (!REX2)
+@@ -298,10 +298,10 @@ e7: OUT Ib,eAX (!REX2)
+ # in "near" jumps and calls is 16-bit. For CALL,
+ # push of return address is 16-bit wide, RSP is decremented by 2
+ # but is not truncated to 16 bits, unlike RIP.
+-e8: CALL Jz (f64) (!REX2)
+-e9: JMP-near Jz (f64) (!REX2)
+-ea: JMP-far Ap (i64) (!REX2)
+-eb: JMP-short Jb (f64) (!REX2)
++e8: CALL Jz (f64),(!REX2)
++e9: JMP-near Jz (f64),(!REX2)
++ea: JMP-far Ap (i64),(!REX2)
++eb: JMP-short Jb (f64),(!REX2)
+ ec: IN AL,DX (!REX2)
+ ed: IN eAX,DX (!REX2)
+ ee: OUT DX,AL (!REX2)
+@@ -478,22 +478,22 @@ AVXcode: 1
+ 7f: movq Qq,Pq | vmovdqa Wx,Vx (66) | vmovdqa32/64 Wx,Vx (66),(evo) | vmovdqu Wx,Vx (F3) | vmovdqu32/64 Wx,Vx (F3),(evo) | vmovdqu8/16 Wx,Vx (F2),(ev)
+ # 0x0f 0x80-0x8f
+ # Note: "forced64" is Intel CPU behavior (see comment about CALL insn).
+-80: JO Jz (f64) (!REX2)
+-81: JNO Jz (f64) (!REX2)
+-82: JB/JC/JNAE Jz (f64) (!REX2)
+-83: JAE/JNB/JNC Jz (f64) (!REX2)
+-84: JE/JZ Jz (f64) (!REX2)
+-85: JNE/JNZ Jz (f64) (!REX2)
+-86: JBE/JNA Jz (f64) (!REX2)
+-87: JA/JNBE Jz (f64) (!REX2)
+-88: JS Jz (f64) (!REX2)
+-89: JNS Jz (f64) (!REX2)
+-8a: JP/JPE Jz (f64) (!REX2)
+-8b: JNP/JPO Jz (f64) (!REX2)
+-8c: JL/JNGE Jz (f64) (!REX2)
+-8d: JNL/JGE Jz (f64) (!REX2)
+-8e: JLE/JNG Jz (f64) (!REX2)
+-8f: JNLE/JG Jz (f64) (!REX2)
++80: JO Jz (f64),(!REX2)
++81: JNO Jz (f64),(!REX2)
++82: JB/JC/JNAE Jz (f64),(!REX2)
++83: JAE/JNB/JNC Jz (f64),(!REX2)
++84: JE/JZ Jz (f64),(!REX2)
++85: JNE/JNZ Jz (f64),(!REX2)
++86: JBE/JNA Jz (f64),(!REX2)
++87: JA/JNBE Jz (f64),(!REX2)
++88: JS Jz (f64),(!REX2)
++89: JNS Jz (f64),(!REX2)
++8a: JP/JPE Jz (f64),(!REX2)
++8b: JNP/JPO Jz (f64),(!REX2)
++8c: JL/JNGE Jz (f64),(!REX2)
++8d: JNL/JGE Jz (f64),(!REX2)
++8e: JLE/JNG Jz (f64),(!REX2)
++8f: JNLE/JG Jz (f64),(!REX2)
+ # 0x0f 0x90-0x9f
+ 90: SETO Eb | kmovw/q Vk,Wk | kmovb/d Vk,Wk (66)
+ 91: SETNO Eb | kmovw/q Mv,Vk | kmovb/d Mv,Vk (66)
+-- 
+2.39.5
+
diff --git a/queue-6.15/x86-irq-ensure-initial-pir-loads-are-performed-exact.patch b/queue-6.15/x86-irq-ensure-initial-pir-loads-are-performed-exact.patch
new file mode 100644 (file)
index 0000000..868e469
--- /dev/null
@@ -0,0 +1,39 @@
+From eafab545da29090a1aca19bee156282321b5046e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 09:34:40 -0700
+Subject: x86/irq: Ensure initial PIR loads are performed exactly once
+
+From: Sean Christopherson <seanjc@google.com>
+
+[ Upstream commit 600e9606046ac3b9b7a3f0500d08a179df84c45e ]
+
+Ensure the PIR is read exactly once at the start of handle_pending_pir(),
+to guarantee that checking for an outstanding posted interrupt in a given
+chuck doesn't reload the chunk from the "real" PIR.  Functionally, a reload
+is benign, but it would defeat the purpose of pre-loading into a copy.
+
+Fixes: 1b03d82ba15e ("x86/irq: Install posted MSI notification handler")
+Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
+Link: https://lore.kernel.org/r/20250401163447.846608-2-seanjc@google.com
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/irq.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
+index 81f9b78e0f7ba..6cd5d2d6c58af 100644
+--- a/arch/x86/kernel/irq.c
++++ b/arch/x86/kernel/irq.c
+@@ -419,7 +419,7 @@ static __always_inline bool handle_pending_pir(u64 *pir, struct pt_regs *regs)
+       bool handled = false;
+       for (i = 0; i < 4; i++)
+-              pir_copy[i] = pir[i];
++              pir_copy[i] = READ_ONCE(pir[i]);
+       for (i = 0; i < 4; i++) {
+               if (!pir_copy[i])
+-- 
+2.39.5
+
diff --git a/queue-6.15/x86-microcode-amd-do-not-return-error-when-microcode.patch b/queue-6.15/x86-microcode-amd-do-not-return-error-when-microcode.patch
new file mode 100644 (file)
index 0000000..6a24674
--- /dev/null
@@ -0,0 +1,46 @@
+From ac286f6a6b7ba0d52a35f19f1efd1b4073de2535 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Apr 2025 05:34:24 +0000
+Subject: x86/microcode/AMD: Do not return error when microcode update is not
+ necessary
+
+From: Annie Li <jiayanli@google.com>
+
+[ Upstream commit b43dc4ab097859c24e2a6993119c927cffc856aa ]
+
+After
+
+  6f059e634dcd("x86/microcode: Clarify the late load logic"),
+
+if the load is up-to-date, the AMD side returns UCODE_OK which leads to
+load_late_locked() returning -EBADFD.
+
+Handle UCODE_OK in the switch case to avoid this error.
+
+  [ bp: Massage commit message. ]
+
+Fixes: 6f059e634dcd ("x86/microcode: Clarify the late load logic")
+Signed-off-by: Annie Li <jiayanli@google.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Link: https://lore.kernel.org/20250430053424.77438-1-jiayanli@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/cpu/microcode/core.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
+index 079f046ee26d1..e8021d3e58824 100644
+--- a/arch/x86/kernel/cpu/microcode/core.c
++++ b/arch/x86/kernel/cpu/microcode/core.c
+@@ -696,6 +696,8 @@ static int load_late_locked(void)
+               return load_late_stop_cpus(true);
+       case UCODE_NFOUND:
+               return -ENOENT;
++      case UCODE_OK:
++              return 0;
+       default:
+               return -EBADFD;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.15/x86-mtrr-check-if-fixed-range-mtrrs-exist-in-mtrr_sa.patch b/queue-6.15/x86-mtrr-check-if-fixed-range-mtrrs-exist-in-mtrr_sa.patch
new file mode 100644 (file)
index 0000000..59bae7d
--- /dev/null
@@ -0,0 +1,47 @@
+From b16ff19fdea4baba5ca67264bf4fdec021685970 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 May 2025 17:06:33 +0000
+Subject: x86/mtrr: Check if fixed-range MTRRs exist in
+ mtrr_save_fixed_ranges()
+
+From: Jiaqing Zhao <jiaqing.zhao@linux.intel.com>
+
+[ Upstream commit 824c6384e8d9275d4ec7204f3f79a4ac6bc10379 ]
+
+When suspending, save_processor_state() calls mtrr_save_fixed_ranges()
+to save fixed-range MTRRs.
+
+On platforms without fixed-range MTRRs like the ACRN hypervisor which
+has removed fixed-range MTRR emulation, accessing these MSRs will
+trigger an unchecked MSR access error. Make sure fixed-range MTRRs are
+supported before access to prevent such error.
+
+Since mtrr_state.have_fixed is only set when MTRRs are present and
+enabled, checking the CPU feature flag in mtrr_save_fixed_ranges() is
+unnecessary.
+
+Fixes: 3ebad5905609 ("[PATCH] x86: Save and restore the fixed-range MTRRs of the BSP when suspending")
+Signed-off-by: Jiaqing Zhao <jiaqing.zhao@linux.intel.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Link: https://lore.kernel.org/20250509170633.3411169-2-jiaqing.zhao@linux.intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/cpu/mtrr/generic.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c
+index e2c6b471d2302..8c18327eb10bb 100644
+--- a/arch/x86/kernel/cpu/mtrr/generic.c
++++ b/arch/x86/kernel/cpu/mtrr/generic.c
+@@ -593,7 +593,7 @@ static void get_fixed_ranges(mtrr_type *frs)
+ void mtrr_save_fixed_ranges(void *info)
+ {
+-      if (boot_cpu_has(X86_FEATURE_MTRR))
++      if (mtrr_state.have_fixed)
+               get_fixed_ranges(mtrr_state.fixed_ranges);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.15/xen-x86-fix-initial-memory-balloon-target.patch b/queue-6.15/xen-x86-fix-initial-memory-balloon-target.patch
new file mode 100644 (file)
index 0000000..96ae578
--- /dev/null
@@ -0,0 +1,69 @@
+From fa0d7e89b113fa8c9368e181ffda9a6b6d39bf6d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 May 2025 10:04:26 +0200
+Subject: xen/x86: fix initial memory balloon target
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Roger Pau Monne <roger.pau@citrix.com>
+
+[ Upstream commit 74287971dbb3fe322bb316afd9e7fb5807e23bee ]
+
+When adding extra memory regions as ballooned pages also adjust the balloon
+target, otherwise when the balloon driver is started it will populate
+memory to match the target value and consume all the extra memory regions
+added.
+
+This made the usage of the Xen `dom0_mem=,max:` command line parameter for
+dom0 not work as expected, as the target won't be adjusted and when the
+balloon is started it will populate memory straight to the 'max:' value.
+It would equally affect domUs that have memory != maxmem.
+
+Kernels built with CONFIG_XEN_UNPOPULATED_ALLOC are not affected, because
+the extra memory regions are consumed by the unpopulated allocation driver,
+and then balloon_add_regions() becomes a no-op.
+
+Reported-by: John <jw@nuclearfallout.net>
+Fixes: 87af633689ce ('x86/xen: fix balloon target initialization for PVH dom0')
+Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Tested-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
+Message-ID: <20250514080427.28129-1-roger.pau@citrix.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/xen/balloon.c | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
+index 8c852807ba1c1..2de37dcd75566 100644
+--- a/drivers/xen/balloon.c
++++ b/drivers/xen/balloon.c
+@@ -704,15 +704,18 @@ static int __init balloon_add_regions(void)
+               /*
+                * Extra regions are accounted for in the physmap, but need
+-               * decreasing from current_pages to balloon down the initial
+-               * allocation, because they are already accounted for in
+-               * total_pages.
++               * decreasing from current_pages and target_pages to balloon
++               * down the initial allocation, because they are already
++               * accounted for in total_pages.
+                */
+-              if (extra_pfn_end - start_pfn >= balloon_stats.current_pages) {
++              pages = extra_pfn_end - start_pfn;
++              if (pages >= balloon_stats.current_pages ||
++                  pages >= balloon_stats.target_pages) {
+                       WARN(1, "Extra pages underflow current target");
+                       return -ERANGE;
+               }
+-              balloon_stats.current_pages -= extra_pfn_end - start_pfn;
++              balloon_stats.current_pages -= pages;
++              balloon_stats.target_pages -= pages;
+       }
+       return 0;
+-- 
+2.39.5
+
diff --git a/queue-6.15/xfrm-add-explicit-dev-to-.xdo_dev_state_-add-delete-.patch b/queue-6.15/xfrm-add-explicit-dev-to-.xdo_dev_state_-add-delete-.patch
new file mode 100644 (file)
index 0000000..455266d
--- /dev/null
@@ -0,0 +1,864 @@
+From 9360cfcf0fd89290e2136d757e741b38ba400259 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Apr 2025 10:49:56 +0300
+Subject: xfrm: Add explicit dev to .xdo_dev_state_{add,delete,free}
+
+From: Cosmin Ratiu <cratiu@nvidia.com>
+
+[ Upstream commit 43eca05b6a3b917c600e10cc6b06bfa57fa57401 ]
+
+Previously, device driver IPSec offload implementations would fall into
+two categories:
+1. Those that used xso.dev to determine the offload device.
+2. Those that used xso.real_dev to determine the offload device.
+
+The first category didn't work with bonding while the second did.
+In a non-bonding setup the two pointers are the same.
+
+This commit adds explicit pointers for the offload netdevice to
+.xdo_dev_state_add() / .xdo_dev_state_delete() / .xdo_dev_state_free()
+which eliminates the confusion and allows drivers from the first
+category to work with bonding.
+
+xso.real_dev now becomes a private pointer managed by the bonding
+driver.
+
+Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Stable-dep-of: fd4e41ebf66c ("bonding: Mark active offloaded xfrm_states")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/networking/xfrm_device.rst      | 10 +++--
+ drivers/net/bonding/bond_main.c               | 33 ++++++++-------
+ .../net/ethernet/chelsio/cxgb4/cxgb4_main.c   | 20 +++++----
+ .../inline_crypto/ch_ipsec/chcr_ipsec.c       | 18 +++++---
+ .../net/ethernet/intel/ixgbe/ixgbe_ipsec.c    | 41 +++++++++++--------
+ drivers/net/ethernet/intel/ixgbevf/ipsec.c    | 21 ++++++----
+ .../marvell/octeontx2/nic/cn10k_ipsec.c       | 18 ++++----
+ .../mellanox/mlx5/core/en_accel/ipsec.c       | 12 +++---
+ .../net/ethernet/netronome/nfp/crypto/ipsec.c | 11 +++--
+ drivers/net/netdevsim/ipsec.c                 | 15 ++++---
+ include/linux/netdevice.h                     | 10 +++--
+ include/net/xfrm.h                            |  8 ++++
+ net/xfrm/xfrm_device.c                        |  4 +-
+ net/xfrm/xfrm_state.c                         | 14 ++++---
+ 14 files changed, 136 insertions(+), 99 deletions(-)
+
+diff --git a/Documentation/networking/xfrm_device.rst b/Documentation/networking/xfrm_device.rst
+index 7f24c09f26943..122204da0fff6 100644
+--- a/Documentation/networking/xfrm_device.rst
++++ b/Documentation/networking/xfrm_device.rst
+@@ -65,9 +65,13 @@ Callbacks to implement
+   /* from include/linux/netdevice.h */
+   struct xfrmdev_ops {
+         /* Crypto and Packet offload callbacks */
+-      int     (*xdo_dev_state_add) (struct xfrm_state *x, struct netlink_ext_ack *extack);
+-      void    (*xdo_dev_state_delete) (struct xfrm_state *x);
+-      void    (*xdo_dev_state_free) (struct xfrm_state *x);
++      int     (*xdo_dev_state_add)(struct net_device *dev,
++                                     struct xfrm_state *x,
++                                     struct netlink_ext_ack *extack);
++      void    (*xdo_dev_state_delete)(struct net_device *dev,
++                                        struct xfrm_state *x);
++      void    (*xdo_dev_state_free)(struct net_device *dev,
++                                      struct xfrm_state *x);
+       bool    (*xdo_dev_offload_ok) (struct sk_buff *skb,
+                                      struct xfrm_state *x);
+       void    (*xdo_dev_state_advance_esn) (struct xfrm_state *x);
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index 8ea183da8d539..b183a3c99f627 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -453,13 +453,14 @@ static struct net_device *bond_ipsec_dev(struct xfrm_state *xs)
+ /**
+  * bond_ipsec_add_sa - program device with a security association
++ * @bond_dev: pointer to the bond net device
+  * @xs: pointer to transformer state struct
+  * @extack: extack point to fill failure reason
+  **/
+-static int bond_ipsec_add_sa(struct xfrm_state *xs,
++static int bond_ipsec_add_sa(struct net_device *bond_dev,
++                           struct xfrm_state *xs,
+                            struct netlink_ext_ack *extack)
+ {
+-      struct net_device *bond_dev = xs->xso.dev;
+       struct net_device *real_dev;
+       netdevice_tracker tracker;
+       struct bond_ipsec *ipsec;
+@@ -496,7 +497,7 @@ static int bond_ipsec_add_sa(struct xfrm_state *xs,
+       }
+       xs->xso.real_dev = real_dev;
+-      err = real_dev->xfrmdev_ops->xdo_dev_state_add(xs, extack);
++      err = real_dev->xfrmdev_ops->xdo_dev_state_add(real_dev, xs, extack);
+       if (!err) {
+               ipsec->xs = xs;
+               INIT_LIST_HEAD(&ipsec->list);
+@@ -540,7 +541,8 @@ static void bond_ipsec_add_sa_all(struct bonding *bond)
+                       continue;
+               ipsec->xs->xso.real_dev = real_dev;
+-              if (real_dev->xfrmdev_ops->xdo_dev_state_add(ipsec->xs, NULL)) {
++              if (real_dev->xfrmdev_ops->xdo_dev_state_add(real_dev,
++                                                           ipsec->xs, NULL)) {
+                       slave_warn(bond_dev, real_dev, "%s: failed to add SA\n", __func__);
+                       ipsec->xs->xso.real_dev = NULL;
+               }
+@@ -551,11 +553,12 @@ static void bond_ipsec_add_sa_all(struct bonding *bond)
+ /**
+  * bond_ipsec_del_sa - clear out this specific SA
++ * @bond_dev: pointer to the bond net device
+  * @xs: pointer to transformer state struct
+  **/
+-static void bond_ipsec_del_sa(struct xfrm_state *xs)
++static void bond_ipsec_del_sa(struct net_device *bond_dev,
++                            struct xfrm_state *xs)
+ {
+-      struct net_device *bond_dev = xs->xso.dev;
+       struct net_device *real_dev;
+       netdevice_tracker tracker;
+       struct bond_ipsec *ipsec;
+@@ -587,7 +590,7 @@ static void bond_ipsec_del_sa(struct xfrm_state *xs)
+               goto out;
+       }
+-      real_dev->xfrmdev_ops->xdo_dev_state_delete(xs);
++      real_dev->xfrmdev_ops->xdo_dev_state_delete(real_dev, xs);
+ out:
+       netdev_put(real_dev, &tracker);
+       mutex_lock(&bond->ipsec_lock);
+@@ -624,18 +627,20 @@ static void bond_ipsec_del_sa_all(struct bonding *bond)
+                       slave_warn(bond_dev, real_dev,
+                                  "%s: no slave xdo_dev_state_delete\n",
+                                  __func__);
+-              } else {
+-                      real_dev->xfrmdev_ops->xdo_dev_state_delete(ipsec->xs);
+-                      if (real_dev->xfrmdev_ops->xdo_dev_state_free)
+-                              real_dev->xfrmdev_ops->xdo_dev_state_free(ipsec->xs);
++                      continue;
+               }
++              real_dev->xfrmdev_ops->xdo_dev_state_delete(real_dev,
++                                                          ipsec->xs);
++              if (real_dev->xfrmdev_ops->xdo_dev_state_free)
++                      real_dev->xfrmdev_ops->xdo_dev_state_free(real_dev,
++                                                                ipsec->xs);
+       }
+       mutex_unlock(&bond->ipsec_lock);
+ }
+-static void bond_ipsec_free_sa(struct xfrm_state *xs)
++static void bond_ipsec_free_sa(struct net_device *bond_dev,
++                             struct xfrm_state *xs)
+ {
+-      struct net_device *bond_dev = xs->xso.dev;
+       struct net_device *real_dev;
+       netdevice_tracker tracker;
+       struct bonding *bond;
+@@ -661,7 +666,7 @@ static void bond_ipsec_free_sa(struct xfrm_state *xs)
+       if (real_dev && real_dev->xfrmdev_ops &&
+           real_dev->xfrmdev_ops->xdo_dev_state_free)
+-              real_dev->xfrmdev_ops->xdo_dev_state_free(xs);
++              real_dev->xfrmdev_ops->xdo_dev_state_free(real_dev, xs);
+ out:
+       netdev_put(real_dev, &tracker);
+ }
+diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+index 551c279dc14be..51395c96b2e99 100644
+--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+@@ -6480,10 +6480,11 @@ static const struct tlsdev_ops cxgb4_ktls_ops = {
+ #if IS_ENABLED(CONFIG_CHELSIO_IPSEC_INLINE)
+-static int cxgb4_xfrm_add_state(struct xfrm_state *x,
++static int cxgb4_xfrm_add_state(struct net_device *dev,
++                              struct xfrm_state *x,
+                               struct netlink_ext_ack *extack)
+ {
+-      struct adapter *adap = netdev2adap(x->xso.dev);
++      struct adapter *adap = netdev2adap(dev);
+       int ret;
+       if (!mutex_trylock(&uld_mutex)) {
+@@ -6494,7 +6495,8 @@ static int cxgb4_xfrm_add_state(struct xfrm_state *x,
+       if (ret)
+               goto out_unlock;
+-      ret = adap->uld[CXGB4_ULD_IPSEC].xfrmdev_ops->xdo_dev_state_add(x, extack);
++      ret = adap->uld[CXGB4_ULD_IPSEC].xfrmdev_ops->xdo_dev_state_add(dev, x,
++                                                                      extack);
+ out_unlock:
+       mutex_unlock(&uld_mutex);
+@@ -6502,9 +6504,9 @@ static int cxgb4_xfrm_add_state(struct xfrm_state *x,
+       return ret;
+ }
+-static void cxgb4_xfrm_del_state(struct xfrm_state *x)
++static void cxgb4_xfrm_del_state(struct net_device *dev, struct xfrm_state *x)
+ {
+-      struct adapter *adap = netdev2adap(x->xso.dev);
++      struct adapter *adap = netdev2adap(dev);
+       if (!mutex_trylock(&uld_mutex)) {
+               dev_dbg(adap->pdev_dev,
+@@ -6514,15 +6516,15 @@ static void cxgb4_xfrm_del_state(struct xfrm_state *x)
+       if (chcr_offload_state(adap, CXGB4_XFRMDEV_OPS))
+               goto out_unlock;
+-      adap->uld[CXGB4_ULD_IPSEC].xfrmdev_ops->xdo_dev_state_delete(x);
++      adap->uld[CXGB4_ULD_IPSEC].xfrmdev_ops->xdo_dev_state_delete(dev, x);
+ out_unlock:
+       mutex_unlock(&uld_mutex);
+ }
+-static void cxgb4_xfrm_free_state(struct xfrm_state *x)
++static void cxgb4_xfrm_free_state(struct net_device *dev, struct xfrm_state *x)
+ {
+-      struct adapter *adap = netdev2adap(x->xso.dev);
++      struct adapter *adap = netdev2adap(dev);
+       if (!mutex_trylock(&uld_mutex)) {
+               dev_dbg(adap->pdev_dev,
+@@ -6532,7 +6534,7 @@ static void cxgb4_xfrm_free_state(struct xfrm_state *x)
+       if (chcr_offload_state(adap, CXGB4_XFRMDEV_OPS))
+               goto out_unlock;
+-      adap->uld[CXGB4_ULD_IPSEC].xfrmdev_ops->xdo_dev_state_free(x);
++      adap->uld[CXGB4_ULD_IPSEC].xfrmdev_ops->xdo_dev_state_free(dev, x);
+ out_unlock:
+       mutex_unlock(&uld_mutex);
+diff --git a/drivers/net/ethernet/chelsio/inline_crypto/ch_ipsec/chcr_ipsec.c b/drivers/net/ethernet/chelsio/inline_crypto/ch_ipsec/chcr_ipsec.c
+index baba96883f48b..ecd9a0bd5e182 100644
+--- a/drivers/net/ethernet/chelsio/inline_crypto/ch_ipsec/chcr_ipsec.c
++++ b/drivers/net/ethernet/chelsio/inline_crypto/ch_ipsec/chcr_ipsec.c
+@@ -75,9 +75,12 @@ static int ch_ipsec_uld_state_change(void *handle, enum cxgb4_state new_state);
+ static int ch_ipsec_xmit(struct sk_buff *skb, struct net_device *dev);
+ static void *ch_ipsec_uld_add(const struct cxgb4_lld_info *infop);
+ static void ch_ipsec_advance_esn_state(struct xfrm_state *x);
+-static void ch_ipsec_xfrm_free_state(struct xfrm_state *x);
+-static void ch_ipsec_xfrm_del_state(struct xfrm_state *x);
+-static int ch_ipsec_xfrm_add_state(struct xfrm_state *x,
++static void ch_ipsec_xfrm_free_state(struct net_device *dev,
++                                   struct xfrm_state *x);
++static void ch_ipsec_xfrm_del_state(struct net_device *dev,
++                                  struct xfrm_state *x);
++static int ch_ipsec_xfrm_add_state(struct net_device *dev,
++                                 struct xfrm_state *x,
+                                  struct netlink_ext_ack *extack);
+ static const struct xfrmdev_ops ch_ipsec_xfrmdev_ops = {
+@@ -223,7 +226,8 @@ static int ch_ipsec_setkey(struct xfrm_state *x,
+  * returns 0 on success, negative error if failed to send message to FPGA
+  * positive error if FPGA returned a bad response
+  */
+-static int ch_ipsec_xfrm_add_state(struct xfrm_state *x,
++static int ch_ipsec_xfrm_add_state(struct net_device *dev,
++                                 struct xfrm_state *x,
+                                  struct netlink_ext_ack *extack)
+ {
+       struct ipsec_sa_entry *sa_entry;
+@@ -302,14 +306,16 @@ static int ch_ipsec_xfrm_add_state(struct xfrm_state *x,
+       return res;
+ }
+-static void ch_ipsec_xfrm_del_state(struct xfrm_state *x)
++static void ch_ipsec_xfrm_del_state(struct net_device *dev,
++                                  struct xfrm_state *x)
+ {
+       /* do nothing */
+       if (!x->xso.offload_handle)
+               return;
+ }
+-static void ch_ipsec_xfrm_free_state(struct xfrm_state *x)
++static void ch_ipsec_xfrm_free_state(struct net_device *dev,
++                                   struct xfrm_state *x)
+ {
+       struct ipsec_sa_entry *sa_entry;
+diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
+index 07ea1954a276e..796e90d741f02 100644
+--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
+@@ -9,7 +9,7 @@
+ #define IXGBE_IPSEC_KEY_BITS  160
+ static const char aes_gcm_name[] = "rfc4106(gcm(aes))";
+-static void ixgbe_ipsec_del_sa(struct xfrm_state *xs);
++static void ixgbe_ipsec_del_sa(struct net_device *dev, struct xfrm_state *xs);
+ /**
+  * ixgbe_ipsec_set_tx_sa - set the Tx SA registers
+@@ -321,7 +321,7 @@ void ixgbe_ipsec_restore(struct ixgbe_adapter *adapter)
+               if (r->used) {
+                       if (r->mode & IXGBE_RXTXMOD_VF)
+-                              ixgbe_ipsec_del_sa(r->xs);
++                              ixgbe_ipsec_del_sa(adapter->netdev, r->xs);
+                       else
+                               ixgbe_ipsec_set_rx_sa(hw, i, r->xs->id.spi,
+                                                     r->key, r->salt,
+@@ -330,7 +330,7 @@ void ixgbe_ipsec_restore(struct ixgbe_adapter *adapter)
+               if (t->used) {
+                       if (t->mode & IXGBE_RXTXMOD_VF)
+-                              ixgbe_ipsec_del_sa(t->xs);
++                              ixgbe_ipsec_del_sa(adapter->netdev, t->xs);
+                       else
+                               ixgbe_ipsec_set_tx_sa(hw, i, t->key, t->salt);
+               }
+@@ -417,6 +417,7 @@ static struct xfrm_state *ixgbe_ipsec_find_rx_state(struct ixgbe_ipsec *ipsec,
+ /**
+  * ixgbe_ipsec_parse_proto_keys - find the key and salt based on the protocol
++ * @dev: pointer to net device
+  * @xs: pointer to xfrm_state struct
+  * @mykey: pointer to key array to populate
+  * @mysalt: pointer to salt value to populate
+@@ -424,10 +425,10 @@ static struct xfrm_state *ixgbe_ipsec_find_rx_state(struct ixgbe_ipsec *ipsec,
+  * This copies the protocol keys and salt to our own data tables.  The
+  * 82599 family only supports the one algorithm.
+  **/
+-static int ixgbe_ipsec_parse_proto_keys(struct xfrm_state *xs,
++static int ixgbe_ipsec_parse_proto_keys(struct net_device *dev,
++                                      struct xfrm_state *xs,
+                                       u32 *mykey, u32 *mysalt)
+ {
+-      struct net_device *dev = xs->xso.real_dev;
+       unsigned char *key_data;
+       char *alg_name = NULL;
+       int key_len;
+@@ -473,11 +474,12 @@ static int ixgbe_ipsec_parse_proto_keys(struct xfrm_state *xs,
+ /**
+  * ixgbe_ipsec_check_mgmt_ip - make sure there is no clash with mgmt IP filters
++ * @dev: pointer to net device
+  * @xs: pointer to transformer state struct
+  **/
+-static int ixgbe_ipsec_check_mgmt_ip(struct xfrm_state *xs)
++static int ixgbe_ipsec_check_mgmt_ip(struct net_device *dev,
++                                   struct xfrm_state *xs)
+ {
+-      struct net_device *dev = xs->xso.real_dev;
+       struct ixgbe_adapter *adapter = netdev_priv(dev);
+       struct ixgbe_hw *hw = &adapter->hw;
+       u32 mfval, manc, reg;
+@@ -556,13 +558,14 @@ static int ixgbe_ipsec_check_mgmt_ip(struct xfrm_state *xs)
+ /**
+  * ixgbe_ipsec_add_sa - program device with a security association
++ * @dev: pointer to device to program
+  * @xs: pointer to transformer state struct
+  * @extack: extack point to fill failure reason
+  **/
+-static int ixgbe_ipsec_add_sa(struct xfrm_state *xs,
++static int ixgbe_ipsec_add_sa(struct net_device *dev,
++                            struct xfrm_state *xs,
+                             struct netlink_ext_ack *extack)
+ {
+-      struct net_device *dev = xs->xso.real_dev;
+       struct ixgbe_adapter *adapter = netdev_priv(dev);
+       struct ixgbe_ipsec *ipsec = adapter->ipsec;
+       struct ixgbe_hw *hw = &adapter->hw;
+@@ -581,7 +584,7 @@ static int ixgbe_ipsec_add_sa(struct xfrm_state *xs,
+               return -EINVAL;
+       }
+-      if (ixgbe_ipsec_check_mgmt_ip(xs)) {
++      if (ixgbe_ipsec_check_mgmt_ip(dev, xs)) {
+               NL_SET_ERR_MSG_MOD(extack, "IPsec IP addr clash with mgmt filters");
+               return -EINVAL;
+       }
+@@ -615,7 +618,7 @@ static int ixgbe_ipsec_add_sa(struct xfrm_state *xs,
+                       rsa.decrypt = xs->ealg || xs->aead;
+               /* get the key and salt */
+-              ret = ixgbe_ipsec_parse_proto_keys(xs, rsa.key, &rsa.salt);
++              ret = ixgbe_ipsec_parse_proto_keys(dev, xs, rsa.key, &rsa.salt);
+               if (ret) {
+                       NL_SET_ERR_MSG_MOD(extack, "Failed to get key data for Rx SA table");
+                       return ret;
+@@ -724,7 +727,7 @@ static int ixgbe_ipsec_add_sa(struct xfrm_state *xs,
+               if (xs->id.proto & IPPROTO_ESP)
+                       tsa.encrypt = xs->ealg || xs->aead;
+-              ret = ixgbe_ipsec_parse_proto_keys(xs, tsa.key, &tsa.salt);
++              ret = ixgbe_ipsec_parse_proto_keys(dev, xs, tsa.key, &tsa.salt);
+               if (ret) {
+                       NL_SET_ERR_MSG_MOD(extack, "Failed to get key data for Tx SA table");
+                       memset(&tsa, 0, sizeof(tsa));
+@@ -752,11 +755,11 @@ static int ixgbe_ipsec_add_sa(struct xfrm_state *xs,
+ /**
+  * ixgbe_ipsec_del_sa - clear out this specific SA
++ * @dev: pointer to device to program
+  * @xs: pointer to transformer state struct
+  **/
+-static void ixgbe_ipsec_del_sa(struct xfrm_state *xs)
++static void ixgbe_ipsec_del_sa(struct net_device *dev, struct xfrm_state *xs)
+ {
+-      struct net_device *dev = xs->xso.real_dev;
+       struct ixgbe_adapter *adapter = netdev_priv(dev);
+       struct ixgbe_ipsec *ipsec = adapter->ipsec;
+       struct ixgbe_hw *hw = &adapter->hw;
+@@ -841,7 +844,8 @@ void ixgbe_ipsec_vf_clear(struct ixgbe_adapter *adapter, u32 vf)
+                       continue;
+               if (ipsec->rx_tbl[i].mode & IXGBE_RXTXMOD_VF &&
+                   ipsec->rx_tbl[i].vf == vf)
+-                      ixgbe_ipsec_del_sa(ipsec->rx_tbl[i].xs);
++                      ixgbe_ipsec_del_sa(adapter->netdev,
++                                         ipsec->rx_tbl[i].xs);
+       }
+       /* search tx sa table */
+@@ -850,7 +854,8 @@ void ixgbe_ipsec_vf_clear(struct ixgbe_adapter *adapter, u32 vf)
+                       continue;
+               if (ipsec->tx_tbl[i].mode & IXGBE_RXTXMOD_VF &&
+                   ipsec->tx_tbl[i].vf == vf)
+-                      ixgbe_ipsec_del_sa(ipsec->tx_tbl[i].xs);
++                      ixgbe_ipsec_del_sa(adapter->netdev,
++                                         ipsec->tx_tbl[i].xs);
+       }
+ }
+@@ -930,7 +935,7 @@ int ixgbe_ipsec_vf_add_sa(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf)
+       memcpy(xs->aead->alg_name, aes_gcm_name, sizeof(aes_gcm_name));
+       /* set up the HW offload */
+-      err = ixgbe_ipsec_add_sa(xs, NULL);
++      err = ixgbe_ipsec_add_sa(adapter->netdev, xs, NULL);
+       if (err)
+               goto err_aead;
+@@ -1034,7 +1039,7 @@ int ixgbe_ipsec_vf_del_sa(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf)
+               xs = ipsec->tx_tbl[sa_idx].xs;
+       }
+-      ixgbe_ipsec_del_sa(xs);
++      ixgbe_ipsec_del_sa(adapter->netdev, xs);
+       /* remove the xs that was made-up in the add request */
+       kfree_sensitive(xs);
+diff --git a/drivers/net/ethernet/intel/ixgbevf/ipsec.c b/drivers/net/ethernet/intel/ixgbevf/ipsec.c
+index 8ba037e3d9c27..65580b9cb06f2 100644
+--- a/drivers/net/ethernet/intel/ixgbevf/ipsec.c
++++ b/drivers/net/ethernet/intel/ixgbevf/ipsec.c
+@@ -201,6 +201,7 @@ struct xfrm_state *ixgbevf_ipsec_find_rx_state(struct ixgbevf_ipsec *ipsec,
+ /**
+  * ixgbevf_ipsec_parse_proto_keys - find the key and salt based on the protocol
++ * @dev: pointer to net device to program
+  * @xs: pointer to xfrm_state struct
+  * @mykey: pointer to key array to populate
+  * @mysalt: pointer to salt value to populate
+@@ -208,10 +209,10 @@ struct xfrm_state *ixgbevf_ipsec_find_rx_state(struct ixgbevf_ipsec *ipsec,
+  * This copies the protocol keys and salt to our own data tables.  The
+  * 82599 family only supports the one algorithm.
+  **/
+-static int ixgbevf_ipsec_parse_proto_keys(struct xfrm_state *xs,
++static int ixgbevf_ipsec_parse_proto_keys(struct net_device *dev,
++                                        struct xfrm_state *xs,
+                                         u32 *mykey, u32 *mysalt)
+ {
+-      struct net_device *dev = xs->xso.real_dev;
+       unsigned char *key_data;
+       char *alg_name = NULL;
+       int key_len;
+@@ -256,13 +257,14 @@ static int ixgbevf_ipsec_parse_proto_keys(struct xfrm_state *xs,
+ /**
+  * ixgbevf_ipsec_add_sa - program device with a security association
++ * @dev: pointer to net device to program
+  * @xs: pointer to transformer state struct
+  * @extack: extack point to fill failure reason
+  **/
+-static int ixgbevf_ipsec_add_sa(struct xfrm_state *xs,
++static int ixgbevf_ipsec_add_sa(struct net_device *dev,
++                              struct xfrm_state *xs,
+                               struct netlink_ext_ack *extack)
+ {
+-      struct net_device *dev = xs->xso.real_dev;
+       struct ixgbevf_adapter *adapter;
+       struct ixgbevf_ipsec *ipsec;
+       u16 sa_idx;
+@@ -310,7 +312,8 @@ static int ixgbevf_ipsec_add_sa(struct xfrm_state *xs,
+                       rsa.decrypt = xs->ealg || xs->aead;
+               /* get the key and salt */
+-              ret = ixgbevf_ipsec_parse_proto_keys(xs, rsa.key, &rsa.salt);
++              ret = ixgbevf_ipsec_parse_proto_keys(dev, xs, rsa.key,
++                                                   &rsa.salt);
+               if (ret) {
+                       NL_SET_ERR_MSG_MOD(extack, "Failed to get key data for Rx SA table");
+                       return ret;
+@@ -363,7 +366,8 @@ static int ixgbevf_ipsec_add_sa(struct xfrm_state *xs,
+               if (xs->id.proto & IPPROTO_ESP)
+                       tsa.encrypt = xs->ealg || xs->aead;
+-              ret = ixgbevf_ipsec_parse_proto_keys(xs, tsa.key, &tsa.salt);
++              ret = ixgbevf_ipsec_parse_proto_keys(dev, xs, tsa.key,
++                                                   &tsa.salt);
+               if (ret) {
+                       NL_SET_ERR_MSG_MOD(extack, "Failed to get key data for Tx SA table");
+                       memset(&tsa, 0, sizeof(tsa));
+@@ -388,11 +392,12 @@ static int ixgbevf_ipsec_add_sa(struct xfrm_state *xs,
+ /**
+  * ixgbevf_ipsec_del_sa - clear out this specific SA
++ * @dev: pointer to net device to program
+  * @xs: pointer to transformer state struct
+  **/
+-static void ixgbevf_ipsec_del_sa(struct xfrm_state *xs)
++static void ixgbevf_ipsec_del_sa(struct net_device *dev,
++                               struct xfrm_state *xs)
+ {
+-      struct net_device *dev = xs->xso.real_dev;
+       struct ixgbevf_adapter *adapter;
+       struct ixgbevf_ipsec *ipsec;
+       u16 sa_idx;
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.c b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.c
+index fc59e50bafce6..a6500e3673f24 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.c
+@@ -663,10 +663,10 @@ static int cn10k_ipsec_inb_add_state(struct xfrm_state *x,
+       return -EOPNOTSUPP;
+ }
+-static int cn10k_ipsec_outb_add_state(struct xfrm_state *x,
++static int cn10k_ipsec_outb_add_state(struct net_device *dev,
++                                    struct xfrm_state *x,
+                                     struct netlink_ext_ack *extack)
+ {
+-      struct net_device *netdev = x->xso.dev;
+       struct cn10k_tx_sa_s *sa_entry;
+       struct qmem *sa_info;
+       struct otx2_nic *pf;
+@@ -676,7 +676,7 @@ static int cn10k_ipsec_outb_add_state(struct xfrm_state *x,
+       if (err)
+               return err;
+-      pf = netdev_priv(netdev);
++      pf = netdev_priv(dev);
+       err = qmem_alloc(pf->dev, &sa_info, pf->ipsec.sa_size, OTX2_ALIGN);
+       if (err)
+@@ -700,18 +700,18 @@ static int cn10k_ipsec_outb_add_state(struct xfrm_state *x,
+       return 0;
+ }
+-static int cn10k_ipsec_add_state(struct xfrm_state *x,
++static int cn10k_ipsec_add_state(struct net_device *dev,
++                               struct xfrm_state *x,
+                                struct netlink_ext_ack *extack)
+ {
+       if (x->xso.dir == XFRM_DEV_OFFLOAD_IN)
+               return cn10k_ipsec_inb_add_state(x, extack);
+       else
+-              return cn10k_ipsec_outb_add_state(x, extack);
++              return cn10k_ipsec_outb_add_state(dev, x, extack);
+ }
+-static void cn10k_ipsec_del_state(struct xfrm_state *x)
++static void cn10k_ipsec_del_state(struct net_device *dev, struct xfrm_state *x)
+ {
+-      struct net_device *netdev = x->xso.dev;
+       struct cn10k_tx_sa_s *sa_entry;
+       struct qmem *sa_info;
+       struct otx2_nic *pf;
+@@ -720,7 +720,7 @@ static void cn10k_ipsec_del_state(struct xfrm_state *x)
+       if (x->xso.dir == XFRM_DEV_OFFLOAD_IN)
+               return;
+-      pf = netdev_priv(netdev);
++      pf = netdev_priv(dev);
+       sa_info = (struct qmem *)x->xso.offload_handle;
+       sa_entry = (struct cn10k_tx_sa_s *)sa_info->base;
+@@ -732,7 +732,7 @@ static void cn10k_ipsec_del_state(struct xfrm_state *x)
+       err = cn10k_outb_write_sa(pf, sa_info);
+       if (err)
+-              netdev_err(netdev, "Error (%d) deleting SA\n", err);
++              netdev_err(dev, "Error (%d) deleting SA\n", err);
+       x->xso.offload_handle = 0;
+       qmem_free(pf->dev, sa_info);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
+index 0dfbbe21936f3..77f61cd28a799 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
+@@ -689,17 +689,17 @@ static int mlx5e_ipsec_create_dwork(struct mlx5e_ipsec_sa_entry *sa_entry)
+       return 0;
+ }
+-static int mlx5e_xfrm_add_state(struct xfrm_state *x,
++static int mlx5e_xfrm_add_state(struct net_device *dev,
++                              struct xfrm_state *x,
+                               struct netlink_ext_ack *extack)
+ {
+       struct mlx5e_ipsec_sa_entry *sa_entry = NULL;
+-      struct net_device *netdev = x->xso.real_dev;
+       struct mlx5e_ipsec *ipsec;
+       struct mlx5e_priv *priv;
+       gfp_t gfp;
+       int err;
+-      priv = netdev_priv(netdev);
++      priv = netdev_priv(dev);
+       if (!priv->ipsec)
+               return -EOPNOTSUPP;
+@@ -710,7 +710,7 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x,
+               return -ENOMEM;
+       sa_entry->x = x;
+-      sa_entry->dev = netdev;
++      sa_entry->dev = dev;
+       sa_entry->ipsec = ipsec;
+       /* Check if this SA is originated from acquire flow temporary SA */
+       if (x->xso.flags & XFRM_DEV_OFFLOAD_FLAG_ACQ)
+@@ -807,7 +807,7 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x,
+       return err;
+ }
+-static void mlx5e_xfrm_del_state(struct xfrm_state *x)
++static void mlx5e_xfrm_del_state(struct net_device *dev, struct xfrm_state *x)
+ {
+       struct mlx5e_ipsec_sa_entry *sa_entry = to_ipsec_sa_entry(x);
+       struct mlx5e_ipsec *ipsec = sa_entry->ipsec;
+@@ -820,7 +820,7 @@ static void mlx5e_xfrm_del_state(struct xfrm_state *x)
+       WARN_ON(old != sa_entry);
+ }
+-static void mlx5e_xfrm_free_state(struct xfrm_state *x)
++static void mlx5e_xfrm_free_state(struct net_device *dev, struct xfrm_state *x)
+ {
+       struct mlx5e_ipsec_sa_entry *sa_entry = to_ipsec_sa_entry(x);
+       struct mlx5e_ipsec *ipsec = sa_entry->ipsec;
+diff --git a/drivers/net/ethernet/netronome/nfp/crypto/ipsec.c b/drivers/net/ethernet/netronome/nfp/crypto/ipsec.c
+index 671af5d4c5d25..9e7c285eaa6bc 100644
+--- a/drivers/net/ethernet/netronome/nfp/crypto/ipsec.c
++++ b/drivers/net/ethernet/netronome/nfp/crypto/ipsec.c
+@@ -266,17 +266,17 @@ static void set_sha2_512hmac(struct nfp_ipsec_cfg_add_sa *cfg, int *trunc_len)
+       }
+ }
+-static int nfp_net_xfrm_add_state(struct xfrm_state *x,
++static int nfp_net_xfrm_add_state(struct net_device *dev,
++                                struct xfrm_state *x,
+                                 struct netlink_ext_ack *extack)
+ {
+-      struct net_device *netdev = x->xso.real_dev;
+       struct nfp_ipsec_cfg_mssg msg = {};
+       int i, key_len, trunc_len, err = 0;
+       struct nfp_ipsec_cfg_add_sa *cfg;
+       struct nfp_net *nn;
+       unsigned int saidx;
+-      nn = netdev_priv(netdev);
++      nn = netdev_priv(dev);
+       cfg = &msg.cfg_add_sa;
+       /* General */
+@@ -546,17 +546,16 @@ static int nfp_net_xfrm_add_state(struct xfrm_state *x,
+       return 0;
+ }
+-static void nfp_net_xfrm_del_state(struct xfrm_state *x)
++static void nfp_net_xfrm_del_state(struct net_device *dev, struct xfrm_state *x)
+ {
+       struct nfp_ipsec_cfg_mssg msg = {
+               .cmd = NFP_IPSEC_CFG_MSSG_INV_SA,
+               .sa_idx = x->xso.offload_handle - 1,
+       };
+-      struct net_device *netdev = x->xso.real_dev;
+       struct nfp_net *nn;
+       int err;
+-      nn = netdev_priv(netdev);
++      nn = netdev_priv(dev);
+       err = nfp_net_sched_mbox_amsg_work(nn, NFP_NET_CFG_MBOX_CMD_IPSEC, &msg,
+                                          sizeof(msg), nfp_net_ipsec_cfg);
+       if (err)
+diff --git a/drivers/net/netdevsim/ipsec.c b/drivers/net/netdevsim/ipsec.c
+index d88bdb9a17176..47cdee5577d46 100644
+--- a/drivers/net/netdevsim/ipsec.c
++++ b/drivers/net/netdevsim/ipsec.c
+@@ -85,11 +85,11 @@ static int nsim_ipsec_find_empty_idx(struct nsim_ipsec *ipsec)
+       return -ENOSPC;
+ }
+-static int nsim_ipsec_parse_proto_keys(struct xfrm_state *xs,
++static int nsim_ipsec_parse_proto_keys(struct net_device *dev,
++                                     struct xfrm_state *xs,
+                                      u32 *mykey, u32 *mysalt)
+ {
+       const char aes_gcm_name[] = "rfc4106(gcm(aes))";
+-      struct net_device *dev = xs->xso.real_dev;
+       unsigned char *key_data;
+       char *alg_name = NULL;
+       int key_len;
+@@ -129,17 +129,16 @@ static int nsim_ipsec_parse_proto_keys(struct xfrm_state *xs,
+       return 0;
+ }
+-static int nsim_ipsec_add_sa(struct xfrm_state *xs,
++static int nsim_ipsec_add_sa(struct net_device *dev,
++                           struct xfrm_state *xs,
+                            struct netlink_ext_ack *extack)
+ {
+       struct nsim_ipsec *ipsec;
+-      struct net_device *dev;
+       struct netdevsim *ns;
+       struct nsim_sa sa;
+       u16 sa_idx;
+       int ret;
+-      dev = xs->xso.real_dev;
+       ns = netdev_priv(dev);
+       ipsec = &ns->ipsec;
+@@ -174,7 +173,7 @@ static int nsim_ipsec_add_sa(struct xfrm_state *xs,
+               sa.crypt = xs->ealg || xs->aead;
+       /* get the key and salt */
+-      ret = nsim_ipsec_parse_proto_keys(xs, sa.key, &sa.salt);
++      ret = nsim_ipsec_parse_proto_keys(dev, xs, sa.key, &sa.salt);
+       if (ret) {
+               NL_SET_ERR_MSG_MOD(extack, "Failed to get key data for SA table");
+               return ret;
+@@ -200,9 +199,9 @@ static int nsim_ipsec_add_sa(struct xfrm_state *xs,
+       return 0;
+ }
+-static void nsim_ipsec_del_sa(struct xfrm_state *xs)
++static void nsim_ipsec_del_sa(struct net_device *dev, struct xfrm_state *xs)
+ {
+-      struct netdevsim *ns = netdev_priv(xs->xso.real_dev);
++      struct netdevsim *ns = netdev_priv(dev);
+       struct nsim_ipsec *ipsec = &ns->ipsec;
+       u16 sa_idx;
+diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
+index 7ea022750e4e0..33338a233cc72 100644
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -1012,9 +1012,13 @@ struct netdev_bpf {
+ #ifdef CONFIG_XFRM_OFFLOAD
+ struct xfrmdev_ops {
+-      int     (*xdo_dev_state_add) (struct xfrm_state *x, struct netlink_ext_ack *extack);
+-      void    (*xdo_dev_state_delete) (struct xfrm_state *x);
+-      void    (*xdo_dev_state_free) (struct xfrm_state *x);
++      int     (*xdo_dev_state_add)(struct net_device *dev,
++                                   struct xfrm_state *x,
++                                   struct netlink_ext_ack *extack);
++      void    (*xdo_dev_state_delete)(struct net_device *dev,
++                                      struct xfrm_state *x);
++      void    (*xdo_dev_state_free)(struct net_device *dev,
++                                    struct xfrm_state *x);
+       bool    (*xdo_dev_offload_ok) (struct sk_buff *skb,
+                                      struct xfrm_state *x);
+       void    (*xdo_dev_state_advance_esn) (struct xfrm_state *x);
+diff --git a/include/net/xfrm.h b/include/net/xfrm.h
+index 06ab2a3d2ebd1..01783dc3d0e32 100644
+--- a/include/net/xfrm.h
++++ b/include/net/xfrm.h
+@@ -147,8 +147,16 @@ enum {
+ };
+ struct xfrm_dev_offload {
++      /* The device for this offload.
++       * Device drivers should not use this directly, as that will prevent
++       * them from working with bonding device. Instead, the device passed
++       * to the add/delete callbacks should be used.
++       */
+       struct net_device       *dev;
+       netdevice_tracker       dev_tracker;
++      /* This is a private pointer used by the bonding driver.
++       * Device drivers should not use it.
++       */
+       struct net_device       *real_dev;
+       unsigned long           offload_handle;
+       u8                      dir : 2;
+diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
+index 4f4165ff738d2..f46a9e5764f01 100644
+--- a/net/xfrm/xfrm_device.c
++++ b/net/xfrm/xfrm_device.c
+@@ -314,7 +314,6 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
+       xso->dev = dev;
+       netdev_tracker_alloc(dev, &xso->dev_tracker, GFP_ATOMIC);
+-      xso->real_dev = dev;
+       if (xuo->flags & XFRM_OFFLOAD_INBOUND)
+               xso->dir = XFRM_DEV_OFFLOAD_IN;
+@@ -326,11 +325,10 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
+       else
+               xso->type = XFRM_DEV_OFFLOAD_CRYPTO;
+-      err = dev->xfrmdev_ops->xdo_dev_state_add(x, extack);
++      err = dev->xfrmdev_ops->xdo_dev_state_add(dev, x, extack);
+       if (err) {
+               xso->dev = NULL;
+               xso->dir = 0;
+-              xso->real_dev = NULL;
+               netdev_put(dev, &xso->dev_tracker);
+               xso->type = XFRM_DEV_OFFLOAD_UNSPECIFIED;
+diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
+index a98e193b55a3e..5ece039846e20 100644
+--- a/net/xfrm/xfrm_state.c
++++ b/net/xfrm/xfrm_state.c
+@@ -767,7 +767,7 @@ void xfrm_dev_state_delete(struct xfrm_state *x)
+       struct net_device *dev = READ_ONCE(xso->dev);
+       if (dev) {
+-              dev->xfrmdev_ops->xdo_dev_state_delete(x);
++              dev->xfrmdev_ops->xdo_dev_state_delete(dev, x);
+               spin_lock_bh(&xfrm_state_dev_gc_lock);
+               hlist_add_head(&x->dev_gclist, &xfrm_state_dev_gc_list);
+               spin_unlock_bh(&xfrm_state_dev_gc_lock);
+@@ -789,7 +789,7 @@ void xfrm_dev_state_free(struct xfrm_state *x)
+               spin_unlock_bh(&xfrm_state_dev_gc_lock);
+               if (dev->xfrmdev_ops->xdo_dev_state_free)
+-                      dev->xfrmdev_ops->xdo_dev_state_free(x);
++                      dev->xfrmdev_ops->xdo_dev_state_free(dev, x);
+               WRITE_ONCE(xso->dev, NULL);
+               xso->type = XFRM_DEV_OFFLOAD_UNSPECIFIED;
+               netdev_put(dev, &xso->dev_tracker);
+@@ -1548,16 +1548,18 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr,
+               if (pol->xdo.type == XFRM_DEV_OFFLOAD_PACKET) {
+                       struct xfrm_dev_offload *xdo = &pol->xdo;
+                       struct xfrm_dev_offload *xso = &x->xso;
++                      struct net_device *dev = xdo->dev;
+                       xso->type = XFRM_DEV_OFFLOAD_PACKET;
+                       xso->dir = xdo->dir;
+-                      xso->dev = xdo->dev;
++                      xso->dev = dev;
+                       xso->flags = XFRM_DEV_OFFLOAD_FLAG_ACQ;
+-                      netdev_hold(xso->dev, &xso->dev_tracker, GFP_ATOMIC);
+-                      error = xso->dev->xfrmdev_ops->xdo_dev_state_add(x, NULL);
++                      netdev_hold(dev, &xso->dev_tracker, GFP_ATOMIC);
++                      error = dev->xfrmdev_ops->xdo_dev_state_add(dev, x,
++                                                                  NULL);
+                       if (error) {
+                               xso->dir = 0;
+-                              netdev_put(xso->dev, &xso->dev_tracker);
++                              netdev_put(dev, &xso->dev_tracker);
+                               xso->dev = NULL;
+                               xso->type = XFRM_DEV_OFFLOAD_UNSPECIFIED;
+                               x->km.state = XFRM_STATE_DEAD;
+-- 
+2.39.5
+
diff --git a/queue-6.15/xfrm-use-xdo.dev-instead-of-xdo.real_dev.patch b/queue-6.15/xfrm-use-xdo.dev-instead-of-xdo.real_dev.patch
new file mode 100644 (file)
index 0000000..d1b2e08
--- /dev/null
@@ -0,0 +1,81 @@
+From 46030104e77dc966b9f2e151869763c020ceb931 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Apr 2025 10:49:54 +0300
+Subject: xfrm: Use xdo.dev instead of xdo.real_dev
+
+From: Cosmin Ratiu <cratiu@nvidia.com>
+
+[ Upstream commit 25ac138f58e7d5c8bffa31e8891418d2819180c4 ]
+
+The policy offload struct was reused from the state offload and
+real_dev was copied from dev, but it was never set to anything else.
+Simplify the code by always using xdo.dev for policies.
+
+Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Stable-dep-of: fd4e41ebf66c ("bonding: Mark active offloaded xfrm_states")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c | 2 +-
+ net/xfrm/xfrm_device.c                                   | 2 --
+ net/xfrm/xfrm_state.c                                    | 2 --
+ 3 files changed, 1 insertion(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
+index 626e525c0f0d7..0dfbbe21936f3 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
+@@ -1164,7 +1164,7 @@ mlx5e_ipsec_build_accel_pol_attrs(struct mlx5e_ipsec_pol_entry *pol_entry,
+ static int mlx5e_xfrm_add_policy(struct xfrm_policy *x,
+                                struct netlink_ext_ack *extack)
+ {
+-      struct net_device *netdev = x->xdo.real_dev;
++      struct net_device *netdev = x->xdo.dev;
+       struct mlx5e_ipsec_pol_entry *pol_entry;
+       struct mlx5e_priv *priv;
+       int err;
+diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
+index d62f76161d83e..4f4165ff738d2 100644
+--- a/net/xfrm/xfrm_device.c
++++ b/net/xfrm/xfrm_device.c
+@@ -378,7 +378,6 @@ int xfrm_dev_policy_add(struct net *net, struct xfrm_policy *xp,
+       xdo->dev = dev;
+       netdev_tracker_alloc(dev, &xdo->dev_tracker, GFP_ATOMIC);
+-      xdo->real_dev = dev;
+       xdo->type = XFRM_DEV_OFFLOAD_PACKET;
+       switch (dir) {
+       case XFRM_POLICY_IN:
+@@ -400,7 +399,6 @@ int xfrm_dev_policy_add(struct net *net, struct xfrm_policy *xp,
+       err = dev->xfrmdev_ops->xdo_dev_policy_add(xp, extack);
+       if (err) {
+               xdo->dev = NULL;
+-              xdo->real_dev = NULL;
+               xdo->type = XFRM_DEV_OFFLOAD_UNSPECIFIED;
+               xdo->dir = 0;
+               netdev_put(dev, &xdo->dev_tracker);
+diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
+index 07fe8e5daa32b..a98e193b55a3e 100644
+--- a/net/xfrm/xfrm_state.c
++++ b/net/xfrm/xfrm_state.c
+@@ -1552,7 +1552,6 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr,
+                       xso->type = XFRM_DEV_OFFLOAD_PACKET;
+                       xso->dir = xdo->dir;
+                       xso->dev = xdo->dev;
+-                      xso->real_dev = xdo->real_dev;
+                       xso->flags = XFRM_DEV_OFFLOAD_FLAG_ACQ;
+                       netdev_hold(xso->dev, &xso->dev_tracker, GFP_ATOMIC);
+                       error = xso->dev->xfrmdev_ops->xdo_dev_state_add(x, NULL);
+@@ -1560,7 +1559,6 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr,
+                               xso->dir = 0;
+                               netdev_put(xso->dev, &xso->dev_tracker);
+                               xso->dev = NULL;
+-                              xso->real_dev = NULL;
+                               xso->type = XFRM_DEV_OFFLOAD_UNSPECIFIED;
+                               x->km.state = XFRM_STATE_DEAD;
+                               to_put = x;
+-- 
+2.39.5
+