]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.14
authorSasha Levin <sashal@kernel.org>
Mon, 7 Apr 2025 14:02:12 +0000 (10:02 -0400)
committerSasha Levin <sashal@kernel.org>
Mon, 7 Apr 2025 14:02:12 +0000 (10:02 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
645 files changed:
queue-6.14/accel-amdxdna-return-error-when-setting-clock-failed.patch [new file with mode: 0644]
queue-6.14/acpi-processor-idle-return-an-error-if-both-p_lvl-2-.patch [new file with mode: 0644]
queue-6.14/alsa-hda-realtek-always-honor-no_shutup_pins.patch [new file with mode: 0644]
queue-6.14/alsa-hda-realtek-fix-built-in-mic-assignment-on-asus.patch [new file with mode: 0644]
queue-6.14/alsa-hda-realtek-fix-built-in-mic-breakage-on-asus-v.patch [new file with mode: 0644]
queue-6.14/alsa-hda-realtek-fix-built-in-mic-on-another-asus-vi.patch [new file with mode: 0644]
queue-6.14/alsa-timer-don-t-take-register_mutex-with-copy_from-.patch [new file with mode: 0644]
queue-6.14/alsa-usb-audio-separate-djm-a9-cap-lvl-options.patch [new file with mode: 0644]
queue-6.14/arch-powerpc-drop-generic_ptdump-from-mpc885_ads_def.patch [new file with mode: 0644]
queue-6.14/arcnet-add-null-check-in-com20020pci_probe.patch [new file with mode: 0644]
queue-6.14/arm-dts-imx6ul-tqma6ul1-change-include-order-to-disa.patch [new file with mode: 0644]
queue-6.14/arm-dts-omap4-panda-a4-add-missing-model-and-compati.patch [new file with mode: 0644]
queue-6.14/arm64-dts-imx8mp-add-audio_axi_clk_root-to-audiomix-.patch [new file with mode: 0644]
queue-6.14/arm64-dts-imx8mp-change-audio_axi_clk_root-freq.-to-.patch [new file with mode: 0644]
queue-6.14/arm64-dts-imx8mp-skov-correct-pmic-board-limits.patch [new file with mode: 0644]
queue-6.14/arm64-dts-imx8mp-skov-operate-cpu-at-850-mv-by-defau.patch [new file with mode: 0644]
queue-6.14/arm64-dts-mediatek-mt6359-fix-dtbs_check-error-for-a.patch [new file with mode: 0644]
queue-6.14/arm64-dts-mediatek-mt8173-elm-drop-pmic-s-address-ce.patch [new file with mode: 0644]
queue-6.14/arm64-dts-mediatek-mt8173-fix-some-node-names.patch [new file with mode: 0644]
queue-6.14/arm64-dts-mediatek-mt8390-genio-700-evk-move-common-.patch [new file with mode: 0644]
queue-6.14/arm64-dts-mediatek-mt8390-genio-common-fix-duplicate.patch [new file with mode: 0644]
queue-6.14/arm64-dts-renesas-r8a774c0-re-add-voltages-to-opp-ta.patch [new file with mode: 0644]
queue-6.14/arm64-dts-renesas-r8a77990-re-add-voltages-to-opp-ta.patch [new file with mode: 0644]
queue-6.14/arm64-dts-rockchip-fix-pcie-reset-gpio-on-orange-pi-.patch [new file with mode: 0644]
queue-6.14/arm64-dts-rockchip-fix-pwm-pinctrl-names.patch [new file with mode: 0644]
queue-6.14/arm64-dts-rockchip-move-rk356x-scmi-shmem-to-reserve.patch [new file with mode: 0644]
queue-6.14/arm64-dts-rockchip-remove-bluetooth-node-from-rock-3.patch [new file with mode: 0644]
queue-6.14/arm64-dts-rockchip-remove-ethm0_clk0_25m_out-from-si.patch [new file with mode: 0644]
queue-6.14/arm64-dts-ti-k3-am62-verdin-dahlia-add-microphone-ja.patch [new file with mode: 0644]
queue-6.14/arm64-dts-ti-k3-am62p-enable-audio_refclkx.patch [new file with mode: 0644]
queue-6.14/arm64-dts-ti-k3-am62p-fix-pinctrl-settings.patch [new file with mode: 0644]
queue-6.14/arm64-dts-ti-k3-j722s-evm-fix-usb2.0_mux_sel-to-sele.patch [new file with mode: 0644]
queue-6.14/arm64-dts-ti-k3-j722s-fix-pinctrl-settings.patch [new file with mode: 0644]
queue-6.14/arm64-realm-use-aliased-addresses-for-device-dma-to-.patch [new file with mode: 0644]
queue-6.14/asoc-amd-acp-fix-for-enabling-dmic-on-acp-platforms-.patch [new file with mode: 0644]
queue-6.14/asoc-codecs-rt5665-fix-some-error-handling-paths-in-.patch [new file with mode: 0644]
queue-6.14/asoc-cs35l41-check-the-return-value-from-spi_setup.patch [new file with mode: 0644]
queue-6.14/asoc-imx-card-add-null-check-in-imx_card_probe.patch [new file with mode: 0644]
queue-6.14/asoc-simple-card-utils-don-t-use-__free-device_node-.patch [new file with mode: 0644]
queue-6.14/asoc-tegra-use-non-atomic-timeout-for-adx-status-reg.patch [new file with mode: 0644]
queue-6.14/asoc-ti-j721e-evm-fix-clock-configuration-for-ti-j72.patch [new file with mode: 0644]
queue-6.14/ata-libata-fix-ncq-non-data-log-not-supported-print.patch [new file with mode: 0644]
queue-6.14/auxdisplay-max6959-should-select-bitreverse.patch [new file with mode: 0644]
queue-6.14/auxdisplay-panel-fix-an-api-misuse-in-panel.c.patch [new file with mode: 0644]
queue-6.14/ax25-remove-broken-autobind.patch [new file with mode: 0644]
queue-6.14/badblocks-attempt-to-merge-adjacent-badblocks-during.patch [new file with mode: 0644]
queue-6.14/badblocks-factor-out-a-helper-try_adjacent_combine.patch [new file with mode: 0644]
queue-6.14/badblocks-fix-error-shitf-ops.patch [new file with mode: 0644]
queue-6.14/badblocks-fix-merge-issue-when-new-badblocks-align-w.patch [new file with mode: 0644]
queue-6.14/badblocks-fix-missing-bad-blocks-on-retry-in-_badblo.patch [new file with mode: 0644]
queue-6.14/badblocks-fix-the-using-of-max_badblocks.patch [new file with mode: 0644]
queue-6.14/badblocks-return-boolean-from-badblocks_set-and-badb.patch [new file with mode: 0644]
queue-6.14/badblocks-return-error-directly-when-setting-badbloc.patch [new file with mode: 0644]
queue-6.14/badblocks-return-error-if-any-badblock-set-fails.patch [new file with mode: 0644]
queue-6.14/badblocks-use-sector_t-instead-of-int-to-avoid-trunc.patch [new file with mode: 0644]
queue-6.14/blk-throttle-fix-lower-bps-rate-by-throtl_trim_slice.patch [new file with mode: 0644]
queue-6.14/block-correctly-initialize-blk_integrity_nogenerate-.patch [new file with mode: 0644]
queue-6.14/block-ensure-correct-integrity-capability-propagatio.patch [new file with mode: 0644]
queue-6.14/block-fix-adding-folio-to-bio.patch [new file with mode: 0644]
queue-6.14/bluetooth-add-quirk-for-broken-read_page_scan_type.patch [new file with mode: 0644]
queue-6.14/bluetooth-add-quirk-for-broken-read_voice_setting.patch [new file with mode: 0644]
queue-6.14/bluetooth-btnxpuart-fix-kernel-panic-during-fw-relea.patch [new file with mode: 0644]
queue-6.14/bluetooth-btusb-fix-regression-in-the-initialization.patch [new file with mode: 0644]
queue-6.14/bluetooth-hci-add-definition-of-hci_rp_remote_name_r.patch [new file with mode: 0644]
queue-6.14/bluetooth-hci_core-enable-buffer-flow-control-for-sc.patch [new file with mode: 0644]
queue-6.14/bluetooth-hci_event-fix-handling-of-hci_ev_le_direct.patch [new file with mode: 0644]
queue-6.14/bnxt_en-linearize-tx-skb-if-the-fragments-exceed-the.patch [new file with mode: 0644]
queue-6.14/bnxt_en-mask-the-bd_cnt-field-in-the-tx-bd-properly.patch [new file with mode: 0644]
queue-6.14/bonding-check-xdp-prog-when-set-bond-mode.patch [new file with mode: 0644]
queue-6.14/bpf-fix-array-bounds-error-with-may_goto.patch [new file with mode: 0644]
queue-6.14/bpf-use-preempt_count-directly-in-bpf_send_signal_co.patch [new file with mode: 0644]
queue-6.14/broadcom-fix-supported-flag-check-in-periodic-output.patch [new file with mode: 0644]
queue-6.14/btrfs-don-t-clobber-ret-in-btrfs_validate_super.patch [new file with mode: 0644]
queue-6.14/btrfs-fix-block-group-refcount-race-in-btrfs_create_.patch [new file with mode: 0644]
queue-6.14/btrfs-fix-reclaimed-bytes-accounting-after-automatic.patch [new file with mode: 0644]
queue-6.14/btrfs-get-used-bytes-while-holding-lock-at-btrfs_rec.patch [new file with mode: 0644]
queue-6.14/bus-qcom-ssc-block-bus-fix-the-error-handling-path-o.patch [new file with mode: 0644]
queue-6.14/bus-qcom-ssc-block-bus-remove-some-duplicated-iounma.patch [new file with mode: 0644]
queue-6.14/can-rockchip_canfd-rkcanfd_chip_fifo_setup-remove-du.patch [new file with mode: 0644]
queue-6.14/clk-amlogic-g12a-fix-mmc-a-peripheral-clock.patch [new file with mode: 0644]
queue-6.14/clk-amlogic-g12b-fix-cluster-a-parent-data.patch [new file with mode: 0644]
queue-6.14/clk-amlogic-gxbb-drop-incorrect-flag-on-32k-clock.patch [new file with mode: 0644]
queue-6.14/clk-amlogic-gxbb-drop-non-existing-32k-clock-parent.patch [new file with mode: 0644]
queue-6.14/clk-clk-imx8mp-audiomix-fix-dsp-ocram_a-clock-parent.patch [new file with mode: 0644]
queue-6.14/clk-mmp-fix-null-vs-is_err-check.patch [new file with mode: 0644]
queue-6.14/clk-qcom-gcc-msm8953-fix-stuck-venus0_core0-clock.patch [new file with mode: 0644]
queue-6.14/clk-qcom-gcc-sm8650-do-not-turn-off-usb-gdscs-during.patch [new file with mode: 0644]
queue-6.14/clk-qcom-gcc-x1e80100-unregister-gcc_gpu_cfg_ahb_clk.patch [new file with mode: 0644]
queue-6.14/clk-qcom-ipq5424-fix-software-and-hardware-flow-cont.patch [new file with mode: 0644]
queue-6.14/clk-qcom-mmcc-sdm660-fix-stuck-video_subcore0-clock.patch [new file with mode: 0644]
queue-6.14/clk-renesas-r8a08g045-check-the-source-of-the-cpu-pl.patch [new file with mode: 0644]
queue-6.14/clk-rockchip-rk3328-fix-wrong-clk_ref_usb3otg-parent.patch [new file with mode: 0644]
queue-6.14/clk-samsung-fix-ubsan-panic-in-samsung_clk_init.patch [new file with mode: 0644]
queue-6.14/clk-stm32f4-fix-an-uninitialized-variable.patch [new file with mode: 0644]
queue-6.14/context_tracking-always-inline-ct_-nmi-irq-_-enter-e.patch [new file with mode: 0644]
queue-6.14/coredump-fixes-core_pipe_limit-sysctl-proc_handler.patch [new file with mode: 0644]
queue-6.14/coresight-catu-fix-number-of-pages-while-using-64k-p.patch [new file with mode: 0644]
queue-6.14/coresight-etm4x-add-isb-before-reading-the-trcstatr.patch [new file with mode: 0644]
queue-6.14/cpufreq-amd-pstate-add-missing-null-ptr-check-in-amd.patch [new file with mode: 0644]
queue-6.14/cpufreq-amd-pstate-convert-all-perf-values-to-u8.patch [new file with mode: 0644]
queue-6.14/cpufreq-amd-pstate-modify-the-min_perf-calculation-i.patch [new file with mode: 0644]
queue-6.14/cpufreq-amd-pstate-pass-min-max_limit_perf-as-min-ma.patch [new file with mode: 0644]
queue-6.14/cpufreq-governor-fix-negative-idle_time-handling-in-.patch [new file with mode: 0644]
queue-6.14/cpufreq-init-cpufreq-only-for-present-cpus.patch [new file with mode: 0644]
queue-6.14/cpufreq-scpi-compare-khz-instead-of-hz.patch [new file with mode: 0644]
queue-6.14/cpufreq-tegra194-allow-building-for-tegra234.patch [new file with mode: 0644]
queue-6.14/cpuidle-init-cpuidle-only-for-present-cpus.patch [new file with mode: 0644]
queue-6.14/crypto-api-call-crypto_alg_put-in-crypto_unregister_.patch [new file with mode: 0644]
queue-6.14/crypto-api-fix-larval-relookup-type-and-mask.patch [new file with mode: 0644]
queue-6.14/crypto-bpf-add-module_description-for-skcipher.patch [new file with mode: 0644]
queue-6.14/crypto-hisilicon-sec2-fix-for-aead-auth-key-length.patch [new file with mode: 0644]
queue-6.14/crypto-hisilicon-sec2-fix-for-aead-authsize-alignmen.patch [new file with mode: 0644]
queue-6.14/crypto-hisilicon-sec2-fix-for-sec-spec-check.patch [new file with mode: 0644]
queue-6.14/crypto-iaa-test-the-correct-request-flag.patch [new file with mode: 0644]
queue-6.14/crypto-nx-fix-uninitialised-hv_nxc-on-error.patch [new file with mode: 0644]
queue-6.14/crypto-powerpc-mark-ghashp8-ppc.o-as-an-object_files.patch [new file with mode: 0644]
queue-6.14/crypto-qat-remove-access-to-parity-register-for-qat-.patch [new file with mode: 0644]
queue-6.14/crypto-qat-set-parity-error-mask-for-qat_420xx.patch [new file with mode: 0644]
queue-6.14/crypto-tegra-check-return-value-for-hash-do_one_req.patch [new file with mode: 0644]
queue-6.14/crypto-tegra-do-not-use-fixed-size-buffers.patch [new file with mode: 0644]
queue-6.14/crypto-tegra-finalize-crypto-req-on-error.patch [new file with mode: 0644]
queue-6.14/crypto-tegra-fix-cmac-intermediate-result-handling.patch [new file with mode: 0644]
queue-6.14/crypto-tegra-fix-format-specifier-in-tegra_sha_prep_.patch [new file with mode: 0644]
queue-6.14/crypto-tegra-fix-hash-intermediate-result-handling.patch [new file with mode: 0644]
queue-6.14/crypto-tegra-reserve-keyslots-to-allocate-dynamicall.patch [new file with mode: 0644]
queue-6.14/crypto-tegra-set-iv-to-null-explicitly-for-aes-ecb.patch [new file with mode: 0644]
queue-6.14/crypto-tegra-transfer-hash-init-function-to-crypto-e.patch [new file with mode: 0644]
queue-6.14/crypto-tegra-use-hmac-fallback-when-keyslots-are-ful.patch [new file with mode: 0644]
queue-6.14/crypto-tegra-use-separate-buffer-for-setkey.patch [new file with mode: 0644]
queue-6.14/dlm-prevent-npd-when-writing-a-positive-value-to-eve.patch [new file with mode: 0644]
queue-6.14/dma-fix-encryption-bit-clearing-for-dma_to_phys.patch [new file with mode: 0644]
queue-6.14/dma-introduce-generic-dma_addr_-crypted-helpers.patch [new file with mode: 0644]
queue-6.14/dmaengine-ae4dma-use-the-msi-count-and-its-correspon.patch [new file with mode: 0644]
queue-6.14/dmaengine-fsl-edma-cleanup-chan-after-dma_async_devi.patch [new file with mode: 0644]
queue-6.14/dmaengine-fsl-edma-free-irq-correctly-in-remove-path.patch [new file with mode: 0644]
queue-6.14/dmaengine-ptdma-utilize-the-ae4dma-engine-s-multi-qu.patch [new file with mode: 0644]
queue-6.14/drivers-clk-qcom-ipq5424-fix-the-freq-table-of-sdcc1.patch [new file with mode: 0644]
queue-6.14/drm-amd-display-avoid-npd-when-asic-does-not-support.patch [new file with mode: 0644]
queue-6.14/drm-amd-display-fix-an-indent-issue-in-dml21.patch [new file with mode: 0644]
queue-6.14/drm-amd-display-fix-type-mismatch-in-calculatedynami.patch [new file with mode: 0644]
queue-6.14/drm-amdgpu-mes-enable-compute-pipes-across-all-mec.patch [new file with mode: 0644]
queue-6.14/drm-amdgpu-mes-optimize-compute-loop-handling.patch [new file with mode: 0644]
queue-6.14/drm-amdgpu-refine-smu-send-msg-debug-log-format.patch [new file with mode: 0644]
queue-6.14/drm-amdgpu-replace-mutex-with-spinlock-for-rlcg-regi.patch [new file with mode: 0644]
queue-6.14/drm-amdgpu-umsch-declare-umsch-firmware.patch [new file with mode: 0644]
queue-6.14/drm-amdgpu-umsch-fix-ucode-check.patch [new file with mode: 0644]
queue-6.14/drm-amdgpu-umsch-remove-vpe-test-from-umsch.patch [new file with mode: 0644]
queue-6.14/drm-amdgpu-vcn5.0.1-use-correct-dpm-helper.patch [new file with mode: 0644]
queue-6.14/drm-amdkfd-fix-circular-locking-dependency-in-svm_ra.patch [new file with mode: 0644]
queue-6.14/drm-bridge-it6505-fix-hdcp-v-match-check-is-not-perf.patch [new file with mode: 0644]
queue-6.14/drm-bridge-ti-sn65dsi86-fix-multiple-instances.patch [new file with mode: 0644]
queue-6.14/drm-dp_mst-fix-drm-rad-print.patch [new file with mode: 0644]
queue-6.14/drm-file-add-fdinfo-helper-for-printing-regions-with.patch [new file with mode: 0644]
queue-6.14/drm-mediatek-dp-drm_err-dev_err-in-hpd-path-to-avoid.patch [new file with mode: 0644]
queue-6.14/drm-mediatek-dsi-fix-error-codes-in-mtk_dsi_host_tra.patch [new file with mode: 0644]
queue-6.14/drm-mediatek-fix-config_updating-flag-never-false-wh.patch [new file with mode: 0644]
queue-6.14/drm-mediatek-mtk_hdmi-fix-typo-for-aud_sampe_size-me.patch [new file with mode: 0644]
queue-6.14/drm-mediatek-mtk_hdmi-unregister-audio-platform-devi.patch [new file with mode: 0644]
queue-6.14/drm-msm-a6xx-fix-a6xx-indexed-regs-in-devcoreduump.patch [new file with mode: 0644]
queue-6.14/drm-msm-dpu-don-t-set-crtc_state-mode_changed-from-a.patch [new file with mode: 0644]
queue-6.14/drm-msm-dpu-don-t-use-active-in-atomic_check.patch [new file with mode: 0644]
queue-6.14/drm-msm-dpu-fall-back-to-a-single-dsc-encoder-1-1-1-.patch [new file with mode: 0644]
queue-6.14/drm-msm-dpu-move-needs_cdm-setting-to-dpu_encoder_ge.patch [new file with mode: 0644]
queue-6.14/drm-msm-dpu-remove-arbitrary-limit-of-1-interface-in.patch [new file with mode: 0644]
queue-6.14/drm-msm-dpu-simplify-dpu_encoder_get_topology-interf.patch [new file with mode: 0644]
queue-6.14/drm-msm-dsi-phy-program-clock-inverters-in-correct-r.patch [new file with mode: 0644]
queue-6.14/drm-msm-dsi-set-phy-usescase-and-mode-before-registe.patch [new file with mode: 0644]
queue-6.14/drm-msm-dsi-use-existing-per-interface-slice-count-i.patch [new file with mode: 0644]
queue-6.14/drm-msm-gem-fix-error-code-msm_parse_deps.patch [new file with mode: 0644]
queue-6.14/drm-panel-ilitek-ili9882t-fix-gpio-name-in-error-mes.patch [new file with mode: 0644]
queue-6.14/drm-panthor-avoid-sleep-locking-in-the-internal-bo-s.patch [new file with mode: 0644]
queue-6.14/drm-panthor-clean-up-fw-version-information-display.patch [new file with mode: 0644]
queue-6.14/drm-panthor-expose-size-of-driver-internal-bo-s-over.patch [new file with mode: 0644]
queue-6.14/drm-panthor-fix-a-race-between-the-reset-and-suspend.patch [new file with mode: 0644]
queue-6.14/drm-panthor-fix-race-condition-when-gathering-fdinfo.patch [new file with mode: 0644]
queue-6.14/drm-panthor-replace-sleep-locks-with-spinlocks-in-fd.patch [new file with mode: 0644]
queue-6.14/drm-panthor-update-cs_status_-defines-to-correct-val.patch [new file with mode: 0644]
queue-6.14/drm-ssd130x-ensure-ssd132x-pitch-is-correct.patch [new file with mode: 0644]
queue-6.14/drm-ssd130x-fix-ssd132x-encoding.patch [new file with mode: 0644]
queue-6.14/drm-ssd130x-set-spi-.id_table-to-prevent-an-spi-core.patch [new file with mode: 0644]
queue-6.14/drm-vkms-fix-use-after-free-and-double-free-on-init-.patch [new file with mode: 0644]
queue-6.14/drm-xlnx-zynqmp-fix-max-dma-segment-size.patch [new file with mode: 0644]
queue-6.14/drm-xlnx-zynqmp_dpsub-add-null-check-in-zynqmp_audio.patch [new file with mode: 0644]
queue-6.14/drm-zynqmp_dp-fix-a-deadlock-in-zynqmp_dp_ignore_hpd.patch [new file with mode: 0644]
queue-6.14/dt-bindings-vendor-prefixes-add-gocontroll.patch [new file with mode: 0644]
queue-6.14/dummycon-fix-default-rows-cols.patch [new file with mode: 0644]
queue-6.14/e1000e-change-k1-configuration-on-mtp-and-later-plat.patch [new file with mode: 0644]
queue-6.14/edac-ie31200-fix-the-dimm-size-mask-for-several-socs.patch [new file with mode: 0644]
queue-6.14/edac-ie31200-fix-the-error-path-order-of-ie31200_ini.patch [new file with mode: 0644]
queue-6.14/edac-ie31200-fix-the-size-of-edac_mc_layer_chip_sele.patch [new file with mode: 0644]
queue-6.14/edac-igen6-fix-the-flood-of-invalid-error-reports.patch [new file with mode: 0644]
queue-6.14/edac-skx_common-i10nm-fix-some-missing-error-reports.patch [new file with mode: 0644]
queue-6.14/erofs-allow-16-byte-volume-name-again.patch [new file with mode: 0644]
queue-6.14/eth-bnxt-fix-out-of-range-access-of-vnic_info-array.patch [new file with mode: 0644]
queue-6.14/exfat-fix-missing-shutdown-check.patch [new file with mode: 0644]
queue-6.14/exfat-fix-the-infinite-loop-in-exfat_find_last_clust.patch [new file with mode: 0644]
queue-6.14/ext4-add-ext4_flags_emergency_ro-bit.patch [new file with mode: 0644]
queue-6.14/ext4-add-missing-brelse-for-bh2-in-ext4_dx_add_entry.patch [new file with mode: 0644]
queue-6.14/ext4-avoid-journaling-sb-update-on-error-if-journal-.patch [new file with mode: 0644]
queue-6.14/ext4-convert-ext4_flags_-defines-to-enum.patch [new file with mode: 0644]
queue-6.14/ext4-correct-behavior-under-errors-remount-ro-mode.patch [new file with mode: 0644]
queue-6.14/ext4-define-ext4_journal_destroy-wrapper.patch [new file with mode: 0644]
queue-6.14/ext4-fix-out-of-bound-read-in-ext4_xattr_inode_dec_r.patch [new file with mode: 0644]
queue-6.14/ext4-fix-potential-null-dereference-in-ext4-kunit-te.patch [new file with mode: 0644]
queue-6.14/ext4-goto-right-label-out_mmap_sem-in-ext4_setattr.patch [new file with mode: 0644]
queue-6.14/ext4-introduce-itail-helper.patch [new file with mode: 0644]
queue-6.14/ext4-show-emergency_ro-when-ext4_flags_emergency_ro-.patch [new file with mode: 0644]
queue-6.14/ext4-verify-fast-symlink-length.patch [new file with mode: 0644]
queue-6.14/f2fs-add-check-for-deleted-inode.patch [new file with mode: 0644]
queue-6.14/f2fs-fix-missing-discard-for-active-segments.patch [new file with mode: 0644]
queue-6.14/f2fs-fix-potential-deadloop-in-prepare_compress_over.patch [new file with mode: 0644]
queue-6.14/f2fs-fix-to-avoid-accessing-uninitialized-curseg.patch [new file with mode: 0644]
queue-6.14/f2fs-fix-to-avoid-panic-once-fallocation-fails-for-p.patch [new file with mode: 0644]
queue-6.14/f2fs-fix-to-avoid-running-out-of-free-segments.patch [new file with mode: 0644]
queue-6.14/f2fs-fix-to-call-f2fs_recover_quota_end-correctly.patch [new file with mode: 0644]
queue-6.14/f2fs-fix-to-set-.discard_granularity-correctly.patch [new file with mode: 0644]
queue-6.14/f2fs-quota-fix-to-avoid-warning-in-dquot_writeback_d.patch [new file with mode: 0644]
queue-6.14/fbdev-au1100fb-move-a-variable-assignment-behind-a-n.patch [new file with mode: 0644]
queue-6.14/fbdev-sm501fb-add-some-geometry-checks.patch [new file with mode: 0644]
queue-6.14/firmware-arm_ffa-explicitly-cast-return-value-from-f.patch [new file with mode: 0644]
queue-6.14/firmware-arm_ffa-explicitly-cast-return-value-from-n.patch [new file with mode: 0644]
queue-6.14/firmware-arm_ffa-refactor-addition-of-partition-info.patch [new file with mode: 0644]
queue-6.14/firmware-arm_ffa-skip-the-first-partition-id-when-pa.patch [new file with mode: 0644]
queue-6.14/firmware-arm_ffa-unregister-the-ff-a-devices-when-cl.patch [new file with mode: 0644]
queue-6.14/firmware-arm_scmi-use-ioread64-instead-of-ioread64_h.patch [new file with mode: 0644]
queue-6.14/firmware-cs_dsp-ensure-cs_dsp_load-_coeff-returns-0-.patch [new file with mode: 0644]
queue-6.14/fs-9p-fix-null-pointer-dereference-on-mkdir.patch [new file with mode: 0644]
queue-6.14/fs-ntfs3-factor-out-ntfs_-create-remove-_proc_root.patch [new file with mode: 0644]
queue-6.14/fs-ntfs3-factor-out-ntfs_-create-remove-_procdir.patch [new file with mode: 0644]
queue-6.14/fs-ntfs3-fix-a-couple-integer-overflows-on-32bit-sys.patch [new file with mode: 0644]
queue-6.14/fs-ntfs3-fix-proc_info_root-leak-when-init-ntfs-fail.patch [new file with mode: 0644]
queue-6.14/fs-ntfs3-prevent-integer-overflow-in-hdr_first_de.patch [new file with mode: 0644]
queue-6.14/fs-ntfs3-update-inode-i_mapping-a_ops-on-compression.patch [new file with mode: 0644]
queue-6.14/fs-procfs-fix-the-comment-above-proc_pid_wchan.patch [new file with mode: 0644]
queue-6.14/fs-support-o_path-fds-with-fsconfig_set_fd.patch [new file with mode: 0644]
queue-6.14/fuse-fix-dax-truncate-punch_hole-fault-path.patch [new file with mode: 0644]
queue-6.14/gfs2-minor-evict-fix.patch [new file with mode: 0644]
queue-6.14/gfs2-skip-if-we-cannot-defer-delete.patch [new file with mode: 0644]
queue-6.14/gpu-cdns-mhdp8546-fix-call-balance-of-mhdp-clk-handl.patch [new file with mode: 0644]
queue-6.14/greybus-gb-beagleplay-add-error-handling-for-gb_grey.patch [new file with mode: 0644]
queue-6.14/hid-remove-superfluous-and-wrong-makefile-entry-for-.patch [new file with mode: 0644]
queue-6.14/i3c-master-svc-fix-missing-the-ibi-rules.patch [new file with mode: 0644]
queue-6.14/ib-mad-check-available-slots-before-posting-receive-.patch [new file with mode: 0644]
queue-6.14/ibmvnic-use-kernel-helpers-for-hex-dumps.patch [new file with mode: 0644]
queue-6.14/ice-ensure-periodic-output-start-time-is-in-the-futu.patch [new file with mode: 0644]
queue-6.14/ice-fix-input-validation-for-virtchnl-bw.patch [new file with mode: 0644]
queue-6.14/ice-fix-reservation-of-resources-for-rdma-when-disab.patch [new file with mode: 0644]
queue-6.14/ice-fix-using-untrusted-value-of-pkt_len-in-ice_vc_f.patch [new file with mode: 0644]
queue-6.14/ice-health.c-fix-compilation-on-gcc-7.5.patch [new file with mode: 0644]
queue-6.14/ice-stop-truncating-queue-ids-when-checking.patch [new file with mode: 0644]
queue-6.14/ice-validate-queue-quanta-parameters-to-prevent-oob-.patch [new file with mode: 0644]
queue-6.14/idpf-check-error-for-register_netdev-on-init.patch [new file with mode: 0644]
queue-6.14/idpf-fix-adapter-null-pointer-dereference-on-reboot.patch [new file with mode: 0644]
queue-6.14/igb-reject-invalid-external-timestamp-requests-for-8.patch [new file with mode: 0644]
queue-6.14/igc-add-launch-time-support-to-xdp-zc.patch [new file with mode: 0644]
queue-6.14/igc-fix-tx-drops-in-xdp-zc.patch [new file with mode: 0644]
queue-6.14/igc-refactor-empty-frame-insertion-for-launch-time-s.patch [new file with mode: 0644]
queue-6.14/iio-accel-mma8452-ensure-error-return-on-failure-to-.patch [new file with mode: 0644]
queue-6.14/iio-accel-msa311-fix-failure-to-release-runtime-pm-i.patch [new file with mode: 0644]
queue-6.14/iio-adc-ad4130-fix-comparison-of-channel-setups.patch [new file with mode: 0644]
queue-6.14/iio-adc-ad7124-fix-comparison-of-channel-configs.patch [new file with mode: 0644]
queue-6.14/iio-adc-ad7124-micro-optimize-channel-disabling.patch [new file with mode: 0644]
queue-6.14/iio-adc-ad7124-really-disable-all-channels-at-probe-.patch [new file with mode: 0644]
queue-6.14/iio-adc-ad7173-fix-comparison-of-channel-configs.patch [new file with mode: 0644]
queue-6.14/iio-adc-ad7173-grab-direct-mode-for-calibration.patch [new file with mode: 0644]
queue-6.14/iio-adc-ad7192-grab-direct-mode-for-calibration.patch [new file with mode: 0644]
queue-6.14/iio-adc-ad7768-1-set-mosi-idle-state-to-prevent-acci.patch [new file with mode: 0644]
queue-6.14/iio-adc-ad_sigma_delta-disable-channel-after-calibra.patch [new file with mode: 0644]
queue-6.14/iio-backend-make-sure-to-null-terminate-stack-buffer.patch [new file with mode: 0644]
queue-6.14/iio-core-rework-claim-and-release-of-direct-mode-to-.patch [new file with mode: 0644]
queue-6.14/iio-dac-adi-axi-dac-modify-stream-enable.patch [new file with mode: 0644]
queue-6.14/iio-gts-helper-export-iio_gts_get_total_gain.patch [new file with mode: 0644]
queue-6.14/iio-light-add-check-for-array-bounds-in-veml6075_rea.patch [new file with mode: 0644]
queue-6.14/iio-light-veml6030-extend-regmap-to-support-regfield.patch [new file with mode: 0644]
queue-6.14/iio-light-veml6030-fix-scale-to-conform-to-abi.patch [new file with mode: 0644]
queue-6.14/io_uring-check-for-iowq-alloc_workqueue-failure.patch [new file with mode: 0644]
queue-6.14/io_uring-fix-retry-handling-off-iowq.patch [new file with mode: 0644]
queue-6.14/io_uring-io-wq-cache-work-flags-in-variable.patch [new file with mode: 0644]
queue-6.14/io_uring-io-wq-do-not-use-bogus-hash-value.patch [new file with mode: 0644]
queue-6.14/io_uring-io-wq-eliminate-redundant-io_work_get_acct-.patch [new file with mode: 0644]
queue-6.14/io_uring-net-improve-recv-bundles.patch [new file with mode: 0644]
queue-6.14/io_uring-net-only-import-send_zc-buffer-once.patch [new file with mode: 0644]
queue-6.14/io_uring-use-lockless_cq-flag-in-io_req_complete_pos.patch [new file with mode: 0644]
queue-6.14/iommu-amd-fix-header-file.patch [new file with mode: 0644]
queue-6.14/iommu-handle-race-with-default-domain-setup.patch [new file with mode: 0644]
queue-6.14/iommu-io-pgtable-dart-only-set-subpage-protection-di.patch [new file with mode: 0644]
queue-6.14/iommu-vt-d-fix-system-hang-on-reboot-f.patch [new file with mode: 0644]
queue-6.14/ipv6-do-not-consider-link-down-nexthops-in-path-sele.patch [new file with mode: 0644]
queue-6.14/ipv6-fix-omitted-netlink-attributes-when-using-rtext.patch [new file with mode: 0644]
queue-6.14/ipv6-start-path-selection-from-the-first-nexthop.patch [new file with mode: 0644]
queue-6.14/isofs-fix-kmsan-uninit-value-bug-in-do_isofs_readdir.patch [new file with mode: 0644]
queue-6.14/ixgbe-fix-media-type-detection-for-e610-device.patch [new file with mode: 0644]
queue-6.14/jbd2-add-a-missing-data-flush-during-file-and-fs-syn.patch [new file with mode: 0644]
queue-6.14/jbd2-fix-off-by-one-while-erasing-journal.patch [new file with mode: 0644]
queue-6.14/jfs-add-check-read-only-before-truncation-in-jfs_tru.patch [new file with mode: 0644]
queue-6.14/jfs-add-check-read-only-before-txbeginanon-call.patch [new file with mode: 0644]
queue-6.14/jfs-reject-on-disk-inodes-of-an-unsupported-type.patch [new file with mode: 0644]
queue-6.14/kernel-events-uprobes-handle-device-exclusive-entrie.patch [new file with mode: 0644]
queue-6.14/kexec-initialize-elf-lowest-address-to-ulong_max.patch [new file with mode: 0644]
queue-6.14/ksmbd-fix-multichannel-connection-failure.patch [new file with mode: 0644]
queue-6.14/ksmbd-fix-r_count-dec-increment-mismatch.patch [new file with mode: 0644]
queue-6.14/ksmbd-use-aead_request_free-to-match-aead_request_al.patch [new file with mode: 0644]
queue-6.14/kunit-stackinit-use-fill-byte-different-from-clang-i.patch [new file with mode: 0644]
queue-6.14/leds-fix-led_off-brightness-race.patch [new file with mode: 0644]
queue-6.14/leds-st1202-check-for-error-code-from-devm_mutex_ini.patch [new file with mode: 0644]
queue-6.14/lib-842-improve-error-handling-in-sw842_compress.patch [new file with mode: 0644]
queue-6.14/libbpf-add-namespace-for-errstr-making-it-libbpf_err.patch [new file with mode: 0644]
queue-6.14/libbpf-fix-accessing-btf.ext-core_relo-header.patch [new file with mode: 0644]
queue-6.14/libbpf-fix-hypothetical-stt_section-extern-null-dere.patch [new file with mode: 0644]
queue-6.14/lockdep-don-t-disable-interrupts-on-rt-in-disable_ir.patch [new file with mode: 0644]
queue-6.14/lockdep-mm-fix-might_fault-lockdep-check-of-current-.patch [new file with mode: 0644]
queue-6.14/loongarch-fix-device-node-refcount-leak-in-fdt_cpu_c.patch [new file with mode: 0644]
queue-6.14/loongarch-fix-help-text-of-cmdline_extend-in-kconfig.patch [new file with mode: 0644]
queue-6.14/loongarch-rework-the-arch_kgdb_breakpoint-implementa.patch [new file with mode: 0644]
queue-6.14/m68k-sun3-fix-debug_mmu_emu-build.patch [new file with mode: 0644]
queue-6.14/m68k-sun3-use-str_read_write-helper-in-mmu_emu_handl.patch [new file with mode: 0644]
queue-6.14/md-ensure-resync-is-prioritized-over-recovery.patch [new file with mode: 0644]
queue-6.14/md-fix-mddev-uaf-while-iterating-all_mddevs-list.patch [new file with mode: 0644]
queue-6.14/md-md-bitmap-fix-wrong-bitmap_limit-for-clustermd-wh.patch [new file with mode: 0644]
queue-6.14/md-raid1-fix-memory-leak-in-raid1_run-if-no-active-r.patch [new file with mode: 0644]
queue-6.14/md-raid1-raid10-don-t-ignore-io-flags.patch [new file with mode: 0644]
queue-6.14/md-raid10-wait-barrier-before-returning-discard-requ.patch [new file with mode: 0644]
queue-6.14/mdacon-rework-dependency-list.patch [new file with mode: 0644]
queue-6.14/media-platform-allgro-dvt-unregister-v4l2_device-on-.patch [new file with mode: 0644]
queue-6.14/media-verisilicon-hevc-initialize-start_bit-field.patch [new file with mode: 0644]
queue-6.14/memory-mtk-smi-add-ostd-setting-for-mt8192.patch [new file with mode: 0644]
queue-6.14/mfd-sm501-switch-to-bit-to-mitigate-integer-overflow.patch [new file with mode: 0644]
queue-6.14/misc-pci_endpoint_test-fix-pci_endpoint_test_bars_re.patch [new file with mode: 0644]
queue-6.14/misc-pci_endpoint_test-handle-bar-sizes-larger-than-.patch [new file with mode: 0644]
queue-6.14/mlxsw-spectrum_acl_bloom_filter-workaround-for-some-.patch [new file with mode: 0644]
queue-6.14/net-airoha-fix-ets-priomap-validation.patch [new file with mode: 0644]
queue-6.14/net-airoha-fix-lan4-support-in-airoha_qdma_get_gdm_p.patch [new file with mode: 0644]
queue-6.14/net-airoha-fix-qid-report-in-airoha_tc_get_htb_get_l.patch [new file with mode: 0644]
queue-6.14/net-decrease-cached-dst-counters-in-dst_release.patch [new file with mode: 0644]
queue-6.14/net-dsa-microchip-fix-dcb-apptrust-configuration-on-.patch [new file with mode: 0644]
queue-6.14/net-dsa-mv88e6xxx-enable-.port_set_policy-for-6320-f.patch [new file with mode: 0644]
queue-6.14/net-dsa-mv88e6xxx-enable-pvt-for-6321-switch.patch [new file with mode: 0644]
queue-6.14/net-dsa-mv88e6xxx-enable-stu-methods-for-6320-family.patch [new file with mode: 0644]
queue-6.14/net-dsa-mv88e6xxx-fix-atu_move_port_mask-for-6341-fa.patch [new file with mode: 0644]
queue-6.14/net-dsa-mv88e6xxx-fix-vtu-methods-for-6320-family.patch [new file with mode: 0644]
queue-6.14/net-dsa-mv88e6xxx-propperly-shutdown-ppu-re-enable-t.patch [new file with mode: 0644]
queue-6.14/net-dsa-sja1105-fix-displaced-ethtool-statistics-cou.patch [new file with mode: 0644]
queue-6.14/net-dsa-sja1105-fix-kasan-out-of-bounds-warning-in-s.patch [new file with mode: 0644]
queue-6.14/net-dsa-sja1105-reject-other-rx-filters-than-hwtstam.patch [new file with mode: 0644]
queue-6.14/net-fix-geneve_opt-length-integer-overflow.patch [new file with mode: 0644]
queue-6.14/net-fix-null-pointer-dereference-in-l3mdev_l3_rcv.patch [new file with mode: 0644]
queue-6.14/net-fix-the-devmem-sock-opts-and-msgs-for-parisc.patch [new file with mode: 0644]
queue-6.14/net-ibmveth-make-veth_pool_store-stop-hanging.patch [new file with mode: 0644]
queue-6.14/net-lan743x-reject-unsupported-external-timestamp-re.patch [new file with mode: 0644]
queue-6.14/net-libwx-fix-tx-descriptor-content-for-some-tunnel-.patch [new file with mode: 0644]
queue-6.14/net-libwx-fix-tx-l4-checksum.patch [new file with mode: 0644]
queue-6.14/net-mlx5-lag-reload-representors-on-lag-creation-fai.patch [new file with mode: 0644]
queue-6.14/net-mlx5-start-health-poll-after-enable-hca.patch [new file with mode: 0644]
queue-6.14/net-mlx5e-fix-ethtool-n-flow-type-ip4-to-rss-context.patch [new file with mode: 0644]
queue-6.14/net-mlx5e-shampo-make-reserved-size-independent-of-p.patch [new file with mode: 0644]
queue-6.14/net-mvpp2-prevent-parser-tcam-memory-corruption.patch [new file with mode: 0644]
queue-6.14/net-phy-broadcom-correct-bcm5221-phy-model-detection.patch [new file with mode: 0644]
queue-6.14/net-remove-rtnl-dance-for-siocbraddif-and-siocbrdeli.patch [new file with mode: 0644]
queue-6.14/net_sched-skbprio-remove-overly-strict-queue-asserti.patch [new file with mode: 0644]
queue-6.14/netfilter-nf_tables-don-t-unregister-hook-when-table.patch [new file with mode: 0644]
queue-6.14/netfilter-nf_tables-only-use-nf_skip_indirect_calls-.patch [new file with mode: 0644]
queue-6.14/netfilter-nfnetlink_queue-initialize-ctx-to-avoid-me.patch [new file with mode: 0644]
queue-6.14/netfilter-nft_set_hash-gc-reaps-elements-with-connco.patch [new file with mode: 0644]
queue-6.14/netfilter-nft_tunnel-fix-geneve_opt-type-confusion-a.patch [new file with mode: 0644]
queue-6.14/netlabel-fix-null-pointer-exception-caused-by-calips.patch [new file with mode: 0644]
queue-6.14/netlink-specs-rt_route-pull-the-ifa-prefix-out-of-th.patch [new file with mode: 0644]
queue-6.14/nfs-add-missing-release-on-error-in-nfs_lock_and_joi.patch [new file with mode: 0644]
queue-6.14/nfs-fix-open_owner_id_maxsz-and-related-fields.patch [new file with mode: 0644]
queue-6.14/nfs-shut-down-the-nfs_client-only-after-all-the-supe.patch [new file with mode: 0644]
queue-6.14/nfsd-fix-callback-decoder-status-codes.patch [new file with mode: 0644]
queue-6.14/nfsv4-avoid-unnecessary-scans-of-filesystems-for-del.patch [new file with mode: 0644]
queue-6.14/nfsv4-avoid-unnecessary-scans-of-filesystems-for-exp.patch [new file with mode: 0644]
queue-6.14/nfsv4-avoid-unnecessary-scans-of-filesystems-for-ret.patch [new file with mode: 0644]
queue-6.14/nfsv4-don-t-trigger-uneccessary-scans-for-return-on-.patch [new file with mode: 0644]
queue-6.14/ntb-intel-fix-using-link-status-db-s.patch [new file with mode: 0644]
queue-6.14/ntb_hw_switchtec-fix-shift-out-of-bounds-in-switchte.patch [new file with mode: 0644]
queue-6.14/null_blk-do-partial-io-for-bad-blocks.patch [new file with mode: 0644]
queue-6.14/null_blk-generate-null_blk-configfs-features-string.patch [new file with mode: 0644]
queue-6.14/null_blk-introduce-badblocks_once-parameter.patch [new file with mode: 0644]
queue-6.14/null_blk-replace-null_process_cmd-call-in-null_zone_.patch [new file with mode: 0644]
queue-6.14/nvme-ioctl-don-t-warn-on-vectorized-uring_cmd-with-f.patch [new file with mode: 0644]
queue-6.14/nvme-pci-skip-nvme_write_sq_db-on-empty-rqlist.patch [new file with mode: 0644]
queue-6.14/nvmet-pci-epf-always-configure-bar0-as-64-bit.patch [new file with mode: 0644]
queue-6.14/objtool-fix-detection-of-consecutive-jump-tables-on-.patch [new file with mode: 0644]
queue-6.14/objtool-fix-segfault-in-ignore_unreachable_insn.patch [new file with mode: 0644]
queue-6.14/objtool-fix-verbose-disassembly-if-cross_compile-isn.patch [new file with mode: 0644]
queue-6.14/objtool-handle-different-entry-size-of-rodata.patch [new file with mode: 0644]
queue-6.14/objtool-handle-pc-relative-relocation-type.patch [new file with mode: 0644]
queue-6.14/objtool-handle-various-symbol-types-of-rodata.patch [new file with mode: 0644]
queue-6.14/objtool-loongarch-add-unwind-hints-in-prepare_framet.patch [new file with mode: 0644]
queue-6.14/objtool-media-dib8000-prevent-divide-by-zero-in-dib8.patch [new file with mode: 0644]
queue-6.14/objtool-nvmet-fix-out-of-bounds-stack-access-in-nvme.patch [new file with mode: 0644]
queue-6.14/objtool-spi-amd-fix-out-of-bounds-stack-access-in-am.patch [new file with mode: 0644]
queue-6.14/ocfs2-validate-l_tree_depth-to-avoid-out-of-bounds-a.patch [new file with mode: 0644]
queue-6.14/octeontx2-af-fix-mbox-intr-handler-when-num-vfs-64.patch [new file with mode: 0644]
queue-6.14/octeontx2-af-free-nix_af_int_vec_gen-irq.patch [new file with mode: 0644]
queue-6.14/of-property-increase-nr_fwnode_reference_args.patch [new file with mode: 0644]
queue-6.14/pci-acs-fix-pci-config_acs-parameter.patch [new file with mode: 0644]
queue-6.14/pci-allow-relaxed-bridge-window-tail-sizing-for-opti.patch [new file with mode: 0644]
queue-6.14/pci-aspm-fix-link-state-exit-during-switch-upstream-.patch [new file with mode: 0644]
queue-6.14/pci-avoid-reset-when-disabled-via-sysfs.patch [new file with mode: 0644]
queue-6.14/pci-brcmstb-fix-error-path-after-a-call-to-regulator.patch [new file with mode: 0644]
queue-6.14/pci-brcmstb-fix-potential-premature-regulator-disabl.patch [new file with mode: 0644]
queue-6.14/pci-brcmstb-set-generation-limit-before-pcie-link-up.patch [new file with mode: 0644]
queue-6.14/pci-brcmstb-use-internal-register-to-change-link-cap.patch [new file with mode: 0644]
queue-6.14/pci-bwctrl-fix-pcie_bwctrl_select_speed-return-type.patch [new file with mode: 0644]
queue-6.14/pci-cadence-ep-fix-the-driver-to-send-msg-tlp-for-in.patch [new file with mode: 0644]
queue-6.14/pci-dwc-ep-return-enomem-for-allocation-failures.patch [new file with mode: 0644]
queue-6.14/pci-endpoint-pci-epf-test-handle-endianness-properly.patch [new file with mode: 0644]
queue-6.14/pci-fix-bar-resizing-when-vf-bars-are-assigned.patch [new file with mode: 0644]
queue-6.14/pci-fix-null-dereference-in-sr-iov-vf-creation-error.patch [new file with mode: 0644]
queue-6.14/pci-histb-fix-an-error-handling-path-in-histb_pcie_p.patch [new file with mode: 0644]
queue-6.14/pci-mediatek-gen3-configure-pbus_csr-registers-for-e.patch [new file with mode: 0644]
queue-6.14/pci-pciehp-don-t-enable-hpie-when-resuming-in-poll-m.patch [new file with mode: 0644]
queue-6.14/pci-portdrv-only-disable-pciehp-interrupts-early-whe.patch [new file with mode: 0644]
queue-6.14/pci-remove-add_align-overwrite-unrelated-to-size0.patch [new file with mode: 0644]
queue-6.14/pci-remove-stray-put_device-in-pci_register_host_bri.patch [new file with mode: 0644]
queue-6.14/pci-simplify-size1-assignment-logic.patch [new file with mode: 0644]
queue-6.14/pci-use-downstream-bridges-for-distributing-resource.patch [new file with mode: 0644]
queue-6.14/pci-xilinx-cpm-fix-irq-domain-leak-in-error-path-of-.patch [new file with mode: 0644]
queue-6.14/perf-always-feature-test-reallocarray.patch [new file with mode: 0644]
queue-6.14/perf-arm-spe-fix-load-store-operation-checking.patch [new file with mode: 0644]
queue-6.14/perf-bench-fix-perf-bench-syscall-loop-count.patch [new file with mode: 0644]
queue-6.14/perf-bpf-filter-fix-a-parsing-error-with-comma.patch [new file with mode: 0644]
queue-6.14/perf-build-fix-in-tree-build-due-to-symbolic-link.patch [new file with mode: 0644]
queue-6.14/perf-debug-avoid-stack-overflow-in-recursive-error-m.patch [new file with mode: 0644]
queue-6.14/perf-dso-fix-dso__is_kallsyms-check.patch [new file with mode: 0644]
queue-6.14/perf-evlist-add-success-path-to-evlist__create_syswi.patch [new file with mode: 0644]
queue-6.14/perf-evsel-tp_format-accessing-improvements.patch [new file with mode: 0644]
queue-6.14/perf-intel-tpebs-fix-incorrect-usage-of-zfree.patch [new file with mode: 0644]
queue-6.14/perf-machine-fixup-kernel-maps-ends-after-adding-ext.patch [new file with mode: 0644]
queue-6.14/perf-pmu-don-t-double-count-common-sysfs-and-json-ev.patch [new file with mode: 0644]
queue-6.14/perf-pmu-dynamically-allocate-tool-pmu.patch [new file with mode: 0644]
queue-6.14/perf-pmu-handle-memory-failure-in-tool_pmu__new.patch [new file with mode: 0644]
queue-6.14/perf-pmus-restructure-pmu_read_sysfs-to-scan-fewer-p.patch [new file with mode: 0644]
queue-6.14/perf-python-check-if-there-is-space-to-copy-all-the-.patch [new file with mode: 0644]
queue-6.14/perf-python-decrement-the-refcount-of-just-created-e.patch [new file with mode: 0644]
queue-6.14/perf-python-don-t-keep-a-raw_data-pointer-to-consume.patch [new file with mode: 0644]
queue-6.14/perf-python-fixup-description-of-sample.id-event-mem.patch [new file with mode: 0644]
queue-6.14/perf-report-add-parallelism-sort-key.patch [new file with mode: 0644]
queue-6.14/perf-report-fix-input-reload-switch-with-symbol-sort.patch [new file with mode: 0644]
queue-6.14/perf-report-switch-data-file-correctly-in-tui.patch [new file with mode: 0644]
queue-6.14/perf-ring_buffer-allow-the-epollrdnorm-flag-for-poll.patch [new file with mode: 0644]
queue-6.14/perf-save-pmu-specific-data-in-task_struct.patch [new file with mode: 0644]
queue-6.14/perf-stat-don-t-merge-counters-purely-on-name.patch [new file with mode: 0644]
queue-6.14/perf-stat-fix-find_stat-for-mixed-legacy-non-legacy-.patch [new file with mode: 0644]
queue-6.14/perf-supply-task-information-to-sched_task.patch [new file with mode: 0644]
queue-6.14/perf-test-add-timeout-to-datasym-workload.patch [new file with mode: 0644]
queue-6.14/perf-test-fix-hwmon-pmu-test-endianess-issue.patch [new file with mode: 0644]
queue-6.14/perf-test-stat_all_pmu.sh-correctly-check-perf-stat-.patch [new file with mode: 0644]
queue-6.14/perf-tests-fix-data-symbol-test-with-lto-builds.patch [new file with mode: 0644]
queue-6.14/perf-tests-fix-tool-pmu-test-segfault.patch [new file with mode: 0644]
queue-6.14/perf-tools-add-skip-check-in-tool_pmu__event_to_str.patch [new file with mode: 0644]
queue-6.14/perf-tools-annotate-asm_pure_loop.s.patch [new file with mode: 0644]
queue-6.14/perf-tools-fix-is_compat_mode-build-break-in-ppc64.patch [new file with mode: 0644]
queue-6.14/perf-units-fix-insufficient-array-space.patch [new file with mode: 0644]
queue-6.14/perf-vendor-events-arm64-ampereonex-fix-frontend_bou.patch [new file with mode: 0644]
queue-6.14/perf-x86-lbr-fix-shorter-lbrs-call-stacks-for-the-sy.patch [new file with mode: 0644]
queue-6.14/perf-x86-topdown-fix-topdown-leader-sampling-test-er.patch [new file with mode: 0644]
queue-6.14/phy-phy-rockchip-samsung-hdptx-don-t-use-dt-aliases-.patch [new file with mode: 0644]
queue-6.14/pinctrl-bcm2835-don-t-einval-on-alternate-funcs-from.patch [new file with mode: 0644]
queue-6.14/pinctrl-intel-fix-wrong-bypass-assignment-in-intel_p.patch [new file with mode: 0644]
queue-6.14/pinctrl-npcm8xx-fix-incorrect-struct-npcm8xx_pincfg-.patch [new file with mode: 0644]
queue-6.14/pinctrl-nuvoton-npcm8xx-fix-error-handling-in-npcm8x.patch [new file with mode: 0644]
queue-6.14/pinctrl-renesas-rza2-fix-missing-of_node_put-call.patch [new file with mode: 0644]
queue-6.14/pinctrl-renesas-rzg2l-fix-missing-of_node_put-call.patch [new file with mode: 0644]
queue-6.14/pinctrl-renesas-rzg2l-suppress-binding-attributes.patch [new file with mode: 0644]
queue-6.14/pinctrl-renesas-rzv2m-fix-missing-of_node_put-call.patch [new file with mode: 0644]
queue-6.14/pinctrl-tegra-set-sfio-mode-to-mux-register.patch [new file with mode: 0644]
queue-6.14/platform-x86-dell-ddv-fix-temperature-calculation.patch [new file with mode: 0644]
queue-6.14/platform-x86-dell-uart-backlight-make-dell_uart_bl_s.patch [new file with mode: 0644]
queue-6.14/platform-x86-lenovo-yoga-tab2-pro-1380-fastcharger-m.patch [new file with mode: 0644]
queue-6.14/pm-sleep-adjust-check-before-setting-power.must_resu.patch [new file with mode: 0644]
queue-6.14/pm-sleep-fix-handling-devices-with-direct_complete-s.patch [new file with mode: 0644]
queue-6.14/power-supply-bq27xxx_battery-do-not-update-cached-fl.patch [new file with mode: 0644]
queue-6.14/power-supply-max77693-fix-wrong-conversion-of-charge.patch [new file with mode: 0644]
queue-6.14/powerpc-kexec-fix-physical-address-calculation-in-cl.patch [new file with mode: 0644]
queue-6.14/powerpc-perf-fix-ref-counting-on-the-pmu-vpa_pmu.patch [new file with mode: 0644]
queue-6.14/ptp-ocp-reject-unsupported-periodic-output-flags.patch [new file with mode: 0644]
queue-6.14/rcu-tasks-always-inline-rcu_irq_work_resched.patch [new file with mode: 0644]
queue-6.14/rdma-core-don-t-expose-hw_counters-outside-of-init-n.patch [new file with mode: 0644]
queue-6.14/rdma-core-fix-use-after-free-when-rename-device-name.patch [new file with mode: 0644]
queue-6.14/rdma-erdma-prevent-use-after-free-in-erdma_accept_ne.patch [new file with mode: 0644]
queue-6.14/rdma-mana_ib-ensure-variable-err-is-initialized.patch [new file with mode: 0644]
queue-6.14/rdma-mlx5-fix-calculation-of-total-invalidated-pages.patch [new file with mode: 0644]
queue-6.14/rdma-mlx5-fix-mlx5_poll_one-cur_qp-update-flow.patch [new file with mode: 0644]
queue-6.14/rdma-mlx5-fix-mr-cache-initialization-error-flow.patch [new file with mode: 0644]
queue-6.14/rdma-mlx5-fix-page_size-variable-overflow.patch [new file with mode: 0644]
queue-6.14/reboot-reboot-not-shutdown-on-hw_protection_reboot-t.patch [new file with mode: 0644]
queue-6.14/reboot-replace-__hw_protection_shutdown-bool-action-.patch [new file with mode: 0644]
queue-6.14/regulator-pca9450-fix-enable-register-for-ldo5.patch [new file with mode: 0644]
queue-6.14/remoteproc-core-clear-table_sz-when-rproc_shutdown.patch [new file with mode: 0644]
queue-6.14/remoteproc-qcom-pas-add-minidump_id-to-sc7280-wpss.patch [new file with mode: 0644]
queue-6.14/remoteproc-qcom_q6v5_mss-handle-platforms-with-one-p.patch [new file with mode: 0644]
queue-6.14/remoteproc-qcom_q6v5_pas-make-single-pd-handling-mor.patch [new file with mode: 0644]
queue-6.14/remoteproc-qcom_q6v5_pas-use-resource-with-cx-pd-for.patch [new file with mode: 0644]
queue-6.14/renesas-reject-ptp_strict_flags-as-unsupported.patch [new file with mode: 0644]
queue-6.14/ring-buffer-fix-bytes_dropped-calculation-issue.patch [new file with mode: 0644]
queue-6.14/risc-v-errata-use-medany-for-relocatable-builds.patch [new file with mode: 0644]
queue-6.14/risc-v-kvm-disable-the-kernel-perf-counter-during-co.patch [new file with mode: 0644]
queue-6.14/risc-v-kvm-teardown-riscv-specific-bits-after-kvm_ex.patch [new file with mode: 0644]
queue-6.14/riscv-annotate-unaligned-access-init-functions.patch [new file with mode: 0644]
queue-6.14/riscv-change-check_unaligned_access_speed_all_cpus-t.patch [new file with mode: 0644]
queue-6.14/riscv-fgraph-fix-stack-layout-to-match-__arch_ftrace.patch [new file with mode: 0644]
queue-6.14/riscv-fgraph-select-have_function_graph_tracer-depen.patch [new file with mode: 0644]
queue-6.14/riscv-fix-check_unaligned_access_all_cpus.patch [new file with mode: 0644]
queue-6.14/riscv-fix-hugetlb-retrieval-of-number-of-ptes-in-cas.patch [new file with mode: 0644]
queue-6.14/riscv-fix-missing-__free_pages-in-check_vector_unali.patch [new file with mode: 0644]
queue-6.14/riscv-fix-riscv_online_cpu_vec.patch [new file with mode: 0644]
queue-6.14/riscv-fix-set-up-of-cpu-hotplug-callbacks.patch [new file with mode: 0644]
queue-6.14/riscv-fix-set-up-of-vector-cpu-hotplug-callback.patch [new file with mode: 0644]
queue-6.14/riscv-fix-the-__riscv_copy_vec_words_unaligned-imple.patch [new file with mode: 0644]
queue-6.14/riscv-ftrace-add-parentheses-in-macro-definitions-of.patch [new file with mode: 0644]
queue-6.14/riscv-kexec_file-handle-r_riscv_64-in-purgatory-relo.patch [new file with mode: 0644]
queue-6.14/riscv-purgatory-4b-align-purgatory_start.patch [new file with mode: 0644]
queue-6.14/rndis_host-flag-rndis-modems-as-wwan-devices.patch [new file with mode: 0644]
queue-6.14/rseq-update-kernel-fields-in-lockstep-with-config_de.patch [new file with mode: 0644]
queue-6.14/rtc-renesas-rtca3-disable-interrupts-only-if-the-rtc.patch [new file with mode: 0644]
queue-6.14/rtnetlink-allocate-vfinfo-size-for-vf-guids-when-sup.patch [new file with mode: 0644]
queue-6.14/rtnetlink-use-register_pernet_subsys-in-rtnl_net_deb.patch [new file with mode: 0644]
queue-6.14/rust-fix-signature-of-rust_fmt_argument.patch [new file with mode: 0644]
queue-6.14/rust-pci-fix-unrestricted-mut-pci-device.patch [new file with mode: 0644]
queue-6.14/rust-pci-use-to_result-in-enable_device_mem.patch [new file with mode: 0644]
queue-6.14/rust-platform-fix-unrestricted-mut-platform-device.patch [new file with mode: 0644]
queue-6.14/rwonce-fix-crash-by-removing-read_once-for-unaligned.patch [new file with mode: 0644]
queue-6.14/rwonce-handle-kcsan-like-kasan-in-read_word_at_a_tim.patch [new file with mode: 0644]
queue-6.14/s390-entry-fix-setting-_cif_mcck_guest-with-lowcore-.patch [new file with mode: 0644]
queue-6.14/s390-remove-ioremap_wt-and-pgprot_writethrough.patch [new file with mode: 0644]
queue-6.14/samples-bpf-fix-broken-vmlinux-path-for-vmlinux_btf.patch [new file with mode: 0644]
queue-6.14/sched-cancel-the-slice-protection-of-the-idle-entity.patch [new file with mode: 0644]
queue-6.14/sched-deadline-generalize-unique-visiting-of-root-do.patch [new file with mode: 0644]
queue-6.14/sched-deadline-ignore-special-tasks-when-rebuilding-.patch [new file with mode: 0644]
queue-6.14/sched-deadline-rebuild-root-domain-accounting-after-.patch [new file with mode: 0644]
queue-6.14/sched-eevdf-force-propagating-min_slice-of-cfs_rq-wh.patch [new file with mode: 0644]
queue-6.14/sched-smt-always-inline-sched_smt_active.patch [new file with mode: 0644]
queue-6.14/sched-topology-wrappers-for-sched_domains_mutex.patch [new file with mode: 0644]
queue-6.14/scripts-gdb-linux-symbols.py-address-changes-to-modu.patch [new file with mode: 0644]
queue-6.14/scsi-hisi_sas-fixed-failure-to-issue-vendor-specific.patch [new file with mode: 0644]
queue-6.14/scsi-mpi3mr-fix-locking-in-an-error-path.patch [new file with mode: 0644]
queue-6.14/scsi-mpt3sas-fix-a-locking-bug-in-an-error-path.patch [new file with mode: 0644]
queue-6.14/scsi-mpt3sas-reduce-log-level-of-ignore_delay_remove.patch [new file with mode: 0644]
queue-6.14/scsi-target-tcm_loop-fix-wrong-abort-tag.patch [new file with mode: 0644]
queue-6.14/sctp-add-mutual-exclusion-in-proc_sctp_do_udp_port.patch [new file with mode: 0644]
queue-6.14/seccomp-fix-the-__secure_computing-stub-for-have_arc.patch [new file with mode: 0644]
queue-6.14/selftests-bpf-fix-freplace_link-segfault-in-tailcall.patch [new file with mode: 0644]
queue-6.14/selftests-bpf-fix-runqslower-cross-endian-build.patch [new file with mode: 0644]
queue-6.14/selftests-bpf-fix-string-read-in-strncmp-benchmark.patch [new file with mode: 0644]
queue-6.14/selftests-bpf-select-numa_no_node-to-create-map.patch [new file with mode: 0644]
queue-6.14/selftests-mm-cow-fix-the-incorrect-error-handling.patch [new file with mode: 0644]
queue-6.14/selftests-pcie_bwctrl-add-set_pcie_speed.sh-to-test_.patch [new file with mode: 0644]
queue-6.14/selinux-chain-up-tool-resolving-errors-in-install_po.patch [new file with mode: 0644]
queue-6.14/series [new file with mode: 0644]
queue-6.14/sfc-fix-null-dereferences-in-ef100_process_design_pa.patch [new file with mode: 0644]
queue-6.14/sfc-rip-out-mdio-support.patch [new file with mode: 0644]
queue-6.14/smack-dont-compile-ipv6-code-unless-ipv6-is-configur.patch [new file with mode: 0644]
queue-6.14/smack-ipv4-ipv6-tcp-dccp-sctp-fix-incorrect-child-so.patch [new file with mode: 0644]
queue-6.14/smb-client-fix-netns-refcount-imbalance-causing-leak.patch [new file with mode: 0644]
queue-6.14/soc-mediatek-mt8167-mmsys-fix-missing-regval-in-all-.patch [new file with mode: 0644]
queue-6.14/soc-mediatek-mt8365-mmsys-fix-routing-table-masks-an.patch [new file with mode: 0644]
queue-6.14/soc-mediatek-mtk-mmsys-fix-mt8188-vdo1-dpi1-output-s.patch [new file with mode: 0644]
queue-6.14/soundwire-slave-fix-an-of-node-reference-leak-in-sou.patch [new file with mode: 0644]
queue-6.14/soundwire-take-in-count-the-bandwidth-of-a-prepared-.patch [new file with mode: 0644]
queue-6.14/spi-bcm2835-do-not-call-gpiod_put-on-invalid-descrip.patch [new file with mode: 0644]
queue-6.14/spi-bcm2835-restore-native-cs-probing-when-pinctrl-b.patch [new file with mode: 0644]
queue-6.14/spi-cadence-fix-out-of-bounds-array-access-in-cdns_m.patch [new file with mode: 0644]
queue-6.14/spufs-fix-a-leak-in-spufs_create_context.patch [new file with mode: 0644]
queue-6.14/spufs-fix-a-leak-on-spufs_new_file-failure.patch [new file with mode: 0644]
queue-6.14/spufs-fix-gang-directory-lifetimes.patch [new file with mode: 0644]
queue-6.14/staging-gpib-add-missing-interface-entry-point.patch [new file with mode: 0644]
queue-6.14/staging-gpib-fix-cb7210-pcmcia-oops.patch [new file with mode: 0644]
queue-6.14/staging-gpib-fix-pr_err-format-warning.patch [new file with mode: 0644]
queue-6.14/staging-rtl8723bs-select-config_crypto_lib_aes.patch [new file with mode: 0644]
queue-6.14/staging-vchiq_arm-fix-possible-npr-of-keep-alive-thr.patch [new file with mode: 0644]
queue-6.14/staging-vchiq_arm-register-debugfs-after-cdev.patch [new file with mode: 0644]
queue-6.14/staging-vchiq_arm-stop-kthreads-if-vchiq-cdev-regist.patch [new file with mode: 0644]
queue-6.14/thermal-core-remove-duplicate-struct-declaration.patch [new file with mode: 0644]
queue-6.14/thermal-int340x-add-null-check-for-adev.patch [new file with mode: 0644]
queue-6.14/timekeeping-fix-possible-inconsistencies-in-_coarse-.patch [new file with mode: 0644]
queue-6.14/tools-rv-keep-user-ldflags-in-build.patch [new file with mode: 0644]
queue-6.14/tools-x86-fix-linux-unaligned.h-include-path-in-lib-.patch [new file with mode: 0644]
queue-6.14/tracing-fix-declare_trace_condition.patch [new file with mode: 0644]
queue-6.14/tty-n_tty-use-uint-for-space-returned-by-tty_write_r.patch [new file with mode: 0644]
queue-6.14/tunnels-accept-packet_host-in-skb_tunnel_check_pmtu.patch [new file with mode: 0644]
queue-6.14/ublk-make-sure-ubq-canceling-is-set-when-queue-is-fr.patch [new file with mode: 0644]
queue-6.14/ucsi_ccg-don-t-show-failed-to-get-fw-build-informati.patch [new file with mode: 0644]
queue-6.14/udp-fix-memory-accounting-leak.patch [new file with mode: 0644]
queue-6.14/udp-fix-multiple-wraparounds-of-sk-sk_rmem_alloc.patch [new file with mode: 0644]
queue-6.14/um-hostfs-avoid-issues-on-inode-number-reuse-by-host.patch [new file with mode: 0644]
queue-6.14/um-pass-the-correct-rust-target-and-options-with-gcc.patch [new file with mode: 0644]
queue-6.14/um-remove-copy_from_kernel_nofault_allowed.patch [new file with mode: 0644]
queue-6.14/usb-typec-thunderbolt-fix-loops-that-iterate-typec_p.patch [new file with mode: 0644]
queue-6.14/usb-typec-thunderbolt-remove-is_err-check-for-plug.patch [new file with mode: 0644]
queue-6.14/usb-xhci-correct-debug-message-page-size-calculation.patch [new file with mode: 0644]
queue-6.14/vhost-scsi-fix-handling-of-multiple-calls-to-vhost_s.patch [new file with mode: 0644]
queue-6.14/virtchnl-make-proto-and-filter-action-count-unsigned.patch [new file with mode: 0644]
queue-6.14/virtio_net-fix-endian-with-virtio_net_ctrl_rss.patch [new file with mode: 0644]
queue-6.14/vmxnet3-unregister-xdp-rxq-info-in-the-reset-path.patch [new file with mode: 0644]
queue-6.14/vsock-avoid-timeout-during-connect-if-the-socket-is-.patch [new file with mode: 0644]
queue-6.14/w1-fix-null-pointer-dereference-in-probe.patch [new file with mode: 0644]
queue-6.14/watch_queue-fix-pipe-accounting-mismatch.patch [new file with mode: 0644]
queue-6.14/watchdog-hardlockup-perf-fix-perf_event-memory-leak.patch [new file with mode: 0644]
queue-6.14/wifi-ath11k-add-srng-lock-for-ath11k_hal_srng_-in-mo.patch [new file with mode: 0644]
queue-6.14/wifi-ath11k-clear-affinity-hint-before-calling-ath11.patch [new file with mode: 0644]
queue-6.14/wifi-ath11k-fix-rcu-stall-while-reaping-monitor-dest.patch [new file with mode: 0644]
queue-6.14/wifi-ath11k-fix-wrong-overriding-for-vht-beamformee-.patch [new file with mode: 0644]
queue-6.14/wifi-ath11k-update-channel-list-in-reg-notifier-inst.patch [new file with mode: 0644]
queue-6.14/wifi-ath12k-add-missing-htt_metadata-flag-in-ath12k_.patch [new file with mode: 0644]
queue-6.14/wifi-ath12k-clear-affinity-hint-before-calling-ath12.patch [new file with mode: 0644]
queue-6.14/wifi-ath12k-encode-max-tx-power-in-scan-channel-list.patch [new file with mode: 0644]
queue-6.14/wifi-ath12k-fix-locking-in-qmi-firmware-ready-error-.patch [new file with mode: 0644]
queue-6.14/wifi-ath12k-fix-pdev-lookup-in-wbm-error-processing.patch [new file with mode: 0644]
queue-6.14/wifi-ath12k-fix-skb_ext_desc-leak-in-ath12k_dp_tx-er.patch [new file with mode: 0644]
queue-6.14/wifi-ath12k-use-link-specific-bss_conf-as-well-in-at.patch [new file with mode: 0644]
queue-6.14/wifi-ath9k-do-not-submit-zero-bytes-to-the-entropy-p.patch [new file with mode: 0644]
queue-6.14/wifi-cfg80211-init-wiphy_work-before-allocating-rfki.patch [new file with mode: 0644]
queue-6.14/wifi-mac80211-check-basic-rates-validity-in-sta_link.patch [new file with mode: 0644]
queue-6.14/wifi-mac80211-remove-ssid-from-ml-reconf.patch [new file with mode: 0644]
queue-6.14/wifi-mt76-mt7915-fix-possible-integer-overflows-in-m.patch [new file with mode: 0644]
queue-6.14/wifi-mwifiex-fix-premature-release-of-rf-calibration.patch [new file with mode: 0644]
queue-6.14/wifi-mwifiex-fix-rf-calibration-data-download-from-f.patch [new file with mode: 0644]
queue-6.14/wifi-nl80211-store-chandef-on-the-correct-link-when-.patch [new file with mode: 0644]
queue-6.14/wifi-rtw89-correct-immediate-cfg_len-calculation-for.patch [new file with mode: 0644]
queue-6.14/wifi-rtw89-fw-correct-debug-message-format-in-rtw89_.patch [new file with mode: 0644]
queue-6.14/wifi-rtw89-pci-correct-isr-rdu-bit-for-8922ae.patch [new file with mode: 0644]
queue-6.14/wifi-rtw89-rtw8852b-t-fix-tssi-debug-timestamps.patch [new file with mode: 0644]
queue-6.14/writeback-fix-calculations-in-trace_balance_dirty_pa.patch [new file with mode: 0644]
queue-6.14/writeback-let-trace_balance_dirty_pages-take-struct-.patch [new file with mode: 0644]
queue-6.14/x86-dumpstack-fix-inaccurate-unwinding-from-exceptio.patch [new file with mode: 0644]
queue-6.14/x86-entry-add-__init-to-ia32_emulation_override_cmdl.patch [new file with mode: 0644]
queue-6.14/x86-entry-fix-orc-unwinder-for-push_regs-with-save_r.patch [new file with mode: 0644]
queue-6.14/x86-fpu-avoid-copying-dynamic-fp-state-from-init_tas.patch [new file with mode: 0644]
queue-6.14/x86-fpu-fix-guest-fpu-state-buffer-allocation-size.patch [new file with mode: 0644]
queue-6.14/x86-fpu-xstate-fix-inconsistencies-in-guest-fpu-xfea.patch [new file with mode: 0644]
queue-6.14/x86-mm-pat-cpa-test-fix-length-for-cpa_array-test.patch [new file with mode: 0644]
queue-6.14/x86-mm-pat-fix-vm_pat-handling-when-fork-fails-in-co.patch [new file with mode: 0644]
queue-6.14/x86-platform-only-allow-config_eisa-for-32-bit.patch [new file with mode: 0644]
queue-6.14/x86-resctrl-fix-allocation-of-cleanest-closid-on-pla.patch [new file with mode: 0644]
queue-6.14/x86-sev-add-missing-rip_rel_ref-invocations-during-s.patch [new file with mode: 0644]
queue-6.14/x86-split_lock-fix-the-delayed-detection-logic.patch [new file with mode: 0644]
queue-6.14/x86-traps-make-exc_double_fault-consistently-noretur.patch [new file with mode: 0644]
queue-6.14/x86-uaccess-improve-performance-by-aligning-writes-t.patch [new file with mode: 0644]
queue-6.14/x86-vdso-fix-latent-bug-in-vclock_pages-calculation.patch [new file with mode: 0644]
queue-6.14/xfrm-delay-initialization-of-offload-path-till-its-a.patch [new file with mode: 0644]
queue-6.14/xsk-add-launch-time-hardware-offload-support-to-xdp-.patch [new file with mode: 0644]
queue-6.14/xsk-fix-__xsk_generic_xmit-error-code-when-cq-is-ful.patch [new file with mode: 0644]

diff --git a/queue-6.14/accel-amdxdna-return-error-when-setting-clock-failed.patch b/queue-6.14/accel-amdxdna-return-error-when-setting-clock-failed.patch
new file mode 100644 (file)
index 0000000..a7a7eb3
--- /dev/null
@@ -0,0 +1,49 @@
+From 11dae4a8048b692831d9cddaca339e1d3333f655 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jan 2025 11:48:11 -0800
+Subject: accel/amdxdna: Return error when setting clock failed for npu1
+
+From: Lizhi Hou <lizhi.hou@amd.com>
+
+[ Upstream commit 0c2768bf818904db705ff18674f771c3c4d8bbca ]
+
+Due to miss returning error when setting clock, the smatch static
+checker reports warning:
+  drivers/accel/amdxdna/aie2_smu.c:68 npu1_set_dpm()
+  error: uninitialized symbol 'freq'.
+
+Fixes: f4d7b8a6bc8c ("accel/amdxdna: Enhance power management settings")
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Closes: https://lore.kernel.org/dri-devel/202267d0-882e-4593-b58d-be9274592f9b@stanley.mountain/
+Signed-off-by: Lizhi Hou <lizhi.hou@amd.com>
+Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250109194811.499505-1-lizhi.hou@amd.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/accel/amdxdna/aie2_smu.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/accel/amdxdna/aie2_smu.c b/drivers/accel/amdxdna/aie2_smu.c
+index 73388443c6767..d303701b0ded4 100644
+--- a/drivers/accel/amdxdna/aie2_smu.c
++++ b/drivers/accel/amdxdna/aie2_smu.c
+@@ -64,6 +64,7 @@ int npu1_set_dpm(struct amdxdna_dev_hdl *ndev, u32 dpm_level)
+       if (ret) {
+               XDNA_ERR(ndev->xdna, "Set npu clock to %d failed, ret %d\n",
+                        ndev->priv->dpm_clk_tbl[dpm_level].npuclk, ret);
++              return ret;
+       }
+       ndev->npuclk_freq = freq;
+@@ -72,6 +73,7 @@ int npu1_set_dpm(struct amdxdna_dev_hdl *ndev, u32 dpm_level)
+       if (ret) {
+               XDNA_ERR(ndev->xdna, "Set h clock to %d failed, ret %d\n",
+                        ndev->priv->dpm_clk_tbl[dpm_level].hclk, ret);
++              return ret;
+       }
+       ndev->hclk_freq = freq;
+       ndev->dpm_level = dpm_level;
+-- 
+2.39.5
+
diff --git a/queue-6.14/acpi-processor-idle-return-an-error-if-both-p_lvl-2-.patch b/queue-6.14/acpi-processor-idle-return-an-error-if-both-p_lvl-2-.patch
new file mode 100644 (file)
index 0000000..05ab6bf
--- /dev/null
@@ -0,0 +1,58 @@
+From f49d9ebdbdd552f36876d955fe71ea058ac545f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Mar 2025 15:30:39 +0100
+Subject: ACPI: processor: idle: Return an error if both P_LVL{2,3} idle states
+ are invalid
+
+From: Giovanni Gherdovich <ggherdovich@suse.cz>
+
+[ Upstream commit 9e9b893404d43894d69a18dd2fc8fcf1c36abb7e ]
+
+Prior to commit 496121c02127 ("ACPI: processor: idle: Allow probing on
+platforms with one ACPI C-state"), the acpi_idle driver wouldn't load on
+systems without a valid C-State at least as deep as C2.
+
+The behavior was desirable for guests on hypervisors such as VMWare
+ESXi, which by default don't have the _CST ACPI method, and set the C2
+and C3 latencies to 101 and 1001 microseconds respectively via the FADT,
+to signify they're unsupported.
+
+Since the above change though, these virtualized deployments end up
+loading acpi_idle, and thus entering the default C1 C-State set by
+acpi_processor_get_power_info_default(); this is undesirable for a
+system that's communicating to the OS it doesn't want C-States (missing
+_CST, and invalid C2/C3 in FADT).
+
+Make acpi_processor_get_power_info_fadt() return -ENODEV in that case,
+so that acpi_processor_get_cstate_info() exits early and doesn't set
+pr->flags.power = 1.
+
+Fixes: 496121c02127 ("ACPI: processor: idle: Allow probing on platforms with one ACPI C-state")
+Signed-off-by: Giovanni Gherdovich <ggherdovich@suse.cz>
+Reviewed-by: Zhang Rui <rui.zhang@intel.com>
+Link: https://patch.msgid.link/20250328143040.9348-1-ggherdovich@suse.cz
+[ rjw: Changelog edits ]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/processor_idle.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
+index 698897b29de24..2df1296ff44d5 100644
+--- a/drivers/acpi/processor_idle.c
++++ b/drivers/acpi/processor_idle.c
+@@ -268,6 +268,10 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
+                        ACPI_CX_DESC_LEN, "ACPI P_LVL3 IOPORT 0x%x",
+                        pr->power.states[ACPI_STATE_C3].address);
++      if (!pr->power.states[ACPI_STATE_C2].address &&
++          !pr->power.states[ACPI_STATE_C3].address)
++              return -ENODEV;
++
+       return 0;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/alsa-hda-realtek-always-honor-no_shutup_pins.patch b/queue-6.14/alsa-hda-realtek-always-honor-no_shutup_pins.patch
new file mode 100644 (file)
index 0000000..4216d5d
--- /dev/null
@@ -0,0 +1,55 @@
+From dd05e91aeb29d9d7a2d0bc8152c475cdd01c71ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 15 Mar 2025 15:30:19 +0100
+Subject: ALSA: hda/realtek: Always honor no_shutup_pins
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit 5a0c72c1da3cbc0cd4940a95d1be2830104c6edf ]
+
+The workaround for Dell machines to skip the pin-shutup for mic pins
+introduced alc_headset_mic_no_shutup() that is replaced from the
+generic snd_hda_shutup_pins() for certain codecs.  The problem is that
+the call is done unconditionally even if spec->no_shutup_pins is set.
+This seems causing problems on other platforms like Lenovo.
+
+This patch corrects the behavior and the driver honors always
+spec->no_shutup_pins flag and skips alc_headset_mic_no_shutup() if
+it's set.
+
+Fixes: dad3197da7a3 ("ALSA: hda/realtek - Fixup headphone noise via runtime suspend")
+Reported-and-tested-by: Oleg Gorobets <oleg.goro@gmail.com>
+Link: https://patch.msgid.link/20250315143020.27184-1-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 78aab243c8b65..abe269fb8ce00 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -586,6 +586,9 @@ static void alc_shutup_pins(struct hda_codec *codec)
+ {
+       struct alc_spec *spec = codec->spec;
++      if (spec->no_shutup_pins)
++              return;
++
+       switch (codec->core.vendor_id) {
+       case 0x10ec0236:
+       case 0x10ec0256:
+@@ -601,8 +604,7 @@ static void alc_shutup_pins(struct hda_codec *codec)
+               alc_headset_mic_no_shutup(codec);
+               break;
+       default:
+-              if (!spec->no_shutup_pins)
+-                      snd_hda_shutup_pins(codec);
++              snd_hda_shutup_pins(codec);
+               break;
+       }
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/alsa-hda-realtek-fix-built-in-mic-assignment-on-asus.patch b/queue-6.14/alsa-hda-realtek-fix-built-in-mic-assignment-on-asus.patch
new file mode 100644 (file)
index 0000000..87fe4bc
--- /dev/null
@@ -0,0 +1,44 @@
+From a0af232affebf5ff4b739263de676b591453a0b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Mar 2025 16:32:32 +0100
+Subject: ALSA: hda/realtek: Fix built-in mic assignment on ASUS VivoBook
+ X515UA
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit 829ee558f3527fd602c6e2e9f270959d1de09fe0 ]
+
+ASUS VivoBook X515UA with PCI SSID 1043:106f had a default quirk
+pickup via pin table that applies ALC256_FIXUP_ASUS_MIC, but this adds
+a bogus built-in mic pin 0x13 enabled.  This was no big problem
+because the pin 0x13 was assigned as the secondary mic, but the recent
+fix made the entries sorted, hence this bogus pin appeared now as the
+primary input and it broke.
+
+For fixing the bug, put the right quirk entry for this device pointing
+to ALC256_FIXUP_ASUS_MIC_NO_PRESENCE.
+
+Fixes: 3b4309546b48 ("ALSA: hda: Fix headset detection failure due to unstable sort")
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=219897
+Link: https://patch.msgid.link/20250324153233.21195-1-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index abe269fb8ce00..d70c72bda90a5 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -10702,6 +10702,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
+       SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
+       SND_PCI_QUIRK(0x1043, 0x1054, "ASUS G614FH/FM/FP", ALC287_FIXUP_CS35L41_I2C_2),
+       SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
++      SND_PCI_QUIRK(0x1043, 0x106f, "ASUS VivoBook X515UA", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1043, 0x1074, "ASUS G614PH/PM/PP", ALC287_FIXUP_CS35L41_I2C_2),
+       SND_PCI_QUIRK(0x1043, 0x10a1, "ASUS UX391UA", ALC294_FIXUP_ASUS_SPK),
+       SND_PCI_QUIRK(0x1043, 0x10a4, "ASUS TP3407SA", ALC287_FIXUP_TAS2781_I2C),
+-- 
+2.39.5
+
diff --git a/queue-6.14/alsa-hda-realtek-fix-built-in-mic-breakage-on-asus-v.patch b/queue-6.14/alsa-hda-realtek-fix-built-in-mic-breakage-on-asus-v.patch
new file mode 100644 (file)
index 0000000..9a2c5b5
--- /dev/null
@@ -0,0 +1,38 @@
+From d95843570aad4438f3bd2dc8ad4d9973322ed9fd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Mar 2025 16:22:01 +0100
+Subject: ALSA: hda/realtek: Fix built-in mic breakage on ASUS VivoBook X515JA
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit 84c3c08f5a6c2e2209428b76156bcaf349c3a62d ]
+
+ASUS VivoBook X515JA with PCI SSID 1043:14f2 also hits the same issue
+as other VivoBook model about the mic pin assignment, and the same
+workaround is required to apply ALC256_FIXUP_ASUS_MIC_NO_PRESENCE
+quirk.
+
+Fixes: 3b4309546b48 ("ALSA: hda: Fix headset detection failure due to unstable sort")
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=219902
+Link: https://patch.msgid.link/20250326152205.26733-1-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index d70c72bda90a5..9df400f7a144e 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -10736,6 +10736,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
+       SND_PCI_QUIRK(0x1043, 0x1493, "ASUS GV601VV/VU/VJ/VQ/VI", ALC285_FIXUP_ASUS_HEADSET_MIC),
+       SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G614JY/JZ/JG", ALC245_FIXUP_CS35L41_SPI_2),
+       SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS G513PI/PU/PV", ALC287_FIXUP_CS35L41_I2C_2),
++      SND_PCI_QUIRK(0x1043, 0x14f2, "ASUS VivoBook X515JA", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1043, 0x1503, "ASUS G733PY/PZ/PZV/PYV", ALC287_FIXUP_CS35L41_I2C_2),
+       SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
+       SND_PCI_QUIRK(0x1043, 0x1533, "ASUS GV302XA/XJ/XQ/XU/XV/XI", ALC287_FIXUP_CS35L41_I2C_2),
+-- 
+2.39.5
+
diff --git a/queue-6.14/alsa-hda-realtek-fix-built-in-mic-on-another-asus-vi.patch b/queue-6.14/alsa-hda-realtek-fix-built-in-mic-on-another-asus-vi.patch
new file mode 100644 (file)
index 0000000..89d1b50
--- /dev/null
@@ -0,0 +1,38 @@
+From 5b82285d4ebbced65f6c3ad6639c79c184b8e223 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Apr 2025 09:42:07 +0200
+Subject: ALSA: hda/realtek: Fix built-in mic on another ASUS VivoBook model
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit 8983dc1b66c0e1928a263b8af0bb06f6cb9229c4 ]
+
+There is another VivoBook model which built-in mic got broken recently
+by the fix of the pin sort.  Apply the correct quirk
+ALC256_FIXUP_ASUS_MIC_NO_PRESENCE to this model for addressing the
+regression, too.
+
+Fixes: 3b4309546b48 ("ALSA: hda: Fix headset detection failure due to unstable sort")
+Closes: https://lore.kernel.org/Z95s5T6OXFPjRnKf@eldamar.lan
+Link: https://patch.msgid.link/20250402074208.7347-1-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 9df400f7a144e..65ece19a6dd7d 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -10776,6 +10776,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
+       SND_PCI_QUIRK(0x1043, 0x1c43, "ASUS UX8406MA", ALC245_FIXUP_CS35L41_SPI_2),
+       SND_PCI_QUIRK(0x1043, 0x1c62, "ASUS GU603", ALC289_FIXUP_ASUS_GA401),
+       SND_PCI_QUIRK(0x1043, 0x1c63, "ASUS GU605M", ALC285_FIXUP_ASUS_GU605_SPI_SPEAKER2_TO_DAC1),
++      SND_PCI_QUIRK(0x1043, 0x1c80, "ASUS VivoBook TP401", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1043, 0x1c92, "ASUS ROG Strix G15", ALC285_FIXUP_ASUS_G533Z_PINS),
+       SND_PCI_QUIRK(0x1043, 0x1c9f, "ASUS G614JU/JV/JI", ALC285_FIXUP_ASUS_HEADSET_MIC),
+       SND_PCI_QUIRK(0x1043, 0x1caf, "ASUS G634JY/JZ/JI/JG", ALC285_FIXUP_ASUS_SPI_REAR_SPEAKERS),
+-- 
+2.39.5
+
diff --git a/queue-6.14/alsa-timer-don-t-take-register_mutex-with-copy_from-.patch b/queue-6.14/alsa-timer-don-t-take-register_mutex-with-copy_from-.patch
new file mode 100644 (file)
index 0000000..206a45f
--- /dev/null
@@ -0,0 +1,263 @@
+From 0cc401e774be66a104416d1cca411739caf0d8b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Mar 2025 18:26:52 +0100
+Subject: ALSA: timer: Don't take register_mutex with copy_from/to_user()
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit 3424c8f53bc63c87712a7fc22dc13d0cc85fb0d6 ]
+
+The infamous mmap_lock taken in copy_from/to_user() can be often
+problematic when it's called inside another mutex, as they might lead
+to deadlocks.
+
+In the case of ALSA timer code, the bad pattern is with
+guard(mutex)(&register_mutex) that covers copy_from/to_user() -- which
+was mistakenly introduced at converting to guard(), and it had been
+carefully worked around in the past.
+
+This patch fixes those pieces simply by moving copy_from/to_user() out
+of the register mutex lock again.
+
+Fixes: 3923de04c817 ("ALSA: pcm: oss: Use guard() for setup")
+Reported-by: syzbot+2b96f44164236dda0f3b@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/67dd86c8.050a0220.25ae54.0059.GAE@google.com
+Link: https://patch.msgid.link/20250321172653.14310-1-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/core/timer.c | 147 ++++++++++++++++++++++++---------------------
+ 1 file changed, 77 insertions(+), 70 deletions(-)
+
+diff --git a/sound/core/timer.c b/sound/core/timer.c
+index fbada79380f9e..d774b9b71ce23 100644
+--- a/sound/core/timer.c
++++ b/sound/core/timer.c
+@@ -1515,91 +1515,97 @@ static void snd_timer_user_copy_id(struct snd_timer_id *id, struct snd_timer *ti
+       id->subdevice = timer->tmr_subdevice;
+ }
+-static int snd_timer_user_next_device(struct snd_timer_id __user *_tid)
++static void get_next_device(struct snd_timer_id *id)
+ {
+-      struct snd_timer_id id;
+       struct snd_timer *timer;
+       struct list_head *p;
+-      if (copy_from_user(&id, _tid, sizeof(id)))
+-              return -EFAULT;
+-      guard(mutex)(&register_mutex);
+-      if (id.dev_class < 0) {         /* first item */
++      if (id->dev_class < 0) {                /* first item */
+               if (list_empty(&snd_timer_list))
+-                      snd_timer_user_zero_id(&id);
++                      snd_timer_user_zero_id(id);
+               else {
+                       timer = list_entry(snd_timer_list.next,
+                                          struct snd_timer, device_list);
+-                      snd_timer_user_copy_id(&id, timer);
++                      snd_timer_user_copy_id(id, timer);
+               }
+       } else {
+-              switch (id.dev_class) {
++              switch (id->dev_class) {
+               case SNDRV_TIMER_CLASS_GLOBAL:
+-                      id.device = id.device < 0 ? 0 : id.device + 1;
++                      id->device = id->device < 0 ? 0 : id->device + 1;
+                       list_for_each(p, &snd_timer_list) {
+                               timer = list_entry(p, struct snd_timer, device_list);
+                               if (timer->tmr_class > SNDRV_TIMER_CLASS_GLOBAL) {
+-                                      snd_timer_user_copy_id(&id, timer);
++                                      snd_timer_user_copy_id(id, timer);
+                                       break;
+                               }
+-                              if (timer->tmr_device >= id.device) {
+-                                      snd_timer_user_copy_id(&id, timer);
++                              if (timer->tmr_device >= id->device) {
++                                      snd_timer_user_copy_id(id, timer);
+                                       break;
+                               }
+                       }
+                       if (p == &snd_timer_list)
+-                              snd_timer_user_zero_id(&id);
++                              snd_timer_user_zero_id(id);
+                       break;
+               case SNDRV_TIMER_CLASS_CARD:
+               case SNDRV_TIMER_CLASS_PCM:
+-                      if (id.card < 0) {
+-                              id.card = 0;
++                      if (id->card < 0) {
++                              id->card = 0;
+                       } else {
+-                              if (id.device < 0) {
+-                                      id.device = 0;
++                              if (id->device < 0) {
++                                      id->device = 0;
+                               } else {
+-                                      if (id.subdevice < 0)
+-                                              id.subdevice = 0;
+-                                      else if (id.subdevice < INT_MAX)
+-                                              id.subdevice++;
++                                      if (id->subdevice < 0)
++                                              id->subdevice = 0;
++                                      else if (id->subdevice < INT_MAX)
++                                              id->subdevice++;
+                               }
+                       }
+                       list_for_each(p, &snd_timer_list) {
+                               timer = list_entry(p, struct snd_timer, device_list);
+-                              if (timer->tmr_class > id.dev_class) {
+-                                      snd_timer_user_copy_id(&id, timer);
++                              if (timer->tmr_class > id->dev_class) {
++                                      snd_timer_user_copy_id(id, timer);
+                                       break;
+                               }
+-                              if (timer->tmr_class < id.dev_class)
++                              if (timer->tmr_class < id->dev_class)
+                                       continue;
+-                              if (timer->card->number > id.card) {
+-                                      snd_timer_user_copy_id(&id, timer);
++                              if (timer->card->number > id->card) {
++                                      snd_timer_user_copy_id(id, timer);
+                                       break;
+                               }
+-                              if (timer->card->number < id.card)
++                              if (timer->card->number < id->card)
+                                       continue;
+-                              if (timer->tmr_device > id.device) {
+-                                      snd_timer_user_copy_id(&id, timer);
++                              if (timer->tmr_device > id->device) {
++                                      snd_timer_user_copy_id(id, timer);
+                                       break;
+                               }
+-                              if (timer->tmr_device < id.device)
++                              if (timer->tmr_device < id->device)
+                                       continue;
+-                              if (timer->tmr_subdevice > id.subdevice) {
+-                                      snd_timer_user_copy_id(&id, timer);
++                              if (timer->tmr_subdevice > id->subdevice) {
++                                      snd_timer_user_copy_id(id, timer);
+                                       break;
+                               }
+-                              if (timer->tmr_subdevice < id.subdevice)
++                              if (timer->tmr_subdevice < id->subdevice)
+                                       continue;
+-                              snd_timer_user_copy_id(&id, timer);
++                              snd_timer_user_copy_id(id, timer);
+                               break;
+                       }
+                       if (p == &snd_timer_list)
+-                              snd_timer_user_zero_id(&id);
++                              snd_timer_user_zero_id(id);
+                       break;
+               default:
+-                      snd_timer_user_zero_id(&id);
++                      snd_timer_user_zero_id(id);
+               }
+       }
++}
++
++static int snd_timer_user_next_device(struct snd_timer_id __user *_tid)
++{
++      struct snd_timer_id id;
++
++      if (copy_from_user(&id, _tid, sizeof(id)))
++              return -EFAULT;
++      scoped_guard(mutex, &register_mutex)
++              get_next_device(&id);
+       if (copy_to_user(_tid, &id, sizeof(*_tid)))
+               return -EFAULT;
+       return 0;
+@@ -1620,23 +1626,24 @@ static int snd_timer_user_ginfo(struct file *file,
+       tid = ginfo->tid;
+       memset(ginfo, 0, sizeof(*ginfo));
+       ginfo->tid = tid;
+-      guard(mutex)(&register_mutex);
+-      t = snd_timer_find(&tid);
+-      if (!t)
+-              return -ENODEV;
+-      ginfo->card = t->card ? t->card->number : -1;
+-      if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)
+-              ginfo->flags |= SNDRV_TIMER_FLG_SLAVE;
+-      strscpy(ginfo->id, t->id, sizeof(ginfo->id));
+-      strscpy(ginfo->name, t->name, sizeof(ginfo->name));
+-      scoped_guard(spinlock_irq, &t->lock)
+-              ginfo->resolution = snd_timer_hw_resolution(t);
+-      if (t->hw.resolution_min > 0) {
+-              ginfo->resolution_min = t->hw.resolution_min;
+-              ginfo->resolution_max = t->hw.resolution_max;
+-      }
+-      list_for_each(p, &t->open_list_head) {
+-              ginfo->clients++;
++      scoped_guard(mutex, &register_mutex) {
++              t = snd_timer_find(&tid);
++              if (!t)
++                      return -ENODEV;
++              ginfo->card = t->card ? t->card->number : -1;
++              if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)
++                      ginfo->flags |= SNDRV_TIMER_FLG_SLAVE;
++              strscpy(ginfo->id, t->id, sizeof(ginfo->id));
++              strscpy(ginfo->name, t->name, sizeof(ginfo->name));
++              scoped_guard(spinlock_irq, &t->lock)
++                      ginfo->resolution = snd_timer_hw_resolution(t);
++              if (t->hw.resolution_min > 0) {
++                      ginfo->resolution_min = t->hw.resolution_min;
++                      ginfo->resolution_max = t->hw.resolution_max;
++              }
++              list_for_each(p, &t->open_list_head) {
++                      ginfo->clients++;
++              }
+       }
+       if (copy_to_user(_ginfo, ginfo, sizeof(*ginfo)))
+               return -EFAULT;
+@@ -1674,31 +1681,31 @@ static int snd_timer_user_gstatus(struct file *file,
+       struct snd_timer_gstatus gstatus;
+       struct snd_timer_id tid;
+       struct snd_timer *t;
+-      int err = 0;
+       if (copy_from_user(&gstatus, _gstatus, sizeof(gstatus)))
+               return -EFAULT;
+       tid = gstatus.tid;
+       memset(&gstatus, 0, sizeof(gstatus));
+       gstatus.tid = tid;
+-      guard(mutex)(&register_mutex);
+-      t = snd_timer_find(&tid);
+-      if (t != NULL) {
+-              guard(spinlock_irq)(&t->lock);
+-              gstatus.resolution = snd_timer_hw_resolution(t);
+-              if (t->hw.precise_resolution) {
+-                      t->hw.precise_resolution(t, &gstatus.resolution_num,
+-                                               &gstatus.resolution_den);
++      scoped_guard(mutex, &register_mutex) {
++              t = snd_timer_find(&tid);
++              if (t != NULL) {
++                      guard(spinlock_irq)(&t->lock);
++                      gstatus.resolution = snd_timer_hw_resolution(t);
++                      if (t->hw.precise_resolution) {
++                              t->hw.precise_resolution(t, &gstatus.resolution_num,
++                                                       &gstatus.resolution_den);
++                      } else {
++                              gstatus.resolution_num = gstatus.resolution;
++                              gstatus.resolution_den = 1000000000uL;
++                      }
+               } else {
+-                      gstatus.resolution_num = gstatus.resolution;
+-                      gstatus.resolution_den = 1000000000uL;
++                      return -ENODEV;
+               }
+-      } else {
+-              err = -ENODEV;
+       }
+-      if (err >= 0 && copy_to_user(_gstatus, &gstatus, sizeof(gstatus)))
+-              err = -EFAULT;
+-      return err;
++      if (copy_to_user(_gstatus, &gstatus, sizeof(gstatus)))
++              return -EFAULT;
++      return 0;
+ }
+ static int snd_timer_user_tselect(struct file *file,
+-- 
+2.39.5
+
diff --git a/queue-6.14/alsa-usb-audio-separate-djm-a9-cap-lvl-options.patch b/queue-6.14/alsa-usb-audio-separate-djm-a9-cap-lvl-options.patch
new file mode 100644 (file)
index 0000000..575d93a
--- /dev/null
@@ -0,0 +1,63 @@
+From fe2ce89c33427871c92907d0267668441549d7b8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 16 Mar 2025 15:33:23 +0000
+Subject: ALSA: usb-audio: separate DJM-A9 cap lvl options
+
+From: Olivia Mackintosh <livvy@base.nu>
+
+[ Upstream commit 38e94cefbf45c1edc5b751ab90a3088f7c6fac1a ]
+
+Mixer quicks for the Pioneer DJM-A9 mixer was added in 5289d00 with
+additional capture level values added to the common DJM array of values.
+
+This breaks the existing DJM mixers however as alsa-utils relies on
+enumeration of the actual mixer options based on the value array which
+results in error when storing state.
+
+This commit just separates the A9 values into a separate array and
+references them in the corresponding mixer control.
+
+Fixes: 5289d0069639 ("ALSA: usb-audio: Add Pioneer DJ/AlphaTheta DJM-A9 Mixer")
+Signed-off-by: Olivia Mackintosh <livvy@base.nu>
+Link: https://patch.msgid.link/20250316153323.16381-1-livvy@base.nu
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/mixer_quirks.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
+index 3d36d22f8e9e6..62b28e9d83c7a 100644
+--- a/sound/usb/mixer_quirks.c
++++ b/sound/usb/mixer_quirks.c
+@@ -3688,8 +3688,7 @@ static const char *snd_djm_get_label(u8 device_idx, u16 wvalue, u16 windex)
+ // common DJM capture level option values
+ static const u16 snd_djm_opts_cap_level[] = {
+-      0x0000, 0x0100, 0x0200, 0x0300, 0x400, 0x500 };
+-
++      0x0000, 0x0100, 0x0200, 0x0300 };
+ // DJM-250MK2
+ static const u16 snd_djm_opts_250mk2_cap1[] = {
+@@ -3831,6 +3830,8 @@ static const struct snd_djm_ctl snd_djm_ctls_750mk2[] = {
+ // DJM-A9
++static const u16 snd_djm_opts_a9_cap_level[] = {
++      0x0000, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500 };
+ static const u16 snd_djm_opts_a9_cap1[] = {
+       0x0107, 0x0108, 0x0109, 0x010a, 0x010e,
+       0x111, 0x112, 0x113, 0x114, 0x0131, 0x132, 0x133, 0x134 };
+@@ -3844,7 +3845,7 @@ static const u16 snd_djm_opts_a9_cap5[] = {
+       0x0501, 0x0502, 0x0503, 0x0505, 0x0506, 0x0507, 0x0508, 0x0509, 0x050a, 0x050e };
+ static const struct snd_djm_ctl snd_djm_ctls_a9[] = {
+-      SND_DJM_CTL("Capture Level", cap_level, 0, SND_DJM_WINDEX_CAPLVL),
++      SND_DJM_CTL("Capture Level", a9_cap_level, 0, SND_DJM_WINDEX_CAPLVL),
+       SND_DJM_CTL("Master Input",  a9_cap1, 3, SND_DJM_WINDEX_CAP),
+       SND_DJM_CTL("Ch1 Input",     a9_cap2, 2, SND_DJM_WINDEX_CAP),
+       SND_DJM_CTL("Ch2 Input",     a9_cap3, 2, SND_DJM_WINDEX_CAP),
+-- 
+2.39.5
+
diff --git a/queue-6.14/arch-powerpc-drop-generic_ptdump-from-mpc885_ads_def.patch b/queue-6.14/arch-powerpc-drop-generic_ptdump-from-mpc885_ads_def.patch
new file mode 100644 (file)
index 0000000..0b2cf70
--- /dev/null
@@ -0,0 +1,52 @@
+From 32d7501b039ae52a082dfa2a60f150d308e1e1aa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Feb 2025 17:54:01 +0530
+Subject: arch/powerpc: drop GENERIC_PTDUMP from mpc885_ads_defconfig
+
+From: Anshuman Khandual <anshuman.khandual@arm.com>
+
+[ Upstream commit 2c5e6ac2db64ace51f66a9f3b3b3ab9553d748e8 ]
+
+GENERIC_PTDUMP gets selected on powerpc explicitly and hence can be
+dropped off from mpc885_ads_defconfig.  Replace with CONFIG_PTDUMP_DEBUGFS
+instead.
+
+Link: https://lkml.kernel.org/r/20250226122404.1927473-3-anshuman.khandual@arm.com
+Fixes: e084728393a5 ("powerpc/ptdump: Convert powerpc to GENERIC_PTDUMP")
+Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
+Suggested-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: Madhavan Srinivasan <maddy@linux.ibm.com>
+Cc: Michael Ellerman <mpe@ellerman.id.au>
+Cc: Nicholas Piggin <npiggin@gmail.com>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Heiko Carstens <hca@linux.ibm.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jonathan Corbet <corbet@lwn.net>
+Cc: Marc Zyngier <maz@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Palmer Dabbelt <palmer@dabbelt.com>
+Cc: Paul Walmsley <paul.walmsley@sifive.com>
+Cc: Steven Price <steven.price@arm.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Vasily Gorbik <gor@linux.ibm.com>
+Cc: Will Deacon <will@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/configs/mpc885_ads_defconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/powerpc/configs/mpc885_ads_defconfig b/arch/powerpc/configs/mpc885_ads_defconfig
+index 77306be62e9ee..129355f87f80f 100644
+--- a/arch/powerpc/configs/mpc885_ads_defconfig
++++ b/arch/powerpc/configs/mpc885_ads_defconfig
+@@ -78,4 +78,4 @@ CONFIG_DEBUG_VM_PGTABLE=y
+ CONFIG_DETECT_HUNG_TASK=y
+ CONFIG_BDI_SWITCH=y
+ CONFIG_PPC_EARLY_DEBUG=y
+-CONFIG_GENERIC_PTDUMP=y
++CONFIG_PTDUMP_DEBUGFS=y
+-- 
+2.39.5
+
diff --git a/queue-6.14/arcnet-add-null-check-in-com20020pci_probe.patch b/queue-6.14/arcnet-add-null-check-in-com20020pci_probe.patch
new file mode 100644 (file)
index 0000000..910a672
--- /dev/null
@@ -0,0 +1,67 @@
+From e8ebf4ac0f77b2f59a033cafc33db785481b32e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Apr 2025 21:50:36 +0800
+Subject: arcnet: Add NULL check in com20020pci_probe()
+
+From: Henry Martin <bsdhenrymartin@gmail.com>
+
+[ Upstream commit fda8c491db2a90ff3e6fbbae58e495b4ddddeca3 ]
+
+devm_kasprintf() returns NULL when memory allocation fails. Currently,
+com20020pci_probe() does not check for this case, which results in a
+NULL pointer dereference.
+
+Add NULL check after devm_kasprintf() to prevent this issue and ensure
+no resources are left allocated.
+
+Fixes: 6b17a597fc2f ("arcnet: restoring support for multiple Sohard Arcnet cards")
+Signed-off-by: Henry Martin <bsdhenrymartin@gmail.com>
+Link: https://patch.msgid.link/20250402135036.44697-1-bsdhenrymartin@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/arcnet/com20020-pci.c | 17 ++++++++++++++++-
+ 1 file changed, 16 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c
+index c5e571ec94c99..0472bcdff1307 100644
+--- a/drivers/net/arcnet/com20020-pci.c
++++ b/drivers/net/arcnet/com20020-pci.c
+@@ -251,18 +251,33 @@ static int com20020pci_probe(struct pci_dev *pdev,
+                       card->tx_led.default_trigger = devm_kasprintf(&pdev->dev,
+                                                       GFP_KERNEL, "arc%d-%d-tx",
+                                                       dev->dev_id, i);
++                      if (!card->tx_led.default_trigger) {
++                              ret = -ENOMEM;
++                              goto err_free_arcdev;
++                      }
+                       card->tx_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+                                                       "pci:green:tx:%d-%d",
+                                                       dev->dev_id, i);
+-
++                      if (!card->tx_led.name) {
++                              ret = -ENOMEM;
++                              goto err_free_arcdev;
++                      }
+                       card->tx_led.dev = &dev->dev;
+                       card->recon_led.brightness_set = led_recon_set;
+                       card->recon_led.default_trigger = devm_kasprintf(&pdev->dev,
+                                                       GFP_KERNEL, "arc%d-%d-recon",
+                                                       dev->dev_id, i);
++                      if (!card->recon_led.default_trigger) {
++                              ret = -ENOMEM;
++                              goto err_free_arcdev;
++                      }
+                       card->recon_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+                                                       "pci:red:recon:%d-%d",
+                                                       dev->dev_id, i);
++                      if (!card->recon_led.name) {
++                              ret = -ENOMEM;
++                              goto err_free_arcdev;
++                      }
+                       card->recon_led.dev = &dev->dev;
+                       ret = devm_led_classdev_register(&pdev->dev, &card->tx_led);
+-- 
+2.39.5
+
diff --git a/queue-6.14/arm-dts-imx6ul-tqma6ul1-change-include-order-to-disa.patch b/queue-6.14/arm-dts-imx6ul-tqma6ul1-change-include-order-to-disa.patch
new file mode 100644 (file)
index 0000000..f7927b6
--- /dev/null
@@ -0,0 +1,55 @@
+From 78f90e25c33b09c60326f5c5a03f16c93b1756cc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Feb 2025 15:44:35 +0100
+Subject: ARM: dts: imx6ul-tqma6ul1: Change include order to disable fec2 node
+
+From: Max Merchel <Max.Merchel@ew.tq-group.com>
+
+[ Upstream commit 22d8f69c8ddcd036d6e81589e95a058b86272bd1 ]
+
+TQMa6UL1 has only one FEC which needs to be disabled as one of the last
+steps.
+imx6ul-tqma6ul2.dtsi can't be included in imx6ul-tqma6ul1.dtsi as the
+defaults from imx6ul.dtsi will be applied again.
+
+Fixes: 7b8861d8e627 ("ARM: dts: imx6ul: add TQ-Systems MBa6ULx device trees")
+Signed-off-by: Max Merchel <Max.Merchel@ew.tq-group.com>
+Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/nxp/imx/imx6ul-tqma6ul1-mba6ulx.dts | 3 ++-
+ arch/arm/boot/dts/nxp/imx/imx6ul-tqma6ul1.dtsi        | 2 --
+ 2 files changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-tqma6ul1-mba6ulx.dts b/arch/arm/boot/dts/nxp/imx/imx6ul-tqma6ul1-mba6ulx.dts
+index f2a5f17f312e5..2e7b96e7b791d 100644
+--- a/arch/arm/boot/dts/nxp/imx/imx6ul-tqma6ul1-mba6ulx.dts
++++ b/arch/arm/boot/dts/nxp/imx/imx6ul-tqma6ul1-mba6ulx.dts
+@@ -6,8 +6,9 @@
+ /dts-v1/;
+-#include "imx6ul-tqma6ul1.dtsi"
++#include "imx6ul-tqma6ul2.dtsi"
+ #include "mba6ulx.dtsi"
++#include "imx6ul-tqma6ul1.dtsi"
+ / {
+       model = "TQ-Systems TQMa6UL1 SoM on MBa6ULx board";
+diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-tqma6ul1.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul-tqma6ul1.dtsi
+index 24192d012ef7e..79c8c5529135a 100644
+--- a/arch/arm/boot/dts/nxp/imx/imx6ul-tqma6ul1.dtsi
++++ b/arch/arm/boot/dts/nxp/imx/imx6ul-tqma6ul1.dtsi
+@@ -4,8 +4,6 @@
+  * Author: Markus Niebel <Markus.Niebel@tq-group.com>
+  */
+-#include "imx6ul-tqma6ul2.dtsi"
+-
+ / {
+       model = "TQ-Systems TQMa6UL1 SoM";
+       compatible = "tq,imx6ul-tqma6ul1", "fsl,imx6ul";
+-- 
+2.39.5
+
diff --git a/queue-6.14/arm-dts-omap4-panda-a4-add-missing-model-and-compati.patch b/queue-6.14/arm-dts-omap4-panda-a4-add-missing-model-and-compati.patch
new file mode 100644 (file)
index 0000000..3e1b9e3
--- /dev/null
@@ -0,0 +1,42 @@
+From e8459767e1e36b246044ebebbe8ec837815ca992 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jan 2025 11:49:01 -0600
+Subject: ARM: dts: omap4-panda-a4: Add missing model and compatible properties
+
+From: Tom Rini <trini@konsulko.com>
+
+[ Upstream commit ea07a4775df03852c353514b5b7646a17bd425be ]
+
+When moving the model and compatible properties out of the common
+Pandaboard files and in to the specific boards, the omap4-panda-a4
+file wasn't updated as well and so has lacked a model and compatible
+entry ever since.
+
+Fixes: a1a57abaaf82 ("ARM: dts: omap4-panda: Fix model and SoC family details")
+Signed-off-by: Tom Rini <trini@konsulko.com>
+Link: https://lore.kernel.org/r/20250123174901.1182176-2-trini@konsulko.com
+Signed-off-by: Kevin Hilman <khilman@baylibre.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/ti/omap/omap4-panda-a4.dts | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/arch/arm/boot/dts/ti/omap/omap4-panda-a4.dts b/arch/arm/boot/dts/ti/omap/omap4-panda-a4.dts
+index 8fd076e5d1b01..4b8bfd0188add 100644
+--- a/arch/arm/boot/dts/ti/omap/omap4-panda-a4.dts
++++ b/arch/arm/boot/dts/ti/omap/omap4-panda-a4.dts
+@@ -7,6 +7,11 @@
+ #include "omap443x.dtsi"
+ #include "omap4-panda-common.dtsi"
++/ {
++      model = "TI OMAP4 PandaBoard (A4)";
++      compatible = "ti,omap4-panda-a4", "ti,omap4-panda", "ti,omap4430", "ti,omap4";
++};
++
+ /* Pandaboard Rev A4+ have external pullups on SCL & SDA */
+ &dss_hdmi_pins {
+       pinctrl-single,pins = <
+-- 
+2.39.5
+
diff --git a/queue-6.14/arm64-dts-imx8mp-add-audio_axi_clk_root-to-audiomix-.patch b/queue-6.14/arm64-dts-imx8mp-add-audio_axi_clk_root-to-audiomix-.patch
new file mode 100644 (file)
index 0000000..efcaf89
--- /dev/null
@@ -0,0 +1,43 @@
+From 0db2ef6be00873d03827f8fad73cfa24a3ebf4c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Feb 2025 11:45:12 -0500
+Subject: arm64: dts: imx8mp: add AUDIO_AXI_CLK_ROOT to AUDIOMIX block
+
+From: Laurentiu Mihalcea <laurentiu.mihalcea@nxp.com>
+
+[ Upstream commit cfe47a3d3f7440cd1bdf2a169b325257eba01534 ]
+
+Needed because the DSP and OCRAM_A components from AUDIOMIX are clocked
+by AUDIO_AXI_CLK_ROOT instead of AUDIO_AHB_CLK_ROOT.
+
+Fixes: b86c3afabb4f ("arm64: dts: imx8mp: Add SAI, SDMA, AudioMIX")
+Signed-off-by: Laurentiu Mihalcea <laurentiu.mihalcea@nxp.com>
+Reviewed-by: Iuliana Prodan <iuliana.prodan@nxp.com>
+Reviewed-by: Peng Fan <peng.fan@nxp.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/freescale/imx8mp.dtsi | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+index e0d3b8cba221e..86c3055789ba7 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+@@ -1619,10 +1619,11 @@
+                                        <&clk IMX8MP_CLK_SAI3>,
+                                        <&clk IMX8MP_CLK_SAI5>,
+                                        <&clk IMX8MP_CLK_SAI6>,
+-                                       <&clk IMX8MP_CLK_SAI7>;
++                                       <&clk IMX8MP_CLK_SAI7>,
++                                       <&clk IMX8MP_CLK_AUDIO_AXI_ROOT>;
+                               clock-names = "ahb",
+                                             "sai1", "sai2", "sai3",
+-                                            "sai5", "sai6", "sai7";
++                                            "sai5", "sai6", "sai7", "axi";
+                               power-domains = <&pgc_audio>;
+                               assigned-clocks = <&clk IMX8MP_AUDIO_PLL1>,
+                                                 <&clk IMX8MP_AUDIO_PLL2>;
+-- 
+2.39.5
+
diff --git a/queue-6.14/arm64-dts-imx8mp-change-audio_axi_clk_root-freq.-to-.patch b/queue-6.14/arm64-dts-imx8mp-change-audio_axi_clk_root-freq.-to-.patch
new file mode 100644 (file)
index 0000000..6be70fe
--- /dev/null
@@ -0,0 +1,40 @@
+From 62f5e3a40c2d8b0c377de07721674f8bacb45060 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Feb 2025 11:45:13 -0500
+Subject: arm64: dts: imx8mp: change AUDIO_AXI_CLK_ROOT freq. to 800MHz
+
+From: Laurentiu Mihalcea <laurentiu.mihalcea@nxp.com>
+
+[ Upstream commit c54e2f908da30a6c66195a6d0aba6412c673ec2c ]
+
+AUDIO_AXI_CLK_ROOT can't run at currently requested 600MHz w/ its parent
+SYS_PLL1 configured at 800MHz. Configure it to run at 800MHz as some
+applications running on the DSP expect the core to run at this frequency
+anyways. This change also affects the AUDIOMIX NoC.
+
+Fixes: b739681b3f8b ("arm64: dts: imx8mp: Fix SDMA2/3 clocks")
+Signed-off-by: Laurentiu Mihalcea <laurentiu.mihalcea@nxp.com>
+Reviewed-by: Iuliana Prodan <iuliana.prodan@nxp.com>
+Reviewed-by: Peng Fan <peng.fan@nxp.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/freescale/imx8mp.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+index 86c3055789ba7..54147bce3b838 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+@@ -834,7 +834,7 @@
+                                               assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_800M>,
+                                                                        <&clk IMX8MP_SYS_PLL1_800M>;
+                                               assigned-clock-rates = <400000000>,
+-                                                                     <600000000>;
++                                                                     <800000000>;
+                                       };
+                                       pgc_gpu2d: power-domain@6 {
+-- 
+2.39.5
+
diff --git a/queue-6.14/arm64-dts-imx8mp-skov-correct-pmic-board-limits.patch b/queue-6.14/arm64-dts-imx8mp-skov-correct-pmic-board-limits.patch
new file mode 100644 (file)
index 0000000..4a74eed
--- /dev/null
@@ -0,0 +1,99 @@
+From 21ed7eae30ebf0d38c6a36adf098ecdaa3d49dad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jan 2025 17:06:36 +0100
+Subject: arm64: dts: imx8mp-skov: correct PMIC board limits
+
+From: Ahmad Fatoum <a.fatoum@pengutronix.de>
+
+[ Upstream commit d19a6f79961df1c29d8b2ac93b01b96788f209fa ]
+
+The PMIC voltage constraints in the device tree currently describe the
+permissible range of the PMIC. This is unnecessary as this information
+already exists in the driver and wrong as it doesn't account for
+board-specific constraints, e.g. a 2.1V on VDD_SOC would fry the SoC and
+a maximum voltage of 3.4V on the VDD_3V3 rail may be unexpected across
+the board.
+
+Fix this by adjusting constraints to reflect the board limits.
+
+Fixes: 6d382d51d979 ("arm64: dts: freescale: Add SKOV IMX8MP CPU revB board")
+Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../boot/dts/freescale/imx8mp-skov-reva.dtsi  | 24 +++++++++----------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
+index 59813ef8e2bb3..ae82166b5c266 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
+@@ -247,8 +247,8 @@
+                       reg_vdd_arm: BUCK2 {
+                               regulator-name = "VDD_ARM";
+-                              regulator-min-microvolt = <600000>;
+-                              regulator-max-microvolt = <2187500>;
++                              regulator-min-microvolt = <850000>;
++                              regulator-max-microvolt = <1000000>;
+                               vin-supply = <&reg_5v_p>;
+                               regulator-boot-on;
+                               regulator-always-on;
+@@ -259,8 +259,8 @@
+                       reg_vdd_3v3: BUCK4 {
+                               regulator-name = "VDD_3V3";
+-                              regulator-min-microvolt = <600000>;
+-                              regulator-max-microvolt = <3400000>;
++                              regulator-min-microvolt = <3300000>;
++                              regulator-max-microvolt = <3300000>;
+                               vin-supply = <&reg_5v_p>;
+                               regulator-boot-on;
+                               regulator-always-on;
+@@ -268,8 +268,8 @@
+                       reg_vdd_1v8: BUCK5 {
+                               regulator-name = "VDD_1V8";
+-                              regulator-min-microvolt = <600000>;
+-                              regulator-max-microvolt = <3400000>;
++                              regulator-min-microvolt = <1800000>;
++                              regulator-max-microvolt = <1800000>;
+                               vin-supply = <&reg_5v_p>;
+                               regulator-boot-on;
+                               regulator-always-on;
+@@ -277,8 +277,8 @@
+                       reg_nvcc_dram_1v1: BUCK6 {
+                               regulator-name = "NVCC_DRAM_1V1";
+-                              regulator-min-microvolt = <600000>;
+-                              regulator-max-microvolt = <3400000>;
++                              regulator-min-microvolt = <1100000>;
++                              regulator-max-microvolt = <1100000>;
+                               vin-supply = <&reg_5v_p>;
+                               regulator-boot-on;
+                               regulator-always-on;
+@@ -286,8 +286,8 @@
+                       reg_nvcc_snvs_1v8: LDO1 {
+                               regulator-name = "NVCC_SNVS_1V8";
+-                              regulator-min-microvolt = <1600000>;
+-                              regulator-max-microvolt = <3300000>;
++                              regulator-min-microvolt = <1800000>;
++                              regulator-max-microvolt = <1800000>;
+                               vin-supply = <&reg_5v_p>;
+                               regulator-boot-on;
+                               regulator-always-on;
+@@ -295,8 +295,8 @@
+                       reg_vdda_1v8: LDO3 {
+                               regulator-name = "VDDA_1V8";
+-                              regulator-min-microvolt = <800000>;
+-                              regulator-max-microvolt = <3300000>;
++                              regulator-min-microvolt = <1800000>;
++                              regulator-max-microvolt = <1800000>;
+                               vin-supply = <&reg_5v_p>;
+                               regulator-boot-on;
+                               regulator-always-on;
+-- 
+2.39.5
+
diff --git a/queue-6.14/arm64-dts-imx8mp-skov-operate-cpu-at-850-mv-by-defau.patch b/queue-6.14/arm64-dts-imx8mp-skov-operate-cpu-at-850-mv-by-defau.patch
new file mode 100644 (file)
index 0000000..9ad7823
--- /dev/null
@@ -0,0 +1,61 @@
+From 60d14b70e672353e35aed903f400d2e8a64a8b50 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jan 2025 17:06:37 +0100
+Subject: arm64: dts: imx8mp-skov: operate CPU at 850 mV by default
+
+From: Ahmad Fatoum <a.fatoum@pengutronix.de>
+
+[ Upstream commit 3d8ffe5702b24a0bd9d97446c0740110325f379b ]
+
+The Skov i.MX8MP boards are passively cooled and heatsink is specced for
+continuous operation at 1.2 GHz only. Short bouts of 1.6 GHz are ok,
+but these should be invoked intentionally, not as part of
+suspend/resume cycles.
+
+Therefore, configure RUN frequency as 850 mV and remove the higher
+voltage operating points from those permissible for suspend.
+
+Fixes: 6d382d51d979 ("arm64: dts: freescale: Add SKOV IMX8MP CPU revB board")
+Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../boot/dts/freescale/imx8mp-skov-reva.dtsi      | 15 ++++++++++++++-
+ 1 file changed, 14 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
+index ae82166b5c266..7ae686d37ddac 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-reva.dtsi
+@@ -163,6 +163,19 @@
+       };
+ };
++/*
++ * Board is passively cooled and heatsink is specced for continuous operation
++ * at 1.2 GHz only. Short bouts of 1.6 GHz are ok, but these should be done
++ * intentionally, not as part of suspend/resume cycles.
++ */
++&{/opp-table/opp-1600000000} {
++      /delete-property/ opp-suspend;
++};
++
++&{/opp-table/opp-1800000000} {
++      /delete-property/ opp-suspend;
++};
++
+ &A53_0 {
+       cpu-supply = <&reg_vdd_arm>;
+ };
+@@ -253,7 +266,7 @@
+                               regulator-boot-on;
+                               regulator-always-on;
+                               regulator-ramp-delay = <3125>;
+-                              nxp,dvs-run-voltage = <950000>;
++                              nxp,dvs-run-voltage = <850000>;
+                               nxp,dvs-standby-voltage = <850000>;
+                       };
+-- 
+2.39.5
+
diff --git a/queue-6.14/arm64-dts-mediatek-mt6359-fix-dtbs_check-error-for-a.patch b/queue-6.14/arm64-dts-mediatek-mt6359-fix-dtbs_check-error-for-a.patch
new file mode 100644 (file)
index 0000000..4cb872e
--- /dev/null
@@ -0,0 +1,42 @@
+From 8a8781c70a6c3b66e482d4f03c136573e7a76372 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 19:37:36 +0800
+Subject: arm64: dts: mediatek: mt6359: fix dtbs_check error for audio-codec
+
+From: Macpaul Lin <macpaul.lin@mediatek.com>
+
+[ Upstream commit 76b35f59bbe66d3eda8a98021bc01f9200131f09 ]
+
+This change fixes these dtbs_check errors for audio-codec:
+1. pmic: 'mt6359codec' does not match any of the regexes: 'pinctrl-[0-9]+'
+ - Replace device node name to generic 'audio-codec'
+2. pmic: regulators: 'compatible' is a required property
+ - Add 'mediatek,mt6359-codec' to compatible.
+
+Fixes: 3b7d143be4b7 ("arm64: dts: mt6359: add PMIC MT6359 related nodes")
+Signed-off-by: Macpaul Lin <macpaul.lin@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20250217113736.1867808-1-macpaul.lin@mediatek.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 | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt6359.dtsi b/arch/arm64/boot/dts/mediatek/mt6359.dtsi
+index 150ad84d5d2b3..7b10f9c59819a 100644
+--- a/arch/arm64/boot/dts/mediatek/mt6359.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt6359.dtsi
+@@ -15,7 +15,8 @@
+                       #io-channel-cells = <1>;
+               };
+-              mt6359codec: mt6359codec {
++              mt6359codec: audio-codec {
++                      compatible = "mediatek,mt6359-codec";
+               };
+               regulators {
+-- 
+2.39.5
+
diff --git a/queue-6.14/arm64-dts-mediatek-mt8173-elm-drop-pmic-s-address-ce.patch b/queue-6.14/arm64-dts-mediatek-mt8173-elm-drop-pmic-s-address-ce.patch
new file mode 100644 (file)
index 0000000..bec8866
--- /dev/null
@@ -0,0 +1,46 @@
+From 405223dd87f3a5e71f4c646273491b52c1151254 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jan 2025 16:34:21 +0800
+Subject: arm64: dts: mediatek: mt8173-elm: Drop pmic's #address-cells and
+ #size-cells
+
+From: Chen-Yu Tsai <wenst@chromium.org>
+
+[ Upstream commit aaa0b40e157c65aaa5e0ad903675f245333381bb ]
+
+The PMIC has child nodes for each of its functions. It is not an actual
+bus and no addressing is involved.
+
+Dropping the bogus properties fixes a DT validation error:
+
+    arch/arm64/boot/dts/mediatek/mt8173-elm.dtb: pmic: '#address-cells', '#size-cells' do not match any of the regexes: 'pinctrl-[0-9]+'
+            from schema $id: http://devicetree.org/schemas/mfd/mediatek,mt6397.yaml#
+
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202412212322.JTFpRD7X-lkp@intel.com/
+Fixes: 689b937bedde ("arm64: dts: mediatek: add mt8173 elm and hana board")
+Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20250108083424.2732375-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/mt8173-elm.dtsi | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi
+index b5d4b5baf4785..0d995b342d463 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi
+@@ -925,8 +925,6 @@
+ &pwrap {
+       pmic: pmic {
+               compatible = "mediatek,mt6397";
+-              #address-cells = <1>;
+-              #size-cells = <1>;
+               interrupts-extended = <&pio 11 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+-- 
+2.39.5
+
diff --git a/queue-6.14/arm64-dts-mediatek-mt8173-fix-some-node-names.patch b/queue-6.14/arm64-dts-mediatek-mt8173-fix-some-node-names.patch
new file mode 100644 (file)
index 0000000..0b4e435
--- /dev/null
@@ -0,0 +1,57 @@
+From a3a98687ae8b94d780818a89c5b6a49256ce6245 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jan 2025 16:34:23 +0800
+Subject: arm64: dts: mediatek: mt8173: Fix some node names
+
+From: Chen-Yu Tsai <wenst@chromium.org>
+
+[ Upstream commit be035e4a26edf8fdcbc4fe95d16c28deade13bb0 ]
+
+Some node names are incorrect, causing DT validations due to mismatches.
+
+Fixes: b3a372484157 ("arm64: dts: Add mediatek MT8173 SoC and evaluation board dts and Makefile")
+Fixes: f2ce70149568 ("arm64: dts: mt8173: Add clock controller device nodes")
+Cc: Eddie Huang <eddie.huang@mediatek.com>
+Cc: Sascha Hauer <s.hauer@pengutronix.de>
+Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20250108083424.2732375-3-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/mt8173.dtsi | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+index 3458be7f7f611..0ca63e8c4e16c 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+@@ -352,14 +352,14 @@
+                       #clock-cells = <1>;
+               };
+-              infracfg: power-controller@10001000 {
++              infracfg: clock-controller@10001000 {
+                       compatible = "mediatek,mt8173-infracfg", "syscon";
+                       reg = <0 0x10001000 0 0x1000>;
+                       #clock-cells = <1>;
+                       #reset-cells = <1>;
+               };
+-              pericfg: power-controller@10003000 {
++              pericfg: clock-controller@10003000 {
+                       compatible = "mediatek,mt8173-pericfg", "syscon";
+                       reg = <0 0x10003000 0 0x1000>;
+                       #clock-cells = <1>;
+@@ -564,7 +564,7 @@
+                       memory-region = <&vpu_dma_reserved>;
+               };
+-              sysirq: intpol-controller@10200620 {
++              sysirq: interrupt-controller@10200620 {
+                       compatible = "mediatek,mt8173-sysirq",
+                                    "mediatek,mt6577-sysirq";
+                       interrupt-controller;
+-- 
+2.39.5
+
diff --git a/queue-6.14/arm64-dts-mediatek-mt8390-genio-700-evk-move-common-.patch b/queue-6.14/arm64-dts-mediatek-mt8390-genio-700-evk-move-common-.patch
new file mode 100644 (file)
index 0000000..fa4d3c6
--- /dev/null
@@ -0,0 +1,2133 @@
+From c73f4bb74707d8a88e28675386b29635d82bebcb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Feb 2025 11:38:10 +0100
+Subject: arm64: dts: mediatek: mt8390-genio-700-evk: Move common parts to dtsi
+
+From: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
+
+[ Upstream commit 73955991b8fb959eb3d8b5307255810e4fb37b24 ]
+
+In preparation for introducing the Genio 510 EVK board support, split
+mt8390-genio-700-evk.dts file in two to create mt8390-genio-common.dtsi
+file, containing common definitions for both boards.
+
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
+Link: https://lore.kernel.org/r/20250206-dts_mt8370-genio-510-v3-3-5ca5c3257a4c@collabora.com
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Stable-dep-of: 18aa138d125d ("arm64: dts: mediatek: mt8390-genio-common: Fix duplicated regulator name")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../dts/mediatek/mt8390-genio-700-evk.dts     | 1033 +---------------
+ .../dts/mediatek/mt8390-genio-common.dtsi     | 1046 +++++++++++++++++
+ 2 files changed, 1047 insertions(+), 1032 deletions(-)
+ create mode 100644 arch/arm64/boot/dts/mediatek/mt8390-genio-common.dtsi
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt8390-genio-700-evk.dts b/arch/arm64/boot/dts/mediatek/mt8390-genio-700-evk.dts
+index 04e4a2f73799d..612336713a64e 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8390-genio-700-evk.dts
++++ b/arch/arm64/boot/dts/mediatek/mt8390-genio-700-evk.dts
+@@ -8,1047 +8,16 @@
+ /dts-v1/;
+ #include "mt8188.dtsi"
+-#include "mt6359.dtsi"
+-#include <dt-bindings/gpio/gpio.h>
+-#include <dt-bindings/input/input.h>
+-#include <dt-bindings/interrupt-controller/irq.h>
+-#include <dt-bindings/pinctrl/mediatek,mt8188-pinfunc.h>
+-#include <dt-bindings/regulator/mediatek,mt6360-regulator.h>
+-#include <dt-bindings/spmi/spmi.h>
+-#include <dt-bindings/usb/pd.h>
++#include "mt8390-genio-common.dtsi"
+ / {
+       model = "MediaTek Genio-700 EVK";
+       compatible = "mediatek,mt8390-evk", "mediatek,mt8390",
+                    "mediatek,mt8188";
+-      aliases {
+-              ethernet0 = &eth;
+-              i2c0 = &i2c0;
+-              i2c1 = &i2c1;
+-              i2c2 = &i2c2;
+-              i2c3 = &i2c3;
+-              i2c4 = &i2c4;
+-              i2c5 = &i2c5;
+-              i2c6 = &i2c6;
+-              mmc0 = &mmc0;
+-              mmc1 = &mmc1;
+-              serial0 = &uart0;
+-      };
+-
+-      chosen {
+-              stdout-path = "serial0:921600n8";
+-      };
+-
+-      firmware {
+-              optee {
+-                      compatible = "linaro,optee-tz";
+-                      method = "smc";
+-              };
+-      };
+-
+       memory@40000000 {
+               device_type = "memory";
+               reg = <0 0x40000000 0x2 0x00000000>;
+       };
+-
+-      reserved-memory {
+-              #address-cells = <2>;
+-              #size-cells = <2>;
+-              ranges;
+-
+-              /*
+-               * 12 MiB reserved for OP-TEE (BL32)
+-               * +-----------------------+ 0x43e0_0000
+-               * |      SHMEM 2MiB       |
+-               * +-----------------------+ 0x43c0_0000
+-               * |        | TA_RAM  8MiB |
+-               * + TZDRAM +--------------+ 0x4340_0000
+-               * |        | TEE_RAM 2MiB |
+-               * +-----------------------+ 0x4320_0000
+-               */
+-              optee_reserved: optee@43200000 {
+-                      no-map;
+-                      reg = <0 0x43200000 0 0x00c00000>;
+-              };
+-
+-              scp_mem: memory@50000000 {
+-                      compatible = "shared-dma-pool";
+-                      reg = <0 0x50000000 0 0x2900000>;
+-                      no-map;
+-              };
+-
+-              /* 2 MiB reserved for ARM Trusted Firmware (BL31) */
+-              bl31_secmon_reserved: memory@54600000 {
+-                      no-map;
+-                      reg = <0 0x54600000 0x0 0x200000>;
+-              };
+-
+-              apu_mem: memory@55000000 {
+-                      compatible = "shared-dma-pool";
+-                      reg = <0 0x55000000 0 0x1400000>; /* 20 MB */
+-              };
+-
+-              vpu_mem: memory@57000000 {
+-                      compatible = "shared-dma-pool";
+-                      reg = <0 0x57000000 0 0x1400000>; /* 20 MB */
+-              };
+-
+-              adsp_mem: memory@60000000 {
+-                      compatible = "shared-dma-pool";
+-                      reg = <0 0x60000000 0 0xf00000>;
+-                      no-map;
+-              };
+-
+-              afe_dma_mem: memory@60f00000 {
+-                      compatible = "shared-dma-pool";
+-                      reg = <0 0x60f00000 0 0x100000>;
+-                      no-map;
+-              };
+-
+-              adsp_dma_mem: memory@61000000 {
+-                      compatible = "shared-dma-pool";
+-                      reg = <0 0x61000000 0 0x100000>;
+-                      no-map;
+-              };
+-      };
+-
+-      common_fixed_5v: regulator-0 {
+-              compatible = "regulator-fixed";
+-              regulator-name = "vdd_5v";
+-              regulator-min-microvolt = <5000000>;
+-              regulator-max-microvolt = <5000000>;
+-              gpio = <&pio 10 GPIO_ACTIVE_HIGH>;
+-              enable-active-high;
+-              regulator-always-on;
+-              vin-supply = <&reg_vsys>;
+-      };
+-
+-      edp_panel_fixed_3v3: regulator-1 {
+-              compatible = "regulator-fixed";
+-              regulator-name = "vedp_3v3";
+-              regulator-min-microvolt = <3300000>;
+-              regulator-max-microvolt = <3300000>;
+-              enable-active-high;
+-              gpio = <&pio 15 GPIO_ACTIVE_HIGH>;
+-              pinctrl-names = "default";
+-              pinctrl-0 = <&edp_panel_3v3_en_pins>;
+-              vin-supply = <&reg_vsys>;
+-      };
+-
+-      gpio_fixed_3v3: regulator-2 {
+-              compatible = "regulator-fixed";
+-              regulator-name = "ext_3v3";
+-              regulator-min-microvolt = <3300000>;
+-              regulator-max-microvolt = <3300000>;
+-              gpio = <&pio 9 GPIO_ACTIVE_HIGH>;
+-              enable-active-high;
+-              regulator-always-on;
+-              vin-supply = <&reg_vsys>;
+-      };
+-
+-      /* system wide 4.2V power rail from charger */
+-      reg_vsys: regulator-vsys {
+-              compatible = "regulator-fixed";
+-              regulator-name = "vsys";
+-              regulator-always-on;
+-              regulator-boot-on;
+-      };
+-
+-      /* used by mmc2 */
+-      sdio_fixed_1v8: regulator-3 {
+-              compatible = "regulator-fixed";
+-              regulator-name = "vio18_conn";
+-              regulator-min-microvolt = <1800000>;
+-              regulator-max-microvolt = <1800000>;
+-              enable-active-high;
+-              regulator-always-on;
+-      };
+-
+-      /* used by mmc2 */
+-      sdio_fixed_3v3: regulator-4 {
+-              compatible = "regulator-fixed";
+-              regulator-name = "wifi_3v3";
+-              regulator-min-microvolt = <3300000>;
+-              regulator-max-microvolt = <3300000>;
+-              gpio = <&pio 74 GPIO_ACTIVE_HIGH>;
+-              enable-active-high;
+-              regulator-always-on;
+-              vin-supply = <&reg_vsys>;
+-      };
+-
+-      touch0_fixed_3v3: regulator-5 {
+-              compatible = "regulator-fixed";
+-              regulator-name = "vio33_tp1";
+-              regulator-min-microvolt = <3300000>;
+-              regulator-max-microvolt = <3300000>;
+-              gpio = <&pio 119 GPIO_ACTIVE_HIGH>;
+-              enable-active-high;
+-              vin-supply = <&reg_vsys>;
+-      };
+-
+-      usb_hub_fixed_3v3: regulator-6 {
+-              compatible = "regulator-fixed";
+-              regulator-name = "vhub_3v3";
+-              regulator-min-microvolt = <3300000>;
+-              regulator-max-microvolt = <3300000>;
+-              gpio = <&pio 112 GPIO_ACTIVE_HIGH>; /* HUB_3V3_EN */
+-              startup-delay-us = <10000>;
+-              enable-active-high;
+-              vin-supply = <&reg_vsys>;
+-      };
+-
+-      usb_p0_vbus: regulator-7 {
+-              compatible = "regulator-fixed";
+-              regulator-name = "vbus_p0";
+-              regulator-min-microvolt = <5000000>;
+-              regulator-max-microvolt = <5000000>;
+-              gpio = <&pio 84 GPIO_ACTIVE_HIGH>;
+-              enable-active-high;
+-              vin-supply = <&reg_vsys>;
+-      };
+-
+-      usb_p1_vbus: regulator-8 {
+-              compatible = "regulator-fixed";
+-              regulator-name = "vbus_p1";
+-              regulator-min-microvolt = <5000000>;
+-              regulator-max-microvolt = <5000000>;
+-              gpio = <&pio 87 GPIO_ACTIVE_HIGH>;
+-              enable-active-high;
+-              vin-supply = <&reg_vsys>;
+-      };
+-
+-      /* used by ssusb2 */
+-      usb_p2_vbus: regulator-9 {
+-              compatible = "regulator-fixed";
+-              regulator-name = "wifi_3v3";
+-              regulator-min-microvolt = <5000000>;
+-              regulator-max-microvolt = <5000000>;
+-              enable-active-high;
+-      };
+-};
+-
+-&adsp {
+-      memory-region = <&adsp_dma_mem>, <&adsp_mem>;
+-      status = "okay";
+-};
+-
+-&afe {
+-      memory-region = <&afe_dma_mem>;
+-      status = "okay";
+-};
+-
+-&gpu {
+-      mali-supply = <&mt6359_vproc2_buck_reg>;
+-      status = "okay";
+-};
+-
+-&i2c0 {
+-      pinctrl-names = "default";
+-      pinctrl-0 = <&i2c0_pins>;
+-      clock-frequency = <400000>;
+-      status = "okay";
+-
+-      touchscreen@5d {
+-              compatible = "goodix,gt9271";
+-              reg = <0x5d>;
+-              interrupt-parent = <&pio>;
+-              interrupts-extended = <&pio 6 IRQ_TYPE_EDGE_RISING>;
+-              irq-gpios = <&pio 6 GPIO_ACTIVE_HIGH>;
+-              reset-gpios = <&pio 5 GPIO_ACTIVE_HIGH>;
+-              AVDD28-supply = <&touch0_fixed_3v3>;
+-              VDDIO-supply = <&mt6359_vio18_ldo_reg>;
+-              pinctrl-names = "default";
+-              pinctrl-0 = <&touch_pins>;
+-      };
+-};
+-
+-&i2c1 {
+-      pinctrl-names = "default";
+-      pinctrl-0 = <&i2c1_pins>;
+-      clock-frequency = <400000>;
+-      status = "okay";
+-};
+-
+-&i2c2 {
+-      pinctrl-names = "default";
+-      pinctrl-0 = <&i2c2_pins>;
+-      clock-frequency = <400000>;
+-      status = "okay";
+-};
+-
+-&i2c3 {
+-      pinctrl-names = "default";
+-      pinctrl-0 = <&i2c3_pins>;
+-      clock-frequency = <400000>;
+-      status = "okay";
+-};
+-
+-&i2c4 {
+-      pinctrl-names = "default";
+-      pinctrl-0 = <&i2c4_pins>;
+-      clock-frequency = <1000000>;
+-      status = "okay";
+-};
+-
+-&i2c5 {
+-      pinctrl-names = "default";
+-      pinctrl-0 = <&i2c5_pins>;
+-      clock-frequency = <400000>;
+-      status = "okay";
+-};
+-
+-&i2c6 {
+-      pinctrl-names = "default";
+-      pinctrl-0 = <&i2c6_pins>;
+-      clock-frequency = <400000>;
+-      status = "okay";
+-};
+-
+-&mfg0 {
+-      domain-supply = <&mt6359_vproc2_buck_reg>;
+-};
+-
+-&mfg1 {
+-      domain-supply = <&mt6359_vsram_others_ldo_reg>;
+-};
+-
+-&mmc0 {
+-      status = "okay";
+-      pinctrl-names = "default", "state_uhs";
+-      pinctrl-0 = <&mmc0_default_pins>;
+-      pinctrl-1 = <&mmc0_uhs_pins>;
+-      bus-width = <8>;
+-      max-frequency = <200000000>;
+-      cap-mmc-highspeed;
+-      mmc-hs200-1_8v;
+-      mmc-hs400-1_8v;
+-      supports-cqe;
+-      cap-mmc-hw-reset;
+-      no-sdio;
+-      no-sd;
+-      hs400-ds-delay = <0x1481b>;
+-      vmmc-supply = <&mt6359_vemc_1_ldo_reg>;
+-      vqmmc-supply = <&mt6359_vufs_ldo_reg>;
+-      non-removable;
+-};
+-
+-&mmc1 {
+-      status = "okay";
+-      pinctrl-names = "default", "state_uhs";
+-      pinctrl-0 = <&mmc1_default_pins>;
+-      pinctrl-1 = <&mmc1_uhs_pins>;
+-      bus-width = <4>;
+-      max-frequency = <200000000>;
+-      cap-sd-highspeed;
+-      sd-uhs-sdr50;
+-      sd-uhs-sdr104;
+-      no-mmc;
+-      no-sdio;
+-      cd-gpios = <&pio 2 GPIO_ACTIVE_LOW>;
+-      vmmc-supply = <&mt6359_vpa_buck_reg>;
+-      vqmmc-supply = <&mt6359_vsim1_ldo_reg>;
+-};
+-
+-&mt6359_vbbck_ldo_reg {
+-      regulator-always-on;
+-};
+-
+-&mt6359_vcn18_ldo_reg {
+-      regulator-name = "vcn18_pmu";
+-      regulator-always-on;
+-};
+-
+-&mt6359_vcn33_2_bt_ldo_reg {
+-      regulator-name = "vcn33_2_pmu";
+-      regulator-always-on;
+-};
+-
+-&mt6359_vcore_buck_reg {
+-      regulator-name = "dvdd_proc_l";
+-      regulator-always-on;
+-};
+-
+-&mt6359_vgpu11_buck_reg {
+-      regulator-name = "dvdd_core";
+-      regulator-always-on;
+-};
+-
+-&mt6359_vpa_buck_reg {
+-      regulator-name = "vpa_pmu";
+-      regulator-max-microvolt = <3100000>;
+-};
+-
+-&mt6359_vproc2_buck_reg {
+-      /* The name "vgpu" is required by mtk-regulator-coupler */
+-      regulator-name = "vgpu";
+-      regulator-min-microvolt = <550000>;
+-      regulator-max-microvolt = <800000>;
+-      regulator-coupled-with = <&mt6359_vsram_others_ldo_reg>;
+-      regulator-coupled-max-spread = <6250>;
+-};
+-
+-&mt6359_vpu_buck_reg {
+-      regulator-name = "dvdd_adsp";
+-      regulator-always-on;
+-};
+-
+-&mt6359_vrf12_ldo_reg {
+-      regulator-name = "va12_abb2_pmu";
+-      regulator-always-on;
+-};
+-
+-&mt6359_vsim1_ldo_reg {
+-      regulator-name = "vsim1_pmu";
+-      regulator-enable-ramp-delay = <480>;
+-};
+-
+-&mt6359_vsram_others_ldo_reg {
+-      /* The name "vsram_gpu" is required by mtk-regulator-coupler */
+-      regulator-name = "vsram_gpu";
+-      regulator-min-microvolt = <750000>;
+-      regulator-max-microvolt = <800000>;
+-      regulator-coupled-with = <&mt6359_vproc2_buck_reg>;
+-      regulator-coupled-max-spread = <6250>;
+-};
+-
+-&mt6359_vufs_ldo_reg {
+-      regulator-name = "vufs18_pmu";
+-      regulator-always-on;
+-};
+-
+-&mt6359codec {
+-      mediatek,mic-type-0 = <1>; /* ACC */
+-      mediatek,mic-type-1 = <3>; /* DCC */
+-};
+-
+-&pcie {
+-      pinctrl-names = "default";
+-      pinctrl-0 = <&pcie_pins_default>;
+-      status = "okay";
+-};
+-
+-&pciephy {
+-      status = "okay";
+-};
+-
+-&pio {
+-      audio_default_pins: audio-default-pins {
+-              pins-cmd-dat {
+-                      pinmux = <PINMUX_GPIO101__FUNC_O_AUD_CLK_MOSI>,
+-                               <PINMUX_GPIO102__FUNC_O_AUD_SYNC_MOSI>,
+-                               <PINMUX_GPIO103__FUNC_O_AUD_DAT_MOSI0>,
+-                               <PINMUX_GPIO104__FUNC_O_AUD_DAT_MOSI1>,
+-                               <PINMUX_GPIO105__FUNC_I0_AUD_DAT_MISO0>,
+-                               <PINMUX_GPIO106__FUNC_I0_AUD_DAT_MISO1>,
+-                               <PINMUX_GPIO107__FUNC_B0_I2SIN_MCK>,
+-                               <PINMUX_GPIO108__FUNC_B0_I2SIN_BCK>,
+-                               <PINMUX_GPIO109__FUNC_B0_I2SIN_WS>,
+-                               <PINMUX_GPIO110__FUNC_I0_I2SIN_D0>,
+-                               <PINMUX_GPIO114__FUNC_O_I2SO2_MCK>,
+-                               <PINMUX_GPIO115__FUNC_B0_I2SO2_BCK>,
+-                               <PINMUX_GPIO116__FUNC_B0_I2SO2_WS>,
+-                               <PINMUX_GPIO117__FUNC_O_I2SO2_D0>,
+-                               <PINMUX_GPIO118__FUNC_O_I2SO2_D1>,
+-                               <PINMUX_GPIO121__FUNC_B0_PCM_CLK>,
+-                               <PINMUX_GPIO122__FUNC_B0_PCM_SYNC>,
+-                               <PINMUX_GPIO124__FUNC_I0_PCM_DI>,
+-                               <PINMUX_GPIO125__FUNC_O_DMIC1_CLK>,
+-                               <PINMUX_GPIO126__FUNC_I0_DMIC1_DAT>,
+-                               <PINMUX_GPIO128__FUNC_O_DMIC2_CLK>,
+-                               <PINMUX_GPIO129__FUNC_I0_DMIC2_DAT>;
+-              };
+-      };
+-
+-      dptx_pins: dptx-pins {
+-              pins-cmd-dat {
+-                      pinmux = <PINMUX_GPIO46__FUNC_I0_DP_TX_HPD>;
+-                      bias-pull-up;
+-              };
+-      };
+-
+-      edp_panel_3v3_en_pins: edp-panel-3v3-en-pins {
+-              pins1 {
+-                      pinmux = <PINMUX_GPIO15__FUNC_B_GPIO15>;
+-                      output-high;
+-              };
+-      };
+-
+-      eth_default_pins: eth-default-pins {
+-              pins-cc {
+-                      pinmux = <PINMUX_GPIO139__FUNC_B0_GBE_TXC>,
+-                               <PINMUX_GPIO140__FUNC_I0_GBE_RXC>,
+-                               <PINMUX_GPIO141__FUNC_I0_GBE_RXDV>,
+-                               <PINMUX_GPIO142__FUNC_O_GBE_TXEN>;
+-                      drive-strength = <8>;
+-              };
+-
+-              pins-mdio {
+-                      pinmux = <PINMUX_GPIO143__FUNC_O_GBE_MDC>,
+-                               <PINMUX_GPIO144__FUNC_B1_GBE_MDIO>;
+-                      drive-strength = <8>;
+-                      input-enable;
+-              };
+-
+-              pins-power {
+-                      pinmux = <PINMUX_GPIO145__FUNC_B_GPIO145>,
+-                               <PINMUX_GPIO146__FUNC_B_GPIO146>;
+-                      output-high;
+-              };
+-
+-              pins-rxd {
+-                      pinmux = <PINMUX_GPIO135__FUNC_I0_GBE_RXD3>,
+-                               <PINMUX_GPIO136__FUNC_I0_GBE_RXD2>,
+-                               <PINMUX_GPIO137__FUNC_I0_GBE_RXD1>,
+-                               <PINMUX_GPIO138__FUNC_I0_GBE_RXD0>;
+-                      drive-strength = <8>;
+-              };
+-
+-              pins-txd {
+-                      pinmux = <PINMUX_GPIO131__FUNC_O_GBE_TXD3>,
+-                               <PINMUX_GPIO132__FUNC_O_GBE_TXD2>,
+-                               <PINMUX_GPIO133__FUNC_O_GBE_TXD1>,
+-                               <PINMUX_GPIO134__FUNC_O_GBE_TXD0>;
+-                      drive-strength = <8>;
+-              };
+-      };
+-
+-      eth_sleep_pins: eth-sleep-pins {
+-              pins-cc {
+-                      pinmux = <PINMUX_GPIO139__FUNC_B_GPIO139>,
+-                               <PINMUX_GPIO140__FUNC_B_GPIO140>,
+-                               <PINMUX_GPIO141__FUNC_B_GPIO141>,
+-                               <PINMUX_GPIO142__FUNC_B_GPIO142>;
+-              };
+-
+-              pins-mdio {
+-                      pinmux = <PINMUX_GPIO143__FUNC_B_GPIO143>,
+-                               <PINMUX_GPIO144__FUNC_B_GPIO144>;
+-                      input-disable;
+-                      bias-disable;
+-              };
+-
+-              pins-rxd {
+-                      pinmux = <PINMUX_GPIO135__FUNC_B_GPIO135>,
+-                               <PINMUX_GPIO136__FUNC_B_GPIO136>,
+-                               <PINMUX_GPIO137__FUNC_B_GPIO137>,
+-                               <PINMUX_GPIO138__FUNC_B_GPIO138>;
+-              };
+-
+-              pins-txd {
+-                      pinmux = <PINMUX_GPIO131__FUNC_B_GPIO131>,
+-                               <PINMUX_GPIO132__FUNC_B_GPIO132>,
+-                               <PINMUX_GPIO133__FUNC_B_GPIO133>,
+-                               <PINMUX_GPIO134__FUNC_B_GPIO134>;
+-              };
+-      };
+-
+-      i2c0_pins: i2c0-pins {
+-              pins {
+-                      pinmux = <PINMUX_GPIO56__FUNC_B1_SDA0>,
+-                               <PINMUX_GPIO55__FUNC_B1_SCL0>;
+-                      bias-pull-up = <MTK_PULL_SET_RSEL_011>;
+-                      drive-strength-microamp = <1000>;
+-              };
+-      };
+-
+-      i2c1_pins: i2c1-pins {
+-              pins {
+-                      pinmux = <PINMUX_GPIO58__FUNC_B1_SDA1>,
+-                               <PINMUX_GPIO57__FUNC_B1_SCL1>;
+-                      bias-pull-up = <MTK_PULL_SET_RSEL_011>;
+-                      drive-strength-microamp = <1000>;
+-              };
+-      };
+-
+-      i2c2_pins: i2c2-pins {
+-              pins {
+-                      pinmux = <PINMUX_GPIO60__FUNC_B1_SDA2>,
+-                               <PINMUX_GPIO59__FUNC_B1_SCL2>;
+-                      bias-pull-up = <MTK_PULL_SET_RSEL_011>;
+-                      drive-strength-microamp = <1000>;
+-              };
+-      };
+-
+-      i2c3_pins: i2c3-pins {
+-              pins {
+-                      pinmux = <PINMUX_GPIO62__FUNC_B1_SDA3>,
+-                               <PINMUX_GPIO61__FUNC_B1_SCL3>;
+-                      bias-pull-up = <MTK_PULL_SET_RSEL_011>;
+-                      drive-strength-microamp = <1000>;
+-              };
+-      };
+-
+-      i2c4_pins: i2c4-pins {
+-              pins {
+-                      pinmux = <PINMUX_GPIO64__FUNC_B1_SDA4>,
+-                               <PINMUX_GPIO63__FUNC_B1_SCL4>;
+-                      bias-pull-up = <MTK_PULL_SET_RSEL_011>;
+-                      drive-strength-microamp = <1000>;
+-              };
+-      };
+-
+-      i2c5_pins: i2c5-pins {
+-              pins {
+-                      pinmux = <PINMUX_GPIO66__FUNC_B1_SDA5>,
+-                               <PINMUX_GPIO65__FUNC_B1_SCL5>;
+-                      bias-pull-up = <MTK_PULL_SET_RSEL_011>;
+-                      drive-strength-microamp = <1000>;
+-              };
+-      };
+-
+-      i2c6_pins: i2c6-pins {
+-              pins {
+-                      pinmux = <PINMUX_GPIO68__FUNC_B1_SDA6>,
+-                               <PINMUX_GPIO67__FUNC_B1_SCL6>;
+-                      bias-pull-up = <MTK_PULL_SET_RSEL_011>;
+-                      drive-strength-microamp = <1000>;
+-              };
+-      };
+-
+-      gpio_key_pins: gpio-key-pins {
+-              pins {
+-                      pinmux = <PINMUX_GPIO42__FUNC_B1_KPCOL0>,
+-                               <PINMUX_GPIO43__FUNC_B1_KPCOL1>,
+-                               <PINMUX_GPIO44__FUNC_B1_KPROW0>;
+-              };
+-      };
+-
+-      mmc0_default_pins: mmc0-default-pins {
+-              pins-clk {
+-                      pinmux = <PINMUX_GPIO157__FUNC_B1_MSDC0_CLK>;
+-                      drive-strength = <6>;
+-                      bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+-              };
+-
+-              pins-cmd-dat {
+-                      pinmux = <PINMUX_GPIO161__FUNC_B1_MSDC0_DAT0>,
+-                               <PINMUX_GPIO160__FUNC_B1_MSDC0_DAT1>,
+-                               <PINMUX_GPIO159__FUNC_B1_MSDC0_DAT2>,
+-                               <PINMUX_GPIO158__FUNC_B1_MSDC0_DAT3>,
+-                               <PINMUX_GPIO154__FUNC_B1_MSDC0_DAT4>,
+-                               <PINMUX_GPIO153__FUNC_B1_MSDC0_DAT5>,
+-                               <PINMUX_GPIO152__FUNC_B1_MSDC0_DAT6>,
+-                               <PINMUX_GPIO151__FUNC_B1_MSDC0_DAT7>,
+-                               <PINMUX_GPIO156__FUNC_B1_MSDC0_CMD>;
+-                      input-enable;
+-                      drive-strength = <6>;
+-                      bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+-              };
+-
+-              pins-rst {
+-                      pinmux = <PINMUX_GPIO155__FUNC_O_MSDC0_RSTB>;
+-                      drive-strength = <6>;
+-                      bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+-              };
+-      };
+-
+-      mmc0_uhs_pins: mmc0-uhs-pins {
+-              pins-clk {
+-                      pinmux = <PINMUX_GPIO157__FUNC_B1_MSDC0_CLK>;
+-                      drive-strength = <8>;
+-                      bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+-              };
+-
+-              pins-cmd-dat {
+-                      pinmux = <PINMUX_GPIO161__FUNC_B1_MSDC0_DAT0>,
+-                               <PINMUX_GPIO160__FUNC_B1_MSDC0_DAT1>,
+-                               <PINMUX_GPIO159__FUNC_B1_MSDC0_DAT2>,
+-                               <PINMUX_GPIO158__FUNC_B1_MSDC0_DAT3>,
+-                               <PINMUX_GPIO154__FUNC_B1_MSDC0_DAT4>,
+-                               <PINMUX_GPIO153__FUNC_B1_MSDC0_DAT5>,
+-                               <PINMUX_GPIO152__FUNC_B1_MSDC0_DAT6>,
+-                               <PINMUX_GPIO151__FUNC_B1_MSDC0_DAT7>,
+-                               <PINMUX_GPIO156__FUNC_B1_MSDC0_CMD>;
+-                      input-enable;
+-                      drive-strength = <8>;
+-                      bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+-              };
+-
+-              pins-ds {
+-                      pinmux = <PINMUX_GPIO162__FUNC_B0_MSDC0_DSL>;
+-                      drive-strength = <8>;
+-                      bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+-              };
+-
+-              pins-rst {
+-                      pinmux = <PINMUX_GPIO155__FUNC_O_MSDC0_RSTB>;
+-                      drive-strength = <8>;
+-                      bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+-              };
+-      };
+-
+-      mmc1_default_pins: mmc1-default-pins {
+-              pins-clk {
+-                      pinmux = <PINMUX_GPIO164__FUNC_B1_MSDC1_CLK>;
+-                      drive-strength = <6>;
+-                      bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+-              };
+-
+-              pins-cmd-dat {
+-                      pinmux = <PINMUX_GPIO163__FUNC_B1_MSDC1_CMD>,
+-                               <PINMUX_GPIO165__FUNC_B1_MSDC1_DAT0>,
+-                               <PINMUX_GPIO166__FUNC_B1_MSDC1_DAT1>,
+-                               <PINMUX_GPIO167__FUNC_B1_MSDC1_DAT2>,
+-                               <PINMUX_GPIO168__FUNC_B1_MSDC1_DAT3>;
+-                      input-enable;
+-                      drive-strength = <6>;
+-                      bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+-              };
+-
+-              pins-insert {
+-                      pinmux = <PINMUX_GPIO2__FUNC_B_GPIO2>;
+-                      bias-pull-up;
+-              };
+-      };
+-
+-      mmc1_uhs_pins: mmc1-uhs-pins {
+-              pins-clk {
+-                      pinmux = <PINMUX_GPIO164__FUNC_B1_MSDC1_CLK>;
+-                      drive-strength = <6>;
+-                      bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+-              };
+-
+-              pins-cmd-dat {
+-                      pinmux = <PINMUX_GPIO163__FUNC_B1_MSDC1_CMD>,
+-                               <PINMUX_GPIO165__FUNC_B1_MSDC1_DAT0>,
+-                               <PINMUX_GPIO166__FUNC_B1_MSDC1_DAT1>,
+-                               <PINMUX_GPIO167__FUNC_B1_MSDC1_DAT2>,
+-                               <PINMUX_GPIO168__FUNC_B1_MSDC1_DAT3>;
+-                      input-enable;
+-                      drive-strength = <6>;
+-                      bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+-              };
+-      };
+-
+-      mmc2_default_pins: mmc2-default-pins {
+-              pins-clk {
+-                      pinmux = <PINMUX_GPIO170__FUNC_B1_MSDC2_CLK>;
+-                      drive-strength = <4>;
+-                      bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+-              };
+-
+-              pins-cmd-dat {
+-                      pinmux = <PINMUX_GPIO169__FUNC_B1_MSDC2_CMD>,
+-                               <PINMUX_GPIO171__FUNC_B1_MSDC2_DAT0>,
+-                               <PINMUX_GPIO172__FUNC_B1_MSDC2_DAT1>,
+-                               <PINMUX_GPIO173__FUNC_B1_MSDC2_DAT2>,
+-                               <PINMUX_GPIO174__FUNC_B1_MSDC2_DAT3>;
+-                      input-enable;
+-                      drive-strength = <6>;
+-                      bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+-              };
+-
+-              pins-pcm {
+-                      pinmux = <PINMUX_GPIO123__FUNC_O_PCM_DO>;
+-              };
+-      };
+-
+-      mmc2_uhs_pins: mmc2-uhs-pins {
+-              pins-clk {
+-                      pinmux = <PINMUX_GPIO170__FUNC_B1_MSDC2_CLK>;
+-                      drive-strength = <4>;
+-                      bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+-              };
+-
+-              pins-cmd-dat {
+-                      pinmux = <PINMUX_GPIO169__FUNC_B1_MSDC2_CMD>,
+-                               <PINMUX_GPIO171__FUNC_B1_MSDC2_DAT0>,
+-                               <PINMUX_GPIO172__FUNC_B1_MSDC2_DAT1>,
+-                               <PINMUX_GPIO173__FUNC_B1_MSDC2_DAT2>,
+-                               <PINMUX_GPIO174__FUNC_B1_MSDC2_DAT3>;
+-                      input-enable;
+-                      drive-strength = <6>;
+-                      bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+-              };
+-      };
+-
+-      mmc2_eint_pins: mmc2-eint-pins {
+-              pins-dat1 {
+-                      pinmux = <PINMUX_GPIO172__FUNC_B_GPIO172>;
+-                      input-enable;
+-                      bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+-              };
+-      };
+-
+-      mmc2_dat1_pins: mmc2-dat1-pins {
+-              pins-dat1 {
+-                      pinmux = <PINMUX_GPIO172__FUNC_B1_MSDC2_DAT1>;
+-                      input-enable;
+-                      drive-strength = <6>;
+-                      bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+-              };
+-      };
+-
+-      panel_default_pins: panel-default-pins {
+-              pins-dcdc {
+-                      pinmux = <PINMUX_GPIO45__FUNC_B_GPIO45>;
+-                      output-low;
+-              };
+-
+-              pins-en {
+-                      pinmux = <PINMUX_GPIO111__FUNC_B_GPIO111>;
+-                      output-low;
+-              };
+-
+-              pins-rst {
+-                      pinmux = <PINMUX_GPIO25__FUNC_B_GPIO25>;
+-                      output-high;
+-              };
+-      };
+-
+-      pcie_pins_default: pcie-default {
+-              mux {
+-                      pinmux = <PINMUX_GPIO47__FUNC_I1_WAKEN>,
+-                               <PINMUX_GPIO48__FUNC_O_PERSTN>,
+-                               <PINMUX_GPIO49__FUNC_B1_CLKREQN>;
+-                      bias-pull-up;
+-              };
+-      };
+-
+-      rt1715_int_pins: rt1715-int-pins {
+-              pins_cmd0_dat {
+-                      pinmux = <PINMUX_GPIO12__FUNC_B_GPIO12>;
+-                      bias-pull-up;
+-                      input-enable;
+-              };
+-      };
+-
+-      spi0_pins: spi0-pins {
+-              pins-spi {
+-                      pinmux = <PINMUX_GPIO69__FUNC_O_SPIM0_CSB>,
+-                              <PINMUX_GPIO70__FUNC_O_SPIM0_CLK>,
+-                              <PINMUX_GPIO71__FUNC_B0_SPIM0_MOSI>,
+-                              <PINMUX_GPIO72__FUNC_B0_SPIM0_MISO>;
+-                      bias-disable;
+-              };
+-      };
+-
+-      spi1_pins: spi1-pins {
+-              pins-spi {
+-                      pinmux = <PINMUX_GPIO75__FUNC_O_SPIM1_CSB>,
+-                              <PINMUX_GPIO76__FUNC_O_SPIM1_CLK>,
+-                              <PINMUX_GPIO77__FUNC_B0_SPIM1_MOSI>,
+-                              <PINMUX_GPIO78__FUNC_B0_SPIM1_MISO>;
+-                      bias-disable;
+-              };
+-      };
+-
+-      spi2_pins: spi2-pins {
+-              pins-spi {
+-                      pinmux = <PINMUX_GPIO79__FUNC_O_SPIM2_CSB>,
+-                              <PINMUX_GPIO80__FUNC_O_SPIM2_CLK>,
+-                              <PINMUX_GPIO81__FUNC_B0_SPIM2_MOSI>,
+-                              <PINMUX_GPIO82__FUNC_B0_SPIM2_MISO>;
+-                      bias-disable;
+-              };
+-      };
+-
+-      touch_pins: touch-pins {
+-              pins-irq {
+-                      pinmux = <PINMUX_GPIO6__FUNC_B_GPIO6>;
+-                      input-enable;
+-                      bias-disable;
+-              };
+-
+-              pins-reset {
+-                      pinmux = <PINMUX_GPIO5__FUNC_B_GPIO5>;
+-                      output-high;
+-              };
+-      };
+-
+-      uart0_pins: uart0-pins {
+-              pins {
+-                      pinmux = <PINMUX_GPIO31__FUNC_O_UTXD0>,
+-                               <PINMUX_GPIO32__FUNC_I1_URXD0>;
+-                      bias-pull-up;
+-              };
+-      };
+-
+-      uart1_pins: uart1-pins {
+-              pins {
+-                      pinmux = <PINMUX_GPIO33__FUNC_O_UTXD1>,
+-                               <PINMUX_GPIO34__FUNC_I1_URXD1>;
+-                      bias-pull-up;
+-              };
+-      };
+-
+-      uart2_pins: uart2-pins {
+-              pins {
+-                      pinmux = <PINMUX_GPIO35__FUNC_O_UTXD2>,
+-                               <PINMUX_GPIO36__FUNC_I1_URXD2>;
+-                      bias-pull-up;
+-              };
+-      };
+-
+-      usb_default_pins: usb-default-pins {
+-              pins-iddig {
+-                      pinmux = <PINMUX_GPIO83__FUNC_B_GPIO83>;
+-                      input-enable;
+-                      bias-pull-up;
+-              };
+-
+-              pins-valid {
+-                      pinmux = <PINMUX_GPIO85__FUNC_I0_VBUSVALID>;
+-                      input-enable;
+-              };
+-
+-              pins-vbus {
+-                      pinmux = <PINMUX_GPIO84__FUNC_O_USB_DRVVBUS>;
+-                      output-high;
+-              };
+-
+-      };
+-
+-      usb1_default_pins: usb1-default-pins {
+-              pins-valid {
+-                      pinmux = <PINMUX_GPIO88__FUNC_I0_VBUSVALID_1P>;
+-                      input-enable;
+-              };
+-
+-              pins-usb-hub-3v3-en {
+-                      pinmux = <PINMUX_GPIO112__FUNC_B_GPIO112>;
+-                      output-high;
+-              };
+-      };
+-
+-      wifi_pwrseq_pins: wifi-pwrseq-pins {
+-              pins-wifi-enable {
+-                      pinmux = <PINMUX_GPIO127__FUNC_B_GPIO127>;
+-                      output-low;
+-              };
+-      };
+-};
+-
+-&eth {
+-      phy-mode ="rgmii-id";
+-      phy-handle = <&ethernet_phy0>;
+-      pinctrl-names = "default", "sleep";
+-      pinctrl-0 = <&eth_default_pins>;
+-      pinctrl-1 = <&eth_sleep_pins>;
+-      mediatek,mac-wol;
+-      snps,reset-gpio = <&pio 147 GPIO_ACTIVE_HIGH>;
+-      snps,reset-delays-us = <0 10000 10000>;
+-      status = "okay";
+-};
+-
+-&eth_mdio {
+-      ethernet_phy0: ethernet-phy@1 {
+-              compatible = "ethernet-phy-id001c.c916";
+-              reg = <0x1>;
+-      };
+-};
+-
+-&pmic {
+-      interrupt-parent = <&pio>;
+-      interrupts = <222 IRQ_TYPE_LEVEL_HIGH>;
+-
+-      mt6359keys: keys {
+-              compatible = "mediatek,mt6359-keys";
+-              mediatek,long-press-mode = <1>;
+-              power-off-time-sec = <0>;
+-
+-              power-key {
+-                      linux,keycodes = <KEY_POWER>;
+-                      wakeup-source;
+-              };
+-      };
+-};
+-
+-&scp {
+-      memory-region = <&scp_mem>;
+-      status = "okay";
+-};
+-
+-&sound {
+-      compatible = "mediatek,mt8390-mt6359-evk", "mediatek,mt8188-mt6359-evb";
+-      model = "mt8390-evk";
+-      pinctrl-names = "default";
+-      pinctrl-0 = <&audio_default_pins>;
+-      audio-routing =
+-              "Headphone", "Headphone L",
+-              "Headphone", "Headphone R";
+-      mediatek,adsp = <&adsp>;
+-      status = "okay";
+-
+-      dai-link-0 {
+-              link-name = "DL_SRC_BE";
+-
+-              codec {
+-                      sound-dai = <&pmic 0>;
+-              };
+-      };
+-};
+-
+-&spi2 {
+-      pinctrl-0 = <&spi2_pins>;
+-      pinctrl-names = "default";
+-      mediatek,pad-select = <0>;
+-      #address-cells = <1>;
+-      #size-cells = <0>;
+-      status = "okay";
+ };
+-&uart0 {
+-      pinctrl-0 = <&uart0_pins>;
+-      pinctrl-names = "default";
+-      status = "okay";
+-};
+-
+-&uart1 {
+-      pinctrl-0 = <&uart1_pins>;
+-      pinctrl-names = "default";
+-      status = "okay";
+-};
+-
+-&uart2 {
+-      pinctrl-0 = <&uart2_pins>;
+-      pinctrl-names = "default";
+-      status = "okay";
+-};
+-
+-&u3phy0 {
+-      status = "okay";
+-};
+-
+-&u3phy1 {
+-      status = "okay";
+-};
+-
+-&u3phy2 {
+-      status = "okay";
+-};
+-
+-&xhci0 {
+-      status = "okay";
+-      vusb33-supply = <&mt6359_vusb_ldo_reg>;
+-};
+-
+-&xhci1 {
+-      status = "okay";
+-      vusb33-supply = <&mt6359_vusb_ldo_reg>;
+-      #address-cells = <1>;
+-      #size-cells = <0>;
+-
+-      hub_2_0: hub@1 {
+-              compatible = "usb451,8025";
+-              reg = <1>;
+-              peer-hub = <&hub_3_0>;
+-              reset-gpios = <&pio 7 GPIO_ACTIVE_HIGH>;
+-              vdd-supply = <&usb_hub_fixed_3v3>;
+-      };
+-
+-      hub_3_0: hub@2 {
+-              compatible = "usb451,8027";
+-              reg = <2>;
+-              peer-hub = <&hub_2_0>;
+-              reset-gpios = <&pio 7 GPIO_ACTIVE_HIGH>;
+-              vdd-supply = <&usb_hub_fixed_3v3>;
+-      };
+-};
+-
+-&xhci2 {
+-      status = "okay";
+-      vusb33-supply = <&mt6359_vusb_ldo_reg>;
+-      vbus-supply = <&sdio_fixed_3v3>; /* wifi_3v3 */
+-};
+diff --git a/arch/arm64/boot/dts/mediatek/mt8390-genio-common.dtsi b/arch/arm64/boot/dts/mediatek/mt8390-genio-common.dtsi
+new file mode 100644
+index 0000000000000..a37cf102a6e92
+--- /dev/null
++++ b/arch/arm64/boot/dts/mediatek/mt8390-genio-common.dtsi
+@@ -0,0 +1,1046 @@
++// SPDX-License-Identifier: (GPL-2.0 OR MIT)
++/*
++ * Copyright (C) 2023 MediaTek Inc.
++ * Author: Chris Chen <chris-qj.chen@mediatek.com>
++ *         Pablo Sun <pablo.sun@mediatek.com>
++ *         Macpaul Lin <macpaul.lin@mediatek.com>
++ *
++ * Copyright (C) 2025 Collabora Ltd.
++ *                    Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
++ *                    AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>   
++ */
++
++#include "mt6359.dtsi"
++#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/input/input.h>
++#include <dt-bindings/interrupt-controller/irq.h>
++#include <dt-bindings/pinctrl/mediatek,mt8188-pinfunc.h>
++#include <dt-bindings/regulator/mediatek,mt6360-regulator.h>
++#include <dt-bindings/spmi/spmi.h>
++#include <dt-bindings/usb/pd.h>
++
++/ {
++      aliases {
++              ethernet0 = &eth;
++              i2c0 = &i2c0;
++              i2c1 = &i2c1;
++              i2c2 = &i2c2;
++              i2c3 = &i2c3;
++              i2c4 = &i2c4;
++              i2c5 = &i2c5;
++              i2c6 = &i2c6;
++              mmc0 = &mmc0;
++              mmc1 = &mmc1;
++              serial0 = &uart0;
++      };
++
++      chosen {
++              stdout-path = "serial0:921600n8";
++      };
++
++      firmware {
++              optee {
++                      compatible = "linaro,optee-tz";
++                      method = "smc";
++              };
++      };
++      reserved-memory {
++              #address-cells = <2>;
++              #size-cells = <2>;
++              ranges;
++
++              /*
++               * 12 MiB reserved for OP-TEE (BL32)
++               * +-----------------------+ 0x43e0_0000
++               * |      SHMEM 2MiB       |
++               * +-----------------------+ 0x43c0_0000
++               * |        | TA_RAM  8MiB |
++               * + TZDRAM +--------------+ 0x4340_0000
++               * |        | TEE_RAM 2MiB |
++               * +-----------------------+ 0x4320_0000
++               */
++              optee_reserved: optee@43200000 {
++                      no-map;
++                      reg = <0 0x43200000 0 0x00c00000>;
++              };
++
++              scp_mem: memory@50000000 {
++                      compatible = "shared-dma-pool";
++                      reg = <0 0x50000000 0 0x2900000>;
++                      no-map;
++              };
++
++              /* 2 MiB reserved for ARM Trusted Firmware (BL31) */
++              bl31_secmon_reserved: memory@54600000 {
++                      no-map;
++                      reg = <0 0x54600000 0x0 0x200000>;
++              };
++
++              apu_mem: memory@55000000 {
++                      compatible = "shared-dma-pool";
++                      reg = <0 0x55000000 0 0x1400000>; /* 20 MB */
++              };
++
++              vpu_mem: memory@57000000 {
++                      compatible = "shared-dma-pool";
++                      reg = <0 0x57000000 0 0x1400000>; /* 20 MB */
++              };
++
++              adsp_mem: memory@60000000 {
++                      compatible = "shared-dma-pool";
++                      reg = <0 0x60000000 0 0xf00000>;
++                      no-map;
++              };
++
++              afe_dma_mem: memory@60f00000 {
++                      compatible = "shared-dma-pool";
++                      reg = <0 0x60f00000 0 0x100000>;
++                      no-map;
++              };
++
++              adsp_dma_mem: memory@61000000 {
++                      compatible = "shared-dma-pool";
++                      reg = <0 0x61000000 0 0x100000>;
++                      no-map;
++              };
++      };
++
++      common_fixed_5v: regulator-0 {
++              compatible = "regulator-fixed";
++              regulator-name = "vdd_5v";
++              regulator-min-microvolt = <5000000>;
++              regulator-max-microvolt = <5000000>;
++              gpio = <&pio 10 GPIO_ACTIVE_HIGH>;
++              enable-active-high;
++              regulator-always-on;
++              vin-supply = <&reg_vsys>;
++      };
++
++      edp_panel_fixed_3v3: regulator-1 {
++              compatible = "regulator-fixed";
++              regulator-name = "vedp_3v3";
++              regulator-min-microvolt = <3300000>;
++              regulator-max-microvolt = <3300000>;
++              enable-active-high;
++              gpio = <&pio 15 GPIO_ACTIVE_HIGH>;
++              pinctrl-names = "default";
++              pinctrl-0 = <&edp_panel_3v3_en_pins>;
++              vin-supply = <&reg_vsys>;
++      };
++
++      gpio_fixed_3v3: regulator-2 {
++              compatible = "regulator-fixed";
++              regulator-name = "ext_3v3";
++              regulator-min-microvolt = <3300000>;
++              regulator-max-microvolt = <3300000>;
++              gpio = <&pio 9 GPIO_ACTIVE_HIGH>;
++              enable-active-high;
++              regulator-always-on;
++              vin-supply = <&reg_vsys>;
++      };
++
++      /* system wide 4.2V power rail from charger */
++      reg_vsys: regulator-vsys {
++              compatible = "regulator-fixed";
++              regulator-name = "vsys";
++              regulator-always-on;
++              regulator-boot-on;
++      };
++
++      /* used by mmc2 */
++      sdio_fixed_1v8: regulator-3 {
++              compatible = "regulator-fixed";
++              regulator-name = "vio18_conn";
++              regulator-min-microvolt = <1800000>;
++              regulator-max-microvolt = <1800000>;
++              enable-active-high;
++              regulator-always-on;
++      };
++
++      /* used by mmc2 */
++      sdio_fixed_3v3: regulator-4 {
++              compatible = "regulator-fixed";
++              regulator-name = "wifi_3v3";
++              regulator-min-microvolt = <3300000>;
++              regulator-max-microvolt = <3300000>;
++              gpio = <&pio 74 GPIO_ACTIVE_HIGH>;
++              enable-active-high;
++              regulator-always-on;
++              vin-supply = <&reg_vsys>;
++      };
++
++      touch0_fixed_3v3: regulator-5 {
++              compatible = "regulator-fixed";
++              regulator-name = "vio33_tp1";
++              regulator-min-microvolt = <3300000>;
++              regulator-max-microvolt = <3300000>;
++              gpio = <&pio 119 GPIO_ACTIVE_HIGH>;
++              enable-active-high;
++              vin-supply = <&reg_vsys>;
++      };
++
++      usb_hub_fixed_3v3: regulator-6 {
++              compatible = "regulator-fixed";
++              regulator-name = "vhub_3v3";
++              regulator-min-microvolt = <3300000>;
++              regulator-max-microvolt = <3300000>;
++              gpio = <&pio 112 GPIO_ACTIVE_HIGH>; /* HUB_3V3_EN */
++              startup-delay-us = <10000>;
++              enable-active-high;
++              vin-supply = <&reg_vsys>;
++      };
++
++      usb_p0_vbus: regulator-7 {
++              compatible = "regulator-fixed";
++              regulator-name = "vbus_p0";
++              regulator-min-microvolt = <5000000>;
++              regulator-max-microvolt = <5000000>;
++              gpio = <&pio 84 GPIO_ACTIVE_HIGH>;
++              enable-active-high;
++              vin-supply = <&reg_vsys>;
++      };
++
++      usb_p1_vbus: regulator-8 {
++              compatible = "regulator-fixed";
++              regulator-name = "vbus_p1";
++              regulator-min-microvolt = <5000000>;
++              regulator-max-microvolt = <5000000>;
++              gpio = <&pio 87 GPIO_ACTIVE_HIGH>;
++              enable-active-high;
++              vin-supply = <&reg_vsys>;
++      };
++
++      /* used by ssusb2 */
++      usb_p2_vbus: regulator-9 {
++              compatible = "regulator-fixed";
++              regulator-name = "wifi_3v3";
++              regulator-min-microvolt = <5000000>;
++              regulator-max-microvolt = <5000000>;
++              enable-active-high;
++      };
++};
++
++&adsp {
++      memory-region = <&adsp_dma_mem>, <&adsp_mem>;
++      status = "okay";
++};
++
++&afe {
++      memory-region = <&afe_dma_mem>;
++      status = "okay";
++};
++
++&gpu {
++      mali-supply = <&mt6359_vproc2_buck_reg>;
++      status = "okay";
++};
++
++&i2c0 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&i2c0_pins>;
++      clock-frequency = <400000>;
++      status = "okay";
++
++      touchscreen@5d {
++              compatible = "goodix,gt9271";
++              reg = <0x5d>;
++              interrupt-parent = <&pio>;
++              interrupts-extended = <&pio 6 IRQ_TYPE_EDGE_RISING>;
++              irq-gpios = <&pio 6 GPIO_ACTIVE_HIGH>;
++              reset-gpios = <&pio 5 GPIO_ACTIVE_HIGH>;
++              AVDD28-supply = <&touch0_fixed_3v3>;
++              VDDIO-supply = <&mt6359_vio18_ldo_reg>;
++              pinctrl-names = "default";
++              pinctrl-0 = <&touch_pins>;
++      };
++};
++
++&i2c1 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&i2c1_pins>;
++      clock-frequency = <400000>;
++      status = "okay";
++};
++
++&i2c2 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&i2c2_pins>;
++      clock-frequency = <400000>;
++      status = "okay";
++};
++
++&i2c3 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&i2c3_pins>;
++      clock-frequency = <400000>;
++      status = "okay";
++};
++
++&i2c4 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&i2c4_pins>;
++      clock-frequency = <1000000>;
++      status = "okay";
++};
++
++&i2c5 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&i2c5_pins>;
++      clock-frequency = <400000>;
++      status = "okay";
++};
++
++&i2c6 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&i2c6_pins>;
++      clock-frequency = <400000>;
++      status = "okay";
++};
++
++&mfg0 {
++      domain-supply = <&mt6359_vproc2_buck_reg>;
++};
++
++&mfg1 {
++      domain-supply = <&mt6359_vsram_others_ldo_reg>;
++};
++
++&mmc0 {
++      status = "okay";
++      pinctrl-names = "default", "state_uhs";
++      pinctrl-0 = <&mmc0_default_pins>;
++      pinctrl-1 = <&mmc0_uhs_pins>;
++      bus-width = <8>;
++      max-frequency = <200000000>;
++      cap-mmc-highspeed;
++      mmc-hs200-1_8v;
++      mmc-hs400-1_8v;
++      supports-cqe;
++      cap-mmc-hw-reset;
++      no-sdio;
++      no-sd;
++      hs400-ds-delay = <0x1481b>;
++      vmmc-supply = <&mt6359_vemc_1_ldo_reg>;
++      vqmmc-supply = <&mt6359_vufs_ldo_reg>;
++      non-removable;
++};
++
++&mmc1 {
++      status = "okay";
++      pinctrl-names = "default", "state_uhs";
++      pinctrl-0 = <&mmc1_default_pins>;
++      pinctrl-1 = <&mmc1_uhs_pins>;
++      bus-width = <4>;
++      max-frequency = <200000000>;
++      cap-sd-highspeed;
++      sd-uhs-sdr50;
++      sd-uhs-sdr104;
++      no-mmc;
++      no-sdio;
++      cd-gpios = <&pio 2 GPIO_ACTIVE_LOW>;
++      vmmc-supply = <&mt6359_vpa_buck_reg>;
++      vqmmc-supply = <&mt6359_vsim1_ldo_reg>;
++};
++
++&mt6359_vbbck_ldo_reg {
++      regulator-always-on;
++};
++
++&mt6359_vcn18_ldo_reg {
++      regulator-name = "vcn18_pmu";
++      regulator-always-on;
++};
++
++&mt6359_vcn33_2_bt_ldo_reg {
++      regulator-name = "vcn33_2_pmu";
++      regulator-always-on;
++};
++
++&mt6359_vcore_buck_reg {
++      regulator-name = "dvdd_proc_l";
++      regulator-always-on;
++};
++
++&mt6359_vgpu11_buck_reg {
++      regulator-name = "dvdd_core";
++      regulator-always-on;
++};
++
++&mt6359_vpa_buck_reg {
++      regulator-name = "vpa_pmu";
++      regulator-max-microvolt = <3100000>;
++};
++
++&mt6359_vproc2_buck_reg {
++      /* The name "vgpu" is required by mtk-regulator-coupler */
++      regulator-name = "vgpu";
++      regulator-min-microvolt = <550000>;
++      regulator-max-microvolt = <800000>;
++      regulator-coupled-with = <&mt6359_vsram_others_ldo_reg>;
++      regulator-coupled-max-spread = <6250>;
++};
++
++&mt6359_vpu_buck_reg {
++      regulator-name = "dvdd_adsp";
++      regulator-always-on;
++};
++
++&mt6359_vrf12_ldo_reg {
++      regulator-name = "va12_abb2_pmu";
++      regulator-always-on;
++};
++
++&mt6359_vsim1_ldo_reg {
++      regulator-name = "vsim1_pmu";
++      regulator-enable-ramp-delay = <480>;
++};
++
++&mt6359_vsram_others_ldo_reg {
++      /* The name "vsram_gpu" is required by mtk-regulator-coupler */
++      regulator-name = "vsram_gpu";
++      regulator-min-microvolt = <750000>;
++      regulator-max-microvolt = <800000>;
++      regulator-coupled-with = <&mt6359_vproc2_buck_reg>;
++      regulator-coupled-max-spread = <6250>;
++};
++
++&mt6359_vufs_ldo_reg {
++      regulator-name = "vufs18_pmu";
++      regulator-always-on;
++};
++
++&mt6359codec {
++      mediatek,mic-type-0 = <1>; /* ACC */
++      mediatek,mic-type-1 = <3>; /* DCC */
++};
++
++&pcie {
++      pinctrl-names = "default";
++      pinctrl-0 = <&pcie_pins_default>;
++      status = "okay";
++};
++
++&pciephy {
++      status = "okay";
++};
++
++&pio {
++      audio_default_pins: audio-default-pins {
++              pins-cmd-dat {
++                      pinmux = <PINMUX_GPIO101__FUNC_O_AUD_CLK_MOSI>,
++                               <PINMUX_GPIO102__FUNC_O_AUD_SYNC_MOSI>,
++                               <PINMUX_GPIO103__FUNC_O_AUD_DAT_MOSI0>,
++                               <PINMUX_GPIO104__FUNC_O_AUD_DAT_MOSI1>,
++                               <PINMUX_GPIO105__FUNC_I0_AUD_DAT_MISO0>,
++                               <PINMUX_GPIO106__FUNC_I0_AUD_DAT_MISO1>,
++                               <PINMUX_GPIO107__FUNC_B0_I2SIN_MCK>,
++                               <PINMUX_GPIO108__FUNC_B0_I2SIN_BCK>,
++                               <PINMUX_GPIO109__FUNC_B0_I2SIN_WS>,
++                               <PINMUX_GPIO110__FUNC_I0_I2SIN_D0>,
++                               <PINMUX_GPIO114__FUNC_O_I2SO2_MCK>,
++                               <PINMUX_GPIO115__FUNC_B0_I2SO2_BCK>,
++                               <PINMUX_GPIO116__FUNC_B0_I2SO2_WS>,
++                               <PINMUX_GPIO117__FUNC_O_I2SO2_D0>,
++                               <PINMUX_GPIO118__FUNC_O_I2SO2_D1>,
++                               <PINMUX_GPIO121__FUNC_B0_PCM_CLK>,
++                               <PINMUX_GPIO122__FUNC_B0_PCM_SYNC>,
++                               <PINMUX_GPIO124__FUNC_I0_PCM_DI>,
++                               <PINMUX_GPIO125__FUNC_O_DMIC1_CLK>,
++                               <PINMUX_GPIO126__FUNC_I0_DMIC1_DAT>,
++                               <PINMUX_GPIO128__FUNC_O_DMIC2_CLK>,
++                               <PINMUX_GPIO129__FUNC_I0_DMIC2_DAT>;
++              };
++      };
++
++      dptx_pins: dptx-pins {
++              pins-cmd-dat {
++                      pinmux = <PINMUX_GPIO46__FUNC_I0_DP_TX_HPD>;
++                      bias-pull-up;
++              };
++      };
++
++      edp_panel_3v3_en_pins: edp-panel-3v3-en-pins {
++              pins1 {
++                      pinmux = <PINMUX_GPIO15__FUNC_B_GPIO15>;
++                      output-high;
++              };
++      };
++
++      eth_default_pins: eth-default-pins {
++              pins-cc {
++                      pinmux = <PINMUX_GPIO139__FUNC_B0_GBE_TXC>,
++                               <PINMUX_GPIO140__FUNC_I0_GBE_RXC>,
++                               <PINMUX_GPIO141__FUNC_I0_GBE_RXDV>,
++                               <PINMUX_GPIO142__FUNC_O_GBE_TXEN>;
++                      drive-strength = <8>;
++              };
++
++              pins-mdio {
++                      pinmux = <PINMUX_GPIO143__FUNC_O_GBE_MDC>,
++                               <PINMUX_GPIO144__FUNC_B1_GBE_MDIO>;
++                      drive-strength = <8>;
++                      input-enable;
++              };
++
++              pins-power {
++                      pinmux = <PINMUX_GPIO145__FUNC_B_GPIO145>,
++                               <PINMUX_GPIO146__FUNC_B_GPIO146>;
++                      output-high;
++              };
++
++              pins-rxd {
++                      pinmux = <PINMUX_GPIO135__FUNC_I0_GBE_RXD3>,
++                               <PINMUX_GPIO136__FUNC_I0_GBE_RXD2>,
++                               <PINMUX_GPIO137__FUNC_I0_GBE_RXD1>,
++                               <PINMUX_GPIO138__FUNC_I0_GBE_RXD0>;
++                      drive-strength = <8>;
++              };
++
++              pins-txd {
++                      pinmux = <PINMUX_GPIO131__FUNC_O_GBE_TXD3>,
++                               <PINMUX_GPIO132__FUNC_O_GBE_TXD2>,
++                               <PINMUX_GPIO133__FUNC_O_GBE_TXD1>,
++                               <PINMUX_GPIO134__FUNC_O_GBE_TXD0>;
++                      drive-strength = <8>;
++              };
++      };
++
++      eth_sleep_pins: eth-sleep-pins {
++              pins-cc {
++                      pinmux = <PINMUX_GPIO139__FUNC_B_GPIO139>,
++                               <PINMUX_GPIO140__FUNC_B_GPIO140>,
++                               <PINMUX_GPIO141__FUNC_B_GPIO141>,
++                               <PINMUX_GPIO142__FUNC_B_GPIO142>;
++              };
++
++              pins-mdio {
++                      pinmux = <PINMUX_GPIO143__FUNC_B_GPIO143>,
++                               <PINMUX_GPIO144__FUNC_B_GPIO144>;
++                      input-disable;
++                      bias-disable;
++              };
++
++              pins-rxd {
++                      pinmux = <PINMUX_GPIO135__FUNC_B_GPIO135>,
++                               <PINMUX_GPIO136__FUNC_B_GPIO136>,
++                               <PINMUX_GPIO137__FUNC_B_GPIO137>,
++                               <PINMUX_GPIO138__FUNC_B_GPIO138>;
++              };
++
++              pins-txd {
++                      pinmux = <PINMUX_GPIO131__FUNC_B_GPIO131>,
++                               <PINMUX_GPIO132__FUNC_B_GPIO132>,
++                               <PINMUX_GPIO133__FUNC_B_GPIO133>,
++                               <PINMUX_GPIO134__FUNC_B_GPIO134>;
++              };
++      };
++
++      i2c0_pins: i2c0-pins {
++              pins {
++                      pinmux = <PINMUX_GPIO56__FUNC_B1_SDA0>,
++                               <PINMUX_GPIO55__FUNC_B1_SCL0>;
++                      bias-pull-up = <MTK_PULL_SET_RSEL_011>;
++                      drive-strength-microamp = <1000>;
++              };
++      };
++
++      i2c1_pins: i2c1-pins {
++              pins {
++                      pinmux = <PINMUX_GPIO58__FUNC_B1_SDA1>,
++                               <PINMUX_GPIO57__FUNC_B1_SCL1>;
++                      bias-pull-up = <MTK_PULL_SET_RSEL_011>;
++                      drive-strength-microamp = <1000>;
++              };
++      };
++
++      i2c2_pins: i2c2-pins {
++              pins {
++                      pinmux = <PINMUX_GPIO60__FUNC_B1_SDA2>,
++                               <PINMUX_GPIO59__FUNC_B1_SCL2>;
++                      bias-pull-up = <MTK_PULL_SET_RSEL_011>;
++                      drive-strength-microamp = <1000>;
++              };
++      };
++
++      i2c3_pins: i2c3-pins {
++              pins {
++                      pinmux = <PINMUX_GPIO62__FUNC_B1_SDA3>,
++                               <PINMUX_GPIO61__FUNC_B1_SCL3>;
++                      bias-pull-up = <MTK_PULL_SET_RSEL_011>;
++                      drive-strength-microamp = <1000>;
++              };
++      };
++
++      i2c4_pins: i2c4-pins {
++              pins {
++                      pinmux = <PINMUX_GPIO64__FUNC_B1_SDA4>,
++                               <PINMUX_GPIO63__FUNC_B1_SCL4>;
++                      bias-pull-up = <MTK_PULL_SET_RSEL_011>;
++                      drive-strength-microamp = <1000>;
++              };
++      };
++
++      i2c5_pins: i2c5-pins {
++              pins {
++                      pinmux = <PINMUX_GPIO66__FUNC_B1_SDA5>,
++                               <PINMUX_GPIO65__FUNC_B1_SCL5>;
++                      bias-pull-up = <MTK_PULL_SET_RSEL_011>;
++                      drive-strength-microamp = <1000>;
++              };
++      };
++
++      i2c6_pins: i2c6-pins {
++              pins {
++                      pinmux = <PINMUX_GPIO68__FUNC_B1_SDA6>,
++                               <PINMUX_GPIO67__FUNC_B1_SCL6>;
++                      bias-pull-up = <MTK_PULL_SET_RSEL_011>;
++                      drive-strength-microamp = <1000>;
++              };
++      };
++
++      gpio_key_pins: gpio-key-pins {
++              pins {
++                      pinmux = <PINMUX_GPIO42__FUNC_B1_KPCOL0>,
++                               <PINMUX_GPIO43__FUNC_B1_KPCOL1>,
++                               <PINMUX_GPIO44__FUNC_B1_KPROW0>;
++              };
++      };
++
++      mmc0_default_pins: mmc0-default-pins {
++              pins-clk {
++                      pinmux = <PINMUX_GPIO157__FUNC_B1_MSDC0_CLK>;
++                      drive-strength = <6>;
++                      bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
++              };
++
++              pins-cmd-dat {
++                      pinmux = <PINMUX_GPIO161__FUNC_B1_MSDC0_DAT0>,
++                               <PINMUX_GPIO160__FUNC_B1_MSDC0_DAT1>,
++                               <PINMUX_GPIO159__FUNC_B1_MSDC0_DAT2>,
++                               <PINMUX_GPIO158__FUNC_B1_MSDC0_DAT3>,
++                               <PINMUX_GPIO154__FUNC_B1_MSDC0_DAT4>,
++                               <PINMUX_GPIO153__FUNC_B1_MSDC0_DAT5>,
++                               <PINMUX_GPIO152__FUNC_B1_MSDC0_DAT6>,
++                               <PINMUX_GPIO151__FUNC_B1_MSDC0_DAT7>,
++                               <PINMUX_GPIO156__FUNC_B1_MSDC0_CMD>;
++                      input-enable;
++                      drive-strength = <6>;
++                      bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
++              };
++
++              pins-rst {
++                      pinmux = <PINMUX_GPIO155__FUNC_O_MSDC0_RSTB>;
++                      drive-strength = <6>;
++                      bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
++              };
++      };
++
++      mmc0_uhs_pins: mmc0-uhs-pins {
++              pins-clk {
++                      pinmux = <PINMUX_GPIO157__FUNC_B1_MSDC0_CLK>;
++                      drive-strength = <8>;
++                      bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
++              };
++
++              pins-cmd-dat {
++                      pinmux = <PINMUX_GPIO161__FUNC_B1_MSDC0_DAT0>,
++                               <PINMUX_GPIO160__FUNC_B1_MSDC0_DAT1>,
++                               <PINMUX_GPIO159__FUNC_B1_MSDC0_DAT2>,
++                               <PINMUX_GPIO158__FUNC_B1_MSDC0_DAT3>,
++                               <PINMUX_GPIO154__FUNC_B1_MSDC0_DAT4>,
++                               <PINMUX_GPIO153__FUNC_B1_MSDC0_DAT5>,
++                               <PINMUX_GPIO152__FUNC_B1_MSDC0_DAT6>,
++                               <PINMUX_GPIO151__FUNC_B1_MSDC0_DAT7>,
++                               <PINMUX_GPIO156__FUNC_B1_MSDC0_CMD>;
++                      input-enable;
++                      drive-strength = <8>;
++                      bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
++              };
++
++              pins-ds {
++                      pinmux = <PINMUX_GPIO162__FUNC_B0_MSDC0_DSL>;
++                      drive-strength = <8>;
++                      bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
++              };
++
++              pins-rst {
++                      pinmux = <PINMUX_GPIO155__FUNC_O_MSDC0_RSTB>;
++                      drive-strength = <8>;
++                      bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
++              };
++      };
++
++      mmc1_default_pins: mmc1-default-pins {
++              pins-clk {
++                      pinmux = <PINMUX_GPIO164__FUNC_B1_MSDC1_CLK>;
++                      drive-strength = <6>;
++                      bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
++              };
++
++              pins-cmd-dat {
++                      pinmux = <PINMUX_GPIO163__FUNC_B1_MSDC1_CMD>,
++                               <PINMUX_GPIO165__FUNC_B1_MSDC1_DAT0>,
++                               <PINMUX_GPIO166__FUNC_B1_MSDC1_DAT1>,
++                               <PINMUX_GPIO167__FUNC_B1_MSDC1_DAT2>,
++                               <PINMUX_GPIO168__FUNC_B1_MSDC1_DAT3>;
++                      input-enable;
++                      drive-strength = <6>;
++                      bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
++              };
++
++              pins-insert {
++                      pinmux = <PINMUX_GPIO2__FUNC_B_GPIO2>;
++                      bias-pull-up;
++              };
++      };
++
++      mmc1_uhs_pins: mmc1-uhs-pins {
++              pins-clk {
++                      pinmux = <PINMUX_GPIO164__FUNC_B1_MSDC1_CLK>;
++                      drive-strength = <6>;
++                      bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
++              };
++
++              pins-cmd-dat {
++                      pinmux = <PINMUX_GPIO163__FUNC_B1_MSDC1_CMD>,
++                               <PINMUX_GPIO165__FUNC_B1_MSDC1_DAT0>,
++                               <PINMUX_GPIO166__FUNC_B1_MSDC1_DAT1>,
++                               <PINMUX_GPIO167__FUNC_B1_MSDC1_DAT2>,
++                               <PINMUX_GPIO168__FUNC_B1_MSDC1_DAT3>;
++                      input-enable;
++                      drive-strength = <6>;
++                      bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
++              };
++      };
++
++      mmc2_default_pins: mmc2-default-pins {
++              pins-clk {
++                      pinmux = <PINMUX_GPIO170__FUNC_B1_MSDC2_CLK>;
++                      drive-strength = <4>;
++                      bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
++              };
++
++              pins-cmd-dat {
++                      pinmux = <PINMUX_GPIO169__FUNC_B1_MSDC2_CMD>,
++                               <PINMUX_GPIO171__FUNC_B1_MSDC2_DAT0>,
++                               <PINMUX_GPIO172__FUNC_B1_MSDC2_DAT1>,
++                               <PINMUX_GPIO173__FUNC_B1_MSDC2_DAT2>,
++                               <PINMUX_GPIO174__FUNC_B1_MSDC2_DAT3>;
++                      input-enable;
++                      drive-strength = <6>;
++                      bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
++              };
++
++              pins-pcm {
++                      pinmux = <PINMUX_GPIO123__FUNC_O_PCM_DO>;
++              };
++      };
++
++      mmc2_uhs_pins: mmc2-uhs-pins {
++              pins-clk {
++                      pinmux = <PINMUX_GPIO170__FUNC_B1_MSDC2_CLK>;
++                      drive-strength = <4>;
++                      bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
++              };
++
++              pins-cmd-dat {
++                      pinmux = <PINMUX_GPIO169__FUNC_B1_MSDC2_CMD>,
++                               <PINMUX_GPIO171__FUNC_B1_MSDC2_DAT0>,
++                               <PINMUX_GPIO172__FUNC_B1_MSDC2_DAT1>,
++                               <PINMUX_GPIO173__FUNC_B1_MSDC2_DAT2>,
++                               <PINMUX_GPIO174__FUNC_B1_MSDC2_DAT3>;
++                      input-enable;
++                      drive-strength = <6>;
++                      bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
++              };
++      };
++
++      mmc2_eint_pins: mmc2-eint-pins {
++              pins-dat1 {
++                      pinmux = <PINMUX_GPIO172__FUNC_B_GPIO172>;
++                      input-enable;
++                      bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
++              };
++      };
++
++      mmc2_dat1_pins: mmc2-dat1-pins {
++              pins-dat1 {
++                      pinmux = <PINMUX_GPIO172__FUNC_B1_MSDC2_DAT1>;
++                      input-enable;
++                      drive-strength = <6>;
++                      bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
++              };
++      };
++
++      panel_default_pins: panel-default-pins {
++              pins-dcdc {
++                      pinmux = <PINMUX_GPIO45__FUNC_B_GPIO45>;
++                      output-low;
++              };
++
++              pins-en {
++                      pinmux = <PINMUX_GPIO111__FUNC_B_GPIO111>;
++                      output-low;
++              };
++
++              pins-rst {
++                      pinmux = <PINMUX_GPIO25__FUNC_B_GPIO25>;
++                      output-high;
++              };
++      };
++
++      pcie_pins_default: pcie-default {
++              mux {
++                      pinmux = <PINMUX_GPIO47__FUNC_I1_WAKEN>,
++                               <PINMUX_GPIO48__FUNC_O_PERSTN>,
++                               <PINMUX_GPIO49__FUNC_B1_CLKREQN>;
++                      bias-pull-up;
++              };
++      };
++
++      rt1715_int_pins: rt1715-int-pins {
++              pins_cmd0_dat {
++                      pinmux = <PINMUX_GPIO12__FUNC_B_GPIO12>;
++                      bias-pull-up;
++                      input-enable;
++              };
++      };
++
++      spi0_pins: spi0-pins {
++              pins-spi {
++                      pinmux = <PINMUX_GPIO69__FUNC_O_SPIM0_CSB>,
++                              <PINMUX_GPIO70__FUNC_O_SPIM0_CLK>,
++                              <PINMUX_GPIO71__FUNC_B0_SPIM0_MOSI>,
++                              <PINMUX_GPIO72__FUNC_B0_SPIM0_MISO>;
++                      bias-disable;
++              };
++      };
++
++      spi1_pins: spi1-pins {
++              pins-spi {
++                      pinmux = <PINMUX_GPIO75__FUNC_O_SPIM1_CSB>,
++                              <PINMUX_GPIO76__FUNC_O_SPIM1_CLK>,
++                              <PINMUX_GPIO77__FUNC_B0_SPIM1_MOSI>,
++                              <PINMUX_GPIO78__FUNC_B0_SPIM1_MISO>;
++                      bias-disable;
++              };
++      };
++
++      spi2_pins: spi2-pins {
++              pins-spi {
++                      pinmux = <PINMUX_GPIO79__FUNC_O_SPIM2_CSB>,
++                              <PINMUX_GPIO80__FUNC_O_SPIM2_CLK>,
++                              <PINMUX_GPIO81__FUNC_B0_SPIM2_MOSI>,
++                              <PINMUX_GPIO82__FUNC_B0_SPIM2_MISO>;
++                      bias-disable;
++              };
++      };
++
++      touch_pins: touch-pins {
++              pins-irq {
++                      pinmux = <PINMUX_GPIO6__FUNC_B_GPIO6>;
++                      input-enable;
++                      bias-disable;
++              };
++
++              pins-reset {
++                      pinmux = <PINMUX_GPIO5__FUNC_B_GPIO5>;
++                      output-high;
++              };
++      };
++
++      uart0_pins: uart0-pins {
++              pins {
++                      pinmux = <PINMUX_GPIO31__FUNC_O_UTXD0>,
++                               <PINMUX_GPIO32__FUNC_I1_URXD0>;
++                      bias-pull-up;
++              };
++      };
++
++      uart1_pins: uart1-pins {
++              pins {
++                      pinmux = <PINMUX_GPIO33__FUNC_O_UTXD1>,
++                               <PINMUX_GPIO34__FUNC_I1_URXD1>;
++                      bias-pull-up;
++              };
++      };
++
++      uart2_pins: uart2-pins {
++              pins {
++                      pinmux = <PINMUX_GPIO35__FUNC_O_UTXD2>,
++                               <PINMUX_GPIO36__FUNC_I1_URXD2>;
++                      bias-pull-up;
++              };
++      };
++
++      usb_default_pins: usb-default-pins {
++              pins-iddig {
++                      pinmux = <PINMUX_GPIO83__FUNC_B_GPIO83>;
++                      input-enable;
++                      bias-pull-up;
++              };
++
++              pins-valid {
++                      pinmux = <PINMUX_GPIO85__FUNC_I0_VBUSVALID>;
++                      input-enable;
++              };
++
++              pins-vbus {
++                      pinmux = <PINMUX_GPIO84__FUNC_O_USB_DRVVBUS>;
++                      output-high;
++              };
++
++      };
++
++      usb1_default_pins: usb1-default-pins {
++              pins-valid {
++                      pinmux = <PINMUX_GPIO88__FUNC_I0_VBUSVALID_1P>;
++                      input-enable;
++              };
++
++              pins-usb-hub-3v3-en {
++                      pinmux = <PINMUX_GPIO112__FUNC_B_GPIO112>;
++                      output-high;
++              };
++      };
++
++      wifi_pwrseq_pins: wifi-pwrseq-pins {
++              pins-wifi-enable {
++                      pinmux = <PINMUX_GPIO127__FUNC_B_GPIO127>;
++                      output-low;
++              };
++      };
++};
++
++&eth {
++      phy-mode ="rgmii-id";
++      phy-handle = <&ethernet_phy0>;
++      pinctrl-names = "default", "sleep";
++      pinctrl-0 = <&eth_default_pins>;
++      pinctrl-1 = <&eth_sleep_pins>;
++      mediatek,mac-wol;
++      snps,reset-gpio = <&pio 147 GPIO_ACTIVE_HIGH>;
++      snps,reset-delays-us = <0 10000 10000>;
++      status = "okay";
++};
++
++&eth_mdio {
++      ethernet_phy0: ethernet-phy@1 {
++              compatible = "ethernet-phy-id001c.c916";
++              reg = <0x1>;
++      };
++};
++
++&pmic {
++      interrupt-parent = <&pio>;
++      interrupts = <222 IRQ_TYPE_LEVEL_HIGH>;
++
++      mt6359keys: keys {
++              compatible = "mediatek,mt6359-keys";
++              mediatek,long-press-mode = <1>;
++              power-off-time-sec = <0>;
++
++              power-key {
++                      linux,keycodes = <KEY_POWER>;
++                      wakeup-source;
++              };
++      };
++};
++
++&scp {
++      memory-region = <&scp_mem>;
++      status = "okay";
++};
++
++&sound {
++      compatible = "mediatek,mt8390-mt6359-evk", "mediatek,mt8188-mt6359-evb";
++      model = "mt8390-evk";
++      pinctrl-names = "default";
++      pinctrl-0 = <&audio_default_pins>;
++      audio-routing =
++              "Headphone", "Headphone L",
++              "Headphone", "Headphone R";
++      mediatek,adsp = <&adsp>;
++      status = "okay";
++
++      dai-link-0 {
++              link-name = "DL_SRC_BE";
++
++              codec {
++                      sound-dai = <&pmic 0>;
++              };
++      };
++};
++
++&spi2 {
++      pinctrl-0 = <&spi2_pins>;
++      pinctrl-names = "default";
++      mediatek,pad-select = <0>;
++      #address-cells = <1>;
++      #size-cells = <0>;
++      status = "okay";
++};
++
++&uart0 {
++      pinctrl-0 = <&uart0_pins>;
++      pinctrl-names = "default";
++      status = "okay";
++};
++
++&uart1 {
++      pinctrl-0 = <&uart1_pins>;
++      pinctrl-names = "default";
++      status = "okay";
++};
++
++&uart2 {
++      pinctrl-0 = <&uart2_pins>;
++      pinctrl-names = "default";
++      status = "okay";
++};
++
++&u3phy0 {
++      status = "okay";
++};
++
++&u3phy1 {
++      status = "okay";
++};
++
++&u3phy2 {
++      status = "okay";
++};
++
++&xhci0 {
++      status = "okay";
++      vusb33-supply = <&mt6359_vusb_ldo_reg>;
++};
++
++&xhci1 {
++      status = "okay";
++      vusb33-supply = <&mt6359_vusb_ldo_reg>;
++      #address-cells = <1>;
++      #size-cells = <0>;
++
++      hub_2_0: hub@1 {
++              compatible = "usb451,8025";
++              reg = <1>;
++              peer-hub = <&hub_3_0>;
++              reset-gpios = <&pio 7 GPIO_ACTIVE_HIGH>;
++              vdd-supply = <&usb_hub_fixed_3v3>;
++      };
++
++      hub_3_0: hub@2 {
++              compatible = "usb451,8027";
++              reg = <2>;
++              peer-hub = <&hub_2_0>;
++              reset-gpios = <&pio 7 GPIO_ACTIVE_HIGH>;
++              vdd-supply = <&usb_hub_fixed_3v3>;
++      };
++};
++
++&xhci2 {
++      status = "okay";
++      vusb33-supply = <&mt6359_vusb_ldo_reg>;
++      vbus-supply = <&sdio_fixed_3v3>; /* wifi_3v3 */
++};
+-- 
+2.39.5
+
diff --git a/queue-6.14/arm64-dts-mediatek-mt8390-genio-common-fix-duplicate.patch b/queue-6.14/arm64-dts-mediatek-mt8390-genio-common-fix-duplicate.patch
new file mode 100644 (file)
index 0000000..510a091
--- /dev/null
@@ -0,0 +1,39 @@
+From 273b782e8415bcdf1bd410ccdb21fb21ec19faae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Feb 2025 09:49:52 +0100
+Subject: arm64: dts: mediatek: mt8390-genio-common: Fix duplicated regulator
+ name
+
+From: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
+
+[ Upstream commit 18aa138d125dd56838edbdb8c813e91e5e95d496 ]
+
+usb_p2_vbus regulator has the same regulator-name property value as
+sdio_fixed_3v3, so change it to avoid this.
+
+Fixes: a4fd1943bf9b ("arm64: dts: mediatek: mt8390-genio-700-evk: update regulator names")
+Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20250221-fix-mtk8390-genio-common-dup-regulator-name-v1-1-92f7b9f7a414@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/mt8390-genio-common.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 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 a37cf102a6e92..e828864433a6f 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8390-genio-common.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8390-genio-common.dtsi
+@@ -213,7 +213,7 @@
+       /* used by ssusb2 */
+       usb_p2_vbus: regulator-9 {
+               compatible = "regulator-fixed";
+-              regulator-name = "wifi_3v3";
++              regulator-name = "vbus_p2";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               enable-active-high;
+-- 
+2.39.5
+
diff --git a/queue-6.14/arm64-dts-renesas-r8a774c0-re-add-voltages-to-opp-ta.patch b/queue-6.14/arm64-dts-renesas-r8a774c0-re-add-voltages-to-opp-ta.patch
new file mode 100644 (file)
index 0000000..a442af7
--- /dev/null
@@ -0,0 +1,61 @@
+From cd29b6175b6c4e82171a6c5a9cc23c6a8b9706da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Oct 2024 11:14:20 +0200
+Subject: arm64: dts: renesas: r8a774c0: Re-add voltages to OPP table
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit ea34dd0f029f4a30c055ddb6daaf7a6f3bee21ed ]
+
+When CONFIG_ENERGY_MODEL=y:
+
+    cpu cpu0: EM: invalid perf. state: -22
+
+When removing the (incorrect) voltages from the Operating Points
+Parameters tables, it was assumed they were optional, and unused, when
+none of the CPU nodes is tied to a regulator using the "cpu-supply"
+property.  This assumption turned out to be incorrect, causing the
+reported error message.
+
+Fix this by re-adding the (correct) voltages.  Note that because all
+voltages are identical, all operating points are considered to have the
+same efficiency, and the energy model always picks the one with the
+highest clock rate.
+
+Reported-by: Renesas Test Team via Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Fixes: 554edc3e9239bb81 ("arm64: dts: renesas: r8a774c0: Remove bogus voltages from OPP table")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/2046da75f3db95b62f86c0482063c4d04c2b47d5.1728377971.git.geert+renesas@glider.be
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/renesas/r8a774c0.dtsi | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
+index 7655d5e3a0341..522e20924e94a 100644
+--- a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
+@@ -47,16 +47,20 @@
+       cluster1_opp: opp-table-1 {
+               compatible = "operating-points-v2";
+               opp-shared;
++
+               opp-800000000 {
+                       opp-hz = /bits/ 64 <800000000>;
++                      opp-microvolt = <1030000>;
+                       clock-latency-ns = <300000>;
+               };
+               opp-1000000000 {
+                       opp-hz = /bits/ 64 <1000000000>;
++                      opp-microvolt = <1030000>;
+                       clock-latency-ns = <300000>;
+               };
+               opp-1200000000 {
+                       opp-hz = /bits/ 64 <1200000000>;
++                      opp-microvolt = <1030000>;
+                       clock-latency-ns = <300000>;
+                       opp-suspend;
+               };
+-- 
+2.39.5
+
diff --git a/queue-6.14/arm64-dts-renesas-r8a77990-re-add-voltages-to-opp-ta.patch b/queue-6.14/arm64-dts-renesas-r8a77990-re-add-voltages-to-opp-ta.patch
new file mode 100644 (file)
index 0000000..301707c
--- /dev/null
@@ -0,0 +1,61 @@
+From 6725d4bd494632ab2a62031a583c6c4da0608471 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Oct 2024 11:14:21 +0200
+Subject: arm64: dts: renesas: r8a77990: Re-add voltages to OPP table
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit c193f877770291f30d1e00bc6f2bb0757fe7a532 ]
+
+When CONFIG_ENERGY_MODEL=y:
+
+    cpu cpu0: EM: invalid perf. state: -22
+
+When removing the (incorrect) voltages from the Operating Points
+Parameters tables, it was assumed they were optional, and unused, when
+none of the CPU nodes is tied to a regulator using the "cpu-supply"
+property.  This assumption turned out to be incorrect, causing the
+reported error message.
+
+Fix this by re-adding the (correct) voltages.  Note that because all
+voltages are identical, all operating points are considered to have the
+same efficiency, and the energy model always picks the one with the
+highest clock rate.
+
+Reported-by: Renesas Test Team via Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Fixes: fb76b0fae3ca8803 ("arm64: dts: renesas: r8a77990: Remove bogus voltages from OPP table")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/80890bc244670bc3e8d6fc89fb2c3cb23e7025f5.1728377971.git.geert+renesas@glider.be
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/renesas/r8a77990.dtsi | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
+index 233af3081e84a..50fbf7251665a 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
+@@ -47,16 +47,20 @@
+       cluster1_opp: opp-table-1 {
+               compatible = "operating-points-v2";
+               opp-shared;
++
+               opp-800000000 {
+                       opp-hz = /bits/ 64 <800000000>;
++                      opp-microvolt = <1030000>;
+                       clock-latency-ns = <300000>;
+               };
+               opp-1000000000 {
+                       opp-hz = /bits/ 64 <1000000000>;
++                      opp-microvolt = <1030000>;
+                       clock-latency-ns = <300000>;
+               };
+               opp-1200000000 {
+                       opp-hz = /bits/ 64 <1200000000>;
++                      opp-microvolt = <1030000>;
+                       clock-latency-ns = <300000>;
+                       opp-suspend;
+               };
+-- 
+2.39.5
+
diff --git a/queue-6.14/arm64-dts-rockchip-fix-pcie-reset-gpio-on-orange-pi-.patch b/queue-6.14/arm64-dts-rockchip-fix-pcie-reset-gpio-on-orange-pi-.patch
new file mode 100644 (file)
index 0000000..beae3b8
--- /dev/null
@@ -0,0 +1,38 @@
+From 73b59636f65a3f380ea79636140bba432bd1bc4c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Mar 2025 22:12:39 +0800
+Subject: arm64: dts: rockchip: Fix pcie reset gpio on Orange Pi 5 Max
+
+From: Jianfeng Liu <liujianfeng1994@gmail.com>
+
+[ Upstream commit e0945a08fc7f7ed26c8dae286a3d30a68ad37d50 ]
+
+According to the schematic, pcie reset gpio is GPIO3_D4,
+not GPIO4_D4.
+
+Fixes: c600d252dc52 ("arm64: dts: rockchip: Add Orange Pi 5 Max board")
+Signed-off-by: Jianfeng Liu <liujianfeng1994@gmail.com>
+Reviewed-by: Jimmy Hon <honyuenkwun@gmail.com>
+Link: https://lore.kernel.org/r/20250311141245.2719796-1-liujianfeng1994@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-compact.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-compact.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-compact.dtsi
+index 87090cb98020b..bcf3cf704a00e 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-compact.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-compact.dtsi
+@@ -73,7 +73,7 @@
+ /* phy2 */
+ &pcie2x1l1 {
+-      reset-gpios = <&gpio4 RK_PD4 GPIO_ACTIVE_HIGH>;
++      reset-gpios = <&gpio3 RK_PD4 GPIO_ACTIVE_HIGH>;
+       vpcie3v3-supply = <&vcc3v3_pcie_eth>;
+       status = "okay";
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.14/arm64-dts-rockchip-fix-pwm-pinctrl-names.patch b/queue-6.14/arm64-dts-rockchip-fix-pwm-pinctrl-names.patch
new file mode 100644 (file)
index 0000000..a0f781a
--- /dev/null
@@ -0,0 +1,91 @@
+From 44db6910476fc4e5b8a2ef7ed2755b9a31f97bac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Mar 2025 14:09:17 +0000
+Subject: arm64: dts: rockchip: Fix PWM pinctrl names
+
+From: Yao Zi <ziyao@disroot.org>
+
+[ Upstream commit 09b0a7b63a6cda138e2e47c6acb2aee80338624c ]
+
+These Rockchip boards assign "active" as the pinctrl name for PWM
+controllers, which has never been supported in mainline Rockchip PWM
+driver. It seems the name used by downstream kernel is accidentally
+brought into maineline. Let's fix them.
+
+Fixes: 4403e1237be3 ("arm64: dts: rockchip: Add devicetree for board roc-rk3308-cc")
+Fixes: 964ed0807b5f ("arm64: dts: rockchip: add rk3318 A95X Z2 board")
+Fixes: e7a095908227 ("arm64: dts: rockchip: Add devicetree for NanoPC-T4")
+Fixes: 3f5d336d64d6 ("arm64: dts: rockchip: Add support for rk3588s based board Cool Pi 4B")
+Signed-off-by: Yao Zi <ziyao@disroot.org>
+Link: https://lore.kernel.org/r/20250310140916.14384-2-ziyao@disroot.org
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts     | 2 +-
+ arch/arm64/boot/dts/rockchip/rk3318-a95x-z2.dts    | 4 ++--
+ arch/arm64/boot/dts/rockchip/rk3399-nanopi4.dtsi   | 2 +-
+ arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts | 2 +-
+ 4 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts
+index 629121de5a13d..5e71819489920 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts
+@@ -147,7 +147,7 @@
+ &pwm5 {
+       status = "okay";
+-      pinctrl-names = "active";
++      pinctrl-names = "default";
+       pinctrl-0 = <&pwm5_pin_pull_down>;
+ };
+diff --git a/arch/arm64/boot/dts/rockchip/rk3318-a95x-z2.dts b/arch/arm64/boot/dts/rockchip/rk3318-a95x-z2.dts
+index a94114fb7cc1d..96c27fc5005d1 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3318-a95x-z2.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3318-a95x-z2.dts
+@@ -274,13 +274,13 @@
+ &pwm0 {
+       pinctrl-0 = <&pwm0_pin_pull_up>;
+-      pinctrl-names = "active";
++      pinctrl-names = "default";
+       status = "okay";
+ };
+ &pwm1 {
+       pinctrl-0 = <&pwm1_pin_pull_up>;
+-      pinctrl-names = "active";
++      pinctrl-names = "default";
+       status = "okay";
+ };
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-nanopi4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-nanopi4.dtsi
+index b169be06d4d1f..c8eb5481f43d0 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399-nanopi4.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopi4.dtsi
+@@ -603,7 +603,7 @@
+ };
+ &pwm2 {
+-      pinctrl-names = "active";
++      pinctrl-names = "default";
+       pinctrl-0 = <&pwm2_pin_pull_down>;
+       status = "okay";
+ };
+diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts b/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts
+index 9c394f733bbfb..b2c30122aacc5 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts
+@@ -429,7 +429,7 @@
+ };
+ &pwm13 {
+-      pinctrl-names = "active";
++      pinctrl-names = "default";
+       pinctrl-0 = <&pwm13m2_pins>;
+       status = "okay";
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.14/arm64-dts-rockchip-move-rk356x-scmi-shmem-to-reserve.patch b/queue-6.14/arm64-dts-rockchip-move-rk356x-scmi-shmem-to-reserve.patch
new file mode 100644 (file)
index 0000000..60d424c
--- /dev/null
@@ -0,0 +1,67 @@
+From 595c29081ddee4e94067a8f489637cbd9408982f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Mar 2025 18:00:01 +0800
+Subject: arm64: dts: rockchip: Move rk356x scmi SHMEM to reserved memory
+
+From: Chukun Pan <amadeus@jmu.edu.cn>
+
+[ Upstream commit 8fbb9376f0c489dfdc7e20d16e90686b29dec8f2 ]
+
+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: a3adc0b9071d ("arm64: dts: rockchip: add core dtsi for RK3568 SoC")
+Signed-off-by: Chukun Pan <amadeus@jmu.edu.cn>
+Link: https://lore.kernel.org/r/20250308100001.572657-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/rk356x-base.dtsi | 25 +++++++++----------
+ 1 file changed, 12 insertions(+), 13 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
+index e553906291140..8421d4b8c7719 100644
+--- a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
+@@ -174,6 +174,18 @@
+               method = "smc";
+       };
++      reserved-memory {
++              #address-cells = <2>;
++              #size-cells = <2>;
++              ranges;
++
++              scmi_shmem: shmem@10f000 {
++                      compatible = "arm,scmi-shmem";
++                      reg = <0x0 0x0010f000 0x0 0x100>;
++                      no-map;
++              };
++      };
++
+       timer {
+               compatible = "arm,armv8-timer";
+               interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH>,
+@@ -199,19 +211,6 @@
+               #clock-cells = <0>;
+       };
+-      sram@10f000 {
+-              compatible = "mmio-sram";
+-              reg = <0x0 0x0010f000 0x0 0x100>;
+-              #address-cells = <1>;
+-              #size-cells = <1>;
+-              ranges = <0 0x0 0x0010f000 0x100>;
+-
+-              scmi_shmem: sram@0 {
+-                      compatible = "arm,scmi-shmem";
+-                      reg = <0x0 0x100>;
+-              };
+-      };
+-
+       sata1: sata@fc400000 {
+               compatible = "rockchip,rk3568-dwc-ahci", "snps,dwc-ahci";
+               reg = <0 0xfc400000 0 0x1000>;
+-- 
+2.39.5
+
diff --git a/queue-6.14/arm64-dts-rockchip-remove-bluetooth-node-from-rock-3.patch b/queue-6.14/arm64-dts-rockchip-remove-bluetooth-node-from-rock-3.patch
new file mode 100644 (file)
index 0000000..492d6ab
--- /dev/null
@@ -0,0 +1,53 @@
+From 23e160a095adec86821e172347c406b70088118b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Feb 2025 00:50:51 +0800
+Subject: arm64: dts: rockchip: Remove bluetooth node from rock-3a
+
+From: Chen-Yu Tsai <wens@csie.org>
+
+[ Upstream commit 6b68387cf5ff5d7b86b189135affb0c679e3384a ]
+
+The Bluetooth node described in the device tree is actually on an M.2
+slot. What module is present depends on what the end user installed,
+and should be left to an overlay.
+
+Remove the existing bluetooth node. This gets rid of bogus timeout
+errors.
+
+Fixes: 8cf890aabd45 ("arm64: dts: rockchip: Add nodes for SDIO/UART Wi-Fi/Bluetooth modules to Radxa Rock 3A")
+Signed-off-by: Chen-Yu Tsai <wens@csie.org>
+Link: https://lore.kernel.org/r/20250220165051.1889055-1-wens@kernel.org
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts | 14 --------------
+ 1 file changed, 14 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
+index ac79140a9ecd6..44cfdfeed6681 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
+@@ -778,20 +778,6 @@
+       pinctrl-0 = <&uart1m0_xfer &uart1m0_ctsn &uart1m0_rtsn>;
+       uart-has-rtscts;
+       status = "okay";
+-
+-      bluetooth {
+-              compatible = "brcm,bcm43438-bt";
+-              clocks = <&rk809 1>;
+-              clock-names = "lpo";
+-              device-wakeup-gpios = <&gpio4 RK_PB5 GPIO_ACTIVE_HIGH>;
+-              host-wakeup-gpios = <&gpio4 RK_PB4 GPIO_ACTIVE_HIGH>;
+-              shutdown-gpios = <&gpio4 RK_PB2 GPIO_ACTIVE_HIGH>;
+-              pinctrl-names = "default";
+-              pinctrl-0 = <&bt_host_wake &bt_wake &bt_enable>;
+-              vbat-supply = <&vcc3v3_sys>;
+-              vddio-supply = <&vcc_1v8>;
+-              /* vddio comes from regulator on module, use IO bank voltage instead */
+-      };
+ };
+ &uart2 {
+-- 
+2.39.5
+
diff --git a/queue-6.14/arm64-dts-rockchip-remove-ethm0_clk0_25m_out-from-si.patch b/queue-6.14/arm64-dts-rockchip-remove-ethm0_clk0_25m_out-from-si.patch
new file mode 100644 (file)
index 0000000..616a4df
--- /dev/null
@@ -0,0 +1,51 @@
+From cb9456de3136fee760ab3a2678b5f6c81a6934f0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Mar 2025 16:35:50 +0100
+Subject: arm64: dts: rockchip: remove ethm0_clk0_25m_out from Sige5 gmac0
+
+From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
+
+[ Upstream commit 73d246b4402c3356f6b3d13665de3a51eea7b555 ]
+
+The GPIO3 A4 pin on the ArmSoM Sige5 is routed to the 40-pin GPIO
+header. This pin can serve a variety of functions, including ones of
+questionable use to us on a GPIO header such as the 25MHz clock of the
+ethernet controller.
+
+Unfortunately, this is the precise function that it is being claimed for
+by the gmac0 node in the Sige5 board dts, meaning it can't be used for
+anything else despite serving no useful function in this role. Since it
+goes through a RS0108 bidirectional voltage level translator with a
+maximum data rate of 24Mbit/s in push-pull mode and 2Mbit/s data rate in
+open-drain mode, it's doubtful as to whether the 25MHz clock signal
+would even survive to the actual user-accessible pin it terminates in.
+
+Remove it to leave the pin for users to play with. It's infinitely more
+useful as a GPIO or even as a PWM.
+
+Fixes: 40f742b07ab2 ("arm64: dts: rockchip: Add rk3576-armsom-sige5 board")
+Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
+Link: https://lore.kernel.org/r/20250314-rk3576-sige5-eth-clk-begone-v1-1-2858338fc555@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/rockchip/rk3576-armsom-sige5.dts | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/rockchip/rk3576-armsom-sige5.dts b/arch/arm64/boot/dts/rockchip/rk3576-armsom-sige5.dts
+index 7c7331936a7fd..a9b9db31d2a3e 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3576-armsom-sige5.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3576-armsom-sige5.dts
+@@ -182,8 +182,7 @@
+                    &eth0m0_tx_bus2
+                    &eth0m0_rx_bus2
+                    &eth0m0_rgmii_clk
+-                   &eth0m0_rgmii_bus
+-                   &ethm0_clk0_25m_out>;
++                   &eth0m0_rgmii_bus>;
+       phy-handle = <&rgmii_phy0>;
+       status = "okay";
+-- 
+2.39.5
+
diff --git a/queue-6.14/arm64-dts-ti-k3-am62-verdin-dahlia-add-microphone-ja.patch b/queue-6.14/arm64-dts-ti-k3-am62-verdin-dahlia-add-microphone-ja.patch
new file mode 100644 (file)
index 0000000..8101c59
--- /dev/null
@@ -0,0 +1,51 @@
+From df562fa576be720a5c3ae7e6d385975958ea89dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 15:46:04 +0100
+Subject: arm64: dts: ti: k3-am62-verdin-dahlia: add Microphone Jack to sound
+ card
+
+From: Stefan Eichenberger <stefan.eichenberger@toradex.com>
+
+[ Upstream commit 7139df64e7c13c079b754476355c62b490213055 ]
+
+The simple-audio-card's microphone widget currently connects to the
+headphone jack. Routing the microphone input to the microphone jack
+allows for independent operation of the microphone and headphones.
+
+This resolves the following boot-time kernel log message, which
+indicated a conflict when the microphone and headphone functions were
+not separated:
+  debugfs: File 'Headphone Jack' in directory 'dapm' already present!
+
+Fixes: f5bf894c865b ("arm64: dts: ti: verdin-am62: dahlia: add sound card")
+Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
+Reviewed-by: Francesco Dolcini <francesco.dolcini@toradex.com>
+Reviewed-by: Jai Luthra <jai.luthra@linux.dev>
+Link: https://lore.kernel.org/r/20250217144643.178222-1-eichest@gmail.com
+Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi
+index 9202181fbd652..fcc4cb2e9389b 100644
+--- a/arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi
+@@ -28,10 +28,10 @@
+                       "Headphone Jack", "HPOUTR",
+                       "IN2L", "Line In Jack",
+                       "IN2R", "Line In Jack",
+-                      "Headphone Jack", "MICBIAS",
+-                      "IN1L", "Headphone Jack";
++                      "Microphone Jack", "MICBIAS",
++                      "IN1L", "Microphone Jack";
+               simple-audio-card,widgets =
+-                      "Microphone", "Headphone Jack",
++                      "Microphone", "Microphone Jack",
+                       "Headphone", "Headphone Jack",
+                       "Line", "Line In Jack";
+-- 
+2.39.5
+
diff --git a/queue-6.14/arm64-dts-ti-k3-am62p-enable-audio_refclkx.patch b/queue-6.14/arm64-dts-ti-k3-am62p-enable-audio_refclkx.patch
new file mode 100644 (file)
index 0000000..6021b02
--- /dev/null
@@ -0,0 +1,57 @@
+From 9476161bf4294fe4796ce46f84f5d5627a71ca51 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Feb 2025 16:39:11 +0100
+Subject: arm64: dts: ti: k3-am62p: Enable AUDIO_REFCLKx
+
+From: Francesco Dolcini <francesco.dolcini@toradex.com>
+
+[ Upstream commit 6a02c9aa222ce0fff47f526686690f84b7a97f4e ]
+
+On AM62P-based SoCs the AUDIO_REFCLKx clocks can be used as an input to
+external peripherals when configured through CTRL_MMR, so add the
+clock nodes.
+
+Link: http://downloads.ti.com/tisci/esd/latest/5_soc_doc/am62px/clocks.html
+Signed-off-by: Francesco Dolcini <francesco.dolcini@toradex.com>
+Link: https://lore.kernel.org/r/20250206153911.414702-1-francesco@dolcini.it
+Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
+Stable-dep-of: 33bab9d84e52 ("arm64: dts: ti: k3-am62p: fix pinctrl settings")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/ti/k3-am62p-main.dtsi | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
+index 420c77c8e9e5e..4b47b07743305 100644
+--- a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
+@@ -42,6 +42,26 @@
+       ti,interrupt-ranges = <5 69 35>;
+ };
++&main_conf {
++      audio_refclk0: clock-controller@82e0 {
++              compatible = "ti,am62-audio-refclk";
++              reg = <0x82e0 0x4>;
++              clocks = <&k3_clks 157 0>;
++              assigned-clocks = <&k3_clks 157 0>;
++              assigned-clock-parents = <&k3_clks 157 16>;
++              #clock-cells = <0>;
++      };
++
++      audio_refclk1: clock-controller@82e4 {
++              compatible = "ti,am62-audio-refclk";
++              reg = <0x82e4 0x4>;
++              clocks = <&k3_clks 157 18>;
++              assigned-clocks = <&k3_clks 157 18>;
++              assigned-clock-parents = <&k3_clks 157 34>;
++              #clock-cells = <0>;
++      };
++};
++
+ &main_pmx0 {
+       pinctrl-single,gpio-range =
+               <&main_pmx0_range 0 32 PIN_GPIO_RANGE_IOPAD>,
+-- 
+2.39.5
+
diff --git a/queue-6.14/arm64-dts-ti-k3-am62p-fix-pinctrl-settings.patch b/queue-6.14/arm64-dts-ti-k3-am62p-fix-pinctrl-settings.patch
new file mode 100644 (file)
index 0000000..5d7f937
--- /dev/null
@@ -0,0 +1,87 @@
+From 07ae7d3237fb73125737e34ad17009de6b67f8c4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Feb 2025 10:14:46 +0100
+Subject: arm64: dts: ti: k3-am62p: fix pinctrl settings
+
+From: Michael Walle <mwalle@kernel.org>
+
+[ Upstream commit 33bab9d84e52188cf73c3573fd7cf3ec0e01d007 ]
+
+It appears that pinctrl-single is misused on this SoC to control both
+the mux and the input and output and bias settings. This results in
+non-working pinctrl configurations for GPIOs within the device tree.
+
+This is what happens:
+ (1) During startup the pinctrl settings are applied according to the
+     device tree. I.e. the pin is configured as output and with
+     pull-ups enabled.
+ (2) During startup a device driver requests a GPIO.
+ (3) pinctrl-single is applying the default GPIO setting according to
+     the pinctrl-single,gpio-range property.
+
+This would work as expected if the pinctrl-single is only controlling
+the function mux, but it also controls the input/output buffer enable,
+the pull-up and pull-down settings etc (pinctrl-single,function-mask
+covers the entire pad setting instead of just the mux field).
+
+Remove the pinctrl-single,gpio-range property, so that no settings are
+applied during a gpio_request() call.
+
+Fixes: d72d73a44c3c ("arm64: dts: ti: k3-am62p: Add gpio-ranges properties")
+Signed-off-by: Michael Walle <mwalle@kernel.org>
+Link: https://lore.kernel.org/r/20250221091447.595199-1-mwalle@kernel.org
+Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../boot/dts/ti/k3-am62p-j722s-common-mcu.dtsi     |  8 --------
+ arch/arm64/boot/dts/ti/k3-am62p-main.dtsi          | 14 --------------
+ 2 files changed, 22 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-mcu.dtsi
+index b33aff0d65c9d..bd6a00d13aea7 100644
+--- a/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-mcu.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-mcu.dtsi
+@@ -12,15 +12,7 @@
+               #pinctrl-cells = <1>;
+               pinctrl-single,register-width = <32>;
+               pinctrl-single,function-mask = <0xffffffff>;
+-              pinctrl-single,gpio-range =
+-                      <&mcu_pmx_range 0 21 PIN_GPIO_RANGE_IOPAD>,
+-                      <&mcu_pmx_range 23 1 PIN_GPIO_RANGE_IOPAD>,
+-                      <&mcu_pmx_range 32 2 PIN_GPIO_RANGE_IOPAD>;
+               bootph-all;
+-
+-              mcu_pmx_range: gpio-range {
+-                      #pinctrl-single,gpio-range-cells = <3>;
+-              };
+       };
+       mcu_esm: esm@4100000 {
+diff --git a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
+index 4b47b07743305..6aea9d3f134e4 100644
+--- a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
+@@ -62,20 +62,6 @@
+       };
+ };
+-&main_pmx0 {
+-      pinctrl-single,gpio-range =
+-              <&main_pmx0_range 0 32 PIN_GPIO_RANGE_IOPAD>,
+-              <&main_pmx0_range 33 38 PIN_GPIO_RANGE_IOPAD>,
+-              <&main_pmx0_range 72 22 PIN_GPIO_RANGE_IOPAD>,
+-              <&main_pmx0_range 137 5 PIN_GPIO_RANGE_IOPAD>,
+-              <&main_pmx0_range 143 3 PIN_GPIO_RANGE_IOPAD>,
+-              <&main_pmx0_range 149 2 PIN_GPIO_RANGE_IOPAD>;
+-
+-      main_pmx0_range: gpio-range {
+-              #pinctrl-single,gpio-range-cells = <3>;
+-      };
+-};
+-
+ &main_gpio0 {
+       gpio-ranges = <&main_pmx0 0 0 32>, <&main_pmx0 32 33 38>,
+                       <&main_pmx0 70 72 22>;
+-- 
+2.39.5
+
diff --git a/queue-6.14/arm64-dts-ti-k3-j722s-evm-fix-usb2.0_mux_sel-to-sele.patch b/queue-6.14/arm64-dts-ti-k3-j722s-evm-fix-usb2.0_mux_sel-to-sele.patch
new file mode 100644 (file)
index 0000000..51ca1a1
--- /dev/null
@@ -0,0 +1,48 @@
+From 15093816191d069673d9648e89c286f6275d5e77 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jan 2025 18:27:26 +0530
+Subject: arm64: dts: ti: k3-j722s-evm: Fix USB2.0_MUX_SEL to select Type-C
+
+From: Hrushikesh Salunke <h-salunke@ti.com>
+
+[ Upstream commit bc8d9e6b5821c40ab5dd3a81e096cb114939de50 ]
+
+J722S SOC has two usb controllers USB0 and USB1. USB0 is brought out on
+the EVM as a stacked USB connector which has one Type-A and one Type-C
+port. These Type-A and Type-C ports are connected to MUX so only
+one of them can be enabled at a time.
+
+Commit under Fixes, tries to enable the USB0 instance of USB to
+interface with the Type-C port via the USB hub, by configuring the
+USB2.0_MUX_SEL to GPIO_ACTIVE_HIGH. But it is observed on J722S-EVM
+that Type-A port is enabled instead of Type-C port.
+
+Fix this by setting USB2.0_MUX_SEL to GPIO_ACTIVE_LOW to enable Type-C
+port.
+
+Fixes: 485705df5d5f ("arm64: dts: ti: k3-j722s: Enable PCIe and USB support on J722S-EVM")
+Signed-off-by: Hrushikesh Salunke <h-salunke@ti.com>
+Reviewed-by: Roger Quadros <rogerq@kernel.org>
+Link: https://lore.kernel.org/r/20250116125726.2549489-1-h-salunke@ti.com
+Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/ti/k3-j722s-evm.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/ti/k3-j722s-evm.dts b/arch/arm64/boot/dts/ti/k3-j722s-evm.dts
+index d184e9c1a0a59..adee69607fdbf 100644
+--- a/arch/arm64/boot/dts/ti/k3-j722s-evm.dts
++++ b/arch/arm64/boot/dts/ti/k3-j722s-evm.dts
+@@ -590,7 +590,7 @@
+               p05-hog {
+                       /* P05 - USB2.0_MUX_SEL */
+                       gpio-hog;
+-                      gpios = <5 GPIO_ACTIVE_HIGH>;
++                      gpios = <5 GPIO_ACTIVE_LOW>;
+                       output-high;
+               };
+-- 
+2.39.5
+
diff --git a/queue-6.14/arm64-dts-ti-k3-j722s-fix-pinctrl-settings.patch b/queue-6.14/arm64-dts-ti-k3-j722s-fix-pinctrl-settings.patch
new file mode 100644 (file)
index 0000000..ab0b29c
--- /dev/null
@@ -0,0 +1,67 @@
+From e3d0c431a66331b646452574ad0b400b8c030e17 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Feb 2025 10:14:47 +0100
+Subject: arm64: dts: ti: k3-j722s: fix pinctrl settings
+
+From: Michael Walle <mwalle@kernel.org>
+
+[ Upstream commit 06daad327d043c23bc1ab4cdb519f589094b9e98 ]
+
+It appears that pinctrl-single is misused on this SoC to control both
+the mux and the input and output and bias settings. This results in
+non-working pinctrl configurations for GPIOs within the device tree.
+
+This is what happens:
+ (1) During startup the pinctrl settings are applied according to the
+     device tree. I.e. the pin is configured as output and with
+     pull-ups enabled.
+ (2) During startup a device driver requests a GPIO.
+ (3) pinctrl-single is applying the default GPIO setting according to
+     the pinctrl-single,gpio-range property.
+
+This would work as expected if the pinctrl-single is only controlling
+the function mux, but it also controls the input/output buffer enable,
+the pull-up and pull-down settings etc (pinctrl-single,function-mask
+covers the entire pad setting instead of just the mux field).
+
+Remove the pinctrl-single,gpio-range property, so that no settings are
+applied during a gpio_request() call.
+
+Fixes: 5e5c50964e2e ("arm64: dts: ti: k3-j722s: Add gpio-ranges properties")
+Signed-off-by: Michael Walle <mwalle@kernel.org>
+Link: https://lore.kernel.org/r/20250221091447.595199-2-mwalle@kernel.org
+Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/ti/k3-j722s-main.dtsi | 15 ---------------
+ 1 file changed, 15 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/ti/k3-j722s-main.dtsi b/arch/arm64/boot/dts/ti/k3-j722s-main.dtsi
+index 3ac2d45a05585..6da7b3a2943c4 100644
+--- a/arch/arm64/boot/dts/ti/k3-j722s-main.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-j722s-main.dtsi
+@@ -251,21 +251,6 @@
+       ti,interrupt-ranges = <7 71 21>;
+ };
+-&main_pmx0 {
+-      pinctrl-single,gpio-range =
+-              <&main_pmx0_range 0 32 PIN_GPIO_RANGE_IOPAD>,
+-              <&main_pmx0_range 33 38 PIN_GPIO_RANGE_IOPAD>,
+-              <&main_pmx0_range 72 17 PIN_GPIO_RANGE_IOPAD>,
+-              <&main_pmx0_range 101 25 PIN_GPIO_RANGE_IOPAD>,
+-              <&main_pmx0_range 137 5 PIN_GPIO_RANGE_IOPAD>,
+-              <&main_pmx0_range 143 3 PIN_GPIO_RANGE_IOPAD>,
+-              <&main_pmx0_range 149 2 PIN_GPIO_RANGE_IOPAD>;
+-
+-      main_pmx0_range: gpio-range {
+-              #pinctrl-single,gpio-range-cells = <3>;
+-      };
+-};
+-
+ &main_gpio0 {
+       gpio-ranges = <&main_pmx0 0 0 32>, <&main_pmx0 32 33 38>,
+                       <&main_pmx0 70 72 17>;
+-- 
+2.39.5
+
diff --git a/queue-6.14/arm64-realm-use-aliased-addresses-for-device-dma-to-.patch b/queue-6.14/arm64-realm-use-aliased-addresses-for-device-dma-to-.patch
new file mode 100644 (file)
index 0000000..778a654
--- /dev/null
@@ -0,0 +1,66 @@
+From b245f1945344e7e8cf92c96e7ce6718e33a4dc85 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 14:41:50 +0000
+Subject: arm64: realm: Use aliased addresses for device DMA to shared buffers
+
+From: Suzuki K Poulose <suzuki.poulose@arm.com>
+
+[ Upstream commit 7d953a06241624ee2efb172d037a4168978f4147 ]
+
+When a device performs DMA to a shared buffer using physical addresses,
+(without Stage1 translation), the device must use the "{I}PA address" with the
+top bit set in Realm. This is to make sure that a trusted device will be able
+to write to shared buffers as well as the protected buffers. Thus, a Realm must
+always program the full address including the "protection" bit, like AMD SME
+encryption bits.
+
+Enable this by providing arm64 specific dma_addr_{encrypted, canonical}
+helpers for Realms. Please note that the VMM needs to similarly make sure that
+the SMMU Stage2 in the Non-secure world is setup accordingly to map IPA at the
+unprotected alias.
+
+Cc: Will Deacon <will@kernel.org>
+Cc: Jean-Philippe Brucker <jean-philippe@linaro.org>
+Cc: Robin Murphy <robin.murphy@arm.com>
+Cc: Steven Price <steven.price@arm.com>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Marek Szyprowski <m.szyprowski@samsung.com>
+Cc: Tom Lendacky <thomas.lendacky@amd.com>
+Cc: Aneesh Kumar K.V <aneesh.kumar@kernel.org>
+Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Reviewed-by: Gavin Shan <gshan@redhat.com>
+Acked-by: Catalin Marinas <catalin.marinas@arm.com>
+Reviewed-by: Robin Murphy <robin.murphy@arm.com>
+Acked-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Fixes: 42be24a4178f ("arm64: Enable memory encrypt for Realms")
+Acked-by: Will Deacon <will@kernel.org>
+Link: https://lore.kernel.org/r/20250227144150.1667735-4-suzuki.poulose@arm.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/include/asm/mem_encrypt.h | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/arch/arm64/include/asm/mem_encrypt.h b/arch/arm64/include/asm/mem_encrypt.h
+index f8f78f622dd2c..a2a1eeb36d4b5 100644
+--- a/arch/arm64/include/asm/mem_encrypt.h
++++ b/arch/arm64/include/asm/mem_encrypt.h
+@@ -21,4 +21,15 @@ static inline bool force_dma_unencrypted(struct device *dev)
+       return is_realm_world();
+ }
++/*
++ * For Arm CCA guests, canonical addresses are "encrypted", so no changes
++ * required for dma_addr_encrypted().
++ * The unencrypted DMA buffers must be accessed via the unprotected IPA,
++ * "top IPA bit" set.
++ */
++#define dma_addr_unencrypted(x)               ((x) | PROT_NS_SHARED)
++
++/* Clear the "top" IPA bit while converting back */
++#define dma_addr_canonical(x)         ((x) & ~PROT_NS_SHARED)
++
+ #endif        /* __ASM_MEM_ENCRYPT_H */
+-- 
+2.39.5
+
diff --git a/queue-6.14/asoc-amd-acp-fix-for-enabling-dmic-on-acp-platforms-.patch b/queue-6.14/asoc-amd-acp-fix-for-enabling-dmic-on-acp-platforms-.patch
new file mode 100644 (file)
index 0000000..6d37fd6
--- /dev/null
@@ -0,0 +1,60 @@
+From 50a3c72994f10d1bbc1f6b0588f0e06f84cfbeef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Mar 2025 00:02:01 +0530
+Subject: ASoC: amd: acp: Fix for enabling DMIC on acp platforms via _DSD entry
+
+From: Venkata Prasad Potturu <venkataprasad.potturu@amd.com>
+
+[ Upstream commit 02e1cf7a352a3ba5f768849f2b4fcaaaa19f89e3 ]
+
+Add condition check to register ACP PDM sound card by reading
+_WOV acpi entry.
+
+Fixes: 09068d624c49 ("ASoC: amd: acp: fix for acp platform device creation failure")
+
+Signed-off-by: Venkata Prasad Potturu <venkataprasad.potturu@amd.com>
+Link: https://patch.msgid.link/20250310183201.11979-15-venkataprasad.potturu@amd.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/amd/acp/acp-legacy-common.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/amd/acp/acp-legacy-common.c b/sound/soc/amd/acp/acp-legacy-common.c
+index 7acc7ed2e8cc9..b9f085c560c2d 100644
+--- a/sound/soc/amd/acp/acp-legacy-common.c
++++ b/sound/soc/amd/acp/acp-legacy-common.c
+@@ -13,6 +13,7 @@
+  */
+ #include "amd.h"
++#include <linux/acpi.h>
+ #include <linux/pci.h>
+ #include <linux/export.h>
+@@ -445,7 +446,9 @@ void check_acp_config(struct pci_dev *pci, struct acp_chip_info *chip)
+ {
+       struct acpi_device *pdm_dev;
+       const union acpi_object *obj;
+-      u32 pdm_addr;
++      acpi_handle handle;
++      acpi_integer dmic_status;
++      u32 pdm_addr, ret;
+       switch (chip->acp_rev) {
+       case ACP_RN_PCI_ID:
+@@ -477,6 +480,11 @@ void check_acp_config(struct pci_dev *pci, struct acp_chip_info *chip)
+                                                  obj->integer.value == pdm_addr)
+                               chip->is_pdm_dev = true;
+               }
++
++              handle = ACPI_HANDLE(&pci->dev);
++              ret = acpi_evaluate_integer(handle, "_WOV", NULL, &dmic_status);
++              if (!ACPI_FAILURE(ret))
++                      chip->is_pdm_dev = dmic_status;
+       }
+ }
+ EXPORT_SYMBOL_NS_GPL(check_acp_config, "SND_SOC_ACP_COMMON");
+-- 
+2.39.5
+
diff --git a/queue-6.14/asoc-codecs-rt5665-fix-some-error-handling-paths-in-.patch b/queue-6.14/asoc-codecs-rt5665-fix-some-error-handling-paths-in-.patch
new file mode 100644 (file)
index 0000000..b93ab09
--- /dev/null
@@ -0,0 +1,100 @@
+From 531c2c36f109ea20aa9f52855d747c7fee39d704 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 22 Mar 2025 08:45:49 +0100
+Subject: ASoC: codecs: rt5665: Fix some error handling paths in rt5665_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 1ebd4944266e86a7ce274f197847f5a6399651e8 ]
+
+Should an error occur after a successful regulator_bulk_enable() call,
+regulator_bulk_disable() should be called, as already done in the remove
+function.
+
+Instead of adding an error handling path in the probe, switch from
+devm_regulator_bulk_get() to devm_regulator_bulk_get_enable() and
+simplify the remove function and some other places accordingly.
+
+Finally, add a missing const when defining rt5665_supply_names to please
+checkpatch and constify a few bytes.
+
+Fixes: 33ada14a26c8 ("ASoC: add rt5665 codec driver")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://patch.msgid.link/e3c2aa1b2fdfa646752d94f4af968630c0d58248.1742629525.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/rt5665.c | 24 ++++--------------------
+ 1 file changed, 4 insertions(+), 20 deletions(-)
+
+diff --git a/sound/soc/codecs/rt5665.c b/sound/soc/codecs/rt5665.c
+index 47df14ba52784..4f0236b34a2d9 100644
+--- a/sound/soc/codecs/rt5665.c
++++ b/sound/soc/codecs/rt5665.c
+@@ -31,9 +31,7 @@
+ #include "rl6231.h"
+ #include "rt5665.h"
+-#define RT5665_NUM_SUPPLIES 3
+-
+-static const char *rt5665_supply_names[RT5665_NUM_SUPPLIES] = {
++static const char * const rt5665_supply_names[] = {
+       "AVDD",
+       "MICVDD",
+       "VBAT",
+@@ -46,7 +44,6 @@ struct rt5665_priv {
+       struct gpio_desc *gpiod_ldo1_en;
+       struct gpio_desc *gpiod_reset;
+       struct snd_soc_jack *hs_jack;
+-      struct regulator_bulk_data supplies[RT5665_NUM_SUPPLIES];
+       struct delayed_work jack_detect_work;
+       struct delayed_work calibrate_work;
+       struct delayed_work jd_check_work;
+@@ -4471,8 +4468,6 @@ static void rt5665_remove(struct snd_soc_component *component)
+       struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component);
+       regmap_write(rt5665->regmap, RT5665_RESET, 0);
+-
+-      regulator_bulk_disable(ARRAY_SIZE(rt5665->supplies), rt5665->supplies);
+ }
+ #ifdef CONFIG_PM
+@@ -4758,7 +4753,7 @@ static int rt5665_i2c_probe(struct i2c_client *i2c)
+ {
+       struct rt5665_platform_data *pdata = dev_get_platdata(&i2c->dev);
+       struct rt5665_priv *rt5665;
+-      int i, ret;
++      int ret;
+       unsigned int val;
+       rt5665 = devm_kzalloc(&i2c->dev, sizeof(struct rt5665_priv),
+@@ -4774,24 +4769,13 @@ static int rt5665_i2c_probe(struct i2c_client *i2c)
+       else
+               rt5665_parse_dt(rt5665, &i2c->dev);
+-      for (i = 0; i < ARRAY_SIZE(rt5665->supplies); i++)
+-              rt5665->supplies[i].supply = rt5665_supply_names[i];
+-
+-      ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(rt5665->supplies),
+-                                    rt5665->supplies);
++      ret = devm_regulator_bulk_get_enable(&i2c->dev, ARRAY_SIZE(rt5665_supply_names),
++                                           rt5665_supply_names);
+       if (ret != 0) {
+               dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
+               return ret;
+       }
+-      ret = regulator_bulk_enable(ARRAY_SIZE(rt5665->supplies),
+-                                  rt5665->supplies);
+-      if (ret != 0) {
+-              dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
+-              return ret;
+-      }
+-
+-
+       rt5665->gpiod_ldo1_en = devm_gpiod_get_optional(&i2c->dev,
+                                                       "realtek,ldo1-en",
+                                                       GPIOD_OUT_HIGH);
+-- 
+2.39.5
+
diff --git a/queue-6.14/asoc-cs35l41-check-the-return-value-from-spi_setup.patch b/queue-6.14/asoc-cs35l41-check-the-return-value-from-spi_setup.patch
new file mode 100644 (file)
index 0000000..06ef98e
--- /dev/null
@@ -0,0 +1,52 @@
+From 5512eebee85118bbc097ad4a7273d30673910879 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Mar 2025 16:56:37 +0500
+Subject: ASoC: cs35l41: check the return value from spi_setup()
+
+From: Vitaliy Shevtsov <v.shevtsov@mt-integration.ru>
+
+[ Upstream commit ad5a0970f86d82e39ebd06d45a1f7aa48a1316f8 ]
+
+Currently the return value from spi_setup() is not checked for a failure.
+It is unlikely it will ever fail in this particular case but it is still
+better to add this check for the sake of completeness and correctness. This
+is cheap since it is performed once when the device is being probed.
+
+Handle spi_setup() return value.
+
+Found by Linux Verification Center (linuxtesting.org) with Svace.
+
+Fixes: 872fc0b6bde8 ("ASoC: cs35l41: Set the max SPI speed for the whole device")
+Signed-off-by: Vitaliy Shevtsov <v.shevtsov@mt-integration.ru>
+Link: https://patch.msgid.link/20250304115643.2748-1-v.shevtsov@mt-integration.ru
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/cs35l41-spi.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/codecs/cs35l41-spi.c b/sound/soc/codecs/cs35l41-spi.c
+index a6db44520c060..f9b6bf7bea9c9 100644
+--- a/sound/soc/codecs/cs35l41-spi.c
++++ b/sound/soc/codecs/cs35l41-spi.c
+@@ -32,13 +32,16 @@ static int cs35l41_spi_probe(struct spi_device *spi)
+       const struct regmap_config *regmap_config = &cs35l41_regmap_spi;
+       struct cs35l41_hw_cfg *hw_cfg = dev_get_platdata(&spi->dev);
+       struct cs35l41_private *cs35l41;
++      int ret;
+       cs35l41 = devm_kzalloc(&spi->dev, sizeof(struct cs35l41_private), GFP_KERNEL);
+       if (!cs35l41)
+               return -ENOMEM;
+       spi->max_speed_hz = CS35L41_SPI_MAX_FREQ;
+-      spi_setup(spi);
++      ret = spi_setup(spi);
++      if (ret < 0)
++              return ret;
+       spi_set_drvdata(spi, cs35l41);
+       cs35l41->regmap = devm_regmap_init_spi(spi, regmap_config);
+-- 
+2.39.5
+
diff --git a/queue-6.14/asoc-imx-card-add-null-check-in-imx_card_probe.patch b/queue-6.14/asoc-imx-card-add-null-check-in-imx_card_probe.patch
new file mode 100644 (file)
index 0000000..e18cdb7
--- /dev/null
@@ -0,0 +1,50 @@
+From d667c0625a28635bf8329f012560dfb83824fa60 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 22:25:10 +0800
+Subject: ASoC: imx-card: Add NULL check in imx_card_probe()
+
+From: Henry Martin <bsdhenrymartin@gmail.com>
+
+[ Upstream commit 93d34608fd162f725172e780b1c60cc93a920719 ]
+
+devm_kasprintf() returns NULL when memory allocation fails. Currently,
+imx_card_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: aa736700f42f ("ASoC: imx-card: Add imx-card machine driver")
+Signed-off-by: Henry Martin <bsdhenrymartin@gmail.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://patch.msgid.link/20250401142510.29900-1-bsdhenrymartin@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/imx-card.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/sound/soc/fsl/imx-card.c b/sound/soc/fsl/imx-card.c
+index ac043ad367ace..21f617f6f9fa8 100644
+--- a/sound/soc/fsl/imx-card.c
++++ b/sound/soc/fsl/imx-card.c
+@@ -767,6 +767,8 @@ static int imx_card_probe(struct platform_device *pdev)
+                               data->dapm_routes[i].sink =
+                                       devm_kasprintf(&pdev->dev, GFP_KERNEL, "%d %s",
+                                                      i + 1, "Playback");
++                              if (!data->dapm_routes[i].sink)
++                                      return -ENOMEM;
+                               data->dapm_routes[i].source = "CPU-Playback";
+                       }
+               }
+@@ -784,6 +786,8 @@ static int imx_card_probe(struct platform_device *pdev)
+                               data->dapm_routes[i].source =
+                                       devm_kasprintf(&pdev->dev, GFP_KERNEL, "%d %s",
+                                                      i + 1, "Capture");
++                              if (!data->dapm_routes[i].source)
++                                      return -ENOMEM;
+                               data->dapm_routes[i].sink = "CPU-Capture";
+                       }
+               }
+-- 
+2.39.5
+
diff --git a/queue-6.14/asoc-simple-card-utils-don-t-use-__free-device_node-.patch b/queue-6.14/asoc-simple-card-utils-don-t-use-__free-device_node-.patch
new file mode 100644 (file)
index 0000000..9abf31c
--- /dev/null
@@ -0,0 +1,65 @@
+From 753349371f2b3d98fc87bec4655baa8e4f85cc94 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Feb 2025 00:29:30 +0000
+Subject: ASoC: simple-card-utils: Don't use __free(device_node) at
+ graph_util_parse_dai()
+
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+
+[ Upstream commit de74ec718e0788e1998eb7289ad07970e27cae27 ]
+
+commit 419d1918105e ("ASoC: simple-card-utils: use __free(device_node) for
+device node") uses __free(device_node) for dlc->of_node, but we need to
+keep it while driver is in use.
+
+Don't use __free(device_node) in graph_util_parse_dai().
+
+Fixes: 419d1918105e ("ASoC: simple-card-utils: use __free(device_node) for device node")
+Reported-by: Thuan Nguyen <thuan.nguyen-hong@banvien.com.vn>
+Reported-by: Detlev Casanova <detlev.casanova@collabora.com>
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Tested-by: Thuan Nguyen <thuan.nguyen-hong@banvien.com.vn>
+Tested-by: Detlev Casanova <detlev.casanova@collabora.com>
+Link: https://patch.msgid.link/87eczisyhh.wl-kuninori.morimoto.gx@renesas.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/generic/simple-card-utils.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c
+index c2445c5ccd84c..32efb30c55d69 100644
+--- a/sound/soc/generic/simple-card-utils.c
++++ b/sound/soc/generic/simple-card-utils.c
+@@ -1077,6 +1077,7 @@ static int graph_get_dai_id(struct device_node *ep)
+ int graph_util_parse_dai(struct device *dev, struct device_node *ep,
+                        struct snd_soc_dai_link_component *dlc, int *is_single_link)
+ {
++      struct device_node *node;
+       struct of_phandle_args args = {};
+       struct snd_soc_dai *dai;
+       int ret;
+@@ -1084,7 +1085,7 @@ int graph_util_parse_dai(struct device *dev, struct device_node *ep,
+       if (!ep)
+               return 0;
+-      struct device_node *node __free(device_node) = of_graph_get_port_parent(ep);
++      node = of_graph_get_port_parent(ep);
+       /*
+        * Try to find from DAI node
+@@ -1126,8 +1127,10 @@ int graph_util_parse_dai(struct device *dev, struct device_node *ep,
+        *    if he unbinded CPU or Codec.
+        */
+       ret = snd_soc_get_dlc(&args, dlc);
+-      if (ret < 0)
++      if (ret < 0) {
++              of_node_put(node);
+               return ret;
++      }
+ parse_dai_end:
+       if (is_single_link)
+-- 
+2.39.5
+
diff --git a/queue-6.14/asoc-tegra-use-non-atomic-timeout-for-adx-status-reg.patch b/queue-6.14/asoc-tegra-use-non-atomic-timeout-for-adx-status-reg.patch
new file mode 100644 (file)
index 0000000..8aaab31
--- /dev/null
@@ -0,0 +1,55 @@
+From 4ad39880096b8edbd37a3fb2e1dc76a1870660ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Mar 2025 06:20:10 +0000
+Subject: ASoC: tegra: Use non-atomic timeout for ADX status register
+
+From: Ritu Chaudhary <rituc@nvidia.com>
+
+[ Upstream commit f1d742c35b659fb0122da0a8ff09ad9309cb29d8 ]
+
+ADX startup() callback uses atomic poll timeout on ADX status register.
+
+This is unnecessary because:
+
+- The startup() callback itself is non-atomic.
+- The subsequent timeout call in the same function already uses a
+  non-atomic version.
+
+Using atomic version can hog CPU when it is not really needed,
+so replace it with non-atomic version.
+
+Fixes: a99ab6f395a9e ("ASoC: tegra: Add Tegra210 based ADX driver")
+Signed-off-by: Ritu Chaudhary <rituc@nvidia.com>
+Signed-off-by: Sheetal <sheetal@nvidia.com>
+Link: https://patch.msgid.link/20250311062010.33412-1-sheetal@nvidia.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/tegra/tegra210_adx.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/sound/soc/tegra/tegra210_adx.c b/sound/soc/tegra/tegra210_adx.c
+index 0aa93b948378f..3c10e09976ad0 100644
+--- a/sound/soc/tegra/tegra210_adx.c
++++ b/sound/soc/tegra/tegra210_adx.c
+@@ -1,5 +1,5 @@
+ // SPDX-License-Identifier: GPL-2.0-only
+-// SPDX-FileCopyrightText: Copyright (c) 2021-2024 NVIDIA CORPORATION & AFFILIATES.
++// SPDX-FileCopyrightText: Copyright (c) 2021-2025 NVIDIA CORPORATION & AFFILIATES.
+ // All rights reserved.
+ //
+ // tegra210_adx.c - Tegra210 ADX driver
+@@ -57,8 +57,8 @@ static int tegra210_adx_startup(struct snd_pcm_substream *substream,
+       int err;
+       /* Ensure if ADX status is disabled */
+-      err = regmap_read_poll_timeout_atomic(adx->regmap, TEGRA210_ADX_STATUS,
+-                                            val, !(val & 0x1), 10, 10000);
++      err = regmap_read_poll_timeout(adx->regmap, TEGRA210_ADX_STATUS,
++                                     val, !(val & 0x1), 10, 10000);
+       if (err < 0) {
+               dev_err(dai->dev, "failed to stop ADX, err = %d\n", err);
+               return err;
+-- 
+2.39.5
+
diff --git a/queue-6.14/asoc-ti-j721e-evm-fix-clock-configuration-for-ti-j72.patch b/queue-6.14/asoc-ti-j721e-evm-fix-clock-configuration-for-ti-j72.patch
new file mode 100644 (file)
index 0000000..3c97faa
--- /dev/null
@@ -0,0 +1,41 @@
+From 8e8ab02d040a142c6057021de2be8235e1613e21 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Mar 2025 17:05:24 +0530
+Subject: ASoC: ti: j721e-evm: Fix clock configuration for ti,j7200-cpb-audio
+ compatible
+
+From: Jayesh Choudhary <j-choudhary@ti.com>
+
+[ Upstream commit 45ff65e30deb919604e68faed156ad96ce7474d9 ]
+
+For 'ti,j7200-cpb-audio' compatible, there is support for only one PLL for
+48k. For 11025, 22050, 44100 and 88200 sampling rates, due to absence of
+J721E_CLK_PARENT_44100, we get EINVAL while running any audio application.
+Add support for these rates by using the 48k parent clock and adjusting
+the clock for these rates later in j721e_configure_refclk.
+
+Fixes: 6748d0559059 ("ASoC: ti: Add custom machine driver for j721e EVM (CPB and IVI)")
+Signed-off-by: Jayesh Choudhary <j-choudhary@ti.com>
+Link: https://patch.msgid.link/20250318113524.57100-1-j-choudhary@ti.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/ti/j721e-evm.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/sound/soc/ti/j721e-evm.c b/sound/soc/ti/j721e-evm.c
+index d9d1e021f5b2e..0f96cc45578d8 100644
+--- a/sound/soc/ti/j721e-evm.c
++++ b/sound/soc/ti/j721e-evm.c
+@@ -182,6 +182,8 @@ static int j721e_configure_refclk(struct j721e_priv *priv,
+               clk_id = J721E_CLK_PARENT_48000;
+       else if (!(rate % 11025) && priv->pll_rates[J721E_CLK_PARENT_44100])
+               clk_id = J721E_CLK_PARENT_44100;
++      else if (!(rate % 11025) && priv->pll_rates[J721E_CLK_PARENT_48000])
++              clk_id = J721E_CLK_PARENT_48000;
+       else
+               return ret;
+-- 
+2.39.5
+
diff --git a/queue-6.14/ata-libata-fix-ncq-non-data-log-not-supported-print.patch b/queue-6.14/ata-libata-fix-ncq-non-data-log-not-supported-print.patch
new file mode 100644 (file)
index 0000000..c8fbd0f
--- /dev/null
@@ -0,0 +1,47 @@
+From 20cc6aca0761a4afab8d65cac9e74be8476a6cce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Mar 2025 12:17:55 +0100
+Subject: ata: libata: Fix NCQ Non-Data log not supported print
+
+From: Niklas Cassel <cassel@kernel.org>
+
+[ Upstream commit b500ee5fde1bd0c85026dfcdadbc175548fb5216 ]
+
+Currently, both ata_dev_config_ncq_send_recv() - which checks for NCQ
+Send/Recv Log (Log Address 13h) and ata_dev_config_ncq_non_data() -
+which checks for NCQ Non-Data Log (Log Address 12h), uses the same
+print when the log is not supported:
+
+  "NCQ Send/Recv Log not supported"
+
+This seems like a copy paste error, since NCQ Non-Data Log is actually
+a separate log.
+
+Fix the print to reference the correct log.
+
+Fixes: 284b3b77ea88 ("libata: NCQ encapsulation for ZAC MANAGEMENT OUT")
+Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Link: https://lore.kernel.org/r/20250317111754.1666084-2-cassel@kernel.org
+Signed-off-by: Niklas Cassel <cassel@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/libata-core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
+index d956735e2a764..3d730c10f7bea 100644
+--- a/drivers/ata/libata-core.c
++++ b/drivers/ata/libata-core.c
+@@ -2243,7 +2243,7 @@ static void ata_dev_config_ncq_non_data(struct ata_device *dev)
+       if (!ata_log_supported(dev, ATA_LOG_NCQ_NON_DATA)) {
+               ata_dev_warn(dev,
+-                           "NCQ Send/Recv Log not supported\n");
++                           "NCQ Non-Data Log not supported\n");
+               return;
+       }
+       err_mask = ata_read_log_page(dev, ATA_LOG_NCQ_NON_DATA,
+-- 
+2.39.5
+
diff --git a/queue-6.14/auxdisplay-max6959-should-select-bitreverse.patch b/queue-6.14/auxdisplay-max6959-should-select-bitreverse.patch
new file mode 100644 (file)
index 0000000..e70d59f
--- /dev/null
@@ -0,0 +1,38 @@
+From 65e48e6384ef646fe24115bb38a1ad5a4f9060d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Feb 2025 08:48:42 +0100
+Subject: auxdisplay: MAX6959 should select BITREVERSE
+
+From: Geert Uytterhoeven <geert@linux-m68k.org>
+
+[ Upstream commit fce85f3da08b76c1b052f53a9f6f9c40a8a10660 ]
+
+If CONFIG_BITREVERSE is not enabled:
+
+    max6959.c:(.text+0x92): undefined reference to `byte_rev_table'
+
+Fixes: a9bcd02fa42217c7 ("auxdisplay: Add driver for MAX695x 7-segment LED controllers")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/202502161703.3Vr4M7qg-lkp@intel.com/
+Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/auxdisplay/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/auxdisplay/Kconfig b/drivers/auxdisplay/Kconfig
+index 8934e6ad5772b..bedc6133f970a 100644
+--- a/drivers/auxdisplay/Kconfig
++++ b/drivers/auxdisplay/Kconfig
+@@ -503,6 +503,7 @@ config HT16K33
+ config MAX6959
+       tristate "Maxim MAX6958/6959 7-segment LED controller"
+       depends on I2C
++      select BITREVERSE
+       select REGMAP_I2C
+       select LINEDISP
+       help
+-- 
+2.39.5
+
diff --git a/queue-6.14/auxdisplay-panel-fix-an-api-misuse-in-panel.c.patch b/queue-6.14/auxdisplay-panel-fix-an-api-misuse-in-panel.c.patch
new file mode 100644 (file)
index 0000000..82322e4
--- /dev/null
@@ -0,0 +1,46 @@
+From 32318b47fcf801888cff65dfe89e9e4d5d8b9108 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Feb 2025 14:36:25 +0200
+Subject: auxdisplay: panel: Fix an API misuse in panel.c
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 72e1c440c848624ad4cfac93d69d8a999a20355b ]
+
+Variable allocated by charlcd_alloc() should be released
+by charlcd_free(). The following patch changed kfree() to
+charlcd_free() to fix an API misuse.
+
+Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Fixes: 718e05ed92ec ("auxdisplay: Introduce hd44780_common.[ch]")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/auxdisplay/panel.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/auxdisplay/panel.c b/drivers/auxdisplay/panel.c
+index a731f28455b45..6dc8798d01f98 100644
+--- a/drivers/auxdisplay/panel.c
++++ b/drivers/auxdisplay/panel.c
+@@ -1664,7 +1664,7 @@ static void panel_attach(struct parport *port)
+       if (lcd.enabled)
+               charlcd_unregister(lcd.charlcd);
+ err_unreg_device:
+-      kfree(lcd.charlcd);
++      charlcd_free(lcd.charlcd);
+       lcd.charlcd = NULL;
+       parport_unregister_device(pprt);
+       pprt = NULL;
+@@ -1692,7 +1692,7 @@ static void panel_detach(struct parport *port)
+               charlcd_unregister(lcd.charlcd);
+               lcd.initialized = false;
+               kfree(lcd.charlcd->drvdata);
+-              kfree(lcd.charlcd);
++              charlcd_free(lcd.charlcd);
+               lcd.charlcd = NULL;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/ax25-remove-broken-autobind.patch b/queue-6.14/ax25-remove-broken-autobind.patch
new file mode 100644 (file)
index 0000000..b54c96d
--- /dev/null
@@ -0,0 +1,233 @@
+From 717f4279f7f6f4dd12e52befe0f6302738dbb57c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Mar 2025 13:53:52 +0300
+Subject: ax25: Remove broken autobind
+
+From: Murad Masimov <m.masimov@mt-integration.ru>
+
+[ Upstream commit 2f6efbabceb6b2914ee9bafb86d9a51feae9cce8 ]
+
+Binding AX25 socket by using the autobind feature leads to memory leaks
+in ax25_connect() and also refcount leaks in ax25_release(). Memory
+leak was detected with kmemleak:
+
+================================================================
+unreferenced object 0xffff8880253cd680 (size 96):
+backtrace:
+__kmalloc_node_track_caller_noprof (./include/linux/kmemleak.h:43)
+kmemdup_noprof (mm/util.c:136)
+ax25_rt_autobind (net/ax25/ax25_route.c:428)
+ax25_connect (net/ax25/af_ax25.c:1282)
+__sys_connect_file (net/socket.c:2045)
+__sys_connect (net/socket.c:2064)
+__x64_sys_connect (net/socket.c:2067)
+do_syscall_64 (arch/x86/entry/common.c:52 arch/x86/entry/common.c:83)
+entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130)
+================================================================
+
+When socket is bound, refcounts must be incremented the way it is done
+in ax25_bind() and ax25_setsockopt() (SO_BINDTODEVICE). In case of
+autobind, the refcounts are not incremented.
+
+This bug leads to the following issue reported by Syzkaller:
+
+================================================================
+ax25_connect(): syz-executor318 uses autobind, please contact jreuter@yaina.de
+------------[ cut here ]------------
+refcount_t: decrement hit 0; leaking memory.
+WARNING: CPU: 0 PID: 5317 at lib/refcount.c:31 refcount_warn_saturate+0xfa/0x1d0 lib/refcount.c:31
+Modules linked in:
+CPU: 0 UID: 0 PID: 5317 Comm: syz-executor318 Not tainted 6.14.0-rc4-syzkaller-00278-gece144f151ac #0
+Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014
+RIP: 0010:refcount_warn_saturate+0xfa/0x1d0 lib/refcount.c:31
+...
+Call Trace:
+ <TASK>
+ __refcount_dec include/linux/refcount.h:336 [inline]
+ refcount_dec include/linux/refcount.h:351 [inline]
+ ref_tracker_free+0x6af/0x7e0 lib/ref_tracker.c:236
+ netdev_tracker_free include/linux/netdevice.h:4302 [inline]
+ netdev_put include/linux/netdevice.h:4319 [inline]
+ ax25_release+0x368/0x960 net/ax25/af_ax25.c:1080
+ __sock_release net/socket.c:647 [inline]
+ sock_close+0xbc/0x240 net/socket.c:1398
+ __fput+0x3e9/0x9f0 fs/file_table.c:464
+ __do_sys_close fs/open.c:1580 [inline]
+ __se_sys_close fs/open.c:1565 [inline]
+ __x64_sys_close+0x7f/0x110 fs/open.c:1565
+ do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+ do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+ ...
+ </TASK>
+================================================================
+
+Considering the issues above and the comments left in the code that say:
+"check if we can remove this feature. It is broken."; "autobinding in this
+may or may not work"; - it is better to completely remove this feature than
+to fix it because it is broken and leads to various kinds of memory bugs.
+
+Now calling connect() without first binding socket will result in an
+error (-EINVAL). Userspace software that relies on the autobind feature
+might get broken. However, this feature does not seem widely used with
+this specific driver as it was not reliable at any point of time, and it
+is already broken anyway. E.g. ax25-tools and ax25-apps packages for
+popular distributions do not use the autobind feature for AF_AX25.
+
+Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+33841dc6aa3e1d86b78a@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=33841dc6aa3e1d86b78a
+Signed-off-by: Murad Masimov <m.masimov@mt-integration.ru>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/ax25.h    |  1 -
+ net/ax25/af_ax25.c    | 30 ++++++------------
+ net/ax25/ax25_route.c | 74 -------------------------------------------
+ 3 files changed, 10 insertions(+), 95 deletions(-)
+
+diff --git a/include/net/ax25.h b/include/net/ax25.h
+index 4ee141aae0a29..a7bba42dde153 100644
+--- a/include/net/ax25.h
++++ b/include/net/ax25.h
+@@ -418,7 +418,6 @@ void ax25_rt_device_down(struct net_device *);
+ int ax25_rt_ioctl(unsigned int, void __user *);
+ extern const struct seq_operations ax25_rt_seqops;
+ ax25_route *ax25_get_route(ax25_address *addr, struct net_device *dev);
+-int ax25_rt_autobind(ax25_cb *, ax25_address *);
+ struct sk_buff *ax25_rt_build_path(struct sk_buff *, ax25_address *,
+                                  ax25_address *, ax25_digi *);
+ void ax25_rt_free(void);
+diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
+index 9f3b8b682adb2..3ee7dba343100 100644
+--- a/net/ax25/af_ax25.c
++++ b/net/ax25/af_ax25.c
+@@ -1270,28 +1270,18 @@ static int __must_check ax25_connect(struct socket *sock,
+               }
+       }
+-      /*
+-       *      Must bind first - autobinding in this may or may not work. If
+-       *      the socket is already bound, check to see if the device has
+-       *      been filled in, error if it hasn't.
+-       */
++      /* Must bind first - autobinding does not work. */
+       if (sock_flag(sk, SOCK_ZAPPED)) {
+-              /* check if we can remove this feature. It is broken. */
+-              printk(KERN_WARNING "ax25_connect(): %s uses autobind, please contact jreuter@yaina.de\n",
+-                      current->comm);
+-              if ((err = ax25_rt_autobind(ax25, &fsa->fsa_ax25.sax25_call)) < 0) {
+-                      kfree(digi);
+-                      goto out_release;
+-              }
++              kfree(digi);
++              err = -EINVAL;
++              goto out_release;
++      }
+-              ax25_fillin_cb(ax25, ax25->ax25_dev);
+-              ax25_cb_add(ax25);
+-      } else {
+-              if (ax25->ax25_dev == NULL) {
+-                      kfree(digi);
+-                      err = -EHOSTUNREACH;
+-                      goto out_release;
+-              }
++      /* Check to see if the device has been filled in, error if it hasn't. */
++      if (ax25->ax25_dev == NULL) {
++              kfree(digi);
++              err = -EHOSTUNREACH;
++              goto out_release;
+       }
+       if (sk->sk_type == SOCK_SEQPACKET &&
+diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c
+index 69de75db0c9c2..10577434f40bf 100644
+--- a/net/ax25/ax25_route.c
++++ b/net/ax25/ax25_route.c
+@@ -373,80 +373,6 @@ ax25_route *ax25_get_route(ax25_address *addr, struct net_device *dev)
+       return ax25_rt;
+ }
+-/*
+- *    Adjust path: If you specify a default route and want to connect
+- *      a target on the digipeater path but w/o having a special route
+- *    set before, the path has to be truncated from your target on.
+- */
+-static inline void ax25_adjust_path(ax25_address *addr, ax25_digi *digipeat)
+-{
+-      int k;
+-
+-      for (k = 0; k < digipeat->ndigi; k++) {
+-              if (ax25cmp(addr, &digipeat->calls[k]) == 0)
+-                      break;
+-      }
+-
+-      digipeat->ndigi = k;
+-}
+-
+-
+-/*
+- *    Find which interface to use.
+- */
+-int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr)
+-{
+-      ax25_uid_assoc *user;
+-      ax25_route *ax25_rt;
+-      int err = 0;
+-
+-      ax25_route_lock_use();
+-      ax25_rt = ax25_get_route(addr, NULL);
+-      if (!ax25_rt) {
+-              ax25_route_lock_unuse();
+-              return -EHOSTUNREACH;
+-      }
+-      rcu_read_lock();
+-      if ((ax25->ax25_dev = ax25_dev_ax25dev(ax25_rt->dev)) == NULL) {
+-              err = -EHOSTUNREACH;
+-              goto put;
+-      }
+-
+-      user = ax25_findbyuid(current_euid());
+-      if (user) {
+-              ax25->source_addr = user->call;
+-              ax25_uid_put(user);
+-      } else {
+-              if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE)) {
+-                      err = -EPERM;
+-                      goto put;
+-              }
+-              ax25->source_addr = *(ax25_address *)ax25->ax25_dev->dev->dev_addr;
+-      }
+-
+-      if (ax25_rt->digipeat != NULL) {
+-              ax25->digipeat = kmemdup(ax25_rt->digipeat, sizeof(ax25_digi),
+-                                       GFP_ATOMIC);
+-              if (ax25->digipeat == NULL) {
+-                      err = -ENOMEM;
+-                      goto put;
+-              }
+-              ax25_adjust_path(addr, ax25->digipeat);
+-      }
+-
+-      if (ax25->sk != NULL) {
+-              local_bh_disable();
+-              bh_lock_sock(ax25->sk);
+-              sock_reset_flag(ax25->sk, SOCK_ZAPPED);
+-              bh_unlock_sock(ax25->sk);
+-              local_bh_enable();
+-      }
+-
+-put:
+-      rcu_read_unlock();
+-      ax25_route_lock_unuse();
+-      return err;
+-}
+ struct sk_buff *ax25_rt_build_path(struct sk_buff *skb, ax25_address *src,
+       ax25_address *dest, ax25_digi *digi)
+-- 
+2.39.5
+
diff --git a/queue-6.14/badblocks-attempt-to-merge-adjacent-badblocks-during.patch b/queue-6.14/badblocks-attempt-to-merge-adjacent-badblocks-during.patch
new file mode 100644 (file)
index 0000000..fe26f58
--- /dev/null
@@ -0,0 +1,47 @@
+From 88dfd098aadb9986552567153282d31ff6a4e389 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 15:54:58 +0800
+Subject: badblocks: attempt to merge adjacent badblocks during
+ ack_all_badblocks
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit 32e9ad4d11f69949ff331e35a417871ee0d31d99 ]
+
+If ack and unack badblocks are adjacent, they will not be merged and will
+remain as two separate badblocks. Even after the bad blocks are written
+to disk and both become ack, they will still remain as two independent
+bad blocks. This is not ideal as it wastes the limited space for
+badblocks. Therefore, during ack_all_badblocks(), attempt to merge
+badblocks if they are adjacent.
+
+Fixes: aa511ff8218b ("badblocks: switch to the improved badblock handling code")
+Signed-off-by: Li Nan <linan122@huawei.com>
+Reviewed-by: Yu Kuai <yukuai3@huawei.com>
+Acked-by: Coly Li <colyli@kernel.org>
+Link: https://lore.kernel.org/r/20250227075507.151331-4-zhengqixing@huaweicloud.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/badblocks.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/block/badblocks.c b/block/badblocks.c
+index f069c93e986df..ad8652fbe1c8f 100644
+--- a/block/badblocks.c
++++ b/block/badblocks.c
+@@ -1491,6 +1491,11 @@ void ack_all_badblocks(struct badblocks *bb)
+                               p[i] = BB_MAKE(start, len, 1);
+                       }
+               }
++
++              for (i = 0; i < bb->count ; i++)
++                      while (try_adjacent_combine(bb, i))
++                              ;
++
+               bb->unacked_exist = 0;
+       }
+       write_sequnlock_irq(&bb->lock);
+-- 
+2.39.5
+
diff --git a/queue-6.14/badblocks-factor-out-a-helper-try_adjacent_combine.patch b/queue-6.14/badblocks-factor-out-a-helper-try_adjacent_combine.patch
new file mode 100644 (file)
index 0000000..f8384cf
--- /dev/null
@@ -0,0 +1,82 @@
+From 9be4e70d08006c6f75fedbf790ea7b8f90952dd7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 15:54:57 +0800
+Subject: badblocks: factor out a helper try_adjacent_combine
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit 270b68fee9688428e0a98d4a2c3e6d4c434a84ba ]
+
+Factor out try_adjacent_combine(), and it will be used in the later patch.
+
+Signed-off-by: Li Nan <linan122@huawei.com>
+Reviewed-by: Yu Kuai <yukuai3@huawei.com>
+Link: https://lore.kernel.org/r/20250227075507.151331-3-zhengqixing@huaweicloud.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Stable-dep-of: 32e9ad4d11f6 ("badblocks: attempt to merge adjacent badblocks during ack_all_badblocks")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/badblocks.c | 40 ++++++++++++++++++++++++++--------------
+ 1 file changed, 26 insertions(+), 14 deletions(-)
+
+diff --git a/block/badblocks.c b/block/badblocks.c
+index bcee057efc476..f069c93e986df 100644
+--- a/block/badblocks.c
++++ b/block/badblocks.c
+@@ -855,6 +855,31 @@ static void badblocks_update_acked(struct badblocks *bb)
+               bb->unacked_exist = 0;
+ }
++/*
++ * Return 'true' if the range indicated by 'bad' is exactly backward
++ * overlapped with the bad range (from bad table) indexed by 'behind'.
++ */
++static bool try_adjacent_combine(struct badblocks *bb, int prev)
++{
++      u64 *p = bb->page;
++
++      if (prev >= 0 && (prev + 1) < bb->count &&
++          BB_END(p[prev]) == BB_OFFSET(p[prev + 1]) &&
++          (BB_LEN(p[prev]) + BB_LEN(p[prev + 1])) <= BB_MAX_LEN &&
++          BB_ACK(p[prev]) == BB_ACK(p[prev + 1])) {
++              p[prev] = BB_MAKE(BB_OFFSET(p[prev]),
++                                BB_LEN(p[prev]) + BB_LEN(p[prev + 1]),
++                                BB_ACK(p[prev]));
++
++              if ((prev + 2) < bb->count)
++                      memmove(p + prev + 1, p + prev + 2,
++                              (bb->count -  (prev + 2)) * 8);
++              bb->count--;
++              return true;
++      }
++      return false;
++}
++
+ /* Do exact work to set bad block range into the bad block table */
+ static int _badblocks_set(struct badblocks *bb, sector_t s, int sectors,
+                         int acknowledged)
+@@ -1022,20 +1047,7 @@ static int _badblocks_set(struct badblocks *bb, sector_t s, int sectors,
+        * merged. (prev < 0) condition is not handled here,
+        * because it's already complicated enough.
+        */
+-      if (prev >= 0 &&
+-          (prev + 1) < bb->count &&
+-          BB_END(p[prev]) == BB_OFFSET(p[prev + 1]) &&
+-          (BB_LEN(p[prev]) + BB_LEN(p[prev + 1])) <= BB_MAX_LEN &&
+-          BB_ACK(p[prev]) == BB_ACK(p[prev + 1])) {
+-              p[prev] = BB_MAKE(BB_OFFSET(p[prev]),
+-                                BB_LEN(p[prev]) + BB_LEN(p[prev + 1]),
+-                                BB_ACK(p[prev]));
+-
+-              if ((prev + 2) < bb->count)
+-                      memmove(p + prev + 1, p + prev + 2,
+-                              (bb->count -  (prev + 2)) * 8);
+-              bb->count--;
+-      }
++      try_adjacent_combine(bb, prev);
+       if (space_desired && !badblocks_full(bb)) {
+               s = orig_start;
+-- 
+2.39.5
+
diff --git a/queue-6.14/badblocks-fix-error-shitf-ops.patch b/queue-6.14/badblocks-fix-error-shitf-ops.patch
new file mode 100644 (file)
index 0000000..d24d434
--- /dev/null
@@ -0,0 +1,62 @@
+From 955b89957d1dca67c4a45cfb9b071dd65c4743a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 15:54:56 +0800
+Subject: badblocks: Fix error shitf ops
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit 7d83c5d73c1a3c7b71ba70d0ad2ae66e7a0e7ace ]
+
+'bb->shift' is used directly in badblocks. It is wrong, fix it.
+
+Fixes: 3ea3354cb9f0 ("badblocks: improve badblocks_check() for multiple ranges handling")
+Signed-off-by: Li Nan <linan122@huawei.com>
+Reviewed-by: Yu Kuai <yukuai3@huawei.com>
+Acked-by: Coly Li <colyli@kernel.org>
+Link: https://lore.kernel.org/r/20250227075507.151331-2-zhengqixing@huaweicloud.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/badblocks.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/block/badblocks.c b/block/badblocks.c
+index db4ec8b9b2a8c..bcee057efc476 100644
+--- a/block/badblocks.c
++++ b/block/badblocks.c
+@@ -880,8 +880,8 @@ static int _badblocks_set(struct badblocks *bb, sector_t s, int sectors,
+               /* round the start down, and the end up */
+               sector_t next = s + sectors;
+-              rounddown(s, bb->shift);
+-              roundup(next, bb->shift);
++              rounddown(s, 1 << bb->shift);
++              roundup(next, 1 << bb->shift);
+               sectors = next - s;
+       }
+@@ -1157,8 +1157,8 @@ static int _badblocks_clear(struct badblocks *bb, sector_t s, int sectors)
+                * isn't than to think a block is not bad when it is.
+                */
+               target = s + sectors;
+-              roundup(s, bb->shift);
+-              rounddown(target, bb->shift);
++              roundup(s, 1 << bb->shift);
++              rounddown(target, 1 << bb->shift);
+               sectors = target - s;
+       }
+@@ -1288,8 +1288,8 @@ static int _badblocks_check(struct badblocks *bb, sector_t s, int sectors,
+               /* round the start down, and the end up */
+               target = s + sectors;
+-              rounddown(s, bb->shift);
+-              roundup(target, bb->shift);
++              rounddown(s, 1 << bb->shift);
++              roundup(target, 1 << bb->shift);
+               sectors = target - s;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/badblocks-fix-merge-issue-when-new-badblocks-align-w.patch b/queue-6.14/badblocks-fix-merge-issue-when-new-badblocks-align-w.patch
new file mode 100644 (file)
index 0000000..6572bb4
--- /dev/null
@@ -0,0 +1,63 @@
+From 3b3b7cdbb75ea62ad0d91a8afd71e49c70ad7bbb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 15:55:03 +0800
+Subject: badblocks: fix merge issue when new badblocks align with pre+1
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit 9ec65dec634a752ab0a1203510ee190356e4cf1a ]
+
+There is a merge issue when adding badblocks as follow:
+  echo 0 10 > bad_blocks
+  echo 30 10 > bad_blocks
+  echo 20 10 > bad_blocks
+  cat bad_blocks
+  0 10
+  20 10    //should be merged with (30 10)
+  30 10
+
+In this case, if new badblocks does not intersect with prev, it is added
+by insert_at(). If there is an intersection with prev+1, the merge will
+be processed in the next re_insert loop.
+
+However, when the end of the new badblocks is exactly equal to the offset
+of prev+1, no further re_insert loop occurs, and the two badblocks are not
+merge.
+
+Fix it by inc prev, badblocks can be merged during the subsequent code.
+
+Fixes: aa511ff8218b ("badblocks: switch to the improved badblock handling code")
+Signed-off-by: Li Nan <linan122@huawei.com>
+Reviewed-by: Yu Kuai <yukuai3@huawei.com>
+Link: https://lore.kernel.org/r/20250227075507.151331-9-zhengqixing@huaweicloud.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/badblocks.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/block/badblocks.c b/block/badblocks.c
+index 43430bd3efa7d..52206a42191da 100644
+--- a/block/badblocks.c
++++ b/block/badblocks.c
+@@ -892,7 +892,7 @@ static int _badblocks_set(struct badblocks *bb, sector_t s, int sectors,
+               len = insert_at(bb, 0, &bad);
+               bb->count++;
+               added++;
+-              hint = 0;
++              hint = ++prev;
+               goto update_sectors;
+       }
+@@ -951,7 +951,7 @@ static int _badblocks_set(struct badblocks *bb, sector_t s, int sectors,
+       len = insert_at(bb, prev + 1, &bad);
+       bb->count++;
+       added++;
+-      hint = prev + 1;
++      hint = ++prev;
+ update_sectors:
+       s += len;
+-- 
+2.39.5
+
diff --git a/queue-6.14/badblocks-fix-missing-bad-blocks-on-retry-in-_badblo.patch b/queue-6.14/badblocks-fix-missing-bad-blocks-on-retry-in-_badblo.patch
new file mode 100644 (file)
index 0000000..449185d
--- /dev/null
@@ -0,0 +1,109 @@
+From dbfbef4a5143aa0e4c99f1e4aab9bf3896e82249 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 15:55:04 +0800
+Subject: badblocks: fix missing bad blocks on retry in _badblocks_check()
+
+From: Zheng Qixing <zhengqixing@huawei.com>
+
+[ Upstream commit 5236f041fa6c81c71eabad44897e54a0d6d5bbf6 ]
+
+The bad blocks check would miss bad blocks when retrying under contention,
+as checking parameters are not reset. These stale values from the previous
+attempt could lead to incorrect scanning in the subsequent retry.
+
+Move seqlock to outer function and reinitialize checking state for each
+retry. This ensures a clean state for each check attempt, preventing any
+missed bad blocks.
+
+Fixes: 3ea3354cb9f0 ("badblocks: improve badblocks_check() for multiple ranges handling")
+Signed-off-by: Zheng Qixing <zhengqixing@huawei.com>
+Reviewed-by: Yu Kuai <yukuai3@huawei.com>
+Acked-by: Coly Li <colyli@kernel.org>
+Link: https://lore.kernel.org/r/20250227075507.151331-10-zhengqixing@huaweicloud.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/badblocks.c | 50 +++++++++++++++++++++++------------------------
+ 1 file changed, 24 insertions(+), 26 deletions(-)
+
+diff --git a/block/badblocks.c b/block/badblocks.c
+index 52206a42191da..f84a35d683b1f 100644
+--- a/block/badblocks.c
++++ b/block/badblocks.c
+@@ -1195,31 +1195,12 @@ static int _badblocks_clear(struct badblocks *bb, sector_t s, int sectors)
+ static int _badblocks_check(struct badblocks *bb, sector_t s, int sectors,
+                           sector_t *first_bad, int *bad_sectors)
+ {
+-      int unacked_badblocks, acked_badblocks;
+       int prev = -1, hint = -1, set = 0;
+       struct badblocks_context bad;
+-      unsigned int seq;
++      int unacked_badblocks = 0;
++      int acked_badblocks = 0;
++      u64 *p = bb->page;
+       int len, rv;
+-      u64 *p;
+-
+-      WARN_ON(bb->shift < 0 || sectors == 0);
+-
+-      if (bb->shift > 0) {
+-              sector_t target;
+-
+-              /* round the start down, and the end up */
+-              target = s + sectors;
+-              rounddown(s, 1 << bb->shift);
+-              roundup(target, 1 << bb->shift);
+-              sectors = target - s;
+-      }
+-
+-retry:
+-      seq = read_seqbegin(&bb->lock);
+-
+-      p = bb->page;
+-      unacked_badblocks = 0;
+-      acked_badblocks = 0;
+ re_check:
+       bad.start = s;
+@@ -1285,9 +1266,6 @@ static int _badblocks_check(struct badblocks *bb, sector_t s, int sectors,
+       else
+               rv = 0;
+-      if (read_seqretry(&bb->lock, seq))
+-              goto retry;
+-
+       return rv;
+ }
+@@ -1328,7 +1306,27 @@ static int _badblocks_check(struct badblocks *bb, sector_t s, int sectors,
+ int badblocks_check(struct badblocks *bb, sector_t s, int sectors,
+                       sector_t *first_bad, int *bad_sectors)
+ {
+-      return _badblocks_check(bb, s, sectors, first_bad, bad_sectors);
++      unsigned int seq;
++      int rv;
++
++      WARN_ON(bb->shift < 0 || sectors == 0);
++
++      if (bb->shift > 0) {
++              /* round the start down, and the end up */
++              sector_t target = s + sectors;
++
++              rounddown(s, 1 << bb->shift);
++              roundup(target, 1 << bb->shift);
++              sectors = target - s;
++      }
++
++retry:
++      seq = read_seqbegin(&bb->lock);
++      rv = _badblocks_check(bb, s, sectors, first_bad, bad_sectors);
++      if (read_seqretry(&bb->lock, seq))
++              goto retry;
++
++      return rv;
+ }
+ EXPORT_SYMBOL_GPL(badblocks_check);
+-- 
+2.39.5
+
diff --git a/queue-6.14/badblocks-fix-the-using-of-max_badblocks.patch b/queue-6.14/badblocks-fix-the-using-of-max_badblocks.patch
new file mode 100644 (file)
index 0000000..0eb389e
--- /dev/null
@@ -0,0 +1,50 @@
+From 648c417665dc62406d88a32311eaf19ccd1ff154 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 15:55:01 +0800
+Subject: badblocks: fix the using of MAX_BADBLOCKS
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit 37446680dfbfbba7cbedd680047182f70a0b857b ]
+
+The number of badblocks cannot exceed MAX_BADBLOCKS, but it should be
+allowed to equal MAX_BADBLOCKS.
+
+Fixes: aa511ff8218b ("badblocks: switch to the improved badblock handling code")
+Fixes: c3c6a86e9efc ("badblocks: add helper routines for badblock ranges handling")
+Signed-off-by: Li Nan <linan122@huawei.com>
+Reviewed-by: Zhu Yanjun <yanjun.zhu@linux.dev>
+Reviewed-by: Yu Kuai <yukuai3@huawei.com>
+Acked-by: Coly Li <colyli@kernel.org>
+Link: https://lore.kernel.org/r/20250227075507.151331-7-zhengqixing@huaweicloud.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/badblocks.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/block/badblocks.c b/block/badblocks.c
+index 88f27d4f38563..43430bd3efa7d 100644
+--- a/block/badblocks.c
++++ b/block/badblocks.c
+@@ -700,7 +700,7 @@ static bool can_front_overwrite(struct badblocks *bb, int prev,
+                       *extra = 2;
+       }
+-      if ((bb->count + (*extra)) >= MAX_BADBLOCKS)
++      if ((bb->count + (*extra)) > MAX_BADBLOCKS)
+               return false;
+       return true;
+@@ -1135,7 +1135,7 @@ static int _badblocks_clear(struct badblocks *bb, sector_t s, int sectors)
+               if ((BB_OFFSET(p[prev]) < bad.start) &&
+                   (BB_END(p[prev]) > (bad.start + bad.len))) {
+                       /* Splitting */
+-                      if ((bb->count + 1) < MAX_BADBLOCKS) {
++                      if ((bb->count + 1) <= MAX_BADBLOCKS) {
+                               len = front_splitting_clear(bb, prev, &bad);
+                               bb->count += 1;
+                               cleared++;
+-- 
+2.39.5
+
diff --git a/queue-6.14/badblocks-return-boolean-from-badblocks_set-and-badb.patch b/queue-6.14/badblocks-return-boolean-from-badblocks_set-and-badb.patch
new file mode 100644 (file)
index 0000000..c5fd32b
--- /dev/null
@@ -0,0 +1,286 @@
+From 4a60d95cb3aa8a557e7bdf2cda4120c49b2b9541 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 15:55:05 +0800
+Subject: badblocks: return boolean from badblocks_set() and badblocks_clear()
+
+From: Zheng Qixing <zhengqixing@huawei.com>
+
+[ Upstream commit c8775aefba959cdfbaa25408a84d3dd15bbeb991 ]
+
+Change the return type of badblocks_set() and badblocks_clear()
+from int to bool, indicating success or failure. Specifically:
+
+- _badblocks_set() and _badblocks_clear() functions now return
+true for success and false for failure.
+- All calls to these functions are updated to handle the new
+boolean return type.
+- This change improves code clarity and ensures a more consistent
+handling of success and failure states.
+
+Signed-off-by: Zheng Qixing <zhengqixing@huawei.com>
+Reviewed-by: Yu Kuai <yukuai3@huawei.com>
+Acked-by: Coly Li <colyli@kernel.org>
+Acked-by: Ira Weiny <ira.weiny@intel.com>
+Link: https://lore.kernel.org/r/20250227075507.151331-11-zhengqixing@huaweicloud.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Stable-dep-of: d301f164c3fb ("badblocks: use sector_t instead of int to avoid truncation of badblocks length")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/badblocks.c             | 41 +++++++++++++++++------------------
+ drivers/block/null_blk/main.c | 14 ++++++------
+ drivers/md/md.c               | 35 +++++++++++++++---------------
+ drivers/nvdimm/badrange.c     |  2 +-
+ include/linux/badblocks.h     |  6 ++---
+ 5 files changed, 49 insertions(+), 49 deletions(-)
+
+diff --git a/block/badblocks.c b/block/badblocks.c
+index f84a35d683b1f..753250a04c3fa 100644
+--- a/block/badblocks.c
++++ b/block/badblocks.c
+@@ -836,8 +836,8 @@ static bool try_adjacent_combine(struct badblocks *bb, int prev)
+ }
+ /* Do exact work to set bad block range into the bad block table */
+-static int _badblocks_set(struct badblocks *bb, sector_t s, int sectors,
+-                        int acknowledged)
++static bool _badblocks_set(struct badblocks *bb, sector_t s, int sectors,
++                         int acknowledged)
+ {
+       int len = 0, added = 0;
+       struct badblocks_context bad;
+@@ -847,11 +847,11 @@ static int _badblocks_set(struct badblocks *bb, sector_t s, int sectors,
+       if (bb->shift < 0)
+               /* badblocks are disabled */
+-              return 1;
++              return false;
+       if (sectors == 0)
+               /* Invalid sectors number */
+-              return 1;
++              return false;
+       if (bb->shift) {
+               /* round the start down, and the end up */
+@@ -981,7 +981,7 @@ static int _badblocks_set(struct badblocks *bb, sector_t s, int sectors,
+       write_sequnlock_irqrestore(&bb->lock, flags);
+-      return sectors;
++      return sectors == 0;
+ }
+ /*
+@@ -1052,21 +1052,20 @@ static int front_splitting_clear(struct badblocks *bb, int prev,
+ }
+ /* Do the exact work to clear bad block range from the bad block table */
+-static int _badblocks_clear(struct badblocks *bb, sector_t s, int sectors)
++static bool _badblocks_clear(struct badblocks *bb, sector_t s, int sectors)
+ {
+       struct badblocks_context bad;
+       int prev = -1, hint = -1;
+       int len = 0, cleared = 0;
+-      int rv = 0;
+       u64 *p;
+       if (bb->shift < 0)
+               /* badblocks are disabled */
+-              return 1;
++              return false;
+       if (sectors == 0)
+               /* Invalid sectors number */
+-              return 1;
++              return false;
+       if (bb->shift) {
+               sector_t target;
+@@ -1186,9 +1185,9 @@ static int _badblocks_clear(struct badblocks *bb, sector_t s, int sectors)
+       write_sequnlock_irq(&bb->lock);
+       if (!cleared)
+-              rv = 1;
++              return false;
+-      return rv;
++      return true;
+ }
+ /* Do the exact work to check bad blocks range from the bad block table */
+@@ -1342,12 +1341,12 @@ EXPORT_SYMBOL_GPL(badblocks_check);
+  * decide how best to handle it.
+  *
+  * Return:
+- *  0: success
+- *  other: failed to set badblocks (out of space). Parital setting will be
++ *  true: success
++ *  false: failed to set badblocks (out of space). Parital setting will be
+  *  treated as failure.
+  */
+-int badblocks_set(struct badblocks *bb, sector_t s, int sectors,
+-                      int acknowledged)
++bool badblocks_set(struct badblocks *bb, sector_t s, int sectors,
++                 int acknowledged)
+ {
+       return _badblocks_set(bb, s, sectors, acknowledged);
+ }
+@@ -1364,10 +1363,10 @@ EXPORT_SYMBOL_GPL(badblocks_set);
+  * drop the remove request.
+  *
+  * Return:
+- *  0: success
+- *  1: failed to clear badblocks
++ *  true: success
++ *  false: failed to clear badblocks
+  */
+-int badblocks_clear(struct badblocks *bb, sector_t s, int sectors)
++bool badblocks_clear(struct badblocks *bb, sector_t s, int sectors)
+ {
+       return _badblocks_clear(bb, s, sectors);
+ }
+@@ -1489,10 +1488,10 @@ ssize_t badblocks_store(struct badblocks *bb, const char *page, size_t len,
+               return -EINVAL;
+       }
+-      if (badblocks_set(bb, sector, length, !unack))
++      if (!badblocks_set(bb, sector, length, !unack))
+               return -ENOSPC;
+-      else
+-              return len;
++
++      return len;
+ }
+ EXPORT_SYMBOL_GPL(badblocks_store);
+diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c
+index cca278f1d2ce7..f2a5f65abbf8b 100644
+--- a/drivers/block/null_blk/main.c
++++ b/drivers/block/null_blk/main.c
+@@ -561,14 +561,14 @@ static ssize_t nullb_device_badblocks_store(struct config_item *item,
+               goto out;
+       /* enable badblocks */
+       cmpxchg(&t_dev->badblocks.shift, -1, 0);
+-      if (buf[0] == '+')
+-              ret = badblocks_set(&t_dev->badblocks, start,
+-                      end - start + 1, 1);
+-      else
+-              ret = badblocks_clear(&t_dev->badblocks, start,
+-                      end - start + 1);
+-      if (ret == 0)
++      if (buf[0] == '+') {
++              if (badblocks_set(&t_dev->badblocks, start,
++                                end - start + 1, 1))
++                      ret = count;
++      } else if (badblocks_clear(&t_dev->badblocks, start,
++                                 end - start + 1)) {
+               ret = count;
++      }
+ out:
+       kfree(orig);
+       return ret;
+diff --git a/drivers/md/md.c b/drivers/md/md.c
+index f501bc5f68f1a..ef859ccb03661 100644
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -1754,7 +1754,7 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_
+                       count <<= sb->bblog_shift;
+                       if (bb + 1 == 0)
+                               break;
+-                      if (badblocks_set(&rdev->badblocks, sector, count, 1))
++                      if (!badblocks_set(&rdev->badblocks, sector, count, 1))
+                               return -EINVAL;
+               }
+       } else if (sb->bblog_offset != 0)
+@@ -9850,7 +9850,6 @@ int rdev_set_badblocks(struct md_rdev *rdev, sector_t s, int sectors,
+                      int is_new)
+ {
+       struct mddev *mddev = rdev->mddev;
+-      int rv;
+       /*
+        * Recording new badblocks for faulty rdev will force unnecessary
+@@ -9866,33 +9865,35 @@ int rdev_set_badblocks(struct md_rdev *rdev, sector_t s, int sectors,
+               s += rdev->new_data_offset;
+       else
+               s += rdev->data_offset;
+-      rv = badblocks_set(&rdev->badblocks, s, sectors, 0);
+-      if (rv == 0) {
+-              /* Make sure they get written out promptly */
+-              if (test_bit(ExternalBbl, &rdev->flags))
+-                      sysfs_notify_dirent_safe(rdev->sysfs_unack_badblocks);
+-              sysfs_notify_dirent_safe(rdev->sysfs_state);
+-              set_mask_bits(&mddev->sb_flags, 0,
+-                            BIT(MD_SB_CHANGE_CLEAN) | BIT(MD_SB_CHANGE_PENDING));
+-              md_wakeup_thread(rdev->mddev->thread);
+-              return 1;
+-      } else
++
++      if (!badblocks_set(&rdev->badblocks, s, sectors, 0))
+               return 0;
++
++      /* Make sure they get written out promptly */
++      if (test_bit(ExternalBbl, &rdev->flags))
++              sysfs_notify_dirent_safe(rdev->sysfs_unack_badblocks);
++      sysfs_notify_dirent_safe(rdev->sysfs_state);
++      set_mask_bits(&mddev->sb_flags, 0,
++                    BIT(MD_SB_CHANGE_CLEAN) | BIT(MD_SB_CHANGE_PENDING));
++      md_wakeup_thread(rdev->mddev->thread);
++      return 1;
+ }
+ EXPORT_SYMBOL_GPL(rdev_set_badblocks);
+ int rdev_clear_badblocks(struct md_rdev *rdev, sector_t s, int sectors,
+                        int is_new)
+ {
+-      int rv;
+       if (is_new)
+               s += rdev->new_data_offset;
+       else
+               s += rdev->data_offset;
+-      rv = badblocks_clear(&rdev->badblocks, s, sectors);
+-      if ((rv == 0) && test_bit(ExternalBbl, &rdev->flags))
++
++      if (!badblocks_clear(&rdev->badblocks, s, sectors))
++              return 0;
++
++      if (test_bit(ExternalBbl, &rdev->flags))
+               sysfs_notify_dirent_safe(rdev->sysfs_badblocks);
+-      return rv;
++      return 1;
+ }
+ EXPORT_SYMBOL_GPL(rdev_clear_badblocks);
+diff --git a/drivers/nvdimm/badrange.c b/drivers/nvdimm/badrange.c
+index a002ea6fdd842..ee478ccde7c6c 100644
+--- a/drivers/nvdimm/badrange.c
++++ b/drivers/nvdimm/badrange.c
+@@ -167,7 +167,7 @@ static void set_badblock(struct badblocks *bb, sector_t s, int num)
+       dev_dbg(bb->dev, "Found a bad range (0x%llx, 0x%llx)\n",
+                       (u64) s * 512, (u64) num * 512);
+       /* this isn't an error as the hardware will still throw an exception */
+-      if (badblocks_set(bb, s, num, 1))
++      if (!badblocks_set(bb, s, num, 1))
+               dev_info_once(bb->dev, "%s: failed for sector %llx\n",
+                               __func__, (u64) s);
+ }
+diff --git a/include/linux/badblocks.h b/include/linux/badblocks.h
+index 670f2dae692fb..8764bed9ff167 100644
+--- a/include/linux/badblocks.h
++++ b/include/linux/badblocks.h
+@@ -50,9 +50,9 @@ struct badblocks_context {
+ int badblocks_check(struct badblocks *bb, sector_t s, int sectors,
+                  sector_t *first_bad, int *bad_sectors);
+-int badblocks_set(struct badblocks *bb, sector_t s, int sectors,
+-                      int acknowledged);
+-int badblocks_clear(struct badblocks *bb, sector_t s, int sectors);
++bool badblocks_set(struct badblocks *bb, sector_t s, int sectors,
++                 int acknowledged);
++bool badblocks_clear(struct badblocks *bb, sector_t s, int sectors);
+ void ack_all_badblocks(struct badblocks *bb);
+ ssize_t badblocks_show(struct badblocks *bb, char *page, int unack);
+ ssize_t badblocks_store(struct badblocks *bb, const char *page, size_t len,
+-- 
+2.39.5
+
diff --git a/queue-6.14/badblocks-return-error-directly-when-setting-badbloc.patch b/queue-6.14/badblocks-return-error-directly-when-setting-badbloc.patch
new file mode 100644 (file)
index 0000000..c254571
--- /dev/null
@@ -0,0 +1,226 @@
+From 4efb86ce993cdf6d54e085c0d37c470469c68932 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 15:54:59 +0800
+Subject: badblocks: return error directly when setting badblocks exceeds 512
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit 28243dcd1f49cc8be398a1396d16a45527882ce5 ]
+
+In the current handling of badblocks settings, a lot of processing has
+been done for scenarios where the number of badblocks exceeds 512.
+This makes the code look quite complex and also introduces some issues,
+
+For example, if there is 512 badblocks already:
+  for((i=0; i<510; i++)); do ((sector=i*2)); echo "$sector 1" > bad_blocks; done
+  echo 2100 10 > bad_blocks
+  echo 2200 10 > bad_blocks
+Set new one, exceed 512:
+  echo 2000 500 > bad_blocks
+Expected:
+  2000 500
+Actual:
+  2100 400
+
+In fact, a disk shouldn't have too many badblocks, and for disks with
+512 badblocks, attempting to set more bad blocks doesn't make much sense.
+At that point, the more appropriate action would be to replace the disk.
+Therefore, to resolve these issues and simplify the code somewhat, return
+error directly when setting badblocks exceeds 512.
+
+Fixes: aa511ff8218b ("badblocks: switch to the improved badblock handling code")
+Signed-off-by: Li Nan <linan122@huawei.com>
+Reviewed-by: Yu Kuai <yukuai3@huawei.com>
+Link: https://lore.kernel.org/r/20250227075507.151331-5-zhengqixing@huaweicloud.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/badblocks.c | 121 ++++++++--------------------------------------
+ 1 file changed, 19 insertions(+), 102 deletions(-)
+
+diff --git a/block/badblocks.c b/block/badblocks.c
+index ad8652fbe1c8f..1c8b8f65f6df4 100644
+--- a/block/badblocks.c
++++ b/block/badblocks.c
+@@ -527,51 +527,6 @@ static int prev_badblocks(struct badblocks *bb, struct badblocks_context *bad,
+       return ret;
+ }
+-/*
+- * Return 'true' if the range indicated by 'bad' can be backward merged
+- * with the bad range (from the bad table) index by 'behind'.
+- */
+-static bool can_merge_behind(struct badblocks *bb,
+-                           struct badblocks_context *bad, int behind)
+-{
+-      sector_t sectors = bad->len;
+-      sector_t s = bad->start;
+-      u64 *p = bb->page;
+-
+-      if ((s < BB_OFFSET(p[behind])) &&
+-          ((s + sectors) >= BB_OFFSET(p[behind])) &&
+-          ((BB_END(p[behind]) - s) <= BB_MAX_LEN) &&
+-          BB_ACK(p[behind]) == bad->ack)
+-              return true;
+-      return false;
+-}
+-
+-/*
+- * Do backward merge for range indicated by 'bad' and the bad range
+- * (from the bad table) indexed by 'behind'. The return value is merged
+- * sectors from bad->len.
+- */
+-static int behind_merge(struct badblocks *bb, struct badblocks_context *bad,
+-                      int behind)
+-{
+-      sector_t sectors = bad->len;
+-      sector_t s = bad->start;
+-      u64 *p = bb->page;
+-      int merged = 0;
+-
+-      WARN_ON(s >= BB_OFFSET(p[behind]));
+-      WARN_ON((s + sectors) < BB_OFFSET(p[behind]));
+-
+-      if (s < BB_OFFSET(p[behind])) {
+-              merged = BB_OFFSET(p[behind]) - s;
+-              p[behind] =  BB_MAKE(s, BB_LEN(p[behind]) + merged, bad->ack);
+-
+-              WARN_ON((BB_LEN(p[behind]) + merged) >= BB_MAX_LEN);
+-      }
+-
+-      return merged;
+-}
+-
+ /*
+  * Return 'true' if the range indicated by 'bad' can be forward
+  * merged with the bad range (from the bad table) indexed by 'prev'.
+@@ -884,11 +839,9 @@ static bool try_adjacent_combine(struct badblocks *bb, int prev)
+ static int _badblocks_set(struct badblocks *bb, sector_t s, int sectors,
+                         int acknowledged)
+ {
+-      int retried = 0, space_desired = 0;
+-      int orig_len, len = 0, added = 0;
++      int len = 0, added = 0;
+       struct badblocks_context bad;
+       int prev = -1, hint = -1;
+-      sector_t orig_start;
+       unsigned long flags;
+       int rv = 0;
+       u64 *p;
+@@ -912,8 +865,6 @@ static int _badblocks_set(struct badblocks *bb, sector_t s, int sectors,
+       write_seqlock_irqsave(&bb->lock, flags);
+-      orig_start = s;
+-      orig_len = sectors;
+       bad.ack = acknowledged;
+       p = bb->page;
+@@ -922,6 +873,11 @@ static int _badblocks_set(struct badblocks *bb, sector_t s, int sectors,
+       bad.len = sectors;
+       len = 0;
++      if (badblocks_full(bb)) {
++              rv = 1;
++              goto out;
++      }
++
+       if (badblocks_empty(bb)) {
+               len = insert_at(bb, 0, &bad);
+               bb->count++;
+@@ -933,32 +889,14 @@ static int _badblocks_set(struct badblocks *bb, sector_t s, int sectors,
+       /* start before all badblocks */
+       if (prev < 0) {
+-              if (!badblocks_full(bb)) {
+-                      /* insert on the first */
+-                      if (bad.len > (BB_OFFSET(p[0]) - bad.start))
+-                              bad.len = BB_OFFSET(p[0]) - bad.start;
+-                      len = insert_at(bb, 0, &bad);
+-                      bb->count++;
+-                      added++;
+-                      hint = 0;
+-                      goto update_sectors;
+-              }
+-
+-              /* No sapce, try to merge */
+-              if (overlap_behind(bb, &bad, 0)) {
+-                      if (can_merge_behind(bb, &bad, 0)) {
+-                              len = behind_merge(bb, &bad, 0);
+-                              added++;
+-                      } else {
+-                              len = BB_OFFSET(p[0]) - s;
+-                              space_desired = 1;
+-                      }
+-                      hint = 0;
+-                      goto update_sectors;
+-              }
+-
+-              /* no table space and give up */
+-              goto out;
++              /* insert on the first */
++              if (bad.len > (BB_OFFSET(p[0]) - bad.start))
++                      bad.len = BB_OFFSET(p[0]) - bad.start;
++              len = insert_at(bb, 0, &bad);
++              bb->count++;
++              added++;
++              hint = 0;
++              goto update_sectors;
+       }
+       /* in case p[prev-1] can be merged with p[prev] */
+@@ -978,6 +916,11 @@ static int _badblocks_set(struct badblocks *bb, sector_t s, int sectors,
+                       int extra = 0;
+                       if (!can_front_overwrite(bb, prev, &bad, &extra)) {
++                              if (extra > 0) {
++                                      rv = 1;
++                                      goto out;
++                              }
++
+                               len = min_t(sector_t,
+                                           BB_END(p[prev]) - s, sectors);
+                               hint = prev;
+@@ -1004,24 +947,6 @@ static int _badblocks_set(struct badblocks *bb, sector_t s, int sectors,
+               goto update_sectors;
+       }
+-      /* if no space in table, still try to merge in the covered range */
+-      if (badblocks_full(bb)) {
+-              /* skip the cannot-merge range */
+-              if (((prev + 1) < bb->count) &&
+-                  overlap_behind(bb, &bad, prev + 1) &&
+-                  ((s + sectors) >= BB_END(p[prev + 1]))) {
+-                      len = BB_END(p[prev + 1]) - s;
+-                      hint = prev + 1;
+-                      goto update_sectors;
+-              }
+-
+-              /* no retry any more */
+-              len = sectors;
+-              space_desired = 1;
+-              hint = -1;
+-              goto update_sectors;
+-      }
+-
+       /* cannot merge and there is space in bad table */
+       if ((prev + 1) < bb->count &&
+           overlap_behind(bb, &bad, prev + 1))
+@@ -1049,14 +974,6 @@ static int _badblocks_set(struct badblocks *bb, sector_t s, int sectors,
+        */
+       try_adjacent_combine(bb, prev);
+-      if (space_desired && !badblocks_full(bb)) {
+-              s = orig_start;
+-              sectors = orig_len;
+-              space_desired = 0;
+-              if (retried++ < 3)
+-                      goto re_insert;
+-      }
+-
+ out:
+       if (added) {
+               set_changed(bb);
+-- 
+2.39.5
+
diff --git a/queue-6.14/badblocks-return-error-if-any-badblock-set-fails.patch b/queue-6.14/badblocks-return-error-if-any-badblock-set-fails.patch
new file mode 100644 (file)
index 0000000..9e18a93
--- /dev/null
@@ -0,0 +1,104 @@
+From 3c0b44827a70392da241d2feee74aa0e5e5d7ff8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 15:55:00 +0800
+Subject: badblocks: return error if any badblock set fails
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit 7f500f0a59b1d7345a05ec4ae703babf34b7e470 ]
+
+_badblocks_set() returns success if at least one badblock is set
+successfully, even if others fail. This can lead to data inconsistencies
+in raid, where a failed badblock set should trigger the disk to be kicked
+out to prevent future reads from failed write areas.
+
+_badblocks_set() should return error if any badblock set fails. Instead
+of relying on 'rv', directly returning 'sectors' for clearer logic. If all
+badblocks are successfully set, 'sectors' will be 0, otherwise it
+indicates the number of badblocks that have not been set yet, thus
+signaling failure.
+
+By the way, it can also fix an issue: when a newly set unack badblock is
+included in an existing ack badblock, the setting will return an error.
+···
+  echo "0 100" /sys/block/md0/md/dev-loop1/bad_blocks
+  echo "0 100" /sys/block/md0/md/dev-loop1/unacknowledged_bad_blocks
+  -bash: echo: write error: No space left on device
+```
+After fix, it will return success.
+
+Fixes: aa511ff8218b ("badblocks: switch to the improved badblock handling code")
+Signed-off-by: Li Nan <linan122@huawei.com>
+Reviewed-by: Yu Kuai <yukuai3@huawei.com>
+Acked-by: Coly Li <colyli@kernel.org>
+Link: https://lore.kernel.org/r/20250227075507.151331-6-zhengqixing@huaweicloud.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/badblocks.c | 17 +++++------------
+ 1 file changed, 5 insertions(+), 12 deletions(-)
+
+diff --git a/block/badblocks.c b/block/badblocks.c
+index 1c8b8f65f6df4..88f27d4f38563 100644
+--- a/block/badblocks.c
++++ b/block/badblocks.c
+@@ -843,7 +843,6 @@ static int _badblocks_set(struct badblocks *bb, sector_t s, int sectors,
+       struct badblocks_context bad;
+       int prev = -1, hint = -1;
+       unsigned long flags;
+-      int rv = 0;
+       u64 *p;
+       if (bb->shift < 0)
+@@ -873,10 +872,8 @@ static int _badblocks_set(struct badblocks *bb, sector_t s, int sectors,
+       bad.len = sectors;
+       len = 0;
+-      if (badblocks_full(bb)) {
+-              rv = 1;
++      if (badblocks_full(bb))
+               goto out;
+-      }
+       if (badblocks_empty(bb)) {
+               len = insert_at(bb, 0, &bad);
+@@ -916,10 +913,8 @@ static int _badblocks_set(struct badblocks *bb, sector_t s, int sectors,
+                       int extra = 0;
+                       if (!can_front_overwrite(bb, prev, &bad, &extra)) {
+-                              if (extra > 0) {
+-                                      rv = 1;
++                              if (extra > 0)
+                                       goto out;
+-                              }
+                               len = min_t(sector_t,
+                                           BB_END(p[prev]) - s, sectors);
+@@ -986,10 +981,7 @@ static int _badblocks_set(struct badblocks *bb, sector_t s, int sectors,
+       write_sequnlock_irqrestore(&bb->lock, flags);
+-      if (!added)
+-              rv = 1;
+-
+-      return rv;
++      return sectors;
+ }
+ /*
+@@ -1353,7 +1345,8 @@ EXPORT_SYMBOL_GPL(badblocks_check);
+  *
+  * Return:
+  *  0: success
+- *  1: failed to set badblocks (out of space)
++ *  other: failed to set badblocks (out of space). Parital setting will be
++ *  treated as failure.
+  */
+ int badblocks_set(struct badblocks *bb, sector_t s, int sectors,
+                       int acknowledged)
+-- 
+2.39.5
+
diff --git a/queue-6.14/badblocks-use-sector_t-instead-of-int-to-avoid-trunc.patch b/queue-6.14/badblocks-use-sector_t-instead-of-int-to-avoid-trunc.patch
new file mode 100644 (file)
index 0000000..a7baea3
--- /dev/null
@@ -0,0 +1,319 @@
+From b8dfd8b712cd178fcba07d17a0ca14ee03654c84 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 15:55:07 +0800
+Subject: badblocks: use sector_t instead of int to avoid truncation of
+ badblocks length
+
+From: Zheng Qixing <zhengqixing@huawei.com>
+
+[ Upstream commit d301f164c3fbff611bd71f57dfa553b9219f0f5e ]
+
+There is a truncation of badblocks length issue when set badblocks as
+follow:
+
+echo "2055 4294967299" > bad_blocks
+cat bad_blocks
+2055 3
+
+Change 'sectors' argument type from 'int' to 'sector_t'.
+
+This change avoids truncation of badblocks length for large sectors by
+replacing 'int' with 'sector_t' (u64), enabling proper handling of larger
+disk sizes and ensuring compatibility with 64-bit sector addressing.
+
+Fixes: 9e0e252a048b ("badblocks: Add core badblock management code")
+Signed-off-by: Zheng Qixing <zhengqixing@huawei.com>
+Reviewed-by: Yu Kuai <yukuai3@huawei.com>
+Acked-by: Coly Li <colyli@kernel.org>
+Link: https://lore.kernel.org/r/20250227075507.151331-13-zhengqixing@huaweicloud.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/badblocks.c             | 20 ++++++++------------
+ drivers/block/null_blk/main.c |  3 +--
+ drivers/md/md.h               |  6 +++---
+ drivers/md/raid1-10.c         |  2 +-
+ drivers/md/raid1.c            |  4 ++--
+ drivers/md/raid10.c           |  8 ++++----
+ drivers/nvdimm/nd.h           |  2 +-
+ drivers/nvdimm/pfn_devs.c     |  7 ++++---
+ drivers/nvdimm/pmem.c         |  2 +-
+ include/linux/badblocks.h     |  8 ++++----
+ 10 files changed, 29 insertions(+), 33 deletions(-)
+
+diff --git a/block/badblocks.c b/block/badblocks.c
+index 753250a04c3fa..dc147c0179612 100644
+--- a/block/badblocks.c
++++ b/block/badblocks.c
+@@ -836,7 +836,7 @@ static bool try_adjacent_combine(struct badblocks *bb, int prev)
+ }
+ /* Do exact work to set bad block range into the bad block table */
+-static bool _badblocks_set(struct badblocks *bb, sector_t s, int sectors,
++static bool _badblocks_set(struct badblocks *bb, sector_t s, sector_t sectors,
+                          int acknowledged)
+ {
+       int len = 0, added = 0;
+@@ -960,8 +960,6 @@ static bool _badblocks_set(struct badblocks *bb, sector_t s, int sectors,
+       if (sectors > 0)
+               goto re_insert;
+-      WARN_ON(sectors < 0);
+-
+       /*
+        * Check whether the following already set range can be
+        * merged. (prev < 0) condition is not handled here,
+@@ -1052,7 +1050,7 @@ static int front_splitting_clear(struct badblocks *bb, int prev,
+ }
+ /* Do the exact work to clear bad block range from the bad block table */
+-static bool _badblocks_clear(struct badblocks *bb, sector_t s, int sectors)
++static bool _badblocks_clear(struct badblocks *bb, sector_t s, sector_t sectors)
+ {
+       struct badblocks_context bad;
+       int prev = -1, hint = -1;
+@@ -1175,8 +1173,6 @@ static bool _badblocks_clear(struct badblocks *bb, sector_t s, int sectors)
+       if (sectors > 0)
+               goto re_clear;
+-      WARN_ON(sectors < 0);
+-
+       if (cleared) {
+               badblocks_update_acked(bb);
+               set_changed(bb);
+@@ -1191,8 +1187,8 @@ static bool _badblocks_clear(struct badblocks *bb, sector_t s, int sectors)
+ }
+ /* Do the exact work to check bad blocks range from the bad block table */
+-static int _badblocks_check(struct badblocks *bb, sector_t s, int sectors,
+-                          sector_t *first_bad, int *bad_sectors)
++static int _badblocks_check(struct badblocks *bb, sector_t s, sector_t sectors,
++                          sector_t *first_bad, sector_t *bad_sectors)
+ {
+       int prev = -1, hint = -1, set = 0;
+       struct badblocks_context bad;
+@@ -1302,8 +1298,8 @@ static int _badblocks_check(struct badblocks *bb, sector_t s, int sectors,
+  * -1: there are bad blocks which have not yet been acknowledged in metadata.
+  * plus the start/length of the first bad section we overlap.
+  */
+-int badblocks_check(struct badblocks *bb, sector_t s, int sectors,
+-                      sector_t *first_bad, int *bad_sectors)
++int badblocks_check(struct badblocks *bb, sector_t s, sector_t sectors,
++                      sector_t *first_bad, sector_t *bad_sectors)
+ {
+       unsigned int seq;
+       int rv;
+@@ -1345,7 +1341,7 @@ EXPORT_SYMBOL_GPL(badblocks_check);
+  *  false: failed to set badblocks (out of space). Parital setting will be
+  *  treated as failure.
+  */
+-bool badblocks_set(struct badblocks *bb, sector_t s, int sectors,
++bool badblocks_set(struct badblocks *bb, sector_t s, sector_t sectors,
+                  int acknowledged)
+ {
+       return _badblocks_set(bb, s, sectors, acknowledged);
+@@ -1366,7 +1362,7 @@ EXPORT_SYMBOL_GPL(badblocks_set);
+  *  true: success
+  *  false: failed to clear badblocks
+  */
+-bool badblocks_clear(struct badblocks *bb, sector_t s, int sectors)
++bool badblocks_clear(struct badblocks *bb, sector_t s, sector_t sectors)
+ {
+       return _badblocks_clear(bb, s, sectors);
+ }
+diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c
+index f2a5f65abbf8b..59a10b0d122ce 100644
+--- a/drivers/block/null_blk/main.c
++++ b/drivers/block/null_blk/main.c
+@@ -1327,8 +1327,7 @@ blk_status_t null_handle_badblocks(struct nullb_cmd *cmd, sector_t sector,
+       struct badblocks *bb = &cmd->nq->dev->badblocks;
+       struct nullb_device *dev = cmd->nq->dev;
+       unsigned int block_sectors = dev->blocksize >> SECTOR_SHIFT;
+-      sector_t first_bad;
+-      int bad_sectors;
++      sector_t first_bad, bad_sectors;
+       unsigned int partial_io_sectors = 0;
+       if (!badblocks_check(bb, sector, *nr_sectors, &first_bad, &bad_sectors))
+diff --git a/drivers/md/md.h b/drivers/md/md.h
+index def808064ad8e..cc31c795369da 100644
+--- a/drivers/md/md.h
++++ b/drivers/md/md.h
+@@ -266,8 +266,8 @@ enum flag_bits {
+       Nonrot,                 /* non-rotational device (SSD) */
+ };
+-static inline int is_badblock(struct md_rdev *rdev, sector_t s, int sectors,
+-                            sector_t *first_bad, int *bad_sectors)
++static inline int is_badblock(struct md_rdev *rdev, sector_t s, sector_t sectors,
++                            sector_t *first_bad, sector_t *bad_sectors)
+ {
+       if (unlikely(rdev->badblocks.count)) {
+               int rv = badblocks_check(&rdev->badblocks, rdev->data_offset + s,
+@@ -284,7 +284,7 @@ static inline int rdev_has_badblock(struct md_rdev *rdev, sector_t s,
+                                   int sectors)
+ {
+       sector_t first_bad;
+-      int bad_sectors;
++      sector_t bad_sectors;
+       return is_badblock(rdev, s, sectors, &first_bad, &bad_sectors);
+ }
+diff --git a/drivers/md/raid1-10.c b/drivers/md/raid1-10.c
+index 4378d3250bd75..62b980b12f93a 100644
+--- a/drivers/md/raid1-10.c
++++ b/drivers/md/raid1-10.c
+@@ -247,7 +247,7 @@ static inline int raid1_check_read_range(struct md_rdev *rdev,
+                                        sector_t this_sector, int *len)
+ {
+       sector_t first_bad;
+-      int bad_sectors;
++      sector_t bad_sectors;
+       /* no bad block overlap */
+       if (!is_badblock(rdev, this_sector, *len, &first_bad, &bad_sectors))
+diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
+index 44dcfebff4f03..15829ab192d2b 100644
+--- a/drivers/md/raid1.c
++++ b/drivers/md/raid1.c
+@@ -1535,7 +1535,7 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
+               atomic_inc(&rdev->nr_pending);
+               if (test_bit(WriteErrorSeen, &rdev->flags)) {
+                       sector_t first_bad;
+-                      int bad_sectors;
++                      sector_t bad_sectors;
+                       int is_bad;
+                       is_bad = is_badblock(rdev, r1_bio->sector, max_sectors,
+@@ -2882,7 +2882,7 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr,
+               } else {
+                       /* may need to read from here */
+                       sector_t first_bad = MaxSector;
+-                      int bad_sectors;
++                      sector_t bad_sectors;
+                       if (is_badblock(rdev, sector_nr, good_sectors,
+                                       &first_bad, &bad_sectors)) {
+diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
+index 918a09f0ddd45..af010b64be63b 100644
+--- a/drivers/md/raid10.c
++++ b/drivers/md/raid10.c
+@@ -747,7 +747,7 @@ static struct md_rdev *read_balance(struct r10conf *conf,
+       for (slot = 0; slot < conf->copies ; slot++) {
+               sector_t first_bad;
+-              int bad_sectors;
++              sector_t bad_sectors;
+               sector_t dev_sector;
+               unsigned int pending;
+               bool nonrot;
+@@ -1430,7 +1430,7 @@ static void raid10_write_request(struct mddev *mddev, struct bio *bio,
+               if (rdev && test_bit(WriteErrorSeen, &rdev->flags)) {
+                       sector_t first_bad;
+                       sector_t dev_sector = r10_bio->devs[i].addr;
+-                      int bad_sectors;
++                      sector_t bad_sectors;
+                       int is_bad;
+                       is_bad = is_badblock(rdev, dev_sector, max_sectors,
+@@ -3404,7 +3404,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
+                               sector_t from_addr, to_addr;
+                               struct md_rdev *rdev = conf->mirrors[d].rdev;
+                               sector_t sector, first_bad;
+-                              int bad_sectors;
++                              sector_t bad_sectors;
+                               if (!rdev ||
+                                   !test_bit(In_sync, &rdev->flags))
+                                       continue;
+@@ -3600,7 +3600,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
+               for (i = 0; i < conf->copies; i++) {
+                       int d = r10_bio->devs[i].devnum;
+                       sector_t first_bad, sector;
+-                      int bad_sectors;
++                      sector_t bad_sectors;
+                       struct md_rdev *rdev;
+                       if (r10_bio->devs[i].repl_bio)
+diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h
+index 5ca06e9a2d292..cc5c8f3f81e8d 100644
+--- a/drivers/nvdimm/nd.h
++++ b/drivers/nvdimm/nd.h
+@@ -673,7 +673,7 @@ static inline bool is_bad_pmem(struct badblocks *bb, sector_t sector,
+ {
+       if (bb->count) {
+               sector_t first_bad;
+-              int num_bad;
++              sector_t num_bad;
+               return !!badblocks_check(bb, sector, len / 512, &first_bad,
+                               &num_bad);
+diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c
+index cfdfe0eaa5121..8f3e816e805d8 100644
+--- a/drivers/nvdimm/pfn_devs.c
++++ b/drivers/nvdimm/pfn_devs.c
+@@ -367,9 +367,10 @@ static int nd_pfn_clear_memmap_errors(struct nd_pfn *nd_pfn)
+       struct nd_namespace_common *ndns = nd_pfn->ndns;
+       void *zero_page = page_address(ZERO_PAGE(0));
+       struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb;
+-      int num_bad, meta_num, rc, bb_present;
++      int meta_num, rc, bb_present;
+       sector_t first_bad, meta_start;
+       struct nd_namespace_io *nsio;
++      sector_t num_bad;
+       if (nd_pfn->mode != PFN_MODE_PMEM)
+               return 0;
+@@ -394,7 +395,7 @@ static int nd_pfn_clear_memmap_errors(struct nd_pfn *nd_pfn)
+               bb_present = badblocks_check(&nd_region->bb, meta_start,
+                               meta_num, &first_bad, &num_bad);
+               if (bb_present) {
+-                      dev_dbg(&nd_pfn->dev, "meta: %x badblocks at %llx\n",
++                      dev_dbg(&nd_pfn->dev, "meta: %llx badblocks at %llx\n",
+                                       num_bad, first_bad);
+                       nsoff = ALIGN_DOWN((nd_region->ndr_start
+                                       + (first_bad << 9)) - nsio->res.start,
+@@ -413,7 +414,7 @@ static int nd_pfn_clear_memmap_errors(struct nd_pfn *nd_pfn)
+                       }
+                       if (rc) {
+                               dev_err(&nd_pfn->dev,
+-                                      "error clearing %x badblocks at %llx\n",
++                                      "error clearing %llx badblocks at %llx\n",
+                                       num_bad, first_bad);
+                               return rc;
+                       }
+diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
+index d81faa9d89c93..43156e1576c93 100644
+--- a/drivers/nvdimm/pmem.c
++++ b/drivers/nvdimm/pmem.c
+@@ -249,7 +249,7 @@ __weak long __pmem_direct_access(struct pmem_device *pmem, pgoff_t pgoff,
+       unsigned int num = PFN_PHYS(nr_pages) >> SECTOR_SHIFT;
+       struct badblocks *bb = &pmem->bb;
+       sector_t first_bad;
+-      int num_bad;
++      sector_t num_bad;
+       if (kaddr)
+               *kaddr = pmem->virt_addr + offset;
+diff --git a/include/linux/badblocks.h b/include/linux/badblocks.h
+index 8764bed9ff167..996493917f366 100644
+--- a/include/linux/badblocks.h
++++ b/include/linux/badblocks.h
+@@ -48,11 +48,11 @@ struct badblocks_context {
+       int             ack;
+ };
+-int badblocks_check(struct badblocks *bb, sector_t s, int sectors,
+-                 sector_t *first_bad, int *bad_sectors);
+-bool badblocks_set(struct badblocks *bb, sector_t s, int sectors,
++int badblocks_check(struct badblocks *bb, sector_t s, sector_t sectors,
++                  sector_t *first_bad, sector_t *bad_sectors);
++bool badblocks_set(struct badblocks *bb, sector_t s, sector_t sectors,
+                  int acknowledged);
+-bool badblocks_clear(struct badblocks *bb, sector_t s, int sectors);
++bool badblocks_clear(struct badblocks *bb, sector_t s, sector_t sectors);
+ void ack_all_badblocks(struct badblocks *bb);
+ ssize_t badblocks_show(struct badblocks *bb, char *page, int unack);
+ ssize_t badblocks_store(struct badblocks *bb, const char *page, size_t len,
+-- 
+2.39.5
+
diff --git a/queue-6.14/blk-throttle-fix-lower-bps-rate-by-throtl_trim_slice.patch b/queue-6.14/blk-throttle-fix-lower-bps-rate-by-throtl_trim_slice.patch
new file mode 100644 (file)
index 0000000..cb1e0d0
--- /dev/null
@@ -0,0 +1,105 @@
+From 1507addf84feaf50d438a531d5909833a478319b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 20:06:45 +0800
+Subject: blk-throttle: fix lower bps rate by throtl_trim_slice()
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit 29cb955934302a5da525db6b327c795572538426 ]
+
+The bio submission time may be a few jiffies more than the expected
+waiting time, due to 'extra_bytes' can't be divided in
+tg_within_bps_limit(), and also due to timer wakeup delay.
+In this case, adjust slice_start to jiffies will discard the extra wait time,
+causing lower rate than expected.
+
+Current in-tree code already covers deviation by rounddown(), but turns
+out it is not enough, because jiffies - slice_start can be a multiple of
+throtl_slice.
+
+For example, assume bps_limit is 1000bytes, 1 jiffes is 10ms, and
+slice is 20ms(2 jiffies), expected rate is 1000 / 1000 * 20 = 20 bytes
+per slice.
+
+If user issues two 21 bytes IO, then wait time will be 30ms for the
+first IO:
+
+bytes_allowed = 20, extra_bytes = 1;
+jiffy_wait = 1 + 2 = 3 jiffies
+
+and consider
+extra 1 jiffies by timer, throtl_trim_slice() will be called at:
+
+jiffies = 40ms
+slice_start = 0ms, slice_end= 40ms
+bytes_disp = 21
+
+In this case, before the patch, real rate in the first two slices is
+10.5 bytes per slice, and slice will be updated to:
+
+jiffies = 40ms
+slice_start = 40ms, slice_end = 60ms,
+bytes_disp = 0;
+
+Hence the second IO will have to wait another 30ms;
+
+With the patch, the real rate in the first slice is 20 bytes per slice,
+which is the same as expected, and slice will be updated:
+
+jiffies=40ms,
+slice_start = 20ms, slice_end = 60ms,
+bytes_disp = 1;
+
+And now, there is still 19 bytes allowed in the second slice, and the
+second IO will only have to wait 10ms;
+
+This problem will cause blktests throtl/001 failure in case of
+CONFIG_HZ_100=y, fix it by preserving one extra finished slice in
+throtl_trim_slice().
+
+Fixes: e43473b7f223 ("blkio: Core implementation of throttle policy")
+Reported-by: Ming Lei <ming.lei@redhat.com>
+Closes: https://lore.kernel.org/linux-block/20250222092823.210318-3-yukuai1@huaweicloud.com/
+Reviewed-by: Ming Lei <ming.lei@redhat.com>
+Acked-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Link: https://lore.kernel.org/r/20250227120645.812815-1-yukuai1@huaweicloud.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-throttle.c | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/block/blk-throttle.c b/block/blk-throttle.c
+index 8d149aff9fd0b..a52f0d6b40ad4 100644
+--- a/block/blk-throttle.c
++++ b/block/blk-throttle.c
+@@ -599,14 +599,23 @@ static inline void throtl_trim_slice(struct throtl_grp *tg, bool rw)
+        * sooner, then we need to reduce slice_end. A high bogus slice_end
+        * is bad because it does not allow new slice to start.
+        */
+-
+       throtl_set_slice_end(tg, rw, jiffies + tg->td->throtl_slice);
+       time_elapsed = rounddown(jiffies - tg->slice_start[rw],
+                                tg->td->throtl_slice);
+-      if (!time_elapsed)
++      /* Don't trim slice until at least 2 slices are used */
++      if (time_elapsed < tg->td->throtl_slice * 2)
+               return;
++      /*
++       * The bio submission time may be a few jiffies more than the expected
++       * waiting time, due to 'extra_bytes' can't be divided in
++       * tg_within_bps_limit(), and also due to timer wakeup delay. In this
++       * case, adjust slice_start will discard the extra wait time, causing
++       * lower rate than expected. Therefore, other than the above rounddown,
++       * one extra slice is preserved for deviation.
++       */
++      time_elapsed -= tg->td->throtl_slice;
+       bytes_trim = calculate_bytes_allowed(tg_bps_limit(tg, rw),
+                                            time_elapsed) +
+                    tg->carryover_bytes[rw];
+-- 
+2.39.5
+
diff --git a/queue-6.14/block-correctly-initialize-blk_integrity_nogenerate-.patch b/queue-6.14/block-correctly-initialize-blk_integrity_nogenerate-.patch
new file mode 100644 (file)
index 0000000..d595f87
--- /dev/null
@@ -0,0 +1,43 @@
+From 7a8cc2ea6f1877a2779ab00a7218ff09bfd65484 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Mar 2025 12:00:33 +0530
+Subject: block: Correctly initialize BLK_INTEGRITY_NOGENERATE and
+ BLK_INTEGRITY_NOVERIFY
+
+From: Anuj Gupta <anuj20.g@samsung.com>
+
+[ Upstream commit 85f72925000e924291a0ebf63d2234994a4f22bd ]
+
+Currently, BLK_INTEGRITY_NOGENERATE and BLK_INTEGRITY_NOVERIFY are not
+explicitly set during integrity initialization. This can lead to
+incorrect reporting of read_verify and write_generate sysfs values,
+particularly when a device does not support integrity. Ensure that these
+flags are correctly initialized by default.
+
+Reported-by: M Nikhil <nikh1092@linux.ibm.com>
+Link: https://lore.kernel.org/linux-block/f6130475-3ccd-45d2-abde-3ccceada0f0a@linux.ibm.com/
+Fixes: 9f4aa46f2a74 ("block: invert the BLK_INTEGRITY_{GENERATE,VERIFY} flags")
+Signed-off-by: Anuj Gupta <anuj20.g@samsung.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Link: https://lore.kernel.org/r/20250305063033.1813-3-anuj20.g@samsung.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-settings.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/block/blk-settings.c b/block/blk-settings.c
+index 0b0641fa33c02..66721afeea546 100644
+--- a/block/blk-settings.c
++++ b/block/blk-settings.c
+@@ -114,6 +114,7 @@ static int blk_validate_integrity_limits(struct queue_limits *lim)
+                       pr_warn("invalid PI settings.\n");
+                       return -EINVAL;
+               }
++              bi->flags |= BLK_INTEGRITY_NOGENERATE | BLK_INTEGRITY_NOVERIFY;
+               return 0;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/block-ensure-correct-integrity-capability-propagatio.patch b/queue-6.14/block-ensure-correct-integrity-capability-propagatio.patch
new file mode 100644 (file)
index 0000000..e9d8ef1
--- /dev/null
@@ -0,0 +1,94 @@
+From 71f0afd75f0f73e37df7b7bb1e5c18901dc29cb5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Mar 2025 12:00:32 +0530
+Subject: block: ensure correct integrity capability propagation in stacked
+ devices
+
+From: Anuj Gupta <anuj20.g@samsung.com>
+
+[ Upstream commit 677e332e4885a17def5efa4788b6e725a737b63c ]
+
+queue_limits_stack_integrity() incorrectly sets
+BLK_INTEGRITY_DEVICE_CAPABLE for a DM device even when none of its
+underlying devices support integrity. This happens because the flag is
+inherited unconditionally. Ensure that integrity capabilities are
+correctly propagated only when the underlying devices actually support
+integrity.
+
+Reported-by: M Nikhil <nikh1092@linux.ibm.com>
+Link: https://lore.kernel.org/linux-block/f6130475-3ccd-45d2-abde-3ccceada0f0a@linux.ibm.com/
+Fixes: c6e56cf6b2e7 ("block: move integrity information into queue_limits")
+Signed-off-by: Anuj Gupta <anuj20.g@samsung.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Link: https://lore.kernel.org/r/20250305063033.1813-2-anuj20.g@samsung.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-settings.c | 50 +++++++++++++++++++-------------------------
+ 1 file changed, 21 insertions(+), 29 deletions(-)
+
+diff --git a/block/blk-settings.c b/block/blk-settings.c
+index b9c6f0ec1c499..0b0641fa33c02 100644
+--- a/block/blk-settings.c
++++ b/block/blk-settings.c
+@@ -867,36 +867,28 @@ bool queue_limits_stack_integrity(struct queue_limits *t,
+       if (!IS_ENABLED(CONFIG_BLK_DEV_INTEGRITY))
+               return true;
+-      if (!ti->tuple_size) {
+-              /* inherit the settings from the first underlying device */
+-              if (!(ti->flags & BLK_INTEGRITY_STACKED)) {
+-                      ti->flags = BLK_INTEGRITY_DEVICE_CAPABLE |
+-                              (bi->flags & BLK_INTEGRITY_REF_TAG);
+-                      ti->csum_type = bi->csum_type;
+-                      ti->tuple_size = bi->tuple_size;
+-                      ti->pi_offset = bi->pi_offset;
+-                      ti->interval_exp = bi->interval_exp;
+-                      ti->tag_size = bi->tag_size;
+-                      goto done;
+-              }
+-              if (!bi->tuple_size)
+-                      goto done;
++      if (ti->flags & BLK_INTEGRITY_STACKED) {
++              if (ti->tuple_size != bi->tuple_size)
++                      goto incompatible;
++              if (ti->interval_exp != bi->interval_exp)
++                      goto incompatible;
++              if (ti->tag_size != bi->tag_size)
++                      goto incompatible;
++              if (ti->csum_type != bi->csum_type)
++                      goto incompatible;
++              if ((ti->flags & BLK_INTEGRITY_REF_TAG) !=
++                  (bi->flags & BLK_INTEGRITY_REF_TAG))
++                      goto incompatible;
++      } else {
++              ti->flags = BLK_INTEGRITY_STACKED;
++              ti->flags |= (bi->flags & BLK_INTEGRITY_DEVICE_CAPABLE) |
++                           (bi->flags & BLK_INTEGRITY_REF_TAG);
++              ti->csum_type = bi->csum_type;
++              ti->tuple_size = bi->tuple_size;
++              ti->pi_offset = bi->pi_offset;
++              ti->interval_exp = bi->interval_exp;
++              ti->tag_size = bi->tag_size;
+       }
+-
+-      if (ti->tuple_size != bi->tuple_size)
+-              goto incompatible;
+-      if (ti->interval_exp != bi->interval_exp)
+-              goto incompatible;
+-      if (ti->tag_size != bi->tag_size)
+-              goto incompatible;
+-      if (ti->csum_type != bi->csum_type)
+-              goto incompatible;
+-      if ((ti->flags & BLK_INTEGRITY_REF_TAG) !=
+-          (bi->flags & BLK_INTEGRITY_REF_TAG))
+-              goto incompatible;
+-
+-done:
+-      ti->flags |= BLK_INTEGRITY_STACKED;
+       return true;
+ incompatible:
+-- 
+2.39.5
+
diff --git a/queue-6.14/block-fix-adding-folio-to-bio.patch b/queue-6.14/block-fix-adding-folio-to-bio.patch
new file mode 100644 (file)
index 0000000..87b54da
--- /dev/null
@@ -0,0 +1,65 @@
+From 1f136a1567901115cd1068011c5ffea6259f7f0d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Mar 2025 22:51:36 +0800
+Subject: block: fix adding folio to bio
+
+From: Ming Lei <ming.lei@redhat.com>
+
+[ Upstream commit 26064d3e2b4d9a14df1072980e558c636fb023ea ]
+
+>4GB folio is possible on some ARCHs, such as aarch64, 16GB hugepage
+is supported, then 'offset' of folio can't be held in 'unsigned int',
+cause warning in bio_add_folio_nofail() and IO failure.
+
+Fix it by adjusting 'page' & trimming 'offset' so that `->bi_offset` won't
+be overflow, and folio can be added to bio successfully.
+
+Fixes: ed9832bc08db ("block: introduce folio awareness and add a bigger size from folio")
+Cc: Kundan Kumar <kundan.kumar@samsung.com>
+Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Luis Chamberlain <mcgrof@kernel.org>
+Cc: Gavin Shan <gshan@redhat.com>
+Signed-off-by: Ming Lei <ming.lei@redhat.com>
+Reviewed-by: Matthew Wilcox (Oracle) <willy@infradead.org>
+Link: https://lore.kernel.org/r/20250312145136.2891229-1-ming.lei@redhat.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/bio.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/block/bio.c b/block/bio.c
+index 6ac5983ba51e6..6deea10b2cd3d 100644
+--- a/block/bio.c
++++ b/block/bio.c
+@@ -1026,9 +1026,10 @@ EXPORT_SYMBOL(bio_add_page);
+ void bio_add_folio_nofail(struct bio *bio, struct folio *folio, size_t len,
+                         size_t off)
+ {
++      unsigned long nr = off / PAGE_SIZE;
++
+       WARN_ON_ONCE(len > UINT_MAX);
+-      WARN_ON_ONCE(off > UINT_MAX);
+-      __bio_add_page(bio, &folio->page, len, off);
++      __bio_add_page(bio, folio_page(folio, nr), len, off % PAGE_SIZE);
+ }
+ EXPORT_SYMBOL_GPL(bio_add_folio_nofail);
+@@ -1049,9 +1050,11 @@ EXPORT_SYMBOL_GPL(bio_add_folio_nofail);
+ bool bio_add_folio(struct bio *bio, struct folio *folio, size_t len,
+                  size_t off)
+ {
+-      if (len > UINT_MAX || off > UINT_MAX)
++      unsigned long nr = off / PAGE_SIZE;
++
++      if (len > UINT_MAX)
+               return false;
+-      return bio_add_page(bio, &folio->page, len, off) > 0;
++      return bio_add_page(bio, folio_page(folio, nr), len, off % PAGE_SIZE) > 0;
+ }
+ EXPORT_SYMBOL(bio_add_folio);
+-- 
+2.39.5
+
diff --git a/queue-6.14/bluetooth-add-quirk-for-broken-read_page_scan_type.patch b/queue-6.14/bluetooth-add-quirk-for-broken-read_page_scan_type.patch
new file mode 100644 (file)
index 0000000..092180d
--- /dev/null
@@ -0,0 +1,57 @@
+From 2ba31213c0b6db5a08325aca7b286d63e042d234 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 Mar 2025 03:22:59 -0300
+Subject: Bluetooth: Add quirk for broken READ_PAGE_SCAN_TYPE
+
+From: Pedro Nishiyama <nishiyama.pedro@gmail.com>
+
+[ Upstream commit 127881334eaad639e0a19a399ee8c91d6c9dc982 ]
+
+Some fake controllers cannot be initialized because they return a smaller
+report than expected for READ_PAGE_SCAN_TYPE.
+
+Signed-off-by: Pedro Nishiyama <nishiyama.pedro@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: 1f04b0e5e3b9 ("Bluetooth: btusb: Fix regression in the initialization of fake Bluetooth controllers")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/hci.h | 8 ++++++++
+ net/bluetooth/hci_sync.c    | 3 ++-
+ 2 files changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
+index 295d97e312e1d..aa684d2b079fa 100644
+--- a/include/net/bluetooth/hci.h
++++ b/include/net/bluetooth/hci.h
+@@ -362,6 +362,14 @@ enum {
+        * This quirk must be set before hci_register_dev is called.
+        */
+       HCI_QUIRK_BROKEN_READ_VOICE_SETTING,
++
++      /* When this quirk is set, the HCI_OP_READ_PAGE_SCAN_TYPE command is
++       * skipped. This is required for a subset of the CSR controller clones
++       * which erroneously claim to support it.
++       *
++       * This quirk must be set before hci_register_dev is called.
++       */
++      HCI_QUIRK_BROKEN_READ_PAGE_SCAN_TYPE,
+ };
+ /* HCI device flags */
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index 0c6a85abba2c5..cf60a8da943a5 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -4132,7 +4132,8 @@ static int hci_read_page_scan_type_sync(struct hci_dev *hdev)
+        * support the Read Page Scan Type command. Check support for
+        * this command in the bit mask of supported commands.
+        */
+-      if (!(hdev->commands[13] & 0x01))
++      if (!(hdev->commands[13] & 0x01) ||
++          test_bit(HCI_QUIRK_BROKEN_READ_PAGE_SCAN_TYPE, &hdev->quirks))
+               return 0;
+       return __hci_cmd_sync_status(hdev, HCI_OP_READ_PAGE_SCAN_TYPE,
+-- 
+2.39.5
+
diff --git a/queue-6.14/bluetooth-add-quirk-for-broken-read_voice_setting.patch b/queue-6.14/bluetooth-add-quirk-for-broken-read_voice_setting.patch
new file mode 100644 (file)
index 0000000..b704ee5
--- /dev/null
@@ -0,0 +1,73 @@
+From f885ed988e02e089c938b2dd9719ccd003d0505a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 Mar 2025 03:22:58 -0300
+Subject: Bluetooth: Add quirk for broken READ_VOICE_SETTING
+
+From: Pedro Nishiyama <nishiyama.pedro@gmail.com>
+
+[ Upstream commit ff26b2dd6568392f60fa67a4e58279938025c3af ]
+
+Some fake controllers cannot be initialized because they return a smaller
+report than expected for READ_VOICE_SETTING.
+
+Signed-off-by: Pedro Nishiyama <nishiyama.pedro@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: 1f04b0e5e3b9 ("Bluetooth: btusb: Fix regression in the initialization of fake Bluetooth controllers")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/hci.h      | 8 ++++++++
+ include/net/bluetooth/hci_core.h | 4 ++++
+ net/bluetooth/hci_sync.c         | 3 +++
+ 3 files changed, 15 insertions(+)
+
+diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
+index 3ec915738112b..295d97e312e1d 100644
+--- a/include/net/bluetooth/hci.h
++++ b/include/net/bluetooth/hci.h
+@@ -354,6 +354,14 @@ enum {
+        * during the hdev->setup vendor callback.
+        */
+       HCI_QUIRK_FIXUP_LE_EXT_ADV_REPORT_PHY,
++
++      /* When this quirk is set, the HCI_OP_READ_VOICE_SETTING command is
++       * skipped. This is required for a subset of the CSR controller clones
++       * which erroneously claim to support it.
++       *
++       * This quirk must be set before hci_register_dev is called.
++       */
++      HCI_QUIRK_BROKEN_READ_VOICE_SETTING,
+ };
+ /* HCI device flags */
+diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
+index 6281063cbd8e4..8649ad17408bb 100644
+--- a/include/net/bluetooth/hci_core.h
++++ b/include/net/bluetooth/hci_core.h
+@@ -1925,6 +1925,10 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
+       ((dev)->commands[20] & 0x10 && \
+        !test_bit(HCI_QUIRK_BROKEN_READ_ENC_KEY_SIZE, &hdev->quirks))
++#define read_voice_setting_capable(dev) \
++      ((dev)->commands[9] & 0x04 && \
++       !test_bit(HCI_QUIRK_BROKEN_READ_VOICE_SETTING, &(dev)->quirks))
++
+ /* Use enhanced synchronous connection if command is supported and its quirk
+  * has not been set.
+  */
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index dd770ef5ec368..0c6a85abba2c5 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -3696,6 +3696,9 @@ static int hci_read_local_name_sync(struct hci_dev *hdev)
+ /* Read Voice Setting */
+ static int hci_read_voice_setting_sync(struct hci_dev *hdev)
+ {
++      if (!read_voice_setting_capable(hdev))
++              return 0;
++
+       return __hci_cmd_sync_status(hdev, HCI_OP_READ_VOICE_SETTING,
+                                    0, NULL, HCI_CMD_TIMEOUT);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/bluetooth-btnxpuart-fix-kernel-panic-during-fw-relea.patch b/queue-6.14/bluetooth-btnxpuart-fix-kernel-panic-during-fw-relea.patch
new file mode 100644 (file)
index 0000000..340f240
--- /dev/null
@@ -0,0 +1,88 @@
+From f14e5b6d569855b4810e9626ddce4e714e7005db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Mar 2025 17:32:31 +0530
+Subject: Bluetooth: btnxpuart: Fix kernel panic during FW release
+
+From: Neeraj Sanjay Kale <neeraj.sanjaykale@nxp.com>
+
+[ Upstream commit 1f77c05408c96bc0b58ae476a9cadc9e5b9cfd0f ]
+
+This fixes a kernel panic seen during release FW in a stress test
+scenario where WLAN and BT FW download occurs simultaneously, and due to
+a HW bug, chip sends out only 1 bootloader signatures.
+
+When driver receives the bootloader signature, it enters FW download
+mode, but since no consequtive bootloader signatures seen, FW file is
+not requested.
+
+After 60 seconds, when FW download times out, release_firmware causes a
+kernel panic.
+
+[ 2601.949184] Unable to handle kernel paging request at virtual address 0000312e6f006573
+[ 2601.992076] user pgtable: 4k pages, 48-bit VAs, pgdp=0000000111802000
+[ 2601.992080] [0000312e6f006573] pgd=0000000000000000, p4d=0000000000000000
+[ 2601.992087] Internal error: Oops: 0000000096000021 [#1] PREEMPT SMP
+[ 2601.992091] Modules linked in: algif_hash algif_skcipher af_alg btnxpuart(O) pciexxx(O) mlan(O) overlay fsl_jr_uio caam_jr caamkeyblob_desc caamhash_desc caamalg_desc crypto_engine authenc libdes crct10dif_ce polyval_ce snd_soc_fsl_easrc snd_soc_fsl_asoc_card imx8_media_dev(C) snd_soc_fsl_micfil polyval_generic snd_soc_fsl_xcvr snd_soc_fsl_sai snd_soc_imx_audmux snd_soc_fsl_asrc snd_soc_imx_card snd_soc_imx_hdmi snd_soc_fsl_aud2htx snd_soc_fsl_utils imx_pcm_dma dw_hdmi_cec flexcan can_dev
+[ 2602.001825] CPU: 2 PID: 20060 Comm: hciconfig Tainted: G         C O       6.6.23-lts-next-06236-gb586a521770e #1
+[ 2602.010182] Hardware name: NXP i.MX8MPlus EVK board (DT)
+[ 2602.010185] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+[ 2602.010191] pc : _raw_spin_lock+0x34/0x68
+[ 2602.010201] lr : free_fw_priv+0x20/0xfc
+[ 2602.020561] sp : ffff800089363b30
+[ 2602.020563] x29: ffff800089363b30 x28: ffff0000d0eb5880 x27: 0000000000000000
+[ 2602.020570] x26: 0000000000000000 x25: ffff0000d728b330 x24: 0000000000000000
+[ 2602.020577] x23: ffff0000dc856f38
+[ 2602.033797] x22: ffff800089363b70 x21: ffff0000dc856000
+[ 2602.033802] x20: ff00312e6f006573 x19: ffff0000d0d9ea80 x18: 0000000000000000
+[ 2602.033809] x17: 0000000000000000 x16: 0000000000000000 x15: 0000aaaad80dd480
+[ 2602.083320] x14: 0000000000000000 x13: 00000000000001b9 x12: 0000000000000002
+[ 2602.083326] x11: 0000000000000000 x10: 0000000000000a60 x9 : ffff800089363a30
+[ 2602.083333] x8 : ffff0001793d75c0 x7 : ffff0000d6dbc400 x6 : 0000000000000000
+[ 2602.083339] x5 : 00000000410fd030 x4 : 0000000000000000 x3 : 0000000000000001
+[ 2602.083346] x2 : 0000000000000000 x1 : 0000000000000001 x0 : ff00312e6f006573
+[ 2602.083354] Call trace:
+[ 2602.083356]  _raw_spin_lock+0x34/0x68
+[ 2602.083364]  release_firmware+0x48/0x6c
+[ 2602.083370]  nxp_setup+0x3c4/0x540 [btnxpuart]
+[ 2602.083383]  hci_dev_open_sync+0xf0/0xa34
+[ 2602.083391]  hci_dev_open+0xd8/0x178
+[ 2602.083399]  hci_sock_ioctl+0x3b0/0x590
+[ 2602.083405]  sock_do_ioctl+0x60/0x118
+[ 2602.083413]  sock_ioctl+0x2f4/0x374
+[ 2602.091430]  __arm64_sys_ioctl+0xac/0xf0
+[ 2602.091437]  invoke_syscall+0x48/0x110
+[ 2602.091445]  el0_svc_common.constprop.0+0xc0/0xe0
+[ 2602.091452]  do_el0_svc+0x1c/0x28
+[ 2602.091457]  el0_svc+0x40/0xe4
+[ 2602.091465]  el0t_64_sync_handler+0x120/0x12c
+[ 2602.091470]  el0t_64_sync+0x190/0x194
+
+Fixes: e3c4891098c8 ("Bluetooth: btnxpuart: Handle FW Download Abort scenario")
+Fixes: 689ca16e5232 ("Bluetooth: NXP: Add protocol support for NXP Bluetooth chipsets")
+Signed-off-by: Neeraj Sanjay Kale <neeraj.sanjaykale@nxp.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btnxpuart.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c
+index aa5ec1d444a9d..6d66668d670a9 100644
+--- a/drivers/bluetooth/btnxpuart.c
++++ b/drivers/bluetooth/btnxpuart.c
+@@ -651,8 +651,10 @@ static int nxp_download_firmware(struct hci_dev *hdev)
+                                                        &nxpdev->tx_state),
+                                              msecs_to_jiffies(60000));
+-      release_firmware(nxpdev->fw);
+-      memset(nxpdev->fw_name, 0, sizeof(nxpdev->fw_name));
++      if (nxpdev->fw && strlen(nxpdev->fw_name)) {
++              release_firmware(nxpdev->fw);
++              memset(nxpdev->fw_name, 0, sizeof(nxpdev->fw_name));
++      }
+       if (err == 0) {
+               bt_dev_err(hdev, "FW Download Timeout. offset: %d",
+-- 
+2.39.5
+
diff --git a/queue-6.14/bluetooth-btusb-fix-regression-in-the-initialization.patch b/queue-6.14/bluetooth-btusb-fix-regression-in-the-initialization.patch
new file mode 100644 (file)
index 0000000..c7c79b1
--- /dev/null
@@ -0,0 +1,42 @@
+From 30106906bb597d4fa4062b220f04d8826c988b3e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 Mar 2025 03:23:01 -0300
+Subject: Bluetooth: btusb: Fix regression in the initialization of fake
+ Bluetooth controllers
+
+From: Pedro Nishiyama <nishiyama.pedro@gmail.com>
+
+[ Upstream commit 1f04b0e5e3b90b30f3ae7bee7e3d42a55fa91d5f ]
+
+Set HCI_READ_VOICE_SETTING and HCI_READ_PAGE_SCAN_TYPE as broken.
+
+Once the min/max length of the commands began to be asserted, these fake
+controllers can no longer be initialized because they return a smaller
+report for these commands.
+
+This affects various fake controllers reusing the 0A12:0001 VID/PID.
+
+Fixes: c8992cffbe74 ("Bluetooth: hci_event: Use of a function table to handle Command Complete")
+Signed-off-by: Pedro Nishiyama <nishiyama.pedro@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index a0fc465458b2f..699ff21d97675 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -2477,6 +2477,8 @@ static int btusb_setup_csr(struct hci_dev *hdev)
+               set_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks);
+               set_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks);
+               set_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks);
++              set_bit(HCI_QUIRK_BROKEN_READ_VOICE_SETTING, &hdev->quirks);
++              set_bit(HCI_QUIRK_BROKEN_READ_PAGE_SCAN_TYPE, &hdev->quirks);
+               /* Clear the reset quirk since this is not an actual
+                * early Bluetooth 1.1 device from CSR.
+-- 
+2.39.5
+
diff --git a/queue-6.14/bluetooth-hci-add-definition-of-hci_rp_remote_name_r.patch b/queue-6.14/bluetooth-hci-add-definition-of-hci_rp_remote_name_r.patch
new file mode 100644 (file)
index 0000000..5112d9a
--- /dev/null
@@ -0,0 +1,77 @@
+From 527f6fb0dd8726fd77120cab89c83e41a35fe955 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Mar 2025 02:50:34 +0800
+Subject: Bluetooth: HCI: Add definition of hci_rp_remote_name_req_cancel
+
+From: Wentao Guan <guanwentao@uniontech.com>
+
+[ Upstream commit e8c00f5433d020a2230226abe7e43f43dc686920 ]
+
+Return Parameters is not only status, also bdaddr:
+
+BLUETOOTH CORE SPECIFICATION Version 5.4 | Vol 4, Part E
+page 1870:
+BLUETOOTH CORE SPECIFICATION Version 5.0 | Vol 2, Part E
+page 802:
+
+Return parameters:
+  Status:
+  Size: 1 octet
+  BD_ADDR:
+  Size: 6 octets
+
+Note that it also fixes the warning:
+"Bluetooth: hci0: unexpected cc 0x041a length: 7 > 1"
+
+Fixes: c8992cffbe741 ("Bluetooth: hci_event: Use of a function table to handle Command Complete")
+Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
+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 | 5 +++++
+ net/bluetooth/hci_event.c   | 6 +++---
+ 2 files changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
+index 6da61c185c949..a8586c3058c7c 100644
+--- a/include/net/bluetooth/hci.h
++++ b/include/net/bluetooth/hci.h
+@@ -879,6 +879,11 @@ struct hci_cp_remote_name_req_cancel {
+       bdaddr_t bdaddr;
+ } __packed;
++struct hci_rp_remote_name_req_cancel {
++      __u8     status;
++      bdaddr_t bdaddr;
++} __packed;
++
+ #define HCI_OP_READ_REMOTE_FEATURES   0x041b
+ struct hci_cp_read_remote_features {
+       __le16   handle;
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index ab95e49f042ea..dd86b7a242b72 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -151,7 +151,7 @@ static u8 hci_cc_exit_periodic_inq(struct hci_dev *hdev, void *data,
+ static u8 hci_cc_remote_name_req_cancel(struct hci_dev *hdev, void *data,
+                                       struct sk_buff *skb)
+ {
+-      struct hci_ev_status *rp = data;
++      struct hci_rp_remote_name_req_cancel *rp = data;
+       bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
+@@ -4012,8 +4012,8 @@ static const struct hci_cc {
+       HCI_CC_STATUS(HCI_OP_INQUIRY_CANCEL, hci_cc_inquiry_cancel),
+       HCI_CC_STATUS(HCI_OP_PERIODIC_INQ, hci_cc_periodic_inq),
+       HCI_CC_STATUS(HCI_OP_EXIT_PERIODIC_INQ, hci_cc_exit_periodic_inq),
+-      HCI_CC_STATUS(HCI_OP_REMOTE_NAME_REQ_CANCEL,
+-                    hci_cc_remote_name_req_cancel),
++      HCI_CC(HCI_OP_REMOTE_NAME_REQ_CANCEL, hci_cc_remote_name_req_cancel,
++             sizeof(struct hci_rp_remote_name_req_cancel)),
+       HCI_CC(HCI_OP_ROLE_DISCOVERY, hci_cc_role_discovery,
+              sizeof(struct hci_rp_role_discovery)),
+       HCI_CC(HCI_OP_READ_LINK_POLICY, hci_cc_read_link_policy,
+-- 
+2.39.5
+
diff --git a/queue-6.14/bluetooth-hci_core-enable-buffer-flow-control-for-sc.patch b/queue-6.14/bluetooth-hci_core-enable-buffer-flow-control-for-sc.patch
new file mode 100644 (file)
index 0000000..3ef429b
--- /dev/null
@@ -0,0 +1,279 @@
+From 7193c84cbde49daf79a51968e55c30045b8e84c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Mar 2025 11:14:20 -0400
+Subject: Bluetooth: hci_core: Enable buffer flow control for SCO/eSCO
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 13218453521d75916dfed55efb8e809bfc03cb4b ]
+
+This enables buffer flow control for SCO/eSCO
+(see: Bluetooth Core 6.0 spec: 6.22. Synchronous Flow Control Enable),
+recently this has caused the following problem and is actually a nice
+addition for the likes of Socket TX complete:
+
+< HCI Command: Read Buffer Size (0x04|0x0005) plen 0
+> HCI Event: Command Complete (0x0e) plen 11
+      Read Buffer Size (0x04|0x0005) ncmd 1
+        Status: Success (0x00)
+        ACL MTU: 1021 ACL max packet: 5
+        SCO MTU: 240  SCO max packet: 8
+...
+< SCO Data TX: Handle 257 flags 0x00 dlen 120
+< SCO Data TX: Handle 257 flags 0x00 dlen 120
+< SCO Data TX: Handle 257 flags 0x00 dlen 120
+< SCO Data TX: Handle 257 flags 0x00 dlen 120
+< SCO Data TX: Handle 257 flags 0x00 dlen 120
+< SCO Data TX: Handle 257 flags 0x00 dlen 120
+< SCO Data TX: Handle 257 flags 0x00 dlen 120
+< SCO Data TX: Handle 257 flags 0x00 dlen 120
+< SCO Data TX: Handle 257 flags 0x00 dlen 120
+> HCI Event: Hardware Error (0x10) plen 1
+        Code: 0x0a
+
+To fix the code will now attempt to enable buffer flow control when
+HCI_QUIRK_SYNC_FLOWCTL_SUPPORTED is set by the driver:
+
+< HCI Command: Write Sync Fl.. (0x03|0x002f) plen 1
+        Flow control: Enabled (0x01)
+> HCI Event: Command Complete (0x0e) plen 4
+      Write Sync Flow Control Enable (0x03|0x002f) ncmd 1
+        Status: Success (0x00)
+
+On success then HCI_SCO_FLOWCTL would be set which indicates sco_cnt
+shall be used for flow contro.
+
+Fixes: 7fedd3bb6b77 ("Bluetooth: Prioritize SCO traffic")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Tested-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/hci.h      | 13 +++++++
+ include/net/bluetooth/hci_core.h |  1 +
+ net/bluetooth/hci_core.c         | 62 +++++++++++++++-----------------
+ net/bluetooth/hci_event.c        |  2 ++
+ net/bluetooth/hci_sync.c         | 24 +++++++++++++
+ 5 files changed, 68 insertions(+), 34 deletions(-)
+
+diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
+index aa684d2b079fa..6da61c185c949 100644
+--- a/include/net/bluetooth/hci.h
++++ b/include/net/bluetooth/hci.h
+@@ -208,6 +208,13 @@ enum {
+        */
+       HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED,
++      /* When this quirk is set consider Sync Flow Control as supported by
++       * the driver.
++       *
++       * This quirk must be set before hci_register_dev is called.
++       */
++      HCI_QUIRK_SYNC_FLOWCTL_SUPPORTED,
++
+       /* When this quirk is set, the LE states reported through the
+        * HCI_LE_READ_SUPPORTED_STATES are invalid/broken.
+        *
+@@ -448,6 +455,7 @@ enum {
+       HCI_WIDEBAND_SPEECH_ENABLED,
+       HCI_EVENT_FILTER_CONFIGURED,
+       HCI_PA_SYNC,
++      HCI_SCO_FLOWCTL,
+       HCI_DUT_MODE,
+       HCI_VENDOR_DIAG,
+@@ -1544,6 +1552,11 @@ struct hci_rp_read_tx_power {
+       __s8     tx_power;
+ } __packed;
++#define HCI_OP_WRITE_SYNC_FLOWCTL     0x0c2f
++struct hci_cp_write_sync_flowctl {
++      __u8     enable;
++} __packed;
++
+ #define HCI_OP_READ_PAGE_SCAN_TYPE    0x0c46
+ struct hci_rp_read_page_scan_type {
+       __u8     status;
+diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
+index 8649ad17408bb..f0b49aad519eb 100644
+--- a/include/net/bluetooth/hci_core.h
++++ b/include/net/bluetooth/hci_core.h
+@@ -1858,6 +1858,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
+ #define lmp_hold_capable(dev)      ((dev)->features[0][0] & LMP_HOLD)
+ #define lmp_sniff_capable(dev)     ((dev)->features[0][0] & LMP_SNIFF)
+ #define lmp_park_capable(dev)      ((dev)->features[0][1] & LMP_PARK)
++#define lmp_sco_capable(dev)       ((dev)->features[0][1] & LMP_SCO)
+ #define lmp_inq_rssi_capable(dev)  ((dev)->features[0][3] & LMP_RSSI_INQ)
+ #define lmp_esco_capable(dev)      ((dev)->features[0][3] & LMP_ESCO)
+ #define lmp_bredr_capable(dev)     (!((dev)->features[0][4] & LMP_NO_BREDR))
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index 012fc107901a6..94d9147612daf 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -3552,42 +3552,27 @@ static void __check_timeout(struct hci_dev *hdev, unsigned int cnt, u8 type)
+ }
+ /* Schedule SCO */
+-static void hci_sched_sco(struct hci_dev *hdev)
++static void hci_sched_sco(struct hci_dev *hdev, __u8 type)
+ {
+       struct hci_conn *conn;
+       struct sk_buff *skb;
+-      int quote;
++      int quote, *cnt;
++      unsigned int pkts = hdev->sco_pkts;
+-      BT_DBG("%s", hdev->name);
++      bt_dev_dbg(hdev, "type %u", type);
+-      if (!hci_conn_num(hdev, SCO_LINK))
++      if (!hci_conn_num(hdev, type) || !pkts)
+               return;
+-      while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
+-              while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
+-                      BT_DBG("skb %p len %d", skb, skb->len);
+-                      hci_send_frame(hdev, skb);
+-
+-                      conn->sent++;
+-                      if (conn->sent == ~0)
+-                              conn->sent = 0;
+-              }
+-      }
+-}
+-
+-static void hci_sched_esco(struct hci_dev *hdev)
+-{
+-      struct hci_conn *conn;
+-      struct sk_buff *skb;
+-      int quote;
+-
+-      BT_DBG("%s", hdev->name);
+-
+-      if (!hci_conn_num(hdev, ESCO_LINK))
+-              return;
++      /* Use sco_pkts if flow control has not been enabled which will limit
++       * the amount of buffer sent in a row.
++       */
++      if (!hci_dev_test_flag(hdev, HCI_SCO_FLOWCTL))
++              cnt = &pkts;
++      else
++              cnt = &hdev->sco_cnt;
+-      while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
+-                                                   &quote))) {
++      while (*cnt && (conn = hci_low_sent(hdev, type, &quote))) {
+               while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
+                       BT_DBG("skb %p len %d", skb, skb->len);
+                       hci_send_frame(hdev, skb);
+@@ -3595,8 +3580,17 @@ static void hci_sched_esco(struct hci_dev *hdev)
+                       conn->sent++;
+                       if (conn->sent == ~0)
+                               conn->sent = 0;
++                      (*cnt)--;
+               }
+       }
++
++      /* Rescheduled if all packets were sent and flow control is not enabled
++       * as there could be more packets queued that could not be sent and
++       * since no HCI_EV_NUM_COMP_PKTS event will be generated the reschedule
++       * needs to be forced.
++       */
++      if (!pkts && !hci_dev_test_flag(hdev, HCI_SCO_FLOWCTL))
++              queue_work(hdev->workqueue, &hdev->tx_work);
+ }
+ static void hci_sched_acl_pkt(struct hci_dev *hdev)
+@@ -3632,8 +3626,8 @@ static void hci_sched_acl_pkt(struct hci_dev *hdev)
+                       chan->conn->sent++;
+                       /* Send pending SCO packets right away */
+-                      hci_sched_sco(hdev);
+-                      hci_sched_esco(hdev);
++                      hci_sched_sco(hdev, SCO_LINK);
++                      hci_sched_sco(hdev, ESCO_LINK);
+               }
+       }
+@@ -3688,8 +3682,8 @@ static void hci_sched_le(struct hci_dev *hdev)
+                       chan->conn->sent++;
+                       /* Send pending SCO packets right away */
+-                      hci_sched_sco(hdev);
+-                      hci_sched_esco(hdev);
++                      hci_sched_sco(hdev, SCO_LINK);
++                      hci_sched_sco(hdev, ESCO_LINK);
+               }
+       }
+@@ -3734,8 +3728,8 @@ static void hci_tx_work(struct work_struct *work)
+       if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
+               /* Schedule queues and send stuff to HCI driver */
+-              hci_sched_sco(hdev);
+-              hci_sched_esco(hdev);
++              hci_sched_sco(hdev, SCO_LINK);
++              hci_sched_sco(hdev, ESCO_LINK);
+               hci_sched_iso(hdev);
+               hci_sched_acl(hdev);
+               hci_sched_le(hdev);
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 903b0b52692aa..ab95e49f042ea 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -4442,9 +4442,11 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data,
+                       break;
+               case SCO_LINK:
++              case ESCO_LINK:
+                       hdev->sco_cnt += count;
+                       if (hdev->sco_cnt > hdev->sco_pkts)
+                               hdev->sco_cnt = hdev->sco_pkts;
++
+                       break;
+               case ISO_LINK:
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index cf60a8da943a5..14c3ee5c6a1e8 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -3769,6 +3769,28 @@ static int hci_write_ca_timeout_sync(struct hci_dev *hdev)
+                                    sizeof(param), &param, HCI_CMD_TIMEOUT);
+ }
++/* Enable SCO flow control if supported */
++static int hci_write_sync_flowctl_sync(struct hci_dev *hdev)
++{
++      struct hci_cp_write_sync_flowctl cp;
++      int err;
++
++      /* Check if the controller supports SCO and HCI_OP_WRITE_SYNC_FLOWCTL */
++      if (!lmp_sco_capable(hdev) || !(hdev->commands[10] & BIT(4)) ||
++          !test_bit(HCI_QUIRK_SYNC_FLOWCTL_SUPPORTED, &hdev->quirks))
++              return 0;
++
++      memset(&cp, 0, sizeof(cp));
++      cp.enable = 0x01;
++
++      err = __hci_cmd_sync_status(hdev, HCI_OP_WRITE_SYNC_FLOWCTL,
++                                  sizeof(cp), &cp, HCI_CMD_TIMEOUT);
++      if (!err)
++              hci_dev_set_flag(hdev, HCI_SCO_FLOWCTL);
++
++      return err;
++}
++
+ /* BR Controller init stage 2 command sequence */
+ static const struct hci_init_stage br_init2[] = {
+       /* HCI_OP_READ_BUFFER_SIZE */
+@@ -3787,6 +3809,8 @@ static const struct hci_init_stage br_init2[] = {
+       HCI_INIT(hci_clear_event_filter_sync),
+       /* HCI_OP_WRITE_CA_TIMEOUT */
+       HCI_INIT(hci_write_ca_timeout_sync),
++      /* HCI_OP_WRITE_SYNC_FLOWCTL */
++      HCI_INIT(hci_write_sync_flowctl_sync),
+       {}
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.14/bluetooth-hci_event-fix-handling-of-hci_ev_le_direct.patch b/queue-6.14/bluetooth-hci_event-fix-handling-of-hci_ev_le_direct.patch
new file mode 100644 (file)
index 0000000..7863911
--- /dev/null
@@ -0,0 +1,81 @@
+From 982e28dc71449cfb332a05e70453581fcf2419e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Mar 2025 11:22:23 -0400
+Subject: Bluetooth: hci_event: Fix handling of HCI_EV_LE_DIRECT_ADV_REPORT
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 3a7fdfb7d876910cfe734488f553dbbc938f8f16 ]
+
+Some controllers seems to generate HCI_EV_LE_DIRECT_ADV_REPORT even when
+scan_filter is not set to 0x02 or 0x03, which indicates that local
+privacy is enabled, causing them to be ignored thus breaking
+auto-connect logic:
+
+< HCI Command: LE Set Scan Parameters (0x08|0x000b) plen 7
+        Type: Passive (0x00)
+        Interval: 60.000 msec (0x0060)
+        Window: 30.000 msec (0x0030)
+        Own address type: Public (0x00)
+        Filter policy: Ignore not in accept list (0x01)
+...
+> HCI Event: LE Meta Event (0x3e) plen 18
+      LE Direct Advertising Report (0x0b)
+        Num reports: 1
+        Event type: Connectable directed - ADV_DIRECT_IND (0x01)
+        Address type: Random (0x01)
+        Address: XX:XX:XX:XX:XX:XX (Static)
+        Direct address type: Random (0x01)
+        Direct address: XX:XX:XX:XX:XX:XX (Non-Resolvable)
+        RSSI: -54 dBm (0xca)
+
+So this attempts to mitigate the above problem by skipping checking of
+direct_addr if local privacy is not enabled.
+
+Link: https://github.com/bluez/bluez/issues/1138
+Fixes: e209e5ccc5ac ("Bluetooth: MGMT: Mark LL Privacy as stable")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index dd86b7a242b72..e2bfbcee06a80 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -6053,8 +6053,17 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
+        * a LE Direct Advertising Report event. In that case it is
+        * important to see if the address is matching the local
+        * controller address.
++       *
++       * If local privacy is not enable the controller shall not be
++       * generating such event since according to its documentation it is only
++       * valid for filter_policy 0x02 and 0x03, but the fact that it did
++       * generate LE Direct Advertising Report means it is probably broken and
++       * won't generate any other event which can potentially break
++       * auto-connect logic so in case local privacy is not enable this
++       * ignores the direct_addr so it works as a regular report.
+        */
+-      if (!hci_dev_test_flag(hdev, HCI_MESH) && direct_addr) {
++      if (!hci_dev_test_flag(hdev, HCI_MESH) && direct_addr &&
++          hci_dev_test_flag(hdev, HCI_PRIVACY)) {
+               direct_addr_type = ev_bdaddr_type(hdev, direct_addr_type,
+                                                 &bdaddr_resolved);
+@@ -6064,12 +6073,6 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
+               if (!hci_bdaddr_is_rpa(direct_addr, direct_addr_type))
+                       return;
+-              /* If the controller is not using resolvable random
+-               * addresses, then this report can be ignored.
+-               */
+-              if (!hci_dev_test_flag(hdev, HCI_PRIVACY))
+-                      return;
+-
+               /* If the local IRK of the controller does not match
+                * with the resolvable random address provided, then
+                * this report can be ignored.
+-- 
+2.39.5
+
diff --git a/queue-6.14/bnxt_en-linearize-tx-skb-if-the-fragments-exceed-the.patch b/queue-6.14/bnxt_en-linearize-tx-skb-if-the-fragments-exceed-the.patch
new file mode 100644 (file)
index 0000000..09c65bd
--- /dev/null
@@ -0,0 +1,68 @@
+From ae9c78eae569420c26f490dac0c0edb1a4c386c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Mar 2025 14:16:39 -0700
+Subject: bnxt_en: Linearize TX SKB if the fragments exceed the max
+
+From: Michael Chan <michael.chan@broadcom.com>
+
+[ Upstream commit b91e82129400bdc40ee1232aa7e32ae6027f9b4f ]
+
+If skb_shinfo(skb)->nr_frags excceds what the chip can support,
+linearize the SKB and warn once to let the user know.
+net.core.max_skb_frags can be lowered, for example, to avoid the
+issue.
+
+Fixes: 3948b05950fd ("net: introduce a config option to tweak MAX_SKB_FRAGS")
+Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
+Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250321211639.3812992-3-michael.chan@broadcom.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/bnxt/bnxt.c | 11 +++++++++++
+ drivers/net/ethernet/broadcom/bnxt/bnxt.h |  4 ++++
+ 2 files changed, 15 insertions(+)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index 158e9789c1f46..2cd79b59cf002 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -485,6 +485,17 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
+       txr = &bp->tx_ring[bp->tx_ring_map[i]];
+       prod = txr->tx_prod;
++#if (MAX_SKB_FRAGS > TX_MAX_FRAGS)
++      if (skb_shinfo(skb)->nr_frags > TX_MAX_FRAGS) {
++              netdev_warn_once(dev, "SKB has too many (%d) fragments, max supported is %d.  SKB will be linearized.\n",
++                               skb_shinfo(skb)->nr_frags, TX_MAX_FRAGS);
++              if (skb_linearize(skb)) {
++                      dev_kfree_skb_any(skb);
++                      dev_core_stats_tx_dropped_inc(dev);
++                      return NETDEV_TX_OK;
++              }
++      }
++#endif
+       free_size = bnxt_tx_avail(bp, txr);
+       if (unlikely(free_size < skb_shinfo(skb)->nr_frags + 2)) {
+               /* We must have raced with NAPI cleanup */
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+index 3b4a044db73e3..d621fb621f30c 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+@@ -84,6 +84,10 @@ struct tx_bd {
+ #define TX_BD_CNT(n)  (((n) << TX_BD_FLAGS_BD_CNT_SHIFT) & TX_BD_FLAGS_BD_CNT)
++#define TX_MAX_BD_CNT 32
++
++#define TX_MAX_FRAGS          (TX_MAX_BD_CNT - 2)
++
+ struct tx_bd_ext {
+       __le32 tx_bd_hsize_lflags;
+       #define TX_BD_FLAGS_TCP_UDP_CHKSUM                      (1 << 0)
+-- 
+2.39.5
+
diff --git a/queue-6.14/bnxt_en-mask-the-bd_cnt-field-in-the-tx-bd-properly.patch b/queue-6.14/bnxt_en-mask-the-bd_cnt-field-in-the-tx-bd-properly.patch
new file mode 100644 (file)
index 0000000..6f3ebef
--- /dev/null
@@ -0,0 +1,90 @@
+From b60503b054192adc55d782f885a5a21e81013648 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Mar 2025 14:16:38 -0700
+Subject: bnxt_en: Mask the bd_cnt field in the TX BD properly
+
+From: Michael Chan <michael.chan@broadcom.com>
+
+[ Upstream commit 107b25db61122d8f990987895c2912927b8b6e3f ]
+
+The bd_cnt field in the TX BD specifies the total number of BDs for
+the TX packet.  The bd_cnt field has 5 bits and the maximum number
+supported is 32 with the value 0.
+
+CONFIG_MAX_SKB_FRAGS can be modified and the total number of SKB
+fragments can approach or exceed the maximum supported by the chip.
+Add a macro to properly mask the bd_cnt field so that the value 32
+will be properly masked and set to 0 in the bd_cnd field.
+
+Without this patch, the out-of-range bd_cnt value will corrupt the
+TX BD and may cause TX timeout.
+
+The next patch will check for values exceeding 32.
+
+Fixes: 3948b05950fd ("net: introduce a config option to tweak MAX_SKB_FRAGS")
+Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
+Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250321211639.3812992-2-michael.chan@broadcom.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/bnxt/bnxt.c     | 4 ++--
+ drivers/net/ethernet/broadcom/bnxt/bnxt.h     | 2 ++
+ drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 3 +--
+ 3 files changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index 0ddc3d41e2d81..158e9789c1f46 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -564,7 +564,7 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
+                                       TX_BD_FLAGS_LHINT_512_AND_SMALLER |
+                                       TX_BD_FLAGS_COAL_NOW |
+                                       TX_BD_FLAGS_PACKET_END |
+-                                      (2 << TX_BD_FLAGS_BD_CNT_SHIFT));
++                                      TX_BD_CNT(2));
+               if (skb->ip_summed == CHECKSUM_PARTIAL)
+                       tx_push1->tx_bd_hsize_lflags =
+@@ -639,7 +639,7 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
+       dma_unmap_addr_set(tx_buf, mapping, mapping);
+       flags = (len << TX_BD_LEN_SHIFT) | TX_BD_TYPE_LONG_TX_BD |
+-              ((last_frag + 2) << TX_BD_FLAGS_BD_CNT_SHIFT);
++              TX_BD_CNT(last_frag + 2);
+       txbd->tx_bd_haddr = cpu_to_le64(mapping);
+       txbd->tx_bd_opaque = SET_TX_OPAQUE(bp, txr, prod, 2 + last_frag);
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+index 2373f423a523e..3b4a044db73e3 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+@@ -82,6 +82,8 @@ struct tx_bd {
+ #define TX_OPAQUE_PROD(bp, opq)       ((TX_OPAQUE_IDX(opq) + TX_OPAQUE_BDS(opq)) &\
+                                (bp)->tx_ring_mask)
++#define TX_BD_CNT(n)  (((n) << TX_BD_FLAGS_BD_CNT_SHIFT) & TX_BD_FLAGS_BD_CNT)
++
+ struct tx_bd_ext {
+       __le32 tx_bd_hsize_lflags;
+       #define TX_BD_FLAGS_TCP_UDP_CHKSUM                      (1 << 0)
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
+index 299822cacca48..d71bad3cfd6bd 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
+@@ -48,8 +48,7 @@ struct bnxt_sw_tx_bd *bnxt_xmit_bd(struct bnxt *bp,
+               tx_buf->page = virt_to_head_page(xdp->data);
+       txbd = &txr->tx_desc_ring[TX_RING(bp, prod)][TX_IDX(prod)];
+-      flags = (len << TX_BD_LEN_SHIFT) |
+-              ((num_frags + 1) << TX_BD_FLAGS_BD_CNT_SHIFT) |
++      flags = (len << TX_BD_LEN_SHIFT) | TX_BD_CNT(num_frags + 1) |
+               bnxt_lhint_arr[len >> 9];
+       txbd->tx_bd_len_flags_type = cpu_to_le32(flags);
+       txbd->tx_bd_opaque = SET_TX_OPAQUE(bp, txr, prod, 1 + num_frags);
+-- 
+2.39.5
+
diff --git a/queue-6.14/bonding-check-xdp-prog-when-set-bond-mode.patch b/queue-6.14/bonding-check-xdp-prog-when-set-bond-mode.patch
new file mode 100644 (file)
index 0000000..9ae79de
--- /dev/null
@@ -0,0 +1,146 @@
+From f739897ecd68bfdd86ea0d727bacdfd867d85909 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Mar 2025 12:48:52 +0800
+Subject: bonding: check xdp prog when set bond mode
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Wang Liang <wangliang74@huawei.com>
+
+[ Upstream commit 094ee6017ea09c11d6af187935a949df32803ce0 ]
+
+Following operations can trigger a warning[1]:
+
+    ip netns add ns1
+    ip netns exec ns1 ip link add bond0 type bond mode balance-rr
+    ip netns exec ns1 ip link set dev bond0 xdp obj af_xdp_kern.o sec xdp
+    ip netns exec ns1 ip link set bond0 type bond mode broadcast
+    ip netns del ns1
+
+When delete the namespace, dev_xdp_uninstall() is called to remove xdp
+program on bond dev, and bond_xdp_set() will check the bond mode. If bond
+mode is changed after attaching xdp program, the warning may occur.
+
+Some bond modes (broadcast, etc.) do not support native xdp. Set bond mode
+with xdp program attached is not good. Add check for xdp program when set
+bond mode.
+
+    [1]
+    ------------[ cut here ]------------
+    WARNING: CPU: 0 PID: 11 at net/core/dev.c:9912 unregister_netdevice_many_notify+0x8d9/0x930
+    Modules linked in:
+    CPU: 0 UID: 0 PID: 11 Comm: kworker/u4:0 Not tainted 6.14.0-rc4 #107
+    Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.15.0-0-g2dd4b9b3f840-prebuilt.qemu.org 04/01/2014
+    Workqueue: netns cleanup_net
+    RIP: 0010:unregister_netdevice_many_notify+0x8d9/0x930
+    Code: 00 00 48 c7 c6 6f e3 a2 82 48 c7 c7 d0 b3 96 82 e8 9c 10 3e ...
+    RSP: 0018:ffffc90000063d80 EFLAGS: 00000282
+    RAX: 00000000ffffffa1 RBX: ffff888004959000 RCX: 00000000ffffdfff
+    RDX: 0000000000000000 RSI: 00000000ffffffea RDI: ffffc90000063b48
+    RBP: ffffc90000063e28 R08: ffffffff82d39b28 R09: 0000000000009ffb
+    R10: 0000000000000175 R11: ffffffff82d09b40 R12: ffff8880049598e8
+    R13: 0000000000000001 R14: dead000000000100 R15: ffffc90000045000
+    FS:  0000000000000000(0000) GS:ffff888007a00000(0000) knlGS:0000000000000000
+    CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+    CR2: 000000000d406b60 CR3: 000000000483e000 CR4: 00000000000006f0
+    Call Trace:
+     <TASK>
+     ? __warn+0x83/0x130
+     ? unregister_netdevice_many_notify+0x8d9/0x930
+     ? report_bug+0x18e/0x1a0
+     ? handle_bug+0x54/0x90
+     ? exc_invalid_op+0x18/0x70
+     ? asm_exc_invalid_op+0x1a/0x20
+     ? unregister_netdevice_many_notify+0x8d9/0x930
+     ? bond_net_exit_batch_rtnl+0x5c/0x90
+     cleanup_net+0x237/0x3d0
+     process_one_work+0x163/0x390
+     worker_thread+0x293/0x3b0
+     ? __pfx_worker_thread+0x10/0x10
+     kthread+0xec/0x1e0
+     ? __pfx_kthread+0x10/0x10
+     ? __pfx_kthread+0x10/0x10
+     ret_from_fork+0x2f/0x50
+     ? __pfx_kthread+0x10/0x10
+     ret_from_fork_asm+0x1a/0x30
+     </TASK>
+    ---[ end trace 0000000000000000 ]---
+
+Fixes: 9e2ee5c7e7c3 ("net, bonding: Add XDP support to the bonding driver")
+Signed-off-by: Wang Liang <wangliang74@huawei.com>
+Acked-by: Jussi Maki <joamaki@gmail.com>
+Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
+Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
+Link: https://patch.msgid.link/20250321044852.1086551-1-wangliang74@huawei.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/bonding/bond_main.c    | 8 ++++----
+ drivers/net/bonding/bond_options.c | 3 +++
+ include/net/bonding.h              | 1 +
+ 3 files changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index e45bba240cbcd..4da5fcb7def47 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -322,9 +322,9 @@ static bool bond_sk_check(struct bonding *bond)
+       }
+ }
+-static bool bond_xdp_check(struct bonding *bond)
++bool bond_xdp_check(struct bonding *bond, int mode)
+ {
+-      switch (BOND_MODE(bond)) {
++      switch (mode) {
+       case BOND_MODE_ROUNDROBIN:
+       case BOND_MODE_ACTIVEBACKUP:
+               return true;
+@@ -1937,7 +1937,7 @@ void bond_xdp_set_features(struct net_device *bond_dev)
+       ASSERT_RTNL();
+-      if (!bond_xdp_check(bond) || !bond_has_slaves(bond)) {
++      if (!bond_xdp_check(bond, BOND_MODE(bond)) || !bond_has_slaves(bond)) {
+               xdp_clear_features_flag(bond_dev);
+               return;
+       }
+@@ -5699,7 +5699,7 @@ static int bond_xdp_set(struct net_device *dev, struct bpf_prog *prog,
+       ASSERT_RTNL();
+-      if (!bond_xdp_check(bond)) {
++      if (!bond_xdp_check(bond, BOND_MODE(bond))) {
+               BOND_NL_ERR(dev, extack,
+                           "No native XDP support for the current bonding mode");
+               return -EOPNOTSUPP;
+diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
+index d1b095af253bd..91893c29b8995 100644
+--- a/drivers/net/bonding/bond_options.c
++++ b/drivers/net/bonding/bond_options.c
+@@ -868,6 +868,9 @@ static bool bond_set_xfrm_features(struct bonding *bond)
+ static int bond_option_mode_set(struct bonding *bond,
+                               const struct bond_opt_value *newval)
+ {
++      if (bond->xdp_prog && !bond_xdp_check(bond, newval->value))
++              return -EOPNOTSUPP;
++
+       if (!bond_mode_uses_arp(newval->value)) {
+               if (bond->params.arp_interval) {
+                       netdev_dbg(bond->dev, "%s mode is incompatible with arp monitoring, start mii monitoring\n",
+diff --git a/include/net/bonding.h b/include/net/bonding.h
+index 8bb5f016969f1..95f67b308c19a 100644
+--- a/include/net/bonding.h
++++ b/include/net/bonding.h
+@@ -695,6 +695,7 @@ void bond_debug_register(struct bonding *bond);
+ void bond_debug_unregister(struct bonding *bond);
+ void bond_debug_reregister(struct bonding *bond);
+ const char *bond_mode_name(int mode);
++bool bond_xdp_check(struct bonding *bond, int mode);
+ void bond_setup(struct net_device *bond_dev);
+ unsigned int bond_get_num_tx_queues(void);
+ int bond_netlink_init(void);
+-- 
+2.39.5
+
diff --git a/queue-6.14/bpf-fix-array-bounds-error-with-may_goto.patch b/queue-6.14/bpf-fix-array-bounds-error-with-may_goto.patch
new file mode 100644 (file)
index 0000000..13471c0
--- /dev/null
@@ -0,0 +1,102 @@
+From c6c22a4a90e96b65f4e90a626982f65b5381c160 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Feb 2025 17:18:21 +0800
+Subject: bpf: Fix array bounds error with may_goto
+
+From: Jiayuan Chen <mrpre@163.com>
+
+[ Upstream commit 6ebc5030e0c5a698f1dd9a6684cddf6ccaed64a0 ]
+
+may_goto uses an additional 8 bytes on the stack, which causes the
+interpreters[] array to go out of bounds when calculating index by
+stack_size.
+
+1. If a BPF program is rewritten, re-evaluate the stack size. For non-JIT
+cases, reject loading directly.
+
+2. For non-JIT cases, calculating interpreters[idx] may still cause
+out-of-bounds array access, and just warn about it.
+
+3. For jit_requested cases, the execution of bpf_func also needs to be
+warned. So move the definition of function __bpf_prog_ret0_warn out of
+the macro definition CONFIG_BPF_JIT_ALWAYS_ON.
+
+Reported-by: syzbot+d2a2c639d03ac200a4f1@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/bpf/0000000000000f823606139faa5d@google.com/
+Fixes: 011832b97b311 ("bpf: Introduce may_goto instruction")
+Signed-off-by: Jiayuan Chen <mrpre@163.com>
+Link: https://lore.kernel.org/r/20250214091823.46042-2-mrpre@163.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/core.c     | 19 +++++++++++++++----
+ kernel/bpf/verifier.c |  7 +++++++
+ 2 files changed, 22 insertions(+), 4 deletions(-)
+
+diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
+index da729cbbaeb90..a0200fbbace99 100644
+--- a/kernel/bpf/core.c
++++ b/kernel/bpf/core.c
+@@ -2290,17 +2290,18 @@ void bpf_patch_call_args(struct bpf_insn *insn, u32 stack_depth)
+       insn->code = BPF_JMP | BPF_CALL_ARGS;
+ }
+ #endif
+-#else
++#endif
++
+ static unsigned int __bpf_prog_ret0_warn(const void *ctx,
+                                        const struct bpf_insn *insn)
+ {
+       /* If this handler ever gets executed, then BPF_JIT_ALWAYS_ON
+-       * is not working properly, so warn about it!
++       * is not working properly, or interpreter is being used when
++       * prog->jit_requested is not 0, so warn about it!
+        */
+       WARN_ON_ONCE(1);
+       return 0;
+ }
+-#endif
+ bool bpf_prog_map_compatible(struct bpf_map *map,
+                            const struct bpf_prog *fp)
+@@ -2380,8 +2381,18 @@ static void bpf_prog_select_func(struct bpf_prog *fp)
+ {
+ #ifndef CONFIG_BPF_JIT_ALWAYS_ON
+       u32 stack_depth = max_t(u32, fp->aux->stack_depth, 1);
++      u32 idx = (round_up(stack_depth, 32) / 32) - 1;
+-      fp->bpf_func = interpreters[(round_up(stack_depth, 32) / 32) - 1];
++      /* may_goto may cause stack size > 512, leading to idx out-of-bounds.
++       * But for non-JITed programs, we don't need bpf_func, so no bounds
++       * check needed.
++       */
++      if (!fp->jit_requested &&
++          !WARN_ON_ONCE(idx >= ARRAY_SIZE(interpreters))) {
++              fp->bpf_func = interpreters[idx];
++      } else {
++              fp->bpf_func = __bpf_prog_ret0_warn;
++      }
+ #else
+       fp->bpf_func = __bpf_prog_ret0_warn;
+ #endif
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 60611df77957a..c6f3b5f4ff2be 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -21897,6 +21897,13 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
+               if (subprogs[cur_subprog + 1].start == i + delta + 1) {
+                       subprogs[cur_subprog].stack_depth += stack_depth_extra;
+                       subprogs[cur_subprog].stack_extra = stack_depth_extra;
++
++                      stack_depth = subprogs[cur_subprog].stack_depth;
++                      if (stack_depth > MAX_BPF_STACK && !prog->jit_requested) {
++                              verbose(env, "stack size %d(extra %d) is too large\n",
++                                      stack_depth, stack_depth_extra);
++                              return -EINVAL;
++                      }
+                       cur_subprog++;
+                       stack_depth = subprogs[cur_subprog].stack_depth;
+                       stack_depth_extra = 0;
+-- 
+2.39.5
+
diff --git a/queue-6.14/bpf-use-preempt_count-directly-in-bpf_send_signal_co.patch b/queue-6.14/bpf-use-preempt_count-directly-in-bpf_send_signal_co.patch
new file mode 100644 (file)
index 0000000..0f68bc2
--- /dev/null
@@ -0,0 +1,47 @@
+From aca870978c3660d28dcba346e34cb6304e68256e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Feb 2025 12:22:59 +0800
+Subject: bpf: Use preempt_count() directly in bpf_send_signal_common()
+
+From: Hou Tao <houtao1@huawei.com>
+
+[ Upstream commit b4a8b5bba712a711d8ca1f7d04646db63f9c88f5 ]
+
+bpf_send_signal_common() uses preemptible() to check whether or not the
+current context is preemptible. If it is preemptible, it will use
+irq_work to send the signal asynchronously instead of trying to hold a
+spin-lock, because spin-lock is sleepable under PREEMPT_RT.
+
+However, preemptible() depends on CONFIG_PREEMPT_COUNT. When
+CONFIG_PREEMPT_COUNT is turned off (e.g., CONFIG_PREEMPT_VOLUNTARY=y),
+!preemptible() will be evaluated as 1 and bpf_send_signal_common() will
+use irq_work unconditionally.
+
+Fix it by unfolding "!preemptible()" and using "preempt_count() != 0 ||
+irqs_disabled()" instead.
+
+Fixes: 87c544108b61 ("bpf: Send signals asynchronously if !preemptible")
+Signed-off-by: Hou Tao <houtao1@huawei.com>
+Link: https://lore.kernel.org/r/20250220042259.1583319-1-houtao@huaweicloud.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, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
+index adc947587eb81..a612f6f182e51 100644
+--- a/kernel/trace/bpf_trace.c
++++ b/kernel/trace/bpf_trace.c
+@@ -843,7 +843,7 @@ static int bpf_send_signal_common(u32 sig, enum pid_type type, struct task_struc
+       if (unlikely(is_global_init(task)))
+               return -EPERM;
+-      if (!preemptible()) {
++      if (preempt_count() != 0 || irqs_disabled()) {
+               /* Do an early check on signal validity. Otherwise,
+                * the error is lost in deferred irq_work.
+                */
+-- 
+2.39.5
+
diff --git a/queue-6.14/broadcom-fix-supported-flag-check-in-periodic-output.patch b/queue-6.14/broadcom-fix-supported-flag-check-in-periodic-output.patch
new file mode 100644 (file)
index 0000000..fcab0bb
--- /dev/null
@@ -0,0 +1,45 @@
+From aa53dd267268671b7afc038a24ba8c62921e5ce0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Mar 2025 15:15:53 -0700
+Subject: broadcom: fix supported flag check in periodic output function
+
+From: Jacob Keller <jacob.e.keller@intel.com>
+
+[ Upstream commit af2b428f7992c07b0767c9a3c341b54d9069542e ]
+
+In bcm_ptp_perout_locked, the driver rejects requests which have
+PTP_PEROUT_PHASE set. This appears to be an attempt to reject any
+unsupported flags. Unfortunately, this only checks one flag, but does not
+protect against PTP_PEROUT_ONE_SHOT, or any future flags which may be
+added.
+
+Fix the check to ensure that no flag other than the supported
+PTP_PEROUT_DUTY_CYCLE is set.
+
+Fixes: 7bfe91efd525 ("net: phy: Add support for 1PPS out and external timestamps")
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250312-jk-net-fixes-supported-extts-flags-v2-4-ea930ba82459@intel.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/bcm-phy-ptp.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/phy/bcm-phy-ptp.c b/drivers/net/phy/bcm-phy-ptp.c
+index 208e8f561e069..eba8b5fb1365f 100644
+--- a/drivers/net/phy/bcm-phy-ptp.c
++++ b/drivers/net/phy/bcm-phy-ptp.c
+@@ -597,7 +597,8 @@ static int bcm_ptp_perout_locked(struct bcm_ptp_private *priv,
+       period = BCM_MAX_PERIOD_8NS;    /* write nonzero value */
+-      if (req->flags & PTP_PEROUT_PHASE)
++      /* Reject unsupported flags */
++      if (req->flags & ~PTP_PEROUT_DUTY_CYCLE)
+               return -EOPNOTSUPP;
+       if (req->flags & PTP_PEROUT_DUTY_CYCLE)
+-- 
+2.39.5
+
diff --git a/queue-6.14/btrfs-don-t-clobber-ret-in-btrfs_validate_super.patch b/queue-6.14/btrfs-don-t-clobber-ret-in-btrfs_validate_super.patch
new file mode 100644 (file)
index 0000000..a852ba6
--- /dev/null
@@ -0,0 +1,42 @@
+From 9f8f951678a86d65c0fc6cb58ae972abf745d028 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Mar 2025 16:39:25 +0000
+Subject: btrfs: don't clobber ret in btrfs_validate_super()
+
+From: Mark Harmstone <maharmstone@fb.com>
+
+[ Upstream commit 9db9c7dd5b4e1d3205137a094805980082c37716 ]
+
+Commit 2a9bb78cfd36 ("btrfs: validate system chunk array at
+btrfs_validate_super()") introduces a call to validate_sys_chunk_array()
+in btrfs_validate_super(), which clobbers the value of ret set earlier.
+This has the effect of negating the validity checks done earlier, making
+it so btrfs could potentially try to mount invalid filesystems.
+
+Fixes: 2a9bb78cfd36 ("btrfs: validate system chunk array at btrfs_validate_super()")
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Mark Harmstone <maharmstone@fb.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/disk-io.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
+index f09db62e61a1b..70b61bc237e98 100644
+--- a/fs/btrfs/disk-io.c
++++ b/fs/btrfs/disk-io.c
+@@ -2561,6 +2561,9 @@ int btrfs_validate_super(const struct btrfs_fs_info *fs_info,
+               ret = -EINVAL;
+       }
++      if (ret)
++              return ret;
++
+       ret = validate_sys_chunk_array(fs_info, sb);
+       /*
+-- 
+2.39.5
+
diff --git a/queue-6.14/btrfs-fix-block-group-refcount-race-in-btrfs_create_.patch b/queue-6.14/btrfs-fix-block-group-refcount-race-in-btrfs_create_.patch
new file mode 100644 (file)
index 0000000..2c07b10
--- /dev/null
@@ -0,0 +1,113 @@
+From 060790d9734f67d2bc10039d1a9867103c3b08a9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Mar 2025 15:03:13 -0800
+Subject: btrfs: fix block group refcount race in
+ btrfs_create_pending_block_groups()
+
+From: Boris Burkov <boris@bur.io>
+
+[ Upstream commit 2d8e5168d48a91e7a802d3003e72afb4304bebfa ]
+
+Block group creation is done in two phases, which results in a slightly
+unintuitive property: a block group can be allocated/deallocated from
+after btrfs_make_block_group() adds it to the space_info with
+btrfs_add_bg_to_space_info(), but before creation is completely completed
+in btrfs_create_pending_block_groups(). As a result, it is possible for a
+block group to go unused and have 'btrfs_mark_bg_unused' called on it
+concurrently with 'btrfs_create_pending_block_groups'. This causes a
+number of issues, which were fixed with the block group flag
+'BLOCK_GROUP_FLAG_NEW'.
+
+However, this fix is not quite complete. Since it does not use the
+unused_bg_lock, it is possible for the following race to occur:
+
+btrfs_create_pending_block_groups            btrfs_mark_bg_unused
+                                           if list_empty // false
+        list_del_init
+        clear_bit
+                                           else if (test_bit) // true
+                                                list_move_tail
+
+And we get into the exact same broken ref count and invalid new_bgs
+state for transaction cleanup that BLOCK_GROUP_FLAG_NEW was designed to
+prevent.
+
+The broken refcount aspect will result in a warning like:
+
+  [1272.943527] refcount_t: underflow; use-after-free.
+  [1272.943967] WARNING: CPU: 1 PID: 61 at lib/refcount.c:28 refcount_warn_saturate+0xba/0x110
+  [1272.944731] Modules linked in: btrfs virtio_net xor zstd_compress raid6_pq null_blk [last unloaded: btrfs]
+  [1272.945550] CPU: 1 UID: 0 PID: 61 Comm: kworker/u32:1 Kdump: loaded Tainted: G        W          6.14.0-rc5+ #108
+  [1272.946368] Tainted: [W]=WARN
+  [1272.946585] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Arch Linux 1.16.3-1-1 04/01/2014
+  [1272.947273] Workqueue: btrfs_discard btrfs_discard_workfn [btrfs]
+  [1272.947788] RIP: 0010:refcount_warn_saturate+0xba/0x110
+  [1272.949532] RSP: 0018:ffffbf1200247df0 EFLAGS: 00010282
+  [1272.949901] RAX: 0000000000000000 RBX: ffffa14b00e3f800 RCX: 0000000000000000
+  [1272.950437] RDX: 0000000000000000 RSI: ffffbf1200247c78 RDI: 00000000ffffdfff
+  [1272.950986] RBP: ffffa14b00dc2860 R08: 00000000ffffdfff R09: ffffffff90526268
+  [1272.951512] R10: ffffffff904762c0 R11: 0000000063666572 R12: ffffa14b00dc28c0
+  [1272.952024] R13: 0000000000000000 R14: ffffa14b00dc2868 R15: 000001285dcd12c0
+  [1272.952850] FS:  0000000000000000(0000) GS:ffffa14d33c40000(0000) knlGS:0000000000000000
+  [1272.953458] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+  [1272.953931] CR2: 00007f838cbda000 CR3: 000000010104e000 CR4: 00000000000006f0
+  [1272.954474] Call Trace:
+  [1272.954655]  <TASK>
+  [1272.954812]  ? refcount_warn_saturate+0xba/0x110
+  [1272.955173]  ? __warn.cold+0x93/0xd7
+  [1272.955487]  ? refcount_warn_saturate+0xba/0x110
+  [1272.955816]  ? report_bug+0xe7/0x120
+  [1272.956103]  ? handle_bug+0x53/0x90
+  [1272.956424]  ? exc_invalid_op+0x13/0x60
+  [1272.956700]  ? asm_exc_invalid_op+0x16/0x20
+  [1272.957011]  ? refcount_warn_saturate+0xba/0x110
+  [1272.957399]  btrfs_discard_cancel_work.cold+0x26/0x2b [btrfs]
+  [1272.957853]  btrfs_put_block_group.cold+0x5d/0x8e [btrfs]
+  [1272.958289]  btrfs_discard_workfn+0x194/0x380 [btrfs]
+  [1272.958729]  process_one_work+0x130/0x290
+  [1272.959026]  worker_thread+0x2ea/0x420
+  [1272.959335]  ? __pfx_worker_thread+0x10/0x10
+  [1272.959644]  kthread+0xd7/0x1c0
+  [1272.959872]  ? __pfx_kthread+0x10/0x10
+  [1272.960172]  ret_from_fork+0x30/0x50
+  [1272.960474]  ? __pfx_kthread+0x10/0x10
+  [1272.960745]  ret_from_fork_asm+0x1a/0x30
+  [1272.961035]  </TASK>
+  [1272.961238] ---[ end trace 0000000000000000 ]---
+
+Though we have seen them in the async discard workfn as well. It is
+most likely to happen after a relocation finishes which cancels discard,
+tears down the block group, etc.
+
+Fix this fully by taking the lock around the list_del_init + clear_bit
+so that the two are done atomically.
+
+Fixes: 0657b20c5a76 ("btrfs: fix use-after-free of new block group that became unused")
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Boris Burkov <boris@bur.io>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/block-group.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
+index 3a89a6c3a7aa1..b96b235943344 100644
+--- a/fs/btrfs/block-group.c
++++ b/fs/btrfs/block-group.c
+@@ -2796,8 +2796,11 @@ void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans)
+               /* Already aborted the transaction if it failed. */
+ next:
+               btrfs_dec_delayed_refs_rsv_bg_inserts(fs_info);
++
++              spin_lock(&fs_info->unused_bgs_lock);
+               list_del_init(&block_group->bg_list);
+               clear_bit(BLOCK_GROUP_FLAG_NEW, &block_group->runtime_flags);
++              spin_unlock(&fs_info->unused_bgs_lock);
+               /*
+                * If the block group is still unused, add it to the list of
+-- 
+2.39.5
+
diff --git a/queue-6.14/btrfs-fix-reclaimed-bytes-accounting-after-automatic.patch b/queue-6.14/btrfs-fix-reclaimed-bytes-accounting-after-automatic.patch
new file mode 100644 (file)
index 0000000..f4943d6
--- /dev/null
@@ -0,0 +1,128 @@
+From c659b36d65c1bd7e2f79e836cb0be25637a217db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Feb 2025 16:22:22 +0000
+Subject: btrfs: fix reclaimed bytes accounting after automatic block group
+ reclaim
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit 620768704326c9a71ea9c8324ffda8748d8d4f10 ]
+
+We are considering the used bytes counter of a block group as the amount
+to update the space info's reclaim bytes counter after relocating the
+block group, but this value alone is often not enough. This is because we
+may have a reserved extent (or more) and in that case its size is
+reflected in the reserved counter of the block group - the size of the
+extent is only transferred from the reserved counter to the used counter
+of the block group when the delayed ref for the extent is run - typically
+when committing the transaction (or when flushing delayed refs due to
+ENOSPC on space reservation). Such call chain for data extents is:
+
+   btrfs_run_delayed_refs_for_head()
+       run_one_delayed_ref()
+           run_delayed_data_ref()
+               alloc_reserved_file_extent()
+                   alloc_reserved_extent()
+                       btrfs_update_block_group()
+                          -> transfers the extent size from the reserved
+                             counter to the used counter
+
+For metadata extents:
+
+   btrfs_run_delayed_refs_for_head()
+       run_one_delayed_ref()
+           run_delayed_tree_ref()
+               alloc_reserved_tree_block()
+                   alloc_reserved_extent()
+                       btrfs_update_block_group()
+                           -> transfers the extent size from the reserved
+                              counter to the used counter
+
+Since relocation flushes delalloc, waits for ordered extent completion
+and commits the current transaction before doing the actual relocation
+work, the correct amount of reclaimed space is therefore the sum of the
+"used" and "reserved" counters of the block group before we call
+btrfs_relocate_chunk() at btrfs_reclaim_bgs_work().
+
+So fix this by taking the "reserved" counter into consideration.
+
+Fixes: 243192b67649 ("btrfs: report reclaim stats in sysfs")
+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/block-group.c | 28 +++++++++++++++++++++-------
+ 1 file changed, 21 insertions(+), 7 deletions(-)
+
+diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
+index ed0b1a955d74a..3a89a6c3a7aa1 100644
+--- a/fs/btrfs/block-group.c
++++ b/fs/btrfs/block-group.c
+@@ -1824,6 +1824,7 @@ void btrfs_reclaim_bgs_work(struct work_struct *work)
+       while (!list_empty(&fs_info->reclaim_bgs)) {
+               u64 zone_unusable;
+               u64 used;
++              u64 reserved;
+               int ret = 0;
+               bg = list_first_entry(&fs_info->reclaim_bgs,
+@@ -1916,21 +1917,32 @@ void btrfs_reclaim_bgs_work(struct work_struct *work)
+                       goto next;
+               /*
+-               * Grab the used bytes counter while holding the block group's
+-               * spinlock to prevent races with tasks concurrently updating it
+-               * due to extent allocation and deallocation (running
+-               * btrfs_update_block_group()) - we have set the block group to
+-               * RO but that only prevents extent reservation, allocation
+-               * happens after reservation.
++               * The amount of bytes reclaimed corresponds to the sum of the
++               * "used" and "reserved" counters. We have set the block group
++               * to RO above, which prevents reservations from happening but
++               * we may have existing reservations for which allocation has
++               * not yet been done - btrfs_update_block_group() was not yet
++               * called, which is where we will transfer a reserved extent's
++               * size from the "reserved" counter to the "used" counter - this
++               * happens when running delayed references. When we relocate the
++               * chunk below, relocation first flushes dellaloc, waits for
++               * ordered extent completion (which is where we create delayed
++               * references for data extents) and commits the current
++               * transaction (which runs delayed references), and only after
++               * it does the actual work to move extents out of the block
++               * group. So the reported amount of reclaimed bytes is
++               * effectively the sum of the 'used' and 'reserved' counters.
+                */
+               spin_lock(&bg->lock);
+               used = bg->used;
++              reserved = bg->reserved;
+               spin_unlock(&bg->lock);
+               btrfs_info(fs_info,
+-                      "reclaiming chunk %llu with %llu%% used %llu%% unusable",
++      "reclaiming chunk %llu with %llu%% used %llu%% reserved %llu%% unusable",
+                               bg->start,
+                               div64_u64(used * 100, bg->length),
++                              div64_u64(reserved * 100, bg->length),
+                               div64_u64(zone_unusable * 100, bg->length));
+               trace_btrfs_reclaim_block_group(bg);
+               ret = btrfs_relocate_chunk(fs_info, bg->start);
+@@ -1939,6 +1951,7 @@ void btrfs_reclaim_bgs_work(struct work_struct *work)
+                       btrfs_err(fs_info, "error relocating chunk %llu",
+                                 bg->start);
+                       used = 0;
++                      reserved = 0;
+                       spin_lock(&space_info->lock);
+                       space_info->reclaim_errors++;
+                       if (READ_ONCE(space_info->periodic_reclaim))
+@@ -1948,6 +1961,7 @@ void btrfs_reclaim_bgs_work(struct work_struct *work)
+               spin_lock(&space_info->lock);
+               space_info->reclaim_count++;
+               space_info->reclaim_bytes += used;
++              space_info->reclaim_bytes += reserved;
+               spin_unlock(&space_info->lock);
+ next:
+-- 
+2.39.5
+
diff --git a/queue-6.14/btrfs-get-used-bytes-while-holding-lock-at-btrfs_rec.patch b/queue-6.14/btrfs-get-used-bytes-while-holding-lock-at-btrfs_rec.patch
new file mode 100644 (file)
index 0000000..21088ff
--- /dev/null
@@ -0,0 +1,88 @@
+From 4abecc47eec15e60389d368a028cb064117870a4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Feb 2025 15:40:26 +0000
+Subject: btrfs: get used bytes while holding lock at btrfs_reclaim_bgs_work()
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit ba5d06440cae63edc4f49465baf78f1f43e55c77 ]
+
+At btrfs_reclaim_bgs_work(), we are grabbing twice the used bytes counter
+of the block group while not holding the block group's spinlock. This can
+result in races, reported by KCSAN and similar tools, since a concurrent
+task can be updating that counter while at btrfs_update_block_group().
+
+So avoid these races by grabbing the counter in a critical section
+delimited by the block group's spinlock after setting the block group to
+RO mode. This also avoids using two different values of the counter in
+case it changes in between each read. This silences KCSAN and is required
+for the next patch in the series too.
+
+Fixes: 243192b67649 ("btrfs: report reclaim stats in sysfs")
+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/block-group.c | 21 ++++++++++++++++-----
+ 1 file changed, 16 insertions(+), 5 deletions(-)
+
+diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
+index c0a8f7d92acc5..ed0b1a955d74a 100644
+--- a/fs/btrfs/block-group.c
++++ b/fs/btrfs/block-group.c
+@@ -1823,7 +1823,7 @@ void btrfs_reclaim_bgs_work(struct work_struct *work)
+       list_sort(NULL, &fs_info->reclaim_bgs, reclaim_bgs_cmp);
+       while (!list_empty(&fs_info->reclaim_bgs)) {
+               u64 zone_unusable;
+-              u64 reclaimed;
++              u64 used;
+               int ret = 0;
+               bg = list_first_entry(&fs_info->reclaim_bgs,
+@@ -1915,19 +1915,30 @@ void btrfs_reclaim_bgs_work(struct work_struct *work)
+               if (ret < 0)
+                       goto next;
++              /*
++               * Grab the used bytes counter while holding the block group's
++               * spinlock to prevent races with tasks concurrently updating it
++               * due to extent allocation and deallocation (running
++               * btrfs_update_block_group()) - we have set the block group to
++               * RO but that only prevents extent reservation, allocation
++               * happens after reservation.
++               */
++              spin_lock(&bg->lock);
++              used = bg->used;
++              spin_unlock(&bg->lock);
++
+               btrfs_info(fs_info,
+                       "reclaiming chunk %llu with %llu%% used %llu%% unusable",
+                               bg->start,
+-                              div64_u64(bg->used * 100, bg->length),
++                              div64_u64(used * 100, bg->length),
+                               div64_u64(zone_unusable * 100, bg->length));
+               trace_btrfs_reclaim_block_group(bg);
+-              reclaimed = bg->used;
+               ret = btrfs_relocate_chunk(fs_info, bg->start);
+               if (ret) {
+                       btrfs_dec_block_group_ro(bg);
+                       btrfs_err(fs_info, "error relocating chunk %llu",
+                                 bg->start);
+-                      reclaimed = 0;
++                      used = 0;
+                       spin_lock(&space_info->lock);
+                       space_info->reclaim_errors++;
+                       if (READ_ONCE(space_info->periodic_reclaim))
+@@ -1936,7 +1947,7 @@ void btrfs_reclaim_bgs_work(struct work_struct *work)
+               }
+               spin_lock(&space_info->lock);
+               space_info->reclaim_count++;
+-              space_info->reclaim_bytes += reclaimed;
++              space_info->reclaim_bytes += used;
+               spin_unlock(&space_info->lock);
+ next:
+-- 
+2.39.5
+
diff --git a/queue-6.14/bus-qcom-ssc-block-bus-fix-the-error-handling-path-o.patch b/queue-6.14/bus-qcom-ssc-block-bus-fix-the-error-handling-path-o.patch
new file mode 100644 (file)
index 0000000..810efa6
--- /dev/null
@@ -0,0 +1,84 @@
+From e0694c2bcd5c5ea015a6fd635197959fe212dc8e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 2 Mar 2025 17:21:35 +0100
+Subject: bus: qcom-ssc-block-bus: Fix the error handling path of
+ qcom_ssc_block_bus_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit f41658cd081ad7697796b3dacd9a717a57919268 ]
+
+If qcom_ssc_block_bus_pds_enable() fails, the previous call to
+qcom_ssc_block_bus_pds_attach() must be undone, as already done in the
+remove function.
+
+In order to do that, move the code related to the power domains management
+to the end of the function, in order to avoid many changes in all the error
+handling path that would need to go through the new error handling path.
+
+Fixes: 97d485edc1d9 ("bus: add driver for initializing the SSC bus on (some) qcom SoCs")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://lore.kernel.org/r/1b89ec7438c9a893c09083e8591772c8ad3cb599.1740932040.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bus/qcom-ssc-block-bus.c | 31 +++++++++++++++++++------------
+ 1 file changed, 19 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/bus/qcom-ssc-block-bus.c b/drivers/bus/qcom-ssc-block-bus.c
+index c95a985e34988..7f5fd4e0940dc 100644
+--- a/drivers/bus/qcom-ssc-block-bus.c
++++ b/drivers/bus/qcom-ssc-block-bus.c
+@@ -264,18 +264,6 @@ static int qcom_ssc_block_bus_probe(struct platform_device *pdev)
+       platform_set_drvdata(pdev, data);
+-      data->pd_names = qcom_ssc_block_pd_names;
+-      data->num_pds = ARRAY_SIZE(qcom_ssc_block_pd_names);
+-
+-      /* power domains */
+-      ret = qcom_ssc_block_bus_pds_attach(&pdev->dev, data->pds, data->pd_names, data->num_pds);
+-      if (ret < 0)
+-              return dev_err_probe(&pdev->dev, ret, "error when attaching power domains\n");
+-
+-      ret = qcom_ssc_block_bus_pds_enable(data->pds, data->num_pds);
+-      if (ret < 0)
+-              return dev_err_probe(&pdev->dev, ret, "error when enabling power domains\n");
+-
+       /* low level overrides for when the HW logic doesn't "just work" */
+       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpm_sscaon_config0");
+       data->reg_mpm_sscaon_config0 = devm_ioremap_resource(&pdev->dev, res);
+@@ -343,11 +331,30 @@ static int qcom_ssc_block_bus_probe(struct platform_device *pdev)
+       data->ssc_axi_halt = halt_args.args[0];
++      /* power domains */
++      data->pd_names = qcom_ssc_block_pd_names;
++      data->num_pds = ARRAY_SIZE(qcom_ssc_block_pd_names);
++
++      ret = qcom_ssc_block_bus_pds_attach(&pdev->dev, data->pds, data->pd_names, data->num_pds);
++      if (ret < 0)
++              return dev_err_probe(&pdev->dev, ret, "error when attaching power domains\n");
++
++      ret = qcom_ssc_block_bus_pds_enable(data->pds, data->num_pds);
++      if (ret < 0) {
++              dev_err_probe(&pdev->dev, ret, "error when enabling power domains\n");
++              goto err_detach_pds_bus;
++      }
++
+       qcom_ssc_block_bus_init(&pdev->dev);
+       of_platform_populate(np, NULL, NULL, &pdev->dev);
+       return 0;
++
++err_detach_pds_bus:
++      qcom_ssc_block_bus_pds_detach(&pdev->dev, data->pds, data->num_pds);
++
++      return ret;
+ }
+ static void qcom_ssc_block_bus_remove(struct platform_device *pdev)
+-- 
+2.39.5
+
diff --git a/queue-6.14/bus-qcom-ssc-block-bus-remove-some-duplicated-iounma.patch b/queue-6.14/bus-qcom-ssc-block-bus-remove-some-duplicated-iounma.patch
new file mode 100644 (file)
index 0000000..326ac39
--- /dev/null
@@ -0,0 +1,41 @@
+From 71faa339348263af2e408b16626c076935d71de2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 2 Mar 2025 17:21:34 +0100
+Subject: bus: qcom-ssc-block-bus: Remove some duplicated iounmap() calls
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit a9ac4ba7dcace2b3b91e7b87bf0ba97c47edd94f ]
+
+reg_mpm_sscaon_config[01] are allocated with devm_ioremap_resource(). So,
+they will be unmapped automatically by the manage resource framework.
+
+Remove the incorrect explicit iounmap() calls from the remove function.
+
+Fixes: 97d485edc1d9 ("bus: add driver for initializing the SSC bus on (some) qcom SoCs")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://lore.kernel.org/r/efd06711b126e761a06eb5ef82daf9ad4e116a10.1740932040.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bus/qcom-ssc-block-bus.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/drivers/bus/qcom-ssc-block-bus.c b/drivers/bus/qcom-ssc-block-bus.c
+index 85d781a32df4b..c95a985e34988 100644
+--- a/drivers/bus/qcom-ssc-block-bus.c
++++ b/drivers/bus/qcom-ssc-block-bus.c
+@@ -356,9 +356,6 @@ static void qcom_ssc_block_bus_remove(struct platform_device *pdev)
+       qcom_ssc_block_bus_deinit(&pdev->dev);
+-      iounmap(data->reg_mpm_sscaon_config0);
+-      iounmap(data->reg_mpm_sscaon_config1);
+-
+       qcom_ssc_block_bus_pds_disable(data->pds, data->num_pds);
+       qcom_ssc_block_bus_pds_detach(&pdev->dev, data->pds, data->num_pds);
+       pm_runtime_disable(&pdev->dev);
+-- 
+2.39.5
+
diff --git a/queue-6.14/can-rockchip_canfd-rkcanfd_chip_fifo_setup-remove-du.patch b/queue-6.14/can-rockchip_canfd-rkcanfd_chip_fifo_setup-remove-du.patch
new file mode 100644 (file)
index 0000000..a474e08
--- /dev/null
@@ -0,0 +1,45 @@
+From 81701b83b5f21cfe5efe3cd21641731e555ae289 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 27 Jan 2025 13:16:44 +0100
+Subject: can: rockchip_canfd: rkcanfd_chip_fifo_setup(): remove duplicated
+ setup of RX FIFO
+
+From: Robin van der Gracht <robin@protonic.nl>
+
+[ Upstream commit d9e1cc087a55286fe028e0f078159b30d7da90bd ]
+
+The rockchip_canfd driver doesn't make use of the TXE FIFO.
+
+Although the comment states that the TXE FIFO is setup, it's actually
+a setup of the RX FIFO. The regular setup of the RX FIFO follows.
+
+Remove the duplicated setup of the RX FIFO.
+
+Fixes: ff60bfbaf67f ("can: rockchip_canfd: add driver for Rockchip CAN-FD controller")
+Signed-off-by: Robin van der Gracht <robin@protonic.nl>
+Link: https://patch.msgid.link/20250219-rk3568-canfd-v1-1-453869358c72@pengutronix.de
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/rockchip/rockchip_canfd-core.c | 5 -----
+ 1 file changed, 5 deletions(-)
+
+diff --git a/drivers/net/can/rockchip/rockchip_canfd-core.c b/drivers/net/can/rockchip/rockchip_canfd-core.c
+index d9a937ba126c3..46201c126703c 100644
+--- a/drivers/net/can/rockchip/rockchip_canfd-core.c
++++ b/drivers/net/can/rockchip/rockchip_canfd-core.c
+@@ -236,11 +236,6 @@ static void rkcanfd_chip_fifo_setup(struct rkcanfd_priv *priv)
+ {
+       u32 reg;
+-      /* TXE FIFO */
+-      reg = rkcanfd_read(priv, RKCANFD_REG_RX_FIFO_CTRL);
+-      reg |= RKCANFD_REG_RX_FIFO_CTRL_RX_FIFO_ENABLE;
+-      rkcanfd_write(priv, RKCANFD_REG_RX_FIFO_CTRL, reg);
+-
+       /* RX FIFO */
+       reg = rkcanfd_read(priv, RKCANFD_REG_RX_FIFO_CTRL);
+       reg |= RKCANFD_REG_RX_FIFO_CTRL_RX_FIFO_ENABLE;
+-- 
+2.39.5
+
diff --git a/queue-6.14/clk-amlogic-g12a-fix-mmc-a-peripheral-clock.patch b/queue-6.14/clk-amlogic-g12a-fix-mmc-a-peripheral-clock.patch
new file mode 100644 (file)
index 0000000..9d48591
--- /dev/null
@@ -0,0 +1,45 @@
+From 78494485e4126a52cf4f092f4d50ee0e4fabc8d6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Dec 2024 11:03:23 +0100
+Subject: clk: amlogic: g12a: fix mmc A peripheral clock
+
+From: Jerome Brunet <jbrunet@baylibre.com>
+
+[ Upstream commit 0079e77c08de692cb20b38e408365c830a44b1ef ]
+
+The bit index of the peripheral clock for mmc A is wrong
+This was probably not a problem for mmc A as the peripheral is likely left
+enabled by the bootloader.
+
+No issues has been reported so far but it could be a problem, most likely
+some form of conflict between the ethernet and mmc A clock, breaking
+ethernet on init.
+
+Use the value provided by the documentation for mmc A before this
+becomes an actual problem.
+
+Fixes: 085a4ea93d54 ("clk: meson: g12a: add peripheral clock controller")
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://lore.kernel.org/r/20241213-amlogic-clk-g12a-mmca-fix-v1-1-5af421f58b64@baylibre.com
+Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/meson/g12a.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c
+index 563759c51f747..ceabebb1863d6 100644
+--- a/drivers/clk/meson/g12a.c
++++ b/drivers/clk/meson/g12a.c
+@@ -4323,7 +4323,7 @@ static MESON_GATE(g12a_spicc_1,                  HHI_GCLK_MPEG0, 14);
+ static MESON_GATE(g12a_hiu_reg,                       HHI_GCLK_MPEG0, 19);
+ static MESON_GATE(g12a_mipi_dsi_phy,          HHI_GCLK_MPEG0, 20);
+ static MESON_GATE(g12a_assist_misc,           HHI_GCLK_MPEG0, 23);
+-static MESON_GATE(g12a_emmc_a,                        HHI_GCLK_MPEG0, 4);
++static MESON_GATE(g12a_emmc_a,                        HHI_GCLK_MPEG0, 24);
+ static MESON_GATE(g12a_emmc_b,                        HHI_GCLK_MPEG0, 25);
+ static MESON_GATE(g12a_emmc_c,                        HHI_GCLK_MPEG0, 26);
+ static MESON_GATE(g12a_audio_codec,           HHI_GCLK_MPEG0, 28);
+-- 
+2.39.5
+
diff --git a/queue-6.14/clk-amlogic-g12b-fix-cluster-a-parent-data.patch b/queue-6.14/clk-amlogic-g12b-fix-cluster-a-parent-data.patch
new file mode 100644 (file)
index 0000000..7c80856
--- /dev/null
@@ -0,0 +1,105 @@
+From a50f2a1b95d9fe71bc834afc3404998410cc1bce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Dec 2024 15:30:17 +0100
+Subject: clk: amlogic: g12b: fix cluster A parent data
+
+From: Jerome Brunet <jbrunet@baylibre.com>
+
+[ Upstream commit 8995f8f108c3ac5ad52b12a6cfbbc7b3b32e9a58 ]
+
+Several clocks used by both g12a and g12b use the g12a cpu A clock hw
+pointer as clock parent. This is incorrect on g12b since the parents of
+cluster A cpu clock are different. Also the hw clock provided as parent to
+these children is not even registered clock on g12b.
+
+Fix the problem by reverting to the global namespace and let CCF pick
+the appropriate, as it is already done for other clocks, such as
+cpu_clk_trace_div.
+
+Fixes: 25e682a02d91 ("clk: meson: g12a: migrate to the new parent description method")
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://lore.kernel.org/r/20241213-amlogic-clk-g12a-cpua-parent-fix-v1-1-d8c0f41865fe@baylibre.com
+Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/meson/g12a.c | 36 ++++++++++++++++++++++++------------
+ 1 file changed, 24 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c
+index cfffd434e998e..563759c51f747 100644
+--- a/drivers/clk/meson/g12a.c
++++ b/drivers/clk/meson/g12a.c
+@@ -1137,8 +1137,18 @@ static struct clk_regmap g12a_cpu_clk_div16_en = {
+       .hw.init = &(struct clk_init_data) {
+               .name = "cpu_clk_div16_en",
+               .ops = &clk_regmap_gate_ro_ops,
+-              .parent_hws = (const struct clk_hw *[]) {
+-                      &g12a_cpu_clk.hw
++              .parent_data = &(const struct clk_parent_data) {
++                      /*
++                       * Note:
++                       * G12A and G12B have different cpu clocks (with
++                       * different struct clk_hw). We fallback to the global
++                       * naming string mechanism so this clock picks
++                       * up the appropriate one. Same goes for the other
++                       * clock using cpu cluster A clock output and present
++                       * on both G12 variant.
++                       */
++                      .name = "cpu_clk",
++                      .index = -1,
+               },
+               .num_parents = 1,
+               /*
+@@ -1203,7 +1213,10 @@ static struct clk_regmap g12a_cpu_clk_apb_div = {
+       .hw.init = &(struct clk_init_data){
+               .name = "cpu_clk_apb_div",
+               .ops = &clk_regmap_divider_ro_ops,
+-              .parent_hws = (const struct clk_hw *[]) { &g12a_cpu_clk.hw },
++              .parent_data = &(const struct clk_parent_data) {
++                      .name = "cpu_clk",
++                      .index = -1,
++              },
+               .num_parents = 1,
+       },
+ };
+@@ -1237,7 +1250,10 @@ static struct clk_regmap g12a_cpu_clk_atb_div = {
+       .hw.init = &(struct clk_init_data){
+               .name = "cpu_clk_atb_div",
+               .ops = &clk_regmap_divider_ro_ops,
+-              .parent_hws = (const struct clk_hw *[]) { &g12a_cpu_clk.hw },
++              .parent_data = &(const struct clk_parent_data) {
++                      .name = "cpu_clk",
++                      .index = -1,
++              },
+               .num_parents = 1,
+       },
+ };
+@@ -1271,7 +1287,10 @@ static struct clk_regmap g12a_cpu_clk_axi_div = {
+       .hw.init = &(struct clk_init_data){
+               .name = "cpu_clk_axi_div",
+               .ops = &clk_regmap_divider_ro_ops,
+-              .parent_hws = (const struct clk_hw *[]) { &g12a_cpu_clk.hw },
++              .parent_data = &(const struct clk_parent_data) {
++                      .name = "cpu_clk",
++                      .index = -1,
++              },
+               .num_parents = 1,
+       },
+ };
+@@ -1306,13 +1325,6 @@ static struct clk_regmap g12a_cpu_clk_trace_div = {
+               .name = "cpu_clk_trace_div",
+               .ops = &clk_regmap_divider_ro_ops,
+               .parent_data = &(const struct clk_parent_data) {
+-                      /*
+-                       * Note:
+-                       * G12A and G12B have different cpu_clks (with
+-                       * different struct clk_hw). We fallback to the global
+-                       * naming string mechanism so cpu_clk_trace_div picks
+-                       * up the appropriate one.
+-                       */
+                       .name = "cpu_clk",
+                       .index = -1,
+               },
+-- 
+2.39.5
+
diff --git a/queue-6.14/clk-amlogic-gxbb-drop-incorrect-flag-on-32k-clock.patch b/queue-6.14/clk-amlogic-gxbb-drop-incorrect-flag-on-32k-clock.patch
new file mode 100644 (file)
index 0000000..96bf0d6
--- /dev/null
@@ -0,0 +1,43 @@
+From 2f8d146cd080a55fbd95717269038c1459428053 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Dec 2024 11:25:36 +0100
+Subject: clk: amlogic: gxbb: drop incorrect flag on 32k clock
+
+From: Jerome Brunet <jbrunet@baylibre.com>
+
+[ Upstream commit f38f7fe4830c5cb4eac138249225f119e7939965 ]
+
+gxbb_32k_clk_div sets CLK_DIVIDER_ROUND_CLOSEST in the init_data flag which
+is incorrect. This is field is not where the divider flags belong.
+
+Thankfully, CLK_DIVIDER_ROUND_CLOSEST maps to bit 4 which is an unused
+clock flag, so there is no unintended consequence to this error.
+
+Effectively, the clock has been used without CLK_DIVIDER_ROUND_CLOSEST
+so far, so just drop it.
+
+Fixes: 14c735c8e308 ("clk: meson-gxbb: Add EE 32K Clock for CEC")
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://lore.kernel.org/r/20241220-amlogic-clk-gxbb-32k-fixes-v1-1-baca56ecf2db@baylibre.com
+Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/meson/gxbb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
+index 8575b84853859..df9250de51dc8 100644
+--- a/drivers/clk/meson/gxbb.c
++++ b/drivers/clk/meson/gxbb.c
+@@ -1306,7 +1306,7 @@ static struct clk_regmap gxbb_32k_clk_div = {
+                       &gxbb_32k_clk_sel.hw
+               },
+               .num_parents = 1,
+-              .flags = CLK_SET_RATE_PARENT | CLK_DIVIDER_ROUND_CLOSEST,
++              .flags = CLK_SET_RATE_PARENT,
+       },
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.14/clk-amlogic-gxbb-drop-non-existing-32k-clock-parent.patch b/queue-6.14/clk-amlogic-gxbb-drop-non-existing-32k-clock-parent.patch
new file mode 100644 (file)
index 0000000..6f5086a
--- /dev/null
@@ -0,0 +1,62 @@
+From a53f7c7e6ed1e89c1ebd3b87a128a1cad5928be0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Dec 2024 11:25:37 +0100
+Subject: clk: amlogic: gxbb: drop non existing 32k clock parent
+
+From: Jerome Brunet <jbrunet@baylibre.com>
+
+[ Upstream commit 7915d7d5407c026fa9343befb4d3343f7a345f97 ]
+
+The 32k clock reference a parent 'cts_slow_oscin' with a fixme note saying
+that this clock should be provided by AO controller.
+
+The HW probably has this clock but it does not exist at the moment in
+any controller implementation. Furthermore, referencing clock by the global
+name should be avoided whenever possible.
+
+There is no reason to keep this hack around, at least for now.
+
+Fixes: 14c735c8e308 ("clk: meson-gxbb: Add EE 32K Clock for CEC")
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://lore.kernel.org/r/20241220-amlogic-clk-gxbb-32k-fixes-v1-2-baca56ecf2db@baylibre.com
+Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/meson/gxbb.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
+index df9250de51dc8..3abb44a2532b9 100644
+--- a/drivers/clk/meson/gxbb.c
++++ b/drivers/clk/meson/gxbb.c
+@@ -1266,14 +1266,13 @@ static struct clk_regmap gxbb_cts_i958 = {
+       },
+ };
++/*
++ * This table skips a clock named 'cts_slow_oscin' in the documentation
++ * This clock does not exist yet in this controller or the AO one
++ */
++static u32 gxbb_32k_clk_parents_val_table[] = { 0, 2, 3 };
+ static const struct clk_parent_data gxbb_32k_clk_parent_data[] = {
+       { .fw_name = "xtal", },
+-      /*
+-       * FIXME: This clock is provided by the ao clock controller but the
+-       * clock is not yet part of the binding of this controller, so string
+-       * name must be use to set this parent.
+-       */
+-      { .name = "cts_slow_oscin", .index = -1 },
+       { .hw = &gxbb_fclk_div3.hw },
+       { .hw = &gxbb_fclk_div5.hw },
+ };
+@@ -1283,6 +1282,7 @@ static struct clk_regmap gxbb_32k_clk_sel = {
+               .offset = HHI_32K_CLK_CNTL,
+               .mask = 0x3,
+               .shift = 16,
++              .table = gxbb_32k_clk_parents_val_table,
+               },
+       .hw.init = &(struct clk_init_data){
+               .name = "32k_clk_sel",
+-- 
+2.39.5
+
diff --git a/queue-6.14/clk-clk-imx8mp-audiomix-fix-dsp-ocram_a-clock-parent.patch b/queue-6.14/clk-clk-imx8mp-audiomix-fix-dsp-ocram_a-clock-parent.patch
new file mode 100644 (file)
index 0000000..1bc318d
--- /dev/null
@@ -0,0 +1,49 @@
+From 43431630cf05c3bc46d1c359cdb0875f46d30e64 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Feb 2025 11:45:11 -0500
+Subject: clk: clk-imx8mp-audiomix: fix dsp/ocram_a clock parents
+
+From: Laurentiu Mihalcea <laurentiu.mihalcea@nxp.com>
+
+[ Upstream commit 91be7d27099dedf813b80702e4ca117d1fb38ce6 ]
+
+The DSP and OCRAM_A modules from AUDIOMIX are clocked by
+AUDIO_AXI_CLK_ROOT, not AUDIO_AHB_CLK_ROOT. Update the clock data
+accordingly.
+
+Fixes: 6cd95f7b151c ("clk: imx: imx8mp: Add audiomix block control")
+Signed-off-by: Laurentiu Mihalcea <laurentiu.mihalcea@nxp.com>
+Reviewed-by: Iuliana Prodan <iuliana.prodan@nxp.com>
+Reviewed-by: Peng Fan <peng.fan@nxp.com>
+Link: https://lore.kernel.org/r/20250226164513.33822-3-laurentiumihalcea111@gmail.com
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-imx8mp-audiomix.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/clk/imx/clk-imx8mp-audiomix.c b/drivers/clk/imx/clk-imx8mp-audiomix.c
+index c409fc7e06186..775f62dddb11d 100644
+--- a/drivers/clk/imx/clk-imx8mp-audiomix.c
++++ b/drivers/clk/imx/clk-imx8mp-audiomix.c
+@@ -180,14 +180,14 @@ static struct clk_imx8mp_audiomix_sel sels[] = {
+       CLK_GATE("asrc", ASRC_IPG),
+       CLK_GATE("pdm", PDM_IPG),
+       CLK_GATE("earc", EARC_IPG),
+-      CLK_GATE("ocrama", OCRAMA_IPG),
++      CLK_GATE_PARENT("ocrama", OCRAMA_IPG, "axi"),
+       CLK_GATE("aud2htx", AUD2HTX_IPG),
+       CLK_GATE_PARENT("earc_phy", EARC_PHY, "sai_pll_out_div2"),
+       CLK_GATE("sdma2", SDMA2_ROOT),
+       CLK_GATE("sdma3", SDMA3_ROOT),
+       CLK_GATE("spba2", SPBA2_ROOT),
+-      CLK_GATE("dsp", DSP_ROOT),
+-      CLK_GATE("dspdbg", DSPDBG_ROOT),
++      CLK_GATE_PARENT("dsp", DSP_ROOT, "axi"),
++      CLK_GATE_PARENT("dspdbg", DSPDBG_ROOT, "axi"),
+       CLK_GATE("edma", EDMA_ROOT),
+       CLK_GATE_PARENT("audpll", AUDPLL_ROOT, "osc_24m"),
+       CLK_GATE("mu2", MU2_ROOT),
+-- 
+2.39.5
+
diff --git a/queue-6.14/clk-mmp-fix-null-vs-is_err-check.patch b/queue-6.14/clk-mmp-fix-null-vs-is_err-check.patch
new file mode 100644 (file)
index 0000000..cc59251
--- /dev/null
@@ -0,0 +1,40 @@
+From 57eaf04d14a98d89512f0c8294a58e05f85a3357 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Mar 2025 14:47:07 +0800
+Subject: clk: mmp: Fix NULL vs IS_ERR() check
+
+From: Charles Han <hanchunchao@inspur.com>
+
+[ Upstream commit 00153c64a72d336cc61f4141e5be53b49b7797e1 ]
+
+The devm_kzalloc() function returns NULL on error, not error pointers.
+Fix the check.
+
+Fixes: 03437e857b0a ("clk: mmp: Add Marvell PXA1908 APMU driver")
+Signed-off-by: Charles Han <hanchunchao@inspur.com>
+Link: https://lore.kernel.org/r/20250307064708.209511-1-hanchunchao@inspur.com
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/mmp/clk-pxa1908-apmu.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/mmp/clk-pxa1908-apmu.c b/drivers/clk/mmp/clk-pxa1908-apmu.c
+index 8cfb1258202f6..d3a070687fc5b 100644
+--- a/drivers/clk/mmp/clk-pxa1908-apmu.c
++++ b/drivers/clk/mmp/clk-pxa1908-apmu.c
+@@ -87,8 +87,8 @@ static int pxa1908_apmu_probe(struct platform_device *pdev)
+       struct pxa1908_clk_unit *pxa_unit;
+       pxa_unit = devm_kzalloc(&pdev->dev, sizeof(*pxa_unit), GFP_KERNEL);
+-      if (IS_ERR(pxa_unit))
+-              return PTR_ERR(pxa_unit);
++      if (!pxa_unit)
++              return -ENOMEM;
+       pxa_unit->base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(pxa_unit->base))
+-- 
+2.39.5
+
diff --git a/queue-6.14/clk-qcom-gcc-msm8953-fix-stuck-venus0_core0-clock.patch b/queue-6.14/clk-qcom-gcc-msm8953-fix-stuck-venus0_core0-clock.patch
new file mode 100644 (file)
index 0000000..68095c8
--- /dev/null
@@ -0,0 +1,43 @@
+From 4a76881a4830ec110c37dc40c8917edbd55d0ab5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 15 Mar 2025 16:26:18 +0100
+Subject: clk: qcom: gcc-msm8953: fix stuck venus0_core0 clock
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Vladimir Lypak <vladimir.lypak@gmail.com>
+
+[ Upstream commit cdc59600bccf2cb4c483645438a97d4ec55f326b ]
+
+This clock can't be enable with VENUS_CORE0 GDSC turned off. But that
+GDSC is under HW control so it can be turned off at any moment.
+Instead of checking the dependent clock we can just vote for it to
+enable later when GDSC gets turned on.
+
+Fixes: 9bb6cfc3c77e6 ("clk: qcom: Add Global Clock Controller driver for MSM8953")
+Signed-off-by: Vladimir Lypak <vladimir.lypak@gmail.com>
+Signed-off-by: Barnabás Czémán <barnabas.czeman@mainlining.org>
+Link: https://lore.kernel.org/r/20250315-clock-fix-v1-2-2efdc4920dda@mainlining.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-msm8953.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/qcom/gcc-msm8953.c b/drivers/clk/qcom/gcc-msm8953.c
+index 855a61966f3ef..8f29ecc74c50b 100644
+--- a/drivers/clk/qcom/gcc-msm8953.c
++++ b/drivers/clk/qcom/gcc-msm8953.c
+@@ -3770,7 +3770,7 @@ static struct clk_branch gcc_venus0_axi_clk = {
+ static struct clk_branch gcc_venus0_core0_vcodec0_clk = {
+       .halt_reg = 0x4c02c,
+-      .halt_check = BRANCH_HALT,
++      .halt_check = BRANCH_HALT_SKIP,
+       .clkr = {
+               .enable_reg = 0x4c02c,
+               .enable_mask = BIT(0),
+-- 
+2.39.5
+
diff --git a/queue-6.14/clk-qcom-gcc-sm8650-do-not-turn-off-usb-gdscs-during.patch b/queue-6.14/clk-qcom-gcc-sm8650-do-not-turn-off-usb-gdscs-during.patch
new file mode 100644 (file)
index 0000000..5157b7b
--- /dev/null
@@ -0,0 +1,53 @@
+From cdfae3212b754eddd1f0dccae299bd12329aec6f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Mar 2025 20:00:29 +0100
+Subject: clk: qcom: gcc-sm8650: Do not turn off USB GDSCs during
+ gdsc_disable()
+
+From: Neil Armstrong <neil.armstrong@linaro.org>
+
+[ Upstream commit 8b75c2973997e66fd897b7e87b5ba2f3d683e94b ]
+
+With PWRSTS_OFF_ON, USB GDSCs are turned off during gdsc_disable(). This
+can happen during scenarios such as system suspend and breaks the resume
+of USB controller from suspend.
+
+So use PWRSTS_RET_ON to indicate the GDSC driver to not turn off the GDSCs
+during gdsc_disable() and allow the hardware to transition the GDSCs to
+retention when the parent domain enters low power state during system
+suspend.
+
+Fixes: c58225b7e3d7 ("clk: qcom: add the SM8650 Global Clock Controller driver, part 1")
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://lore.kernel.org/r/20250305-topic-sm8650-upstream-fix-usb-suspend-v1-1-649036ab0557@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-sm8650.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/qcom/gcc-sm8650.c b/drivers/clk/qcom/gcc-sm8650.c
+index 9dd5c48f33bed..fa1672c4e7d81 100644
+--- a/drivers/clk/qcom/gcc-sm8650.c
++++ b/drivers/clk/qcom/gcc-sm8650.c
+@@ -3497,7 +3497,7 @@ static struct gdsc usb30_prim_gdsc = {
+       .pd = {
+               .name = "usb30_prim_gdsc",
+       },
+-      .pwrsts = PWRSTS_OFF_ON,
++      .pwrsts = PWRSTS_RET_ON,
+       .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
+ };
+@@ -3506,7 +3506,7 @@ static struct gdsc usb3_phy_gdsc = {
+       .pd = {
+               .name = "usb3_phy_gdsc",
+       },
+-      .pwrsts = PWRSTS_OFF_ON,
++      .pwrsts = PWRSTS_RET_ON,
+       .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.14/clk-qcom-gcc-x1e80100-unregister-gcc_gpu_cfg_ahb_clk.patch b/queue-6.14/clk-qcom-gcc-x1e80100-unregister-gcc_gpu_cfg_ahb_clk.patch
new file mode 100644 (file)
index 0000000..234fc7d
--- /dev/null
@@ -0,0 +1,99 @@
+From e81f759cc0ed0db8c9e5a8bec1ad2593f1655021 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Jan 2025 17:54:18 +0100
+Subject: clk: qcom: gcc-x1e80100: Unregister
+ GCC_GPU_CFG_AHB_CLK/GCC_DISP_XO_CLK
+
+From: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+
+[ Upstream commit b60521eff227ef459e03879cbea2b2bd85a8d7af ]
+
+The GPU clock is required for CPU access to GPUSS registers. It was
+previously decided (on this and many more platforms) that the added
+overhead/hassle introduced by keeping track of it would not bring much
+measurable improvement in the power department.
+
+The display clock is basically the same story over again.
+
+Now, we're past that discussion and this commit is not trying to change
+that. Instead, the clocks are both force-enabled in .probe *and*
+registered with the common clock framework, resulting in them being
+toggled off after ignore_unused.
+
+Unregister said clocks to fix breakage when clk_ignore_unused is absent
+(as it should be).
+
+Fixes: 161b7c401f4b ("clk: qcom: Add Global Clock controller (GCC) driver for X1E80100")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Link: https://lore.kernel.org/r/20250111-topic-x1e_fixups-v1-1-77dc39237c12@oss.qualcomm.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-x1e80100.c | 30 ------------------------------
+ 1 file changed, 30 deletions(-)
+
+diff --git a/drivers/clk/qcom/gcc-x1e80100.c b/drivers/clk/qcom/gcc-x1e80100.c
+index 7288af845434d..009f39139b644 100644
+--- a/drivers/clk/qcom/gcc-x1e80100.c
++++ b/drivers/clk/qcom/gcc-x1e80100.c
+@@ -2564,19 +2564,6 @@ static struct clk_branch gcc_disp_hf_axi_clk = {
+       },
+ };
+-static struct clk_branch gcc_disp_xo_clk = {
+-      .halt_reg = 0x27018,
+-      .halt_check = BRANCH_HALT,
+-      .clkr = {
+-              .enable_reg = 0x27018,
+-              .enable_mask = BIT(0),
+-              .hw.init = &(const struct clk_init_data) {
+-                      .name = "gcc_disp_xo_clk",
+-                      .ops = &clk_branch2_ops,
+-              },
+-      },
+-};
+-
+ static struct clk_branch gcc_gp1_clk = {
+       .halt_reg = 0x64000,
+       .halt_check = BRANCH_HALT,
+@@ -2631,21 +2618,6 @@ static struct clk_branch gcc_gp3_clk = {
+       },
+ };
+-static struct clk_branch gcc_gpu_cfg_ahb_clk = {
+-      .halt_reg = 0x71004,
+-      .halt_check = BRANCH_HALT_VOTED,
+-      .hwcg_reg = 0x71004,
+-      .hwcg_bit = 1,
+-      .clkr = {
+-              .enable_reg = 0x71004,
+-              .enable_mask = BIT(0),
+-              .hw.init = &(const struct clk_init_data) {
+-                      .name = "gcc_gpu_cfg_ahb_clk",
+-                      .ops = &clk_branch2_ops,
+-              },
+-      },
+-};
+-
+ static struct clk_branch gcc_gpu_gpll0_cph_clk_src = {
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+@@ -6268,7 +6240,6 @@ static struct clk_regmap *gcc_x1e80100_clocks[] = {
+       [GCC_CNOC_PCIE_TUNNEL_CLK] = &gcc_cnoc_pcie_tunnel_clk.clkr,
+       [GCC_DDRSS_GPU_AXI_CLK] = &gcc_ddrss_gpu_axi_clk.clkr,
+       [GCC_DISP_HF_AXI_CLK] = &gcc_disp_hf_axi_clk.clkr,
+-      [GCC_DISP_XO_CLK] = &gcc_disp_xo_clk.clkr,
+       [GCC_GP1_CLK] = &gcc_gp1_clk.clkr,
+       [GCC_GP1_CLK_SRC] = &gcc_gp1_clk_src.clkr,
+       [GCC_GP2_CLK] = &gcc_gp2_clk.clkr,
+@@ -6281,7 +6252,6 @@ static struct clk_regmap *gcc_x1e80100_clocks[] = {
+       [GCC_GPLL7] = &gcc_gpll7.clkr,
+       [GCC_GPLL8] = &gcc_gpll8.clkr,
+       [GCC_GPLL9] = &gcc_gpll9.clkr,
+-      [GCC_GPU_CFG_AHB_CLK] = &gcc_gpu_cfg_ahb_clk.clkr,
+       [GCC_GPU_GPLL0_CPH_CLK_SRC] = &gcc_gpu_gpll0_cph_clk_src.clkr,
+       [GCC_GPU_GPLL0_DIV_CPH_CLK_SRC] = &gcc_gpu_gpll0_div_cph_clk_src.clkr,
+       [GCC_GPU_MEMNOC_GFX_CLK] = &gcc_gpu_memnoc_gfx_clk.clkr,
+-- 
+2.39.5
+
diff --git a/queue-6.14/clk-qcom-ipq5424-fix-software-and-hardware-flow-cont.patch b/queue-6.14/clk-qcom-ipq5424-fix-software-and-hardware-flow-cont.patch
new file mode 100644 (file)
index 0000000..f426082
--- /dev/null
@@ -0,0 +1,67 @@
+From 2804ad2c48e2694d234ac4cc40103cc798e23a6c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jan 2025 11:39:14 +0530
+Subject: clk: qcom: ipq5424: fix software and hardware flow control error of
+ UART
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Manikanta Mylavarapu <quic_mmanikan@quicinc.com>
+
+[ Upstream commit 4b28beb882a0a1af0ce47a8a87e7877a3ae6ad36 ]
+
+The UART’s software and hardware flow control are currently not
+functioning correctly.
+
+For software flow control, the following error is encountered:
+qcom_geni_serial 1a80000.serial: Couldn't find suitable
+clock rate for 56000000, 3500000, 2500000, 1152000, 921600, 19200
+
+During hardware flow control testing, a “Retry 0: Got ZCAN error” is
+observed.
+
+To address these issues, update the UART frequency table to include all
+supported frequencies according to the frequency plan.
+
+Fixes: 21b5d5a4a311 ("clk: qcom: add Global Clock controller (GCC) driver for IPQ5424 SoC")
+Signed-off-by: Manikanta Mylavarapu <quic_mmanikan@quicinc.com>
+Link: https://lore.kernel.org/r/20250124060914.1564681-1-quic_mmanikan@quicinc.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-ipq5424.c | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/clk/qcom/gcc-ipq5424.c b/drivers/clk/qcom/gcc-ipq5424.c
+index 107424395ef17..3d42f3d85c7a9 100644
+--- a/drivers/clk/qcom/gcc-ipq5424.c
++++ b/drivers/clk/qcom/gcc-ipq5424.c
+@@ -592,13 +592,19 @@ static struct clk_rcg2 gcc_qupv3_spi1_clk_src = {
+ };
+ static const struct freq_tbl ftbl_gcc_qupv3_uart0_clk_src[] = {
+-      F(960000, P_XO, 10, 2, 5),
+-      F(4800000, P_XO, 5, 0, 0),
+-      F(9600000, P_XO, 2, 4, 5),
+-      F(16000000, P_GPLL0_OUT_MAIN, 10, 1, 5),
++      F(3686400,  P_GCC_GPLL0_OUT_MAIN_DIV_CLK_SRC, 1, 144, 15625),
++      F(7372800,  P_GCC_GPLL0_OUT_MAIN_DIV_CLK_SRC, 1, 288, 15625),
++      F(14745600, P_GCC_GPLL0_OUT_MAIN_DIV_CLK_SRC, 1, 576, 15625),
+       F(24000000, P_XO, 1, 0, 0),
+       F(25000000, P_GPLL0_OUT_MAIN, 16, 1, 2),
+-      F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0),
++      F(32000000, P_GPLL0_OUT_MAIN, 1, 1, 25),
++      F(40000000, P_GPLL0_OUT_MAIN, 1, 1, 20),
++      F(46400000, P_GPLL0_OUT_MAIN, 1, 29, 500),
++      F(48000000, P_GPLL0_OUT_MAIN, 1, 3, 50),
++      F(51200000, P_GPLL0_OUT_MAIN, 1, 8, 125),
++      F(56000000, P_GPLL0_OUT_MAIN, 1, 7, 100),
++      F(58982400, P_GPLL0_OUT_MAIN, 1, 1152, 15625),
++      F(60000000, P_GPLL0_OUT_MAIN, 1, 3, 40),
+       F(64000000, P_GPLL0_OUT_MAIN, 12.5, 0, 0),
+       { }
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.14/clk-qcom-mmcc-sdm660-fix-stuck-video_subcore0-clock.patch b/queue-6.14/clk-qcom-mmcc-sdm660-fix-stuck-video_subcore0-clock.patch
new file mode 100644 (file)
index 0000000..b2da2ff
--- /dev/null
@@ -0,0 +1,42 @@
+From 6c5e74050c2239604012037e66d09446848afd3c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 15 Mar 2025 16:26:17 +0100
+Subject: clk: qcom: mmcc-sdm660: fix stuck video_subcore0 clock
+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 000cbe3896c56bf5c625e286ff096533a6b27657 ]
+
+This clock can't be enable with VENUS_CORE0 GDSC turned off. But that
+GDSC is under HW control so it can be turned off at any moment.
+Instead of checking the dependent clock we can just vote for it to
+enable later when GDSC gets turned on.
+
+Fixes: 5db3ae8b33de6 ("clk: qcom: Add SDM660 Multimedia Clock Controller (MMCC) driver")
+Signed-off-by: Barnabás Czémán <barnabas.czeman@mainlining.org>
+Link: https://lore.kernel.org/r/20250315-clock-fix-v1-1-2efdc4920dda@mainlining.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/mmcc-sdm660.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/qcom/mmcc-sdm660.c b/drivers/clk/qcom/mmcc-sdm660.c
+index 98ba5b4518fb3..b9f02d91004e8 100644
+--- a/drivers/clk/qcom/mmcc-sdm660.c
++++ b/drivers/clk/qcom/mmcc-sdm660.c
+@@ -2544,7 +2544,7 @@ static struct clk_branch video_core_clk = {
+ static struct clk_branch video_subcore0_clk = {
+       .halt_reg = 0x1048,
+-      .halt_check = BRANCH_HALT,
++      .halt_check = BRANCH_HALT_SKIP,
+       .clkr = {
+               .enable_reg = 0x1048,
+               .enable_mask = BIT(0),
+-- 
+2.39.5
+
diff --git a/queue-6.14/clk-renesas-r8a08g045-check-the-source-of-the-cpu-pl.patch b/queue-6.14/clk-renesas-r8a08g045-check-the-source-of-the-cpu-pl.patch
new file mode 100644 (file)
index 0000000..6ca7b1a
--- /dev/null
@@ -0,0 +1,140 @@
+From 444f638464180ca1ce480190ed555837840d9603 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jan 2025 16:20:58 +0200
+Subject: clk: renesas: r8a08g045: Check the source of the CPU PLL settings
+
+From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+
+[ Upstream commit dc0f16c1b76293ac942a783e960abfd19e95fdf5 ]
+
+On the RZ/G3S SoC, the CPU PLL settings can be set and retrieved through
+the CPG_PLL1_CLK1 and CPG_PLL1_CLK2 registers.  However, these settings
+are applied only when CPG_PLL1_SETTING.SEL_PLL1 is set to 0.
+Otherwise, the CPU PLL operates at the default frequency of 1.1 GHz.
+Hence add support to the PLL driver for returning the 1.1 GHz frequency
+when the CPU PLL is configured with the default frequency.
+
+Fixes: 01eabef547e6 ("clk: renesas: rzg2l: Add support for RZ/G3S PLL")
+Fixes: de60a3ebe410 ("clk: renesas: Add minimal boot support for RZ/G3S SoC")
+Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/20250115142059.1833063-1-claudiu.beznea.uj@bp.renesas.com
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/renesas/r9a08g045-cpg.c |  5 +++--
+ drivers/clk/renesas/rzg2l-cpg.c     | 13 ++++++++++++-
+ drivers/clk/renesas/rzg2l-cpg.h     | 10 +++++++---
+ 3 files changed, 22 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/clk/renesas/r9a08g045-cpg.c b/drivers/clk/renesas/r9a08g045-cpg.c
+index 0e7e3bf05b52d..cb63d397429f6 100644
+--- a/drivers/clk/renesas/r9a08g045-cpg.c
++++ b/drivers/clk/renesas/r9a08g045-cpg.c
+@@ -51,7 +51,7 @@
+ #define G3S_SEL_SDHI2         SEL_PLL_PACK(G3S_CPG_SDHI_DSEL, 8, 2)
+ /* PLL 1/4/6 configuration registers macro. */
+-#define G3S_PLL146_CONF(clk1, clk2)   ((clk1) << 22 | (clk2) << 12)
++#define G3S_PLL146_CONF(clk1, clk2, setting)  ((clk1) << 22 | (clk2) << 12 | (setting))
+ #define DEF_G3S_MUX(_name, _id, _conf, _parent_names, _mux_flags, _clk_flags) \
+       DEF_TYPE(_name, _id, CLK_TYPE_MUX, .conf = (_conf), \
+@@ -134,7 +134,8 @@ static const struct cpg_core_clk r9a08g045_core_clks[] __initconst = {
+       /* Internal Core Clocks */
+       DEF_FIXED(".osc_div1000", CLK_OSC_DIV1000, CLK_EXTAL, 1, 1000),
+-      DEF_G3S_PLL(".pll1", CLK_PLL1, CLK_EXTAL, G3S_PLL146_CONF(0x4, 0x8)),
++      DEF_G3S_PLL(".pll1", CLK_PLL1, CLK_EXTAL, G3S_PLL146_CONF(0x4, 0x8, 0x100),
++                  1100000000UL),
+       DEF_FIXED(".pll2", CLK_PLL2, CLK_EXTAL, 200, 3),
+       DEF_FIXED(".pll3", CLK_PLL3, CLK_EXTAL, 200, 3),
+       DEF_FIXED(".pll4", CLK_PLL4, CLK_EXTAL, 100, 3),
+diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c
+index ddf722ca79eb0..4bd8862dc82be 100644
+--- a/drivers/clk/renesas/rzg2l-cpg.c
++++ b/drivers/clk/renesas/rzg2l-cpg.c
+@@ -51,6 +51,7 @@
+ #define RZG3S_DIV_M           GENMASK(25, 22)
+ #define RZG3S_DIV_NI          GENMASK(21, 13)
+ #define RZG3S_DIV_NF          GENMASK(12, 1)
++#define RZG3S_SEL_PLL         BIT(0)
+ #define CLK_ON_R(reg)         (reg)
+ #define CLK_MON_R(reg)                (0x180 + (reg))
+@@ -60,6 +61,7 @@
+ #define GET_REG_OFFSET(val)           ((val >> 20) & 0xfff)
+ #define GET_REG_SAMPLL_CLK1(val)      ((val >> 22) & 0xfff)
+ #define GET_REG_SAMPLL_CLK2(val)      ((val >> 12) & 0xfff)
++#define GET_REG_SAMPLL_SETTING(val)   ((val) & 0xfff)
+ #define CPG_WEN_BIT           BIT(16)
+@@ -943,6 +945,7 @@ rzg2l_cpg_sipll5_register(const struct cpg_core_clk *core,
+ struct pll_clk {
+       struct clk_hw hw;
++      unsigned long default_rate;
+       unsigned int conf;
+       unsigned int type;
+       void __iomem *base;
+@@ -980,12 +983,19 @@ static unsigned long rzg3s_cpg_pll_clk_recalc_rate(struct clk_hw *hw,
+ {
+       struct pll_clk *pll_clk = to_pll(hw);
+       struct rzg2l_cpg_priv *priv = pll_clk->priv;
+-      u32 nir, nfr, mr, pr, val;
++      u32 nir, nfr, mr, pr, val, setting;
+       u64 rate;
+       if (pll_clk->type != CLK_TYPE_G3S_PLL)
+               return parent_rate;
++      setting = GET_REG_SAMPLL_SETTING(pll_clk->conf);
++      if (setting) {
++              val = readl(priv->base + setting);
++              if (val & RZG3S_SEL_PLL)
++                      return pll_clk->default_rate;
++      }
++
+       val = readl(priv->base + GET_REG_SAMPLL_CLK1(pll_clk->conf));
+       pr = 1 << FIELD_GET(RZG3S_DIV_P, val);
+@@ -1038,6 +1048,7 @@ rzg2l_cpg_pll_clk_register(const struct cpg_core_clk *core,
+       pll_clk->base = priv->base;
+       pll_clk->priv = priv;
+       pll_clk->type = core->type;
++      pll_clk->default_rate = core->default_rate;
+       ret = devm_clk_hw_register(dev, &pll_clk->hw);
+       if (ret)
+diff --git a/drivers/clk/renesas/rzg2l-cpg.h b/drivers/clk/renesas/rzg2l-cpg.h
+index 881a89b5a7100..b74c94a16986e 100644
+--- a/drivers/clk/renesas/rzg2l-cpg.h
++++ b/drivers/clk/renesas/rzg2l-cpg.h
+@@ -102,7 +102,10 @@ struct cpg_core_clk {
+       const struct clk_div_table *dtable;
+       const u32 *mtable;
+       const unsigned long invalid_rate;
+-      const unsigned long max_rate;
++      union {
++              const unsigned long max_rate;
++              const unsigned long default_rate;
++      };
+       const char * const *parent_names;
+       notifier_fn_t notifier;
+       u32 flag;
+@@ -144,8 +147,9 @@ enum clk_types {
+       DEF_TYPE(_name, _id, _type, .parent = _parent)
+ #define DEF_SAMPLL(_name, _id, _parent, _conf) \
+       DEF_TYPE(_name, _id, CLK_TYPE_SAM_PLL, .parent = _parent, .conf = _conf)
+-#define DEF_G3S_PLL(_name, _id, _parent, _conf) \
+-      DEF_TYPE(_name, _id, CLK_TYPE_G3S_PLL, .parent = _parent, .conf = _conf)
++#define DEF_G3S_PLL(_name, _id, _parent, _conf, _default_rate) \
++      DEF_TYPE(_name, _id, CLK_TYPE_G3S_PLL, .parent = _parent, .conf = _conf, \
++               .default_rate = _default_rate)
+ #define DEF_INPUT(_name, _id) \
+       DEF_TYPE(_name, _id, CLK_TYPE_IN)
+ #define DEF_FIXED(_name, _id, _parent, _mult, _div) \
+-- 
+2.39.5
+
diff --git a/queue-6.14/clk-rockchip-rk3328-fix-wrong-clk_ref_usb3otg-parent.patch b/queue-6.14/clk-rockchip-rk3328-fix-wrong-clk_ref_usb3otg-parent.patch
new file mode 100644 (file)
index 0000000..a9cffdf
--- /dev/null
@@ -0,0 +1,39 @@
+From 5b9569cbdb251d1e4daa05edeacc3a987c65c4b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jan 2025 01:26:22 +0000
+Subject: clk: rockchip: rk3328: fix wrong clk_ref_usb3otg parent
+
+From: Peter Geis <pgwipeout@gmail.com>
+
+[ Upstream commit a9e60f1ffe1ca57d6af6a2573e2f950e76efbf5b ]
+
+Correct the clk_ref_usb3otg parent to fix clock control for the usb3
+controller on rk3328. Verified against the rk3328 trm, the rk3228h trm,
+and the rk3328 usb3 phy clock map.
+
+Fixes: fe3511ad8a1c ("clk: rockchip: add clock controller for rk3328")
+Signed-off-by: Peter Geis <pgwipeout@gmail.com>
+Reviewed-by: Dragan Simic <dsimic@manjaro.org>
+Link: https://lore.kernel.org/r/20250115012628.1035928-2-pgwipeout@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/rockchip/clk-rk3328.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/rockchip/clk-rk3328.c b/drivers/clk/rockchip/clk-rk3328.c
+index 3bb87b27b662d..cf60fcf2fa5cd 100644
+--- a/drivers/clk/rockchip/clk-rk3328.c
++++ b/drivers/clk/rockchip/clk-rk3328.c
+@@ -201,7 +201,7 @@ PNAME(mux_aclk_peri_pre_p) = { "cpll_peri",
+                                   "gpll_peri",
+                                   "hdmiphy_peri" };
+ PNAME(mux_ref_usb3otg_src_p)  = { "xin24m",
+-                                  "clk_usb3otg_ref" };
++                                  "clk_ref_usb3otg_src" };
+ PNAME(mux_xin24m_32k_p)               = { "xin24m",
+                                   "clk_rtc32k" };
+ PNAME(mux_mac2io_src_p)               = { "clk_mac2io_src",
+-- 
+2.39.5
+
diff --git a/queue-6.14/clk-samsung-fix-ubsan-panic-in-samsung_clk_init.patch b/queue-6.14/clk-samsung-fix-ubsan-panic-in-samsung_clk_init.patch
new file mode 100644 (file)
index 0000000..deaba87
--- /dev/null
@@ -0,0 +1,53 @@
+From d5bae3a314d13f73df7ef524d3057f5e869aa001 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Feb 2025 10:32:52 -0800
+Subject: clk: samsung: Fix UBSAN panic in samsung_clk_init()
+
+From: Will McVicker <willmcvicker@google.com>
+
+[ Upstream commit d19d7345a7bcdb083b65568a11b11adffe0687af ]
+
+With UBSAN_ARRAY_BOUNDS=y, I'm hitting the below panic due to
+dereferencing `ctx->clk_data.hws` before setting
+`ctx->clk_data.num = nr_clks`. Move that up to fix the crash.
+
+  UBSAN: array index out of bounds: 00000000f2005512 [#1] PREEMPT SMP
+  <snip>
+  Call trace:
+   samsung_clk_init+0x110/0x124 (P)
+   samsung_clk_init+0x48/0x124 (L)
+   samsung_cmu_register_one+0x3c/0xa0
+   exynos_arm64_register_cmu+0x54/0x64
+   __gs101_cmu_top_of_clk_init_declare+0x28/0x60
+   ...
+
+Fixes: e620a1e061c4 ("drivers/clk: convert VL struct to struct_size")
+Signed-off-by: Will McVicker <willmcvicker@google.com>
+Link: https://lore.kernel.org/r/20250212183253.509771-1-willmcvicker@google.com
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/samsung/clk.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c
+index 283c523763e6b..8d440cf56bd45 100644
+--- a/drivers/clk/samsung/clk.c
++++ b/drivers/clk/samsung/clk.c
+@@ -74,12 +74,12 @@ struct samsung_clk_provider * __init samsung_clk_init(struct device *dev,
+       if (!ctx)
+               panic("could not allocate clock provider context.\n");
++      ctx->clk_data.num = nr_clks;
+       for (i = 0; i < nr_clks; ++i)
+               ctx->clk_data.hws[i] = ERR_PTR(-ENOENT);
+       ctx->dev = dev;
+       ctx->reg_base = base;
+-      ctx->clk_data.num = nr_clks;
+       spin_lock_init(&ctx->lock);
+       return ctx;
+-- 
+2.39.5
+
diff --git a/queue-6.14/clk-stm32f4-fix-an-uninitialized-variable.patch b/queue-6.14/clk-stm32f4-fix-an-uninitialized-variable.patch
new file mode 100644 (file)
index 0000000..0b9e7c8
--- /dev/null
@@ -0,0 +1,49 @@
+From d7d1d917372a847eb1ac7177cff8bd97c1c3748d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jan 2025 12:16:54 +0100
+Subject: clk: stm32f4: fix an uninitialized variable
+
+From: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+
+[ Upstream commit 9c981c868f5f335e1b51e766b5d36799de163d43 ]
+
+The variable s, used by pr_debug() to print the mnemonic of the modulation
+depth in use, was not initialized. Fix the output by addressing the correct
+mnemonic.
+
+Fixes: 65b3516dbe50 ("clk: stm32f4: support spread spectrum clock generation")
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Closes: https://lore.kernel.org/r/77355eb9-19b3-46e5-a003-c21c0fae5bcd@stanley.mountain
+Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+Link: https://lore.kernel.org/r/20250124111711.1051436-1-dario.binacchi@amarulasolutions.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk-stm32f4.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c
+index f476883bc93ba..85e23961ec341 100644
+--- a/drivers/clk/clk-stm32f4.c
++++ b/drivers/clk/clk-stm32f4.c
+@@ -888,7 +888,6 @@ static int __init stm32f4_pll_ssc_parse_dt(struct device_node *np,
+                                          struct stm32f4_pll_ssc *conf)
+ {
+       int ret;
+-      const char *s;
+       if (!conf)
+               return -EINVAL;
+@@ -916,7 +915,8 @@ static int __init stm32f4_pll_ssc_parse_dt(struct device_node *np,
+       conf->mod_type = ret;
+       pr_debug("%pOF: SSCG settings: mod_freq: %d, mod_depth: %d mod_method: %s [%d]\n",
+-               np, conf->mod_freq, conf->mod_depth, s, conf->mod_type);
++               np, conf->mod_freq, conf->mod_depth,
++               stm32f4_ssc_mod_methods[ret], conf->mod_type);
+       return 0;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/context_tracking-always-inline-ct_-nmi-irq-_-enter-e.patch b/queue-6.14/context_tracking-always-inline-ct_-nmi-irq-_-enter-e.patch
new file mode 100644 (file)
index 0000000..caca17e
--- /dev/null
@@ -0,0 +1,57 @@
+From 94a833eea33280aa8d5b576a3f40bf1446685656 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Mar 2025 21:26:45 -0700
+Subject: context_tracking: Always inline ct_{nmi,irq}_{enter,exit}()
+
+From: Josh Poimboeuf <jpoimboe@kernel.org>
+
+[ Upstream commit 9ac50f7311dc8b39e355582f14c1e82da47a8196 ]
+
+Thanks to CONFIG_DEBUG_SECTION_MISMATCH, empty functions can be
+generated out of line.  These can be called from noinstr code, so make
+sure they're always inlined.
+
+Fixes the following warnings:
+
+  vmlinux.o: warning: objtool: irqentry_nmi_enter+0xa2: call to ct_nmi_enter() leaves .noinstr.text section
+  vmlinux.o: warning: objtool: irqentry_nmi_exit+0x16: call to ct_nmi_exit() leaves .noinstr.text section
+  vmlinux.o: warning: objtool: irqentry_exit+0x78: call to ct_irq_exit() leaves .noinstr.text section
+
+Fixes: 6f0e6c1598b1 ("context_tracking: Take IRQ eqs entrypoints over RCU")
+Reported-by: Randy Dunlap <rdunlap@infradead.org>
+Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Cc: Frederic Weisbecker <frederic@kernel.org>
+Cc: Paul E. McKenney <paulmck@kernel.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Link: https://lore.kernel.org/r/8509bce3f536bcd4ae7af3a2cf6930d48c5e631a.1743481539.git.jpoimboe@kernel.org
+Closes: https://lore.kernel.org/d1eca076-fdde-484a-b33e-70e0d167c36d@infradead.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/context_tracking_irq.h | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/include/linux/context_tracking_irq.h b/include/linux/context_tracking_irq.h
+index c50b5670c4a52..197916ee91a4b 100644
+--- a/include/linux/context_tracking_irq.h
++++ b/include/linux/context_tracking_irq.h
+@@ -10,12 +10,12 @@ void ct_irq_exit_irqson(void);
+ void ct_nmi_enter(void);
+ void ct_nmi_exit(void);
+ #else
+-static inline void ct_irq_enter(void) { }
+-static inline void ct_irq_exit(void) { }
++static __always_inline void ct_irq_enter(void) { }
++static __always_inline void ct_irq_exit(void) { }
+ static inline void ct_irq_enter_irqson(void) { }
+ static inline void ct_irq_exit_irqson(void) { }
+-static inline void ct_nmi_enter(void) { }
+-static inline void ct_nmi_exit(void) { }
++static __always_inline void ct_nmi_enter(void) { }
++static __always_inline void ct_nmi_exit(void) { }
+ #endif
+ #endif
+-- 
+2.39.5
+
diff --git a/queue-6.14/coredump-fixes-core_pipe_limit-sysctl-proc_handler.patch b/queue-6.14/coredump-fixes-core_pipe_limit-sysctl-proc_handler.patch
new file mode 100644 (file)
index 0000000..2d99baf
--- /dev/null
@@ -0,0 +1,55 @@
+From d2cd7b2f6a644d94a3de5b8ffb2ad1c56d8940a4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jan 2025 14:22:08 +0100
+Subject: coredump: Fixes core_pipe_limit sysctl proc_handler
+
+From: Nicolas Bouchinet <nicolas.bouchinet@ssi.gouv.fr>
+
+[ Upstream commit 049439e22825507a90d4dedf3934e24fd0a8ff62 ]
+
+proc_dointvec converts a string to a vector of signed int, which is
+stored in the unsigned int .data core_pipe_limit.
+It was thus authorized to write a negative value to core_pipe_limit
+sysctl which once stored in core_pipe_limit, leads to the signed int
+dump_count check against core_pipe_limit never be true. The same can be
+achieved with core_pipe_limit set to INT_MAX.
+
+Any negative write or >= to INT_MAX in core_pipe_limit sysctl would
+hypothetically allow a user to create very high load on the system by
+running processes that produces a coredump in case the core_pattern
+sysctl is configured to pipe core files to user space helper.
+Memory or PID exhaustion should happen before but it anyway breaks the
+core_pipe_limit semantic.
+
+This commit fixes this by changing core_pipe_limit sysctl's proc_handler
+to proc_dointvec_minmax and bound checking between SYSCTL_ZERO and
+SYSCTL_INT_MAX.
+
+Fixes: a293980c2e26 ("exec: let do_coredump() limit the number of concurrent dumps to pipes")
+Signed-off-by: Nicolas Bouchinet <nicolas.bouchinet@ssi.gouv.fr>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Kees Cook <kees@kernel.org>
+Signed-off-by: Joel Granados <joel.granados@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/coredump.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/fs/coredump.c b/fs/coredump.c
+index 4375c70144d0a..4ebec51fe4f22 100644
+--- a/fs/coredump.c
++++ b/fs/coredump.c
+@@ -1016,7 +1016,9 @@ static const struct ctl_table coredump_sysctls[] = {
+               .data           = &core_pipe_limit,
+               .maxlen         = sizeof(unsigned int),
+               .mode           = 0644,
+-              .proc_handler   = proc_dointvec,
++              .proc_handler   = proc_dointvec_minmax,
++              .extra1         = SYSCTL_ZERO,
++              .extra2         = SYSCTL_INT_MAX,
+       },
+       {
+               .procname       = "core_file_note_size_limit",
+-- 
+2.39.5
+
diff --git a/queue-6.14/coresight-catu-fix-number-of-pages-while-using-64k-p.patch b/queue-6.14/coresight-catu-fix-number-of-pages-while-using-64k-p.patch
new file mode 100644 (file)
index 0000000..24bae1d
--- /dev/null
@@ -0,0 +1,41 @@
+From 38f10f26540eea8b970d65ed036ab0daff56908d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jan 2025 21:53:48 +0000
+Subject: coresight: catu: Fix number of pages while using 64k pages
+
+From: Ilkka Koskinen <ilkka@os.amperecomputing.com>
+
+[ Upstream commit 0e14e062f5ff98aa15264dfa87c5f5e924028561 ]
+
+Trying to record a trace on kernel with 64k pages resulted in -ENOMEM.
+This happens due to a bug in calculating the number of table pages, which
+returns zero. Fix the issue by rounding up.
+
+$ perf record --kcore -e cs_etm/@tmc_etr55,cycacc,branch_broadcast/k --per-thread taskset --cpu-list 1 dd if=/dev/zero of=/dev/null
+failed to mmap with 12 (Cannot allocate memory)
+
+Fixes: 8ed536b1e283 ("coresight: catu: Add support for scatter gather tables")
+Signed-off-by: Ilkka Koskinen <ilkka@os.amperecomputing.com>
+Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Link: https://lore.kernel.org/r/20250109215348.5483-1-ilkka@os.amperecomputing.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwtracing/coresight/coresight-catu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c
+index 275cc0d9f505f..3378bb77e6b41 100644
+--- a/drivers/hwtracing/coresight/coresight-catu.c
++++ b/drivers/hwtracing/coresight/coresight-catu.c
+@@ -269,7 +269,7 @@ catu_init_sg_table(struct device *catu_dev, int node,
+        * Each table can address upto 1MB and we can have
+        * CATU_PAGES_PER_SYSPAGE tables in a system page.
+        */
+-      nr_tpages = DIV_ROUND_UP(size, SZ_1M) / CATU_PAGES_PER_SYSPAGE;
++      nr_tpages = DIV_ROUND_UP(size, CATU_PAGES_PER_SYSPAGE * SZ_1M);
+       catu_table = tmc_alloc_sg_table(catu_dev, node, nr_tpages,
+                                       size >> PAGE_SHIFT, pages);
+       if (IS_ERR(catu_table))
+-- 
+2.39.5
+
diff --git a/queue-6.14/coresight-etm4x-add-isb-before-reading-the-trcstatr.patch b/queue-6.14/coresight-etm4x-add-isb-before-reading-the-trcstatr.patch
new file mode 100644 (file)
index 0000000..3f938c9
--- /dev/null
@@ -0,0 +1,196 @@
+From 708469dac7719f8c1fd32af1602b87e6b58e2996 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jan 2025 17:04:20 +0800
+Subject: coresight-etm4x: add isb() before reading the TRCSTATR
+
+From: Yuanfang Zhang <quic_yuanfang@quicinc.com>
+
+[ Upstream commit 4ff6039ffb79a4a8a44b63810a8a2f2b43264856 ]
+
+As recommended by section 4.3.7 ("Synchronization when using system
+instructions to progrom the trace unit") of ARM IHI 0064H.b, the
+self-hosted trace analyzer must perform a Context synchronization
+event between writing to the TRCPRGCTLR and reading the TRCSTATR.
+Additionally, add an ISB between the each read of TRCSTATR on
+coresight_timeout() when using system instructions to program the
+trace unit.
+
+Fixes: 1ab3bb9df5e3 ("coresight: etm4x: Add necessary synchronization for sysreg access")
+Signed-off-by: Yuanfang Zhang <quic_yuanfang@quicinc.com>
+Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Link: https://lore.kernel.org/r/20250116-etm_sync-v4-1-39f2b05e9514@quicinc.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwtracing/coresight/coresight-core.c  | 20 ++++++--
+ .../coresight/coresight-etm4x-core.c          | 48 +++++++++++++++++--
+ include/linux/coresight.h                     |  4 ++
+ 3 files changed, 62 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
+index 0a9380350fb52..4936dc2f7a56b 100644
+--- a/drivers/hwtracing/coresight/coresight-core.c
++++ b/drivers/hwtracing/coresight/coresight-core.c
+@@ -1092,18 +1092,20 @@ static void coresight_remove_conns(struct coresight_device *csdev)
+ }
+ /**
+- * coresight_timeout - loop until a bit has changed to a specific register
+- *                    state.
++ * coresight_timeout_action - loop until a bit has changed to a specific register
++ *                  state, with a callback after every trial.
+  * @csa: coresight device access for the device
+  * @offset: Offset of the register from the base of the device.
+  * @position: the position of the bit of interest.
+  * @value: the value the bit should have.
++ * @cb: Call back after each trial.
+  *
+  * Return: 0 as soon as the bit has taken the desired state or -EAGAIN if
+  * TIMEOUT_US has elapsed, which ever happens first.
+  */
+-int coresight_timeout(struct csdev_access *csa, u32 offset,
+-                    int position, int value)
++int coresight_timeout_action(struct csdev_access *csa, u32 offset,
++                    int position, int value,
++                        coresight_timeout_cb_t cb)
+ {
+       int i;
+       u32 val;
+@@ -1119,7 +1121,8 @@ int coresight_timeout(struct csdev_access *csa, u32 offset,
+                       if (!(val & BIT(position)))
+                               return 0;
+               }
+-
++              if (cb)
++                      cb(csa, offset, position, value);
+               /*
+                * Delay is arbitrary - the specification doesn't say how long
+                * we are expected to wait.  Extra check required to make sure
+@@ -1131,6 +1134,13 @@ int coresight_timeout(struct csdev_access *csa, u32 offset,
+       return -EAGAIN;
+ }
++EXPORT_SYMBOL_GPL(coresight_timeout_action);
++
++int coresight_timeout(struct csdev_access *csa, u32 offset,
++                    int position, int value)
++{
++      return coresight_timeout_action(csa, offset, position, value, NULL);
++}
+ EXPORT_SYMBOL_GPL(coresight_timeout);
+ u32 coresight_relaxed_read32(struct coresight_device *csdev, u32 offset)
+diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
+index 2c1a60577728e..5bda265d02340 100644
+--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
+@@ -428,6 +428,29 @@ static void etm4_check_arch_features(struct etmv4_drvdata *drvdata,
+ }
+ #endif /* CONFIG_ETM4X_IMPDEF_FEATURE */
++static void etm4x_sys_ins_barrier(struct csdev_access *csa, u32 offset, int pos, int val)
++{
++      if (!csa->io_mem)
++              isb();
++}
++
++/*
++ * etm4x_wait_status: Poll for TRCSTATR.<pos> == <val>. While using system
++ * instruction to access the trace unit, each access must be separated by a
++ * synchronization barrier. See ARM IHI0064H.b section "4.3.7 Synchronization of
++ * register updates", for system instructions section, in "Notes":
++ *
++ *   "In particular, whenever disabling or enabling the trace unit, a poll of
++ *    TRCSTATR needs explicit synchronization between each read of TRCSTATR"
++ */
++static int etm4x_wait_status(struct csdev_access *csa, int pos, int val)
++{
++      if (!csa->io_mem)
++              return coresight_timeout_action(csa, TRCSTATR, pos, val,
++                                              etm4x_sys_ins_barrier);
++      return coresight_timeout(csa, TRCSTATR, pos, val);
++}
++
+ static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
+ {
+       int i, rc;
+@@ -459,7 +482,7 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
+               isb();
+       /* wait for TRCSTATR.IDLE to go up */
+-      if (coresight_timeout(csa, TRCSTATR, TRCSTATR_IDLE_BIT, 1))
++      if (etm4x_wait_status(csa, TRCSTATR_IDLE_BIT, 1))
+               dev_err(etm_dev,
+                       "timeout while waiting for Idle Trace Status\n");
+       if (drvdata->nr_pe)
+@@ -552,7 +575,7 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
+               isb();
+       /* wait for TRCSTATR.IDLE to go back down to '0' */
+-      if (coresight_timeout(csa, TRCSTATR, TRCSTATR_IDLE_BIT, 0))
++      if (etm4x_wait_status(csa, TRCSTATR_IDLE_BIT, 0))
+               dev_err(etm_dev,
+                       "timeout while waiting for Idle Trace Status\n");
+@@ -941,10 +964,25 @@ static void etm4_disable_hw(void *info)
+       tsb_csync();
+       etm4x_relaxed_write32(csa, control, TRCPRGCTLR);
++      /*
++       * As recommended by section 4.3.7 ("Synchronization when using system
++       * instructions to progrom the trace unit") of ARM IHI 0064H.b, the
++       * self-hosted trace analyzer must perform a Context synchronization
++       * event between writing to the TRCPRGCTLR and reading the TRCSTATR.
++       */
++      if (!csa->io_mem)
++              isb();
++
+       /* wait for TRCSTATR.PMSTABLE to go to '1' */
+-      if (coresight_timeout(csa, TRCSTATR, TRCSTATR_PMSTABLE_BIT, 1))
++      if (etm4x_wait_status(csa, TRCSTATR_PMSTABLE_BIT, 1))
+               dev_err(etm_dev,
+                       "timeout while waiting for PM stable Trace Status\n");
++      /*
++       * As recommended by section 4.3.7 (Synchronization of register updates)
++       * of ARM IHI 0064H.b.
++       */
++      isb();
++
+       /* read the status of the single shot comparators */
+       for (i = 0; i < drvdata->nr_ss_cmp; i++) {
+               config->ss_status[i] =
+@@ -1746,7 +1784,7 @@ static int __etm4_cpu_save(struct etmv4_drvdata *drvdata)
+       etm4_os_lock(drvdata);
+       /* wait for TRCSTATR.PMSTABLE to go up */
+-      if (coresight_timeout(csa, TRCSTATR, TRCSTATR_PMSTABLE_BIT, 1)) {
++      if (etm4x_wait_status(csa, TRCSTATR_PMSTABLE_BIT, 1)) {
+               dev_err(etm_dev,
+                       "timeout while waiting for PM Stable Status\n");
+               etm4_os_unlock(drvdata);
+@@ -1837,7 +1875,7 @@ static int __etm4_cpu_save(struct etmv4_drvdata *drvdata)
+               state->trcpdcr = etm4x_read32(csa, TRCPDCR);
+       /* wait for TRCSTATR.IDLE to go up */
+-      if (coresight_timeout(csa, TRCSTATR, TRCSTATR_IDLE_BIT, 1)) {
++      if (etm4x_wait_status(csa, TRCSTATR_PMSTABLE_BIT, 1)) {
+               dev_err(etm_dev,
+                       "timeout while waiting for Idle Trace Status\n");
+               etm4_os_unlock(drvdata);
+diff --git a/include/linux/coresight.h b/include/linux/coresight.h
+index 17276965ff1d0..6ddcbb8be5165 100644
+--- a/include/linux/coresight.h
++++ b/include/linux/coresight.h
+@@ -649,6 +649,10 @@ extern int coresight_enable_sysfs(struct coresight_device *csdev);
+ extern void coresight_disable_sysfs(struct coresight_device *csdev);
+ extern int coresight_timeout(struct csdev_access *csa, u32 offset,
+                            int position, int value);
++typedef void (*coresight_timeout_cb_t) (struct csdev_access *, u32, int, int);
++extern int coresight_timeout_action(struct csdev_access *csa, u32 offset,
++                                      int position, int value,
++                                      coresight_timeout_cb_t cb);
+ extern int coresight_claim_device(struct coresight_device *csdev);
+ extern int coresight_claim_device_unlocked(struct coresight_device *csdev);
+-- 
+2.39.5
+
diff --git a/queue-6.14/cpufreq-amd-pstate-add-missing-null-ptr-check-in-amd.patch b/queue-6.14/cpufreq-amd-pstate-add-missing-null-ptr-check-in-amd.patch
new file mode 100644 (file)
index 0000000..38f41ec
--- /dev/null
@@ -0,0 +1,39 @@
+From cd1aa8322e1b534597f09693fe835a859069bca2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Feb 2025 11:25:21 +0000
+Subject: cpufreq/amd-pstate: Add missing NULL ptr check in amd_pstate_update
+
+From: Dhananjay Ugwekar <dhananjay.ugwekar@amd.com>
+
+[ Upstream commit 426db24d4db2e4f0d6720aeb7795eafcb9e82640 ]
+
+Check if policy is NULL before dereferencing it in amd_pstate_update.
+
+Fixes: e8f555daacd3 ("cpufreq/amd-pstate: fix setting policy current frequency value")
+Signed-off-by: Dhananjay Ugwekar <dhananjay.ugwekar@amd.com>
+Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
+Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
+Link: https://lore.kernel.org/r/20250205112523.201101-11-dhananjay.ugwekar@amd.com
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/amd-pstate.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
+index 32f1b659904bc..bd63837eabb4e 100644
+--- a/drivers/cpufreq/amd-pstate.c
++++ b/drivers/cpufreq/amd-pstate.c
+@@ -538,6 +538,9 @@ static void amd_pstate_update(struct amd_cpudata *cpudata, u8 min_perf,
+       struct cpufreq_policy *policy = cpufreq_cpu_get(cpudata->cpu);
+       u8 nominal_perf = READ_ONCE(cpudata->nominal_perf);
++      if (!policy)
++              return;
++
+       des_perf = clamp_t(u8, des_perf, min_perf, max_perf);
+       max_freq = READ_ONCE(cpudata->max_limit_freq);
+-- 
+2.39.5
+
diff --git a/queue-6.14/cpufreq-amd-pstate-convert-all-perf-values-to-u8.patch b/queue-6.14/cpufreq-amd-pstate-convert-all-perf-values-to-u8.patch
new file mode 100644 (file)
index 0000000..8186ae3
--- /dev/null
@@ -0,0 +1,373 @@
+From f13465948afc310862d717712b5f549025a0bcf1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Feb 2025 11:25:17 +0000
+Subject: cpufreq/amd-pstate: Convert all perf values to u8
+
+From: Dhananjay Ugwekar <dhananjay.ugwekar@amd.com>
+
+[ Upstream commit 555bbe67a622b297405e246d1868dbda3284bde8 ]
+
+All perf values are always within 0-255 range, hence convert their
+datatype to u8 everywhere.
+
+Signed-off-by: Dhananjay Ugwekar <dhananjay.ugwekar@amd.com>
+Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
+Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
+Link: https://lore.kernel.org/r/20250205112523.201101-7-dhananjay.ugwekar@amd.com
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Stable-dep-of: 426db24d4db2 ("cpufreq/amd-pstate: Add missing NULL ptr check in amd_pstate_update")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/amd-pstate-trace.h | 46 +++++++++++------------
+ drivers/cpufreq/amd-pstate.c       | 60 +++++++++++++++---------------
+ drivers/cpufreq/amd-pstate.h       | 18 ++++-----
+ 3 files changed, 62 insertions(+), 62 deletions(-)
+
+diff --git a/drivers/cpufreq/amd-pstate-trace.h b/drivers/cpufreq/amd-pstate-trace.h
+index 8d692415d9050..f457d4af2c62e 100644
+--- a/drivers/cpufreq/amd-pstate-trace.h
++++ b/drivers/cpufreq/amd-pstate-trace.h
+@@ -24,9 +24,9 @@
+ TRACE_EVENT(amd_pstate_perf,
+-      TP_PROTO(unsigned long min_perf,
+-               unsigned long target_perf,
+-               unsigned long capacity,
++      TP_PROTO(u8 min_perf,
++               u8 target_perf,
++               u8 capacity,
+                u64 freq,
+                u64 mperf,
+                u64 aperf,
+@@ -47,9 +47,9 @@ TRACE_EVENT(amd_pstate_perf,
+               ),
+       TP_STRUCT__entry(
+-              __field(unsigned long, min_perf)
+-              __field(unsigned long, target_perf)
+-              __field(unsigned long, capacity)
++              __field(u8, min_perf)
++              __field(u8, target_perf)
++              __field(u8, capacity)
+               __field(unsigned long long, freq)
+               __field(unsigned long long, mperf)
+               __field(unsigned long long, aperf)
+@@ -70,10 +70,10 @@ TRACE_EVENT(amd_pstate_perf,
+               __entry->fast_switch = fast_switch;
+               ),
+-      TP_printk("amd_min_perf=%lu amd_des_perf=%lu amd_max_perf=%lu freq=%llu mperf=%llu aperf=%llu tsc=%llu cpu_id=%u fast_switch=%s",
+-                (unsigned long)__entry->min_perf,
+-                (unsigned long)__entry->target_perf,
+-                (unsigned long)__entry->capacity,
++      TP_printk("amd_min_perf=%hhu amd_des_perf=%hhu amd_max_perf=%hhu freq=%llu mperf=%llu aperf=%llu tsc=%llu cpu_id=%u fast_switch=%s",
++                (u8)__entry->min_perf,
++                (u8)__entry->target_perf,
++                (u8)__entry->capacity,
+                 (unsigned long long)__entry->freq,
+                 (unsigned long long)__entry->mperf,
+                 (unsigned long long)__entry->aperf,
+@@ -86,10 +86,10 @@ TRACE_EVENT(amd_pstate_perf,
+ TRACE_EVENT(amd_pstate_epp_perf,
+       TP_PROTO(unsigned int cpu_id,
+-               unsigned int highest_perf,
+-               unsigned int epp,
+-               unsigned int min_perf,
+-               unsigned int max_perf,
++               u8 highest_perf,
++               u8 epp,
++               u8 min_perf,
++               u8 max_perf,
+                bool boost
+                ),
+@@ -102,10 +102,10 @@ TRACE_EVENT(amd_pstate_epp_perf,
+       TP_STRUCT__entry(
+               __field(unsigned int, cpu_id)
+-              __field(unsigned int, highest_perf)
+-              __field(unsigned int, epp)
+-              __field(unsigned int, min_perf)
+-              __field(unsigned int, max_perf)
++              __field(u8, highest_perf)
++              __field(u8, epp)
++              __field(u8, min_perf)
++              __field(u8, max_perf)
+               __field(bool, boost)
+               ),
+@@ -118,12 +118,12 @@ TRACE_EVENT(amd_pstate_epp_perf,
+               __entry->boost = boost;
+               ),
+-      TP_printk("cpu%u: [%u<->%u]/%u, epp=%u, boost=%u",
++      TP_printk("cpu%u: [%hhu<->%hhu]/%hhu, epp=%hhu, boost=%u",
+                 (unsigned int)__entry->cpu_id,
+-                (unsigned int)__entry->min_perf,
+-                (unsigned int)__entry->max_perf,
+-                (unsigned int)__entry->highest_perf,
+-                (unsigned int)__entry->epp,
++                (u8)__entry->min_perf,
++                (u8)__entry->max_perf,
++                (u8)__entry->highest_perf,
++                (u8)__entry->epp,
+                 (bool)__entry->boost
+                )
+ );
+diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
+index 3ef10aae0502f..32f1b659904bc 100644
+--- a/drivers/cpufreq/amd-pstate.c
++++ b/drivers/cpufreq/amd-pstate.c
+@@ -186,7 +186,7 @@ static inline int get_mode_idx_from_str(const char *str, size_t size)
+ static DEFINE_MUTEX(amd_pstate_limits_lock);
+ static DEFINE_MUTEX(amd_pstate_driver_lock);
+-static s16 msr_get_epp(struct amd_cpudata *cpudata)
++static u8 msr_get_epp(struct amd_cpudata *cpudata)
+ {
+       u64 value;
+       int ret;
+@@ -207,7 +207,7 @@ static inline s16 amd_pstate_get_epp(struct amd_cpudata *cpudata)
+       return static_call(amd_pstate_get_epp)(cpudata);
+ }
+-static s16 shmem_get_epp(struct amd_cpudata *cpudata)
++static u8 shmem_get_epp(struct amd_cpudata *cpudata)
+ {
+       u64 epp;
+       int ret;
+@@ -218,11 +218,11 @@ static s16 shmem_get_epp(struct amd_cpudata *cpudata)
+               return ret;
+       }
+-      return (s16)(epp & 0xff);
++      return FIELD_GET(AMD_CPPC_EPP_PERF_MASK, epp);
+ }
+-static int msr_update_perf(struct amd_cpudata *cpudata, u32 min_perf,
+-                         u32 des_perf, u32 max_perf, u32 epp, bool fast_switch)
++static int msr_update_perf(struct amd_cpudata *cpudata, u8 min_perf,
++                         u8 des_perf, u8 max_perf, u8 epp, bool fast_switch)
+ {
+       u64 value, prev;
+@@ -257,15 +257,15 @@ static int msr_update_perf(struct amd_cpudata *cpudata, u32 min_perf,
+ DEFINE_STATIC_CALL(amd_pstate_update_perf, msr_update_perf);
+ static inline int amd_pstate_update_perf(struct amd_cpudata *cpudata,
+-                                        u32 min_perf, u32 des_perf,
+-                                        u32 max_perf, u32 epp,
++                                        u8 min_perf, u8 des_perf,
++                                        u8 max_perf, u8 epp,
+                                         bool fast_switch)
+ {
+       return static_call(amd_pstate_update_perf)(cpudata, min_perf, des_perf,
+                                                  max_perf, epp, fast_switch);
+ }
+-static int msr_set_epp(struct amd_cpudata *cpudata, u32 epp)
++static int msr_set_epp(struct amd_cpudata *cpudata, u8 epp)
+ {
+       u64 value, prev;
+       int ret;
+@@ -292,12 +292,12 @@ static int msr_set_epp(struct amd_cpudata *cpudata, u32 epp)
+ DEFINE_STATIC_CALL(amd_pstate_set_epp, msr_set_epp);
+-static inline int amd_pstate_set_epp(struct amd_cpudata *cpudata, u32 epp)
++static inline int amd_pstate_set_epp(struct amd_cpudata *cpudata, u8 epp)
+ {
+       return static_call(amd_pstate_set_epp)(cpudata, epp);
+ }
+-static int shmem_set_epp(struct amd_cpudata *cpudata, u32 epp)
++static int shmem_set_epp(struct amd_cpudata *cpudata, u8 epp)
+ {
+       int ret;
+       struct cppc_perf_ctrls perf_ctrls;
+@@ -320,7 +320,7 @@ static int amd_pstate_set_energy_pref_index(struct cpufreq_policy *policy,
+                                           int pref_index)
+ {
+       struct amd_cpudata *cpudata = policy->driver_data;
+-      int epp;
++      u8 epp;
+       if (!pref_index)
+               epp = cpudata->epp_default;
+@@ -479,8 +479,8 @@ static inline int amd_pstate_init_perf(struct amd_cpudata *cpudata)
+       return static_call(amd_pstate_init_perf)(cpudata);
+ }
+-static int shmem_update_perf(struct amd_cpudata *cpudata, u32 min_perf,
+-                           u32 des_perf, u32 max_perf, u32 epp, bool fast_switch)
++static int shmem_update_perf(struct amd_cpudata *cpudata, u8 min_perf,
++                           u8 des_perf, u8 max_perf, u8 epp, bool fast_switch)
+ {
+       struct cppc_perf_ctrls perf_ctrls;
+@@ -531,14 +531,14 @@ static inline bool amd_pstate_sample(struct amd_cpudata *cpudata)
+       return true;
+ }
+-static void amd_pstate_update(struct amd_cpudata *cpudata, u32 min_perf,
+-                            u32 des_perf, u32 max_perf, bool fast_switch, int gov_flags)
++static void amd_pstate_update(struct amd_cpudata *cpudata, u8 min_perf,
++                            u8 des_perf, u8 max_perf, bool fast_switch, int gov_flags)
+ {
+       unsigned long max_freq;
+       struct cpufreq_policy *policy = cpufreq_cpu_get(cpudata->cpu);
+-      u32 nominal_perf = READ_ONCE(cpudata->nominal_perf);
++      u8 nominal_perf = READ_ONCE(cpudata->nominal_perf);
+-      des_perf = clamp_t(unsigned long, des_perf, min_perf, max_perf);
++      des_perf = clamp_t(u8, des_perf, min_perf, max_perf);
+       max_freq = READ_ONCE(cpudata->max_limit_freq);
+       policy->cur = div_u64(des_perf * max_freq, max_perf);
+@@ -550,7 +550,7 @@ static void amd_pstate_update(struct amd_cpudata *cpudata, u32 min_perf,
+       /* limit the max perf when core performance boost feature is disabled */
+       if (!cpudata->boost_supported)
+-              max_perf = min_t(unsigned long, nominal_perf, max_perf);
++              max_perf = min_t(u8, nominal_perf, max_perf);
+       if (trace_amd_pstate_perf_enabled() && amd_pstate_sample(cpudata)) {
+               trace_amd_pstate_perf(min_perf, des_perf, max_perf, cpudata->freq,
+@@ -591,7 +591,8 @@ static int amd_pstate_verify(struct cpufreq_policy_data *policy_data)
+ static int amd_pstate_update_min_max_limit(struct cpufreq_policy *policy)
+ {
+-      u32 max_limit_perf, min_limit_perf, max_perf, max_freq;
++      u8 max_limit_perf, min_limit_perf, max_perf;
++      u32 max_freq;
+       struct amd_cpudata *cpudata = policy->driver_data;
+       max_perf = READ_ONCE(cpudata->highest_perf);
+@@ -615,7 +616,7 @@ static int amd_pstate_update_freq(struct cpufreq_policy *policy,
+ {
+       struct cpufreq_freqs freqs;
+       struct amd_cpudata *cpudata = policy->driver_data;
+-      unsigned long des_perf, cap_perf;
++      u8 des_perf, cap_perf;
+       if (!cpudata->max_freq)
+               return -ENODEV;
+@@ -670,8 +671,7 @@ static void amd_pstate_adjust_perf(unsigned int cpu,
+                                  unsigned long target_perf,
+                                  unsigned long capacity)
+ {
+-      unsigned long max_perf, min_perf, des_perf,
+-                    cap_perf, min_limit_perf;
++      u8 max_perf, min_perf, des_perf, cap_perf, min_limit_perf;
+       struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
+       struct amd_cpudata *cpudata;
+@@ -907,8 +907,8 @@ static int amd_pstate_init_freq(struct amd_cpudata *cpudata)
+ {
+       int ret;
+       u32 min_freq, max_freq;
+-      u32 highest_perf, nominal_perf, nominal_freq;
+-      u32 lowest_nonlinear_perf, lowest_nonlinear_freq;
++      u8 highest_perf, nominal_perf, lowest_nonlinear_perf;
++      u32 nominal_freq, lowest_nonlinear_freq;
+       struct cppc_perf_caps cppc_perf;
+       ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf);
+@@ -1115,7 +1115,7 @@ static ssize_t show_amd_pstate_lowest_nonlinear_freq(struct cpufreq_policy *poli
+ static ssize_t show_amd_pstate_highest_perf(struct cpufreq_policy *policy,
+                                           char *buf)
+ {
+-      u32 perf;
++      u8 perf;
+       struct amd_cpudata *cpudata = policy->driver_data;
+       perf = READ_ONCE(cpudata->highest_perf);
+@@ -1126,7 +1126,7 @@ static ssize_t show_amd_pstate_highest_perf(struct cpufreq_policy *policy,
+ static ssize_t show_amd_pstate_prefcore_ranking(struct cpufreq_policy *policy,
+                                               char *buf)
+ {
+-      u32 perf;
++      u8 perf;
+       struct amd_cpudata *cpudata = policy->driver_data;
+       perf = READ_ONCE(cpudata->prefcore_ranking);
+@@ -1189,7 +1189,7 @@ static ssize_t show_energy_performance_preference(
+                               struct cpufreq_policy *policy, char *buf)
+ {
+       struct amd_cpudata *cpudata = policy->driver_data;
+-      int preference;
++      u8 preference;
+       switch (cpudata->epp_cached) {
+       case AMD_CPPC_EPP_PERFORMANCE:
+@@ -1551,7 +1551,7 @@ static void amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy)
+ static int amd_pstate_epp_update_limit(struct cpufreq_policy *policy)
+ {
+       struct amd_cpudata *cpudata = policy->driver_data;
+-      u32 epp;
++      u8 epp;
+       amd_pstate_update_min_max_limit(policy);
+@@ -1600,7 +1600,7 @@ static int amd_pstate_epp_set_policy(struct cpufreq_policy *policy)
+ static int amd_pstate_epp_reenable(struct cpufreq_policy *policy)
+ {
+       struct amd_cpudata *cpudata = policy->driver_data;
+-      u64 max_perf;
++      u8 max_perf;
+       int ret;
+       ret = amd_pstate_cppc_enable(true);
+@@ -1637,7 +1637,7 @@ static int amd_pstate_epp_cpu_online(struct cpufreq_policy *policy)
+ static int amd_pstate_epp_cpu_offline(struct cpufreq_policy *policy)
+ {
+       struct amd_cpudata *cpudata = policy->driver_data;
+-      int min_perf;
++      u8 min_perf;
+       if (cpudata->suspended)
+               return 0;
+diff --git a/drivers/cpufreq/amd-pstate.h b/drivers/cpufreq/amd-pstate.h
+index 9747e3be6ceee..19d405c6d805e 100644
+--- a/drivers/cpufreq/amd-pstate.h
++++ b/drivers/cpufreq/amd-pstate.h
+@@ -70,13 +70,13 @@ struct amd_cpudata {
+       struct  freq_qos_request req[2];
+       u64     cppc_req_cached;
+-      u32     highest_perf;
+-      u32     nominal_perf;
+-      u32     lowest_nonlinear_perf;
+-      u32     lowest_perf;
+-      u32     prefcore_ranking;
+-      u32     min_limit_perf;
+-      u32     max_limit_perf;
++      u8      highest_perf;
++      u8      nominal_perf;
++      u8      lowest_nonlinear_perf;
++      u8      lowest_perf;
++      u8      prefcore_ranking;
++      u8      min_limit_perf;
++      u8      max_limit_perf;
+       u32     min_limit_freq;
+       u32     max_limit_freq;
+@@ -93,11 +93,11 @@ struct amd_cpudata {
+       bool    hw_prefcore;
+       /* EPP feature related attributes*/
+-      s16     epp_cached;
++      u8      epp_cached;
+       u32     policy;
+       u64     cppc_cap1_cached;
+       bool    suspended;
+-      s16     epp_default;
++      u8      epp_default;
+ };
+ /*
+-- 
+2.39.5
+
diff --git a/queue-6.14/cpufreq-amd-pstate-modify-the-min_perf-calculation-i.patch b/queue-6.14/cpufreq-amd-pstate-modify-the-min_perf-calculation-i.patch
new file mode 100644 (file)
index 0000000..6e38836
--- /dev/null
@@ -0,0 +1,73 @@
+From 5486c84961edce173a4ae864b8ae52a120f1a5b6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Feb 2025 11:25:14 +0000
+Subject: cpufreq/amd-pstate: Modify the min_perf calculation in adjust_perf
+ callback
+
+From: Dhananjay Ugwekar <dhananjay.ugwekar@amd.com>
+
+[ Upstream commit 6ceb877d5cecd5417d63239bf833a1cd5f8f271c ]
+
+Instead of setting a fixed floor at lowest_nonlinear_perf, use the
+min_limit_perf value, so that it gives the user the freedom to lower the
+floor further.
+
+There are two minimum frequency/perf limits that we need to consider in
+the adjust_perf callback. One provided by schedutil i.e. the sg_cpu->bw_min
+value passed in _min_perf arg, another is the effective value of
+min_freq_qos request that is updated in cpudata->min_limit_perf. Modify the
+code to use the bigger of these two values.
+
+Signed-off-by: Dhananjay Ugwekar <dhananjay.ugwekar@amd.com>
+Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
+Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
+Link: https://lore.kernel.org/r/20250205112523.201101-4-dhananjay.ugwekar@amd.com
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Stable-dep-of: 426db24d4db2 ("cpufreq/amd-pstate: Add missing NULL ptr check in amd_pstate_update")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/amd-pstate.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
+index 313550fa62d41..17595a2454e1c 100644
+--- a/drivers/cpufreq/amd-pstate.c
++++ b/drivers/cpufreq/amd-pstate.c
+@@ -672,7 +672,7 @@ static void amd_pstate_adjust_perf(unsigned int cpu,
+                                  unsigned long capacity)
+ {
+       unsigned long max_perf, min_perf, des_perf,
+-                    cap_perf, lowest_nonlinear_perf;
++                    cap_perf, min_limit_perf;
+       struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
+       struct amd_cpudata *cpudata;
+@@ -684,20 +684,20 @@ static void amd_pstate_adjust_perf(unsigned int cpu,
+       if (policy->min != cpudata->min_limit_freq || policy->max != cpudata->max_limit_freq)
+               amd_pstate_update_min_max_limit(policy);
+-
+       cap_perf = READ_ONCE(cpudata->highest_perf);
+-      lowest_nonlinear_perf = READ_ONCE(cpudata->lowest_nonlinear_perf);
++      min_limit_perf = READ_ONCE(cpudata->min_limit_perf);
+       des_perf = cap_perf;
+       if (target_perf < capacity)
+               des_perf = DIV_ROUND_UP(cap_perf * target_perf, capacity);
+-      min_perf = READ_ONCE(cpudata->lowest_perf);
+       if (_min_perf < capacity)
+               min_perf = DIV_ROUND_UP(cap_perf * _min_perf, capacity);
++      else
++              min_perf = cap_perf;
+-      if (min_perf < lowest_nonlinear_perf)
+-              min_perf = lowest_nonlinear_perf;
++      if (min_perf < min_limit_perf)
++              min_perf = min_limit_perf;
+       max_perf = cpudata->max_limit_perf;
+       if (max_perf < min_perf)
+-- 
+2.39.5
+
diff --git a/queue-6.14/cpufreq-amd-pstate-pass-min-max_limit_perf-as-min-ma.patch b/queue-6.14/cpufreq-amd-pstate-pass-min-max_limit_perf-as-min-ma.patch
new file mode 100644 (file)
index 0000000..1467e06
--- /dev/null
@@ -0,0 +1,65 @@
+From b1824fed88e5d54fcd0c153cc31cdef75a26a2af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Feb 2025 11:25:16 +0000
+Subject: cpufreq/amd-pstate: Pass min/max_limit_perf as min/max_perf to
+ amd_pstate_update
+
+From: Dhananjay Ugwekar <dhananjay.ugwekar@amd.com>
+
+[ Upstream commit e9869c836b2a460c48e2d69ae79d786303dbffda ]
+
+Currently, amd_pstate_update_freq passes the hardware perf limits as
+min/max_perf to amd_pstate_update, which eventually gets programmed into
+the min/max_perf fields of the CPPC_REQ register.
+
+Instead pass the effective perf limits i.e. min/max_limit_perf values to
+amd_pstate_update as min/max_perf.
+
+Signed-off-by: Dhananjay Ugwekar <dhananjay.ugwekar@amd.com>
+Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
+Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
+Link: https://lore.kernel.org/r/20250205112523.201101-6-dhananjay.ugwekar@amd.com
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Stable-dep-of: 426db24d4db2 ("cpufreq/amd-pstate: Add missing NULL ptr check in amd_pstate_update")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/amd-pstate.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
+index 17595a2454e1c..3ef10aae0502f 100644
+--- a/drivers/cpufreq/amd-pstate.c
++++ b/drivers/cpufreq/amd-pstate.c
+@@ -615,7 +615,7 @@ static int amd_pstate_update_freq(struct cpufreq_policy *policy,
+ {
+       struct cpufreq_freqs freqs;
+       struct amd_cpudata *cpudata = policy->driver_data;
+-      unsigned long max_perf, min_perf, des_perf, cap_perf;
++      unsigned long des_perf, cap_perf;
+       if (!cpudata->max_freq)
+               return -ENODEV;
+@@ -624,8 +624,6 @@ static int amd_pstate_update_freq(struct cpufreq_policy *policy,
+               amd_pstate_update_min_max_limit(policy);
+       cap_perf = READ_ONCE(cpudata->highest_perf);
+-      min_perf = READ_ONCE(cpudata->lowest_perf);
+-      max_perf = cap_perf;
+       freqs.old = policy->cur;
+       freqs.new = target_freq;
+@@ -642,8 +640,9 @@ static int amd_pstate_update_freq(struct cpufreq_policy *policy,
+       if (!fast_switch)
+               cpufreq_freq_transition_begin(policy, &freqs);
+-      amd_pstate_update(cpudata, min_perf, des_perf,
+-                      max_perf, fast_switch, policy->governor->flags);
++      amd_pstate_update(cpudata, cpudata->min_limit_perf, des_perf,
++                        cpudata->max_limit_perf, fast_switch,
++                        policy->governor->flags);
+       if (!fast_switch)
+               cpufreq_freq_transition_end(policy, &freqs, false);
+-- 
+2.39.5
+
diff --git a/queue-6.14/cpufreq-governor-fix-negative-idle_time-handling-in-.patch b/queue-6.14/cpufreq-governor-fix-negative-idle_time-handling-in-.patch
new file mode 100644 (file)
index 0000000..b10ce2d
--- /dev/null
@@ -0,0 +1,116 @@
+From b45ed5fa4606caacc9cba89ec6f012c53dc493ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Feb 2025 11:55:10 +0800
+Subject: cpufreq: governor: Fix negative 'idle_time' handling in dbs_update()
+
+From: Jie Zhan <zhanjie9@hisilicon.com>
+
+[ Upstream commit 3698dd6b139dc37b35a9ad83d9330c1f99666c02 ]
+
+We observed an issue that the CPU frequency can't raise up with a 100% CPU
+load when NOHZ is off and the 'conservative' governor is selected.
+
+'idle_time' can be negative if it's obtained from get_cpu_idle_time_jiffy()
+when NOHZ is off.  This was found and explained in commit 9485e4ca0b48
+("cpufreq: governor: Fix handling of special cases in dbs_update()").
+
+However, commit 7592019634f8 ("cpufreq: governors: Fix long idle detection
+logic in load calculation") introduced a comparison between 'idle_time' and
+'samling_rate' to detect a long idle interval.  While 'idle_time' is
+converted to int before comparison, it's actually promoted to unsigned
+again when compared with an unsigned 'sampling_rate'.  Hence, this leads to
+wrong idle interval detection when it's in fact 100% busy and sets
+policy_dbs->idle_periods to a very large value.  'conservative' adjusts the
+frequency to minimum because of the large 'idle_periods', such that the
+frequency can't raise up.  'Ondemand' doesn't use policy_dbs->idle_periods
+so it fortunately avoids the issue.
+
+Correct negative 'idle_time' to 0 before any use of it in dbs_update().
+
+Fixes: 7592019634f8 ("cpufreq: governors: Fix long idle detection logic in load calculation")
+Signed-off-by: Jie Zhan <zhanjie9@hisilicon.com>
+Reviewed-by: Chen Yu <yu.c.chen@intel.com>
+Link: https://patch.msgid.link/20250213035510.2402076-1-zhanjie9@hisilicon.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/cpufreq_governor.c | 45 +++++++++++++++---------------
+ 1 file changed, 23 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c
+index af44ee6a64304..1a7fcaf39cc9b 100644
+--- a/drivers/cpufreq/cpufreq_governor.c
++++ b/drivers/cpufreq/cpufreq_governor.c
+@@ -145,7 +145,23 @@ unsigned int dbs_update(struct cpufreq_policy *policy)
+               time_elapsed = update_time - j_cdbs->prev_update_time;
+               j_cdbs->prev_update_time = update_time;
+-              idle_time = cur_idle_time - j_cdbs->prev_cpu_idle;
++              /*
++               * cur_idle_time could be smaller than j_cdbs->prev_cpu_idle if
++               * it's obtained from get_cpu_idle_time_jiffy() when NOHZ is
++               * off, where idle_time is calculated by the difference between
++               * time elapsed in jiffies and "busy time" obtained from CPU
++               * statistics.  If a CPU is 100% busy, the time elapsed and busy
++               * time should grow with the same amount in two consecutive
++               * samples, but in practice there could be a tiny difference,
++               * making the accumulated idle time decrease sometimes.  Hence,
++               * in this case, idle_time should be regarded as 0 in order to
++               * make the further process correct.
++               */
++              if (cur_idle_time > j_cdbs->prev_cpu_idle)
++                      idle_time = cur_idle_time - j_cdbs->prev_cpu_idle;
++              else
++                      idle_time = 0;
++
+               j_cdbs->prev_cpu_idle = cur_idle_time;
+               if (ignore_nice) {
+@@ -162,7 +178,7 @@ unsigned int dbs_update(struct cpufreq_policy *policy)
+                        * calls, so the previous load value can be used then.
+                        */
+                       load = j_cdbs->prev_load;
+-              } else if (unlikely((int)idle_time > 2 * sampling_rate &&
++              } else if (unlikely(idle_time > 2 * sampling_rate &&
+                                   j_cdbs->prev_load)) {
+                       /*
+                        * If the CPU had gone completely idle and a task has
+@@ -189,30 +205,15 @@ unsigned int dbs_update(struct cpufreq_policy *policy)
+                       load = j_cdbs->prev_load;
+                       j_cdbs->prev_load = 0;
+               } else {
+-                      if (time_elapsed >= idle_time) {
++                      if (time_elapsed > idle_time)
+                               load = 100 * (time_elapsed - idle_time) / time_elapsed;
+-                      } else {
+-                              /*
+-                               * That can happen if idle_time is returned by
+-                               * get_cpu_idle_time_jiffy().  In that case
+-                               * idle_time is roughly equal to the difference
+-                               * between time_elapsed and "busy time" obtained
+-                               * from CPU statistics.  Then, the "busy time"
+-                               * can end up being greater than time_elapsed
+-                               * (for example, if jiffies_64 and the CPU
+-                               * statistics are updated by different CPUs),
+-                               * so idle_time may in fact be negative.  That
+-                               * means, though, that the CPU was busy all
+-                               * the time (on the rough average) during the
+-                               * last sampling interval and 100 can be
+-                               * returned as the load.
+-                               */
+-                              load = (int)idle_time < 0 ? 100 : 0;
+-                      }
++                      else
++                              load = 0;
++
+                       j_cdbs->prev_load = load;
+               }
+-              if (unlikely((int)idle_time > 2 * sampling_rate)) {
++              if (unlikely(idle_time > 2 * sampling_rate)) {
+                       unsigned int periods = idle_time / sampling_rate;
+                       if (periods < idle_periods)
+-- 
+2.39.5
+
diff --git a/queue-6.14/cpufreq-init-cpufreq-only-for-present-cpus.patch b/queue-6.14/cpufreq-init-cpufreq-only-for-present-cpus.patch
new file mode 100644 (file)
index 0000000..c44f082
--- /dev/null
@@ -0,0 +1,232 @@
+From 83d0908a96219c736e4d7b21c92ceb66ca634f2f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Mar 2025 09:39:28 +0800
+Subject: cpufreq: Init cpufreq only for present CPUs
+
+From: Jacky Bai <ping.bai@nxp.com>
+
+[ Upstream commit 45f589b7167f36290d29c79e3a442dc0b13c086a ]
+
+for_each_possible_cpu() is currently used to initialize cpufreq.
+However, in cpu_dev_register_generic(), for_each_present_cpu()
+is used to register CPU devices which means the CPU devices are
+only registered for present CPUs and not all possible CPUs.
+
+With nosmp or maxcpus=0, only the boot CPU is present, lead
+to the cpufreq probe failure or defer probe due to no cpu device
+available for not present CPUs.
+
+Change for_each_possible_cpu() to for_each_present_cpu() in the
+above cpufreq drivers to ensure it only registers cpufreq for
+CPUs that are actually present.
+
+Fixes: b0c69e1214bc ("drivers: base: Use present CPUs in GENERIC_CPU_DEVICES")
+Reviewed-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Jacky Bai <ping.bai@nxp.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/armada-8k-cpufreq.c    | 2 +-
+ drivers/cpufreq/cpufreq-dt.c           | 2 +-
+ drivers/cpufreq/mediatek-cpufreq-hw.c  | 2 +-
+ drivers/cpufreq/mediatek-cpufreq.c     | 2 +-
+ drivers/cpufreq/mvebu-cpufreq.c        | 2 +-
+ drivers/cpufreq/qcom-cpufreq-hw.c      | 2 +-
+ drivers/cpufreq/qcom-cpufreq-nvmem.c   | 8 ++++----
+ drivers/cpufreq/scmi-cpufreq.c         | 2 +-
+ drivers/cpufreq/scpi-cpufreq.c         | 2 +-
+ drivers/cpufreq/sun50i-cpufreq-nvmem.c | 6 +++---
+ drivers/cpufreq/virtual-cpufreq.c      | 2 +-
+ 11 files changed, 16 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/cpufreq/armada-8k-cpufreq.c b/drivers/cpufreq/armada-8k-cpufreq.c
+index 7a979db81f098..5a3545bd0d8d2 100644
+--- a/drivers/cpufreq/armada-8k-cpufreq.c
++++ b/drivers/cpufreq/armada-8k-cpufreq.c
+@@ -47,7 +47,7 @@ static void __init armada_8k_get_sharing_cpus(struct clk *cur_clk,
+ {
+       int cpu;
+-      for_each_possible_cpu(cpu) {
++      for_each_present_cpu(cpu) {
+               struct device *cpu_dev;
+               struct clk *clk;
+diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c
+index 3a7c3372bda75..f3913eea5e553 100644
+--- a/drivers/cpufreq/cpufreq-dt.c
++++ b/drivers/cpufreq/cpufreq-dt.c
+@@ -303,7 +303,7 @@ static int dt_cpufreq_probe(struct platform_device *pdev)
+       int ret, cpu;
+       /* Request resources early so we can return in case of -EPROBE_DEFER */
+-      for_each_possible_cpu(cpu) {
++      for_each_present_cpu(cpu) {
+               ret = dt_cpufreq_early_init(&pdev->dev, cpu);
+               if (ret)
+                       goto err;
+diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c b/drivers/cpufreq/mediatek-cpufreq-hw.c
+index 9252ebd60373f..478257523cc3c 100644
+--- a/drivers/cpufreq/mediatek-cpufreq-hw.c
++++ b/drivers/cpufreq/mediatek-cpufreq-hw.c
+@@ -304,7 +304,7 @@ static int mtk_cpufreq_hw_driver_probe(struct platform_device *pdev)
+       struct regulator *cpu_reg;
+       /* Make sure that all CPU supplies are available before proceeding. */
+-      for_each_possible_cpu(cpu) {
++      for_each_present_cpu(cpu) {
+               cpu_dev = get_cpu_device(cpu);
+               if (!cpu_dev)
+                       return dev_err_probe(&pdev->dev, -EPROBE_DEFER,
+diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c
+index 663f61565cf72..2e4f9ca0af350 100644
+--- a/drivers/cpufreq/mediatek-cpufreq.c
++++ b/drivers/cpufreq/mediatek-cpufreq.c
+@@ -632,7 +632,7 @@ static int mtk_cpufreq_probe(struct platform_device *pdev)
+               return dev_err_probe(&pdev->dev, -ENODEV,
+                                    "failed to get mtk cpufreq platform data\n");
+-      for_each_possible_cpu(cpu) {
++      for_each_present_cpu(cpu) {
+               info = mtk_cpu_dvfs_info_lookup(cpu);
+               if (info)
+                       continue;
+diff --git a/drivers/cpufreq/mvebu-cpufreq.c b/drivers/cpufreq/mvebu-cpufreq.c
+index 7f3cfe668f307..2aad4c04673cc 100644
+--- a/drivers/cpufreq/mvebu-cpufreq.c
++++ b/drivers/cpufreq/mvebu-cpufreq.c
+@@ -56,7 +56,7 @@ static int __init armada_xp_pmsu_cpufreq_init(void)
+        * it), and registers the clock notifier that will take care
+        * of doing the PMSU part of a frequency transition.
+        */
+-      for_each_possible_cpu(cpu) {
++      for_each_present_cpu(cpu) {
+               struct device *cpu_dev;
+               struct clk *clk;
+               int ret;
+diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c
+index b2e7e89feaac4..dce7cad1813fb 100644
+--- a/drivers/cpufreq/qcom-cpufreq-hw.c
++++ b/drivers/cpufreq/qcom-cpufreq-hw.c
+@@ -306,7 +306,7 @@ static void qcom_get_related_cpus(int index, struct cpumask *m)
+       struct of_phandle_args args;
+       int cpu, ret;
+-      for_each_possible_cpu(cpu) {
++      for_each_present_cpu(cpu) {
+               cpu_np = of_cpu_device_node_get(cpu);
+               if (!cpu_np)
+                       continue;
+diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c
+index 3a8ed723a23e5..54f8117103c85 100644
+--- a/drivers/cpufreq/qcom-cpufreq-nvmem.c
++++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c
+@@ -489,7 +489,7 @@ static int qcom_cpufreq_probe(struct platform_device *pdev)
+               nvmem_cell_put(speedbin_nvmem);
+       }
+-      for_each_possible_cpu(cpu) {
++      for_each_present_cpu(cpu) {
+               struct dev_pm_opp_config config = {
+                       .supported_hw = NULL,
+               };
+@@ -543,7 +543,7 @@ static int qcom_cpufreq_probe(struct platform_device *pdev)
+       dev_err(cpu_dev, "Failed to register platform device\n");
+ free_opp:
+-      for_each_possible_cpu(cpu) {
++      for_each_present_cpu(cpu) {
+               dev_pm_domain_detach_list(drv->cpus[cpu].pd_list);
+               dev_pm_opp_clear_config(drv->cpus[cpu].opp_token);
+       }
+@@ -557,7 +557,7 @@ static void qcom_cpufreq_remove(struct platform_device *pdev)
+       platform_device_unregister(cpufreq_dt_pdev);
+-      for_each_possible_cpu(cpu) {
++      for_each_present_cpu(cpu) {
+               dev_pm_domain_detach_list(drv->cpus[cpu].pd_list);
+               dev_pm_opp_clear_config(drv->cpus[cpu].opp_token);
+       }
+@@ -568,7 +568,7 @@ static int qcom_cpufreq_suspend(struct device *dev)
+       struct qcom_cpufreq_drv *drv = dev_get_drvdata(dev);
+       unsigned int cpu;
+-      for_each_possible_cpu(cpu)
++      for_each_present_cpu(cpu)
+               qcom_cpufreq_suspend_pd_devs(drv, cpu);
+       return 0;
+diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c
+index b8fe758aeb010..914bf2c940a03 100644
+--- a/drivers/cpufreq/scmi-cpufreq.c
++++ b/drivers/cpufreq/scmi-cpufreq.c
+@@ -104,7 +104,7 @@ scmi_get_sharing_cpus(struct device *cpu_dev, int domain,
+       int cpu, tdomain;
+       struct device *tcpu_dev;
+-      for_each_possible_cpu(cpu) {
++      for_each_present_cpu(cpu) {
+               if (cpu == cpu_dev->id)
+                       continue;
+diff --git a/drivers/cpufreq/scpi-cpufreq.c b/drivers/cpufreq/scpi-cpufreq.c
+index 9e09565e41c09..1f97b949763fa 100644
+--- a/drivers/cpufreq/scpi-cpufreq.c
++++ b/drivers/cpufreq/scpi-cpufreq.c
+@@ -65,7 +65,7 @@ scpi_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask)
+       if (domain < 0)
+               return domain;
+-      for_each_possible_cpu(cpu) {
++      for_each_present_cpu(cpu) {
+               if (cpu == cpu_dev->id)
+                       continue;
+diff --git a/drivers/cpufreq/sun50i-cpufreq-nvmem.c b/drivers/cpufreq/sun50i-cpufreq-nvmem.c
+index 17d6a149f580d..47d6840b34899 100644
+--- a/drivers/cpufreq/sun50i-cpufreq-nvmem.c
++++ b/drivers/cpufreq/sun50i-cpufreq-nvmem.c
+@@ -262,7 +262,7 @@ static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev)
+       snprintf(name, sizeof(name), "speed%d", speed);
+       config.prop_name = name;
+-      for_each_possible_cpu(cpu) {
++      for_each_present_cpu(cpu) {
+               struct device *cpu_dev = get_cpu_device(cpu);
+               if (!cpu_dev) {
+@@ -288,7 +288,7 @@ static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev)
+       pr_err("Failed to register platform device\n");
+ free_opp:
+-      for_each_possible_cpu(cpu)
++      for_each_present_cpu(cpu)
+               dev_pm_opp_clear_config(opp_tokens[cpu]);
+       kfree(opp_tokens);
+@@ -302,7 +302,7 @@ static void sun50i_cpufreq_nvmem_remove(struct platform_device *pdev)
+       platform_device_unregister(cpufreq_dt_pdev);
+-      for_each_possible_cpu(cpu)
++      for_each_present_cpu(cpu)
+               dev_pm_opp_clear_config(opp_tokens[cpu]);
+       kfree(opp_tokens);
+diff --git a/drivers/cpufreq/virtual-cpufreq.c b/drivers/cpufreq/virtual-cpufreq.c
+index a050b3a6737f0..272dc3c85106c 100644
+--- a/drivers/cpufreq/virtual-cpufreq.c
++++ b/drivers/cpufreq/virtual-cpufreq.c
+@@ -138,7 +138,7 @@ static int virt_cpufreq_get_sharing_cpus(struct cpufreq_policy *policy)
+       cur_perf_domain = readl_relaxed(base + policy->cpu *
+                                       PER_CPU_OFFSET + REG_PERF_DOMAIN_OFFSET);
+-      for_each_possible_cpu(cpu) {
++      for_each_present_cpu(cpu) {
+               cpu_dev = get_cpu_device(cpu);
+               if (!cpu_dev)
+                       continue;
+-- 
+2.39.5
+
diff --git a/queue-6.14/cpufreq-scpi-compare-khz-instead-of-hz.patch b/queue-6.14/cpufreq-scpi-compare-khz-instead-of-hz.patch
new file mode 100644 (file)
index 0000000..05786ea
--- /dev/null
@@ -0,0 +1,52 @@
+From 220e48d13faf15344257cc4884c63b5065075c4b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 25 Jan 2025 08:49:49 +0000
+Subject: cpufreq: scpi: compare kHz instead of Hz
+
+From: zuoqian <zuoqian113@gmail.com>
+
+[ Upstream commit 4742da9774a416908ef8e3916164192c15c0e2d1 ]
+
+The CPU rate from clk_get_rate() may not be divisible by 1000
+(e.g., 133333333). But the rate calculated from frequency(kHz) is
+always divisible by 1000 (e.g., 133333000).
+Comparing the rate causes a warning during CPU scaling:
+"cpufreq: __target_index: Failed to change cpu frequency: -5".
+When we choose to compare kHz here, the issue does not occur.
+
+Fixes: 343a8d17fa8d ("cpufreq: scpi: remove arm_big_little dependency")
+Signed-off-by: zuoqian <zuoqian113@gmail.com>
+Reviewed-by: Dan Carpenter <dan.carpenter@linaro.org>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/scpi-cpufreq.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/cpufreq/scpi-cpufreq.c b/drivers/cpufreq/scpi-cpufreq.c
+index cd89c1b9832c0..9e09565e41c09 100644
+--- a/drivers/cpufreq/scpi-cpufreq.c
++++ b/drivers/cpufreq/scpi-cpufreq.c
+@@ -39,8 +39,9 @@ static unsigned int scpi_cpufreq_get_rate(unsigned int cpu)
+ static int
+ scpi_cpufreq_set_target(struct cpufreq_policy *policy, unsigned int index)
+ {
+-      u64 rate = policy->freq_table[index].frequency * 1000;
++      unsigned long freq_khz = policy->freq_table[index].frequency;
+       struct scpi_data *priv = policy->driver_data;
++      unsigned long rate = freq_khz * 1000;
+       int ret;
+       ret = clk_set_rate(priv->clk, rate);
+@@ -48,7 +49,7 @@ scpi_cpufreq_set_target(struct cpufreq_policy *policy, unsigned int index)
+       if (ret)
+               return ret;
+-      if (clk_get_rate(priv->clk) != rate)
++      if (clk_get_rate(priv->clk) / 1000 != freq_khz)
+               return -EIO;
+       return 0;
+-- 
+2.39.5
+
diff --git a/queue-6.14/cpufreq-tegra194-allow-building-for-tegra234.patch b/queue-6.14/cpufreq-tegra194-allow-building-for-tegra234.patch
new file mode 100644 (file)
index 0000000..8882a83
--- /dev/null
@@ -0,0 +1,36 @@
+From 3fce387a379f6230cba40486eac97b4c9c916a4a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Feb 2025 12:51:59 -0600
+Subject: cpufreq: tegra194: Allow building for Tegra234
+
+From: Aaron Kling <webgeek1234@gmail.com>
+
+[ Upstream commit 4a1e3bf61fc78ad100018adb573355303915dca3 ]
+
+Support was added for Tegra234 in the referenced commit, but the Kconfig
+was not updated to allow building for the arch.
+
+Fixes: 273bc890a2a8 ("cpufreq: tegra194: Add support for Tegra234")
+Signed-off-by: Aaron Kling <webgeek1234@gmail.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/Kconfig.arm | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
+index 9e46960f6a862..4f9cb943d945c 100644
+--- a/drivers/cpufreq/Kconfig.arm
++++ b/drivers/cpufreq/Kconfig.arm
+@@ -254,7 +254,7 @@ config ARM_TEGRA186_CPUFREQ
+ config ARM_TEGRA194_CPUFREQ
+       tristate "Tegra194 CPUFreq support"
+-      depends on ARCH_TEGRA_194_SOC || (64BIT && COMPILE_TEST)
++      depends on ARCH_TEGRA_194_SOC || ARCH_TEGRA_234_SOC || (64BIT && COMPILE_TEST)
+       depends on TEGRA_BPMP
+       default y
+       help
+-- 
+2.39.5
+
diff --git a/queue-6.14/cpuidle-init-cpuidle-only-for-present-cpus.patch b/queue-6.14/cpuidle-init-cpuidle-only-for-present-cpus.patch
new file mode 100644 (file)
index 0000000..bce83c2
--- /dev/null
@@ -0,0 +1,141 @@
+From f0cfd877edb54e0afbdfb87ff8e2697c14a83e23 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Mar 2025 22:55:47 +0800
+Subject: cpuidle: Init cpuidle only for present CPUs
+
+From: Jacky Bai <ping.bai@nxp.com>
+
+[ Upstream commit 68cb0139fec8e05b93978dc0ef1bc8df90a86419 ]
+
+for_each_possible_cpu() is currently used to initialize cpuidle
+in below cpuidle drivers:
+  drivers/cpuidle/cpuidle-arm.c
+  drivers/cpuidle/cpuidle-big_little.c
+  drivers/cpuidle/cpuidle-psci.c
+  drivers/cpuidle/cpuidle-qcom-spm.c
+  drivers/cpuidle/cpuidle-riscv-sbi.c
+
+However, in cpu_dev_register_generic(), for_each_present_cpu()
+is used to register CPU devices which means the CPU devices are
+only registered for present CPUs and not all possible CPUs.
+
+With nosmp or maxcpus=0, only the boot CPU is present, lead
+to the failure:
+
+  |  Failed to register cpuidle device for cpu1
+
+Then rollback to cancel all CPUs' cpuidle registration.
+
+Change for_each_possible_cpu() to for_each_present_cpu() in the
+above cpuidle drivers to ensure it only registers cpuidle devices
+for CPUs that are actually present.
+
+Fixes: b0c69e1214bc ("drivers: base: Use present CPUs in GENERIC_CPU_DEVICES")
+Reviewed-by: Dhruva Gole <d-gole@ti.com>
+Reviewed-by: Sudeep Holla <sudeep.holla@arm.com>
+Tested-by: Yuanjie Yang <quic_yuanjiey@quicinc.com>
+Signed-off-by: Jacky Bai <ping.bai@nxp.com>
+Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
+Link: https://patch.msgid.link/20250307145547.2784821-1-ping.bai@nxp.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpuidle/cpuidle-arm.c        | 8 ++++----
+ drivers/cpuidle/cpuidle-big_little.c | 2 +-
+ drivers/cpuidle/cpuidle-psci.c       | 4 ++--
+ drivers/cpuidle/cpuidle-qcom-spm.c   | 2 +-
+ drivers/cpuidle/cpuidle-riscv-sbi.c  | 4 ++--
+ 5 files changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c
+index caba6f4bb1b79..e044fefdb8167 100644
+--- a/drivers/cpuidle/cpuidle-arm.c
++++ b/drivers/cpuidle/cpuidle-arm.c
+@@ -137,9 +137,9 @@ static int __init arm_idle_init_cpu(int cpu)
+ /*
+  * arm_idle_init - Initializes arm cpuidle driver
+  *
+- * Initializes arm cpuidle driver for all CPUs, if any CPU fails
+- * to register cpuidle driver then rollback to cancel all CPUs
+- * registration.
++ * Initializes arm cpuidle driver for all present CPUs, if any
++ * CPU fails to register cpuidle driver then rollback to cancel
++ * all CPUs registration.
+  */
+ static int __init arm_idle_init(void)
+ {
+@@ -147,7 +147,7 @@ static int __init arm_idle_init(void)
+       struct cpuidle_driver *drv;
+       struct cpuidle_device *dev;
+-      for_each_possible_cpu(cpu) {
++      for_each_present_cpu(cpu) {
+               ret = arm_idle_init_cpu(cpu);
+               if (ret)
+                       goto out_fail;
+diff --git a/drivers/cpuidle/cpuidle-big_little.c b/drivers/cpuidle/cpuidle-big_little.c
+index 74972deda0ead..4abba42fcc311 100644
+--- a/drivers/cpuidle/cpuidle-big_little.c
++++ b/drivers/cpuidle/cpuidle-big_little.c
+@@ -148,7 +148,7 @@ static int __init bl_idle_driver_init(struct cpuidle_driver *drv, int part_id)
+       if (!cpumask)
+               return -ENOMEM;
+-      for_each_possible_cpu(cpu)
++      for_each_present_cpu(cpu)
+               if (smp_cpuid_part(cpu) == part_id)
+                       cpumask_set_cpu(cpu, cpumask);
+diff --git a/drivers/cpuidle/cpuidle-psci.c b/drivers/cpuidle/cpuidle-psci.c
+index 2562dc001fc1d..a4594c3d6562d 100644
+--- a/drivers/cpuidle/cpuidle-psci.c
++++ b/drivers/cpuidle/cpuidle-psci.c
+@@ -400,7 +400,7 @@ static int psci_idle_init_cpu(struct device *dev, int cpu)
+ /*
+  * psci_idle_probe - Initializes PSCI cpuidle driver
+  *
+- * Initializes PSCI cpuidle driver for all CPUs, if any CPU fails
++ * Initializes PSCI cpuidle driver for all present CPUs, if any CPU fails
+  * to register cpuidle driver then rollback to cancel all CPUs
+  * registration.
+  */
+@@ -410,7 +410,7 @@ static int psci_cpuidle_probe(struct platform_device *pdev)
+       struct cpuidle_driver *drv;
+       struct cpuidle_device *dev;
+-      for_each_possible_cpu(cpu) {
++      for_each_present_cpu(cpu) {
+               ret = psci_idle_init_cpu(&pdev->dev, cpu);
+               if (ret)
+                       goto out_fail;
+diff --git a/drivers/cpuidle/cpuidle-qcom-spm.c b/drivers/cpuidle/cpuidle-qcom-spm.c
+index 3ab240e0e1229..5f386761b1562 100644
+--- a/drivers/cpuidle/cpuidle-qcom-spm.c
++++ b/drivers/cpuidle/cpuidle-qcom-spm.c
+@@ -135,7 +135,7 @@ static int spm_cpuidle_drv_probe(struct platform_device *pdev)
+       if (ret)
+               return dev_err_probe(&pdev->dev, ret, "set warm boot addr failed");
+-      for_each_possible_cpu(cpu) {
++      for_each_present_cpu(cpu) {
+               ret = spm_cpuidle_register(&pdev->dev, cpu);
+               if (ret && ret != -ENODEV) {
+                       dev_err(&pdev->dev,
+diff --git a/drivers/cpuidle/cpuidle-riscv-sbi.c b/drivers/cpuidle/cpuidle-riscv-sbi.c
+index 0c92a628bbd40..0fe1ece9fbdca 100644
+--- a/drivers/cpuidle/cpuidle-riscv-sbi.c
++++ b/drivers/cpuidle/cpuidle-riscv-sbi.c
+@@ -529,8 +529,8 @@ static int sbi_cpuidle_probe(struct platform_device *pdev)
+                       return ret;
+       }
+-      /* Initialize CPU idle driver for each CPU */
+-      for_each_possible_cpu(cpu) {
++      /* Initialize CPU idle driver for each present CPU */
++      for_each_present_cpu(cpu) {
+               ret = sbi_cpuidle_init_cpu(&pdev->dev, cpu);
+               if (ret) {
+                       pr_debug("HART%ld: idle driver init failed\n",
+-- 
+2.39.5
+
diff --git a/queue-6.14/crypto-api-call-crypto_alg_put-in-crypto_unregister_.patch b/queue-6.14/crypto-api-call-crypto_alg_put-in-crypto_unregister_.patch
new file mode 100644 (file)
index 0000000..871d642
--- /dev/null
@@ -0,0 +1,37 @@
+From db969228e5fd9eca992281a76f1089d9c9cba85e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 16 Mar 2025 17:50:24 +0800
+Subject: crypto: api - Call crypto_alg_put in crypto_unregister_alg
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+[ Upstream commit 27b13425349e94ad77b174b032674097cab241c8 ]
+
+Instead of calling cra_destroy by hand, call it through
+crypto_alg_put so that the correct unwinding functions are called
+through crypto_destroy_alg.
+
+Fixes: 3d6979bf3bd5 ("crypto: api - Add cra_type->destroy hook")
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ crypto/algapi.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/crypto/algapi.c b/crypto/algapi.c
+index 5318c214debb0..6120329eadada 100644
+--- a/crypto/algapi.c
++++ b/crypto/algapi.c
+@@ -464,8 +464,7 @@ void crypto_unregister_alg(struct crypto_alg *alg)
+       if (WARN_ON(refcount_read(&alg->cra_refcnt) != 1))
+               return;
+-      if (alg->cra_destroy)
+-              alg->cra_destroy(alg);
++      crypto_alg_put(alg);
+       crypto_remove_final(&list);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/crypto-api-fix-larval-relookup-type-and-mask.patch b/queue-6.14/crypto-api-fix-larval-relookup-type-and-mask.patch
new file mode 100644 (file)
index 0000000..fe1196e
--- /dev/null
@@ -0,0 +1,93 @@
+From 6da9a9702aac6a15e66cb72dfcec6338346f7167 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Feb 2025 10:31:25 +0800
+Subject: crypto: api - Fix larval relookup type and mask
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+[ Upstream commit 7505436e2925d89a13706a295a6734d6cabb4b43 ]
+
+When the lookup is retried after instance construction, it uses
+the type and mask from the larval, which may not match the values
+used by the caller.  For example, if the caller is requesting for
+a !NEEDS_FALLBACK algorithm, it may end up getting an algorithm
+that needs fallbacks.
+
+Fix this by making the caller supply the type/mask and using that
+for the lookup.
+
+Reported-by: Coiby Xu <coxu@redhat.com>
+Fixes: 96ad59552059 ("crypto: api - Remove instance larval fulfilment")
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ crypto/api.c | 17 +++++++----------
+ 1 file changed, 7 insertions(+), 10 deletions(-)
+
+diff --git a/crypto/api.c b/crypto/api.c
+index bfd177a4313a0..c2c4eb14ef955 100644
+--- a/crypto/api.c
++++ b/crypto/api.c
+@@ -36,7 +36,8 @@ EXPORT_SYMBOL_GPL(crypto_chain);
+ DEFINE_STATIC_KEY_FALSE(__crypto_boot_test_finished);
+ #endif
+-static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg);
++static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg,
++                                           u32 type, u32 mask);
+ static struct crypto_alg *crypto_alg_lookup(const char *name, u32 type,
+                                           u32 mask);
+@@ -145,7 +146,7 @@ static struct crypto_alg *crypto_larval_add(const char *name, u32 type,
+       if (alg != &larval->alg) {
+               kfree(larval);
+               if (crypto_is_larval(alg))
+-                      alg = crypto_larval_wait(alg);
++                      alg = crypto_larval_wait(alg, type, mask);
+       }
+       return alg;
+@@ -197,7 +198,8 @@ static void crypto_start_test(struct crypto_larval *larval)
+       crypto_schedule_test(larval);
+ }
+-static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg)
++static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg,
++                                           u32 type, u32 mask)
+ {
+       struct crypto_larval *larval;
+       long time_left;
+@@ -219,12 +221,7 @@ static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg)
+                       crypto_larval_kill(larval);
+               alg = ERR_PTR(-ETIMEDOUT);
+       } else if (!alg) {
+-              u32 type;
+-              u32 mask;
+-
+               alg = &larval->alg;
+-              type = alg->cra_flags & ~(CRYPTO_ALG_LARVAL | CRYPTO_ALG_DEAD);
+-              mask = larval->mask;
+               alg = crypto_alg_lookup(alg->cra_name, type, mask) ?:
+                     ERR_PTR(-EAGAIN);
+       } else if (IS_ERR(alg))
+@@ -304,7 +301,7 @@ static struct crypto_alg *crypto_larval_lookup(const char *name, u32 type,
+       }
+       if (!IS_ERR_OR_NULL(alg) && crypto_is_larval(alg))
+-              alg = crypto_larval_wait(alg);
++              alg = crypto_larval_wait(alg, type, mask);
+       else if (alg)
+               ;
+       else if (!(mask & CRYPTO_ALG_TESTED))
+@@ -352,7 +349,7 @@ struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask)
+       ok = crypto_probing_notify(CRYPTO_MSG_ALG_REQUEST, larval);
+       if (ok == NOTIFY_STOP)
+-              alg = crypto_larval_wait(larval);
++              alg = crypto_larval_wait(larval, type, mask);
+       else {
+               crypto_mod_put(larval);
+               alg = ERR_PTR(-ENOENT);
+-- 
+2.39.5
+
diff --git a/queue-6.14/crypto-bpf-add-module_description-for-skcipher.patch b/queue-6.14/crypto-bpf-add-module_description-for-skcipher.patch
new file mode 100644 (file)
index 0000000..8ae8854
--- /dev/null
@@ -0,0 +1,37 @@
+From a30fec32841b19165be7cae0ad4dddebd6bc69c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 13:55:55 +0100
+Subject: crypto: bpf - Add MODULE_DESCRIPTION for skcipher
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit f307c87ea06c64b87fcd3221a682cd713cde51e9 ]
+
+All modules should have a description, building with extra warnings
+enabled prints this outfor the for bpf_crypto_skcipher module:
+
+WARNING: modpost: missing MODULE_DESCRIPTION() in crypto/bpf_crypto_skcipher.o
+
+Add a description line.
+
+Fixes: fda4f71282b2 ("bpf: crypto: add skcipher to bpf crypto")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ crypto/bpf_crypto_skcipher.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/crypto/bpf_crypto_skcipher.c b/crypto/bpf_crypto_skcipher.c
+index b5e657415770a..a88798d3e8c87 100644
+--- a/crypto/bpf_crypto_skcipher.c
++++ b/crypto/bpf_crypto_skcipher.c
+@@ -80,3 +80,4 @@ static void __exit bpf_crypto_skcipher_exit(void)
+ module_init(bpf_crypto_skcipher_init);
+ module_exit(bpf_crypto_skcipher_exit);
+ MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("Symmetric key cipher support for BPF");
+-- 
+2.39.5
+
diff --git a/queue-6.14/crypto-hisilicon-sec2-fix-for-aead-auth-key-length.patch b/queue-6.14/crypto-hisilicon-sec2-fix-for-aead-auth-key-length.patch
new file mode 100644 (file)
index 0000000..8775a1e
--- /dev/null
@@ -0,0 +1,52 @@
+From 6f739a3f70742e024a70e197a291fe5b5612cac3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Feb 2025 11:56:26 +0800
+Subject: crypto: hisilicon/sec2 - fix for aead auth key length
+
+From: Wenkai Lin <linwenkai6@hisilicon.com>
+
+[ Upstream commit 1b284ffc30b02808a0de698667cbcf5ce5f9144e ]
+
+According to the HMAC RFC, the authentication key
+can be 0 bytes, and the hardware can handle this
+scenario. Therefore, remove the incorrect validation
+for this case.
+
+Fixes: 2f072d75d1ab ("crypto: hisilicon - Add aead support on SEC2")
+Signed-off-by: Wenkai Lin <linwenkai6@hisilicon.com>
+Signed-off-by: Chenghai Huang <huangchenghai2@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/hisilicon/sec2/sec_crypto.c | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c
+index 82827d637492a..8ea5305bc320f 100644
+--- a/drivers/crypto/hisilicon/sec2/sec_crypto.c
++++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c
+@@ -1085,11 +1085,6 @@ static int sec_aead_auth_set_key(struct sec_auth_ctx *ctx,
+       struct crypto_shash *hash_tfm = ctx->hash_tfm;
+       int blocksize, digestsize, ret;
+-      if (!keys->authkeylen) {
+-              pr_err("hisi_sec2: aead auth key error!\n");
+-              return -EINVAL;
+-      }
+-
+       blocksize = crypto_shash_blocksize(hash_tfm);
+       digestsize = crypto_shash_digestsize(hash_tfm);
+       if (keys->authkeylen > blocksize) {
+@@ -1101,7 +1096,8 @@ static int sec_aead_auth_set_key(struct sec_auth_ctx *ctx,
+               }
+               ctx->a_key_len = digestsize;
+       } else {
+-              memcpy(ctx->a_key, keys->authkey, keys->authkeylen);
++              if (keys->authkeylen)
++                      memcpy(ctx->a_key, keys->authkey, keys->authkeylen);
+               ctx->a_key_len = keys->authkeylen;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/crypto-hisilicon-sec2-fix-for-aead-authsize-alignmen.patch b/queue-6.14/crypto-hisilicon-sec2-fix-for-aead-authsize-alignmen.patch
new file mode 100644 (file)
index 0000000..56b84fd
--- /dev/null
@@ -0,0 +1,106 @@
+From 2e57eacf8ceaadc541dc39c4aa5172f66829e06e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Feb 2025 11:56:27 +0800
+Subject: crypto: hisilicon/sec2 - fix for aead authsize alignment
+
+From: Wenkai Lin <linwenkai6@hisilicon.com>
+
+[ Upstream commit a49cc71e219040d771a8c1254879984f98192811 ]
+
+The hardware only supports authentication sizes
+that are 4-byte aligned. Therefore, the driver
+switches to software computation in this case.
+
+Fixes: 2f072d75d1ab ("crypto: hisilicon - Add aead support on SEC2")
+Signed-off-by: Wenkai Lin <linwenkai6@hisilicon.com>
+Signed-off-by: Chenghai Huang <huangchenghai2@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Stable-dep-of: f4f353cb7ae9 ("crypto: hisilicon/sec2 - fix for sec spec check")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/hisilicon/sec2/sec_crypto.c | 22 +++++++++-------------
+ 1 file changed, 9 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c
+index 66bc07da9eb6f..50223e3c4bccf 100644
+--- a/drivers/crypto/hisilicon/sec2/sec_crypto.c
++++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c
+@@ -57,7 +57,6 @@
+ #define SEC_TYPE_MASK         0x0F
+ #define SEC_DONE_MASK         0x0001
+ #define SEC_ICV_MASK          0x000E
+-#define SEC_SQE_LEN_RATE_MASK 0x3
+ #define SEC_TOTAL_IV_SZ(depth)        (SEC_IV_SIZE * (depth))
+ #define SEC_SGL_SGE_NR                128
+@@ -80,16 +79,16 @@
+ #define SEC_TOTAL_PBUF_SZ(depth)      (PAGE_SIZE * SEC_PBUF_PAGE_NUM(depth) + \
+                               SEC_PBUF_LEFT_SZ(depth))
+-#define SEC_SQE_LEN_RATE      4
+ #define SEC_SQE_CFLAG         2
+ #define SEC_SQE_AEAD_FLAG     3
+ #define SEC_SQE_DONE          0x1
+ #define SEC_ICV_ERR           0x2
+-#define MIN_MAC_LEN           4
+ #define MAC_LEN_MASK          0x1U
+ #define MAX_INPUT_DATA_LEN    0xFFFE00
+ #define BITS_MASK             0xFF
++#define WORD_MASK             0x3
+ #define BYTE_BITS             0x8
++#define BYTES_TO_WORDS(bcount)        ((bcount) >> 2)
+ #define SEC_XTS_NAME_SZ               0x3
+ #define IV_CM_CAL_NUM         2
+ #define IV_CL_MASK            0x7
+@@ -1175,7 +1174,7 @@ static int sec_aead_setkey(struct crypto_aead *tfm, const u8 *key,
+               goto bad_key;
+       }
+-      if (ctx->a_ctx.a_key_len & SEC_SQE_LEN_RATE_MASK) {
++      if (ctx->a_ctx.a_key_len & WORD_MASK) {
+               ret = -EINVAL;
+               dev_err(dev, "AUTH key length error!\n");
+               goto bad_key;
+@@ -1583,11 +1582,10 @@ static void sec_auth_bd_fill_ex(struct sec_auth_ctx *ctx, int dir,
+       sec_sqe->type2.a_key_addr = cpu_to_le64(ctx->a_key_dma);
+-      sec_sqe->type2.mac_key_alg = cpu_to_le32(authsize / SEC_SQE_LEN_RATE);
++      sec_sqe->type2.mac_key_alg = cpu_to_le32(BYTES_TO_WORDS(authsize));
+       sec_sqe->type2.mac_key_alg |=
+-                      cpu_to_le32((u32)((ctx->a_key_len) /
+-                      SEC_SQE_LEN_RATE) << SEC_AKEY_OFFSET);
++                      cpu_to_le32((u32)BYTES_TO_WORDS(ctx->a_key_len) << SEC_AKEY_OFFSET);
+       sec_sqe->type2.mac_key_alg |=
+                       cpu_to_le32((u32)(ctx->a_alg) << SEC_AEAD_ALG_OFFSET);
+@@ -1639,12 +1637,10 @@ static void sec_auth_bd_fill_ex_v3(struct sec_auth_ctx *ctx, int dir,
+       sqe3->a_key_addr = cpu_to_le64(ctx->a_key_dma);
+       sqe3->auth_mac_key |=
+-                      cpu_to_le32((u32)(authsize /
+-                      SEC_SQE_LEN_RATE) << SEC_MAC_OFFSET_V3);
++                      cpu_to_le32(BYTES_TO_WORDS(authsize) << SEC_MAC_OFFSET_V3);
+       sqe3->auth_mac_key |=
+-                      cpu_to_le32((u32)(ctx->a_key_len /
+-                      SEC_SQE_LEN_RATE) << SEC_AKEY_OFFSET_V3);
++                      cpu_to_le32((u32)BYTES_TO_WORDS(ctx->a_key_len) << SEC_AKEY_OFFSET_V3);
+       sqe3->auth_mac_key |=
+                       cpu_to_le32((u32)(ctx->a_alg) << SEC_AUTH_ALG_OFFSET_V3);
+@@ -2234,8 +2230,8 @@ static int sec_aead_spec_check(struct sec_ctx *ctx, struct sec_req *sreq)
+       struct device *dev = ctx->dev;
+       int ret;
+-      /* Hardware does not handle cases where authsize is less than 4 bytes */
+-      if (unlikely(sz < MIN_MAC_LEN)) {
++      /* Hardware does not handle cases where authsize is not 4 bytes aligned */
++      if (c_mode == SEC_CMODE_CBC && (sz & WORD_MASK)) {
+               sreq->aead_req.fallback = true;
+               return -EINVAL;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/crypto-hisilicon-sec2-fix-for-sec-spec-check.patch b/queue-6.14/crypto-hisilicon-sec2-fix-for-sec-spec-check.patch
new file mode 100644 (file)
index 0000000..5b2ead3
--- /dev/null
@@ -0,0 +1,277 @@
+From 05369364c8787ff08b6ee16a362d24b0c0e97a68 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Feb 2025 11:56:28 +0800
+Subject: crypto: hisilicon/sec2 - fix for sec spec check
+
+From: Wenkai Lin <linwenkai6@hisilicon.com>
+
+[ Upstream commit f4f353cb7ae9bb43e34943edb693532a39118eca ]
+
+During encryption and decryption, user requests
+must be checked first, if the specifications that
+are not supported by the hardware are used, the
+software computing is used for processing.
+
+Fixes: 2f072d75d1ab ("crypto: hisilicon - Add aead support on SEC2")
+Signed-off-by: Wenkai Lin <linwenkai6@hisilicon.com>
+Signed-off-by: Chenghai Huang <huangchenghai2@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/hisilicon/sec2/sec.h        |   1 -
+ drivers/crypto/hisilicon/sec2/sec_crypto.c | 101 ++++++++-------------
+ 2 files changed, 39 insertions(+), 63 deletions(-)
+
+diff --git a/drivers/crypto/hisilicon/sec2/sec.h b/drivers/crypto/hisilicon/sec2/sec.h
+index 4b99702308228..703920b49c7c0 100644
+--- a/drivers/crypto/hisilicon/sec2/sec.h
++++ b/drivers/crypto/hisilicon/sec2/sec.h
+@@ -37,7 +37,6 @@ struct sec_aead_req {
+       u8 *a_ivin;
+       dma_addr_t a_ivin_dma;
+       struct aead_request *aead_req;
+-      bool fallback;
+ };
+ /* SEC request of Crypto */
+diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c
+index 50223e3c4bccf..82827d637492a 100644
+--- a/drivers/crypto/hisilicon/sec2/sec_crypto.c
++++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c
+@@ -690,14 +690,10 @@ static int sec_skcipher_fbtfm_init(struct crypto_skcipher *tfm)
+       c_ctx->fallback = false;
+-      /* Currently, only XTS mode need fallback tfm when using 192bit key */
+-      if (likely(strncmp(alg, "xts", SEC_XTS_NAME_SZ)))
+-              return 0;
+-
+       c_ctx->fbtfm = crypto_alloc_sync_skcipher(alg, 0,
+                                                 CRYPTO_ALG_NEED_FALLBACK);
+       if (IS_ERR(c_ctx->fbtfm)) {
+-              pr_err("failed to alloc xts mode fallback tfm!\n");
++              pr_err("failed to alloc fallback tfm for %s!\n", alg);
+               return PTR_ERR(c_ctx->fbtfm);
+       }
+@@ -857,7 +853,7 @@ static int sec_skcipher_setkey(struct crypto_skcipher *tfm, const u8 *key,
+       }
+       memcpy(c_ctx->c_key, key, keylen);
+-      if (c_ctx->fallback && c_ctx->fbtfm) {
++      if (c_ctx->fbtfm) {
+               ret = crypto_sync_skcipher_setkey(c_ctx->fbtfm, key, keylen);
+               if (ret) {
+                       dev_err(dev, "failed to set fallback skcipher key!\n");
+@@ -1159,8 +1155,10 @@ static int sec_aead_setkey(struct crypto_aead *tfm, const u8 *key,
+       }
+       ret = crypto_authenc_extractkeys(&keys, key, keylen);
+-      if (ret)
++      if (ret) {
++              dev_err(dev, "sec extract aead keys err!\n");
+               goto bad_key;
++      }
+       ret = sec_aead_aes_set_key(c_ctx, &keys);
+       if (ret) {
+@@ -1174,12 +1172,6 @@ static int sec_aead_setkey(struct crypto_aead *tfm, const u8 *key,
+               goto bad_key;
+       }
+-      if (ctx->a_ctx.a_key_len & WORD_MASK) {
+-              ret = -EINVAL;
+-              dev_err(dev, "AUTH key length error!\n");
+-              goto bad_key;
+-      }
+-
+       ret = sec_aead_fallback_setkey(a_ctx, tfm, key, keylen);
+       if (ret) {
+               dev_err(dev, "set sec fallback key err!\n");
+@@ -1999,8 +1991,7 @@ static int sec_aead_sha512_ctx_init(struct crypto_aead *tfm)
+       return sec_aead_ctx_init(tfm, "sha512");
+ }
+-static int sec_skcipher_cryptlen_check(struct sec_ctx *ctx,
+-      struct sec_req *sreq)
++static int sec_skcipher_cryptlen_check(struct sec_ctx *ctx, struct sec_req *sreq)
+ {
+       u32 cryptlen = sreq->c_req.sk_req->cryptlen;
+       struct device *dev = ctx->dev;
+@@ -2022,10 +2013,6 @@ static int sec_skcipher_cryptlen_check(struct sec_ctx *ctx,
+               }
+               break;
+       case SEC_CMODE_CTR:
+-              if (unlikely(ctx->sec->qm.ver < QM_HW_V3)) {
+-                      dev_err(dev, "skcipher HW version error!\n");
+-                      ret = -EINVAL;
+-              }
+               break;
+       default:
+               ret = -EINVAL;
+@@ -2034,17 +2021,21 @@ static int sec_skcipher_cryptlen_check(struct sec_ctx *ctx,
+       return ret;
+ }
+-static int sec_skcipher_param_check(struct sec_ctx *ctx, struct sec_req *sreq)
++static int sec_skcipher_param_check(struct sec_ctx *ctx,
++                                  struct sec_req *sreq, bool *need_fallback)
+ {
+       struct skcipher_request *sk_req = sreq->c_req.sk_req;
+       struct device *dev = ctx->dev;
+       u8 c_alg = ctx->c_ctx.c_alg;
+-      if (unlikely(!sk_req->src || !sk_req->dst ||
+-                   sk_req->cryptlen > MAX_INPUT_DATA_LEN)) {
++      if (unlikely(!sk_req->src || !sk_req->dst)) {
+               dev_err(dev, "skcipher input param error!\n");
+               return -EINVAL;
+       }
++
++      if (sk_req->cryptlen > MAX_INPUT_DATA_LEN)
++              *need_fallback = true;
++
+       sreq->c_req.c_len = sk_req->cryptlen;
+       if (ctx->pbuf_supported && sk_req->cryptlen <= SEC_PBUF_SZ)
+@@ -2102,6 +2093,7 @@ static int sec_skcipher_crypto(struct skcipher_request *sk_req, bool encrypt)
+       struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(sk_req);
+       struct sec_req *req = skcipher_request_ctx(sk_req);
+       struct sec_ctx *ctx = crypto_skcipher_ctx(tfm);
++      bool need_fallback = false;
+       int ret;
+       if (!sk_req->cryptlen) {
+@@ -2115,11 +2107,11 @@ static int sec_skcipher_crypto(struct skcipher_request *sk_req, bool encrypt)
+       req->c_req.encrypt = encrypt;
+       req->ctx = ctx;
+-      ret = sec_skcipher_param_check(ctx, req);
++      ret = sec_skcipher_param_check(ctx, req, &need_fallback);
+       if (unlikely(ret))
+               return -EINVAL;
+-      if (unlikely(ctx->c_ctx.fallback))
++      if (unlikely(ctx->c_ctx.fallback || need_fallback))
+               return sec_skcipher_soft_crypto(ctx, sk_req, encrypt);
+       return ctx->req_op->process(ctx, req);
+@@ -2227,52 +2219,35 @@ static int sec_aead_spec_check(struct sec_ctx *ctx, struct sec_req *sreq)
+       struct crypto_aead *tfm = crypto_aead_reqtfm(req);
+       size_t sz = crypto_aead_authsize(tfm);
+       u8 c_mode = ctx->c_ctx.c_mode;
+-      struct device *dev = ctx->dev;
+       int ret;
+-      /* Hardware does not handle cases where authsize is not 4 bytes aligned */
+-      if (c_mode == SEC_CMODE_CBC && (sz & WORD_MASK)) {
+-              sreq->aead_req.fallback = true;
++      if (unlikely(ctx->sec->qm.ver == QM_HW_V2 && !sreq->c_req.c_len))
+               return -EINVAL;
+-      }
+       if (unlikely(req->cryptlen + req->assoclen > MAX_INPUT_DATA_LEN ||
+-          req->assoclen > SEC_MAX_AAD_LEN)) {
+-              dev_err(dev, "aead input spec error!\n");
++                   req->assoclen > SEC_MAX_AAD_LEN))
+               return -EINVAL;
+-      }
+       if (c_mode == SEC_CMODE_CCM) {
+-              if (unlikely(req->assoclen > SEC_MAX_CCM_AAD_LEN)) {
+-                      dev_err_ratelimited(dev, "CCM input aad parameter is too long!\n");
++              if (unlikely(req->assoclen > SEC_MAX_CCM_AAD_LEN))
+                       return -EINVAL;
+-              }
+-              ret = aead_iv_demension_check(req);
+-              if (ret) {
+-                      dev_err(dev, "aead input iv param error!\n");
+-                      return ret;
+-              }
+-      }
+-      if (sreq->c_req.encrypt)
+-              sreq->c_req.c_len = req->cryptlen;
+-      else
+-              sreq->c_req.c_len = req->cryptlen - sz;
+-      if (c_mode == SEC_CMODE_CBC) {
+-              if (unlikely(sreq->c_req.c_len & (AES_BLOCK_SIZE - 1))) {
+-                      dev_err(dev, "aead crypto length error!\n");
++              ret = aead_iv_demension_check(req);
++              if (unlikely(ret))
++                      return -EINVAL;
++      } else if (c_mode == SEC_CMODE_CBC) {
++              if (unlikely(sz & WORD_MASK))
++                      return -EINVAL;
++              if (unlikely(ctx->a_ctx.a_key_len & WORD_MASK))
+                       return -EINVAL;
+-              }
+       }
+       return 0;
+ }
+-static int sec_aead_param_check(struct sec_ctx *ctx, struct sec_req *sreq)
++static int sec_aead_param_check(struct sec_ctx *ctx, struct sec_req *sreq, bool *need_fallback)
+ {
+       struct aead_request *req = sreq->aead_req.aead_req;
+-      struct crypto_aead *tfm = crypto_aead_reqtfm(req);
+-      size_t authsize = crypto_aead_authsize(tfm);
+       struct device *dev = ctx->dev;
+       u8 c_alg = ctx->c_ctx.c_alg;
+@@ -2281,12 +2256,10 @@ static int sec_aead_param_check(struct sec_ctx *ctx, struct sec_req *sreq)
+               return -EINVAL;
+       }
+-      if (ctx->sec->qm.ver == QM_HW_V2) {
+-              if (unlikely(!req->cryptlen || (!sreq->c_req.encrypt &&
+-                           req->cryptlen <= authsize))) {
+-                      sreq->aead_req.fallback = true;
+-                      return -EINVAL;
+-              }
++      if (unlikely(ctx->c_ctx.c_mode == SEC_CMODE_CBC &&
++                   sreq->c_req.c_len & (AES_BLOCK_SIZE - 1))) {
++              dev_err(dev, "aead cbc mode input data length error!\n");
++              return -EINVAL;
+       }
+       /* Support AES or SM4 */
+@@ -2295,8 +2268,10 @@ static int sec_aead_param_check(struct sec_ctx *ctx, struct sec_req *sreq)
+               return -EINVAL;
+       }
+-      if (unlikely(sec_aead_spec_check(ctx, sreq)))
++      if (unlikely(sec_aead_spec_check(ctx, sreq))) {
++              *need_fallback = true;
+               return -EINVAL;
++      }
+       if (ctx->pbuf_supported && (req->cryptlen + req->assoclen) <=
+               SEC_PBUF_SZ)
+@@ -2340,17 +2315,19 @@ static int sec_aead_crypto(struct aead_request *a_req, bool encrypt)
+       struct crypto_aead *tfm = crypto_aead_reqtfm(a_req);
+       struct sec_req *req = aead_request_ctx(a_req);
+       struct sec_ctx *ctx = crypto_aead_ctx(tfm);
++      size_t sz = crypto_aead_authsize(tfm);
++      bool need_fallback = false;
+       int ret;
+       req->flag = a_req->base.flags;
+       req->aead_req.aead_req = a_req;
+       req->c_req.encrypt = encrypt;
+       req->ctx = ctx;
+-      req->aead_req.fallback = false;
++      req->c_req.c_len = a_req->cryptlen - (req->c_req.encrypt ? 0 : sz);
+-      ret = sec_aead_param_check(ctx, req);
++      ret = sec_aead_param_check(ctx, req, &need_fallback);
+       if (unlikely(ret)) {
+-              if (req->aead_req.fallback)
++              if (need_fallback)
+                       return sec_aead_soft_crypto(ctx, a_req, encrypt);
+               return -EINVAL;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/crypto-iaa-test-the-correct-request-flag.patch b/queue-6.14/crypto-iaa-test-the-correct-request-flag.patch
new file mode 100644 (file)
index 0000000..1d565cc
--- /dev/null
@@ -0,0 +1,43 @@
+From 3ec2c95901527e6516c5fd45c7e652dd145e43e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 18:14:55 +0800
+Subject: crypto: iaa - Test the correct request flag
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+[ Upstream commit fc4bd01d9ff592f620c499686245c093440db0e8 ]
+
+Test the correct flags for the MAY_SLEEP bit.
+
+Fixes: 2ec6761df889 ("crypto: iaa - Add support for deflate-iaa compression algorithm")
+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 | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/crypto/intel/iaa/iaa_crypto_main.c b/drivers/crypto/intel/iaa/iaa_crypto_main.c
+index c3776b0de51d7..990ea46955bbf 100644
+--- a/drivers/crypto/intel/iaa/iaa_crypto_main.c
++++ b/drivers/crypto/intel/iaa/iaa_crypto_main.c
+@@ -1537,7 +1537,7 @@ static int iaa_comp_acompress(struct acomp_req *req)
+       iaa_wq = idxd_wq_get_private(wq);
+       if (!req->dst) {
+-              gfp_t flags = req->flags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL : GFP_ATOMIC;
++              gfp_t flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL : GFP_ATOMIC;
+               /* incompressible data will always be < 2 * slen */
+               req->dlen = 2 * req->slen;
+@@ -1619,7 +1619,7 @@ static int iaa_comp_acompress(struct acomp_req *req)
+ static int iaa_comp_adecompress_alloc_dest(struct acomp_req *req)
+ {
+-      gfp_t flags = req->flags & CRYPTO_TFM_REQ_MAY_SLEEP ?
++      gfp_t flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ?
+               GFP_KERNEL : GFP_ATOMIC;
+       struct crypto_tfm *tfm = req->base.tfm;
+       dma_addr_t src_addr, dst_addr;
+-- 
+2.39.5
+
diff --git a/queue-6.14/crypto-nx-fix-uninitialised-hv_nxc-on-error.patch b/queue-6.14/crypto-nx-fix-uninitialised-hv_nxc-on-error.patch
new file mode 100644 (file)
index 0000000..3863e19
--- /dev/null
@@ -0,0 +1,95 @@
+From ebb4643ac31992713902d95c85ab00adbfd2158e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 15 Mar 2025 16:50:42 +0800
+Subject: crypto: nx - Fix uninitialised hv_nxc on error
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+[ Upstream commit 9b00eb923f3e60ca76cbc8b31123716f3a87ac6a ]
+
+The compiler correctly warns that hv_nxc may be used uninitialised
+as that will occur when NX-GZIP is unavailable.
+
+Fix it by rearranging the code and delay setting caps_feat until
+the final query succeeds.
+
+Fixes: b4ba22114c78 ("crypto/nx: Get NX capabilities for GZIP coprocessor type")
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/nx/nx-common-pseries.c | 37 ++++++++++++---------------
+ 1 file changed, 17 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/crypto/nx/nx-common-pseries.c b/drivers/crypto/nx/nx-common-pseries.c
+index 1660c5cf3641c..56129bdf53ab0 100644
+--- a/drivers/crypto/nx/nx-common-pseries.c
++++ b/drivers/crypto/nx/nx-common-pseries.c
+@@ -1145,6 +1145,7 @@ static void __init nxcop_get_capabilities(void)
+ {
+       struct hv_vas_all_caps *hv_caps;
+       struct hv_nx_cop_caps *hv_nxc;
++      u64 feat;
+       int rc;
+       hv_caps = kmalloc(sizeof(*hv_caps), GFP_KERNEL);
+@@ -1155,27 +1156,26 @@ static void __init nxcop_get_capabilities(void)
+        */
+       rc = h_query_vas_capabilities(H_QUERY_NX_CAPABILITIES, 0,
+                                         (u64)virt_to_phys(hv_caps));
++      if (!rc)
++              feat = be64_to_cpu(hv_caps->feat_type);
++      kfree(hv_caps);
+       if (rc)
+-              goto out;
++              return;
++      if (!(feat & VAS_NX_GZIP_FEAT_BIT))
++              return;
+-      caps_feat = be64_to_cpu(hv_caps->feat_type);
+       /*
+        * NX-GZIP feature available
+        */
+-      if (caps_feat & VAS_NX_GZIP_FEAT_BIT) {
+-              hv_nxc = kmalloc(sizeof(*hv_nxc), GFP_KERNEL);
+-              if (!hv_nxc)
+-                      goto out;
+-              /*
+-               * Get capabilities for NX-GZIP feature
+-               */
+-              rc = h_query_vas_capabilities(H_QUERY_NX_CAPABILITIES,
+-                                                VAS_NX_GZIP_FEAT,
+-                                                (u64)virt_to_phys(hv_nxc));
+-      } else {
+-              pr_err("NX-GZIP feature is not available\n");
+-              rc = -EINVAL;
+-      }
++      hv_nxc = kmalloc(sizeof(*hv_nxc), GFP_KERNEL);
++      if (!hv_nxc)
++              return;
++      /*
++       * Get capabilities for NX-GZIP feature
++       */
++      rc = h_query_vas_capabilities(H_QUERY_NX_CAPABILITIES,
++                                        VAS_NX_GZIP_FEAT,
++                                        (u64)virt_to_phys(hv_nxc));
+       if (!rc) {
+               nx_cop_caps.descriptor = be64_to_cpu(hv_nxc->descriptor);
+@@ -1185,13 +1185,10 @@ static void __init nxcop_get_capabilities(void)
+                               be64_to_cpu(hv_nxc->min_compress_len);
+               nx_cop_caps.min_decompress_len =
+                               be64_to_cpu(hv_nxc->min_decompress_len);
+-      } else {
+-              caps_feat = 0;
++              caps_feat = feat;
+       }
+       kfree(hv_nxc);
+-out:
+-      kfree(hv_caps);
+ }
+ static const struct vio_device_id nx842_vio_driver_ids[] = {
+-- 
+2.39.5
+
diff --git a/queue-6.14/crypto-powerpc-mark-ghashp8-ppc.o-as-an-object_files.patch b/queue-6.14/crypto-powerpc-mark-ghashp8-ppc.o-as-an-object_files.patch
new file mode 100644 (file)
index 0000000..ef31659
--- /dev/null
@@ -0,0 +1,87 @@
+From 7fd5f457356d2c0ec0768e0d6b0b304422d9a28c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Mar 2025 00:02:39 +0100
+Subject: crypto: powerpc: Mark ghashp8-ppc.o as an OBJECT_FILES_NON_STANDARD
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+[ Upstream commit 1e4d73d06c98f5a1af4f7591cf7c2c4eee5b94fa ]
+
+The following build warning has been reported:
+
+  arch/powerpc/crypto/ghashp8-ppc.o: warning: objtool: .text+0x22c: unannotated intra-function call
+
+This happens due to commit bb7f054f4de2 ("objtool/powerpc: Add support
+for decoding all types of uncond branches")
+
+Disassembly of arch/powerpc/crypto/ghashp8-ppc.o shows:
+
+ arch/powerpc/crypto/ghashp8-ppc.o:     file format elf64-powerpcle
+
+ Disassembly of section .text:
+
+ 0000000000000140 <gcm_ghash_p8>:
+   140:    f8 ff 00 3c     lis     r0,-8
+ ...
+   20c:    20 00 80 4e     blr
+   210:    00 00 00 00     .long 0x0
+   214:    00 0c 14 00     .long 0x140c00
+   218:    00 00 04 00     .long 0x40000
+   21c:    00 00 00 00     .long 0x0
+   220:    47 48 41 53     rlwimi. r1,r26,9,1,3
+   224:    48 20 66 6f     xoris   r6,r27,8264
+   228:    72 20 50 6f     xoris   r16,r26,8306
+   22c:    77 65 72 49     bla     1726574 <gcm_ghash_p8+0x1726434>      <==
+ ...
+
+It corresponds to the following code in ghashp8-ppc.o :
+
+ _GLOBAL(gcm_ghash_p8)
+    lis    0,0xfff8
+ ...
+    blr
+ .long    0
+ .byte    0,12,0x14,0,0,0,4,0
+ .long    0
+ .size    gcm_ghash_p8,.-gcm_ghash_p8
+
+ .byte 71,72,65,83,72,32,102,111,114,32,80,111,119,101,114,73,83,65,32,50,46,48,55,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+ .align    2
+ .align    2
+
+In fact this is raw data that is after the function end and that is
+not text so shouldn't be disassembled as text. But ghashp8-ppc.S is
+generated by a perl script and should have been marked as
+OBJECT_FILES_NON_STANDARD.
+
+Now that 'bla' is understood as a call instruction, that raw data
+is mis-interpreted as an infra-function call.
+
+Mark ghashp8-ppc.o as a OBJECT_FILES_NON_STANDARD to avoid this
+warning.
+
+Reported-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
+Closes: https://lore.kernel.org/all/8c4c3fc2-2bd7-4148-af68-2f504d6119e0@linux.ibm.com
+Fixes: 109303336a0c ("crypto: vmx - Move to arch/powerpc/crypto")
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Tested-By: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
+Reviewed-by: Sathvika Vasireddy <sv@linux.ibm.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/7aa7eb73fe6bc95ac210510e22394ca0ae227b69.1741128786.git.christophe.leroy@csgroup.eu
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/crypto/Makefile | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/powerpc/crypto/Makefile b/arch/powerpc/crypto/Makefile
+index 9b38f4a7bc152..2f00b22b0823e 100644
+--- a/arch/powerpc/crypto/Makefile
++++ b/arch/powerpc/crypto/Makefile
+@@ -51,3 +51,4 @@ $(obj)/aesp8-ppc.S $(obj)/ghashp8-ppc.S: $(obj)/%.S: $(src)/%.pl FORCE
+ OBJECT_FILES_NON_STANDARD_aesp10-ppc.o := y
+ OBJECT_FILES_NON_STANDARD_ghashp10-ppc.o := y
+ OBJECT_FILES_NON_STANDARD_aesp8-ppc.o := y
++OBJECT_FILES_NON_STANDARD_ghashp8-ppc.o := y
+-- 
+2.39.5
+
diff --git a/queue-6.14/crypto-qat-remove-access-to-parity-register-for-qat-.patch b/queue-6.14/crypto-qat-remove-access-to-parity-register-for-qat-.patch
new file mode 100644 (file)
index 0000000..6e6c483
--- /dev/null
@@ -0,0 +1,114 @@
+From 53fee94d27913b65a7218cf32ed17eb90beb9965 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Mar 2025 15:09:31 +0000
+Subject: crypto: qat - remove access to parity register for QAT GEN4
+
+From: Bairavi Alagappan <bairavix.alagappan@intel.com>
+
+[ Upstream commit 92c6a707d82f0629debf1c21dd87717776d96af2 ]
+
+The firmware already handles parity errors reported by the accelerators
+by clearing them through the corresponding SSMSOFTERRORPARITY register.
+To ensure consistent behavior and prevent race conditions between the
+driver and firmware, remove the logic that checks the SSMSOFTERRORPARITY
+registers.
+
+Additionally, change the return type of the function
+adf_handle_rf_parr_err() to void, as it consistently returns false.
+Parity errors are recoverable and do not necessitate a device reset.
+
+Fixes: 895f7d532c84 ("crypto: qat - add handling of errors from ERRSOU2 for QAT GEN4")
+Signed-off-by: Bairavi Alagappan <bairavix.alagappan@intel.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../intel/qat/qat_common/adf_gen4_ras.c       | 57 ++-----------------
+ 1 file changed, 5 insertions(+), 52 deletions(-)
+
+diff --git a/drivers/crypto/intel/qat/qat_common/adf_gen4_ras.c b/drivers/crypto/intel/qat/qat_common/adf_gen4_ras.c
+index bf0ea09faa650..0f7f00a19e7dc 100644
+--- a/drivers/crypto/intel/qat/qat_common/adf_gen4_ras.c
++++ b/drivers/crypto/intel/qat/qat_common/adf_gen4_ras.c
+@@ -1043,63 +1043,16 @@ static bool adf_handle_ssmcpppar_err(struct adf_accel_dev *accel_dev,
+       return reset_required;
+ }
+-static bool adf_handle_rf_parr_err(struct adf_accel_dev *accel_dev,
++static void adf_handle_rf_parr_err(struct adf_accel_dev *accel_dev,
+                                  void __iomem *csr, u32 iastatssm)
+ {
+-      struct adf_dev_err_mask *err_mask = GET_ERR_MASK(accel_dev);
+-      u32 reg;
+-
+       if (!(iastatssm & ADF_GEN4_IAINTSTATSSM_SSMSOFTERRORPARITY_BIT))
+-              return false;
+-
+-      reg = ADF_CSR_RD(csr, ADF_GEN4_SSMSOFTERRORPARITY_SRC);
+-      reg &= ADF_GEN4_SSMSOFTERRORPARITY_SRC_BIT;
+-      if (reg) {
+-              ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR);
+-              ADF_CSR_WR(csr, ADF_GEN4_SSMSOFTERRORPARITY_SRC, reg);
+-      }
+-
+-      reg = ADF_CSR_RD(csr, ADF_GEN4_SSMSOFTERRORPARITY_ATH_CPH);
+-      reg &= err_mask->parerr_ath_cph_mask;
+-      if (reg) {
+-              ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR);
+-              ADF_CSR_WR(csr, ADF_GEN4_SSMSOFTERRORPARITY_ATH_CPH, reg);
+-      }
+-
+-      reg = ADF_CSR_RD(csr, ADF_GEN4_SSMSOFTERRORPARITY_CPR_XLT);
+-      reg &= err_mask->parerr_cpr_xlt_mask;
+-      if (reg) {
+-              ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR);
+-              ADF_CSR_WR(csr, ADF_GEN4_SSMSOFTERRORPARITY_CPR_XLT, reg);
+-      }
+-
+-      reg = ADF_CSR_RD(csr, ADF_GEN4_SSMSOFTERRORPARITY_DCPR_UCS);
+-      reg &= err_mask->parerr_dcpr_ucs_mask;
+-      if (reg) {
+-              ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR);
+-              ADF_CSR_WR(csr, ADF_GEN4_SSMSOFTERRORPARITY_DCPR_UCS, reg);
+-      }
+-
+-      reg = ADF_CSR_RD(csr, ADF_GEN4_SSMSOFTERRORPARITY_PKE);
+-      reg &= err_mask->parerr_pke_mask;
+-      if (reg) {
+-              ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR);
+-              ADF_CSR_WR(csr, ADF_GEN4_SSMSOFTERRORPARITY_PKE, reg);
+-      }
+-
+-      if (err_mask->parerr_wat_wcp_mask) {
+-              reg = ADF_CSR_RD(csr, ADF_GEN4_SSMSOFTERRORPARITY_WAT_WCP);
+-              reg &= err_mask->parerr_wat_wcp_mask;
+-              if (reg) {
+-                      ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR);
+-                      ADF_CSR_WR(csr, ADF_GEN4_SSMSOFTERRORPARITY_WAT_WCP,
+-                                 reg);
+-              }
+-      }
++              return;
++      ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR);
+       dev_err(&GET_DEV(accel_dev), "Slice ssm soft parity error reported");
+-      return false;
++      return;
+ }
+ static bool adf_handle_ser_err_ssmsh(struct adf_accel_dev *accel_dev,
+@@ -1171,8 +1124,8 @@ static bool adf_handle_iaintstatssm(struct adf_accel_dev *accel_dev,
+       reset_required |= adf_handle_slice_hang_error(accel_dev, csr, iastatssm);
+       reset_required |= adf_handle_spppar_err(accel_dev, csr, iastatssm);
+       reset_required |= adf_handle_ssmcpppar_err(accel_dev, csr, iastatssm);
+-      reset_required |= adf_handle_rf_parr_err(accel_dev, csr, iastatssm);
+       reset_required |= adf_handle_ser_err_ssmsh(accel_dev, csr, iastatssm);
++      adf_handle_rf_parr_err(accel_dev, csr, iastatssm);
+       ADF_CSR_WR(csr, ADF_GEN4_IAINTSTATSSM, iastatssm);
+-- 
+2.39.5
+
diff --git a/queue-6.14/crypto-qat-set-parity-error-mask-for-qat_420xx.patch b/queue-6.14/crypto-qat-set-parity-error-mask-for-qat_420xx.patch
new file mode 100644 (file)
index 0000000..9cdb734
--- /dev/null
@@ -0,0 +1,58 @@
+From e659a3953457d51e3a9284eab1700a85d996020f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Mar 2025 13:14:29 +0000
+Subject: crypto: qat - set parity error mask for qat_420xx
+
+From: Bairavi Alagappan <bairavix.alagappan@intel.com>
+
+[ Upstream commit f9555d18084985c80a91baa4fdb7d205b401a754 ]
+
+The field parerr_wat_wcp_mask in the structure adf_dev_err_mask enables
+the detection and reporting of parity errors for the wireless cipher and
+wireless authentication accelerators.
+
+Set the parerr_wat_wcp_mask field, which was inadvertently omitted
+during the initial enablement of the qat_420xx driver, to ensure that
+parity errors are enabled for those accelerators.
+
+In addition, fix the string used to report such errors that was
+inadvertently set to "ath_cph" (authentication and cipher).
+
+Fixes: fcf60f4bcf54 ("crypto: qat - add support for 420xx devices")
+Signed-off-by: Bairavi Alagappan <bairavix.alagappan@intel.com>
+Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/intel/qat/qat_420xx/adf_420xx_hw_data.c | 1 +
+ drivers/crypto/intel/qat/qat_common/adf_gen4_ras.c     | 2 +-
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/intel/qat/qat_420xx/adf_420xx_hw_data.c b/drivers/crypto/intel/qat/qat_420xx/adf_420xx_hw_data.c
+index 9faef33e54bd3..a17adc4beda2e 100644
+--- a/drivers/crypto/intel/qat/qat_420xx/adf_420xx_hw_data.c
++++ b/drivers/crypto/intel/qat/qat_420xx/adf_420xx_hw_data.c
+@@ -420,6 +420,7 @@ static void adf_gen4_set_err_mask(struct adf_dev_err_mask *dev_err_mask)
+       dev_err_mask->parerr_cpr_xlt_mask = ADF_420XX_PARITYERRORMASK_CPR_XLT_MASK;
+       dev_err_mask->parerr_dcpr_ucs_mask = ADF_420XX_PARITYERRORMASK_DCPR_UCS_MASK;
+       dev_err_mask->parerr_pke_mask = ADF_420XX_PARITYERRORMASK_PKE_MASK;
++      dev_err_mask->parerr_wat_wcp_mask = ADF_420XX_PARITYERRORMASK_WAT_WCP_MASK;
+       dev_err_mask->ssmfeatren_mask = ADF_420XX_SSMFEATREN_MASK;
+ }
+diff --git a/drivers/crypto/intel/qat/qat_common/adf_gen4_ras.c b/drivers/crypto/intel/qat/qat_common/adf_gen4_ras.c
+index 2dd3772bf58a6..bf0ea09faa650 100644
+--- a/drivers/crypto/intel/qat/qat_common/adf_gen4_ras.c
++++ b/drivers/crypto/intel/qat/qat_common/adf_gen4_ras.c
+@@ -695,7 +695,7 @@ static bool adf_handle_slice_hang_error(struct adf_accel_dev *accel_dev,
+       if (err_mask->parerr_wat_wcp_mask)
+               adf_poll_slicehang_csr(accel_dev, csr,
+                                      ADF_GEN4_SLICEHANGSTATUS_WAT_WCP,
+-                                     "ath_cph");
++                                     "wat_wcp");
+       return false;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/crypto-tegra-check-return-value-for-hash-do_one_req.patch b/queue-6.14/crypto-tegra-check-return-value-for-hash-do_one_req.patch
new file mode 100644 (file)
index 0000000..fbedc25
--- /dev/null
@@ -0,0 +1,86 @@
+From 476c7d7d0cd2824a5333896895849b0ae1780382 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Feb 2025 14:46:04 +0530
+Subject: crypto: tegra - check return value for hash do_one_req
+
+From: Akhil R <akhilrajeev@nvidia.com>
+
+[ Upstream commit dcf8b7e49b86738296c77fb58c123dd2d74a22a7 ]
+
+Initialize and check the return value in hash *do_one_req() functions
+and exit the function if there is an error. This fixes the
+'uninitialized variable' warnings reported by testbots.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Closes: https://lore.kernel.org/r/202412071747.flPux4oB-lkp@intel.com/
+Fixes: 0880bb3b00c8 ("crypto: tegra - Add Tegra Security Engine driver")
+Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Stable-dep-of: ff4b7df0b511 ("crypto: tegra - Fix HASH intermediate result handling")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/tegra/tegra-se-aes.c  | 10 ++++++++--
+ drivers/crypto/tegra/tegra-se-hash.c |  7 +++++++
+ 2 files changed, 15 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/crypto/tegra/tegra-se-aes.c b/drivers/crypto/tegra/tegra-se-aes.c
+index c2b8891a905dc..dd147fa4af977 100644
+--- a/drivers/crypto/tegra/tegra-se-aes.c
++++ b/drivers/crypto/tegra/tegra-se-aes.c
+@@ -1596,18 +1596,24 @@ static int tegra_cmac_do_one_req(struct crypto_engine *engine, void *areq)
+       struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+       struct tegra_cmac_ctx *ctx = crypto_ahash_ctx(tfm);
+       struct tegra_se *se = ctx->se;
+-      int ret;
++      int ret = 0;
+       if (rctx->task & SHA_UPDATE) {
+               ret = tegra_cmac_do_update(req);
++              if (ret)
++                      goto out;
++
+               rctx->task &= ~SHA_UPDATE;
+       }
+       if (rctx->task & SHA_FINAL) {
+               ret = tegra_cmac_do_final(req);
++              if (ret)
++                      goto out;
++
+               rctx->task &= ~SHA_FINAL;
+       }
+-
++out:
+       crypto_finalize_hash_request(se->engine, req, ret);
+       return 0;
+diff --git a/drivers/crypto/tegra/tegra-se-hash.c b/drivers/crypto/tegra/tegra-se-hash.c
+index b4a179a8febd5..0ae5ce67bdd04 100644
+--- a/drivers/crypto/tegra/tegra-se-hash.c
++++ b/drivers/crypto/tegra/tegra-se-hash.c
+@@ -437,14 +437,21 @@ static int tegra_sha_do_one_req(struct crypto_engine *engine, void *areq)
+       if (rctx->task & SHA_UPDATE) {
+               ret = tegra_sha_do_update(req);
++              if (ret)
++                      goto out;
++
+               rctx->task &= ~SHA_UPDATE;
+       }
+       if (rctx->task & SHA_FINAL) {
+               ret = tegra_sha_do_final(req);
++              if (ret)
++                      goto out;
++
+               rctx->task &= ~SHA_FINAL;
+       }
++out:
+       crypto_finalize_hash_request(se->engine, req, ret);
+       return 0;
+-- 
+2.39.5
+
diff --git a/queue-6.14/crypto-tegra-do-not-use-fixed-size-buffers.patch b/queue-6.14/crypto-tegra-do-not-use-fixed-size-buffers.patch
new file mode 100644 (file)
index 0000000..7977c36
--- /dev/null
@@ -0,0 +1,381 @@
+From 5cecfa0a288e98e728a65ca85ba7ae63c4f8a2a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Feb 2025 14:46:02 +0530
+Subject: crypto: tegra - Do not use fixed size buffers
+
+From: Akhil R <akhilrajeev@nvidia.com>
+
+[ Upstream commit 1cb328da4e8f34350c61a2b6548766c79b4bb64c ]
+
+Allocate the buffer based on the request instead of a fixed buffer
+length. In operations which may require larger buffer size, a fixed
+buffer may fail.
+
+Fixes: 0880bb3b00c8 ("crypto: tegra - Add Tegra Security Engine driver")
+Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Stable-dep-of: ff4b7df0b511 ("crypto: tegra - Fix HASH intermediate result handling")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/tegra/tegra-se-aes.c  | 124 ++++++++++++++-------------
+ drivers/crypto/tegra/tegra-se-hash.c |  38 +++++---
+ drivers/crypto/tegra/tegra-se.h      |   2 -
+ 3 files changed, 89 insertions(+), 75 deletions(-)
+
+diff --git a/drivers/crypto/tegra/tegra-se-aes.c b/drivers/crypto/tegra/tegra-se-aes.c
+index 7da7e169a314b..c2b8891a905dc 100644
+--- a/drivers/crypto/tegra/tegra-se-aes.c
++++ b/drivers/crypto/tegra/tegra-se-aes.c
+@@ -263,12 +263,6 @@ static int tegra_aes_do_one_req(struct crypto_engine *engine, void *areq)
+       unsigned int cmdlen;
+       int ret;
+-      rctx->datbuf.buf = dma_alloc_coherent(se->dev, SE_AES_BUFLEN,
+-                                            &rctx->datbuf.addr, GFP_KERNEL);
+-      if (!rctx->datbuf.buf)
+-              return -ENOMEM;
+-
+-      rctx->datbuf.size = SE_AES_BUFLEN;
+       rctx->iv = (u32 *)req->iv;
+       rctx->len = req->cryptlen;
+@@ -278,6 +272,12 @@ static int tegra_aes_do_one_req(struct crypto_engine *engine, void *areq)
+                       rctx->len += AES_BLOCK_SIZE - (rctx->len % AES_BLOCK_SIZE);
+       }
++      rctx->datbuf.size = rctx->len;
++      rctx->datbuf.buf = dma_alloc_coherent(se->dev, rctx->datbuf.size,
++                                            &rctx->datbuf.addr, GFP_KERNEL);
++      if (!rctx->datbuf.buf)
++              return -ENOMEM;
++
+       scatterwalk_map_and_copy(rctx->datbuf.buf, req->src, 0, req->cryptlen, 0);
+       /* Prepare the command and submit for execution */
+@@ -289,7 +289,7 @@ static int tegra_aes_do_one_req(struct crypto_engine *engine, void *areq)
+       scatterwalk_map_and_copy(rctx->datbuf.buf, req->dst, 0, req->cryptlen, 1);
+       /* Free the buffer */
+-      dma_free_coherent(ctx->se->dev, SE_AES_BUFLEN,
++      dma_free_coherent(ctx->se->dev, rctx->datbuf.size,
+                         rctx->datbuf.buf, rctx->datbuf.addr);
+       crypto_finalize_skcipher_request(se->engine, req, ret);
+@@ -1117,6 +1117,11 @@ static int tegra_ccm_crypt_init(struct aead_request *req, struct tegra_se *se,
+       rctx->assoclen = req->assoclen;
+       rctx->authsize = crypto_aead_authsize(tfm);
++      if (rctx->encrypt)
++              rctx->cryptlen = req->cryptlen;
++      else
++              rctx->cryptlen = req->cryptlen - rctx->authsize;
++
+       memcpy(iv, req->iv, 16);
+       ret = tegra_ccm_check_iv(iv);
+@@ -1145,30 +1150,26 @@ static int tegra_ccm_do_one_req(struct crypto_engine *engine, void *areq)
+       struct tegra_se *se = ctx->se;
+       int ret;
++      ret = tegra_ccm_crypt_init(req, se, rctx);
++      if (ret)
++              return ret;
++
+       /* Allocate buffers required */
+-      rctx->inbuf.buf = dma_alloc_coherent(ctx->se->dev, SE_AES_BUFLEN,
++      rctx->inbuf.size = rctx->assoclen + rctx->authsize + rctx->cryptlen + 100;
++      rctx->inbuf.buf = dma_alloc_coherent(ctx->se->dev, rctx->inbuf.size,
+                                            &rctx->inbuf.addr, GFP_KERNEL);
+       if (!rctx->inbuf.buf)
+               return -ENOMEM;
+-      rctx->inbuf.size = SE_AES_BUFLEN;
+-
+-      rctx->outbuf.buf = dma_alloc_coherent(ctx->se->dev, SE_AES_BUFLEN,
++      rctx->outbuf.size = rctx->assoclen + rctx->authsize + rctx->cryptlen + 100;
++      rctx->outbuf.buf = dma_alloc_coherent(ctx->se->dev, rctx->outbuf.size,
+                                             &rctx->outbuf.addr, GFP_KERNEL);
+       if (!rctx->outbuf.buf) {
+               ret = -ENOMEM;
+               goto outbuf_err;
+       }
+-      rctx->outbuf.size = SE_AES_BUFLEN;
+-
+-      ret = tegra_ccm_crypt_init(req, se, rctx);
+-      if (ret)
+-              goto out;
+-
+       if (rctx->encrypt) {
+-              rctx->cryptlen = req->cryptlen;
+-
+               /* CBC MAC Operation */
+               ret = tegra_ccm_compute_auth(ctx, rctx);
+               if (ret)
+@@ -1179,8 +1180,6 @@ static int tegra_ccm_do_one_req(struct crypto_engine *engine, void *areq)
+               if (ret)
+                       goto out;
+       } else {
+-              rctx->cryptlen = req->cryptlen - ctx->authsize;
+-
+               /* CTR operation */
+               ret = tegra_ccm_do_ctr(ctx, rctx);
+               if (ret)
+@@ -1193,11 +1192,11 @@ static int tegra_ccm_do_one_req(struct crypto_engine *engine, void *areq)
+       }
+ out:
+-      dma_free_coherent(ctx->se->dev, SE_AES_BUFLEN,
++      dma_free_coherent(ctx->se->dev, rctx->inbuf.size,
+                         rctx->outbuf.buf, rctx->outbuf.addr);
+ outbuf_err:
+-      dma_free_coherent(ctx->se->dev, SE_AES_BUFLEN,
++      dma_free_coherent(ctx->se->dev, rctx->outbuf.size,
+                         rctx->inbuf.buf, rctx->inbuf.addr);
+       crypto_finalize_aead_request(ctx->se->engine, req, ret);
+@@ -1213,23 +1212,6 @@ static int tegra_gcm_do_one_req(struct crypto_engine *engine, void *areq)
+       struct tegra_aead_reqctx *rctx = aead_request_ctx(req);
+       int ret;
+-      /* Allocate buffers required */
+-      rctx->inbuf.buf = dma_alloc_coherent(ctx->se->dev, SE_AES_BUFLEN,
+-                                           &rctx->inbuf.addr, GFP_KERNEL);
+-      if (!rctx->inbuf.buf)
+-              return -ENOMEM;
+-
+-      rctx->inbuf.size = SE_AES_BUFLEN;
+-
+-      rctx->outbuf.buf = dma_alloc_coherent(ctx->se->dev, SE_AES_BUFLEN,
+-                                            &rctx->outbuf.addr, GFP_KERNEL);
+-      if (!rctx->outbuf.buf) {
+-              ret = -ENOMEM;
+-              goto outbuf_err;
+-      }
+-
+-      rctx->outbuf.size = SE_AES_BUFLEN;
+-
+       rctx->src_sg = req->src;
+       rctx->dst_sg = req->dst;
+       rctx->assoclen = req->assoclen;
+@@ -1243,6 +1225,21 @@ static int tegra_gcm_do_one_req(struct crypto_engine *engine, void *areq)
+       memcpy(rctx->iv, req->iv, GCM_AES_IV_SIZE);
+       rctx->iv[3] = (1 << 24);
++      /* Allocate buffers required */
++      rctx->inbuf.size = rctx->assoclen + rctx->authsize + rctx->cryptlen;
++      rctx->inbuf.buf = dma_alloc_coherent(ctx->se->dev, rctx->inbuf.size,
++                                           &rctx->inbuf.addr, GFP_KERNEL);
++      if (!rctx->inbuf.buf)
++              return -ENOMEM;
++
++      rctx->outbuf.size = rctx->assoclen + rctx->authsize + rctx->cryptlen;
++      rctx->outbuf.buf = dma_alloc_coherent(ctx->se->dev, rctx->outbuf.size,
++                                            &rctx->outbuf.addr, GFP_KERNEL);
++      if (!rctx->outbuf.buf) {
++              ret = -ENOMEM;
++              goto outbuf_err;
++      }
++
+       /* If there is associated data perform GMAC operation */
+       if (rctx->assoclen) {
+               ret = tegra_gcm_do_gmac(ctx, rctx);
+@@ -1266,11 +1263,11 @@ static int tegra_gcm_do_one_req(struct crypto_engine *engine, void *areq)
+               ret = tegra_gcm_do_verify(ctx->se, rctx);
+ out:
+-      dma_free_coherent(ctx->se->dev, SE_AES_BUFLEN,
++      dma_free_coherent(ctx->se->dev, rctx->outbuf.size,
+                         rctx->outbuf.buf, rctx->outbuf.addr);
+ outbuf_err:
+-      dma_free_coherent(ctx->se->dev, SE_AES_BUFLEN,
++      dma_free_coherent(ctx->se->dev, rctx->inbuf.size,
+                         rctx->inbuf.buf, rctx->inbuf.addr);
+       /* Finalize the request if there are no errors */
+@@ -1497,6 +1494,11 @@ static int tegra_cmac_do_update(struct ahash_request *req)
+               return 0;
+       }
++      rctx->datbuf.buf = dma_alloc_coherent(se->dev, rctx->datbuf.size,
++                                            &rctx->datbuf.addr, GFP_KERNEL);
++      if (!rctx->datbuf.buf)
++              return -ENOMEM;
++
+       /* Copy the previous residue first */
+       if (rctx->residue.size)
+               memcpy(rctx->datbuf.buf, rctx->residue.buf, rctx->residue.size);
+@@ -1529,6 +1531,9 @@ static int tegra_cmac_do_update(struct ahash_request *req)
+       if (!(rctx->task & SHA_FINAL))
+               tegra_cmac_copy_result(ctx->se, rctx);
++      dma_free_coherent(ctx->se->dev, rctx->datbuf.size,
++                        rctx->datbuf.buf, rctx->datbuf.addr);
++
+       return ret;
+ }
+@@ -1543,10 +1548,20 @@ static int tegra_cmac_do_final(struct ahash_request *req)
+       if (!req->nbytes && !rctx->total_len && ctx->fallback_tfm) {
+               return crypto_shash_tfm_digest(ctx->fallback_tfm,
+-                                      rctx->datbuf.buf, 0, req->result);
++                                      NULL, 0, req->result);
++      }
++
++      if (rctx->residue.size) {
++              rctx->datbuf.buf = dma_alloc_coherent(se->dev, rctx->residue.size,
++                                                    &rctx->datbuf.addr, GFP_KERNEL);
++              if (!rctx->datbuf.buf) {
++                      ret = -ENOMEM;
++                      goto out_free;
++              }
++
++              memcpy(rctx->datbuf.buf, rctx->residue.buf, rctx->residue.size);
+       }
+-      memcpy(rctx->datbuf.buf, rctx->residue.buf, rctx->residue.size);
+       rctx->datbuf.size = rctx->residue.size;
+       rctx->total_len += rctx->residue.size;
+       rctx->config = tegra234_aes_cfg(SE_ALG_CMAC, 0);
+@@ -1565,8 +1580,10 @@ static int tegra_cmac_do_final(struct ahash_request *req)
+               writel(0, se->base + se->hw->regs->result + (i * 4));
+ out:
+-      dma_free_coherent(se->dev, SE_SHA_BUFLEN,
+-                        rctx->datbuf.buf, rctx->datbuf.addr);
++      if (rctx->residue.size)
++              dma_free_coherent(se->dev, rctx->datbuf.size,
++                                rctx->datbuf.buf, rctx->datbuf.addr);
++out_free:
+       dma_free_coherent(se->dev, crypto_ahash_blocksize(tfm) * 2,
+                         rctx->residue.buf, rctx->residue.addr);
+       return ret;
+@@ -1672,28 +1689,15 @@ static int tegra_cmac_init(struct ahash_request *req)
+       rctx->residue.buf = dma_alloc_coherent(se->dev, rctx->blk_size * 2,
+                                              &rctx->residue.addr, GFP_KERNEL);
+       if (!rctx->residue.buf)
+-              goto resbuf_fail;
++              return -ENOMEM;
+       rctx->residue.size = 0;
+-      rctx->datbuf.buf = dma_alloc_coherent(se->dev, SE_SHA_BUFLEN,
+-                                            &rctx->datbuf.addr, GFP_KERNEL);
+-      if (!rctx->datbuf.buf)
+-              goto datbuf_fail;
+-
+-      rctx->datbuf.size = 0;
+-
+       /* Clear any previous result */
+       for (i = 0; i < CMAC_RESULT_REG_COUNT; i++)
+               writel(0, se->base + se->hw->regs->result + (i * 4));
+       return 0;
+-
+-datbuf_fail:
+-      dma_free_coherent(se->dev, rctx->blk_size, rctx->residue.buf,
+-                        rctx->residue.addr);
+-resbuf_fail:
+-      return -ENOMEM;
+ }
+ static int tegra_cmac_setkey(struct crypto_ahash *tfm, const u8 *key,
+diff --git a/drivers/crypto/tegra/tegra-se-hash.c b/drivers/crypto/tegra/tegra-se-hash.c
+index c7b2a062a03c0..b4a179a8febd5 100644
+--- a/drivers/crypto/tegra/tegra-se-hash.c
++++ b/drivers/crypto/tegra/tegra-se-hash.c
+@@ -332,6 +332,11 @@ static int tegra_sha_do_update(struct ahash_request *req)
+               return 0;
+       }
++      rctx->datbuf.buf = dma_alloc_coherent(ctx->se->dev, rctx->datbuf.size,
++                                            &rctx->datbuf.addr, GFP_KERNEL);
++      if (!rctx->datbuf.buf)
++              return -ENOMEM;
++
+       /* Copy the previous residue first */
+       if (rctx->residue.size)
+               memcpy(rctx->datbuf.buf, rctx->residue.buf, rctx->residue.size);
+@@ -368,6 +373,9 @@ static int tegra_sha_do_update(struct ahash_request *req)
+       if (!(rctx->task & SHA_FINAL))
+               tegra_sha_copy_hash_result(se, rctx);
++      dma_free_coherent(ctx->se->dev, rctx->datbuf.size,
++                        rctx->datbuf.buf, rctx->datbuf.addr);
++
+       return ret;
+ }
+@@ -380,7 +388,17 @@ static int tegra_sha_do_final(struct ahash_request *req)
+       u32 *cpuvaddr = se->cmdbuf->addr;
+       int size, ret = 0;
+-      memcpy(rctx->datbuf.buf, rctx->residue.buf, rctx->residue.size);
++      if (rctx->residue.size) {
++              rctx->datbuf.buf = dma_alloc_coherent(se->dev, rctx->residue.size,
++                                                    &rctx->datbuf.addr, GFP_KERNEL);
++              if (!rctx->datbuf.buf) {
++                      ret = -ENOMEM;
++                      goto out_free;
++              }
++
++              memcpy(rctx->datbuf.buf, rctx->residue.buf, rctx->residue.size);
++      }
++
+       rctx->datbuf.size = rctx->residue.size;
+       rctx->total_len += rctx->residue.size;
+@@ -397,8 +415,10 @@ static int tegra_sha_do_final(struct ahash_request *req)
+       memcpy(req->result, rctx->digest.buf, rctx->digest.size);
+ out:
+-      dma_free_coherent(se->dev, SE_SHA_BUFLEN,
+-                        rctx->datbuf.buf, rctx->datbuf.addr);
++      if (rctx->residue.size)
++              dma_free_coherent(se->dev, rctx->datbuf.size,
++                                rctx->datbuf.buf, rctx->datbuf.addr);
++out_free:
+       dma_free_coherent(se->dev, crypto_ahash_blocksize(tfm),
+                         rctx->residue.buf, rctx->residue.addr);
+       dma_free_coherent(se->dev, rctx->digest.size, rctx->digest.buf,
+@@ -527,19 +547,11 @@ static int tegra_sha_init(struct ahash_request *req)
+       if (!rctx->residue.buf)
+               goto resbuf_fail;
+-      rctx->datbuf.buf = dma_alloc_coherent(se->dev, SE_SHA_BUFLEN,
+-                                            &rctx->datbuf.addr, GFP_KERNEL);
+-      if (!rctx->datbuf.buf)
+-              goto datbuf_fail;
+-
+       return 0;
+-datbuf_fail:
+-      dma_free_coherent(se->dev, rctx->blk_size, rctx->residue.buf,
+-                        rctx->residue.addr);
+ resbuf_fail:
+-      dma_free_coherent(se->dev, SE_SHA_BUFLEN, rctx->datbuf.buf,
+-                        rctx->datbuf.addr);
++      dma_free_coherent(se->dev, rctx->digest.size, rctx->digest.buf,
++                        rctx->digest.addr);
+ digbuf_fail:
+       return -ENOMEM;
+ }
+diff --git a/drivers/crypto/tegra/tegra-se.h b/drivers/crypto/tegra/tegra-se.h
+index b54aefe717a17..e196a90eedb92 100644
+--- a/drivers/crypto/tegra/tegra-se.h
++++ b/drivers/crypto/tegra/tegra-se.h
+@@ -340,8 +340,6 @@
+ #define SE_CRYPTO_CTR_REG_COUNT                       4
+ #define SE_MAX_KEYSLOT                                15
+ #define SE_MAX_MEM_ALLOC                      SZ_4M
+-#define SE_AES_BUFLEN                         0x8000
+-#define SE_SHA_BUFLEN                         0x2000
+ #define SHA_FIRST     BIT(0)
+ #define SHA_UPDATE    BIT(1)
+-- 
+2.39.5
+
diff --git a/queue-6.14/crypto-tegra-finalize-crypto-req-on-error.patch b/queue-6.14/crypto-tegra-finalize-crypto-req-on-error.patch
new file mode 100644 (file)
index 0000000..7001bae
--- /dev/null
@@ -0,0 +1,123 @@
+From d7ebfd477052da78ae34c3c219f017989c30473b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Feb 2025 14:46:03 +0530
+Subject: crypto: tegra - finalize crypto req on error
+
+From: Akhil R <akhilrajeev@nvidia.com>
+
+[ Upstream commit 1e245948ca0c252f561792fabb45de5518301d97 ]
+
+Call the crypto finalize function before exiting *do_one_req() functions.
+This allows the driver to take up further requests even if the previous
+one fails.
+
+Fixes: 0880bb3b00c8 ("crypto: tegra - Add Tegra Security Engine driver")
+Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Stable-dep-of: b157e7a228ae ("crypto: tegra - Reserve keyslots to allocate dynamically")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/tegra/tegra-se-aes.c | 28 +++++++++++++++++-----------
+ 1 file changed, 17 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/crypto/tegra/tegra-se-aes.c b/drivers/crypto/tegra/tegra-se-aes.c
+index be0a0b51f5a59..a1b469c3a55ba 100644
+--- a/drivers/crypto/tegra/tegra-se-aes.c
++++ b/drivers/crypto/tegra/tegra-se-aes.c
+@@ -275,8 +275,10 @@ static int tegra_aes_do_one_req(struct crypto_engine *engine, void *areq)
+       rctx->datbuf.size = rctx->len;
+       rctx->datbuf.buf = dma_alloc_coherent(se->dev, rctx->datbuf.size,
+                                             &rctx->datbuf.addr, GFP_KERNEL);
+-      if (!rctx->datbuf.buf)
+-              return -ENOMEM;
++      if (!rctx->datbuf.buf) {
++              ret = -ENOMEM;
++              goto out_finalize;
++      }
+       scatterwalk_map_and_copy(rctx->datbuf.buf, req->src, 0, req->cryptlen, 0);
+@@ -292,6 +294,7 @@ static int tegra_aes_do_one_req(struct crypto_engine *engine, void *areq)
+       dma_free_coherent(ctx->se->dev, rctx->datbuf.size,
+                         rctx->datbuf.buf, rctx->datbuf.addr);
++out_finalize:
+       crypto_finalize_skcipher_request(se->engine, req, ret);
+       return 0;
+@@ -1155,21 +1158,21 @@ static int tegra_ccm_do_one_req(struct crypto_engine *engine, void *areq)
+       ret = tegra_ccm_crypt_init(req, se, rctx);
+       if (ret)
+-              return ret;
++              goto out_finalize;
+       /* Allocate buffers required */
+       rctx->inbuf.size = rctx->assoclen + rctx->authsize + rctx->cryptlen + 100;
+       rctx->inbuf.buf = dma_alloc_coherent(ctx->se->dev, rctx->inbuf.size,
+                                            &rctx->inbuf.addr, GFP_KERNEL);
+       if (!rctx->inbuf.buf)
+-              return -ENOMEM;
++              goto out_finalize;
+       rctx->outbuf.size = rctx->assoclen + rctx->authsize + rctx->cryptlen + 100;
+       rctx->outbuf.buf = dma_alloc_coherent(ctx->se->dev, rctx->outbuf.size,
+                                             &rctx->outbuf.addr, GFP_KERNEL);
+       if (!rctx->outbuf.buf) {
+               ret = -ENOMEM;
+-              goto outbuf_err;
++              goto out_free_inbuf;
+       }
+       if (rctx->encrypt) {
+@@ -1198,10 +1201,11 @@ static int tegra_ccm_do_one_req(struct crypto_engine *engine, void *areq)
+       dma_free_coherent(ctx->se->dev, rctx->inbuf.size,
+                         rctx->outbuf.buf, rctx->outbuf.addr);
+-outbuf_err:
++out_free_inbuf:
+       dma_free_coherent(ctx->se->dev, rctx->outbuf.size,
+                         rctx->inbuf.buf, rctx->inbuf.addr);
++out_finalize:
+       crypto_finalize_aead_request(ctx->se->engine, req, ret);
+       return 0;
+@@ -1232,15 +1236,17 @@ static int tegra_gcm_do_one_req(struct crypto_engine *engine, void *areq)
+       rctx->inbuf.size = rctx->assoclen + rctx->authsize + rctx->cryptlen;
+       rctx->inbuf.buf = dma_alloc_coherent(ctx->se->dev, rctx->inbuf.size,
+                                            &rctx->inbuf.addr, GFP_KERNEL);
+-      if (!rctx->inbuf.buf)
+-              return -ENOMEM;
++      if (!rctx->inbuf.buf) {
++              ret = -ENOMEM;
++              goto out_finalize;
++      }
+       rctx->outbuf.size = rctx->assoclen + rctx->authsize + rctx->cryptlen;
+       rctx->outbuf.buf = dma_alloc_coherent(ctx->se->dev, rctx->outbuf.size,
+                                             &rctx->outbuf.addr, GFP_KERNEL);
+       if (!rctx->outbuf.buf) {
+               ret = -ENOMEM;
+-              goto outbuf_err;
++              goto out_free_inbuf;
+       }
+       /* If there is associated data perform GMAC operation */
+@@ -1269,11 +1275,11 @@ static int tegra_gcm_do_one_req(struct crypto_engine *engine, void *areq)
+       dma_free_coherent(ctx->se->dev, rctx->outbuf.size,
+                         rctx->outbuf.buf, rctx->outbuf.addr);
+-outbuf_err:
++out_free_inbuf:
+       dma_free_coherent(ctx->se->dev, rctx->inbuf.size,
+                         rctx->inbuf.buf, rctx->inbuf.addr);
+-      /* Finalize the request if there are no errors */
++out_finalize:
+       crypto_finalize_aead_request(ctx->se->engine, req, ret);
+       return 0;
+-- 
+2.39.5
+
diff --git a/queue-6.14/crypto-tegra-fix-cmac-intermediate-result-handling.patch b/queue-6.14/crypto-tegra-fix-cmac-intermediate-result-handling.patch
new file mode 100644 (file)
index 0000000..c6eb8ea
--- /dev/null
@@ -0,0 +1,69 @@
+From d426a8bd3381089443564cc7056113b3367c3660 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Feb 2025 14:46:07 +0530
+Subject: crypto: tegra - Fix CMAC intermediate result handling
+
+From: Akhil R <akhilrajeev@nvidia.com>
+
+[ Upstream commit ce390d6c2675d2e24d798169a1a0e3cdbc076907 ]
+
+Saving and restoring of the intermediate results are needed if there is
+context switch caused by another ongoing request on the same engine.
+This is therefore not only to support import/export functionality.
+Hence, save and restore the intermediate result for every non-first task.
+
+Fixes: 0880bb3b00c8 ("crypto: tegra - Add Tegra Security Engine driver")
+Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/tegra/tegra-se-aes.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/crypto/tegra/tegra-se-aes.c b/drivers/crypto/tegra/tegra-se-aes.c
+index 5d8237cda58f0..cdcf05e235cad 100644
+--- a/drivers/crypto/tegra/tegra-se-aes.c
++++ b/drivers/crypto/tegra/tegra-se-aes.c
+@@ -1541,9 +1541,8 @@ static int tegra_cmac_do_update(struct ahash_request *req)
+       rctx->residue.size = nresidue;
+       /*
+-       * If this is not the first 'update' call, paste the previous copied
++       * If this is not the first task, paste the previous copied
+        * intermediate results to the registers so that it gets picked up.
+-       * This is to support the import/export functionality.
+        */
+       if (!(rctx->task & SHA_FIRST))
+               tegra_cmac_paste_result(ctx->se, rctx);
+@@ -1551,13 +1550,7 @@ static int tegra_cmac_do_update(struct ahash_request *req)
+       cmdlen = tegra_cmac_prep_cmd(ctx, rctx);
+       ret = tegra_se_host1x_submit(se, se->cmdbuf, cmdlen);
+-      /*
+-       * If this is not the final update, copy the intermediate results
+-       * from the registers so that it can be used in the next 'update'
+-       * call. This is to support the import/export functionality.
+-       */
+-      if (!(rctx->task & SHA_FINAL))
+-              tegra_cmac_copy_result(ctx->se, rctx);
++      tegra_cmac_copy_result(ctx->se, rctx);
+       dma_free_coherent(ctx->se->dev, rctx->datbuf.size,
+                         rctx->datbuf.buf, rctx->datbuf.addr);
+@@ -1594,6 +1587,13 @@ static int tegra_cmac_do_final(struct ahash_request *req)
+       rctx->total_len += rctx->residue.size;
+       rctx->config = tegra234_aes_cfg(SE_ALG_CMAC, 0);
++      /*
++       * If this is not the first task, paste the previous copied
++       * intermediate results to the registers so that it gets picked up.
++       */
++      if (!(rctx->task & SHA_FIRST))
++              tegra_cmac_paste_result(ctx->se, rctx);
++
+       /* Prepare command and submit */
+       cmdlen = tegra_cmac_prep_cmd(ctx, rctx);
+       ret = tegra_se_host1x_submit(se, se->cmdbuf, cmdlen);
+-- 
+2.39.5
+
diff --git a/queue-6.14/crypto-tegra-fix-format-specifier-in-tegra_sha_prep_.patch b/queue-6.14/crypto-tegra-fix-format-specifier-in-tegra_sha_prep_.patch
new file mode 100644 (file)
index 0000000..4e5d6d7
--- /dev/null
@@ -0,0 +1,55 @@
+From 4b6262ff26cff07d5ceeb2b9754f48b29c75cd3c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Mar 2025 16:29:31 +0100
+Subject: crypto: tegra - Fix format specifier in tegra_sha_prep_cmd()
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+[ Upstream commit 795e5bdb0ada2c77ea28611d88f1d5d7ca9b2f4d ]
+
+When building for 32-bit targets, for which ssize_t is 'int' instead of
+'long', there is a warning due to an incorrect format specifier:
+
+  In file included from include/linux/printk.h:610,
+                   from include/linux/kernel.h:31,
+                   from include/linux/clk.h:13,
+                   from drivers/crypto/tegra/tegra-se-hash.c:7:
+  drivers/crypto/tegra/tegra-se-hash.c: In function 'tegra_sha_prep_cmd':
+  drivers/crypto/tegra/tegra-se-hash.c:343:26: error: format '%lu' expects argument of type 'long unsigned int', but argument 6 has type 'ssize_t' {aka 'int'} [-Werror=format=]
+    343 |         dev_dbg(se->dev, "msg len %llu msg left %llu sz %lu cfg %#x",
+        |                          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ...
+  drivers/crypto/tegra/tegra-se-hash.c:343:59: note: format string is defined here
+    343 |         dev_dbg(se->dev, "msg len %llu msg left %llu sz %lu cfg %#x",
+        |                                                         ~~^
+        |                                                           |
+        |                                                           long unsigned int
+        |                                                         %u
+  cc1: all warnings being treated as errors
+
+Use '%zd', the proper specifier for ssize_t, to resolve the warning.
+
+Fixes: ff4b7df0b511 ("crypto: tegra - Fix HASH intermediate result handling")
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/tegra/tegra-se-hash.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/tegra/tegra-se-hash.c b/drivers/crypto/tegra/tegra-se-hash.c
+index 65a50f29bd7e6..42d007b7af45d 100644
+--- a/drivers/crypto/tegra/tegra-se-hash.c
++++ b/drivers/crypto/tegra/tegra-se-hash.c
+@@ -340,7 +340,7 @@ static int tegra_sha_prep_cmd(struct tegra_sha_ctx *ctx, u32 *cpuvaddr,
+       cpuvaddr[i++] = host1x_uclass_incr_syncpt_cond_f(1) |
+                       host1x_uclass_incr_syncpt_indx_f(se->syncpt_id);
+-      dev_dbg(se->dev, "msg len %llu msg left %llu sz %lu cfg %#x",
++      dev_dbg(se->dev, "msg len %llu msg left %llu sz %zd cfg %#x",
+               msg_len, msg_left, rctx->datbuf.size, rctx->config);
+       return i;
+-- 
+2.39.5
+
diff --git a/queue-6.14/crypto-tegra-fix-hash-intermediate-result-handling.patch b/queue-6.14/crypto-tegra-fix-hash-intermediate-result-handling.patch
new file mode 100644 (file)
index 0000000..06aefe3
--- /dev/null
@@ -0,0 +1,303 @@
+From 29612f8b942862360a362ff1856ddb521bc74772 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Feb 2025 14:46:06 +0530
+Subject: crypto: tegra - Fix HASH intermediate result handling
+
+From: Akhil R <akhilrajeev@nvidia.com>
+
+[ Upstream commit ff4b7df0b511b6121f3386607f02c16fb5d41192 ]
+
+The intermediate hash values generated during an update task were
+handled incorrectly in the driver. The values have a defined format for
+each algorithm. Copying and pasting from the HASH_RESULT register
+balantly would not work for all the supported algorithms. This incorrect
+handling causes failures when there is a context switch between multiple
+operations.
+
+To handle the expected format correctly, add a separate buffer for
+storing the intermediate results for each request. Remove the previous
+copy/paste functions which read/wrote to the registers directly. Instead
+configure the hardware to get the intermediate result copied to the
+buffer and use host1x path to restore the intermediate hash results.
+
+Fixes: 0880bb3b00c8 ("crypto: tegra - Add Tegra Security Engine driver")
+Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/tegra/tegra-se-hash.c | 149 +++++++++++++++++----------
+ drivers/crypto/tegra/tegra-se.h      |   1 +
+ 2 files changed, 98 insertions(+), 52 deletions(-)
+
+diff --git a/drivers/crypto/tegra/tegra-se-hash.c b/drivers/crypto/tegra/tegra-se-hash.c
+index 07e4c7320ec8d..8bed13552ab9e 100644
+--- a/drivers/crypto/tegra/tegra-se-hash.c
++++ b/drivers/crypto/tegra/tegra-se-hash.c
+@@ -34,6 +34,7 @@ struct tegra_sha_reqctx {
+       struct tegra_se_datbuf datbuf;
+       struct tegra_se_datbuf residue;
+       struct tegra_se_datbuf digest;
++      struct tegra_se_datbuf intr_res;
+       unsigned int alg;
+       unsigned int config;
+       unsigned int total_len;
+@@ -211,9 +212,62 @@ static int tegra_sha_fallback_export(struct ahash_request *req, void *out)
+       return crypto_ahash_export(&rctx->fallback_req, out);
+ }
+-static int tegra_sha_prep_cmd(struct tegra_se *se, u32 *cpuvaddr,
++static int tegra_se_insert_hash_result(struct tegra_sha_ctx *ctx, u32 *cpuvaddr,
++                                     struct tegra_sha_reqctx *rctx)
++{
++      __be32 *res_be = (__be32 *)rctx->intr_res.buf;
++      u32 *res = (u32 *)rctx->intr_res.buf;
++      int i = 0, j;
++
++      cpuvaddr[i++] = 0;
++      cpuvaddr[i++] = host1x_opcode_setpayload(HASH_RESULT_REG_COUNT);
++      cpuvaddr[i++] = se_host1x_opcode_incr_w(SE_SHA_HASH_RESULT);
++
++      for (j = 0; j < HASH_RESULT_REG_COUNT; j++) {
++              int idx = j;
++
++              /*
++               * The initial, intermediate and final hash value of SHA-384, SHA-512
++               * in SHA_HASH_RESULT registers follow the below layout of bytes.
++               *
++               * +---------------+------------+
++               * | HASH_RESULT_0 | B4...B7    |
++               * +---------------+------------+
++               * | HASH_RESULT_1 | B0...B3    |
++               * +---------------+------------+
++               * | HASH_RESULT_2 | B12...B15  |
++               * +---------------+------------+
++               * | HASH_RESULT_3 | B8...B11   |
++               * +---------------+------------+
++               * |            ......          |
++               * +---------------+------------+
++               * | HASH_RESULT_14| B60...B63  |
++               * +---------------+------------+
++               * | HASH_RESULT_15| B56...B59  |
++               * +---------------+------------+
++               *
++               */
++              if (ctx->alg == SE_ALG_SHA384 || ctx->alg == SE_ALG_SHA512)
++                      idx = (j % 2) ? j - 1 : j + 1;
++
++              /* For SHA-1, SHA-224, SHA-256, SHA-384, SHA-512 the initial
++               * intermediate and final hash value when stored in
++               * SHA_HASH_RESULT registers, the byte order is NOT in
++               * little-endian.
++               */
++              if (ctx->alg <= SE_ALG_SHA512)
++                      cpuvaddr[i++] = be32_to_cpu(res_be[idx]);
++              else
++                      cpuvaddr[i++] = res[idx];
++      }
++
++      return i;
++}
++
++static int tegra_sha_prep_cmd(struct tegra_sha_ctx *ctx, u32 *cpuvaddr,
+                             struct tegra_sha_reqctx *rctx)
+ {
++      struct tegra_se *se = ctx->se;
+       u64 msg_len, msg_left;
+       int i = 0;
+@@ -241,7 +295,7 @@ static int tegra_sha_prep_cmd(struct tegra_se *se, u32 *cpuvaddr,
+       cpuvaddr[i++] = upper_32_bits(msg_left);
+       cpuvaddr[i++] = 0;
+       cpuvaddr[i++] = 0;
+-      cpuvaddr[i++] = host1x_opcode_setpayload(6);
++      cpuvaddr[i++] = host1x_opcode_setpayload(2);
+       cpuvaddr[i++] = se_host1x_opcode_incr_w(SE_SHA_CFG);
+       cpuvaddr[i++] = rctx->config;
+@@ -249,15 +303,29 @@ static int tegra_sha_prep_cmd(struct tegra_se *se, u32 *cpuvaddr,
+               cpuvaddr[i++] = SE_SHA_TASK_HASH_INIT;
+               rctx->task &= ~SHA_FIRST;
+       } else {
+-              cpuvaddr[i++] = 0;
++              /*
++               * If it isn't the first task, program the HASH_RESULT register
++               * with the intermediate result from the previous task
++               */
++              i += tegra_se_insert_hash_result(ctx, cpuvaddr + i, rctx);
+       }
++      cpuvaddr[i++] = host1x_opcode_setpayload(4);
++      cpuvaddr[i++] = se_host1x_opcode_incr_w(SE_SHA_IN_ADDR);
+       cpuvaddr[i++] = rctx->datbuf.addr;
+       cpuvaddr[i++] = (u32)(SE_ADDR_HI_MSB(upper_32_bits(rctx->datbuf.addr)) |
+                               SE_ADDR_HI_SZ(rctx->datbuf.size));
+-      cpuvaddr[i++] = rctx->digest.addr;
+-      cpuvaddr[i++] = (u32)(SE_ADDR_HI_MSB(upper_32_bits(rctx->digest.addr)) |
+-                              SE_ADDR_HI_SZ(rctx->digest.size));
++
++      if (rctx->task & SHA_UPDATE) {
++              cpuvaddr[i++] = rctx->intr_res.addr;
++              cpuvaddr[i++] = (u32)(SE_ADDR_HI_MSB(upper_32_bits(rctx->intr_res.addr)) |
++                                      SE_ADDR_HI_SZ(rctx->intr_res.size));
++      } else {
++              cpuvaddr[i++] = rctx->digest.addr;
++              cpuvaddr[i++] = (u32)(SE_ADDR_HI_MSB(upper_32_bits(rctx->digest.addr)) |
++                                      SE_ADDR_HI_SZ(rctx->digest.size));
++      }
++
+       if (rctx->key_id) {
+               cpuvaddr[i++] = host1x_opcode_setpayload(1);
+               cpuvaddr[i++] = se_host1x_opcode_nonincr_w(SE_SHA_CRYPTO_CFG);
+@@ -266,36 +334,18 @@ static int tegra_sha_prep_cmd(struct tegra_se *se, u32 *cpuvaddr,
+       cpuvaddr[i++] = host1x_opcode_setpayload(1);
+       cpuvaddr[i++] = se_host1x_opcode_nonincr_w(SE_SHA_OPERATION);
+-      cpuvaddr[i++] = SE_SHA_OP_WRSTALL |
+-                      SE_SHA_OP_START |
++      cpuvaddr[i++] = SE_SHA_OP_WRSTALL | SE_SHA_OP_START |
+                       SE_SHA_OP_LASTBUF;
+       cpuvaddr[i++] = se_host1x_opcode_nonincr(host1x_uclass_incr_syncpt_r(), 1);
+       cpuvaddr[i++] = host1x_uclass_incr_syncpt_cond_f(1) |
+                       host1x_uclass_incr_syncpt_indx_f(se->syncpt_id);
+-      dev_dbg(se->dev, "msg len %llu msg left %llu cfg %#x",
+-              msg_len, msg_left, rctx->config);
++      dev_dbg(se->dev, "msg len %llu msg left %llu sz %lu cfg %#x",
++              msg_len, msg_left, rctx->datbuf.size, rctx->config);
+       return i;
+ }
+-static void tegra_sha_copy_hash_result(struct tegra_se *se, struct tegra_sha_reqctx *rctx)
+-{
+-      int i;
+-
+-      for (i = 0; i < HASH_RESULT_REG_COUNT; i++)
+-              rctx->result[i] = readl(se->base + se->hw->regs->result + (i * 4));
+-}
+-
+-static void tegra_sha_paste_hash_result(struct tegra_se *se, struct tegra_sha_reqctx *rctx)
+-{
+-      int i;
+-
+-      for (i = 0; i < HASH_RESULT_REG_COUNT; i++)
+-              writel(rctx->result[i],
+-                     se->base + se->hw->regs->result + (i * 4));
+-}
+-
+ static int tegra_sha_do_init(struct ahash_request *req)
+ {
+       struct tegra_sha_reqctx *rctx = ahash_request_ctx(req);
+@@ -325,8 +375,17 @@ static int tegra_sha_do_init(struct ahash_request *req)
+       if (!rctx->residue.buf)
+               goto resbuf_fail;
++      rctx->intr_res.size = HASH_RESULT_REG_COUNT * 4;
++      rctx->intr_res.buf = dma_alloc_coherent(se->dev, rctx->intr_res.size,
++                                              &rctx->intr_res.addr, GFP_KERNEL);
++      if (!rctx->intr_res.buf)
++              goto intr_res_fail;
++
+       return 0;
++intr_res_fail:
++      dma_free_coherent(se->dev, rctx->residue.size, rctx->residue.buf,
++                        rctx->residue.addr);
+ resbuf_fail:
+       dma_free_coherent(se->dev, rctx->digest.size, rctx->digest.buf,
+                         rctx->digest.addr);
+@@ -356,7 +415,6 @@ static int tegra_sha_do_update(struct ahash_request *req)
+       rctx->src_sg = req->src;
+       rctx->datbuf.size = (req->nbytes + rctx->residue.size) - nresidue;
+-      rctx->total_len += rctx->datbuf.size;
+       /*
+        * If nbytes are less than a block size, copy it residue and
+@@ -365,12 +423,12 @@ static int tegra_sha_do_update(struct ahash_request *req)
+       if (nblks < 1) {
+               scatterwalk_map_and_copy(rctx->residue.buf + rctx->residue.size,
+                                        rctx->src_sg, 0, req->nbytes, 0);
+-
+               rctx->residue.size += req->nbytes;
++
+               return 0;
+       }
+-      rctx->datbuf.buf = dma_alloc_coherent(ctx->se->dev, rctx->datbuf.size,
++      rctx->datbuf.buf = dma_alloc_coherent(se->dev, rctx->datbuf.size,
+                                             &rctx->datbuf.addr, GFP_KERNEL);
+       if (!rctx->datbuf.buf)
+               return -ENOMEM;
+@@ -387,31 +445,15 @@ static int tegra_sha_do_update(struct ahash_request *req)
+       /* Update residue value with the residue after current block */
+       rctx->residue.size = nresidue;
++      rctx->total_len += rctx->datbuf.size;
+       rctx->config = tegra_sha_get_config(rctx->alg) |
+-                      SE_SHA_DST_HASH_REG;
+-
+-      /*
+-       * If this is not the first 'update' call, paste the previous copied
+-       * intermediate results to the registers so that it gets picked up.
+-       * This is to support the import/export functionality.
+-       */
+-      if (!(rctx->task & SHA_FIRST))
+-              tegra_sha_paste_hash_result(se, rctx);
+-
+-      size = tegra_sha_prep_cmd(se, cpuvaddr, rctx);
++                      SE_SHA_DST_MEMORY;
++      size = tegra_sha_prep_cmd(ctx, cpuvaddr, rctx);
+       ret = tegra_se_host1x_submit(se, se->cmdbuf, size);
+-      /*
+-       * If this is not the final update, copy the intermediate results
+-       * from the registers so that it can be used in the next 'update'
+-       * call. This is to support the import/export functionality.
+-       */
+-      if (!(rctx->task & SHA_FINAL))
+-              tegra_sha_copy_hash_result(se, rctx);
+-
+-      dma_free_coherent(ctx->se->dev, rctx->datbuf.size,
++      dma_free_coherent(se->dev, rctx->datbuf.size,
+                         rctx->datbuf.buf, rctx->datbuf.addr);
+       return ret;
+@@ -443,8 +485,7 @@ static int tegra_sha_do_final(struct ahash_request *req)
+       rctx->config = tegra_sha_get_config(rctx->alg) |
+                      SE_SHA_DST_MEMORY;
+-      size = tegra_sha_prep_cmd(se, cpuvaddr, rctx);
+-
++      size = tegra_sha_prep_cmd(ctx, cpuvaddr, rctx);
+       ret = tegra_se_host1x_submit(se, se->cmdbuf, size);
+       if (ret)
+               goto out;
+@@ -461,6 +502,10 @@ static int tegra_sha_do_final(struct ahash_request *req)
+                         rctx->residue.buf, rctx->residue.addr);
+       dma_free_coherent(se->dev, rctx->digest.size, rctx->digest.buf,
+                         rctx->digest.addr);
++
++      dma_free_coherent(se->dev, rctx->intr_res.size, rctx->intr_res.buf,
++                        rctx->intr_res.addr);
++
+       return ret;
+ }
+diff --git a/drivers/crypto/tegra/tegra-se.h b/drivers/crypto/tegra/tegra-se.h
+index e1ec37bfb80a8..0f5bcf27358bd 100644
+--- a/drivers/crypto/tegra/tegra-se.h
++++ b/drivers/crypto/tegra/tegra-se.h
+@@ -24,6 +24,7 @@
+ #define SE_STREAM_ID                                  0x90
+ #define SE_SHA_CFG                                    0x4004
++#define SE_SHA_IN_ADDR                                        0x400c
+ #define SE_SHA_KEY_ADDR                                       0x4094
+ #define SE_SHA_KEY_DATA                                       0x4098
+ #define SE_SHA_KEYMANIFEST                            0x409c
+-- 
+2.39.5
+
diff --git a/queue-6.14/crypto-tegra-reserve-keyslots-to-allocate-dynamicall.patch b/queue-6.14/crypto-tegra-reserve-keyslots-to-allocate-dynamicall.patch
new file mode 100644 (file)
index 0000000..805047d
--- /dev/null
@@ -0,0 +1,499 @@
+From fdc1292745f6360fbea6dfb4c1321a35ac93dad6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Feb 2025 14:46:09 +0530
+Subject: crypto: tegra - Reserve keyslots to allocate dynamically
+
+From: Akhil R <akhilrajeev@nvidia.com>
+
+[ Upstream commit b157e7a228aee9b48c2de05129476b822aa7956d ]
+
+The HW supports only storing 15 keys at a time. This limits the number
+of tfms that can work without failutes. Reserve keyslots to solve this
+and use the reserved ones during the encryption/decryption operation.
+This allow users to have the capability of hardware protected keys
+and faster operations if there are limited number of tfms while not
+halting the operation if there are more tfms.
+
+Fixes: 0880bb3b00c8 ("crypto: tegra - Add Tegra Security Engine driver")
+Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/tegra/tegra-se-aes.c | 139 +++++++++++++++++++++++-----
+ drivers/crypto/tegra/tegra-se-key.c |  19 +++-
+ drivers/crypto/tegra/tegra-se.h     |  28 ++++++
+ 3 files changed, 164 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/crypto/tegra/tegra-se-aes.c b/drivers/crypto/tegra/tegra-se-aes.c
+index a1b469c3a55ba..ca9d0cca1f748 100644
+--- a/drivers/crypto/tegra/tegra-se-aes.c
++++ b/drivers/crypto/tegra/tegra-se-aes.c
+@@ -28,6 +28,9 @@ struct tegra_aes_ctx {
+       u32 ivsize;
+       u32 key1_id;
+       u32 key2_id;
++      u32 keylen;
++      u8 key1[AES_MAX_KEY_SIZE];
++      u8 key2[AES_MAX_KEY_SIZE];
+ };
+ struct tegra_aes_reqctx {
+@@ -43,8 +46,9 @@ struct tegra_aead_ctx {
+       struct tegra_se *se;
+       unsigned int authsize;
+       u32 alg;
+-      u32 keylen;
+       u32 key_id;
++      u32 keylen;
++      u8 key[AES_MAX_KEY_SIZE];
+ };
+ struct tegra_aead_reqctx {
+@@ -56,8 +60,8 @@ struct tegra_aead_reqctx {
+       unsigned int cryptlen;
+       unsigned int authsize;
+       bool encrypt;
+-      u32 config;
+       u32 crypto_config;
++      u32 config;
+       u32 key_id;
+       u32 iv[4];
+       u8 authdata[16];
+@@ -67,6 +71,8 @@ struct tegra_cmac_ctx {
+       struct tegra_se *se;
+       unsigned int alg;
+       u32 key_id;
++      u32 keylen;
++      u8 key[AES_MAX_KEY_SIZE];
+       struct crypto_shash *fallback_tfm;
+ };
+@@ -260,11 +266,13 @@ static int tegra_aes_do_one_req(struct crypto_engine *engine, void *areq)
+       struct tegra_aes_ctx *ctx = crypto_skcipher_ctx(crypto_skcipher_reqtfm(req));
+       struct tegra_aes_reqctx *rctx = skcipher_request_ctx(req);
+       struct tegra_se *se = ctx->se;
+-      unsigned int cmdlen;
++      unsigned int cmdlen, key1_id, key2_id;
+       int ret;
+       rctx->iv = (u32 *)req->iv;
+       rctx->len = req->cryptlen;
++      key1_id = ctx->key1_id;
++      key2_id = ctx->key2_id;
+       /* Pad input to AES Block size */
+       if (ctx->alg != SE_ALG_XTS) {
+@@ -282,6 +290,29 @@ static int tegra_aes_do_one_req(struct crypto_engine *engine, void *areq)
+       scatterwalk_map_and_copy(rctx->datbuf.buf, req->src, 0, req->cryptlen, 0);
++      rctx->config = tegra234_aes_cfg(ctx->alg, rctx->encrypt);
++      rctx->crypto_config = tegra234_aes_crypto_cfg(ctx->alg, rctx->encrypt);
++
++      if (!key1_id) {
++              ret = tegra_key_submit_reserved_aes(ctx->se, ctx->key1,
++                                                  ctx->keylen, ctx->alg, &key1_id);
++              if (ret)
++                      goto out;
++      }
++
++      rctx->crypto_config |= SE_AES_KEY_INDEX(key1_id);
++
++      if (ctx->alg == SE_ALG_XTS) {
++              if (!key2_id) {
++                      ret = tegra_key_submit_reserved_xts(ctx->se, ctx->key2,
++                                                          ctx->keylen, ctx->alg, &key2_id);
++                      if (ret)
++                              goto out;
++              }
++
++              rctx->crypto_config |= SE_AES_KEY2_INDEX(key2_id);
++      }
++
+       /* Prepare the command and submit for execution */
+       cmdlen = tegra_aes_prep_cmd(ctx, rctx);
+       ret = tegra_se_host1x_submit(se, se->cmdbuf, cmdlen);
+@@ -290,10 +321,17 @@ static int tegra_aes_do_one_req(struct crypto_engine *engine, void *areq)
+       tegra_aes_update_iv(req, ctx);
+       scatterwalk_map_and_copy(rctx->datbuf.buf, req->dst, 0, req->cryptlen, 1);
++out:
+       /* Free the buffer */
+       dma_free_coherent(ctx->se->dev, rctx->datbuf.size,
+                         rctx->datbuf.buf, rctx->datbuf.addr);
++      if (tegra_key_is_reserved(key1_id))
++              tegra_key_invalidate_reserved(ctx->se, key1_id, ctx->alg);
++
++      if (tegra_key_is_reserved(key2_id))
++              tegra_key_invalidate_reserved(ctx->se, key2_id, ctx->alg);
++
+ out_finalize:
+       crypto_finalize_skcipher_request(se->engine, req, ret);
+@@ -316,6 +354,7 @@ static int tegra_aes_cra_init(struct crypto_skcipher *tfm)
+       ctx->se = se_alg->se_dev;
+       ctx->key1_id = 0;
+       ctx->key2_id = 0;
++      ctx->keylen = 0;
+       algname = crypto_tfm_alg_name(&tfm->base);
+       ret = se_algname_to_algid(algname);
+@@ -344,13 +383,20 @@ static int tegra_aes_setkey(struct crypto_skcipher *tfm,
+                           const u8 *key, u32 keylen)
+ {
+       struct tegra_aes_ctx *ctx = crypto_skcipher_ctx(tfm);
++      int ret;
+       if (aes_check_keylen(keylen)) {
+               dev_dbg(ctx->se->dev, "invalid key length (%d)\n", keylen);
+               return -EINVAL;
+       }
+-      return tegra_key_submit(ctx->se, key, keylen, ctx->alg, &ctx->key1_id);
++      ret = tegra_key_submit(ctx->se, key, keylen, ctx->alg, &ctx->key1_id);
++      if (ret) {
++              ctx->keylen = keylen;
++              memcpy(ctx->key1, key, keylen);
++      }
++
++      return 0;
+ }
+ static int tegra_xts_setkey(struct crypto_skcipher *tfm,
+@@ -368,11 +414,17 @@ static int tegra_xts_setkey(struct crypto_skcipher *tfm,
+       ret = tegra_key_submit(ctx->se, key, len,
+                              ctx->alg, &ctx->key1_id);
+-      if (ret)
+-              return ret;
++      if (ret) {
++              ctx->keylen = len;
++              memcpy(ctx->key1, key, len);
++      }
+-      return tegra_key_submit(ctx->se, key + len, len,
++      ret = tegra_key_submit(ctx->se, key + len, len,
+                              ctx->alg, &ctx->key2_id);
++      if (ret) {
++              ctx->keylen = len;
++              memcpy(ctx->key2, key + len, len);
++      }
+       return 0;
+ }
+@@ -450,12 +502,6 @@ static int tegra_aes_crypt(struct skcipher_request *req, bool encrypt)
+               req->iv = NULL;
+       rctx->encrypt = encrypt;
+-      rctx->config = tegra234_aes_cfg(ctx->alg, encrypt);
+-      rctx->crypto_config = tegra234_aes_crypto_cfg(ctx->alg, encrypt);
+-      rctx->crypto_config |= SE_AES_KEY_INDEX(ctx->key1_id);
+-
+-      if (ctx->key2_id)
+-              rctx->crypto_config |= SE_AES_KEY2_INDEX(ctx->key2_id);
+       return crypto_transfer_skcipher_request_to_engine(ctx->se->engine, req);
+ }
+@@ -721,7 +767,7 @@ static int tegra_gcm_do_gmac(struct tegra_aead_ctx *ctx, struct tegra_aead_reqct
+       rctx->config = tegra234_aes_cfg(SE_ALG_GMAC, rctx->encrypt);
+       rctx->crypto_config = tegra234_aes_crypto_cfg(SE_ALG_GMAC, rctx->encrypt) |
+-                            SE_AES_KEY_INDEX(ctx->key_id);
++                            SE_AES_KEY_INDEX(rctx->key_id);
+       cmdlen = tegra_gmac_prep_cmd(ctx, rctx);
+@@ -738,7 +784,7 @@ static int tegra_gcm_do_crypt(struct tegra_aead_ctx *ctx, struct tegra_aead_reqc
+       rctx->config = tegra234_aes_cfg(SE_ALG_GCM, rctx->encrypt);
+       rctx->crypto_config = tegra234_aes_crypto_cfg(SE_ALG_GCM, rctx->encrypt) |
+-                            SE_AES_KEY_INDEX(ctx->key_id);
++                            SE_AES_KEY_INDEX(rctx->key_id);
+       /* Prepare command and submit */
+       cmdlen = tegra_gcm_crypt_prep_cmd(ctx, rctx);
+@@ -761,7 +807,7 @@ static int tegra_gcm_do_final(struct tegra_aead_ctx *ctx, struct tegra_aead_reqc
+       rctx->config = tegra234_aes_cfg(SE_ALG_GCM_FINAL, rctx->encrypt);
+       rctx->crypto_config = tegra234_aes_crypto_cfg(SE_ALG_GCM_FINAL, rctx->encrypt) |
+-                            SE_AES_KEY_INDEX(ctx->key_id);
++                            SE_AES_KEY_INDEX(rctx->key_id);
+       /* Prepare command and submit */
+       cmdlen = tegra_gcm_prep_final_cmd(se, cpuvaddr, rctx);
+@@ -892,7 +938,7 @@ static int tegra_ccm_do_cbcmac(struct tegra_aead_ctx *ctx, struct tegra_aead_req
+       rctx->config = tegra234_aes_cfg(SE_ALG_CBC_MAC, rctx->encrypt);
+       rctx->crypto_config = tegra234_aes_crypto_cfg(SE_ALG_CBC_MAC,
+                                                     rctx->encrypt) |
+-                                                    SE_AES_KEY_INDEX(ctx->key_id);
++                                                    SE_AES_KEY_INDEX(rctx->key_id);
+       /* Prepare command and submit */
+       cmdlen = tegra_cbcmac_prep_cmd(ctx, rctx);
+@@ -1079,7 +1125,7 @@ static int tegra_ccm_do_ctr(struct tegra_aead_ctx *ctx, struct tegra_aead_reqctx
+       rctx->config = tegra234_aes_cfg(SE_ALG_CTR, rctx->encrypt);
+       rctx->crypto_config = tegra234_aes_crypto_cfg(SE_ALG_CTR, rctx->encrypt) |
+-                            SE_AES_KEY_INDEX(ctx->key_id);
++                            SE_AES_KEY_INDEX(rctx->key_id);
+       /* Copy authdata in the top of buffer for encryption/decryption */
+       if (rctx->encrypt)
+@@ -1160,6 +1206,8 @@ static int tegra_ccm_do_one_req(struct crypto_engine *engine, void *areq)
+       if (ret)
+               goto out_finalize;
++      rctx->key_id = ctx->key_id;
++
+       /* Allocate buffers required */
+       rctx->inbuf.size = rctx->assoclen + rctx->authsize + rctx->cryptlen + 100;
+       rctx->inbuf.buf = dma_alloc_coherent(ctx->se->dev, rctx->inbuf.size,
+@@ -1175,6 +1223,13 @@ static int tegra_ccm_do_one_req(struct crypto_engine *engine, void *areq)
+               goto out_free_inbuf;
+       }
++      if (!ctx->key_id) {
++              ret = tegra_key_submit_reserved_aes(ctx->se, ctx->key,
++                                                  ctx->keylen, ctx->alg, &rctx->key_id);
++              if (ret)
++                      goto out;
++      }
++
+       if (rctx->encrypt) {
+               /* CBC MAC Operation */
+               ret = tegra_ccm_compute_auth(ctx, rctx);
+@@ -1205,6 +1260,9 @@ static int tegra_ccm_do_one_req(struct crypto_engine *engine, void *areq)
+       dma_free_coherent(ctx->se->dev, rctx->outbuf.size,
+                         rctx->inbuf.buf, rctx->inbuf.addr);
++      if (tegra_key_is_reserved(rctx->key_id))
++              tegra_key_invalidate_reserved(ctx->se, rctx->key_id, ctx->alg);
++
+ out_finalize:
+       crypto_finalize_aead_request(ctx->se->engine, req, ret);
+@@ -1232,6 +1290,8 @@ static int tegra_gcm_do_one_req(struct crypto_engine *engine, void *areq)
+       memcpy(rctx->iv, req->iv, GCM_AES_IV_SIZE);
+       rctx->iv[3] = (1 << 24);
++      rctx->key_id = ctx->key_id;
++
+       /* Allocate buffers required */
+       rctx->inbuf.size = rctx->assoclen + rctx->authsize + rctx->cryptlen;
+       rctx->inbuf.buf = dma_alloc_coherent(ctx->se->dev, rctx->inbuf.size,
+@@ -1249,6 +1309,13 @@ static int tegra_gcm_do_one_req(struct crypto_engine *engine, void *areq)
+               goto out_free_inbuf;
+       }
++      if (!ctx->key_id) {
++              ret = tegra_key_submit_reserved_aes(ctx->se, ctx->key,
++                                                  ctx->keylen, ctx->alg, &rctx->key_id);
++              if (ret)
++                      goto out;
++      }
++
+       /* If there is associated data perform GMAC operation */
+       if (rctx->assoclen) {
+               ret = tegra_gcm_do_gmac(ctx, rctx);
+@@ -1279,6 +1346,9 @@ static int tegra_gcm_do_one_req(struct crypto_engine *engine, void *areq)
+       dma_free_coherent(ctx->se->dev, rctx->inbuf.size,
+                         rctx->inbuf.buf, rctx->inbuf.addr);
++      if (tegra_key_is_reserved(rctx->key_id))
++              tegra_key_invalidate_reserved(ctx->se, rctx->key_id, ctx->alg);
++
+ out_finalize:
+       crypto_finalize_aead_request(ctx->se->engine, req, ret);
+@@ -1301,6 +1371,7 @@ static int tegra_aead_cra_init(struct crypto_aead *tfm)
+       ctx->se = se_alg->se_dev;
+       ctx->key_id = 0;
++      ctx->keylen = 0;
+       ret = se_algname_to_algid(algname);
+       if (ret < 0) {
+@@ -1382,13 +1453,20 @@ static int tegra_aead_setkey(struct crypto_aead *tfm,
+                            const u8 *key, u32 keylen)
+ {
+       struct tegra_aead_ctx *ctx = crypto_aead_ctx(tfm);
++      int ret;
+       if (aes_check_keylen(keylen)) {
+               dev_dbg(ctx->se->dev, "invalid key length (%d)\n", keylen);
+               return -EINVAL;
+       }
+-      return tegra_key_submit(ctx->se, key, keylen, ctx->alg, &ctx->key_id);
++      ret = tegra_key_submit(ctx->se, key, keylen, ctx->alg, &ctx->key_id);
++      if (ret) {
++              ctx->keylen = keylen;
++              memcpy(ctx->key, key, keylen);
++      }
++
++      return 0;
+ }
+ static unsigned int tegra_cmac_prep_cmd(struct tegra_cmac_ctx *ctx,
+@@ -1473,6 +1551,7 @@ static int tegra_cmac_do_init(struct ahash_request *req)
+       rctx->total_len = 0;
+       rctx->datbuf.size = 0;
+       rctx->residue.size = 0;
++      rctx->key_id = ctx->key_id;
+       rctx->task |= SHA_FIRST;
+       rctx->blk_size = crypto_ahash_blocksize(tfm);
+@@ -1517,7 +1596,7 @@ static int tegra_cmac_do_update(struct ahash_request *req)
+       rctx->datbuf.size = (req->nbytes + rctx->residue.size) - nresidue;
+       rctx->total_len += rctx->datbuf.size;
+       rctx->config = tegra234_aes_cfg(SE_ALG_CMAC, 0);
+-      rctx->crypto_config = SE_AES_KEY_INDEX(ctx->key_id);
++      rctx->crypto_config = SE_AES_KEY_INDEX(rctx->key_id);
+       /*
+        * Keep one block and residue bytes in residue and
+@@ -1643,6 +1722,13 @@ static int tegra_cmac_do_one_req(struct crypto_engine *engine, void *areq)
+               rctx->task &= ~SHA_INIT;
+       }
++      if (!ctx->key_id) {
++              ret = tegra_key_submit_reserved_aes(ctx->se, ctx->key,
++                                                  ctx->keylen, ctx->alg, &rctx->key_id);
++              if (ret)
++                      goto out;
++      }
++
+       if (rctx->task & SHA_UPDATE) {
+               ret = tegra_cmac_do_update(req);
+               if (ret)
+@@ -1659,6 +1745,9 @@ static int tegra_cmac_do_one_req(struct crypto_engine *engine, void *areq)
+               rctx->task &= ~SHA_FINAL;
+       }
+ out:
++      if (tegra_key_is_reserved(rctx->key_id))
++              tegra_key_invalidate_reserved(ctx->se, rctx->key_id, ctx->alg);
++
+       crypto_finalize_hash_request(se->engine, req, ret);
+       return 0;
+@@ -1699,6 +1788,7 @@ static int tegra_cmac_cra_init(struct crypto_tfm *tfm)
+       ctx->se = se_alg->se_dev;
+       ctx->key_id = 0;
++      ctx->keylen = 0;
+       ret = se_algname_to_algid(algname);
+       if (ret < 0) {
+@@ -1727,6 +1817,7 @@ static int tegra_cmac_setkey(struct crypto_ahash *tfm, const u8 *key,
+                            unsigned int keylen)
+ {
+       struct tegra_cmac_ctx *ctx = crypto_ahash_ctx(tfm);
++      int ret;
+       if (aes_check_keylen(keylen)) {
+               dev_dbg(ctx->se->dev, "invalid key length (%d)\n", keylen);
+@@ -1736,7 +1827,13 @@ static int tegra_cmac_setkey(struct crypto_ahash *tfm, const u8 *key,
+       if (ctx->fallback_tfm)
+               crypto_shash_setkey(ctx->fallback_tfm, key, keylen);
+-      return tegra_key_submit(ctx->se, key, keylen, ctx->alg, &ctx->key_id);
++      ret = tegra_key_submit(ctx->se, key, keylen, ctx->alg, &ctx->key_id);
++      if (ret) {
++              ctx->keylen = keylen;
++              memcpy(ctx->key, key, keylen);
++      }
++
++      return 0;
+ }
+ static int tegra_cmac_init(struct ahash_request *req)
+diff --git a/drivers/crypto/tegra/tegra-se-key.c b/drivers/crypto/tegra/tegra-se-key.c
+index 276b261fb6df1..956fa9b4e9b1a 100644
+--- a/drivers/crypto/tegra/tegra-se-key.c
++++ b/drivers/crypto/tegra/tegra-se-key.c
+@@ -141,6 +141,23 @@ void tegra_key_invalidate(struct tegra_se *se, u32 keyid, u32 alg)
+       tegra_keyslot_free(keyid);
+ }
++void tegra_key_invalidate_reserved(struct tegra_se *se, u32 keyid, u32 alg)
++{
++      u8 zkey[AES_MAX_KEY_SIZE] = {0};
++
++      if (!keyid)
++              return;
++
++      /* Overwrite the key with 0s */
++      tegra_key_insert(se, zkey, AES_MAX_KEY_SIZE, keyid, alg);
++}
++
++inline int tegra_key_submit_reserved(struct tegra_se *se, const u8 *key,
++                                   u32 keylen, u32 alg, u32 *keyid)
++{
++      return tegra_key_insert(se, key, keylen, *keyid, alg);
++}
++
+ int tegra_key_submit(struct tegra_se *se, const u8 *key, u32 keylen, u32 alg, u32 *keyid)
+ {
+       int ret;
+@@ -149,7 +166,7 @@ int tegra_key_submit(struct tegra_se *se, const u8 *key, u32 keylen, u32 alg, u3
+       if (!tegra_key_in_kslt(*keyid)) {
+               *keyid = tegra_keyslot_alloc();
+               if (!(*keyid)) {
+-                      dev_err(se->dev, "failed to allocate key slot\n");
++                      dev_dbg(se->dev, "failed to allocate key slot\n");
+                       return -ENOMEM;
+               }
+       }
+diff --git a/drivers/crypto/tegra/tegra-se.h b/drivers/crypto/tegra/tegra-se.h
+index 0f5bcf27358bd..b6cac9384f666 100644
+--- a/drivers/crypto/tegra/tegra-se.h
++++ b/drivers/crypto/tegra/tegra-se.h
+@@ -342,6 +342,9 @@
+ #define SE_MAX_KEYSLOT                                15
+ #define SE_MAX_MEM_ALLOC                      SZ_4M
++#define TEGRA_AES_RESERVED_KSLT                       14
++#define TEGRA_XTS_RESERVED_KSLT                       15
++
+ #define SHA_FIRST     BIT(0)
+ #define SHA_INIT      BIT(1)
+ #define SHA_UPDATE    BIT(2)
+@@ -502,9 +505,34 @@ void tegra_deinit_aes(struct tegra_se *se);
+ void tegra_deinit_hash(struct tegra_se *se);
+ int tegra_key_submit(struct tegra_se *se, const u8 *key,
+                    u32 keylen, u32 alg, u32 *keyid);
++
++int tegra_key_submit_reserved(struct tegra_se *se, const u8 *key,
++                            u32 keylen, u32 alg, u32 *keyid);
++
+ void tegra_key_invalidate(struct tegra_se *se, u32 keyid, u32 alg);
++void tegra_key_invalidate_reserved(struct tegra_se *se, u32 keyid, u32 alg);
+ int tegra_se_host1x_submit(struct tegra_se *se, struct tegra_se_cmdbuf *cmdbuf, u32 size);
++static inline int tegra_key_submit_reserved_aes(struct tegra_se *se, const u8 *key,
++                                              u32 keylen, u32 alg, u32 *keyid)
++{
++      *keyid = TEGRA_AES_RESERVED_KSLT;
++      return tegra_key_submit_reserved(se, key, keylen, alg, keyid);
++}
++
++static inline int tegra_key_submit_reserved_xts(struct tegra_se *se, const u8 *key,
++                                              u32 keylen, u32 alg, u32 *keyid)
++{
++      *keyid = TEGRA_XTS_RESERVED_KSLT;
++      return tegra_key_submit_reserved(se, key, keylen, alg, keyid);
++}
++
++static inline bool tegra_key_is_reserved(u32 keyid)
++{
++      return ((keyid == TEGRA_AES_RESERVED_KSLT) ||
++              (keyid == TEGRA_XTS_RESERVED_KSLT));
++}
++
+ /* HOST1x OPCODES */
+ static inline u32 host1x_opcode_setpayload(unsigned int payload)
+ {
+-- 
+2.39.5
+
diff --git a/queue-6.14/crypto-tegra-set-iv-to-null-explicitly-for-aes-ecb.patch b/queue-6.14/crypto-tegra-set-iv-to-null-explicitly-for-aes-ecb.patch
new file mode 100644 (file)
index 0000000..6d95683
--- /dev/null
@@ -0,0 +1,40 @@
+From 0536036485a5ad970b82e16aae85b97ac3513b70 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Feb 2025 14:46:08 +0530
+Subject: crypto: tegra - Set IV to NULL explicitly for AES ECB
+
+From: Akhil R <akhilrajeev@nvidia.com>
+
+[ Upstream commit bde558220866e74f19450e16d9a2472b488dfedf ]
+
+It may happen that the variable req->iv may have stale values or
+zero sized buffer by default and may end up getting used during
+encryption/decryption. This inturn may corrupt the results or break the
+operation. Set the req->iv variable to NULL explicitly for algorithms
+like AES-ECB where IV is not used.
+
+Fixes: 0880bb3b00c8 ("crypto: tegra - Add Tegra Security Engine driver")
+Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/tegra/tegra-se-aes.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/crypto/tegra/tegra-se-aes.c b/drivers/crypto/tegra/tegra-se-aes.c
+index cdcf05e235cad..be0a0b51f5a59 100644
+--- a/drivers/crypto/tegra/tegra-se-aes.c
++++ b/drivers/crypto/tegra/tegra-se-aes.c
+@@ -443,6 +443,9 @@ static int tegra_aes_crypt(struct skcipher_request *req, bool encrypt)
+       if (!req->cryptlen)
+               return 0;
++      if (ctx->alg == SE_ALG_ECB)
++              req->iv = NULL;
++
+       rctx->encrypt = encrypt;
+       rctx->config = tegra234_aes_cfg(ctx->alg, encrypt);
+       rctx->crypto_config = tegra234_aes_crypto_cfg(ctx->alg, encrypt);
+-- 
+2.39.5
+
diff --git a/queue-6.14/crypto-tegra-transfer-hash-init-function-to-crypto-e.patch b/queue-6.14/crypto-tegra-transfer-hash-init-function-to-crypto-e.patch
new file mode 100644 (file)
index 0000000..5ea576e
--- /dev/null
@@ -0,0 +1,311 @@
+From 9640ad86228f3af9cb0460ee64c18a36a9c77925 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Feb 2025 14:46:05 +0530
+Subject: crypto: tegra - Transfer HASH init function to crypto engine
+
+From: Akhil R <akhilrajeev@nvidia.com>
+
+[ Upstream commit 97ee15ea101629d2ffe21d3c5dc03b8d8be43603 ]
+
+Ahash init() function was called asynchronous to the crypto engine queue.
+This could corrupt the request context if there is any ongoing operation
+for the same request. Queue the init function as well to the crypto
+engine queue so that this scenario can be avoided.
+
+Fixes: 0880bb3b00c8 ("crypto: tegra - Add Tegra Security Engine driver")
+Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Stable-dep-of: ff4b7df0b511 ("crypto: tegra - Fix HASH intermediate result handling")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/tegra/tegra-se-aes.c  |  81 ++++++++++++---------
+ drivers/crypto/tegra/tegra-se-hash.c | 101 +++++++++++++++------------
+ drivers/crypto/tegra/tegra-se.h      |   5 +-
+ 3 files changed, 109 insertions(+), 78 deletions(-)
+
+diff --git a/drivers/crypto/tegra/tegra-se-aes.c b/drivers/crypto/tegra/tegra-se-aes.c
+index dd147fa4af977..5d8237cda58f0 100644
+--- a/drivers/crypto/tegra/tegra-se-aes.c
++++ b/drivers/crypto/tegra/tegra-se-aes.c
+@@ -1453,6 +1453,34 @@ static void tegra_cmac_paste_result(struct tegra_se *se, struct tegra_cmac_reqct
+                      se->base + se->hw->regs->result + (i * 4));
+ }
++static int tegra_cmac_do_init(struct ahash_request *req)
++{
++      struct tegra_cmac_reqctx *rctx = ahash_request_ctx(req);
++      struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
++      struct tegra_cmac_ctx *ctx = crypto_ahash_ctx(tfm);
++      struct tegra_se *se = ctx->se;
++      int i;
++
++      rctx->total_len = 0;
++      rctx->datbuf.size = 0;
++      rctx->residue.size = 0;
++      rctx->task |= SHA_FIRST;
++      rctx->blk_size = crypto_ahash_blocksize(tfm);
++
++      rctx->residue.buf = dma_alloc_coherent(se->dev, rctx->blk_size * 2,
++                                             &rctx->residue.addr, GFP_KERNEL);
++      if (!rctx->residue.buf)
++              return -ENOMEM;
++
++      rctx->residue.size = 0;
++
++      /* Clear any previous result */
++      for (i = 0; i < CMAC_RESULT_REG_COUNT; i++)
++              writel(0, se->base + se->hw->regs->result + (i * 4));
++
++      return 0;
++}
++
+ static int tegra_cmac_do_update(struct ahash_request *req)
+ {
+       struct tegra_cmac_reqctx *rctx = ahash_request_ctx(req);
+@@ -1598,6 +1626,14 @@ static int tegra_cmac_do_one_req(struct crypto_engine *engine, void *areq)
+       struct tegra_se *se = ctx->se;
+       int ret = 0;
++      if (rctx->task & SHA_INIT) {
++              ret = tegra_cmac_do_init(req);
++              if (ret)
++                      goto out;
++
++              rctx->task &= ~SHA_INIT;
++      }
++
+       if (rctx->task & SHA_UPDATE) {
+               ret = tegra_cmac_do_update(req);
+               if (ret)
+@@ -1678,34 +1714,6 @@ static void tegra_cmac_cra_exit(struct crypto_tfm *tfm)
+       tegra_key_invalidate(ctx->se, ctx->key_id, ctx->alg);
+ }
+-static int tegra_cmac_init(struct ahash_request *req)
+-{
+-      struct tegra_cmac_reqctx *rctx = ahash_request_ctx(req);
+-      struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+-      struct tegra_cmac_ctx *ctx = crypto_ahash_ctx(tfm);
+-      struct tegra_se *se = ctx->se;
+-      int i;
+-
+-      rctx->total_len = 0;
+-      rctx->datbuf.size = 0;
+-      rctx->residue.size = 0;
+-      rctx->task = SHA_FIRST;
+-      rctx->blk_size = crypto_ahash_blocksize(tfm);
+-
+-      rctx->residue.buf = dma_alloc_coherent(se->dev, rctx->blk_size * 2,
+-                                             &rctx->residue.addr, GFP_KERNEL);
+-      if (!rctx->residue.buf)
+-              return -ENOMEM;
+-
+-      rctx->residue.size = 0;
+-
+-      /* Clear any previous result */
+-      for (i = 0; i < CMAC_RESULT_REG_COUNT; i++)
+-              writel(0, se->base + se->hw->regs->result + (i * 4));
+-
+-      return 0;
+-}
+-
+ static int tegra_cmac_setkey(struct crypto_ahash *tfm, const u8 *key,
+                            unsigned int keylen)
+ {
+@@ -1722,6 +1730,17 @@ static int tegra_cmac_setkey(struct crypto_ahash *tfm, const u8 *key,
+       return tegra_key_submit(ctx->se, key, keylen, ctx->alg, &ctx->key_id);
+ }
++static int tegra_cmac_init(struct ahash_request *req)
++{
++      struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
++      struct tegra_cmac_ctx *ctx = crypto_ahash_ctx(tfm);
++      struct tegra_cmac_reqctx *rctx = ahash_request_ctx(req);
++
++      rctx->task = SHA_INIT;
++
++      return crypto_transfer_hash_request_to_engine(ctx->se->engine, req);
++}
++
+ static int tegra_cmac_update(struct ahash_request *req)
+ {
+       struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+@@ -1760,13 +1779,9 @@ static int tegra_cmac_digest(struct ahash_request *req)
+       struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+       struct tegra_cmac_ctx *ctx = crypto_ahash_ctx(tfm);
+       struct tegra_cmac_reqctx *rctx = ahash_request_ctx(req);
+-      int ret;
+-      ret = tegra_cmac_init(req);
+-      if (ret)
+-              return ret;
++      rctx->task |= SHA_INIT | SHA_UPDATE | SHA_FINAL;
+-      rctx->task |= SHA_UPDATE | SHA_FINAL;
+       return crypto_transfer_hash_request_to_engine(ctx->se->engine, req);
+ }
+diff --git a/drivers/crypto/tegra/tegra-se-hash.c b/drivers/crypto/tegra/tegra-se-hash.c
+index 0ae5ce67bdd04..07e4c7320ec8d 100644
+--- a/drivers/crypto/tegra/tegra-se-hash.c
++++ b/drivers/crypto/tegra/tegra-se-hash.c
+@@ -296,6 +296,44 @@ static void tegra_sha_paste_hash_result(struct tegra_se *se, struct tegra_sha_re
+                      se->base + se->hw->regs->result + (i * 4));
+ }
++static int tegra_sha_do_init(struct ahash_request *req)
++{
++      struct tegra_sha_reqctx *rctx = ahash_request_ctx(req);
++      struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
++      struct tegra_sha_ctx *ctx = crypto_ahash_ctx(tfm);
++      struct tegra_se *se = ctx->se;
++
++      if (ctx->fallback)
++              return tegra_sha_fallback_init(req);
++
++      rctx->total_len = 0;
++      rctx->datbuf.size = 0;
++      rctx->residue.size = 0;
++      rctx->key_id = ctx->key_id;
++      rctx->task |= SHA_FIRST;
++      rctx->alg = ctx->alg;
++      rctx->blk_size = crypto_ahash_blocksize(tfm);
++      rctx->digest.size = crypto_ahash_digestsize(tfm);
++
++      rctx->digest.buf = dma_alloc_coherent(se->dev, rctx->digest.size,
++                                            &rctx->digest.addr, GFP_KERNEL);
++      if (!rctx->digest.buf)
++              goto digbuf_fail;
++
++      rctx->residue.buf = dma_alloc_coherent(se->dev, rctx->blk_size,
++                                             &rctx->residue.addr, GFP_KERNEL);
++      if (!rctx->residue.buf)
++              goto resbuf_fail;
++
++      return 0;
++
++resbuf_fail:
++      dma_free_coherent(se->dev, rctx->digest.size, rctx->digest.buf,
++                        rctx->digest.addr);
++digbuf_fail:
++      return -ENOMEM;
++}
++
+ static int tegra_sha_do_update(struct ahash_request *req)
+ {
+       struct tegra_sha_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
+@@ -435,6 +473,14 @@ static int tegra_sha_do_one_req(struct crypto_engine *engine, void *areq)
+       struct tegra_se *se = ctx->se;
+       int ret = 0;
++      if (rctx->task & SHA_INIT) {
++              ret = tegra_sha_do_init(req);
++              if (ret)
++                      goto out;
++
++              rctx->task &= ~SHA_INIT;
++      }
++
+       if (rctx->task & SHA_UPDATE) {
+               ret = tegra_sha_do_update(req);
+               if (ret)
+@@ -525,44 +571,6 @@ static void tegra_sha_cra_exit(struct crypto_tfm *tfm)
+       tegra_key_invalidate(ctx->se, ctx->key_id, ctx->alg);
+ }
+-static int tegra_sha_init(struct ahash_request *req)
+-{
+-      struct tegra_sha_reqctx *rctx = ahash_request_ctx(req);
+-      struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+-      struct tegra_sha_ctx *ctx = crypto_ahash_ctx(tfm);
+-      struct tegra_se *se = ctx->se;
+-
+-      if (ctx->fallback)
+-              return tegra_sha_fallback_init(req);
+-
+-      rctx->total_len = 0;
+-      rctx->datbuf.size = 0;
+-      rctx->residue.size = 0;
+-      rctx->key_id = ctx->key_id;
+-      rctx->task = SHA_FIRST;
+-      rctx->alg = ctx->alg;
+-      rctx->blk_size = crypto_ahash_blocksize(tfm);
+-      rctx->digest.size = crypto_ahash_digestsize(tfm);
+-
+-      rctx->digest.buf = dma_alloc_coherent(se->dev, rctx->digest.size,
+-                                            &rctx->digest.addr, GFP_KERNEL);
+-      if (!rctx->digest.buf)
+-              goto digbuf_fail;
+-
+-      rctx->residue.buf = dma_alloc_coherent(se->dev, rctx->blk_size,
+-                                             &rctx->residue.addr, GFP_KERNEL);
+-      if (!rctx->residue.buf)
+-              goto resbuf_fail;
+-
+-      return 0;
+-
+-resbuf_fail:
+-      dma_free_coherent(se->dev, rctx->digest.size, rctx->digest.buf,
+-                        rctx->digest.addr);
+-digbuf_fail:
+-      return -ENOMEM;
+-}
+-
+ static int tegra_hmac_fallback_setkey(struct tegra_sha_ctx *ctx, const u8 *key,
+                                     unsigned int keylen)
+ {
+@@ -588,6 +596,17 @@ static int tegra_hmac_setkey(struct crypto_ahash *tfm, const u8 *key,
+       return tegra_key_submit(ctx->se, key, keylen, ctx->alg, &ctx->key_id);
+ }
++static int tegra_sha_init(struct ahash_request *req)
++{
++      struct tegra_sha_reqctx *rctx = ahash_request_ctx(req);
++      struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
++      struct tegra_sha_ctx *ctx = crypto_ahash_ctx(tfm);
++
++      rctx->task = SHA_INIT;
++
++      return crypto_transfer_hash_request_to_engine(ctx->se->engine, req);
++}
++
+ static int tegra_sha_update(struct ahash_request *req)
+ {
+       struct tegra_sha_reqctx *rctx = ahash_request_ctx(req);
+@@ -635,16 +654,12 @@ static int tegra_sha_digest(struct ahash_request *req)
+       struct tegra_sha_reqctx *rctx = ahash_request_ctx(req);
+       struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+       struct tegra_sha_ctx *ctx = crypto_ahash_ctx(tfm);
+-      int ret;
+       if (ctx->fallback)
+               return tegra_sha_fallback_digest(req);
+-      ret = tegra_sha_init(req);
+-      if (ret)
+-              return ret;
++      rctx->task |= SHA_INIT | SHA_UPDATE | SHA_FINAL;
+-      rctx->task |= SHA_UPDATE | SHA_FINAL;
+       return crypto_transfer_hash_request_to_engine(ctx->se->engine, req);
+ }
+diff --git a/drivers/crypto/tegra/tegra-se.h b/drivers/crypto/tegra/tegra-se.h
+index e196a90eedb92..e1ec37bfb80a8 100644
+--- a/drivers/crypto/tegra/tegra-se.h
++++ b/drivers/crypto/tegra/tegra-se.h
+@@ -342,8 +342,9 @@
+ #define SE_MAX_MEM_ALLOC                      SZ_4M
+ #define SHA_FIRST     BIT(0)
+-#define SHA_UPDATE    BIT(1)
+-#define SHA_FINAL     BIT(2)
++#define SHA_INIT      BIT(1)
++#define SHA_UPDATE    BIT(2)
++#define SHA_FINAL     BIT(3)
+ /* Security Engine operation modes */
+ enum se_aes_alg {
+-- 
+2.39.5
+
diff --git a/queue-6.14/crypto-tegra-use-hmac-fallback-when-keyslots-are-ful.patch b/queue-6.14/crypto-tegra-use-hmac-fallback-when-keyslots-are-ful.patch
new file mode 100644 (file)
index 0000000..5da06b8
--- /dev/null
@@ -0,0 +1,49 @@
+From 8018efa399820d641d69d3bd70dc7a3bed57dc6f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Feb 2025 14:46:10 +0530
+Subject: crypto: tegra - Use HMAC fallback when keyslots are full
+
+From: Akhil R <akhilrajeev@nvidia.com>
+
+[ Upstream commit f80a2e2e77bedd0aa645a60f89b4f581c70accda ]
+
+The intermediate results for HMAC is stored in the allocated keyslot by
+the hardware. Dynamic allocation of keyslot during an operation is hence
+not possible. As the number of keyslots are limited in the hardware,
+fallback to the HMAC software implementation if keyslots are not available
+
+Fixes: 0880bb3b00c8 ("crypto: tegra - Add Tegra Security Engine driver")
+Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/tegra/tegra-se-hash.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/tegra/tegra-se-hash.c b/drivers/crypto/tegra/tegra-se-hash.c
+index 8bed13552ab9e..65a50f29bd7e6 100644
+--- a/drivers/crypto/tegra/tegra-se-hash.c
++++ b/drivers/crypto/tegra/tegra-se-hash.c
+@@ -632,13 +632,18 @@ static int tegra_hmac_setkey(struct crypto_ahash *tfm, const u8 *key,
+                            unsigned int keylen)
+ {
+       struct tegra_sha_ctx *ctx = crypto_ahash_ctx(tfm);
++      int ret;
+       if (aes_check_keylen(keylen))
+               return tegra_hmac_fallback_setkey(ctx, key, keylen);
++      ret = tegra_key_submit(ctx->se, key, keylen, ctx->alg, &ctx->key_id);
++      if (ret)
++              return tegra_hmac_fallback_setkey(ctx, key, keylen);
++
+       ctx->fallback = false;
+-      return tegra_key_submit(ctx->se, key, keylen, ctx->alg, &ctx->key_id);
++      return 0;
+ }
+ static int tegra_sha_init(struct ahash_request *req)
+-- 
+2.39.5
+
diff --git a/queue-6.14/crypto-tegra-use-separate-buffer-for-setkey.patch b/queue-6.14/crypto-tegra-use-separate-buffer-for-setkey.patch
new file mode 100644 (file)
index 0000000..09b8c66
--- /dev/null
@@ -0,0 +1,251 @@
+From 4dcc3500a0190f7a2beadbd80a91801c60b254cc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Feb 2025 14:46:01 +0530
+Subject: crypto: tegra - Use separate buffer for setkey
+
+From: Akhil R <akhilrajeev@nvidia.com>
+
+[ Upstream commit bcfc8fc53f3acb3213fb9d28675244aa4ce208e0 ]
+
+The buffer which sends the commands to host1x was shared for all tasks
+in the engine. This causes a problem with the setkey() function as it
+gets called asynchronous to the crypto engine queue. Modifying the same
+cmdbuf in setkey() will corrupt the ongoing host1x task and in turn
+break the encryption/decryption operation. Hence use a separate cmdbuf
+for setkey().
+
+Fixes: 0880bb3b00c8 ("crypto: tegra - Add Tegra Security Engine driver")
+Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Stable-dep-of: ff4b7df0b511 ("crypto: tegra - Fix HASH intermediate result handling")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/tegra/tegra-se-aes.c  | 16 ++++++++--------
+ drivers/crypto/tegra/tegra-se-hash.c | 13 +++++++------
+ drivers/crypto/tegra/tegra-se-key.c  | 10 ++++++++--
+ drivers/crypto/tegra/tegra-se-main.c | 16 ++++++++++++----
+ drivers/crypto/tegra/tegra-se.h      |  3 ++-
+ 5 files changed, 37 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/crypto/tegra/tegra-se-aes.c b/drivers/crypto/tegra/tegra-se-aes.c
+index d734c9a567868..7da7e169a314b 100644
+--- a/drivers/crypto/tegra/tegra-se-aes.c
++++ b/drivers/crypto/tegra/tegra-se-aes.c
+@@ -282,7 +282,7 @@ static int tegra_aes_do_one_req(struct crypto_engine *engine, void *areq)
+       /* Prepare the command and submit for execution */
+       cmdlen = tegra_aes_prep_cmd(ctx, rctx);
+-      ret = tegra_se_host1x_submit(se, cmdlen);
++      ret = tegra_se_host1x_submit(se, se->cmdbuf, cmdlen);
+       /* Copy the result */
+       tegra_aes_update_iv(req, ctx);
+@@ -719,7 +719,7 @@ static int tegra_gcm_do_gmac(struct tegra_aead_ctx *ctx, struct tegra_aead_reqct
+       cmdlen = tegra_gmac_prep_cmd(ctx, rctx);
+-      return tegra_se_host1x_submit(se, cmdlen);
++      return tegra_se_host1x_submit(se, se->cmdbuf, cmdlen);
+ }
+ static int tegra_gcm_do_crypt(struct tegra_aead_ctx *ctx, struct tegra_aead_reqctx *rctx)
+@@ -736,7 +736,7 @@ static int tegra_gcm_do_crypt(struct tegra_aead_ctx *ctx, struct tegra_aead_reqc
+       /* Prepare command and submit */
+       cmdlen = tegra_gcm_crypt_prep_cmd(ctx, rctx);
+-      ret = tegra_se_host1x_submit(se, cmdlen);
++      ret = tegra_se_host1x_submit(se, se->cmdbuf, cmdlen);
+       if (ret)
+               return ret;
+@@ -759,7 +759,7 @@ static int tegra_gcm_do_final(struct tegra_aead_ctx *ctx, struct tegra_aead_reqc
+       /* Prepare command and submit */
+       cmdlen = tegra_gcm_prep_final_cmd(se, cpuvaddr, rctx);
+-      ret = tegra_se_host1x_submit(se, cmdlen);
++      ret = tegra_se_host1x_submit(se, se->cmdbuf, cmdlen);
+       if (ret)
+               return ret;
+@@ -891,7 +891,7 @@ static int tegra_ccm_do_cbcmac(struct tegra_aead_ctx *ctx, struct tegra_aead_req
+       /* Prepare command and submit */
+       cmdlen = tegra_cbcmac_prep_cmd(ctx, rctx);
+-      return tegra_se_host1x_submit(se, cmdlen);
++      return tegra_se_host1x_submit(se, se->cmdbuf, cmdlen);
+ }
+ static int tegra_ccm_set_msg_len(u8 *block, unsigned int msglen, int csize)
+@@ -1098,7 +1098,7 @@ static int tegra_ccm_do_ctr(struct tegra_aead_ctx *ctx, struct tegra_aead_reqctx
+       /* Prepare command and submit */
+       cmdlen = tegra_ctr_prep_cmd(ctx, rctx);
+-      ret = tegra_se_host1x_submit(se, cmdlen);
++      ret = tegra_se_host1x_submit(se, se->cmdbuf, cmdlen);
+       if (ret)
+               return ret;
+@@ -1519,8 +1519,8 @@ static int tegra_cmac_do_update(struct ahash_request *req)
+               tegra_cmac_paste_result(ctx->se, rctx);
+       cmdlen = tegra_cmac_prep_cmd(ctx, rctx);
++      ret = tegra_se_host1x_submit(se, se->cmdbuf, cmdlen);
+-      ret = tegra_se_host1x_submit(se, cmdlen);
+       /*
+        * If this is not the final update, copy the intermediate results
+        * from the registers so that it can be used in the next 'update'
+@@ -1553,7 +1553,7 @@ static int tegra_cmac_do_final(struct ahash_request *req)
+       /* Prepare command and submit */
+       cmdlen = tegra_cmac_prep_cmd(ctx, rctx);
+-      ret = tegra_se_host1x_submit(se, cmdlen);
++      ret = tegra_se_host1x_submit(se, se->cmdbuf, cmdlen);
+       if (ret)
+               goto out;
+diff --git a/drivers/crypto/tegra/tegra-se-hash.c b/drivers/crypto/tegra/tegra-se-hash.c
+index 0b5cdd5676b17..c7b2a062a03c0 100644
+--- a/drivers/crypto/tegra/tegra-se-hash.c
++++ b/drivers/crypto/tegra/tegra-se-hash.c
+@@ -300,8 +300,9 @@ static int tegra_sha_do_update(struct ahash_request *req)
+ {
+       struct tegra_sha_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
+       struct tegra_sha_reqctx *rctx = ahash_request_ctx(req);
++      struct tegra_se *se = ctx->se;
+       unsigned int nblks, nresidue, size, ret;
+-      u32 *cpuvaddr = ctx->se->cmdbuf->addr;
++      u32 *cpuvaddr = se->cmdbuf->addr;
+       nresidue = (req->nbytes + rctx->residue.size) % rctx->blk_size;
+       nblks = (req->nbytes + rctx->residue.size) / rctx->blk_size;
+@@ -353,11 +354,11 @@ static int tegra_sha_do_update(struct ahash_request *req)
+        * This is to support the import/export functionality.
+        */
+       if (!(rctx->task & SHA_FIRST))
+-              tegra_sha_paste_hash_result(ctx->se, rctx);
++              tegra_sha_paste_hash_result(se, rctx);
+-      size = tegra_sha_prep_cmd(ctx->se, cpuvaddr, rctx);
++      size = tegra_sha_prep_cmd(se, cpuvaddr, rctx);
+-      ret = tegra_se_host1x_submit(ctx->se, size);
++      ret = tegra_se_host1x_submit(se, se->cmdbuf, size);
+       /*
+        * If this is not the final update, copy the intermediate results
+@@ -365,7 +366,7 @@ static int tegra_sha_do_update(struct ahash_request *req)
+        * call. This is to support the import/export functionality.
+        */
+       if (!(rctx->task & SHA_FINAL))
+-              tegra_sha_copy_hash_result(ctx->se, rctx);
++              tegra_sha_copy_hash_result(se, rctx);
+       return ret;
+ }
+@@ -388,7 +389,7 @@ static int tegra_sha_do_final(struct ahash_request *req)
+       size = tegra_sha_prep_cmd(se, cpuvaddr, rctx);
+-      ret = tegra_se_host1x_submit(se, size);
++      ret = tegra_se_host1x_submit(se, se->cmdbuf, size);
+       if (ret)
+               goto out;
+diff --git a/drivers/crypto/tegra/tegra-se-key.c b/drivers/crypto/tegra/tegra-se-key.c
+index ac14678dbd30d..276b261fb6df1 100644
+--- a/drivers/crypto/tegra/tegra-se-key.c
++++ b/drivers/crypto/tegra/tegra-se-key.c
+@@ -115,11 +115,17 @@ static int tegra_key_insert(struct tegra_se *se, const u8 *key,
+                           u32 keylen, u16 slot, u32 alg)
+ {
+       const u32 *keyval = (u32 *)key;
+-      u32 *addr = se->cmdbuf->addr, size;
++      u32 *addr = se->keybuf->addr, size;
++      int ret;
++
++      mutex_lock(&kslt_lock);
+       size = tegra_key_prep_ins_cmd(se, addr, keyval, keylen, slot, alg);
++      ret = tegra_se_host1x_submit(se, se->keybuf, size);
+-      return tegra_se_host1x_submit(se, size);
++      mutex_unlock(&kslt_lock);
++
++      return ret;
+ }
+ void tegra_key_invalidate(struct tegra_se *se, u32 keyid, u32 alg)
+diff --git a/drivers/crypto/tegra/tegra-se-main.c b/drivers/crypto/tegra/tegra-se-main.c
+index 918c0b10614d4..1c94f1de05467 100644
+--- a/drivers/crypto/tegra/tegra-se-main.c
++++ b/drivers/crypto/tegra/tegra-se-main.c
+@@ -141,7 +141,7 @@ static struct tegra_se_cmdbuf *tegra_se_host1x_bo_alloc(struct tegra_se *se, ssi
+       return cmdbuf;
+ }
+-int tegra_se_host1x_submit(struct tegra_se *se, u32 size)
++int tegra_se_host1x_submit(struct tegra_se *se, struct tegra_se_cmdbuf *cmdbuf, u32 size)
+ {
+       struct host1x_job *job;
+       int ret;
+@@ -160,9 +160,9 @@ int tegra_se_host1x_submit(struct tegra_se *se, u32 size)
+       job->engine_fallback_streamid = se->stream_id;
+       job->engine_streamid_offset = SE_STREAM_ID;
+-      se->cmdbuf->words = size;
++      cmdbuf->words = size;
+-      host1x_job_add_gather(job, &se->cmdbuf->bo, size, 0);
++      host1x_job_add_gather(job, &cmdbuf->bo, size, 0);
+       ret = host1x_job_pin(job, se->dev);
+       if (ret) {
+@@ -220,14 +220,22 @@ static int tegra_se_client_init(struct host1x_client *client)
+               goto syncpt_put;
+       }
++      se->keybuf = tegra_se_host1x_bo_alloc(se, SZ_4K);
++      if (!se->keybuf) {
++              ret = -ENOMEM;
++              goto cmdbuf_put;
++      }
++
+       ret = se->hw->init_alg(se);
+       if (ret) {
+               dev_err(se->dev, "failed to register algorithms\n");
+-              goto cmdbuf_put;
++              goto keybuf_put;
+       }
+       return 0;
++keybuf_put:
++      tegra_se_cmdbuf_put(&se->keybuf->bo);
+ cmdbuf_put:
+       tegra_se_cmdbuf_put(&se->cmdbuf->bo);
+ syncpt_put:
+diff --git a/drivers/crypto/tegra/tegra-se.h b/drivers/crypto/tegra/tegra-se.h
+index b9dd7ceb8783c..b54aefe717a17 100644
+--- a/drivers/crypto/tegra/tegra-se.h
++++ b/drivers/crypto/tegra/tegra-se.h
+@@ -420,6 +420,7 @@ struct tegra_se {
+       struct host1x_client client;
+       struct host1x_channel *channel;
+       struct tegra_se_cmdbuf *cmdbuf;
++      struct tegra_se_cmdbuf *keybuf;
+       struct crypto_engine *engine;
+       struct host1x_syncpt *syncpt;
+       struct device *dev;
+@@ -502,7 +503,7 @@ void tegra_deinit_hash(struct tegra_se *se);
+ int tegra_key_submit(struct tegra_se *se, const u8 *key,
+                    u32 keylen, u32 alg, u32 *keyid);
+ void tegra_key_invalidate(struct tegra_se *se, u32 keyid, u32 alg);
+-int tegra_se_host1x_submit(struct tegra_se *se, u32 size);
++int tegra_se_host1x_submit(struct tegra_se *se, struct tegra_se_cmdbuf *cmdbuf, u32 size);
+ /* HOST1x OPCODES */
+ static inline u32 host1x_opcode_setpayload(unsigned int payload)
+-- 
+2.39.5
+
diff --git a/queue-6.14/dlm-prevent-npd-when-writing-a-positive-value-to-eve.patch b/queue-6.14/dlm-prevent-npd-when-writing-a-positive-value-to-eve.patch
new file mode 100644 (file)
index 0000000..81c40b8
--- /dev/null
@@ -0,0 +1,46 @@
+From 236f8ee5e8170d7affb8df38872e855469662f30 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Feb 2025 13:16:22 -0600
+Subject: dlm: prevent NPD when writing a positive value to event_done
+
+From: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
+
+[ Upstream commit 8e2bad543eca5c25cd02cbc63d72557934d45f13 ]
+
+do_uevent returns the value written to event_done. In case it is a
+positive value, new_lockspace would undo all the work, and lockspace
+would not be set. __dlm_new_lockspace, however, would treat that
+positive value as a success due to commit 8511a2728ab8 ("dlm: fix use
+count with multiple joins").
+
+Down the line, device_create_lockspace would pass that NULL lockspace to
+dlm_find_lockspace_local, leading to a NULL pointer dereference.
+
+Treating such positive values as successes prevents the problem. Given
+this has been broken for so long, this is unlikely to break userspace
+expectations.
+
+Fixes: 8511a2728ab8 ("dlm: fix use count with multiple joins")
+Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
+Signed-off-by: David Teigland <teigland@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/dlm/lockspace.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c
+index 8afac6e2dff00..1929327ffbe1c 100644
+--- a/fs/dlm/lockspace.c
++++ b/fs/dlm/lockspace.c
+@@ -576,7 +576,7 @@ static int new_lockspace(const char *name, const char *cluster,
+          lockspace to start running (via sysfs) in dlm_ls_start(). */
+       error = do_uevent(ls, 1);
+-      if (error)
++      if (error < 0)
+               goto out_recoverd;
+       /* wait until recovery is successful or failed */
+-- 
+2.39.5
+
diff --git a/queue-6.14/dma-fix-encryption-bit-clearing-for-dma_to_phys.patch b/queue-6.14/dma-fix-encryption-bit-clearing-for-dma_to_phys.patch
new file mode 100644 (file)
index 0000000..39f1c3d
--- /dev/null
@@ -0,0 +1,61 @@
+From 3c67cb8b6b093bcea8f1f55dd3c36267fca04e74 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 14:41:48 +0000
+Subject: dma: Fix encryption bit clearing for dma_to_phys
+
+From: Suzuki K Poulose <suzuki.poulose@arm.com>
+
+[ Upstream commit c380931712d16e23f6aa90703f438330139e9731 ]
+
+phys_to_dma() sets the encryption bit on the translated DMA address. But
+dma_to_phys() clears the encryption bit after it has been translated back
+to the physical address, which could fail if the device uses DMA ranges.
+
+AMD SME doesn't use the DMA ranges and thus this is harmless. But as we
+are about to add support for other architectures, let us fix this.
+
+Reported-by: Aneesh Kumar K.V <aneesh.kumar@kernel.org>
+Link: https://lkml.kernel.org/r/yq5amsen9stc.fsf@kernel.org
+Cc: Will Deacon <will@kernel.org>
+Cc: Jean-Philippe Brucker <jean-philippe@linaro.org>
+Cc: Robin Murphy <robin.murphy@arm.com>
+Cc: Steven Price <steven.price@arm.com>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Marek Szyprowski <m.szyprowski@samsung.com>
+Cc: Tom Lendacky <thomas.lendacky@amd.com>
+Reviewed-by: Robin Murphy <robin.murphy@arm.com>
+Acked-by: Tom Lendacky <thomas.lendacky@amd.com>
+Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Reviewed-by: Gavin Shan <gshan@redhat.com>
+Acked-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Fixes: 42be24a4178f ("arm64: Enable memory encrypt for Realms")
+Acked-by: Will Deacon <will@kernel.org>
+Link: https://lore.kernel.org/r/20250227144150.1667735-2-suzuki.poulose@arm.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/dma-direct.h | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/include/linux/dma-direct.h b/include/linux/dma-direct.h
+index d7e30d4f7503a..d20ecc24cb0f5 100644
+--- a/include/linux/dma-direct.h
++++ b/include/linux/dma-direct.h
+@@ -101,12 +101,13 @@ static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dma_addr)
+ {
+       phys_addr_t paddr;
++      dma_addr = __sme_clr(dma_addr);
+       if (dev->dma_range_map)
+               paddr = translate_dma_to_phys(dev, dma_addr);
+       else
+               paddr = dma_addr;
+-      return __sme_clr(paddr);
++      return paddr;
+ }
+ #endif /* !CONFIG_ARCH_HAS_PHYS_TO_DMA */
+-- 
+2.39.5
+
diff --git a/queue-6.14/dma-introduce-generic-dma_addr_-crypted-helpers.patch b/queue-6.14/dma-introduce-generic-dma_addr_-crypted-helpers.patch
new file mode 100644 (file)
index 0000000..ff3b735
--- /dev/null
@@ -0,0 +1,137 @@
+From 07fc72dc449db39d65ab2b1db6109fc46af52fae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 14:41:49 +0000
+Subject: dma: Introduce generic dma_addr_*crypted helpers
+
+From: Suzuki K Poulose <suzuki.poulose@arm.com>
+
+[ Upstream commit b66e2ee7b6c8d45bbe4b6f6885ee27511506812c ]
+
+AMD SME added __sme_set/__sme_clr primitives to modify the DMA address for
+encrypted/decrypted traffic. However this doesn't fit in with other models,
+e.g., Arm CCA where the meanings are the opposite. i.e., "decrypted" traffic
+has a bit set and "encrypted" traffic has the top bit cleared.
+
+In preparation for adding the support for Arm CCA DMA conversions, convert the
+existing primitives to more generic ones that can be provided by the backends.
+i.e., add helpers to
+ 1. dma_addr_encrypted - Convert a DMA address to "encrypted" [ == __sme_set() ]
+ 2. dma_addr_unencrypted - Convert a DMA address to "decrypted" [ None exists today ]
+ 3. dma_addr_canonical - Clear any "encryption"/"decryption" bits from DMA
+    address [ SME uses __sme_clr() ] and convert to a canonical DMA address.
+
+Since the original __sme_xxx helpers come from linux/mem_encrypt.h, use that
+as the home for the new definitions and provide dummy ones when none is provided
+by the architectures.
+
+With the above, phys_to_dma_unencrypted() uses the newly added dma_addr_unencrypted()
+helper and to make it a bit more easier to read and avoid double conversion,
+provide __phys_to_dma().
+
+Suggested-by: Robin Murphy <robin.murphy@arm.com>
+Cc: Will Deacon <will@kernel.org>
+Cc: Jean-Philippe Brucker <jean-philippe@linaro.org>
+Cc: Robin Murphy <robin.murphy@arm.com>
+Cc: Steven Price <steven.price@arm.com>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Marek Szyprowski <m.szyprowski@samsung.com>
+Cc: Tom Lendacky <thomas.lendacky@amd.com>
+Cc: Aneesh Kumar K.V <aneesh.kumar@kernel.org>
+Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Reviewed-by: Robin Murphy <robin.murphy@arm.com>
+Reviewed-by: Gavin Shan <gshan@redhat.com>
+Acked-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Fixes: 42be24a4178f ("arm64: Enable memory encrypt for Realms")
+Acked-by: Will Deacon <will@kernel.org>
+Link: https://lore.kernel.org/r/20250227144150.1667735-3-suzuki.poulose@arm.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/dma-direct.h  | 12 ++++++++----
+ include/linux/mem_encrypt.h | 23 +++++++++++++++++++++++
+ 2 files changed, 31 insertions(+), 4 deletions(-)
+
+diff --git a/include/linux/dma-direct.h b/include/linux/dma-direct.h
+index d20ecc24cb0f5..f3bc0bcd70980 100644
+--- a/include/linux/dma-direct.h
++++ b/include/linux/dma-direct.h
+@@ -78,14 +78,18 @@ static inline dma_addr_t dma_range_map_max(const struct bus_dma_region *map)
+ #define phys_to_dma_unencrypted               phys_to_dma
+ #endif
+ #else
+-static inline dma_addr_t phys_to_dma_unencrypted(struct device *dev,
+-              phys_addr_t paddr)
++static inline dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
+ {
+       if (dev->dma_range_map)
+               return translate_phys_to_dma(dev, paddr);
+       return paddr;
+ }
++static inline dma_addr_t phys_to_dma_unencrypted(struct device *dev,
++                                              phys_addr_t paddr)
++{
++      return dma_addr_unencrypted(__phys_to_dma(dev, paddr));
++}
+ /*
+  * If memory encryption is supported, phys_to_dma will set the memory encryption
+  * bit in the DMA address, and dma_to_phys will clear it.
+@@ -94,14 +98,14 @@ static inline dma_addr_t phys_to_dma_unencrypted(struct device *dev,
+  */
+ static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
+ {
+-      return __sme_set(phys_to_dma_unencrypted(dev, paddr));
++      return dma_addr_encrypted(__phys_to_dma(dev, paddr));
+ }
+ static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dma_addr)
+ {
+       phys_addr_t paddr;
+-      dma_addr = __sme_clr(dma_addr);
++      dma_addr = dma_addr_canonical(dma_addr);
+       if (dev->dma_range_map)
+               paddr = translate_dma_to_phys(dev, dma_addr);
+       else
+diff --git a/include/linux/mem_encrypt.h b/include/linux/mem_encrypt.h
+index ae45263892611..07584c5e36fb4 100644
+--- a/include/linux/mem_encrypt.h
++++ b/include/linux/mem_encrypt.h
+@@ -26,11 +26,34 @@
+  */
+ #define __sme_set(x)          ((x) | sme_me_mask)
+ #define __sme_clr(x)          ((x) & ~sme_me_mask)
++
++#define dma_addr_encrypted(x) __sme_set(x)
++#define dma_addr_canonical(x) __sme_clr(x)
++
+ #else
+ #define __sme_set(x)          (x)
+ #define __sme_clr(x)          (x)
+ #endif
++/*
++ * dma_addr_encrypted() and dma_addr_unencrypted() are for converting a given DMA
++ * address to the respective type of addressing.
++ *
++ * dma_addr_canonical() is used to reverse any conversions for encrypted/decrypted
++ * back to the canonical address.
++ */
++#ifndef dma_addr_encrypted
++#define dma_addr_encrypted(x)         (x)
++#endif
++
++#ifndef dma_addr_unencrypted
++#define dma_addr_unencrypted(x)               (x)
++#endif
++
++#ifndef dma_addr_canonical
++#define dma_addr_canonical(x)         (x)
++#endif
++
+ #endif        /* __ASSEMBLY__ */
+ #endif        /* __MEM_ENCRYPT_H__ */
+-- 
+2.39.5
+
diff --git a/queue-6.14/dmaengine-ae4dma-use-the-msi-count-and-its-correspon.patch b/queue-6.14/dmaengine-ae4dma-use-the-msi-count-and-its-correspon.patch
new file mode 100644 (file)
index 0000000..7ecc6eb
--- /dev/null
@@ -0,0 +1,40 @@
+From b49fe2c0df16e12fc409c519975003dc401392cc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Feb 2025 21:55:10 +0530
+Subject: dmaengine: ae4dma: Use the MSI count and its corresponding IRQ number
+
+From: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
+
+[ Upstream commit feba04e6fdf4daccc83fc09d499a3e32c178edb4 ]
+
+Instead of using the defined maximum hardware queue, which can lead to
+incorrect values if the counts mismatch, use the exact supported MSI
+count and its corresponding IRQ number.
+
+Fixes: 90a30e268d9b ("dmaengine: ae4dma: Add AMD ae4dma controller driver")
+Signed-off-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
+Link: https://lore.kernel.org/r/20250203162511.911946-3-Basavaraj.Natikar@amd.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/amd/ae4dma/ae4dma-pci.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/dma/amd/ae4dma/ae4dma-pci.c b/drivers/dma/amd/ae4dma/ae4dma-pci.c
+index aad0dc4294a39..587c5a10c1a8b 100644
+--- a/drivers/dma/amd/ae4dma/ae4dma-pci.c
++++ b/drivers/dma/amd/ae4dma/ae4dma-pci.c
+@@ -46,8 +46,8 @@ static int ae4_get_irqs(struct ae4_device *ae4)
+       } else {
+               ae4_msix->msix_count = ret;
+-              for (i = 0; i < MAX_AE4_HW_QUEUES; i++)
+-                      ae4->ae4_irq[i] = ae4_msix->msix_entry[i].vector;
++              for (i = 0; i < ae4_msix->msix_count; i++)
++                      ae4->ae4_irq[i] = pci_irq_vector(pdev, i);
+       }
+       return ret;
+-- 
+2.39.5
+
diff --git a/queue-6.14/dmaengine-fsl-edma-cleanup-chan-after-dma_async_devi.patch b/queue-6.14/dmaengine-fsl-edma-cleanup-chan-after-dma_async_devi.patch
new file mode 100644 (file)
index 0000000..c97fd16
--- /dev/null
@@ -0,0 +1,52 @@
+From 870f6af853bc328c3c9a56ff68ba090c33b0a249 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Feb 2025 15:17:19 +0800
+Subject: dmaengine: fsl-edma: cleanup chan after dma_async_device_unregister
+
+From: Peng Fan <peng.fan@nxp.com>
+
+[ Upstream commit c9c59da76ce9cb3f215b66eb3708cda1134a5206 ]
+
+There is kernel dump when do module test:
+sysfs: cannot create duplicate filename
+/devices/platform/soc@0/44000000.bus/44000000.dma-controller/dma/dma0chan0
+ __dma_async_device_channel_register+0x128/0x19c
+ dma_async_device_register+0x150/0x454
+ fsl_edma_probe+0x6cc/0x8a0
+ platform_probe+0x68/0xc8
+
+fsl_edma_cleanup_vchan will unlink vchan.chan.device_node, while
+dma_async_device_unregister  needs the link to do
+__dma_async_device_channel_unregister. So need move fsl_edma_cleanup_vchan
+after dma_async_device_unregister to make sure channel could be freed.
+
+So clean up chan after dma_async_device_unregister to address this.
+
+Fixes: 6f93b93b2a1b ("dmaengine: fsl-edma: kill the tasklets upon exit")
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Link: https://lore.kernel.org/r/20250228071720.3780479-1-peng.fan@oss.nxp.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/fsl-edma-main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/dma/fsl-edma-main.c b/drivers/dma/fsl-edma-main.c
+index f989b6c9c0a98..133bdb48d1a5c 100644
+--- a/drivers/dma/fsl-edma-main.c
++++ b/drivers/dma/fsl-edma-main.c
+@@ -802,9 +802,9 @@ static void fsl_edma_remove(struct platform_device *pdev)
+       struct fsl_edma_engine *fsl_edma = platform_get_drvdata(pdev);
+       fsl_edma_irq_exit(pdev, fsl_edma);
+-      fsl_edma_cleanup_vchan(&fsl_edma->dma_dev);
+       of_dma_controller_free(np);
+       dma_async_device_unregister(&fsl_edma->dma_dev);
++      fsl_edma_cleanup_vchan(&fsl_edma->dma_dev);
+       fsl_disable_clocks(fsl_edma, fsl_edma->drvdata->dmamuxs);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/dmaengine-fsl-edma-free-irq-correctly-in-remove-path.patch b/queue-6.14/dmaengine-fsl-edma-free-irq-correctly-in-remove-path.patch
new file mode 100644 (file)
index 0000000..af6a2c2
--- /dev/null
@@ -0,0 +1,77 @@
+From a755d6d9ebaf889775ef528542a3cd205e81a1f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Feb 2025 15:17:20 +0800
+Subject: dmaengine: fsl-edma: free irq correctly in remove path
+
+From: Peng Fan <peng.fan@nxp.com>
+
+[ Upstream commit fa70c4c3c580c239a0f9e83a14770ab026e8d820 ]
+
+Add fsl_edma->txirq/errirq check to avoid below warning because no
+errirq at i.MX9 platform. Otherwise there will be kernel dump:
+WARNING: CPU: 0 PID: 11 at kernel/irq/devres.c:144 devm_free_irq+0x74/0x80
+Modules linked in:
+CPU: 0 UID: 0 PID: 11 Comm: kworker/u8:0 Not tainted 6.12.0-rc7#18
+Hardware name: NXP i.MX93 11X11 EVK board (DT)
+Workqueue: events_unbound deferred_probe_work_func
+pstate: 60400009 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+pc : devm_free_irq+0x74/0x80
+lr : devm_free_irq+0x48/0x80
+Call trace:
+ devm_free_irq+0x74/0x80 (P)
+ devm_free_irq+0x48/0x80 (L)
+ fsl_edma_remove+0xc4/0xc8
+ platform_remove+0x28/0x44
+ device_remove+0x4c/0x80
+
+Fixes: 44eb827264de ("dmaengine: fsl-edma: request per-channel IRQ only when channel is allocated")
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Link: https://lore.kernel.org/r/20250228071720.3780479-2-peng.fan@oss.nxp.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/fsl-edma-main.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/dma/fsl-edma-main.c b/drivers/dma/fsl-edma-main.c
+index 133bdb48d1a5c..e3e0e88a76d3c 100644
+--- a/drivers/dma/fsl-edma-main.c
++++ b/drivers/dma/fsl-edma-main.c
+@@ -401,6 +401,7 @@ fsl_edma2_irq_init(struct platform_device *pdev,
+               /* The last IRQ is for eDMA err */
+               if (i == count - 1) {
++                      fsl_edma->errirq = irq;
+                       ret = devm_request_irq(&pdev->dev, irq,
+                                               fsl_edma_err_handler,
+                                               0, "eDMA2-ERR", fsl_edma);
+@@ -420,10 +421,13 @@ static void fsl_edma_irq_exit(
+               struct platform_device *pdev, struct fsl_edma_engine *fsl_edma)
+ {
+       if (fsl_edma->txirq == fsl_edma->errirq) {
+-              devm_free_irq(&pdev->dev, fsl_edma->txirq, fsl_edma);
++              if (fsl_edma->txirq >= 0)
++                      devm_free_irq(&pdev->dev, fsl_edma->txirq, fsl_edma);
+       } else {
+-              devm_free_irq(&pdev->dev, fsl_edma->txirq, fsl_edma);
+-              devm_free_irq(&pdev->dev, fsl_edma->errirq, fsl_edma);
++              if (fsl_edma->txirq >= 0)
++                      devm_free_irq(&pdev->dev, fsl_edma->txirq, fsl_edma);
++              if (fsl_edma->errirq >= 0)
++                      devm_free_irq(&pdev->dev, fsl_edma->errirq, fsl_edma);
+       }
+ }
+@@ -620,6 +624,8 @@ static int fsl_edma_probe(struct platform_device *pdev)
+       if (!fsl_edma)
+               return -ENOMEM;
++      fsl_edma->errirq = -EINVAL;
++      fsl_edma->txirq = -EINVAL;
+       fsl_edma->drvdata = drvdata;
+       fsl_edma->n_chans = chans;
+       mutex_init(&fsl_edma->fsl_edma_mutex);
+-- 
+2.39.5
+
diff --git a/queue-6.14/dmaengine-ptdma-utilize-the-ae4dma-engine-s-multi-qu.patch b/queue-6.14/dmaengine-ptdma-utilize-the-ae4dma-engine-s-multi-qu.patch
new file mode 100644 (file)
index 0000000..b574451
--- /dev/null
@@ -0,0 +1,211 @@
+From 9c8ef7c93e8a8e368c62e14aaa4dea4ec796d011 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Feb 2025 21:55:11 +0530
+Subject: dmaengine: ptdma: Utilize the AE4DMA engine's multi-queue
+ functionality
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
+
+[ Upstream commit 6565439894570a07b00dba0b739729fe6b56fba4 ]
+
+As AE4DMA offers multi-channel functionality compared to PTDMA’s single
+queue, utilize multi-queue, which supports higher speeds than PTDMA, to
+achieve higher performance using the AE4DMA workqueue based mechanism.
+
+Fixes: 69a47b16a51b ("dmaengine: ptdma: Extend ptdma to support multi-channel and version")
+Signed-off-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
+Link: https://lore.kernel.org/r/20250203162511.911946-4-Basavaraj.Natikar@amd.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/amd/ae4dma/ae4dma.h         |  2 +
+ drivers/dma/amd/ptdma/ptdma-dmaengine.c | 90 ++++++++++++++++++++++++-
+ 2 files changed, 89 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/dma/amd/ae4dma/ae4dma.h b/drivers/dma/amd/ae4dma/ae4dma.h
+index 265c5d4360080..57f6048726bb6 100644
+--- a/drivers/dma/amd/ae4dma/ae4dma.h
++++ b/drivers/dma/amd/ae4dma/ae4dma.h
+@@ -37,6 +37,8 @@
+ #define AE4_DMA_VERSION                       4
+ #define CMD_AE4_DESC_DW0_VAL          2
++#define AE4_TIME_OUT                  5000
++
+ struct ae4_msix {
+       int msix_count;
+       struct msix_entry msix_entry[MAX_AE4_HW_QUEUES];
+diff --git a/drivers/dma/amd/ptdma/ptdma-dmaengine.c b/drivers/dma/amd/ptdma/ptdma-dmaengine.c
+index 35c84ec9608b4..715ac3ae067b8 100644
+--- a/drivers/dma/amd/ptdma/ptdma-dmaengine.c
++++ b/drivers/dma/amd/ptdma/ptdma-dmaengine.c
+@@ -198,8 +198,10 @@ static struct pt_dma_desc *pt_handle_active_desc(struct pt_dma_chan *chan,
+ {
+       struct dma_async_tx_descriptor *tx_desc;
+       struct virt_dma_desc *vd;
++      struct pt_device *pt;
+       unsigned long flags;
++      pt = chan->pt;
+       /* Loop over descriptors until one is found with commands */
+       do {
+               if (desc) {
+@@ -217,7 +219,7 @@ static struct pt_dma_desc *pt_handle_active_desc(struct pt_dma_chan *chan,
+               spin_lock_irqsave(&chan->vc.lock, flags);
+-              if (desc) {
++              if (pt->ver != AE4_DMA_VERSION && desc) {
+                       if (desc->status != DMA_COMPLETE) {
+                               if (desc->status != DMA_ERROR)
+                                       desc->status = DMA_COMPLETE;
+@@ -235,7 +237,7 @@ static struct pt_dma_desc *pt_handle_active_desc(struct pt_dma_chan *chan,
+               spin_unlock_irqrestore(&chan->vc.lock, flags);
+-              if (tx_desc) {
++              if (pt->ver != AE4_DMA_VERSION && tx_desc) {
+                       dmaengine_desc_get_callback_invoke(tx_desc, NULL);
+                       dma_run_dependencies(tx_desc);
+                       vchan_vdesc_fini(vd);
+@@ -245,11 +247,25 @@ static struct pt_dma_desc *pt_handle_active_desc(struct pt_dma_chan *chan,
+       return NULL;
+ }
++static inline bool ae4_core_queue_full(struct pt_cmd_queue *cmd_q)
++{
++      u32 front_wi = readl(cmd_q->reg_control + AE4_WR_IDX_OFF);
++      u32 rear_ri = readl(cmd_q->reg_control + AE4_RD_IDX_OFF);
++
++      if (((MAX_CMD_QLEN + front_wi - rear_ri) % MAX_CMD_QLEN)  >= (MAX_CMD_QLEN - 1))
++              return true;
++
++      return false;
++}
++
+ static void pt_cmd_callback(void *data, int err)
+ {
+       struct pt_dma_desc *desc = data;
++      struct ae4_cmd_queue *ae4cmd_q;
+       struct dma_chan *dma_chan;
+       struct pt_dma_chan *chan;
++      struct ae4_device *ae4;
++      struct pt_device *pt;
+       int ret;
+       if (err == -EINPROGRESS)
+@@ -257,11 +273,32 @@ static void pt_cmd_callback(void *data, int err)
+       dma_chan = desc->vd.tx.chan;
+       chan = to_pt_chan(dma_chan);
++      pt = chan->pt;
+       if (err)
+               desc->status = DMA_ERROR;
+       while (true) {
++              if (pt->ver == AE4_DMA_VERSION) {
++                      ae4 = container_of(pt, struct ae4_device, pt);
++                      ae4cmd_q = &ae4->ae4cmd_q[chan->id];
++
++                      if (ae4cmd_q->q_cmd_count >= (CMD_Q_LEN - 1) ||
++                          ae4_core_queue_full(&ae4cmd_q->cmd_q)) {
++                              wake_up(&ae4cmd_q->q_w);
++
++                              if (wait_for_completion_timeout(&ae4cmd_q->cmp,
++                                                              msecs_to_jiffies(AE4_TIME_OUT))
++                                                              == 0) {
++                                      dev_err(pt->dev, "TIMEOUT %d:\n", ae4cmd_q->id);
++                                      break;
++                              }
++
++                              reinit_completion(&ae4cmd_q->cmp);
++                              continue;
++                      }
++              }
++
+               /* Check for DMA descriptor completion */
+               desc = pt_handle_active_desc(chan, desc);
+@@ -296,6 +333,49 @@ static struct pt_dma_desc *pt_alloc_dma_desc(struct pt_dma_chan *chan,
+       return desc;
+ }
++static void pt_cmd_callback_work(void *data, int err)
++{
++      struct dma_async_tx_descriptor *tx_desc;
++      struct pt_dma_desc *desc = data;
++      struct dma_chan *dma_chan;
++      struct virt_dma_desc *vd;
++      struct pt_dma_chan *chan;
++      unsigned long flags;
++
++      dma_chan = desc->vd.tx.chan;
++      chan = to_pt_chan(dma_chan);
++
++      if (err == -EINPROGRESS)
++              return;
++
++      tx_desc = &desc->vd.tx;
++      vd = &desc->vd;
++
++      if (err)
++              desc->status = DMA_ERROR;
++
++      spin_lock_irqsave(&chan->vc.lock, flags);
++      if (desc) {
++              if (desc->status != DMA_COMPLETE) {
++                      if (desc->status != DMA_ERROR)
++                              desc->status = DMA_COMPLETE;
++
++                      dma_cookie_complete(tx_desc);
++                      dma_descriptor_unmap(tx_desc);
++              } else {
++                      tx_desc = NULL;
++              }
++      }
++      spin_unlock_irqrestore(&chan->vc.lock, flags);
++
++      if (tx_desc) {
++              dmaengine_desc_get_callback_invoke(tx_desc, NULL);
++              dma_run_dependencies(tx_desc);
++              list_del(&desc->vd.node);
++              vchan_vdesc_fini(vd);
++      }
++}
++
+ static struct pt_dma_desc *pt_create_desc(struct dma_chan *dma_chan,
+                                         dma_addr_t dst,
+                                         dma_addr_t src,
+@@ -327,6 +407,7 @@ static struct pt_dma_desc *pt_create_desc(struct dma_chan *dma_chan,
+       desc->len = len;
+       if (pt->ver == AE4_DMA_VERSION) {
++              pt_cmd->pt_cmd_callback = pt_cmd_callback_work;
+               ae4 = container_of(pt, struct ae4_device, pt);
+               ae4cmd_q = &ae4->ae4cmd_q[chan->id];
+               mutex_lock(&ae4cmd_q->cmd_lock);
+@@ -367,13 +448,16 @@ static void pt_issue_pending(struct dma_chan *dma_chan)
+ {
+       struct pt_dma_chan *chan = to_pt_chan(dma_chan);
+       struct pt_dma_desc *desc;
++      struct pt_device *pt;
+       unsigned long flags;
+       bool engine_is_idle = true;
++      pt = chan->pt;
++
+       spin_lock_irqsave(&chan->vc.lock, flags);
+       desc = pt_next_dma_desc(chan);
+-      if (desc)
++      if (desc && pt->ver != AE4_DMA_VERSION)
+               engine_is_idle = false;
+       vchan_issue_pending(&chan->vc);
+-- 
+2.39.5
+
diff --git a/queue-6.14/drivers-clk-qcom-ipq5424-fix-the-freq-table-of-sdcc1.patch b/queue-6.14/drivers-clk-qcom-ipq5424-fix-the-freq-table-of-sdcc1.patch
new file mode 100644 (file)
index 0000000..52c949c
--- /dev/null
@@ -0,0 +1,53 @@
+From dcacbc9cbf3774f3e7785850076dd75a43ede05c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Mar 2025 16:59:00 +0530
+Subject: drivers: clk: qcom: ipq5424: fix the freq table of sdcc1_apps clock
+
+From: Manikanta Mylavarapu <quic_mmanikan@quicinc.com>
+
+[ Upstream commit e9ed0ac3ccba65c17ed0d59c77a340a75abc317b ]
+
+The divider values in the sdcc1_apps frequency table were incorrectly
+updated, assuming the frequency of gpll2_out_main to be 1152MHz.
+However, the frequency of the gpll2_out_main clock is actually 576MHz
+(gpll2/2).
+
+Due to these incorrect divider values, the sdcc1_apps clock is running
+at half of the expected frequency.
+
+Fixing the frequency table of sdcc1_apps allows the sdcc1_apps clock to
+run according to the frequency plan.
+
+Fixes: 21b5d5a4a311 ("clk: qcom: add Global Clock controller (GCC) driver for IPQ5424 SoC")
+Signed-off-by: Manikanta Mylavarapu <quic_mmanikan@quicinc.com>
+Reviewed-by: Kathiravan Thirumoorthy <kathiravan.thirumoorthy@oss.qualcomm.com>
+Link: https://lore.kernel.org/r/20250306112900.3319330-1-quic_mmanikan@quicinc.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-ipq5424.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/clk/qcom/gcc-ipq5424.c b/drivers/clk/qcom/gcc-ipq5424.c
+index d5b218b76e291..107424395ef17 100644
+--- a/drivers/clk/qcom/gcc-ipq5424.c
++++ b/drivers/clk/qcom/gcc-ipq5424.c
+@@ -634,11 +634,11 @@ static struct clk_rcg2 gcc_qupv3_uart1_clk_src = {
+ static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk_src[] = {
+       F(144000, P_XO, 16, 12, 125),
+       F(400000, P_XO, 12, 1, 5),
+-      F(24000000, P_XO, 1, 0, 0),
+-      F(48000000, P_GPLL2_OUT_MAIN, 12, 1, 2),
+-      F(96000000, P_GPLL2_OUT_MAIN, 6, 1, 2),
++      F(24000000, P_GPLL2_OUT_MAIN, 12, 1, 2),
++      F(48000000, P_GPLL2_OUT_MAIN, 12, 0, 0),
++      F(96000000, P_GPLL2_OUT_MAIN, 6, 0, 0),
+       F(177777778, P_GPLL0_OUT_MAIN, 4.5, 0, 0),
+-      F(192000000, P_GPLL2_OUT_MAIN, 6, 0, 0),
++      F(192000000, P_GPLL2_OUT_MAIN, 3, 0, 0),
+       F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+       { }
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-amd-display-avoid-npd-when-asic-does-not-support.patch b/queue-6.14/drm-amd-display-avoid-npd-when-asic-does-not-support.patch
new file mode 100644 (file)
index 0000000..56e4700
--- /dev/null
@@ -0,0 +1,149 @@
+From 694b6129bf6901f9126b31d54d7c58ffb8a5cb70 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Feb 2025 10:06:38 -0300
+Subject: drm/amd/display: avoid NPD when ASIC does not support DMUB
+
+From: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
+
+[ Upstream commit 42d9d7bed270247f134190ba0cb05bbd072f58c2 ]
+
+ctx->dmub_srv will de NULL if the ASIC does not support DMUB, which is
+tested in dm_dmub_sw_init.
+
+However, it will be dereferenced in dmub_hw_lock_mgr_cmd if
+should_use_dmub_lock returns true.
+
+This has been the case since dmub support has been added for PSR1.
+
+Fix this by checking for dmub_srv in should_use_dmub_lock.
+
+[   37.440832] BUG: kernel NULL pointer dereference, address: 0000000000000058
+[   37.447808] #PF: supervisor read access in kernel mode
+[   37.452959] #PF: error_code(0x0000) - not-present page
+[   37.458112] PGD 0 P4D 0
+[   37.460662] Oops: Oops: 0000 [#1] PREEMPT SMP NOPTI
+[   37.465553] CPU: 2 UID: 1000 PID: 1745 Comm: DrmThread Not tainted 6.14.0-rc1-00003-gd62e938120f0 #23 99720e1cb1e0fc4773b8513150932a07de3c6e88
+[   37.478324] Hardware name: Google Morphius/Morphius, BIOS Google_Morphius.13434.858.0 10/26/2023
+[   37.487103] RIP: 0010:dmub_hw_lock_mgr_cmd+0x77/0xb0
+[   37.492074] Code: 44 24 0e 00 00 00 00 48 c7 04 24 45 00 00 0c 40 88 74 24 0d 0f b6 02 88 44 24 0c 8b 01 89 44 24 08 85 f6 75 05 c6 44 24 0e 01 <48> 8b 7f 58 48 89 e6 ba 01 00 00 00 e8 08 3c 2a 00 65 48 8b 04 5
+[   37.510822] RSP: 0018:ffff969442853300 EFLAGS: 00010202
+[   37.516052] RAX: 0000000000000000 RBX: ffff92db03000000 RCX: ffff969442853358
+[   37.523185] RDX: ffff969442853368 RSI: 0000000000000001 RDI: 0000000000000000
+[   37.530322] RBP: 0000000000000001 R08: 00000000000004a7 R09: 00000000000004a5
+[   37.537453] R10: 0000000000000476 R11: 0000000000000062 R12: ffff92db0ade8000
+[   37.544589] R13: ffff92da01180ae0 R14: ffff92da011802a8 R15: ffff92db03000000
+[   37.551725] FS:  0000784a9cdfc6c0(0000) GS:ffff92db2af00000(0000) knlGS:0000000000000000
+[   37.559814] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[   37.565562] CR2: 0000000000000058 CR3: 0000000112b1c000 CR4: 00000000003506f0
+[   37.572697] Call Trace:
+[   37.575152]  <TASK>
+[   37.577258]  ? __die_body+0x66/0xb0
+[   37.580756]  ? page_fault_oops+0x3e7/0x4a0
+[   37.584861]  ? exc_page_fault+0x3e/0xe0
+[   37.588706]  ? exc_page_fault+0x5c/0xe0
+[   37.592550]  ? asm_exc_page_fault+0x22/0x30
+[   37.596742]  ? dmub_hw_lock_mgr_cmd+0x77/0xb0
+[   37.601107]  dcn10_cursor_lock+0x1e1/0x240
+[   37.605211]  program_cursor_attributes+0x81/0x190
+[   37.609923]  commit_planes_for_stream+0x998/0x1ef0
+[   37.614722]  update_planes_and_stream_v2+0x41e/0x5c0
+[   37.619703]  dc_update_planes_and_stream+0x78/0x140
+[   37.624588]  amdgpu_dm_atomic_commit_tail+0x4362/0x49f0
+[   37.629832]  ? srso_return_thunk+0x5/0x5f
+[   37.633847]  ? mark_held_locks+0x6d/0xd0
+[   37.637774]  ? _raw_spin_unlock_irq+0x24/0x50
+[   37.642135]  ? srso_return_thunk+0x5/0x5f
+[   37.646148]  ? lockdep_hardirqs_on+0x95/0x150
+[   37.650510]  ? srso_return_thunk+0x5/0x5f
+[   37.654522]  ? _raw_spin_unlock_irq+0x2f/0x50
+[   37.658883]  ? srso_return_thunk+0x5/0x5f
+[   37.662897]  ? wait_for_common+0x186/0x1c0
+[   37.666998]  ? srso_return_thunk+0x5/0x5f
+[   37.671009]  ? drm_crtc_next_vblank_start+0xc3/0x170
+[   37.675983]  commit_tail+0xf5/0x1c0
+[   37.679478]  drm_atomic_helper_commit+0x2a2/0x2b0
+[   37.684186]  drm_atomic_commit+0xd6/0x100
+[   37.688199]  ? __cfi___drm_printfn_info+0x10/0x10
+[   37.692911]  drm_atomic_helper_update_plane+0xe5/0x130
+[   37.698054]  drm_mode_cursor_common+0x501/0x670
+[   37.702600]  ? __cfi_drm_mode_cursor_ioctl+0x10/0x10
+[   37.707572]  drm_mode_cursor_ioctl+0x48/0x70
+[   37.711851]  drm_ioctl_kernel+0xf2/0x150
+[   37.715781]  drm_ioctl+0x363/0x590
+[   37.719189]  ? __cfi_drm_mode_cursor_ioctl+0x10/0x10
+[   37.724165]  amdgpu_drm_ioctl+0x41/0x80
+[   37.728013]  __se_sys_ioctl+0x7f/0xd0
+[   37.731685]  do_syscall_64+0x87/0x100
+[   37.735355]  ? vma_end_read+0x12/0xe0
+[   37.739024]  ? srso_return_thunk+0x5/0x5f
+[   37.743041]  ? find_held_lock+0x47/0xf0
+[   37.746884]  ? vma_end_read+0x12/0xe0
+[   37.750552]  ? srso_return_thunk+0x5/0x5f
+[   37.754565]  ? lock_release+0x1c4/0x2e0
+[   37.758406]  ? vma_end_read+0x12/0xe0
+[   37.762079]  ? exc_page_fault+0x84/0xe0
+[   37.765921]  ? srso_return_thunk+0x5/0x5f
+[   37.769938]  ? lockdep_hardirqs_on+0x95/0x150
+[   37.774303]  ? srso_return_thunk+0x5/0x5f
+[   37.778317]  ? exc_page_fault+0x84/0xe0
+[   37.782163]  entry_SYSCALL_64_after_hwframe+0x55/0x5d
+[   37.787218] RIP: 0033:0x784aa5ec3059
+[   37.790803] Code: 04 25 28 00 00 00 48 89 45 c8 31 c0 48 8d 45 10 c7 45 b0 10 00 00 00 48 89 45 b8 48 8d 45 d0 48 89 45 c0 b8 10 00 00 00 0f 05 <41> 89 c0 3d 00 f0 ff ff 77 1d 48 8b 45 c8 64 48 2b 04 25 28 00 0
+[   37.809553] RSP: 002b:0000784a9cdf90e0 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
+[   37.817121] RAX: ffffffffffffffda RBX: 0000784a9cdf917c RCX: 0000784aa5ec3059
+[   37.824256] RDX: 0000784a9cdf917c RSI: 00000000c01c64a3 RDI: 0000000000000020
+[   37.831391] RBP: 0000784a9cdf9130 R08: 0000000000000100 R09: 0000000000ff0000
+[   37.838525] R10: 0000000000000000 R11: 0000000000000246 R12: 0000025c01606ed0
+[   37.845657] R13: 0000025c00030200 R14: 00000000c01c64a3 R15: 0000000000000020
+[   37.852799]  </TASK>
+[   37.854992] Modules linked in:
+[   37.864546] gsmi: Log Shutdown Reason 0x03
+[   37.868656] CR2: 0000000000000058
+[   37.871979] ---[ end trace 0000000000000000 ]---
+[   37.880976] RIP: 0010:dmub_hw_lock_mgr_cmd+0x77/0xb0
+[   37.885954] Code: 44 24 0e 00 00 00 00 48 c7 04 24 45 00 00 0c 40 88 74 24 0d 0f b6 02 88 44 24 0c 8b 01 89 44 24 08 85 f6 75 05 c6 44 24 0e 01 <48> 8b 7f 58 48 89 e6 ba 01 00 00 00 e8 08 3c 2a 00 65 48 8b 04 5
+[   37.904703] RSP: 0018:ffff969442853300 EFLAGS: 00010202
+[   37.909933] RAX: 0000000000000000 RBX: ffff92db03000000 RCX: ffff969442853358
+[   37.917068] RDX: ffff969442853368 RSI: 0000000000000001 RDI: 0000000000000000
+[   37.924201] RBP: 0000000000000001 R08: 00000000000004a7 R09: 00000000000004a5
+[   37.931336] R10: 0000000000000476 R11: 0000000000000062 R12: ffff92db0ade8000
+[   37.938469] R13: ffff92da01180ae0 R14: ffff92da011802a8 R15: ffff92db03000000
+[   37.945602] FS:  0000784a9cdfc6c0(0000) GS:ffff92db2af00000(0000) knlGS:0000000000000000
+[   37.953689] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[   37.959435] CR2: 0000000000000058 CR3: 0000000112b1c000 CR4: 00000000003506f0
+[   37.966570] Kernel panic - not syncing: Fatal exception
+[   37.971901] Kernel Offset: 0x30200000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff)
+[   37.982840] gsmi: Log Shutdown Reason 0x02
+
+Fixes: b5c764d6ed55 ("drm/amd/display: Use HW lock mgr for PSR1")
+Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
+Cc: Sun peng Li <sunpeng.li@amd.com>
+Cc: Tom Chung <chiahsuan.chung@amd.com>
+Cc: Daniel Wheeler <daniel.wheeler@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Reviewed-by: Rodrigo Siqueira <siqueira@igalia.com>
+Reviewed-by: Leo Li <sunpeng.li@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/dce/dmub_hw_lock_mgr.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c
+index 6e2fce329d738..d37ecfdde4f1b 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c
++++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c
+@@ -63,6 +63,10 @@ void dmub_hw_lock_mgr_inbox0_cmd(struct dc_dmub_srv *dmub_srv,
+ bool should_use_dmub_lock(struct dc_link *link)
+ {
++      /* ASIC doesn't support DMUB */
++      if (!link->ctx->dmub_srv)
++              return false;
++
+       if (link->psr_settings.psr_version == DC_PSR_VERSION_SU_1)
+               return true;
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-amd-display-fix-an-indent-issue-in-dml21.patch b/queue-6.14/drm-amd-display-fix-an-indent-issue-in-dml21.patch
new file mode 100644 (file)
index 0000000..ee6ea67
--- /dev/null
@@ -0,0 +1,41 @@
+From f2c36536987f5a48589aeb8b5dea82b4a8ba75bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Feb 2025 09:45:12 -0500
+Subject: drm/amd/display: fix an indent issue in DML21
+
+From: Aurabindo Pillai <aurabindo.pillai@amd.com>
+
+[ Upstream commit a1addcf8499a566496847f1e36e1cf0b4ad72a26 ]
+
+Remove extraneous tab and newline in dml2_core_dcn4.c that was
+reported by the bot
+
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202502211920.txUfwtSj-lkp@intel.com/
+Fixes: 70839da6360 ("drm/amd/display: Add new DCN401 sources")
+Signed-off-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
+Reviewed-by: Harry Wentland <harry.wentland@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.c   | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.c
+index d68b4567e218a..7216d25c783e6 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.c
++++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.c
+@@ -141,9 +141,8 @@ bool core_dcn4_initialize(struct dml2_core_initialize_in_out *in_out)
+               core->clean_me_up.mode_lib.ip.subvp_fw_processing_delay_us = core_dcn4_ip_caps_base.subvp_pstate_allow_width_us;
+               core->clean_me_up.mode_lib.ip.subvp_swath_height_margin_lines = core_dcn4_ip_caps_base.subvp_swath_height_margin_lines;
+       } else {
+-                      memcpy(&core->clean_me_up.mode_lib.ip, &core_dcn4_ip_caps_base, sizeof(struct dml2_core_ip_params));
++              memcpy(&core->clean_me_up.mode_lib.ip, &core_dcn4_ip_caps_base, sizeof(struct dml2_core_ip_params));
+               patch_ip_params_with_ip_caps(&core->clean_me_up.mode_lib.ip, in_out->ip_caps);
+-
+               core->clean_me_up.mode_lib.ip.imall_supported = false;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-amd-display-fix-type-mismatch-in-calculatedynami.patch b/queue-6.14/drm-amd-display-fix-type-mismatch-in-calculatedynami.patch
new file mode 100644 (file)
index 0000000..7c2efb9
--- /dev/null
@@ -0,0 +1,64 @@
+From d116c2be95e5a2f47da5556fd020a034500600ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 01:28:51 +0500
+Subject: drm/amd/display: fix type mismatch in
+ CalculateDynamicMetadataParameters()
+
+From: Vitaliy Shevtsov <v.shevtsov@mt-integration.ru>
+
+[ Upstream commit c3c584c18c90a024a54716229809ba36424f9660 ]
+
+There is a type mismatch between what CalculateDynamicMetadataParameters()
+takes and what is passed to it. Currently this function accepts several
+args as signed long but it's called with unsigned integers and integer. On
+some systems where long is 32 bits and one of these unsigned int params is
+greater than INT_MAX it may cause passing input params as negative values.
+
+Fix this by changing these argument types from long to unsigned int and to
+int respectively. Also this will align the function's definition with
+similar functions in other dcn* drivers.
+
+Found by Linux Verification Center (linuxtesting.org) with Svace.
+
+Fixes: 6725a88f88a7 ("drm/amd/display: Add DCN3 DML")
+Signed-off-by: Vitaliy Shevtsov <v.shevtsov@mt-integration.ru>
+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>
+---
+ .../amd/display/dc/dml/dcn30/display_mode_vba_30.c   | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c
+index cee1b351e1058..f1fe49401bc0a 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c
+@@ -281,10 +281,10 @@ static void CalculateDynamicMetadataParameters(
+               double DISPCLK,
+               double DCFClkDeepSleep,
+               double PixelClock,
+-              long HTotal,
+-              long VBlank,
+-              long DynamicMetadataTransmittedBytes,
+-              long DynamicMetadataLinesBeforeActiveRequired,
++              unsigned int HTotal,
++              unsigned int VBlank,
++              unsigned int DynamicMetadataTransmittedBytes,
++              int DynamicMetadataLinesBeforeActiveRequired,
+               int InterlaceEnable,
+               bool ProgressiveToInterlaceUnitInOPP,
+               double *Tsetup,
+@@ -3265,8 +3265,8 @@ static double CalculateWriteBackDelay(
+ static void CalculateDynamicMetadataParameters(int MaxInterDCNTileRepeaters, double DPPCLK, double DISPCLK,
+-              double DCFClkDeepSleep, double PixelClock, long HTotal, long VBlank, long DynamicMetadataTransmittedBytes,
+-              long DynamicMetadataLinesBeforeActiveRequired, int InterlaceEnable, bool ProgressiveToInterlaceUnitInOPP,
++              double DCFClkDeepSleep, double PixelClock, unsigned int HTotal, unsigned int VBlank, unsigned int DynamicMetadataTransmittedBytes,
++              int DynamicMetadataLinesBeforeActiveRequired, int InterlaceEnable, bool ProgressiveToInterlaceUnitInOPP,
+               double *Tsetup, double *Tdmbf, double *Tdmec, double *Tdmsks)
+ {
+       double TotalRepeaterDelayTime = 0;
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-amdgpu-mes-enable-compute-pipes-across-all-mec.patch b/queue-6.14/drm-amdgpu-mes-enable-compute-pipes-across-all-mec.patch
new file mode 100644 (file)
index 0000000..25e6f23
--- /dev/null
@@ -0,0 +1,37 @@
+From bb975ce79fc186642298b5c5e036010a2062663b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Mar 2025 10:42:45 -0400
+Subject: drm/amdgpu/mes: enable compute pipes across all MEC
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit a52077b6b6f7d1553d2dc89666f111f89d7418e0 ]
+
+Enable pipes on both MECs for MES.
+
+Fixes: 745f46b6a99f ("drm/amdgpu: enable mes v12 self test")
+Acked-by: Lijo Lazar <lijo.lazar@amd.com>
+Reviewed-by: Prike Liang <Prike.Liang@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
+index c16ad5f790d15..6fa20980a0b15 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
+@@ -145,8 +145,7 @@ int amdgpu_mes_init(struct amdgpu_device *adev)
+       adev->mes.vmid_mask_gfxhub = 0xffffff00;
+       for (i = 0; i < AMDGPU_MES_MAX_COMPUTE_PIPES; i++) {
+-              /* use only 1st MEC pipes */
+-              if (i >= adev->gfx.mec.num_pipe_per_mec)
++              if (i >= (adev->gfx.mec.num_pipe_per_mec * adev->gfx.mec.num_mec))
+                       break;
+               adev->mes.compute_hqd_mask[i] = 0xc;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-amdgpu-mes-optimize-compute-loop-handling.patch b/queue-6.14/drm-amdgpu-mes-optimize-compute-loop-handling.patch
new file mode 100644 (file)
index 0000000..0b9de92
--- /dev/null
@@ -0,0 +1,36 @@
+From 5f166fa5514a7a7f18921c2d8f45ca915911628e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Mar 2025 09:56:00 -0400
+Subject: drm/amdgpu/mes: optimize compute loop handling
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit 5608ddf6e94c41a673170b2a7e3aad485fd8b88a ]
+
+Break when we get to the end of the supported pipes
+rather than continuing the loop.
+
+Reviewed-by: Shaoyun.liu <Shaoyun.liu@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: a52077b6b6f7 ("drm/amdgpu/mes: enable compute pipes across all MEC")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
+index 709c11cbeabd8..c16ad5f790d15 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
+@@ -147,7 +147,7 @@ int amdgpu_mes_init(struct amdgpu_device *adev)
+       for (i = 0; i < AMDGPU_MES_MAX_COMPUTE_PIPES; i++) {
+               /* use only 1st MEC pipes */
+               if (i >= adev->gfx.mec.num_pipe_per_mec)
+-                      continue;
++                      break;
+               adev->mes.compute_hqd_mask[i] = 0xc;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-amdgpu-refine-smu-send-msg-debug-log-format.patch b/queue-6.14/drm-amdgpu-refine-smu-send-msg-debug-log-format.patch
new file mode 100644 (file)
index 0000000..7d2a520
--- /dev/null
@@ -0,0 +1,39 @@
+From 7fcf2551bc3667ecfbfe884a46484075433bcd15 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Feb 2025 15:46:42 +0800
+Subject: drm/amdgpu: refine smu send msg debug log format
+
+From: Yang Wang <kevinyang.wang@amd.com>
+
+[ Upstream commit 8c6631234557515a7567c6251505a98e9793c8a6 ]
+
+remove unnecessary line breaks.
+
+[   51.280860] amdgpu 0000:24:00.0: amdgpu: smu send message: GetEnabledSmuFeaturesHigh(13) param: 0x00000000, resp: 0x00000001,                        readval: 0x00003763
+
+Fixes: 0cd2bc06de72 ("drm/amd/pm: enable amdgpu smu send message log")
+Signed-off-by: Yang Wang <kevinyang.wang@amd.com>
+Reviewed-by: Kenneth Feng <kenneth.feng@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
+index 9f55207ea9bc3..d834d134ad2b8 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
+@@ -459,8 +459,7 @@ int smu_cmn_send_smc_msg_with_param(struct smu_context *smu,
+       }
+       if (read_arg) {
+               smu_cmn_read_arg(smu, read_arg);
+-              dev_dbg(adev->dev, "smu send message: %s(%d) param: 0x%08x, resp: 0x%08x,\
+-                      readval: 0x%08x\n",
++              dev_dbg(adev->dev, "smu send message: %s(%d) param: 0x%08x, resp: 0x%08x, readval: 0x%08x\n",
+                       smu_get_message_name(smu, msg), index, param, reg, *read_arg);
+       } else {
+               dev_dbg(adev->dev, "smu send message: %s(%d) param: 0x%08x, resp: 0x%08x\n",
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-amdgpu-replace-mutex-with-spinlock-for-rlcg-regi.patch b/queue-6.14/drm-amdgpu-replace-mutex-with-spinlock-for-rlcg-regi.patch
new file mode 100644 (file)
index 0000000..0d11f2b
--- /dev/null
@@ -0,0 +1,180 @@
+From 31464bda296652204fcd991cfe72376e570b0684 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Feb 2025 14:22:17 +0530
+Subject: drm/amdgpu: Replace Mutex with Spinlock for RLCG register access to
+ avoid Priority Inversion in SRIOV
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+
+[ Upstream commit dc0297f3198bd60108ccbd167ee5d9fa4af31ed0 ]
+
+RLCG Register Access is a way for virtual functions to safely access GPU
+registers in a virtualized environment., including TLB flushes and
+register reads. When multiple threads or VFs try to access the same
+registers simultaneously, it can lead to race conditions. By using the
+RLCG interface, the driver can serialize access to the registers. This
+means that only one thread can access the registers at a time,
+preventing conflicts and ensuring that operations are performed
+correctly. Additionally, when a low-priority task holds a mutex that a
+high-priority task needs, ie., If a thread holding a spinlock tries to
+acquire a mutex, it can lead to priority inversion. register access in
+amdgpu_virt_rlcg_reg_rw especially in a fast code path is critical.
+
+The call stack shows that the function amdgpu_virt_rlcg_reg_rw is being
+called, which attempts to acquire the mutex. This function is invoked
+from amdgpu_sriov_wreg, which in turn is called from
+gmc_v11_0_flush_gpu_tlb.
+
+The [ BUG: Invalid wait context ] indicates that a thread is trying to
+acquire a mutex while it is in a context that does not allow it to sleep
+(like holding a spinlock).
+
+Fixes the below:
+
+[  253.013423] =============================
+[  253.013434] [ BUG: Invalid wait context ]
+[  253.013446] 6.12.0-amdstaging-drm-next-lol-050225 #14 Tainted: G     U     OE
+[  253.013464] -----------------------------
+[  253.013475] kworker/0:1/10 is trying to lock:
+[  253.013487] ffff9f30542e3cf8 (&adev->virt.rlcg_reg_lock){+.+.}-{3:3}, at: amdgpu_virt_rlcg_reg_rw+0xf6/0x330 [amdgpu]
+[  253.013815] other info that might help us debug this:
+[  253.013827] context-{4:4}
+[  253.013835] 3 locks held by kworker/0:1/10:
+[  253.013847]  #0: ffff9f3040050f58 ((wq_completion)events){+.+.}-{0:0}, at: process_one_work+0x3f5/0x680
+[  253.013877]  #1: ffffb789c008be40 ((work_completion)(&wfc.work)){+.+.}-{0:0}, at: process_one_work+0x1d6/0x680
+[  253.013905]  #2: ffff9f3054281838 (&adev->gmc.invalidate_lock){+.+.}-{2:2}, at: gmc_v11_0_flush_gpu_tlb+0x198/0x4f0 [amdgpu]
+[  253.014154] stack backtrace:
+[  253.014164] CPU: 0 UID: 0 PID: 10 Comm: kworker/0:1 Tainted: G     U     OE      6.12.0-amdstaging-drm-next-lol-050225 #14
+[  253.014189] Tainted: [U]=USER, [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
+[  253.014203] Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS Hyper-V UEFI Release v4.1 11/18/2024
+[  253.014224] Workqueue: events work_for_cpu_fn
+[  253.014241] Call Trace:
+[  253.014250]  <TASK>
+[  253.014260]  dump_stack_lvl+0x9b/0xf0
+[  253.014275]  dump_stack+0x10/0x20
+[  253.014287]  __lock_acquire+0xa47/0x2810
+[  253.014303]  ? srso_alias_return_thunk+0x5/0xfbef5
+[  253.014321]  lock_acquire+0xd1/0x300
+[  253.014333]  ? amdgpu_virt_rlcg_reg_rw+0xf6/0x330 [amdgpu]
+[  253.014562]  ? __lock_acquire+0xa6b/0x2810
+[  253.014578]  __mutex_lock+0x85/0xe20
+[  253.014591]  ? amdgpu_virt_rlcg_reg_rw+0xf6/0x330 [amdgpu]
+[  253.014782]  ? sched_clock_noinstr+0x9/0x10
+[  253.014795]  ? srso_alias_return_thunk+0x5/0xfbef5
+[  253.014808]  ? local_clock_noinstr+0xe/0xc0
+[  253.014822]  ? amdgpu_virt_rlcg_reg_rw+0xf6/0x330 [amdgpu]
+[  253.015012]  ? srso_alias_return_thunk+0x5/0xfbef5
+[  253.015029]  mutex_lock_nested+0x1b/0x30
+[  253.015044]  ? mutex_lock_nested+0x1b/0x30
+[  253.015057]  amdgpu_virt_rlcg_reg_rw+0xf6/0x330 [amdgpu]
+[  253.015249]  amdgpu_sriov_wreg+0xc5/0xd0 [amdgpu]
+[  253.015435]  gmc_v11_0_flush_gpu_tlb+0x44b/0x4f0 [amdgpu]
+[  253.015667]  gfx_v11_0_hw_init+0x499/0x29c0 [amdgpu]
+[  253.015901]  ? __pfx_smu_v13_0_update_pcie_parameters+0x10/0x10 [amdgpu]
+[  253.016159]  ? srso_alias_return_thunk+0x5/0xfbef5
+[  253.016173]  ? smu_hw_init+0x18d/0x300 [amdgpu]
+[  253.016403]  amdgpu_device_init+0x29ad/0x36a0 [amdgpu]
+[  253.016614]  amdgpu_driver_load_kms+0x1a/0xc0 [amdgpu]
+[  253.017057]  amdgpu_pci_probe+0x1c2/0x660 [amdgpu]
+[  253.017493]  local_pci_probe+0x4b/0xb0
+[  253.017746]  work_for_cpu_fn+0x1a/0x30
+[  253.017995]  process_one_work+0x21e/0x680
+[  253.018248]  worker_thread+0x190/0x330
+[  253.018500]  ? __pfx_worker_thread+0x10/0x10
+[  253.018746]  kthread+0xe7/0x120
+[  253.018988]  ? __pfx_kthread+0x10/0x10
+[  253.019231]  ret_from_fork+0x3c/0x60
+[  253.019468]  ? __pfx_kthread+0x10/0x10
+[  253.019701]  ret_from_fork_asm+0x1a/0x30
+[  253.019939]  </TASK>
+
+v2: s/spin_trylock/spin_lock_irqsave to be safe (Christian).
+
+Fixes: e864180ee49b ("drm/amdgpu: Add lock around VF RLCG interface")
+Cc: lin cao <lin.cao@amd.com>
+Cc: Jingwen Chen <Jingwen.Chen2@amd.com>
+Cc: Victor Skvortsov <victor.skvortsov@amd.com>
+Cc: Zhigang Luo <zhigang.luo@amd.com>
+Cc: Christian König <christian.koenig@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+Suggested-by: Alex Deucher <alexander.deucher@amd.com>
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c   | 5 +++--
+ drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h   | 3 ++-
+ 3 files changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+index 018dfccd771ba..f5909977eed4b 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -4223,7 +4223,6 @@ int amdgpu_device_init(struct amdgpu_device *adev,
+       mutex_init(&adev->grbm_idx_mutex);
+       mutex_init(&adev->mn_lock);
+       mutex_init(&adev->virt.vf_errors.lock);
+-      mutex_init(&adev->virt.rlcg_reg_lock);
+       hash_init(adev->mn_hash);
+       mutex_init(&adev->psp.mutex);
+       mutex_init(&adev->notifier_lock);
+@@ -4249,6 +4248,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
+       spin_lock_init(&adev->se_cac_idx_lock);
+       spin_lock_init(&adev->audio_endpt_idx_lock);
+       spin_lock_init(&adev->mm_stats.lock);
++      spin_lock_init(&adev->virt.rlcg_reg_lock);
+       spin_lock_init(&adev->wb.lock);
+       INIT_LIST_HEAD(&adev->reset_list);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
+index 0af469ec6fccd..13e5709ea1caa 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
+@@ -1017,6 +1017,7 @@ u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v, u32 f
+       void *scratch_reg2;
+       void *scratch_reg3;
+       void *spare_int;
++      unsigned long flags;
+       if (!adev->gfx.rlc.rlcg_reg_access_supported) {
+               dev_err(adev->dev,
+@@ -1038,7 +1039,7 @@ u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v, u32 f
+       scratch_reg2 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg2;
+       scratch_reg3 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg3;
+-      mutex_lock(&adev->virt.rlcg_reg_lock);
++      spin_lock_irqsave(&adev->virt.rlcg_reg_lock, flags);
+       if (reg_access_ctrl->spare_int)
+               spare_int = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->spare_int;
+@@ -1097,7 +1098,7 @@ u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v, u32 f
+       ret = readl(scratch_reg0);
+-      mutex_unlock(&adev->virt.rlcg_reg_lock);
++      spin_unlock_irqrestore(&adev->virt.rlcg_reg_lock, flags);
+       return ret;
+ }
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
+index 5381b8d596e62..0ca73343a7689 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
+@@ -279,7 +279,8 @@ struct amdgpu_virt {
+       /* the ucode id to signal the autoload */
+       uint32_t autoload_ucode_id;
+-      struct mutex rlcg_reg_lock;
++      /* Spinlock to protect access to the RLCG register interface */
++      spinlock_t rlcg_reg_lock;
+       union amd_sriov_ras_caps ras_en_caps;
+       union amd_sriov_ras_caps ras_telemetry_en_caps;
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-amdgpu-umsch-declare-umsch-firmware.patch b/queue-6.14/drm-amdgpu-umsch-declare-umsch-firmware.patch
new file mode 100644 (file)
index 0000000..2065026
--- /dev/null
@@ -0,0 +1,36 @@
+From 64b3f97d2dc82158e48630e43c0c99d2678efc9f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Feb 2025 16:20:15 -0500
+Subject: drm/amdgpu/umsch: declare umsch firmware
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit fe652becdbfccf265f4cea0eb379418d08c6596a ]
+
+Needed to be properly picked up for the initrd, etc.
+
+Fixes: 3488c79beafa ("drm/amdgpu: add initial support for UMSCH")
+Reviewed-by: Saleemkhan Jamadar <saleemkhan.jamadar@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: Lang Yu <Lang.Yu@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
+index 2cfa2447d13e7..78319988b0545 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
+@@ -32,6 +32,8 @@
+ #include "amdgpu_umsch_mm.h"
+ #include "umsch_mm_v4_0.h"
++MODULE_FIRMWARE("amdgpu/umsch_mm_4_0_0.bin");
++
+ int amdgpu_umsch_mm_submit_pkt(struct amdgpu_umsch_mm *umsch, void *pkt, int ndws)
+ {
+       struct amdgpu_ring *ring = &umsch->ring;
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-amdgpu-umsch-fix-ucode-check.patch b/queue-6.14/drm-amdgpu-umsch-fix-ucode-check.patch
new file mode 100644 (file)
index 0000000..4a53e82
--- /dev/null
@@ -0,0 +1,43 @@
+From fac711527dddba4b881586e41625a3df426b3a9d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Feb 2025 16:31:43 -0500
+Subject: drm/amdgpu/umsch: fix ucode check
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit c917e39cbdcd9fff421184db6cc461cc58d52c17 ]
+
+Return an error if the IP version doesn't match otherwise
+we end up passing a NULL string to amdgpu_ucode_request.
+We should never hit this in practice today since we only
+enable the umsch code on the supported IP versions, but
+add a check to be safe.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202502130406.iWQ0eBug-lkp@intel.com/
+Fixes: 020620424b27 ("drm/amd: Use a constant format string for amdgpu_ucode_request")
+Reviewed-by: Saleemkhan Jamadar <saleemkhan.jamadar@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: Arnd Bergmann <arnd@arndb.de>
+Cc: Lang Yu <Lang.Yu@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
+index 78319988b0545..a7f2648245ec0 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
+@@ -129,7 +129,7 @@ int amdgpu_umsch_mm_init_microcode(struct amdgpu_umsch_mm *umsch)
+               fw_name = "amdgpu/umsch_mm_4_0_0.bin";
+               break;
+       default:
+-              break;
++              return -EINVAL;
+       }
+       r = amdgpu_ucode_request(adev, &adev->umsch_mm.fw, AMDGPU_UCODE_REQUIRED,
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-amdgpu-umsch-remove-vpe-test-from-umsch.patch b/queue-6.14/drm-amdgpu-umsch-remove-vpe-test-from-umsch.patch
new file mode 100644 (file)
index 0000000..a836d7d
--- /dev/null
@@ -0,0 +1,504 @@
+From 8b90ea91c46812426cd113658d7f1e9e6c45ae80 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Dec 2024 17:27:44 +0530
+Subject: drm/amdgpu/umsch: remove vpe test from umsch
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Saleemkhan Jamadar <saleemkhan.jamadar@amd.com>
+
+[ Upstream commit b0bebbe4ea2a25937d341fa1f2ab2cd8ce339cad ]
+
+current test is more intrusive for user queue test
+
+Signed-off-by: Saleemkhan Jamadar <saleemkhan.jamadar@amd.com>
+Suggested-by: Christian Koenig <christian.koenig@amd.com>
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: fe652becdbfc ("drm/amdgpu/umsch: declare umsch firmware")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c | 459 +------------------
+ 1 file changed, 1 insertion(+), 458 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
+index dde15c6a96e1a..2cfa2447d13e7 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
+@@ -32,463 +32,6 @@
+ #include "amdgpu_umsch_mm.h"
+ #include "umsch_mm_v4_0.h"
+-struct umsch_mm_test_ctx_data {
+-      uint8_t process_csa[PAGE_SIZE];
+-      uint8_t vpe_ctx_csa[PAGE_SIZE];
+-      uint8_t vcn_ctx_csa[PAGE_SIZE];
+-};
+-
+-struct umsch_mm_test_mqd_data {
+-      uint8_t vpe_mqd[PAGE_SIZE];
+-      uint8_t vcn_mqd[PAGE_SIZE];
+-};
+-
+-struct umsch_mm_test_ring_data {
+-      uint8_t vpe_ring[PAGE_SIZE];
+-      uint8_t vpe_ib[PAGE_SIZE];
+-      uint8_t vcn_ring[PAGE_SIZE];
+-      uint8_t vcn_ib[PAGE_SIZE];
+-};
+-
+-struct umsch_mm_test_queue_info {
+-      uint64_t mqd_addr;
+-      uint64_t csa_addr;
+-      uint32_t doorbell_offset_0;
+-      uint32_t doorbell_offset_1;
+-      enum UMSCH_SWIP_ENGINE_TYPE engine;
+-};
+-
+-struct umsch_mm_test {
+-      struct amdgpu_bo        *ctx_data_obj;
+-      uint64_t                ctx_data_gpu_addr;
+-      uint32_t                *ctx_data_cpu_addr;
+-
+-      struct amdgpu_bo        *mqd_data_obj;
+-      uint64_t                mqd_data_gpu_addr;
+-      uint32_t                *mqd_data_cpu_addr;
+-
+-      struct amdgpu_bo        *ring_data_obj;
+-      uint64_t                ring_data_gpu_addr;
+-      uint32_t                *ring_data_cpu_addr;
+-
+-
+-      struct amdgpu_vm        *vm;
+-      struct amdgpu_bo_va     *bo_va;
+-      uint32_t                pasid;
+-      uint32_t                vm_cntx_cntl;
+-      uint32_t                num_queues;
+-};
+-
+-static int map_ring_data(struct amdgpu_device *adev, struct amdgpu_vm *vm,
+-                        struct amdgpu_bo *bo, struct amdgpu_bo_va **bo_va,
+-                        uint64_t addr, uint32_t size)
+-{
+-      struct amdgpu_sync sync;
+-      struct drm_exec exec;
+-      int r;
+-
+-      amdgpu_sync_create(&sync);
+-
+-      drm_exec_init(&exec, 0, 0);
+-      drm_exec_until_all_locked(&exec) {
+-              r = drm_exec_lock_obj(&exec, &bo->tbo.base);
+-              drm_exec_retry_on_contention(&exec);
+-              if (unlikely(r))
+-                      goto error_fini_exec;
+-
+-              r = amdgpu_vm_lock_pd(vm, &exec, 0);
+-              drm_exec_retry_on_contention(&exec);
+-              if (unlikely(r))
+-                      goto error_fini_exec;
+-      }
+-
+-      *bo_va = amdgpu_vm_bo_add(adev, vm, bo);
+-      if (!*bo_va) {
+-              r = -ENOMEM;
+-              goto error_fini_exec;
+-      }
+-
+-      r = amdgpu_vm_bo_map(adev, *bo_va, addr, 0, size,
+-                           AMDGPU_PTE_READABLE | AMDGPU_PTE_WRITEABLE |
+-                           AMDGPU_PTE_EXECUTABLE);
+-
+-      if (r)
+-              goto error_del_bo_va;
+-
+-
+-      r = amdgpu_vm_bo_update(adev, *bo_va, false);
+-      if (r)
+-              goto error_del_bo_va;
+-
+-      amdgpu_sync_fence(&sync, (*bo_va)->last_pt_update);
+-
+-      r = amdgpu_vm_update_pdes(adev, vm, false);
+-      if (r)
+-              goto error_del_bo_va;
+-
+-      amdgpu_sync_fence(&sync, vm->last_update);
+-
+-      amdgpu_sync_wait(&sync, false);
+-      drm_exec_fini(&exec);
+-
+-      amdgpu_sync_free(&sync);
+-
+-      return 0;
+-
+-error_del_bo_va:
+-      amdgpu_vm_bo_del(adev, *bo_va);
+-      amdgpu_sync_free(&sync);
+-
+-error_fini_exec:
+-      drm_exec_fini(&exec);
+-      amdgpu_sync_free(&sync);
+-      return r;
+-}
+-
+-static int unmap_ring_data(struct amdgpu_device *adev, struct amdgpu_vm *vm,
+-                          struct amdgpu_bo *bo, struct amdgpu_bo_va *bo_va,
+-                          uint64_t addr)
+-{
+-      struct drm_exec exec;
+-      long r;
+-
+-      drm_exec_init(&exec, 0, 0);
+-      drm_exec_until_all_locked(&exec) {
+-              r = drm_exec_lock_obj(&exec, &bo->tbo.base);
+-              drm_exec_retry_on_contention(&exec);
+-              if (unlikely(r))
+-                      goto out_unlock;
+-
+-              r = amdgpu_vm_lock_pd(vm, &exec, 0);
+-              drm_exec_retry_on_contention(&exec);
+-              if (unlikely(r))
+-                      goto out_unlock;
+-      }
+-
+-
+-      r = amdgpu_vm_bo_unmap(adev, bo_va, addr);
+-      if (r)
+-              goto out_unlock;
+-
+-      amdgpu_vm_bo_del(adev, bo_va);
+-
+-out_unlock:
+-      drm_exec_fini(&exec);
+-
+-      return r;
+-}
+-
+-static void setup_vpe_queue(struct amdgpu_device *adev,
+-                          struct umsch_mm_test *test,
+-                          struct umsch_mm_test_queue_info *qinfo)
+-{
+-      struct MQD_INFO *mqd = (struct MQD_INFO *)test->mqd_data_cpu_addr;
+-      uint64_t ring_gpu_addr = test->ring_data_gpu_addr;
+-
+-      mqd->rb_base_lo = (ring_gpu_addr >> 8);
+-      mqd->rb_base_hi = (ring_gpu_addr >> 40);
+-      mqd->rb_size = PAGE_SIZE / 4;
+-      mqd->wptr_val = 0;
+-      mqd->rptr_val = 0;
+-      mqd->unmapped = 1;
+-
+-      if (adev->vpe.collaborate_mode)
+-              memcpy(++mqd, test->mqd_data_cpu_addr, sizeof(struct MQD_INFO));
+-
+-      qinfo->mqd_addr = test->mqd_data_gpu_addr;
+-      qinfo->csa_addr = test->ctx_data_gpu_addr +
+-              offsetof(struct umsch_mm_test_ctx_data, vpe_ctx_csa);
+-      qinfo->doorbell_offset_0 = 0;
+-      qinfo->doorbell_offset_1 = 0;
+-}
+-
+-static void setup_vcn_queue(struct amdgpu_device *adev,
+-                          struct umsch_mm_test *test,
+-                          struct umsch_mm_test_queue_info *qinfo)
+-{
+-}
+-
+-static int add_test_queue(struct amdgpu_device *adev,
+-                        struct umsch_mm_test *test,
+-                        struct umsch_mm_test_queue_info *qinfo)
+-{
+-      struct umsch_mm_add_queue_input queue_input = {};
+-      int r;
+-
+-      queue_input.process_id = test->pasid;
+-      queue_input.page_table_base_addr = amdgpu_gmc_pd_addr(test->vm->root.bo);
+-
+-      queue_input.process_va_start = 0;
+-      queue_input.process_va_end = (adev->vm_manager.max_pfn - 1) << AMDGPU_GPU_PAGE_SHIFT;
+-
+-      queue_input.process_quantum = 100000; /* 10ms */
+-      queue_input.process_csa_addr = test->ctx_data_gpu_addr +
+-                                     offsetof(struct umsch_mm_test_ctx_data, process_csa);
+-
+-      queue_input.context_quantum = 10000; /* 1ms */
+-      queue_input.context_csa_addr = qinfo->csa_addr;
+-
+-      queue_input.inprocess_context_priority = CONTEXT_PRIORITY_LEVEL_NORMAL;
+-      queue_input.context_global_priority_level = CONTEXT_PRIORITY_LEVEL_NORMAL;
+-      queue_input.doorbell_offset_0 = qinfo->doorbell_offset_0;
+-      queue_input.doorbell_offset_1 = qinfo->doorbell_offset_1;
+-
+-      queue_input.engine_type = qinfo->engine;
+-      queue_input.mqd_addr = qinfo->mqd_addr;
+-      queue_input.vm_context_cntl = test->vm_cntx_cntl;
+-
+-      amdgpu_umsch_mm_lock(&adev->umsch_mm);
+-      r = adev->umsch_mm.funcs->add_queue(&adev->umsch_mm, &queue_input);
+-      amdgpu_umsch_mm_unlock(&adev->umsch_mm);
+-      if (r)
+-              return r;
+-
+-      return 0;
+-}
+-
+-static int remove_test_queue(struct amdgpu_device *adev,
+-                           struct umsch_mm_test *test,
+-                           struct umsch_mm_test_queue_info *qinfo)
+-{
+-      struct umsch_mm_remove_queue_input queue_input = {};
+-      int r;
+-
+-      queue_input.doorbell_offset_0 = qinfo->doorbell_offset_0;
+-      queue_input.doorbell_offset_1 = qinfo->doorbell_offset_1;
+-      queue_input.context_csa_addr = qinfo->csa_addr;
+-
+-      amdgpu_umsch_mm_lock(&adev->umsch_mm);
+-      r = adev->umsch_mm.funcs->remove_queue(&adev->umsch_mm, &queue_input);
+-      amdgpu_umsch_mm_unlock(&adev->umsch_mm);
+-      if (r)
+-              return r;
+-
+-      return 0;
+-}
+-
+-static int submit_vpe_queue(struct amdgpu_device *adev, struct umsch_mm_test *test)
+-{
+-      struct MQD_INFO *mqd = (struct MQD_INFO *)test->mqd_data_cpu_addr;
+-      uint32_t *ring = test->ring_data_cpu_addr +
+-              offsetof(struct umsch_mm_test_ring_data, vpe_ring) / 4;
+-      uint32_t *ib = test->ring_data_cpu_addr +
+-              offsetof(struct umsch_mm_test_ring_data, vpe_ib) / 4;
+-      uint64_t ib_gpu_addr = test->ring_data_gpu_addr +
+-              offsetof(struct umsch_mm_test_ring_data, vpe_ib);
+-      uint32_t *fence = ib + 2048 / 4;
+-      uint64_t fence_gpu_addr = ib_gpu_addr + 2048;
+-      const uint32_t test_pattern = 0xdeadbeef;
+-      int i;
+-
+-      ib[0] = VPE_CMD_HEADER(VPE_CMD_OPCODE_FENCE, 0);
+-      ib[1] = lower_32_bits(fence_gpu_addr);
+-      ib[2] = upper_32_bits(fence_gpu_addr);
+-      ib[3] = test_pattern;
+-
+-      ring[0] = VPE_CMD_HEADER(VPE_CMD_OPCODE_INDIRECT, 0);
+-      ring[1] = (ib_gpu_addr & 0xffffffe0);
+-      ring[2] = upper_32_bits(ib_gpu_addr);
+-      ring[3] = 4;
+-      ring[4] = 0;
+-      ring[5] = 0;
+-
+-      mqd->wptr_val = (6 << 2);
+-      if (adev->vpe.collaborate_mode)
+-              (++mqd)->wptr_val = (6 << 2);
+-
+-      WDOORBELL32(adev->umsch_mm.agdb_index[CONTEXT_PRIORITY_LEVEL_NORMAL], mqd->wptr_val);
+-
+-      for (i = 0; i < adev->usec_timeout; i++) {
+-              if (*fence == test_pattern)
+-                      return 0;
+-              udelay(1);
+-      }
+-
+-      dev_err(adev->dev, "vpe queue submission timeout\n");
+-
+-      return -ETIMEDOUT;
+-}
+-
+-static int submit_vcn_queue(struct amdgpu_device *adev, struct umsch_mm_test *test)
+-{
+-      return 0;
+-}
+-
+-static int setup_umsch_mm_test(struct amdgpu_device *adev,
+-                        struct umsch_mm_test *test)
+-{
+-      struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_MMHUB0(0)];
+-      int r;
+-
+-      test->vm_cntx_cntl = hub->vm_cntx_cntl;
+-
+-      test->vm = kzalloc(sizeof(*test->vm), GFP_KERNEL);
+-      if (!test->vm) {
+-              r = -ENOMEM;
+-              return r;
+-      }
+-
+-      r = amdgpu_vm_init(adev, test->vm, -1);
+-      if (r)
+-              goto error_free_vm;
+-
+-      r = amdgpu_pasid_alloc(16);
+-      if (r < 0)
+-              goto error_fini_vm;
+-      test->pasid = r;
+-
+-      r = amdgpu_bo_create_kernel(adev, sizeof(struct umsch_mm_test_ctx_data),
+-                                  PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT,
+-                                  &test->ctx_data_obj,
+-                                  &test->ctx_data_gpu_addr,
+-                                  (void **)&test->ctx_data_cpu_addr);
+-      if (r)
+-              goto error_free_pasid;
+-
+-      memset(test->ctx_data_cpu_addr, 0, sizeof(struct umsch_mm_test_ctx_data));
+-
+-      r = amdgpu_bo_create_kernel(adev, PAGE_SIZE,
+-                                  PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT,
+-                                  &test->mqd_data_obj,
+-                                  &test->mqd_data_gpu_addr,
+-                                  (void **)&test->mqd_data_cpu_addr);
+-      if (r)
+-              goto error_free_ctx_data_obj;
+-
+-      memset(test->mqd_data_cpu_addr, 0, PAGE_SIZE);
+-
+-      r = amdgpu_bo_create_kernel(adev, sizeof(struct umsch_mm_test_ring_data),
+-                                  PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT,
+-                                  &test->ring_data_obj,
+-                                  NULL,
+-                                  (void **)&test->ring_data_cpu_addr);
+-      if (r)
+-              goto error_free_mqd_data_obj;
+-
+-      memset(test->ring_data_cpu_addr, 0, sizeof(struct umsch_mm_test_ring_data));
+-
+-      test->ring_data_gpu_addr = AMDGPU_VA_RESERVED_BOTTOM;
+-      r = map_ring_data(adev, test->vm, test->ring_data_obj, &test->bo_va,
+-                        test->ring_data_gpu_addr, sizeof(struct umsch_mm_test_ring_data));
+-      if (r)
+-              goto error_free_ring_data_obj;
+-
+-      return 0;
+-
+-error_free_ring_data_obj:
+-      amdgpu_bo_free_kernel(&test->ring_data_obj, NULL,
+-                            (void **)&test->ring_data_cpu_addr);
+-error_free_mqd_data_obj:
+-      amdgpu_bo_free_kernel(&test->mqd_data_obj, &test->mqd_data_gpu_addr,
+-                            (void **)&test->mqd_data_cpu_addr);
+-error_free_ctx_data_obj:
+-      amdgpu_bo_free_kernel(&test->ctx_data_obj, &test->ctx_data_gpu_addr,
+-                            (void **)&test->ctx_data_cpu_addr);
+-error_free_pasid:
+-      amdgpu_pasid_free(test->pasid);
+-error_fini_vm:
+-      amdgpu_vm_fini(adev, test->vm);
+-error_free_vm:
+-      kfree(test->vm);
+-
+-      return r;
+-}
+-
+-static void cleanup_umsch_mm_test(struct amdgpu_device *adev,
+-                                struct umsch_mm_test *test)
+-{
+-      unmap_ring_data(adev, test->vm, test->ring_data_obj,
+-                      test->bo_va, test->ring_data_gpu_addr);
+-      amdgpu_bo_free_kernel(&test->mqd_data_obj, &test->mqd_data_gpu_addr,
+-                            (void **)&test->mqd_data_cpu_addr);
+-      amdgpu_bo_free_kernel(&test->ring_data_obj, NULL,
+-                            (void **)&test->ring_data_cpu_addr);
+-      amdgpu_bo_free_kernel(&test->ctx_data_obj, &test->ctx_data_gpu_addr,
+-                             (void **)&test->ctx_data_cpu_addr);
+-      amdgpu_pasid_free(test->pasid);
+-      amdgpu_vm_fini(adev, test->vm);
+-      kfree(test->vm);
+-}
+-
+-static int setup_test_queues(struct amdgpu_device *adev,
+-                           struct umsch_mm_test *test,
+-                           struct umsch_mm_test_queue_info *qinfo)
+-{
+-      int i, r;
+-
+-      for (i = 0; i < test->num_queues; i++) {
+-              if (qinfo[i].engine == UMSCH_SWIP_ENGINE_TYPE_VPE)
+-                      setup_vpe_queue(adev, test, &qinfo[i]);
+-              else
+-                      setup_vcn_queue(adev, test, &qinfo[i]);
+-
+-              r = add_test_queue(adev, test, &qinfo[i]);
+-              if (r)
+-                      return r;
+-      }
+-
+-      return 0;
+-}
+-
+-static int submit_test_queues(struct amdgpu_device *adev,
+-                            struct umsch_mm_test *test,
+-                            struct umsch_mm_test_queue_info *qinfo)
+-{
+-      int i, r;
+-
+-      for (i = 0; i < test->num_queues; i++) {
+-              if (qinfo[i].engine == UMSCH_SWIP_ENGINE_TYPE_VPE)
+-                      r = submit_vpe_queue(adev, test);
+-              else
+-                      r = submit_vcn_queue(adev, test);
+-              if (r)
+-                      return r;
+-      }
+-
+-      return 0;
+-}
+-
+-static void cleanup_test_queues(struct amdgpu_device *adev,
+-                            struct umsch_mm_test *test,
+-                            struct umsch_mm_test_queue_info *qinfo)
+-{
+-      int i;
+-
+-      for (i = 0; i < test->num_queues; i++)
+-              remove_test_queue(adev, test, &qinfo[i]);
+-}
+-
+-static int umsch_mm_test(struct amdgpu_device *adev)
+-{
+-      struct umsch_mm_test_queue_info qinfo[] = {
+-              { .engine = UMSCH_SWIP_ENGINE_TYPE_VPE },
+-      };
+-      struct umsch_mm_test test = { .num_queues = ARRAY_SIZE(qinfo) };
+-      int r;
+-
+-      r = setup_umsch_mm_test(adev, &test);
+-      if (r)
+-              return r;
+-
+-      r = setup_test_queues(adev, &test, qinfo);
+-      if (r)
+-              goto cleanup;
+-
+-      r = submit_test_queues(adev, &test, qinfo);
+-      if (r)
+-              goto cleanup;
+-
+-      cleanup_test_queues(adev, &test, qinfo);
+-      cleanup_umsch_mm_test(adev, &test);
+-
+-      return 0;
+-
+-cleanup:
+-      cleanup_test_queues(adev, &test, qinfo);
+-      cleanup_umsch_mm_test(adev, &test);
+-      return r;
+-}
+-
+ int amdgpu_umsch_mm_submit_pkt(struct amdgpu_umsch_mm *umsch, void *pkt, int ndws)
+ {
+       struct amdgpu_ring *ring = &umsch->ring;
+@@ -792,7 +335,7 @@ static int umsch_mm_late_init(struct amdgpu_ip_block *ip_block)
+       if (amdgpu_in_reset(adev) || adev->in_s0ix || adev->in_suspend)
+               return 0;
+-      return umsch_mm_test(adev);
++      return 0;
+ }
+ static int umsch_mm_sw_init(struct amdgpu_ip_block *ip_block)
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-amdgpu-vcn5.0.1-use-correct-dpm-helper.patch b/queue-6.14/drm-amdgpu-vcn5.0.1-use-correct-dpm-helper.patch
new file mode 100644 (file)
index 0000000..dbe257b
--- /dev/null
@@ -0,0 +1,57 @@
+From 626a456207c1f23d550513377a858e526f94e985 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Feb 2025 17:45:14 -0500
+Subject: drm/amdgpu/vcn5.0.1: use correct dpm helper
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit 0487f50310cfeec1bb4480a67294fc7081c5ed22 ]
+
+The VCN and UVD helpers were split in
+commit ff69bba05f08 ("drm/amd/pm: add inst to dpm_set_powergating_by_smu")
+However, this happened in parallel to the vcn 5.0.1
+development so it was missed there.
+
+Fixes: 346492f30ce3 ("drm/amdgpu: Add VCN_5_0_1 support")
+Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: Sonny Jiang <sonjiang@amd.com>
+Cc: Boyuan Zhang <boyuan.zhang@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c
+index 8b463c977d08f..8b0b3739a5377 100644
+--- a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c
++++ b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c
+@@ -575,8 +575,10 @@ static int vcn_v5_0_1_start(struct amdgpu_device *adev)
+       uint32_t tmp;
+       int i, j, k, r, vcn_inst;
+-      if (adev->pm.dpm_enabled)
+-              amdgpu_dpm_enable_uvd(adev, true);
++      for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
++              if (adev->pm.dpm_enabled)
++                      amdgpu_dpm_enable_vcn(adev, true, i);
++      }
+       for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
+               fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
+@@ -816,8 +818,10 @@ static int vcn_v5_0_1_stop(struct amdgpu_device *adev)
+               WREG32_SOC15(VCN, vcn_inst, regUVD_STATUS, 0);
+       }
+-      if (adev->pm.dpm_enabled)
+-              amdgpu_dpm_enable_uvd(adev, false);
++      for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
++              if (adev->pm.dpm_enabled)
++                      amdgpu_dpm_enable_vcn(adev, false, i);
++      }
+       return 0;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-amdkfd-fix-circular-locking-dependency-in-svm_ra.patch b/queue-6.14/drm-amdkfd-fix-circular-locking-dependency-in-svm_ra.patch
new file mode 100644 (file)
index 0000000..f829f51
--- /dev/null
@@ -0,0 +1,279 @@
+From 71325927c8d8085cd03afbd6c80ba828c855d064 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Feb 2025 13:46:32 +0530
+Subject: drm/amdkfd: Fix Circular Locking Dependency in
+ 'svm_range_cpu_invalidate_pagetables'
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+
+[ Upstream commit fddc45026311c05a5355fd34b9dc0a1d7eaef4a2 ]
+
+This commit addresses a circular locking dependency in the
+svm_range_cpu_invalidate_pagetables function. The function previously
+held a lock while determining whether to perform an unmap or eviction
+operation, which could lead to deadlocks.
+
+Fixes the below:
+
+[  223.418794] ======================================================
+[  223.418820] WARNING: possible circular locking dependency detected
+[  223.418845] 6.12.0-amdstaging-drm-next-lol-050225 #14 Tainted: G     U     OE
+[  223.418869] ------------------------------------------------------
+[  223.418889] kfdtest/3939 is trying to acquire lock:
+[  223.418906] ffff8957552eae38 (&dqm->lock_hidden){+.+.}-{3:3}, at: evict_process_queues_cpsch+0x43/0x210 [amdgpu]
+[  223.419302]
+               but task is already holding lock:
+[  223.419303] ffff8957556b83b0 (&prange->lock){+.+.}-{3:3}, at: svm_range_cpu_invalidate_pagetables+0x9d/0x850 [amdgpu]
+[  223.419447] Console: switching to colour dummy device 80x25
+[  223.419477] [IGT] amd_basic: executing
+[  223.419599]
+               which lock already depends on the new lock.
+
+[  223.419611]
+               the existing dependency chain (in reverse order) is:
+[  223.419621]
+               -> #2 (&prange->lock){+.+.}-{3:3}:
+[  223.419636]        __mutex_lock+0x85/0xe20
+[  223.419647]        mutex_lock_nested+0x1b/0x30
+[  223.419656]        svm_range_validate_and_map+0x2f1/0x15b0 [amdgpu]
+[  223.419954]        svm_range_set_attr+0xe8c/0x1710 [amdgpu]
+[  223.420236]        svm_ioctl+0x46/0x50 [amdgpu]
+[  223.420503]        kfd_ioctl_svm+0x50/0x90 [amdgpu]
+[  223.420763]        kfd_ioctl+0x409/0x6d0 [amdgpu]
+[  223.421024]        __x64_sys_ioctl+0x95/0xd0
+[  223.421036]        x64_sys_call+0x1205/0x20d0
+[  223.421047]        do_syscall_64+0x87/0x140
+[  223.421056]        entry_SYSCALL_64_after_hwframe+0x76/0x7e
+[  223.421068]
+               -> #1 (reservation_ww_class_mutex){+.+.}-{3:3}:
+[  223.421084]        __ww_mutex_lock.constprop.0+0xab/0x1560
+[  223.421095]        ww_mutex_lock+0x2b/0x90
+[  223.421103]        amdgpu_amdkfd_alloc_gtt_mem+0xcc/0x2b0 [amdgpu]
+[  223.421361]        add_queue_mes+0x3bc/0x440 [amdgpu]
+[  223.421623]        unhalt_cpsch+0x1ae/0x240 [amdgpu]
+[  223.421888]        kgd2kfd_start_sched+0x5e/0xd0 [amdgpu]
+[  223.422148]        amdgpu_amdkfd_start_sched+0x3d/0x50 [amdgpu]
+[  223.422414]        amdgpu_gfx_enforce_isolation_handler+0x132/0x270 [amdgpu]
+[  223.422662]        process_one_work+0x21e/0x680
+[  223.422673]        worker_thread+0x190/0x330
+[  223.422682]        kthread+0xe7/0x120
+[  223.422690]        ret_from_fork+0x3c/0x60
+[  223.422699]        ret_from_fork_asm+0x1a/0x30
+[  223.422708]
+               -> #0 (&dqm->lock_hidden){+.+.}-{3:3}:
+[  223.422723]        __lock_acquire+0x16f4/0x2810
+[  223.422734]        lock_acquire+0xd1/0x300
+[  223.422742]        __mutex_lock+0x85/0xe20
+[  223.422751]        mutex_lock_nested+0x1b/0x30
+[  223.422760]        evict_process_queues_cpsch+0x43/0x210 [amdgpu]
+[  223.423025]        kfd_process_evict_queues+0x8a/0x1d0 [amdgpu]
+[  223.423285]        kgd2kfd_quiesce_mm+0x43/0x90 [amdgpu]
+[  223.423540]        svm_range_cpu_invalidate_pagetables+0x4a7/0x850 [amdgpu]
+[  223.423807]        __mmu_notifier_invalidate_range_start+0x1f5/0x250
+[  223.423819]        copy_page_range+0x1e94/0x1ea0
+[  223.423829]        copy_process+0x172f/0x2ad0
+[  223.423839]        kernel_clone+0x9c/0x3f0
+[  223.423847]        __do_sys_clone+0x66/0x90
+[  223.423856]        __x64_sys_clone+0x25/0x30
+[  223.423864]        x64_sys_call+0x1d7c/0x20d0
+[  223.423872]        do_syscall_64+0x87/0x140
+[  223.423880]        entry_SYSCALL_64_after_hwframe+0x76/0x7e
+[  223.423891]
+               other info that might help us debug this:
+
+[  223.423903] Chain exists of:
+                 &dqm->lock_hidden --> reservation_ww_class_mutex --> &prange->lock
+
+[  223.423926]  Possible unsafe locking scenario:
+
+[  223.423935]        CPU0                    CPU1
+[  223.423942]        ----                    ----
+[  223.423949]   lock(&prange->lock);
+[  223.423958]                                lock(reservation_ww_class_mutex);
+[  223.423970]                                lock(&prange->lock);
+[  223.423981]   lock(&dqm->lock_hidden);
+[  223.423990]
+                *** DEADLOCK ***
+
+[  223.423999] 5 locks held by kfdtest/3939:
+[  223.424006]  #0: ffffffffb82b4fc0 (dup_mmap_sem){.+.+}-{0:0}, at: copy_process+0x1387/0x2ad0
+[  223.424026]  #1: ffff89575eda81b0 (&mm->mmap_lock){++++}-{3:3}, at: copy_process+0x13a8/0x2ad0
+[  223.424046]  #2: ffff89575edaf3b0 (&mm->mmap_lock/1){+.+.}-{3:3}, at: copy_process+0x13e4/0x2ad0
+[  223.424066]  #3: ffffffffb82e76e0 (mmu_notifier_invalidate_range_start){+.+.}-{0:0}, at: copy_page_range+0x1cea/0x1ea0
+[  223.424088]  #4: ffff8957556b83b0 (&prange->lock){+.+.}-{3:3}, at: svm_range_cpu_invalidate_pagetables+0x9d/0x850 [amdgpu]
+[  223.424365]
+               stack backtrace:
+[  223.424374] CPU: 0 UID: 0 PID: 3939 Comm: kfdtest Tainted: G     U     OE      6.12.0-amdstaging-drm-next-lol-050225 #14
+[  223.424392] Tainted: [U]=USER, [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
+[  223.424401] Hardware name: Gigabyte Technology Co., Ltd. X570 AORUS PRO WIFI/X570 AORUS PRO WIFI, BIOS F36a 02/16/2022
+[  223.424416] Call Trace:
+[  223.424423]  <TASK>
+[  223.424430]  dump_stack_lvl+0x9b/0xf0
+[  223.424441]  dump_stack+0x10/0x20
+[  223.424449]  print_circular_bug+0x275/0x350
+[  223.424460]  check_noncircular+0x157/0x170
+[  223.424469]  ? __bfs+0xfd/0x2c0
+[  223.424481]  __lock_acquire+0x16f4/0x2810
+[  223.424490]  ? srso_return_thunk+0x5/0x5f
+[  223.424505]  lock_acquire+0xd1/0x300
+[  223.424514]  ? evict_process_queues_cpsch+0x43/0x210 [amdgpu]
+[  223.424783]  __mutex_lock+0x85/0xe20
+[  223.424792]  ? evict_process_queues_cpsch+0x43/0x210 [amdgpu]
+[  223.425058]  ? srso_return_thunk+0x5/0x5f
+[  223.425067]  ? mark_held_locks+0x54/0x90
+[  223.425076]  ? evict_process_queues_cpsch+0x43/0x210 [amdgpu]
+[  223.425339]  ? srso_return_thunk+0x5/0x5f
+[  223.425350]  mutex_lock_nested+0x1b/0x30
+[  223.425358]  ? mutex_lock_nested+0x1b/0x30
+[  223.425367]  evict_process_queues_cpsch+0x43/0x210 [amdgpu]
+[  223.425631]  kfd_process_evict_queues+0x8a/0x1d0 [amdgpu]
+[  223.425893]  kgd2kfd_quiesce_mm+0x43/0x90 [amdgpu]
+[  223.426156]  svm_range_cpu_invalidate_pagetables+0x4a7/0x850 [amdgpu]
+[  223.426423]  ? srso_return_thunk+0x5/0x5f
+[  223.426436]  __mmu_notifier_invalidate_range_start+0x1f5/0x250
+[  223.426450]  copy_page_range+0x1e94/0x1ea0
+[  223.426461]  ? srso_return_thunk+0x5/0x5f
+[  223.426474]  ? srso_return_thunk+0x5/0x5f
+[  223.426484]  ? lock_acquire+0xd1/0x300
+[  223.426494]  ? copy_process+0x1718/0x2ad0
+[  223.426502]  ? srso_return_thunk+0x5/0x5f
+[  223.426510]  ? sched_clock_noinstr+0x9/0x10
+[  223.426519]  ? local_clock_noinstr+0xe/0xc0
+[  223.426528]  ? copy_process+0x1718/0x2ad0
+[  223.426537]  ? srso_return_thunk+0x5/0x5f
+[  223.426550]  copy_process+0x172f/0x2ad0
+[  223.426569]  kernel_clone+0x9c/0x3f0
+[  223.426577]  ? __schedule+0x4c9/0x1b00
+[  223.426586]  ? srso_return_thunk+0x5/0x5f
+[  223.426594]  ? sched_clock_noinstr+0x9/0x10
+[  223.426602]  ? srso_return_thunk+0x5/0x5f
+[  223.426610]  ? local_clock_noinstr+0xe/0xc0
+[  223.426619]  ? schedule+0x107/0x1a0
+[  223.426629]  __do_sys_clone+0x66/0x90
+[  223.426643]  __x64_sys_clone+0x25/0x30
+[  223.426652]  x64_sys_call+0x1d7c/0x20d0
+[  223.426661]  do_syscall_64+0x87/0x140
+[  223.426671]  ? srso_return_thunk+0x5/0x5f
+[  223.426679]  ? common_nsleep+0x44/0x50
+[  223.426690]  ? srso_return_thunk+0x5/0x5f
+[  223.426698]  ? trace_hardirqs_off+0x52/0xd0
+[  223.426709]  ? srso_return_thunk+0x5/0x5f
+[  223.426717]  ? syscall_exit_to_user_mode+0xcc/0x200
+[  223.426727]  ? srso_return_thunk+0x5/0x5f
+[  223.426736]  ? do_syscall_64+0x93/0x140
+[  223.426748]  ? srso_return_thunk+0x5/0x5f
+[  223.426756]  ? up_write+0x1c/0x1e0
+[  223.426765]  ? srso_return_thunk+0x5/0x5f
+[  223.426775]  ? srso_return_thunk+0x5/0x5f
+[  223.426783]  ? trace_hardirqs_off+0x52/0xd0
+[  223.426792]  ? srso_return_thunk+0x5/0x5f
+[  223.426800]  ? syscall_exit_to_user_mode+0xcc/0x200
+[  223.426810]  ? srso_return_thunk+0x5/0x5f
+[  223.426818]  ? do_syscall_64+0x93/0x140
+[  223.426826]  ? syscall_exit_to_user_mode+0xcc/0x200
+[  223.426836]  ? srso_return_thunk+0x5/0x5f
+[  223.426844]  ? do_syscall_64+0x93/0x140
+[  223.426853]  ? srso_return_thunk+0x5/0x5f
+[  223.426861]  ? irqentry_exit+0x6b/0x90
+[  223.426869]  ? srso_return_thunk+0x5/0x5f
+[  223.426877]  ? exc_page_fault+0xa7/0x2c0
+[  223.426888]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
+[  223.426898] RIP: 0033:0x7f46758eab57
+[  223.426906] Code: ba 04 00 f3 0f 1e fa 64 48 8b 04 25 10 00 00 00 45 31 c0 31 d2 31 f6 bf 11 00 20 01 4c 8d 90 d0 02 00 00 b8 38 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 41 41 89 c0 85 c0 75 2c 64 48 8b 04 25 10 00
+[  223.426930] RSP: 002b:00007fff5c3e5188 EFLAGS: 00000246 ORIG_RAX: 0000000000000038
+[  223.426943] RAX: ffffffffffffffda RBX: 00007f4675f8c040 RCX: 00007f46758eab57
+[  223.426954] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000001200011
+[  223.426965] RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000
+[  223.426975] R10: 00007f4675e81a50 R11: 0000000000000246 R12: 0000000000000001
+[  223.426986] R13: 00007fff5c3e5470 R14: 00007fff5c3e53e0 R15: 00007fff5c3e5410
+[  223.427004]  </TASK>
+
+v2: To resolve this issue, the allocation of the process context buffer
+(`proc_ctx_bo`) has been moved from the `add_queue_mes` function to the
+`pqm_create_queue` function. This change ensures that the buffer is
+allocated only when the first queue for a process is created and only if
+the Micro Engine Scheduler (MES) is enabled. (Felix)
+
+v3: Fix typo s/Memory Execution Scheduler (MES)/Micro Engine Scheduler
+in commit message. (Lijo)
+
+Fixes: 438b39ac74e2 ("drm/amdkfd: pause autosuspend when creating pdd")
+Cc: Jesse Zhang <jesse.zhang@amd.com>
+Cc: Yunxiang Li <Yunxiang.Li@amd.com>
+Cc: Philip Yang <Philip.Yang@amd.com>
+Cc: Alex Sierra <alex.sierra@amd.com>
+Cc: Felix Kuehling <Felix.Kuehling@amd.com>
+Cc: Christian König <christian.koenig@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+Reviewed-by: Felix Kuehling <felix.kuehling@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../drm/amd/amdkfd/kfd_device_queue_manager.c    | 15 ---------------
+ .../drm/amd/amdkfd/kfd_process_queue_manager.c   | 16 ++++++++++++++++
+ 2 files changed, 16 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+index 34c2c42c0f95c..ad9cb50a9fa38 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+@@ -207,21 +207,6 @@ static int add_queue_mes(struct device_queue_manager *dqm, struct queue *q,
+       if (!down_read_trylock(&adev->reset_domain->sem))
+               return -EIO;
+-      if (!pdd->proc_ctx_cpu_ptr) {
+-              r = amdgpu_amdkfd_alloc_gtt_mem(adev,
+-                              AMDGPU_MES_PROC_CTX_SIZE,
+-                              &pdd->proc_ctx_bo,
+-                              &pdd->proc_ctx_gpu_addr,
+-                              &pdd->proc_ctx_cpu_ptr,
+-                              false);
+-              if (r) {
+-                      dev_err(adev->dev,
+-                              "failed to allocate process context bo\n");
+-                      return r;
+-              }
+-              memset(pdd->proc_ctx_cpu_ptr, 0, AMDGPU_MES_PROC_CTX_SIZE);
+-      }
+-
+       memset(&queue_input, 0x0, sizeof(struct mes_add_queue_input));
+       queue_input.process_id = qpd->pqm->process->pasid;
+       queue_input.page_table_base_addr =  qpd->page_table_base;
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
+index bd36a75309e12..6c02bc36d6344 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
+@@ -363,10 +363,26 @@ int pqm_create_queue(struct process_queue_manager *pqm,
+       if (retval != 0)
+               return retval;
++      /* Register process if this is the first queue */
+       if (list_empty(&pdd->qpd.queues_list) &&
+           list_empty(&pdd->qpd.priv_queue_list))
+               dev->dqm->ops.register_process(dev->dqm, &pdd->qpd);
++      /* Allocate proc_ctx_bo only if MES is enabled and this is the first queue */
++      if (!pdd->proc_ctx_cpu_ptr && dev->kfd->shared_resources.enable_mes) {
++              retval = amdgpu_amdkfd_alloc_gtt_mem(dev->adev,
++                                                   AMDGPU_MES_PROC_CTX_SIZE,
++                                                   &pdd->proc_ctx_bo,
++                                                   &pdd->proc_ctx_gpu_addr,
++                                                   &pdd->proc_ctx_cpu_ptr,
++                                                   false);
++              if (retval) {
++                      dev_err(dev->adev->dev, "failed to allocate process context bo\n");
++                      return retval;
++              }
++              memset(pdd->proc_ctx_cpu_ptr, 0, AMDGPU_MES_PROC_CTX_SIZE);
++      }
++
+       pqn = kzalloc(sizeof(*pqn), GFP_KERNEL);
+       if (!pqn) {
+               retval = -ENOMEM;
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-bridge-it6505-fix-hdcp-v-match-check-is-not-perf.patch b/queue-6.14/drm-bridge-it6505-fix-hdcp-v-match-check-is-not-perf.patch
new file mode 100644 (file)
index 0000000..33cc72c
--- /dev/null
@@ -0,0 +1,51 @@
+From d8c6d0530a0f39a26b2427280f7f2f3107c8fd31 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Jan 2025 15:01:51 +0800
+Subject: drm/bridge: it6505: fix HDCP V match check is not performed correctly
+
+From: Hermes Wu <Hermes.wu@ite.com.tw>
+
+[ Upstream commit a5072fc77fb9e38fa9fd883642c83c3720049159 ]
+
+Fix a typo where V compare incorrectly compares av[] with av[] itself,
+which can result in HDCP failure.
+
+The loop of V compare is expected to iterate for 5 times
+which compare V array form av[0][] to av[4][].
+It should check loop counter reach the last statement "i == 5"
+before return true
+
+Fixes: 0989c02c7a5c ("drm/bridge: it6505: fix HDCP CTS compare V matching")
+Signed-off-by: Hermes Wu <Hermes.wu@ite.com.tw>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Robert Foss <rfoss@kernel.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250121-fix-hdcp-v-comp-v4-1-185f45c728dc@ite.com.tw
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/ite-it6505.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c
+index 88ef76a37fe6a..76dabca04d0d1 100644
+--- a/drivers/gpu/drm/bridge/ite-it6505.c
++++ b/drivers/gpu/drm/bridge/ite-it6505.c
+@@ -2250,12 +2250,13 @@ static bool it6505_hdcp_part2_ksvlist_check(struct it6505 *it6505)
+                       continue;
+               }
+-              for (i = 0; i < 5; i++) {
++              for (i = 0; i < 5; i++)
+                       if (bv[i][3] != av[i][0] || bv[i][2] != av[i][1] ||
+-                          av[i][1] != av[i][2] || bv[i][0] != av[i][3])
++                          bv[i][1] != av[i][2] || bv[i][0] != av[i][3])
+                               break;
+-                      DRM_DEV_DEBUG_DRIVER(dev, "V' all match!! %d, %d", retry, i);
++              if (i == 5) {
++                      DRM_DEV_DEBUG_DRIVER(dev, "V' all match!! %d", retry);
+                       return true;
+               }
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-bridge-ti-sn65dsi86-fix-multiple-instances.patch b/queue-6.14/drm-bridge-ti-sn65dsi86-fix-multiple-instances.patch
new file mode 100644 (file)
index 0000000..ac86d7c
--- /dev/null
@@ -0,0 +1,52 @@
+From 9c7116ec63b84c3adc39ee65e0217593862cbb2c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Dec 2024 15:18:46 +0100
+Subject: drm/bridge: ti-sn65dsi86: Fix multiple instances
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 574f5ee2c85a00a579549d50e9fc9c6c072ee4c4 ]
+
+Each bridge instance creates up to four auxiliary devices with different
+names.  However, their IDs are always zero, causing duplicate filename
+errors when a system has multiple bridges:
+
+    sysfs: cannot create duplicate filename '/bus/auxiliary/devices/ti_sn65dsi86.gpio.0'
+
+Fix this by using a unique instance ID per bridge instance.  The
+instance ID is derived from the I2C adapter number and the bridge's I2C
+address, to support multiple instances on the same bus.
+
+Fixes: bf73537f411b ("drm/bridge: ti-sn65dsi86: Break GPIO and MIPI-to-eDP bridge into sub-drivers")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/7a68a0e3f927e26edca6040067fb653eb06efb79.1733840089.git.geert+renesas@glider.be
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/ti-sn65dsi86.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
+index e4d9006b59f1b..b3d617505dda7 100644
+--- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c
++++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
+@@ -480,6 +480,7 @@ static int ti_sn65dsi86_add_aux_device(struct ti_sn65dsi86 *pdata,
+                                      const char *name)
+ {
+       struct device *dev = pdata->dev;
++      const struct i2c_client *client = to_i2c_client(dev);
+       struct auxiliary_device *aux;
+       int ret;
+@@ -488,6 +489,7 @@ static int ti_sn65dsi86_add_aux_device(struct ti_sn65dsi86 *pdata,
+               return -ENOMEM;
+       aux->name = name;
++      aux->id = (client->adapter->nr << 10) | client->addr;
+       aux->dev.parent = dev;
+       aux->dev.release = ti_sn65dsi86_aux_device_release;
+       device_set_of_node_from_dev(&aux->dev, dev);
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-dp_mst-fix-drm-rad-print.patch b/queue-6.14/drm-dp_mst-fix-drm-rad-print.patch
new file mode 100644 (file)
index 0000000..47c22ac
--- /dev/null
@@ -0,0 +1,95 @@
+From 51b6dbe6426f83faec6cde0f6a613ebeb3ae84d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jan 2025 17:10:59 +0800
+Subject: drm/dp_mst: Fix drm RAD print
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Wayne Lin <Wayne.Lin@amd.com>
+
+[ Upstream commit 6bbce873a9c97cb12f5455c497be279ac58e707f ]
+
+[Why]
+The RAD of sideband message printed today is incorrect.
+For RAD stored within MST branch
+- If MST branch LCT is 1, it's RAD array is untouched and remained as 0.
+- If MST branch LCT is larger than 1, use nibble to store the up facing
+  port number in cascaded sequence as illustrated below:
+
+  u8 RAD[0] = (LCT_2_UFP << 4) | LCT_3_UFP
+     RAD[1] = (LCT_4_UFP << 4) | LCT_5_UFP
+     ...
+
+In drm_dp_mst_rad_to_str(), it wrongly to use BIT_MASK(4) to fetch the port
+number of one nibble.
+
+[How]
+Adjust the code by:
+- RAD array items are valuable only for LCT >= 1.
+- Use 0xF as the mask to replace BIT_MASK(4)
+
+V2:
+- Document how RAD is constructed (Imre)
+
+V3:
+- Adjust the comment for rad[] so kdoc formats it properly (Lyude)
+
+Fixes: 2f015ec6eab6 ("drm/dp_mst: Add sideband down request tracing + selftests")
+Cc: Imre Deak <imre.deak@intel.com>
+Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Cc: Harry Wentland <hwentlan@amd.com>
+Cc: Lyude Paul <lyude@redhat.com>
+Reviewed-by: Lyude Paul <lyude@redhat.com>
+Signed-off-by: Wayne Lin <Wayne.Lin@amd.com>
+Signed-off-by: Lyude Paul <lyude@redhat.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250113091100.3314533-2-Wayne.Lin@amd.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/display/drm_dp_mst_topology.c | 8 ++++----
+ include/drm/display/drm_dp_mst_helper.h       | 7 +++++++
+ 2 files changed, 11 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c
+index 6d09bef671da0..314b394cb7e12 100644
+--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
++++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
+@@ -175,13 +175,13 @@ static int
+ drm_dp_mst_rad_to_str(const u8 rad[8], u8 lct, char *out, size_t len)
+ {
+       int i;
+-      u8 unpacked_rad[16];
++      u8 unpacked_rad[16] = {};
+-      for (i = 0; i < lct; i++) {
++      for (i = 1; i < lct; i++) {
+               if (i % 2)
+-                      unpacked_rad[i] = rad[i / 2] >> 4;
++                      unpacked_rad[i] = rad[(i - 1) / 2] >> 4;
+               else
+-                      unpacked_rad[i] = rad[i / 2] & BIT_MASK(4);
++                      unpacked_rad[i] = rad[(i - 1) / 2] & 0xF;
+       }
+       /* TODO: Eventually add something to printk so we can format the rad
+diff --git a/include/drm/display/drm_dp_mst_helper.h b/include/drm/display/drm_dp_mst_helper.h
+index e39de161c9386..2cfe1d4bfc960 100644
+--- a/include/drm/display/drm_dp_mst_helper.h
++++ b/include/drm/display/drm_dp_mst_helper.h
+@@ -222,6 +222,13 @@ struct drm_dp_mst_branch {
+        */
+       struct list_head destroy_next;
++      /**
++       * @rad: Relative Address of the MST branch.
++       * For &drm_dp_mst_topology_mgr.mst_primary, it's rad[8] are all 0,
++       * unset and unused. For MST branches connected after mst_primary,
++       * in each element of rad[] the nibbles are ordered by the most
++       * signifcant 4 bits first and the least significant 4 bits second.
++       */
+       u8 rad[8];
+       u8 lct;
+       int num_ports;
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-file-add-fdinfo-helper-for-printing-regions-with.patch b/queue-6.14/drm-file-add-fdinfo-helper-for-printing-regions-with.patch
new file mode 100644 (file)
index 0000000..658b65b
--- /dev/null
@@ -0,0 +1,108 @@
+From cea979a51b85d5b32d3065278ebcfe1393f063bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Jan 2025 17:28:10 +0000
+Subject: drm/file: Add fdinfo helper for printing regions with prefix
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Adrián Larumbe <adrian.larumbe@collabora.com>
+
+[ Upstream commit af6c2b7c46e16701fba44a21326cb634786e3e71 ]
+
+This is motivated by the desire of some drivers (eg. Panthor) to print the
+size of internal memory regions with a prefix that reflects the driver
+name, as suggested in the previous documentation commit.
+
+That means adding a new argument to print_size and making it available for
+DRM users.
+
+Cc: Tvrtko Ursulin <tursulin@ursulin.net>
+Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
+Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com>
+Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250130172851.941597-3-adrian.larumbe@collabora.com
+Stable-dep-of: e379856b428a ("drm/panthor: Replace sleep locks with spinlocks in fdinfo path")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_file.c | 26 ++++++++++++++++++--------
+ include/drm/drm_file.h     |  5 +++++
+ 2 files changed, 23 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c
+index 2289e71e2fa24..c299cd94d3f78 100644
+--- a/drivers/gpu/drm/drm_file.c
++++ b/drivers/gpu/drm/drm_file.c
+@@ -830,8 +830,11 @@ void drm_send_event(struct drm_device *dev, struct drm_pending_event *e)
+ }
+ EXPORT_SYMBOL(drm_send_event);
+-static void print_size(struct drm_printer *p, const char *stat,
+-                     const char *region, u64 sz)
++void drm_fdinfo_print_size(struct drm_printer *p,
++                         const char *prefix,
++                         const char *stat,
++                         const char *region,
++                         u64 sz)
+ {
+       const char *units[] = {"", " KiB", " MiB"};
+       unsigned u;
+@@ -842,8 +845,10 @@ static void print_size(struct drm_printer *p, const char *stat,
+               sz = div_u64(sz, SZ_1K);
+       }
+-      drm_printf(p, "drm-%s-%s:\t%llu%s\n", stat, region, sz, units[u]);
++      drm_printf(p, "%s-%s-%s:\t%llu%s\n",
++                 prefix, stat, region, sz, units[u]);
+ }
++EXPORT_SYMBOL(drm_fdinfo_print_size);
+ int drm_memory_stats_is_zero(const struct drm_memory_stats *stats)
+ {
+@@ -868,17 +873,22 @@ void drm_print_memory_stats(struct drm_printer *p,
+                           enum drm_gem_object_status supported_status,
+                           const char *region)
+ {
+-      print_size(p, "total", region, stats->private + stats->shared);
+-      print_size(p, "shared", region, stats->shared);
++      const char *prefix = "drm";
++
++      drm_fdinfo_print_size(p, prefix, "total", region,
++                            stats->private + stats->shared);
++      drm_fdinfo_print_size(p, prefix, "shared", region, stats->shared);
+       if (supported_status & DRM_GEM_OBJECT_ACTIVE)
+-              print_size(p, "active", region, stats->active);
++              drm_fdinfo_print_size(p, prefix, "active", region, stats->active);
+       if (supported_status & DRM_GEM_OBJECT_RESIDENT)
+-              print_size(p, "resident", region, stats->resident);
++              drm_fdinfo_print_size(p, prefix, "resident", region,
++                                    stats->resident);
+       if (supported_status & DRM_GEM_OBJECT_PURGEABLE)
+-              print_size(p, "purgeable", region, stats->purgeable);
++              drm_fdinfo_print_size(p, prefix, "purgeable", region,
++                                    stats->purgeable);
+ }
+ EXPORT_SYMBOL(drm_print_memory_stats);
+diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h
+index ef817926cddd3..94d365b225052 100644
+--- a/include/drm/drm_file.h
++++ b/include/drm/drm_file.h
+@@ -495,6 +495,11 @@ struct drm_memory_stats {
+ enum drm_gem_object_status;
+ int drm_memory_stats_is_zero(const struct drm_memory_stats *stats);
++void drm_fdinfo_print_size(struct drm_printer *p,
++                         const char *prefix,
++                         const char *stat,
++                         const char *region,
++                         u64 sz);
+ void drm_print_memory_stats(struct drm_printer *p,
+                           const struct drm_memory_stats *stats,
+                           enum drm_gem_object_status supported_status,
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-mediatek-dp-drm_err-dev_err-in-hpd-path-to-avoid.patch b/queue-6.14/drm-mediatek-dp-drm_err-dev_err-in-hpd-path-to-avoid.patch
new file mode 100644 (file)
index 0000000..286800e
--- /dev/null
@@ -0,0 +1,69 @@
+From 60fc7fe4271654facd0aa3c3a8fd14db4adbbec0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jan 2025 09:42:50 -0800
+Subject: drm/mediatek: dp: drm_err => dev_err in HPD path to avoid NULL ptr
+
+From: Douglas Anderson <dianders@chromium.org>
+
+[ Upstream commit 106a6de46cf4887d535018185ec528ce822d6d84 ]
+
+The function mtk_dp_wait_hpd_asserted() may be called before the
+`mtk_dp->drm_dev` pointer is assigned in mtk_dp_bridge_attach().
+Specifically it can be called via this callpath:
+ - mtk_edp_wait_hpd_asserted
+ - [panel probe]
+ - dp_aux_ep_probe
+
+Using "drm" level prints anywhere in this callpath causes a NULL
+pointer dereference. Change the error message directly in
+mtk_dp_wait_hpd_asserted() to dev_err() to avoid this. Also change the
+error messages in mtk_dp_parse_capabilities(), which is called by
+mtk_dp_wait_hpd_asserted().
+
+While touching these prints, also add the error code to them to make
+future debugging easier.
+
+Fixes: 7eacba9a083b ("drm/mediatek: dp: Add .wait_hpd_asserted() for AUX bus")
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Reviewed-by: CK Hu <ck.hu@mediatek.com>
+Link: https://patchwork.kernel.org/project/dri-devel/patch/20250116094249.1.I29b0b621abb613ddc70ab4996426a3909e1aa75f@changeid/
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_dp.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
+index cd385ba4c66aa..d2cf09124d108 100644
+--- a/drivers/gpu/drm/mediatek/mtk_dp.c
++++ b/drivers/gpu/drm/mediatek/mtk_dp.c
+@@ -1766,7 +1766,7 @@ static int mtk_dp_parse_capabilities(struct mtk_dp *mtk_dp)
+       ret = drm_dp_dpcd_readb(&mtk_dp->aux, DP_MSTM_CAP, &val);
+       if (ret < 1) {
+-              drm_err(mtk_dp->drm_dev, "Read mstm cap failed\n");
++              dev_err(mtk_dp->dev, "Read mstm cap failed: %zd\n", ret);
+               return ret == 0 ? -EIO : ret;
+       }
+@@ -1776,7 +1776,7 @@ static int mtk_dp_parse_capabilities(struct mtk_dp *mtk_dp)
+                                       DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0,
+                                       &val);
+               if (ret < 1) {
+-                      drm_err(mtk_dp->drm_dev, "Read irq vector failed\n");
++                      dev_err(mtk_dp->dev, "Read irq vector failed: %zd\n", ret);
+                       return ret == 0 ? -EIO : ret;
+               }
+@@ -2059,7 +2059,7 @@ static int mtk_dp_wait_hpd_asserted(struct drm_dp_aux *mtk_aux, unsigned long wa
+       ret = mtk_dp_parse_capabilities(mtk_dp);
+       if (ret) {
+-              drm_err(mtk_dp->drm_dev, "Can't parse capabilities\n");
++              dev_err(mtk_dp->dev, "Can't parse capabilities: %d\n", ret);
+               return ret;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-mediatek-dsi-fix-error-codes-in-mtk_dsi_host_tra.patch b/queue-6.14/drm-mediatek-dsi-fix-error-codes-in-mtk_dsi_host_tra.patch
new file mode 100644 (file)
index 0000000..0fe4a64
--- /dev/null
@@ -0,0 +1,64 @@
+From 5c3765639766ee637cce2cab5ac3ac44d0b33292 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jan 2025 12:35:57 +0300
+Subject: drm/mediatek: dsi: fix error codes in mtk_dsi_host_transfer()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit dcb166ee43c3d594e7b73a24f6e8cf5663eeff2c ]
+
+There is a type bug because the return statement:
+
+        return ret < 0 ? ret : recv_cnt;
+
+The issue is that ret is an int, recv_cnt is a u32 and the function
+returns ssize_t, which is a signed long.  The way that the type promotion
+works is that the negative error codes are first cast to u32 and then
+to signed long.  The error codes end up being positive instead of
+negative and the callers treat them as success.
+
+Fixes: 81cc7e51c4f1 ("drm/mediatek: Allow commands to be sent during video mode")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/r/202412210801.iADw0oIH-lkp@intel.com/
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Reviewed-by: Mattijs Korpershoek <mkorpershoek@baylibre.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: CK Hu <ck.hu@mediatek.com>
+Link: https://patchwork.kernel.org/project/dri-devel/patch/b754a408-4f39-4e37-b52d-7706c132e27f@stanley.mountain/
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_dsi.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
+index 40752f2320548..852aeef9f38dc 100644
+--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
++++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
+@@ -1116,12 +1116,12 @@ static ssize_t mtk_dsi_host_transfer(struct mipi_dsi_host *host,
+                                    const struct mipi_dsi_msg *msg)
+ {
+       struct mtk_dsi *dsi = host_to_dsi(host);
+-      u32 recv_cnt, i;
++      ssize_t recv_cnt;
+       u8 read_data[16];
+       void *src_addr;
+       u8 irq_flag = CMD_DONE_INT_FLAG;
+       u32 dsi_mode;
+-      int ret;
++      int ret, i;
+       dsi_mode = readl(dsi->regs + DSI_MODE_CTRL);
+       if (dsi_mode & MODE) {
+@@ -1170,7 +1170,7 @@ static ssize_t mtk_dsi_host_transfer(struct mipi_dsi_host *host,
+       if (recv_cnt)
+               memcpy(msg->rx_buf, src_addr, recv_cnt);
+-      DRM_INFO("dsi get %d byte data from the panel address(0x%x)\n",
++      DRM_INFO("dsi get %zd byte data from the panel address(0x%x)\n",
+                recv_cnt, *((u8 *)(msg->tx_buf)));
+ restore_dsi_mode:
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-mediatek-fix-config_updating-flag-never-false-wh.patch b/queue-6.14/drm-mediatek-fix-config_updating-flag-never-false-wh.patch
new file mode 100644 (file)
index 0000000..9114c5e
--- /dev/null
@@ -0,0 +1,53 @@
+From 7edbbf569662e4e0d9dea5b352b5d3083f8ae2cf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Feb 2025 13:12:21 +0800
+Subject: drm/mediatek: Fix config_updating flag never false when no mbox
+ channel
+
+From: Jason-JH Lin <jason-jh.lin@mediatek.com>
+
+[ Upstream commit 4ba973c8bad04d59fd4efa62512f4d9cee131714 ]
+
+When CONFIG_MTK_CMDQ is enabled, if the display is controlled by the CPU
+while other hardware is controlled by the GCE, the display will encounter
+a mbox request channel failure.
+However, it will still enter the CONFIG_MTK_CMDQ statement, causing the
+config_updating flag to never be set to false. As a result, no page flip
+event is sent back to user space, and the screen does not update.
+
+Fixes: da03801ad08f ("drm/mediatek: Move mtk_crtc_finish_page_flip() to ddp_cmdq_cb()")
+Signed-off-by: Jason-JH Lin <jason-jh.lin@mediatek.com>
+Reviewed-by: CK Hu <ck.hu@mediatek.com>
+Link: https://patchwork.kernel.org/project/dri-devel/patch/20250224051301.3538484-1-jason-jh.lin@mediatek.com/
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_crtc.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_crtc.c b/drivers/gpu/drm/mediatek/mtk_crtc.c
+index 5674f5707cca8..8f6fba4217ece 100644
+--- a/drivers/gpu/drm/mediatek/mtk_crtc.c
++++ b/drivers/gpu/drm/mediatek/mtk_crtc.c
+@@ -620,13 +620,16 @@ static void mtk_crtc_update_config(struct mtk_crtc *mtk_crtc, bool needs_vblank)
+               mbox_send_message(mtk_crtc->cmdq_client.chan, cmdq_handle);
+               mbox_client_txdone(mtk_crtc->cmdq_client.chan, 0);
++              goto update_config_out;
+       }
+-#else
++#endif
+       spin_lock_irqsave(&mtk_crtc->config_lock, flags);
+       mtk_crtc->config_updating = false;
+       spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
+-#endif
++#if IS_REACHABLE(CONFIG_MTK_CMDQ)
++update_config_out:
++#endif
+       mutex_unlock(&mtk_crtc->hw_lock);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-mediatek-mtk_hdmi-fix-typo-for-aud_sampe_size-me.patch b/queue-6.14/drm-mediatek-mtk_hdmi-fix-typo-for-aud_sampe_size-me.patch
new file mode 100644 (file)
index 0000000..a157580
--- /dev/null
@@ -0,0 +1,66 @@
+From 9e9fc8dd818456d66aa5b7133500b5ebd9fd0179 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 16:48:12 +0100
+Subject: drm/mediatek: mtk_hdmi: Fix typo for aud_sampe_size member
+
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+[ Upstream commit 72fcb88e7bbc053ed4fc74cebb0315b98a0f20c3 ]
+
+Rename member aud_sampe_size of struct hdmi_audio_param to
+aud_sample_size to fix a typo and enhance readability.
+
+This commit brings no functional changes.
+
+Fixes: 8f83f26891e1 ("drm/mediatek: Add HDMI support")
+Reviewed-by: CK Hu <ck.hu@mediatek.com>
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20250217154836.108895-20-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_hdmi.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
+index 1018a9a7433f9..250ad0d4027d6 100644
+--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
++++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
+@@ -137,7 +137,7 @@ enum hdmi_aud_channel_swap_type {
+ struct hdmi_audio_param {
+       enum hdmi_audio_coding_type aud_codec;
+-      enum hdmi_audio_sample_size aud_sampe_size;
++      enum hdmi_audio_sample_size aud_sample_size;
+       enum hdmi_aud_input_type aud_input_type;
+       enum hdmi_aud_i2s_fmt aud_i2s_fmt;
+       enum hdmi_aud_mclk aud_mclk;
+@@ -1075,7 +1075,7 @@ static int mtk_hdmi_output_init(struct mtk_hdmi *hdmi)
+       hdmi->csp = HDMI_COLORSPACE_RGB;
+       aud_param->aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
+-      aud_param->aud_sampe_size = HDMI_AUDIO_SAMPLE_SIZE_16;
++      aud_param->aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
+       aud_param->aud_input_type = HDMI_AUD_INPUT_I2S;
+       aud_param->aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
+       aud_param->aud_mclk = HDMI_AUD_MCLK_128FS;
+@@ -1573,14 +1573,14 @@ static int mtk_hdmi_audio_hw_params(struct device *dev, void *data,
+       switch (daifmt->fmt) {
+       case HDMI_I2S:
+               hdmi_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
+-              hdmi_params.aud_sampe_size = HDMI_AUDIO_SAMPLE_SIZE_16;
++              hdmi_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
+               hdmi_params.aud_input_type = HDMI_AUD_INPUT_I2S;
+               hdmi_params.aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
+               hdmi_params.aud_mclk = HDMI_AUD_MCLK_128FS;
+               break;
+       case HDMI_SPDIF:
+               hdmi_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
+-              hdmi_params.aud_sampe_size = HDMI_AUDIO_SAMPLE_SIZE_16;
++              hdmi_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
+               hdmi_params.aud_input_type = HDMI_AUD_INPUT_SPDIF;
+               break;
+       default:
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-mediatek-mtk_hdmi-unregister-audio-platform-devi.patch b/queue-6.14/drm-mediatek-mtk_hdmi-unregister-audio-platform-devi.patch
new file mode 100644 (file)
index 0000000..5e97bf0
--- /dev/null
@@ -0,0 +1,85 @@
+From ae3dbae615687464c7d90f9e88c564cad9cbf674 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 16:48:10 +0100
+Subject: drm/mediatek: mtk_hdmi: Unregister audio platform device on failure
+
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+[ Upstream commit 0be123cafc06eed0fd1227166a66e786434b0c50 ]
+
+The probe function of this driver may fail after registering the
+audio platform device: in that case, the state is not getting
+cleaned up, leaving this device registered.
+
+Adding up to the mix, should the probe function of this driver
+return a probe deferral for N times, we're registering up to N
+audio platform devices and, again, never freeing them up.
+
+To fix this, add a pointer to the audio platform device in the
+mtk_hdmi structure, and add a devm action to unregister it upon
+driver removal or probe failure.
+
+Fixes: 8f83f26891e1 ("drm/mediatek: Add HDMI support")
+Reviewed-by: CK Hu <ck.hu@mediatek.com>
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20250217154836.108895-18-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_hdmi.c | 25 +++++++++++++++++++------
+ 1 file changed, 19 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
+index ca82bc829cb96..1018a9a7433f9 100644
+--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
++++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
+@@ -173,6 +173,7 @@ struct mtk_hdmi {
+       unsigned int sys_offset;
+       void __iomem *regs;
+       enum hdmi_colorspace csp;
++      struct platform_device *audio_pdev;
+       struct hdmi_audio_param aud_param;
+       bool audio_enable;
+       bool powered;
+@@ -1662,6 +1663,11 @@ static const struct hdmi_codec_ops mtk_hdmi_audio_codec_ops = {
+       .hook_plugged_cb = mtk_hdmi_audio_hook_plugged_cb,
+ };
++static void mtk_hdmi_unregister_audio_driver(void *data)
++{
++      platform_device_unregister(data);
++}
++
+ static int mtk_hdmi_register_audio_driver(struct device *dev)
+ {
+       struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
+@@ -1672,13 +1678,20 @@ static int mtk_hdmi_register_audio_driver(struct device *dev)
+               .data = hdmi,
+               .no_capture_mute = 1,
+       };
+-      struct platform_device *pdev;
++      int ret;
+-      pdev = platform_device_register_data(dev, HDMI_CODEC_DRV_NAME,
+-                                           PLATFORM_DEVID_AUTO, &codec_data,
+-                                           sizeof(codec_data));
+-      if (IS_ERR(pdev))
+-              return PTR_ERR(pdev);
++      hdmi->audio_pdev = platform_device_register_data(dev,
++                                                       HDMI_CODEC_DRV_NAME,
++                                                       PLATFORM_DEVID_AUTO,
++                                                       &codec_data,
++                                                       sizeof(codec_data));
++      if (IS_ERR(hdmi->audio_pdev))
++              return PTR_ERR(hdmi->audio_pdev);
++
++      ret = devm_add_action_or_reset(dev, mtk_hdmi_unregister_audio_driver,
++                                     hdmi->audio_pdev);
++      if (ret)
++              return ret;
+       DRM_INFO("%s driver bound to HDMI\n", HDMI_CODEC_DRV_NAME);
+       return 0;
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-msm-a6xx-fix-a6xx-indexed-regs-in-devcoreduump.patch b/queue-6.14/drm-msm-a6xx-fix-a6xx-indexed-regs-in-devcoreduump.patch
new file mode 100644 (file)
index 0000000..e14f67e
--- /dev/null
@@ -0,0 +1,38 @@
+From 4b8a2bd1fe29f0f08ba7c3d2a8aedf39ec6bac68 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Feb 2025 13:31:24 -0800
+Subject: drm/msm/a6xx: Fix a6xx indexed-regs in devcoreduump
+
+From: Rob Clark <robdclark@chromium.org>
+
+[ Upstream commit 06dd5d86c6aef1c7609ca3a5ffa4097e475e2213 ]
+
+Somehow, possibly as a result of rebase gone badly, setting
+nr_indexed_regs for pre-a650 a6xx devices lost the setting of
+nr_indexed_regs, resulting in values getting snapshot, but omitted
+from the devcoredump.
+
+Fixes: e997ae5f45ca ("drm/msm/a6xx: Mostly implement A7xx gpu_state")
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Patchwork: https://patchwork.freedesktop.org/patch/640289/
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c
+index 0fcae53c0b140..159665cb6b14f 100644
+--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c
++++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c
+@@ -1507,6 +1507,8 @@ static void a6xx_get_indexed_registers(struct msm_gpu *gpu,
+       /* Restore the size in the hardware */
+       gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, mempool_size);
++
++      a6xx_state->nr_indexed_regs = count;
+ }
+ static void a7xx_get_indexed_registers(struct msm_gpu *gpu,
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-msm-dpu-don-t-set-crtc_state-mode_changed-from-a.patch b/queue-6.14/drm-msm-dpu-don-t-set-crtc_state-mode_changed-from-a.patch
new file mode 100644 (file)
index 0000000..425f5eb
--- /dev/null
@@ -0,0 +1,191 @@
+From 20dc1bf23d34572fbc92cf0fabb15c0d989ae82a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jan 2025 14:43:36 +0200
+Subject: drm/msm/dpu: don't set crtc_state->mode_changed from atomic_check()
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 2dde2aadaed113feb724c19063ac61e2f6ba61a4 ]
+
+The MSM driver uses drm_atomic_helper_check() which mandates that none
+of the atomic_check() callbacks toggles crtc_state->mode_changed.
+Perform corresponding check before calling the drm_atomic_helper_check()
+function.
+
+Fixes: 8b45a26f2ba9 ("drm/msm/dpu: reserve cdm blocks for writeback in case of YUV output")
+Reported-by: Simona Vetter <simona.vetter@ffwll.ch>
+Closes: https://lore.kernel.org/dri-devel/ZtW_S0j5AEr4g0QW@phenom.ffwll.local/
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+[DB: dropped the WARN_ON]
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Patchwork: https://patchwork.freedesktop.org/patch/633400/
+Link: https://lore.kernel.org/r/20250123-drm-dirty-modeset-v2-4-bbfd3a6cd1a4@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 32 ++++++++++++++++++---
+ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h |  4 +++
+ drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c     | 24 ++++++++++++++++
+ drivers/gpu/drm/msm/msm_atomic.c            | 13 ++++++++-
+ drivers/gpu/drm/msm/msm_kms.h               |  7 +++++
+ 5 files changed, 75 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+index 9928e72dfabda..7b56da24711e4 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+@@ -760,6 +760,34 @@ static void dpu_encoder_assign_crtc_resources(struct dpu_kms *dpu_kms,
+       cstate->num_mixers = num_lm;
+ }
++/**
++ * dpu_encoder_virt_check_mode_changed: check if full modeset is required
++ * @drm_enc:    Pointer to drm encoder structure
++ * @crtc_state:       Corresponding CRTC state to be checked
++ * @conn_state: Corresponding Connector's state to be checked
++ *
++ * Check if the changes in the object properties demand full mode set.
++ */
++int dpu_encoder_virt_check_mode_changed(struct drm_encoder *drm_enc,
++                                      struct drm_crtc_state *crtc_state,
++                                      struct drm_connector_state *conn_state)
++{
++      struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
++      struct msm_display_topology topology;
++
++      DPU_DEBUG_ENC(dpu_enc, "\n");
++
++      /* Using mode instead of adjusted_mode as it wasn't computed yet */
++      topology = dpu_encoder_get_topology(dpu_enc, &crtc_state->mode, crtc_state, conn_state);
++
++      if (topology.needs_cdm && !dpu_enc->cur_master->hw_cdm)
++              crtc_state->mode_changed = true;
++      else if (!topology.needs_cdm && dpu_enc->cur_master->hw_cdm)
++              crtc_state->mode_changed = true;
++
++      return 0;
++}
++
+ static int dpu_encoder_virt_atomic_check(
+               struct drm_encoder *drm_enc,
+               struct drm_crtc_state *crtc_state,
+@@ -793,10 +821,6 @@ static int dpu_encoder_virt_atomic_check(
+       topology = dpu_encoder_get_topology(dpu_enc, adj_mode, crtc_state, conn_state);
+-      if (topology.needs_cdm && !dpu_enc->cur_master->hw_cdm)
+-              crtc_state->mode_changed = true;
+-      else if (!topology.needs_cdm && dpu_enc->cur_master->hw_cdm)
+-              crtc_state->mode_changed = true;
+       /*
+        * Release and Allocate resources on every modeset
+        */
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
+index 92b5ee390788d..da133ee4701a3 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
+@@ -88,4 +88,8 @@ void dpu_encoder_cleanup_wb_job(struct drm_encoder *drm_enc,
+ bool dpu_encoder_is_valid_for_commit(struct drm_encoder *drm_enc);
++int dpu_encoder_virt_check_mode_changed(struct drm_encoder *drm_enc,
++                                      struct drm_crtc_state *crtc_state,
++                                      struct drm_connector_state *conn_state);
++
+ #endif /* __DPU_ENCODER_H__ */
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+index 97e9cb8c2b099..8741dc6fc8ddc 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+@@ -446,6 +446,29 @@ static void dpu_kms_disable_commit(struct msm_kms *kms)
+       pm_runtime_put_sync(&dpu_kms->pdev->dev);
+ }
++static int dpu_kms_check_mode_changed(struct msm_kms *kms, struct drm_atomic_state *state)
++{
++      struct drm_crtc_state *new_crtc_state;
++      struct drm_connector *connector;
++      struct drm_connector_state *new_conn_state;
++      int i;
++
++      for_each_new_connector_in_state(state, connector, new_conn_state, i) {
++              struct drm_encoder *encoder;
++
++              if (!new_conn_state->crtc || !new_conn_state->best_encoder)
++                      continue;
++
++              new_crtc_state = drm_atomic_get_new_crtc_state(state, new_conn_state->crtc);
++
++              encoder = new_conn_state->best_encoder;
++
++              dpu_encoder_virt_check_mode_changed(encoder, new_crtc_state, new_conn_state);
++      }
++
++      return 0;
++}
++
+ static void dpu_kms_flush_commit(struct msm_kms *kms, unsigned crtc_mask)
+ {
+       struct dpu_kms *dpu_kms = to_dpu_kms(kms);
+@@ -1062,6 +1085,7 @@ static const struct msm_kms_funcs kms_funcs = {
+       .irq             = dpu_core_irq,
+       .enable_commit   = dpu_kms_enable_commit,
+       .disable_commit  = dpu_kms_disable_commit,
++      .check_mode_changed = dpu_kms_check_mode_changed,
+       .flush_commit    = dpu_kms_flush_commit,
+       .wait_flush      = dpu_kms_wait_flush,
+       .complete_commit = dpu_kms_complete_commit,
+diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c
+index a7a2384044ffd..364df245e3a20 100644
+--- a/drivers/gpu/drm/msm/msm_atomic.c
++++ b/drivers/gpu/drm/msm/msm_atomic.c
+@@ -183,10 +183,16 @@ static unsigned get_crtc_mask(struct drm_atomic_state *state)
+ int msm_atomic_check(struct drm_device *dev, struct drm_atomic_state *state)
+ {
++      struct msm_drm_private *priv = dev->dev_private;
++      struct msm_kms *kms = priv->kms;
+       struct drm_crtc_state *old_crtc_state, *new_crtc_state;
+       struct drm_crtc *crtc;
+-      int i;
++      int i, ret = 0;
++      /*
++       * FIXME: stop setting allow_modeset and move this check to the DPU
++       * driver.
++       */
+       for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state,
+                                     new_crtc_state, i) {
+               if ((old_crtc_state->ctm && !new_crtc_state->ctm) ||
+@@ -196,6 +202,11 @@ int msm_atomic_check(struct drm_device *dev, struct drm_atomic_state *state)
+               }
+       }
++      if (kms && kms->funcs && kms->funcs->check_mode_changed)
++              ret = kms->funcs->check_mode_changed(kms, state);
++      if (ret)
++              return ret;
++
+       return drm_atomic_helper_check(dev, state);
+ }
+diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h
+index e60162744c669..ec2a75af89b09 100644
+--- a/drivers/gpu/drm/msm/msm_kms.h
++++ b/drivers/gpu/drm/msm/msm_kms.h
+@@ -59,6 +59,13 @@ struct msm_kms_funcs {
+       void (*enable_commit)(struct msm_kms *kms);
+       void (*disable_commit)(struct msm_kms *kms);
++      /**
++       * @check_mode_changed:
++       *
++       * Verify if the commit requires a full modeset on one of CRTCs.
++       */
++      int (*check_mode_changed)(struct msm_kms *kms, struct drm_atomic_state *state);
++
+       /**
+        * Prepare for atomic commit.  This is called after any previous
+        * (async or otherwise) commit has completed.
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-msm-dpu-don-t-use-active-in-atomic_check.patch b/queue-6.14/drm-msm-dpu-don-t-use-active-in-atomic_check.patch
new file mode 100644 (file)
index 0000000..2a01945
--- /dev/null
@@ -0,0 +1,65 @@
+From 3877c7df157472d93b5ddf6527feafcbe69e87b0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jan 2025 14:43:33 +0200
+Subject: drm/msm/dpu: don't use active in atomic_check()
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 25b4614843bcc56ba150f7c99905125a019e656c ]
+
+The driver isn't supposed to consult crtc_state->active/active_check for
+resource allocation. Instead all resources should be allocated if
+crtc_state->enabled is set. Stop consulting active / active_changed in
+order to determine whether the hardware resources should be
+(re)allocated.
+
+Fixes: ccc862b957c6 ("drm/msm/dpu: Fix reservation failures in modeset")
+Reported-by: Simona Vetter <simona.vetter@ffwll.ch>
+Closes: https://lore.kernel.org/dri-devel/ZtW_S0j5AEr4g0QW@phenom.ffwll.local/
+Reviewed-by: Simona Vetter <simona.vetter@ffwll.ch>
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Patchwork: https://patchwork.freedesktop.org/patch/633393/
+Link: https://lore.kernel.org/r/20250123-drm-dirty-modeset-v2-1-bbfd3a6cd1a4@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c    | 4 ----
+ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 3 +--
+ 2 files changed, 1 insertion(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+index e5dcd41a361f4..29485e76f531f 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+@@ -1262,10 +1262,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
+       DRM_DEBUG_ATOMIC("%s: check\n", dpu_crtc->name);
+-      /* force a full mode set if active state changed */
+-      if (crtc_state->active_changed)
+-              crtc_state->mode_changed = true;
+-
+       if (cstate->num_mixers) {
+               rc = _dpu_crtc_check_and_setup_lm_bounds(crtc, crtc_state);
+               if (rc)
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+index 48e6e8d74c855..ee7dacf8a1cb6 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+@@ -793,12 +793,11 @@ static int dpu_encoder_virt_atomic_check(
+               crtc_state->mode_changed = true;
+       /*
+        * Release and Allocate resources on every modeset
+-       * Dont allocate when active is false.
+        */
+       if (drm_atomic_crtc_needs_modeset(crtc_state)) {
+               dpu_rm_release(global_state, drm_enc);
+-              if (!crtc_state->active_changed || crtc_state->enable)
++              if (crtc_state->enable)
+                       ret = dpu_rm_reserve(&dpu_kms->rm, global_state,
+                                       drm_enc, crtc_state, &topology);
+               if (!ret)
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-msm-dpu-fall-back-to-a-single-dsc-encoder-1-1-1-.patch b/queue-6.14/drm-msm-dpu-fall-back-to-a-single-dsc-encoder-1-1-1-.patch
new file mode 100644 (file)
index 0000000..156ecf2
--- /dev/null
@@ -0,0 +1,140 @@
+From 0308388f2cbfd97e6a73eaf02efaba5c1912f0c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jan 2025 17:23:44 +0100
+Subject: drm/msm/dpu: Fall back to a single DSC encoder (1:1:1) on small SoCs
+
+From: Marijn Suijten <marijn.suijten@somainline.org>
+
+[ Upstream commit b6090ffb30f3301d3831774f9c3e2f1b1141a399 ]
+
+Some SoCs such as SC7280 (used in the Fairphone 5) have only a single
+DSC "hard slice" encoder.  The current hardcoded use of 2:2:1 topology
+(2 LM and 2 DSC for a single interface) make it impossible to use
+Display Stream Compression panels with mainline, which is exactly what's
+installed on the Fairphone 5.
+
+By loosening the hardcoded `num_dsc = 2` to fall back to `num_dsc =
+1` when the catalog only contains one entry, we can trivially support
+this phone and unblock further panel enablement on mainline.  A few
+more supporting changes in this patch ensure hardcoded constants of 2
+DSC encoders are replaced to count or read back the actual number of
+DSC hardware blocks that are enabled for the given virtual encoder.
+Likewise DSC_MODE_SPLIT_PANEL can no longer be unconditionally enabled.
+
+Cc: Luca Weiss <luca.weiss@fairphone.com>
+Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Tested-by: Luca Weiss <luca.weiss@fairphone.com>
+Reviewed-by: Jessica Zhang <quic_jesszhan@quicinc.com>
+Tested-by: Danila Tikhonov <danila@jiaxyga.com>
+Patchwork: https://patchwork.freedesktop.org/patch/633318/
+Link: https://lore.kernel.org/r/20250122-dpu-111-topology-v2-1-505e95964af9@somainline.org
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Stable-dep-of: d245ce568929 ("drm/msm/dpu: Remove arbitrary limit of 1 interface in DSC topology")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 47 +++++++++++----------
+ 1 file changed, 25 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+index ee7dacf8a1cb6..88591b6f9e350 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+@@ -622,9 +622,9 @@ bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc)
+               if (dpu_enc->phys_encs[i])
+                       intf_count++;
+-      /* See dpu_encoder_get_topology, we only support 2:2:1 topology */
+-      if (dpu_enc->dsc)
+-              num_dsc = 2;
++      for (i = 0; i < MAX_CHANNELS_PER_ENC; i++)
++              if (dpu_enc->hw_dsc[i])
++                      num_dsc++;
+       return (num_dsc > 0) && (num_dsc > intf_count);
+ }
+@@ -686,13 +686,19 @@ static struct msm_display_topology dpu_encoder_get_topology(
+       if (dsc) {
+               /*
+-               * In case of Display Stream Compression (DSC), we would use
+-               * 2 DSC encoders, 2 layer mixers and 1 interface
+-               * this is power optimal and can drive up to (including) 4k
+-               * screens
++               * Use 2 DSC encoders and 2 layer mixers per single interface
++               * when Display Stream Compression (DSC) is enabled,
++               * and when enough DSC blocks are available.
++               * This is power-optimal and can drive up to (including) 4k
++               * screens.
+                */
+-              topology.num_dsc = 2;
+-              topology.num_lm = 2;
++              if (dpu_kms->catalog->dsc_count >= 2) {
++                      topology.num_dsc = 2;
++                      topology.num_lm = 2;
++              } else {
++                      topology.num_dsc = 1;
++                      topology.num_lm = 1;
++              }
+               topology.num_intf = 1;
+       }
+@@ -2019,7 +2025,6 @@ static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_ctl *ctl,
+ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc,
+                                struct drm_dsc_config *dsc)
+ {
+-      /* coding only for 2LM, 2enc, 1 dsc config */
+       struct dpu_encoder_phys *enc_master = dpu_enc->cur_master;
+       struct dpu_hw_ctl *ctl = enc_master->hw_ctl;
+       struct dpu_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC];
+@@ -2029,22 +2034,24 @@ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc,
+       int dsc_common_mode;
+       int pic_width;
+       u32 initial_lines;
++      int num_dsc = 0;
+       int i;
+       for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
+               hw_pp[i] = dpu_enc->hw_pp[i];
+               hw_dsc[i] = dpu_enc->hw_dsc[i];
+-              if (!hw_pp[i] || !hw_dsc[i]) {
+-                      DPU_ERROR_ENC(dpu_enc, "invalid params for DSC\n");
+-                      return;
+-              }
++              if (!hw_pp[i] || !hw_dsc[i])
++                      break;
++
++              num_dsc++;
+       }
+-      dsc_common_mode = 0;
+       pic_width = dsc->pic_width;
+-      dsc_common_mode = DSC_MODE_SPLIT_PANEL;
++      dsc_common_mode = 0;
++      if (num_dsc > 1)
++              dsc_common_mode |= DSC_MODE_SPLIT_PANEL;
+       if (dpu_encoder_use_dsc_merge(enc_master->parent))
+               dsc_common_mode |= DSC_MODE_MULTIPLEX;
+       if (enc_master->intf_mode == INTF_MODE_VIDEO)
+@@ -2053,14 +2060,10 @@ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc,
+       this_frame_slices = pic_width / dsc->slice_width;
+       intf_ip_w = this_frame_slices * dsc->slice_width;
+-      /*
+-       * dsc merge case: when using 2 encoders for the same stream,
+-       * no. of slices need to be same on both the encoders.
+-       */
+-      enc_ip_w = intf_ip_w / 2;
++      enc_ip_w = intf_ip_w / num_dsc;
+       initial_lines = dpu_encoder_dsc_initial_line_calc(dsc, enc_ip_w);
+-      for (i = 0; i < MAX_CHANNELS_PER_ENC; i++)
++      for (i = 0; i < num_dsc; i++)
+               dpu_encoder_dsc_pipe_cfg(ctl, hw_dsc[i], hw_pp[i],
+                                        dsc, dsc_common_mode, initial_lines);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-msm-dpu-move-needs_cdm-setting-to-dpu_encoder_ge.patch b/queue-6.14/drm-msm-dpu-move-needs_cdm-setting-to-dpu_encoder_ge.patch
new file mode 100644 (file)
index 0000000..d88e34f
--- /dev/null
@@ -0,0 +1,109 @@
+From 996a471646e63b7dd3024f4233557b9b92186169 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jan 2025 14:43:34 +0200
+Subject: drm/msm/dpu: move needs_cdm setting to dpu_encoder_get_topology()
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 7d39f5bb82c0d7155037982dd0ff583a68db1c34 ]
+
+As a preparation for calling dpu_encoder_get_topology() from different
+places, move the code setting topology->needs_cdm to that function
+(instead of patching topology separately).
+
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Patchwork: https://patchwork.freedesktop.org/patch/633395/
+Link: https://lore.kernel.org/r/20250123-drm-dirty-modeset-v2-2-bbfd3a6cd1a4@linaro.org
+Stable-dep-of: 2dde2aadaed1 ("drm/msm/dpu: don't set crtc_state->mode_changed from atomic_check()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 41 +++++++++++----------
+ 1 file changed, 22 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+index e3555765eefb1..66dc2b1dee7f8 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+@@ -652,8 +652,11 @@ static struct msm_display_topology dpu_encoder_get_topology(
+                       struct dpu_kms *dpu_kms,
+                       struct drm_display_mode *mode,
+                       struct drm_crtc_state *crtc_state,
++                      struct drm_connector_state *conn_state,
+                       struct drm_dsc_config *dsc)
+ {
++      struct msm_drm_private *priv = dpu_enc->base.dev->dev_private;
++      struct msm_display_info *disp_info = &dpu_enc->disp_info;
+       struct msm_display_topology topology = {0};
+       int i, intf_count = 0;
+@@ -703,6 +706,23 @@ static struct msm_display_topology dpu_encoder_get_topology(
+               }
+       }
++      /*
++       * Use CDM only for writeback or DP at the moment as other interfaces cannot handle it.
++       * If writeback itself cannot handle cdm for some reason it will fail in its atomic_check()
++       * earlier.
++       */
++      if (disp_info->intf_type == INTF_WB && conn_state->writeback_job) {
++              struct drm_framebuffer *fb;
++
++              fb = conn_state->writeback_job->fb;
++
++              if (fb && MSM_FORMAT_IS_YUV(msm_framebuffer_format(fb)))
++                      topology.needs_cdm = true;
++      } else if (disp_info->intf_type == INTF_DP) {
++              if (msm_dp_is_yuv_420_enabled(priv->dp[disp_info->h_tile_instance[0]], mode))
++                      topology.needs_cdm = true;
++      }
++
+       return topology;
+ }
+@@ -750,9 +770,7 @@ static int dpu_encoder_virt_atomic_check(
+       struct dpu_kms *dpu_kms;
+       struct drm_display_mode *adj_mode;
+       struct msm_display_topology topology;
+-      struct msm_display_info *disp_info;
+       struct dpu_global_state *global_state;
+-      struct drm_framebuffer *fb;
+       struct drm_dsc_config *dsc;
+       int ret = 0;
+@@ -766,7 +784,6 @@ static int dpu_encoder_virt_atomic_check(
+       DPU_DEBUG_ENC(dpu_enc, "\n");
+       priv = drm_enc->dev->dev_private;
+-      disp_info = &dpu_enc->disp_info;
+       dpu_kms = to_dpu_kms(priv->kms);
+       adj_mode = &crtc_state->adjusted_mode;
+       global_state = dpu_kms_get_global_state(crtc_state->state);
+@@ -777,22 +794,8 @@ static int dpu_encoder_virt_atomic_check(
+       dsc = dpu_encoder_get_dsc_config(drm_enc);
+-      topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, crtc_state, dsc);
+-
+-      /*
+-       * Use CDM only for writeback or DP at the moment as other interfaces cannot handle it.
+-       * If writeback itself cannot handle cdm for some reason it will fail in its atomic_check()
+-       * earlier.
+-       */
+-      if (disp_info->intf_type == INTF_WB && conn_state->writeback_job) {
+-              fb = conn_state->writeback_job->fb;
+-
+-              if (fb && MSM_FORMAT_IS_YUV(msm_framebuffer_format(fb)))
+-                      topology.needs_cdm = true;
+-      } else if (disp_info->intf_type == INTF_DP) {
+-              if (msm_dp_is_yuv_420_enabled(priv->dp[disp_info->h_tile_instance[0]], adj_mode))
+-                      topology.needs_cdm = true;
+-      }
++      topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, crtc_state, conn_state,
++                                          dsc);
+       if (topology.needs_cdm && !dpu_enc->cur_master->hw_cdm)
+               crtc_state->mode_changed = true;
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-msm-dpu-remove-arbitrary-limit-of-1-interface-in.patch b/queue-6.14/drm-msm-dpu-remove-arbitrary-limit-of-1-interface-in.patch
new file mode 100644 (file)
index 0000000..f06e209
--- /dev/null
@@ -0,0 +1,62 @@
+From 96a07bce4785db8054d9f41552013e090fa0c77c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 12:17:43 +0100
+Subject: drm/msm/dpu: Remove arbitrary limit of 1 interface in DSC topology
+
+From: Marijn Suijten <marijn.suijten@somainline.org>
+
+[ Upstream commit d245ce568929e30f650e260631f7ad14970d7c2c ]
+
+When DSC is enabled the number of interfaces is forced to be 1, and
+documented that it is a "power-optimal" layout to use two DSC encoders
+together with two Layer Mixers.  However, the same layout (two DSC
+hard-slice encoders with two LMs) is also used when the display is
+fed with data over two instead of one interface (common on 4k@120Hz
+smartphone panels with Dual-DSI).  Solve this by simply removing the
+num_intf = 1 assignment as the count is already calculated by computing
+the number of physical encoders within the virtual encoder.
+
+Fixes: 7e9cc175b159 ("drm/msm/disp/dpu1: Add support for DSC in topology")
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Jessica Zhang <quic_jesszhan@quicinc.com>
+Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
+Patchwork: https://patchwork.freedesktop.org/patch/637649/
+Link: https://lore.kernel.org/r/20250217-drm-msm-initial-dualpipe-dsc-fixes-v3-3-913100d6103f@somainline.org
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+index 88591b6f9e350..e3555765eefb1 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+@@ -686,20 +686,21 @@ static struct msm_display_topology dpu_encoder_get_topology(
+       if (dsc) {
+               /*
+-               * Use 2 DSC encoders and 2 layer mixers per single interface
++               * Use 2 DSC encoders, 2 layer mixers and 1 or 2 interfaces
+                * when Display Stream Compression (DSC) is enabled,
+                * and when enough DSC blocks are available.
+                * This is power-optimal and can drive up to (including) 4k
+                * screens.
+                */
+-              if (dpu_kms->catalog->dsc_count >= 2) {
++              WARN(topology.num_intf > 2,
++                   "DSC topology cannot support more than 2 interfaces\n");
++              if (intf_count >= 2 || dpu_kms->catalog->dsc_count >= 2) {
+                       topology.num_dsc = 2;
+                       topology.num_lm = 2;
+               } else {
+                       topology.num_dsc = 1;
+                       topology.num_lm = 1;
+               }
+-              topology.num_intf = 1;
+       }
+       return topology;
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-msm-dpu-simplify-dpu_encoder_get_topology-interf.patch b/queue-6.14/drm-msm-dpu-simplify-dpu_encoder_get_topology-interf.patch
new file mode 100644 (file)
index 0000000..ca0875a
--- /dev/null
@@ -0,0 +1,68 @@
+From 9ac3a887d8b528aea5352412286f351b0eba0c04 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jan 2025 14:43:35 +0200
+Subject: drm/msm/dpu: simplify dpu_encoder_get_topology() interface
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 41921f231abf9a3a95550b2b565df8e4329319cb ]
+
+As a preparation for calling dpu_encoder_get_topology() from different
+code paths, simplify its calling interface, obtaining some data pointers
+internally instead passing them via arguments.
+
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Patchwork: https://patchwork.freedesktop.org/patch/633396/
+Link: https://lore.kernel.org/r/20250123-drm-dirty-modeset-v2-3-bbfd3a6cd1a4@linaro.org
+Stable-dep-of: 2dde2aadaed1 ("drm/msm/dpu: don't set crtc_state->mode_changed from atomic_check()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 12 ++++--------
+ 1 file changed, 4 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+index 66dc2b1dee7f8..9928e72dfabda 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+@@ -649,14 +649,14 @@ struct drm_dsc_config *dpu_encoder_get_dsc_config(struct drm_encoder *drm_enc)
+ static struct msm_display_topology dpu_encoder_get_topology(
+                       struct dpu_encoder_virt *dpu_enc,
+-                      struct dpu_kms *dpu_kms,
+                       struct drm_display_mode *mode,
+                       struct drm_crtc_state *crtc_state,
+-                      struct drm_connector_state *conn_state,
+-                      struct drm_dsc_config *dsc)
++                      struct drm_connector_state *conn_state)
+ {
+       struct msm_drm_private *priv = dpu_enc->base.dev->dev_private;
+       struct msm_display_info *disp_info = &dpu_enc->disp_info;
++      struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms);
++      struct drm_dsc_config *dsc = dpu_encoder_get_dsc_config(&dpu_enc->base);
+       struct msm_display_topology topology = {0};
+       int i, intf_count = 0;
+@@ -771,7 +771,6 @@ static int dpu_encoder_virt_atomic_check(
+       struct drm_display_mode *adj_mode;
+       struct msm_display_topology topology;
+       struct dpu_global_state *global_state;
+-      struct drm_dsc_config *dsc;
+       int ret = 0;
+       if (!drm_enc || !crtc_state || !conn_state) {
+@@ -792,10 +791,7 @@ static int dpu_encoder_virt_atomic_check(
+       trace_dpu_enc_atomic_check(DRMID(drm_enc));
+-      dsc = dpu_encoder_get_dsc_config(drm_enc);
+-
+-      topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, crtc_state, conn_state,
+-                                          dsc);
++      topology = dpu_encoder_get_topology(dpu_enc, adj_mode, crtc_state, conn_state);
+       if (topology.needs_cdm && !dpu_enc->cur_master->hw_cdm)
+               crtc_state->mode_changed = true;
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-msm-dsi-phy-program-clock-inverters-in-correct-r.patch b/queue-6.14/drm-msm-dsi-phy-program-clock-inverters-in-correct-r.patch
new file mode 100644 (file)
index 0000000..0ae4991
--- /dev/null
@@ -0,0 +1,42 @@
+From 06455d83d17dbb97615cca36874df18c00cfe1c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Jan 2025 12:55:04 +0100
+Subject: drm/msm/dsi/phy: Program clock inverters in correct register
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit baf49072877726616c7f5943a6b45eb86bfeca0a ]
+
+Since SM8250 all downstream sources program clock inverters in
+PLL_CLOCK_INVERTERS_1 register and leave the PLL_CLOCK_INVERTERS as
+reset value (0x0).  The most recent Hardware Programming Guide for 3 nm,
+4 nm, 5 nm and 7 nm PHYs also mention PLL_CLOCK_INVERTERS_1.
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Fixes: 1ef7c99d145c ("drm/msm/dsi: add support for 7nm DSI PHY/PLL")
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reported-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Patchwork: https://patchwork.freedesktop.org/patch/634489/
+Link: https://lore.kernel.org/r/20250129115504.40080-1-krzysztof.kozlowski@linaro.org
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c
+index 798168180c1ab..a2c87c84aa05b 100644
+--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c
++++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c
+@@ -305,7 +305,7 @@ static void dsi_pll_commit(struct dsi_pll_7nm *pll, struct dsi_pll_config *confi
+       writel(pll->phy->cphy_mode ? 0x00 : 0x10,
+              base + REG_DSI_7nm_PHY_PLL_CMODE_1);
+       writel(config->pll_clock_inverters,
+-             base + REG_DSI_7nm_PHY_PLL_CLOCK_INVERTERS);
++             base + REG_DSI_7nm_PHY_PLL_CLOCK_INVERTERS_1);
+ }
+ static int dsi_pll_7nm_vco_set_rate(struct clk_hw *hw, unsigned long rate,
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-msm-dsi-set-phy-usescase-and-mode-before-registe.patch b/queue-6.14/drm-msm-dsi-set-phy-usescase-and-mode-before-registe.patch
new file mode 100644 (file)
index 0000000..781f8e1
--- /dev/null
@@ -0,0 +1,102 @@
+From 753a48ae6384ce86bf8bd088708f0d2fbcea4699 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 12:17:42 +0100
+Subject: drm/msm/dsi: Set PHY usescase (and mode) before registering DSI host
+
+From: Marijn Suijten <marijn.suijten@somainline.org>
+
+[ Upstream commit 660c396c98c061f9696bebacc178b74072e80054 ]
+
+Ordering issues here cause an uninitialized (default STANDALONE)
+usecase to be programmed (which appears to be a MUX) in some cases
+when msm_dsi_host_register() is called, leading to the slave PLL in
+bonded-DSI mode to source from a clock parent (dsi1vco) that is off.
+
+This should seemingly not be a problem as the actual dispcc clocks from
+DSI1 that are muxed in the clock tree of DSI0 are way further down, this
+bit still seems to have an effect on them somehow and causes the right
+side of the panel controlled by DSI1 to not function.
+
+In an ideal world this code is refactored to no longer have such
+error-prone calls "across subsystems", and instead model the "PLL src"
+register field as a regular mux so that changing the clock parents
+programmatically or in DTS via `assigned-clock-parents` has the
+desired effect.
+But for the avid reader, the clocks that we *are* muxing into DSI0's
+tree are way further down, so if this bit turns out to be a simple mux
+between dsiXvco and out_div, that shouldn't have any effect as this
+whole tree is off anyway.
+
+Fixes: 57bf43389337 ("drm/msm/dsi: Pass down use case to PHY")
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
+Patchwork: https://patchwork.freedesktop.org/patch/637650/
+Link: https://lore.kernel.org/r/20250217-drm-msm-initial-dualpipe-dsc-fixes-v3-2-913100d6103f@somainline.org
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/dsi/dsi_manager.c | 32 ++++++++++++++++++---------
+ 1 file changed, 21 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c
+index a210b7c9e5ca2..4fabb01345aa2 100644
+--- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
++++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
+@@ -74,17 +74,35 @@ static int dsi_mgr_setup_components(int id)
+       int ret;
+       if (!IS_BONDED_DSI()) {
++              /*
++               * Set the usecase before calling msm_dsi_host_register(), which would
++               * already program the PLL source mux based on a default usecase.
++               */
++              msm_dsi_phy_set_usecase(msm_dsi->phy, MSM_DSI_PHY_STANDALONE);
++              msm_dsi_host_set_phy_mode(msm_dsi->host, msm_dsi->phy);
++
+               ret = msm_dsi_host_register(msm_dsi->host);
+               if (ret)
+                       return ret;
+-
+-              msm_dsi_phy_set_usecase(msm_dsi->phy, MSM_DSI_PHY_STANDALONE);
+-              msm_dsi_host_set_phy_mode(msm_dsi->host, msm_dsi->phy);
+       } else if (other_dsi) {
+               struct msm_dsi *master_link_dsi = IS_MASTER_DSI_LINK(id) ?
+                                                       msm_dsi : other_dsi;
+               struct msm_dsi *slave_link_dsi = IS_MASTER_DSI_LINK(id) ?
+                                                       other_dsi : msm_dsi;
++
++              /*
++               * PLL0 is to drive both DSI link clocks in bonded DSI mode.
++               *
++               * Set the usecase before calling msm_dsi_host_register(), which would
++               * already program the PLL source mux based on a default usecase.
++               */
++              msm_dsi_phy_set_usecase(clk_master_dsi->phy,
++                                      MSM_DSI_PHY_MASTER);
++              msm_dsi_phy_set_usecase(clk_slave_dsi->phy,
++                                      MSM_DSI_PHY_SLAVE);
++              msm_dsi_host_set_phy_mode(msm_dsi->host, msm_dsi->phy);
++              msm_dsi_host_set_phy_mode(other_dsi->host, other_dsi->phy);
++
+               /* Register slave host first, so that slave DSI device
+                * has a chance to probe, and do not block the master
+                * DSI device's probe.
+@@ -98,14 +116,6 @@ static int dsi_mgr_setup_components(int id)
+               ret = msm_dsi_host_register(master_link_dsi->host);
+               if (ret)
+                       return ret;
+-
+-              /* PLL0 is to drive both 2 DSI link clocks in bonded DSI mode. */
+-              msm_dsi_phy_set_usecase(clk_master_dsi->phy,
+-                                      MSM_DSI_PHY_MASTER);
+-              msm_dsi_phy_set_usecase(clk_slave_dsi->phy,
+-                                      MSM_DSI_PHY_SLAVE);
+-              msm_dsi_host_set_phy_mode(msm_dsi->host, msm_dsi->phy);
+-              msm_dsi_host_set_phy_mode(other_dsi->host, other_dsi->phy);
+       }
+       return 0;
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-msm-dsi-use-existing-per-interface-slice-count-i.patch b/queue-6.14/drm-msm-dsi-use-existing-per-interface-slice-count-i.patch
new file mode 100644 (file)
index 0000000..0a4cca9
--- /dev/null
@@ -0,0 +1,107 @@
+From aa72269c9319da1669d2f50fda01405503ada39d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 12:17:41 +0100
+Subject: drm/msm/dsi: Use existing per-interface slice count in DSC timing
+
+From: Marijn Suijten <marijn.suijten@somainline.org>
+
+[ Upstream commit 14ad809ceb66d0874cbe4bd5ca9edf0de8d9ad96 ]
+
+When configuring the timing of DSI hosts (interfaces) in
+dsi_timing_setup() all values written to registers are taking
+bonded-mode into account by dividing the original mode width by 2
+(half the data is sent over each of the two DSI hosts), but the full
+width instead of the interface width is passed as hdisplay parameter to
+dsi_update_dsc_timing().
+
+Currently only msm_dsc_get_slices_per_intf() is called within
+dsi_update_dsc_timing() with the `hdisplay` argument which clearly
+documents that it wants the width of a single interface (which, again,
+in bonded DSI mode is half the total width of the mode) resulting in all
+subsequent values to be completely off.
+
+However, as soon as we start to pass the halved hdisplay
+into dsi_update_dsc_timing() we might as well discard
+msm_dsc_get_slices_per_intf() since the value it calculates is already
+available in dsc->slice_count which is per-interface by the current
+design of MSM DPU/DSI implementations and their use of the DRM DSC
+helpers.
+
+Fixes: 08802f515c3c ("drm/msm/dsi: Add support for DSC configuration")
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Jessica Zhang <quic_jesszhan@quicinc.com>
+Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
+Patchwork: https://patchwork.freedesktop.org/patch/637648/
+Link: https://lore.kernel.org/r/20250217-drm-msm-initial-dualpipe-dsc-fixes-v3-1-913100d6103f@somainline.org
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/dsi/dsi_host.c   |  8 ++++----
+ drivers/gpu/drm/msm/msm_dsc_helper.h | 11 -----------
+ 2 files changed, 4 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
+index 007311c21fdaa..42e100a8adca0 100644
+--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
++++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
+@@ -846,7 +846,7 @@ static void dsi_ctrl_enable(struct msm_dsi_host *msm_host,
+               dsi_write(msm_host, REG_DSI_CPHY_MODE_CTRL, BIT(0));
+ }
+-static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mode, u32 hdisplay)
++static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mode)
+ {
+       struct drm_dsc_config *dsc = msm_host->dsc;
+       u32 reg, reg_ctrl, reg_ctrl2;
+@@ -858,7 +858,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mod
+       /* first calculate dsc parameters and then program
+        * compress mode registers
+        */
+-      slice_per_intf = msm_dsc_get_slices_per_intf(dsc, hdisplay);
++      slice_per_intf = dsc->slice_count;
+       total_bytes_per_intf = dsc->slice_chunk_size * slice_per_intf;
+       bytes_per_pkt = dsc->slice_chunk_size; /* * slice_per_pkt; */
+@@ -991,7 +991,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
+       if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO) {
+               if (msm_host->dsc)
+-                      dsi_update_dsc_timing(msm_host, false, mode->hdisplay);
++                      dsi_update_dsc_timing(msm_host, false);
+               dsi_write(msm_host, REG_DSI_ACTIVE_H,
+                       DSI_ACTIVE_H_START(ha_start) |
+@@ -1012,7 +1012,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
+                       DSI_ACTIVE_VSYNC_VPOS_END(vs_end));
+       } else {                /* command mode */
+               if (msm_host->dsc)
+-                      dsi_update_dsc_timing(msm_host, true, mode->hdisplay);
++                      dsi_update_dsc_timing(msm_host, true);
+               /* image data and 1 byte write_memory_start cmd */
+               if (!msm_host->dsc)
+diff --git a/drivers/gpu/drm/msm/msm_dsc_helper.h b/drivers/gpu/drm/msm/msm_dsc_helper.h
+index b9049fe1e2790..63f95523b2cbb 100644
+--- a/drivers/gpu/drm/msm/msm_dsc_helper.h
++++ b/drivers/gpu/drm/msm/msm_dsc_helper.h
+@@ -12,17 +12,6 @@
+ #include <linux/math.h>
+ #include <drm/display/drm_dsc_helper.h>
+-/**
+- * msm_dsc_get_slices_per_intf() - calculate number of slices per interface
+- * @dsc: Pointer to drm dsc config struct
+- * @intf_width: interface width in pixels
+- * Returns: Integer representing the number of slices for the given interface
+- */
+-static inline u32 msm_dsc_get_slices_per_intf(const struct drm_dsc_config *dsc, u32 intf_width)
+-{
+-      return DIV_ROUND_UP(intf_width, dsc->slice_width);
+-}
+-
+ /**
+  * msm_dsc_get_bytes_per_line() - calculate bytes per line
+  * @dsc: Pointer to drm dsc config struct
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-msm-gem-fix-error-code-msm_parse_deps.patch b/queue-6.14/drm-msm-gem-fix-error-code-msm_parse_deps.patch
new file mode 100644 (file)
index 0000000..ca3fc0d
--- /dev/null
@@ -0,0 +1,39 @@
+From 059c78219060cdfdf2d3f056d310a46b65b91d77 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 10:32:11 +0300
+Subject: drm/msm/gem: Fix error code msm_parse_deps()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 0b305b7cadce835505bd93183a599acb1f800a05 ]
+
+The SUBMIT_ERROR() macro turns the error code negative.  This extra '-'
+operation turns it back to positive EINVAL again.  The error code is
+passed to ERR_PTR() and since positive values are not an IS_ERR() it
+eventually will lead to an oops.  Delete the '-'.
+
+Fixes: 866e43b945bf ("drm/msm: UAPI error reporting")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Patchwork: https://patchwork.freedesktop.org/patch/637625/
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/msm_gem_submit.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c
+index dee4704030368..3e9aa2cc38ef9 100644
+--- a/drivers/gpu/drm/msm/msm_gem_submit.c
++++ b/drivers/gpu/drm/msm/msm_gem_submit.c
+@@ -509,7 +509,7 @@ static struct drm_syncobj **msm_parse_deps(struct msm_gem_submit *submit,
+               }
+               if (syncobj_desc.flags & ~MSM_SUBMIT_SYNCOBJ_FLAGS) {
+-                      ret = -SUBMIT_ERROR(EINVAL, submit, "invalid syncobj flags: %x", syncobj_desc.flags);
++                      ret = SUBMIT_ERROR(EINVAL, submit, "invalid syncobj flags: %x", syncobj_desc.flags);
+                       break;
+               }
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-panel-ilitek-ili9882t-fix-gpio-name-in-error-mes.patch b/queue-6.14/drm-panel-ilitek-ili9882t-fix-gpio-name-in-error-mes.patch
new file mode 100644 (file)
index 0000000..13dac7d
--- /dev/null
@@ -0,0 +1,38 @@
+From 1d5d35b495b83235dcfbc6ba4041ffa12cae3a3b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 12:04:28 +0000
+Subject: drm/panel: ilitek-ili9882t: fix GPIO name in error message
+
+From: John Keeping <jkeeping@inmusicbrands.com>
+
+[ Upstream commit 4ce2c7e201c265df1c62a9190a98a98803208b8f ]
+
+This driver uses the enable-gpios property and it is confusing that the
+error message refers to reset-gpios.  Use the correct name when the
+enable GPIO is not found.
+
+Fixes: e2450d32e5fb5 ("drm/panel: ili9882t: Break out as separate driver")
+Signed-off-by: John Keeping <jkeeping@inmusicbrands.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250217120428.3779197-1-jkeeping@inmusicbrands.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/panel/panel-ilitek-ili9882t.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
+index 266a087fe14c1..3c24a63b6be8c 100644
+--- a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
++++ b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
+@@ -607,7 +607,7 @@ static int ili9882t_add(struct ili9882t *ili)
+       ili->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
+       if (IS_ERR(ili->enable_gpio)) {
+-              dev_err(dev, "cannot get reset-gpios %ld\n",
++              dev_err(dev, "cannot get enable-gpios %ld\n",
+                       PTR_ERR(ili->enable_gpio));
+               return PTR_ERR(ili->enable_gpio);
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-panthor-avoid-sleep-locking-in-the-internal-bo-s.patch b/queue-6.14/drm-panthor-avoid-sleep-locking-in-the-internal-bo-s.patch
new file mode 100644 (file)
index 0000000..55a46ee
--- /dev/null
@@ -0,0 +1,245 @@
+From 5618520687a1aabaad30d8689d6733e1d6efaf92 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Mar 2025 19:08:46 +0000
+Subject: drm/panthor: Avoid sleep locking in the internal BO size path
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Adrián Larumbe <adrian.larumbe@collabora.com>
+
+[ Upstream commit c63c3bfdde2656a3ead50ac3ce4a51a634e22dab ]
+
+Commit 434e5ca5b5d7 ("drm/panthor: Expose size of driver internal BO's over
+fdinfo") locks the VMS xarray, to avoid UAF errors when the same VM is
+being concurrently destroyed by another thread. However, that puts the
+current thread in atomic context, which means taking the VMS' heap locks
+will trigger a warning as the thread is no longer allowed to sleep.
+
+Because in this case replacing the heap mutex with a spinlock isn't
+feasible, the fdinfo handler no longer traverses the list of heaps for
+every single VM associated with an open DRM file. Instead, when a new heap
+chunk is allocated, its size is accumulated into a pool-wide tally, which
+also makes the atomic context code path somewhat faster.
+
+Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com>
+Fixes: 434e5ca5b5d7 ("drm/panthor: Expose size of driver internal BO's over fdinfo")
+Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
+Reviewed-by: Steven Price <steven.price@arm.com>
+Signed-off-by: Steven Price <steven.price@arm.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250303190923.1639985-2-adrian.larumbe@collabora.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/panthor/panthor_heap.c | 62 +++++++++++++-------------
+ drivers/gpu/drm/panthor/panthor_mmu.c  |  8 +---
+ 2 files changed, 31 insertions(+), 39 deletions(-)
+
+diff --git a/drivers/gpu/drm/panthor/panthor_heap.c b/drivers/gpu/drm/panthor/panthor_heap.c
+index db0285ce58126..3bdf61c142644 100644
+--- a/drivers/gpu/drm/panthor/panthor_heap.c
++++ b/drivers/gpu/drm/panthor/panthor_heap.c
+@@ -97,6 +97,9 @@ struct panthor_heap_pool {
+       /** @gpu_contexts: Buffer object containing the GPU heap contexts. */
+       struct panthor_kernel_bo *gpu_contexts;
++
++      /** @size: Size of all chunks across all heaps in the pool. */
++      atomic_t size;
+ };
+ static int panthor_heap_ctx_stride(struct panthor_device *ptdev)
+@@ -118,7 +121,7 @@ static void *panthor_get_heap_ctx(struct panthor_heap_pool *pool, int id)
+              panthor_get_heap_ctx_offset(pool, id);
+ }
+-static void panthor_free_heap_chunk(struct panthor_vm *vm,
++static void panthor_free_heap_chunk(struct panthor_heap_pool *pool,
+                                   struct panthor_heap *heap,
+                                   struct panthor_heap_chunk *chunk)
+ {
+@@ -127,12 +130,13 @@ static void panthor_free_heap_chunk(struct panthor_vm *vm,
+       heap->chunk_count--;
+       mutex_unlock(&heap->lock);
++      atomic_sub(heap->chunk_size, &pool->size);
++
+       panthor_kernel_bo_destroy(chunk->bo);
+       kfree(chunk);
+ }
+-static int panthor_alloc_heap_chunk(struct panthor_device *ptdev,
+-                                  struct panthor_vm *vm,
++static int panthor_alloc_heap_chunk(struct panthor_heap_pool *pool,
+                                   struct panthor_heap *heap,
+                                   bool initial_chunk)
+ {
+@@ -144,7 +148,7 @@ static int panthor_alloc_heap_chunk(struct panthor_device *ptdev,
+       if (!chunk)
+               return -ENOMEM;
+-      chunk->bo = panthor_kernel_bo_create(ptdev, vm, heap->chunk_size,
++      chunk->bo = panthor_kernel_bo_create(pool->ptdev, pool->vm, heap->chunk_size,
+                                            DRM_PANTHOR_BO_NO_MMAP,
+                                            DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC,
+                                            PANTHOR_VM_KERNEL_AUTO_VA);
+@@ -180,6 +184,8 @@ static int panthor_alloc_heap_chunk(struct panthor_device *ptdev,
+       heap->chunk_count++;
+       mutex_unlock(&heap->lock);
++      atomic_add(heap->chunk_size, &pool->size);
++
+       return 0;
+ err_destroy_bo:
+@@ -191,17 +197,16 @@ static int panthor_alloc_heap_chunk(struct panthor_device *ptdev,
+       return ret;
+ }
+-static void panthor_free_heap_chunks(struct panthor_vm *vm,
++static void panthor_free_heap_chunks(struct panthor_heap_pool *pool,
+                                    struct panthor_heap *heap)
+ {
+       struct panthor_heap_chunk *chunk, *tmp;
+       list_for_each_entry_safe(chunk, tmp, &heap->chunks, node)
+-              panthor_free_heap_chunk(vm, heap, chunk);
++              panthor_free_heap_chunk(pool, heap, chunk);
+ }
+-static int panthor_alloc_heap_chunks(struct panthor_device *ptdev,
+-                                   struct panthor_vm *vm,
++static int panthor_alloc_heap_chunks(struct panthor_heap_pool *pool,
+                                    struct panthor_heap *heap,
+                                    u32 chunk_count)
+ {
+@@ -209,7 +214,7 @@ static int panthor_alloc_heap_chunks(struct panthor_device *ptdev,
+       u32 i;
+       for (i = 0; i < chunk_count; i++) {
+-              ret = panthor_alloc_heap_chunk(ptdev, vm, heap, true);
++              ret = panthor_alloc_heap_chunk(pool, heap, true);
+               if (ret)
+                       return ret;
+       }
+@@ -226,7 +231,7 @@ panthor_heap_destroy_locked(struct panthor_heap_pool *pool, u32 handle)
+       if (!heap)
+               return -EINVAL;
+-      panthor_free_heap_chunks(pool->vm, heap);
++      panthor_free_heap_chunks(pool, heap);
+       mutex_destroy(&heap->lock);
+       kfree(heap);
+       return 0;
+@@ -308,8 +313,7 @@ int panthor_heap_create(struct panthor_heap_pool *pool,
+       heap->max_chunks = max_chunks;
+       heap->target_in_flight = target_in_flight;
+-      ret = panthor_alloc_heap_chunks(pool->ptdev, vm, heap,
+-                                      initial_chunk_count);
++      ret = panthor_alloc_heap_chunks(pool, heap, initial_chunk_count);
+       if (ret)
+               goto err_free_heap;
+@@ -342,7 +346,7 @@ int panthor_heap_create(struct panthor_heap_pool *pool,
+       return id;
+ err_free_heap:
+-      panthor_free_heap_chunks(pool->vm, heap);
++      panthor_free_heap_chunks(pool, heap);
+       mutex_destroy(&heap->lock);
+       kfree(heap);
+@@ -389,6 +393,7 @@ int panthor_heap_return_chunk(struct panthor_heap_pool *pool,
+                       removed = chunk;
+                       list_del(&chunk->node);
+                       heap->chunk_count--;
++                      atomic_sub(heap->chunk_size, &pool->size);
+                       break;
+               }
+       }
+@@ -466,7 +471,7 @@ int panthor_heap_grow(struct panthor_heap_pool *pool,
+        * further jobs in this queue fail immediately instead of having to
+        * wait for the job timeout.
+        */
+-      ret = panthor_alloc_heap_chunk(pool->ptdev, pool->vm, heap, false);
++      ret = panthor_alloc_heap_chunk(pool, heap, false);
+       if (ret)
+               goto out_unlock;
+@@ -560,6 +565,8 @@ panthor_heap_pool_create(struct panthor_device *ptdev, struct panthor_vm *vm)
+       if (ret)
+               goto err_destroy_pool;
++      atomic_add(pool->gpu_contexts->obj->size, &pool->size);
++
+       return pool;
+ err_destroy_pool:
+@@ -594,8 +601,10 @@ void panthor_heap_pool_destroy(struct panthor_heap_pool *pool)
+       xa_for_each(&pool->xa, i, heap)
+               drm_WARN_ON(&pool->ptdev->base, panthor_heap_destroy_locked(pool, i));
+-      if (!IS_ERR_OR_NULL(pool->gpu_contexts))
++      if (!IS_ERR_OR_NULL(pool->gpu_contexts)) {
++              atomic_sub(pool->gpu_contexts->obj->size, &pool->size);
+               panthor_kernel_bo_destroy(pool->gpu_contexts);
++      }
+       /* Reflects the fact the pool has been destroyed. */
+       pool->vm = NULL;
+@@ -605,27 +614,16 @@ void panthor_heap_pool_destroy(struct panthor_heap_pool *pool)
+ }
+ /**
+- * panthor_heap_pool_size() - Calculate size of all chunks across all heaps in a pool
+- * @pool: Pool whose total chunk size to calculate.
++ * panthor_heap_pool_size() - Get a heap pool's total size
++ * @pool: Pool whose total chunks size to return
+  *
+- * This function adds the size of all heap chunks across all heaps in the
+- * argument pool. It also adds the size of the gpu contexts kernel bo.
+- * It is meant to be used by fdinfo for displaying the size of internal
+- * driver BO's that aren't exposed to userspace through a GEM handle.
++ * Returns the aggregated size of all chunks for all heaps in the pool
+  *
+  */
+ size_t panthor_heap_pool_size(struct panthor_heap_pool *pool)
+ {
+-      struct panthor_heap *heap;
+-      unsigned long i;
+-      size_t size = 0;
+-
+-      down_read(&pool->lock);
+-      xa_for_each(&pool->xa, i, heap)
+-              size += heap->chunk_size * heap->chunk_count;
+-      up_read(&pool->lock);
+-
+-      size += pool->gpu_contexts->obj->size;
++      if (!pool)
++              return 0;
+-      return size;
++      return atomic_read(&pool->size);
+ }
+diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c
+index 11771ca8147f9..1202de8811c2a 100644
+--- a/drivers/gpu/drm/panthor/panthor_mmu.c
++++ b/drivers/gpu/drm/panthor/panthor_mmu.c
+@@ -1960,13 +1960,7 @@ void panthor_vm_heaps_sizes(struct panthor_file *pfile, struct drm_memory_stats
+       xa_lock(&pfile->vms->xa);
+       xa_for_each(&pfile->vms->xa, i, vm) {
+-              size_t size = 0;
+-
+-              mutex_lock(&vm->heaps.lock);
+-              if (vm->heaps.pool)
+-                      size = panthor_heap_pool_size(vm->heaps.pool);
+-              mutex_unlock(&vm->heaps.lock);
+-
++              size_t size = panthor_heap_pool_size(vm->heaps.pool);
+               stats->resident += size;
+               if (vm->as.id >= 0)
+                       stats->active += size;
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-panthor-clean-up-fw-version-information-display.patch b/queue-6.14/drm-panthor-clean-up-fw-version-information-display.patch
new file mode 100644 (file)
index 0000000..5611036
--- /dev/null
@@ -0,0 +1,67 @@
+From d780913eb6c767d9885664b4f787537f4fefbcac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Feb 2025 16:12:48 +0000
+Subject: drm/panthor: Clean up FW version information display
+
+From: Steven Price <steven.price@arm.com>
+
+[ Upstream commit 3b87886bfb038de2c62e627079472ba612e89410 ]
+
+Assigning a string to an array which is too small to include the NUL
+byte at the end causes a warning on some compilers. But this function
+also has some other oddities like the 'header' array which is only ever
+used within sizeof().
+
+Tidy up the function by removing the 'header' array, allow the NUL byte
+to be present in git_sha_header, and calculate the length directly from
+git_sha_header.
+
+Reported-by: Will Deacon <will@kernel.org>
+Closes: https://lore.kernel.org/all/20250213154237.GA11897@willie-the-truck/
+Fixes: 9d443deb0441 ("drm/panthor: Display FW version information")
+Signed-off-by: Steven Price <steven.price@arm.com>
+Acked-by: Will Deacon <will@kernel.org>
+Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250213161248.1642392-1-steven.price@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/panthor/panthor_fw.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/panthor/panthor_fw.c b/drivers/gpu/drm/panthor/panthor_fw.c
+index 68eb4fb4d3a8a..a024b475b6887 100644
+--- a/drivers/gpu/drm/panthor/panthor_fw.c
++++ b/drivers/gpu/drm/panthor/panthor_fw.c
+@@ -637,8 +637,8 @@ static int panthor_fw_read_build_info(struct panthor_device *ptdev,
+                                     u32 ehdr)
+ {
+       struct panthor_fw_build_info_hdr hdr;
+-      char header[9];
+-      const char git_sha_header[sizeof(header)] = "git_sha: ";
++      static const char git_sha_header[] = "git_sha: ";
++      const int header_len = sizeof(git_sha_header) - 1;
+       int ret;
+       ret = panthor_fw_binary_iter_read(ptdev, iter, &hdr, sizeof(hdr));
+@@ -652,8 +652,7 @@ static int panthor_fw_read_build_info(struct panthor_device *ptdev,
+               return 0;
+       }
+-      if (memcmp(git_sha_header, fw->data + hdr.meta_start,
+-                 sizeof(git_sha_header))) {
++      if (memcmp(git_sha_header, fw->data + hdr.meta_start, header_len)) {
+               /* Not the expected header, this isn't metadata we understand */
+               return 0;
+       }
+@@ -666,7 +665,7 @@ static int panthor_fw_read_build_info(struct panthor_device *ptdev,
+       }
+       drm_info(&ptdev->base, "Firmware git sha: %s\n",
+-               fw->data + hdr.meta_start + sizeof(git_sha_header));
++               fw->data + hdr.meta_start + header_len);
+       return 0;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-panthor-expose-size-of-driver-internal-bo-s-over.patch b/queue-6.14/drm-panthor-expose-size-of-driver-internal-bo-s-over.patch
new file mode 100644 (file)
index 0000000..d5b7944
--- /dev/null
@@ -0,0 +1,305 @@
+From a37045555c5f99e63e4e64225cb67b7965b55f05 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Jan 2025 17:28:11 +0000
+Subject: drm/panthor: Expose size of driver internal BO's over fdinfo
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Adrián Larumbe <adrian.larumbe@collabora.com>
+
+[ Upstream commit 434e5ca5b5d7ea415670d4fcb399d90d355a1e38 ]
+
+This will display the sizes of kenrel BO's bound to an open file, which are
+otherwise not exposed to UM through a handle.
+
+The sizes recorded are as follows:
+ - Per group: suspend buffer, protm-suspend buffer, syncobjcs
+ - Per queue: ringbuffer, profiling slots, firmware interface
+ - For all heaps in all heap pools across all VM's bound to an open file,
+ record size of all heap chuks, and for each pool the gpu_context BO too.
+
+This does not record the size of FW regions, as these aren't bound to a
+specific open file and remain active through the whole life of the driver.
+
+Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
+Reviewed-by: Mihail Atanassov <mihail.atanassov@arm.com>
+Reviewed-by: Steven Price <steven.price@arm.com>
+Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
+Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com>
+Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250130172851.941597-4-adrian.larumbe@collabora.com
+Stable-dep-of: e379856b428a ("drm/panthor: Replace sleep locks with spinlocks in fdinfo path")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/panthor/panthor_drv.c   | 14 +++++++
+ drivers/gpu/drm/panthor/panthor_heap.c  | 26 ++++++++++++
+ drivers/gpu/drm/panthor/panthor_heap.h  |  2 +
+ drivers/gpu/drm/panthor/panthor_mmu.c   | 33 +++++++++++++++
+ drivers/gpu/drm/panthor/panthor_mmu.h   |  3 ++
+ drivers/gpu/drm/panthor/panthor_sched.c | 56 ++++++++++++++++++++++++-
+ drivers/gpu/drm/panthor/panthor_sched.h |  3 ++
+ 7 files changed, 136 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/panthor/panthor_drv.c
+index 08136e790ca0a..06fe46e320738 100644
+--- a/drivers/gpu/drm/panthor/panthor_drv.c
++++ b/drivers/gpu/drm/panthor/panthor_drv.c
+@@ -1458,12 +1458,26 @@ static void panthor_gpu_show_fdinfo(struct panthor_device *ptdev,
+       drm_printf(p, "drm-curfreq-panthor:\t%lu Hz\n", ptdev->current_frequency);
+ }
++static void panthor_show_internal_memory_stats(struct drm_printer *p, struct drm_file *file)
++{
++      char *drv_name = file->minor->dev->driver->name;
++      struct panthor_file *pfile = file->driver_priv;
++      struct drm_memory_stats stats = {0};
++
++      panthor_fdinfo_gather_group_mem_info(pfile, &stats);
++      panthor_vm_heaps_sizes(pfile, &stats);
++
++      drm_fdinfo_print_size(p, drv_name, "resident", "memory", stats.resident);
++      drm_fdinfo_print_size(p, drv_name, "active", "memory", stats.active);
++}
++
+ static void panthor_show_fdinfo(struct drm_printer *p, struct drm_file *file)
+ {
+       struct drm_device *dev = file->minor->dev;
+       struct panthor_device *ptdev = container_of(dev, struct panthor_device, base);
+       panthor_gpu_show_fdinfo(ptdev, file->driver_priv, p);
++      panthor_show_internal_memory_stats(p, file);
+       drm_show_memory_stats(p, file);
+ }
+diff --git a/drivers/gpu/drm/panthor/panthor_heap.c b/drivers/gpu/drm/panthor/panthor_heap.c
+index 3796a9eb22af2..db0285ce58126 100644
+--- a/drivers/gpu/drm/panthor/panthor_heap.c
++++ b/drivers/gpu/drm/panthor/panthor_heap.c
+@@ -603,3 +603,29 @@ void panthor_heap_pool_destroy(struct panthor_heap_pool *pool)
+       panthor_heap_pool_put(pool);
+ }
++
++/**
++ * panthor_heap_pool_size() - Calculate size of all chunks across all heaps in a pool
++ * @pool: Pool whose total chunk size to calculate.
++ *
++ * This function adds the size of all heap chunks across all heaps in the
++ * argument pool. It also adds the size of the gpu contexts kernel bo.
++ * It is meant to be used by fdinfo for displaying the size of internal
++ * driver BO's that aren't exposed to userspace through a GEM handle.
++ *
++ */
++size_t panthor_heap_pool_size(struct panthor_heap_pool *pool)
++{
++      struct panthor_heap *heap;
++      unsigned long i;
++      size_t size = 0;
++
++      down_read(&pool->lock);
++      xa_for_each(&pool->xa, i, heap)
++              size += heap->chunk_size * heap->chunk_count;
++      up_read(&pool->lock);
++
++      size += pool->gpu_contexts->obj->size;
++
++      return size;
++}
+diff --git a/drivers/gpu/drm/panthor/panthor_heap.h b/drivers/gpu/drm/panthor/panthor_heap.h
+index 25a5f2bba4457..e3358d4e8edb2 100644
+--- a/drivers/gpu/drm/panthor/panthor_heap.h
++++ b/drivers/gpu/drm/panthor/panthor_heap.h
+@@ -27,6 +27,8 @@ struct panthor_heap_pool *
+ panthor_heap_pool_get(struct panthor_heap_pool *pool);
+ void panthor_heap_pool_put(struct panthor_heap_pool *pool);
++size_t panthor_heap_pool_size(struct panthor_heap_pool *pool);
++
+ int panthor_heap_grow(struct panthor_heap_pool *pool,
+                     u64 heap_gpu_va,
+                     u32 renderpasses_in_flight,
+diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c
+index c39e3eb1c15d5..11771ca8147f9 100644
+--- a/drivers/gpu/drm/panthor/panthor_mmu.c
++++ b/drivers/gpu/drm/panthor/panthor_mmu.c
+@@ -1941,6 +1941,39 @@ struct panthor_heap_pool *panthor_vm_get_heap_pool(struct panthor_vm *vm, bool c
+       return pool;
+ }
++/**
++ * panthor_vm_heaps_sizes() - Calculate size of all heap chunks across all
++ * heaps over all the heap pools in a VM
++ * @pfile: File.
++ * @stats: Memory stats to be updated.
++ *
++ * Calculate all heap chunk sizes in all heap pools bound to a VM. If the VM
++ * is active, record the size as active as well.
++ */
++void panthor_vm_heaps_sizes(struct panthor_file *pfile, struct drm_memory_stats *stats)
++{
++      struct panthor_vm *vm;
++      unsigned long i;
++
++      if (!pfile->vms)
++              return;
++
++      xa_lock(&pfile->vms->xa);
++      xa_for_each(&pfile->vms->xa, i, vm) {
++              size_t size = 0;
++
++              mutex_lock(&vm->heaps.lock);
++              if (vm->heaps.pool)
++                      size = panthor_heap_pool_size(vm->heaps.pool);
++              mutex_unlock(&vm->heaps.lock);
++
++              stats->resident += size;
++              if (vm->as.id >= 0)
++                      stats->active += size;
++      }
++      xa_unlock(&pfile->vms->xa);
++}
++
+ static u64 mair_to_memattr(u64 mair, bool coherent)
+ {
+       u64 memattr = 0;
+diff --git a/drivers/gpu/drm/panthor/panthor_mmu.h b/drivers/gpu/drm/panthor/panthor_mmu.h
+index 8d21e83d8aba1..fc274637114e5 100644
+--- a/drivers/gpu/drm/panthor/panthor_mmu.h
++++ b/drivers/gpu/drm/panthor/panthor_mmu.h
+@@ -9,6 +9,7 @@
+ struct drm_exec;
+ struct drm_sched_job;
++struct drm_memory_stats;
+ struct panthor_gem_object;
+ struct panthor_heap_pool;
+ struct panthor_vm;
+@@ -37,6 +38,8 @@ int panthor_vm_flush_all(struct panthor_vm *vm);
+ struct panthor_heap_pool *
+ panthor_vm_get_heap_pool(struct panthor_vm *vm, bool create);
++void panthor_vm_heaps_sizes(struct panthor_file *pfile, struct drm_memory_stats *stats);
++
+ struct panthor_vm *panthor_vm_get(struct panthor_vm *vm);
+ void panthor_vm_put(struct panthor_vm *vm);
+ struct panthor_vm *panthor_vm_create(struct panthor_device *ptdev, bool for_mcu,
+diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c
+index 1349581196780..2f92ef2b5ab99 100644
+--- a/drivers/gpu/drm/panthor/panthor_sched.c
++++ b/drivers/gpu/drm/panthor/panthor_sched.c
+@@ -628,7 +628,7 @@ struct panthor_group {
+        */
+       struct panthor_kernel_bo *syncobjs;
+-      /** @fdinfo: Per-file total cycle and timestamp values reference. */
++      /** @fdinfo: Per-file info exposed through /proc/<process>/fdinfo */
+       struct {
+               /** @data: Total sampled values for jobs in queues from this group. */
+               struct panthor_gpu_usage data;
+@@ -638,6 +638,9 @@ struct panthor_group {
+                * and job post-completion processing function
+                */
+               struct mutex lock;
++
++              /** @fdinfo.kbo_sizes: Aggregate size of private kernel BO's held by the group. */
++              size_t kbo_sizes;
+       } fdinfo;
+       /** @state: Group state. */
+@@ -3383,6 +3386,29 @@ group_create_queue(struct panthor_group *group,
+       return ERR_PTR(ret);
+ }
++static void add_group_kbo_sizes(struct panthor_device *ptdev,
++                              struct panthor_group *group)
++{
++      struct panthor_queue *queue;
++      int i;
++
++      if (drm_WARN_ON(&ptdev->base, IS_ERR_OR_NULL(group)))
++              return;
++      if (drm_WARN_ON(&ptdev->base, ptdev != group->ptdev))
++              return;
++
++      group->fdinfo.kbo_sizes += group->suspend_buf->obj->size;
++      group->fdinfo.kbo_sizes += group->protm_suspend_buf->obj->size;
++      group->fdinfo.kbo_sizes += group->syncobjs->obj->size;
++
++      for (i = 0; i < group->queue_count; i++) {
++              queue = group->queues[i];
++              group->fdinfo.kbo_sizes += queue->ringbuf->obj->size;
++              group->fdinfo.kbo_sizes += queue->iface.mem->obj->size;
++              group->fdinfo.kbo_sizes += queue->profiling.slots->obj->size;
++      }
++}
++
+ #define MAX_GROUPS_PER_POOL           128
+ int panthor_group_create(struct panthor_file *pfile,
+@@ -3507,6 +3533,7 @@ int panthor_group_create(struct panthor_file *pfile,
+       }
+       mutex_unlock(&sched->reset.lock);
++      add_group_kbo_sizes(group->ptdev, group);
+       mutex_init(&group->fdinfo.lock);
+       return gid;
+@@ -3626,6 +3653,33 @@ void panthor_group_pool_destroy(struct panthor_file *pfile)
+       pfile->groups = NULL;
+ }
++/**
++ * panthor_fdinfo_gather_group_mem_info() - Retrieve aggregate size of all private kernel BO's
++ * belonging to all the groups owned by an open Panthor file
++ * @pfile: File.
++ * @stats: Memory statistics to be updated.
++ *
++ */
++void
++panthor_fdinfo_gather_group_mem_info(struct panthor_file *pfile,
++                                   struct drm_memory_stats *stats)
++{
++      struct panthor_group_pool *gpool = pfile->groups;
++      struct panthor_group *group;
++      unsigned long i;
++
++      if (IS_ERR_OR_NULL(gpool))
++              return;
++
++      xa_lock(&gpool->xa);
++      xa_for_each(&gpool->xa, i, group) {
++              stats->resident += group->fdinfo.kbo_sizes;
++              if (group->csg_id >= 0)
++                      stats->active += group->fdinfo.kbo_sizes;
++      }
++      xa_unlock(&gpool->xa);
++}
++
+ static void job_release(struct kref *ref)
+ {
+       struct panthor_job *job = container_of(ref, struct panthor_job, refcount);
+diff --git a/drivers/gpu/drm/panthor/panthor_sched.h b/drivers/gpu/drm/panthor/panthor_sched.h
+index 5ae6b4bde7c50..e650a445cf507 100644
+--- a/drivers/gpu/drm/panthor/panthor_sched.h
++++ b/drivers/gpu/drm/panthor/panthor_sched.h
+@@ -9,6 +9,7 @@ struct dma_fence;
+ struct drm_file;
+ struct drm_gem_object;
+ struct drm_sched_job;
++struct drm_memory_stats;
+ struct drm_panthor_group_create;
+ struct drm_panthor_queue_create;
+ struct drm_panthor_group_get_state;
+@@ -36,6 +37,8 @@ void panthor_job_update_resvs(struct drm_exec *exec, struct drm_sched_job *job);
+ int panthor_group_pool_create(struct panthor_file *pfile);
+ void panthor_group_pool_destroy(struct panthor_file *pfile);
++void panthor_fdinfo_gather_group_mem_info(struct panthor_file *pfile,
++                                        struct drm_memory_stats *stats);
+ int panthor_sched_init(struct panthor_device *ptdev);
+ void panthor_sched_unplug(struct panthor_device *ptdev);
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-panthor-fix-a-race-between-the-reset-and-suspend.patch b/queue-6.14/drm-panthor-fix-a-race-between-the-reset-and-suspend.patch
new file mode 100644 (file)
index 0000000..6302a70
--- /dev/null
@@ -0,0 +1,80 @@
+From eba19235c328f83f21b367a1c29cff18b4fb6767 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Dec 2024 10:24:57 +0100
+Subject: drm/panthor: Fix a race between the reset and suspend path
+
+From: Boris Brezillon <boris.brezillon@collabora.com>
+
+[ Upstream commit 57e233c3bd63f32d2c7e937db2e16b98f723ce2f ]
+
+If a reset is scheduled when the suspend happens, we drop the
+reset-pending info on the floor assuming the resume will fix things,
+but the resume logic might try a fast reset. If we're lucky, the
+fast reset fails and we fallback to a slow reset, but if the FW was
+corrupted in a way that makes it partially functional (it boots but
+doesn't quite do what it's expected to do), we won't notice immediately
+that things are not working correctly, leading to a new reset further
+down the road.
+
+Fixes: 5fe909cae118 ("drm/panthor: Add the device logical block")
+Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
+Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
+Reviewed-by: Steven Price <steven.price@arm.com>
+Signed-off-by: Steven Price <steven.price@arm.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20241217092457.1582053-1-boris.brezillon@collabora.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/panthor/panthor_device.c | 22 ++++++++++++----------
+ 1 file changed, 12 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/gpu/drm/panthor/panthor_device.c b/drivers/gpu/drm/panthor/panthor_device.c
+index 0a37cfeeb181c..a9da1d1eeb707 100644
+--- a/drivers/gpu/drm/panthor/panthor_device.c
++++ b/drivers/gpu/drm/panthor/panthor_device.c
+@@ -128,14 +128,11 @@ static void panthor_device_reset_work(struct work_struct *work)
+       struct panthor_device *ptdev = container_of(work, struct panthor_device, reset.work);
+       int ret = 0, cookie;
+-      if (atomic_read(&ptdev->pm.state) != PANTHOR_DEVICE_PM_STATE_ACTIVE) {
+-              /*
+-               * No need for a reset as the device has been (or will be)
+-               * powered down
+-               */
+-              atomic_set(&ptdev->reset.pending, 0);
++      /* If the device is entering suspend, we don't reset. A slow reset will
++       * be forced at resume time instead.
++       */
++      if (atomic_read(&ptdev->pm.state) != PANTHOR_DEVICE_PM_STATE_ACTIVE)
+               return;
+-      }
+       if (!drm_dev_enter(&ptdev->base, &cookie))
+               return;
+@@ -477,6 +474,14 @@ int panthor_device_resume(struct device *dev)
+       if (panthor_device_is_initialized(ptdev) &&
+           drm_dev_enter(&ptdev->base, &cookie)) {
++              /* If there was a reset pending at the time we suspended the
++               * device, we force a slow reset.
++               */
++              if (atomic_read(&ptdev->reset.pending)) {
++                      ptdev->reset.fast = false;
++                      atomic_set(&ptdev->reset.pending, 0);
++              }
++
+               ret = panthor_device_resume_hw_components(ptdev);
+               if (ret && ptdev->reset.fast) {
+                       drm_err(&ptdev->base, "Fast reset failed, trying a slow reset");
+@@ -493,9 +498,6 @@ int panthor_device_resume(struct device *dev)
+                       goto err_suspend_devfreq;
+       }
+-      if (atomic_read(&ptdev->reset.pending))
+-              queue_work(ptdev->reset.wq, &ptdev->reset.work);
+-
+       /* Clear all IOMEM mappings pointing to this device after we've
+        * resumed. This way the fake mappings pointing to the dummy pages
+        * are removed and the real iomem mapping will be restored on next
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-panthor-fix-race-condition-when-gathering-fdinfo.patch b/queue-6.14/drm-panthor-fix-race-condition-when-gathering-fdinfo.patch
new file mode 100644 (file)
index 0000000..5d2c8b8
--- /dev/null
@@ -0,0 +1,51 @@
+From 46688cadec453fc9131fd937bac4020eadc5c1db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Jan 2025 17:28:13 +0000
+Subject: drm/panthor: Fix race condition when gathering fdinfo group samples
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Adrián Larumbe <adrian.larumbe@collabora.com>
+
+[ Upstream commit 0590c94c3596d6c1a3d549ae611366f2ad4e1d8d ]
+
+Commit e16635d88fa0 ("drm/panthor: add DRM fdinfo support") failed to
+protect access to groups with an xarray lock, which could lead to
+use-after-free errors.
+
+Fixes: e16635d88fa0 ("drm/panthor: add DRM fdinfo support")
+Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
+Reviewed-by: Steven Price <steven.price@arm.com>
+Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com>
+Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250130172851.941597-6-adrian.larumbe@collabora.com
+Link: https://patchwork.freedesktop.org/patch/msgid/20250107173310.88329-1-florent.tomasin@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/panthor/panthor_sched.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c
+index 77b184c3fb0ce..1349581196780 100644
+--- a/drivers/gpu/drm/panthor/panthor_sched.c
++++ b/drivers/gpu/drm/panthor/panthor_sched.c
+@@ -2878,6 +2878,7 @@ void panthor_fdinfo_gather_group_samples(struct panthor_file *pfile)
+       if (IS_ERR_OR_NULL(gpool))
+               return;
++      xa_lock(&gpool->xa);
+       xa_for_each(&gpool->xa, i, group) {
+               mutex_lock(&group->fdinfo.lock);
+               pfile->stats.cycles += group->fdinfo.data.cycles;
+@@ -2886,6 +2887,7 @@ void panthor_fdinfo_gather_group_samples(struct panthor_file *pfile)
+               group->fdinfo.data.time = 0;
+               mutex_unlock(&group->fdinfo.lock);
+       }
++      xa_unlock(&gpool->xa);
+ }
+ static void group_sync_upd_work(struct work_struct *work)
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-panthor-replace-sleep-locks-with-spinlocks-in-fd.patch b/queue-6.14/drm-panthor-replace-sleep-locks-with-spinlocks-in-fd.patch
new file mode 100644 (file)
index 0000000..7359587
--- /dev/null
@@ -0,0 +1,115 @@
+From e681dd915e278af95a773a116f557e963b57ff30 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Mar 2025 19:08:45 +0000
+Subject: drm/panthor: Replace sleep locks with spinlocks in fdinfo path
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Adrián Larumbe <adrian.larumbe@collabora.com>
+
+[ Upstream commit e379856b428acafb8ed689f31d65814da6447b2e ]
+
+Commit 0590c94c3596 ("drm/panthor: Fix race condition when gathering fdinfo
+group samples") introduced an xarray lock to deal with potential
+use-after-free errors when accessing groups fdinfo figures. However, this
+toggles the kernel's atomic context status, so the next nested mutex lock
+will raise a warning when the kernel is compiled with mutex debug options:
+
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_DEBUG_MUTEXES=y
+
+Replace Panthor's group fdinfo data mutex with a guarded spinlock.
+
+Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com>
+Fixes: 0590c94c3596 ("drm/panthor: Fix race condition when gathering fdinfo group samples")
+Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
+Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
+Reviewed-by: Steven Price <steven.price@arm.com>
+Signed-off-by: Steven Price <steven.price@arm.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250303190923.1639985-1-adrian.larumbe@collabora.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/panthor/panthor_sched.c | 26 ++++++++++++-------------
+ 1 file changed, 12 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c
+index 2f92ef2b5ab99..b8dbeb1586f64 100644
+--- a/drivers/gpu/drm/panthor/panthor_sched.c
++++ b/drivers/gpu/drm/panthor/panthor_sched.c
+@@ -9,6 +9,7 @@
+ #include <drm/panthor_drm.h>
+ #include <linux/build_bug.h>
++#include <linux/cleanup.h>
+ #include <linux/clk.h>
+ #include <linux/delay.h>
+ #include <linux/dma-mapping.h>
+@@ -634,10 +635,10 @@ struct panthor_group {
+               struct panthor_gpu_usage data;
+               /**
+-               * @lock: Mutex to govern concurrent access from drm file's fdinfo callback
+-               * and job post-completion processing function
++               * @fdinfo.lock: Spinlock to govern concurrent access from drm file's fdinfo
++               * callback and job post-completion processing function
+                */
+-              struct mutex lock;
++              spinlock_t lock;
+               /** @fdinfo.kbo_sizes: Aggregate size of private kernel BO's held by the group. */
+               size_t kbo_sizes;
+@@ -913,8 +914,6 @@ static void group_release_work(struct work_struct *work)
+                                                  release_work);
+       u32 i;
+-      mutex_destroy(&group->fdinfo.lock);
+-
+       for (i = 0; i < group->queue_count; i++)
+               group_free_queue(group, group->queues[i]);
+@@ -2864,12 +2863,12 @@ static void update_fdinfo_stats(struct panthor_job *job)
+       struct panthor_job_profiling_data *slots = queue->profiling.slots->kmap;
+       struct panthor_job_profiling_data *data = &slots[job->profiling.slot];
+-      mutex_lock(&group->fdinfo.lock);
+-      if (job->profiling.mask & PANTHOR_DEVICE_PROFILING_CYCLES)
+-              fdinfo->cycles += data->cycles.after - data->cycles.before;
+-      if (job->profiling.mask & PANTHOR_DEVICE_PROFILING_TIMESTAMP)
+-              fdinfo->time += data->time.after - data->time.before;
+-      mutex_unlock(&group->fdinfo.lock);
++      scoped_guard(spinlock, &group->fdinfo.lock) {
++              if (job->profiling.mask & PANTHOR_DEVICE_PROFILING_CYCLES)
++                      fdinfo->cycles += data->cycles.after - data->cycles.before;
++              if (job->profiling.mask & PANTHOR_DEVICE_PROFILING_TIMESTAMP)
++                      fdinfo->time += data->time.after - data->time.before;
++      }
+ }
+ void panthor_fdinfo_gather_group_samples(struct panthor_file *pfile)
+@@ -2883,12 +2882,11 @@ void panthor_fdinfo_gather_group_samples(struct panthor_file *pfile)
+       xa_lock(&gpool->xa);
+       xa_for_each(&gpool->xa, i, group) {
+-              mutex_lock(&group->fdinfo.lock);
++              guard(spinlock)(&group->fdinfo.lock);
+               pfile->stats.cycles += group->fdinfo.data.cycles;
+               pfile->stats.time += group->fdinfo.data.time;
+               group->fdinfo.data.cycles = 0;
+               group->fdinfo.data.time = 0;
+-              mutex_unlock(&group->fdinfo.lock);
+       }
+       xa_unlock(&gpool->xa);
+ }
+@@ -3534,7 +3532,7 @@ int panthor_group_create(struct panthor_file *pfile,
+       mutex_unlock(&sched->reset.lock);
+       add_group_kbo_sizes(group->ptdev, group);
+-      mutex_init(&group->fdinfo.lock);
++      spin_lock_init(&group->fdinfo.lock);
+       return gid;
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-panthor-update-cs_status_-defines-to-correct-val.patch b/queue-6.14/drm-panthor-update-cs_status_-defines-to-correct-val.patch
new file mode 100644 (file)
index 0000000..c842dc0
--- /dev/null
@@ -0,0 +1,50 @@
+From ae691db6418db92c0f36dfbb23d0ba4ba766c511 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Mar 2025 18:04:32 +0000
+Subject: drm/panthor: Update CS_STATUS_ defines to correct values
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ashley Smith <ashley.smith@collabora.com>
+
+[ Upstream commit c82734fbdc50dc9e568e8686622eaa4498acb81e ]
+
+Values for SC_STATUS_BLOCKED_REASON_ are documented in the G610 "Odin"
+GPU specification (CS_STATUS_BLOCKED_REASON register).
+
+This change updates the defines to the correct values.
+
+Fixes: 2718d91816ee ("drm/panthor: Add the FW logical block")
+Signed-off-by: Ashley Smith <ashley.smith@collabora.com>
+Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
+Reviewed-by: Adrián Larumbe <adrian.larumbe@collabora.com>
+Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
+Reviewed-by: Steven Price <steven.price@arm.com>
+Signed-off-by: Steven Price <steven.price@arm.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250303180444.3768993-1-ashley.smith@collabora.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/panthor/panthor_fw.h | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/panthor/panthor_fw.h b/drivers/gpu/drm/panthor/panthor_fw.h
+index 22448abde9923..6598d96c6d2aa 100644
+--- a/drivers/gpu/drm/panthor/panthor_fw.h
++++ b/drivers/gpu/drm/panthor/panthor_fw.h
+@@ -102,9 +102,9 @@ struct panthor_fw_cs_output_iface {
+ #define CS_STATUS_BLOCKED_REASON_SB_WAIT      1
+ #define CS_STATUS_BLOCKED_REASON_PROGRESS_WAIT        2
+ #define CS_STATUS_BLOCKED_REASON_SYNC_WAIT    3
+-#define CS_STATUS_BLOCKED_REASON_DEFERRED     5
+-#define CS_STATUS_BLOCKED_REASON_RES          6
+-#define CS_STATUS_BLOCKED_REASON_FLUSH                7
++#define CS_STATUS_BLOCKED_REASON_DEFERRED     4
++#define CS_STATUS_BLOCKED_REASON_RESOURCE     5
++#define CS_STATUS_BLOCKED_REASON_FLUSH                6
+ #define CS_STATUS_BLOCKED_REASON_MASK         GENMASK(3, 0)
+       u32 status_blocked_reason;
+       u32 status_wait_sync_value_hi;
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-ssd130x-ensure-ssd132x-pitch-is-correct.patch b/queue-6.14/drm-ssd130x-ensure-ssd132x-pitch-is-correct.patch
new file mode 100644 (file)
index 0000000..2b6f763
--- /dev/null
@@ -0,0 +1,48 @@
+From 8bd1dd29bee064b59d10aca1b829e487d99bf428 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jan 2025 11:01:38 +0000
+Subject: drm/ssd130x: ensure ssd132x pitch is correct
+
+From: John Keeping <jkeeping@inmusicbrands.com>
+
+[ Upstream commit 229adcffdb54b13332d2afd2dc5d203418d50908 ]
+
+The bounding rectangle is adjusted to ensure it aligns to
+SSD132X_SEGMENT_WIDTH, which may adjust the pitch.  Calculate the pitch
+after aligning the left and right edge.
+
+Fixes: fdd591e00a9c ("drm/ssd130x: Add support for the SSD132x OLED controller family")
+Signed-off-by: John Keeping <jkeeping@inmusicbrands.com>
+Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250115110139.1672488-3-jkeeping@inmusicbrands.com
+Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/solomon/ssd130x.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c
+index 4bb663f984ce3..dd2006d51c7a2 100644
+--- a/drivers/gpu/drm/solomon/ssd130x.c
++++ b/drivers/gpu/drm/solomon/ssd130x.c
+@@ -1037,7 +1037,7 @@ static int ssd132x_fb_blit_rect(struct drm_framebuffer *fb,
+                               struct drm_format_conv_state *fmtcnv_state)
+ {
+       struct ssd130x_device *ssd130x = drm_to_ssd130x(fb->dev);
+-      unsigned int dst_pitch = drm_rect_width(rect);
++      unsigned int dst_pitch;
+       struct iosys_map dst;
+       int ret = 0;
+@@ -1046,6 +1046,8 @@ static int ssd132x_fb_blit_rect(struct drm_framebuffer *fb,
+       rect->x2 = min_t(unsigned int, round_up(rect->x2, SSD132X_SEGMENT_WIDTH),
+                        ssd130x->width);
++      dst_pitch = drm_rect_width(rect);
++
+       ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE);
+       if (ret)
+               return ret;
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-ssd130x-fix-ssd132x-encoding.patch b/queue-6.14/drm-ssd130x-fix-ssd132x-encoding.patch
new file mode 100644 (file)
index 0000000..f7d0b96
--- /dev/null
@@ -0,0 +1,40 @@
+From 9077bd66d997a00996d4b7c904dbd6c49c525d1d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jan 2025 11:01:37 +0000
+Subject: drm/ssd130x: fix ssd132x encoding
+
+From: John Keeping <jkeeping@inmusicbrands.com>
+
+[ Upstream commit 1e14484677c8e87548f5f0d4eb8800e408004404 ]
+
+The ssd132x buffer is encoded one pixel per nibble, with two pixels in
+each byte.  When encoding an 8-bit greyscale input, take the top 4-bits
+as the value and ensure the two pixels are distinct and do not overwrite
+each other.
+
+Fixes: fdd591e00a9c ("drm/ssd130x: Add support for the SSD132x OLED controller family")
+Signed-off-by: John Keeping <jkeeping@inmusicbrands.com>
+Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250115110139.1672488-2-jkeeping@inmusicbrands.com
+Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/solomon/ssd130x.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c
+index b777690fd6607..4bb663f984ce3 100644
+--- a/drivers/gpu/drm/solomon/ssd130x.c
++++ b/drivers/gpu/drm/solomon/ssd130x.c
+@@ -880,7 +880,7 @@ static int ssd132x_update_rect(struct ssd130x_device *ssd130x,
+                       u8 n1 = buf[i * width + j];
+                       u8 n2 = buf[i * width + j + 1];
+-                      data_array[array_idx++] = (n2 << 4) | n1;
++                      data_array[array_idx++] = (n2 & 0xf0) | (n1 >> 4);
+               }
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-ssd130x-set-spi-.id_table-to-prevent-an-spi-core.patch b/queue-6.14/drm-ssd130x-set-spi-.id_table-to-prevent-an-spi-core.patch
new file mode 100644 (file)
index 0000000..fb7fd3a
--- /dev/null
@@ -0,0 +1,95 @@
+From 1828bd7806d3a902b079d9d50efc4dc15a7ae2ca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 31 Dec 2024 12:44:58 +0100
+Subject: drm/ssd130x: Set SPI .id_table to prevent an SPI core warning
+
+From: Javier Martinez Canillas <javierm@redhat.com>
+
+[ Upstream commit 5d40d4fae6f2fb789f48207a9d4772bbee970b5c ]
+
+The only reason for the ssd130x-spi driver to have an spi_device_id table
+is that the SPI core always reports an "spi:" MODALIAS, even when the SPI
+device has been registered via a Device Tree Blob.
+
+Without spi_device_id table information in the module's metadata, module
+autoloading would not work because there won't be an alias that matches
+the MODALIAS reported by the SPI core.
+
+This spi_device_id table is not needed for device matching though, since
+the of_device_id table is always used in this case. For this reason, the
+struct spi_driver .id_table member is currently not set in the SPI driver.
+
+Because the spi_device_id table is always required for module autoloading,
+the SPI core checks during driver registration that both an of_device_id
+table and a spi_device_id table are present and that they contain the same
+entries for all the SPI devices.
+
+Not setting the .id_table member in the driver then confuses the core and
+leads to the following warning when the ssd130x-spi driver is registered:
+
+  [   41.091198] SPI driver ssd130x-spi has no spi_device_id for sinowealth,sh1106
+  [   41.098614] SPI driver ssd130x-spi has no spi_device_id for solomon,ssd1305
+  [   41.105862] SPI driver ssd130x-spi has no spi_device_id for solomon,ssd1306
+  [   41.113062] SPI driver ssd130x-spi has no spi_device_id for solomon,ssd1307
+  [   41.120247] SPI driver ssd130x-spi has no spi_device_id for solomon,ssd1309
+  [   41.127449] SPI driver ssd130x-spi has no spi_device_id for solomon,ssd1322
+  [   41.134627] SPI driver ssd130x-spi has no spi_device_id for solomon,ssd1325
+  [   41.141784] SPI driver ssd130x-spi has no spi_device_id for solomon,ssd1327
+  [   41.149021] SPI driver ssd130x-spi has no spi_device_id for solomon,ssd1331
+
+To prevent the warning, set the .id_table even though it's not necessary.
+
+Since the check is done even for built-in drivers, drop the condition to
+only define the ID table when the driver is built as a module. Finally,
+rename the variable to use the "_spi_id" convention used for ID tables.
+
+Fixes: 74373977d2ca ("drm/solomon: Add SSD130x OLED displays SPI support")
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20241231114516.2063201-1-javierm@redhat.com
+Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/solomon/ssd130x-spi.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/solomon/ssd130x-spi.c b/drivers/gpu/drm/solomon/ssd130x-spi.c
+index 08334be386946..7c935870f7d2a 100644
+--- a/drivers/gpu/drm/solomon/ssd130x-spi.c
++++ b/drivers/gpu/drm/solomon/ssd130x-spi.c
+@@ -151,7 +151,6 @@ static const struct of_device_id ssd130x_of_match[] = {
+ };
+ MODULE_DEVICE_TABLE(of, ssd130x_of_match);
+-#if IS_MODULE(CONFIG_DRM_SSD130X_SPI)
+ /*
+  * The SPI core always reports a MODALIAS uevent of the form "spi:<dev>", even
+  * if the device was registered via OF. This means that the module will not be
+@@ -160,7 +159,7 @@ MODULE_DEVICE_TABLE(of, ssd130x_of_match);
+  * To workaround this issue, add a SPI device ID table. Even when this should
+  * not be needed for this driver to match the registered SPI devices.
+  */
+-static const struct spi_device_id ssd130x_spi_table[] = {
++static const struct spi_device_id ssd130x_spi_id[] = {
+       /* ssd130x family */
+       { "sh1106",  SH1106_ID },
+       { "ssd1305", SSD1305_ID },
+@@ -175,14 +174,14 @@ static const struct spi_device_id ssd130x_spi_table[] = {
+       { "ssd1331", SSD1331_ID },
+       { /* sentinel */ }
+ };
+-MODULE_DEVICE_TABLE(spi, ssd130x_spi_table);
+-#endif
++MODULE_DEVICE_TABLE(spi, ssd130x_spi_id);
+ static struct spi_driver ssd130x_spi_driver = {
+       .driver = {
+               .name = DRIVER_NAME,
+               .of_match_table = ssd130x_of_match,
+       },
++      .id_table = ssd130x_spi_id,
+       .probe = ssd130x_spi_probe,
+       .remove = ssd130x_spi_remove,
+       .shutdown = ssd130x_spi_shutdown,
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-vkms-fix-use-after-free-and-double-free-on-init-.patch b/queue-6.14/drm-vkms-fix-use-after-free-and-double-free-on-init-.patch
new file mode 100644 (file)
index 0000000..83ade6e
--- /dev/null
@@ -0,0 +1,76 @@
+From 85fdf745f8fd6c2092f30d8e2f128535d353130c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Feb 2025 09:49:12 +0100
+Subject: drm/vkms: Fix use after free and double free on init error
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: José Expósito <jose.exposito89@gmail.com>
+
+[ Upstream commit ed15511a773df86205bda66c37193569575ae828 ]
+
+If the driver initialization fails, the vkms_exit() function might
+access an uninitialized or freed default_config pointer and it might
+double free it.
+
+Fix both possible errors by initializing default_config only when the
+driver initialization succeeded.
+
+Reported-by: Louis Chauvet <louis.chauvet@bootlin.com>
+Closes: https://lore.kernel.org/all/Z5uDHcCmAwiTsGte@louis-chauvet-laptop/
+Fixes: 2df7af93fdad ("drm/vkms: Add vkms_config type")
+Signed-off-by: José Expósito <jose.exposito89@gmail.com>
+Reviewed-by: Thomas Zimmermann <tzimmremann@suse.de>
+Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250212084912.3196-1-jose.exposito89@gmail.com
+Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vkms/vkms_drv.c | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
+index e0409aba93496..7fefef690ab6b 100644
+--- a/drivers/gpu/drm/vkms/vkms_drv.c
++++ b/drivers/gpu/drm/vkms/vkms_drv.c
+@@ -244,17 +244,19 @@ static int __init vkms_init(void)
+       if (!config)
+               return -ENOMEM;
+-      default_config = config;
+-
+       config->cursor = enable_cursor;
+       config->writeback = enable_writeback;
+       config->overlay = enable_overlay;
+       ret = vkms_create(config);
+-      if (ret)
++      if (ret) {
+               kfree(config);
++              return ret;
++      }
+-      return ret;
++      default_config = config;
++
++      return 0;
+ }
+ static void vkms_destroy(struct vkms_config *config)
+@@ -278,9 +280,10 @@ static void vkms_destroy(struct vkms_config *config)
+ static void __exit vkms_exit(void)
+ {
+-      if (default_config->dev)
+-              vkms_destroy(default_config);
++      if (!default_config)
++              return;
++      vkms_destroy(default_config);
+       kfree(default_config);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-xlnx-zynqmp-fix-max-dma-segment-size.patch b/queue-6.14/drm-xlnx-zynqmp-fix-max-dma-segment-size.patch
new file mode 100644 (file)
index 0000000..881ddeb
--- /dev/null
@@ -0,0 +1,38 @@
+From 8482eb38ab63d51e860846931c58449893894801 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jan 2025 11:03:39 +0200
+Subject: drm: xlnx: zynqmp: Fix max dma segment size
+
+From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+
+[ Upstream commit 28b529a98525123acd37372a04d21e87ec2edcf7 ]
+
+Fix "mapping sg segment longer than device claims to support" warning by
+setting the max segment size.
+
+Fixes: d76271d22694 ("drm: xlnx: DRM/KMS driver for Xilinx ZynqMP DisplayPort Subsystem")
+Reviewed-by: Sean Anderson <sean.anderson@linux.dev>
+Tested-by: Sean Anderson <sean.anderson@linux.dev>
+Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250115-xilinx-formats-v2-10-160327ca652a@ideasonboard.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xlnx/zynqmp_dpsub.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/xlnx/zynqmp_dpsub.c b/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
+index f953ca48a9303..3a9544b97bc53 100644
+--- a/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
++++ b/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
+@@ -201,6 +201,8 @@ static int zynqmp_dpsub_probe(struct platform_device *pdev)
+       if (ret)
+               return ret;
++      dma_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
++
+       /* Try the reserved memory. Proceed if there's none. */
+       of_reserved_mem_device_init(&pdev->dev);
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-xlnx-zynqmp_dpsub-add-null-check-in-zynqmp_audio.patch b/queue-6.14/drm-xlnx-zynqmp_dpsub-add-null-check-in-zynqmp_audio.patch
new file mode 100644 (file)
index 0000000..d8c6b6d
--- /dev/null
@@ -0,0 +1,49 @@
+From 9f32e3d51a824f91a3e0ebec46edd876db7e77d1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Feb 2025 18:20:49 +0800
+Subject: drm: xlnx: zynqmp_dpsub: Add NULL check in zynqmp_audio_init
+
+From: Charles Han <hanchunchao@inspur.com>
+
+[ Upstream commit d0660f9c588a1246a1a543c91a1e3cad910237da ]
+
+devm_kasprintf() calls can return null pointers on failure.
+But some return values were not checked in zynqmp_audio_init().
+
+Add NULL check in zynqmp_audio_init(), avoid referencing null
+pointers in the subsequent code.
+
+Fixes: 3ec5c1579305 ("drm: xlnx: zynqmp_dpsub: Add DP audio support")
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Charles Han <hanchunchao@inspur.com>
+Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250211102049.6468-1-hanchunchao@inspur.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xlnx/zynqmp_dp_audio.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp_audio.c b/drivers/gpu/drm/xlnx/zynqmp_dp_audio.c
+index fa5f0ace60842..f07ff4eb3a6de 100644
+--- a/drivers/gpu/drm/xlnx/zynqmp_dp_audio.c
++++ b/drivers/gpu/drm/xlnx/zynqmp_dp_audio.c
+@@ -323,12 +323,16 @@ int zynqmp_audio_init(struct zynqmp_dpsub *dpsub)
+       audio->dai_name = devm_kasprintf(dev, GFP_KERNEL,
+                                        "%s-dai", dev_name(dev));
++      if (!audio->dai_name)
++              return -ENOMEM;
+       for (unsigned int i = 0; i < ZYNQMP_NUM_PCMS; ++i) {
+               audio->link_names[i] = devm_kasprintf(dev, GFP_KERNEL,
+                                                     "%s-dp-%u", dev_name(dev), i);
+               audio->pcm_names[i] = devm_kasprintf(dev, GFP_KERNEL,
+                                                    "%s-pcm-%u", dev_name(dev), i);
++              if (!audio->link_names[i] || !audio->pcm_names[i])
++                      return -ENOMEM;
+       }
+       audio->base = devm_platform_ioremap_resource_byname(pdev, "aud");
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-zynqmp_dp-fix-a-deadlock-in-zynqmp_dp_ignore_hpd.patch b/queue-6.14/drm-zynqmp_dp-fix-a-deadlock-in-zynqmp_dp_ignore_hpd.patch
new file mode 100644 (file)
index 0000000..db5a6e6
--- /dev/null
@@ -0,0 +1,44 @@
+From ac72133823056b4005378dab4e9e40fc7e7383b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Feb 2025 11:25:27 -0500
+Subject: drm: zynqmp_dp: Fix a deadlock in zynqmp_dp_ignore_hpd_set()
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit f887685ee0eb4ef716391355568181230338f6eb ]
+
+Instead of attempting the same mutex twice, lock and unlock it.
+
+This bug has been detected by the Clang thread-safety analyzer.
+
+Cc: Sean Anderson <sean.anderson@linux.dev>
+Cc: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+Fixes: 28edaacb821c ("drm: zynqmp_dp: Add debugfs interface for compliance testing")
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Reviewed-by: Sean Anderson <sean.anderson@linux.dev>
+Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Reviewed-by: Sean Anderson <sean.anderson@seco.com>
+Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250207162528.1651426-2-sean.anderson@linux.dev
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xlnx/zynqmp_dp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c
+index 979f6d3239ba6..189a08cdc73c0 100644
+--- a/drivers/gpu/drm/xlnx/zynqmp_dp.c
++++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c
+@@ -2295,7 +2295,7 @@ static int zynqmp_dp_ignore_hpd_set(void *data, u64 val)
+       mutex_lock(&dp->lock);
+       dp->ignore_hpd = val;
+-      mutex_lock(&dp->lock);
++      mutex_unlock(&dp->lock);
+       return 0;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/dt-bindings-vendor-prefixes-add-gocontroll.patch b/queue-6.14/dt-bindings-vendor-prefixes-add-gocontroll.patch
new file mode 100644 (file)
index 0000000..983dea8
--- /dev/null
@@ -0,0 +1,37 @@
+From e467127c10ac2bca122cab771a03b55efd1fb1c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Feb 2025 15:19:13 +0100
+Subject: dt-bindings: vendor-prefixes: add GOcontroll
+
+From: Maud Spierings <maudspierings@gocontroll.com>
+
+[ Upstream commit 5f0d2de417166698c8eba433b696037ce04730da ]
+
+GOcontroll produces embedded linux systems and IO modules to use in
+these systems, add its prefix.
+
+Acked-by: Rob Herring (Arm) <robh@kernel.org>
+Signed-off-by: Maud Spierings <maudspierings@gocontroll.com>
+Link: https://patch.msgid.link/20250226-initial_display-v2-2-23fafa130817@gocontroll.com
+Signed-off-by: Mark Brown <broonie@kernel.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 5079ca6ce1d1e..b5979832ddce6 100644
+--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
++++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
+@@ -593,6 +593,8 @@ patternProperties:
+     description: GlobalTop Technology, Inc.
+   "^gmt,.*":
+     description: Global Mixed-mode Technology, Inc.
++  "^gocontroll,.*":
++    description: GOcontroll Modular Embedded Electronics B.V.
+   "^goldelico,.*":
+     description: Golden Delicious Computers GmbH & Co. KG
+   "^goodix,.*":
+-- 
+2.39.5
+
diff --git a/queue-6.14/dummycon-fix-default-rows-cols.patch b/queue-6.14/dummycon-fix-default-rows-cols.patch
new file mode 100644 (file)
index 0000000..36d58ca
--- /dev/null
@@ -0,0 +1,60 @@
+From a937db248eae72989f61ee2e5077cc22dac3045c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Feb 2025 17:44:22 +0100
+Subject: dummycon: fix default rows/cols
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit beefaba1978c04ea2950d34236f58fe6cf6a7f58 ]
+
+dummycon fails to build on ARM/footbridge when the VGA console is
+disabled, since I got the dependencies slightly wrong in a previous
+patch:
+
+drivers/video/console/dummycon.c: In function 'dummycon_init':
+drivers/video/console/dummycon.c:27:25: error: 'CONFIG_DUMMY_CONSOLE_COLUMNS' undeclared (first use in this function); did you mean 'CONFIG_DUMMY_CONSOLE'?
+   27 | #define DUMMY_COLUMNS   CONFIG_DUMMY_CONSOLE_COLUMNS
+drivers/video/console/dummycon.c:28:25: error: 'CONFIG_DUMMY_CONSOLE_ROWS' undeclared (first use in this function); did you mean 'CONFIG_DUMMY_CONSOLE'?
+   28 | #define DUMMY_ROWS      CONFIG_DUMMY_CONSOLE_ROWS
+
+This only showed up after many thousand randconfig builds on Arm, and
+doesn't matter in practice, but should still be fixed. Address it by
+using the default row/columns on footbridge after all in that corner
+case.
+
+Fixes: 4293b0925149 ("dummycon: limit Arm console size hack to footbridge")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202409151512.LML1slol-lkp@intel.com/
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/console/Kconfig | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
+index bc31db6ef7d26..c4a8f74df2493 100644
+--- a/drivers/video/console/Kconfig
++++ b/drivers/video/console/Kconfig
+@@ -52,7 +52,7 @@ config DUMMY_CONSOLE
+ config DUMMY_CONSOLE_COLUMNS
+       int "Initial number of console screen columns"
+-      depends on DUMMY_CONSOLE && !ARCH_FOOTBRIDGE
++      depends on DUMMY_CONSOLE && !(ARCH_FOOTBRIDGE && VGA_CONSOLE)
+       default 160 if PARISC
+       default 80
+       help
+@@ -62,7 +62,7 @@ config DUMMY_CONSOLE_COLUMNS
+ config DUMMY_CONSOLE_ROWS
+       int "Initial number of console screen rows"
+-      depends on DUMMY_CONSOLE && !ARCH_FOOTBRIDGE
++      depends on DUMMY_CONSOLE && !(ARCH_FOOTBRIDGE && VGA_CONSOLE)
+       default 64 if PARISC
+       default 30 if ARM
+       default 25
+-- 
+2.39.5
+
diff --git a/queue-6.14/e1000e-change-k1-configuration-on-mtp-and-later-plat.patch b/queue-6.14/e1000e-change-k1-configuration-on-mtp-and-later-plat.patch
new file mode 100644 (file)
index 0000000..f64d39f
--- /dev/null
@@ -0,0 +1,178 @@
+From aa602b1b17efbc6f0eee9b2cb13f6f930bd6b52b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Mar 2025 16:05:56 +0200
+Subject: e1000e: change k1 configuration on MTP and later platforms
+
+From: Vitaly Lifshits <vitaly.lifshits@intel.com>
+
+[ Upstream commit efaaf344bc2917cbfa5997633bc18a05d3aed27f ]
+
+Starting from Meteor Lake, the Kumeran interface between the integrated
+MAC and the I219 PHY works at a different frequency. This causes sporadic
+MDI errors when accessing the PHY, and in rare circumstances could lead
+to packet corruption.
+
+To overcome this, introduce minor changes to the Kumeran idle
+state (K1) parameters during device initialization. Hardware reset
+reverts this configuration, therefore it needs to be applied in a few
+places.
+
+Fixes: cc23f4f0b6b9 ("e1000e: Add support for Meteor Lake")
+Signed-off-by: Vitaly Lifshits <vitaly.lifshits@intel.com>
+Tested-by: Avigail Dahan <avigailx.dahan@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/e1000e/defines.h |  3 +
+ drivers/net/ethernet/intel/e1000e/ich8lan.c | 80 +++++++++++++++++++--
+ drivers/net/ethernet/intel/e1000e/ich8lan.h |  4 ++
+ 3 files changed, 82 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/e1000e/defines.h b/drivers/net/ethernet/intel/e1000e/defines.h
+index 5e2cfa73f8891..8294a7c4f122c 100644
+--- a/drivers/net/ethernet/intel/e1000e/defines.h
++++ b/drivers/net/ethernet/intel/e1000e/defines.h
+@@ -803,4 +803,7 @@
+ /* SerDes Control */
+ #define E1000_GEN_POLL_TIMEOUT          640
++#define E1000_FEXTNVM12_PHYPD_CTRL_MASK       0x00C00000
++#define E1000_FEXTNVM12_PHYPD_CTRL_P1 0x00800000
++
+ #endif /* _E1000_DEFINES_H_ */
+diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c
+index 2f9655cf5dd9e..364378133526a 100644
+--- a/drivers/net/ethernet/intel/e1000e/ich8lan.c
++++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c
+@@ -285,6 +285,45 @@ static void e1000_toggle_lanphypc_pch_lpt(struct e1000_hw *hw)
+       }
+ }
++/**
++ * e1000_reconfigure_k1_exit_timeout - reconfigure K1 exit timeout to
++ * align to MTP and later platform requirements.
++ * @hw: pointer to the HW structure
++ *
++ * Context: PHY semaphore must be held by caller.
++ * Return: 0 on success, negative on failure
++ */
++static s32 e1000_reconfigure_k1_exit_timeout(struct e1000_hw *hw)
++{
++      u16 phy_timeout;
++      u32 fextnvm12;
++      s32 ret_val;
++
++      if (hw->mac.type < e1000_pch_mtp)
++              return 0;
++
++      /* Change Kumeran K1 power down state from P0s to P1 */
++      fextnvm12 = er32(FEXTNVM12);
++      fextnvm12 &= ~E1000_FEXTNVM12_PHYPD_CTRL_MASK;
++      fextnvm12 |= E1000_FEXTNVM12_PHYPD_CTRL_P1;
++      ew32(FEXTNVM12, fextnvm12);
++
++      /* Wait for the interface the settle */
++      usleep_range(1000, 1100);
++
++      /* Change K1 exit timeout */
++      ret_val = e1e_rphy_locked(hw, I217_PHY_TIMEOUTS_REG,
++                                &phy_timeout);
++      if (ret_val)
++              return ret_val;
++
++      phy_timeout &= ~I217_PHY_TIMEOUTS_K1_EXIT_TO_MASK;
++      phy_timeout |= 0xF00;
++
++      return e1e_wphy_locked(hw, I217_PHY_TIMEOUTS_REG,
++                                phy_timeout);
++}
++
+ /**
+  *  e1000_init_phy_workarounds_pchlan - PHY initialization workarounds
+  *  @hw: pointer to the HW structure
+@@ -327,15 +366,22 @@ static s32 e1000_init_phy_workarounds_pchlan(struct e1000_hw *hw)
+        * LANPHYPC Value bit to force the interconnect to PCIe mode.
+        */
+       switch (hw->mac.type) {
++      case e1000_pch_mtp:
++      case e1000_pch_lnp:
++      case e1000_pch_ptp:
++      case e1000_pch_nvp:
++              /* At this point the PHY might be inaccessible so don't
++               * propagate the failure
++               */
++              if (e1000_reconfigure_k1_exit_timeout(hw))
++                      e_dbg("Failed to reconfigure K1 exit timeout\n");
++
++              fallthrough;
+       case e1000_pch_lpt:
+       case e1000_pch_spt:
+       case e1000_pch_cnp:
+       case e1000_pch_tgp:
+       case e1000_pch_adp:
+-      case e1000_pch_mtp:
+-      case e1000_pch_lnp:
+-      case e1000_pch_ptp:
+-      case e1000_pch_nvp:
+               if (e1000_phy_is_accessible_pchlan(hw))
+                       break;
+@@ -419,8 +465,20 @@ static s32 e1000_init_phy_workarounds_pchlan(struct e1000_hw *hw)
+                *  the PHY is in.
+                */
+               ret_val = hw->phy.ops.check_reset_block(hw);
+-              if (ret_val)
++              if (ret_val) {
+                       e_err("ME blocked access to PHY after reset\n");
++                      goto out;
++              }
++
++              if (hw->mac.type >= e1000_pch_mtp) {
++                      ret_val = hw->phy.ops.acquire(hw);
++                      if (ret_val) {
++                              e_err("Failed to reconfigure K1 exit timeout\n");
++                              goto out;
++                      }
++                      ret_val = e1000_reconfigure_k1_exit_timeout(hw);
++                      hw->phy.ops.release(hw);
++              }
+       }
+ out:
+@@ -4888,6 +4946,18 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw)
+       u16 i;
+       e1000_initialize_hw_bits_ich8lan(hw);
++      if (hw->mac.type >= e1000_pch_mtp) {
++              ret_val = hw->phy.ops.acquire(hw);
++              if (ret_val)
++                      return ret_val;
++
++              ret_val = e1000_reconfigure_k1_exit_timeout(hw);
++              hw->phy.ops.release(hw);
++              if (ret_val) {
++                      e_dbg("Error failed to reconfigure K1 exit timeout\n");
++                      return ret_val;
++              }
++      }
+       /* Initialize identification LED */
+       ret_val = mac->ops.id_led_init(hw);
+diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.h b/drivers/net/ethernet/intel/e1000e/ich8lan.h
+index 2504b11c3169f..5feb589a9b5ff 100644
+--- a/drivers/net/ethernet/intel/e1000e/ich8lan.h
++++ b/drivers/net/ethernet/intel/e1000e/ich8lan.h
+@@ -219,6 +219,10 @@
+ #define I217_PLL_CLOCK_GATE_REG       PHY_REG(772, 28)
+ #define I217_PLL_CLOCK_GATE_MASK      0x07FF
++/* PHY Timeouts */
++#define I217_PHY_TIMEOUTS_REG                   PHY_REG(770, 21)
++#define I217_PHY_TIMEOUTS_K1_EXIT_TO_MASK       0x0FC0
++
+ #define SW_FLAG_TIMEOUT               1000    /* SW Semaphore flag timeout in ms */
+ /* Inband Control */
+-- 
+2.39.5
+
diff --git a/queue-6.14/edac-ie31200-fix-the-dimm-size-mask-for-several-socs.patch b/queue-6.14/edac-ie31200-fix-the-dimm-size-mask-for-several-socs.patch
new file mode 100644 (file)
index 0000000..1c0b0cb
--- /dev/null
@@ -0,0 +1,46 @@
+From 05670eb4a34bb36f06bbf9096f97ba18954ae4c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Mar 2025 09:14:02 +0800
+Subject: EDAC/ie31200: Fix the DIMM size mask for several SoCs
+
+From: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+
+[ Upstream commit 3427befbbca6b19fe0e37f91d66ce5221de70bf1 ]
+
+The DIMM size mask for {Sky, Kaby, Coffee} Lake is not bits{7:0},
+but bits{5:0}. Fix it.
+
+Fixes: 953dee9bbd24 ("EDAC, ie31200_edac: Add Skylake support")
+Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+Signed-off-by: Tony Luck <tony.luck@intel.com>
+Tested-by: Gary Wang <gary.c.wang@intel.com>
+Link: https://lore.kernel.org/r/20250310011411.31685-3-qiuxu.zhuo@intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/edac/ie31200_edac.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/edac/ie31200_edac.c b/drivers/edac/ie31200_edac.c
+index c3d34d1fc9ad7..da4008c22f0d3 100644
+--- a/drivers/edac/ie31200_edac.c
++++ b/drivers/edac/ie31200_edac.c
+@@ -165,6 +165,7 @@
+ #define IE31200_MAD_DIMM_0_OFFSET             0x5004
+ #define IE31200_MAD_DIMM_0_OFFSET_SKL         0x500C
+ #define IE31200_MAD_DIMM_SIZE                 GENMASK_ULL(7, 0)
++#define IE31200_MAD_DIMM_SIZE_SKL             GENMASK_ULL(5, 0)
+ #define IE31200_MAD_DIMM_A_RANK                       BIT(17)
+ #define IE31200_MAD_DIMM_A_RANK_SHIFT         17
+ #define IE31200_MAD_DIMM_A_RANK_SKL           BIT(10)
+@@ -378,7 +379,7 @@ static void __iomem *ie31200_map_mchbar(struct pci_dev *pdev)
+ static void __skl_populate_dimm_info(struct dimm_data *dd, u32 addr_decode,
+                                    int chan)
+ {
+-      dd->size = (addr_decode >> (chan << 4)) & IE31200_MAD_DIMM_SIZE;
++      dd->size = (addr_decode >> (chan << 4)) & IE31200_MAD_DIMM_SIZE_SKL;
+       dd->dual_rank = (addr_decode & (IE31200_MAD_DIMM_A_RANK_SKL << (chan << 4))) ? 1 : 0;
+       dd->x16_width = ((addr_decode & (IE31200_MAD_DIMM_A_WIDTH_SKL << (chan << 4))) >>
+                               (IE31200_MAD_DIMM_A_WIDTH_SKL_SHIFT + (chan << 4)));
+-- 
+2.39.5
+
diff --git a/queue-6.14/edac-ie31200-fix-the-error-path-order-of-ie31200_ini.patch b/queue-6.14/edac-ie31200-fix-the-error-path-order-of-ie31200_ini.patch
new file mode 100644 (file)
index 0000000..137ad65
--- /dev/null
@@ -0,0 +1,68 @@
+From 57835521fcf564c1bf227f439a7437fcd3e38fb3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Mar 2025 09:14:03 +0800
+Subject: EDAC/ie31200: Fix the error path order of ie31200_init()
+
+From: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+
+[ Upstream commit 231e341036d9988447e3b3345cf741a98139199e ]
+
+The error path order of ie31200_init() is incorrect, fix it.
+
+Fixes: 709ed1bcef12 ("EDAC/ie31200: Fallback if host bridge device is already initialized")
+Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+Signed-off-by: Tony Luck <tony.luck@intel.com>
+Tested-by: Gary Wang <gary.c.wang@intel.com>
+Link: https://lore.kernel.org/r/20250310011411.31685-4-qiuxu.zhuo@intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/edac/ie31200_edac.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/edac/ie31200_edac.c b/drivers/edac/ie31200_edac.c
+index da4008c22f0d3..9b02a6b43ab58 100644
+--- a/drivers/edac/ie31200_edac.c
++++ b/drivers/edac/ie31200_edac.c
+@@ -621,7 +621,7 @@ static int __init ie31200_init(void)
+       pci_rc = pci_register_driver(&ie31200_driver);
+       if (pci_rc < 0)
+-              goto fail0;
++              return pci_rc;
+       if (!mci_pdev) {
+               ie31200_registered = 0;
+@@ -632,11 +632,13 @@ static int __init ie31200_init(void)
+                       if (mci_pdev)
+                               break;
+               }
++
+               if (!mci_pdev) {
+                       edac_dbg(0, "ie31200 pci_get_device fail\n");
+                       pci_rc = -ENODEV;
+-                      goto fail1;
++                      goto fail0;
+               }
++
+               pci_rc = ie31200_init_one(mci_pdev, &ie31200_pci_tbl[i]);
+               if (pci_rc < 0) {
+                       edac_dbg(0, "ie31200 init fail\n");
+@@ -644,12 +646,12 @@ static int __init ie31200_init(void)
+                       goto fail1;
+               }
+       }
+-      return 0;
++      return 0;
+ fail1:
+-      pci_unregister_driver(&ie31200_driver);
+-fail0:
+       pci_dev_put(mci_pdev);
++fail0:
++      pci_unregister_driver(&ie31200_driver);
+       return pci_rc;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/edac-ie31200-fix-the-size-of-edac_mc_layer_chip_sele.patch b/queue-6.14/edac-ie31200-fix-the-size-of-edac_mc_layer_chip_sele.patch
new file mode 100644 (file)
index 0000000..456a12d
--- /dev/null
@@ -0,0 +1,48 @@
+From 06c0d94f87bb78338e7764d90cb7c4822bf101d6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Mar 2025 09:14:01 +0800
+Subject: EDAC/ie31200: Fix the size of EDAC_MC_LAYER_CHIP_SELECT layer
+
+From: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+
+[ Upstream commit d59d844e319d97682c8de29b88d2d60922a683b3 ]
+
+The EDAC_MC_LAYER_CHIP_SELECT layer pertains to the rank, not the DIMM.
+Fix its size to reflect the number of ranks instead of the number of DIMMs.
+Also delete the unused macros IE31200_{DIMMS,RANKS}.
+
+Fixes: 7ee40b897d18 ("ie31200_edac: Introduce the driver")
+Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+Signed-off-by: Tony Luck <tony.luck@intel.com>
+Tested-by: Gary Wang <gary.c.wang@intel.com>
+Link: https://lore.kernel.org/r/20250310011411.31685-2-qiuxu.zhuo@intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/edac/ie31200_edac.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/edac/ie31200_edac.c b/drivers/edac/ie31200_edac.c
+index 4fc16922dc1af..c3d34d1fc9ad7 100644
+--- a/drivers/edac/ie31200_edac.c
++++ b/drivers/edac/ie31200_edac.c
+@@ -94,8 +94,6 @@
+        (((did) & PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_MASK) ==                 \
+         PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_MASK))
+-#define IE31200_DIMMS                 4
+-#define IE31200_RANKS                 8
+ #define IE31200_RANKS_PER_CHANNEL     4
+ #define IE31200_DIMMS_PER_CHANNEL     2
+ #define IE31200_CHANNELS              2
+@@ -429,7 +427,7 @@ static int ie31200_probe1(struct pci_dev *pdev, int dev_idx)
+       nr_channels = how_many_channels(pdev);
+       layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
+-      layers[0].size = IE31200_DIMMS;
++      layers[0].size = IE31200_RANKS_PER_CHANNEL;
+       layers[0].is_virt_csrow = true;
+       layers[1].type = EDAC_MC_LAYER_CHANNEL;
+       layers[1].size = nr_channels;
+-- 
+2.39.5
+
diff --git a/queue-6.14/edac-igen6-fix-the-flood-of-invalid-error-reports.patch b/queue-6.14/edac-igen6-fix-the-flood-of-invalid-error-reports.patch
new file mode 100644 (file)
index 0000000..f694215
--- /dev/null
@@ -0,0 +1,66 @@
+From 9bbbb61d1175a7e2b9d45a3daa12a789c970b470 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Feb 2025 16:33:54 +0800
+Subject: EDAC/igen6: Fix the flood of invalid error reports
+
+From: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+
+[ Upstream commit 267e5b1d267539d9a927dc04aab6f15aca57da92 ]
+
+The ECC_ERROR_LOG register of certain SoCs may contain the invalid value
+~0, which results in a flood of invalid error reports in polling mode.
+
+Fix the flood of invalid error reports by skipping the invalid ECC error
+log value ~0.
+
+Fixes: e14232afa944 ("EDAC/igen6: Add polling support")
+Reported-by: Ramses <ramses@well-founded.dev>
+Closes: https://lore.kernel.org/all/OISL8Rv--F-9@well-founded.dev/
+Tested-by: Ramses <ramses@well-founded.dev>
+Reported-by: John <therealgraysky@proton.me>
+Closes: https://lore.kernel.org/all/p5YcxOE6M3Ncxpn2-Ia_wCt61EM4LwIiN3LroQvT_-G2jMrFDSOW5k2A9D8UUzD2toGpQBN1eI0sL5dSKnkO8iteZegLoQEj-DwQaMhGx4A=@proton.me/
+Tested-by: John <therealgraysky@proton.me>
+Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+Signed-off-by: Tony Luck <tony.luck@intel.com>
+Link: https://lore.kernel.org/r/20250212083354.31919-1-qiuxu.zhuo@intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/edac/igen6_edac.c | 21 +++++++++++++++------
+ 1 file changed, 15 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/edac/igen6_edac.c b/drivers/edac/igen6_edac.c
+index fdf3a84fe6988..595908af9e5c9 100644
+--- a/drivers/edac/igen6_edac.c
++++ b/drivers/edac/igen6_edac.c
+@@ -785,13 +785,22 @@ static u64 ecclog_read_and_clear(struct igen6_imc *imc)
+ {
+       u64 ecclog = readq(imc->window + ECC_ERROR_LOG_OFFSET);
+-      if (ecclog & (ECC_ERROR_LOG_CE | ECC_ERROR_LOG_UE)) {
+-              /* Clear CE/UE bits by writing 1s */
+-              writeq(ecclog, imc->window + ECC_ERROR_LOG_OFFSET);
+-              return ecclog;
+-      }
++      /*
++       * Quirk: The ECC_ERROR_LOG register of certain SoCs may contain
++       *        the invalid value ~0. This will result in a flood of invalid
++       *        error reports in polling mode. Skip it.
++       */
++      if (ecclog == ~0)
++              return 0;
+-      return 0;
++      /* Neither a CE nor a UE. Skip it.*/
++      if (!(ecclog & (ECC_ERROR_LOG_CE | ECC_ERROR_LOG_UE)))
++              return 0;
++
++      /* Clear CE/UE bits by writing 1s */
++      writeq(ecclog, imc->window + ECC_ERROR_LOG_OFFSET);
++
++      return ecclog;
+ }
+ static void errsts_clear(struct igen6_imc *imc)
+-- 
+2.39.5
+
diff --git a/queue-6.14/edac-skx_common-i10nm-fix-some-missing-error-reports.patch b/queue-6.14/edac-skx_common-i10nm-fix-some-missing-error-reports.patch
new file mode 100644 (file)
index 0000000..3de6c66
--- /dev/null
@@ -0,0 +1,144 @@
+From 62f3738a2c97d884889f72081308e267b74fcc23 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Feb 2025 08:27:28 +0800
+Subject: EDAC/{skx_common,i10nm}: Fix some missing error reports on Emerald
+ Rapids
+
+From: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+
+[ Upstream commit d9207cf7760f5f5599e9ff7eb0fedf56821a1d59 ]
+
+When doing error injection to some memory DIMMs on certain Intel Emerald
+Rapids servers, the i10nm_edac missed error reports for some memory DIMMs.
+
+Certain BIOS configurations may hide some memory controllers, and the
+i10nm_edac doesn't enumerate these hidden memory controllers. However, the
+ADXL decodes memory errors using memory controller physical indices even
+if there are hidden memory controllers. Therefore, the memory controller
+physical indices reported by the ADXL may mismatch the logical indices
+enumerated by the i10nm_edac, resulting in missed error reports for some
+memory DIMMs.
+
+Fix this issue by creating a mapping table from memory controller physical
+indices (used by the ADXL) to logical indices (used by the i10nm_edac) and
+using it to convert the physical indices to the logical indices during the
+error handling process.
+
+Fixes: c545f5e41225 ("EDAC/i10nm: Skip the absent memory controllers")
+Reported-by: Kevin Chang <kevin1.chang@intel.com>
+Tested-by: Kevin Chang <kevin1.chang@intel.com>
+Reported-by: Thomas Chen <Thomas.Chen@intel.com>
+Tested-by: Thomas Chen <Thomas.Chen@intel.com>
+Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+Signed-off-by: Tony Luck <tony.luck@intel.com>
+Link: https://lore.kernel.org/r/20250214002728.6287-1-qiuxu.zhuo@intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/edac/i10nm_base.c |  2 ++
+ drivers/edac/skx_common.c | 33 +++++++++++++++++++++++++++++++++
+ drivers/edac/skx_common.h | 11 +++++++++++
+ 3 files changed, 46 insertions(+)
+
+diff --git a/drivers/edac/i10nm_base.c b/drivers/edac/i10nm_base.c
+index f45d849d3f150..355a977019e94 100644
+--- a/drivers/edac/i10nm_base.c
++++ b/drivers/edac/i10nm_base.c
+@@ -751,6 +751,8 @@ static int i10nm_get_ddr_munits(void)
+                               continue;
+                       } else {
+                               d->imc[lmc].mdev = mdev;
++                              if (res_cfg->type == SPR)
++                                      skx_set_mc_mapping(d, i, lmc);
+                               lmc++;
+                       }
+               }
+diff --git a/drivers/edac/skx_common.c b/drivers/edac/skx_common.c
+index f7bd930e058fe..fa5b442b18449 100644
+--- a/drivers/edac/skx_common.c
++++ b/drivers/edac/skx_common.c
+@@ -121,6 +121,35 @@ void skx_adxl_put(void)
+ }
+ EXPORT_SYMBOL_GPL(skx_adxl_put);
++static void skx_init_mc_mapping(struct skx_dev *d)
++{
++      /*
++       * By default, the BIOS presents all memory controllers within each
++       * socket to the EDAC driver. The physical indices are the same as
++       * the logical indices of the memory controllers enumerated by the
++       * EDAC driver.
++       */
++      for (int i = 0; i < NUM_IMC; i++)
++              d->mc_mapping[i] = i;
++}
++
++void skx_set_mc_mapping(struct skx_dev *d, u8 pmc, u8 lmc)
++{
++      edac_dbg(0, "Set the mapping of mc phy idx to logical idx: %02d -> %02d\n",
++               pmc, lmc);
++
++      d->mc_mapping[pmc] = lmc;
++}
++EXPORT_SYMBOL_GPL(skx_set_mc_mapping);
++
++static u8 skx_get_mc_mapping(struct skx_dev *d, u8 pmc)
++{
++      edac_dbg(0, "Get the mapping of mc phy idx to logical idx: %02d -> %02d\n",
++               pmc, d->mc_mapping[pmc]);
++
++      return d->mc_mapping[pmc];
++}
++
+ static bool skx_adxl_decode(struct decoded_addr *res, enum error_source err_src)
+ {
+       struct skx_dev *d;
+@@ -188,6 +217,8 @@ static bool skx_adxl_decode(struct decoded_addr *res, enum error_source err_src)
+               return false;
+       }
++      res->imc = skx_get_mc_mapping(d, res->imc);
++
+       for (i = 0; i < adxl_component_count; i++) {
+               if (adxl_values[i] == ~0x0ull)
+                       continue;
+@@ -326,6 +357,8 @@ int skx_get_all_bus_mappings(struct res_config *cfg, struct list_head **list)
+                        d->bus[0], d->bus[1], d->bus[2], d->bus[3]);
+               list_add_tail(&d->list, &dev_edac_list);
+               prev = pdev;
++
++              skx_init_mc_mapping(d);
+       }
+       if (list)
+diff --git a/drivers/edac/skx_common.h b/drivers/edac/skx_common.h
+index b0845bdd45164..ca5408803f878 100644
+--- a/drivers/edac/skx_common.h
++++ b/drivers/edac/skx_common.h
+@@ -93,6 +93,16 @@ struct skx_dev {
+       struct pci_dev *uracu; /* for i10nm CPU */
+       struct pci_dev *pcu_cr3; /* for HBM memory detection */
+       u32 mcroute;
++      /*
++       * Some server BIOS may hide certain memory controllers, and the
++       * EDAC driver skips those hidden memory controllers. However, the
++       * ADXL still decodes memory error address using physical memory
++       * controller indices. The mapping table is used to convert the
++       * physical indices (reported by ADXL) to the logical indices
++       * (used the EDAC driver) of present memory controllers during the
++       * error handling process.
++       */
++      u8 mc_mapping[NUM_IMC];
+       struct skx_imc {
+               struct mem_ctl_info *mci;
+               struct pci_dev *mdev; /* for i10nm CPU */
+@@ -242,6 +252,7 @@ void skx_adxl_put(void);
+ void skx_set_decode(skx_decode_f decode, skx_show_retry_log_f show_retry_log);
+ void skx_set_mem_cfg(bool mem_cfg_2lm);
+ void skx_set_res_cfg(struct res_config *cfg);
++void skx_set_mc_mapping(struct skx_dev *d, u8 pmc, u8 lmc);
+ int skx_get_src_id(struct skx_dev *d, int off, u8 *id);
+-- 
+2.39.5
+
diff --git a/queue-6.14/erofs-allow-16-byte-volume-name-again.patch b/queue-6.14/erofs-allow-16-byte-volume-name-again.patch
new file mode 100644 (file)
index 0000000..4871a2b
--- /dev/null
@@ -0,0 +1,66 @@
+From 1854d6cef80d34dc423d3f23ddd30aaf8b6dc61a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Feb 2025 11:39:34 +0800
+Subject: erofs: allow 16-byte volume name again
+
+From: Gao Xiang <hsiangkao@linux.alibaba.com>
+
+[ Upstream commit 579450277780159b8ba94a08b2f1d1da2002aec5 ]
+
+Actually, volume name doesn't need to include the NIL terminator if
+the string length matches the on-disk field size as mentioned in [1].
+
+I tend to relax it together with the upcoming 48-bit block addressing
+(or stable kernels which backport this fix) so that we could have a
+chance to record a 16-byte volume name like ext4.
+
+Since in-memory `volume_name` has no user, just get rid of the unneeded
+check for now.  `sbi->uuid` is useless and avoid it too.
+
+[1] https://lore.kernel.org/r/96efe46b-dcce-4490-bba1-a0b00932d1cc@linux.alibaba.com
+
+Fixes: a64d9493f587 ("staging: erofs: refuse to mount images with malformed volume name")
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+Link: https://lore.kernel.org/r/20250225033934.2542635-1-hsiangkao@linux.alibaba.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/erofs/internal.h | 2 --
+ fs/erofs/super.c    | 8 --------
+ 2 files changed, 10 deletions(-)
+
+diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h
+index 686d835eb533a..efd25f3101f1f 100644
+--- a/fs/erofs/internal.h
++++ b/fs/erofs/internal.h
+@@ -152,8 +152,6 @@ struct erofs_sb_info {
+       /* used for statfs, f_files - f_favail */
+       u64 inos;
+-      u8 uuid[16];                    /* 128-bit uuid for volume */
+-      u8 volume_name[16];             /* volume name */
+       u32 feature_compat;
+       u32 feature_incompat;
+diff --git a/fs/erofs/super.c b/fs/erofs/super.c
+index 827b626656494..9f2bce5af9c83 100644
+--- a/fs/erofs/super.c
++++ b/fs/erofs/super.c
+@@ -317,14 +317,6 @@ static int erofs_read_superblock(struct super_block *sb)
+       super_set_uuid(sb, (void *)dsb->uuid, sizeof(dsb->uuid));
+-      ret = strscpy(sbi->volume_name, dsb->volume_name,
+-                    sizeof(dsb->volume_name));
+-      if (ret < 0) {  /* -E2BIG */
+-              erofs_err(sb, "bad volume name without NIL terminator");
+-              ret = -EFSCORRUPTED;
+-              goto out;
+-      }
+-
+       /* parse on-disk compression configurations */
+       ret = z_erofs_parse_cfgs(sb, dsb);
+       if (ret < 0)
+-- 
+2.39.5
+
diff --git a/queue-6.14/eth-bnxt-fix-out-of-range-access-of-vnic_info-array.patch b/queue-6.14/eth-bnxt-fix-out-of-range-access-of-vnic_info-array.patch
new file mode 100644 (file)
index 0000000..a1d3630
--- /dev/null
@@ -0,0 +1,48 @@
+From bcc58d7daad601f746a701413619a6e379613587 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 16 Mar 2025 02:58:37 +0000
+Subject: eth: bnxt: fix out-of-range access of vnic_info array
+
+From: Taehee Yoo <ap420073@gmail.com>
+
+[ Upstream commit 919f9f497dbcee75d487400e8f9815b74a6a37df ]
+
+The bnxt_queue_{start | stop}() access vnic_info as much as allocated,
+which indicates bp->nr_vnics.
+So, it should not reach bp->vnic_info[bp->nr_vnics].
+
+Fixes: 661958552eda ("eth: bnxt: do not use BNXT_VNIC_NTUPLE unconditionally in queue restart logic")
+Signed-off-by: Taehee Yoo <ap420073@gmail.com>
+Reviewed-by: Michael Chan <michael.chan@broadcom.com>
+Link: https://patch.msgid.link/20250316025837.939527-1-ap420073@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/bnxt/bnxt.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index 55f553debd3b2..0ddc3d41e2d81 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -15651,7 +15651,7 @@ static int bnxt_queue_start(struct net_device *dev, void *qmem, int idx)
+       cpr = &rxr->bnapi->cp_ring;
+       cpr->sw_stats->rx.rx_resets++;
+-      for (i = 0; i <= bp->nr_vnics; i++) {
++      for (i = 0; i < bp->nr_vnics; i++) {
+               vnic = &bp->vnic_info[i];
+               rc = bnxt_hwrm_vnic_set_rss_p5(bp, vnic, true);
+@@ -15679,7 +15679,7 @@ static int bnxt_queue_stop(struct net_device *dev, void *qmem, int idx)
+       struct bnxt_vnic_info *vnic;
+       int i;
+-      for (i = 0; i <= bp->nr_vnics; i++) {
++      for (i = 0; i < bp->nr_vnics; i++) {
+               vnic = &bp->vnic_info[i];
+               vnic->mru = 0;
+               bnxt_hwrm_vnic_update(bp, vnic,
+-- 
+2.39.5
+
diff --git a/queue-6.14/exfat-fix-missing-shutdown-check.patch b/queue-6.14/exfat-fix-missing-shutdown-check.patch
new file mode 100644 (file)
index 0000000..b0574c2
--- /dev/null
@@ -0,0 +1,97 @@
+From 20b10cc11097c71a987ce322046b9ab1d89cc303 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Mar 2025 15:02:07 +0800
+Subject: exfat: fix missing shutdown check
+
+From: Yuezhang Mo <Yuezhang.Mo@sony.com>
+
+[ Upstream commit 47e35366bc6fa3cf189a8305bce63992495f3efa ]
+
+xfstests generic/730 test failed because after deleting the device
+that still had dirty data, the file could still be read without
+returning an error. The reason is the missing shutdown check in
+->read_iter.
+
+I also noticed that shutdown checks were missing from ->write_iter,
+->splice_read, and ->mmap. This commit adds shutdown checks to all
+of them.
+
+Fixes: f761fcdd289d ("exfat: Implement sops->shutdown and ioctl")
+Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/exfat/file.c | 29 +++++++++++++++++++++++++++--
+ 1 file changed, 27 insertions(+), 2 deletions(-)
+
+diff --git a/fs/exfat/file.c b/fs/exfat/file.c
+index 807349d8ea050..841a5b18e3dfd 100644
+--- a/fs/exfat/file.c
++++ b/fs/exfat/file.c
+@@ -582,6 +582,9 @@ static ssize_t exfat_file_write_iter(struct kiocb *iocb, struct iov_iter *iter)
+       loff_t pos = iocb->ki_pos;
+       loff_t valid_size;
++      if (unlikely(exfat_forced_shutdown(inode->i_sb)))
++              return -EIO;
++
+       inode_lock(inode);
+       valid_size = ei->valid_size;
+@@ -635,6 +638,16 @@ static ssize_t exfat_file_write_iter(struct kiocb *iocb, struct iov_iter *iter)
+       return ret;
+ }
++static ssize_t exfat_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
++{
++      struct inode *inode = file_inode(iocb->ki_filp);
++
++      if (unlikely(exfat_forced_shutdown(inode->i_sb)))
++              return -EIO;
++
++      return generic_file_read_iter(iocb, iter);
++}
++
+ static vm_fault_t exfat_page_mkwrite(struct vm_fault *vmf)
+ {
+       int err;
+@@ -672,14 +685,26 @@ static const struct vm_operations_struct exfat_file_vm_ops = {
+ static int exfat_file_mmap(struct file *file, struct vm_area_struct *vma)
+ {
++      if (unlikely(exfat_forced_shutdown(file_inode(file)->i_sb)))
++              return -EIO;
++
+       file_accessed(file);
+       vma->vm_ops = &exfat_file_vm_ops;
+       return 0;
+ }
++static ssize_t exfat_splice_read(struct file *in, loff_t *ppos,
++              struct pipe_inode_info *pipe, size_t len, unsigned int flags)
++{
++      if (unlikely(exfat_forced_shutdown(file_inode(in)->i_sb)))
++              return -EIO;
++
++      return filemap_splice_read(in, ppos, pipe, len, flags);
++}
++
+ const struct file_operations exfat_file_operations = {
+       .llseek         = generic_file_llseek,
+-      .read_iter      = generic_file_read_iter,
++      .read_iter      = exfat_file_read_iter,
+       .write_iter     = exfat_file_write_iter,
+       .unlocked_ioctl = exfat_ioctl,
+ #ifdef CONFIG_COMPAT
+@@ -687,7 +712,7 @@ const struct file_operations exfat_file_operations = {
+ #endif
+       .mmap           = exfat_file_mmap,
+       .fsync          = exfat_file_fsync,
+-      .splice_read    = filemap_splice_read,
++      .splice_read    = exfat_splice_read,
+       .splice_write   = iter_file_splice_write,
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.14/exfat-fix-the-infinite-loop-in-exfat_find_last_clust.patch b/queue-6.14/exfat-fix-the-infinite-loop-in-exfat_find_last_clust.patch
new file mode 100644 (file)
index 0000000..f4efd7f
--- /dev/null
@@ -0,0 +1,46 @@
+From 7c1f33aa393e713ec14db1520b837cdaa1a06e3d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Mar 2025 10:53:10 +0800
+Subject: exfat: fix the infinite loop in exfat_find_last_cluster()
+
+From: Yuezhang Mo <Yuezhang.Mo@sony.com>
+
+[ Upstream commit b0522303f67255926b946aa66885a0104d1b2980 ]
+
+In exfat_find_last_cluster(), the cluster chain is traversed until
+the EOF cluster. If the cluster chain includes a loop due to file
+system corruption, the EOF cluster cannot be traversed, resulting
+in an infinite loop.
+
+If the number of clusters indicated by the file size is inconsistent
+with the cluster chain length, exfat_find_last_cluster() will return
+an error, so if this inconsistency is found, the traversal can be
+aborted without traversing to the EOF cluster.
+
+Reported-by: syzbot+f7d147e6db52b1e09dba@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=f7d147e6db52b1e09dba
+Tested-by: syzbot+f7d147e6db52b1e09dba@syzkaller.appspotmail.com
+Fixes: 31023864e67a ("exfat: add fat entry operations")
+Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/exfat/fatent.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/exfat/fatent.c b/fs/exfat/fatent.c
+index 6f3651c6ca91e..8df5ad6ebb10c 100644
+--- a/fs/exfat/fatent.c
++++ b/fs/exfat/fatent.c
+@@ -265,7 +265,7 @@ int exfat_find_last_cluster(struct super_block *sb, struct exfat_chain *p_chain,
+               clu = next;
+               if (exfat_ent_get(sb, clu, &next))
+                       return -EIO;
+-      } while (next != EXFAT_EOF_CLUSTER);
++      } while (next != EXFAT_EOF_CLUSTER && count <= p_chain->size);
+       if (p_chain->size != count) {
+               exfat_fs_error(sb,
+-- 
+2.39.5
+
diff --git a/queue-6.14/ext4-add-ext4_flags_emergency_ro-bit.patch b/queue-6.14/ext4-add-ext4_flags_emergency_ro-bit.patch
new file mode 100644 (file)
index 0000000..10440df
--- /dev/null
@@ -0,0 +1,53 @@
+From 2040986d1a6849625362cc2174a4cfcdac1ed897 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jan 2025 19:41:25 +0800
+Subject: ext4: add EXT4_FLAGS_EMERGENCY_RO bit
+
+From: Baokun Li <libaokun1@huawei.com>
+
+[ Upstream commit f3054e53c2f367bd3cf6535afe9ab13198d2d739 ]
+
+EXT4_FLAGS_EMERGENCY_RO Indicates that the current file system has become
+read-only due to some error. Compared to SB_RDONLY, setting it does not
+require a lock because we won't clear it, which avoids over-coupling with
+vfs freeze. Also, add a helper function ext4_emergency_ro() to check if
+the bit is set.
+
+Signed-off-by: Baokun Li <libaokun1@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Zhang Yi <yi.zhang@huawei.com>
+Link: https://patch.msgid.link/20250122114130.229709-3-libaokun@huaweicloud.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Stable-dep-of: 8f984530c242 ("ext4: correct behavior under errors=remount-ro mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/ext4.h | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
+index b3528e4eba180..7f5fd1a433662 100644
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -2236,6 +2236,7 @@ enum {
+       EXT4_FLAGS_RESIZING,    /* Avoid superblock update and resize race */
+       EXT4_FLAGS_SHUTDOWN,    /* Prevent access to the file system */
+       EXT4_FLAGS_BDEV_IS_DAX, /* Current block device support DAX */
++      EXT4_FLAGS_EMERGENCY_RO,/* Emergency read-only due to fs errors */
+ };
+ static inline int ext4_forced_shutdown(struct super_block *sb)
+@@ -2243,6 +2244,11 @@ static inline int ext4_forced_shutdown(struct super_block *sb)
+       return test_bit(EXT4_FLAGS_SHUTDOWN, &EXT4_SB(sb)->s_ext4_flags);
+ }
++static inline int ext4_emergency_ro(struct super_block *sb)
++{
++      return test_bit(EXT4_FLAGS_EMERGENCY_RO, &EXT4_SB(sb)->s_ext4_flags);
++}
++
+ /*
+  * Default values for user and/or group using reserved blocks
+  */
+-- 
+2.39.5
+
diff --git a/queue-6.14/ext4-add-missing-brelse-for-bh2-in-ext4_dx_add_entry.patch b/queue-6.14/ext4-add-missing-brelse-for-bh2-in-ext4_dx_add_entry.patch
new file mode 100644 (file)
index 0000000..3aa2ed5
--- /dev/null
@@ -0,0 +1,77 @@
+From c00a37265b9447a15db9112fffc1e8c59688ef08 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jan 2025 00:20:48 +0800
+Subject: ext4: add missing brelse() for bh2 in ext4_dx_add_entry()
+
+From: Kemeng Shi <shikemeng@huaweicloud.com>
+
+[ Upstream commit eb640af64db6d4702a85ab001b9cc7f4c5dd6abb ]
+
+Add missing brelse() for bh2 in ext4_dx_add_entry().
+
+Fixes: ac27a0ec112a ("[PATCH] ext4: initial copy of files from ext3")
+Signed-off-by: Kemeng Shi <shikemeng@huaweicloud.com>
+Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
+Reviewed-by: Zhang Yi <yi.zhang@huawei.com>
+Link: https://patch.msgid.link/20250123162050.2114499-2-shikemeng@huaweicloud.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/namei.c | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
+index 536d56d150726..8e49cb7118581 100644
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -2577,8 +2577,10 @@ static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname,
+               BUFFER_TRACE(frame->bh, "get_write_access");
+               err = ext4_journal_get_write_access(handle, sb, frame->bh,
+                                                   EXT4_JTR_NONE);
+-              if (err)
++              if (err) {
++                      brelse(bh2);
+                       goto journal_error;
++              }
+               if (!add_level) {
+                       unsigned icount1 = icount/2, icount2 = icount - icount1;
+                       unsigned hash2 = dx_get_hash(entries + icount1);
+@@ -2589,8 +2591,10 @@ static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname,
+                       err = ext4_journal_get_write_access(handle, sb,
+                                                           (frame - 1)->bh,
+                                                           EXT4_JTR_NONE);
+-                      if (err)
++                      if (err) {
++                              brelse(bh2);
+                               goto journal_error;
++                      }
+                       memcpy((char *) entries2, (char *) (entries + icount1),
+                              icount2 * sizeof(struct dx_entry));
+@@ -2609,8 +2613,10 @@ static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname,
+                       dxtrace(dx_show_index("node",
+                              ((struct dx_node *) bh2->b_data)->entries));
+                       err = ext4_handle_dirty_dx_node(handle, dir, bh2);
+-                      if (err)
++                      if (err) {
++                              brelse(bh2);
+                               goto journal_error;
++                      }
+                       brelse (bh2);
+                       err = ext4_handle_dirty_dx_node(handle, dir,
+                                                  (frame - 1)->bh);
+@@ -2635,8 +2641,10 @@ static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname,
+                                      "Creating %d level index...\n",
+                                      dxroot->info.indirect_levels));
+                       err = ext4_handle_dirty_dx_node(handle, dir, frame->bh);
+-                      if (err)
++                      if (err) {
++                              brelse(bh2);
+                               goto journal_error;
++                      }
+                       err = ext4_handle_dirty_dx_node(handle, dir, bh2);
+                       brelse(bh2);
+                       restart = 1;
+-- 
+2.39.5
+
diff --git a/queue-6.14/ext4-avoid-journaling-sb-update-on-error-if-journal-.patch b/queue-6.14/ext4-avoid-journaling-sb-update-on-error-if-journal-.patch
new file mode 100644 (file)
index 0000000..1deeba6
--- /dev/null
@@ -0,0 +1,173 @@
+From 65d2d49dd037af531914ea3c67d8da391c06d09b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Mar 2025 13:22:56 +0530
+Subject: ext4: avoid journaling sb update on error if journal is destroying
+
+From: Ojaswin Mujoo <ojaswin@linux.ibm.com>
+
+[ Upstream commit ce2f26e73783b4a7c46a86e3af5b5c8de0971790 ]
+
+Presently we always BUG_ON if trying to start a transaction on a journal marked
+with JBD2_UNMOUNT, since this should never happen. However, while ltp running
+stress tests, it was observed that in case of some error handling paths, it is
+possible for update_super_work to start a transaction after the journal is
+destroyed eg:
+
+(umount)
+ext4_kill_sb
+  kill_block_super
+    generic_shutdown_super
+      sync_filesystem /* commits all txns */
+      evict_inodes
+        /* might start a new txn */
+      ext4_put_super
+       flush_work(&sbi->s_sb_upd_work) /* flush the workqueue */
+        jbd2_journal_destroy
+          journal_kill_thread
+            journal->j_flags |= JBD2_UNMOUNT;
+          jbd2_journal_commit_transaction
+            jbd2_journal_get_descriptor_buffer
+              jbd2_journal_bmap
+                ext4_journal_bmap
+                  ext4_map_blocks
+                    ...
+                    ext4_inode_error
+                      ext4_handle_error
+                        schedule_work(&sbi->s_sb_upd_work)
+
+                                               /* work queue kicks in */
+                                               update_super_work
+                                                 jbd2_journal_start
+                                                   start_this_handle
+                                                     BUG_ON(journal->j_flags &
+                                                            JBD2_UNMOUNT)
+
+Hence, introduce a new mount flag to indicate journal is destroying and only do
+a journaled (and deferred) update of sb if this flag is not set. Otherwise, just
+fallback to an un-journaled commit.
+
+Further, in the journal destroy path, we have the following sequence:
+
+  1. Set mount flag indicating journal is destroying
+  2. force a commit and wait for it
+  3. flush pending sb updates
+
+This sequence is important as it ensures that, after this point, there is no sb
+update that might be journaled so it is safe to update the sb outside the
+journal. (To avoid race discussed in 2d01ddc86606)
+
+Also, we don't need a similar check in ext4_grp_locked_error since it is only
+called from mballoc and AFAICT it would be always valid to schedule work here.
+
+Fixes: 2d01ddc86606 ("ext4: save error info to sb through journal if available")
+Reported-by: Mahesh Kumar <maheshkumar657g@gmail.com>
+Signed-off-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://patch.msgid.link/9613c465d6ff00cd315602f99283d5f24018c3f7.1742279837.git.ojaswin@linux.ibm.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/ext4.h      |  3 ++-
+ fs/ext4/ext4_jbd2.h | 15 +++++++++++++++
+ fs/ext4/super.c     | 16 ++++++++--------
+ 3 files changed, 25 insertions(+), 9 deletions(-)
+
+diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
+index 7f5fd1a433662..df30d9f235123 100644
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -1821,7 +1821,8 @@ static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino)
+  */
+ enum {
+       EXT4_MF_MNTDIR_SAMPLED,
+-      EXT4_MF_FC_INELIGIBLE   /* Fast commit ineligible */
++      EXT4_MF_FC_INELIGIBLE,  /* Fast commit ineligible */
++      EXT4_MF_JOURNAL_DESTROY /* Journal is in process of destroying */
+ };
+ static inline void ext4_set_mount_flag(struct super_block *sb, int bit)
+diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h
+index 930778e507cc4..ada46189b0860 100644
+--- a/fs/ext4/ext4_jbd2.h
++++ b/fs/ext4/ext4_jbd2.h
+@@ -521,6 +521,21 @@ static inline int ext4_journal_destroy(struct ext4_sb_info *sbi, journal_t *jour
+ {
+       int err = 0;
++      /*
++       * At this point only two things can be operating on the journal.
++       * JBD2 thread performing transaction commit and s_sb_upd_work
++       * issuing sb update through the journal. Once we set
++       * EXT4_JOURNAL_DESTROY, new ext4_handle_error() calls will not
++       * queue s_sb_upd_work and ext4_force_commit() makes sure any
++       * ext4_handle_error() calls from the running transaction commit are
++       * finished. Hence no new s_sb_upd_work can be queued after we
++       * flush it here.
++       */
++      ext4_set_mount_flag(sbi->s_sb, EXT4_MF_JOURNAL_DESTROY);
++
++      ext4_force_commit(sbi->s_sb);
++      flush_work(&sbi->s_sb_upd_work);
++
+       err = jbd2_journal_destroy(journal);
+       sbi->s_journal = NULL;
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index f658c017055f3..b666ef71a034a 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -716,9 +716,13 @@ static void ext4_handle_error(struct super_block *sb, bool force_ro, int error,
+                * In case the fs should keep running, we need to writeout
+                * superblock through the journal. Due to lock ordering
+                * constraints, it may not be safe to do it right here so we
+-               * defer superblock flushing to a workqueue.
++               * defer superblock flushing to a workqueue. We just need to be
++               * careful when the journal is already shutting down. If we get
++               * here in that case, just update the sb directly as the last
++               * transaction won't commit anyway.
+                */
+-              if (continue_fs && journal)
++              if (continue_fs && journal &&
++                  !ext4_test_mount_flag(sb, EXT4_MF_JOURNAL_DESTROY))
+                       schedule_work(&EXT4_SB(sb)->s_sb_upd_work);
+               else
+                       ext4_commit_super(sb);
+@@ -1303,7 +1307,6 @@ static void ext4_put_super(struct super_block *sb)
+       ext4_unregister_li_request(sb);
+       ext4_quotas_off(sb, EXT4_MAXQUOTAS);
+-      flush_work(&sbi->s_sb_upd_work);
+       destroy_workqueue(sbi->rsv_conversion_wq);
+       ext4_release_orphan_info(sb);
+@@ -1313,7 +1316,8 @@ static void ext4_put_super(struct super_block *sb)
+               if ((err < 0) && !aborted) {
+                       ext4_abort(sb, -err, "Couldn't clean up the journal");
+               }
+-      }
++      } else
++              flush_work(&sbi->s_sb_upd_work);
+       ext4_es_unregister_shrinker(sbi);
+       timer_shutdown_sync(&sbi->s_err_report);
+@@ -4972,8 +4976,6 @@ static int ext4_load_and_init_journal(struct super_block *sb,
+       return 0;
+ out:
+-      /* flush s_sb_upd_work before destroying the journal. */
+-      flush_work(&sbi->s_sb_upd_work);
+       ext4_journal_destroy(sbi, sbi->s_journal);
+       return -EINVAL;
+ }
+@@ -5663,8 +5665,6 @@ failed_mount8: __maybe_unused
+       sbi->s_ea_block_cache = NULL;
+       if (sbi->s_journal) {
+-              /* flush s_sb_upd_work before journal destroy. */
+-              flush_work(&sbi->s_sb_upd_work);
+               ext4_journal_destroy(sbi, sbi->s_journal);
+       }
+ failed_mount3a:
+-- 
+2.39.5
+
diff --git a/queue-6.14/ext4-convert-ext4_flags_-defines-to-enum.patch b/queue-6.14/ext4-convert-ext4_flags_-defines-to-enum.patch
new file mode 100644 (file)
index 0000000..65efd2b
--- /dev/null
@@ -0,0 +1,44 @@
+From cb59aebb8e91ab456be0622d78f2e2b09b136c63 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jan 2025 19:41:24 +0800
+Subject: ext4: convert EXT4_FLAGS_* defines to enum
+
+From: Baokun Li <libaokun1@huawei.com>
+
+[ Upstream commit 99708f8a9d30081a71638d6f4e216350a4340cc3 ]
+
+Do away with the defines and use an enum as it's cleaner.
+
+Signed-off-by: Baokun Li <libaokun1@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Zhang Yi <yi.zhang@huawei.com>
+Link: https://patch.msgid.link/20250122114130.229709-2-libaokun@huaweicloud.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Stable-dep-of: 8f984530c242 ("ext4: correct behavior under errors=remount-ro mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/ext4.h | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
+index 4e7de7eaa374a..b3528e4eba180 100644
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -2232,9 +2232,11 @@ extern int ext4_feature_set_ok(struct super_block *sb, int readonly);
+ /*
+  * Superblock flags
+  */
+-#define EXT4_FLAGS_RESIZING   0
+-#define EXT4_FLAGS_SHUTDOWN   1
+-#define EXT4_FLAGS_BDEV_IS_DAX        2
++enum {
++      EXT4_FLAGS_RESIZING,    /* Avoid superblock update and resize race */
++      EXT4_FLAGS_SHUTDOWN,    /* Prevent access to the file system */
++      EXT4_FLAGS_BDEV_IS_DAX, /* Current block device support DAX */
++};
+ static inline int ext4_forced_shutdown(struct super_block *sb)
+ {
+-- 
+2.39.5
+
diff --git a/queue-6.14/ext4-correct-behavior-under-errors-remount-ro-mode.patch b/queue-6.14/ext4-correct-behavior-under-errors-remount-ro-mode.patch
new file mode 100644 (file)
index 0000000..c5b1977
--- /dev/null
@@ -0,0 +1,76 @@
+From 815e5c1d935de53a552f69718135a3e471644b4d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jan 2025 19:41:28 +0800
+Subject: ext4: correct behavior under errors=remount-ro mode
+
+From: Baokun Li <libaokun1@huawei.com>
+
+[ Upstream commit 8f984530c242c569bafecfa35bce969a9b8fb0dd ]
+
+And after commit 95257987a638 ("ext4: drop EXT4_MF_FS_ABORTED flag") in
+v6.6-rc1, the EXT4_FLAGS_SHUTDOWN bit is set in ext4_handle_error() under
+errors=remount-ro mode. This causes the read to fail even when the error
+is triggered in errors=remount-ro mode.
+
+To correct the behavior under errors=remount-ro, EXT4_FLAGS_SHUTDOWN is
+replaced by the newly introduced EXT4_FLAGS_EMERGENCY_RO. This new flag
+only prevents writes, matching the previous behavior with SB_RDONLY.
+
+Fixes: 95257987a638 ("ext4: drop EXT4_MF_FS_ABORTED flag")
+Closes: https://lore.kernel.org/all/22d652f6-cb3c-43f5-b2fe-0a4bb6516a04@huawei.com/
+Suggested-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Baokun Li <libaokun1@huawei.com>
+Reviewed-by: Zhang Yi <yi.zhang@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://patch.msgid.link/20250122114130.229709-6-libaokun@huaweicloud.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/super.c | 19 ++++++++-----------
+ 1 file changed, 8 insertions(+), 11 deletions(-)
+
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index a50e5c31b9378..0ff0c3d0a3c08 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -707,11 +707,8 @@ static void ext4_handle_error(struct super_block *sb, bool force_ro, int error,
+       if (test_opt(sb, WARN_ON_ERROR))
+               WARN_ON_ONCE(1);
+-      if (!continue_fs && !sb_rdonly(sb)) {
+-              set_bit(EXT4_FLAGS_SHUTDOWN, &EXT4_SB(sb)->s_ext4_flags);
+-              if (journal)
+-                      jbd2_journal_abort(journal, -EIO);
+-      }
++      if (!continue_fs && !ext4_emergency_ro(sb) && journal)
++              jbd2_journal_abort(journal, -EIO);
+       if (!bdev_read_only(sb->s_bdev)) {
+               save_error_info(sb, error, ino, block, func, line);
+@@ -737,17 +734,17 @@ static void ext4_handle_error(struct super_block *sb, bool force_ro, int error,
+                       sb->s_id);
+       }
+-      if (sb_rdonly(sb) || continue_fs)
++      if (ext4_emergency_ro(sb) || continue_fs)
+               return;
+       ext4_msg(sb, KERN_CRIT, "Remounting filesystem read-only");
+       /*
+-       * EXT4_FLAGS_SHUTDOWN was set which stops all filesystem
+-       * modifications. We don't set SB_RDONLY because that requires
+-       * sb->s_umount semaphore and setting it without proper remount
+-       * procedure is confusing code such as freeze_super() leading to
+-       * deadlocks and other problems.
++       * We don't set SB_RDONLY because that requires sb->s_umount
++       * semaphore and setting it without proper remount procedure is
++       * confusing code such as freeze_super() leading to deadlocks
++       * and other problems.
+        */
++      set_bit(EXT4_FLAGS_EMERGENCY_RO, &EXT4_SB(sb)->s_ext4_flags);
+ }
+ static void update_super_work(struct work_struct *work)
+-- 
+2.39.5
+
diff --git a/queue-6.14/ext4-define-ext4_journal_destroy-wrapper.patch b/queue-6.14/ext4-define-ext4_journal_destroy-wrapper.patch
new file mode 100644 (file)
index 0000000..757a714
--- /dev/null
@@ -0,0 +1,114 @@
+From 270eb329c745cbae85aec252be8f6844c756a87e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Mar 2025 13:22:55 +0530
+Subject: ext4: define ext4_journal_destroy wrapper
+
+From: Ojaswin Mujoo <ojaswin@linux.ibm.com>
+
+[ Upstream commit 5a02a6204ca37e7c22fbb55a789c503f05e8e89a ]
+
+Define an ext4 wrapper over jbd2_journal_destroy to make sure we
+have consistent behavior during journal destruction. This will also
+come useful in the next patch where we add some ext4 specific logic
+in the destroy path.
+
+Reviewed-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Baokun Li <libaokun1@huawei.com>
+Signed-off-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
+Link: https://patch.msgid.link/c3ba78c5c419757e6d5f2d8ebb4a8ce9d21da86a.1742279837.git.ojaswin@linux.ibm.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Stable-dep-of: ce2f26e73783 ("ext4: avoid journaling sb update on error if journal is destroying")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/ext4_jbd2.h | 14 ++++++++++++++
+ fs/ext4/super.c     | 16 ++++++----------
+ 2 files changed, 20 insertions(+), 10 deletions(-)
+
+diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h
+index 0c77697d5e90d..930778e507cc4 100644
+--- a/fs/ext4/ext4_jbd2.h
++++ b/fs/ext4/ext4_jbd2.h
+@@ -513,4 +513,18 @@ static inline int ext4_should_dioread_nolock(struct inode *inode)
+       return 1;
+ }
++/*
++ * Pass journal explicitly as it may not be cached in the sbi->s_journal in some
++ * cases
++ */
++static inline int ext4_journal_destroy(struct ext4_sb_info *sbi, journal_t *journal)
++{
++      int err = 0;
++
++      err = jbd2_journal_destroy(journal);
++      sbi->s_journal = NULL;
++
++      return err;
++}
++
+ #endif        /* _EXT4_JBD2_H */
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index 0d1c3eefe438a..f658c017055f3 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -1309,8 +1309,7 @@ static void ext4_put_super(struct super_block *sb)
+       if (sbi->s_journal) {
+               aborted = is_journal_aborted(sbi->s_journal);
+-              err = jbd2_journal_destroy(sbi->s_journal);
+-              sbi->s_journal = NULL;
++              err = ext4_journal_destroy(sbi, sbi->s_journal);
+               if ((err < 0) && !aborted) {
+                       ext4_abort(sb, -err, "Couldn't clean up the journal");
+               }
+@@ -4975,8 +4974,7 @@ static int ext4_load_and_init_journal(struct super_block *sb,
+ out:
+       /* flush s_sb_upd_work before destroying the journal. */
+       flush_work(&sbi->s_sb_upd_work);
+-      jbd2_journal_destroy(sbi->s_journal);
+-      sbi->s_journal = NULL;
++      ext4_journal_destroy(sbi, sbi->s_journal);
+       return -EINVAL;
+ }
+@@ -5667,8 +5665,7 @@ failed_mount8: __maybe_unused
+       if (sbi->s_journal) {
+               /* flush s_sb_upd_work before journal destroy. */
+               flush_work(&sbi->s_sb_upd_work);
+-              jbd2_journal_destroy(sbi->s_journal);
+-              sbi->s_journal = NULL;
++              ext4_journal_destroy(sbi, sbi->s_journal);
+       }
+ failed_mount3a:
+       ext4_es_unregister_shrinker(sbi);
+@@ -5973,7 +5970,7 @@ static journal_t *ext4_open_dev_journal(struct super_block *sb,
+       return journal;
+ out_journal:
+-      jbd2_journal_destroy(journal);
++      ext4_journal_destroy(EXT4_SB(sb), journal);
+ out_bdev:
+       bdev_fput(bdev_file);
+       return ERR_PTR(errno);
+@@ -6090,8 +6087,7 @@ static int ext4_load_journal(struct super_block *sb,
+       EXT4_SB(sb)->s_journal = journal;
+       err = ext4_clear_journal_err(sb, es);
+       if (err) {
+-              EXT4_SB(sb)->s_journal = NULL;
+-              jbd2_journal_destroy(journal);
++              ext4_journal_destroy(EXT4_SB(sb), journal);
+               return err;
+       }
+@@ -6109,7 +6105,7 @@ static int ext4_load_journal(struct super_block *sb,
+       return 0;
+ err_out:
+-      jbd2_journal_destroy(journal);
++      ext4_journal_destroy(EXT4_SB(sb), journal);
+       return err;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/ext4-fix-out-of-bound-read-in-ext4_xattr_inode_dec_r.patch b/queue-6.14/ext4-fix-out-of-bound-read-in-ext4_xattr_inode_dec_r.patch
new file mode 100644 (file)
index 0000000..d2c3ee7
--- /dev/null
@@ -0,0 +1,199 @@
+From af217f4c41103594e1b1b4704f78d71822d1bfdc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Feb 2025 14:31:41 +0800
+Subject: ext4: fix out-of-bound read in ext4_xattr_inode_dec_ref_all()
+
+From: Ye Bin <yebin10@huawei.com>
+
+[ Upstream commit 5701875f9609b000d91351eaa6bfd97fe2f157f4 ]
+
+There's issue as follows:
+BUG: KASAN: use-after-free in ext4_xattr_inode_dec_ref_all+0x6ff/0x790
+Read of size 4 at addr ffff88807b003000 by task syz-executor.0/15172
+
+CPU: 3 PID: 15172 Comm: syz-executor.0
+Call Trace:
+ __dump_stack lib/dump_stack.c:82 [inline]
+ dump_stack+0xbe/0xfd lib/dump_stack.c:123
+ print_address_description.constprop.0+0x1e/0x280 mm/kasan/report.c:400
+ __kasan_report.cold+0x6c/0x84 mm/kasan/report.c:560
+ kasan_report+0x3a/0x50 mm/kasan/report.c:585
+ ext4_xattr_inode_dec_ref_all+0x6ff/0x790 fs/ext4/xattr.c:1137
+ ext4_xattr_delete_inode+0x4c7/0xda0 fs/ext4/xattr.c:2896
+ ext4_evict_inode+0xb3b/0x1670 fs/ext4/inode.c:323
+ evict+0x39f/0x880 fs/inode.c:622
+ iput_final fs/inode.c:1746 [inline]
+ iput fs/inode.c:1772 [inline]
+ iput+0x525/0x6c0 fs/inode.c:1758
+ ext4_orphan_cleanup fs/ext4/super.c:3298 [inline]
+ ext4_fill_super+0x8c57/0xba40 fs/ext4/super.c:5300
+ mount_bdev+0x355/0x410 fs/super.c:1446
+ legacy_get_tree+0xfe/0x220 fs/fs_context.c:611
+ vfs_get_tree+0x8d/0x2f0 fs/super.c:1576
+ do_new_mount fs/namespace.c:2983 [inline]
+ path_mount+0x119a/0x1ad0 fs/namespace.c:3316
+ do_mount+0xfc/0x110 fs/namespace.c:3329
+ __do_sys_mount fs/namespace.c:3540 [inline]
+ __se_sys_mount+0x219/0x2e0 fs/namespace.c:3514
+ do_syscall_64+0x33/0x40 arch/x86/entry/common.c:46
+ entry_SYSCALL_64_after_hwframe+0x67/0xd1
+
+Memory state around the buggy address:
+ ffff88807b002f00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ ffff88807b002f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+>ffff88807b003000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
+                   ^
+ ffff88807b003080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
+ ffff88807b003100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
+
+Above issue happens as ext4_xattr_delete_inode() isn't check xattr
+is valid if xattr is in inode.
+To solve above issue call xattr_check_inode() check if xattr if valid
+in inode. In fact, we can directly verify in ext4_iget_extra_inode(),
+so that there is no divergent verification.
+
+Fixes: e50e5129f384 ("ext4: xattr-in-inode support")
+Signed-off-by: Ye Bin <yebin10@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://patch.msgid.link/20250208063141.1539283-3-yebin@huaweicloud.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/inode.c |  5 +++++
+ fs/ext4/xattr.c | 26 +-------------------------
+ fs/ext4/xattr.h |  7 +++++++
+ 3 files changed, 13 insertions(+), 25 deletions(-)
+
+diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
+index 64e280fed9119..891bd1e2d19f8 100644
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -4674,6 +4674,11 @@ static inline int ext4_iget_extra_inode(struct inode *inode,
+           *magic == cpu_to_le32(EXT4_XATTR_MAGIC)) {
+               int err;
++              err = xattr_check_inode(inode, IHDR(inode, raw_inode),
++                                      ITAIL(inode, raw_inode));
++              if (err)
++                      return err;
++
+               ext4_set_inode_state(inode, EXT4_STATE_XATTR);
+               err = ext4_find_inline_data_nolock(inode);
+               if (!err && ext4_has_inline_data(inode))
+diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
+index 0e4494863d153..a10fb8a9d02dc 100644
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -308,7 +308,7 @@ __ext4_xattr_check_block(struct inode *inode, struct buffer_head *bh,
+       __ext4_xattr_check_block((inode), (bh),  __func__, __LINE__)
+-static inline int
++int
+ __xattr_check_inode(struct inode *inode, struct ext4_xattr_ibody_header *header,
+                        void *end, const char *function, unsigned int line)
+ {
+@@ -316,9 +316,6 @@ __xattr_check_inode(struct inode *inode, struct ext4_xattr_ibody_header *header,
+                           function, line);
+ }
+-#define xattr_check_inode(inode, header, end) \
+-      __xattr_check_inode((inode), (header), (end), __func__, __LINE__)
+-
+ static int
+ xattr_find_entry(struct inode *inode, struct ext4_xattr_entry **pentry,
+                void *end, int name_index, const char *name, int sorted)
+@@ -650,9 +647,6 @@ ext4_xattr_ibody_get(struct inode *inode, int name_index, const char *name,
+       raw_inode = ext4_raw_inode(&iloc);
+       header = IHDR(inode, raw_inode);
+       end = ITAIL(inode, raw_inode);
+-      error = xattr_check_inode(inode, header, end);
+-      if (error)
+-              goto cleanup;
+       entry = IFIRST(header);
+       error = xattr_find_entry(inode, &entry, end, name_index, name, 0);
+       if (error)
+@@ -783,7 +777,6 @@ ext4_xattr_ibody_list(struct dentry *dentry, char *buffer, size_t buffer_size)
+       struct ext4_xattr_ibody_header *header;
+       struct ext4_inode *raw_inode;
+       struct ext4_iloc iloc;
+-      void *end;
+       int error;
+       if (!ext4_test_inode_state(inode, EXT4_STATE_XATTR))
+@@ -793,14 +786,9 @@ ext4_xattr_ibody_list(struct dentry *dentry, char *buffer, size_t buffer_size)
+               return error;
+       raw_inode = ext4_raw_inode(&iloc);
+       header = IHDR(inode, raw_inode);
+-      end = ITAIL(inode, raw_inode);
+-      error = xattr_check_inode(inode, header, end);
+-      if (error)
+-              goto cleanup;
+       error = ext4_xattr_list_entries(dentry, IFIRST(header),
+                                       buffer, buffer_size);
+-cleanup:
+       brelse(iloc.bh);
+       return error;
+ }
+@@ -868,7 +856,6 @@ int ext4_get_inode_usage(struct inode *inode, qsize_t *usage)
+       struct ext4_xattr_ibody_header *header;
+       struct ext4_xattr_entry *entry;
+       qsize_t ea_inode_refs = 0;
+-      void *end;
+       int ret;
+       lockdep_assert_held_read(&EXT4_I(inode)->xattr_sem);
+@@ -879,10 +866,6 @@ int ext4_get_inode_usage(struct inode *inode, qsize_t *usage)
+                       goto out;
+               raw_inode = ext4_raw_inode(&iloc);
+               header = IHDR(inode, raw_inode);
+-              end = ITAIL(inode, raw_inode);
+-              ret = xattr_check_inode(inode, header, end);
+-              if (ret)
+-                      goto out;
+               for (entry = IFIRST(header); !IS_LAST_ENTRY(entry);
+                    entry = EXT4_XATTR_NEXT(entry))
+@@ -2237,9 +2220,6 @@ int ext4_xattr_ibody_find(struct inode *inode, struct ext4_xattr_info *i,
+       is->s.here = is->s.first;
+       is->s.end = ITAIL(inode, raw_inode);
+       if (ext4_test_inode_state(inode, EXT4_STATE_XATTR)) {
+-              error = xattr_check_inode(inode, header, is->s.end);
+-              if (error)
+-                      return error;
+               /* Find the named attribute. */
+               error = xattr_find_entry(inode, &is->s.here, is->s.end,
+                                        i->name_index, i->name, 0);
+@@ -2790,10 +2770,6 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
+       min_offs = end - base;
+       total_ino = sizeof(struct ext4_xattr_ibody_header) + sizeof(u32);
+-      error = xattr_check_inode(inode, header, end);
+-      if (error)
+-              goto cleanup;
+-
+       ifree = ext4_xattr_free_space(base, &min_offs, base, &total_ino);
+       if (ifree >= isize_diff)
+               goto shift;
+diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h
+index 5197f17ffd9a2..1fedf44d4fb65 100644
+--- a/fs/ext4/xattr.h
++++ b/fs/ext4/xattr.h
+@@ -209,6 +209,13 @@ extern int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode,
+ extern struct mb_cache *ext4_xattr_create_cache(void);
+ extern void ext4_xattr_destroy_cache(struct mb_cache *);
++extern int
++__xattr_check_inode(struct inode *inode, struct ext4_xattr_ibody_header *header,
++                  void *end, const char *function, unsigned int line);
++
++#define xattr_check_inode(inode, header, end) \
++      __xattr_check_inode((inode), (header), (end), __func__, __LINE__)
++
+ #ifdef CONFIG_EXT4_FS_SECURITY
+ extern int ext4_init_security(handle_t *handle, struct inode *inode,
+                             struct inode *dir, const struct qstr *qstr);
+-- 
+2.39.5
+
diff --git a/queue-6.14/ext4-fix-potential-null-dereference-in-ext4-kunit-te.patch b/queue-6.14/ext4-fix-potential-null-dereference-in-ext4-kunit-te.patch
new file mode 100644 (file)
index 0000000..dca1dba
--- /dev/null
@@ -0,0 +1,47 @@
+From b378698db9cf5d0e576c0cd0efc78c46766f8431 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jan 2025 17:24:21 +0800
+Subject: ext4: fix potential null dereference in ext4 kunit test
+
+From: Charles Han <hanchunchao@inspur.com>
+
+[ Upstream commit 57e7239ce0ed14e81e414c99d57f516f6220a995 ]
+
+kunit_kzalloc() may return a NULL pointer, dereferencing it
+without NULL check may lead to NULL dereference.
+Add a NULL check for grp.
+
+Fixes: ac96b56a2fbd ("ext4: Add unit test for mb_mark_used")
+Fixes: b7098e1fa7bc ("ext4: Add unit test for mb_free_blocks")
+Signed-off-by: Charles Han <hanchunchao@inspur.com>
+Reviewed-by: Kemeng Shi <shikemeng@huaweicloud.com>
+Link: https://patch.msgid.link/20250110092421.35619-1-hanchunchao@inspur.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/mballoc-test.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/fs/ext4/mballoc-test.c b/fs/ext4/mballoc-test.c
+index bb2a223b207c1..d634c12f19847 100644
+--- a/fs/ext4/mballoc-test.c
++++ b/fs/ext4/mballoc-test.c
+@@ -796,6 +796,7 @@ static void test_mb_mark_used(struct kunit *test)
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buddy);
+       grp = kunit_kzalloc(test, offsetof(struct ext4_group_info,
+                               bb_counters[MB_NUM_ORDERS(sb)]), GFP_KERNEL);
++      KUNIT_ASSERT_NOT_ERR_OR_NULL(test, grp);
+       ret = ext4_mb_load_buddy(sb, TEST_GOAL_GROUP, &e4b);
+       KUNIT_ASSERT_EQ(test, ret, 0);
+@@ -860,6 +861,7 @@ static void test_mb_free_blocks(struct kunit *test)
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buddy);
+       grp = kunit_kzalloc(test, offsetof(struct ext4_group_info,
+                               bb_counters[MB_NUM_ORDERS(sb)]), GFP_KERNEL);
++      KUNIT_ASSERT_NOT_ERR_OR_NULL(test, grp);
+       ret = ext4_mb_load_buddy(sb, TEST_GOAL_GROUP, &e4b);
+       KUNIT_ASSERT_EQ(test, ret, 0);
+-- 
+2.39.5
+
diff --git a/queue-6.14/ext4-goto-right-label-out_mmap_sem-in-ext4_setattr.patch b/queue-6.14/ext4-goto-right-label-out_mmap_sem-in-ext4_setattr.patch
new file mode 100644 (file)
index 0000000..d21a786
--- /dev/null
@@ -0,0 +1,61 @@
+From f2b8543ba420b681be5b098971d9de451aac005c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Feb 2025 19:22:47 +0800
+Subject: ext4: goto right label 'out_mmap_sem' in ext4_setattr()
+
+From: Baokun Li <libaokun1@huawei.com>
+
+[ Upstream commit 7e91ae31e2d264155dfd102101afc2de7bd74a64 ]
+
+Otherwise, if ext4_inode_attach_jinode() fails, a hung task will
+happen because filemap_invalidate_unlock() isn't called to unlock
+mapping->invalidate_lock. Like this:
+
+EXT4-fs error (device sda) in ext4_setattr:5557: Out of memory
+INFO: task fsstress:374 blocked for more than 122 seconds.
+      Not tainted 6.14.0-rc1-next-20250206-xfstests-dirty #726
+"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+task:fsstress state:D stack:0     pid:374   tgid:374   ppid:373
+                                  task_flags:0x440140 flags:0x00000000
+Call Trace:
+ <TASK>
+ __schedule+0x2c9/0x7f0
+ schedule+0x27/0xa0
+ schedule_preempt_disabled+0x15/0x30
+ rwsem_down_read_slowpath+0x278/0x4c0
+ down_read+0x59/0xb0
+ page_cache_ra_unbounded+0x65/0x1b0
+ filemap_get_pages+0x124/0x3e0
+ filemap_read+0x114/0x3d0
+ vfs_read+0x297/0x360
+ ksys_read+0x6c/0xe0
+ do_syscall_64+0x4b/0x110
+ entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+Fixes: c7fc0366c656 ("ext4: partial zero eof block on unaligned inode size extension")
+Signed-off-by: Baokun Li <libaokun1@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Brian Foster <bfoster@redhat.com>
+Link: https://patch.msgid.link/20250213112247.3168709-1-libaokun@huaweicloud.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/inode.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
+index 891bd1e2d19f8..4009f9017a0e9 100644
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -5477,7 +5477,7 @@ int ext4_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
+                           oldsize & (inode->i_sb->s_blocksize - 1)) {
+                               error = ext4_inode_attach_jinode(inode);
+                               if (error)
+-                                      goto err_out;
++                                      goto out_mmap_sem;
+                       }
+                       handle = ext4_journal_start(inode, EXT4_HT_INODE, 3);
+-- 
+2.39.5
+
diff --git a/queue-6.14/ext4-introduce-itail-helper.patch b/queue-6.14/ext4-introduce-itail-helper.patch
new file mode 100644 (file)
index 0000000..252e766
--- /dev/null
@@ -0,0 +1,88 @@
+From 192e8c85dbe031bcbd6eb461a48def57ea1ceefc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Feb 2025 14:31:40 +0800
+Subject: ext4: introduce ITAIL helper
+
+From: Ye Bin <yebin10@huawei.com>
+
+[ Upstream commit 69f3a3039b0d0003de008659cafd5a1eaaa0a7a4 ]
+
+Introduce ITAIL helper to get the bound of xattr in inode.
+
+Signed-off-by: Ye Bin <yebin10@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://patch.msgid.link/20250208063141.1539283-2-yebin@huaweicloud.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Stable-dep-of: 5701875f9609 ("ext4: fix out-of-bound read in ext4_xattr_inode_dec_ref_all()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/xattr.c | 10 +++++-----
+ fs/ext4/xattr.h |  3 +++
+ 2 files changed, 8 insertions(+), 5 deletions(-)
+
+diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
+index 7647e9f6e1903..0e4494863d153 100644
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -649,7 +649,7 @@ ext4_xattr_ibody_get(struct inode *inode, int name_index, const char *name,
+               return error;
+       raw_inode = ext4_raw_inode(&iloc);
+       header = IHDR(inode, raw_inode);
+-      end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
++      end = ITAIL(inode, raw_inode);
+       error = xattr_check_inode(inode, header, end);
+       if (error)
+               goto cleanup;
+@@ -793,7 +793,7 @@ ext4_xattr_ibody_list(struct dentry *dentry, char *buffer, size_t buffer_size)
+               return error;
+       raw_inode = ext4_raw_inode(&iloc);
+       header = IHDR(inode, raw_inode);
+-      end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
++      end = ITAIL(inode, raw_inode);
+       error = xattr_check_inode(inode, header, end);
+       if (error)
+               goto cleanup;
+@@ -879,7 +879,7 @@ int ext4_get_inode_usage(struct inode *inode, qsize_t *usage)
+                       goto out;
+               raw_inode = ext4_raw_inode(&iloc);
+               header = IHDR(inode, raw_inode);
+-              end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
++              end = ITAIL(inode, raw_inode);
+               ret = xattr_check_inode(inode, header, end);
+               if (ret)
+                       goto out;
+@@ -2235,7 +2235,7 @@ int ext4_xattr_ibody_find(struct inode *inode, struct ext4_xattr_info *i,
+       header = IHDR(inode, raw_inode);
+       is->s.base = is->s.first = IFIRST(header);
+       is->s.here = is->s.first;
+-      is->s.end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
++      is->s.end = ITAIL(inode, raw_inode);
+       if (ext4_test_inode_state(inode, EXT4_STATE_XATTR)) {
+               error = xattr_check_inode(inode, header, is->s.end);
+               if (error)
+@@ -2786,7 +2786,7 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
+        */
+       base = IFIRST(header);
+-      end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
++      end = ITAIL(inode, raw_inode);
+       min_offs = end - base;
+       total_ino = sizeof(struct ext4_xattr_ibody_header) + sizeof(u32);
+diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h
+index b25c2d7b5f991..5197f17ffd9a2 100644
+--- a/fs/ext4/xattr.h
++++ b/fs/ext4/xattr.h
+@@ -67,6 +67,9 @@ struct ext4_xattr_entry {
+               ((void *)raw_inode + \
+               EXT4_GOOD_OLD_INODE_SIZE + \
+               EXT4_I(inode)->i_extra_isize))
++#define ITAIL(inode, raw_inode) \
++      ((void *)(raw_inode) + \
++       EXT4_SB((inode)->i_sb)->s_inode_size)
+ #define IFIRST(hdr) ((struct ext4_xattr_entry *)((hdr)+1))
+ /*
+-- 
+2.39.5
+
diff --git a/queue-6.14/ext4-show-emergency_ro-when-ext4_flags_emergency_ro-.patch b/queue-6.14/ext4-show-emergency_ro-when-ext4_flags_emergency_ro-.patch
new file mode 100644 (file)
index 0000000..df557d7
--- /dev/null
@@ -0,0 +1,47 @@
+From ec76c939740490625b92629679d1464594f68bc7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jan 2025 19:41:29 +0800
+Subject: ext4: show 'emergency_ro' when EXT4_FLAGS_EMERGENCY_RO is set
+
+From: Baokun Li <libaokun1@huawei.com>
+
+[ Upstream commit 6b76715d5e41fc332b0b879e66fad6ef3db07a3f ]
+
+After commit d3476f3dad4a ("ext4: don't set SB_RDONLY after filesystem
+errors") in v6.12-rc1, the 'errors=remount-ro' mode no longer sets
+SB_RDONLY on errors, which results in us seeing the filesystem is still
+in rw state after errors.
+
+Therefore, after setting EXT4_FLAGS_EMERGENCY_RO, display the emergency_ro
+option so that users can query whether the current file system has become
+emergency read-only due to errors through commands such as 'mount' or
+'cat /proc/fs/ext4/sdx/options'.
+
+Fixes: d3476f3dad4a ("ext4: don't set SB_RDONLY after filesystem errors")
+Signed-off-by: Baokun Li <libaokun1@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Zhang Yi <yi.zhang@huawei.com>
+Link: https://patch.msgid.link/20250122114130.229709-7-libaokun@huaweicloud.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/super.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index 0ff0c3d0a3c08..0d1c3eefe438a 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -3035,6 +3035,9 @@ static int _ext4_show_options(struct seq_file *seq, struct super_block *sb,
+       if (nodefs && !test_opt(sb, NO_PREFETCH_BLOCK_BITMAPS))
+               SEQ_OPTS_PUTS("prefetch_block_bitmaps");
++      if (ext4_emergency_ro(sb))
++              SEQ_OPTS_PUTS("emergency_ro");
++
+       ext4_show_quota_options(seq, sb);
+       return 0;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/ext4-verify-fast-symlink-length.patch b/queue-6.14/ext4-verify-fast-symlink-length.patch
new file mode 100644 (file)
index 0000000..697d209
--- /dev/null
@@ -0,0 +1,52 @@
+From 4fa22c1b541e019fb28acad46dae6ecfb4932523 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Feb 2025 10:44:55 +0100
+Subject: ext4: verify fast symlink length
+
+From: Jan Kara <jack@suse.cz>
+
+[ Upstream commit 5f920d5d60839f7cbbb1ed50eac68d8bc0a73a7c ]
+
+Verify fast symlink length stored in inode->i_size matches the string
+stored in the inode to avoid surprises from corrupted filesystems.
+
+Reported-by: syzbot+48a99e426f29859818c0@syzkaller.appspotmail.com
+Tested-by: syzbot+48a99e426f29859818c0@syzkaller.appspotmail.com
+Fixes: bae80473f7b0 ("ext4: use inode_set_cached_link()")
+Suggested-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Baokun Li <libaokun1@huawei.com>
+Reviewed-by: Darrick J. Wong <djwong@kernel.org>
+Link: https://patch.msgid.link/20250206094454.20522-2-jack@suse.cz
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/inode.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
+index 7c54ae5fcbd45..64e280fed9119 100644
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -5007,8 +5007,16 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
+                       inode->i_op = &ext4_encrypted_symlink_inode_operations;
+               } else if (ext4_inode_is_fast_symlink(inode)) {
+                       inode->i_op = &ext4_fast_symlink_inode_operations;
+-                      nd_terminate_link(ei->i_data, inode->i_size,
+-                              sizeof(ei->i_data) - 1);
++                      if (inode->i_size == 0 ||
++                          inode->i_size >= sizeof(ei->i_data) ||
++                          strnlen((char *)ei->i_data, inode->i_size + 1) !=
++                                                              inode->i_size) {
++                              ext4_error_inode(inode, function, line, 0,
++                                      "invalid fast symlink length %llu",
++                                       (unsigned long long)inode->i_size);
++                              ret = -EFSCORRUPTED;
++                              goto bad_inode;
++                      }
+                       inode_set_cached_link(inode, (char *)ei->i_data,
+                                             inode->i_size);
+               } else {
+-- 
+2.39.5
+
diff --git a/queue-6.14/f2fs-add-check-for-deleted-inode.patch b/queue-6.14/f2fs-add-check-for-deleted-inode.patch
new file mode 100644 (file)
index 0000000..28cc23f
--- /dev/null
@@ -0,0 +1,49 @@
+From 37b0a5cc380da6b81b1eb53611824e96f094b5fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 23:54:20 +0800
+Subject: f2fs: add check for deleted inode
+
+From: Leo Stone <leocstone@gmail.com>
+
+[ Upstream commit 81edb983b3f5d6900d3e337b9af7b1bec4bef0f2 ]
+
+The syzbot reproducer mounts a f2fs image, then tries to unlink an
+existing file. However, the unlinked file already has a link count of 0
+when it is read for the first time in do_read_inode().
+
+Add a check to sanity_check_inode() for i_nlink == 0.
+
+[Chao Yu: rebase the code and fix orphan inode recovery issue]
+Reported-by: syzbot+b01a36acd7007e273a83@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=b01a36acd7007e273a83
+Fixes: 39a53e0ce0df ("f2fs: add superblock and major in-memory structure")
+Signed-off-by: Leo Stone <leocstone@gmail.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/namei.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
+index a278c7da81778..3d85d8116dae7 100644
+--- a/fs/f2fs/namei.c
++++ b/fs/f2fs/namei.c
+@@ -502,6 +502,14 @@ static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry,
+               goto out;
+       }
++      if (inode->i_nlink == 0) {
++              f2fs_warn(F2FS_I_SB(inode), "%s: inode (ino=%lx) has zero i_nlink",
++                        __func__, inode->i_ino);
++              err = -EFSCORRUPTED;
++              set_sbi_flag(F2FS_I_SB(inode), SBI_NEED_FSCK);
++              goto out_iput;
++      }
++
+       if (IS_ENCRYPTED(dir) &&
+           (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) &&
+           !fscrypt_has_permitted_context(dir, inode)) {
+-- 
+2.39.5
+
diff --git a/queue-6.14/f2fs-fix-missing-discard-for-active-segments.patch b/queue-6.14/f2fs-fix-missing-discard-for-active-segments.patch
new file mode 100644 (file)
index 0000000..dd5de32
--- /dev/null
@@ -0,0 +1,85 @@
+From 7149db20149d056f93d295655ba0ce0ee30ea94c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Mar 2025 04:16:24 -0600
+Subject: f2fs: fix missing discard for active segments
+
+From: Chunhai Guo <guochunhai@vivo.com>
+
+[ Upstream commit 21263d035ff21fa0ccf79adba20bab9cd8cca0f2 ]
+
+During a checkpoint, the current active segment X may not be handled
+properly. This occurs when segment X has 0 valid blocks and a non-zero
+number of discard blocks, for the following reasons:
+
+locate_dirty_segment() does not mark any active segment as a prefree
+segment. As a result, segment X is not included in dirty_segmap[PRE], and
+f2fs_clear_prefree_segments() skips it when handling prefree segments.
+
+add_discard_addrs() skips any segment with 0 valid blocks, so segment X is
+also skipped.
+
+Consequently, no `struct discard_cmd` is actually created for segment X.
+However, the ckpt_valid_map and cur_valid_map of segment X are synced by
+seg_info_to_raw_sit() during the current checkpoint process. As a result,
+it cannot find the missing discard bits even in subsequent checkpoints.
+Consequently, the value of sbi->discard_blks remains non-zero. Thus, when
+f2fs is umounted, CP_TRIMMED_FLAG will not be set due to the non-zero
+sbi->discard_blks.
+
+Relevant code process:
+
+f2fs_write_checkpoint()
+    f2fs_flush_sit_entries()
+         list_for_each_entry_safe(ses, tmp, head, set_list) {
+             for_each_set_bit_from(segno, bitmap, end) {
+                 ...
+                 add_discard_addrs(sbi, cpc, false); // skip segment X due to its 0 valid blocks
+                 ...
+                 seg_info_to_raw_sit(); // sync ckpt_valid_map with cur_valid_map for segment X
+                 ...
+             }
+         }
+    f2fs_clear_prefree_segments(); // segment X is not included in dirty_segmap[PRE] and is skipped
+
+This issue is easy to reproduce with the following operations:
+
+root # mkfs.f2fs -f /dev/f2fs_dev
+root # mount -t f2fs /dev/f2fs_dev /mnt_point
+root # dd if=/dev/blk_dev of=/mnt_point/1.bin bs=4k count=256
+root # sync
+root # rm /mnt_point/1.bin
+root # umount /mnt_point
+root # dump.f2fs /dev/f2fs_dev | grep "checkpoint state"
+Info: checkpoint state = 45 :  crc compacted_summary unmount ---- 'trimmed' flag is missing
+
+Since add_discard_addrs() can handle active segments with non-zero valid
+blocks, it is reasonable to fix this issue by allowing it to also handle
+active segments with 0 valid blocks.
+
+Fixes: b29555505d81 ("f2fs: add key functions for small discards")
+Signed-off-by: Chunhai Guo <guochunhai@vivo.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/segment.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index 2b415926641f0..384bca002ec9a 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -2096,7 +2096,9 @@ static bool add_discard_addrs(struct f2fs_sb_info *sbi, struct cp_control *cpc,
+               return false;
+       if (!force) {
+-              if (!f2fs_realtime_discard_enable(sbi) || !se->valid_blocks ||
++              if (!f2fs_realtime_discard_enable(sbi) ||
++                      (!se->valid_blocks &&
++                              !IS_CURSEG(sbi, cpc->trim_start)) ||
+                       SM_I(sbi)->dcc_info->nr_discards >=
+                               SM_I(sbi)->dcc_info->max_discards)
+                       return false;
+-- 
+2.39.5
+
diff --git a/queue-6.14/f2fs-fix-potential-deadloop-in-prepare_compress_over.patch b/queue-6.14/f2fs-fix-potential-deadloop-in-prepare_compress_over.patch
new file mode 100644 (file)
index 0000000..06b308c
--- /dev/null
@@ -0,0 +1,107 @@
+From 4adf850a3f52f1b29810f60192cb33653c7c53d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Mar 2025 11:23:29 +0800
+Subject: f2fs: fix potential deadloop in prepare_compress_overwrite()
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 3147ee567dd9004a49826ddeaf0a4b12865d4409 ]
+
+Jan Prusakowski reported a kernel hang issue as below:
+
+When running xfstests on linux-next kernel (6.14.0-rc3, 6.12) I
+encountered a problem in generic/475 test where fsstress process
+gets blocked in __f2fs_write_data_pages() and the test hangs.
+The options I used are:
+
+MKFS_OPTIONS  -- -O compression -O extra_attr -O project_quota -O quota /dev/vdc
+MOUNT_OPTIONS -- -o acl,user_xattr -o discard,compress_extension=* /dev/vdc /vdc
+
+INFO: task kworker/u8:0:11 blocked for more than 122 seconds.
+      Not tainted 6.14.0-rc3-xfstests-lockdep #1
+"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+task:kworker/u8:0    state:D stack:0     pid:11    tgid:11    ppid:2      task_flags:0x4208160 flags:0x00004000
+Workqueue: writeback wb_workfn (flush-253:0)
+Call Trace:
+ <TASK>
+ __schedule+0x309/0x8e0
+ schedule+0x3a/0x100
+ schedule_preempt_disabled+0x15/0x30
+ __mutex_lock+0x59a/0xdb0
+ __f2fs_write_data_pages+0x3ac/0x400
+ do_writepages+0xe8/0x290
+ __writeback_single_inode+0x5c/0x360
+ writeback_sb_inodes+0x22f/0x570
+ wb_writeback+0xb0/0x410
+ wb_do_writeback+0x47/0x2f0
+ wb_workfn+0x5a/0x1c0
+ process_one_work+0x223/0x5b0
+ worker_thread+0x1d5/0x3c0
+ kthread+0xfd/0x230
+ ret_from_fork+0x31/0x50
+ ret_from_fork_asm+0x1a/0x30
+ </TASK>
+
+The root cause is: once generic/475 starts toload error table to dm
+device, f2fs_prepare_compress_overwrite() will loop reading compressed
+cluster pages due to IO error, meanwhile it has held .writepages lock,
+it can block all other writeback tasks.
+
+Let's fix this issue w/ below changes:
+- add f2fs_handle_page_eio() in prepare_compress_overwrite() to
+detect IO error.
+- detect cp_error earler in f2fs_read_multi_pages().
+
+Fixes: 4c8ff7095bef ("f2fs: support data compression")
+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/compress.c |  1 +
+ fs/f2fs/data.c     | 10 ++++++----
+ 2 files changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
+index 985690d81a82c..9b94810675c19 100644
+--- a/fs/f2fs/compress.c
++++ b/fs/f2fs/compress.c
+@@ -1150,6 +1150,7 @@ static int prepare_compress_overwrite(struct compress_ctx *cc,
+               f2fs_compress_ctx_add_page(cc, page_folio(page));
+               if (!PageUptodate(page)) {
++                      f2fs_handle_page_eio(sbi, page_folio(page), DATA);
+ release_and_retry:
+                       f2fs_put_rpages(cc);
+                       f2fs_unlock_rpages(cc, i + 1);
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index de4da6d9cd93a..8440a1ed24f23 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -2178,6 +2178,12 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
+       int i;
+       int ret = 0;
++      if (unlikely(f2fs_cp_error(sbi))) {
++              ret = -EIO;
++              from_dnode = false;
++              goto out_put_dnode;
++      }
++
+       f2fs_bug_on(sbi, f2fs_cluster_is_empty(cc));
+       last_block_in_file = F2FS_BYTES_TO_BLK(f2fs_readpage_limit(inode) +
+@@ -2221,10 +2227,6 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
+       if (ret)
+               goto out;
+-      if (unlikely(f2fs_cp_error(sbi))) {
+-              ret = -EIO;
+-              goto out_put_dnode;
+-      }
+       f2fs_bug_on(sbi, dn.data_blkaddr != COMPRESS_ADDR);
+ skip_reading_dnode:
+-- 
+2.39.5
+
diff --git a/queue-6.14/f2fs-fix-to-avoid-accessing-uninitialized-curseg.patch b/queue-6.14/f2fs-fix-to-avoid-accessing-uninitialized-curseg.patch
new file mode 100644 (file)
index 0000000..c3515d7
--- /dev/null
@@ -0,0 +1,121 @@
+From 429f22515d290f68286cb49c8b080dd8c1177746 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Feb 2025 18:29:23 +0800
+Subject: f2fs: fix to avoid accessing uninitialized curseg
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 986c50f6bca109c6cf362b4e2babcb85aba958f6 ]
+
+syzbot reports a f2fs bug as below:
+
+F2FS-fs (loop3): Stopped filesystem due to reason: 7
+kworker/u8:7: attempt to access beyond end of device
+BUG: unable to handle page fault for address: ffffed1604ea3dfa
+RIP: 0010:get_ckpt_valid_blocks fs/f2fs/segment.h:361 [inline]
+RIP: 0010:has_curseg_enough_space fs/f2fs/segment.h:570 [inline]
+RIP: 0010:__get_secs_required fs/f2fs/segment.h:620 [inline]
+RIP: 0010:has_not_enough_free_secs fs/f2fs/segment.h:633 [inline]
+RIP: 0010:has_enough_free_secs+0x575/0x1660 fs/f2fs/segment.h:649
+ <TASK>
+ f2fs_is_checkpoint_ready fs/f2fs/segment.h:671 [inline]
+ f2fs_write_inode+0x425/0x540 fs/f2fs/inode.c:791
+ write_inode fs/fs-writeback.c:1525 [inline]
+ __writeback_single_inode+0x708/0x10d0 fs/fs-writeback.c:1745
+ writeback_sb_inodes+0x820/0x1360 fs/fs-writeback.c:1976
+ wb_writeback+0x413/0xb80 fs/fs-writeback.c:2156
+ wb_do_writeback fs/fs-writeback.c:2303 [inline]
+ wb_workfn+0x410/0x1080 fs/fs-writeback.c:2343
+ process_one_work kernel/workqueue.c:3236 [inline]
+ process_scheduled_works+0xa66/0x1840 kernel/workqueue.c:3317
+ worker_thread+0x870/0xd30 kernel/workqueue.c:3398
+ kthread+0x7a9/0x920 kernel/kthread.c:464
+ ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:148
+ ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
+
+Commit 8b10d3653735 ("f2fs: introduce FAULT_NO_SEGMENT") allows to trigger
+no free segment fault in allocator, then it will update curseg->segno to
+NULL_SEGNO, though, CP_ERROR_FLAG has been set, f2fs_write_inode() missed
+to check the flag, and access invalid curseg->segno directly in below call
+path, then resulting in panic:
+
+- f2fs_write_inode
+ - f2fs_is_checkpoint_ready
+  - has_enough_free_secs
+   - has_not_enough_free_secs
+    - __get_secs_required
+     - has_curseg_enough_space
+      - get_ckpt_valid_blocks
+      : access invalid curseg->segno
+
+To avoid this issue, let's:
+- check CP_ERROR_FLAG flag in prior to f2fs_is_checkpoint_ready() in
+f2fs_write_inode().
+- in has_curseg_enough_space(), save curseg->segno into a temp variable,
+and verify its validation before use.
+
+Fixes: 8b10d3653735 ("f2fs: introduce FAULT_NO_SEGMENT")
+Reported-by: syzbot+b6b347b7a4ea1b2e29b6@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/all/67973c2b.050a0220.11b1bb.0089.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/inode.c   | 7 +++++++
+ fs/f2fs/segment.h | 9 ++++++++-
+ 2 files changed, 15 insertions(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
+index 3dd25f64d6f1e..cd17d6f4c291f 100644
+--- a/fs/f2fs/inode.c
++++ b/fs/f2fs/inode.c
+@@ -789,6 +789,13 @@ int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc)
+               !is_inode_flag_set(inode, FI_DIRTY_INODE))
+               return 0;
++      /*
++       * no need to update inode page, ultimately f2fs_evict_inode() will
++       * clear dirty status of inode.
++       */
++      if (f2fs_cp_error(sbi))
++              return -EIO;
++
+       if (!f2fs_is_checkpoint_ready(sbi)) {
+               f2fs_mark_inode_dirty_sync(inode, true);
+               return -ENOSPC;
+diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
+index 943be4f1d6d2d..0465dc00b349d 100644
+--- a/fs/f2fs/segment.h
++++ b/fs/f2fs/segment.h
+@@ -559,13 +559,16 @@ static inline bool has_curseg_enough_space(struct f2fs_sb_info *sbi,
+                       unsigned int node_blocks, unsigned int data_blocks,
+                       unsigned int dent_blocks)
+ {
+-
+       unsigned int segno, left_blocks, blocks;
+       int i;
+       /* check current data/node sections in the worst case. */
+       for (i = CURSEG_HOT_DATA; i < NR_PERSISTENT_LOG; i++) {
+               segno = CURSEG_I(sbi, i)->segno;
++
++              if (unlikely(segno == NULL_SEGNO))
++                      return false;
++
+               left_blocks = CAP_BLKS_PER_SEC(sbi) -
+                               get_ckpt_valid_blocks(sbi, segno, true);
+@@ -576,6 +579,10 @@ static inline bool has_curseg_enough_space(struct f2fs_sb_info *sbi,
+       /* check current data section for dentry blocks. */
+       segno = CURSEG_I(sbi, CURSEG_HOT_DATA)->segno;
++
++      if (unlikely(segno == NULL_SEGNO))
++              return false;
++
+       left_blocks = CAP_BLKS_PER_SEC(sbi) -
+                       get_ckpt_valid_blocks(sbi, segno, true);
+       if (dent_blocks > left_blocks)
+-- 
+2.39.5
+
diff --git a/queue-6.14/f2fs-fix-to-avoid-panic-once-fallocation-fails-for-p.patch b/queue-6.14/f2fs-fix-to-avoid-panic-once-fallocation-fails-for-p.patch
new file mode 100644 (file)
index 0000000..4e64e13
--- /dev/null
@@ -0,0 +1,143 @@
+From 19bd25f40497a1da6e392a84695dded151dc2949 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Feb 2025 14:36:57 +0800
+Subject: f2fs: fix to avoid panic once fallocation fails for pinfile
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 48ea8b200414ac69ea96f4c231f5c7ef1fbeffef ]
+
+syzbot reports a f2fs bug as below:
+
+------------[ cut here ]------------
+kernel BUG at fs/f2fs/segment.c:2746!
+CPU: 0 UID: 0 PID: 5323 Comm: syz.0.0 Not tainted 6.13.0-rc2-syzkaller-00018-g7cb1b4663150 #0
+RIP: 0010:get_new_segment fs/f2fs/segment.c:2746 [inline]
+RIP: 0010:new_curseg+0x1f52/0x1f70 fs/f2fs/segment.c:2876
+Call Trace:
+ <TASK>
+ __allocate_new_segment+0x1ce/0x940 fs/f2fs/segment.c:3210
+ f2fs_allocate_new_section fs/f2fs/segment.c:3224 [inline]
+ f2fs_allocate_pinning_section+0xfa/0x4e0 fs/f2fs/segment.c:3238
+ f2fs_expand_inode_data+0x696/0xca0 fs/f2fs/file.c:1830
+ f2fs_fallocate+0x537/0xa10 fs/f2fs/file.c:1940
+ vfs_fallocate+0x569/0x6e0 fs/open.c:327
+ do_vfs_ioctl+0x258c/0x2e40 fs/ioctl.c:885
+ __do_sys_ioctl fs/ioctl.c:904 [inline]
+ __se_sys_ioctl+0x80/0x170 fs/ioctl.c:892
+ do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+ do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Concurrent pinfile allocation may run out of free section, result in
+panic in get_new_segment(), let's expand pin_sem lock coverage to
+include f2fs_gc(), so that we can make sure to reclaim enough free
+space for following allocation.
+
+In addition, do below changes to enhance error path handling:
+- call f2fs_bug_on() only in non-pinfile allocation path in
+get_new_segment().
+- call reset_curseg_fields() to reset all fields of curseg in
+new_curseg()
+
+Fixes: f5a53edcf01e ("f2fs: support aligned pinned file")
+Reported-by: syzbot+15669ec8c35ddf6c3d43@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/linux-f2fs-devel/675cd64e.050a0220.37aaf.00bb.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/file.c    |  8 +++++---
+ fs/f2fs/segment.c | 20 ++++++++++----------
+ 2 files changed, 15 insertions(+), 13 deletions(-)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index f92a9fba9991b..1bb70499ab598 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -1834,18 +1834,20 @@ static int f2fs_expand_inode_data(struct inode *inode, loff_t offset,
+               map.m_len = sec_blks;
+ next_alloc:
++              f2fs_down_write(&sbi->pin_sem);
++
+               if (has_not_enough_free_secs(sbi, 0, f2fs_sb_has_blkzoned(sbi) ?
+                       ZONED_PIN_SEC_REQUIRED_COUNT :
+                       GET_SEC_FROM_SEG(sbi, overprovision_segments(sbi)))) {
+                       f2fs_down_write(&sbi->gc_lock);
+                       stat_inc_gc_call_count(sbi, FOREGROUND);
+                       err = f2fs_gc(sbi, &gc_control);
+-                      if (err && err != -ENODATA)
++                      if (err && err != -ENODATA) {
++                              f2fs_up_write(&sbi->pin_sem);
+                               goto out_err;
++                      }
+               }
+-              f2fs_down_write(&sbi->pin_sem);
+-
+               err = f2fs_allocate_pinning_section(sbi);
+               if (err) {
+                       f2fs_up_write(&sbi->pin_sem);
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index c282e8a0a2ec1..6ebe25eafafa5 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -2806,7 +2806,7 @@ static int get_new_segment(struct f2fs_sb_info *sbi,
+                                                       MAIN_SECS(sbi));
+               if (secno >= MAIN_SECS(sbi)) {
+                       ret = -ENOSPC;
+-                      f2fs_bug_on(sbi, 1);
++                      f2fs_bug_on(sbi, !pinning);
+                       goto out_unlock;
+               }
+       }
+@@ -2848,7 +2848,7 @@ static int get_new_segment(struct f2fs_sb_info *sbi,
+ out_unlock:
+       spin_unlock(&free_i->segmap_lock);
+-      if (ret == -ENOSPC)
++      if (ret == -ENOSPC && !pinning)
+               f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_NO_SEGMENT);
+       return ret;
+ }
+@@ -2921,6 +2921,13 @@ static unsigned int __get_next_segno(struct f2fs_sb_info *sbi, int type)
+       return curseg->segno;
+ }
++static void reset_curseg_fields(struct curseg_info *curseg)
++{
++      curseg->inited = false;
++      curseg->segno = NULL_SEGNO;
++      curseg->next_segno = 0;
++}
++
+ /*
+  * Allocate a current working segment.
+  * This function always allocates a free segment in LFS manner.
+@@ -2939,7 +2946,7 @@ static int new_curseg(struct f2fs_sb_info *sbi, int type, bool new_sec)
+       ret = get_new_segment(sbi, &segno, new_sec, pinning);
+       if (ret) {
+               if (ret == -ENOSPC)
+-                      curseg->segno = NULL_SEGNO;
++                      reset_curseg_fields(curseg);
+               return ret;
+       }
+@@ -3710,13 +3717,6 @@ static void f2fs_randomize_chunk(struct f2fs_sb_info *sbi,
+               get_random_u32_inclusive(1, sbi->max_fragment_hole);
+ }
+-static void reset_curseg_fields(struct curseg_info *curseg)
+-{
+-      curseg->inited = false;
+-      curseg->segno = NULL_SEGNO;
+-      curseg->next_segno = 0;
+-}
+-
+ int f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
+               block_t old_blkaddr, block_t *new_blkaddr,
+               struct f2fs_summary *sum, int type,
+-- 
+2.39.5
+
diff --git a/queue-6.14/f2fs-fix-to-avoid-running-out-of-free-segments.patch b/queue-6.14/f2fs-fix-to-avoid-running-out-of-free-segments.patch
new file mode 100644 (file)
index 0000000..7b619af
--- /dev/null
@@ -0,0 +1,63 @@
+From 629a19dd61c5085f59fedd02978760b3208cfa91 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Mar 2025 17:01:25 +0800
+Subject: f2fs: fix to avoid running out of free segments
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit f7f8932ca6bb22494ef6db671633ad3b4d982271 ]
+
+If checkpoint is disabled, GC can not reclaim any segments, we need
+to detect such condition and bail out from fallocate() of a pinfile,
+rather than letting allocator running out of free segment, which may
+cause f2fs to be shutdown.
+
+reproducer:
+mkfs.f2fs -f /dev/vda 16777216
+mount -o checkpoint=disable:10% /dev/vda /mnt/f2fs
+for ((i=0;i<4096;i++)) do { dd if=/dev/zero of=/mnt/f2fs/$i bs=1M count=1; } done
+sync
+for ((i=0;i<4096;i+=2)) do { rm /mnt/f2fs/$i; } done
+sync
+touch /mnt/f2fs/pinfile
+f2fs_io pinfile set /mnt/f2fs/pinfile
+f2fs_io fallocate 0 0 4201644032 /mnt/f2fs/pinfile
+
+cat /sys/kernel/debug/f2fs/status
+output:
+  - Free: 0 (0)
+
+Fixes: f5a53edcf01e ("f2fs: support aligned pinned file")
+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/file.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 1bb70499ab598..44a658662462d 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -1836,6 +1836,18 @@ static int f2fs_expand_inode_data(struct inode *inode, loff_t offset,
+ next_alloc:
+               f2fs_down_write(&sbi->pin_sem);
++              if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) {
++                      if (has_not_enough_free_secs(sbi, 0, 0)) {
++                              f2fs_up_write(&sbi->pin_sem);
++                              err = -ENOSPC;
++                              f2fs_warn_ratelimited(sbi,
++                                      "ino:%lu, start:%lu, end:%lu, need to trigger GC to "
++                                      "reclaim enough free segment when checkpoint is enabled",
++                                      inode->i_ino, pg_start, pg_end);
++                              goto out_err;
++                      }
++              }
++
+               if (has_not_enough_free_secs(sbi, 0, f2fs_sb_has_blkzoned(sbi) ?
+                       ZONED_PIN_SEC_REQUIRED_COUNT :
+                       GET_SEC_FROM_SEG(sbi, overprovision_segments(sbi)))) {
+-- 
+2.39.5
+
diff --git a/queue-6.14/f2fs-fix-to-call-f2fs_recover_quota_end-correctly.patch b/queue-6.14/f2fs-fix-to-call-f2fs_recover_quota_end-correctly.patch
new file mode 100644 (file)
index 0000000..3188581
--- /dev/null
@@ -0,0 +1,40 @@
+From 077e9591077e9c1c9f7373aff11075597a422209 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Mar 2025 11:25:00 +0800
+Subject: f2fs: fix to call f2fs_recover_quota_end() correctly
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit d8f5b91d77a651705d3f76ba0ebd5d7981533333 ]
+
+f2fs_recover_quota_begin() and f2fs_recover_quota_end() should be called
+in pair, there is some cases we may skip calling f2fs_recover_quota_end(),
+fix it.
+
+Fixes: e1bb7d3d9cbf ("f2fs: fix to recover quota data correctly")
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/super.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index 1beff52ae80b3..26b1021427ae0 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -4800,10 +4800,10 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
+               }
+       }
++reset_checkpoint:
+ #ifdef CONFIG_QUOTA
+       f2fs_recover_quota_end(sbi, quota_enabled);
+ #endif
+-reset_checkpoint:
+       /*
+        * If the f2fs is not readonly and fsync data recovery succeeds,
+        * write pointer consistency of cursegs and other zones are already
+-- 
+2.39.5
+
diff --git a/queue-6.14/f2fs-fix-to-set-.discard_granularity-correctly.patch b/queue-6.14/f2fs-fix-to-set-.discard_granularity-correctly.patch
new file mode 100644 (file)
index 0000000..b2fe55f
--- /dev/null
@@ -0,0 +1,46 @@
+From 7c9b5e269fa0d03c0e62b4f3638fb2157027ef01 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Feb 2025 14:20:07 +0800
+Subject: f2fs: fix to set .discard_granularity correctly
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 1b60b23975d6d81703826e3797738e471c3009c6 ]
+
+commit 4f993264fe29 ("f2fs: introduce discard_unit mount option") introduced
+a bug, when we enable discard_unit=section option, it will set
+.discard_granularity to BLKS_PER_SEC(), however discard granularity only
+supports [1, 512], once section size is not equal to segment size, it will
+cause issue_discard_thread() in DPOLICY_BG mode will not select discard entry
+w/ any granularity to issue.
+
+Fixes: 4f993264fe29 ("f2fs: introduce discard_unit mount option")
+Reviewed-by: Daeho Jeong <daehojeong@google.com>
+Signed-off-by: Yohan Joung <yohan.joung@sk.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/segment.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index 6ebe25eafafa5..2b415926641f0 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -2320,10 +2320,9 @@ static int create_discard_cmd_control(struct f2fs_sb_info *sbi)
+       dcc->discard_granularity = DEFAULT_DISCARD_GRANULARITY;
+       dcc->max_ordered_discard = DEFAULT_MAX_ORDERED_DISCARD_GRANULARITY;
+       dcc->discard_io_aware = DPOLICY_IO_AWARE_ENABLE;
+-      if (F2FS_OPTION(sbi).discard_unit == DISCARD_UNIT_SEGMENT)
++      if (F2FS_OPTION(sbi).discard_unit == DISCARD_UNIT_SEGMENT ||
++              F2FS_OPTION(sbi).discard_unit == DISCARD_UNIT_SECTION)
+               dcc->discard_granularity = BLKS_PER_SEG(sbi);
+-      else if (F2FS_OPTION(sbi).discard_unit == DISCARD_UNIT_SECTION)
+-              dcc->discard_granularity = BLKS_PER_SEC(sbi);
+       INIT_LIST_HEAD(&dcc->entry_list);
+       for (i = 0; i < MAX_PLIST_NUM; i++)
+-- 
+2.39.5
+
diff --git a/queue-6.14/f2fs-quota-fix-to-avoid-warning-in-dquot_writeback_d.patch b/queue-6.14/f2fs-quota-fix-to-avoid-warning-in-dquot_writeback_d.patch
new file mode 100644 (file)
index 0000000..f04c763
--- /dev/null
@@ -0,0 +1,335 @@
+From 5b80e8732f7280ffa5ab74857f686c2692e38128 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Feb 2025 10:33:21 +0800
+Subject: f2fs: quota: fix to avoid warning in dquot_writeback_dquots()
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit eb85c2410d6f581e957cd03a644ff6ddbe592af9 ]
+
+F2FS-fs (dm-59): checkpoint=enable has some unwritten data.
+
+------------[ cut here ]------------
+WARNING: CPU: 6 PID: 8013 at fs/quota/dquot.c:691 dquot_writeback_dquots+0x2fc/0x308
+pc : dquot_writeback_dquots+0x2fc/0x308
+lr : f2fs_quota_sync+0xcc/0x1c4
+Call trace:
+dquot_writeback_dquots+0x2fc/0x308
+f2fs_quota_sync+0xcc/0x1c4
+f2fs_write_checkpoint+0x3d4/0x9b0
+f2fs_issue_checkpoint+0x1bc/0x2c0
+f2fs_sync_fs+0x54/0x150
+f2fs_do_sync_file+0x2f8/0x814
+__f2fs_ioctl+0x1960/0x3244
+f2fs_ioctl+0x54/0xe0
+__arm64_sys_ioctl+0xa8/0xe4
+invoke_syscall+0x58/0x114
+
+checkpoint and f2fs_remount may race as below, resulting triggering warning
+in dquot_writeback_dquots().
+
+atomic write                                    remount
+                                                - do_remount
+                                                 - down_write(&sb->s_umount);
+                                                  - f2fs_remount
+- ioctl
+ - f2fs_do_sync_file
+  - f2fs_sync_fs
+   - f2fs_write_checkpoint
+    - block_operations
+     - locked = down_read_trylock(&sbi->sb->s_umount)
+       : fail to lock due to the write lock was held by remount
+                                                 - up_write(&sb->s_umount);
+     - f2fs_quota_sync
+      - dquot_writeback_dquots
+       - WARN_ON_ONCE(!rwsem_is_locked(&sb->s_umount))
+       : trigger warning because s_umount lock was unlocked by remount
+
+If checkpoint comes from mount/umount/remount/freeze/quotactl, caller of
+checkpoint has already held s_umount lock, calling dquot_writeback_dquots()
+in the context should be safe.
+
+So let's record task to sbi->umount_lock_holder, so that checkpoint can
+know whether the lock has held in the context or not by checking current
+w/ it.
+
+In addition, in order to not misrepresent caller of checkpoint, we should
+not allow to trigger async checkpoint for those callers: mount/umount/remount/
+freeze/quotactl.
+
+Fixes: af033b2aa8a8 ("f2fs: guarantee journalled quota data by checkpoint")
+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/checkpoint.c | 15 ++++++----
+ fs/f2fs/f2fs.h       |  3 +-
+ fs/f2fs/super.c      | 65 ++++++++++++++++++++++++++++++++++----------
+ 3 files changed, 61 insertions(+), 22 deletions(-)
+
+diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
+index efda9a0229816..bd890738b94d7 100644
+--- a/fs/f2fs/checkpoint.c
++++ b/fs/f2fs/checkpoint.c
+@@ -1237,7 +1237,7 @@ static int block_operations(struct f2fs_sb_info *sbi)
+ retry_flush_quotas:
+       f2fs_lock_all(sbi);
+       if (__need_flush_quota(sbi)) {
+-              int locked;
++              bool need_lock = sbi->umount_lock_holder != current;
+               if (++cnt > DEFAULT_RETRY_QUOTA_FLUSH_COUNT) {
+                       set_sbi_flag(sbi, SBI_QUOTA_SKIP_FLUSH);
+@@ -1246,11 +1246,13 @@ static int block_operations(struct f2fs_sb_info *sbi)
+               }
+               f2fs_unlock_all(sbi);
+-              /* only failed during mount/umount/freeze/quotactl */
+-              locked = down_read_trylock(&sbi->sb->s_umount);
+-              f2fs_quota_sync(sbi->sb, -1);
+-              if (locked)
++              /* don't grab s_umount lock during mount/umount/remount/freeze/quotactl */
++              if (!need_lock) {
++                      f2fs_do_quota_sync(sbi->sb, -1);
++              } else if (down_read_trylock(&sbi->sb->s_umount)) {
++                      f2fs_do_quota_sync(sbi->sb, -1);
+                       up_read(&sbi->sb->s_umount);
++              }
+               cond_resched();
+               goto retry_flush_quotas;
+       }
+@@ -1867,7 +1869,8 @@ int f2fs_issue_checkpoint(struct f2fs_sb_info *sbi)
+       struct cp_control cpc;
+       cpc.reason = __get_cp_reason(sbi);
+-      if (!test_opt(sbi, MERGE_CHECKPOINT) || cpc.reason != CP_SYNC) {
++      if (!test_opt(sbi, MERGE_CHECKPOINT) || cpc.reason != CP_SYNC ||
++              sbi->umount_lock_holder == current) {
+               int ret;
+               f2fs_down_write(&sbi->gc_lock);
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 1afa7be16e7da..493dda2d4b663 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -1659,6 +1659,7 @@ struct f2fs_sb_info {
+       unsigned int nquota_files;              /* # of quota sysfile */
+       struct f2fs_rwsem quota_sem;            /* blocking cp for flags */
++      struct task_struct *umount_lock_holder; /* s_umount lock holder */
+       /* # of pages, see count_type */
+       atomic_t nr_pages[NR_COUNT_TYPE];
+@@ -3624,7 +3625,7 @@ int f2fs_inode_dirtied(struct inode *inode, bool sync);
+ void f2fs_inode_synced(struct inode *inode);
+ int f2fs_dquot_initialize(struct inode *inode);
+ int f2fs_enable_quota_files(struct f2fs_sb_info *sbi, bool rdonly);
+-int f2fs_quota_sync(struct super_block *sb, int type);
++int f2fs_do_quota_sync(struct super_block *sb, int type);
+ loff_t max_file_blocks(struct inode *inode);
+ void f2fs_quota_off_umount(struct super_block *sb);
+ void f2fs_save_errors(struct f2fs_sb_info *sbi, unsigned char flag);
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index 19b67828ae325..1beff52ae80b3 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -1737,22 +1737,28 @@ int f2fs_sync_fs(struct super_block *sb, int sync)
+ static int f2fs_freeze(struct super_block *sb)
+ {
++      struct f2fs_sb_info *sbi = F2FS_SB(sb);
++
+       if (f2fs_readonly(sb))
+               return 0;
+       /* IO error happened before */
+-      if (unlikely(f2fs_cp_error(F2FS_SB(sb))))
++      if (unlikely(f2fs_cp_error(sbi)))
+               return -EIO;
+       /* must be clean, since sync_filesystem() was already called */
+-      if (is_sbi_flag_set(F2FS_SB(sb), SBI_IS_DIRTY))
++      if (is_sbi_flag_set(sbi, SBI_IS_DIRTY))
+               return -EINVAL;
++      sbi->umount_lock_holder = current;
++
+       /* Let's flush checkpoints and stop the thread. */
+-      f2fs_flush_ckpt_thread(F2FS_SB(sb));
++      f2fs_flush_ckpt_thread(sbi);
++
++      sbi->umount_lock_holder = NULL;
+       /* to avoid deadlock on f2fs_evict_inode->SB_FREEZE_FS */
+-      set_sbi_flag(F2FS_SB(sb), SBI_IS_FREEZING);
++      set_sbi_flag(sbi, SBI_IS_FREEZING);
+       return 0;
+ }
+@@ -2329,6 +2335,8 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
+       org_mount_opt = sbi->mount_opt;
+       old_sb_flags = sb->s_flags;
++      sbi->umount_lock_holder = current;
++
+ #ifdef CONFIG_QUOTA
+       org_mount_opt.s_jquota_fmt = F2FS_OPTION(sbi).s_jquota_fmt;
+       for (i = 0; i < MAXQUOTAS; i++) {
+@@ -2552,6 +2560,8 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
+       limit_reserve_root(sbi);
+       *flags = (*flags & ~SB_LAZYTIME) | (sb->s_flags & SB_LAZYTIME);
++
++      sbi->umount_lock_holder = NULL;
+       return 0;
+ restore_checkpoint:
+       if (need_enable_checkpoint) {
+@@ -2592,6 +2602,8 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
+ #endif
+       sbi->mount_opt = org_mount_opt;
+       sb->s_flags = old_sb_flags;
++
++      sbi->umount_lock_holder = NULL;
+       return err;
+ }
+@@ -2908,7 +2920,7 @@ static int f2fs_quota_sync_file(struct f2fs_sb_info *sbi, int type)
+       return ret;
+ }
+-int f2fs_quota_sync(struct super_block *sb, int type)
++int f2fs_do_quota_sync(struct super_block *sb, int type)
+ {
+       struct f2fs_sb_info *sbi = F2FS_SB(sb);
+       struct quota_info *dqopt = sb_dqopt(sb);
+@@ -2956,11 +2968,21 @@ int f2fs_quota_sync(struct super_block *sb, int type)
+       return ret;
+ }
++static int f2fs_quota_sync(struct super_block *sb, int type)
++{
++      int ret;
++
++      F2FS_SB(sb)->umount_lock_holder = current;
++      ret = f2fs_do_quota_sync(sb, type);
++      F2FS_SB(sb)->umount_lock_holder = NULL;
++      return ret;
++}
++
+ static int f2fs_quota_on(struct super_block *sb, int type, int format_id,
+                                                       const struct path *path)
+ {
+       struct inode *inode;
+-      int err;
++      int err = 0;
+       /* if quota sysfile exists, deny enabling quota with specific file */
+       if (f2fs_sb_has_quota_ino(F2FS_SB(sb))) {
+@@ -2971,31 +2993,34 @@ static int f2fs_quota_on(struct super_block *sb, int type, int format_id,
+       if (path->dentry->d_sb != sb)
+               return -EXDEV;
+-      err = f2fs_quota_sync(sb, type);
++      F2FS_SB(sb)->umount_lock_holder = current;
++
++      err = f2fs_do_quota_sync(sb, type);
+       if (err)
+-              return err;
++              goto out;
+       inode = d_inode(path->dentry);
+       err = filemap_fdatawrite(inode->i_mapping);
+       if (err)
+-              return err;
++              goto out;
+       err = filemap_fdatawait(inode->i_mapping);
+       if (err)
+-              return err;
++              goto out;
+       err = dquot_quota_on(sb, type, format_id, path);
+       if (err)
+-              return err;
++              goto out;
+       inode_lock(inode);
+       F2FS_I(inode)->i_flags |= F2FS_QUOTA_DEFAULT_FL;
+       f2fs_set_inode_flags(inode);
+       inode_unlock(inode);
+       f2fs_mark_inode_dirty_sync(inode, false);
+-
+-      return 0;
++out:
++      F2FS_SB(sb)->umount_lock_holder = NULL;
++      return err;
+ }
+ static int __f2fs_quota_off(struct super_block *sb, int type)
+@@ -3006,7 +3031,7 @@ static int __f2fs_quota_off(struct super_block *sb, int type)
+       if (!inode || !igrab(inode))
+               return dquot_quota_off(sb, type);
+-      err = f2fs_quota_sync(sb, type);
++      err = f2fs_do_quota_sync(sb, type);
+       if (err)
+               goto out_put;
+@@ -3029,6 +3054,8 @@ static int f2fs_quota_off(struct super_block *sb, int type)
+       struct f2fs_sb_info *sbi = F2FS_SB(sb);
+       int err;
++      F2FS_SB(sb)->umount_lock_holder = current;
++
+       err = __f2fs_quota_off(sb, type);
+       /*
+@@ -3038,6 +3065,9 @@ static int f2fs_quota_off(struct super_block *sb, int type)
+        */
+       if (is_journalled_quota(sbi))
+               set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR);
++
++      F2FS_SB(sb)->umount_lock_holder = NULL;
++
+       return err;
+ }
+@@ -3170,7 +3200,7 @@ int f2fs_dquot_initialize(struct inode *inode)
+       return 0;
+ }
+-int f2fs_quota_sync(struct super_block *sb, int type)
++int f2fs_do_quota_sync(struct super_block *sb, int type)
+ {
+       return 0;
+ }
+@@ -4703,6 +4733,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
+       if (err)
+               goto free_compress_inode;
++      sbi->umount_lock_holder = current;
+ #ifdef CONFIG_QUOTA
+       /* Enable quota usage during mount */
+       if (f2fs_sb_has_quota_ino(sbi) && !f2fs_readonly(sb)) {
+@@ -4829,6 +4860,8 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
+       f2fs_update_time(sbi, CP_TIME);
+       f2fs_update_time(sbi, REQ_TIME);
+       clear_sbi_flag(sbi, SBI_CP_DISABLED_QUICK);
++
++      sbi->umount_lock_holder = NULL;
+       return 0;
+ sync_free_meta:
+@@ -4931,6 +4964,8 @@ static void kill_f2fs_super(struct super_block *sb)
+       struct f2fs_sb_info *sbi = F2FS_SB(sb);
+       if (sb->s_root) {
++              sbi->umount_lock_holder = current;
++
+               set_sbi_flag(sbi, SBI_IS_CLOSE);
+               f2fs_stop_gc_thread(sbi);
+               f2fs_stop_discard_thread(sbi);
+-- 
+2.39.5
+
diff --git a/queue-6.14/fbdev-au1100fb-move-a-variable-assignment-behind-a-n.patch b/queue-6.14/fbdev-au1100fb-move-a-variable-assignment-behind-a-n.patch
new file mode 100644 (file)
index 0000000..79435b3
--- /dev/null
@@ -0,0 +1,52 @@
+From 68d9da34a2d9d9b443bfbc268011f9bf050dc7c1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Apr 2023 21:35:36 +0200
+Subject: fbdev: au1100fb: Move a variable assignment behind a null pointer
+ check
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Markus Elfring <elfring@users.sourceforge.net>
+
+[ Upstream commit 2df2c0caaecfd869b49e14f2b8df822397c5dd7f ]
+
+The address of a data structure member was determined before
+a corresponding null pointer check in the implementation of
+the function “au1100fb_setmode”.
+
+This issue was detected by using the Coccinelle software.
+
+Fixes: 3b495f2bb749 ("Au1100 FB driver uplift for 2.6.")
+Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
+Acked-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/au1100fb.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/video/fbdev/au1100fb.c b/drivers/video/fbdev/au1100fb.c
+index 840f221607635..6251a6b07b3a1 100644
+--- a/drivers/video/fbdev/au1100fb.c
++++ b/drivers/video/fbdev/au1100fb.c
+@@ -137,13 +137,15 @@ static int au1100fb_fb_blank(int blank_mode, struct fb_info *fbi)
+        */
+ int au1100fb_setmode(struct au1100fb_device *fbdev)
+ {
+-      struct fb_info *info = &fbdev->info;
++      struct fb_info *info;
+       u32 words;
+       int index;
+       if (!fbdev)
+               return -EINVAL;
++      info = &fbdev->info;
++
+       /* Update var-dependent FB info */
+       if (panel_is_active(fbdev->panel) || panel_is_color(fbdev->panel)) {
+               if (info->var.bits_per_pixel <= 8) {
+-- 
+2.39.5
+
diff --git a/queue-6.14/fbdev-sm501fb-add-some-geometry-checks.patch b/queue-6.14/fbdev-sm501fb-add-some-geometry-checks.patch
new file mode 100644 (file)
index 0000000..dd31ad1
--- /dev/null
@@ -0,0 +1,44 @@
+From b9e251f45794be17cb98b049652d85d8df231127 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Mar 2025 01:30:11 +0000
+Subject: fbdev: sm501fb: Add some geometry checks.
+
+From: Danila Chernetsov <listdansp@mail.ru>
+
+[ Upstream commit aee50bd88ea5fde1ff4cc021385598f81a65830c ]
+
+Added checks for xoffset, yoffset settings.
+Incorrect settings of these parameters can lead to errors
+in sm501fb_pan_ functions.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: 5fc404e47bdf ("[PATCH] fb: SM501 framebuffer driver")
+Signed-off-by: Danila Chernetsov <listdansp@mail.ru>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/sm501fb.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/video/fbdev/sm501fb.c b/drivers/video/fbdev/sm501fb.c
+index 7734377b2d87b..ed6f4f43e2d52 100644
+--- a/drivers/video/fbdev/sm501fb.c
++++ b/drivers/video/fbdev/sm501fb.c
+@@ -327,6 +327,13 @@ static int sm501fb_check_var(struct fb_var_screeninfo *var,
+       if (var->xres_virtual > 4096 || var->yres_virtual > 2048)
+               return -EINVAL;
++      /* geometry sanity checks */
++      if (var->xres + var->xoffset > var->xres_virtual)
++              return -EINVAL;
++
++      if (var->yres + var->yoffset > var->yres_virtual)
++              return -EINVAL;
++
+       /* can cope with 8,16 or 32bpp */
+       if (var->bits_per_pixel <= 8)
+-- 
+2.39.5
+
diff --git a/queue-6.14/firmware-arm_ffa-explicitly-cast-return-value-from-f.patch b/queue-6.14/firmware-arm_ffa-explicitly-cast-return-value-from-f.patch
new file mode 100644 (file)
index 0000000..f604e4e
--- /dev/null
@@ -0,0 +1,46 @@
+From 4e874672303a2a66d44c2843124d08bf39621035 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Feb 2025 09:56:31 +0000
+Subject: firmware: arm_ffa: Explicitly cast return value from FFA_VERSION
+ before comparison
+
+From: Sudeep Holla <sudeep.holla@arm.com>
+
+[ Upstream commit cecf6a504137aa238d768ae440a1f6488cb2f436 ]
+
+The return value ver.a0 is unsigned long type and FFA_RET_NOT_SUPPORTED
+is a negative value.
+
+Since the return value from the firmware can be just 32-bit even on
+64-bit systems as FFA specification mentions it as int32 error code in
+w0 register, explicitly casting to s32 ensures correct sign interpretation
+when comparing against a signed error code FFA_RET_NOT_SUPPORTED.
+
+Without casting, comparison between unsigned long and a negative
+constant could lead to unintended results due to type promotions.
+
+Fixes: 3bbfe9871005 ("firmware: arm_ffa: Add initial Arm FFA driver support")
+Reported-by: Andrei Homescu <ahomescu@google.com>
+Message-Id: <20250221095633.506678-1-sudeep.holla@arm.com>
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_ffa/driver.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
+index 8aa05bbab5c8d..ce1ec015e076b 100644
+--- a/drivers/firmware/arm_ffa/driver.c
++++ b/drivers/firmware/arm_ffa/driver.c
+@@ -145,7 +145,7 @@ static int ffa_version_check(u32 *version)
+                     .a0 = FFA_VERSION, .a1 = FFA_DRIVER_VERSION,
+                     }, &ver);
+-      if (ver.a0 == FFA_RET_NOT_SUPPORTED) {
++      if ((s32)ver.a0 == FFA_RET_NOT_SUPPORTED) {
+               pr_info("FFA_VERSION returned not supported\n");
+               return -EOPNOTSUPP;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/firmware-arm_ffa-explicitly-cast-return-value-from-n.patch b/queue-6.14/firmware-arm_ffa-explicitly-cast-return-value-from-n.patch
new file mode 100644 (file)
index 0000000..4620c8e
--- /dev/null
@@ -0,0 +1,46 @@
+From a17458e55b2ade0385ccc1827840b8a350dd3dac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Feb 2025 09:56:32 +0000
+Subject: firmware: arm_ffa: Explicitly cast return value from
+ NOTIFICATION_INFO_GET
+
+From: Sudeep Holla <sudeep.holla@arm.com>
+
+[ Upstream commit 3e282f41585c4dd49b688bd6395fd6f21a57c9f7 ]
+
+The return value ret.a2 is of type unsigned long and FFA_RET_NO_DATA is
+a negative value.
+
+Since the return value from the firmware can be just 32-bit even on
+64-bit systems as FFA specification mentions it as int32 error code in
+w0 register, explicitly casting to s32 ensures correct sign interpretation
+when comparing against a signed error code FFA_RET_NO_DATA.
+
+Without casting, comparison between unsigned long and a negative
+constant could lead to unintended results due to type promotions.
+
+Fixes: 3522be48d82b ("firmware: arm_ffa: Implement the NOTIFICATION_INFO_GET interface")
+Reported-by: Andrei Homescu <ahomescu@google.com>
+Message-Id: <20250221095633.506678-2-sudeep.holla@arm.com>
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_ffa/driver.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
+index ce1ec015e076b..25b52acae4662 100644
+--- a/drivers/firmware/arm_ffa/driver.c
++++ b/drivers/firmware/arm_ffa/driver.c
+@@ -899,7 +899,7 @@ static void ffa_notification_info_get(void)
+                         }, &ret);
+               if (ret.a0 != FFA_FN_NATIVE(SUCCESS) && ret.a0 != FFA_SUCCESS) {
+-                      if (ret.a2 != FFA_RET_NO_DATA)
++                      if ((s32)ret.a2 != FFA_RET_NO_DATA)
+                               pr_err("Notification Info fetch failed: 0x%lx (0x%lx)",
+                                      ret.a0, ret.a2);
+                       return;
+-- 
+2.39.5
+
diff --git a/queue-6.14/firmware-arm_ffa-refactor-addition-of-partition-info.patch b/queue-6.14/firmware-arm_ffa-refactor-addition-of-partition-info.patch
new file mode 100644 (file)
index 0000000..13114b5
--- /dev/null
@@ -0,0 +1,103 @@
+From 9e230bbe11f5387cf82f2f2a92dbc982417d4469 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 15:38:47 +0000
+Subject: firmware: arm_ffa: Refactor addition of partition information into
+ XArray
+
+From: Viresh Kumar <viresh.kumar@linaro.org>
+
+[ Upstream commit 3c3d6767466ea316869c9f2bdd976aec8ce44545 ]
+
+Move the common code handling addition of the FF-A partition information
+into the XArray as a new routine. No functional change.
+
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Message-Id: <20250217-ffa_updates-v3-6-bd1d9de615e7@arm.com>
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Stable-dep-of: 46dcd68aacca ("firmware: arm_ffa: Unregister the FF-A devices when cleaning up the partitions")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_ffa/driver.c | 47 +++++++++++++++----------------
+ 1 file changed, 22 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
+index 2c2ec3c35f156..353900c33eee3 100644
+--- a/drivers/firmware/arm_ffa/driver.c
++++ b/drivers/firmware/arm_ffa/driver.c
+@@ -1384,11 +1384,30 @@ static struct notifier_block ffa_bus_nb = {
+       .notifier_call = ffa_bus_notifier,
+ };
++static int ffa_xa_add_partition_info(int vm_id)
++{
++      struct ffa_dev_part_info *info;
++      int ret;
++
++      info = kzalloc(sizeof(*info), GFP_KERNEL);
++      if (!info)
++              return -ENOMEM;
++
++      rwlock_init(&info->rw_lock);
++      ret = xa_insert(&drv_info->partition_info, vm_id, info, GFP_KERNEL);
++      if (ret) {
++              pr_err("%s: failed to save partition ID 0x%x - ret:%d. Abort.\n",
++                     __func__, vm_id, ret);
++              kfree(info);
++      }
++
++      return ret;
++}
++
+ static int ffa_setup_partitions(void)
+ {
+       int count, idx, ret;
+       struct ffa_device *ffa_dev;
+-      struct ffa_dev_part_info *info;
+       struct ffa_partition_info *pbuf, *tpbuf;
+       if (drv_info->version == FFA_VERSION_1_0) {
+@@ -1422,39 +1441,17 @@ static int ffa_setup_partitions(void)
+                   !(tpbuf->properties & FFA_PARTITION_AARCH64_EXEC))
+                       ffa_mode_32bit_set(ffa_dev);
+-              info = kzalloc(sizeof(*info), GFP_KERNEL);
+-              if (!info) {
++              if (ffa_xa_add_partition_info(ffa_dev->vm_id)) {
+                       ffa_device_unregister(ffa_dev);
+                       continue;
+               }
+-              rwlock_init(&info->rw_lock);
+-              ret = xa_insert(&drv_info->partition_info, tpbuf->id,
+-                              info, GFP_KERNEL);
+-              if (ret) {
+-                      pr_err("%s: failed to save partition ID 0x%x - ret:%d\n",
+-                             __func__, tpbuf->id, ret);
+-                      ffa_device_unregister(ffa_dev);
+-                      kfree(info);
+-              }
+       }
+       kfree(pbuf);
+       /* Allocate for the host */
+-      info = kzalloc(sizeof(*info), GFP_KERNEL);
+-      if (!info) {
+-              /* Already registered devices are freed on bus_exit */
+-              ffa_partitions_cleanup();
+-              return -ENOMEM;
+-      }
+-
+-      rwlock_init(&info->rw_lock);
+-      ret = xa_insert(&drv_info->partition_info, drv_info->vm_id,
+-                      info, GFP_KERNEL);
++      ret = ffa_xa_add_partition_info(drv_info->vm_id);
+       if (ret) {
+-              pr_err("%s: failed to save Host partition ID 0x%x - ret:%d. Abort.\n",
+-                     __func__, drv_info->vm_id, ret);
+-              kfree(info);
+               /* Already registered devices are freed on bus_exit */
+               ffa_partitions_cleanup();
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/firmware-arm_ffa-skip-the-first-partition-id-when-pa.patch b/queue-6.14/firmware-arm_ffa-skip-the-first-partition-id-when-pa.patch
new file mode 100644 (file)
index 0000000..d6c6738
--- /dev/null
@@ -0,0 +1,42 @@
+From cc35797aae950253d5e40b90aa505b5c9621a495 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 Feb 2025 21:39:09 +0000
+Subject: firmware: arm_ffa: Skip the first/partition ID when parsing vCPU list
+
+From: Sudeep Holla <sudeep.holla@arm.com>
+
+[ Upstream commit c67c2332f8c80b03990914dfb66950c8d2fb87d8 ]
+
+The FF-A notification id list received in response to the call
+FFA_NOTIFICATION_INFO_GET is encoded as: partition ID followed by 0 or
+more vCPU ID. The count includes all of them.
+
+Fix the issue by skipping the first/partition ID so that only the list
+of vCPU IDs are processed correctly for a given partition ID. The first/
+partition ID is read before the start of the loop.
+
+Fixes: 3522be48d82b ("firmware: arm_ffa: Implement the NOTIFICATION_INFO_GET interface")
+Reported-by: Andrei Homescu <ahomescu@google.com>
+Message-Id: <20250223213909.1197786-1-sudeep.holla@arm.com>
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_ffa/driver.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
+index 25b52acae4662..655672a880959 100644
+--- a/drivers/firmware/arm_ffa/driver.c
++++ b/drivers/firmware/arm_ffa/driver.c
+@@ -935,7 +935,7 @@ static void ffa_notification_info_get(void)
+                       }
+                       /* Per vCPU Notification */
+-                      for (idx = 0; idx < ids_count[list]; idx++) {
++                      for (idx = 1; idx < ids_count[list]; idx++) {
+                               if (ids_processed >= max_ids - 1)
+                                       break;
+-- 
+2.39.5
+
diff --git a/queue-6.14/firmware-arm_ffa-unregister-the-ff-a-devices-when-cl.patch b/queue-6.14/firmware-arm_ffa-unregister-the-ff-a-devices-when-cl.patch
new file mode 100644 (file)
index 0000000..23ca225
--- /dev/null
@@ -0,0 +1,100 @@
+From 7920b99227df2ef3bff852a28108e0d7c0200b06 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 15:38:49 +0000
+Subject: firmware: arm_ffa: Unregister the FF-A devices when cleaning up the
+ partitions
+
+From: Sudeep Holla <sudeep.holla@arm.com>
+
+[ Upstream commit 46dcd68aaccac0812c12ec3f4e59c8963e2760ad ]
+
+Both the FF-A core and the bus were in a single module before the
+commit 18c250bd7ed0 ("firmware: arm_ffa: Split bus and driver into distinct modules").
+
+The arm_ffa_bus_exit() takes care of unregistering all the FF-A devices.
+Now that there are 2 distinct modules, if the core driver is unloaded and
+reloaded, it will end up adding duplicate FF-A devices as the previously
+registered devices weren't unregistered when we cleaned up the modules.
+
+Fix the same by unregistering all the FF-A devices on the FF-A bus during
+the cleaning up of the partitions and hence the cleanup of the module.
+
+Fixes: 18c250bd7ed0 ("firmware: arm_ffa: Split bus and driver into distinct modules")
+Tested-by: Viresh Kumar <viresh.kumar@linaro.org>
+Message-Id: <20250217-ffa_updates-v3-8-bd1d9de615e7@arm.com>
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_ffa/bus.c    | 3 ++-
+ drivers/firmware/arm_ffa/driver.c | 7 ++++---
+ include/linux/arm_ffa.h           | 3 +++
+ 3 files changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/firmware/arm_ffa/bus.c b/drivers/firmware/arm_ffa/bus.c
+index dfda5ffc14db7..fa09a82b44921 100644
+--- a/drivers/firmware/arm_ffa/bus.c
++++ b/drivers/firmware/arm_ffa/bus.c
+@@ -160,11 +160,12 @@ static int __ffa_devices_unregister(struct device *dev, void *data)
+       return 0;
+ }
+-static void ffa_devices_unregister(void)
++void ffa_devices_unregister(void)
+ {
+       bus_for_each_dev(&ffa_bus_type, NULL, NULL,
+                        __ffa_devices_unregister);
+ }
++EXPORT_SYMBOL_GPL(ffa_devices_unregister);
+ bool ffa_device_is_valid(struct ffa_device *ffa_dev)
+ {
+diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
+index 353900c33eee3..8aa05bbab5c8d 100644
+--- a/drivers/firmware/arm_ffa/driver.c
++++ b/drivers/firmware/arm_ffa/driver.c
+@@ -1451,10 +1451,8 @@ static int ffa_setup_partitions(void)
+       /* Allocate for the host */
+       ret = ffa_xa_add_partition_info(drv_info->vm_id);
+-      if (ret) {
+-              /* Already registered devices are freed on bus_exit */
++      if (ret)
+               ffa_partitions_cleanup();
+-      }
+       return ret;
+ }
+@@ -1464,6 +1462,9 @@ static void ffa_partitions_cleanup(void)
+       struct ffa_dev_part_info *info;
+       unsigned long idx;
++      /* Clean up/free all registered devices */
++      ffa_devices_unregister();
++
+       xa_for_each(&drv_info->partition_info, idx, info) {
+               xa_erase(&drv_info->partition_info, idx);
+               kfree(info);
+diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h
+index 74169dd0f6594..53f2837ce7df4 100644
+--- a/include/linux/arm_ffa.h
++++ b/include/linux/arm_ffa.h
+@@ -176,6 +176,7 @@ void ffa_device_unregister(struct ffa_device *ffa_dev);
+ int ffa_driver_register(struct ffa_driver *driver, struct module *owner,
+                       const char *mod_name);
+ void ffa_driver_unregister(struct ffa_driver *driver);
++void ffa_devices_unregister(void);
+ bool ffa_device_is_valid(struct ffa_device *ffa_dev);
+ #else
+@@ -188,6 +189,8 @@ ffa_device_register(const struct ffa_partition_info *part_info,
+ static inline void ffa_device_unregister(struct ffa_device *dev) {}
++static inline void ffa_devices_unregister(void) {}
++
+ static inline int
+ ffa_driver_register(struct ffa_driver *driver, struct module *owner,
+                   const char *mod_name)
+-- 
+2.39.5
+
diff --git a/queue-6.14/firmware-arm_scmi-use-ioread64-instead-of-ioread64_h.patch b/queue-6.14/firmware-arm_scmi-use-ioread64-instead-of-ioread64_h.patch
new file mode 100644 (file)
index 0000000..726bb23
--- /dev/null
@@ -0,0 +1,53 @@
+From 9a6febb54c3a7e384bb12a8a64d39d7df2204645 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Mar 2025 15:43:34 +0100
+Subject: firmware: arm_scmi: use ioread64() instead of ioread64_hi_lo()
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 3b8c56d8072750fd9625f03b92d8d6000c98628f ]
+
+The scmi_common_fastchannel_db_ring() function calls either ioread64()
+or ioread64_hi_lo() depending on whether it is compiler for 32-bit
+or 64-bit architectures.
+
+The same logic is used to define ioread64() itself in the
+linux/io-64-nonatomic-hi-lo.h header file, so the special case
+is not really needed.
+
+The behavior here should not change at all.
+
+Fixes: 6f9ea4dabd2d ("firmware: arm_scmi: Generalize the fast channel support")
+Reviewed-by: Sudeep Holla <sudeep.holla@arm.com>
+Link: https://lore.kernel.org/r/20250304144346.1025658-1-arnd@kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_scmi/driver.c | 10 ----------
+ 1 file changed, 10 deletions(-)
+
+diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
+index 60050da54bf24..1c75a4c9c3716 100644
+--- a/drivers/firmware/arm_scmi/driver.c
++++ b/drivers/firmware/arm_scmi/driver.c
+@@ -1997,17 +1997,7 @@ static void scmi_common_fastchannel_db_ring(struct scmi_fc_db_info *db)
+       else if (db->width == 4)
+               SCMI_PROTO_FC_RING_DB(32);
+       else /* db->width == 8 */
+-#ifdef CONFIG_64BIT
+               SCMI_PROTO_FC_RING_DB(64);
+-#else
+-      {
+-              u64 val = 0;
+-
+-              if (db->mask)
+-                      val = ioread64_hi_lo(db->addr) & db->mask;
+-              iowrite64_hi_lo(db->set | val, db->addr);
+-      }
+-#endif
+ }
+ /**
+-- 
+2.39.5
+
diff --git a/queue-6.14/firmware-cs_dsp-ensure-cs_dsp_load-_coeff-returns-0-.patch b/queue-6.14/firmware-cs_dsp-ensure-cs_dsp_load-_coeff-returns-0-.patch
new file mode 100644 (file)
index 0000000..69fb602
--- /dev/null
@@ -0,0 +1,67 @@
+From 220fc23726bccfc7cb9f5ea1a732e5a85d84e1d5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 Mar 2025 17:05:29 +0000
+Subject: firmware: cs_dsp: Ensure cs_dsp_load[_coeff]() returns 0 on success
+
+From: Richard Fitzgerald <rf@opensource.cirrus.com>
+
+[ Upstream commit 2593f7e0dc93a898a84220b3fb180d86f1ca8c60 ]
+
+Set ret = 0 on successful completion of the processing loop in
+cs_dsp_load() and cs_dsp_load_coeff() to ensure that the function
+returns 0 on success.
+
+All normal firmware files will have at least one data block, and
+processing this block will set ret == 0, from the result of either
+regmap_raw_write() or cs_dsp_parse_coeff().
+
+The kunit tests create a dummy firmware file that contains only the
+header, without any data blocks. This gives cs_dsp a file to "load"
+that will not cause any side-effects. As there aren't any data blocks,
+the processing loop will not set ret == 0.
+
+Originally there was a line after the processing loop:
+
+    ret = regmap_async_complete(regmap);
+
+which would set ret == 0 before the function returned.
+
+Commit fe08b7d5085a ("firmware: cs_dsp: Remove async regmap writes")
+changed the regmap write to a normal sync write, so the call to
+regmap_async_complete() wasn't necessary and was removed. It was
+overlooked that the ret here wasn't only to check the result of
+regmap_async_complete(), it also set the final return value of the
+function.
+
+Fixes: fe08b7d5085a ("firmware: cs_dsp: Remove async regmap writes")
+Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
+Link: https://patch.msgid.link/20250323170529.197205-1-rf@opensource.cirrus.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/cirrus/cs_dsp.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c
+index 42433c19eb308..560724ce21aa3 100644
+--- a/drivers/firmware/cirrus/cs_dsp.c
++++ b/drivers/firmware/cirrus/cs_dsp.c
+@@ -1631,6 +1631,7 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware,
+       cs_dsp_debugfs_save_wmfwname(dsp, file);
++      ret = 0;
+ out_fw:
+       cs_dsp_buf_free(&buf_list);
+@@ -2338,6 +2339,7 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware
+       cs_dsp_debugfs_save_binname(dsp, file);
++      ret = 0;
+ out_fw:
+       cs_dsp_buf_free(&buf_list);
+-- 
+2.39.5
+
diff --git a/queue-6.14/fs-9p-fix-null-pointer-dereference-on-mkdir.patch b/queue-6.14/fs-9p-fix-null-pointer-dereference-on-mkdir.patch
new file mode 100644 (file)
index 0000000..dfb0e52
--- /dev/null
@@ -0,0 +1,73 @@
+From fb0d96f44e3c5a4fad615ca626e0193bb9b7efa2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Mar 2025 13:59:32 +0100
+Subject: fs/9p: fix NULL pointer dereference on mkdir
+
+From: Christian Schoenebeck <linux_oss@crudebyte.com>
+
+[ Upstream commit 3f61ac7c65bdb26accb52f9db66313597e759821 ]
+
+When a 9p tree was mounted with option 'posixacl', parent directory had a
+default ACL set for its subdirectories, e.g.:
+
+  setfacl -m default:group:simpsons:rwx parentdir
+
+then creating a subdirectory crashed 9p client, as v9fs_fid_add() call in
+function v9fs_vfs_mkdir_dotl() sets the passed 'fid' pointer to NULL
+(since dafbe689736) even though the subsequent v9fs_set_create_acl() call
+expects a valid non-NULL 'fid' pointer:
+
+  [   37.273191] BUG: kernel NULL pointer dereference, address: 0000000000000000
+  ...
+  [   37.322338] Call Trace:
+  [   37.323043]  <TASK>
+  [   37.323621] ? __die (arch/x86/kernel/dumpstack.c:421 arch/x86/kernel/dumpstack.c:434)
+  [   37.324448] ? page_fault_oops (arch/x86/mm/fault.c:714)
+  [   37.325532] ? search_module_extables (kernel/module/main.c:3733)
+  [   37.326742] ? p9_client_walk (net/9p/client.c:1165) 9pnet
+  [   37.328006] ? search_bpf_extables (kernel/bpf/core.c:804)
+  [   37.329142] ? exc_page_fault (./arch/x86/include/asm/paravirt.h:686 arch/x86/mm/fault.c:1488 arch/x86/mm/fault.c:1538)
+  [   37.330196] ? asm_exc_page_fault (./arch/x86/include/asm/idtentry.h:574)
+  [   37.331330] ? p9_client_walk (net/9p/client.c:1165) 9pnet
+  [   37.332562] ? v9fs_fid_xattr_get (fs/9p/xattr.c:30) 9p
+  [   37.333824] v9fs_fid_xattr_set (fs/9p/fid.h:23 fs/9p/xattr.c:121) 9p
+  [   37.335077] v9fs_set_acl (fs/9p/acl.c:276) 9p
+  [   37.336112] v9fs_set_create_acl (fs/9p/acl.c:307) 9p
+  [   37.337326] v9fs_vfs_mkdir_dotl (fs/9p/vfs_inode_dotl.c:411) 9p
+  [   37.338590] vfs_mkdir (fs/namei.c:4313)
+  [   37.339535] do_mkdirat (fs/namei.c:4336)
+  [   37.340465] __x64_sys_mkdir (fs/namei.c:4354)
+  [   37.341455] do_syscall_64 (arch/x86/entry/common.c:52 arch/x86/entry/common.c:83)
+  [   37.342447] entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130)
+
+Fix this by simply swapping the sequence of these two calls in
+v9fs_vfs_mkdir_dotl(), i.e. calling v9fs_set_create_acl() before
+v9fs_fid_add().
+
+Fixes: dafbe689736f ("9p fid refcount: cleanup p9_fid_put calls")
+Reported-by: syzbot+5b667f9a1fee4ba3775a@syzkaller.appspotmail.com
+Signed-off-by: Christian Schoenebeck <linux_oss@crudebyte.com>
+Message-ID: <E1tsiI6-002iMG-Kh@kylie.crudebyte.com>
+Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/9p/vfs_inode_dotl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c
+index 143ac03b7425c..3397939fd2d5a 100644
+--- a/fs/9p/vfs_inode_dotl.c
++++ b/fs/9p/vfs_inode_dotl.c
+@@ -407,8 +407,8 @@ static int v9fs_vfs_mkdir_dotl(struct mnt_idmap *idmap,
+                        err);
+               goto error;
+       }
+-      v9fs_fid_add(dentry, &fid);
+       v9fs_set_create_acl(inode, fid, dacl, pacl);
++      v9fs_fid_add(dentry, &fid);
+       d_instantiate(dentry, inode);
+       err = 0;
+       inc_nlink(dir);
+-- 
+2.39.5
+
diff --git a/queue-6.14/fs-ntfs3-factor-out-ntfs_-create-remove-_proc_root.patch b/queue-6.14/fs-ntfs3-factor-out-ntfs_-create-remove-_proc_root.patch
new file mode 100644 (file)
index 0000000..3521fbd
--- /dev/null
@@ -0,0 +1,77 @@
+From c62d692a50cdaa31fc57f4902b49c94701f970be Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Oct 2024 15:40:24 +0800
+Subject: fs/ntfs3: Factor out ntfs_{create/remove}_proc_root()
+
+From: Ye Bin <yebin10@huawei.com>
+
+[ Upstream commit c5a396295370fa99ddc0c4c4d25f8a3ee4f013d8 ]
+
+Introduce ntfs_create_proc_root()/ntfs_remove_proc_root() for
+create/remove "/proc/fs/ntfs3".
+
+Signed-off-by: Ye Bin <yebin10@huawei.com>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Stable-dep-of: 1d1a7e252549 ("fs/ntfs3: Fix 'proc_info_root' leak when init ntfs failed")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/super.c | 26 +++++++++++++++++---------
+ 1 file changed, 17 insertions(+), 9 deletions(-)
+
+diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c
+index 415492fc655ac..66047cf0e6e81 100644
+--- a/fs/ntfs3/super.c
++++ b/fs/ntfs3/super.c
+@@ -586,9 +586,24 @@ static void ntfs_remove_procdir(struct super_block *sb)
+       remove_proc_entry(sb->s_id, proc_info_root);
+       sbi->procdir = NULL;
+ }
++
++static void ntfs_create_proc_root(void)
++{
++      proc_info_root = proc_mkdir("fs/ntfs3", NULL);
++}
++
++static void ntfs_remove_proc_root(void)
++{
++      if (proc_info_root) {
++              remove_proc_entry("fs/ntfs3", NULL);
++              proc_info_root = NULL;
++      }
++}
+ #else
+ static void ntfs_create_procdir(struct super_block *sb) {}
+ static void ntfs_remove_procdir(struct super_block *sb) {}
++static void ntfs_create_proc_root(void) {}
++static void ntfs_remove_proc_root(void) {}
+ #endif
+ static struct kmem_cache *ntfs_inode_cachep;
+@@ -1866,10 +1881,7 @@ static int __init init_ntfs_fs(void)
+       if (IS_ENABLED(CONFIG_NTFS3_LZX_XPRESS))
+               pr_info("ntfs3: Read-only LZX/Xpress compression included\n");
+-#ifdef CONFIG_PROC_FS
+-      /* Create "/proc/fs/ntfs3" */
+-      proc_info_root = proc_mkdir("fs/ntfs3", NULL);
+-#endif
++      ntfs_create_proc_root();
+       err = ntfs3_init_bitmap();
+       if (err)
+@@ -1903,11 +1915,7 @@ static void __exit exit_ntfs_fs(void)
+       unregister_filesystem(&ntfs_fs_type);
+       unregister_as_ntfs_legacy();
+       ntfs3_exit_bitmap();
+-
+-#ifdef CONFIG_PROC_FS
+-      if (proc_info_root)
+-              remove_proc_entry("fs/ntfs3", NULL);
+-#endif
++      ntfs_remove_proc_root();
+ }
+ MODULE_LICENSE("GPL");
+-- 
+2.39.5
+
diff --git a/queue-6.14/fs-ntfs3-factor-out-ntfs_-create-remove-_procdir.patch b/queue-6.14/fs-ntfs3-factor-out-ntfs_-create-remove-_procdir.patch
new file mode 100644 (file)
index 0000000..6a87417
--- /dev/null
@@ -0,0 +1,107 @@
+From 4bc97603d26e18bbd0e98f129d78cc267e2bca55 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Oct 2024 15:40:23 +0800
+Subject: fs/ntfs3: Factor out ntfs_{create/remove}_procdir()
+
+From: Ye Bin <yebin10@huawei.com>
+
+[ Upstream commit e2d74c47a3d3d84a5fa444f380c126328b44f4db ]
+
+Introduce ntfs_create_procdir() and ntfs_remove_procdir() to
+create/remove "/proc/fs/ntfs3/.."
+
+Signed-off-by: Ye Bin <yebin10@huawei.com>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Stable-dep-of: 1d1a7e252549 ("fs/ntfs3: Fix 'proc_info_root' leak when init ntfs failed")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/super.c | 59 +++++++++++++++++++++++++++++-------------------
+ 1 file changed, 36 insertions(+), 23 deletions(-)
+
+diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c
+index 6a0f6b0a3ab2a..415492fc655ac 100644
+--- a/fs/ntfs3/super.c
++++ b/fs/ntfs3/super.c
+@@ -555,6 +555,40 @@ static const struct proc_ops ntfs3_label_fops = {
+       .proc_write = ntfs3_label_write,
+ };
++static void ntfs_create_procdir(struct super_block *sb)
++{
++      struct proc_dir_entry *e;
++
++      if (!proc_info_root)
++              return;
++
++      e = proc_mkdir(sb->s_id, proc_info_root);
++      if (e) {
++              struct ntfs_sb_info *sbi = sb->s_fs_info;
++
++              proc_create_data("volinfo", 0444, e,
++                               &ntfs3_volinfo_fops, sb);
++              proc_create_data("label", 0644, e,
++                               &ntfs3_label_fops, sb);
++              sbi->procdir = e;
++      }
++}
++
++static void ntfs_remove_procdir(struct super_block *sb)
++{
++      struct ntfs_sb_info *sbi = sb->s_fs_info;
++
++      if (!sbi->procdir)
++              return;
++
++      remove_proc_entry("label", sbi->procdir);
++      remove_proc_entry("volinfo", sbi->procdir);
++      remove_proc_entry(sb->s_id, proc_info_root);
++      sbi->procdir = NULL;
++}
++#else
++static void ntfs_create_procdir(struct super_block *sb) {}
++static void ntfs_remove_procdir(struct super_block *sb) {}
+ #endif
+ static struct kmem_cache *ntfs_inode_cachep;
+@@ -644,15 +678,7 @@ static void ntfs_put_super(struct super_block *sb)
+ {
+       struct ntfs_sb_info *sbi = sb->s_fs_info;
+-#ifdef CONFIG_PROC_FS
+-      // Remove /proc/fs/ntfs3/..
+-      if (sbi->procdir) {
+-              remove_proc_entry("label", sbi->procdir);
+-              remove_proc_entry("volinfo", sbi->procdir);
+-              remove_proc_entry(sb->s_id, proc_info_root);
+-              sbi->procdir = NULL;
+-      }
+-#endif
++      ntfs_remove_procdir(sb);
+       /* Mark rw ntfs as clear, if possible. */
+       ntfs_set_state(sbi, NTFS_DIRTY_CLEAR);
+@@ -1590,20 +1616,7 @@ static int ntfs_fill_super(struct super_block *sb, struct fs_context *fc)
+               kfree(boot2);
+       }
+-#ifdef CONFIG_PROC_FS
+-      /* Create /proc/fs/ntfs3/.. */
+-      if (proc_info_root) {
+-              struct proc_dir_entry *e = proc_mkdir(sb->s_id, proc_info_root);
+-              static_assert((S_IRUGO | S_IWUSR) == 0644);
+-              if (e) {
+-                      proc_create_data("volinfo", S_IRUGO, e,
+-                                       &ntfs3_volinfo_fops, sb);
+-                      proc_create_data("label", S_IRUGO | S_IWUSR, e,
+-                                       &ntfs3_label_fops, sb);
+-                      sbi->procdir = e;
+-              }
+-      }
+-#endif
++      ntfs_create_procdir(sb);
+       if (is_legacy_ntfs(sb))
+               sb->s_flags |= SB_RDONLY;
+-- 
+2.39.5
+
diff --git a/queue-6.14/fs-ntfs3-fix-a-couple-integer-overflows-on-32bit-sys.patch b/queue-6.14/fs-ntfs3-fix-a-couple-integer-overflows-on-32bit-sys.patch
new file mode 100644 (file)
index 0000000..0aef971
--- /dev/null
@@ -0,0 +1,45 @@
+From 57c1461e9e879b26391a86387b59f8ff6cc1ac58 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 16 Feb 2025 23:52:00 +0300
+Subject: fs/ntfs3: Fix a couple integer overflows on 32bit systems
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 5ad414f4df2294b28836b5b7b69787659d6aa708 ]
+
+On 32bit systems the "off + sizeof(struct NTFS_DE)" addition can
+have an integer wrapping issue.  Fix it by using size_add().
+
+Fixes: 82cae269cfa9 ("fs/ntfs3: Add initialization of super block")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/index.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/fs/ntfs3/index.c b/fs/ntfs3/index.c
+index 7eb9fae22f8da..78d20e4baa2c9 100644
+--- a/fs/ntfs3/index.c
++++ b/fs/ntfs3/index.c
+@@ -618,7 +618,7 @@ static bool index_hdr_check(const struct INDEX_HDR *hdr, u32 bytes)
+       u32 off = le32_to_cpu(hdr->de_off);
+       if (!IS_ALIGNED(off, 8) || tot > bytes || end > tot ||
+-          off + sizeof(struct NTFS_DE) > end) {
++          size_add(off, sizeof(struct NTFS_DE)) > end) {
+               /* incorrect index buffer. */
+               return false;
+       }
+@@ -736,7 +736,7 @@ static struct NTFS_DE *hdr_find_e(const struct ntfs_index *indx,
+       if (end > total)
+               return NULL;
+-      if (off + sizeof(struct NTFS_DE) > end)
++      if (size_add(off, sizeof(struct NTFS_DE)) > end)
+               return NULL;
+       e = Add2Ptr(hdr, off);
+-- 
+2.39.5
+
diff --git a/queue-6.14/fs-ntfs3-fix-proc_info_root-leak-when-init-ntfs-fail.patch b/queue-6.14/fs-ntfs3-fix-proc_info_root-leak-when-init-ntfs-fail.patch
new file mode 100644 (file)
index 0000000..3b2824c
--- /dev/null
@@ -0,0 +1,61 @@
+From 0b4fcc07bb89402b2a3727c6dfd430c22c0e1e41 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Oct 2024 15:40:25 +0800
+Subject: fs/ntfs3: Fix 'proc_info_root' leak when init ntfs failed
+
+From: Ye Bin <yebin10@huawei.com>
+
+[ Upstream commit 1d1a7e2525491f56901f5f63370a0775768044b8 ]
+
+There's a issue as follows:
+  proc_dir_entry 'fs/ntfs3' already registered
+  WARNING: CPU: 3 PID: 9788 at fs/proc/generic.c:375 proc_register+0x418/0x590
+  Modules linked in: ntfs3(E+)
+  Call Trace:
+   <TASK>
+   _proc_mkdir+0x165/0x200
+   init_ntfs_fs+0x36/0xf90 [ntfs3]
+   do_one_initcall+0x115/0x6c0
+   do_init_module+0x253/0x760
+   load_module+0x55f2/0x6c80
+   init_module_from_file+0xd2/0x130
+   __x64_sys_finit_module+0xbf/0x130
+   do_syscall_64+0x72/0x1c0
+
+Above issue happens as missing destroy 'proc_info_root' when error
+happens after create 'proc_info_root' in init_ntfs_fs().
+So destroy 'proc_info_root' in error path in init_ntfs_fs().
+
+Fixes: 7832e123490a ("fs/ntfs3: Add support /proc/fs/ntfs3/<dev>/volinfo and /proc/fs/ntfs3/<dev>/label")
+Signed-off-by: Ye Bin <yebin10@huawei.com>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/super.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c
+index 66047cf0e6e81..920a1ab47b631 100644
+--- a/fs/ntfs3/super.c
++++ b/fs/ntfs3/super.c
+@@ -1885,7 +1885,7 @@ static int __init init_ntfs_fs(void)
+       err = ntfs3_init_bitmap();
+       if (err)
+-              return err;
++              goto out2;
+       ntfs_inode_cachep = kmem_cache_create(
+               "ntfs_inode_cache", sizeof(struct ntfs_inode), 0,
+@@ -1905,6 +1905,8 @@ static int __init init_ntfs_fs(void)
+       kmem_cache_destroy(ntfs_inode_cachep);
+ out1:
+       ntfs3_exit_bitmap();
++out2:
++      ntfs_remove_proc_root();
+       return err;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/fs-ntfs3-prevent-integer-overflow-in-hdr_first_de.patch b/queue-6.14/fs-ntfs3-prevent-integer-overflow-in-hdr_first_de.patch
new file mode 100644 (file)
index 0000000..ff9f148
--- /dev/null
@@ -0,0 +1,38 @@
+From df1897c4d7e6e99025bb35b6a3c72be0b383e864 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 16 Feb 2025 23:52:10 +0300
+Subject: fs/ntfs3: Prevent integer overflow in hdr_first_de()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 6bb81b94f7a9cba6bde9a905cef52a65317a8b04 ]
+
+The "de_off" and "used" variables come from the disk so they both need to
+check.  The problem is that on 32bit systems if they're both greater than
+UINT_MAX - 16 then the check does work as intended because of an integer
+overflow.
+
+Fixes: 60ce8dfde035 ("fs/ntfs3: Fix wrong if in hdr_first_de")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/ntfs.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/ntfs3/ntfs.h b/fs/ntfs3/ntfs.h
+index 241f2ffdd9201..1ff13b6f96132 100644
+--- a/fs/ntfs3/ntfs.h
++++ b/fs/ntfs3/ntfs.h
+@@ -717,7 +717,7 @@ static inline struct NTFS_DE *hdr_first_de(const struct INDEX_HDR *hdr)
+       struct NTFS_DE *e;
+       u16 esize;
+-      if (de_off >= used || de_off + sizeof(struct NTFS_DE) > used )
++      if (de_off >= used || size_add(de_off, sizeof(struct NTFS_DE)) > used)
+               return NULL;
+       e = Add2Ptr(hdr, de_off);
+-- 
+2.39.5
+
diff --git a/queue-6.14/fs-ntfs3-update-inode-i_mapping-a_ops-on-compression.patch b/queue-6.14/fs-ntfs3-update-inode-i_mapping-a_ops-on-compression.patch
new file mode 100644 (file)
index 0000000..313d832
--- /dev/null
@@ -0,0 +1,98 @@
+From f677c9b719b7e370c0133c3b868f8521d64b4198 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Jan 2025 17:03:41 +0300
+Subject: fs/ntfs3: Update inode->i_mapping->a_ops on compression state
+
+From: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+
+[ Upstream commit b432163ebd15a0fb74051949cb61456d6c55ccbd ]
+
+Update inode->i_mapping->a_ops when the compression state changes to
+ensure correct address space operations.
+Clear ATTR_FLAG_SPARSED/FILE_ATTRIBUTE_SPARSE_FILE when enabling
+compression to prevent flag conflicts.
+
+v2:
+Additionally, ensure that all dirty pages are flushed and concurrent access
+to the page cache is blocked.
+
+Fixes: 6b39bfaeec44 ("fs/ntfs3: Add support for the compression attribute")
+Reported-by: Kun Hu <huk23@m.fudan.edu.cn>, Jiaji Qin <jjtan24@m.fudan.edu.cn>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/attrib.c  |  3 ++-
+ fs/ntfs3/file.c    | 22 ++++++++++++++++++++--
+ fs/ntfs3/frecord.c |  6 ++++--
+ 3 files changed, 26 insertions(+), 5 deletions(-)
+
+diff --git a/fs/ntfs3/attrib.c b/fs/ntfs3/attrib.c
+index af94e3737470d..e946f75eb5406 100644
+--- a/fs/ntfs3/attrib.c
++++ b/fs/ntfs3/attrib.c
+@@ -2664,8 +2664,9 @@ int attr_set_compress(struct ntfs_inode *ni, bool compr)
+               attr->nres.run_off = cpu_to_le16(run_off);
+       }
+-      /* Update data attribute flags. */
++      /* Update attribute flags. */
+       if (compr) {
++              attr->flags &= ~ATTR_FLAG_SPARSED;
+               attr->flags |= ATTR_FLAG_COMPRESSED;
+               attr->nres.c_unit = NTFS_LZNT_CUNIT;
+       } else {
+diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c
+index 3f96a11804c90..e9f701f884e72 100644
+--- a/fs/ntfs3/file.c
++++ b/fs/ntfs3/file.c
+@@ -101,8 +101,26 @@ int ntfs_fileattr_set(struct mnt_idmap *idmap, struct dentry *dentry,
+       /* Allowed to change compression for empty files and for directories only. */
+       if (!is_dedup(ni) && !is_encrypted(ni) &&
+           (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
+-              /* Change compress state. */
+-              int err = ni_set_compress(inode, flags & FS_COMPR_FL);
++              int err = 0;
++              struct address_space *mapping = inode->i_mapping;
++
++              /* write out all data and wait. */
++              filemap_invalidate_lock(mapping);
++              err = filemap_write_and_wait(mapping);
++
++              if (err >= 0) {
++                      /* Change compress state. */
++                      bool compr = flags & FS_COMPR_FL;
++                      err = ni_set_compress(inode, compr);
++
++                      /* For files change a_ops too. */
++                      if (!err)
++                              mapping->a_ops = compr ? &ntfs_aops_cmpr :
++                                                       &ntfs_aops;
++              }
++
++              filemap_invalidate_unlock(mapping);
++
+               if (err)
+                       return err;
+       }
+diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c
+index 5df6a0b5add90..81271196c5571 100644
+--- a/fs/ntfs3/frecord.c
++++ b/fs/ntfs3/frecord.c
+@@ -3434,10 +3434,12 @@ int ni_set_compress(struct inode *inode, bool compr)
+       }
+       ni->std_fa = std->fa;
+-      if (compr)
++      if (compr) {
++              std->fa &= ~FILE_ATTRIBUTE_SPARSE_FILE;
+               std->fa |= FILE_ATTRIBUTE_COMPRESSED;
+-      else
++      } else {
+               std->fa &= ~FILE_ATTRIBUTE_COMPRESSED;
++      }
+       if (ni->std_fa != std->fa) {
+               ni->std_fa = std->fa;
+-- 
+2.39.5
+
diff --git a/queue-6.14/fs-procfs-fix-the-comment-above-proc_pid_wchan.patch b/queue-6.14/fs-procfs-fix-the-comment-above-proc_pid_wchan.patch
new file mode 100644 (file)
index 0000000..8a0377c
--- /dev/null
@@ -0,0 +1,41 @@
+From d89bbb76e618cd157398685ce4b1dcb2ff0c0dfe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Mar 2025 14:02:22 -0700
+Subject: fs/procfs: fix the comment above proc_pid_wchan()
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit 6287fbad1cd91f0c25cdc3a580499060828a8f30 ]
+
+proc_pid_wchan() used to report kernel addresses to user space but that is
+no longer the case today.  Bring the comment above proc_pid_wchan() in
+sync with the implementation.
+
+Link: https://lkml.kernel.org/r/20250319210222.1518771-1-bvanassche@acm.org
+Fixes: b2f73922d119 ("fs/proc, core/debug: Don't expose absolute kernel addresses via wchan")
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Cc: Kees Cook <kees@kernel.org>
+Cc: Eric W. Biederman <ebiederm@xmission.com>
+Cc: Alexey Dobriyan <adobriyan@gmail.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/proc/base.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/proc/base.c b/fs/proc/base.c
+index cd89e956c3224..7feb8f41aa253 100644
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -416,7 +416,7 @@ static const struct file_operations proc_pid_cmdline_ops = {
+ #ifdef CONFIG_KALLSYMS
+ /*
+  * Provides a wchan file via kallsyms in a proper one-value-per-file format.
+- * Returns the resolved symbol.  If that fails, simply return the address.
++ * Returns the resolved symbol to user space.
+  */
+ static int proc_pid_wchan(struct seq_file *m, struct pid_namespace *ns,
+                         struct pid *pid, struct task_struct *task)
+-- 
+2.39.5
+
diff --git a/queue-6.14/fs-support-o_path-fds-with-fsconfig_set_fd.patch b/queue-6.14/fs-support-o_path-fds-with-fsconfig_set_fd.patch
new file mode 100644 (file)
index 0000000..a695556
--- /dev/null
@@ -0,0 +1,54 @@
+From 90d0d971d55deb93101e46093d3426cd48dc6140 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Feb 2025 13:38:59 +0100
+Subject: fs: support O_PATH fds with FSCONFIG_SET_FD
+
+From: Christian Brauner <brauner@kernel.org>
+
+[ Upstream commit 0ff053b98a0f039e52c2bd8d0cb38f2831edfaf5 ]
+
+Let FSCONFIG_SET_FD handle O_PATH file descriptors. This is particularly
+useful in the context of overlayfs where layers can be specified via
+file descriptors instead of paths. But userspace must currently use
+non-O_PATH file desriptors which is often pointless especially if
+the file descriptors have been created via open_tree(OPEN_TREE_CLONE).
+
+Link: https://lore.kernel.org/r/20250210-work-overlayfs-v2-1-ed2a949b674b@kernel.org
+Fixes: a08557d19ef41 ("ovl: specify layers via file descriptors")
+Reviewed-by: Amir Goldstein <amir73il@gmail.com>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/autofs/autofs_i.h | 2 ++
+ fs/fsopen.c          | 2 +-
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/fs/autofs/autofs_i.h b/fs/autofs/autofs_i.h
+index 77c7991d89aac..23cea74f9933b 100644
+--- a/fs/autofs/autofs_i.h
++++ b/fs/autofs/autofs_i.h
+@@ -218,6 +218,8 @@ void autofs_clean_ino(struct autofs_info *);
+ static inline int autofs_check_pipe(struct file *pipe)
+ {
++      if (pipe->f_mode & FMODE_PATH)
++              return -EINVAL;
+       if (!(pipe->f_mode & FMODE_CAN_WRITE))
+               return -EINVAL;
+       if (!S_ISFIFO(file_inode(pipe)->i_mode))
+diff --git a/fs/fsopen.c b/fs/fsopen.c
+index 094a7f510edfe..1aaf4cb2afb29 100644
+--- a/fs/fsopen.c
++++ b/fs/fsopen.c
+@@ -453,7 +453,7 @@ SYSCALL_DEFINE5(fsconfig,
+       case FSCONFIG_SET_FD:
+               param.type = fs_value_is_file;
+               ret = -EBADF;
+-              param.file = fget(aux);
++              param.file = fget_raw(aux);
+               if (!param.file)
+                       goto out_key;
+               param.dirfd = aux;
+-- 
+2.39.5
+
diff --git a/queue-6.14/fuse-fix-dax-truncate-punch_hole-fault-path.patch b/queue-6.14/fuse-fix-dax-truncate-punch_hole-fault-path.patch
new file mode 100644 (file)
index 0000000..70c59f0
--- /dev/null
@@ -0,0 +1,146 @@
+From 7e87dc3b98df36e6cecc77142dfea68ec8c9482c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Feb 2025 14:30:56 +1100
+Subject: fuse: fix dax truncate/punch_hole fault path
+
+From: Alistair Popple <apopple@nvidia.com>
+
+[ Upstream commit 7851bf649d423edd7286b292739f2eefded3d35c ]
+
+Patch series "fs/dax: Fix ZONE_DEVICE page reference counts", v9.
+
+Device and FS DAX pages have always maintained their own page reference
+counts without following the normal rules for page reference counting.  In
+particular pages are considered free when the refcount hits one rather
+than zero and refcounts are not added when mapping the page.
+
+Tracking this requires special PTE bits (PTE_DEVMAP) and a secondary
+mechanism for allowing GUP to hold references on the page (see
+get_dev_pagemap).  However there doesn't seem to be any reason why FS DAX
+pages need their own reference counting scheme.
+
+By treating the refcounts on these pages the same way as normal pages we
+can remove a lot of special checks.  In particular pXd_trans_huge()
+becomes the same as pXd_leaf(), although I haven't made that change here.
+It also frees up a valuable SW define PTE bit on architectures that have
+devmap PTE bits defined.
+
+It also almost certainly allows further clean-up of the devmap managed
+functions, but I have left that as a future improvment.  It also enables
+support for compound ZONE_DEVICE pages which is one of my primary
+motivators for doing this work.
+
+This patch (of 20):
+
+FS DAX requires file systems to call into the DAX layout prior to
+unlinking inodes to ensure there is no ongoing DMA or other remote access
+to the direct mapped page.  The fuse file system implements
+fuse_dax_break_layouts() to do this which includes a comment indicating
+that passing dmap_end == 0 leads to unmapping of the whole file.
+
+However this is not true - passing dmap_end == 0 will not unmap anything
+before dmap_start, and further more dax_layout_busy_page_range() will not
+scan any of the range to see if there maybe ongoing DMA access to the
+range.  Fix this by passing -1 for dmap_end to fuse_dax_break_layouts()
+which will invalidate the entire file range to
+dax_layout_busy_page_range().
+
+Link: https://lkml.kernel.org/r/cover.8068ad144a7eea4a813670301f4d2a86a8e68ec4.1740713401.git-series.apopple@nvidia.com
+Link: https://lkml.kernel.org/r/f09a34b6c40032022e4ddee6fadb7cc676f08867.1740713401.git-series.apopple@nvidia.com
+Fixes: 6ae330cad6ef ("virtiofs: serialize truncate/punch_hole and dax fault path")
+Signed-off-by: Alistair Popple <apopple@nvidia.com>
+Co-developed-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Reviewed-by: Balbir Singh <balbirs@nvidia.com>
+Tested-by: Alison Schofield <alison.schofield@intel.com>
+Cc: Vivek Goyal <vgoyal@redhat.com>
+Cc: Alexander Gordeev <agordeev@linux.ibm.com>
+Cc: Asahi Lina <lina@asahilina.net>
+Cc: Bjorn Helgaas <bhelgaas@google.com>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Christian Borntraeger <borntraeger@linux.ibm.com>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Chunyan Zhang <zhang.lyra@gmail.com>
+Cc: "Darrick J. Wong" <djwong@kernel.org>
+Cc: Dave Chinner <david@fromorbit.com>
+Cc: Dave Hansen <dave.hansen@linux.intel.com>
+Cc: Dave Jiang <dave.jiang@intel.com>
+Cc: David Hildenbrand <david@redhat.com>
+Cc: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
+Cc: Heiko Carstens <hca@linux.ibm.com>
+Cc: Huacai Chen <chenhuacai@kernel.org>
+Cc: Ira Weiny <ira.weiny@intel.com>
+Cc: Jan Kara <jack@suse.cz>
+Cc: Jason Gunthorpe <jgg@nvidia.com>
+Cc: Jason Gunthorpe <jgg@ziepe.ca>
+Cc: John Hubbard <jhubbard@nvidia.com>
+Cc: linmiaohe <linmiaohe@huawei.com>
+Cc: Logan Gunthorpe <logang@deltatee.com>
+Cc: Matthew Wilcow (Oracle) <willy@infradead.org>
+Cc: Michael "Camp Drill Sergeant" Ellerman <mpe@ellerman.id.au>
+Cc: Nicholas Piggin <npiggin@gmail.com>
+Cc: Peter Xu <peterx@redhat.com>
+Cc: Sven Schnelle <svens@linux.ibm.com>
+Cc: Ted Ts'o <tytso@mit.edu>
+Cc: Vasily Gorbik <gor@linux.ibm.com>
+Cc: Vishal Verma <vishal.l.verma@intel.com>
+Cc: WANG Xuerui <kernel@xen0n.name>
+Cc: Will Deacon <will@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/fuse/dax.c  | 1 -
+ fs/fuse/dir.c  | 2 +-
+ fs/fuse/file.c | 4 ++--
+ 3 files changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/fs/fuse/dax.c b/fs/fuse/dax.c
+index 0b6ee6dd1fd65..b7f805d2a14fd 100644
+--- a/fs/fuse/dax.c
++++ b/fs/fuse/dax.c
+@@ -682,7 +682,6 @@ static int __fuse_dax_break_layouts(struct inode *inode, bool *retry,
+                       0, 0, fuse_wait_dax_page(inode));
+ }
+-/* dmap_end == 0 leads to unmapping of whole file */
+ int fuse_dax_break_layouts(struct inode *inode, u64 dmap_start,
+                                 u64 dmap_end)
+ {
+diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
+index 3805f9b06c9d2..3b031d24d3691 100644
+--- a/fs/fuse/dir.c
++++ b/fs/fuse/dir.c
+@@ -1940,7 +1940,7 @@ int fuse_do_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
+       if (FUSE_IS_DAX(inode) && is_truncate) {
+               filemap_invalidate_lock(mapping);
+               fault_blocked = true;
+-              err = fuse_dax_break_layouts(inode, 0, 0);
++              err = fuse_dax_break_layouts(inode, 0, -1);
+               if (err) {
+                       filemap_invalidate_unlock(mapping);
+                       return err;
+diff --git a/fs/fuse/file.c b/fs/fuse/file.c
+index d63e56fd3dd20..754378dd9f715 100644
+--- a/fs/fuse/file.c
++++ b/fs/fuse/file.c
+@@ -253,7 +253,7 @@ static int fuse_open(struct inode *inode, struct file *file)
+       if (dax_truncate) {
+               filemap_invalidate_lock(inode->i_mapping);
+-              err = fuse_dax_break_layouts(inode, 0, 0);
++              err = fuse_dax_break_layouts(inode, 0, -1);
+               if (err)
+                       goto out_inode_unlock;
+       }
+@@ -3205,7 +3205,7 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
+       inode_lock(inode);
+       if (block_faults) {
+               filemap_invalidate_lock(inode->i_mapping);
+-              err = fuse_dax_break_layouts(inode, 0, 0);
++              err = fuse_dax_break_layouts(inode, 0, -1);
+               if (err)
+                       goto out;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/gfs2-minor-evict-fix.patch b/queue-6.14/gfs2-minor-evict-fix.patch
new file mode 100644 (file)
index 0000000..62c7b3e
--- /dev/null
@@ -0,0 +1,64 @@
+From c61dd7276d798ffa404e3ff101dc02126e5da4b2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Mar 2025 11:28:23 +0100
+Subject: gfs2: minor evict fix
+
+From: Andreas Gruenbacher <agruenba@redhat.com>
+
+[ Upstream commit e9e38ed7250f8ef6b2928216156c09df8b4834b3 ]
+
+In evict_should_delete(), when gfs2_upgrade_iopen_glock() fails, we
+detach the iopen glock from the inode without calling
+glock_clear_object().  This leads to a warning in glock_set_object()
+when the same inode is recreated and the glock is reused.
+Fix that by only detaching the iopen glock in gfs2_evict_inode().
+
+In addition, remove the dequeue code from evict_should_delete(); we
+already perform a conditional dequeue in gfs2_evict_inode().
+
+Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
+Stable-dep-of: 41a8e04c94b8 ("gfs2: skip if we cannot defer delete")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/gfs2/super.c | 17 +++--------------
+ 1 file changed, 3 insertions(+), 14 deletions(-)
+
+diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
+index 92a3b6ddafdc1..ff8fdc6134ff5 100644
+--- a/fs/gfs2/super.c
++++ b/fs/gfs2/super.c
+@@ -1338,12 +1338,8 @@ static enum evict_behavior evict_should_delete(struct inode *inode,
+       /* Must not read inode block until block type has been verified */
+       ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, gh);
+-      if (unlikely(ret)) {
+-              glock_clear_object(ip->i_iopen_gh.gh_gl, ip);
+-              ip->i_iopen_gh.gh_flags |= GL_NOCACHE;
+-              gfs2_glock_dq_uninit(&ip->i_iopen_gh);
++      if (unlikely(ret))
+               return EVICT_SHOULD_DEFER_DELETE;
+-      }
+       if (gfs2_inode_already_deleted(ip->i_gl, ip->i_no_formal_ino))
+               return EVICT_SHOULD_SKIP_DELETE;
+@@ -1363,15 +1359,8 @@ static enum evict_behavior evict_should_delete(struct inode *inode,
+ should_delete:
+       if (gfs2_holder_initialized(&ip->i_iopen_gh) &&
+-          test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) {
+-              enum evict_behavior behavior =
+-                      gfs2_upgrade_iopen_glock(inode);
+-
+-              if (behavior != EVICT_SHOULD_DELETE) {
+-                      gfs2_holder_uninit(&ip->i_iopen_gh);
+-                      return behavior;
+-              }
+-      }
++          test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags))
++              return gfs2_upgrade_iopen_glock(inode);
+       return EVICT_SHOULD_DELETE;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/gfs2-skip-if-we-cannot-defer-delete.patch b/queue-6.14/gfs2-skip-if-we-cannot-defer-delete.patch
new file mode 100644 (file)
index 0000000..3daacd9
--- /dev/null
@@ -0,0 +1,49 @@
+From 35e46358e18114e6385d3bd49f060a06914dd930 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Mar 2025 22:13:28 +0100
+Subject: gfs2: skip if we cannot defer delete
+
+From: Andreas Gruenbacher <agruenba@redhat.com>
+
+[ Upstream commit 41a8e04c94b868023986ec35ca06756e31e1e229 ]
+
+In gfs2_evict_inode(), in the unlikely case that we cannot defer
+deleting the inode, it is not safe to fall back to deleting the inode;
+the only valid choice we have is to skip the delete.
+
+In addition, in evict_should_delete(), if we cannot lock the inode glock
+exclusively, we are in a bad enough state that skipping the delete is
+likely a better choice than trying to recover from the failure later.
+
+Fixes: c5b7a2400edc ("gfs2: Only defer deletes when we have an iopen glock")
+Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/gfs2/super.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
+index ff8fdc6134ff5..0e6ad7bf32be8 100644
+--- a/fs/gfs2/super.c
++++ b/fs/gfs2/super.c
+@@ -1339,7 +1339,7 @@ static enum evict_behavior evict_should_delete(struct inode *inode,
+       /* Must not read inode block until block type has been verified */
+       ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, gh);
+       if (unlikely(ret))
+-              return EVICT_SHOULD_DEFER_DELETE;
++              return EVICT_SHOULD_SKIP_DELETE;
+       if (gfs2_inode_already_deleted(ip->i_gl, ip->i_no_formal_ino))
+               return EVICT_SHOULD_SKIP_DELETE;
+@@ -1498,7 +1498,7 @@ static void gfs2_evict_inode(struct inode *inode)
+                               gfs2_glock_put(io_gl);
+                       goto out;
+               }
+-              behavior = EVICT_SHOULD_DELETE;
++              behavior = EVICT_SHOULD_SKIP_DELETE;
+       }
+       if (behavior == EVICT_SHOULD_DELETE)
+               ret = evict_unlinked_inode(inode);
+-- 
+2.39.5
+
diff --git a/queue-6.14/gpu-cdns-mhdp8546-fix-call-balance-of-mhdp-clk-handl.patch b/queue-6.14/gpu-cdns-mhdp8546-fix-call-balance-of-mhdp-clk-handl.patch
new file mode 100644 (file)
index 0000000..49b2b6d
--- /dev/null
@@ -0,0 +1,85 @@
+From 00bd980ed8bdca4c7af52b060c3d8381aa14b882 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Feb 2025 18:46:32 +0300
+Subject: gpu: cdns-mhdp8546: fix call balance of mhdp->clk handling routines
+
+From: Vitalii Mordan <mordan@ispras.ru>
+
+[ Upstream commit f65727be3fa5f252c8d982d15023aab8255ded19 ]
+
+If the clock mhdp->clk was not enabled in cdns_mhdp_probe(), it should not
+be disabled in any path.
+
+The return value of clk_prepare_enable() is not checked. If mhdp->clk was
+not enabled, it may be disabled in the error path of cdns_mhdp_probe()
+(e.g., if cdns_mhdp_load_firmware() fails) or in cdns_mhdp_remove() after
+a successful cdns_mhdp_probe() call.
+
+Use the devm_clk_get_enabled() helper function to ensure proper call
+balance for mhdp->clk.
+
+Found by Linux Verification Center (linuxtesting.org) with Klever.
+
+Fixes: fb43aa0acdfd ("drm: bridge: Add support for Cadence MHDP8546 DPI/DP bridge")
+Signed-off-by: Vitalii Mordan <mordan@ispras.ru>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Robert Foss <rfoss@kernel.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250214154632.1907425-1-mordan@ispras.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c | 12 +++---------
+ 1 file changed, 3 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
+index d081850e3c03e..d4e4f484cbe5e 100644
+--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
++++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
+@@ -2463,9 +2463,9 @@ static int cdns_mhdp_probe(struct platform_device *pdev)
+       if (!mhdp)
+               return -ENOMEM;
+-      clk = devm_clk_get(dev, NULL);
++      clk = devm_clk_get_enabled(dev, NULL);
+       if (IS_ERR(clk)) {
+-              dev_err(dev, "couldn't get clk: %ld\n", PTR_ERR(clk));
++              dev_err(dev, "couldn't get and enable clk: %ld\n", PTR_ERR(clk));
+               return PTR_ERR(clk);
+       }
+@@ -2504,14 +2504,12 @@ static int cdns_mhdp_probe(struct platform_device *pdev)
+       mhdp->info = of_device_get_match_data(dev);
+-      clk_prepare_enable(clk);
+-
+       pm_runtime_enable(dev);
+       ret = pm_runtime_resume_and_get(dev);
+       if (ret < 0) {
+               dev_err(dev, "pm_runtime_resume_and_get failed\n");
+               pm_runtime_disable(dev);
+-              goto clk_disable;
++              return ret;
+       }
+       if (mhdp->info && mhdp->info->ops && mhdp->info->ops->init) {
+@@ -2590,8 +2588,6 @@ static int cdns_mhdp_probe(struct platform_device *pdev)
+ runtime_put:
+       pm_runtime_put_sync(dev);
+       pm_runtime_disable(dev);
+-clk_disable:
+-      clk_disable_unprepare(mhdp->clk);
+       return ret;
+ }
+@@ -2632,8 +2628,6 @@ static void cdns_mhdp_remove(struct platform_device *pdev)
+       cancel_work_sync(&mhdp->modeset_retry_work);
+       flush_work(&mhdp->hpd_work);
+       /* Ignoring mhdp->hdcp.check_work and mhdp->hdcp.prop_work here. */
+-
+-      clk_disable_unprepare(mhdp->clk);
+ }
+ static const struct of_device_id mhdp_ids[] = {
+-- 
+2.39.5
+
diff --git a/queue-6.14/greybus-gb-beagleplay-add-error-handling-for-gb_grey.patch b/queue-6.14/greybus-gb-beagleplay-add-error-handling-for-gb_grey.patch
new file mode 100644 (file)
index 0000000..1cba7d2
--- /dev/null
@@ -0,0 +1,42 @@
+From 47df7aa56dcd17f986f1b76ff4ad88b06a3f4b55 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jan 2025 22:05:47 +0800
+Subject: greybus: gb-beagleplay: Add error handling for gb_greybus_init
+
+From: Wentao Liang <vulab@iscas.ac.cn>
+
+[ Upstream commit be382372d55d65b5c7e5a523793ca5e403f8c595 ]
+
+Add error handling for the gb_greybus_init(bg) function call
+during the firmware reflash process to maintain consistency
+in error handling throughout the codebase. If initialization
+fails, log an error and return FW_UPLOAD_ERR_RW_ERROR.
+
+Fixes: 0cf7befa3ea2 ("greybus: gb-beagleplay: Add firmware upload API")
+Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
+Reviewed-by: Ayush Singh <ayush@beagleboard.org>
+Link: https://lore.kernel.org/r/20250120140547.1460-1-vulab@iscas.ac.cn
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/greybus/gb-beagleplay.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/greybus/gb-beagleplay.c b/drivers/greybus/gb-beagleplay.c
+index 473ac3f2d3821..da31f1131afca 100644
+--- a/drivers/greybus/gb-beagleplay.c
++++ b/drivers/greybus/gb-beagleplay.c
+@@ -912,7 +912,9 @@ static enum fw_upload_err cc1352_prepare(struct fw_upload *fw_upload,
+               cc1352_bootloader_reset(bg);
+               WRITE_ONCE(bg->flashing_mode, false);
+               msleep(200);
+-              gb_greybus_init(bg);
++              if (gb_greybus_init(bg) < 0)
++                      return dev_err_probe(&bg->sd->dev, FW_UPLOAD_ERR_RW_ERROR,
++                                           "Failed to initialize greybus");
+               gb_beagleplay_start_svc(bg);
+               return FW_UPLOAD_ERR_FW_INVALID;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/hid-remove-superfluous-and-wrong-makefile-entry-for-.patch b/queue-6.14/hid-remove-superfluous-and-wrong-makefile-entry-for-.patch
new file mode 100644 (file)
index 0000000..900d516
--- /dev/null
@@ -0,0 +1,44 @@
+From 039ca97ddf380958af6777f31b02999454c78c31 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Mar 2025 09:08:22 +0100
+Subject: HID: remove superfluous (and wrong) Makefile entry for
+ CONFIG_INTEL_ISH_FIRMWARE_DOWNLOADER
+
+From: Jiri Kosina <jkosina@suse.com>
+
+[ Upstream commit fe0fb58325e519008e2606a5aa2cff7ad23e212d ]
+
+The line
+
+       obj-$(INTEL_ISH_FIRMWARE_DOWNLOADER)   += intel-ish-hid/
+
+in top-level HID Makefile is both superfluous (as CONFIG_INTEL_ISH_FIRMWARE_DOWNLOADER
+depends on CONFIG_INTEL_ISH_HID, which contains intel-ish-hid/ already) and wrong (as it's
+missing the CONFIG_ prefix).
+
+Just remove it.
+
+Fixes: 91b228107da3e ("HID: intel-ish-hid: ISH firmware loader client driver")
+Reported-by: Jiri Slaby <jirislaby@kernel.org>
+Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/Makefile | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
+index 482b096eea280..0abfe51704a0b 100644
+--- a/drivers/hid/Makefile
++++ b/drivers/hid/Makefile
+@@ -166,7 +166,6 @@ obj-$(CONFIG_USB_KBD)              += usbhid/
+ obj-$(CONFIG_I2C_HID_CORE)    += i2c-hid/
+ obj-$(CONFIG_INTEL_ISH_HID)   += intel-ish-hid/
+-obj-$(INTEL_ISH_FIRMWARE_DOWNLOADER)  += intel-ish-hid/
+ obj-$(CONFIG_AMD_SFH_HID)       += amd-sfh-hid/
+-- 
+2.39.5
+
diff --git a/queue-6.14/i3c-master-svc-fix-missing-the-ibi-rules.patch b/queue-6.14/i3c-master-svc-fix-missing-the-ibi-rules.patch
new file mode 100644 (file)
index 0000000..fc26ca1
--- /dev/null
@@ -0,0 +1,40 @@
+From 8833eaf12fb142876cb6313377bde13eeaf20262 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Mar 2025 13:36:04 +0800
+Subject: i3c: master: svc: Fix missing the IBI rules
+
+From: Stanley Chu <yschu@nuvoton.com>
+
+[ Upstream commit 9cecad134d84d14dc72a0eea7a107691c3e5a837 ]
+
+The code does not add IBI rules for devices with controller capability.
+However, the secondary controller has the controller capability and works
+at target mode when the device is probed. Therefore, add IBI rules for
+such devices.
+
+Fixes: dd3c52846d59 ("i3c: master: svc: Add Silvaco I3C master driver")
+Signed-off-by: Stanley Chu <yschu@nuvoton.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://lore.kernel.org/r/20250318053606.3087121-2-yschu@nuvoton.com
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i3c/master/svc-i3c-master.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/i3c/master/svc-i3c-master.c b/drivers/i3c/master/svc-i3c-master.c
+index d6057d8c7dec4..ecc07c17f4c79 100644
+--- a/drivers/i3c/master/svc-i3c-master.c
++++ b/drivers/i3c/master/svc-i3c-master.c
+@@ -1037,7 +1037,7 @@ static int svc_i3c_update_ibirules(struct svc_i3c_master *master)
+       /* Create the IBIRULES register for both cases */
+       i3c_bus_for_each_i3cdev(&master->base.bus, dev) {
+-              if (I3C_BCR_DEVICE_ROLE(dev->info.bcr) == I3C_BCR_I3C_MASTER)
++              if (!(dev->info.bcr & I3C_BCR_IBI_REQ_CAP))
+                       continue;
+               if (dev->info.bcr & I3C_BCR_IBI_PAYLOAD) {
+-- 
+2.39.5
+
diff --git a/queue-6.14/ib-mad-check-available-slots-before-posting-receive-.patch b/queue-6.14/ib-mad-check-available-slots-before-posting-receive-.patch
new file mode 100644 (file)
index 0000000..78cb807
--- /dev/null
@@ -0,0 +1,133 @@
+From 08528db5c62e99be9cfa0cbef9a6b979909e3a29 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Mar 2025 16:20:17 +0200
+Subject: IB/mad: Check available slots before posting receive WRs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Maher Sanalla <msanalla@nvidia.com>
+
+[ Upstream commit 37826f0a8c2f6b6add5179003b8597e32a445362 ]
+
+The ib_post_receive_mads() function handles posting receive work
+requests (WRs) to MAD QPs and is called in two cases:
+1) When a MAD port is opened.
+2) When a receive WQE is consumed upon receiving a new MAD.
+
+Whereas, if MADs arrive during the port open phase, a race condition
+might cause an extra WR to be posted, exceeding the QP’s capacity.
+This leads to failures such as:
+infiniband mlx5_0: ib_post_recv failed: -12
+infiniband mlx5_0: Couldn't post receive WRs
+infiniband mlx5_0: Couldn't start port
+infiniband mlx5_0: Couldn't open port 1
+
+Fix this by checking the current receive count before posting a new WR.
+If the QP’s receive queue is full, do not post additional WRs.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Maher Sanalla <msanalla@nvidia.com>
+Link: https://patch.msgid.link/c4984ba3c3a98a5711a558bccefcad789587ecf1.1741875592.git.leon@kernel.org
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/mad.c | 38 ++++++++++++++++++-----------------
+ 1 file changed, 20 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
+index 1fd54d5c4dd8b..73f3a0b9a54b5 100644
+--- a/drivers/infiniband/core/mad.c
++++ b/drivers/infiniband/core/mad.c
+@@ -2671,11 +2671,11 @@ static int ib_mad_post_receive_mads(struct ib_mad_qp_info *qp_info,
+                                   struct ib_mad_private *mad)
+ {
+       unsigned long flags;
+-      int post, ret;
+       struct ib_mad_private *mad_priv;
+       struct ib_sge sg_list;
+       struct ib_recv_wr recv_wr;
+       struct ib_mad_queue *recv_queue = &qp_info->recv_queue;
++      int ret = 0;
+       /* Initialize common scatter list fields */
+       sg_list.lkey = qp_info->port_priv->pd->local_dma_lkey;
+@@ -2685,7 +2685,7 @@ static int ib_mad_post_receive_mads(struct ib_mad_qp_info *qp_info,
+       recv_wr.sg_list = &sg_list;
+       recv_wr.num_sge = 1;
+-      do {
++      while (true) {
+               /* Allocate and map receive buffer */
+               if (mad) {
+                       mad_priv = mad;
+@@ -2693,10 +2693,8 @@ static int ib_mad_post_receive_mads(struct ib_mad_qp_info *qp_info,
+               } else {
+                       mad_priv = alloc_mad_private(port_mad_size(qp_info->port_priv),
+                                                    GFP_ATOMIC);
+-                      if (!mad_priv) {
+-                              ret = -ENOMEM;
+-                              break;
+-                      }
++                      if (!mad_priv)
++                              return -ENOMEM;
+               }
+               sg_list.length = mad_priv_dma_size(mad_priv);
+               sg_list.addr = ib_dma_map_single(qp_info->port_priv->device,
+@@ -2705,37 +2703,41 @@ static int ib_mad_post_receive_mads(struct ib_mad_qp_info *qp_info,
+                                                DMA_FROM_DEVICE);
+               if (unlikely(ib_dma_mapping_error(qp_info->port_priv->device,
+                                                 sg_list.addr))) {
+-                      kfree(mad_priv);
+                       ret = -ENOMEM;
+-                      break;
++                      goto free_mad_priv;
+               }
+               mad_priv->header.mapping = sg_list.addr;
+               mad_priv->header.mad_list.mad_queue = recv_queue;
+               mad_priv->header.mad_list.cqe.done = ib_mad_recv_done;
+               recv_wr.wr_cqe = &mad_priv->header.mad_list.cqe;
+-
+-              /* Post receive WR */
+               spin_lock_irqsave(&recv_queue->lock, flags);
+-              post = (++recv_queue->count < recv_queue->max_active);
+-              list_add_tail(&mad_priv->header.mad_list.list, &recv_queue->list);
++              if (recv_queue->count >= recv_queue->max_active) {
++                      /* Fully populated the receive queue */
++                      spin_unlock_irqrestore(&recv_queue->lock, flags);
++                      break;
++              }
++              recv_queue->count++;
++              list_add_tail(&mad_priv->header.mad_list.list,
++                            &recv_queue->list);
+               spin_unlock_irqrestore(&recv_queue->lock, flags);
++
+               ret = ib_post_recv(qp_info->qp, &recv_wr, NULL);
+               if (ret) {
+                       spin_lock_irqsave(&recv_queue->lock, flags);
+                       list_del(&mad_priv->header.mad_list.list);
+                       recv_queue->count--;
+                       spin_unlock_irqrestore(&recv_queue->lock, flags);
+-                      ib_dma_unmap_single(qp_info->port_priv->device,
+-                                          mad_priv->header.mapping,
+-                                          mad_priv_dma_size(mad_priv),
+-                                          DMA_FROM_DEVICE);
+-                      kfree(mad_priv);
+                       dev_err(&qp_info->port_priv->device->dev,
+                               "ib_post_recv failed: %d\n", ret);
+                       break;
+               }
+-      } while (post);
++      }
++      ib_dma_unmap_single(qp_info->port_priv->device,
++                          mad_priv->header.mapping,
++                          mad_priv_dma_size(mad_priv), DMA_FROM_DEVICE);
++free_mad_priv:
++      kfree(mad_priv);
+       return ret;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/ibmvnic-use-kernel-helpers-for-hex-dumps.patch b/queue-6.14/ibmvnic-use-kernel-helpers-for-hex-dumps.patch
new file mode 100644 (file)
index 0000000..61899cb
--- /dev/null
@@ -0,0 +1,119 @@
+From 3cbedc0461d20a6a49c90d7722db2999b892cacd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Mar 2025 16:29:51 -0500
+Subject: ibmvnic: Use kernel helpers for hex dumps
+
+From: Nick Child <nnac123@linux.ibm.com>
+
+[ Upstream commit d93a6caab5d7d9b5ce034d75b1e1e993338e3852 ]
+
+Previously, when the driver was printing hex dumps, the buffer was cast
+to an 8 byte long and printed using string formatters. If the buffer
+size was not a multiple of 8 then a read buffer overflow was possible.
+
+Therefore, create a new ibmvnic function that loops over a buffer and
+calls hex_dump_to_buffer instead.
+
+This patch address KASAN reports like the one below:
+  ibmvnic 30000003 env3: Login Buffer:
+  ibmvnic 30000003 env3: 01000000af000000
+  <...>
+  ibmvnic 30000003 env3: 2e6d62692e736261
+  ibmvnic 30000003 env3: 65050003006d6f63
+  ==================================================================
+  BUG: KASAN: slab-out-of-bounds in ibmvnic_login+0xacc/0xffc [ibmvnic]
+  Read of size 8 at addr c0000001331a9aa8 by task ip/17681
+  <...>
+  Allocated by task 17681:
+  <...>
+  ibmvnic_login+0x2f0/0xffc [ibmvnic]
+  ibmvnic_open+0x148/0x308 [ibmvnic]
+  __dev_open+0x1ac/0x304
+  <...>
+  The buggy address is located 168 bytes inside of
+                allocated 175-byte region [c0000001331a9a00, c0000001331a9aaf)
+  <...>
+  =================================================================
+  ibmvnic 30000003 env3: 000000000033766e
+
+Fixes: 032c5e82847a ("Driver for IBM System i/p VNIC protocol")
+Signed-off-by: Nick Child <nnac123@linux.ibm.com>
+Reviewed-by: Dave Marquardt <davemarq@linux.ibm.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250320212951.11142-1-nnac123@linux.ibm.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ibm/ibmvnic.c | 30 ++++++++++++++++++------------
+ 1 file changed, 18 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
+index 0676fc547b6f4..480606d1245ea 100644
+--- a/drivers/net/ethernet/ibm/ibmvnic.c
++++ b/drivers/net/ethernet/ibm/ibmvnic.c
+@@ -4829,6 +4829,18 @@ static void vnic_add_client_data(struct ibmvnic_adapter *adapter,
+       strscpy(vlcd->name, adapter->netdev->name, len);
+ }
++static void ibmvnic_print_hex_dump(struct net_device *dev, void *buf,
++                                 size_t len)
++{
++      unsigned char hex_str[16 * 3];
++
++      for (size_t i = 0; i < len; i += 16) {
++              hex_dump_to_buffer((unsigned char *)buf + i, len - i, 16, 8,
++                                 hex_str, sizeof(hex_str), false);
++              netdev_dbg(dev, "%s\n", hex_str);
++      }
++}
++
+ static int send_login(struct ibmvnic_adapter *adapter)
+ {
+       struct ibmvnic_login_rsp_buffer *login_rsp_buffer;
+@@ -4939,10 +4951,8 @@ static int send_login(struct ibmvnic_adapter *adapter)
+       vnic_add_client_data(adapter, vlcd);
+       netdev_dbg(adapter->netdev, "Login Buffer:\n");
+-      for (i = 0; i < (adapter->login_buf_sz - 1) / 8 + 1; i++) {
+-              netdev_dbg(adapter->netdev, "%016lx\n",
+-                         ((unsigned long *)(adapter->login_buf))[i]);
+-      }
++      ibmvnic_print_hex_dump(adapter->netdev, adapter->login_buf,
++                             adapter->login_buf_sz);
+       memset(&crq, 0, sizeof(crq));
+       crq.login.first = IBMVNIC_CRQ_CMD;
+@@ -5319,15 +5329,13 @@ static void handle_query_ip_offload_rsp(struct ibmvnic_adapter *adapter)
+ {
+       struct device *dev = &adapter->vdev->dev;
+       struct ibmvnic_query_ip_offload_buffer *buf = &adapter->ip_offload_buf;
+-      int i;
+       dma_unmap_single(dev, adapter->ip_offload_tok,
+                        sizeof(adapter->ip_offload_buf), DMA_FROM_DEVICE);
+       netdev_dbg(adapter->netdev, "Query IP Offload Buffer:\n");
+-      for (i = 0; i < (sizeof(adapter->ip_offload_buf) - 1) / 8 + 1; i++)
+-              netdev_dbg(adapter->netdev, "%016lx\n",
+-                         ((unsigned long *)(buf))[i]);
++      ibmvnic_print_hex_dump(adapter->netdev, buf,
++                             sizeof(adapter->ip_offload_buf));
+       netdev_dbg(adapter->netdev, "ipv4_chksum = %d\n", buf->ipv4_chksum);
+       netdev_dbg(adapter->netdev, "ipv6_chksum = %d\n", buf->ipv6_chksum);
+@@ -5558,10 +5566,8 @@ static int handle_login_rsp(union ibmvnic_crq *login_rsp_crq,
+       netdev->mtu = adapter->req_mtu - ETH_HLEN;
+       netdev_dbg(adapter->netdev, "Login Response Buffer:\n");
+-      for (i = 0; i < (adapter->login_rsp_buf_sz - 1) / 8 + 1; i++) {
+-              netdev_dbg(adapter->netdev, "%016lx\n",
+-                         ((unsigned long *)(adapter->login_rsp_buf))[i]);
+-      }
++      ibmvnic_print_hex_dump(netdev, adapter->login_rsp_buf,
++                             adapter->login_rsp_buf_sz);
+       /* Sanity checks */
+       if (login->num_txcomp_subcrqs != login_rsp->num_txsubm_subcrqs ||
+-- 
+2.39.5
+
diff --git a/queue-6.14/ice-ensure-periodic-output-start-time-is-in-the-futu.patch b/queue-6.14/ice-ensure-periodic-output-start-time-is-in-the-futu.patch
new file mode 100644 (file)
index 0000000..3de248b
--- /dev/null
@@ -0,0 +1,101 @@
+From eb2e68a806dccb39d9d85b68465d6fe830abedff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Feb 2025 14:13:27 -0800
+Subject: ice: ensure periodic output start time is in the future
+
+From: Karol Kolacinski <karol.kolacinski@intel.com>
+
+[ Upstream commit 53ce7166cbffd2b8f3bd821fd3918be665afd4c6 ]
+
+On E800 series hardware, if the start time for a periodic output signal is
+programmed into GLTSYN_TGT_H and GLTSYN_TGT_L registers, the hardware logic
+locks up and the periodic output signal never starts. Any future attempt to
+reprogram the clock function is futile as the hardware will not reset until
+a power on.
+
+The ice_ptp_cfg_perout function has logic to prevent this, as it checks if
+the requested start time is in the past. If so, a new start time is
+calculated by rounding up.
+
+Since commit d755a7e129a5 ("ice: Cache perout/extts requests and check
+flags"), the rounding is done to the nearest multiple of the clock period,
+rather than to a full second. This is more accurate, since it ensures the
+signal matches the user request precisely.
+
+Unfortunately, there is a race condition with this rounding logic. If the
+current time is close to the multiple of the period, we could calculate a
+target time that is extremely soon. It takes time for the software to
+program the registers, during which time this requested start time could
+become a start time in the past. If that happens, the periodic output
+signal will lock up.
+
+For large enough periods, or for the logic prior to the mentioned commit,
+this is unlikely. However, with the new logic rounding to the period and
+with a small enough period, this becomes inevitable.
+
+For example, attempting to enable a 10MHz signal requires a period of 100
+nanoseconds. This means in the *best* case, we have 99 nanoseconds to
+program the clock output. This is essentially impossible, and thus such a
+small period practically guarantees that the clock output function will
+lock up.
+
+To fix this, add some slop to the clock time used to check if the start
+time is in the past. Because it is not critical that output signals start
+immediately, but it *is* critical that we do not brick the function, 0.5
+seconds is selected. This does mean that any requested output will be
+delayed by at least 0.5 seconds.
+
+This slop is applied before rounding, so that we always round up to the
+nearest multiple of the period that is at least 0.5 seconds in the future,
+ensuring a minimum of 0.5 seconds to program the clock output registers.
+
+Finally, to ensure that the hardware registers programming the clock output
+complete in a timely manner, add a write flush to the end of
+ice_ptp_write_perout. This ensures we don't risk any issue with PCIe
+transaction batching.
+
+Strictly speaking, this fixes a race condition all the way back at the
+initial implementation of periodic output programming, as it is
+theoretically possible to trigger this bug even on the old logic when
+always rounding to a full second. However, the window is narrow, and the
+code has been refactored heavily since then, making a direct backport not
+apply cleanly.
+
+Fixes: d755a7e129a5 ("ice: Cache perout/extts requests and check flags")
+Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Tested-by: Rinitha S <sx.rinitha@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_ptp.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
+index e26320ce52ca1..a99e0fbd0b8b5 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
++++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
+@@ -1783,6 +1783,7 @@ static int ice_ptp_write_perout(struct ice_hw *hw, unsigned int chan,
+                                 8 + chan + (tmr_idx * 4));
+       wr32(hw, GLGEN_GPIO_CTL(gpio_pin), val);
++      ice_flush(hw);
+       return 0;
+ }
+@@ -1843,9 +1844,10 @@ static int ice_ptp_cfg_perout(struct ice_pf *pf, struct ptp_perout_request *rq,
+               div64_u64_rem(start, period, &phase);
+       /* If we have only phase or start time is in the past, start the timer
+-       * at the next multiple of period, maintaining phase.
++       * at the next multiple of period, maintaining phase at least 0.5 second
++       * from now, so we have time to write it to HW.
+        */
+-      clk = ice_ptp_read_src_clk_reg(pf, NULL);
++      clk = ice_ptp_read_src_clk_reg(pf, NULL) + NSEC_PER_MSEC * 500;
+       if (rq->flags & PTP_PEROUT_PHASE || start <= clk - prop_delay_ns)
+               start = div64_u64(clk + period - 1, period) * period + phase;
+-- 
+2.39.5
+
diff --git a/queue-6.14/ice-fix-input-validation-for-virtchnl-bw.patch b/queue-6.14/ice-fix-input-validation-for-virtchnl-bw.patch
new file mode 100644 (file)
index 0000000..5b9da32
--- /dev/null
@@ -0,0 +1,73 @@
+From 8319a8c4840a2654ed0ebd53ab44290e527039c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Mar 2025 12:08:34 +0100
+Subject: ice: fix input validation for virtchnl BW
+
+From: Lukasz Czapnik <lukasz.czapnik@intel.com>
+
+[ Upstream commit c5be6562de5a19c44605b1c1edba8e339f2022c8 ]
+
+Add missing validation of tc and queue id values sent by a VF in
+ice_vc_cfg_q_bw().
+Additionally fixed logged value in the warning message,
+where max_tx_rate was incorrectly referenced instead of min_tx_rate.
+Also correct error handling in this function by properly exiting
+when invalid configuration is detected.
+
+Fixes: 015307754a19 ("ice: Support VF queue rate limit and quanta size configuration")
+Reviewed-by: Jedrzej Jagielski <jedrzej.jagielski@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Lukasz Czapnik <lukasz.czapnik@intel.com>
+Co-developed-by: Martyna Szapar-Mudlaw <martyna.szapar-mudlaw@linux.intel.com>
+Signed-off-by: Martyna Szapar-Mudlaw <martyna.szapar-mudlaw@linux.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/ice/ice_virtchnl.c | 24 ++++++++++++++++---
+ 1 file changed, 21 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl.c b/drivers/net/ethernet/intel/ice/ice_virtchnl.c
+index df13f5110168d..1af51469f070b 100644
+--- a/drivers/net/ethernet/intel/ice/ice_virtchnl.c
++++ b/drivers/net/ethernet/intel/ice/ice_virtchnl.c
+@@ -1862,15 +1862,33 @@ static int ice_vc_cfg_q_bw(struct ice_vf *vf, u8 *msg)
+       for (i = 0; i < qbw->num_queues; i++) {
+               if (qbw->cfg[i].shaper.peak != 0 && vf->max_tx_rate != 0 &&
+-                  qbw->cfg[i].shaper.peak > vf->max_tx_rate)
++                  qbw->cfg[i].shaper.peak > vf->max_tx_rate) {
+                       dev_warn(ice_pf_to_dev(vf->pf), "The maximum queue %d rate limit configuration may not take effect because the maximum TX rate for VF-%d is %d\n",
+                                qbw->cfg[i].queue_id, vf->vf_id,
+                                vf->max_tx_rate);
++                      v_ret = VIRTCHNL_STATUS_ERR_PARAM;
++                      goto err;
++              }
+               if (qbw->cfg[i].shaper.committed != 0 && vf->min_tx_rate != 0 &&
+-                  qbw->cfg[i].shaper.committed < vf->min_tx_rate)
++                  qbw->cfg[i].shaper.committed < vf->min_tx_rate) {
+                       dev_warn(ice_pf_to_dev(vf->pf), "The minimum queue %d rate limit configuration may not take effect because the minimum TX rate for VF-%d is %d\n",
+                                qbw->cfg[i].queue_id, vf->vf_id,
+-                               vf->max_tx_rate);
++                               vf->min_tx_rate);
++                      v_ret = VIRTCHNL_STATUS_ERR_PARAM;
++                      goto err;
++              }
++              if (qbw->cfg[i].queue_id > vf->num_vf_qs) {
++                      dev_warn(ice_pf_to_dev(vf->pf), "VF-%d trying to configure invalid queue_id\n",
++                               vf->vf_id);
++                      v_ret = VIRTCHNL_STATUS_ERR_PARAM;
++                      goto err;
++              }
++              if (qbw->cfg[i].tc >= ICE_MAX_TRAFFIC_CLASS) {
++                      dev_warn(ice_pf_to_dev(vf->pf), "VF-%d trying to configure a traffic class higher than allowed\n",
++                               vf->vf_id);
++                      v_ret = VIRTCHNL_STATUS_ERR_PARAM;
++                      goto err;
++              }
+       }
+       for (i = 0; i < qbw->num_queues; i++) {
+-- 
+2.39.5
+
diff --git a/queue-6.14/ice-fix-reservation-of-resources-for-rdma-when-disab.patch b/queue-6.14/ice-fix-reservation-of-resources-for-rdma-when-disab.patch
new file mode 100644 (file)
index 0000000..c328e36
--- /dev/null
@@ -0,0 +1,49 @@
+From 045119b2f143cf5888626d367fcd441649c9021c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Mar 2025 09:56:34 -0800
+Subject: ice: fix reservation of resources for RDMA when disabled
+
+From: Jesse Brandeburg <jbrandeburg@cloudflare.com>
+
+[ Upstream commit 7fd71f317288d5150d353ce9d65b1e2abf99a8e2 ]
+
+If the CONFIG_INFINIBAND_IRDMA symbol is not enabled as a module or a
+built-in, then don't let the driver reserve resources for RDMA. The result
+of this change is a large savings in resources for older kernels, and a
+cleaner driver configuration for the IRDMA=n case for old and new kernels.
+
+Implement this by avoiding enabling the RDMA capability when scanning
+hardware capabilities.
+
+Note: Loading the out-of-tree irdma driver in connection to the in-kernel
+ice driver, is not supported, and should not be attempted, especially when
+disabling IRDMA in the kernel config.
+
+Fixes: d25a0fc41c1f ("ice: Initialize RDMA support")
+Signed-off-by: Jesse Brandeburg <jbrandeburg@cloudflare.com>
+Acked-by: Dave Ertman <david.m.ertman@intel.com>
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Tested-by: Rinitha S <sx.rinitha@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_common.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
+index 7a2a2e8da8fab..1e801300310e9 100644
+--- a/drivers/net/ethernet/intel/ice/ice_common.c
++++ b/drivers/net/ethernet/intel/ice/ice_common.c
+@@ -2271,7 +2271,8 @@ ice_parse_common_caps(struct ice_hw *hw, struct ice_hw_common_caps *caps,
+                         caps->nvm_unified_update);
+               break;
+       case ICE_AQC_CAPS_RDMA:
+-              caps->rdma = (number == 1);
++              if (IS_ENABLED(CONFIG_INFINIBAND_IRDMA))
++                      caps->rdma = (number == 1);
+               ice_debug(hw, ICE_DBG_INIT, "%s: rdma = %d\n", prefix, caps->rdma);
+               break;
+       case ICE_AQC_CAPS_MAX_MTU:
+-- 
+2.39.5
+
diff --git a/queue-6.14/ice-fix-using-untrusted-value-of-pkt_len-in-ice_vc_f.patch b/queue-6.14/ice-fix-using-untrusted-value-of-pkt_len-in-ice_vc_f.patch
new file mode 100644 (file)
index 0000000..1a2ef19
--- /dev/null
@@ -0,0 +1,92 @@
+From a3ac4ce7b5bee51e8690711c4b57dcec1c129d58 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Mar 2025 12:08:36 +0100
+Subject: ice: fix using untrusted value of pkt_len in ice_vc_fdir_parse_raw()
+
+From: Mateusz Polchlopek <mateusz.polchlopek@intel.com>
+
+[ Upstream commit 1388dd564183a5a18ec4a966748037736b5653c5 ]
+
+Fix using the untrusted value of proto->raw.pkt_len in function
+ice_vc_fdir_parse_raw() by verifying if it does not exceed the
+VIRTCHNL_MAX_SIZE_RAW_PACKET value.
+
+Fixes: 99f419df8a5c ("ice: enable FDIR filters from raw binary patterns for VFs")
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Signed-off-by: Mateusz Polchlopek <mateusz.polchlopek@intel.com>
+Signed-off-by: Martyna Szapar-Mudlaw <martyna.szapar-mudlaw@linux.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>
+---
+ .../ethernet/intel/ice/ice_virtchnl_fdir.c    | 24 ++++++++++++-------
+ 1 file changed, 15 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c b/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c
+index 14e3f0f89c78d..9be4bd717512d 100644
+--- a/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c
++++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c
+@@ -832,21 +832,27 @@ ice_vc_fdir_parse_raw(struct ice_vf *vf,
+                     struct virtchnl_proto_hdrs *proto,
+                     struct virtchnl_fdir_fltr_conf *conf)
+ {
+-      u8 *pkt_buf, *msk_buf __free(kfree);
++      u8 *pkt_buf, *msk_buf __free(kfree) = NULL;
+       struct ice_parser_result rslt;
+       struct ice_pf *pf = vf->pf;
++      u16 pkt_len, udp_port = 0;
+       struct ice_parser *psr;
+       int status = -ENOMEM;
+       struct ice_hw *hw;
+-      u16 udp_port = 0;
+-      pkt_buf = kzalloc(proto->raw.pkt_len, GFP_KERNEL);
+-      msk_buf = kzalloc(proto->raw.pkt_len, GFP_KERNEL);
++      pkt_len = proto->raw.pkt_len;
++
++      if (!pkt_len || pkt_len > VIRTCHNL_MAX_SIZE_RAW_PACKET)
++              return -EINVAL;
++
++      pkt_buf = kzalloc(pkt_len, GFP_KERNEL);
++      msk_buf = kzalloc(pkt_len, GFP_KERNEL);
++
+       if (!pkt_buf || !msk_buf)
+               goto err_mem_alloc;
+-      memcpy(pkt_buf, proto->raw.spec, proto->raw.pkt_len);
+-      memcpy(msk_buf, proto->raw.mask, proto->raw.pkt_len);
++      memcpy(pkt_buf, proto->raw.spec, pkt_len);
++      memcpy(msk_buf, proto->raw.mask, pkt_len);
+       hw = &pf->hw;
+@@ -862,7 +868,7 @@ ice_vc_fdir_parse_raw(struct ice_vf *vf,
+       if (ice_get_open_tunnel_port(hw, &udp_port, TNL_VXLAN))
+               ice_parser_vxlan_tunnel_set(psr, udp_port, true);
+-      status = ice_parser_run(psr, pkt_buf, proto->raw.pkt_len, &rslt);
++      status = ice_parser_run(psr, pkt_buf, pkt_len, &rslt);
+       if (status)
+               goto err_parser_destroy;
+@@ -876,7 +882,7 @@ ice_vc_fdir_parse_raw(struct ice_vf *vf,
+       }
+       status = ice_parser_profile_init(&rslt, pkt_buf, msk_buf,
+-                                       proto->raw.pkt_len, ICE_BLK_FD,
++                                       pkt_len, ICE_BLK_FD,
+                                        conf->prof);
+       if (status)
+               goto err_parser_profile_init;
+@@ -885,7 +891,7 @@ ice_vc_fdir_parse_raw(struct ice_vf *vf,
+               ice_parser_profile_dump(hw, conf->prof);
+       /* Store raw flow info into @conf */
+-      conf->pkt_len = proto->raw.pkt_len;
++      conf->pkt_len = pkt_len;
+       conf->pkt_buf = pkt_buf;
+       conf->parser_ena = true;
+-- 
+2.39.5
+
diff --git a/queue-6.14/ice-health.c-fix-compilation-on-gcc-7.5.patch b/queue-6.14/ice-health.c-fix-compilation-on-gcc-7.5.patch
new file mode 100644 (file)
index 0000000..d9368c4
--- /dev/null
@@ -0,0 +1,69 @@
+From 92c93fdc5485cd1883eef3c936cb0e68d80d64dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Feb 2025 23:30:23 +0100
+Subject: ice: health.c: fix compilation on gcc 7.5
+
+From: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+
+[ Upstream commit fa8eda19015ca9ae625f46d4ecb13df651bb54cc ]
+
+GCC 7 is not as good as GCC 8+ in telling what is a compile-time
+const, and thus could be used for static storage.
+Fortunately keeping strings as const arrays is enough to make old
+gcc happy.
+
+Excerpt from the report:
+My GCC is: gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0.
+
+  CC [M]  drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.o
+drivers/net/ethernet/intel/ice/devlink/health.c:35:3: error: initializer element is not constant
+   ice_common_port_solutions, {ice_port_number_label}},
+   ^~~~~~~~~~~~~~~~~~~~~~~~~
+drivers/net/ethernet/intel/ice/devlink/health.c:35:3: note: (near initialization for 'ice_health_status_lookup[0].solution')
+drivers/net/ethernet/intel/ice/devlink/health.c:35:31: error: initializer element is not constant
+   ice_common_port_solutions, {ice_port_number_label}},
+                               ^~~~~~~~~~~~~~~~~~~~~
+drivers/net/ethernet/intel/ice/devlink/health.c:35:31: note: (near initialization for 'ice_health_status_lookup[0].data_label[0]')
+drivers/net/ethernet/intel/ice/devlink/health.c:37:46: error: initializer element is not constant
+   "Change or replace the module or cable.", {ice_port_number_label}},
+                                              ^~~~~~~~~~~~~~~~~~~~~
+drivers/net/ethernet/intel/ice/devlink/health.c:37:46: note: (near initialization for 'ice_health_status_lookup[1].data_label[0]')
+drivers/net/ethernet/intel/ice/devlink/health.c:39:3: error: initializer element is not constant
+   ice_common_port_solutions, {ice_port_number_label}},
+   ^~~~~~~~~~~~~~~~~~~~~~~~~
+
+Fixes: 85d6164ec56d ("ice: add fw and port health reporters")
+Reported-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+Closes: https://lore.kernel.org/netdev/CY8PR11MB7134BF7A46D71E50D25FA7A989F72@CY8PR11MB7134.namprd11.prod.outlook.com
+Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
+Suggested-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Tested-by: Sunitha Mekala <sunithax.d.mekala@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/devlink/health.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/devlink/health.c b/drivers/net/ethernet/intel/ice/devlink/health.c
+index ea40f79412590..19c3d37aa768b 100644
+--- a/drivers/net/ethernet/intel/ice/devlink/health.c
++++ b/drivers/net/ethernet/intel/ice/devlink/health.c
+@@ -25,10 +25,10 @@ struct ice_health_status {
+  * The below lookup requires to be sorted by code.
+  */
+-static const char *const ice_common_port_solutions =
++static const char ice_common_port_solutions[] =
+       "Check your cable connection. Change or replace the module or cable. Manually set speed and duplex.";
+-static const char *const ice_port_number_label = "Port Number";
+-static const char *const ice_update_nvm_solution = "Update to the latest NVM image.";
++static const char ice_port_number_label[] = "Port Number";
++static const char ice_update_nvm_solution[] = "Update to the latest NVM image.";
+ static const struct ice_health_status ice_health_status_lookup[] = {
+       {ICE_AQC_HEALTH_STATUS_ERR_UNKNOWN_MOD_STRICT, "An unsupported module was detected.",
+-- 
+2.39.5
+
diff --git a/queue-6.14/ice-stop-truncating-queue-ids-when-checking.patch b/queue-6.14/ice-stop-truncating-queue-ids-when-checking.patch
new file mode 100644 (file)
index 0000000..e0bee9c
--- /dev/null
@@ -0,0 +1,41 @@
+From 4408563cab4b29737ff70658e877232c7cfdaa6b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Mar 2025 12:08:32 +0100
+Subject: ice: stop truncating queue ids when checking
+
+From: Jan Glaza <jan.glaza@intel.com>
+
+[ Upstream commit f91d0efcc3dd7b341bb370499b99dc02d4fb792f ]
+
+Queue IDs can be up to 4096, fix invalid check to stop
+truncating IDs to 8 bits.
+
+Fixes: bf93bf791cec8 ("ice: introduce ice_virtchnl.c and ice_virtchnl.h")
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Reviewed-by: Jedrzej Jagielski <jedrzej.jagielski@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Jan Glaza <jan.glaza@intel.com>
+Signed-off-by: Martyna Szapar-Mudlaw <martyna.szapar-mudlaw@linux.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/ice/ice_virtchnl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl.c b/drivers/net/ethernet/intel/ice/ice_virtchnl.c
+index ff4ad788d96ac..346aee373ccd4 100644
+--- a/drivers/net/ethernet/intel/ice/ice_virtchnl.c
++++ b/drivers/net/ethernet/intel/ice/ice_virtchnl.c
+@@ -562,7 +562,7 @@ bool ice_vc_isvalid_vsi_id(struct ice_vf *vf, u16 vsi_id)
+  *
+  * check for the valid queue ID
+  */
+-static bool ice_vc_isvalid_q_id(struct ice_vsi *vsi, u8 qid)
++static bool ice_vc_isvalid_q_id(struct ice_vsi *vsi, u16 qid)
+ {
+       /* allocated Tx and Rx queues should be always equal for VF VSI */
+       return qid < vsi->alloc_txq;
+-- 
+2.39.5
+
diff --git a/queue-6.14/ice-validate-queue-quanta-parameters-to-prevent-oob-.patch b/queue-6.14/ice-validate-queue-quanta-parameters-to-prevent-oob-.patch
new file mode 100644 (file)
index 0000000..b952e3a
--- /dev/null
@@ -0,0 +1,71 @@
+From 340add927f4b564e78b7b1ca7022bfee7b7f6670 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Mar 2025 12:08:33 +0100
+Subject: ice: validate queue quanta parameters to prevent OOB access
+
+From: Jan Glaza <jan.glaza@intel.com>
+
+[ Upstream commit e2f7d3f7331b92cb820da23e8c45133305da1e63 ]
+
+Add queue wraparound prevention in quanta configuration.
+Ensure end_qid does not overflow by validating start_qid and num_queues.
+
+Fixes: 015307754a19 ("ice: Support VF queue rate limit and quanta size configuration")
+Reviewed-by: Jedrzej Jagielski <jedrzej.jagielski@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Jan Glaza <jan.glaza@intel.com>
+Signed-off-by: Martyna Szapar-Mudlaw <martyna.szapar-mudlaw@linux.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/ice/ice_virtchnl.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl.c b/drivers/net/ethernet/intel/ice/ice_virtchnl.c
+index 346aee373ccd4..df13f5110168d 100644
+--- a/drivers/net/ethernet/intel/ice/ice_virtchnl.c
++++ b/drivers/net/ethernet/intel/ice/ice_virtchnl.c
+@@ -1900,13 +1900,21 @@ static int ice_vc_cfg_q_bw(struct ice_vf *vf, u8 *msg)
+  */
+ static int ice_vc_cfg_q_quanta(struct ice_vf *vf, u8 *msg)
+ {
++      u16 quanta_prof_id, quanta_size, start_qid, num_queues, end_qid, i;
+       enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS;
+-      u16 quanta_prof_id, quanta_size, start_qid, end_qid, i;
+       struct virtchnl_quanta_cfg *qquanta =
+               (struct virtchnl_quanta_cfg *)msg;
+       struct ice_vsi *vsi;
+       int ret;
++      start_qid = qquanta->queue_select.start_queue_id;
++      num_queues = qquanta->queue_select.num_queues;
++
++      if (check_add_overflow(start_qid, num_queues, &end_qid)) {
++              v_ret = VIRTCHNL_STATUS_ERR_PARAM;
++              goto err;
++      }
++
+       if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) {
+               v_ret = VIRTCHNL_STATUS_ERR_PARAM;
+               goto err;
+@@ -1918,8 +1926,6 @@ static int ice_vc_cfg_q_quanta(struct ice_vf *vf, u8 *msg)
+               goto err;
+       }
+-      end_qid = qquanta->queue_select.start_queue_id +
+-                qquanta->queue_select.num_queues;
+       if (end_qid > ICE_MAX_RSS_QS_PER_VF ||
+           end_qid > min_t(u16, vsi->alloc_txq, vsi->alloc_rxq)) {
+               dev_err(ice_pf_to_dev(vf->pf), "VF-%d trying to configure more than allocated number of queues: %d\n",
+@@ -1948,7 +1954,6 @@ static int ice_vc_cfg_q_quanta(struct ice_vf *vf, u8 *msg)
+               goto err;
+       }
+-      start_qid = qquanta->queue_select.start_queue_id;
+       for (i = start_qid; i < end_qid; i++)
+               vsi->tx_rings[i]->quanta_prof_id = quanta_prof_id;
+-- 
+2.39.5
+
diff --git a/queue-6.14/idpf-check-error-for-register_netdev-on-init.patch b/queue-6.14/idpf-check-error-for-register_netdev-on-init.patch
new file mode 100644 (file)
index 0000000..9cf0b89
--- /dev/null
@@ -0,0 +1,102 @@
+From c511988b2e591381dfe94def5f54aa661b388325 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Feb 2025 09:18:16 -0800
+Subject: idpf: check error for register_netdev() on init
+
+From: Emil Tantilov <emil.s.tantilov@intel.com>
+
+[ Upstream commit 680811c67906191b237bbafe7dabbbad64649b39 ]
+
+Current init logic ignores the error code from register_netdev(),
+which will cause WARN_ON() on attempt to unregister it, if there was one,
+and there is no info for the user that the creation of the netdev failed.
+
+WARNING: CPU: 89 PID: 6902 at net/core/dev.c:11512 unregister_netdevice_many_notify+0x211/0x1a10
+...
+[ 3707.563641]  unregister_netdev+0x1c/0x30
+[ 3707.563656]  idpf_vport_dealloc+0x5cf/0xce0 [idpf]
+[ 3707.563684]  idpf_deinit_task+0xef/0x160 [idpf]
+[ 3707.563712]  idpf_vc_core_deinit+0x84/0x320 [idpf]
+[ 3707.563739]  idpf_remove+0xbf/0x780 [idpf]
+[ 3707.563769]  pci_device_remove+0xab/0x1e0
+[ 3707.563786]  device_release_driver_internal+0x371/0x530
+[ 3707.563803]  driver_detach+0xbf/0x180
+[ 3707.563816]  bus_remove_driver+0x11b/0x2a0
+[ 3707.563829]  pci_unregister_driver+0x2a/0x250
+
+Introduce an error check and log the vport number and error code.
+On removal make sure to check VPORT_REG_NETDEV flag prior to calling
+unregister and free on the netdev.
+
+Add local variables for idx, vport_config and netdev for readability.
+
+Fixes: 0fe45467a104 ("idpf: add create vport and netdev configuration")
+Suggested-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Emil Tantilov <emil.s.tantilov@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 | 31 +++++++++++++++-------
+ 1 file changed, 22 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_lib.c b/drivers/net/ethernet/intel/idpf/idpf_lib.c
+index a3d6b8f198a86..a055a47449f12 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_lib.c
++++ b/drivers/net/ethernet/intel/idpf/idpf_lib.c
+@@ -927,15 +927,19 @@ static int idpf_stop(struct net_device *netdev)
+ static void idpf_decfg_netdev(struct idpf_vport *vport)
+ {
+       struct idpf_adapter *adapter = vport->adapter;
++      u16 idx = vport->idx;
+       kfree(vport->rx_ptype_lkup);
+       vport->rx_ptype_lkup = NULL;
+-      unregister_netdev(vport->netdev);
+-      free_netdev(vport->netdev);
++      if (test_and_clear_bit(IDPF_VPORT_REG_NETDEV,
++                             adapter->vport_config[idx]->flags)) {
++              unregister_netdev(vport->netdev);
++              free_netdev(vport->netdev);
++      }
+       vport->netdev = NULL;
+-      adapter->netdevs[vport->idx] = NULL;
++      adapter->netdevs[idx] = NULL;
+ }
+ /**
+@@ -1536,13 +1540,22 @@ void idpf_init_task(struct work_struct *work)
+       }
+       for (index = 0; index < adapter->max_vports; index++) {
+-              if (adapter->netdevs[index] &&
+-                  !test_bit(IDPF_VPORT_REG_NETDEV,
+-                            adapter->vport_config[index]->flags)) {
+-                      register_netdev(adapter->netdevs[index]);
+-                      set_bit(IDPF_VPORT_REG_NETDEV,
+-                              adapter->vport_config[index]->flags);
++              struct net_device *netdev = adapter->netdevs[index];
++              struct idpf_vport_config *vport_config;
++
++              vport_config = adapter->vport_config[index];
++
++              if (!netdev ||
++                  test_bit(IDPF_VPORT_REG_NETDEV, vport_config->flags))
++                      continue;
++
++              err = register_netdev(netdev);
++              if (err) {
++                      dev_err(&pdev->dev, "failed to register netdev for vport %d: %pe\n",
++                              index, ERR_PTR(err));
++                      continue;
+               }
++              set_bit(IDPF_VPORT_REG_NETDEV, vport_config->flags);
+       }
+       /* As all the required vports are created, clear the reset flag
+-- 
+2.39.5
+
diff --git a/queue-6.14/idpf-fix-adapter-null-pointer-dereference-on-reboot.patch b/queue-6.14/idpf-fix-adapter-null-pointer-dereference-on-reboot.patch
new file mode 100644 (file)
index 0000000..990a51a
--- /dev/null
@@ -0,0 +1,77 @@
+From de96bd25a69c0348bc1d53a3e6e0647d90ec0242 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Mar 2025 22:42:02 -0700
+Subject: idpf: fix adapter NULL pointer dereference on reboot
+
+From: Emil Tantilov <emil.s.tantilov@intel.com>
+
+[ Upstream commit 4c9106f4906a85f6b13542d862e423bcdc118cc3 ]
+
+With SRIOV enabled, idpf ends up calling into idpf_remove() twice.
+First via idpf_shutdown() and then again when idpf_remove() calls into
+sriov_disable(), because the VF devices use the idpf driver, hence the
+same remove routine. When that happens, it is possible for the adapter
+to be NULL from the first call to idpf_remove(), leading to a NULL
+pointer dereference.
+
+echo 1 > /sys/class/net/<netif>/device/sriov_numvfs
+reboot
+
+BUG: kernel NULL pointer dereference, address: 0000000000000020
+...
+RIP: 0010:idpf_remove+0x22/0x1f0 [idpf]
+...
+? idpf_remove+0x22/0x1f0 [idpf]
+? idpf_remove+0x1e4/0x1f0 [idpf]
+pci_device_remove+0x3f/0xb0
+device_release_driver_internal+0x19f/0x200
+pci_stop_bus_device+0x6d/0x90
+pci_stop_and_remove_bus_device+0x12/0x20
+pci_iov_remove_virtfn+0xbe/0x120
+sriov_disable+0x34/0xe0
+idpf_sriov_configure+0x58/0x140 [idpf]
+idpf_remove+0x1b9/0x1f0 [idpf]
+idpf_shutdown+0x12/0x30 [idpf]
+pci_device_shutdown+0x35/0x60
+device_shutdown+0x156/0x200
+...
+
+Replace the direct idpf_remove() call in idpf_shutdown() with
+idpf_vc_core_deinit() and idpf_deinit_dflt_mbx(), which perform
+the bulk of the cleanup, such as stopping the init task, freeing IRQs,
+destroying the vports and freeing the mailbox. This avoids the calls to
+sriov_disable() in addition to a small netdev cleanup, and destroying
+workqueues, which don't seem to be required on shutdown.
+
+Reported-by: Yuying Ma <yuma@redhat.com>
+Fixes: e850efed5e15 ("idpf: add module register and probe functionality")
+Reviewed-by: Madhu Chittim <madhu.chittim@intel.com>
+Signed-off-by: Emil Tantilov <emil.s.tantilov@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_main.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_main.c b/drivers/net/ethernet/intel/idpf/idpf_main.c
+index b6c515d14cbf0..bec4a02c53733 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_main.c
++++ b/drivers/net/ethernet/intel/idpf/idpf_main.c
+@@ -87,7 +87,11 @@ static void idpf_remove(struct pci_dev *pdev)
+  */
+ static void idpf_shutdown(struct pci_dev *pdev)
+ {
+-      idpf_remove(pdev);
++      struct idpf_adapter *adapter = pci_get_drvdata(pdev);
++
++      cancel_delayed_work_sync(&adapter->vc_event_task);
++      idpf_vc_core_deinit(adapter);
++      idpf_deinit_dflt_mbx(adapter);
+       if (system_state == SYSTEM_POWER_OFF)
+               pci_set_power_state(pdev, PCI_D3hot);
+-- 
+2.39.5
+
diff --git a/queue-6.14/igb-reject-invalid-external-timestamp-requests-for-8.patch b/queue-6.14/igb-reject-invalid-external-timestamp-requests-for-8.patch
new file mode 100644 (file)
index 0000000..5224875
--- /dev/null
@@ -0,0 +1,69 @@
+From 3e22a8e9eb75c01be9cd2063ce089dd54d0ba06d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Mar 2025 15:15:50 -0700
+Subject: igb: reject invalid external timestamp requests for 82580-based HW
+
+From: Jacob Keller <jacob.e.keller@intel.com>
+
+[ Upstream commit 5eada2aabf13dcc4574b0a281b963b8cc55a52cc ]
+
+The igb_ptp_feature_enable_82580 function correctly checks that unknown
+flags are not passed to the function. However, it does not actually check
+PTP_RISING_EDGE or PTP_FALLING_EDGE when configuring the external timestamp
+function.
+
+The data sheet for the 82580 product says:
+
+  Upon a change in the input level of one of the SDP pins that was
+  configured to detect Time stamp events using the TSSDP register, a time
+  stamp of the system time is captured into one of the two auxiliary time
+  stamp registers (AUXSTMPL/H0 or AUXSTMPL/H1).
+
+  For example to define timestamping of events in the AUXSTMPL0 and
+  AUXSTMPH0 registers, Software should:
+
+  1. Set the TSSDP.AUX0_SDP_SEL field to select the SDP pin that detects
+     the level change and set the TSSDP.AUX0_TS_SDP_EN bit to 1.
+
+  2. Set the TSAUXC.EN_TS0 bit to 1 to enable timestamping
+
+The same paragraph is in the i350 and i354 data sheets.
+
+The wording implies that the time stamps are captured at any level change.
+There does not appear to be any way to only timestamp one edge of the
+signal.
+
+Reject requests which do not set both PTP_RISING_EDGE and PTP_FALLING_EDGE
+when operating under PTP_STRICT_FLAGS mode via PTP_EXTTS_REQUEST2.
+
+Fixes: 38970eac41db ("igb: support EXTTS on 82580/i354/i350")
+Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250312-jk-net-fixes-supported-extts-flags-v2-1-ea930ba82459@intel.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/igb/igb_ptp.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c
+index f945705561200..f323e1c1989f1 100644
+--- a/drivers/net/ethernet/intel/igb/igb_ptp.c
++++ b/drivers/net/ethernet/intel/igb/igb_ptp.c
+@@ -509,6 +509,12 @@ static int igb_ptp_feature_enable_82580(struct ptp_clock_info *ptp,
+                                       PTP_STRICT_FLAGS))
+                       return -EOPNOTSUPP;
++              /* Both the rising and falling edge are timestamped */
++              if (rq->extts.flags & PTP_STRICT_FLAGS &&
++                  (rq->extts.flags & PTP_ENABLE_FEATURE) &&
++                  (rq->extts.flags & PTP_EXTTS_EDGES) != PTP_EXTTS_EDGES)
++                      return -EOPNOTSUPP;
++
+               if (on) {
+                       pin = ptp_find_pin(igb->ptp_clock, PTP_PF_EXTTS,
+                                          rq->extts.index);
+-- 
+2.39.5
+
diff --git a/queue-6.14/igc-add-launch-time-support-to-xdp-zc.patch b/queue-6.14/igc-add-launch-time-support-to-xdp-zc.patch
new file mode 100644 (file)
index 0000000..c656efa
--- /dev/null
@@ -0,0 +1,201 @@
+From 779e244ecc14a115bac09fa0029660315ee48b24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 16 Feb 2025 17:34:30 +0800
+Subject: igc: Add launch time support to XDP ZC
+
+From: Song Yoong Siang <yoong.siang.song@intel.com>
+
+[ Upstream commit d7c3a7ff75028bea9e4879bd3dcd04a6dc3e33c8 ]
+
+Enable Launch Time Control (LTC) support for XDP zero copy via XDP Tx
+metadata framework.
+
+This patch has been tested with tools/testing/selftests/bpf/xdp_hw_metadata
+on Intel I225-LM Ethernet controller. Below are the test steps and result.
+
+Test 1: Send a single packet with the launch time set to 1 s in the future.
+
+Test steps:
+1. On the DUT, start the xdp_hw_metadata selftest application:
+   $ sudo ./xdp_hw_metadata enp2s0 -l 1000000000 -L 1
+
+2. On the Link Partner, send a UDP packet with VLAN priority 1 to port 9091
+   of the DUT.
+
+Result:
+When the launch time is set to 1 s in the future, the delta between the
+launch time and the transmit hardware timestamp is 0.016 us, as shown in
+printout of the xdp_hw_metadata application below.
+  0x562ff5dc8880: rx_desc[4]->addr=84110 addr=84110 comp_addr=84110 EoP
+  rx_hash: 0xE343384 with RSS type:0x1
+  HW RX-time:   1734578015467548904 (sec:1734578015.4675)
+                delta to User RX-time sec:0.0002 (183.103 usec)
+  XDP RX-time:   1734578015467651698 (sec:1734578015.4677)
+                 delta to User RX-time sec:0.0001 (80.309 usec)
+  No rx_vlan_tci or rx_vlan_proto, err=-95
+  0x562ff5dc8880: ping-pong with csum=561c (want c7dd)
+                  csum_start=34 csum_offset=6
+  HW RX-time:   1734578015467548904 (sec:1734578015.4675)
+                delta to HW Launch-time sec:1.0000 (1000000.000 usec)
+  0x562ff5dc8880: complete tx idx=4 addr=4018
+  HW Launch-time:   1734578016467548904 (sec:1734578016.4675)
+                    delta to HW TX-complete-time sec:0.0000 (0.016 usec)
+  HW TX-complete-time:   1734578016467548920 (sec:1734578016.4675)
+                         delta to User TX-complete-time sec:0.0000
+                         (32.546 usec)
+  XDP RX-time:   1734578015467651698 (sec:1734578015.4677)
+                 delta to User TX-complete-time sec:0.9999
+                 (999929.768 usec)
+  HW RX-time:   1734578015467548904 (sec:1734578015.4675)
+                delta to HW TX-complete-time sec:1.0000 (1000000.016 usec)
+  0x562ff5dc8880: complete rx idx=132 addr=84110
+
+Test 2: Send 1000 packets with a 10 ms interval and the launch time set to
+        500 us in the future.
+
+Test steps:
+1. On the DUT, start the xdp_hw_metadata selftest application:
+   $ sudo chrt -f 99 ./xdp_hw_metadata enp2s0 -l 500000 -L 1 > \
+     /dev/shm/result.log
+
+2. On the Link Partner, send 1000 UDP packets with a 10 ms interval and
+   VLAN priority 1 to port 9091 of the DUT.
+
+Result:
+When the launch time is set to 500 us in the future, the average delta
+between the launch time and the transmit hardware timestamp is 0.016 us,
+as shown in the analysis of /dev/shm/result.log below. The XDP launch time
+works correctly in sending 1000 packets continuously.
+  Min delta: 0.005 us
+  Avr delta: 0.016 us
+  Max delta: 0.031 us
+  Total packets forwarded: 1000
+
+Signed-off-by: Song Yoong Siang <yoong.siang.song@intel.com>
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Reviewed-by: Faizal Rahim <faizal.abdul.rahim@linux.intel.com>
+Reviewed-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
+Link: https://patch.msgid.link/20250216093430.957880-6-yoong.siang.song@intel.com
+Stable-dep-of: d931cf9b38da ("igc: Fix TX drops in XDP ZC")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/igc/igc.h      |  1 +
+ drivers/net/ethernet/intel/igc/igc_main.c | 61 ++++++++++++++++++++++-
+ 2 files changed, 60 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h
+index b8111ad9a9a83..cd1d7b6c17823 100644
+--- a/drivers/net/ethernet/intel/igc/igc.h
++++ b/drivers/net/ethernet/intel/igc/igc.h
+@@ -579,6 +579,7 @@ struct igc_metadata_request {
+       struct xsk_tx_metadata *meta;
+       struct igc_ring *tx_ring;
+       u32 cmd_type;
++      u16 used_desc;
+ };
+ struct igc_q_vector {
+diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
+index 1bfa71545e371..3044392e8ded8 100644
+--- a/drivers/net/ethernet/intel/igc/igc_main.c
++++ b/drivers/net/ethernet/intel/igc/igc_main.c
+@@ -2971,9 +2971,48 @@ static u64 igc_xsk_fill_timestamp(void *_priv)
+       return *(u64 *)_priv;
+ }
++static void igc_xsk_request_launch_time(u64 launch_time, void *_priv)
++{
++      struct igc_metadata_request *meta_req = _priv;
++      struct igc_ring *tx_ring = meta_req->tx_ring;
++      __le32 launch_time_offset;
++      bool insert_empty = false;
++      bool first_flag = false;
++      u16 used_desc = 0;
++
++      if (!tx_ring->launchtime_enable)
++              return;
++
++      launch_time_offset = igc_tx_launchtime(tx_ring,
++                                             ns_to_ktime(launch_time),
++                                             &first_flag, &insert_empty);
++      if (insert_empty) {
++              /* Disregard the launch time request if the required empty frame
++               * fails to be inserted.
++               */
++              if (igc_insert_empty_frame(tx_ring))
++                      return;
++
++              meta_req->tx_buffer =
++                      &tx_ring->tx_buffer_info[tx_ring->next_to_use];
++              /* Inserting an empty packet requires two descriptors:
++               * one data descriptor and one context descriptor.
++               */
++              used_desc += 2;
++      }
++
++      /* Use one context descriptor to specify launch time and first flag. */
++      igc_tx_ctxtdesc(tx_ring, launch_time_offset, first_flag, 0, 0, 0);
++      used_desc += 1;
++
++      /* Update the number of used descriptors in this request */
++      meta_req->used_desc += used_desc;
++}
++
+ const struct xsk_tx_metadata_ops igc_xsk_tx_metadata_ops = {
+       .tmo_request_timestamp          = igc_xsk_request_timestamp,
+       .tmo_fill_timestamp             = igc_xsk_fill_timestamp,
++      .tmo_request_launch_time        = igc_xsk_request_launch_time,
+ };
+ static void igc_xdp_xmit_zc(struct igc_ring *ring)
+@@ -2996,7 +3035,13 @@ static void igc_xdp_xmit_zc(struct igc_ring *ring)
+       ntu = ring->next_to_use;
+       budget = igc_desc_unused(ring);
+-      while (xsk_tx_peek_desc(pool, &xdp_desc) && budget--) {
++      /* Packets with launch time require one data descriptor and one context
++       * descriptor. When the launch time falls into the next Qbv cycle, we
++       * may need to insert an empty packet, which requires two more
++       * descriptors. Therefore, to be safe, we always ensure we have at least
++       * 4 descriptors available.
++       */
++      while (xsk_tx_peek_desc(pool, &xdp_desc) && budget >= 4) {
+               struct igc_metadata_request meta_req;
+               struct xsk_tx_metadata *meta = NULL;
+               struct igc_tx_buffer *bi;
+@@ -3017,9 +3062,19 @@ static void igc_xdp_xmit_zc(struct igc_ring *ring)
+               meta_req.tx_ring = ring;
+               meta_req.tx_buffer = bi;
+               meta_req.meta = meta;
++              meta_req.used_desc = 0;
+               xsk_tx_metadata_request(meta, &igc_xsk_tx_metadata_ops,
+                                       &meta_req);
++              /* xsk_tx_metadata_request() may have updated next_to_use */
++              ntu = ring->next_to_use;
++
++              /* xsk_tx_metadata_request() may have updated Tx buffer info */
++              bi = meta_req.tx_buffer;
++
++              /* xsk_tx_metadata_request() may use a few descriptors */
++              budget -= meta_req.used_desc;
++
+               tx_desc = IGC_TX_DESC(ring, ntu);
+               tx_desc->read.cmd_type_len = cpu_to_le32(meta_req.cmd_type);
+               tx_desc->read.olinfo_status = cpu_to_le32(olinfo_status);
+@@ -3037,9 +3092,11 @@ static void igc_xdp_xmit_zc(struct igc_ring *ring)
+               ntu++;
+               if (ntu == ring->count)
+                       ntu = 0;
++
++              ring->next_to_use = ntu;
++              budget--;
+       }
+-      ring->next_to_use = ntu;
+       if (tx_desc) {
+               igc_flush_tx_descriptors(ring);
+               xsk_tx_release(pool);
+-- 
+2.39.5
+
diff --git a/queue-6.14/igc-fix-tx-drops-in-xdp-zc.patch b/queue-6.14/igc-fix-tx-drops-in-xdp-zc.patch
new file mode 100644 (file)
index 0000000..a4ffecc
--- /dev/null
@@ -0,0 +1,45 @@
+From 928274876bc4146e60394944459cfbb3ee3458bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Mar 2025 15:18:48 +0100
+Subject: igc: Fix TX drops in XDP ZC
+
+From: Zdenek Bouska <zdenek.bouska@siemens.com>
+
+[ Upstream commit d931cf9b38da0f533cacfe51c863a9912e67822f ]
+
+Fixes TX frame drops in AF_XDP zero copy mode when budget < 4.
+xsk_tx_peek_desc() consumed TX frame and it was ignored because of
+low budget. Not even AF_XDP completion was done for dropped frames.
+
+It can be reproduced on i226 by sending 100000x 60 B frames with
+launch time set to minimal IPG (672 ns between starts of frames)
+on 1Gbit/s. Always 1026 frames are not sent and are missing a
+completion.
+
+Fixes: 9acf59a752d4c ("igc: Enable TX via AF_XDP zero-copy")
+Signed-off-by: Zdenek Bouska <zdenek.bouska@siemens.com>
+Reviewed-by: Song Yoong Siang <yoong.siang.song@intel.com>
+Reviewed-by: Florian Bezdeka <florian.bezdeka@siemens.com>
+Tested-by: Mor Bar-Gabay <morx.bar.gabay@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/igc/igc_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
+index 3044392e8ded8..706dd26d4dde2 100644
+--- a/drivers/net/ethernet/intel/igc/igc_main.c
++++ b/drivers/net/ethernet/intel/igc/igc_main.c
+@@ -3041,7 +3041,7 @@ static void igc_xdp_xmit_zc(struct igc_ring *ring)
+        * descriptors. Therefore, to be safe, we always ensure we have at least
+        * 4 descriptors available.
+        */
+-      while (xsk_tx_peek_desc(pool, &xdp_desc) && budget >= 4) {
++      while (budget >= 4 && xsk_tx_peek_desc(pool, &xdp_desc)) {
+               struct igc_metadata_request meta_req;
+               struct xsk_tx_metadata *meta = NULL;
+               struct igc_tx_buffer *bi;
+-- 
+2.39.5
+
diff --git a/queue-6.14/igc-refactor-empty-frame-insertion-for-launch-time-s.patch b/queue-6.14/igc-refactor-empty-frame-insertion-for-launch-time-s.patch
new file mode 100644 (file)
index 0000000..62216ee
--- /dev/null
@@ -0,0 +1,175 @@
+From a9a4d19bcd879931f3668a3636b156fa0bc7d290 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 16 Feb 2025 17:34:29 +0800
+Subject: igc: Refactor empty frame insertion for launch time support
+
+From: Song Yoong Siang <yoong.siang.song@intel.com>
+
+[ Upstream commit f9b53bb13923f0a6ed2e784a35301cfb4c28f4f4 ]
+
+Refactor the code for inserting an empty frame into a new function
+igc_insert_empty_frame(). This change extracts the logic for inserting
+an empty packet from igc_xmit_frame_ring() into a separate function,
+allowing it to be reused in future implementations, such as the XDP
+zero copy transmit function.
+
+Remove the igc_desc_unused() checking in igc_init_tx_empty_descriptor()
+because the number of descriptors needed is guaranteed.
+
+Ensure that skb allocation and DMA mapping work for the empty frame,
+before proceeding to fill in igc_tx_buffer info, context descriptor,
+and data descriptor.
+
+Rate limit the error messages for skb allocation and DMA mapping failures.
+
+Update the comment to indicate that the 2 descriptors needed by the empty
+frame are already taken into consideration in igc_xmit_frame_ring().
+
+Handle the case where the insertion of an empty frame fails and explain
+the reason behind this handling.
+
+Signed-off-by: Song Yoong Siang <yoong.siang.song@intel.com>
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Reviewed-by: Faizal Rahim <faizal.abdul.rahim@linux.intel.com>
+Reviewed-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
+Link: https://patch.msgid.link/20250216093430.957880-5-yoong.siang.song@intel.com
+Stable-dep-of: d931cf9b38da ("igc: Fix TX drops in XDP ZC")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/igc/igc_main.c | 82 ++++++++++++++---------
+ 1 file changed, 50 insertions(+), 32 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
+index 84307bb7313e0..1bfa71545e371 100644
+--- a/drivers/net/ethernet/intel/igc/igc_main.c
++++ b/drivers/net/ethernet/intel/igc/igc_main.c
+@@ -1092,7 +1092,8 @@ static int igc_init_empty_frame(struct igc_ring *ring,
+       dma = dma_map_single(ring->dev, skb->data, size, DMA_TO_DEVICE);
+       if (dma_mapping_error(ring->dev, dma)) {
+-              netdev_err_once(ring->netdev, "Failed to map DMA for TX\n");
++              net_err_ratelimited("%s: DMA mapping error for empty frame\n",
++                                  netdev_name(ring->netdev));
+               return -ENOMEM;
+       }
+@@ -1108,20 +1109,12 @@ static int igc_init_empty_frame(struct igc_ring *ring,
+       return 0;
+ }
+-static int igc_init_tx_empty_descriptor(struct igc_ring *ring,
+-                                      struct sk_buff *skb,
+-                                      struct igc_tx_buffer *first)
++static void igc_init_tx_empty_descriptor(struct igc_ring *ring,
++                                       struct sk_buff *skb,
++                                       struct igc_tx_buffer *first)
+ {
+       union igc_adv_tx_desc *desc;
+       u32 cmd_type, olinfo_status;
+-      int err;
+-
+-      if (!igc_desc_unused(ring))
+-              return -EBUSY;
+-
+-      err = igc_init_empty_frame(ring, first, skb);
+-      if (err)
+-              return err;
+       cmd_type = IGC_ADVTXD_DTYP_DATA | IGC_ADVTXD_DCMD_DEXT |
+                  IGC_ADVTXD_DCMD_IFCS | IGC_TXD_DCMD |
+@@ -1140,8 +1133,6 @@ static int igc_init_tx_empty_descriptor(struct igc_ring *ring,
+       ring->next_to_use++;
+       if (ring->next_to_use == ring->count)
+               ring->next_to_use = 0;
+-
+-      return 0;
+ }
+ #define IGC_EMPTY_FRAME_SIZE 60
+@@ -1567,6 +1558,40 @@ static bool igc_request_tx_tstamp(struct igc_adapter *adapter, struct sk_buff *s
+       return false;
+ }
++static int igc_insert_empty_frame(struct igc_ring *tx_ring)
++{
++      struct igc_tx_buffer *empty_info;
++      struct sk_buff *empty_skb;
++      void *data;
++      int ret;
++
++      empty_info = &tx_ring->tx_buffer_info[tx_ring->next_to_use];
++      empty_skb = alloc_skb(IGC_EMPTY_FRAME_SIZE, GFP_ATOMIC);
++      if (unlikely(!empty_skb)) {
++              net_err_ratelimited("%s: skb alloc error for empty frame\n",
++                                  netdev_name(tx_ring->netdev));
++              return -ENOMEM;
++      }
++
++      data = skb_put(empty_skb, IGC_EMPTY_FRAME_SIZE);
++      memset(data, 0, IGC_EMPTY_FRAME_SIZE);
++
++      /* Prepare DMA mapping and Tx buffer information */
++      ret = igc_init_empty_frame(tx_ring, empty_info, empty_skb);
++      if (unlikely(ret)) {
++              dev_kfree_skb_any(empty_skb);
++              return ret;
++      }
++
++      /* Prepare advanced context descriptor for empty packet */
++      igc_tx_ctxtdesc(tx_ring, 0, false, 0, 0, 0);
++
++      /* Prepare advanced data descriptor for empty packet */
++      igc_init_tx_empty_descriptor(tx_ring, empty_skb, empty_info);
++
++      return 0;
++}
++
+ static netdev_tx_t igc_xmit_frame_ring(struct sk_buff *skb,
+                                      struct igc_ring *tx_ring)
+ {
+@@ -1586,6 +1611,7 @@ static netdev_tx_t igc_xmit_frame_ring(struct sk_buff *skb,
+        *      + 1 desc for skb_headlen/IGC_MAX_DATA_PER_TXD,
+        *      + 2 desc gap to keep tail from touching head,
+        *      + 1 desc for context descriptor,
++       *      + 2 desc for inserting an empty packet for launch time,
+        * otherwise try next time
+        */
+       for (f = 0; f < skb_shinfo(skb)->nr_frags; f++)
+@@ -1605,24 +1631,16 @@ static netdev_tx_t igc_xmit_frame_ring(struct sk_buff *skb,
+       launch_time = igc_tx_launchtime(tx_ring, txtime, &first_flag, &insert_empty);
+       if (insert_empty) {
+-              struct igc_tx_buffer *empty_info;
+-              struct sk_buff *empty;
+-              void *data;
+-
+-              empty_info = &tx_ring->tx_buffer_info[tx_ring->next_to_use];
+-              empty = alloc_skb(IGC_EMPTY_FRAME_SIZE, GFP_ATOMIC);
+-              if (!empty)
+-                      goto done;
+-
+-              data = skb_put(empty, IGC_EMPTY_FRAME_SIZE);
+-              memset(data, 0, IGC_EMPTY_FRAME_SIZE);
+-
+-              igc_tx_ctxtdesc(tx_ring, 0, false, 0, 0, 0);
+-
+-              if (igc_init_tx_empty_descriptor(tx_ring,
+-                                               empty,
+-                                               empty_info) < 0)
+-                      dev_kfree_skb_any(empty);
++              /* Reset the launch time if the required empty frame fails to
++               * be inserted. However, this packet is not dropped, so it
++               * "dirties" the current Qbv cycle. This ensures that the
++               * upcoming packet, which is scheduled in the next Qbv cycle,
++               * does not require an empty frame. This way, the launch time
++               * continues to function correctly despite the current failure
++               * to insert the empty frame.
++               */
++              if (igc_insert_empty_frame(tx_ring))
++                      launch_time = 0;
+       }
+ done:
+-- 
+2.39.5
+
diff --git a/queue-6.14/iio-accel-mma8452-ensure-error-return-on-failure-to-.patch b/queue-6.14/iio-accel-mma8452-ensure-error-return-on-failure-to-.patch
new file mode 100644 (file)
index 0000000..2a122f1
--- /dev/null
@@ -0,0 +1,61 @@
+From baf6af1e72284e02414b240916319e1ab58fd98b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 14:01:28 +0000
+Subject: iio: accel: mma8452: Ensure error return on failure to matching
+ oversampling ratio
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit df330c808182a8beab5d0f84a6cbc9cff76c61fc ]
+
+If a match was not found, then the write_raw() callback would return
+the odr index, not an error. Return -EINVAL if this occurs.
+To avoid similar issues in future, introduce j, a new indexing variable
+rather than using ret for this purpose.
+
+Fixes: 79de2ee469aa ("iio: accel: mma8452: claim direct mode during write raw")
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+Link: https://patch.msgid.link/20250217140135.896574-2-jic23@kernel.org
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/accel/mma8452.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c
+index 962d289065ab7..1b2014c4c4b46 100644
+--- a/drivers/iio/accel/mma8452.c
++++ b/drivers/iio/accel/mma8452.c
+@@ -712,7 +712,7 @@ static int mma8452_write_raw(struct iio_dev *indio_dev,
+                            int val, int val2, long mask)
+ {
+       struct mma8452_data *data = iio_priv(indio_dev);
+-      int i, ret;
++      int i, j, ret;
+       ret = iio_device_claim_direct_mode(indio_dev);
+       if (ret)
+@@ -772,14 +772,18 @@ static int mma8452_write_raw(struct iio_dev *indio_dev,
+               break;
+       case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
+-              ret = mma8452_get_odr_index(data);
++              j = mma8452_get_odr_index(data);
+               for (i = 0; i < ARRAY_SIZE(mma8452_os_ratio); i++) {
+-                      if (mma8452_os_ratio[i][ret] == val) {
++                      if (mma8452_os_ratio[i][j] == val) {
+                               ret = mma8452_set_power_mode(data, i);
+                               break;
+                       }
+               }
++              if (i == ARRAY_SIZE(mma8452_os_ratio)) {
++                      ret = -EINVAL;
++                      break;
++              }
+               break;
+       default:
+               ret = -EINVAL;
+-- 
+2.39.5
+
diff --git a/queue-6.14/iio-accel-msa311-fix-failure-to-release-runtime-pm-i.patch b/queue-6.14/iio-accel-msa311-fix-failure-to-release-runtime-pm-i.patch
new file mode 100644 (file)
index 0000000..0e0c827
--- /dev/null
@@ -0,0 +1,100 @@
+From b979021fbbb51e3282b4aafd6df293db73b9e0dc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 14:01:33 +0000
+Subject: iio: accel: msa311: Fix failure to release runtime pm if direct mode
+ claim fails.
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 60a0cf2ebab92011055ab7db6553c0fc3c546938 ]
+
+Reorder the claiming of direct mode and runtime pm calls to simplify
+handling a little.  For correct error handling, after the reorder
+iio_device_release_direct_mode() must be claimed in an error occurs
+in pm_runtime_resume_and_get()
+
+Fixes: 1ca2cfbc0c33 ("iio: add MEMSensing MSA311 3-axis accelerometer driver")
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+Link: https://patch.msgid.link/20250217140135.896574-7-jic23@kernel.org
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/accel/msa311.c | 26 +++++++++++++++-----------
+ 1 file changed, 15 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/iio/accel/msa311.c b/drivers/iio/accel/msa311.c
+index e7fb860f32337..c2b05d1f7239a 100644
+--- a/drivers/iio/accel/msa311.c
++++ b/drivers/iio/accel/msa311.c
+@@ -594,23 +594,25 @@ static int msa311_read_raw_data(struct iio_dev *indio_dev,
+       __le16 axis;
+       int err;
+-      err = pm_runtime_resume_and_get(dev);
++      err = iio_device_claim_direct_mode(indio_dev);
+       if (err)
+               return err;
+-      err = iio_device_claim_direct_mode(indio_dev);
+-      if (err)
++      err = pm_runtime_resume_and_get(dev);
++      if (err) {
++              iio_device_release_direct_mode(indio_dev);
+               return err;
++      }
+       mutex_lock(&msa311->lock);
+       err = msa311_get_axis(msa311, chan, &axis);
+       mutex_unlock(&msa311->lock);
+-      iio_device_release_direct_mode(indio_dev);
+-
+       pm_runtime_mark_last_busy(dev);
+       pm_runtime_put_autosuspend(dev);
++      iio_device_release_direct_mode(indio_dev);
++
+       if (err) {
+               dev_err(dev, "can't get axis %s (%pe)\n",
+                       chan->datasheet_name, ERR_PTR(err));
+@@ -756,10 +758,6 @@ static int msa311_write_samp_freq(struct iio_dev *indio_dev, int val, int val2)
+       unsigned int odr;
+       int err;
+-      err = pm_runtime_resume_and_get(dev);
+-      if (err)
+-              return err;
+-
+       /*
+        * Sampling frequency changing is prohibited when buffer mode is
+        * enabled, because sometimes MSA311 chip returns outliers during
+@@ -769,6 +767,12 @@ static int msa311_write_samp_freq(struct iio_dev *indio_dev, int val, int val2)
+       if (err)
+               return err;
++      err = pm_runtime_resume_and_get(dev);
++      if (err) {
++              iio_device_release_direct_mode(indio_dev);
++              return err;
++      }
++
+       err = -EINVAL;
+       for (odr = 0; odr < ARRAY_SIZE(msa311_odr_table); odr++)
+               if (val == msa311_odr_table[odr].integral &&
+@@ -779,11 +783,11 @@ static int msa311_write_samp_freq(struct iio_dev *indio_dev, int val, int val2)
+                       break;
+               }
+-      iio_device_release_direct_mode(indio_dev);
+-
+       pm_runtime_mark_last_busy(dev);
+       pm_runtime_put_autosuspend(dev);
++      iio_device_release_direct_mode(indio_dev);
++
+       if (err)
+               dev_err(dev, "can't update frequency (%pe)\n", ERR_PTR(err));
+-- 
+2.39.5
+
diff --git a/queue-6.14/iio-adc-ad4130-fix-comparison-of-channel-setups.patch b/queue-6.14/iio-adc-ad4130-fix-comparison-of-channel-setups.patch
new file mode 100644 (file)
index 0000000..e016bb1
--- /dev/null
@@ -0,0 +1,109 @@
+From 6c242ca8191713f6d36b3d3c3e7966eb534dd461 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Mar 2025 12:47:00 +0100
+Subject: iio: adc: ad4130: Fix comparison of channel setups
+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 280acb19824663d55a3f4d09087c76fabe86fa3c ]
+
+Checking the binary representation of two structs (of the same type)
+for equality doesn't have the same semantic as comparing all members for
+equality. The former might find a difference where the latter doesn't in
+the presence of padding or when ambiguous types like float or bool are
+involved. (Floats typically have different representations for single
+values, like -0.0 vs +0.0, or 0.5 * 2² vs 0.25 * 2³. The type bool has
+at least 8 bits and the raw values 1 and 2 (probably) both evaluate to
+true, but memcmp finds a difference.)
+
+When searching for a channel that already has the configuration we need,
+the comparison by member is the one that is needed.
+
+Convert the comparison accordingly to compare the members one after
+another. Also add a static_assert guard to (somewhat) ensure that when
+struct ad4130_setup_info is expanded, the comparison is adapted, too.
+
+This issue is somewhat theoretic, but using memcmp() on a struct is a
+bad pattern that is worth fixing.
+
+Fixes: 62094060cf3a ("iio: adc: ad4130: add AD4130 driver")
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
+Link: https://patch.msgid.link/20250303114659.1672695-12-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/ad4130.c | 41 ++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 39 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/adc/ad4130.c b/drivers/iio/adc/ad4130.c
+index de32cc9d18c5e..712f95f53c9ec 100644
+--- a/drivers/iio/adc/ad4130.c
++++ b/drivers/iio/adc/ad4130.c
+@@ -223,6 +223,10 @@ enum ad4130_pin_function {
+       AD4130_PIN_FN_VBIAS = BIT(3),
+ };
++/*
++ * If you make adaptations in this struct, you most likely also have to adapt
++ * ad4130_setup_info_eq(), too.
++ */
+ struct ad4130_setup_info {
+       unsigned int                    iout0_val;
+       unsigned int                    iout1_val;
+@@ -591,6 +595,40 @@ static irqreturn_t ad4130_irq_handler(int irq, void *private)
+       return IRQ_HANDLED;
+ }
++static bool ad4130_setup_info_eq(struct ad4130_setup_info *a,
++                               struct ad4130_setup_info *b)
++{
++      /*
++       * This is just to make sure that the comparison is adapted after
++       * struct ad4130_setup_info was changed.
++       */
++      static_assert(sizeof(*a) ==
++                    sizeof(struct {
++                                   unsigned int iout0_val;
++                                   unsigned int iout1_val;
++                                   unsigned int burnout;
++                                   unsigned int pga;
++                                   unsigned int fs;
++                                   u32 ref_sel;
++                                   enum ad4130_filter_mode filter_mode;
++                                   bool ref_bufp;
++                                   bool ref_bufm;
++                           }));
++
++      if (a->iout0_val != b->iout0_val ||
++          a->iout1_val != b->iout1_val ||
++          a->burnout != b->burnout ||
++          a->pga != b->pga ||
++          a->fs != b->fs ||
++          a->ref_sel != b->ref_sel ||
++          a->filter_mode != b->filter_mode ||
++          a->ref_bufp != b->ref_bufp ||
++          a->ref_bufm != b->ref_bufm)
++              return false;
++
++      return true;
++}
++
+ static int ad4130_find_slot(struct ad4130_state *st,
+                           struct ad4130_setup_info *target_setup_info,
+                           unsigned int *slot, bool *overwrite)
+@@ -604,8 +642,7 @@ static int ad4130_find_slot(struct ad4130_state *st,
+               struct ad4130_slot_info *slot_info = &st->slots_info[i];
+               /* Immediately accept a matching setup info. */
+-              if (!memcmp(target_setup_info, &slot_info->setup,
+-                          sizeof(*target_setup_info))) {
++              if (ad4130_setup_info_eq(target_setup_info, &slot_info->setup)) {
+                       *slot = i;
+                       return 0;
+               }
+-- 
+2.39.5
+
diff --git a/queue-6.14/iio-adc-ad7124-fix-comparison-of-channel-configs.patch b/queue-6.14/iio-adc-ad7124-fix-comparison-of-channel-configs.patch
new file mode 100644 (file)
index 0000000..c0a50f4
--- /dev/null
@@ -0,0 +1,103 @@
+From 5c50a9993601d5f6e06d1794956615f78b705ca9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Mar 2025 12:47:01 +0100
+Subject: iio: adc: ad7124: Fix comparison of channel configs
+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 05a5d874f7327b75e9bc4359618017e047cc129c ]
+
+Checking the binary representation of two structs (of the same type)
+for equality doesn't have the same semantic as comparing all members for
+equality. The former might find a difference where the latter doesn't in
+the presence of padding or when ambiguous types like float or bool are
+involved. (Floats typically have different representations for single
+values, like -0.0 vs +0.0, or 0.5 * 2² vs 0.25 * 2³. The type bool has
+at least 8 bits and the raw values 1 and 2 (probably) both evaluate to
+true, but memcmp finds a difference.)
+
+When searching for a channel that already has the configuration we need,
+the comparison by member is the one that is needed.
+
+Convert the comparison accordingly to compare the members one after
+another. Also add a static_assert guard to (somewhat) ensure that when
+struct ad7124_channel_config::config_props is expanded, the comparison
+is adapted, too.
+
+This issue is somewhat theoretic, but using memcmp() on a struct is a
+bad pattern that is worth fixing.
+
+Fixes: 7b8d045e497a ("iio: adc: ad7124: allow more than 8 channels")
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
+Link: https://patch.msgid.link/20250303114659.1672695-13-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 | 35 +++++++++++++++++++++++++++++++----
+ 1 file changed, 31 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/iio/adc/ad7124.c b/drivers/iio/adc/ad7124.c
+index 6bc418d388202..de90ecb5f6307 100644
+--- a/drivers/iio/adc/ad7124.c
++++ b/drivers/iio/adc/ad7124.c
+@@ -151,7 +151,11 @@ struct ad7124_chip_info {
+ struct ad7124_channel_config {
+       bool live;
+       unsigned int cfg_slot;
+-      /* Following fields are used to compare equality. */
++      /*
++       * Following fields are used to compare for equality. If you
++       * make adaptations in it, you most likely also have to adapt
++       * ad7124_find_similar_live_cfg(), too.
++       */
+       struct_group(config_props,
+               enum ad7124_ref_sel refsel;
+               bool bipolar;
+@@ -338,15 +342,38 @@ static struct ad7124_channel_config *ad7124_find_similar_live_cfg(struct ad7124_
+                                                                 struct ad7124_channel_config *cfg)
+ {
+       struct ad7124_channel_config *cfg_aux;
+-      ptrdiff_t cmp_size;
+       int i;
+-      cmp_size = sizeof_field(struct ad7124_channel_config, config_props);
++      /*
++       * This is just to make sure that the comparison is adapted after
++       * struct ad7124_channel_config was changed.
++       */
++      static_assert(sizeof_field(struct ad7124_channel_config, config_props) ==
++                    sizeof(struct {
++                                   enum ad7124_ref_sel refsel;
++                                   bool bipolar;
++                                   bool buf_positive;
++                                   bool buf_negative;
++                                   unsigned int vref_mv;
++                                   unsigned int pga_bits;
++                                   unsigned int odr;
++                                   unsigned int odr_sel_bits;
++                                   unsigned int filter_type;
++                           }));
++
+       for (i = 0; i < st->num_channels; i++) {
+               cfg_aux = &st->channels[i].cfg;
+               if (cfg_aux->live &&
+-                  !memcmp(&cfg->config_props, &cfg_aux->config_props, cmp_size))
++                  cfg->refsel == cfg_aux->refsel &&
++                  cfg->bipolar == cfg_aux->bipolar &&
++                  cfg->buf_positive == cfg_aux->buf_positive &&
++                  cfg->buf_negative == cfg_aux->buf_negative &&
++                  cfg->vref_mv == cfg_aux->vref_mv &&
++                  cfg->pga_bits == cfg_aux->pga_bits &&
++                  cfg->odr == cfg_aux->odr &&
++                  cfg->odr_sel_bits == cfg_aux->odr_sel_bits &&
++                  cfg->filter_type == cfg_aux->filter_type)
+                       return cfg_aux;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/iio-adc-ad7124-micro-optimize-channel-disabling.patch b/queue-6.14/iio-adc-ad7124-micro-optimize-channel-disabling.patch
new file mode 100644 (file)
index 0000000..dad3cfd
--- /dev/null
@@ -0,0 +1,78 @@
+From 0a1462729ef7d48616c20a90278147b2ac3ec272 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jan 2025 15:07:09 +0100
+Subject: iio: adc: ad7124: Micro-optimize channel disabling
+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 cf67879bd4280f6243103e281595f9b523c61481 ]
+
+The key objective in ad7124_disable_one() is clearing the
+AD7124_CHANNEL_EN_MSK bit in the channel register. However there is no
+advantage to keep the other bits in that register because when the
+channel is used next time, all fields are rewritten anyhow. So instead
+of using ad7124_spi_write_mask() (which is a register read plus a
+register write) use a simple register write clearing the complete
+register.
+
+Also do the same in the .disable_all() callback by using the
+.disable_one() callback there.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
+Reviewed-by: Nuno Sa <nuno.sa@analog.com>
+Link: https://patch.msgid.link/20250120140708.1093655-2-u.kleine-koenig@baylibre.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: e903868b4ce7 ("iio: adc: ad7124: Really disable all channels at probe time")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad7124.c | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/iio/adc/ad7124.c b/drivers/iio/adc/ad7124.c
+index 6ae27cdd32503..2fdeb32479522 100644
+--- a/drivers/iio/adc/ad7124.c
++++ b/drivers/iio/adc/ad7124.c
+@@ -540,6 +540,14 @@ static int ad7124_append_status(struct ad_sigma_delta *sd, bool append)
+       return 0;
+ }
++static int ad7124_disable_one(struct ad_sigma_delta *sd, unsigned int chan)
++{
++      struct ad7124_state *st = container_of(sd, struct ad7124_state, sd);
++
++      /* The relevant thing here is that AD7124_CHANNEL_EN_MSK is cleared. */
++      return ad_sd_write_reg(&st->sd, AD7124_CHANNEL(chan), 2, 0);
++}
++
+ static int ad7124_disable_all(struct ad_sigma_delta *sd)
+ {
+       struct ad7124_state *st = container_of(sd, struct ad7124_state, sd);
+@@ -547,7 +555,7 @@ static int ad7124_disable_all(struct ad_sigma_delta *sd)
+       int i;
+       for (i = 0; i < st->num_channels; i++) {
+-              ret = ad7124_spi_write_mask(st, AD7124_CHANNEL(i), AD7124_CHANNEL_EN_MSK, 0, 2);
++              ret = ad7124_disable_one(sd, i);
+               if (ret < 0)
+                       return ret;
+       }
+@@ -555,13 +563,6 @@ static int ad7124_disable_all(struct ad_sigma_delta *sd)
+       return 0;
+ }
+-static int ad7124_disable_one(struct ad_sigma_delta *sd, unsigned int chan)
+-{
+-      struct ad7124_state *st = container_of(sd, struct ad7124_state, sd);
+-
+-      return ad7124_spi_write_mask(st, AD7124_CHANNEL(chan), AD7124_CHANNEL_EN_MSK, 0, 2);
+-}
+-
+ static const struct ad_sigma_delta_info ad7124_sigma_delta_info = {
+       .set_channel = ad7124_set_channel,
+       .append_status = ad7124_append_status,
+-- 
+2.39.5
+
diff --git a/queue-6.14/iio-adc-ad7124-really-disable-all-channels-at-probe-.patch b/queue-6.14/iio-adc-ad7124-really-disable-all-channels-at-probe-.patch
new file mode 100644 (file)
index 0000000..ebb3b7a
--- /dev/null
@@ -0,0 +1,66 @@
+From 8b16dee9690074fea48b670689a35e163784b156 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Feb 2025 12:50:23 +0100
+Subject: iio: adc: ad7124: Really disable all channels at probe time
+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 e903868b4ce73d1ba3663d5e0718424946cebd99 ]
+
+If one or more of the 16 channels are enabled and the driver is not
+aware of that, unexpected things happen because different channels are
+used than intended. To prevent that, all channels should be disabled at
+probe time. In Commit 4be339af334c ("iio: adc: ad7124: Disable all
+channels at probe time") I intended do that, however only the channels
+that are potentially used by the driver and not all channels are
+disabled since then. So disable all 16 channels and not only the used
+ones.
+
+Also fix the same issue in the .disable_all() callback.
+
+Fixes: 4be339af334c ("iio: adc: ad7124: Disable all channels at probe time")
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
+Link: https://patch.msgid.link/20250204115023.265813-2-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 | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/iio/adc/ad7124.c b/drivers/iio/adc/ad7124.c
+index 2fdeb32479522..6bc418d388202 100644
+--- a/drivers/iio/adc/ad7124.c
++++ b/drivers/iio/adc/ad7124.c
+@@ -550,11 +550,10 @@ static int ad7124_disable_one(struct ad_sigma_delta *sd, unsigned int chan)
+ static int ad7124_disable_all(struct ad_sigma_delta *sd)
+ {
+-      struct ad7124_state *st = container_of(sd, struct ad7124_state, sd);
+       int ret;
+       int i;
+-      for (i = 0; i < st->num_channels; i++) {
++      for (i = 0; i < 16; i++) {
+               ret = ad7124_disable_one(sd, i);
+               if (ret < 0)
+                       return ret;
+@@ -1017,11 +1016,10 @@ static int ad7124_setup(struct ad7124_state *st)
+                * set all channels to this default value.
+                */
+               ad7124_set_channel_odr(st, i, 10);
+-
+-              /* Disable all channels to prevent unintended conversions. */
+-              ad_sd_write_reg(&st->sd, AD7124_CHANNEL(i), 2, 0);
+       }
++      ad7124_disable_all(&st->sd);
++
+       ret = ad_sd_write_reg(&st->sd, AD7124_ADC_CONTROL, 2, st->adc_control);
+       if (ret < 0)
+               return dev_err_probe(dev, ret, "Failed to setup CONTROL register\n");
+-- 
+2.39.5
+
diff --git a/queue-6.14/iio-adc-ad7173-fix-comparison-of-channel-configs.patch b/queue-6.14/iio-adc-ad7173-fix-comparison-of-channel-configs.patch
new file mode 100644 (file)
index 0000000..804bcb1
--- /dev/null
@@ -0,0 +1,93 @@
+From a7e40a234bdfa2e1b52398b5b77049f20c238175 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Mar 2025 12:47:02 +0100
+Subject: iio: adc: ad7173: Fix comparison of channel configs
+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 7b6033ed5a9e1a369a9cf58018388ae4c5f17e41 ]
+
+Checking the binary representation of two structs (of the same type)
+for equality doesn't have the same semantic as comparing all members for
+equality. The former might find a difference where the latter doesn't in
+the presence of padding or when ambiguous types like float or bool are
+involved. (Floats typically have different representations for single
+values, like -0.0 vs +0.0, or 0.5 * 2² vs 0.25 * 2³. The type bool has
+at least 8 bits and the raw values 1 and 2 (probably) both evaluate to
+true, but memcmp finds a difference.)
+
+When searching for a channel that already has the configuration we need,
+the comparison by member is the one that is needed.
+
+Convert the comparison accordingly to compare the members one after
+another. Also add a static_assert guard to (somewhat) ensure that when
+struct ad7173_channel_config::config_props is expanded, the comparison
+is adapted, too.
+
+This issue is somewhat theoretic, but using memcmp() on a struct is a
+bad pattern that is worth fixing.
+
+Fixes: 76a1e6a42802 ("iio: adc: ad7173: add AD7173 driver")
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
+Link: https://patch.msgid.link/20250303114659.1672695-14-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/ad7173.c | 25 +++++++++++++++++++++----
+ 1 file changed, 21 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/iio/adc/ad7173.c b/drivers/iio/adc/ad7173.c
+index 6645a811764fd..4f8810e35a8d1 100644
+--- a/drivers/iio/adc/ad7173.c
++++ b/drivers/iio/adc/ad7173.c
+@@ -189,7 +189,11 @@ struct ad7173_channel_config {
+       u8 cfg_slot;
+       bool live;
+-      /* Following fields are used to compare equality. */
++      /*
++       * Following fields are used to compare equality. If you
++       * make adaptations in it, you most likely also have to adapt
++       * ad7173_find_live_config(), too.
++       */
+       struct_group(config_props,
+               bool bipolar;
+               bool input_buf;
+@@ -717,15 +721,28 @@ static struct ad7173_channel_config *
+ ad7173_find_live_config(struct ad7173_state *st, struct ad7173_channel_config *cfg)
+ {
+       struct ad7173_channel_config *cfg_aux;
+-      ptrdiff_t cmp_size;
+       int i;
+-      cmp_size = sizeof_field(struct ad7173_channel_config, config_props);
++      /*
++       * This is just to make sure that the comparison is adapted after
++       * struct ad7173_channel_config was changed.
++       */
++      static_assert(sizeof_field(struct ad7173_channel_config, config_props) ==
++                    sizeof(struct {
++                                   bool bipolar;
++                                   bool input_buf;
++                                   u8 odr;
++                                   u8 ref_sel;
++                           }));
++
+       for (i = 0; i < st->num_channels; i++) {
+               cfg_aux = &st->channels[i].cfg;
+               if (cfg_aux->live &&
+-                  !memcmp(&cfg->config_props, &cfg_aux->config_props, cmp_size))
++                  cfg->bipolar == cfg_aux->bipolar &&
++                  cfg->input_buf == cfg_aux->input_buf &&
++                  cfg->odr == cfg_aux->odr &&
++                  cfg->ref_sel == cfg_aux->ref_sel)
+                       return cfg_aux;
+       }
+       return NULL;
+-- 
+2.39.5
+
diff --git a/queue-6.14/iio-adc-ad7173-grab-direct-mode-for-calibration.patch b/queue-6.14/iio-adc-ad7173-grab-direct-mode-for-calibration.patch
new file mode 100644 (file)
index 0000000..5857c66
--- /dev/null
@@ -0,0 +1,52 @@
+From de973ee16cde1448747aed42a21bb388391ec966 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 12:35:27 +0100
+Subject: iio: adc: ad7173: Grab direct mode for calibration
+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 7021d97fb89b216557561ca8cdf68144c016993b ]
+
+While a calibration is running, better don't make the device do anything
+else.
+
+To enforce that, grab direct mode during calibration.
+
+Fixes: 031bdc8aee01 ("iio: adc: ad7173: add calibration support")
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
+Link: https://patch.msgid.link/8319fa2dc881c9899d60db4eba7fe8e984716617.1740655250.git.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/ad7173.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/iio/adc/ad7173.c b/drivers/iio/adc/ad7173.c
+index 6c4ed10ae580d..6645a811764fd 100644
+--- a/drivers/iio/adc/ad7173.c
++++ b/drivers/iio/adc/ad7173.c
+@@ -559,6 +559,9 @@ static ssize_t ad7173_write_syscalib(struct iio_dev *indio_dev,
+       if (ret)
+               return ret;
++      if (!iio_device_claim_direct(indio_dev))
++              return -EBUSY;
++
+       mode = st->channels[chan->channel].syscalib_mode;
+       if (sys_calib) {
+               if (mode == AD7173_SYSCALIB_ZERO_SCALE)
+@@ -569,6 +572,8 @@ static ssize_t ad7173_write_syscalib(struct iio_dev *indio_dev,
+                                             chan->address);
+       }
++      iio_device_release_direct(indio_dev);
++
+       return ret ? : len;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/iio-adc-ad7192-grab-direct-mode-for-calibration.patch b/queue-6.14/iio-adc-ad7192-grab-direct-mode-for-calibration.patch
new file mode 100644 (file)
index 0000000..7e4d290
--- /dev/null
@@ -0,0 +1,52 @@
+From 6f2af463884aec45dc12e2d77599684bcd2d79fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 12:35:28 +0100
+Subject: iio: adc: ad7192: Grab direct mode for calibration
+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 08808b3ef384974b1eaf4975de707f93f8cda62d ]
+
+While a calibration is running, better don't make the device do anything
+else.
+
+To enforce that, grab direct mode during calibration.
+
+Fixes: 42776c14c692 ("staging: iio: adc: ad7192: Add system calibration support")
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
+Link: https://patch.msgid.link/8aade802afca6a89641e24c1ae1d4b8d82cff58d.1740655250.git.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/ad7192.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/iio/adc/ad7192.c b/drivers/iio/adc/ad7192.c
+index cfaf8f7e0a07d..1ebb738d99f57 100644
+--- a/drivers/iio/adc/ad7192.c
++++ b/drivers/iio/adc/ad7192.c
+@@ -256,6 +256,9 @@ static ssize_t ad7192_write_syscalib(struct iio_dev *indio_dev,
+       if (ret)
+               return ret;
++      if (!iio_device_claim_direct(indio_dev))
++              return -EBUSY;
++
+       temp = st->syscalib_mode[chan->channel];
+       if (sys_calib) {
+               if (temp == AD7192_SYSCALIB_ZERO_SCALE)
+@@ -266,6 +269,8 @@ static ssize_t ad7192_write_syscalib(struct iio_dev *indio_dev,
+                                             chan->address);
+       }
++      iio_device_release_direct(indio_dev);
++
+       return ret ? ret : len;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/iio-adc-ad7768-1-set-mosi-idle-state-to-prevent-acci.patch b/queue-6.14/iio-adc-ad7768-1-set-mosi-idle-state-to-prevent-acci.patch
new file mode 100644 (file)
index 0000000..adb217d
--- /dev/null
@@ -0,0 +1,55 @@
+From 91e734326f7edcdcee2b36fc9c26af0b4417b846 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Mar 2025 18:00:43 -0300
+Subject: iio: adc: ad7768-1: set MOSI idle state to prevent accidental reset
+
+From: Jonathan Santos <Jonathan.Santos@analog.com>
+
+[ Upstream commit 2416cec859299be04d021b4cf98eff814f345af7 ]
+
+Datasheet recommends Setting the MOSI idle state to high in order to
+prevent accidental reset of the device when SCLK is free running.
+This happens when the controller clocks out a 1 followed by 63 zeros
+while the CS is held low.
+
+Check if SPI controller supports SPI_MOSI_IDLE_HIGH flag and set it.
+
+Fixes: a5f8c7da3dbe ("iio: adc: Add AD7768-1 ADC basic support")
+Signed-off-by: Jonathan Santos <Jonathan.Santos@analog.com>
+Reviewed-by: Marcelo Schmitt <marcelo.schmitt@analog.com>
+Link: https://patch.msgid.link/c2a2b0f3d54829079763a5511359a1fa80516cfb.1741268122.git.Jonathan.Santos@analog.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad7768-1.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/drivers/iio/adc/ad7768-1.c b/drivers/iio/adc/ad7768-1.c
+index 113703fb72454..6f8816483f1a0 100644
+--- a/drivers/iio/adc/ad7768-1.c
++++ b/drivers/iio/adc/ad7768-1.c
+@@ -574,6 +574,21 @@ static int ad7768_probe(struct spi_device *spi)
+               return -ENOMEM;
+       st = iio_priv(indio_dev);
++      /*
++       * Datasheet recommends SDI line to be kept high when data is not being
++       * clocked out of the controller and the spi clock is free running,
++       * to prevent accidental reset.
++       * Since many controllers do not support the SPI_MOSI_IDLE_HIGH flag
++       * yet, only request the MOSI idle state to enable if the controller
++       * supports it.
++       */
++      if (spi->controller->mode_bits & SPI_MOSI_IDLE_HIGH) {
++              spi->mode |= SPI_MOSI_IDLE_HIGH;
++              ret = spi_setup(spi);
++              if (ret < 0)
++                      return ret;
++      }
++
+       st->spi = spi;
+       st->vref = devm_regulator_get(&spi->dev, "vref");
+-- 
+2.39.5
+
diff --git a/queue-6.14/iio-adc-ad_sigma_delta-disable-channel-after-calibra.patch b/queue-6.14/iio-adc-ad_sigma_delta-disable-channel-after-calibra.patch
new file mode 100644 (file)
index 0000000..865462b
--- /dev/null
@@ -0,0 +1,48 @@
+From 3dffc6a9036ada018df64061807472a2dd6f32f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Mar 2025 12:46:59 +0100
+Subject: iio: adc: ad_sigma_delta: Disable channel after calibration
+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 fb3a0811a7bc12d51cba4b75d6b123ab62e2fe4d ]
+
+The function ad_sd_calibrate() enables the channel to calibrate at
+function entry but doesn't disable it on exit. This is problematic
+because if two (or more) channels are calibrated in a row, the second
+calibration isn't executed as intended as the first (still enabled)
+channel is recalibrated and after the first irq (i.e. when the
+calibration of the first channel completed) the calibration is aborted.
+
+This currently affects ad7173 only, as the other drivers using
+ad_sd_calibrate() never have more than one channel enabled at a time.
+
+To fix this, disable the calibrated channel after calibration.
+
+Fixes: 031bdc8aee01 ("iio: adc: ad7173: add calibration support")
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
+Link: https://patch.msgid.link/20250303114659.1672695-11-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/ad_sigma_delta.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c
+index d5d81581ab340..77b4e8bc47485 100644
+--- a/drivers/iio/adc/ad_sigma_delta.c
++++ b/drivers/iio/adc/ad_sigma_delta.c
+@@ -339,6 +339,7 @@ int ad_sd_calibrate(struct ad_sigma_delta *sigma_delta,
+ out:
+       sigma_delta->keep_cs_asserted = false;
+       ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
++      ad_sigma_delta_disable_one(sigma_delta, channel);
+       sigma_delta->bus_locked = false;
+       spi_bus_unlock(sigma_delta->spi->controller);
+-- 
+2.39.5
+
diff --git a/queue-6.14/iio-backend-make-sure-to-null-terminate-stack-buffer.patch b/queue-6.14/iio-backend-make-sure-to-null-terminate-stack-buffer.patch
new file mode 100644 (file)
index 0000000..02a8856
--- /dev/null
@@ -0,0 +1,47 @@
+From 77965c4d7622c58203fcb5d89d32c926d5b526c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Feb 2025 10:31:25 +0000
+Subject: iio: backend: make sure to NULL terminate stack buffer
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Nuno Sá <nuno.sa@analog.com>
+
+[ Upstream commit 035b4989211dc1c8626e186d655ae8ca5141bb73 ]
+
+Make sure to NULL terminate the buffer in
+iio_backend_debugfs_write_reg() before passing it to sscanf(). It is a
+stack variable so we should not assume it will 0 initialized.
+
+Fixes: cdf01e0809a4 ("iio: backend: add debugFs interface")
+Signed-off-by: Nuno Sá <nuno.sa@analog.com>
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+Link: https://patch.msgid.link/20250218-dev-iio-misc-v1-1-bf72b20a1eb8@analog.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/industrialio-backend.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/iio/industrialio-backend.c b/drivers/iio/industrialio-backend.c
+index 3632812720352..aa2b8b38ab587 100644
+--- a/drivers/iio/industrialio-backend.c
++++ b/drivers/iio/industrialio-backend.c
+@@ -155,10 +155,12 @@ static ssize_t iio_backend_debugfs_write_reg(struct file *file,
+       ssize_t rc;
+       int ret;
+-      rc = simple_write_to_buffer(buf, sizeof(buf), ppos, userbuf, count);
++      rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, userbuf, count);
+       if (rc < 0)
+               return rc;
++      buf[count] = '\0';
++
+       ret = sscanf(buf, "%i %i", &back->cached_reg_addr, &val);
+       switch (ret) {
+-- 
+2.39.5
+
diff --git a/queue-6.14/iio-core-rework-claim-and-release-of-direct-mode-to-.patch b/queue-6.14/iio-core-rework-claim-and-release-of-direct-mode-to-.patch
new file mode 100644 (file)
index 0000000..a6518ad
--- /dev/null
@@ -0,0 +1,94 @@
+From c23006d42aa42b17d9b9d7545a87f64eb3d7df91 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Feb 2025 18:05:58 +0000
+Subject: iio: core: Rework claim and release of direct mode to work with
+ sparse.
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit d795e38df4b7ebac1072bbf7d8a5500c1ea83332 ]
+
+Initial thought was to do something similar to __cond_lock()
+
+       do_iio_device_claim_direct_mode(iio_dev) ? : ({ __acquire(iio_dev); 0; })
++ Appropriate static inline iio_device_release_direct_mode()
+
+However with that, sparse generates false positives. E.g.
+
+drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c:1811:17: warning: context imbalance in 'st_lsm6dsx_read_raw' - unexpected unlock
+
+So instead, this patch rethinks the return type and makes it more
+'conditional lock like' (which is part of what is going on under the hood
+anyway) and return a boolean - true for successfully acquired, false for
+did not acquire.
+
+To allow a migration path given the rework is now non trivial, take a leaf
+out of the naming of the conditional guard we currently have for IIO
+device direct mode and drop the _mode postfix from the new functions giving
+iio_device_claim_direct() and iio_device_release_direct()
+
+Whilst the kernel supports __cond_acquires() upstream sparse does not
+yet do so.  Hence rely on sparse expanding a static inline wrapper
+to explicitly see whether __acquire() is called.
+
+Note that even with the solution here, sparse sometimes gives false
+positives. However in the few cases seen they were complex code
+structures that benefited from simplification anyway.
+
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+Reviewed-by: Nuno Sa <nuno.sa@analog.com>
+Link: https://patch.msgid.link/20250209180624.701140-2-jic23@kernel.org
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: 7021d97fb89b ("iio: adc: ad7173: Grab direct mode for calibration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/iio/iio.h | 26 ++++++++++++++++++++++++++
+ 1 file changed, 26 insertions(+)
+
+diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h
+index 56161e02f002c..5ed03e36178fc 100644
+--- a/include/linux/iio/iio.h
++++ b/include/linux/iio/iio.h
+@@ -10,6 +10,7 @@
+ #include <linux/device.h>
+ #include <linux/cdev.h>
+ #include <linux/cleanup.h>
++#include <linux/compiler_types.h>
+ #include <linux/slab.h>
+ #include <linux/iio/types.h>
+ /* IIO TODO LIST */
+@@ -662,6 +663,31 @@ int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp);
+ int iio_device_claim_direct_mode(struct iio_dev *indio_dev);
+ void iio_device_release_direct_mode(struct iio_dev *indio_dev);
++/*
++ * Helper functions that allow claim and release of direct mode
++ * in a fashion that doesn't generate many false positives from sparse.
++ * Note this must remain static inline in the header so that sparse
++ * can see the __acquire() marking. Revisit when sparse supports
++ * __cond_acquires()
++ */
++static inline bool iio_device_claim_direct(struct iio_dev *indio_dev)
++{
++      int ret = iio_device_claim_direct_mode(indio_dev);
++
++      if (ret)
++              return false;
++
++      __acquire(iio_dev);
++
++      return true;
++}
++
++static inline void iio_device_release_direct(struct iio_dev *indio_dev)
++{
++      iio_device_release_direct_mode(indio_dev);
++      __release(indio_dev);
++}
++
+ /*
+  * This autocleanup logic is normally used via
+  * iio_device_claim_direct_scoped().
+-- 
+2.39.5
+
diff --git a/queue-6.14/iio-dac-adi-axi-dac-modify-stream-enable.patch b/queue-6.14/iio-dac-adi-axi-dac-modify-stream-enable.patch
new file mode 100644 (file)
index 0000000..06db19d
--- /dev/null
@@ -0,0 +1,45 @@
+From 0637f17c1766845cfff8753a86d549a63cf7e761 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jan 2025 16:30:12 +0100
+Subject: iio: dac: adi-axi-dac: modify stream enable
+
+From: Angelo Dureghello <adureghello@baylibre.com>
+
+[ Upstream commit 6cc60bc38e8428544f8f4f12ddb6cc05fc83a7da ]
+
+Change suggested from the AXI HDL team, modify the function
+axi_dac_data_stream_enable() to check for interface busy, to avoid
+possible issues when starting the stream.
+
+Fixes: e61d7178429a ("iio: dac: adi-axi-dac: extend features")
+Reviewed-by: Nuno Sa <nuno.sa@analog.com>
+Signed-off-by: Angelo Dureghello <adureghello@baylibre.com>
+Link: https://patch.msgid.link/20250114-wip-bl-ad3552r-axi-v0-iio-testing-carlos-v4-3-979402e33545@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 b143f7ed68472..ac871deb8063c 100644
+--- a/drivers/iio/dac/adi-axi-dac.c
++++ b/drivers/iio/dac/adi-axi-dac.c
+@@ -585,6 +585,14 @@ static int axi_dac_ddr_disable(struct iio_backend *back)
+ static int axi_dac_data_stream_enable(struct iio_backend *back)
+ {
+       struct axi_dac_state *st = iio_backend_get_priv(back);
++      int ret, val;
++
++      ret = regmap_read_poll_timeout(st->regmap,
++                              AXI_DAC_UI_STATUS_REG, val,
++                              FIELD_GET(AXI_DAC_UI_STATUS_IF_BUSY, val) == 0,
++                              10, 100 * KILO);
++      if (ret)
++              return ret;
+       return regmap_set_bits(st->regmap, AXI_DAC_CUSTOM_CTRL_REG,
+                              AXI_DAC_CUSTOM_CTRL_STREAM_ENABLE);
+-- 
+2.39.5
+
diff --git a/queue-6.14/iio-gts-helper-export-iio_gts_get_total_gain.patch b/queue-6.14/iio-gts-helper-export-iio_gts_get_total_gain.patch
new file mode 100644 (file)
index 0000000..53dfb69
--- /dev/null
@@ -0,0 +1,68 @@
+From da1eaaaaac2049adbaa17025eb02ff80b3cab393 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 27 Jan 2025 20:30:22 +0100
+Subject: iio: gts-helper: export iio_gts_get_total_gain()
+
+From: Javier Carrasco <javier.carrasco.cruz@gmail.com>
+
+[ Upstream commit dbd2e08ff09fd6bd51215b44474899cc1b7b7a16 ]
+
+Export this function in preparation for the fix in veml6030.c, where the
+total gain can be used to ease the calculation of the processed value of
+the IIO_LIGHT channel compared to acquiring the scale in NANO.
+
+Suggested-by: Matti Vaittinen <mazziesaccount@gmail.com>
+Signed-off-by: Javier Carrasco <javier.carrasco.cruz@gmail.com>
+Reviewed-by: Matti Vaittinen <mazziesaccount@gmail.com>
+Link: https://patch.msgid.link/20250127-veml6030-scale-v3-1-4f32ba03df94@gmail.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: 22eaca4283b2 ("iio: light: veml6030: fix scale to conform to ABI")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/industrialio-gts-helper.c | 11 ++++++++++-
+ include/linux/iio/iio-gts-helper.h    |  1 +
+ 2 files changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/iio/industrialio-gts-helper.c b/drivers/iio/industrialio-gts-helper.c
+index d70ebe3bf7742..d14f3507f34ea 100644
+--- a/drivers/iio/industrialio-gts-helper.c
++++ b/drivers/iio/industrialio-gts-helper.c
+@@ -950,7 +950,15 @@ int iio_gts_find_gain_time_sel_for_scale(struct iio_gts *gts, int scale_int,
+ }
+ EXPORT_SYMBOL_NS_GPL(iio_gts_find_gain_time_sel_for_scale, "IIO_GTS_HELPER");
+-static int iio_gts_get_total_gain(struct iio_gts *gts, int gain, int time)
++/**
++ * iio_gts_get_total_gain - Fetch total gain for given HW-gain and time
++ * @gts:      Gain time scale descriptor
++ * @gain:     HW-gain for which the total gain is searched for
++ * @time:     Integration time for which the total gain is searched for
++ *
++ * Return: total gain on success and -EINVAL on error.
++ */
++int iio_gts_get_total_gain(struct iio_gts *gts, int gain, int time)
+ {
+       const struct iio_itime_sel_mul *itime;
+@@ -966,6 +974,7 @@ static int iio_gts_get_total_gain(struct iio_gts *gts, int gain, int time)
+       return gain * itime->mul;
+ }
++EXPORT_SYMBOL_NS_GPL(iio_gts_get_total_gain, "IIO_GTS_HELPER");
+ static int iio_gts_get_scale_linear(struct iio_gts *gts, int gain, int time,
+                                   u64 *scale)
+diff --git a/include/linux/iio/iio-gts-helper.h b/include/linux/iio/iio-gts-helper.h
+index e5de7a124bad6..66f830ab9b49b 100644
+--- a/include/linux/iio/iio-gts-helper.h
++++ b/include/linux/iio/iio-gts-helper.h
+@@ -208,5 +208,6 @@ int iio_gts_all_avail_scales(struct iio_gts *gts, const int **vals, int *type,
+                            int *length);
+ int iio_gts_avail_scales_for_time(struct iio_gts *gts, int time,
+                                 const int **vals, int *type, int *length);
++int iio_gts_get_total_gain(struct iio_gts *gts, int gain, int time);
+ #endif
+-- 
+2.39.5
+
diff --git a/queue-6.14/iio-light-add-check-for-array-bounds-in-veml6075_rea.patch b/queue-6.14/iio-light-add-check-for-array-bounds-in-veml6075_rea.patch
new file mode 100644 (file)
index 0000000..e6bc0c7
--- /dev/null
@@ -0,0 +1,59 @@
+From ca74a8a289abbf2124f3fdcd4f25d706d9da9d70 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Feb 2025 17:34:36 +0000
+Subject: iio: light: Add check for array bounds in veml6075_read_int_time_ms
+
+From: Karan Sanghavi <karansanghvi98@gmail.com>
+
+[ Upstream commit ee735aa33db16c1fb5ebccbaf84ad38f5583f3cc ]
+
+The array contains only 5 elements, but the index calculated by
+veml6075_read_int_time_index can range from 0 to 7,
+which could lead to out-of-bounds access. The check prevents this issue.
+
+Coverity Issue
+CID 1574309: (#1 of 1): Out-of-bounds read (OVERRUN)
+overrun-local: Overrunning array veml6075_it_ms of 5 4-byte
+elements at element index 7 (byte offset 31) using
+index int_index (which evaluates to 7)
+
+This is hardening against potentially broken hardware. Good to have
+but not necessary to backport.
+
+Fixes: 3b82f43238ae ("iio: light: add VEML6075 UVA and UVB light sensor driver")
+Signed-off-by: Karan Sanghavi <karansanghvi98@gmail.com>
+Reviewed-by: Javier Carrasco <javier.carrasco.cruz@gmail.com>
+Link: https://patch.msgid.link/Z7dnrEpKQdRZ2qFU@Emma
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/light/veml6075.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/light/veml6075.c b/drivers/iio/light/veml6075.c
+index 05d4c0e9015d6..859891e8f1152 100644
+--- a/drivers/iio/light/veml6075.c
++++ b/drivers/iio/light/veml6075.c
+@@ -195,13 +195,17 @@ static int veml6075_read_uv_direct(struct veml6075_data *data, int chan,
+ static int veml6075_read_int_time_index(struct veml6075_data *data)
+ {
+-      int ret, conf;
++      int ret, conf, int_index;
+       ret = regmap_read(data->regmap, VEML6075_CMD_CONF, &conf);
+       if (ret < 0)
+               return ret;
+-      return FIELD_GET(VEML6075_CONF_IT, conf);
++      int_index = FIELD_GET(VEML6075_CONF_IT, conf);
++      if (int_index >= ARRAY_SIZE(veml6075_it_ms))
++              return -EINVAL;
++
++      return int_index;
+ }
+ static int veml6075_read_int_time_ms(struct veml6075_data *data, int *val)
+-- 
+2.39.5
+
diff --git a/queue-6.14/iio-light-veml6030-extend-regmap-to-support-regfield.patch b/queue-6.14/iio-light-veml6030-extend-regmap-to-support-regfield.patch
new file mode 100644 (file)
index 0000000..ced1b6b
--- /dev/null
@@ -0,0 +1,278 @@
+From c1123c84875a67006d18ba19ff05deaa6ce0e701 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 19 Jan 2025 18:31:58 +0100
+Subject: iio: light: veml6030: extend regmap to support regfields
+
+From: Javier Carrasco <javier.carrasco.cruz@gmail.com>
+
+[ Upstream commit 9c7eb1ab2eec47ad9eaf6e11ce14d3d6fd54e677 ]
+
+Add support for regfields as well to simplify register operations,
+taking into account the different fields for the veml6030/veml7700 and
+veml6035.
+
+Signed-off-by: Javier Carrasco <javier.carrasco.cruz@gmail.com>
+Link: https://patch.msgid.link/20250119-veml6030-scale-v2-1-6bfc4062a371@gmail.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: 22eaca4283b2 ("iio: light: veml6030: fix scale to conform to ABI")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/light/veml6030.c | 95 ++++++++++++++++++++++++++----------
+ 1 file changed, 70 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/iio/light/veml6030.c b/drivers/iio/light/veml6030.c
+index 9b71825eea9be..8e4eb8b0c1927 100644
+--- a/drivers/iio/light/veml6030.c
++++ b/drivers/iio/light/veml6030.c
+@@ -59,18 +59,31 @@
+ #define VEML6035_INT_CHAN     BIT(3)
+ #define VEML6035_CHAN_EN      BIT(2)
++/* Regfields */
++#define VEML6030_GAIN_RF      REG_FIELD(VEML6030_REG_ALS_CONF, 11, 12)
++#define VEML6030_IT_RF        REG_FIELD(VEML6030_REG_ALS_CONF, 6, 9)
++
++#define VEML6035_GAIN_RF      REG_FIELD(VEML6030_REG_ALS_CONF, 10, 12)
++
+ enum veml6030_scan {
+       VEML6030_SCAN_ALS,
+       VEML6030_SCAN_WH,
+       VEML6030_SCAN_TIMESTAMP,
+ };
++struct veml6030_rf {
++      struct regmap_field *it;
++      struct regmap_field *gain;
++};
++
+ struct veml603x_chip {
+       const char *name;
+       const int(*scale_vals)[][2];
+       const int num_scale_vals;
+       const struct iio_chan_spec *channels;
+       const int num_channels;
++      const struct reg_field gain_rf;
++      const struct reg_field it_rf;
+       int (*hw_init)(struct iio_dev *indio_dev, struct device *dev);
+       int (*set_info)(struct iio_dev *indio_dev);
+       int (*set_als_gain)(struct iio_dev *indio_dev, int val, int val2);
+@@ -91,6 +104,7 @@ struct veml603x_chip {
+ struct veml6030_data {
+       struct i2c_client *client;
+       struct regmap *regmap;
++      struct veml6030_rf rf;
+       int cur_resolution;
+       int cur_gain;
+       int cur_integration_time;
+@@ -330,17 +344,17 @@ static const struct regmap_config veml6030_regmap_config = {
+ static int veml6030_get_intgrn_tm(struct iio_dev *indio_dev,
+                                               int *val, int *val2)
+ {
+-      int ret, reg;
++      int it_idx, ret;
+       struct veml6030_data *data = iio_priv(indio_dev);
+-      ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, &reg);
++      ret = regmap_field_read(data->rf.it, &it_idx);
+       if (ret) {
+               dev_err(&data->client->dev,
+                               "can't read als conf register %d\n", ret);
+               return ret;
+       }
+-      switch ((reg >> 6) & 0xF) {
++      switch (it_idx) {
+       case 0:
+               *val2 = 100000;
+               break;
+@@ -405,8 +419,7 @@ static int veml6030_set_intgrn_tm(struct iio_dev *indio_dev,
+               return -EINVAL;
+       }
+-      ret = regmap_update_bits(data->regmap, VEML6030_REG_ALS_CONF,
+-                                      VEML6030_ALS_IT, new_int_time);
++      ret = regmap_field_write(data->rf.it, new_int_time);
+       if (ret) {
+               dev_err(&data->client->dev,
+                               "can't update als integration time %d\n", ret);
+@@ -510,23 +523,22 @@ static int veml6030_set_als_gain(struct iio_dev *indio_dev,
+       struct veml6030_data *data = iio_priv(indio_dev);
+       if (val == 0 && val2 == 125000) {
+-              new_gain = 0x1000; /* 0x02 << 11 */
++              new_gain = 0x01;
+               gain_idx = 3;
+       } else if (val == 0 && val2 == 250000) {
+-              new_gain = 0x1800;
++              new_gain = 0x11;
+               gain_idx = 2;
+       } else if (val == 1 && val2 == 0) {
+               new_gain = 0x00;
+               gain_idx = 1;
+       } else if (val == 2 && val2 == 0) {
+-              new_gain = 0x800;
++              new_gain = 0x01;
+               gain_idx = 0;
+       } else {
+               return -EINVAL;
+       }
+-      ret = regmap_update_bits(data->regmap, VEML6030_REG_ALS_CONF,
+-                                      VEML6030_ALS_GAIN, new_gain);
++      ret = regmap_field_write(data->rf.gain, new_gain);
+       if (ret) {
+               dev_err(&data->client->dev,
+                               "can't set als gain %d\n", ret);
+@@ -544,30 +556,31 @@ static int veml6035_set_als_gain(struct iio_dev *indio_dev, int val, int val2)
+       struct veml6030_data *data = iio_priv(indio_dev);
+       if (val == 0 && val2 == 125000) {
+-              new_gain = VEML6035_SENS;
++              new_gain = FIELD_GET(VEML6035_GAIN_M, VEML6035_SENS);
+               gain_idx = 5;
+       } else if (val == 0 && val2 == 250000) {
+-              new_gain = VEML6035_SENS | VEML6035_GAIN;
++              new_gain = FIELD_GET(VEML6035_GAIN_M, VEML6035_SENS |
++                                    VEML6035_GAIN);
+               gain_idx = 4;
+       } else if (val == 0 && val2 == 500000) {
+-              new_gain = VEML6035_SENS | VEML6035_GAIN |
+-                      VEML6035_DG;
++              new_gain = FIELD_GET(VEML6035_GAIN_M, VEML6035_SENS |
++                                    VEML6035_GAIN | VEML6035_DG);
+               gain_idx = 3;
+       } else if (val == 1 && val2 == 0) {
+               new_gain = 0x0000;
+               gain_idx = 2;
+       } else if (val == 2 && val2 == 0) {
+-              new_gain = VEML6035_GAIN;
++              new_gain = FIELD_GET(VEML6035_GAIN_M, VEML6035_GAIN);
+               gain_idx = 1;
+       } else if (val == 4 && val2 == 0) {
+-              new_gain = VEML6035_GAIN | VEML6035_DG;
++              new_gain = FIELD_GET(VEML6035_GAIN_M, VEML6035_GAIN |
++                                    VEML6035_DG);
+               gain_idx = 0;
+       } else {
+               return -EINVAL;
+       }
+-      ret = regmap_update_bits(data->regmap, VEML6030_REG_ALS_CONF,
+-                               VEML6035_GAIN_M, new_gain);
++      ret = regmap_field_write(data->rf.gain, new_gain);
+       if (ret) {
+               dev_err(&data->client->dev, "can't set als gain %d\n", ret);
+               return ret;
+@@ -581,17 +594,17 @@ static int veml6035_set_als_gain(struct iio_dev *indio_dev, int val, int val2)
+ static int veml6030_get_als_gain(struct iio_dev *indio_dev,
+                                               int *val, int *val2)
+ {
+-      int ret, reg;
++      int gain, ret;
+       struct veml6030_data *data = iio_priv(indio_dev);
+-      ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, &reg);
++      ret = regmap_field_read(data->rf.gain, &gain);
+       if (ret) {
+               dev_err(&data->client->dev,
+                               "can't read als conf register %d\n", ret);
+               return ret;
+       }
+-      switch ((reg >> 11) & 0x03) {
++      switch (gain) {
+       case 0:
+               *val = 1;
+               *val2 = 0;
+@@ -617,17 +630,17 @@ static int veml6030_get_als_gain(struct iio_dev *indio_dev,
+ static int veml6035_get_als_gain(struct iio_dev *indio_dev, int *val, int *val2)
+ {
+-      int ret, reg;
++      int gain, ret;
+       struct veml6030_data *data = iio_priv(indio_dev);
+-      ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, &reg);
++      ret = regmap_field_read(data->rf.gain, &gain);
+       if (ret) {
+               dev_err(&data->client->dev,
+-                      "can't read als conf register %d\n", ret);
++                              "can't read als conf register %d\n", ret);
+               return ret;
+       }
+-      switch (FIELD_GET(VEML6035_GAIN_M, reg)) {
++      switch (gain) {
+       case 0:
+               *val = 1;
+               *val2 = 0;
+@@ -990,6 +1003,27 @@ static int veml7700_set_info(struct iio_dev *indio_dev)
+       return 0;
+ }
++static int veml6030_regfield_init(struct iio_dev *indio_dev)
++{
++      struct veml6030_data *data = iio_priv(indio_dev);
++      struct regmap *regmap = data->regmap;
++      struct device *dev = &data->client->dev;
++      struct regmap_field *rm_field;
++      struct veml6030_rf *rf = &data->rf;
++
++      rm_field = devm_regmap_field_alloc(dev, regmap, data->chip->it_rf);
++      if (IS_ERR(rm_field))
++              return PTR_ERR(rm_field);
++      rf->it = rm_field;
++
++      rm_field = devm_regmap_field_alloc(dev, regmap, data->chip->gain_rf);
++      if (IS_ERR(rm_field))
++              return PTR_ERR(rm_field);
++      rf->gain = rm_field;
++
++      return 0;
++}
++
+ /*
+  * Set ALS gain to 1/8, integration time to 100 ms, PSM to mode 2,
+  * persistence to 1 x integration time and the threshold
+@@ -1143,6 +1177,11 @@ static int veml6030_probe(struct i2c_client *client)
+       if (ret < 0)
+               return ret;
++      ret = veml6030_regfield_init(indio_dev);
++      if (ret)
++              return dev_err_probe(&client->dev, ret,
++                                   "failed to init regfields\n");
++
+       ret = data->chip->hw_init(indio_dev, &client->dev);
+       if (ret < 0)
+               return ret;
+@@ -1191,6 +1230,8 @@ static const struct veml603x_chip veml6030_chip = {
+       .num_scale_vals = ARRAY_SIZE(veml6030_scale_vals),
+       .channels = veml6030_channels,
+       .num_channels = ARRAY_SIZE(veml6030_channels),
++      .gain_rf = VEML6030_GAIN_RF,
++      .it_rf = VEML6030_IT_RF,
+       .hw_init = veml6030_hw_init,
+       .set_info = veml6030_set_info,
+       .set_als_gain = veml6030_set_als_gain,
+@@ -1203,6 +1244,8 @@ static const struct veml603x_chip veml6035_chip = {
+       .num_scale_vals = ARRAY_SIZE(veml6035_scale_vals),
+       .channels = veml6030_channels,
+       .num_channels = ARRAY_SIZE(veml6030_channels),
++      .gain_rf = VEML6035_GAIN_RF,
++      .it_rf = VEML6030_IT_RF,
+       .hw_init = veml6035_hw_init,
+       .set_info = veml6030_set_info,
+       .set_als_gain = veml6035_set_als_gain,
+@@ -1215,6 +1258,8 @@ static const struct veml603x_chip veml7700_chip = {
+       .num_scale_vals = ARRAY_SIZE(veml6030_scale_vals),
+       .channels = veml7700_channels,
+       .num_channels = ARRAY_SIZE(veml7700_channels),
++      .gain_rf = VEML6030_GAIN_RF,
++      .it_rf = VEML6030_IT_RF,
+       .hw_init = veml6030_hw_init,
+       .set_info = veml7700_set_info,
+       .set_als_gain = veml6030_set_als_gain,
+-- 
+2.39.5
+
diff --git a/queue-6.14/iio-light-veml6030-fix-scale-to-conform-to-abi.patch b/queue-6.14/iio-light-veml6030-fix-scale-to-conform-to-abi.patch
new file mode 100644 (file)
index 0000000..5c1d5e9
--- /dev/null
@@ -0,0 +1,802 @@
+From 5172b3ca2fe38c990a64de6ecf4c9b1794c5be88 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 27 Jan 2025 20:30:23 +0100
+Subject: iio: light: veml6030: fix scale to conform to ABI
+
+From: Javier Carrasco <javier.carrasco.cruz@gmail.com>
+
+[ Upstream commit 22eaca4283b216f5e1f7721e4ad0ecb3d23c6774 ]
+
+The current scale is not ABI-compliant as it is just the sensor gain
+instead of the value that acts as a multiplier to be applied to the raw
+value (there is no offset).
+
+Use the iio-gts helpers to obtain the proper scale values according to
+the gain and integration time to match the resolution tables from the
+datasheet and drop dedicated variables to store the current values of
+the integration time, gain and resolution. When at it, use 'scale'
+instead of 'gain' consistently for the get/set functions to avoid
+misunderstandings.
+
+Fixes: 7b779f573c48 ("iio: light: add driver for veml6030 ambient light sensor")
+Acked-by: Matti Vaittinen <mazziesaccount@gmail.com>
+Signed-off-by: Javier Carrasco <javier.carrasco.cruz@gmail.com>
+Link: https://patch.msgid.link/20250127-veml6030-scale-v3-2-4f32ba03df94@gmail.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/light/Kconfig    |   1 +
+ drivers/iio/light/veml6030.c | 528 ++++++++++++++---------------------
+ 2 files changed, 218 insertions(+), 311 deletions(-)
+
+diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig
+index e34e551eef3e8..eb7f56eaeae07 100644
+--- a/drivers/iio/light/Kconfig
++++ b/drivers/iio/light/Kconfig
+@@ -683,6 +683,7 @@ config VEML6030
+       select REGMAP_I2C
+       select IIO_BUFFER
+       select IIO_TRIGGERED_BUFFER
++      select IIO_GTS_HELPER
+       depends on I2C
+       help
+         Say Y here if you want to build a driver for the Vishay VEML6030
+diff --git a/drivers/iio/light/veml6030.c b/drivers/iio/light/veml6030.c
+index 8e4eb8b0c1927..750d3c2267a49 100644
+--- a/drivers/iio/light/veml6030.c
++++ b/drivers/iio/light/veml6030.c
+@@ -24,10 +24,12 @@
+ #include <linux/regmap.h>
+ #include <linux/interrupt.h>
+ #include <linux/pm_runtime.h>
++#include <linux/units.h>
+ #include <linux/regulator/consumer.h>
+ #include <linux/iio/iio.h>
+ #include <linux/iio/sysfs.h>
+ #include <linux/iio/events.h>
++#include <linux/iio/iio-gts-helper.h>
+ #include <linux/iio/trigger_consumer.h>
+ #include <linux/iio/triggered_buffer.h>
+@@ -65,6 +67,10 @@
+ #define VEML6035_GAIN_RF      REG_FIELD(VEML6030_REG_ALS_CONF, 10, 12)
++/* Maximum scales x 10000 to work with integers */
++#define VEML6030_MAX_SCALE    21504
++#define VEML6035_MAX_SCALE    4096
++
+ enum veml6030_scan {
+       VEML6030_SCAN_ALS,
+       VEML6030_SCAN_WH,
+@@ -78,16 +84,13 @@ struct veml6030_rf {
+ struct veml603x_chip {
+       const char *name;
+-      const int(*scale_vals)[][2];
+-      const int num_scale_vals;
+       const struct iio_chan_spec *channels;
+       const int num_channels;
+       const struct reg_field gain_rf;
+       const struct reg_field it_rf;
++      const int max_scale;
+       int (*hw_init)(struct iio_dev *indio_dev, struct device *dev);
+       int (*set_info)(struct iio_dev *indio_dev);
+-      int (*set_als_gain)(struct iio_dev *indio_dev, int val, int val2);
+-      int (*get_als_gain)(struct iio_dev *indio_dev, int *val, int *val2);
+ };
+ /*
+@@ -105,40 +108,55 @@ struct veml6030_data {
+       struct i2c_client *client;
+       struct regmap *regmap;
+       struct veml6030_rf rf;
+-      int cur_resolution;
+-      int cur_gain;
+-      int cur_integration_time;
+       const struct veml603x_chip *chip;
++      struct iio_gts gts;
++
+ };
+-static const int veml6030_it_times[][2] = {
+-      { 0, 25000 },
+-      { 0, 50000 },
+-      { 0, 100000 },
+-      { 0, 200000 },
+-      { 0, 400000 },
+-      { 0, 800000 },
++#define VEML6030_SEL_IT_25MS  0x0C
++#define VEML6030_SEL_IT_50MS  0x08
++#define VEML6030_SEL_IT_100MS 0x00
++#define VEML6030_SEL_IT_200MS 0x01
++#define VEML6030_SEL_IT_400MS 0x02
++#define VEML6030_SEL_IT_800MS 0x03
++static const struct iio_itime_sel_mul veml6030_it_sel[] = {
++      GAIN_SCALE_ITIME_US(25000, VEML6030_SEL_IT_25MS, 1),
++      GAIN_SCALE_ITIME_US(50000, VEML6030_SEL_IT_50MS, 2),
++      GAIN_SCALE_ITIME_US(100000, VEML6030_SEL_IT_100MS, 4),
++      GAIN_SCALE_ITIME_US(200000, VEML6030_SEL_IT_200MS, 8),
++      GAIN_SCALE_ITIME_US(400000, VEML6030_SEL_IT_400MS, 16),
++      GAIN_SCALE_ITIME_US(800000, VEML6030_SEL_IT_800MS, 32),
+ };
+-/*
+- * Scale is 1/gain. Value 0.125 is ALS gain x (1/8), 0.25 is
+- * ALS gain x (1/4), 0.5 is ALS gain x (1/2), 1.0 is ALS gain x 1,
+- * 2.0 is ALS gain x2, and 4.0 is ALS gain x 4.
++/* Gains are multiplied by 8 to work with integers. The values in the
++ * iio-gts tables don't need corrections because the maximum value of
++ * the scale refers to GAIN = x1, and the rest of the values are
++ * obtained from the resulting linear function.
+  */
+-static const int veml6030_scale_vals[][2] = {
+-      { 0, 125000 },
+-      { 0, 250000 },
+-      { 1, 0 },
+-      { 2, 0 },
++#define VEML6030_SEL_MILLI_GAIN_X125  2
++#define VEML6030_SEL_MILLI_GAIN_X250  3
++#define VEML6030_SEL_MILLI_GAIN_X1000 0
++#define VEML6030_SEL_MILLI_GAIN_X2000 1
++static const struct iio_gain_sel_pair veml6030_gain_sel[] = {
++      GAIN_SCALE_GAIN(1, VEML6030_SEL_MILLI_GAIN_X125),
++      GAIN_SCALE_GAIN(2, VEML6030_SEL_MILLI_GAIN_X250),
++      GAIN_SCALE_GAIN(8, VEML6030_SEL_MILLI_GAIN_X1000),
++      GAIN_SCALE_GAIN(16, VEML6030_SEL_MILLI_GAIN_X2000),
+ };
+-static const int veml6035_scale_vals[][2] = {
+-      { 0, 125000 },
+-      { 0, 250000 },
+-      { 0, 500000 },
+-      { 1, 0 },
+-      { 2, 0 },
+-      { 4, 0 },
++#define VEML6035_SEL_MILLI_GAIN_X125  4
++#define VEML6035_SEL_MILLI_GAIN_X250  5
++#define VEML6035_SEL_MILLI_GAIN_X500  7
++#define VEML6035_SEL_MILLI_GAIN_X1000 0
++#define VEML6035_SEL_MILLI_GAIN_X2000 1
++#define VEML6035_SEL_MILLI_GAIN_X4000 3
++static const struct iio_gain_sel_pair veml6035_gain_sel[] = {
++      GAIN_SCALE_GAIN(1, VEML6035_SEL_MILLI_GAIN_X125),
++      GAIN_SCALE_GAIN(2, VEML6035_SEL_MILLI_GAIN_X250),
++      GAIN_SCALE_GAIN(4, VEML6035_SEL_MILLI_GAIN_X500),
++      GAIN_SCALE_GAIN(8, VEML6035_SEL_MILLI_GAIN_X1000),
++      GAIN_SCALE_GAIN(16, VEML6035_SEL_MILLI_GAIN_X2000),
++      GAIN_SCALE_GAIN(32, VEML6035_SEL_MILLI_GAIN_X4000),
+ };
+ /*
+@@ -341,104 +359,73 @@ static const struct regmap_config veml6030_regmap_config = {
+       .val_format_endian = REGMAP_ENDIAN_LITTLE,
+ };
+-static int veml6030_get_intgrn_tm(struct iio_dev *indio_dev,
+-                                              int *val, int *val2)
++static int veml6030_get_it(struct veml6030_data *data, int *val, int *val2)
+ {
+-      int it_idx, ret;
+-      struct veml6030_data *data = iio_priv(indio_dev);
++      int ret, it_idx;
+       ret = regmap_field_read(data->rf.it, &it_idx);
+-      if (ret) {
+-              dev_err(&data->client->dev,
+-                              "can't read als conf register %d\n", ret);
++      if (ret)
+               return ret;
+-      }
+-      switch (it_idx) {
+-      case 0:
+-              *val2 = 100000;
+-              break;
+-      case 1:
+-              *val2 = 200000;
+-              break;
+-      case 2:
+-              *val2 = 400000;
+-              break;
+-      case 3:
+-              *val2 = 800000;
+-              break;
+-      case 8:
+-              *val2 = 50000;
+-              break;
+-      case 12:
+-              *val2 = 25000;
+-              break;
+-      default:
+-              return -EINVAL;
+-      }
++      ret = iio_gts_find_int_time_by_sel(&data->gts, it_idx);
++      if (ret < 0)
++              return ret;
++      *val2 = ret;
+       *val = 0;
++
+       return IIO_VAL_INT_PLUS_MICRO;
+ }
+-static int veml6030_set_intgrn_tm(struct iio_dev *indio_dev,
+-                                              int val, int val2)
++static int veml6030_set_it(struct iio_dev *indio_dev, int val, int val2)
+ {
+-      int ret, new_int_time, int_idx;
+       struct veml6030_data *data = iio_priv(indio_dev);
++      int ret, gain_idx, it_idx, new_gain, prev_gain, prev_it;
++      bool in_range;
+-      if (val)
++      if (val || !iio_gts_valid_time(&data->gts, val2))
+               return -EINVAL;
+-      switch (val2) {
+-      case 25000:
+-              new_int_time = 0x300;
+-              int_idx = 5;
+-              break;
+-      case 50000:
+-              new_int_time = 0x200;
+-              int_idx = 4;
+-              break;
+-      case 100000:
+-              new_int_time = 0x00;
+-              int_idx = 3;
+-              break;
+-      case 200000:
+-              new_int_time = 0x40;
+-              int_idx = 2;
+-              break;
+-      case 400000:
+-              new_int_time = 0x80;
+-              int_idx = 1;
+-              break;
+-      case 800000:
+-              new_int_time = 0xC0;
+-              int_idx = 0;
+-              break;
+-      default:
+-              return -EINVAL;
+-      }
++      ret = regmap_field_read(data->rf.it, &it_idx);
++      if (ret)
++              return ret;
+-      ret = regmap_field_write(data->rf.it, new_int_time);
+-      if (ret) {
+-              dev_err(&data->client->dev,
+-                              "can't update als integration time %d\n", ret);
++      ret = regmap_field_read(data->rf.gain, &gain_idx);
++      if (ret)
+               return ret;
+-      }
+-      /*
+-       * Cache current integration time and update resolution. For every
+-       * increase in integration time to next level, resolution is halved
+-       * and vice-versa.
+-       */
+-      if (data->cur_integration_time < int_idx)
+-              data->cur_resolution <<= int_idx - data->cur_integration_time;
+-      else if (data->cur_integration_time > int_idx)
+-              data->cur_resolution >>= data->cur_integration_time - int_idx;
++      prev_it = iio_gts_find_int_time_by_sel(&data->gts, it_idx);
++      if (prev_it < 0)
++              return prev_it;
++
++      if (prev_it == val2)
++              return 0;
+-      data->cur_integration_time = int_idx;
++      prev_gain = iio_gts_find_gain_by_sel(&data->gts, gain_idx);
++      if (prev_gain < 0)
++              return prev_gain;
+-      return ret;
++      ret = iio_gts_find_new_gain_by_gain_time_min(&data->gts, prev_gain, prev_it,
++                                                   val2, &new_gain, &in_range);
++      if (ret)
++              return ret;
++
++      if (!in_range)
++              dev_dbg(&data->client->dev, "Optimal gain out of range\n");
++
++      ret = iio_gts_find_sel_by_int_time(&data->gts, val2);
++      if (ret < 0)
++              return ret;
++
++      ret = regmap_field_write(data->rf.it, ret);
++      if (ret)
++              return ret;
++
++      ret = iio_gts_find_sel_by_gain(&data->gts, new_gain);
++      if (ret < 0)
++              return ret;
++
++      return regmap_field_write(data->rf.gain, ret);
+ }
+ static int veml6030_read_persistence(struct iio_dev *indio_dev,
+@@ -447,7 +434,7 @@ static int veml6030_read_persistence(struct iio_dev *indio_dev,
+       int ret, reg, period, x, y;
+       struct veml6030_data *data = iio_priv(indio_dev);
+-      ret = veml6030_get_intgrn_tm(indio_dev, &x, &y);
++      ret = veml6030_get_it(data, &x, &y);
+       if (ret < 0)
+               return ret;
+@@ -472,7 +459,7 @@ static int veml6030_write_persistence(struct iio_dev *indio_dev,
+       int ret, period, x, y;
+       struct veml6030_data *data = iio_priv(indio_dev);
+-      ret = veml6030_get_intgrn_tm(indio_dev, &x, &y);
++      ret = veml6030_get_it(data, &x, &y);
+       if (ret < 0)
+               return ret;
+@@ -501,177 +488,29 @@ static int veml6030_write_persistence(struct iio_dev *indio_dev,
+       return ret;
+ }
+-/*
+- * Cache currently set gain & update resolution. For every
+- * increase in the gain to next level, resolution is halved
+- * and vice-versa.
+- */
+-static void veml6030_update_gain_res(struct veml6030_data *data, int gain_idx)
+-{
+-      if (data->cur_gain < gain_idx)
+-              data->cur_resolution <<= gain_idx - data->cur_gain;
+-      else if (data->cur_gain > gain_idx)
+-              data->cur_resolution >>= data->cur_gain - gain_idx;
+-
+-      data->cur_gain = gain_idx;
+-}
+-
+-static int veml6030_set_als_gain(struct iio_dev *indio_dev,
+-                                              int val, int val2)
++static int veml6030_set_scale(struct iio_dev *indio_dev, int val, int val2)
+ {
+-      int ret, new_gain, gain_idx;
++      int ret, gain_sel, it_idx, it_sel;
+       struct veml6030_data *data = iio_priv(indio_dev);
+-      if (val == 0 && val2 == 125000) {
+-              new_gain = 0x01;
+-              gain_idx = 3;
+-      } else if (val == 0 && val2 == 250000) {
+-              new_gain = 0x11;
+-              gain_idx = 2;
+-      } else if (val == 1 && val2 == 0) {
+-              new_gain = 0x00;
+-              gain_idx = 1;
+-      } else if (val == 2 && val2 == 0) {
+-              new_gain = 0x01;
+-              gain_idx = 0;
+-      } else {
+-              return -EINVAL;
+-      }
+-
+-      ret = regmap_field_write(data->rf.gain, new_gain);
+-      if (ret) {
+-              dev_err(&data->client->dev,
+-                              "can't set als gain %d\n", ret);
++      ret = regmap_field_read(data->rf.it, &it_idx);
++      if (ret)
+               return ret;
+-      }
+-
+-      veml6030_update_gain_res(data, gain_idx);
+-
+-      return 0;
+-}
+-
+-static int veml6035_set_als_gain(struct iio_dev *indio_dev, int val, int val2)
+-{
+-      int ret, new_gain, gain_idx;
+-      struct veml6030_data *data = iio_priv(indio_dev);
+-
+-      if (val == 0 && val2 == 125000) {
+-              new_gain = FIELD_GET(VEML6035_GAIN_M, VEML6035_SENS);
+-              gain_idx = 5;
+-      } else if (val == 0 && val2 == 250000) {
+-              new_gain = FIELD_GET(VEML6035_GAIN_M, VEML6035_SENS |
+-                                    VEML6035_GAIN);
+-              gain_idx = 4;
+-      } else if (val == 0 && val2 == 500000) {
+-              new_gain = FIELD_GET(VEML6035_GAIN_M, VEML6035_SENS |
+-                                    VEML6035_GAIN | VEML6035_DG);
+-              gain_idx = 3;
+-      } else if (val == 1 && val2 == 0) {
+-              new_gain = 0x0000;
+-              gain_idx = 2;
+-      } else if (val == 2 && val2 == 0) {
+-              new_gain = FIELD_GET(VEML6035_GAIN_M, VEML6035_GAIN);
+-              gain_idx = 1;
+-      } else if (val == 4 && val2 == 0) {
+-              new_gain = FIELD_GET(VEML6035_GAIN_M, VEML6035_GAIN |
+-                                    VEML6035_DG);
+-              gain_idx = 0;
+-      } else {
+-              return -EINVAL;
+-      }
+-      ret = regmap_field_write(data->rf.gain, new_gain);
+-      if (ret) {
+-              dev_err(&data->client->dev, "can't set als gain %d\n", ret);
++      ret = iio_gts_find_gain_time_sel_for_scale(&data->gts, val, val2,
++                                                 &gain_sel, &it_sel);
++      if (ret)
+               return ret;
+-      }
+-
+-      veml6030_update_gain_res(data, gain_idx);
+-
+-      return 0;
+-}
+-
+-static int veml6030_get_als_gain(struct iio_dev *indio_dev,
+-                                              int *val, int *val2)
+-{
+-      int gain, ret;
+-      struct veml6030_data *data = iio_priv(indio_dev);
+-      ret = regmap_field_read(data->rf.gain, &gain);
+-      if (ret) {
+-              dev_err(&data->client->dev,
+-                              "can't read als conf register %d\n", ret);
++      ret = regmap_field_write(data->rf.it, it_sel);
++      if (ret)
+               return ret;
+-      }
+-      switch (gain) {
+-      case 0:
+-              *val = 1;
+-              *val2 = 0;
+-              break;
+-      case 1:
+-              *val = 2;
+-              *val2 = 0;
+-              break;
+-      case 2:
+-              *val = 0;
+-              *val2 = 125000;
+-              break;
+-      case 3:
+-              *val = 0;
+-              *val2 = 250000;
+-              break;
+-      default:
+-              return -EINVAL;
+-      }
+-
+-      return IIO_VAL_INT_PLUS_MICRO;
+-}
+-
+-static int veml6035_get_als_gain(struct iio_dev *indio_dev, int *val, int *val2)
+-{
+-      int gain, ret;
+-      struct veml6030_data *data = iio_priv(indio_dev);
+-
+-      ret = regmap_field_read(data->rf.gain, &gain);
+-      if (ret) {
+-              dev_err(&data->client->dev,
+-                              "can't read als conf register %d\n", ret);
++      ret = regmap_field_write(data->rf.gain, gain_sel);
++      if (ret)
+               return ret;
+-      }
+-
+-      switch (gain) {
+-      case 0:
+-              *val = 1;
+-              *val2 = 0;
+-              break;
+-      case 1:
+-      case 2:
+-              *val = 2;
+-              *val2 = 0;
+-              break;
+-      case 3:
+-              *val = 4;
+-              *val2 = 0;
+-              break;
+-      case 4:
+-              *val = 0;
+-              *val2 = 125000;
+-              break;
+-      case 5:
+-      case 6:
+-              *val = 0;
+-              *val2 = 250000;
+-              break;
+-      case 7:
+-              *val = 0;
+-              *val2 = 500000;
+-              break;
+-      default:
+-              return -EINVAL;
+-      }
+-      return IIO_VAL_INT_PLUS_MICRO;
++      return 0;
+ }
+ static int veml6030_read_thresh(struct iio_dev *indio_dev,
+@@ -718,6 +557,71 @@ static int veml6030_write_thresh(struct iio_dev *indio_dev,
+       return ret;
+ }
++static int veml6030_get_total_gain(struct veml6030_data *data)
++{
++      int gain, it, reg, ret;
++
++      ret = regmap_field_read(data->rf.gain, &reg);
++      if (ret)
++              return ret;
++
++      gain = iio_gts_find_gain_by_sel(&data->gts, reg);
++      if (gain < 0)
++              return gain;
++
++      ret = regmap_field_read(data->rf.it, &reg);
++      if (ret)
++              return ret;
++
++      it = iio_gts_find_int_time_by_sel(&data->gts, reg);
++      if (it < 0)
++              return it;
++
++      return iio_gts_get_total_gain(&data->gts, gain, it);
++}
++
++static int veml6030_get_scale(struct veml6030_data *data, int *val, int *val2)
++{
++      int gain, it, reg, ret;
++
++      ret = regmap_field_read(data->rf.gain, &reg);
++      if (ret)
++              return ret;
++
++      gain = iio_gts_find_gain_by_sel(&data->gts, reg);
++      if (gain < 0)
++              return gain;
++
++      ret = regmap_field_read(data->rf.it, &reg);
++      if (ret)
++              return ret;
++
++      it = iio_gts_find_int_time_by_sel(&data->gts, reg);
++      if (it < 0)
++              return it;
++
++      ret = iio_gts_get_scale(&data->gts, gain, it, val, val2);
++      if (ret)
++              return ret;
++
++      return IIO_VAL_INT_PLUS_NANO;
++}
++
++static int veml6030_process_als(struct veml6030_data *data, int raw,
++                              int *val, int *val2)
++{
++      int total_gain;
++
++      total_gain = veml6030_get_total_gain(data);
++      if (total_gain < 0)
++              return total_gain;
++
++      *val = raw * data->chip->max_scale / total_gain / 10000;
++      *val2 = raw * data->chip->max_scale / total_gain % 10000 * 100;
++
++      return IIO_VAL_INT_PLUS_MICRO;
++}
++
+ /*
+  * Provide both raw as well as light reading in lux.
+  * light (in lux) = resolution * raw reading
+@@ -741,11 +645,9 @@ static int veml6030_read_raw(struct iio_dev *indio_dev,
+                               dev_err(dev, "can't read als data %d\n", ret);
+                               return ret;
+                       }
+-                      if (mask == IIO_CHAN_INFO_PROCESSED) {
+-                              *val = (reg * data->cur_resolution) / 10000;
+-                              *val2 = (reg * data->cur_resolution) % 10000 * 100;
+-                              return IIO_VAL_INT_PLUS_MICRO;
+-                      }
++                      if (mask == IIO_CHAN_INFO_PROCESSED)
++                              return veml6030_process_als(data, reg, val, val2);
++
+                       *val = reg;
+                       return IIO_VAL_INT;
+               case IIO_INTENSITY:
+@@ -760,9 +662,9 @@ static int veml6030_read_raw(struct iio_dev *indio_dev,
+                       return -EINVAL;
+               }
+       case IIO_CHAN_INFO_INT_TIME:
+-              return veml6030_get_intgrn_tm(indio_dev, val, val2);
++              return veml6030_get_it(data, val, val2);
+       case IIO_CHAN_INFO_SCALE:
+-              return data->chip->get_als_gain(indio_dev, val, val2);
++              return veml6030_get_scale(data, val, val2);
+       default:
+               return -EINVAL;
+       }
+@@ -777,15 +679,9 @@ static int veml6030_read_avail(struct iio_dev *indio_dev,
+       switch (mask) {
+       case IIO_CHAN_INFO_INT_TIME:
+-              *vals = (int *)&veml6030_it_times;
+-              *length = 2 * ARRAY_SIZE(veml6030_it_times);
+-              *type = IIO_VAL_INT_PLUS_MICRO;
+-              return IIO_AVAIL_LIST;
++              return iio_gts_avail_times(&data->gts, vals, type, length);
+       case IIO_CHAN_INFO_SCALE:
+-              *vals = (int *)*data->chip->scale_vals;
+-              *length = 2 * data->chip->num_scale_vals;
+-              *type = IIO_VAL_INT_PLUS_MICRO;
+-              return IIO_AVAIL_LIST;
++              return iio_gts_all_avail_scales(&data->gts, vals, type, length);
+       }
+       return -EINVAL;
+@@ -795,13 +691,25 @@ static int veml6030_write_raw(struct iio_dev *indio_dev,
+                               struct iio_chan_spec const *chan,
+                               int val, int val2, long mask)
+ {
+-      struct veml6030_data *data = iio_priv(indio_dev);
+-
+       switch (mask) {
+       case IIO_CHAN_INFO_INT_TIME:
+-              return veml6030_set_intgrn_tm(indio_dev, val, val2);
++              return veml6030_set_it(indio_dev, val, val2);
++      case IIO_CHAN_INFO_SCALE:
++              return veml6030_set_scale(indio_dev, val, val2);
++      default:
++              return -EINVAL;
++      }
++}
++
++static int veml6030_write_raw_get_fmt(struct iio_dev *indio_dev,
++                                    struct iio_chan_spec const *chan,
++                                    long mask)
++{
++      switch (mask) {
+       case IIO_CHAN_INFO_SCALE:
+-              return data->chip->set_als_gain(indio_dev, val, val2);
++              return IIO_VAL_INT_PLUS_NANO;
++      case IIO_CHAN_INFO_INT_TIME:
++              return IIO_VAL_INT_PLUS_MICRO;
+       default:
+               return -EINVAL;
+       }
+@@ -899,6 +807,7 @@ static const struct iio_info veml6030_info = {
+       .read_raw  = veml6030_read_raw,
+       .read_avail  = veml6030_read_avail,
+       .write_raw = veml6030_write_raw,
++      .write_raw_get_fmt = veml6030_write_raw_get_fmt,
+       .read_event_value = veml6030_read_event_val,
+       .write_event_value      = veml6030_write_event_val,
+       .read_event_config = veml6030_read_interrupt_config,
+@@ -910,6 +819,7 @@ static const struct iio_info veml6030_info_no_irq = {
+       .read_raw  = veml6030_read_raw,
+       .read_avail  = veml6030_read_avail,
+       .write_raw = veml6030_write_raw,
++      .write_raw_get_fmt = veml6030_write_raw_get_fmt,
+ };
+ static irqreturn_t veml6030_event_handler(int irq, void *private)
+@@ -1035,6 +945,13 @@ static int veml6030_hw_init(struct iio_dev *indio_dev, struct device *dev)
+       int ret, val;
+       struct veml6030_data *data = iio_priv(indio_dev);
++      ret = devm_iio_init_iio_gts(dev, 2, 150400000,
++                                  veml6030_gain_sel, ARRAY_SIZE(veml6030_gain_sel),
++                                  veml6030_it_sel, ARRAY_SIZE(veml6030_it_sel),
++                                  &data->gts);
++      if (ret)
++              return dev_err_probe(dev, ret, "failed to init iio gts\n");
++
+       ret = veml6030_als_shut_down(data);
+       if (ret)
+               return dev_err_probe(dev, ret, "can't shutdown als\n");
+@@ -1070,11 +987,6 @@ static int veml6030_hw_init(struct iio_dev *indio_dev, struct device *dev)
+               return dev_err_probe(dev, ret,
+                                    "can't clear als interrupt status\n");
+-      /* Cache currently active measurement parameters */
+-      data->cur_gain = 3;
+-      data->cur_resolution = 5376;
+-      data->cur_integration_time = 3;
+-
+       return ret;
+ }
+@@ -1090,6 +1002,13 @@ static int veml6035_hw_init(struct iio_dev *indio_dev, struct device *dev)
+       int ret, val;
+       struct veml6030_data *data = iio_priv(indio_dev);
++      ret = devm_iio_init_iio_gts(dev, 0, 409600000,
++                                  veml6035_gain_sel, ARRAY_SIZE(veml6035_gain_sel),
++                                  veml6030_it_sel, ARRAY_SIZE(veml6030_it_sel),
++                                  &data->gts);
++      if (ret)
++              return dev_err_probe(dev, ret, "failed to init iio gts\n");
++
+       ret = veml6030_als_shut_down(data);
+       if (ret)
+               return dev_err_probe(dev, ret, "can't shutdown als\n");
+@@ -1126,11 +1045,6 @@ static int veml6035_hw_init(struct iio_dev *indio_dev, struct device *dev)
+               return dev_err_probe(dev, ret,
+                                    "can't clear als interrupt status\n");
+-      /* Cache currently active measurement parameters */
+-      data->cur_gain = 5;
+-      data->cur_resolution = 1024;
+-      data->cur_integration_time = 3;
+-
+       return 0;
+ }
+@@ -1226,44 +1140,35 @@ static DEFINE_RUNTIME_DEV_PM_OPS(veml6030_pm_ops, veml6030_runtime_suspend,
+ static const struct veml603x_chip veml6030_chip = {
+       .name = "veml6030",
+-      .scale_vals = &veml6030_scale_vals,
+-      .num_scale_vals = ARRAY_SIZE(veml6030_scale_vals),
+       .channels = veml6030_channels,
+       .num_channels = ARRAY_SIZE(veml6030_channels),
+       .gain_rf = VEML6030_GAIN_RF,
+       .it_rf = VEML6030_IT_RF,
++      .max_scale = VEML6030_MAX_SCALE,
+       .hw_init = veml6030_hw_init,
+       .set_info = veml6030_set_info,
+-      .set_als_gain = veml6030_set_als_gain,
+-      .get_als_gain = veml6030_get_als_gain,
+ };
+ static const struct veml603x_chip veml6035_chip = {
+       .name = "veml6035",
+-      .scale_vals = &veml6035_scale_vals,
+-      .num_scale_vals = ARRAY_SIZE(veml6035_scale_vals),
+       .channels = veml6030_channels,
+       .num_channels = ARRAY_SIZE(veml6030_channels),
+       .gain_rf = VEML6035_GAIN_RF,
+       .it_rf = VEML6030_IT_RF,
++      .max_scale = VEML6035_MAX_SCALE,
+       .hw_init = veml6035_hw_init,
+       .set_info = veml6030_set_info,
+-      .set_als_gain = veml6035_set_als_gain,
+-      .get_als_gain = veml6035_get_als_gain,
+ };
+ static const struct veml603x_chip veml7700_chip = {
+       .name = "veml7700",
+-      .scale_vals = &veml6030_scale_vals,
+-      .num_scale_vals = ARRAY_SIZE(veml6030_scale_vals),
+       .channels = veml7700_channels,
+       .num_channels = ARRAY_SIZE(veml7700_channels),
+       .gain_rf = VEML6030_GAIN_RF,
+       .it_rf = VEML6030_IT_RF,
++      .max_scale = VEML6030_MAX_SCALE,
+       .hw_init = veml6030_hw_init,
+       .set_info = veml7700_set_info,
+-      .set_als_gain = veml6030_set_als_gain,
+-      .get_als_gain = veml6030_get_als_gain,
+ };
+ static const struct of_device_id veml6030_of_match[] = {
+@@ -1305,3 +1210,4 @@ module_i2c_driver(veml6030_driver);
+ MODULE_AUTHOR("Rishi Gupta <gupt21@gmail.com>");
+ MODULE_DESCRIPTION("VEML6030 Ambient Light Sensor");
+ MODULE_LICENSE("GPL v2");
++MODULE_IMPORT_NS("IIO_GTS_HELPER");
+-- 
+2.39.5
+
diff --git a/queue-6.14/io_uring-check-for-iowq-alloc_workqueue-failure.patch b/queue-6.14/io_uring-check-for-iowq-alloc_workqueue-failure.patch
new file mode 100644 (file)
index 0000000..d81b58b
--- /dev/null
@@ -0,0 +1,36 @@
+From 0795165d214b607fd288e5febc014a9181d812ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Jan 2025 17:28:21 +0000
+Subject: io_uring: check for iowq alloc_workqueue failure
+
+From: Pavel Begunkov <asml.silence@gmail.com>
+
+[ Upstream commit 7215469659cb9751a9bf80e43b24a48749004d26 ]
+
+alloc_workqueue() can fail even during init in io_uring_init(), check
+the result and panic if anything went wrong.
+
+Fixes: 73eaa2b583493 ("io_uring: use private workqueue for exit work")
+Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
+Link: https://lore.kernel.org/r/3a046063902f888f66151f89fa42f84063b9727b.1738343083.git.asml.silence@gmail.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ io_uring/io_uring.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
+index f7acae5f7e1d0..573b3f542b82a 100644
+--- a/io_uring/io_uring.c
++++ b/io_uring/io_uring.c
+@@ -3922,6 +3922,7 @@ static int __init io_uring_init(void)
+                                         SLAB_HWCACHE_ALIGN | SLAB_PANIC | SLAB_ACCOUNT);
+       iou_wq = alloc_workqueue("iou_exit", WQ_UNBOUND, 64);
++      BUG_ON(!iou_wq);
+ #ifdef CONFIG_SYSCTL
+       register_sysctl_init("kernel", kernel_io_uring_disabled_table);
+-- 
+2.39.5
+
diff --git a/queue-6.14/io_uring-fix-retry-handling-off-iowq.patch b/queue-6.14/io_uring-fix-retry-handling-off-iowq.patch
new file mode 100644 (file)
index 0000000..fcbdfa1
--- /dev/null
@@ -0,0 +1,38 @@
+From 7b61ac899c110ca07750fe62fb1115bf88dae98c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Mar 2025 15:32:32 +0000
+Subject: io_uring: fix retry handling off iowq
+
+From: Pavel Begunkov <asml.silence@gmail.com>
+
+[ Upstream commit 3f0cb8de56b9a5c052a9e43fa548856926059810 ]
+
+io_req_complete_post() doesn't handle reissue and if called with a
+REQ_F_REISSUE request it might post extra unexpected completions. Fix it
+by pushing into flush_completion via task work.
+
+Fixes: d803d123948fe ("io_uring/rw: handle -EAGAIN retry at IO completion time")
+Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
+Link: https://lore.kernel.org/r/badb3d7e462881e7edbfcc2be6301090b07dbe53.1742829388.git.asml.silence@gmail.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ io_uring/io_uring.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
+index 99b83487c8158..4910ee7ac18aa 100644
+--- a/io_uring/io_uring.c
++++ b/io_uring/io_uring.c
+@@ -899,7 +899,7 @@ static void io_req_complete_post(struct io_kiocb *req, unsigned issue_flags)
+        * Handle special CQ sync cases via task_work. DEFER_TASKRUN requires
+        * the submitter task context, IOPOLL protects with uring_lock.
+        */
+-      if (ctx->lockless_cq) {
++      if (ctx->lockless_cq || (req->flags & REQ_F_REISSUE)) {
+               req->io_task_work.func = io_req_task_complete;
+               io_req_task_work_add(req);
+               return;
+-- 
+2.39.5
+
diff --git a/queue-6.14/io_uring-io-wq-cache-work-flags-in-variable.patch b/queue-6.14/io_uring-io-wq-cache-work-flags-in-variable.patch
new file mode 100644 (file)
index 0000000..8407516
--- /dev/null
@@ -0,0 +1,183 @@
+From e42afeb38a26b057411cb0897732807f1804c4c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Jan 2025 14:39:23 +0100
+Subject: io_uring/io-wq: cache work->flags in variable
+
+From: Max Kellermann <max.kellermann@ionos.com>
+
+[ Upstream commit 6ee78354eaa602002448f098b34678396d99043d ]
+
+This eliminates several redundant atomic reads and therefore reduces
+the duration the surrounding spinlocks are held.
+
+In several io_uring benchmarks, this reduced the CPU time spent in
+queued_spin_lock_slowpath() considerably:
+
+io_uring benchmark with a flood of `IORING_OP_NOP` and `IOSQE_ASYNC`:
+
+    38.86%     -1.49%  [kernel.kallsyms]  [k] queued_spin_lock_slowpath
+     6.75%     +0.36%  [kernel.kallsyms]  [k] io_worker_handle_work
+     2.60%     +0.19%  [kernel.kallsyms]  [k] io_nop
+     3.92%     +0.18%  [kernel.kallsyms]  [k] io_req_task_complete
+     6.34%     -0.18%  [kernel.kallsyms]  [k] io_wq_submit_work
+
+HTTP server, static file:
+
+    42.79%     -2.77%  [kernel.kallsyms]     [k] queued_spin_lock_slowpath
+     2.08%     +0.23%  [kernel.kallsyms]     [k] io_wq_submit_work
+     1.19%     +0.20%  [kernel.kallsyms]     [k] amd_iommu_iotlb_sync_map
+     1.46%     +0.15%  [kernel.kallsyms]     [k] ep_poll_callback
+     1.80%     +0.15%  [kernel.kallsyms]     [k] io_worker_handle_work
+
+HTTP server, PHP:
+
+    35.03%     -1.80%  [kernel.kallsyms]     [k] queued_spin_lock_slowpath
+     0.84%     +0.21%  [kernel.kallsyms]     [k] amd_iommu_iotlb_sync_map
+     1.39%     +0.12%  [kernel.kallsyms]     [k] _copy_to_iter
+     0.21%     +0.10%  [kernel.kallsyms]     [k] update_sd_lb_stats
+
+Signed-off-by: Max Kellermann <max.kellermann@ionos.com>
+Link: https://lore.kernel.org/r/20250128133927.3989681-5-max.kellermann@ionos.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Stable-dep-of: 486ba4d84d62 ("io_uring/io-wq: do not use bogus hash value")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ io_uring/io-wq.c | 33 +++++++++++++++++++++------------
+ io_uring/io-wq.h |  7 ++++++-
+ 2 files changed, 27 insertions(+), 13 deletions(-)
+
+diff --git a/io_uring/io-wq.c b/io_uring/io-wq.c
+index f7d09698e43ce..d1eaa3e39cd5f 100644
+--- a/io_uring/io-wq.c
++++ b/io_uring/io-wq.c
+@@ -160,9 +160,9 @@ static inline struct io_wq_acct *io_get_acct(struct io_wq *wq, bool bound)
+ }
+ static inline struct io_wq_acct *io_work_get_acct(struct io_wq *wq,
+-                                                struct io_wq_work *work)
++                                                unsigned int work_flags)
+ {
+-      return io_get_acct(wq, !(atomic_read(&work->flags) & IO_WQ_WORK_UNBOUND));
++      return io_get_acct(wq, !(work_flags & IO_WQ_WORK_UNBOUND));
+ }
+ static inline struct io_wq_acct *io_wq_get_acct(struct io_worker *worker)
+@@ -452,9 +452,14 @@ static void __io_worker_idle(struct io_wq *wq, struct io_worker *worker)
+       }
+ }
++static inline unsigned int __io_get_work_hash(unsigned int work_flags)
++{
++      return work_flags >> IO_WQ_HASH_SHIFT;
++}
++
+ static inline unsigned int io_get_work_hash(struct io_wq_work *work)
+ {
+-      return atomic_read(&work->flags) >> IO_WQ_HASH_SHIFT;
++      return __io_get_work_hash(atomic_read(&work->flags));
+ }
+ static bool io_wait_on_hash(struct io_wq *wq, unsigned int hash)
+@@ -484,17 +489,19 @@ static struct io_wq_work *io_get_next_work(struct io_wq_acct *acct,
+       struct io_wq *wq = worker->wq;
+       wq_list_for_each(node, prev, &acct->work_list) {
++              unsigned int work_flags;
+               unsigned int hash;
+               work = container_of(node, struct io_wq_work, list);
+               /* not hashed, can run anytime */
+-              if (!io_wq_is_hashed(work)) {
++              work_flags = atomic_read(&work->flags);
++              if (!__io_wq_is_hashed(work_flags)) {
+                       wq_list_del(&acct->work_list, node, prev);
+                       return work;
+               }
+-              hash = io_get_work_hash(work);
++              hash = __io_get_work_hash(work_flags);
+               /* all items with this hash lie in [work, tail] */
+               tail = wq->hash_tail[hash];
+@@ -591,12 +598,13 @@ static void io_worker_handle_work(struct io_wq_acct *acct,
+               /* handle a whole dependent link */
+               do {
+                       struct io_wq_work *next_hashed, *linked;
+-                      unsigned int hash = io_get_work_hash(work);
++                      unsigned int work_flags = atomic_read(&work->flags);
++                      unsigned int hash = __io_get_work_hash(work_flags);
+                       next_hashed = wq_next_work(work);
+                       if (do_kill &&
+-                          (atomic_read(&work->flags) & IO_WQ_WORK_UNBOUND))
++                          (work_flags & IO_WQ_WORK_UNBOUND))
+                               atomic_or(IO_WQ_WORK_CANCEL, &work->flags);
+                       wq->do_work(work);
+                       io_assign_current_work(worker, NULL);
+@@ -916,18 +924,19 @@ static void io_run_cancel(struct io_wq_work *work, struct io_wq *wq)
+       } while (work);
+ }
+-static void io_wq_insert_work(struct io_wq *wq, struct io_wq_acct *acct, struct io_wq_work *work)
++static void io_wq_insert_work(struct io_wq *wq, struct io_wq_acct *acct,
++                            struct io_wq_work *work, unsigned int work_flags)
+ {
+       unsigned int hash;
+       struct io_wq_work *tail;
+-      if (!io_wq_is_hashed(work)) {
++      if (!__io_wq_is_hashed(work_flags)) {
+ append:
+               wq_list_add_tail(&work->list, &acct->work_list);
+               return;
+       }
+-      hash = io_get_work_hash(work);
++      hash = __io_get_work_hash(work_flags);
+       tail = wq->hash_tail[hash];
+       wq->hash_tail[hash] = work;
+       if (!tail)
+@@ -943,8 +952,8 @@ static bool io_wq_work_match_item(struct io_wq_work *work, void *data)
+ void io_wq_enqueue(struct io_wq *wq, struct io_wq_work *work)
+ {
+-      struct io_wq_acct *acct = io_work_get_acct(wq, work);
+       unsigned int work_flags = atomic_read(&work->flags);
++      struct io_wq_acct *acct = io_work_get_acct(wq, work_flags);
+       struct io_cb_cancel_data match = {
+               .fn             = io_wq_work_match_item,
+               .data           = work,
+@@ -963,7 +972,7 @@ void io_wq_enqueue(struct io_wq *wq, struct io_wq_work *work)
+       }
+       raw_spin_lock(&acct->lock);
+-      io_wq_insert_work(wq, acct, work);
++      io_wq_insert_work(wq, acct, work, work_flags);
+       clear_bit(IO_ACCT_STALLED_BIT, &acct->flags);
+       raw_spin_unlock(&acct->lock);
+diff --git a/io_uring/io-wq.h b/io_uring/io-wq.h
+index b3b004a7b6252..d4fb2940e435f 100644
+--- a/io_uring/io-wq.h
++++ b/io_uring/io-wq.h
+@@ -54,9 +54,14 @@ int io_wq_cpu_affinity(struct io_uring_task *tctx, cpumask_var_t mask);
+ int io_wq_max_workers(struct io_wq *wq, int *new_count);
+ bool io_wq_worker_stopped(void);
++static inline bool __io_wq_is_hashed(unsigned int work_flags)
++{
++      return work_flags & IO_WQ_WORK_HASHED;
++}
++
+ static inline bool io_wq_is_hashed(struct io_wq_work *work)
+ {
+-      return atomic_read(&work->flags) & IO_WQ_WORK_HASHED;
++      return __io_wq_is_hashed(atomic_read(&work->flags));
+ }
+ typedef bool (work_cancel_fn)(struct io_wq_work *, void *);
+-- 
+2.39.5
+
diff --git a/queue-6.14/io_uring-io-wq-do-not-use-bogus-hash-value.patch b/queue-6.14/io_uring-io-wq-do-not-use-bogus-hash-value.patch
new file mode 100644 (file)
index 0000000..dc499aa
--- /dev/null
@@ -0,0 +1,56 @@
+From 7749467c5f9aa433ee66e585741f7c9e04cb203f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Jan 2025 14:39:24 +0100
+Subject: io_uring/io-wq: do not use bogus hash value
+
+From: Max Kellermann <max.kellermann@ionos.com>
+
+[ Upstream commit 486ba4d84d62e92716cd395c4b1612b8ce70a257 ]
+
+Previously, the `hash` variable was initialized with `-1` and only
+updated by io_get_next_work() if the current work was hashed.  Commit
+60cf46ae6054 ("io-wq: hash dependent work") changed this to always
+call io_get_work_hash() even if the work was not hashed.  This caused
+the `hash != -1U` check to always be true, adding some overhead for
+the `hash->wait` code.
+
+This patch fixes the regression by checking the `IO_WQ_WORK_HASHED`
+flag.
+
+Perf diff for a flood of `IORING_OP_NOP` with `IOSQE_ASYNC`:
+
+    38.55%     -1.57%  [kernel.kallsyms]  [k] queued_spin_lock_slowpath
+     6.86%     -0.72%  [kernel.kallsyms]  [k] io_worker_handle_work
+     0.10%     +0.67%  [kernel.kallsyms]  [k] put_prev_entity
+     1.96%     +0.59%  [kernel.kallsyms]  [k] io_nop_prep
+     3.31%     -0.51%  [kernel.kallsyms]  [k] try_to_wake_up
+     7.18%     -0.47%  [kernel.kallsyms]  [k] io_wq_free_work
+
+Fixes: 60cf46ae6054 ("io-wq: hash dependent work")
+Cc: Pavel Begunkov <asml.silence@gmail.com>
+Signed-off-by: Max Kellermann <max.kellermann@ionos.com>
+Link: https://lore.kernel.org/r/20250128133927.3989681-6-max.kellermann@ionos.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ io_uring/io-wq.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/io_uring/io-wq.c b/io_uring/io-wq.c
+index d1eaa3e39cd5f..24f06fba43096 100644
+--- a/io_uring/io-wq.c
++++ b/io_uring/io-wq.c
+@@ -599,7 +599,9 @@ static void io_worker_handle_work(struct io_wq_acct *acct,
+               do {
+                       struct io_wq_work *next_hashed, *linked;
+                       unsigned int work_flags = atomic_read(&work->flags);
+-                      unsigned int hash = __io_get_work_hash(work_flags);
++                      unsigned int hash = __io_wq_is_hashed(work_flags)
++                              ? __io_get_work_hash(work_flags)
++                              : -1U;
+                       next_hashed = wq_next_work(work);
+-- 
+2.39.5
+
diff --git a/queue-6.14/io_uring-io-wq-eliminate-redundant-io_work_get_acct-.patch b/queue-6.14/io_uring-io-wq-eliminate-redundant-io_work_get_acct-.patch
new file mode 100644 (file)
index 0000000..c83da4e
--- /dev/null
@@ -0,0 +1,72 @@
+From 60788765a619d0a24f7afb2cbbdc82cca878d72b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Jan 2025 14:39:20 +0100
+Subject: io_uring/io-wq: eliminate redundant io_work_get_acct() calls
+
+From: Max Kellermann <max.kellermann@ionos.com>
+
+[ Upstream commit 3c75635f8ed482300931327847c50068a865a648 ]
+
+Instead of calling io_work_get_acct() again, pass acct to
+io_wq_insert_work() and io_wq_remove_pending().
+
+This atomic access in io_work_get_acct() was done under the
+`acct->lock`, and optimizing it away reduces lock contention a bit.
+
+Signed-off-by: Max Kellermann <max.kellermann@ionos.com>
+Link: https://lore.kernel.org/r/20250128133927.3989681-2-max.kellermann@ionos.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Stable-dep-of: 486ba4d84d62 ("io_uring/io-wq: do not use bogus hash value")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ io_uring/io-wq.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/io_uring/io-wq.c b/io_uring/io-wq.c
+index 91019b4d03088..f7d09698e43ce 100644
+--- a/io_uring/io-wq.c
++++ b/io_uring/io-wq.c
+@@ -916,9 +916,8 @@ static void io_run_cancel(struct io_wq_work *work, struct io_wq *wq)
+       } while (work);
+ }
+-static void io_wq_insert_work(struct io_wq *wq, struct io_wq_work *work)
++static void io_wq_insert_work(struct io_wq *wq, struct io_wq_acct *acct, struct io_wq_work *work)
+ {
+-      struct io_wq_acct *acct = io_work_get_acct(wq, work);
+       unsigned int hash;
+       struct io_wq_work *tail;
+@@ -964,7 +963,7 @@ void io_wq_enqueue(struct io_wq *wq, struct io_wq_work *work)
+       }
+       raw_spin_lock(&acct->lock);
+-      io_wq_insert_work(wq, work);
++      io_wq_insert_work(wq, acct, work);
+       clear_bit(IO_ACCT_STALLED_BIT, &acct->flags);
+       raw_spin_unlock(&acct->lock);
+@@ -1034,10 +1033,10 @@ static bool io_wq_worker_cancel(struct io_worker *worker, void *data)
+ }
+ static inline void io_wq_remove_pending(struct io_wq *wq,
++                                      struct io_wq_acct *acct,
+                                        struct io_wq_work *work,
+                                        struct io_wq_work_node *prev)
+ {
+-      struct io_wq_acct *acct = io_work_get_acct(wq, work);
+       unsigned int hash = io_get_work_hash(work);
+       struct io_wq_work *prev_work = NULL;
+@@ -1064,7 +1063,7 @@ static bool io_acct_cancel_pending_work(struct io_wq *wq,
+               work = container_of(node, struct io_wq_work, list);
+               if (!match->fn(work, match->data))
+                       continue;
+-              io_wq_remove_pending(wq, work, prev);
++              io_wq_remove_pending(wq, acct, work, prev);
+               raw_spin_unlock(&acct->lock);
+               io_run_cancel(work, wq);
+               match->nr_pending++;
+-- 
+2.39.5
+
diff --git a/queue-6.14/io_uring-net-improve-recv-bundles.patch b/queue-6.14/io_uring-net-improve-recv-bundles.patch
new file mode 100644 (file)
index 0000000..ea48a4a
--- /dev/null
@@ -0,0 +1,133 @@
+From 22e4a71444dfc6c063a80d3ffe7773416ae25679 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Feb 2025 10:50:34 -0700
+Subject: io_uring/net: improve recv bundles
+
+From: Jens Axboe <axboe@kernel.dk>
+
+[ Upstream commit 7c71a0af81ba72de9b2c501065e4e718aba9a271 ]
+
+Current recv bundles are only supported for multishot receives, and
+additionally they also always post at least 2 CQEs if more data is
+available than what a buffer will hold. This happens because the initial
+bundle recv will do a single buffer, and then do the rest of what is in
+the socket as a followup receive. As shown in a test program, if 1k
+buffers are available and 32k is available to receive in the socket,
+you'd get the following completions:
+
+bundle=1, mshot=0
+cqe res 1024
+cqe res 1024
+[...]
+cqe res 1024
+
+bundle=1, mshot=1
+cqe res 1024
+cqe res 31744
+
+where bundle=1 && mshot=0 will post 32 1k completions, and bundle=1 &&
+mshot=1 will post a 1k completion and then a 31k completion.
+
+To support bundle recv without multishot, it's possible to simply retry
+the recv immediately and post a single completion, rather than split it
+into two completions. With the below patch, the same test looks as
+follows:
+
+bundle=1, mshot=0
+cqe res 32768
+
+bundle=1, mshot=1
+cqe res 32768
+
+where mshot=0 works fine for bundles, and both of them post just a
+single 32k completion rather than split it into separate completions.
+Posting fewer completions is always a nice win, and not needing
+multishot for proper bundle efficiency is nice for cases that can't
+necessarily use multishot.
+
+Reported-by: Norman Maurer <norman_maurer@apple.com>
+Link: https://lore.kernel.org/r/184f9f92-a682-4205-a15d-89e18f664502@kernel.dk
+Fixes: 2f9c9515bdfd ("io_uring/net: support bundles for recv")
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ io_uring/net.c | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/io_uring/net.c b/io_uring/net.c
+index 50e8a3ccc9de9..e9bea0235c130 100644
+--- a/io_uring/net.c
++++ b/io_uring/net.c
+@@ -76,6 +76,7 @@ struct io_sr_msg {
+       /* initialised and used only by !msg send variants */
+       u16                             buf_group;
+       u16                             buf_index;
++      bool                            retry;
+       void __user                     *msg_control;
+       /* used only for send zerocopy */
+       struct io_kiocb                 *notif;
+@@ -187,6 +188,7 @@ static inline void io_mshot_prep_retry(struct io_kiocb *req,
+       req->flags &= ~REQ_F_BL_EMPTY;
+       sr->done_io = 0;
++      sr->retry = false;
+       sr->len = 0; /* get from the provided buffer */
+       req->buf_index = sr->buf_group;
+ }
+@@ -404,6 +406,7 @@ int io_sendmsg_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
+       struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
+       sr->done_io = 0;
++      sr->retry = false;
+       if (req->opcode != IORING_OP_SEND) {
+               if (sqe->addr2 || sqe->file_index)
+@@ -786,6 +789,7 @@ int io_recvmsg_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
+       struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
+       sr->done_io = 0;
++      sr->retry = false;
+       if (unlikely(sqe->file_index || sqe->addr2))
+               return -EINVAL;
+@@ -834,6 +838,9 @@ int io_recvmsg_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
+       return io_recvmsg_prep_setup(req);
+ }
++/* bits to clear in old and inherit in new cflags on bundle retry */
++#define CQE_F_MASK    (IORING_CQE_F_SOCK_NONEMPTY|IORING_CQE_F_MORE)
++
+ /*
+  * Finishes io_recv and io_recvmsg.
+  *
+@@ -853,9 +860,19 @@ static inline bool io_recv_finish(struct io_kiocb *req, int *ret,
+       if (sr->flags & IORING_RECVSEND_BUNDLE) {
+               cflags |= io_put_kbufs(req, *ret, io_bundle_nbufs(kmsg, *ret),
+                                     issue_flags);
++              if (sr->retry)
++                      cflags = req->cqe.flags | (cflags & CQE_F_MASK);
+               /* bundle with no more immediate buffers, we're done */
+               if (req->flags & REQ_F_BL_EMPTY)
+                       goto finish;
++              /* if more is available, retry and append to this one */
++              if (!sr->retry && kmsg->msg.msg_inq > 0 && *ret > 0) {
++                      req->cqe.flags = cflags & ~CQE_F_MASK;
++                      sr->len = kmsg->msg.msg_inq;
++                      sr->done_io += *ret;
++                      sr->retry = true;
++                      return false;
++              }
+       } else {
+               cflags |= io_put_kbuf(req, *ret, issue_flags);
+       }
+@@ -1234,6 +1251,7 @@ int io_send_zc_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
+       struct io_kiocb *notif;
+       zc->done_io = 0;
++      zc->retry = false;
+       req->flags |= REQ_F_POLL_NO_LAZY;
+       if (unlikely(READ_ONCE(sqe->__pad2[0]) || READ_ONCE(sqe->addr3)))
+-- 
+2.39.5
+
diff --git a/queue-6.14/io_uring-net-only-import-send_zc-buffer-once.patch b/queue-6.14/io_uring-net-only-import-send_zc-buffer-once.patch
new file mode 100644 (file)
index 0000000..3e3b752
--- /dev/null
@@ -0,0 +1,60 @@
+From aedf91129a4b50679b6310ea092dc26631343b8f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Mar 2025 12:48:17 -0600
+Subject: io_uring/net: only import send_zc buffer once
+
+From: Caleb Sander Mateos <csander@purestorage.com>
+
+[ Upstream commit 8e3100fcc5cbba03518b8b5c059624aba5c29d50 ]
+
+io_send_zc() guards its call to io_send_zc_import() with if (!done_io)
+in an attempt to avoid calling it redundantly on the same req. However,
+if the initial non-blocking issue returns -EAGAIN, done_io will stay 0.
+This causes the subsequent issue to unnecessarily re-import the buffer.
+
+Add an explicit flag "imported" to io_sr_msg to track if its buffer has
+already been imported. Clear the flag in io_send_zc_prep(). Call
+io_send_zc_import() and set the flag in io_send_zc() if it is unset.
+
+Signed-off-by: Caleb Sander Mateos <csander@purestorage.com>
+Fixes: 54cdcca05abd ("io_uring/net: switch io_send() and io_send_zc() to using io_async_msghdr")
+Link: https://lore.kernel.org/r/20250321184819.3847386-2-csander@purestorage.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ io_uring/net.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/io_uring/net.c b/io_uring/net.c
+index e9bea0235c130..16d54cd4d53f3 100644
+--- a/io_uring/net.c
++++ b/io_uring/net.c
+@@ -77,6 +77,7 @@ struct io_sr_msg {
+       u16                             buf_group;
+       u16                             buf_index;
+       bool                            retry;
++      bool                            imported; /* only for io_send_zc */
+       void __user                     *msg_control;
+       /* used only for send zerocopy */
+       struct io_kiocb                 *notif;
+@@ -1252,6 +1253,7 @@ int io_send_zc_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
+       zc->done_io = 0;
+       zc->retry = false;
++      zc->imported = false;
+       req->flags |= REQ_F_POLL_NO_LAZY;
+       if (unlikely(READ_ONCE(sqe->__pad2[0]) || READ_ONCE(sqe->addr3)))
+@@ -1414,7 +1416,8 @@ int io_send_zc(struct io_kiocb *req, unsigned int issue_flags)
+           (zc->flags & IORING_RECVSEND_POLL_FIRST))
+               return -EAGAIN;
+-      if (!zc->done_io) {
++      if (!zc->imported) {
++              zc->imported = true;
+               ret = io_send_zc_import(req, issue_flags);
+               if (unlikely(ret))
+                       return ret;
+-- 
+2.39.5
+
diff --git a/queue-6.14/io_uring-use-lockless_cq-flag-in-io_req_complete_pos.patch b/queue-6.14/io_uring-use-lockless_cq-flag-in-io_req_complete_pos.patch
new file mode 100644 (file)
index 0000000..c732d31
--- /dev/null
@@ -0,0 +1,40 @@
+From ac8d0697a8246d85e7cd88880f3204fc07688efe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Feb 2025 17:51:18 -0700
+Subject: io_uring: use lockless_cq flag in io_req_complete_post()
+
+From: Caleb Sander Mateos <csander@purestorage.com>
+
+[ Upstream commit 62aa9805d123165102273eb277f776aaca908e0e ]
+
+io_uring_create() computes ctx->lockless_cq as:
+ctx->task_complete || (ctx->flags & IORING_SETUP_IOPOLL)
+
+So use it to simplify that expression in io_req_complete_post().
+
+Signed-off-by: Caleb Sander Mateos <csander@purestorage.com>
+Reviewed-by: Li Zetao <lizetao1@huawei.com>
+Link: https://lore.kernel.org/r/20250212005119.3433005-1-csander@purestorage.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Stable-dep-of: 3f0cb8de56b9 ("io_uring: fix retry handling off iowq")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ io_uring/io_uring.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
+index 573b3f542b82a..99b83487c8158 100644
+--- a/io_uring/io_uring.c
++++ b/io_uring/io_uring.c
+@@ -899,7 +899,7 @@ static void io_req_complete_post(struct io_kiocb *req, unsigned issue_flags)
+        * Handle special CQ sync cases via task_work. DEFER_TASKRUN requires
+        * the submitter task context, IOPOLL protects with uring_lock.
+        */
+-      if (ctx->task_complete || (ctx->flags & IORING_SETUP_IOPOLL)) {
++      if (ctx->lockless_cq) {
+               req->io_task_work.func = io_req_task_complete;
+               io_req_task_work_add(req);
+               return;
+-- 
+2.39.5
+
diff --git a/queue-6.14/iommu-amd-fix-header-file.patch b/queue-6.14/iommu-amd-fix-header-file.patch
new file mode 100644 (file)
index 0000000..c46c673
--- /dev/null
@@ -0,0 +1,46 @@
+From 5bf07061ffefdc855be064926ff1b51886dc4628 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 16:23:18 +0000
+Subject: iommu/amd: Fix header file
+
+From: Vasant Hegde <vasant.hegde@amd.com>
+
+[ Upstream commit ee4cf9260afe8e4be6b6d64f56fa7493d051d8de ]
+
+Move function declaration inside AMD_IOMMU_H defination.
+
+Fixes: fd5dff9de4be ("iommu/amd: Modify set_dte_entry() to use 256-bit DTE helpers")
+Fixes: 457da5764668 ("iommu/amd: Lock DTE before updating the entry with WRITE_ONCE()")
+Cc: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
+Signed-off-by: Vasant Hegde <vasant.hegde@amd.com>
+Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
+Link: https://lore.kernel.org/r/20250227162320.5805-6-vasant.hegde@amd.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/amd/amd_iommu.h | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/iommu/amd/amd_iommu.h b/drivers/iommu/amd/amd_iommu.h
+index 68debf5ee2d75..e3bf27da1339e 100644
+--- a/drivers/iommu/amd/amd_iommu.h
++++ b/drivers/iommu/amd/amd_iommu.h
+@@ -176,12 +176,11 @@ void amd_iommu_apply_ivrs_quirks(void);
+ #else
+ static inline void amd_iommu_apply_ivrs_quirks(void) { }
+ #endif
++struct dev_table_entry *amd_iommu_get_ivhd_dte_flags(u16 segid, u16 devid);
+ void amd_iommu_domain_set_pgtable(struct protection_domain *domain,
+                                 u64 *root, int mode);
+ struct dev_table_entry *get_dev_table(struct amd_iommu *iommu);
+-
+-#endif
+-
+-struct dev_table_entry *amd_iommu_get_ivhd_dte_flags(u16 segid, u16 devid);
+ struct iommu_dev_data *search_dev_data(struct amd_iommu *iommu, u16 devid);
++
++#endif /* AMD_IOMMU_H */
+-- 
+2.39.5
+
diff --git a/queue-6.14/iommu-handle-race-with-default-domain-setup.patch b/queue-6.14/iommu-handle-race-with-default-domain-setup.patch
new file mode 100644 (file)
index 0000000..7ec7107
--- /dev/null
@@ -0,0 +1,57 @@
+From 03a391950995413b4bddd9c0b4fb8a49469a6435 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Feb 2025 15:46:30 +0000
+Subject: iommu: Handle race with default domain setup
+
+From: Robin Murphy <robin.murphy@arm.com>
+
+[ Upstream commit b46064a18810bad3aea089a79993ca5ea7a3d2b2 ]
+
+It turns out that deferred default domain creation leaves a subtle
+race window during iommu_device_register() wherein a client driver may
+asynchronously probe in parallel and get as far as performing DMA API
+operations with dma-direct, only to be switched to iommu-dma underfoot
+once the default domain attachment finally happens, with obviously
+disastrous consequences. Even the wonky of_iommu_configure() path is at
+risk, since iommu_fwspec_init() will no longer defer client probe as the
+instance ops are (necessarily) already registered, and the "replay"
+iommu_probe_device() call can see dev->iommu_group already set and so
+think there's nothing to do either.
+
+Fortunately we already have the right tool in the right place in the
+form of iommu_device_use_default_domain(), which just needs to ensure
+that said default domain is actually ready to *be* used. Deferring the
+client probe shouldn't have too much impact, given that this only
+happens while the IOMMU driver is probing, and thus due to kick the
+deferred probe list again once it finishes.
+
+Reported-by: Charan Teja Kalla <quic_charante@quicinc.com>
+Fixes: 98ac73f99bc4 ("iommu: Require a default_domain for all iommu drivers")
+Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Robin Murphy <robin.murphy@arm.com>
+Link: https://lore.kernel.org/r/e88b94c9b575034a2c98a48b3d383654cbda7902.1740753261.git.robin.murphy@arm.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/iommu.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
+index 60aed01e54f27..e3df1f06afbeb 100644
+--- a/drivers/iommu/iommu.c
++++ b/drivers/iommu/iommu.c
+@@ -3097,6 +3097,11 @@ int iommu_device_use_default_domain(struct device *dev)
+               return 0;
+       mutex_lock(&group->mutex);
++      /* We may race against bus_iommu_probe() finalising groups here */
++      if (!group->default_domain) {
++              ret = -EPROBE_DEFER;
++              goto unlock_out;
++      }
+       if (group->owner_cnt) {
+               if (group->domain != group->default_domain || group->owner ||
+                   !xa_empty(&group->pasid_array)) {
+-- 
+2.39.5
+
diff --git a/queue-6.14/iommu-io-pgtable-dart-only-set-subpage-protection-di.patch b/queue-6.14/iommu-io-pgtable-dart-only-set-subpage-protection-di.patch
new file mode 100644 (file)
index 0000000..58fd4ce
--- /dev/null
@@ -0,0 +1,47 @@
+From 9486734923927d3d2704ff9bc58f41608155b59e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Feb 2025 10:13:53 +0100
+Subject: iommu/io-pgtable-dart: Only set subpage protection disable for DART 1
+
+From: Asahi Lina <lina@asahilina.net>
+
+[ Upstream commit 5276c1e07679c44ee021e88045bbb5190831b328 ]
+
+Subpage protection can't be disabled on t6000-style darts,
+as such the disable flag no longer applies, and probably
+even affects something else.
+
+Fixes: dc09fe1c5edd ("iommu/io-pgtable-dart: Add DART PTE support for t6000")
+Signed-off-by: Asahi Lina <lina@asahilina.net>
+Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
+Reviewed-by: Sven Peter <sven@svenpeter.dev>
+Link: https://lore.kernel.org/r/20250219-dart2-no-sp-disable-v1-1-9f324cfa4e70@gmail.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/io-pgtable-dart.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iommu/io-pgtable-dart.c b/drivers/iommu/io-pgtable-dart.c
+index c004640640ee5..06aca9ab52f9a 100644
+--- a/drivers/iommu/io-pgtable-dart.c
++++ b/drivers/iommu/io-pgtable-dart.c
+@@ -135,7 +135,6 @@ static int dart_init_pte(struct dart_io_pgtable *data,
+       pte |= FIELD_PREP(APPLE_DART_PTE_SUBPAGE_START, 0);
+       pte |= FIELD_PREP(APPLE_DART_PTE_SUBPAGE_END, 0xfff);
+-      pte |= APPLE_DART1_PTE_PROT_SP_DIS;
+       pte |= APPLE_DART_PTE_VALID;
+       for (i = 0; i < num_entries; i++)
+@@ -211,6 +210,7 @@ static dart_iopte dart_prot_to_pte(struct dart_io_pgtable *data,
+       dart_iopte pte = 0;
+       if (data->iop.fmt == APPLE_DART) {
++              pte |= APPLE_DART1_PTE_PROT_SP_DIS;
+               if (!(prot & IOMMU_WRITE))
+                       pte |= APPLE_DART1_PTE_PROT_NO_WRITE;
+               if (!(prot & IOMMU_READ))
+-- 
+2.39.5
+
diff --git a/queue-6.14/iommu-vt-d-fix-system-hang-on-reboot-f.patch b/queue-6.14/iommu-vt-d-fix-system-hang-on-reboot-f.patch
new file mode 100644 (file)
index 0000000..2adb081
--- /dev/null
@@ -0,0 +1,93 @@
+From dd5ec70a60d720099f6adebc4b1b4078b2699c7f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Mar 2025 10:47:44 +0800
+Subject: iommu/vt-d: Fix system hang on reboot -f
+
+From: Yunhui Cui <cuiyunhui@bytedance.com>
+
+[ Upstream commit 9ce7603ad3cbae64003087de57834e8c5c856a20 ]
+
+We found that executing the command ./a.out &;reboot -f (where a.out is a
+program that only executes a while(1) infinite loop) can probabilistically
+cause the system to hang in the intel_iommu_shutdown() function, rendering
+it unresponsive. Through analysis, we identified that the factors
+contributing to this issue are as follows:
+
+1. The reboot -f command does not prompt the kernel to notify the
+application layer to perform cleanup actions, allowing the application to
+continue running.
+
+2. When the kernel reaches the intel_iommu_shutdown() function, only the
+BSP (Bootstrap Processor) CPU is operational in the system.
+
+3. During the execution of intel_iommu_shutdown(), the function down_write
+(&dmar_global_lock) causes the process to sleep and be scheduled out.
+
+4. At this point, though the processor's interrupt flag is not cleared,
+ allowing interrupts to be accepted. However, only legacy devices and NMI
+(Non-Maskable Interrupt) interrupts could come in, as other interrupts
+routing have already been disabled. If no legacy or NMI interrupts occur
+at this stage, the scheduler will not be able to run.
+
+5. If the application got scheduled at this time is executing a while(1)-
+type loop, it will be unable to be preempted, leading to an infinite loop
+and causing the system to become unresponsive.
+
+To resolve this issue, the intel_iommu_shutdown() function should not
+execute down_write(), which can potentially cause the process to be
+scheduled out. Furthermore, since only the BSP is running during the later
+stages of the reboot, there is no need for protection against parallel
+access to the DMAR (DMA Remapping) unit. Therefore, the following lines
+could be removed:
+
+down_write(&dmar_global_lock);
+up_write(&dmar_global_lock);
+
+After testing, the issue has been resolved.
+
+Fixes: 6c3a44ed3c55 ("iommu/vt-d: Turn off translations at shutdown")
+Co-developed-by: Ethan Zhao <haifeng.zhao@linux.intel.com>
+Signed-off-by: Ethan Zhao <haifeng.zhao@linux.intel.com>
+Signed-off-by: Yunhui Cui <cuiyunhui@bytedance.com>
+Link: https://lore.kernel.org/r/20250303062421.17929-1-cuiyunhui@bytedance.com
+Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/intel/iommu.c | 17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
+index bf1f0c8143483..25d31f8c129a6 100644
+--- a/drivers/iommu/intel/iommu.c
++++ b/drivers/iommu/intel/iommu.c
+@@ -2871,16 +2871,19 @@ void intel_iommu_shutdown(void)
+       if (no_iommu || dmar_disabled)
+               return;
+-      down_write(&dmar_global_lock);
++      /*
++       * All other CPUs were brought down, hotplug interrupts were disabled,
++       * no lock and RCU checking needed anymore
++       */
++      list_for_each_entry(drhd, &dmar_drhd_units, list) {
++              iommu = drhd->iommu;
+-      /* Disable PMRs explicitly here. */
+-      for_each_iommu(iommu, drhd)
++              /* Disable PMRs explicitly here. */
+               iommu_disable_protect_mem_regions(iommu);
+-      /* Make sure the IOMMUs are switched off */
+-      intel_disable_iommus();
+-
+-      up_write(&dmar_global_lock);
++              /* Make sure the IOMMUs are switched off */
++              iommu_disable_translation(iommu);
++      }
+ }
+ static struct intel_iommu *dev_to_intel_iommu(struct device *dev)
+-- 
+2.39.5
+
diff --git a/queue-6.14/ipv6-do-not-consider-link-down-nexthops-in-path-sele.patch b/queue-6.14/ipv6-do-not-consider-link-down-nexthops-in-path-sele.patch
new file mode 100644 (file)
index 0000000..244b5eb
--- /dev/null
@@ -0,0 +1,64 @@
+From 6fb367a2bdb46f5af1e7a9fb578e4ae15688e726 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Apr 2025 14:42:24 +0300
+Subject: ipv6: Do not consider link down nexthops in path selection
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 8b8e0dd357165e0258d9f9cdab5366720ed2f619 ]
+
+Nexthops whose link is down are not supposed to be considered during
+path selection when the "ignore_routes_with_linkdown" sysctl is set.
+This is done by assigning them a negative region boundary.
+
+However, when comparing the computed hash (unsigned) with the region
+boundary (signed), the negative region boundary is treated as unsigned,
+resulting in incorrect nexthop selection.
+
+Fix by treating the computed hash as signed. Note that the computed hash
+is always in range of [0, 2^31 - 1].
+
+Fixes: 3d709f69a3e7 ("ipv6: Use hash-threshold instead of modulo-N")
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20250402114224.293392-3-idosch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/route.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/net/ipv6/route.c b/net/ipv6/route.c
+index 07ff19ae263f5..169a7b9bc40ea 100644
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -442,6 +442,7 @@ void fib6_select_path(const struct net *net, struct fib6_result *res,
+ {
+       struct fib6_info *first, *match = res->f6i;
+       struct fib6_info *sibling;
++      int hash;
+       if (!match->nh && (!match->fib6_nsiblings || have_oif_match))
+               goto out;
+@@ -468,7 +469,8 @@ void fib6_select_path(const struct net *net, struct fib6_result *res,
+       if (!first)
+               goto out;
+-      if (fl6->mp_hash <= atomic_read(&first->fib6_nh->fib_nh_upper_bound) &&
++      hash = fl6->mp_hash;
++      if (hash <= atomic_read(&first->fib6_nh->fib_nh_upper_bound) &&
+           rt6_score_route(first->fib6_nh, first->fib6_flags, oif,
+                           strict) >= 0) {
+               match = first;
+@@ -481,7 +483,7 @@ void fib6_select_path(const struct net *net, struct fib6_result *res,
+               int nh_upper_bound;
+               nh_upper_bound = atomic_read(&nh->fib_nh_upper_bound);
+-              if (fl6->mp_hash > nh_upper_bound)
++              if (hash > nh_upper_bound)
+                       continue;
+               if (rt6_score_route(nh, sibling->fib6_flags, oif, strict) < 0)
+                       break;
+-- 
+2.39.5
+
diff --git a/queue-6.14/ipv6-fix-omitted-netlink-attributes-when-using-rtext.patch b/queue-6.14/ipv6-fix-omitted-netlink-attributes-when-using-rtext.patch
new file mode 100644 (file)
index 0000000..424889c
--- /dev/null
@@ -0,0 +1,87 @@
+From bf52317672eaee9039c9103cf725ffae264fbb93 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Apr 2025 14:17:51 +0200
+Subject: ipv6: fix omitted netlink attributes when using
+ RTEXT_FILTER_SKIP_STATS
+
+From: Fernando Fernandez Mancera <ffmancera@riseup.net>
+
+[ Upstream commit 7ac6ea4a3e0898db76aecccd68fb2c403eb7d24e ]
+
+Using RTEXT_FILTER_SKIP_STATS is incorrectly skipping non-stats IPv6
+netlink attributes on link dump. This causes issues on userspace tools,
+e.g iproute2 is not rendering address generation mode as it should due
+to missing netlink attribute.
+
+Move the filling of IFLA_INET6_STATS and IFLA_INET6_ICMP6STATS to a
+helper function guarded by a flag check to avoid hitting the same
+situation in the future.
+
+Fixes: d5566fd72ec1 ("rtnetlink: RTEXT_FILTER_SKIP_STATS support to avoid dumping inet/inet6 stats")
+Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250402121751.3108-1-ffmancera@riseup.net
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/addrconf.c | 37 +++++++++++++++++++++++++------------
+ 1 file changed, 25 insertions(+), 12 deletions(-)
+
+diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
+index ac8cc10765360..54a8ea004da28 100644
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -5784,6 +5784,27 @@ static void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype,
+       }
+ }
++static int inet6_fill_ifla6_stats_attrs(struct sk_buff *skb,
++                                      struct inet6_dev *idev)
++{
++      struct nlattr *nla;
++
++      nla = nla_reserve(skb, IFLA_INET6_STATS, IPSTATS_MIB_MAX * sizeof(u64));
++      if (!nla)
++              goto nla_put_failure;
++      snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_STATS, nla_len(nla));
++
++      nla = nla_reserve(skb, IFLA_INET6_ICMP6STATS, ICMP6_MIB_MAX * sizeof(u64));
++      if (!nla)
++              goto nla_put_failure;
++      snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_ICMP6STATS, nla_len(nla));
++
++      return 0;
++
++nla_put_failure:
++      return -EMSGSIZE;
++}
++
+ static int inet6_fill_ifla6_attrs(struct sk_buff *skb, struct inet6_dev *idev,
+                                 u32 ext_filter_mask)
+ {
+@@ -5806,18 +5827,10 @@ static int inet6_fill_ifla6_attrs(struct sk_buff *skb, struct inet6_dev *idev,
+       /* XXX - MC not implemented */
+-      if (ext_filter_mask & RTEXT_FILTER_SKIP_STATS)
+-              return 0;
+-
+-      nla = nla_reserve(skb, IFLA_INET6_STATS, IPSTATS_MIB_MAX * sizeof(u64));
+-      if (!nla)
+-              goto nla_put_failure;
+-      snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_STATS, nla_len(nla));
+-
+-      nla = nla_reserve(skb, IFLA_INET6_ICMP6STATS, ICMP6_MIB_MAX * sizeof(u64));
+-      if (!nla)
+-              goto nla_put_failure;
+-      snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_ICMP6STATS, nla_len(nla));
++      if (!(ext_filter_mask & RTEXT_FILTER_SKIP_STATS)) {
++              if (inet6_fill_ifla6_stats_attrs(skb, idev) < 0)
++                      goto nla_put_failure;
++      }
+       nla = nla_reserve(skb, IFLA_INET6_TOKEN, sizeof(struct in6_addr));
+       if (!nla)
+-- 
+2.39.5
+
diff --git a/queue-6.14/ipv6-start-path-selection-from-the-first-nexthop.patch b/queue-6.14/ipv6-start-path-selection-from-the-first-nexthop.patch
new file mode 100644 (file)
index 0000000..b110fc3
--- /dev/null
@@ -0,0 +1,101 @@
+From 7cffaf4157929a0ae26826a6338482ad25518363 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Apr 2025 14:42:23 +0300
+Subject: ipv6: Start path selection from the first nexthop
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 4d0ab3a6885e3e9040310a8d8f54503366083626 ]
+
+Cited commit transitioned IPv6 path selection to use hash-threshold
+instead of modulo-N. With hash-threshold, each nexthop is assigned a
+region boundary in the multipath hash function's output space and a
+nexthop is chosen if the calculated hash is smaller than the nexthop's
+region boundary.
+
+Hash-threshold does not work correctly if path selection does not start
+with the first nexthop. For example, if fib6_select_path() is always
+passed the last nexthop in the group, then it will always be chosen
+because its region boundary covers the entire hash function's output
+space.
+
+Fix this by starting the selection process from the first nexthop and do
+not consider nexthops for which rt6_score_route() provided a negative
+score.
+
+Fixes: 3d709f69a3e7 ("ipv6: Use hash-threshold instead of modulo-N")
+Reported-by: Stanislav Fomichev <stfomichev@gmail.com>
+Closes: https://lore.kernel.org/netdev/Z9RIyKZDNoka53EO@mini-arch/
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20250402114224.293392-2-idosch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/route.c | 38 +++++++++++++++++++++++++++++++++++---
+ 1 file changed, 35 insertions(+), 3 deletions(-)
+
+diff --git a/net/ipv6/route.c b/net/ipv6/route.c
+index 15ce21afc8c62..07ff19ae263f5 100644
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -412,11 +412,35 @@ static bool rt6_check_expired(const struct rt6_info *rt)
+       return false;
+ }
++static struct fib6_info *
++rt6_multipath_first_sibling_rcu(const struct fib6_info *rt)
++{
++      struct fib6_info *iter;
++      struct fib6_node *fn;
++
++      fn = rcu_dereference(rt->fib6_node);
++      if (!fn)
++              goto out;
++      iter = rcu_dereference(fn->leaf);
++      if (!iter)
++              goto out;
++
++      while (iter) {
++              if (iter->fib6_metric == rt->fib6_metric &&
++                  rt6_qualify_for_ecmp(iter))
++                      return iter;
++              iter = rcu_dereference(iter->fib6_next);
++      }
++
++out:
++      return NULL;
++}
++
+ void fib6_select_path(const struct net *net, struct fib6_result *res,
+                     struct flowi6 *fl6, int oif, bool have_oif_match,
+                     const struct sk_buff *skb, int strict)
+ {
+-      struct fib6_info *match = res->f6i;
++      struct fib6_info *first, *match = res->f6i;
+       struct fib6_info *sibling;
+       if (!match->nh && (!match->fib6_nsiblings || have_oif_match))
+@@ -440,10 +464,18 @@ void fib6_select_path(const struct net *net, struct fib6_result *res,
+               return;
+       }
+-      if (fl6->mp_hash <= atomic_read(&match->fib6_nh->fib_nh_upper_bound))
++      first = rt6_multipath_first_sibling_rcu(match);
++      if (!first)
+               goto out;
+-      list_for_each_entry_rcu(sibling, &match->fib6_siblings,
++      if (fl6->mp_hash <= atomic_read(&first->fib6_nh->fib_nh_upper_bound) &&
++          rt6_score_route(first->fib6_nh, first->fib6_flags, oif,
++                          strict) >= 0) {
++              match = first;
++              goto out;
++      }
++
++      list_for_each_entry_rcu(sibling, &first->fib6_siblings,
+                               fib6_siblings) {
+               const struct fib6_nh *nh = sibling->fib6_nh;
+               int nh_upper_bound;
+-- 
+2.39.5
+
diff --git a/queue-6.14/isofs-fix-kmsan-uninit-value-bug-in-do_isofs_readdir.patch b/queue-6.14/isofs-fix-kmsan-uninit-value-bug-in-do_isofs_readdir.patch
new file mode 100644 (file)
index 0000000..2069245
--- /dev/null
@@ -0,0 +1,89 @@
+From 913a6d2fac1e4b1bb1735149e19cc3886f724ae4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Feb 2025 19:59:00 +0000
+Subject: isofs: fix KMSAN uninit-value bug in do_isofs_readdir()
+
+From: Qasim Ijaz <qasdev00@gmail.com>
+
+[ Upstream commit 81a82e8f33880793029cd6f8a766fb13b737e6a7 ]
+
+In do_isofs_readdir() when assigning the variable
+"struct iso_directory_record *de" the b_data field of the buffer_head
+is accessed and an offset is added to it, the size of b_data is 2048
+and the offset size is 2047, meaning
+"de = (struct iso_directory_record *) (bh->b_data + offset);"
+yields the final byte of the 2048 sized b_data block.
+
+The first byte of the directory record (de_len) is then read and
+found to be 31, meaning the directory record size is 31 bytes long.
+The directory record is defined by the structure:
+
+       struct iso_directory_record {
+               __u8 length;                     // 1 byte
+               __u8 ext_attr_length;            // 1 byte
+               __u8 extent[8];                  // 8 bytes
+               __u8 size[8];                    // 8 bytes
+               __u8 date[7];                    // 7 bytes
+               __u8 flags;                      // 1 byte
+               __u8 file_unit_size;             // 1 byte
+               __u8 interleave;                 // 1 byte
+               __u8 volume_sequence_number[4];  // 4 bytes
+               __u8 name_len;                   // 1 byte
+               char name[];                     // variable size
+       } __attribute__((packed));
+
+The fixed portion of this structure occupies 33 bytes. Therefore, a
+valid directory record must be at least 33 bytes long
+(even without considering the variable-length name field).
+Since de_len is only 31, it is insufficient to contain
+the complete fixed header.
+
+The code later hits the following sanity check that
+compares de_len against the sum of de->name_len and
+sizeof(struct iso_directory_record):
+
+       if (de_len < de->name_len[0] + sizeof(struct iso_directory_record)) {
+               ...
+       }
+
+Since the fixed portion of the structure is
+33 bytes (up to and including name_len member),
+a valid record should have de_len of at least 33 bytes;
+here, however, de_len is too short, and the field de->name_len
+(located at offset 32) is accessed even though it lies beyond
+the available 31 bytes.
+
+This access on the corrupted isofs data triggers a KASAN uninitialized
+memory warning. The fix would be to first verify that de_len is at least
+sizeof(struct iso_directory_record) before accessing any
+fields like de->name_len.
+
+Reported-by: syzbot <syzbot+812641c6c3d7586a1613@syzkaller.appspotmail.com>
+Tested-by: syzbot <syzbot+812641c6c3d7586a1613@syzkaller.appspotmail.com>
+Closes: https://syzkaller.appspot.com/bug?extid=812641c6c3d7586a1613
+Fixes: 2deb1acc653c ("isofs: fix access to unallocated memory when reading corrupted filesystem")
+Signed-off-by: Qasim Ijaz <qasdev00@gmail.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Link: https://patch.msgid.link/20250211195900.42406-1-qasdev00@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/isofs/dir.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fs/isofs/dir.c b/fs/isofs/dir.c
+index eb2f8273e6f15..09df40b612fbf 100644
+--- a/fs/isofs/dir.c
++++ b/fs/isofs/dir.c
+@@ -147,7 +147,8 @@ static int do_isofs_readdir(struct inode *inode, struct file *file,
+                       de = tmpde;
+               }
+               /* Basic sanity check, whether name doesn't exceed dir entry */
+-              if (de_len < de->name_len[0] +
++              if (de_len < sizeof(struct iso_directory_record) ||
++                  de_len < de->name_len[0] +
+                                       sizeof(struct iso_directory_record)) {
+                       printk(KERN_NOTICE "iso9660: Corrupted directory entry"
+                              " in block %lu of inode %lu\n", block,
+-- 
+2.39.5
+
diff --git a/queue-6.14/ixgbe-fix-media-type-detection-for-e610-device.patch b/queue-6.14/ixgbe-fix-media-type-detection-for-e610-device.patch
new file mode 100644 (file)
index 0000000..04c976c
--- /dev/null
@@ -0,0 +1,58 @@
+From 10e0957a46558ad9d1aec4653095f54026fbbb13 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Feb 2025 16:49:17 +0100
+Subject: ixgbe: fix media type detection for E610 device
+
+From: Piotr Kwapulinski <piotr.kwapulinski@intel.com>
+
+[ Upstream commit 40206599beec98cfeb01913ee417f015e3f6190c ]
+
+The commit 23c0e5a16bcc ("ixgbe: Add link management support for E610
+device") introduced incorrect media type detection for E610 device. It
+reproduces when advertised speed is modified after driver reload. Clear
+the previous outdated PHY type high value.
+
+Reproduction steps:
+modprobe ixgbe
+ethtool -s eth0 advertise 0x1000000000000
+modprobe -r ixgbe
+modprobe ixgbe
+ethtool -s eth0 advertise 0x1000000000000
+Result before the fix:
+netlink error: link settings update failed
+netlink error: Invalid argument
+Result after the fix:
+No output error
+
+Fixes: 23c0e5a16bcc ("ixgbe: Add link management support for E610 device")
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Piotr Kwapulinski <piotr.kwapulinski@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Tested-by: Bharath R <bharath.r@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
+index cb07ecd8937d3..00935747c8c55 100644
+--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
+@@ -1453,9 +1453,11 @@ enum ixgbe_media_type ixgbe_get_media_type_e610(struct ixgbe_hw *hw)
+                       hw->link.link_info.phy_type_low = 0;
+               } else {
+                       highest_bit = fls64(le64_to_cpu(pcaps.phy_type_low));
+-                      if (highest_bit)
++                      if (highest_bit) {
+                               hw->link.link_info.phy_type_low =
+                                       BIT_ULL(highest_bit - 1);
++                              hw->link.link_info.phy_type_high = 0;
++                      }
+               }
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/jbd2-add-a-missing-data-flush-during-file-and-fs-syn.patch b/queue-6.14/jbd2-add-a-missing-data-flush-during-file-and-fs-syn.patch
new file mode 100644 (file)
index 0000000..7687444
--- /dev/null
@@ -0,0 +1,70 @@
+From b585990ec3d5f2f3574b9395b0525dd1e43ea78d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Dec 2024 19:13:27 +0800
+Subject: jbd2: add a missing data flush during file and fs synchronization
+
+From: Zhang Yi <yi.zhang@huawei.com>
+
+[ Upstream commit aac45075f6d79a63ac8dff93b3e1d7053a6ba628 ]
+
+When the filesystem performs file or filesystem synchronization (e.g.,
+ext4_sync_file()), it queries the journal to determine whether to flush
+the file device through jbd2_trans_will_send_data_barrier(). If the
+target transaction has not started committing, it assumes that the
+journal will submit the flush command, allowing the filesystem to bypass
+a redundant flush command. However, this assumption is not always valid.
+If the journal is not located on the filesystem device, the journal
+commit thread will not submit the flush command unless the variable
+->t_need_data_flush is set to 1. Consequently, the flush may be missed,
+and data may be lost following a power failure or system crash, even if
+the synchronization appears to succeed.
+
+Unfortunately, we cannot determine with certainty whether the target
+transaction will flush to the filesystem device before it commits.
+However, if it has not started committing, it must be the running
+transaction. Therefore, fix it by always set its t_need_data_flush to 1,
+ensuring that the committing thread will flush the filesystem device.
+
+Fixes: bbd2be369107 ("jbd2: Add function jbd2_trans_will_send_data_barrier()")
+Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://patch.msgid.link/20241206111327.4171337-1-yi.zhang@huaweicloud.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/jbd2/journal.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
+index 49a9e99cbc03d..a10e086a0165b 100644
+--- a/fs/jbd2/journal.c
++++ b/fs/jbd2/journal.c
+@@ -603,7 +603,7 @@ int jbd2_journal_start_commit(journal_t *journal, tid_t *ptid)
+ int jbd2_trans_will_send_data_barrier(journal_t *journal, tid_t tid)
+ {
+       int ret = 0;
+-      transaction_t *commit_trans;
++      transaction_t *commit_trans, *running_trans;
+       if (!(journal->j_flags & JBD2_BARRIER))
+               return 0;
+@@ -613,6 +613,16 @@ int jbd2_trans_will_send_data_barrier(journal_t *journal, tid_t tid)
+               goto out;
+       commit_trans = journal->j_committing_transaction;
+       if (!commit_trans || commit_trans->t_tid != tid) {
++              running_trans = journal->j_running_transaction;
++              /*
++               * The query transaction hasn't started committing,
++               * it must still be running.
++               */
++              if (WARN_ON_ONCE(!running_trans ||
++                               running_trans->t_tid != tid))
++                      goto out;
++
++              running_trans->t_need_data_flush = 1;
+               ret = 1;
+               goto out;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/jbd2-fix-off-by-one-while-erasing-journal.patch b/queue-6.14/jbd2-fix-off-by-one-while-erasing-journal.patch
new file mode 100644 (file)
index 0000000..d5401af
--- /dev/null
@@ -0,0 +1,85 @@
+From dc010836281f313cb42f5de07fe82aa458a168f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 14:59:55 +0800
+Subject: jbd2: fix off-by-one while erasing journal
+
+From: Zhang Yi <yi.zhang@huawei.com>
+
+[ Upstream commit 18aba2adb3e2a676fff0d81e51f5045f3c636666 ]
+
+In __jbd2_journal_erase(), the block_stop parameter includes the last
+block of a contiguous region; however, the calculation of byte_stop is
+incorrect, as it does not account for the bytes in that last block.
+Consequently, the page cache is not cleared properly, which occasionally
+causes the ext4/050 test to fail.
+
+Since block_stop operates on inclusion semantics, it involves repeated
+increments and decrements by 1, significantly increasing the complexity
+of the calculations. Optimize the calculation and fix the incorrect
+byte_stop by make both block_stop and byte_stop to use exclusion
+semantics.
+
+This fixes a failure in fstests ext4/050.
+
+Fixes: 01d5d96542fd ("ext4: add discard/zeroout flags to journal flush")
+Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
+Reviewed-by: Baokun Li <libaokun1@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://patch.msgid.link/20250217065955.3829229-1-yi.zhang@huaweicloud.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/jbd2/journal.c | 15 ++++++---------
+ 1 file changed, 6 insertions(+), 9 deletions(-)
+
+diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
+index d8084b31b3610..49a9e99cbc03d 100644
+--- a/fs/jbd2/journal.c
++++ b/fs/jbd2/journal.c
+@@ -1965,17 +1965,15 @@ static int __jbd2_journal_erase(journal_t *journal, unsigned int flags)
+                       return err;
+               }
+-              if (block_start == ~0ULL) {
+-                      block_start = phys_block;
+-                      block_stop = block_start - 1;
+-              }
++              if (block_start == ~0ULL)
++                      block_stop = block_start = phys_block;
+               /*
+                * last block not contiguous with current block,
+                * process last contiguous region and return to this block on
+                * next loop
+                */
+-              if (phys_block != block_stop + 1) {
++              if (phys_block != block_stop) {
+                       block--;
+               } else {
+                       block_stop++;
+@@ -1994,11 +1992,10 @@ static int __jbd2_journal_erase(journal_t *journal, unsigned int flags)
+                */
+               byte_start = block_start * journal->j_blocksize;
+               byte_stop = block_stop * journal->j_blocksize;
+-              byte_count = (block_stop - block_start + 1) *
+-                              journal->j_blocksize;
++              byte_count = (block_stop - block_start) * journal->j_blocksize;
+               truncate_inode_pages_range(journal->j_dev->bd_mapping,
+-                              byte_start, byte_stop);
++                              byte_start, byte_stop - 1);
+               if (flags & JBD2_JOURNAL_FLUSH_DISCARD) {
+                       err = blkdev_issue_discard(journal->j_dev,
+@@ -2013,7 +2010,7 @@ static int __jbd2_journal_erase(journal_t *journal, unsigned int flags)
+               }
+               if (unlikely(err != 0)) {
+-                      pr_err("JBD2: (error %d) unable to wipe journal at physical blocks %llu - %llu",
++                      pr_err("JBD2: (error %d) unable to wipe journal at physical blocks [%llu, %llu)",
+                                       err, block_start, block_stop);
+                       return err;
+               }
+-- 
+2.39.5
+
diff --git a/queue-6.14/jfs-add-check-read-only-before-truncation-in-jfs_tru.patch b/queue-6.14/jfs-add-check-read-only-before-truncation-in-jfs_tru.patch
new file mode 100644 (file)
index 0000000..d410fb9
--- /dev/null
@@ -0,0 +1,56 @@
+From 781262b3ddbed7e7d7396caf53b6aac65749a913 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Dec 2024 17:49:14 +0300
+Subject: jfs: add check read-only before truncation in jfs_truncate_nolock()
+
+From: Vasiliy Kovalev <kovalev@altlinux.org>
+
+[ Upstream commit b5799dd77054c1ec49b0088b006c9908e256843b ]
+
+Added a check for "read-only" mode in the `jfs_truncate_nolock`
+function to avoid errors related to writing to a read-only
+filesystem.
+
+Call stack:
+
+block_write_begin() {
+  jfs_write_failed() {
+    jfs_truncate() {
+      jfs_truncate_nolock() {
+        txEnd() {
+          ...
+          log = JFS_SBI(tblk->sb)->log;
+          // (log == NULL)
+
+If the `isReadOnly(ip)` condition is triggered in
+`jfs_truncate_nolock`, the function execution will stop, and no
+further data modification will occur. Instead, the `xtTruncate`
+function will be called with the "COMMIT_WMAP" flag, preventing
+modifications in "read-only" mode.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+4e89b5368baba8324e07@syzkaller.appspotmail.com
+Link: https://syzkaller.appspot.com/bug?extid=4e89b5368baba8324e07
+Signed-off-by: Vasiliy Kovalev <kovalev@altlinux.org>
+Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/jfs/inode.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
+index 07cfdc4405968..60fc92dee24d2 100644
+--- a/fs/jfs/inode.c
++++ b/fs/jfs/inode.c
+@@ -369,7 +369,7 @@ void jfs_truncate_nolock(struct inode *ip, loff_t length)
+       ASSERT(length >= 0);
+-      if (test_cflag(COMMIT_Nolink, ip)) {
++      if (test_cflag(COMMIT_Nolink, ip) || isReadOnly(ip)) {
+               xtTruncate(0, ip, length, COMMIT_WMAP);
+               return;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/jfs-add-check-read-only-before-txbeginanon-call.patch b/queue-6.14/jfs-add-check-read-only-before-txbeginanon-call.patch
new file mode 100644 (file)
index 0000000..f71eb25
--- /dev/null
@@ -0,0 +1,63 @@
+From 81a70debc4e4a6cf2b53592d64919c07b5563061 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Dec 2024 17:49:13 +0300
+Subject: jfs: add check read-only before txBeginAnon() call
+
+From: Vasiliy Kovalev <kovalev@altlinux.org>
+
+[ Upstream commit 0176e69743ecc02961f2ae1ea42439cd2bf9ed58 ]
+
+Added a read-only check before calling `txBeginAnon` in `extAlloc`
+and `extRecord`. This prevents modification attempts on a read-only
+mounted filesystem, avoiding potential errors or crashes.
+
+Call trace:
+ txBeginAnon+0xac/0x154
+ extAlloc+0xe8/0xdec fs/jfs/jfs_extent.c:78
+ jfs_get_block+0x340/0xb98 fs/jfs/inode.c:248
+ __block_write_begin_int+0x580/0x166c fs/buffer.c:2128
+ __block_write_begin fs/buffer.c:2177 [inline]
+ block_write_begin+0x98/0x11c fs/buffer.c:2236
+ jfs_write_begin+0x44/0x88 fs/jfs/inode.c:299
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+4e89b5368baba8324e07@syzkaller.appspotmail.com
+Link: https://syzkaller.appspot.com/bug?extid=4e89b5368baba8324e07
+Signed-off-by: Vasiliy Kovalev <kovalev@altlinux.org>
+Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/jfs/jfs_extent.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/fs/jfs/jfs_extent.c b/fs/jfs/jfs_extent.c
+index 63d21822d309b..46529bcc8297e 100644
+--- a/fs/jfs/jfs_extent.c
++++ b/fs/jfs/jfs_extent.c
+@@ -74,6 +74,11 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, bool abnr)
+       int rc;
+       int xflag;
++      if (isReadOnly(ip)) {
++              jfs_error(ip->i_sb, "read-only filesystem\n");
++              return -EIO;
++      }
++
+       /* This blocks if we are low on resources */
+       txBeginAnon(ip->i_sb);
+@@ -253,6 +258,11 @@ int extRecord(struct inode *ip, xad_t * xp)
+ {
+       int rc;
++      if (isReadOnly(ip)) {
++              jfs_error(ip->i_sb, "read-only filesystem\n");
++              return -EIO;
++      }
++
+       txBeginAnon(ip->i_sb);
+       mutex_lock(&JFS_IP(ip)->commit_mutex);
+-- 
+2.39.5
+
diff --git a/queue-6.14/jfs-reject-on-disk-inodes-of-an-unsupported-type.patch b/queue-6.14/jfs-reject-on-disk-inodes-of-an-unsupported-type.patch
new file mode 100644 (file)
index 0000000..b4ac285
--- /dev/null
@@ -0,0 +1,116 @@
+From 47c44050d29a3a2e5749b9e17d1b9c4736d6ce89 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Nov 2024 08:42:28 +0300
+Subject: jfs: reject on-disk inodes of an unsupported type
+
+From: Dmitry Antipov <dmantipov@yandex.ru>
+
+[ Upstream commit 8c3f9a70d2d4dd6c640afe294b05c6a0a45434d9 ]
+
+Syzbot has reported the following BUG:
+
+kernel BUG at fs/inode.c:668!
+Oops: invalid opcode: 0000 [#1] PREEMPT SMP KASAN PTI
+CPU: 3 UID: 0 PID: 139 Comm: jfsCommit Not tainted 6.12.0-rc4-syzkaller-00085-g4e46774408d9 #0
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-3.fc41 04/01/2014
+RIP: 0010:clear_inode+0x168/0x190
+Code: 4c 89 f7 e8 ba fe e5 ff e9 61 ff ff ff 44 89 f1 80 e1 07 80 c1 03 38 c1 7c c1 4c 89 f7 e8 90 ff e5 ff eb b7
+ 0b e8 01 5d 7f ff 90 0f 0b e8 f9 5c 7f ff 90 0f 0b e8 f1 5c 7f
+RSP: 0018:ffffc900027dfae8 EFLAGS: 00010093
+RAX: ffffffff82157a87 RBX: 0000000000000001 RCX: ffff888104d4b980
+RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000000
+RBP: ffffc900027dfc90 R08: ffffffff82157977 R09: fffff520004fbf38
+R10: dffffc0000000000 R11: fffff520004fbf38 R12: dffffc0000000000
+R13: ffff88811315bc00 R14: ffff88811315bda8 R15: ffff88811315bb80
+FS:  0000000000000000(0000) GS:ffff888135f00000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00005565222e0578 CR3: 0000000026ef0000 CR4: 00000000000006f0
+Call Trace:
+ <TASK>
+ ? __die_body+0x5f/0xb0
+ ? die+0x9e/0xc0
+ ? do_trap+0x15a/0x3a0
+ ? clear_inode+0x168/0x190
+ ? do_error_trap+0x1dc/0x2c0
+ ? clear_inode+0x168/0x190
+ ? __pfx_do_error_trap+0x10/0x10
+ ? report_bug+0x3cd/0x500
+ ? handle_invalid_op+0x34/0x40
+ ? clear_inode+0x168/0x190
+ ? exc_invalid_op+0x38/0x50
+ ? asm_exc_invalid_op+0x1a/0x20
+ ? clear_inode+0x57/0x190
+ ? clear_inode+0x167/0x190
+ ? clear_inode+0x168/0x190
+ ? clear_inode+0x167/0x190
+ jfs_evict_inode+0xb5/0x440
+ ? __pfx_jfs_evict_inode+0x10/0x10
+ evict+0x4ea/0x9b0
+ ? __pfx_evict+0x10/0x10
+ ? iput+0x713/0xa50
+ txUpdateMap+0x931/0xb10
+ ? __pfx_txUpdateMap+0x10/0x10
+ jfs_lazycommit+0x49a/0xb80
+ ? _raw_spin_unlock_irqrestore+0x8f/0x140
+ ? lockdep_hardirqs_on+0x99/0x150
+ ? __pfx_jfs_lazycommit+0x10/0x10
+ ? __pfx_default_wake_function+0x10/0x10
+ ? __kthread_parkme+0x169/0x1d0
+ ? __pfx_jfs_lazycommit+0x10/0x10
+ kthread+0x2f2/0x390
+ ? __pfx_jfs_lazycommit+0x10/0x10
+ ? __pfx_kthread+0x10/0x10
+ ret_from_fork+0x4d/0x80
+ ? __pfx_kthread+0x10/0x10
+ ret_from_fork_asm+0x1a/0x30
+ </TASK>
+
+This happens when 'clear_inode()' makes an attempt to finalize an underlying
+JFS inode of unknown type. According to JFS layout description from
+https://jfs.sourceforge.net/project/pub/jfslayout.pdf, inode types from 5 to
+15 are reserved for future extensions and should not be encountered on a valid
+filesystem. So add an extra check for valid inode type in 'copy_from_dinode()'.
+
+Reported-by: syzbot+ac2116e48989e84a2893@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=ac2116e48989e84a2893
+Fixes: 79ac5a46c5c1 ("jfs_lookup(): don't bother with . or ..")
+Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
+Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/jfs/jfs_imap.c | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c
+index a360b24ed320c..debfc1389cb3e 100644
+--- a/fs/jfs/jfs_imap.c
++++ b/fs/jfs/jfs_imap.c
+@@ -3029,14 +3029,23 @@ static void duplicateIXtree(struct super_block *sb, s64 blkno,
+  *
+  * RETURN VALUES:
+  *    0       - success
+- *    -ENOMEM - insufficient memory
++ *    -EINVAL - unexpected inode type
+  */
+ static int copy_from_dinode(struct dinode * dip, struct inode *ip)
+ {
+       struct jfs_inode_info *jfs_ip = JFS_IP(ip);
+       struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
++      int fileset = le32_to_cpu(dip->di_fileset);
++
++      switch (fileset) {
++      case AGGR_RESERVED_I: case AGGREGATE_I: case BMAP_I:
++      case LOG_I: case BADBLOCK_I: case FILESYSTEM_I:
++              break;
++      default:
++              return -EINVAL;
++      }
+-      jfs_ip->fileset = le32_to_cpu(dip->di_fileset);
++      jfs_ip->fileset = fileset;
+       jfs_ip->mode2 = le32_to_cpu(dip->di_mode);
+       jfs_set_inode_flags(ip);
+-- 
+2.39.5
+
diff --git a/queue-6.14/kernel-events-uprobes-handle-device-exclusive-entrie.patch b/queue-6.14/kernel-events-uprobes-handle-device-exclusive-entrie.patch
new file mode 100644 (file)
index 0000000..79cc112
--- /dev/null
@@ -0,0 +1,99 @@
+From 4d40a4739778621c30e7e11a265cefe1cfe46fd9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Feb 2025 20:37:50 +0100
+Subject: kernel/events/uprobes: handle device-exclusive entries correctly in
+ __replace_page()
+
+From: David Hildenbrand <david@redhat.com>
+
+[ Upstream commit 096cbb80ab3fd85a9035ec17a1312c2a7db8bc8c ]
+
+Ever since commit b756a3b5e7ea ("mm: device exclusive memory access") we
+can return with a device-exclusive entry from page_vma_mapped_walk().
+
+__replace_page() is not prepared for that, so teach it about these PFN
+swap PTEs.  Note that device-private entries are so far not applicable on
+that path, because GUP would never have returned such folios (conversion
+to device-private happens by page migration, not in-place conversion of
+the PTE).
+
+There is a race between GUP and us locking the folio to look it up using
+page_vma_mapped_walk(), so this is likely a fix (unless something else
+could prevent that race, but it doesn't look like).  pte_pfn() on
+something that is not a present pte could give use garbage, and we'd
+wrongly mess up the mapcount because it was already adjusted by calling
+folio_remove_rmap_pte() when making the entry device-exclusive.
+
+Link: https://lkml.kernel.org/r/20250210193801.781278-9-david@redhat.com
+Fixes: b756a3b5e7ea ("mm: device exclusive memory access")
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Tested-by: Alistair Popple <apopple@nvidia.com>
+Cc: Alex Shi <alexs@kernel.org>
+Cc: Danilo Krummrich <dakr@kernel.org>
+Cc: Dave Airlie <airlied@gmail.com>
+Cc: Jann Horn <jannh@google.com>
+Cc: Jason Gunthorpe <jgg@nvidia.com>
+Cc: Jerome Glisse <jglisse@redhat.com>
+Cc: John Hubbard <jhubbard@nvidia.com>
+Cc: Jonathan Corbet <corbet@lwn.net>
+Cc: Karol Herbst <kherbst@redhat.com>
+Cc: Liam Howlett <liam.howlett@oracle.com>
+Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
+Cc: Lyude <lyude@redhat.com>
+Cc: "Masami Hiramatsu (Google)" <mhiramat@kernel.org>
+Cc: Oleg Nesterov <oleg@redhat.com>
+Cc: Pasha Tatashin <pasha.tatashin@soleen.com>
+Cc: Peter Xu <peterx@redhat.com>
+Cc: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: SeongJae Park <sj@kernel.org>
+Cc: Simona Vetter <simona.vetter@ffwll.ch>
+Cc: Vlastimil Babka <vbabka@suse.cz>
+Cc: Yanteng Si <si.yanteng@linux.dev>
+Cc: Barry Song <v-songbaohua@oppo.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/events/uprobes.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
+index b4ca8898fe178..eac24f39c2c2d 100644
+--- a/kernel/events/uprobes.c
++++ b/kernel/events/uprobes.c
+@@ -173,6 +173,7 @@ static int __replace_page(struct vm_area_struct *vma, unsigned long addr,
+       DEFINE_FOLIO_VMA_WALK(pvmw, old_folio, vma, addr, 0);
+       int err;
+       struct mmu_notifier_range range;
++      pte_t pte;
+       mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, mm, addr,
+                               addr + PAGE_SIZE);
+@@ -192,6 +193,16 @@ static int __replace_page(struct vm_area_struct *vma, unsigned long addr,
+       if (!page_vma_mapped_walk(&pvmw))
+               goto unlock;
+       VM_BUG_ON_PAGE(addr != pvmw.address, old_page);
++      pte = ptep_get(pvmw.pte);
++
++      /*
++       * Handle PFN swap PTES, such as device-exclusive ones, that actually
++       * map pages: simply trigger GUP again to fix it up.
++       */
++      if (unlikely(!pte_present(pte))) {
++              page_vma_mapped_walk_done(&pvmw);
++              goto unlock;
++      }
+       if (new_page) {
+               folio_get(new_folio);
+@@ -206,7 +217,7 @@ static int __replace_page(struct vm_area_struct *vma, unsigned long addr,
+               inc_mm_counter(mm, MM_ANONPAGES);
+       }
+-      flush_cache_page(vma, addr, pte_pfn(ptep_get(pvmw.pte)));
++      flush_cache_page(vma, addr, pte_pfn(pte));
+       ptep_clear_flush(vma, addr, pvmw.pte);
+       if (new_page)
+               set_pte_at(mm, addr, pvmw.pte,
+-- 
+2.39.5
+
diff --git a/queue-6.14/kexec-initialize-elf-lowest-address-to-ulong_max.patch b/queue-6.14/kexec-initialize-elf-lowest-address-to-ulong_max.patch
new file mode 100644 (file)
index 0000000..d22592e
--- /dev/null
@@ -0,0 +1,71 @@
+From fc826c964f336f33b21f8c445c7ecf453bf6a9f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Jan 2025 17:08:24 +0530
+Subject: kexec: initialize ELF lowest address to ULONG_MAX
+
+From: Sourabh Jain <sourabhjain@linux.ibm.com>
+
+[ Upstream commit 9986fb5164c8b21f6439cfd45ba36d8cc80c9710 ]
+
+Patch series "powerpc/crash: use generic crashkernel reservation", v3.
+
+Commit 0ab97169aa05 ("crash_core: add generic function to do reservation")
+added a generic function to reserve crashkernel memory.  So let's use the
+same function on powerpc and remove the architecture-specific code that
+essentially does the same thing.
+
+The generic crashkernel reservation also provides a way to split the
+crashkernel reservation into high and low memory reservations, which can
+be enabled for powerpc in the future.
+
+Additionally move powerpc to use generic APIs to locate memory hole for
+kexec segments while loading kdump kernel.
+
+This patch (of 7):
+
+kexec_elf_load() loads an ELF executable and sets the address of the
+lowest PT_LOAD section to the address held by the lowest_load_addr
+function argument.
+
+To determine the lowest PT_LOAD address, a local variable lowest_addr
+(type unsigned long) is initialized to UINT_MAX.  After loading each
+PT_LOAD, its address is compared to lowest_addr.  If a loaded PT_LOAD
+address is lower, lowest_addr is updated.  However, setting lowest_addr to
+UINT_MAX won't work when the kernel image is loaded above 4G, as the
+returned lowest PT_LOAD address would be invalid.  This is resolved by
+initializing lowest_addr to ULONG_MAX instead.
+
+This issue was discovered while implementing crashkernel high/low
+reservation on the PowerPC architecture.
+
+Link: https://lkml.kernel.org/r/20250131113830.925179-1-sourabhjain@linux.ibm.com
+Link: https://lkml.kernel.org/r/20250131113830.925179-2-sourabhjain@linux.ibm.com
+Fixes: a0458284f062 ("powerpc: Add support code for kexec_file_load()")
+Signed-off-by: Sourabh Jain <sourabhjain@linux.ibm.com>
+Acked-by: Hari Bathini <hbathini@linux.ibm.com>
+Acked-by: Baoquan He <bhe@redhat.com>
+Cc: Madhavan Srinivasan <maddy@linux.ibm.com>
+Cc: Mahesh Salgaonkar <mahesh@linux.ibm.com>
+Cc: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/kexec_elf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/kexec_elf.c b/kernel/kexec_elf.c
+index d3689632e8b90..3a5c25b2adc94 100644
+--- a/kernel/kexec_elf.c
++++ b/kernel/kexec_elf.c
+@@ -390,7 +390,7 @@ int kexec_elf_load(struct kimage *image, struct elfhdr *ehdr,
+                        struct kexec_buf *kbuf,
+                        unsigned long *lowest_load_addr)
+ {
+-      unsigned long lowest_addr = UINT_MAX;
++      unsigned long lowest_addr = ULONG_MAX;
+       int ret;
+       size_t i;
+-- 
+2.39.5
+
diff --git a/queue-6.14/ksmbd-fix-multichannel-connection-failure.patch b/queue-6.14/ksmbd-fix-multichannel-connection-failure.patch
new file mode 100644 (file)
index 0000000..4a62e64
--- /dev/null
@@ -0,0 +1,127 @@
+From 503a2bb079be46e3e1931eedc0bb6036eae60c67 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Mar 2025 20:19:20 +0900
+Subject: ksmbd: fix multichannel connection failure
+
+From: Namjae Jeon <linkinjeon@kernel.org>
+
+[ Upstream commit c1883049aa9b2b7dffd3a68c5fc67fa92c174bd9 ]
+
+ksmbd check that the session of second channel is in the session list of
+first connection. If it is in session list, multichannel connection
+should not be allowed.
+
+Fixes: b95629435b84 ("ksmbd: fix racy issue from session lookup and expire")
+Reported-by: Sean Heelan <seanheelan@gmail.com>
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/server/mgmt/user_session.c | 16 ++++++++++++++++
+ fs/smb/server/mgmt/user_session.h |  2 ++
+ fs/smb/server/smb2pdu.c           | 12 ++++--------
+ 3 files changed, 22 insertions(+), 8 deletions(-)
+
+diff --git a/fs/smb/server/mgmt/user_session.c b/fs/smb/server/mgmt/user_session.c
+index 71c6939dfbf13..e5c835c8822ca 100644
+--- a/fs/smb/server/mgmt/user_session.c
++++ b/fs/smb/server/mgmt/user_session.c
+@@ -256,6 +256,22 @@ void ksmbd_sessions_deregister(struct ksmbd_conn *conn)
+       up_write(&sessions_table_lock);
+ }
++bool is_ksmbd_session_in_connection(struct ksmbd_conn *conn,
++                                 unsigned long long id)
++{
++      struct ksmbd_session *sess;
++
++      down_read(&conn->session_lock);
++      sess = xa_load(&conn->sessions, id);
++      if (sess) {
++              up_read(&conn->session_lock);
++              return true;
++      }
++      up_read(&conn->session_lock);
++
++      return false;
++}
++
+ struct ksmbd_session *ksmbd_session_lookup(struct ksmbd_conn *conn,
+                                          unsigned long long id)
+ {
+diff --git a/fs/smb/server/mgmt/user_session.h b/fs/smb/server/mgmt/user_session.h
+index c1c4b20bd5c6c..f21348381d598 100644
+--- a/fs/smb/server/mgmt/user_session.h
++++ b/fs/smb/server/mgmt/user_session.h
+@@ -87,6 +87,8 @@ void ksmbd_session_destroy(struct ksmbd_session *sess);
+ struct ksmbd_session *ksmbd_session_lookup_slowpath(unsigned long long id);
+ struct ksmbd_session *ksmbd_session_lookup(struct ksmbd_conn *conn,
+                                          unsigned long long id);
++bool is_ksmbd_session_in_connection(struct ksmbd_conn *conn,
++                                   unsigned long long id);
+ int ksmbd_session_register(struct ksmbd_conn *conn,
+                          struct ksmbd_session *sess);
+ void ksmbd_sessions_deregister(struct ksmbd_conn *conn);
+diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
+index c53121538990e..ad4754339fa03 100644
+--- a/fs/smb/server/smb2pdu.c
++++ b/fs/smb/server/smb2pdu.c
+@@ -1707,44 +1707,38 @@ int smb2_sess_setup(struct ksmbd_work *work)
+               if (conn->dialect != sess->dialect) {
+                       rc = -EINVAL;
+-                      ksmbd_user_session_put(sess);
+                       goto out_err;
+               }
+               if (!(req->hdr.Flags & SMB2_FLAGS_SIGNED)) {
+                       rc = -EINVAL;
+-                      ksmbd_user_session_put(sess);
+                       goto out_err;
+               }
+               if (strncmp(conn->ClientGUID, sess->ClientGUID,
+                           SMB2_CLIENT_GUID_SIZE)) {
+                       rc = -ENOENT;
+-                      ksmbd_user_session_put(sess);
+                       goto out_err;
+               }
+               if (sess->state == SMB2_SESSION_IN_PROGRESS) {
+                       rc = -EACCES;
+-                      ksmbd_user_session_put(sess);
+                       goto out_err;
+               }
+               if (sess->state == SMB2_SESSION_EXPIRED) {
+                       rc = -EFAULT;
+-                      ksmbd_user_session_put(sess);
+                       goto out_err;
+               }
+-              ksmbd_user_session_put(sess);
+               if (ksmbd_conn_need_reconnect(conn)) {
+                       rc = -EFAULT;
++                      ksmbd_user_session_put(sess);
+                       sess = NULL;
+                       goto out_err;
+               }
+-              sess = ksmbd_session_lookup(conn, sess_id);
+-              if (!sess) {
++              if (is_ksmbd_session_in_connection(conn, sess_id)) {
+                       rc = -EACCES;
+                       goto out_err;
+               }
+@@ -1910,6 +1904,8 @@ int smb2_sess_setup(struct ksmbd_work *work)
+                       sess->last_active = jiffies;
+                       sess->state = SMB2_SESSION_EXPIRED;
++                      ksmbd_user_session_put(sess);
++                      work->sess = NULL;
+                       if (try_delay) {
+                               ksmbd_conn_set_need_reconnect(conn);
+                               ssleep(5);
+-- 
+2.39.5
+
diff --git a/queue-6.14/ksmbd-fix-r_count-dec-increment-mismatch.patch b/queue-6.14/ksmbd-fix-r_count-dec-increment-mismatch.patch
new file mode 100644 (file)
index 0000000..5ded012
--- /dev/null
@@ -0,0 +1,51 @@
+From a934c47e73eb6c32bc578bafd65fb1cbbf9b5c3d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Mar 2025 00:00:24 +0900
+Subject: ksmbd: fix r_count dec/increment mismatch
+
+From: Namjae Jeon <linkinjeon@kernel.org>
+
+[ Upstream commit ddb7ea36ba7129c2ed107e2186591128618864e1 ]
+
+r_count is only increased when there is an oplock break wait,
+so r_count inc/decrement are not paired. This can cause r_count
+to become negative, which can lead to a problem where the ksmbd
+thread does not terminate.
+
+Fixes: 3aa660c05924 ("ksmbd: prevent connection release during oplock break notification")
+Reported-by: Norbert Szetei <norbert@doyensec.com>
+Tested-by: Norbert Szetei <norbert@doyensec.com>
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/server/oplock.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/fs/smb/server/oplock.c b/fs/smb/server/oplock.c
+index 28886ff1ee577..8e6d226dc4e0a 100644
+--- a/fs/smb/server/oplock.c
++++ b/fs/smb/server/oplock.c
+@@ -724,8 +724,8 @@ static int smb2_oplock_break_noti(struct oplock_info *opinfo)
+       work->conn = conn;
+       work->sess = opinfo->sess;
++      ksmbd_conn_r_count_inc(conn);
+       if (opinfo->op_state == OPLOCK_ACK_WAIT) {
+-              ksmbd_conn_r_count_inc(conn);
+               INIT_WORK(&work->work, __smb2_oplock_break_noti);
+               ksmbd_queue_work(work);
+@@ -833,8 +833,8 @@ static int smb2_lease_break_noti(struct oplock_info *opinfo)
+       work->conn = conn;
+       work->sess = opinfo->sess;
++      ksmbd_conn_r_count_inc(conn);
+       if (opinfo->op_state == OPLOCK_ACK_WAIT) {
+-              ksmbd_conn_r_count_inc(conn);
+               INIT_WORK(&work->work, __smb2_lease_break_noti);
+               ksmbd_queue_work(work);
+               wait_for_break_ack(opinfo);
+-- 
+2.39.5
+
diff --git a/queue-6.14/ksmbd-use-aead_request_free-to-match-aead_request_al.patch b/queue-6.14/ksmbd-use-aead_request_free-to-match-aead_request_al.patch
new file mode 100644 (file)
index 0000000..8bd21cb
--- /dev/null
@@ -0,0 +1,38 @@
+From a62acf0706e11ef5b7b8507e346ddd7439e13db8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Mar 2025 20:12:34 +0800
+Subject: ksmbd: use aead_request_free to match aead_request_alloc
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 6171063e9d046ffa46f51579b2ca4a43caef581a ]
+
+Use aead_request_free() instead of kfree() to properly free memory
+allocated by aead_request_alloc(). This ensures sensitive crypto data
+is zeroed before being freed.
+
+Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Acked-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/server/auth.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/smb/server/auth.c b/fs/smb/server/auth.c
+index 2a5b4a96bf993..00b31cf864627 100644
+--- a/fs/smb/server/auth.c
++++ b/fs/smb/server/auth.c
+@@ -1218,7 +1218,7 @@ int ksmbd_crypt_message(struct ksmbd_work *work, struct kvec *iov,
+ free_sg:
+       kfree(sg);
+ free_req:
+-      kfree(req);
++      aead_request_free(req);
+ free_ctx:
+       ksmbd_release_crypto_ctx(ctx);
+       return rc;
+-- 
+2.39.5
+
diff --git a/queue-6.14/kunit-stackinit-use-fill-byte-different-from-clang-i.patch b/queue-6.14/kunit-stackinit-use-fill-byte-different-from-clang-i.patch
new file mode 100644 (file)
index 0000000..9fb253f
--- /dev/null
@@ -0,0 +1,124 @@
+From 33edcc0de149657c2a1e244df967f7f0be8b3068 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Mar 2025 14:56:11 -0800
+Subject: kunit/stackinit: Use fill byte different from Clang i386 pattern
+
+From: Kees Cook <kees@kernel.org>
+
+[ Upstream commit d985e4399adffb58e10b38dbb5479ef29d53cde6 ]
+
+The byte initialization values used with -ftrivial-auto-var-init=pattern
+(CONFIG_INIT_STACK_ALL_PATTERN=y) depends on the compiler, architecture,
+and byte position relative to struct member types. On i386 with Clang,
+this includes the 0xFF value, which means it looks like nothing changes
+between the leaf byte filling pass and the expected "stack wiping"
+pass of the stackinit test.
+
+Use the byte fill value of 0x99 instead, fixing the test for i386 Clang
+builds.
+
+Reported-by: ernsteiswuerfel
+Closes: https://github.com/ClangBuiltLinux/linux/issues/2071
+Fixes: 8c30d32b1a32 ("lib/test_stackinit: Handle Clang auto-initialization pattern")
+Tested-by: Nathan Chancellor <nathan@kernel.org>
+Link: https://lore.kernel.org/r/20250304225606.work.030-kees@kernel.org
+Signed-off-by: Kees Cook <kees@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/stackinit_kunit.c | 30 ++++++++++++++++++++----------
+ 1 file changed, 20 insertions(+), 10 deletions(-)
+
+diff --git a/lib/stackinit_kunit.c b/lib/stackinit_kunit.c
+index 135322592faf8..63aa78e6f5c1a 100644
+--- a/lib/stackinit_kunit.c
++++ b/lib/stackinit_kunit.c
+@@ -184,6 +184,15 @@ static bool stackinit_range_contains(char *haystack_start, size_t haystack_size,
+ #define INIT_UNION_assigned_copy(var_type)            \
+       INIT_STRUCT_assigned_copy(var_type)
++/*
++ * The "did we actually fill the stack?" check value needs
++ * to be neither 0 nor any of the "pattern" bytes. The
++ * pattern bytes are compiler, architecture, and type based,
++ * so we have to pick a value that never appears for those
++ * combinations. Use 0x99 which is not 0xFF, 0xFE, nor 0xAA.
++ */
++#define FILL_BYTE     0x99
++
+ /*
+  * @name: unique string name for the test
+  * @var_type: type to be tested for zeroing initialization
+@@ -206,12 +215,12 @@ static noinline void test_ ## name (struct kunit *test)          \
+       ZERO_CLONE_ ## which(zero);                             \
+       /* Clear entire check buffer for 0xFF overlap test. */  \
+       memset(check_buf, 0x00, sizeof(check_buf));             \
+-      /* Fill stack with 0xFF. */                             \
++      /* Fill stack with FILL_BYTE. */                        \
+       ignored = leaf_ ##name((unsigned long)&ignored, 1,      \
+                               FETCH_ARG_ ## which(zero));     \
+-      /* Verify all bytes overwritten with 0xFF. */           \
++      /* Verify all bytes overwritten with FILL_BYTE. */      \
+       for (sum = 0, i = 0; i < target_size; i++)              \
+-              sum += (check_buf[i] != 0xFF);                  \
++              sum += (check_buf[i] != FILL_BYTE);             \
+       /* Clear entire check buffer for later bit tests. */    \
+       memset(check_buf, 0x00, sizeof(check_buf));             \
+       /* Extract stack-defined variable contents. */          \
+@@ -222,7 +231,8 @@ static noinline void test_ ## name (struct kunit *test)            \
+        * possible between the two leaf function calls.        \
+        */                                                     \
+       KUNIT_ASSERT_EQ_MSG(test, sum, 0,                       \
+-                          "leaf fill was not 0xFF!?\n");      \
++                          "leaf fill was not 0x%02X!?\n",     \
++                          FILL_BYTE);                         \
+                                                               \
+       /* Validate that compiler lined up fill and target. */  \
+       KUNIT_ASSERT_TRUE_MSG(test,                             \
+@@ -234,9 +244,9 @@ static noinline void test_ ## name (struct kunit *test)            \
+               (int)((ssize_t)(uintptr_t)fill_start -          \
+                     (ssize_t)(uintptr_t)target_start));       \
+                                                               \
+-      /* Look for any bytes still 0xFF in check region. */    \
++      /* Validate check region has no FILL_BYTE bytes. */     \
+       for (sum = 0, i = 0; i < target_size; i++)              \
+-              sum += (check_buf[i] == 0xFF);                  \
++              sum += (check_buf[i] == FILL_BYTE);             \
+                                                               \
+       if (sum != 0 && xfail)                                  \
+               kunit_skip(test,                                \
+@@ -271,12 +281,12 @@ static noinline int leaf_ ## name(unsigned long sp, bool fill,   \
+        * stack frame of SOME kind...                          \
+        */                                                     \
+       memset(buf, (char)(sp & 0xff), sizeof(buf));            \
+-      /* Fill variable with 0xFF. */                          \
++      /* Fill variable with FILL_BYTE. */                     \
+       if (fill) {                                             \
+               fill_start = &var;                              \
+               fill_size = sizeof(var);                        \
+               memset(fill_start,                              \
+-                     (char)((sp & 0xff) | forced_mask),       \
++                     FILL_BYTE & forced_mask,                 \
+                      fill_size);                              \
+       }                                                       \
+                                                               \
+@@ -469,7 +479,7 @@ static int noinline __leaf_switch_none(int path, bool fill)
+                       fill_start = &var;
+                       fill_size = sizeof(var);
+-                      memset(fill_start, forced_mask | 0x55, fill_size);
++                      memset(fill_start, (forced_mask | 0x55) & FILL_BYTE, fill_size);
+               }
+               memcpy(check_buf, target_start, target_size);
+               break;
+@@ -480,7 +490,7 @@ static int noinline __leaf_switch_none(int path, bool fill)
+                       fill_start = &var;
+                       fill_size = sizeof(var);
+-                      memset(fill_start, forced_mask | 0xaa, fill_size);
++                      memset(fill_start, (forced_mask | 0xaa) & FILL_BYTE, fill_size);
+               }
+               memcpy(check_buf, target_start, target_size);
+               break;
+-- 
+2.39.5
+
diff --git a/queue-6.14/leds-fix-led_off-brightness-race.patch b/queue-6.14/leds-fix-led_off-brightness-race.patch
new file mode 100644 (file)
index 0000000..44c4e50
--- /dev/null
@@ -0,0 +1,108 @@
+From 82c4e71541d27ea35614de9fb1ffda28d14c5cfc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Feb 2025 12:23:17 +0100
+Subject: leds: Fix LED_OFF brightness race
+
+From: Remi Pommarel <repk@triplefau.lt>
+
+[ Upstream commit 2c70953b6f535f7698ccbf22c1f5ba26cb6c2816 ]
+
+While commit fa15d8c69238 ("leds: Fix set_brightness_delayed() race")
+successfully forces led_set_brightness() to be called with LED_OFF at
+least once when switching from blinking to LED on state so that
+hw-blinking can be disabled, another race remains. Indeed in
+led_set_brightness(LED_OFF) followed by led_set_brightness(any)
+scenario the following CPU scheduling can happen:
+
+    CPU0                                     CPU1
+    ----                                     ----
+ set_brightness_delayed() {
+   test_and_clear_bit(BRIGHTNESS_OFF)
+                                         led_set_brightness(LED_OFF) {
+                                           set_bit(BRIGHTNESS_OFF)
+                                          queue_work()
+                                         }
+                                         led_set_brightness(any) {
+                                           set_bit(BRIGHTNESS)
+                                          queue_work() //already queued
+                                         }
+   test_and_clear_bit(BRIGHTNESS)
+     /* LED set with brightness any */
+ }
+
+ /* From previous CPU1 queue_work() */
+ set_brightness_delayed() {
+   test_and_clear_bit(BRIGHTNESS_OFF)
+     /* LED turned off */
+   test_and_clear_bit(BRIGHTNESS)
+     /* Clear from previous run, LED remains off */
+
+In that case the led_set_brightness(LED_OFF)/led_set_brightness(any)
+sequence will be effectively executed in reverse order and LED will
+remain off.
+
+With the introduction of commit 32360bf6a5d4 ("leds: Introduce ordered
+workqueue for LEDs events instead of system_wq") the race is easier to
+trigger as sysfs brightness configuration does not wait for
+set_brightness_delayed() work to finish (flush_work() removal).
+
+Use delayed_set_value to optionnally re-configure brightness after a
+LED_OFF. That way a LED state could be configured more that once but
+final state will always be as expected. Ensure that delayed_set_value
+modification is seen before set_bit() using smp_mb__before_atomic().
+
+Fixes: fa15d8c69238 ("leds: Fix set_brightness_delayed() race")
+Signed-off-by: Remi Pommarel <repk@triplefau.lt>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/19c81177059dab7b656c42063958011a8e4d1a66.1740050412.git.repk@triplefau.lt
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/leds/led-core.c | 22 ++++++++++++++++++----
+ 1 file changed, 18 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c
+index f6c46d2e5276b..e3d8ddcff5670 100644
+--- a/drivers/leds/led-core.c
++++ b/drivers/leds/led-core.c
+@@ -159,8 +159,19 @@ static void set_brightness_delayed(struct work_struct *ws)
+        * before this work item runs once. To make sure this works properly
+        * handle LED_SET_BRIGHTNESS_OFF first.
+        */
+-      if (test_and_clear_bit(LED_SET_BRIGHTNESS_OFF, &led_cdev->work_flags))
++      if (test_and_clear_bit(LED_SET_BRIGHTNESS_OFF, &led_cdev->work_flags)) {
+               set_brightness_delayed_set_brightness(led_cdev, LED_OFF);
++              /*
++               * The consecutives led_set_brightness(LED_OFF),
++               * led_set_brightness(LED_FULL) could have been executed out of
++               * order (LED_FULL first), if the work_flags has been set
++               * between LED_SET_BRIGHTNESS_OFF and LED_SET_BRIGHTNESS of this
++               * work. To avoid ending with the LED turned off, turn the LED
++               * on again.
++               */
++              if (led_cdev->delayed_set_value != LED_OFF)
++                      set_bit(LED_SET_BRIGHTNESS, &led_cdev->work_flags);
++      }
+       if (test_and_clear_bit(LED_SET_BRIGHTNESS, &led_cdev->work_flags))
+               set_brightness_delayed_set_brightness(led_cdev, led_cdev->delayed_set_value);
+@@ -331,10 +342,13 @@ void led_set_brightness_nopm(struct led_classdev *led_cdev, unsigned int value)
+        * change is done immediately afterwards (before the work runs),
+        * it uses a separate work_flag.
+        */
+-      if (value) {
+-              led_cdev->delayed_set_value = value;
++      led_cdev->delayed_set_value = value;
++      /* Ensure delayed_set_value is seen before work_flags modification */
++      smp_mb__before_atomic();
++
++      if (value)
+               set_bit(LED_SET_BRIGHTNESS, &led_cdev->work_flags);
+-      } else {
++      else {
+               clear_bit(LED_SET_BRIGHTNESS, &led_cdev->work_flags);
+               clear_bit(LED_SET_BLINK, &led_cdev->work_flags);
+               set_bit(LED_SET_BRIGHTNESS_OFF, &led_cdev->work_flags);
+-- 
+2.39.5
+
diff --git a/queue-6.14/leds-st1202-check-for-error-code-from-devm_mutex_ini.patch b/queue-6.14/leds-st1202-check-for-error-code-from-devm_mutex_ini.patch
new file mode 100644 (file)
index 0000000..2823238
--- /dev/null
@@ -0,0 +1,44 @@
+From 8cf8349d75defe48386cf4eb7b0226e488b4419e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Feb 2025 07:52:50 +0100
+Subject: leds: st1202: Check for error code from devm_mutex_init() call
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Thomas Weißschuh <linux@weissschuh.net>
+
+[ Upstream commit 8168906bbb3ba678583422de29e6349407a94bb5 ]
+
+Even if it's not critical, the avoidance of checking the error code
+from devm_mutex_init() call today diminishes the point of using devm
+variant of it. Tomorrow it may even leak something. Add the missed
+check.
+
+Fixes: 259230378c65 ("leds: Add LED1202 I2C driver")
+Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
+Link: https://lore.kernel.org/r/20250204-must_check-devm_mutex_init-v2-1-7b6271c4b7e6@weissschuh.net
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/leds/leds-st1202.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/leds/leds-st1202.c b/drivers/leds/leds-st1202.c
+index e894b3f9a0f46..4cebc0203c227 100644
+--- a/drivers/leds/leds-st1202.c
++++ b/drivers/leds/leds-st1202.c
+@@ -345,7 +345,9 @@ static int st1202_probe(struct i2c_client *client)
+       if (!chip)
+               return -ENOMEM;
+-      devm_mutex_init(&client->dev, &chip->lock);
++      ret = devm_mutex_init(&client->dev, &chip->lock);
++      if (ret < 0)
++              return ret;
+       chip->client = client;
+       ret = st1202_dt_init(chip);
+-- 
+2.39.5
+
diff --git a/queue-6.14/lib-842-improve-error-handling-in-sw842_compress.patch b/queue-6.14/lib-842-improve-error-handling-in-sw842_compress.patch
new file mode 100644 (file)
index 0000000..0dcdac3
--- /dev/null
@@ -0,0 +1,44 @@
+From b2bf5d1cdd9afa2b7789b6f748ce4dbdd347c03b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jan 2025 19:42:04 +0530
+Subject: lib: 842: Improve error handling in sw842_compress()
+
+From: Tanya Agarwal <tanyaagarwal25699@gmail.com>
+
+[ Upstream commit af324dc0e2b558678aec42260cce38be16cc77ca ]
+
+The static code analysis tool "Coverity Scan" pointed the following
+implementation details out for further development considerations:
+CID 1309755: Unused value
+In sw842_compress: A value assigned to a variable is never used. (CWE-563)
+returned_value: Assigning value from add_repeat_template(p, repeat_count)
+to ret here, but that stored value is overwritten before it can be used.
+
+Conclusion:
+Add error handling for the return value from an add_repeat_template()
+call.
+
+Fixes: 2da572c959dd ("lib: add software 842 compression/decompression")
+Signed-off-by: Tanya Agarwal <tanyaagarwal25699@gmail.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/842/842_compress.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/lib/842/842_compress.c b/lib/842/842_compress.c
+index c02baa4168e16..055356508d97c 100644
+--- a/lib/842/842_compress.c
++++ b/lib/842/842_compress.c
+@@ -532,6 +532,8 @@ int sw842_compress(const u8 *in, unsigned int ilen,
+               }
+               if (repeat_count) {
+                       ret = add_repeat_template(p, repeat_count);
++                      if (ret)
++                              return ret;
+                       repeat_count = 0;
+                       if (next == last) /* reached max repeat bits */
+                               goto repeat;
+-- 
+2.39.5
+
diff --git a/queue-6.14/libbpf-add-namespace-for-errstr-making-it-libbpf_err.patch b/queue-6.14/libbpf-add-namespace-for-errstr-making-it-libbpf_err.patch
new file mode 100644 (file)
index 0000000..2567ef3
--- /dev/null
@@ -0,0 +1,62 @@
+From ce046a03e3f3c9aad6f2b43a57c77f60124465b0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Mar 2025 15:24:39 -0700
+Subject: libbpf: Add namespace for errstr making it libbpf_errstr
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 307ef667e94530c2f2f77797bfe9ea85c22bec7d ]
+
+When statically linking symbols can be replaced with those from other
+statically linked libraries depending on the link order and the hoped
+for "multiple definition" error may not appear. To avoid conflicts it
+is good practice to namespace symbols, this change renames errstr to
+libbpf_errstr. To avoid churn a #define is used to turn use of
+errstr(err) to libbpf_errstr(err).
+
+Fixes: 1633a83bf993 ("libbpf: Introduce errstr() for stringifying errno")
+Signed-off-by: Ian Rogers <irogers@google.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20250320222439.1350187-1-irogers@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/str_error.c | 2 +-
+ tools/lib/bpf/str_error.h | 7 +++++--
+ 2 files changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/tools/lib/bpf/str_error.c b/tools/lib/bpf/str_error.c
+index 8743049e32b7d..9a541762f54c0 100644
+--- a/tools/lib/bpf/str_error.c
++++ b/tools/lib/bpf/str_error.c
+@@ -36,7 +36,7 @@ char *libbpf_strerror_r(int err, char *dst, int len)
+       return dst;
+ }
+-const char *errstr(int err)
++const char *libbpf_errstr(int err)
+ {
+       static __thread char buf[12];
+diff --git a/tools/lib/bpf/str_error.h b/tools/lib/bpf/str_error.h
+index 66ffebde0684a..53e7fbffc13ec 100644
+--- a/tools/lib/bpf/str_error.h
++++ b/tools/lib/bpf/str_error.h
+@@ -7,10 +7,13 @@
+ char *libbpf_strerror_r(int err, char *dst, int len);
+ /**
+- * @brief **errstr()** returns string corresponding to numeric errno
++ * @brief **libbpf_errstr()** returns string corresponding to numeric errno
+  * @param err negative numeric errno
+  * @return pointer to string representation of the errno, that is invalidated
+  * upon the next call.
+  */
+-const char *errstr(int err);
++const char *libbpf_errstr(int err);
++
++#define errstr(err) libbpf_errstr(err)
++
+ #endif /* __LIBBPF_STR_ERROR_H */
+-- 
+2.39.5
+
diff --git a/queue-6.14/libbpf-fix-accessing-btf.ext-core_relo-header.patch b/queue-6.14/libbpf-fix-accessing-btf.ext-core_relo-header.patch
new file mode 100644 (file)
index 0000000..c1c631f
--- /dev/null
@@ -0,0 +1,49 @@
+From fdc0529e04889d45502928a195b145d369307aff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jan 2025 22:52:36 -0800
+Subject: libbpf: Fix accessing BTF.ext core_relo header
+
+From: Tony Ambardar <tony.ambardar@gmail.com>
+
+[ Upstream commit 0a7c2a84359612e54328aa52030eb202093da6e2 ]
+
+Update btf_ext_parse_info() to ensure the core_relo header is present
+before reading its fields. This avoids a potential buffer read overflow
+reported by the OSS Fuzz project.
+
+Fixes: cf579164e9ea ("libbpf: Support BTF.ext loading and output in either endianness")
+Signed-off-by: Tony Ambardar <tony.ambardar@gmail.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://issues.oss-fuzz.com/issues/388905046
+Link: https://lore.kernel.org/bpf/20250125065236.2603346-1-itugrok@yahoo.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/btf.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
+index 48c66f3a92002..560b519f820e2 100644
+--- a/tools/lib/bpf/btf.c
++++ b/tools/lib/bpf/btf.c
+@@ -3015,8 +3015,6 @@ static int btf_ext_parse_info(struct btf_ext *btf_ext, bool is_native)
+               .desc = "line_info",
+       };
+       struct btf_ext_sec_info_param core_relo = {
+-              .off = btf_ext->hdr->core_relo_off,
+-              .len = btf_ext->hdr->core_relo_len,
+               .min_rec_size = sizeof(struct bpf_core_relo),
+               .ext_info = &btf_ext->core_relo_info,
+               .desc = "core_relo",
+@@ -3034,6 +3032,8 @@ static int btf_ext_parse_info(struct btf_ext *btf_ext, bool is_native)
+       if (btf_ext->hdr->hdr_len < offsetofend(struct btf_ext_header, core_relo_len))
+               return 0; /* skip core relos parsing */
++      core_relo.off = btf_ext->hdr->core_relo_off;
++      core_relo.len = btf_ext->hdr->core_relo_len;
+       err = btf_ext_parse_sec_info(btf_ext, &core_relo, is_native);
+       if (err)
+               return err;
+-- 
+2.39.5
+
diff --git a/queue-6.14/libbpf-fix-hypothetical-stt_section-extern-null-dere.patch b/queue-6.14/libbpf-fix-hypothetical-stt_section-extern-null-dere.patch
new file mode 100644 (file)
index 0000000..56bf2f9
--- /dev/null
@@ -0,0 +1,41 @@
+From 78bd018ce080610f165bf87419e8b884a23579b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Feb 2025 16:28:21 -0800
+Subject: libbpf: Fix hypothetical STT_SECTION extern NULL deref case
+
+From: Andrii Nakryiko <andrii@kernel.org>
+
+[ Upstream commit e0525cd72b5979d8089fe524a071ea93fd011dc9 ]
+
+Fix theoretical NULL dereference in linker when resolving *extern*
+STT_SECTION symbol against not-yet-existing ELF section. Not sure if
+it's possible in practice for valid ELF object files (this would require
+embedded assembly manipulations, at which point BTF will be missing),
+but fix the s/dst_sym/dst_sec/ typo guarding this condition anyways.
+
+Fixes: faf6ed321cf6 ("libbpf: Add BPF static linker APIs")
+Fixes: a46349227cd8 ("libbpf: Add linker extern resolution support for functions and global variables")
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/r/20250220002821.834400-1-andrii@kernel.org
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/linker.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/lib/bpf/linker.c b/tools/lib/bpf/linker.c
+index b52f71c59616f..800e0ef09c378 100644
+--- a/tools/lib/bpf/linker.c
++++ b/tools/lib/bpf/linker.c
+@@ -2163,7 +2163,7 @@ static int linker_append_elf_sym(struct bpf_linker *linker, struct src_obj *obj,
+       obj->sym_map[src_sym_idx] = dst_sym_idx;
+-      if (sym_type == STT_SECTION && dst_sym) {
++      if (sym_type == STT_SECTION && dst_sec) {
+               dst_sec->sec_sym_idx = dst_sym_idx;
+               dst_sym->st_value = 0;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/lockdep-don-t-disable-interrupts-on-rt-in-disable_ir.patch b/queue-6.14/lockdep-don-t-disable-interrupts-on-rt-in-disable_ir.patch
new file mode 100644 (file)
index 0000000..5c148f9
--- /dev/null
@@ -0,0 +1,82 @@
+From 5e170c5bf91f7f4fb3e7df04df04c746d2b66e35 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Feb 2025 11:36:18 +0100
+Subject: lockdep: Don't disable interrupts on RT in
+ disable_irq_nosync_lockdep.*()
+
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+
+[ Upstream commit 87886b32d669abc11c7be95ef44099215e4f5788 ]
+
+disable_irq_nosync_lockdep() disables interrupts with lockdep enabled to
+avoid false positive reports by lockdep that a certain lock has not been
+acquired with disabled interrupts. The user of this macros expects that
+a lock can be acquried without disabling interrupts because the IRQ line
+triggering the interrupt is disabled.
+
+This triggers a warning on PREEMPT_RT because after
+disable_irq_nosync_lockdep.*() the following spinlock_t now is acquired
+with disabled interrupts.
+
+On PREEMPT_RT there is no difference between spin_lock() and
+spin_lock_irq() so avoiding disabling interrupts in this case works for
+the two remaining callers as of today.
+
+Don't disable interrupts on PREEMPT_RT in disable_irq_nosync_lockdep.*().
+
+Closes: https://lore.kernel.org/760e34f9-6034-40e0-82a5-ee9becd24438@roeck-us.net
+Fixes: e8106b941ceab ("[PATCH] lockdep: core, add enable/disable_irq_irqsave/irqrestore() APIs")
+Reported-by: Guenter Roeck <linux@roeck-us.net>
+Suggested-by: "Steven Rostedt (Google)" <rostedt@goodmis.org>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/20250212103619.2560503-2-bigeasy@linutronix.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/interrupt.h | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
+index 8cd9327e4e78d..a1b1be9bf73b2 100644
+--- a/include/linux/interrupt.h
++++ b/include/linux/interrupt.h
+@@ -448,7 +448,7 @@ irq_calc_affinity_vectors(unsigned int minvec, unsigned int maxvec,
+ static inline void disable_irq_nosync_lockdep(unsigned int irq)
+ {
+       disable_irq_nosync(irq);
+-#ifdef CONFIG_LOCKDEP
++#if defined(CONFIG_LOCKDEP) && !defined(CONFIG_PREEMPT_RT)
+       local_irq_disable();
+ #endif
+ }
+@@ -456,7 +456,7 @@ static inline void disable_irq_nosync_lockdep(unsigned int irq)
+ static inline void disable_irq_nosync_lockdep_irqsave(unsigned int irq, unsigned long *flags)
+ {
+       disable_irq_nosync(irq);
+-#ifdef CONFIG_LOCKDEP
++#if defined(CONFIG_LOCKDEP) && !defined(CONFIG_PREEMPT_RT)
+       local_irq_save(*flags);
+ #endif
+ }
+@@ -471,7 +471,7 @@ static inline void disable_irq_lockdep(unsigned int irq)
+ static inline void enable_irq_lockdep(unsigned int irq)
+ {
+-#ifdef CONFIG_LOCKDEP
++#if defined(CONFIG_LOCKDEP) && !defined(CONFIG_PREEMPT_RT)
+       local_irq_enable();
+ #endif
+       enable_irq(irq);
+@@ -479,7 +479,7 @@ static inline void enable_irq_lockdep(unsigned int irq)
+ static inline void enable_irq_lockdep_irqrestore(unsigned int irq, unsigned long *flags)
+ {
+-#ifdef CONFIG_LOCKDEP
++#if defined(CONFIG_LOCKDEP) && !defined(CONFIG_PREEMPT_RT)
+       local_irq_restore(*flags);
+ #endif
+       enable_irq(irq);
+-- 
+2.39.5
+
diff --git a/queue-6.14/lockdep-mm-fix-might_fault-lockdep-check-of-current-.patch b/queue-6.14/lockdep-mm-fix-might_fault-lockdep-check-of-current-.patch
new file mode 100644 (file)
index 0000000..eec33f0
--- /dev/null
@@ -0,0 +1,52 @@
+From 18188a48f4e56e881ef114f98b95dc55fd079474 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Nov 2024 14:39:10 +0100
+Subject: lockdep/mm: Fix might_fault() lockdep check of current->mm->mmap_lock
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+[ Upstream commit a1b65f3f7c6f7f0a08a7dba8be458c6415236487 ]
+
+Turns out that this commit, about 10 years ago:
+
+  9ec23531fd48 ("sched/preempt, mm/fault: Trigger might_sleep() in might_fault() with disabled pagefaults")
+
+... accidentally (and unnessecarily) put the lockdep part of
+__might_fault() under CONFIG_DEBUG_ATOMIC_SLEEP=y.
+
+This is potentially notable because large distributions such as
+Ubuntu are running with !CONFIG_DEBUG_ATOMIC_SLEEP.
+
+Restore the debug check.
+
+[ mingo: Update changelog. ]
+
+Fixes: 9ec23531fd48 ("sched/preempt, mm/fault: Trigger might_sleep() in might_fault() with disabled pagefaults")
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Link: https://lore.kernel.org/r/20241104135517.536628371@infradead.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/memory.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/mm/memory.c b/mm/memory.c
+index fb7b8dc751679..4f6d9766a0460 100644
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -6834,10 +6834,8 @@ void __might_fault(const char *file, int line)
+       if (pagefault_disabled())
+               return;
+       __might_sleep(file, line);
+-#if defined(CONFIG_DEBUG_ATOMIC_SLEEP)
+       if (current->mm)
+               might_lock_read(&current->mm->mmap_lock);
+-#endif
+ }
+ EXPORT_SYMBOL(__might_fault);
+ #endif
+-- 
+2.39.5
+
diff --git a/queue-6.14/loongarch-fix-device-node-refcount-leak-in-fdt_cpu_c.patch b/queue-6.14/loongarch-fix-device-node-refcount-leak-in-fdt_cpu_c.patch
new file mode 100644 (file)
index 0000000..3916f9c
--- /dev/null
@@ -0,0 +1,36 @@
+From 18735de67374bd06d8782229f2dc15260d7a7389 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 30 Mar 2025 16:31:09 +0800
+Subject: LoongArch: Fix device node refcount leak in fdt_cpu_clk_init()
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 2e3bc71e4f394ecf8f499d21923cf556b4bfa1e7 ]
+
+Add missing of_node_put() to properly handle the reference count of the
+device node obtained from of_get_cpu_node().
+
+Fixes: 44a01f1f726a ("LoongArch: Parsing CPU-related information from DTS")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/loongarch/kernel/env.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/loongarch/kernel/env.c b/arch/loongarch/kernel/env.c
+index 2f1f5b08638f8..27144de5c5fe4 100644
+--- a/arch/loongarch/kernel/env.c
++++ b/arch/loongarch/kernel/env.c
+@@ -68,6 +68,8 @@ static int __init fdt_cpu_clk_init(void)
+               return -ENODEV;
+       clk = of_clk_get(np, 0);
++      of_node_put(np);
++
+       if (IS_ERR(clk))
+               return -ENODEV;
+-- 
+2.39.5
+
diff --git a/queue-6.14/loongarch-fix-help-text-of-cmdline_extend-in-kconfig.patch b/queue-6.14/loongarch-fix-help-text-of-cmdline_extend-in-kconfig.patch
new file mode 100644 (file)
index 0000000..23e5c77
--- /dev/null
@@ -0,0 +1,41 @@
+From a1a85be7e4661fd9db01e51f1d76717cbe752874 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 30 Mar 2025 16:31:09 +0800
+Subject: LoongArch: Fix help text of CMDLINE_EXTEND in Kconfig
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: 谢致邦 (XIE Zhibang) <Yeking@Red54.com>
+
+[ Upstream commit be216cbc1ddf99a51915414ce147311c0dfd50a2 ]
+
+It is the built-in command line appended to the bootloader command line,
+not the bootloader command line appended to the built-in command line.
+
+Fixes: fa96b57c1490 ("LoongArch: Add build infrastructure")
+Signed-off-by: 谢致邦 (XIE Zhibang) <Yeking@Red54.com>
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/loongarch/Kconfig | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
+index 2b8bd27a852fe..bdb989c49c094 100644
+--- a/arch/loongarch/Kconfig
++++ b/arch/loongarch/Kconfig
+@@ -382,8 +382,8 @@ config CMDLINE_BOOTLOADER
+ config CMDLINE_EXTEND
+       bool "Use built-in to extend bootloader kernel arguments"
+       help
+-        The command-line arguments provided during boot will be
+-        appended to the built-in command line. This is useful in
++        The built-in command line will be appended to the command-
++        line arguments provided during boot. This is useful in
+         cases where the provided arguments are insufficient and
+         you don't want to or cannot modify them.
+-- 
+2.39.5
+
diff --git a/queue-6.14/loongarch-rework-the-arch_kgdb_breakpoint-implementa.patch b/queue-6.14/loongarch-rework-the-arch_kgdb_breakpoint-implementa.patch
new file mode 100644 (file)
index 0000000..a0b11cd
--- /dev/null
@@ -0,0 +1,74 @@
+From 3ac2c2fefe0edca42ed1531755f7980bed1a1e16 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 30 Mar 2025 16:31:09 +0800
+Subject: LoongArch: Rework the arch_kgdb_breakpoint() implementation
+
+From: Yuli Wang <wangyuli@uniontech.com>
+
+[ Upstream commit 29c92a41c6d2879c1f62220fe4758dce191bb38f ]
+
+The arch_kgdb_breakpoint() function defines the kgdb_breakinst symbol
+using inline assembly.
+
+1. There's a potential issue where the compiler might inline
+arch_kgdb_breakpoint(), which would then define the kgdb_breakinst
+symbol multiple times, leading to a linker error.
+
+To prevent this, declare arch_kgdb_breakpoint() as noinline.
+
+Fix follow error with LLVM-19 *only* when LTO_CLANG_FULL:
+    LD      vmlinux.o
+  ld.lld-19: error: ld-temp.o <inline asm>:3:1: symbol 'kgdb_breakinst' is already defined
+  kgdb_breakinst: break 2
+  ^
+
+2. Remove "nop" in the inline assembly because it's meaningless for
+LoongArch here.
+
+3. Add "STACK_FRAME_NON_STANDARD" for arch_kgdb_breakpoint() to avoid
+the objtool warning.
+
+Fixes: e14dd076964e ("LoongArch: Add basic KGDB & KDB support")
+Tested-by: Binbin Zhou <zhoubinbin@loongson.cn>
+Co-developed-by: Winston Wen <wentao@uniontech.com>
+Signed-off-by: Winston Wen <wentao@uniontech.com>
+Co-developed-by: Wentao Guan <guanwentao@uniontech.com>
+Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
+Signed-off-by: Yuli Wang <wangyuli@uniontech.com>
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/loongarch/kernel/kgdb.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/arch/loongarch/kernel/kgdb.c b/arch/loongarch/kernel/kgdb.c
+index 445c452d72a79..7be5b4c0c9002 100644
+--- a/arch/loongarch/kernel/kgdb.c
++++ b/arch/loongarch/kernel/kgdb.c
+@@ -8,6 +8,7 @@
+ #include <linux/hw_breakpoint.h>
+ #include <linux/kdebug.h>
+ #include <linux/kgdb.h>
++#include <linux/objtool.h>
+ #include <linux/processor.h>
+ #include <linux/ptrace.h>
+ #include <linux/sched.h>
+@@ -224,13 +225,13 @@ void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
+       regs->csr_era = pc;
+ }
+-void arch_kgdb_breakpoint(void)
++noinline void arch_kgdb_breakpoint(void)
+ {
+       __asm__ __volatile__ (                  \
+               ".globl kgdb_breakinst\n\t"     \
+-              "nop\n"                         \
+               "kgdb_breakinst:\tbreak 2\n\t"); /* BRK_KDB = 2 */
+ }
++STACK_FRAME_NON_STANDARD(arch_kgdb_breakpoint);
+ /*
+  * Calls linux_debug_hook before the kernel dies. If KGDB is enabled,
+-- 
+2.39.5
+
diff --git a/queue-6.14/m68k-sun3-fix-debug_mmu_emu-build.patch b/queue-6.14/m68k-sun3-fix-debug_mmu_emu-build.patch
new file mode 100644 (file)
index 0000000..a04fe77
--- /dev/null
@@ -0,0 +1,94 @@
+From ea387c100c88f0581f1ee52e046e4ed18221fa8d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jan 2025 16:40:22 +0100
+Subject: m68k: sun3: Fix DEBUG_MMU_EMU build
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Geert Uytterhoeven <geert@linux-m68k.org>
+
+[ Upstream commit 723be3c6ab31b320afe0075e2eb9b8dd41f3b6d1 ]
+
+With DEBUG_MMU_EMU enabled:
+
+    arch/m68k/sun3/mmu_emu.c: In function ‘mmu_emu_handle_fault’:
+    arch/m68k/sun3/mmu_emu.c:420:38: error: implicit declaration of function ‘get_fs’; did you mean ‘sget_fc’? [-Werror=implicit-function-declaration]
+      420 |         pr_info("seg:%ld crp:%p ->", get_fs().seg, crp);
+         |                                      ^~~~~~
+
+    [...]
+
+    arch/m68k/sun3/mmu_emu.c:420:46: error: request for member ‘seg’ in something not a structure or union
+      420 |         pr_info("seg:%ld crp:%p ->", get_fs().seg, crp);
+         |                                              ^
+
+Fix this by reintroducing and using a helper to retrieve the current
+value of the DFC register.
+
+While at it, replace "%p" by "%px", as there is no point in printing
+obfuscated pointers during debugging.
+
+Fixes: 9fde0348640252c7 ("m68k: Remove set_fs()")
+Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Link: https://lore.kernel.org/b1d12a1d24b4aea9f98d905383ba932b2dc382e6.1737387419.git.geert@linux-m68k.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/m68k/include/asm/processor.h | 14 ++++++++++++++
+ arch/m68k/sun3/mmu_emu.c          |  4 ++--
+ 2 files changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/arch/m68k/include/asm/processor.h b/arch/m68k/include/asm/processor.h
+index 8f2676c3a9882..3c43c09d44894 100644
+--- a/arch/m68k/include/asm/processor.h
++++ b/arch/m68k/include/asm/processor.h
+@@ -95,10 +95,24 @@ static inline void set_fc(unsigned long val)
+                             "movec %0,%/dfc\n\t"
+                             : /* no outputs */ : "r" (val) : "memory");
+ }
++
++static inline unsigned long get_fc(void)
++{
++      unsigned long val;
++
++      __asm__ ("movec %/dfc,%0" : "=r" (val) : );
++
++      return val;
++}
+ #else
+ static inline void set_fc(unsigned long val)
+ {
+ }
++
++static inline unsigned long get_fc(void)
++{
++      return USER_DATA;
++}
+ #endif /* CONFIG_CPU_HAS_ADDRESS_SPACES */
+ struct thread_struct {
+diff --git a/arch/m68k/sun3/mmu_emu.c b/arch/m68k/sun3/mmu_emu.c
+index 7b15cc12637bf..b39fc3717d8ea 100644
+--- a/arch/m68k/sun3/mmu_emu.c
++++ b/arch/m68k/sun3/mmu_emu.c
+@@ -371,7 +371,7 @@ int mmu_emu_handle_fault (unsigned long vaddr, int read_flag, int kernel_fault)
+       }
+ #ifdef DEBUG_MMU_EMU
+-      pr_info("%s: vaddr=%lx type=%s crp=%p\n", __func__, vaddr,
++      pr_info("%s: vaddr=%lx type=%s crp=%px\n", __func__, vaddr,
+               str_read_write(read_flag), crp);
+ #endif
+@@ -418,7 +418,7 @@ int mmu_emu_handle_fault (unsigned long vaddr, int read_flag, int kernel_fault)
+               pte_val (*pte) |= SUN3_PAGE_ACCESSED;
+ #ifdef DEBUG_MMU_EMU
+-      pr_info("seg:%ld crp:%p ->", get_fs().seg, crp);
++      pr_info("seg:%ld crp:%px ->", get_fc(), crp);
+       print_pte_vaddr (vaddr);
+       pr_cont("\n");
+ #endif
+-- 
+2.39.5
+
diff --git a/queue-6.14/m68k-sun3-use-str_read_write-helper-in-mmu_emu_handl.patch b/queue-6.14/m68k-sun3-use-str_read_write-helper-in-mmu_emu_handl.patch
new file mode 100644 (file)
index 0000000..dfcb38f
--- /dev/null
@@ -0,0 +1,45 @@
+From 28f8b4af5e2415be7f060ffc0641458efa27f1a7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jan 2025 13:06:05 +0100
+Subject: m68k: sun3: Use str_read_write() helper in mmu_emu_handle_fault()
+
+From: Thorsten Blum <thorsten.blum@linux.dev>
+
+[ Upstream commit 751b3d8d886e73ecc24a5426adba228ef7eb39e8 ]
+
+Remove hard-coded strings by using the str_read_write() helper.
+
+Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
+Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Link: https://lore.kernel.org/20250117120605.126941-2-thorsten.blum@linux.dev
+Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Stable-dep-of: 723be3c6ab31 ("m68k: sun3: Fix DEBUG_MMU_EMU build")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/m68k/sun3/mmu_emu.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/m68k/sun3/mmu_emu.c b/arch/m68k/sun3/mmu_emu.c
+index 119bd32efcfbc..7b15cc12637bf 100644
+--- a/arch/m68k/sun3/mmu_emu.c
++++ b/arch/m68k/sun3/mmu_emu.c
+@@ -17,6 +17,7 @@
+ #include <linux/bitops.h>
+ #include <linux/module.h>
+ #include <linux/sched/mm.h>
++#include <linux/string_choices.h>
+ #include <asm/setup.h>
+ #include <asm/traps.h>
+@@ -371,7 +372,7 @@ int mmu_emu_handle_fault (unsigned long vaddr, int read_flag, int kernel_fault)
+ #ifdef DEBUG_MMU_EMU
+       pr_info("%s: vaddr=%lx type=%s crp=%p\n", __func__, vaddr,
+-              read_flag ? "read" : "write", crp);
++              str_read_write(read_flag), crp);
+ #endif
+       segment = (vaddr >> SUN3_PMEG_SIZE_BITS) & 0x7FF;
+-- 
+2.39.5
+
diff --git a/queue-6.14/md-ensure-resync-is-prioritized-over-recovery.patch b/queue-6.14/md-ensure-resync-is-prioritized-over-recovery.patch
new file mode 100644 (file)
index 0000000..cd5eb99
--- /dev/null
@@ -0,0 +1,62 @@
+From 3b3d25fa3e7591a5c14807718a92262e11c21aba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Feb 2025 21:15:30 +0800
+Subject: md: ensure resync is prioritized over recovery
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit 4b10a3bc67c1232f76aa1e04778ca26d6c0ddf7f ]
+
+If a new disk is added during resync, the resync process is interrupted,
+and recovery is triggered, causing the previous resync to be lost. In
+reality, disk addition should not terminate resync, fix it.
+
+Steps to reproduce the issue:
+  mdadm -CR /dev/md0 -l1 -n3 -x1 /dev/sd[abcd]
+  mdadm --fail /dev/md0 /dev/sdc
+
+Fixes: 24dd469d728d ("[PATCH] md: allow a manual resync with md")
+Signed-off-by: Li Nan <linan122@huawei.com>
+Reviewed-by: Yu Kuai <yukuai3@huawei.com>
+Link: https://lore.kernel.org/linux-raid/20250213131530.3698600-1-linan666@huaweicloud.com
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/md.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/md/md.c b/drivers/md/md.c
+index 30b3dbbce2d2d..827646b3eb594 100644
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -9460,6 +9460,13 @@ static bool md_choose_sync_action(struct mddev *mddev, int *spares)
+               return true;
+       }
++      /* Check if resync is in progress. */
++      if (mddev->recovery_cp < MaxSector) {
++              set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
++              clear_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
++              return true;
++      }
++
+       /*
+        * Remove any failed drives, then add spares if possible. Spares are
+        * also removed and re-added, to allow the personality to fail the
+@@ -9476,13 +9483,6 @@ static bool md_choose_sync_action(struct mddev *mddev, int *spares)
+               return true;
+       }
+-      /* Check if recovery is in progress. */
+-      if (mddev->recovery_cp < MaxSector) {
+-              set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
+-              clear_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
+-              return true;
+-      }
+-
+       /* Delay to choose resync/check/repair in md_do_sync(). */
+       if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
+               return true;
+-- 
+2.39.5
+
diff --git a/queue-6.14/md-fix-mddev-uaf-while-iterating-all_mddevs-list.patch b/queue-6.14/md-fix-mddev-uaf-while-iterating-all_mddevs-list.patch
new file mode 100644 (file)
index 0000000..9586538
--- /dev/null
@@ -0,0 +1,135 @@
+From 7e9bd276b31eb924cd8d1d9005636b90a8970c40 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Feb 2025 20:43:48 +0800
+Subject: md: fix mddev uaf while iterating all_mddevs list
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit 8542870237c3a48ff049b6c5df5f50c8728284fa ]
+
+While iterating all_mddevs list from md_notify_reboot() and md_exit(),
+list_for_each_entry_safe is used, and this can race with deletint the
+next mddev, causing UAF:
+
+t1:
+spin_lock
+//list_for_each_entry_safe(mddev, n, ...)
+ mddev_get(mddev1)
+ // assume mddev2 is the next entry
+ spin_unlock
+            t2:
+            //remove mddev2
+            ...
+            mddev_free
+            spin_lock
+            list_del
+            spin_unlock
+            kfree(mddev2)
+ mddev_put(mddev1)
+ spin_lock
+ //continue dereference mddev2->all_mddevs
+
+The old helper for_each_mddev() actually grab the reference of mddev2
+while holding the lock, to prevent from being freed. This problem can be
+fixed the same way, however, the code will be complex.
+
+Hence switch to use list_for_each_entry, in this case mddev_put() can free
+the mddev1 and it's not safe as well. Refer to md_seq_show(), also factor
+out a helper mddev_put_locked() to fix this problem.
+
+Cc: Christoph Hellwig <hch@lst.de>
+Link: https://lore.kernel.org/linux-raid/20250220124348.845222-1-yukuai1@huaweicloud.com
+Fixes: f26514342255 ("md: stop using for_each_mddev in md_notify_reboot")
+Fixes: 16648bac862f ("md: stop using for_each_mddev in md_exit")
+Reported-and-tested-by: Guillaume Morin <guillaume@morinfr.org>
+Closes: https://lore.kernel.org/all/Z7Y0SURoA8xwg7vn@bender.morinfr.org/
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/md.c | 22 +++++++++++++---------
+ 1 file changed, 13 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/md/md.c b/drivers/md/md.c
+index 827646b3eb594..f501bc5f68f1a 100644
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -629,6 +629,12 @@ static void __mddev_put(struct mddev *mddev)
+       queue_work(md_misc_wq, &mddev->del_work);
+ }
++static void mddev_put_locked(struct mddev *mddev)
++{
++      if (atomic_dec_and_test(&mddev->active))
++              __mddev_put(mddev);
++}
++
+ void mddev_put(struct mddev *mddev)
+ {
+       if (!atomic_dec_and_lock(&mddev->active, &all_mddevs_lock))
+@@ -8461,9 +8467,7 @@ static int md_seq_show(struct seq_file *seq, void *v)
+       if (mddev == list_last_entry(&all_mddevs, struct mddev, all_mddevs))
+               status_unused(seq);
+-      if (atomic_dec_and_test(&mddev->active))
+-              __mddev_put(mddev);
+-
++      mddev_put_locked(mddev);
+       return 0;
+ }
+@@ -9895,11 +9899,11 @@ EXPORT_SYMBOL_GPL(rdev_clear_badblocks);
+ static int md_notify_reboot(struct notifier_block *this,
+                           unsigned long code, void *x)
+ {
+-      struct mddev *mddev, *n;
++      struct mddev *mddev;
+       int need_delay = 0;
+       spin_lock(&all_mddevs_lock);
+-      list_for_each_entry_safe(mddev, n, &all_mddevs, all_mddevs) {
++      list_for_each_entry(mddev, &all_mddevs, all_mddevs) {
+               if (!mddev_get(mddev))
+                       continue;
+               spin_unlock(&all_mddevs_lock);
+@@ -9911,8 +9915,8 @@ static int md_notify_reboot(struct notifier_block *this,
+                       mddev_unlock(mddev);
+               }
+               need_delay = 1;
+-              mddev_put(mddev);
+               spin_lock(&all_mddevs_lock);
++              mddev_put_locked(mddev);
+       }
+       spin_unlock(&all_mddevs_lock);
+@@ -10245,7 +10249,7 @@ void md_autostart_arrays(int part)
+ static __exit void md_exit(void)
+ {
+-      struct mddev *mddev, *n;
++      struct mddev *mddev;
+       int delay = 1;
+       unregister_blkdev(MD_MAJOR,"md");
+@@ -10266,7 +10270,7 @@ static __exit void md_exit(void)
+       remove_proc_entry("mdstat", NULL);
+       spin_lock(&all_mddevs_lock);
+-      list_for_each_entry_safe(mddev, n, &all_mddevs, all_mddevs) {
++      list_for_each_entry(mddev, &all_mddevs, all_mddevs) {
+               if (!mddev_get(mddev))
+                       continue;
+               spin_unlock(&all_mddevs_lock);
+@@ -10278,8 +10282,8 @@ static __exit void md_exit(void)
+                * the mddev for destruction by a workqueue, and the
+                * destroy_workqueue() below will wait for that to complete.
+                */
+-              mddev_put(mddev);
+               spin_lock(&all_mddevs_lock);
++              mddev_put_locked(mddev);
+       }
+       spin_unlock(&all_mddevs_lock);
+-- 
+2.39.5
+
diff --git a/queue-6.14/md-md-bitmap-fix-wrong-bitmap_limit-for-clustermd-wh.patch b/queue-6.14/md-md-bitmap-fix-wrong-bitmap_limit-for-clustermd-wh.patch
new file mode 100644 (file)
index 0000000..e101f86
--- /dev/null
@@ -0,0 +1,66 @@
+From fd4c044de51c78315b7dd86a81e927b7eb64a5cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Mar 2025 11:39:18 +0800
+Subject: md/md-bitmap: fix wrong bitmap_limit for clustermd when write sb
+
+From: Su Yue <glass.su@suse.com>
+
+[ Upstream commit 6130825f34d41718c98a9b1504a79a23e379701e ]
+
+In clustermd, separate write-intent-bitmaps are used for each cluster
+node:
+
+0                    4k                     8k                    12k
+-------------------------------------------------------------------
+| idle                | md super            | bm super [0] + bits |
+| bm bits[0, contd]   | bm super[1] + bits  | bm bits[1, contd]   |
+| bm super[2] + bits  | bm bits [2, contd]  | bm super[3] + bits  |
+| bm bits [3, contd]  |                     |                     |
+
+So in node 1, pg_index in __write_sb_page() could equal to
+bitmap->storage.file_pages. Then bitmap_limit will be calculated to
+0. md_super_write() will be called with 0 size.
+That means the first 4k sb area of node 1 will never be updated
+through filemap_write_page().
+This bug causes hang of mdadm/clustermd_tests/01r1_Grow_resize.
+
+Here use (pg_index % bitmap->storage.file_pages) to make calculation
+of bitmap_limit correct.
+
+Fixes: ab99a87542f1 ("md/md-bitmap: fix writing non bitmap pages")
+Signed-off-by: Su Yue <glass.su@suse.com>
+Reviewed-by: Heming Zhao <heming.zhao@suse.com>
+Link: https://lore.kernel.org/linux-raid/20250303033918.32136-1-glass.su@suse.com
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/md-bitmap.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
+index 23c09d22fcdbc..9ae6cc8e30cbd 100644
+--- a/drivers/md/md-bitmap.c
++++ b/drivers/md/md-bitmap.c
+@@ -426,8 +426,8 @@ static int __write_sb_page(struct md_rdev *rdev, struct bitmap *bitmap,
+       struct block_device *bdev;
+       struct mddev *mddev = bitmap->mddev;
+       struct bitmap_storage *store = &bitmap->storage;
+-      unsigned int bitmap_limit = (bitmap->storage.file_pages - pg_index) <<
+-              PAGE_SHIFT;
++      unsigned long num_pages = bitmap->storage.file_pages;
++      unsigned int bitmap_limit = (num_pages - pg_index % num_pages) << PAGE_SHIFT;
+       loff_t sboff, offset = mddev->bitmap_info.offset;
+       sector_t ps = pg_index * PAGE_SIZE / SECTOR_SIZE;
+       unsigned int size = PAGE_SIZE;
+@@ -436,7 +436,7 @@ static int __write_sb_page(struct md_rdev *rdev, struct bitmap *bitmap,
+       bdev = (rdev->meta_bdev) ? rdev->meta_bdev : rdev->bdev;
+       /* we compare length (page numbers), not page offset. */
+-      if ((pg_index - store->sb_index) == store->file_pages - 1) {
++      if ((pg_index - store->sb_index) == num_pages - 1) {
+               unsigned int last_page_size = store->bytes & (PAGE_SIZE - 1);
+               if (last_page_size == 0)
+-- 
+2.39.5
+
diff --git a/queue-6.14/md-raid1-fix-memory-leak-in-raid1_run-if-no-active-r.patch b/queue-6.14/md-raid1-fix-memory-leak-in-raid1_run-if-no-active-r.patch
new file mode 100644 (file)
index 0000000..ab1787b
--- /dev/null
@@ -0,0 +1,60 @@
+From 67dde4fa72498756199c10e15795486fe860bcc8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 15 Feb 2025 10:01:37 +0800
+Subject: md/raid1: fix memory leak in raid1_run() if no active rdev
+
+From: Zheng Qixing <zhengqixing@huawei.com>
+
+[ Upstream commit 5fbcf76e0dfe68578ffa2a8a691cc44cf586ae35 ]
+
+When `raid1_set_limits()` fails or when the array has no active
+`rdev`, the allocated memory for `conf` is not properly freed.
+
+Add raid1_free() call to properly free the conf in error path.
+
+Fixes: 799af947ed13 ("md/raid1: don't free conf on raid0_run failure")
+Signed-off-by: Zheng Qixing <zhengqixing@huawei.com>
+Link: https://lore.kernel.org/linux-raid/20250215020137.3703757-1-zhengqixing@huaweicloud.com
+Singed-off-by: Yu Kuai <yukuai3@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/raid1.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
+index 10ea3af40991d..cb108b3e28c4d 100644
+--- a/drivers/md/raid1.c
++++ b/drivers/md/raid1.c
+@@ -45,6 +45,7 @@
+ static void allow_barrier(struct r1conf *conf, sector_t sector_nr);
+ static void lower_barrier(struct r1conf *conf, sector_t sector_nr);
++static void raid1_free(struct mddev *mddev, void *priv);
+ #define RAID_1_10_NAME "raid1"
+ #include "raid1-10.c"
+@@ -3256,8 +3257,11 @@ static int raid1_run(struct mddev *mddev)
+       if (!mddev_is_dm(mddev)) {
+               ret = raid1_set_limits(mddev);
+-              if (ret)
++              if (ret) {
++                      if (!mddev->private)
++                              raid1_free(mddev, conf);
+                       return ret;
++              }
+       }
+       mddev->degraded = 0;
+@@ -3271,6 +3275,8 @@ static int raid1_run(struct mddev *mddev)
+        */
+       if (conf->raid_disks - mddev->degraded < 1) {
+               md_unregister_thread(mddev, &conf->thread);
++              if (!mddev->private)
++                      raid1_free(mddev, conf);
+               return -EINVAL;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/md-raid1-raid10-don-t-ignore-io-flags.patch b/queue-6.14/md-raid1-raid10-don-t-ignore-io-flags.patch
new file mode 100644 (file)
index 0000000..2377ecd
--- /dev/null
@@ -0,0 +1,105 @@
+From c6a2ffa0baf01960f769ef65d1318cb38d6fbc23 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 20:16:57 +0800
+Subject: md/raid1,raid10: don't ignore IO flags
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit e879a0d9cb086c8e52ce6c04e5bfa63825a6213c ]
+
+If blk-wbt is enabled by default, it's found that raid write performance
+is quite bad because all IO are throttled by wbt of underlying disks,
+due to flag REQ_IDLE is ignored. And turns out this behaviour exist since
+blk-wbt is introduced.
+
+Other than REQ_IDLE, other flags should not be ignored as well, for
+example REQ_META can be set for filesystems, clearing it can cause priority
+reverse problems; And REQ_NOWAIT should not be cleared as well, because
+io will wait instead of failing directly in underlying disks.
+
+Fix those problems by keep IO flags from master bio.
+
+Fises: f51d46d0e7cb ("md: add support for REQ_NOWAIT")
+Fixes: e34cbd307477 ("blk-wbt: add general throttling mechanism")
+Fixes: 5404bc7a87b9 ("[PATCH] Allow file systems to differentiate between data and meta reads")
+Link: https://lore.kernel.org/linux-raid/20250227121657.832356-1-yukuai1@huaweicloud.com
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/raid1.c  | 5 -----
+ drivers/md/raid10.c | 8 --------
+ 2 files changed, 13 deletions(-)
+
+diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
+index cb108b3e28c4d..44dcfebff4f03 100644
+--- a/drivers/md/raid1.c
++++ b/drivers/md/raid1.c
+@@ -1316,8 +1316,6 @@ static void raid1_read_request(struct mddev *mddev, struct bio *bio,
+       struct r1conf *conf = mddev->private;
+       struct raid1_info *mirror;
+       struct bio *read_bio;
+-      const enum req_op op = bio_op(bio);
+-      const blk_opf_t do_sync = bio->bi_opf & REQ_SYNC;
+       int max_sectors;
+       int rdisk, error;
+       bool r1bio_existed = !!r1_bio;
+@@ -1405,7 +1403,6 @@ static void raid1_read_request(struct mddev *mddev, struct bio *bio,
+       read_bio->bi_iter.bi_sector = r1_bio->sector +
+               mirror->rdev->data_offset;
+       read_bio->bi_end_io = raid1_end_read_request;
+-      read_bio->bi_opf = op | do_sync;
+       if (test_bit(FailFast, &mirror->rdev->flags) &&
+           test_bit(R1BIO_FailFast, &r1_bio->state))
+               read_bio->bi_opf |= MD_FAILFAST;
+@@ -1654,8 +1651,6 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
+               mbio->bi_iter.bi_sector = (r1_bio->sector + rdev->data_offset);
+               mbio->bi_end_io = raid1_end_write_request;
+-              mbio->bi_opf = bio_op(bio) |
+-                      (bio->bi_opf & (REQ_SYNC | REQ_FUA | REQ_ATOMIC));
+               if (test_bit(FailFast, &rdev->flags) &&
+                   !test_bit(WriteMostly, &rdev->flags) &&
+                   conf->raid_disks - mddev->degraded > 1)
+diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
+index 15b9ae5bf84d8..c897b19dc2d53 100644
+--- a/drivers/md/raid10.c
++++ b/drivers/md/raid10.c
+@@ -1146,8 +1146,6 @@ static void raid10_read_request(struct mddev *mddev, struct bio *bio,
+ {
+       struct r10conf *conf = mddev->private;
+       struct bio *read_bio;
+-      const enum req_op op = bio_op(bio);
+-      const blk_opf_t do_sync = bio->bi_opf & REQ_SYNC;
+       int max_sectors;
+       struct md_rdev *rdev;
+       char b[BDEVNAME_SIZE];
+@@ -1228,7 +1226,6 @@ static void raid10_read_request(struct mddev *mddev, struct bio *bio,
+       read_bio->bi_iter.bi_sector = r10_bio->devs[slot].addr +
+               choose_data_offset(r10_bio, rdev);
+       read_bio->bi_end_io = raid10_end_read_request;
+-      read_bio->bi_opf = op | do_sync;
+       if (test_bit(FailFast, &rdev->flags) &&
+           test_bit(R10BIO_FailFast, &r10_bio->state))
+               read_bio->bi_opf |= MD_FAILFAST;
+@@ -1247,10 +1244,6 @@ static void raid10_write_one_disk(struct mddev *mddev, struct r10bio *r10_bio,
+                                 struct bio *bio, bool replacement,
+                                 int n_copy)
+ {
+-      const enum req_op op = bio_op(bio);
+-      const blk_opf_t do_sync = bio->bi_opf & REQ_SYNC;
+-      const blk_opf_t do_fua = bio->bi_opf & REQ_FUA;
+-      const blk_opf_t do_atomic = bio->bi_opf & REQ_ATOMIC;
+       unsigned long flags;
+       struct r10conf *conf = mddev->private;
+       struct md_rdev *rdev;
+@@ -1269,7 +1262,6 @@ static void raid10_write_one_disk(struct mddev *mddev, struct r10bio *r10_bio,
+       mbio->bi_iter.bi_sector = (r10_bio->devs[n_copy].addr +
+                                  choose_data_offset(r10_bio, rdev));
+       mbio->bi_end_io = raid10_end_write_request;
+-      mbio->bi_opf = op | do_sync | do_fua | do_atomic;
+       if (!replacement && test_bit(FailFast,
+                                    &conf->mirrors[devnum].rdev->flags)
+                        && enough(conf, devnum))
+-- 
+2.39.5
+
diff --git a/queue-6.14/md-raid10-wait-barrier-before-returning-discard-requ.patch b/queue-6.14/md-raid10-wait-barrier-before-returning-discard-requ.patch
new file mode 100644 (file)
index 0000000..cfba712
--- /dev/null
@@ -0,0 +1,45 @@
+From ea9f0cd98faaeb4335a3c93f74caf36e928cdb0c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Mar 2025 17:49:38 +0800
+Subject: md/raid10: wait barrier before returning discard request with
+ REQ_NOWAIT
+
+From: Xiao Ni <xni@redhat.com>
+
+[ Upstream commit 3db4404435397a345431b45f57876a3df133f3b4 ]
+
+raid10_handle_discard should wait barrier before returning a discard bio
+which has REQ_NOWAIT. And there is no need to print warning calltrace
+if a discard bio has REQ_NOWAIT flag. Quality engineer usually checks
+dmesg and reports error if dmesg has warning/error calltrace.
+
+Fixes: c9aa889b035f ("md: raid10 add nowait support")
+Signed-off-by: Xiao Ni <xni@redhat.com>
+Acked-by: Coly Li <colyli@kernel.org>
+Link: https://lore.kernel.org/linux-raid/20250306094938.48952-1-xni@redhat.com
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/raid10.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
+index c897b19dc2d53..918a09f0ddd45 100644
+--- a/drivers/md/raid10.c
++++ b/drivers/md/raid10.c
+@@ -1623,11 +1623,10 @@ static int raid10_handle_discard(struct mddev *mddev, struct bio *bio)
+       if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
+               return -EAGAIN;
+-      if (WARN_ON_ONCE(bio->bi_opf & REQ_NOWAIT)) {
++      if (!wait_barrier(conf, bio->bi_opf & REQ_NOWAIT)) {
+               bio_wouldblock_error(bio);
+               return 0;
+       }
+-      wait_barrier(conf, false);
+       /*
+        * Check reshape again to avoid reshape happens after checking
+-- 
+2.39.5
+
diff --git a/queue-6.14/mdacon-rework-dependency-list.patch b/queue-6.14/mdacon-rework-dependency-list.patch
new file mode 100644 (file)
index 0000000..52c5519
--- /dev/null
@@ -0,0 +1,47 @@
+From 2d4eec4133b54d956ccc5907acf8f64eb68f9106 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Feb 2025 17:44:23 +0100
+Subject: mdacon: rework dependency list
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 5bbcc7645f4b244ffb5ac6563fbe9d3d42194447 ]
+
+mdacon has roughly the same dependencies as vgacon but expresses them
+as a negative list instead of a positive list, with the only practical
+difference being PowerPC/CHRP, which uses vga16fb instead of vgacon.
+
+The CONFIG_MDA_CONSOLE description advises to only turn it on when vgacon
+is also used because MDA/Hercules-only systems should be using vgacon
+instead, so just change the list to enforce that directly for simplicity.
+
+The probing was broken from 2002 to 2008, this improves on the fix
+that was added then: If vgacon is a loadable module, then mdacon
+cannot be built-in now, and the list of systems that support vgacon
+is carried over.
+
+Fixes: 0b9cf3aa6b1e ("mdacon messing up default vc's - set default to vc13-16 again")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/console/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
+index c4a8f74df2493..3e9f2bda67027 100644
+--- a/drivers/video/console/Kconfig
++++ b/drivers/video/console/Kconfig
+@@ -24,7 +24,7 @@ config VGA_CONSOLE
+         Say Y.
+ config MDA_CONSOLE
+-      depends on !M68K && !PARISC && ISA
++      depends on VGA_CONSOLE && ISA
+       tristate "MDA text console (dual-headed)"
+       help
+         Say Y here if you have an old MDA or monochrome Hercules graphics
+-- 
+2.39.5
+
diff --git a/queue-6.14/media-platform-allgro-dvt-unregister-v4l2_device-on-.patch b/queue-6.14/media-platform-allgro-dvt-unregister-v4l2_device-on-.patch
new file mode 100644 (file)
index 0000000..1932db5
--- /dev/null
@@ -0,0 +1,38 @@
+From f62b1f5dc674fb0e0a9ce9965e124228af317b16 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Dec 2024 11:06:21 +0900
+Subject: media: platform: allgro-dvt: unregister v4l2_device on the error path
+
+From: Joe Hattori <joe@pf.is.s.u-tokyo.ac.jp>
+
+[ Upstream commit c2b96a6818159fba8a3bcc38262da9e77f9b3ec7 ]
+
+In allegro_probe(), the v4l2 device is not unregistered in the error
+path, which results in a memory leak. Fix it by calling
+v4l2_device_unregister() before returning error.
+
+Fixes: d74d4e2359ec ("media: allegro: move driver out of staging")
+Signed-off-by: Joe Hattori <joe@pf.is.s.u-tokyo.ac.jp>
+Reviewed-by: Michael Tretter <m.tretter@pengutronix.de>
+Signed-off-by: Sebastian Fricke <sebastian.fricke@collabora.com>
+Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/allegro-dvt/allegro-core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/media/platform/allegro-dvt/allegro-core.c b/drivers/media/platform/allegro-dvt/allegro-core.c
+index e491399afcc98..eb03df0d86527 100644
+--- a/drivers/media/platform/allegro-dvt/allegro-core.c
++++ b/drivers/media/platform/allegro-dvt/allegro-core.c
+@@ -3912,6 +3912,7 @@ static int allegro_probe(struct platform_device *pdev)
+       if (ret < 0) {
+               v4l2_err(&dev->v4l2_dev,
+                        "failed to request firmware: %d\n", ret);
++              v4l2_device_unregister(&dev->v4l2_dev);
+               return ret;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/media-verisilicon-hevc-initialize-start_bit-field.patch b/queue-6.14/media-verisilicon-hevc-initialize-start_bit-field.patch
new file mode 100644 (file)
index 0000000..9240405
--- /dev/null
@@ -0,0 +1,40 @@
+From 09b1a00f5a7cdd91e8db0350f6a31b18a8284275 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jan 2025 09:10:52 +0100
+Subject: media: verisilicon: HEVC: Initialize start_bit field
+
+From: Benjamin Gaignard <benjamin.gaignard@collabora.com>
+
+[ Upstream commit 7fcb42b3835e90ef18d68555934cf72adaf58402 ]
+
+The HEVC driver needs to set the start_bit field explicitly to avoid
+causing corrupted frames when the VP9 decoder is used in parallel. The
+reason for this problem is that the VP9 and the HEVC decoder share this
+register.
+
+Fixes: cb5dd5a0fa51 ("media: hantro: Introduce G2/HEVC decoder")
+Signed-off-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
+Tested-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Signed-off-by: Sebastian Fricke <sebastian.fricke@collabora.com>
+Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c b/drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c
+index 85a44143b3786..0e212198dd65b 100644
+--- a/drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c
++++ b/drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c
+@@ -518,6 +518,7 @@ static void set_buffers(struct hantro_ctx *ctx)
+       hantro_reg_write(vpu, &g2_stream_len, src_len);
+       hantro_reg_write(vpu, &g2_strm_buffer_len, src_buf_len);
+       hantro_reg_write(vpu, &g2_strm_start_offset, 0);
++      hantro_reg_write(vpu, &g2_start_bit, 0);
+       hantro_reg_write(vpu, &g2_write_mvs_e, 1);
+       hantro_write_addr(vpu, G2_TILE_SIZES_ADDR, ctx->hevc_dec.tile_sizes.dma);
+-- 
+2.39.5
+
diff --git a/queue-6.14/memory-mtk-smi-add-ostd-setting-for-mt8192.patch b/queue-6.14/memory-mtk-smi-add-ostd-setting-for-mt8192.patch
new file mode 100644 (file)
index 0000000..258d310
--- /dev/null
@@ -0,0 +1,79 @@
+From ce9a89fa3887becfef24ab0e963c191919bb6344 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Mar 2025 13:45:08 +0800
+Subject: memory: mtk-smi: Add ostd setting for mt8192
+
+From: Xueqi Zhang <xueqi.zhang@mediatek.com>
+
+[ Upstream commit 90a0fbaac4a588a1116a191521c3c837c25582ee ]
+
+Add initial ostd setting for mt8192. All the settings come from DE.
+These settings help adjust Multimedia HW's bandwidth limits to achieve
+a balanced bandwidth requirement.
+Without this, the VENC HW work abnormal while stress testing.
+
+Fixes: 02c02ddce427 ("memory: mtk-smi: Add mt8192 support")
+Signed-off-by: Xueqi Zhang <xueqi.zhang@mediatek.com>
+Reviewed-by: Yong Wu <yong.wu@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20250307054515.23455-1-xueqi.zhang@mediatek.com
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/memory/mtk-smi.c | 33 +++++++++++++++++++++++++++++++++
+ 1 file changed, 33 insertions(+)
+
+diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
+index 5710348f72f6f..a8f5467d6b31e 100644
+--- a/drivers/memory/mtk-smi.c
++++ b/drivers/memory/mtk-smi.c
+@@ -332,6 +332,38 @@ static const u8 mtk_smi_larb_mt8188_ostd[][SMI_LARB_PORT_NR_MAX] = {
+       [25] = {0x01},
+ };
++static const u8 mtk_smi_larb_mt8192_ostd[][SMI_LARB_PORT_NR_MAX] = {
++      [0] = {0x2, 0x2, 0x28, 0xa, 0xc, 0x28,},
++      [1] = {0x2, 0x2, 0x18, 0x18, 0x18, 0xa, 0xc, 0x28,},
++      [2] = {0x5, 0x5, 0x5, 0x5, 0x1,},
++      [3] = {},
++      [4] = {0x28, 0x19, 0xb, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x4, 0x1,},
++      [5] = {0x1, 0x1, 0x4, 0x1, 0x1, 0x1, 0x1, 0x16,},
++      [6] = {},
++      [7] = {0x1, 0x3, 0x2, 0x1, 0x1, 0x5, 0x2, 0x12, 0x13, 0x4, 0x4, 0x1,
++             0x4, 0x2, 0x1,},
++      [8] = {},
++      [9] = {0xa, 0x7, 0xf, 0x8, 0x1, 0x8, 0x9, 0x3, 0x3, 0x6, 0x7, 0x4,
++             0xa, 0x3, 0x4, 0xe, 0x1, 0x7, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,
++             0x1, 0x1, 0x1, 0x1, 0x1,},
++      [10] = {},
++      [11] = {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,
++              0x1, 0x1, 0x1, 0xe, 0x1, 0x7, 0x8, 0x7, 0x7, 0x1, 0x6, 0x2,
++              0xf, 0x8, 0x1, 0x1, 0x1,},
++      [12] = {},
++      [13] = {0x2, 0xc, 0xc, 0xe, 0x6, 0x6, 0x6, 0x6, 0x6, 0x12, 0x6, 0x28,
++              0x2, 0xc, 0xc, 0x28, 0x12, 0x6,},
++      [14] = {},
++      [15] = {0x28, 0x14, 0x2, 0xc, 0x18, 0x4, 0x28, 0x14, 0x4, 0x4, 0x4, 0x2,
++              0x4, 0x2, 0x8, 0x4, 0x4,},
++      [16] = {0x28, 0x14, 0x2, 0xc, 0x18, 0x4, 0x28, 0x14, 0x4, 0x4, 0x4, 0x2,
++              0x4, 0x2, 0x8, 0x4, 0x4,},
++      [17] = {0x28, 0x14, 0x2, 0xc, 0x18, 0x4, 0x28, 0x14, 0x4, 0x4, 0x4, 0x2,
++              0x4, 0x2, 0x8, 0x4, 0x4,},
++      [18] = {0x2, 0x2, 0x4, 0x2,},
++      [19] = {0x9, 0x9, 0x5, 0x5, 0x1, 0x1,},
++};
++
+ static const u8 mtk_smi_larb_mt8195_ostd[][SMI_LARB_PORT_NR_MAX] = {
+       [0] = {0x0a, 0xc, 0x22, 0x22, 0x01, 0x0a,}, /* larb0 */
+       [1] = {0x0a, 0xc, 0x22, 0x22, 0x01, 0x0a,}, /* larb1 */
+@@ -427,6 +459,7 @@ static const struct mtk_smi_larb_gen mtk_smi_larb_mt8188 = {
+ static const struct mtk_smi_larb_gen mtk_smi_larb_mt8192 = {
+       .config_port                = mtk_smi_larb_config_port_gen2_general,
++      .ostd                       = mtk_smi_larb_mt8192_ostd,
+ };
+ static const struct mtk_smi_larb_gen mtk_smi_larb_mt8195 = {
+-- 
+2.39.5
+
diff --git a/queue-6.14/mfd-sm501-switch-to-bit-to-mitigate-integer-overflow.patch b/queue-6.14/mfd-sm501-switch-to-bit-to-mitigate-integer-overflow.patch
new file mode 100644 (file)
index 0000000..d4461cb
--- /dev/null
@@ -0,0 +1,63 @@
+From 2842a1c8cc923f3db6ce327c65a4bc3087a952c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jan 2025 09:12:06 -0800
+Subject: mfd: sm501: Switch to BIT() to mitigate integer overflows
+
+From: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+
+[ Upstream commit 2d8cb9ffe18c2f1e5bd07a19cbce85b26c1d0cf0 ]
+
+If offset end up being high enough, right hand expression in functions
+like sm501_gpio_set() shifted left for that number of bits, may
+not fit in int type.
+
+Just in case, fix that by using BIT() both as an option safe from
+overflow issues and to make this step look similar to other gpio
+drivers.
+
+Found by Linux Verification Center (linuxtesting.org) with static
+analysis tool SVACE.
+
+Fixes: f61be273d369 ("sm501: add gpiolib support")
+Signed-off-by: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+Link: https://lore.kernel.org/r/20250115171206.20308-1-n.zhandarovich@fintech.ru
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/sm501.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c
+index 0469e85d72cff..7ee293b09f628 100644
+--- a/drivers/mfd/sm501.c
++++ b/drivers/mfd/sm501.c
+@@ -920,7 +920,7 @@ static void sm501_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+ {
+       struct sm501_gpio_chip *smchip = gpiochip_get_data(chip);
+       struct sm501_gpio *smgpio = smchip->ourgpio;
+-      unsigned long bit = 1 << offset;
++      unsigned long bit = BIT(offset);
+       void __iomem *regs = smchip->regbase;
+       unsigned long save;
+       unsigned long val;
+@@ -946,7 +946,7 @@ static int sm501_gpio_input(struct gpio_chip *chip, unsigned offset)
+       struct sm501_gpio_chip *smchip = gpiochip_get_data(chip);
+       struct sm501_gpio *smgpio = smchip->ourgpio;
+       void __iomem *regs = smchip->regbase;
+-      unsigned long bit = 1 << offset;
++      unsigned long bit = BIT(offset);
+       unsigned long save;
+       unsigned long ddr;
+@@ -971,7 +971,7 @@ static int sm501_gpio_output(struct gpio_chip *chip,
+ {
+       struct sm501_gpio_chip *smchip = gpiochip_get_data(chip);
+       struct sm501_gpio *smgpio = smchip->ourgpio;
+-      unsigned long bit = 1 << offset;
++      unsigned long bit = BIT(offset);
+       void __iomem *regs = smchip->regbase;
+       unsigned long save;
+       unsigned long val;
+-- 
+2.39.5
+
diff --git a/queue-6.14/misc-pci_endpoint_test-fix-pci_endpoint_test_bars_re.patch b/queue-6.14/misc-pci_endpoint_test-fix-pci_endpoint_test_bars_re.patch
new file mode 100644 (file)
index 0000000..eacb1c9
--- /dev/null
@@ -0,0 +1,53 @@
+From 3d5a79b5be531754359323f8ce66ee0db784f457 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Feb 2025 12:06:41 +0100
+Subject: misc: pci_endpoint_test: Fix pci_endpoint_test_bars_read_bar() error
+ handling
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Niklas Cassel <cassel@kernel.org>
+
+[ Upstream commit 2a93192d2058507b2e39b590fc1efa0e03344136 ]
+
+Commit f26d37ee9bda ("misc: pci_endpoint_test: Fix IOCTL return value")
+changed the return value of pci_endpoint_test_bars_read_bar() from false
+to -EINVAL on error, however, it failed to update the error handling.
+
+Fixes: f26d37ee9bda ("misc: pci_endpoint_test: Fix IOCTL return value")
+Signed-off-by: Niklas Cassel <cassel@kernel.org>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/20250204110640.570823-2-cassel@kernel.org
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/pci_endpoint_test.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
+index d5ac71a493865..7584d18768598 100644
+--- a/drivers/misc/pci_endpoint_test.c
++++ b/drivers/misc/pci_endpoint_test.c
+@@ -382,7 +382,7 @@ static int pci_endpoint_test_bars_read_bar(struct pci_endpoint_test *test,
+ static int pci_endpoint_test_bars(struct pci_endpoint_test *test)
+ {
+       enum pci_barno bar;
+-      bool ret;
++      int ret;
+       /* Write all BARs in order (without reading). */
+       for (bar = 0; bar < PCI_STD_NUM_BARS; bar++)
+@@ -398,7 +398,7 @@ static int pci_endpoint_test_bars(struct pci_endpoint_test *test)
+       for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
+               if (test->bar[bar]) {
+                       ret = pci_endpoint_test_bars_read_bar(test, bar);
+-                      if (!ret)
++                      if (ret)
+                               return ret;
+               }
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/misc-pci_endpoint_test-handle-bar-sizes-larger-than-.patch b/queue-6.14/misc-pci_endpoint_test-handle-bar-sizes-larger-than-.patch
new file mode 100644 (file)
index 0000000..434a8c9
--- /dev/null
@@ -0,0 +1,93 @@
+From 738c21591c83b668872cc42d117def5da2ba692b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jan 2025 10:33:01 +0100
+Subject: misc: pci_endpoint_test: Handle BAR sizes larger than INT_MAX
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Niklas Cassel <cassel@kernel.org>
+
+[ Upstream commit 7962c82a6e648d07bf0067796e4a0e69ba1fc702 ]
+
+Running 'pcitest -b 0' fails with "TEST FAILED" when the BAR0 size
+is e.g. 8 GB.
+
+The return value of the pci_resource_len() macro can be larger than that
+of a signed integer type. Thus, when using 'pcitest' with an 8 GB BAR,
+the bar_size of the integer type will overflow.
+
+Change bar_size from integer to resource_size_t to prevent integer
+overflow for large BAR sizes with 32-bit compilers.
+
+In order to handle 64-bit resource_type_t on 32-bit platforms, we would
+have needed to use a function like div_u64() or similar. Instead, change
+the code to use addition instead of division. This avoids the need for
+div_u64() or similar, while also simplifying the code.
+
+Fixes: cda370ec6d1f ("misc: pci_endpoint_test: Avoid using hard-coded BAR sizes")
+Co-developed-by: Hans Zhang <18255117159@163.com>
+Signed-off-by: Hans Zhang <18255117159@163.com>
+Signed-off-by: Niklas Cassel <cassel@kernel.org>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Tested-by: Jon Hunter <jonathanh@nvidia.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://lore.kernel.org/r/20250124093300.3629624-2-cassel@kernel.org
+[mani: added fixes tag]
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/pci_endpoint_test.c | 18 ++++++++++--------
+ 1 file changed, 10 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
+index 7584d18768598..9dac7cbe8748c 100644
+--- a/drivers/misc/pci_endpoint_test.c
++++ b/drivers/misc/pci_endpoint_test.c
+@@ -272,9 +272,9 @@ static const u32 bar_test_pattern[] = {
+ };
+ static int pci_endpoint_test_bar_memcmp(struct pci_endpoint_test *test,
+-                                      enum pci_barno barno, int offset,
+-                                      void *write_buf, void *read_buf,
+-                                      int size)
++                                      enum pci_barno barno,
++                                      resource_size_t offset, void *write_buf,
++                                      void *read_buf, int size)
+ {
+       memset(write_buf, bar_test_pattern[barno], size);
+       memcpy_toio(test->bar[barno] + offset, write_buf, size);
+@@ -287,10 +287,11 @@ static int pci_endpoint_test_bar_memcmp(struct pci_endpoint_test *test,
+ static int pci_endpoint_test_bar(struct pci_endpoint_test *test,
+                                 enum pci_barno barno)
+ {
+-      int j, bar_size, buf_size, iters;
++      resource_size_t bar_size, offset = 0;
+       void *write_buf __free(kfree) = NULL;
+       void *read_buf __free(kfree) = NULL;
+       struct pci_dev *pdev = test->pdev;
++      int buf_size;
+       if (!test->bar[barno])
+               return -ENOMEM;
+@@ -314,11 +315,12 @@ static int pci_endpoint_test_bar(struct pci_endpoint_test *test,
+       if (!read_buf)
+               return -ENOMEM;
+-      iters = bar_size / buf_size;
+-      for (j = 0; j < iters; j++)
+-              if (pci_endpoint_test_bar_memcmp(test, barno, buf_size * j,
+-                                               write_buf, read_buf, buf_size))
++      while (offset < bar_size) {
++              if (pci_endpoint_test_bar_memcmp(test, barno, offset, write_buf,
++                                               read_buf, buf_size))
+                       return -EIO;
++              offset += buf_size;
++      }
+       return 0;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/mlxsw-spectrum_acl_bloom_filter-workaround-for-some-.patch b/queue-6.14/mlxsw-spectrum_acl_bloom_filter-workaround-for-some-.patch
new file mode 100644 (file)
index 0000000..ac897aa
--- /dev/null
@@ -0,0 +1,115 @@
+From e7802eeb5e1ecee9ed36317b32751d778c9d45ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Mar 2025 18:36:54 +0800
+Subject: mlxsw: spectrum_acl_bloom_filter: Workaround for some LLVM versions
+
+From: WangYuli <wangyuli@uniontech.com>
+
+[ Upstream commit 4af9939a4977e05ccaaa645848f6208e82e06c61 ]
+
+This is a workaround to mitigate a compiler anomaly.
+
+During LLVM toolchain compilation of this driver on s390x architecture, an
+unreasonable __write_overflow_field warning occurs.
+
+Contextually, chunk_index is restricted to 0, 1 or 2. By expanding these
+possibilities, the compile warning is suppressed.
+
+Fix follow error with clang-19 when -Werror:
+  In file included from drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c:5:
+  In file included from ./include/linux/gfp.h:7:
+  In file included from ./include/linux/mmzone.h:8:
+  In file included from ./include/linux/spinlock.h:63:
+  In file included from ./include/linux/lockdep.h:14:
+  In file included from ./include/linux/smp.h:13:
+  In file included from ./include/linux/cpumask.h:12:
+  In file included from ./include/linux/bitmap.h:13:
+  In file included from ./include/linux/string.h:392:
+  ./include/linux/fortify-string.h:571:4: error: call to '__write_overflow_field' declared with 'warning' attribute: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Werror,-Wattribute-warning]
+    571 |                         __write_overflow_field(p_size_field, size);
+        |                         ^
+  1 error generated.
+
+According to the testing, we can be fairly certain that this is a clang
+compiler bug, impacting only clang-19 and below. Clang versions 20 and
+21 do not exhibit this behavior.
+
+Link: https://lore.kernel.org/all/484364B641C901CD+20250311141025.1624528-1-wangyuli@uniontech.com/
+Fixes: 7585cacdb978 ("mlxsw: spectrum_acl: Add Bloom filter handling")
+Co-developed-by: Zijian Chen <czj2441@163.com>
+Signed-off-by: Zijian Chen <czj2441@163.com>
+Co-developed-by: Wentao Guan <guanwentao@uniontech.com>
+Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
+Suggested-by: Paolo Abeni <pabeni@redhat.com>
+Co-developed-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Tested-by: Ido Schimmel <idosch@nvidia.com>
+Tested-by: WangYuli <wangyuli@uniontech.com>
+Signed-off-by: WangYuli <wangyuli@uniontech.com>
+Link: https://patch.msgid.link/A1858F1D36E653E0+20250318103654.708077-1-wangyuli@uniontech.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mlxsw/spectrum_acl_bloom_filter.c         | 27 +++++++++++++++----
+ 1 file changed, 22 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c
+index a54eedb69a3f5..067f0055a55af 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c
+@@ -212,7 +212,22 @@ static const u8 mlxsw_sp4_acl_bf_crc6_tab[256] = {
+  * This array defines key offsets for easy access when copying key blocks from
+  * entry key to Bloom filter chunk.
+  */
+-static const u8 chunk_key_offsets[MLXSW_BLOOM_KEY_CHUNKS] = {2, 20, 38};
++static char *
++mlxsw_sp_acl_bf_enc_key_get(struct mlxsw_sp_acl_atcam_entry *aentry,
++                          u8 chunk_index)
++{
++      switch (chunk_index) {
++      case 0:
++              return &aentry->ht_key.enc_key[2];
++      case 1:
++              return &aentry->ht_key.enc_key[20];
++      case 2:
++              return &aentry->ht_key.enc_key[38];
++      default:
++              WARN_ON_ONCE(1);
++              return &aentry->ht_key.enc_key[0];
++      }
++}
+ static u16 mlxsw_sp2_acl_bf_crc16_byte(u16 crc, u8 c)
+ {
+@@ -235,9 +250,10 @@ __mlxsw_sp_acl_bf_key_encode(struct mlxsw_sp_acl_atcam_region *aregion,
+                            u8 key_offset, u8 chunk_key_len, u8 chunk_len)
+ {
+       struct mlxsw_afk_key_info *key_info = aregion->region->key_info;
+-      u8 chunk_index, chunk_count, block_count;
++      u8 chunk_index, chunk_count;
+       char *chunk = output;
+       __be16 erp_region_id;
++      u32 block_count;
+       block_count = mlxsw_afk_key_info_blocks_count_get(key_info);
+       chunk_count = 1 + ((block_count - 1) >> 2);
+@@ -245,12 +261,13 @@ __mlxsw_sp_acl_bf_key_encode(struct mlxsw_sp_acl_atcam_region *aregion,
+                                  (aregion->region->id << 4));
+       for (chunk_index = max_chunks - chunk_count; chunk_index < max_chunks;
+            chunk_index++) {
++              char *enc_key;
++
+               memset(chunk, 0, pad_bytes);
+               memcpy(chunk + pad_bytes, &erp_region_id,
+                      sizeof(erp_region_id));
+-              memcpy(chunk + key_offset,
+-                     &aentry->ht_key.enc_key[chunk_key_offsets[chunk_index]],
+-                     chunk_key_len);
++              enc_key = mlxsw_sp_acl_bf_enc_key_get(aentry, chunk_index);
++              memcpy(chunk + key_offset, enc_key, chunk_key_len);
+               chunk += chunk_len;
+       }
+       *len = chunk_count * chunk_len;
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-airoha-fix-ets-priomap-validation.patch b/queue-6.14/net-airoha-fix-ets-priomap-validation.patch
new file mode 100644 (file)
index 0000000..3403f9e
--- /dev/null
@@ -0,0 +1,68 @@
+From 446558b1738138367c2a788227b95773c8083e49 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Mar 2025 18:17:31 +0200
+Subject: net: airoha: Fix ETS priomap validation
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit 367579274f60cb23c570ae5348966ab51e1509a4 ]
+
+ETS Qdisc schedules SP bands in a priority order assigning band-0 the
+highest priority (band-0 > band-1 > .. > band-n) while EN7581 arranges
+SP bands in a priority order assigning band-7 the highest priority
+(band-7 > band-6, .. > band-n).
+Fix priomap check in airoha_qdma_set_tx_ets_sched routine in order to
+align ETS Qdisc and airoha_eth driver SP priority ordering.
+
+Fixes: b56e4d660a96 ("net: airoha: Enforce ETS Qdisc priomap")
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Davide Caratti <dcaratti@redhat.com>
+Link: https://patch.msgid.link/20250331-airoha-ets-validate-priomap-v1-1-60a524488672@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mediatek/airoha_eth.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/ethernet/mediatek/airoha_eth.c b/drivers/net/ethernet/mediatek/airoha_eth.c
+index 71975c490822b..0c244ea5244cc 100644
+--- a/drivers/net/ethernet/mediatek/airoha_eth.c
++++ b/drivers/net/ethernet/mediatek/airoha_eth.c
+@@ -2793,7 +2793,7 @@ static int airoha_qdma_set_tx_ets_sched(struct airoha_gdm_port *port,
+       struct tc_ets_qopt_offload_replace_params *p = &opt->replace_params;
+       enum tx_sched_mode mode = TC_SCH_SP;
+       u16 w[AIROHA_NUM_QOS_QUEUES] = {};
+-      int i, nstrict = 0, nwrr, qidx;
++      int i, nstrict = 0;
+       if (p->bands > AIROHA_NUM_QOS_QUEUES)
+               return -EINVAL;
+@@ -2811,17 +2811,17 @@ static int airoha_qdma_set_tx_ets_sched(struct airoha_gdm_port *port,
+        * lowest priorities with respect to SP ones.
+        * e.g: WRR0, WRR1, .., WRRm, SP0, SP1, .., SPn
+        */
+-      nwrr = p->bands - nstrict;
+-      qidx = nstrict && nwrr ? nstrict : 0;
+-      for (i = 1; i <= p->bands; i++) {
+-              if (p->priomap[i % AIROHA_NUM_QOS_QUEUES] != qidx)
++      for (i = 0; i < nstrict; i++) {
++              if (p->priomap[p->bands - i - 1] != i)
+                       return -EINVAL;
+-
+-              qidx = i == nwrr ? 0 : qidx + 1;
+       }
+-      for (i = 0; i < nwrr; i++)
++      for (i = 0; i < p->bands - nstrict; i++) {
++              if (p->priomap[i] != nstrict + i)
++                      return -EINVAL;
++
+               w[i] = p->weights[nstrict + i];
++      }
+       if (!nstrict)
+               mode = TC_SCH_WRR8;
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-airoha-fix-lan4-support-in-airoha_qdma_get_gdm_p.patch b/queue-6.14/net-airoha-fix-lan4-support-in-airoha_qdma_get_gdm_p.patch
new file mode 100644 (file)
index 0000000..9f815fd
--- /dev/null
@@ -0,0 +1,38 @@
+From 89136f833925ba92ee114393e8226c8e9616ff8e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Mar 2025 15:38:05 +0100
+Subject: net: airoha: Fix lan4 support in airoha_qdma_get_gdm_port()
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit 35ea4f06fd33fc32f556a0c26d1d8340497fa7f8 ]
+
+EN7581 SoC supports lan{1,4} ports on MT7530 DSA switch. Fix lan4
+reported value in airoha_qdma_get_gdm_port routine.
+
+Fixes: 23020f0493270 ("net: airoha: Introduce ethernet support for EN7581 SoC")
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250304-airoha-eth-fix-lan4-v1-1-832417da4bb5@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mediatek/airoha_eth.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mediatek/airoha_eth.c b/drivers/net/ethernet/mediatek/airoha_eth.c
+index 09f448f291240..c1c2ab82a08d8 100644
+--- a/drivers/net/ethernet/mediatek/airoha_eth.c
++++ b/drivers/net/ethernet/mediatek/airoha_eth.c
+@@ -1547,7 +1547,7 @@ static int airoha_qdma_get_gdm_port(struct airoha_eth *eth,
+       sport = FIELD_GET(QDMA_ETH_RXMSG_SPORT_MASK, msg1);
+       switch (sport) {
+-      case 0x10 ... 0x13:
++      case 0x10 ... 0x14:
+               port = 0;
+               break;
+       case 0x2 ... 0x4:
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-airoha-fix-qid-report-in-airoha_tc_get_htb_get_l.patch b/queue-6.14/net-airoha-fix-qid-report-in-airoha_tc_get_htb_get_l.patch
new file mode 100644 (file)
index 0000000..655b00e
--- /dev/null
@@ -0,0 +1,86 @@
+From 9f7b715607deb46570225567057fb12fefb6dc9e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Mar 2025 08:52:53 +0200
+Subject: net: airoha: Fix qid report in airoha_tc_get_htb_get_leaf_queue()
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit 57b290d97c6150774bf929117ca737a26d8fc33d ]
+
+Fix the following kernel warning deleting HTB offloaded leafs and/or root
+HTB qdisc in airoha_eth driver properly reporting qid in
+airoha_tc_get_htb_get_leaf_queue routine.
+
+$tc qdisc replace dev eth1 root handle 10: htb offload
+$tc class add dev eth1 arent 10: classid 10:4 htb rate 100mbit ceil 100mbit
+$tc qdisc replace dev eth1 parent 10:4 handle 4: ets bands 8 \
+ quanta 1514 3028 4542 6056 7570 9084 10598 12112
+$tc qdisc del dev eth1 root
+
+[   55.827864] ------------[ cut here ]------------
+[   55.832493] WARNING: CPU: 3 PID: 2678 at 0xffffffc0798695a4
+[   55.956510] CPU: 3 PID: 2678 Comm: tc Tainted: G           O 6.6.71 #0
+[   55.963557] Hardware name: Airoha AN7581 Evaluation Board (DT)
+[   55.969383] pstate: 20400005 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+[   55.976344] pc : 0xffffffc0798695a4
+[   55.979851] lr : 0xffffffc079869a20
+[   55.983358] sp : ffffffc0850536a0
+[   55.986665] x29: ffffffc0850536a0 x28: 0000000000000024 x27: 0000000000000001
+[   55.993800] x26: 0000000000000000 x25: ffffff8008b19000 x24: ffffff800222e800
+[   56.000935] x23: 0000000000000001 x22: 0000000000000000 x21: ffffff8008b19000
+[   56.008071] x20: ffffff8002225800 x19: ffffff800379d000 x18: 0000000000000000
+[   56.015206] x17: ffffffbf9ea59000 x16: ffffffc080018000 x15: 0000000000000000
+[   56.022342] x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000001
+[   56.029478] x11: ffffffc081471008 x10: ffffffc081575a98 x9 : 0000000000000000
+[   56.036614] x8 : ffffffc08167fd40 x7 : ffffffc08069e104 x6 : ffffff8007f86000
+[   56.043748] x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000001
+[   56.050884] x2 : 0000000000000000 x1 : 0000000000000250 x0 : ffffff800222c000
+[   56.058020] Call trace:
+[   56.060459]  0xffffffc0798695a4
+[   56.063618]  0xffffffc079869a20
+[   56.066777]  __qdisc_destroy+0x40/0xa0
+[   56.070528]  qdisc_put+0x54/0x6c
+[   56.073748]  qdisc_graft+0x41c/0x648
+[   56.077324]  tc_get_qdisc+0x168/0x2f8
+[   56.080978]  rtnetlink_rcv_msg+0x230/0x330
+[   56.085076]  netlink_rcv_skb+0x5c/0x128
+[   56.088913]  rtnetlink_rcv+0x14/0x1c
+[   56.092490]  netlink_unicast+0x1e0/0x2c8
+[   56.096413]  netlink_sendmsg+0x198/0x3c8
+[   56.100337]  ____sys_sendmsg+0x1c4/0x274
+[   56.104261]  ___sys_sendmsg+0x7c/0xc0
+[   56.107924]  __sys_sendmsg+0x44/0x98
+[   56.111492]  __arm64_sys_sendmsg+0x20/0x28
+[   56.115580]  invoke_syscall.constprop.0+0x58/0xfc
+[   56.120285]  do_el0_svc+0x3c/0xbc
+[   56.123592]  el0_svc+0x18/0x4c
+[   56.126647]  el0t_64_sync_handler+0x118/0x124
+[   56.131005]  el0t_64_sync+0x150/0x154
+[   56.134660] ---[ end trace 0000000000000000 ]---
+
+Fixes: ef1ca9271313b ("net: airoha: Add sched HTB offload support")
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Acked-by: Paolo Abeni <pabeni@redhat.com>
+Link: https://patch.msgid.link/20250331-airoha-htb-qdisc-offload-del-fix-v1-1-4ea429c2c968@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mediatek/airoha_eth.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mediatek/airoha_eth.c b/drivers/net/ethernet/mediatek/airoha_eth.c
+index c1c2ab82a08d8..71975c490822b 100644
+--- a/drivers/net/ethernet/mediatek/airoha_eth.c
++++ b/drivers/net/ethernet/mediatek/airoha_eth.c
+@@ -3082,7 +3082,7 @@ static int airoha_tc_get_htb_get_leaf_queue(struct airoha_gdm_port *port,
+               return -EINVAL;
+       }
+-      opt->qid = channel;
++      opt->qid = AIROHA_NUM_TX_RING + channel;
+       return 0;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-decrease-cached-dst-counters-in-dst_release.patch b/queue-6.14/net-decrease-cached-dst-counters-in-dst_release.patch
new file mode 100644 (file)
index 0000000..447538c
--- /dev/null
@@ -0,0 +1,61 @@
+From b64ad2d47b3f0cdb15f682bc76f600148d3cdbce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Mar 2025 18:36:32 +0100
+Subject: net: decrease cached dst counters in dst_release
+
+From: Antoine Tenart <atenart@kernel.org>
+
+[ Upstream commit 3a0a3ff6593d670af2451ec363ccb7b18aec0c0a ]
+
+Upstream fix ac888d58869b ("net: do not delay dst_entries_add() in
+dst_release()") moved decrementing the dst count from dst_destroy to
+dst_release to avoid accessing already freed data in case of netns
+dismantle. However in case CONFIG_DST_CACHE is enabled and OvS+tunnels
+are used, this fix is incomplete as the same issue will be seen for
+cached dsts:
+
+  Unable to handle kernel paging request at virtual address ffff5aabf6b5c000
+  Call trace:
+   percpu_counter_add_batch+0x3c/0x160 (P)
+   dst_release+0xec/0x108
+   dst_cache_destroy+0x68/0xd8
+   dst_destroy+0x13c/0x168
+   dst_destroy_rcu+0x1c/0xb0
+   rcu_do_batch+0x18c/0x7d0
+   rcu_core+0x174/0x378
+   rcu_core_si+0x18/0x30
+
+Fix this by invalidating the cache, and thus decrementing cached dst
+counters, in dst_release too.
+
+Fixes: d71785ffc7e7 ("net: add dst_cache to ovs vxlan lwtunnel")
+Signed-off-by: Antoine Tenart <atenart@kernel.org>
+Link: https://patch.msgid.link/20250326173634.31096-1-atenart@kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/dst.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/net/core/dst.c b/net/core/dst.c
+index 9552a90d4772d..6d76b799ce645 100644
+--- a/net/core/dst.c
++++ b/net/core/dst.c
+@@ -165,6 +165,14 @@ static void dst_count_dec(struct dst_entry *dst)
+ void dst_release(struct dst_entry *dst)
+ {
+       if (dst && rcuref_put(&dst->__rcuref)) {
++#ifdef CONFIG_DST_CACHE
++              if (dst->flags & DST_METADATA) {
++                      struct metadata_dst *md_dst = (struct metadata_dst *)dst;
++
++                      if (md_dst->type == METADATA_IP_TUNNEL)
++                              dst_cache_reset_now(&md_dst->u.tun_info.dst_cache);
++              }
++#endif
+               dst_count_dec(dst);
+               call_rcu_hurry(&dst->rcu_head, dst_destroy_rcu);
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-dsa-microchip-fix-dcb-apptrust-configuration-on-.patch b/queue-6.14/net-dsa-microchip-fix-dcb-apptrust-configuration-on-.patch
new file mode 100644 (file)
index 0000000..e86e8bb
--- /dev/null
@@ -0,0 +1,350 @@
+From 53a7953258486502a86652ae942e7323176ebef1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Mar 2025 15:10:44 +0100
+Subject: net: dsa: microchip: fix DCB apptrust configuration on KSZ88x3
+
+From: Oleksij Rempel <o.rempel@pengutronix.de>
+
+[ Upstream commit 1ae1d705a1120e8e0ca41698c5a0fff6f5290bc1 ]
+
+Remove KSZ88x3-specific priority and apptrust configuration logic that was
+based on incorrect register access assumptions. Also fix the register
+offset for KSZ8_REG_PORT_1_CTRL_0 to align with get_port_addr() logic.
+
+The KSZ88x3 switch family uses a different register layout compared to
+KSZ9477-compatible variants. Specifically, port control registers need
+offset adjustment through get_port_addr(), and do not match the datasheet
+values directly.
+
+Commit a1ea57710c9d ("net: dsa: microchip: dcb: add special handling for
+KSZ88X3 family") introduced quirks based on datasheet offsets, which do
+not work with the driver's internal addressing model. As a result, these
+quirks addressed the wrong ports and caused unstable behavior.
+
+This patch removes all KSZ88x3-specific DCB quirks and corrects the port
+control register offset, effectively restoring working and predictable
+apptrust configuration.
+
+Fixes: a1ea57710c9d ("net: dsa: microchip: dcb: add special handling for KSZ88X3 family")
+Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250321141044.2128973-1-o.rempel@pengutronix.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/microchip/ksz8.c    |  11 +-
+ drivers/net/dsa/microchip/ksz_dcb.c | 231 +---------------------------
+ 2 files changed, 9 insertions(+), 233 deletions(-)
+
+diff --git a/drivers/net/dsa/microchip/ksz8.c b/drivers/net/dsa/microchip/ksz8.c
+index da7110d675583..be433b4e2b1ca 100644
+--- a/drivers/net/dsa/microchip/ksz8.c
++++ b/drivers/net/dsa/microchip/ksz8.c
+@@ -1625,7 +1625,6 @@ void ksz8_port_setup(struct ksz_device *dev, int port, bool cpu_port)
+       const u16 *regs = dev->info->regs;
+       struct dsa_switch *ds = dev->ds;
+       const u32 *masks;
+-      int queues;
+       u8 member;
+       masks = dev->info->masks;
+@@ -1633,15 +1632,7 @@ void ksz8_port_setup(struct ksz_device *dev, int port, bool cpu_port)
+       /* enable broadcast storm limit */
+       ksz_port_cfg(dev, port, P_BCAST_STORM_CTRL, PORT_BROADCAST_STORM, true);
+-      /* For KSZ88x3 enable only one queue by default, otherwise we won't
+-       * be able to get rid of PCP prios on Port 2.
+-       */
+-      if (ksz_is_ksz88x3(dev))
+-              queues = 1;
+-      else
+-              queues = dev->info->num_tx_queues;
+-
+-      ksz8_port_queue_split(dev, port, queues);
++      ksz8_port_queue_split(dev, port, dev->info->num_tx_queues);
+       /* replace priority */
+       ksz_port_cfg(dev, port, P_802_1P_CTRL,
+diff --git a/drivers/net/dsa/microchip/ksz_dcb.c b/drivers/net/dsa/microchip/ksz_dcb.c
+index 30b4a6186e38f..c3b501997ac94 100644
+--- a/drivers/net/dsa/microchip/ksz_dcb.c
++++ b/drivers/net/dsa/microchip/ksz_dcb.c
+@@ -10,7 +10,12 @@
+ #include "ksz_dcb.h"
+ #include "ksz8.h"
+-#define KSZ8_REG_PORT_1_CTRL_0                        0x10
++/* Port X Control 0 register.
++ * The datasheet specifies: Port 1 - 0x10, Port 2 - 0x20, Port 3 - 0x30.
++ * However, the driver uses get_port_addr(), which maps Port 1 to offset 0.
++ * Therefore, we define the base offset as 0x00 here to align with that logic.
++ */
++#define KSZ8_REG_PORT_1_CTRL_0                        0x00
+ #define KSZ8_PORT_DIFFSERV_ENABLE             BIT(6)
+ #define KSZ8_PORT_802_1P_ENABLE                       BIT(5)
+ #define KSZ8_PORT_BASED_PRIO_M                        GENMASK(4, 3)
+@@ -181,49 +186,6 @@ int ksz_port_get_default_prio(struct dsa_switch *ds, int port)
+       return (data & mask) >> shift;
+ }
+-/**
+- * ksz88x3_port_set_default_prio_quirks - Quirks for default priority
+- * @dev: Pointer to the KSZ switch device structure
+- * @port: Port number for which to set the default priority
+- * @prio: Priority value to set
+- *
+- * This function implements quirks for setting the default priority on KSZ88x3
+- * devices. On Port 2, no other priority providers are working
+- * except of PCP. So, configuring default priority on Port 2 is not possible.
+- * On Port 1, it is not possible to configure port priority if PCP
+- * apptrust on Port 2 is disabled. Since we disable multiple queues on the
+- * switch to disable PCP on Port 2, we need to ensure that the default priority
+- * configuration on Port 1 is in agreement with the configuration on Port 2.
+- *
+- * Return: 0 on success, or a negative error code on failure
+- */
+-static int ksz88x3_port_set_default_prio_quirks(struct ksz_device *dev, int port,
+-                                              u8 prio)
+-{
+-      if (!prio)
+-              return 0;
+-
+-      if (port == KSZ_PORT_2) {
+-              dev_err(dev->dev, "Port priority configuration is not working on Port 2\n");
+-              return -EINVAL;
+-      } else if (port == KSZ_PORT_1) {
+-              u8 port2_data;
+-              int ret;
+-
+-              ret = ksz_pread8(dev, KSZ_PORT_2, KSZ8_REG_PORT_1_CTRL_0,
+-                               &port2_data);
+-              if (ret)
+-                      return ret;
+-
+-              if (!(port2_data & KSZ8_PORT_802_1P_ENABLE)) {
+-                      dev_err(dev->dev, "Not possible to configure port priority on Port 1 if PCP apptrust on Port 2 is disabled\n");
+-                      return -EINVAL;
+-              }
+-      }
+-
+-      return 0;
+-}
+-
+ /**
+  * ksz_port_set_default_prio - Sets the default priority for a port on a KSZ
+  *                           switch
+@@ -239,18 +201,12 @@ static int ksz88x3_port_set_default_prio_quirks(struct ksz_device *dev, int port
+ int ksz_port_set_default_prio(struct dsa_switch *ds, int port, u8 prio)
+ {
+       struct ksz_device *dev = ds->priv;
+-      int reg, shift, ret;
++      int reg, shift;
+       u8 mask;
+       if (prio >= dev->info->num_ipms)
+               return -EINVAL;
+-      if (ksz_is_ksz88x3(dev)) {
+-              ret = ksz88x3_port_set_default_prio_quirks(dev, port, prio);
+-              if (ret)
+-                      return ret;
+-      }
+-
+       ksz_get_default_port_prio_reg(dev, &reg, &mask, &shift);
+       return ksz_prmw8(dev, port, reg, mask, (prio << shift) & mask);
+@@ -518,155 +474,6 @@ static int ksz_port_set_apptrust_validate(struct ksz_device *dev, int port,
+       return -EINVAL;
+ }
+-/**
+- * ksz88x3_port1_apptrust_quirk - Quirk for apptrust configuration on Port 1
+- *                              of KSZ88x3 devices
+- * @dev: Pointer to the KSZ switch device structure
+- * @port: Port number for which to set the apptrust selectors
+- * @reg: Register address for the apptrust configuration
+- * @port1_data: Data to set for the apptrust configuration
+- *
+- * This function implements a quirk for apptrust configuration on Port 1 of
+- * KSZ88x3 devices. It ensures that apptrust configuration on Port 1 is not
+- * possible if PCP apptrust on Port 2 is disabled. This is because the Port 2
+- * seems to be permanently hardwired to PCP classification, so we need to
+- * do Port 1 configuration always in agreement with Port 2 configuration.
+- *
+- * Return: 0 on success, or a negative error code on failure
+- */
+-static int ksz88x3_port1_apptrust_quirk(struct ksz_device *dev, int port,
+-                                      int reg, u8 port1_data)
+-{
+-      u8 port2_data;
+-      int ret;
+-
+-      /* If no apptrust is requested for Port 1, no need to care about Port 2
+-       * configuration.
+-       */
+-      if (!(port1_data & (KSZ8_PORT_802_1P_ENABLE | KSZ8_PORT_DIFFSERV_ENABLE)))
+-              return 0;
+-
+-      /* We got request to enable any apptrust on Port 1. To make it possible,
+-       * we need to enable multiple queues on the switch. If we enable
+-       * multiqueue support, PCP classification on Port 2 will be
+-       * automatically activated by HW.
+-       */
+-      ret = ksz_pread8(dev, KSZ_PORT_2, reg, &port2_data);
+-      if (ret)
+-              return ret;
+-
+-      /* If KSZ8_PORT_802_1P_ENABLE bit is set on Port 2, the driver showed
+-       * the interest in PCP classification on Port 2. In this case,
+-       * multiqueue support is enabled and we can enable any apptrust on
+-       * Port 1.
+-       * If KSZ8_PORT_802_1P_ENABLE bit is not set on Port 2, the PCP
+-       * classification on Port 2 is still active, but the driver disabled
+-       * multiqueue support and made frame prioritization inactive for
+-       * all ports. In this case, we can't enable any apptrust on Port 1.
+-       */
+-      if (!(port2_data & KSZ8_PORT_802_1P_ENABLE)) {
+-              dev_err(dev->dev, "Not possible to enable any apptrust on Port 1 if PCP apptrust on Port 2 is disabled\n");
+-              return -EINVAL;
+-      }
+-
+-      return 0;
+-}
+-
+-/**
+- * ksz88x3_port2_apptrust_quirk - Quirk for apptrust configuration on Port 2
+- *                              of KSZ88x3 devices
+- * @dev: Pointer to the KSZ switch device structure
+- * @port: Port number for which to set the apptrust selectors
+- * @reg: Register address for the apptrust configuration
+- * @port2_data: Data to set for the apptrust configuration
+- *
+- * This function implements a quirk for apptrust configuration on Port 2 of
+- * KSZ88x3 devices. It ensures that DSCP apptrust is not working on Port 2 and
+- * that it is not possible to disable PCP on Port 2. The only way to disable PCP
+- * on Port 2 is to disable multiple queues on the switch.
+- *
+- * Return: 0 on success, or a negative error code on failure
+- */
+-static int ksz88x3_port2_apptrust_quirk(struct ksz_device *dev, int port,
+-                                      int reg, u8 port2_data)
+-{
+-      struct dsa_switch *ds = dev->ds;
+-      u8 port1_data;
+-      int ret;
+-
+-      /* First validate Port 2 configuration. DiffServ/DSCP is not working
+-       * on this port.
+-       */
+-      if (port2_data & KSZ8_PORT_DIFFSERV_ENABLE) {
+-              dev_err(dev->dev, "DSCP apptrust is not working on Port 2\n");
+-              return -EINVAL;
+-      }
+-
+-      /* If PCP support is requested, we need to enable all queues on the
+-       * switch to make PCP priority working on Port 2.
+-       */
+-      if (port2_data & KSZ8_PORT_802_1P_ENABLE)
+-              return ksz8_all_queues_split(dev, dev->info->num_tx_queues);
+-
+-      /* We got request to disable PCP priority on Port 2.
+-       * Now, we need to compare Port 2 configuration with Port 1
+-       * configuration.
+-       */
+-      ret = ksz_pread8(dev, KSZ_PORT_1, reg, &port1_data);
+-      if (ret)
+-              return ret;
+-
+-      /* If Port 1 has any apptrust enabled, we can't disable multiple queues
+-       * on the switch, so we can't disable PCP on Port 2.
+-       */
+-      if (port1_data & (KSZ8_PORT_802_1P_ENABLE | KSZ8_PORT_DIFFSERV_ENABLE)) {
+-              dev_err(dev->dev, "Not possible to disable PCP on Port 2 if any apptrust is enabled on Port 1\n");
+-              return -EINVAL;
+-      }
+-
+-      /* Now we need to ensure that default priority on Port 1 is set to 0
+-       * otherwise we can't disable multiqueue support on the switch.
+-       */
+-      ret = ksz_port_get_default_prio(ds, KSZ_PORT_1);
+-      if (ret < 0) {
+-              return ret;
+-      } else if (ret) {
+-              dev_err(dev->dev, "Not possible to disable PCP on Port 2 if non zero default priority is set on Port 1\n");
+-              return -EINVAL;
+-      }
+-
+-      /* Port 1 has no apptrust or default priority set and we got request to
+-       * disable PCP on Port 2. We can disable multiqueue support to disable
+-       * PCP on Port 2.
+-       */
+-      return ksz8_all_queues_split(dev, 1);
+-}
+-
+-/**
+- * ksz88x3_port_apptrust_quirk - Quirk for apptrust configuration on KSZ88x3
+- *                           devices
+- * @dev: Pointer to the KSZ switch device structure
+- * @port: Port number for which to set the apptrust selectors
+- * @reg: Register address for the apptrust configuration
+- * @data: Data to set for the apptrust configuration
+- *
+- * This function implements a quirk for apptrust configuration on KSZ88x3
+- * devices. It ensures that apptrust configuration on Port 1 and
+- * Port 2 is done in agreement with each other.
+- *
+- * Return: 0 on success, or a negative error code on failure
+- */
+-static int ksz88x3_port_apptrust_quirk(struct ksz_device *dev, int port,
+-                                     int reg, u8 data)
+-{
+-      if (port == KSZ_PORT_1)
+-              return ksz88x3_port1_apptrust_quirk(dev, port, reg, data);
+-      else if (port == KSZ_PORT_2)
+-              return ksz88x3_port2_apptrust_quirk(dev, port, reg, data);
+-
+-      return 0;
+-}
+-
+ /**
+  * ksz_port_set_apptrust - Sets the apptrust selectors for a port on a KSZ
+  *                       switch
+@@ -707,12 +514,6 @@ int ksz_port_set_apptrust(struct dsa_switch *ds, int port,
+               }
+       }
+-      if (ksz_is_ksz88x3(dev)) {
+-              ret = ksz88x3_port_apptrust_quirk(dev, port, reg, data);
+-              if (ret)
+-                      return ret;
+-      }
+-
+       return ksz_prmw8(dev, port, reg, mask, data);
+ }
+@@ -799,21 +600,5 @@ int ksz_dcb_init_port(struct ksz_device *dev, int port)
+  */
+ int ksz_dcb_init(struct ksz_device *dev)
+ {
+-      int ret;
+-
+-      ret = ksz_init_global_dscp_map(dev);
+-      if (ret)
+-              return ret;
+-
+-      /* Enable 802.1p priority control on Port 2 during switch initialization.
+-       * This setup is critical for the apptrust functionality on Port 1, which
+-       * relies on the priority settings of Port 2. Note: Port 1 is naturally
+-       * configured before Port 2, necessitating this configuration order.
+-       */
+-      if (ksz_is_ksz88x3(dev))
+-              return ksz_prmw8(dev, KSZ_PORT_2, KSZ8_REG_PORT_1_CTRL_0,
+-                               KSZ8_PORT_802_1P_ENABLE,
+-                               KSZ8_PORT_802_1P_ENABLE);
+-
+-      return 0;
++      return ksz_init_global_dscp_map(dev);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-dsa-mv88e6xxx-enable-.port_set_policy-for-6320-f.patch b/queue-6.14/net-dsa-mv88e6xxx-enable-.port_set_policy-for-6320-f.patch
new file mode 100644 (file)
index 0000000..28c61bf
--- /dev/null
@@ -0,0 +1,48 @@
+From c9b8afc72b78bcce9f59702142756ee42e50e593 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Mar 2025 18:32:47 +0100
+Subject: net: dsa: mv88e6xxx: enable .port_set_policy() for 6320 family
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Marek Behún <kabel@kernel.org>
+
+[ Upstream commit a2ef58e2c4aea4de166fc9832eb2b621e88c98d5 ]
+
+Commit f3a2cd326e44 ("net: dsa: mv88e6xxx: introduce .port_set_policy")
+did not add the .port_set_policy() method for the 6320 family. Fix it.
+
+Fixes: f3a2cd326e44 ("net: dsa: mv88e6xxx: introduce .port_set_policy")
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250317173250.28780-5-kabel@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/mv88e6xxx/chip.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
+index d8f037da5e294..b110704a7ee9a 100644
+--- a/drivers/net/dsa/mv88e6xxx/chip.c
++++ b/drivers/net/dsa/mv88e6xxx/chip.c
+@@ -5145,6 +5145,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
+       .port_set_rgmii_delay = mv88e6320_port_set_rgmii_delay,
+       .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
+       .port_tag_remap = mv88e6095_port_tag_remap,
++      .port_set_policy = mv88e6352_port_set_policy,
+       .port_set_frame_mode = mv88e6351_port_set_frame_mode,
+       .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
+       .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
+@@ -5194,6 +5195,7 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
+       .port_set_rgmii_delay = mv88e6320_port_set_rgmii_delay,
+       .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
+       .port_tag_remap = mv88e6095_port_tag_remap,
++      .port_set_policy = mv88e6352_port_set_policy,
+       .port_set_frame_mode = mv88e6351_port_set_frame_mode,
+       .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
+       .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-dsa-mv88e6xxx-enable-pvt-for-6321-switch.patch b/queue-6.14/net-dsa-mv88e6xxx-enable-pvt-for-6321-switch.patch
new file mode 100644 (file)
index 0000000..56a5e44
--- /dev/null
@@ -0,0 +1,40 @@
+From 6af543af31c19d15662ff618802e9ef548120b46 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Mar 2025 18:32:46 +0100
+Subject: net: dsa: mv88e6xxx: enable PVT for 6321 switch
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Marek Behún <kabel@kernel.org>
+
+[ Upstream commit f85c69369854a43af2c5d3b3896da0908d713133 ]
+
+Commit f36456522168 ("net: dsa: mv88e6xxx: move PVT description in
+info") did not enable PVT for 6321 switch. Fix it.
+
+Fixes: f36456522168 ("net: dsa: mv88e6xxx: move PVT description in info")
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250317173250.28780-4-kabel@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/mv88e6xxx/chip.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
+index 841da8437738c..d8f037da5e294 100644
+--- a/drivers/net/dsa/mv88e6xxx/chip.c
++++ b/drivers/net/dsa/mv88e6xxx/chip.c
+@@ -6274,6 +6274,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+               .g2_irqs = 10,
+               .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
+               .atu_move_port_mask = 0xf,
++              .pvt = true,
+               .multi_chip = true,
+               .edsa_support = MV88E6XXX_EDSA_SUPPORTED,
+               .ptp_support = true,
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-dsa-mv88e6xxx-enable-stu-methods-for-6320-family.patch b/queue-6.14/net-dsa-mv88e6xxx-enable-stu-methods-for-6320-family.patch
new file mode 100644 (file)
index 0000000..a1257c0
--- /dev/null
@@ -0,0 +1,67 @@
+From 3311351fe6e7d277417a1159716ab2ed0daa1aec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Mar 2025 18:32:48 +0100
+Subject: net: dsa: mv88e6xxx: enable STU methods for 6320 family
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Marek Behún <kabel@kernel.org>
+
+[ Upstream commit 1428a6109b20e356188c3fb027bdb7998cc2fb98 ]
+
+Commit c050f5e91b47 ("net: dsa: mv88e6xxx: Fill in STU support for all
+supported chips") introduced STU methods, but did not add them to the
+6320 family. Fix it.
+
+Fixes: c050f5e91b47 ("net: dsa: mv88e6xxx: Fill in STU support for all supported chips")
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250317173250.28780-6-kabel@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/mv88e6xxx/chip.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
+index f886a69d7a3ce..74b8bae226e4b 100644
+--- a/drivers/net/dsa/mv88e6xxx/chip.c
++++ b/drivers/net/dsa/mv88e6xxx/chip.c
+@@ -5172,6 +5172,8 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
+       .reset = mv88e6352_g1_reset,
+       .vtu_getnext = mv88e6352_g1_vtu_getnext,
+       .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
++      .stu_getnext = mv88e6352_g1_stu_getnext,
++      .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
+       .gpio_ops = &mv88e6352_gpio_ops,
+       .avb_ops = &mv88e6352_avb_ops,
+       .ptp_ops = &mv88e6352_ptp_ops,
+@@ -5221,6 +5223,8 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
+       .reset = mv88e6352_g1_reset,
+       .vtu_getnext = mv88e6352_g1_vtu_getnext,
+       .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
++      .stu_getnext = mv88e6352_g1_stu_getnext,
++      .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
+       .gpio_ops = &mv88e6352_gpio_ops,
+       .avb_ops = &mv88e6352_avb_ops,
+       .ptp_ops = &mv88e6352_ptp_ops,
+@@ -6241,6 +6245,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+               .num_internal_phys = 5,
+               .num_gpio = 15,
+               .max_vid = 4095,
++              .max_sid = 63,
+               .port_base_addr = 0x10,
+               .phy_base_addr = 0x0,
+               .global1_addr = 0x1b,
+@@ -6267,6 +6272,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+               .num_internal_phys = 5,
+               .num_gpio = 15,
+               .max_vid = 4095,
++              .max_sid = 63,
+               .port_base_addr = 0x10,
+               .phy_base_addr = 0x0,
+               .global1_addr = 0x1b,
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-dsa-mv88e6xxx-fix-atu_move_port_mask-for-6341-fa.patch b/queue-6.14/net-dsa-mv88e6xxx-fix-atu_move_port_mask-for-6341-fa.patch
new file mode 100644 (file)
index 0000000..b05585f
--- /dev/null
@@ -0,0 +1,50 @@
+From 43ada44a88e834e6f983b9d606f0377f2e37ed31 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Mar 2025 18:32:45 +0100
+Subject: net: dsa: mv88e6xxx: fix atu_move_port_mask for 6341 family
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Marek Behún <kabel@kernel.org>
+
+[ Upstream commit 4ae01ec007716986e1a20f1285eb013cbf188830 ]
+
+The atu_move_port_mask for 6341 family (Topaz) is 0xf, not 0x1f. The
+PortVec field is 8 bits wide, not 11 as in 6390 family. Fix this.
+
+Fixes: e606ca36bbf2 ("net: dsa: mv88e6xxx: rework ATU Remove")
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250317173250.28780-3-kabel@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/mv88e6xxx/chip.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
+index 5db96ca52505a..841da8437738c 100644
+--- a/drivers/net/dsa/mv88e6xxx/chip.c
++++ b/drivers/net/dsa/mv88e6xxx/chip.c
+@@ -5818,7 +5818,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+               .global1_addr = 0x1b,
+               .global2_addr = 0x1c,
+               .age_time_coeff = 3750,
+-              .atu_move_port_mask = 0x1f,
++              .atu_move_port_mask = 0xf,
+               .g1_irqs = 9,
+               .g2_irqs = 10,
+               .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
+@@ -6296,7 +6296,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+               .global1_addr = 0x1b,
+               .global2_addr = 0x1c,
+               .age_time_coeff = 3750,
+-              .atu_move_port_mask = 0x1f,
++              .atu_move_port_mask = 0xf,
+               .g1_irqs = 9,
+               .g2_irqs = 10,
+               .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-dsa-mv88e6xxx-fix-vtu-methods-for-6320-family.patch b/queue-6.14/net-dsa-mv88e6xxx-fix-vtu-methods-for-6320-family.patch
new file mode 100644 (file)
index 0000000..bf61219
--- /dev/null
@@ -0,0 +1,56 @@
+From 117d552a354513ee07e18e5f582951e6390040d5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Mar 2025 18:32:44 +0100
+Subject: net: dsa: mv88e6xxx: fix VTU methods for 6320 family
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Marek Behún <kabel@kernel.org>
+
+[ Upstream commit f9a457722cf5e3534be5ffab549d6b49737fca72 ]
+
+The VTU registers of the 6320 family use the 6352 semantics, not 6185.
+Fix it.
+
+Fixes: b8fee9571063 ("net: dsa: mv88e6xxx: add VLAN Get Next support")
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Cc: <stable@vger.kernel.org> # 5.15.x
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250317173250.28780-2-kabel@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 1428a6109b20 ("net: dsa: mv88e6xxx: enable STU methods for 6320 family")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/mv88e6xxx/chip.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
+index b110704a7ee9a..f886a69d7a3ce 100644
+--- a/drivers/net/dsa/mv88e6xxx/chip.c
++++ b/drivers/net/dsa/mv88e6xxx/chip.c
+@@ -5170,8 +5170,8 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
+       .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
+       .hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
+       .reset = mv88e6352_g1_reset,
+-      .vtu_getnext = mv88e6185_g1_vtu_getnext,
+-      .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
++      .vtu_getnext = mv88e6352_g1_vtu_getnext,
++      .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
+       .gpio_ops = &mv88e6352_gpio_ops,
+       .avb_ops = &mv88e6352_avb_ops,
+       .ptp_ops = &mv88e6352_ptp_ops,
+@@ -5219,8 +5219,8 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
+       .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
+       .hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
+       .reset = mv88e6352_g1_reset,
+-      .vtu_getnext = mv88e6185_g1_vtu_getnext,
+-      .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
++      .vtu_getnext = mv88e6352_g1_vtu_getnext,
++      .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
+       .gpio_ops = &mv88e6352_gpio_ops,
+       .avb_ops = &mv88e6352_avb_ops,
+       .ptp_ops = &mv88e6352_ptp_ops,
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-dsa-mv88e6xxx-propperly-shutdown-ppu-re-enable-t.patch b/queue-6.14/net-dsa-mv88e6xxx-propperly-shutdown-ppu-re-enable-t.patch
new file mode 100644 (file)
index 0000000..f3cedb0
--- /dev/null
@@ -0,0 +1,126 @@
+From bb4f685e245692536c6be854a8b3dc316ca67da2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 15:56:37 +0200
+Subject: net: dsa: mv88e6xxx: propperly shutdown PPU re-enable timer on
+ destroy
+
+From: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
+
+[ Upstream commit a58d882841a0750da3c482cd3d82432b1c7edb77 ]
+
+The mv88e6xxx has an internal PPU that polls PHY state. If we want to
+access the internal PHYs, we need to disable the PPU first. Because
+that is a slow operation, a 10ms timer is used to re-enable it,
+canceled with every access, so bulk operations effectively only
+disable it once and re-enable it some 10ms after the last access.
+
+If a PHY is accessed and then the mv88e6xxx module is removed before
+the 10ms are up, the PPU re-enable ends up accessing a dangling pointer.
+
+This especially affects probing during bootup. The MDIO bus and PHY
+registration may succeed, but registration with the DSA framework
+may fail later on (e.g. because the CPU port depends on another,
+very slow device that isn't done probing yet, returning -EPROBE_DEFER).
+In this case, probe() fails, but the MDIO subsystem may already have
+accessed the MIDO bus or PHYs, arming the timer.
+
+This is fixed as follows:
+ - If probe fails after mv88e6xxx_phy_init(), make sure we also call
+   mv88e6xxx_phy_destroy() before returning
+ - In mv88e6xxx_remove(), make sure we do the teardown in the correct
+   order, calling mv88e6xxx_phy_destroy() after unregistering the
+   switch device.
+ - In mv88e6xxx_phy_destroy(), destroy both the timer and the work item
+   that the timer might schedule, synchronously waiting in case one of
+   the callbacks already fired and destroying the timer first, before
+   waiting for the work item.
+ - Access to the PPU is guarded by a mutex, the worker acquires it
+   with a mutex_trylock(), not proceeding with the expensive shutdown
+   if that fails. We grab the mutex in mv88e6xxx_phy_destroy() to make
+   sure the slow PPU shutdown is already done or won't even enter, when
+   we wait for the work item.
+
+Fixes: 2e5f032095ff ("dsa: add support for the Marvell 88E6131 switch chip")
+Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Link: https://patch.msgid.link/20250401135705.92760-1-david.oberhollenzer@sigma-star.at
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/mv88e6xxx/chip.c | 11 +++++++----
+ drivers/net/dsa/mv88e6xxx/phy.c  |  3 +++
+ 2 files changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
+index 74b8bae226e4b..4a9fbfa8db41a 100644
+--- a/drivers/net/dsa/mv88e6xxx/chip.c
++++ b/drivers/net/dsa/mv88e6xxx/chip.c
+@@ -7331,13 +7331,13 @@ static int mv88e6xxx_probe(struct mdio_device *mdiodev)
+       err = mv88e6xxx_switch_reset(chip);
+       mv88e6xxx_reg_unlock(chip);
+       if (err)
+-              goto out;
++              goto out_phy;
+       if (np) {
+               chip->irq = of_irq_get(np, 0);
+               if (chip->irq == -EPROBE_DEFER) {
+                       err = chip->irq;
+-                      goto out;
++                      goto out_phy;
+               }
+       }
+@@ -7356,7 +7356,7 @@ static int mv88e6xxx_probe(struct mdio_device *mdiodev)
+       mv88e6xxx_reg_unlock(chip);
+       if (err)
+-              goto out;
++              goto out_phy;
+       if (chip->info->g2_irqs > 0) {
+               err = mv88e6xxx_g2_irq_setup(chip);
+@@ -7390,6 +7390,8 @@ static int mv88e6xxx_probe(struct mdio_device *mdiodev)
+               mv88e6xxx_g1_irq_free(chip);
+       else
+               mv88e6xxx_irq_poll_free(chip);
++out_phy:
++      mv88e6xxx_phy_destroy(chip);
+ out:
+       if (pdata)
+               dev_put(pdata->netdev);
+@@ -7412,7 +7414,6 @@ static void mv88e6xxx_remove(struct mdio_device *mdiodev)
+               mv88e6xxx_ptp_free(chip);
+       }
+-      mv88e6xxx_phy_destroy(chip);
+       mv88e6xxx_unregister_switch(chip);
+       mv88e6xxx_g1_vtu_prob_irq_free(chip);
+@@ -7425,6 +7426,8 @@ static void mv88e6xxx_remove(struct mdio_device *mdiodev)
+               mv88e6xxx_g1_irq_free(chip);
+       else
+               mv88e6xxx_irq_poll_free(chip);
++
++      mv88e6xxx_phy_destroy(chip);
+ }
+ static void mv88e6xxx_shutdown(struct mdio_device *mdiodev)
+diff --git a/drivers/net/dsa/mv88e6xxx/phy.c b/drivers/net/dsa/mv88e6xxx/phy.c
+index 8bb88b3d900db..ee9e5d7e52770 100644
+--- a/drivers/net/dsa/mv88e6xxx/phy.c
++++ b/drivers/net/dsa/mv88e6xxx/phy.c
+@@ -229,7 +229,10 @@ static void mv88e6xxx_phy_ppu_state_init(struct mv88e6xxx_chip *chip)
+ static void mv88e6xxx_phy_ppu_state_destroy(struct mv88e6xxx_chip *chip)
+ {
++      mutex_lock(&chip->ppu_mutex);
+       del_timer_sync(&chip->ppu_timer);
++      cancel_work_sync(&chip->ppu_work);
++      mutex_unlock(&chip->ppu_mutex);
+ }
+ int mv88e6185_phy_ppu_read(struct mv88e6xxx_chip *chip, struct mii_bus *bus,
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-dsa-sja1105-fix-displaced-ethtool-statistics-cou.patch b/queue-6.14/net-dsa-sja1105-fix-displaced-ethtool-statistics-cou.patch
new file mode 100644 (file)
index 0000000..b809128
--- /dev/null
@@ -0,0 +1,63 @@
+From 64c4af0d938a2a0217c0ed07af970d36d6d7c9d2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Mar 2025 13:57:14 +0200
+Subject: net: dsa: sja1105: fix displaced ethtool statistics counters
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 00eb88752f48615ae7b4c1df6f9271cdd62c1d95 ]
+
+Port counters with no name (aka
+sja1105_port_counters[__SJA1105_COUNTER_UNUSED]) are skipped when
+reporting sja1105_get_sset_count(), but are not skipped during
+sja1105_get_strings() and sja1105_get_ethtool_stats().
+
+As a consequence, the first reported counter has an empty name and a
+bogus value (reads from area 0, aka MAC, from offset 0, bits start:end
+0:0). Also, the last counter (N_NOT_REACH on E/T, N_RX_BCAST on P/Q/R/S)
+gets pushed out of the statistics counters that get shown.
+
+Skip __SJA1105_COUNTER_UNUSED consistently, so that the bogus counter
+with an empty name disappears, and in its place appears a valid counter.
+
+Fixes: 039b167d68a3 ("net: dsa: sja1105: don't use burst SPI reads for port statistics")
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250318115716.2124395-2-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/sja1105/sja1105_ethtool.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/dsa/sja1105/sja1105_ethtool.c b/drivers/net/dsa/sja1105/sja1105_ethtool.c
+index 2ea64b1d026d7..84d7d3f66bd03 100644
+--- a/drivers/net/dsa/sja1105/sja1105_ethtool.c
++++ b/drivers/net/dsa/sja1105/sja1105_ethtool.c
+@@ -571,6 +571,9 @@ void sja1105_get_ethtool_stats(struct dsa_switch *ds, int port, u64 *data)
+               max_ctr = __MAX_SJA1105PQRS_PORT_COUNTER;
+       for (i = 0; i < max_ctr; i++) {
++              if (!strlen(sja1105_port_counters[i].name))
++                      continue;
++
+               rc = sja1105_port_counter_read(priv, port, i, &data[k++]);
+               if (rc) {
+                       dev_err(ds->dev,
+@@ -596,8 +599,12 @@ void sja1105_get_strings(struct dsa_switch *ds, int port,
+       else
+               max_ctr = __MAX_SJA1105PQRS_PORT_COUNTER;
+-      for (i = 0; i < max_ctr; i++)
++      for (i = 0; i < max_ctr; i++) {
++              if (!strlen(sja1105_port_counters[i].name))
++                      continue;
++
+               ethtool_puts(&data, sja1105_port_counters[i].name);
++      }
+ }
+ int sja1105_get_sset_count(struct dsa_switch *ds, int port, int sset)
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-dsa-sja1105-fix-kasan-out-of-bounds-warning-in-s.patch b/queue-6.14/net-dsa-sja1105-fix-kasan-out-of-bounds-warning-in-s.patch
new file mode 100644 (file)
index 0000000..11b5127
--- /dev/null
@@ -0,0 +1,51 @@
+From 64610c2066dc397edc6eaf1bfed6081de1606c18 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Mar 2025 13:57:16 +0200
+Subject: net: dsa: sja1105: fix kasan out-of-bounds warning in
+ sja1105_table_delete_entry()
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 5f2b28b79d2d1946ee36ad8b3dc0066f73c90481 ]
+
+There are actually 2 problems:
+- deleting the last element doesn't require the memmove of elements
+  [i + 1, end) over it. Actually, element i+1 is out of bounds.
+- The memmove itself should move size - i - 1 elements, because the last
+  element is out of bounds.
+
+The out-of-bounds element still remains out of bounds after being
+accessed, so the problem is only that we touch it, not that it becomes
+in active use. But I suppose it can lead to issues if the out-of-bounds
+element is part of an unmapped page.
+
+Fixes: 6666cebc5e30 ("net: dsa: sja1105: Add support for VLAN operations")
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250318115716.2124395-4-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/sja1105/sja1105_static_config.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/dsa/sja1105/sja1105_static_config.c b/drivers/net/dsa/sja1105/sja1105_static_config.c
+index 3d790f8c6f4da..ffece8a400a66 100644
+--- a/drivers/net/dsa/sja1105/sja1105_static_config.c
++++ b/drivers/net/dsa/sja1105/sja1105_static_config.c
+@@ -1917,8 +1917,10 @@ int sja1105_table_delete_entry(struct sja1105_table *table, int i)
+       if (i > table->entry_count)
+               return -ERANGE;
+-      memmove(entries + i * entry_size, entries + (i + 1) * entry_size,
+-              (table->entry_count - i) * entry_size);
++      if (i + 1 < table->entry_count) {
++              memmove(entries + i * entry_size, entries + (i + 1) * entry_size,
++                      (table->entry_count - i - 1) * entry_size);
++      }
+       table->entry_count--;
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-dsa-sja1105-reject-other-rx-filters-than-hwtstam.patch b/queue-6.14/net-dsa-sja1105-reject-other-rx-filters-than-hwtstam.patch
new file mode 100644 (file)
index 0000000..853ab55
--- /dev/null
@@ -0,0 +1,83 @@
+From 2e908e279f595687f383f97c900f0b6e2f42a84d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Mar 2025 13:57:15 +0200
+Subject: net: dsa: sja1105: reject other RX filters than
+ HWTSTAMP_FILTER_PTP_V2_L2_EVENT
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit b6a177b559717b707087114e08537fd47a4d1aca ]
+
+This is all that we can support timestamping, so we shouldn't accept
+anything else. Also see sja1105_hwtstamp_get().
+
+To avoid erroring out in an inconsistent state, operate on copies of
+priv->hwts_rx_en and priv->hwts_tx_en, and write them back when nothing
+else can fail anymore.
+
+Fixes: a602afd200f5 ("net: dsa: sja1105: Expose PTP timestamping ioctls to userspace")
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250318115716.2124395-3-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/sja1105/sja1105_ptp.c | 20 +++++++++++++++-----
+ 1 file changed, 15 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/dsa/sja1105/sja1105_ptp.c b/drivers/net/dsa/sja1105/sja1105_ptp.c
+index a1f4ca6ad888f..08b45fdd1d248 100644
+--- a/drivers/net/dsa/sja1105/sja1105_ptp.c
++++ b/drivers/net/dsa/sja1105/sja1105_ptp.c
+@@ -61,17 +61,21 @@ enum sja1105_ptp_clk_mode {
+ int sja1105_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr)
+ {
+       struct sja1105_private *priv = ds->priv;
++      unsigned long hwts_tx_en, hwts_rx_en;
+       struct hwtstamp_config config;
+       if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
+               return -EFAULT;
++      hwts_tx_en = priv->hwts_tx_en;
++      hwts_rx_en = priv->hwts_rx_en;
++
+       switch (config.tx_type) {
+       case HWTSTAMP_TX_OFF:
+-              priv->hwts_tx_en &= ~BIT(port);
++              hwts_tx_en &= ~BIT(port);
+               break;
+       case HWTSTAMP_TX_ON:
+-              priv->hwts_tx_en |= BIT(port);
++              hwts_tx_en |= BIT(port);
+               break;
+       default:
+               return -ERANGE;
+@@ -79,15 +83,21 @@ int sja1105_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr)
+       switch (config.rx_filter) {
+       case HWTSTAMP_FILTER_NONE:
+-              priv->hwts_rx_en &= ~BIT(port);
++              hwts_rx_en &= ~BIT(port);
+               break;
+-      default:
+-              priv->hwts_rx_en |= BIT(port);
++      case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
++              hwts_rx_en |= BIT(port);
+               break;
++      default:
++              return -ERANGE;
+       }
+       if (copy_to_user(ifr->ifr_data, &config, sizeof(config)))
+               return -EFAULT;
++
++      priv->hwts_tx_en = hwts_tx_en;
++      priv->hwts_rx_en = hwts_rx_en;
++
+       return 0;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-fix-geneve_opt-length-integer-overflow.patch b/queue-6.14/net-fix-geneve_opt-length-integer-overflow.patch
new file mode 100644 (file)
index 0000000..e37181f
--- /dev/null
@@ -0,0 +1,134 @@
+From 7dc5d98df94af67f0655d53b08e208079378da72 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Apr 2025 00:56:32 +0800
+Subject: net: fix geneve_opt length integer overflow
+
+From: Lin Ma <linma@zju.edu.cn>
+
+[ Upstream commit b27055a08ad4b415dcf15b63034f9cb236f7fb40 ]
+
+struct geneve_opt uses 5 bit length for each single option, which
+means every vary size option should be smaller than 128 bytes.
+
+However, all current related Netlink policies cannot promise this
+length condition and the attacker can exploit a exact 128-byte size
+option to *fake* a zero length option and confuse the parsing logic,
+further achieve heap out-of-bounds read.
+
+One example crash log is like below:
+
+[    3.905425] ==================================================================
+[    3.905925] BUG: KASAN: slab-out-of-bounds in nla_put+0xa9/0xe0
+[    3.906255] Read of size 124 at addr ffff888005f291cc by task poc/177
+[    3.906646]
+[    3.906775] CPU: 0 PID: 177 Comm: poc-oob-read Not tainted 6.1.132 #1
+[    3.907131] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014
+[    3.907784] Call Trace:
+[    3.907925]  <TASK>
+[    3.908048]  dump_stack_lvl+0x44/0x5c
+[    3.908258]  print_report+0x184/0x4be
+[    3.909151]  kasan_report+0xc5/0x100
+[    3.909539]  kasan_check_range+0xf3/0x1a0
+[    3.909794]  memcpy+0x1f/0x60
+[    3.909968]  nla_put+0xa9/0xe0
+[    3.910147]  tunnel_key_dump+0x945/0xba0
+[    3.911536]  tcf_action_dump_1+0x1c1/0x340
+[    3.912436]  tcf_action_dump+0x101/0x180
+[    3.912689]  tcf_exts_dump+0x164/0x1e0
+[    3.912905]  fw_dump+0x18b/0x2d0
+[    3.913483]  tcf_fill_node+0x2ee/0x460
+[    3.914778]  tfilter_notify+0xf4/0x180
+[    3.915208]  tc_new_tfilter+0xd51/0x10d0
+[    3.918615]  rtnetlink_rcv_msg+0x4a2/0x560
+[    3.919118]  netlink_rcv_skb+0xcd/0x200
+[    3.919787]  netlink_unicast+0x395/0x530
+[    3.921032]  netlink_sendmsg+0x3d0/0x6d0
+[    3.921987]  __sock_sendmsg+0x99/0xa0
+[    3.922220]  __sys_sendto+0x1b7/0x240
+[    3.922682]  __x64_sys_sendto+0x72/0x90
+[    3.922906]  do_syscall_64+0x5e/0x90
+[    3.923814]  entry_SYSCALL_64_after_hwframe+0x6e/0xd8
+[    3.924122] RIP: 0033:0x7e83eab84407
+[    3.924331] Code: 48 89 fa 4c 89 df e8 38 aa 00 00 8b 93 08 03 00 00 59 5e 48 83 f8 fc 74 1a 5b c3 0f 1f 84 00 00 00 00 00 48 8b 44 24 10 0f 05 <5b> c3 0f 1f 80 00 00 00 00 83 e2 39 83 faf
+[    3.925330] RSP: 002b:00007ffff505e370 EFLAGS: 00000202 ORIG_RAX: 000000000000002c
+[    3.925752] RAX: ffffffffffffffda RBX: 00007e83eaafa740 RCX: 00007e83eab84407
+[    3.926173] RDX: 00000000000001a8 RSI: 00007ffff505e3c0 RDI: 0000000000000003
+[    3.926587] RBP: 00007ffff505f460 R08: 00007e83eace1000 R09: 000000000000000c
+[    3.926977] R10: 0000000000000000 R11: 0000000000000202 R12: 00007ffff505f3c0
+[    3.927367] R13: 00007ffff505f5c8 R14: 00007e83ead1b000 R15: 00005d4fbbe6dcb8
+
+Fix these issues by enforing correct length condition in related
+policies.
+
+Fixes: 925d844696d9 ("netfilter: nft_tunnel: add support for geneve opts")
+Fixes: 4ece47787077 ("lwtunnel: add options setting and dumping for geneve")
+Fixes: 0ed5269f9e41 ("net/sched: add tunnel option support to act_tunnel_key")
+Fixes: 0a6e77784f49 ("net/sched: allow flower to match tunnel options")
+Signed-off-by: Lin Ma <linma@zju.edu.cn>
+Reviewed-by: Xin Long <lucien.xin@gmail.com>
+Acked-by: Cong Wang <xiyou.wangcong@gmail.com>
+Link: https://patch.msgid.link/20250402165632.6958-1-linma@zju.edu.cn
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/ip_tunnel_core.c  | 2 +-
+ net/netfilter/nft_tunnel.c | 2 +-
+ net/sched/act_tunnel_key.c | 2 +-
+ net/sched/cls_flower.c     | 2 +-
+ 4 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
+index 364ea798511ea..f65d2f7273813 100644
+--- a/net/ipv4/ip_tunnel_core.c
++++ b/net/ipv4/ip_tunnel_core.c
+@@ -451,7 +451,7 @@ static const struct nla_policy
+ geneve_opt_policy[LWTUNNEL_IP_OPT_GENEVE_MAX + 1] = {
+       [LWTUNNEL_IP_OPT_GENEVE_CLASS]  = { .type = NLA_U16 },
+       [LWTUNNEL_IP_OPT_GENEVE_TYPE]   = { .type = NLA_U8 },
+-      [LWTUNNEL_IP_OPT_GENEVE_DATA]   = { .type = NLA_BINARY, .len = 128 },
++      [LWTUNNEL_IP_OPT_GENEVE_DATA]   = { .type = NLA_BINARY, .len = 127 },
+ };
+ static const struct nla_policy
+diff --git a/net/netfilter/nft_tunnel.c b/net/netfilter/nft_tunnel.c
+index 2e40f575aed9f..0c63d1367cf7a 100644
+--- a/net/netfilter/nft_tunnel.c
++++ b/net/netfilter/nft_tunnel.c
+@@ -335,7 +335,7 @@ static int nft_tunnel_obj_erspan_init(const struct nlattr *attr,
+ static const struct nla_policy nft_tunnel_opts_geneve_policy[NFTA_TUNNEL_KEY_GENEVE_MAX + 1] = {
+       [NFTA_TUNNEL_KEY_GENEVE_CLASS]  = { .type = NLA_U16 },
+       [NFTA_TUNNEL_KEY_GENEVE_TYPE]   = { .type = NLA_U8 },
+-      [NFTA_TUNNEL_KEY_GENEVE_DATA]   = { .type = NLA_BINARY, .len = 128 },
++      [NFTA_TUNNEL_KEY_GENEVE_DATA]   = { .type = NLA_BINARY, .len = 127 },
+ };
+ static int nft_tunnel_obj_geneve_init(const struct nlattr *attr,
+diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c
+index af7c998459488..e296714803dc0 100644
+--- a/net/sched/act_tunnel_key.c
++++ b/net/sched/act_tunnel_key.c
+@@ -68,7 +68,7 @@ geneve_opt_policy[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX + 1] = {
+       [TCA_TUNNEL_KEY_ENC_OPT_GENEVE_CLASS]      = { .type = NLA_U16 },
+       [TCA_TUNNEL_KEY_ENC_OPT_GENEVE_TYPE]       = { .type = NLA_U8 },
+       [TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA]       = { .type = NLA_BINARY,
+-                                                     .len = 128 },
++                                                     .len = 127 },
+ };
+ static const struct nla_policy
+diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
+index 03505673d5234..099ff6a3e1f51 100644
+--- a/net/sched/cls_flower.c
++++ b/net/sched/cls_flower.c
+@@ -766,7 +766,7 @@ geneve_opt_policy[TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX + 1] = {
+       [TCA_FLOWER_KEY_ENC_OPT_GENEVE_CLASS]      = { .type = NLA_U16 },
+       [TCA_FLOWER_KEY_ENC_OPT_GENEVE_TYPE]       = { .type = NLA_U8 },
+       [TCA_FLOWER_KEY_ENC_OPT_GENEVE_DATA]       = { .type = NLA_BINARY,
+-                                                     .len = 128 },
++                                                     .len = 127 },
+ };
+ static const struct nla_policy
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-fix-null-pointer-dereference-in-l3mdev_l3_rcv.patch b/queue-6.14/net-fix-null-pointer-dereference-in-l3mdev_l3_rcv.patch
new file mode 100644 (file)
index 0000000..6e39e0d
--- /dev/null
@@ -0,0 +1,66 @@
+From cdb4d9598aa997b693a176ca3a033ae199e5ad81 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Mar 2025 17:03:53 +0800
+Subject: net: fix NULL pointer dereference in l3mdev_l3_rcv
+
+From: Wang Liang <wangliang74@huawei.com>
+
+[ Upstream commit 0032c99e83b9ce6d5995d65900aa4b6ffb501cce ]
+
+When delete l3s ipvlan:
+
+    ip link del link eth0 ipvlan1 type ipvlan mode l3s
+
+This may cause a null pointer dereference:
+
+    Call trace:
+     ip_rcv_finish+0x48/0xd0
+     ip_rcv+0x5c/0x100
+     __netif_receive_skb_one_core+0x64/0xb0
+     __netif_receive_skb+0x20/0x80
+     process_backlog+0xb4/0x204
+     napi_poll+0xe8/0x294
+     net_rx_action+0xd8/0x22c
+     __do_softirq+0x12c/0x354
+
+This is because l3mdev_l3_rcv() visit dev->l3mdev_ops after
+ipvlan_l3s_unregister() assign the dev->l3mdev_ops to NULL. The process
+like this:
+
+    (CPU1)                     | (CPU2)
+    l3mdev_l3_rcv()            |
+      check dev->priv_flags:   |
+        master = skb->dev;     |
+                               |
+                               | ipvlan_l3s_unregister()
+                               |   set dev->priv_flags
+                               |   dev->l3mdev_ops = NULL;
+                               |
+      visit master->l3mdev_ops |
+
+To avoid this by do not set dev->l3mdev_ops when unregister l3s ipvlan.
+
+Suggested-by: David Ahern <dsahern@kernel.org>
+Fixes: c675e06a98a4 ("ipvlan: decouple l3s mode dependencies from other modes")
+Signed-off-by: Wang Liang <wangliang74@huawei.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250321090353.1170545-1-wangliang74@huawei.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ipvlan/ipvlan_l3s.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/net/ipvlan/ipvlan_l3s.c b/drivers/net/ipvlan/ipvlan_l3s.c
+index b4ef386bdb1ba..7c017fe35522a 100644
+--- a/drivers/net/ipvlan/ipvlan_l3s.c
++++ b/drivers/net/ipvlan/ipvlan_l3s.c
+@@ -226,5 +226,4 @@ void ipvlan_l3s_unregister(struct ipvl_port *port)
+       dev->priv_flags &= ~IFF_L3MDEV_RX_HANDLER;
+       ipvlan_unregister_nf_hook(read_pnet(&port->pnet));
+-      dev->l3mdev_ops = NULL;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-fix-the-devmem-sock-opts-and-msgs-for-parisc.patch b/queue-6.14/net-fix-the-devmem-sock-opts-and-msgs-for-parisc.patch
new file mode 100644 (file)
index 0000000..c46993e
--- /dev/null
@@ -0,0 +1,65 @@
+From b261dcf8be84d8261c5fbf5dc110310d5fe3711a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Mar 2025 07:42:27 +0000
+Subject: net: Fix the devmem sock opts and msgs for parisc
+
+From: Pranjal Shrivastava <praan@google.com>
+
+[ Upstream commit fd87b7783802b45cdd261b273e6b2b792823064d ]
+
+The devmem socket options and socket control message definitions
+introduced in the TCP devmem series[1] incorrectly continued the socket
+definitions for arch/parisc.
+
+The UAPI change seems safe as there are currently no drivers that
+declare support for devmem TCP RX via PP_FLAG_ALLOW_UNREADABLE_NETMEM.
+Hence, fixing this UAPI should be safe.
+
+Fix the devmem socket options and socket control message definitions to
+reflect the series followed by arch/parisc.
+
+[1]
+https://lore.kernel.org/lkml/20240910171458.219195-10-almasrymina@google.com/
+
+Fixes: 8f0b3cc9a4c10 ("tcp: RX path for devmem TCP")
+Signed-off-by: Pranjal Shrivastava <praan@google.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Reviewed-by: Jason Xing <kerneljasonxing@gmail.com>
+Reviewed-by: Mina Almasry <almasrymina@google.com>
+Link: https://patch.msgid.link/20250324074228.3139088-1-praan@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/parisc/include/uapi/asm/socket.h | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h
+index aa9cd4b951fe5..96831c9886065 100644
+--- a/arch/parisc/include/uapi/asm/socket.h
++++ b/arch/parisc/include/uapi/asm/socket.h
+@@ -132,16 +132,16 @@
+ #define SO_PASSPIDFD          0x404A
+ #define SO_PEERPIDFD          0x404B
+-#define SO_DEVMEM_LINEAR      78
+-#define SCM_DEVMEM_LINEAR     SO_DEVMEM_LINEAR
+-#define SO_DEVMEM_DMABUF      79
+-#define SCM_DEVMEM_DMABUF     SO_DEVMEM_DMABUF
+-#define SO_DEVMEM_DONTNEED    80
+-
+ #define SCM_TS_OPT_ID         0x404C
+ #define SO_RCVPRIORITY                0x404D
++#define SO_DEVMEM_LINEAR      0x404E
++#define SCM_DEVMEM_LINEAR     SO_DEVMEM_LINEAR
++#define SO_DEVMEM_DMABUF      0x404F
++#define SCM_DEVMEM_DMABUF     SO_DEVMEM_DMABUF
++#define SO_DEVMEM_DONTNEED    0x4050
++
+ #if !defined(__KERNEL__)
+ #if __BITS_PER_LONG == 64
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-ibmveth-make-veth_pool_store-stop-hanging.patch b/queue-6.14/net-ibmveth-make-veth_pool_store-stop-hanging.patch
new file mode 100644 (file)
index 0000000..ec66751
--- /dev/null
@@ -0,0 +1,211 @@
+From 20ed1547669d6f5ef0e15dcb1c77a2c4e11afd2b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Apr 2025 10:44:03 -0500
+Subject: net: ibmveth: make veth_pool_store stop hanging
+
+From: Dave Marquardt <davemarq@linux.ibm.com>
+
+[ Upstream commit 053f3ff67d7feefc75797863f3d84b47ad47086f ]
+
+v2:
+- Created a single error handling unlock and exit in veth_pool_store
+- Greatly expanded commit message with previous explanatory-only text
+
+Summary: Use rtnl_mutex to synchronize veth_pool_store with itself,
+ibmveth_close and ibmveth_open, preventing multiple calls in a row to
+napi_disable.
+
+Background: Two (or more) threads could call veth_pool_store through
+writing to /sys/devices/vio/30000002/pool*/*. You can do this easily
+with a little shell script. This causes a hang.
+
+I configured LOCKDEP, compiled ibmveth.c with DEBUG, and built a new
+kernel. I ran this test again and saw:
+
+    Setting pool0/active to 0
+    Setting pool1/active to 1
+    [   73.911067][ T4365] ibmveth 30000002 eth0: close starting
+    Setting pool1/active to 1
+    Setting pool1/active to 0
+    [   73.911367][ T4366] ibmveth 30000002 eth0: close starting
+    [   73.916056][ T4365] ibmveth 30000002 eth0: close complete
+    [   73.916064][ T4365] ibmveth 30000002 eth0: open starting
+    [  110.808564][  T712] systemd-journald[712]: Sent WATCHDOG=1 notification.
+    [  230.808495][  T712] systemd-journald[712]: Sent WATCHDOG=1 notification.
+    [  243.683786][  T123] INFO: task stress.sh:4365 blocked for more than 122 seconds.
+    [  243.683827][  T123]       Not tainted 6.14.0-01103-g2df0c02dab82-dirty #8
+    [  243.683833][  T123] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+    [  243.683838][  T123] task:stress.sh       state:D stack:28096 pid:4365  tgid:4365  ppid:4364   task_flags:0x400040 flags:0x00042000
+    [  243.683852][  T123] Call Trace:
+    [  243.683857][  T123] [c00000000c38f690] [0000000000000001] 0x1 (unreliable)
+    [  243.683868][  T123] [c00000000c38f840] [c00000000001f908] __switch_to+0x318/0x4e0
+    [  243.683878][  T123] [c00000000c38f8a0] [c000000001549a70] __schedule+0x500/0x12a0
+    [  243.683888][  T123] [c00000000c38f9a0] [c00000000154a878] schedule+0x68/0x210
+    [  243.683896][  T123] [c00000000c38f9d0] [c00000000154ac80] schedule_preempt_disabled+0x30/0x50
+    [  243.683904][  T123] [c00000000c38fa00] [c00000000154dbb0] __mutex_lock+0x730/0x10f0
+    [  243.683913][  T123] [c00000000c38fb10] [c000000001154d40] napi_enable+0x30/0x60
+    [  243.683921][  T123] [c00000000c38fb40] [c000000000f4ae94] ibmveth_open+0x68/0x5dc
+    [  243.683928][  T123] [c00000000c38fbe0] [c000000000f4aa20] veth_pool_store+0x220/0x270
+    [  243.683936][  T123] [c00000000c38fc70] [c000000000826278] sysfs_kf_write+0x68/0xb0
+    [  243.683944][  T123] [c00000000c38fcb0] [c0000000008240b8] kernfs_fop_write_iter+0x198/0x2d0
+    [  243.683951][  T123] [c00000000c38fd00] [c00000000071b9ac] vfs_write+0x34c/0x650
+    [  243.683958][  T123] [c00000000c38fdc0] [c00000000071bea8] ksys_write+0x88/0x150
+    [  243.683966][  T123] [c00000000c38fe10] [c0000000000317f4] system_call_exception+0x124/0x340
+    [  243.683973][  T123] [c00000000c38fe50] [c00000000000d05c] system_call_vectored_common+0x15c/0x2ec
+    ...
+    [  243.684087][  T123] Showing all locks held in the system:
+    [  243.684095][  T123] 1 lock held by khungtaskd/123:
+    [  243.684099][  T123]  #0: c00000000278e370 (rcu_read_lock){....}-{1:2}, at: debug_show_all_locks+0x50/0x248
+    [  243.684114][  T123] 4 locks held by stress.sh/4365:
+    [  243.684119][  T123]  #0: c00000003a4cd3f8 (sb_writers#3){.+.+}-{0:0}, at: ksys_write+0x88/0x150
+    [  243.684132][  T123]  #1: c000000041aea888 (&of->mutex#2){+.+.}-{3:3}, at: kernfs_fop_write_iter+0x154/0x2d0
+    [  243.684143][  T123]  #2: c0000000366fb9a8 (kn->active#64){.+.+}-{0:0}, at: kernfs_fop_write_iter+0x160/0x2d0
+    [  243.684155][  T123]  #3: c000000035ff4cb8 (&dev->lock){+.+.}-{3:3}, at: napi_enable+0x30/0x60
+    [  243.684166][  T123] 5 locks held by stress.sh/4366:
+    [  243.684170][  T123]  #0: c00000003a4cd3f8 (sb_writers#3){.+.+}-{0:0}, at: ksys_write+0x88/0x150
+    [  243.684183][  T123]  #1: c00000000aee2288 (&of->mutex#2){+.+.}-{3:3}, at: kernfs_fop_write_iter+0x154/0x2d0
+    [  243.684194][  T123]  #2: c0000000366f4ba8 (kn->active#64){.+.+}-{0:0}, at: kernfs_fop_write_iter+0x160/0x2d0
+    [  243.684205][  T123]  #3: c000000035ff4cb8 (&dev->lock){+.+.}-{3:3}, at: napi_disable+0x30/0x60
+    [  243.684216][  T123]  #4: c0000003ff9bbf18 (&rq->__lock){-.-.}-{2:2}, at: __schedule+0x138/0x12a0
+
+From the ibmveth debug, two threads are calling veth_pool_store, which
+calls ibmveth_close and ibmveth_open. Here's the sequence:
+
+  T4365             T4366
+  ----------------- ----------------- ---------
+  veth_pool_store   veth_pool_store
+                    ibmveth_close
+  ibmveth_close
+  napi_disable
+                    napi_disable
+  ibmveth_open
+  napi_enable                         <- HANG
+
+ibmveth_close calls napi_disable at the top and ibmveth_open calls
+napi_enable at the top.
+
+https://docs.kernel.org/networking/napi.html]] says
+
+  The control APIs are not idempotent. Control API calls are safe
+  against concurrent use of datapath APIs but an incorrect sequence of
+  control API calls may result in crashes, deadlocks, or race
+  conditions. For example, calling napi_disable() multiple times in a
+  row will deadlock.
+
+In the normal open and close paths, rtnl_mutex is acquired to prevent
+other callers. This is missing from veth_pool_store. Use rtnl_mutex in
+veth_pool_store fixes these hangs.
+
+Signed-off-by: Dave Marquardt <davemarq@linux.ibm.com>
+Fixes: 860f242eb534 ("[PATCH] ibmveth change buffer pools dynamically")
+Reviewed-by: Nick Child <nnac123@linux.ibm.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250402154403.386744-1-davemarq@linux.ibm.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ibm/ibmveth.c | 39 +++++++++++++++++++++---------
+ 1 file changed, 27 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c
+index b619a3ec245b2..04192190bebab 100644
+--- a/drivers/net/ethernet/ibm/ibmveth.c
++++ b/drivers/net/ethernet/ibm/ibmveth.c
+@@ -1802,18 +1802,22 @@ static ssize_t veth_pool_store(struct kobject *kobj, struct attribute *attr,
+       long value = simple_strtol(buf, NULL, 10);
+       long rc;
++      rtnl_lock();
++
+       if (attr == &veth_active_attr) {
+               if (value && !pool->active) {
+                       if (netif_running(netdev)) {
+                               if (ibmveth_alloc_buffer_pool(pool)) {
+                                       netdev_err(netdev,
+                                                  "unable to alloc pool\n");
+-                                      return -ENOMEM;
++                                      rc = -ENOMEM;
++                                      goto unlock_err;
+                               }
+                               pool->active = 1;
+                               ibmveth_close(netdev);
+-                              if ((rc = ibmveth_open(netdev)))
+-                                      return rc;
++                              rc = ibmveth_open(netdev);
++                              if (rc)
++                                      goto unlock_err;
+                       } else {
+                               pool->active = 1;
+                       }
+@@ -1833,48 +1837,59 @@ static ssize_t veth_pool_store(struct kobject *kobj, struct attribute *attr,
+                       if (i == IBMVETH_NUM_BUFF_POOLS) {
+                               netdev_err(netdev, "no active pool >= MTU\n");
+-                              return -EPERM;
++                              rc = -EPERM;
++                              goto unlock_err;
+                       }
+                       if (netif_running(netdev)) {
+                               ibmveth_close(netdev);
+                               pool->active = 0;
+-                              if ((rc = ibmveth_open(netdev)))
+-                                      return rc;
++                              rc = ibmveth_open(netdev);
++                              if (rc)
++                                      goto unlock_err;
+                       }
+                       pool->active = 0;
+               }
+       } else if (attr == &veth_num_attr) {
+               if (value <= 0 || value > IBMVETH_MAX_POOL_COUNT) {
+-                      return -EINVAL;
++                      rc = -EINVAL;
++                      goto unlock_err;
+               } else {
+                       if (netif_running(netdev)) {
+                               ibmveth_close(netdev);
+                               pool->size = value;
+-                              if ((rc = ibmveth_open(netdev)))
+-                                      return rc;
++                              rc = ibmveth_open(netdev);
++                              if (rc)
++                                      goto unlock_err;
+                       } else {
+                               pool->size = value;
+                       }
+               }
+       } else if (attr == &veth_size_attr) {
+               if (value <= IBMVETH_BUFF_OH || value > IBMVETH_MAX_BUF_SIZE) {
+-                      return -EINVAL;
++                      rc = -EINVAL;
++                      goto unlock_err;
+               } else {
+                       if (netif_running(netdev)) {
+                               ibmveth_close(netdev);
+                               pool->buff_size = value;
+-                              if ((rc = ibmveth_open(netdev)))
+-                                      return rc;
++                              rc = ibmveth_open(netdev);
++                              if (rc)
++                                      goto unlock_err;
+                       } else {
+                               pool->buff_size = value;
+                       }
+               }
+       }
++      rtnl_unlock();
+       /* kick the interrupt handler to allocate/deallocate pools */
+       ibmveth_interrupt(netdev->irq, netdev);
+       return count;
++
++unlock_err:
++      rtnl_unlock();
++      return rc;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-lan743x-reject-unsupported-external-timestamp-re.patch b/queue-6.14/net-lan743x-reject-unsupported-external-timestamp-re.patch
new file mode 100644 (file)
index 0000000..80976f9
--- /dev/null
@@ -0,0 +1,48 @@
+From 8272f856dff510ace46d78ff923394a9448c85a3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Mar 2025 15:15:52 -0700
+Subject: net: lan743x: reject unsupported external timestamp requests
+
+From: Jacob Keller <jacob.e.keller@intel.com>
+
+[ Upstream commit c0b4ddd30871c59043ed3592e6abeee55c3bf045 ]
+
+The lan743x_ptp_io_event_cap_en() function checks that the given request
+sets only one of PTP_RISING_EDGE or PTP_FALLING_EDGE, but not both.
+
+However, this driver does not check whether other flags (such as
+PTP_EXT_OFF) are set, nor whether any future unrecognized flags are set.
+
+Fix this by adding the appropriate check to the lan743x_ptp_io_extts()
+function.
+
+Fixes: 60942c397af6 ("net: lan743x: Add support for PTP-IO Event Input External Timestamp (extts)")
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250312-jk-net-fixes-supported-extts-flags-v2-3-ea930ba82459@intel.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/microchip/lan743x_ptp.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/net/ethernet/microchip/lan743x_ptp.c b/drivers/net/ethernet/microchip/lan743x_ptp.c
+index 4a777b449ecd0..0be44dcb33938 100644
+--- a/drivers/net/ethernet/microchip/lan743x_ptp.c
++++ b/drivers/net/ethernet/microchip/lan743x_ptp.c
+@@ -942,6 +942,12 @@ static int lan743x_ptp_io_extts(struct lan743x_adapter *adapter, int on,
+       extts = &ptp->extts[index];
++      if (extts_request->flags & ~(PTP_ENABLE_FEATURE |
++                                   PTP_RISING_EDGE |
++                                   PTP_FALLING_EDGE |
++                                   PTP_STRICT_FLAGS))
++              return -EOPNOTSUPP;
++
+       if (on) {
+               extts_pin = ptp_find_pin(ptp->ptp_clock, PTP_PF_EXTTS, index);
+               if (extts_pin < 0)
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-libwx-fix-tx-descriptor-content-for-some-tunnel-.patch b/queue-6.14/net-libwx-fix-tx-descriptor-content-for-some-tunnel-.patch
new file mode 100644 (file)
index 0000000..1392071
--- /dev/null
@@ -0,0 +1,183 @@
+From b5ba6a9512628f0d93eb717625be95e3efacc40d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Mar 2025 18:32:34 +0800
+Subject: net: libwx: fix Tx descriptor content for some tunnel packets
+
+From: Jiawen Wu <jiawenwu@trustnetic.com>
+
+[ Upstream commit a44940d094afa2e04b5b164b1e136fc18bcb4a2d ]
+
+The length of skb header was incorrectly calculated when transmit a tunnel
+packet with outer IPv6 extension header, or a IP over IP packet which has
+inner IPv6 header. Thus the correct Tx context descriptor cannot be
+composed, resulting in Tx ring hang.
+
+Fixes: 3403960cdf86 ("net: wangxun: libwx add tx offload functions")
+Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
+Link: https://patch.msgid.link/20250324103235.823096-1-jiawenwu@trustnetic.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/wangxun/libwx/wx_lib.c | 61 +++++++++++++--------
+ 1 file changed, 37 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/net/ethernet/wangxun/libwx/wx_lib.c b/drivers/net/ethernet/wangxun/libwx/wx_lib.c
+index 2b3d6586f44a5..9294a9d8c5541 100644
+--- a/drivers/net/ethernet/wangxun/libwx/wx_lib.c
++++ b/drivers/net/ethernet/wangxun/libwx/wx_lib.c
+@@ -1082,26 +1082,6 @@ static void wx_tx_ctxtdesc(struct wx_ring *tx_ring, u32 vlan_macip_lens,
+       context_desc->mss_l4len_idx     = cpu_to_le32(mss_l4len_idx);
+ }
+-static void wx_get_ipv6_proto(struct sk_buff *skb, int offset, u8 *nexthdr)
+-{
+-      struct ipv6hdr *hdr = (struct ipv6hdr *)(skb->data + offset);
+-
+-      *nexthdr = hdr->nexthdr;
+-      offset += sizeof(struct ipv6hdr);
+-      while (ipv6_ext_hdr(*nexthdr)) {
+-              struct ipv6_opt_hdr _hdr, *hp;
+-
+-              if (*nexthdr == NEXTHDR_NONE)
+-                      return;
+-              hp = skb_header_pointer(skb, offset, sizeof(_hdr), &_hdr);
+-              if (!hp)
+-                      return;
+-              if (*nexthdr == NEXTHDR_FRAGMENT)
+-                      break;
+-              *nexthdr = hp->nexthdr;
+-      }
+-}
+-
+ union network_header {
+       struct iphdr *ipv4;
+       struct ipv6hdr *ipv6;
+@@ -1112,6 +1092,8 @@ static u8 wx_encode_tx_desc_ptype(const struct wx_tx_buffer *first)
+ {
+       u8 tun_prot = 0, l4_prot = 0, ptype = 0;
+       struct sk_buff *skb = first->skb;
++      unsigned char *exthdr, *l4_hdr;
++      __be16 frag_off;
+       if (skb->encapsulation) {
+               union network_header hdr;
+@@ -1122,14 +1104,18 @@ static u8 wx_encode_tx_desc_ptype(const struct wx_tx_buffer *first)
+                       ptype = WX_PTYPE_TUN_IPV4;
+                       break;
+               case htons(ETH_P_IPV6):
+-                      wx_get_ipv6_proto(skb, skb_network_offset(skb), &tun_prot);
++                      l4_hdr = skb_transport_header(skb);
++                      exthdr = skb_network_header(skb) + sizeof(struct ipv6hdr);
++                      tun_prot = ipv6_hdr(skb)->nexthdr;
++                      if (l4_hdr != exthdr)
++                              ipv6_skip_exthdr(skb, exthdr - skb->data, &tun_prot, &frag_off);
+                       ptype = WX_PTYPE_TUN_IPV6;
+                       break;
+               default:
+                       return ptype;
+               }
+-              if (tun_prot == IPPROTO_IPIP) {
++              if (tun_prot == IPPROTO_IPIP || tun_prot == IPPROTO_IPV6) {
+                       hdr.raw = (void *)inner_ip_hdr(skb);
+                       ptype |= WX_PTYPE_PKT_IPIP;
+               } else if (tun_prot == IPPROTO_UDP) {
+@@ -1166,7 +1152,11 @@ static u8 wx_encode_tx_desc_ptype(const struct wx_tx_buffer *first)
+                       l4_prot = hdr.ipv4->protocol;
+                       break;
+               case 6:
+-                      wx_get_ipv6_proto(skb, skb_inner_network_offset(skb), &l4_prot);
++                      l4_hdr = skb_inner_transport_header(skb);
++                      exthdr = skb_inner_network_header(skb) + sizeof(struct ipv6hdr);
++                      l4_prot = inner_ipv6_hdr(skb)->nexthdr;
++                      if (l4_hdr != exthdr)
++                              ipv6_skip_exthdr(skb, exthdr - skb->data, &l4_prot, &frag_off);
+                       ptype |= WX_PTYPE_PKT_IPV6;
+                       break;
+               default:
+@@ -1179,7 +1169,11 @@ static u8 wx_encode_tx_desc_ptype(const struct wx_tx_buffer *first)
+                       ptype = WX_PTYPE_PKT_IP;
+                       break;
+               case htons(ETH_P_IPV6):
+-                      wx_get_ipv6_proto(skb, skb_network_offset(skb), &l4_prot);
++                      l4_hdr = skb_transport_header(skb);
++                      exthdr = skb_network_header(skb) + sizeof(struct ipv6hdr);
++                      l4_prot = ipv6_hdr(skb)->nexthdr;
++                      if (l4_hdr != exthdr)
++                              ipv6_skip_exthdr(skb, exthdr - skb->data, &l4_prot, &frag_off);
+                       ptype = WX_PTYPE_PKT_IP | WX_PTYPE_PKT_IPV6;
+                       break;
+               default:
+@@ -1269,13 +1263,20 @@ static int wx_tso(struct wx_ring *tx_ring, struct wx_tx_buffer *first,
+       /* vlan_macip_lens: HEADLEN, MACLEN, VLAN tag */
+       if (enc) {
++              unsigned char *exthdr, *l4_hdr;
++              __be16 frag_off;
++
+               switch (first->protocol) {
+               case htons(ETH_P_IP):
+                       tun_prot = ip_hdr(skb)->protocol;
+                       first->tx_flags |= WX_TX_FLAGS_OUTER_IPV4;
+                       break;
+               case htons(ETH_P_IPV6):
++                      l4_hdr = skb_transport_header(skb);
++                      exthdr = skb_network_header(skb) + sizeof(struct ipv6hdr);
+                       tun_prot = ipv6_hdr(skb)->nexthdr;
++                      if (l4_hdr != exthdr)
++                              ipv6_skip_exthdr(skb, exthdr - skb->data, &tun_prot, &frag_off);
+                       break;
+               default:
+                       break;
+@@ -1298,6 +1299,7 @@ static int wx_tso(struct wx_ring *tx_ring, struct wx_tx_buffer *first,
+                                               WX_TXD_TUNNEL_LEN_SHIFT);
+                       break;
+               case IPPROTO_IPIP:
++              case IPPROTO_IPV6:
+                       tunhdr_eiplen_tunlen = (((char *)inner_ip_hdr(skb) -
+                                               (char *)ip_hdr(skb)) >> 2) <<
+                                               WX_TXD_OUTER_IPLEN_SHIFT;
+@@ -1341,6 +1343,8 @@ static void wx_tx_csum(struct wx_ring *tx_ring, struct wx_tx_buffer *first,
+               vlan_macip_lens = skb_network_offset(skb) <<
+                                 WX_TXD_MACLEN_SHIFT;
+       } else {
++              unsigned char *exthdr, *l4_hdr;
++              __be16 frag_off;
+               u8 l4_prot = 0;
+               union {
+                       struct iphdr *ipv4;
+@@ -1362,7 +1366,12 @@ static void wx_tx_csum(struct wx_ring *tx_ring, struct wx_tx_buffer *first,
+                               tun_prot = ip_hdr(skb)->protocol;
+                               break;
+                       case htons(ETH_P_IPV6):
++                              l4_hdr = skb_transport_header(skb);
++                              exthdr = skb_network_header(skb) + sizeof(struct ipv6hdr);
+                               tun_prot = ipv6_hdr(skb)->nexthdr;
++                              if (l4_hdr != exthdr)
++                                      ipv6_skip_exthdr(skb, exthdr - skb->data,
++                                                       &tun_prot, &frag_off);
+                               break;
+                       default:
+                               return;
+@@ -1386,6 +1395,7 @@ static void wx_tx_csum(struct wx_ring *tx_ring, struct wx_tx_buffer *first,
+                                                         WX_TXD_TUNNEL_LEN_SHIFT);
+                               break;
+                       case IPPROTO_IPIP:
++                      case IPPROTO_IPV6:
+                               tunhdr_eiplen_tunlen = (((char *)inner_ip_hdr(skb) -
+                                                       (char *)ip_hdr(skb)) >> 2) <<
+                                                       WX_TXD_OUTER_IPLEN_SHIFT;
+@@ -1408,7 +1418,10 @@ static void wx_tx_csum(struct wx_ring *tx_ring, struct wx_tx_buffer *first,
+                       break;
+               case 6:
+                       vlan_macip_lens |= (transport_hdr.raw - network_hdr.raw) >> 1;
++                      exthdr = network_hdr.raw + sizeof(struct ipv6hdr);
+                       l4_prot = network_hdr.ipv6->nexthdr;
++                      if (transport_hdr.raw != exthdr)
++                              ipv6_skip_exthdr(skb, exthdr - skb->data, &l4_prot, &frag_off);
+                       break;
+               default:
+                       break;
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-libwx-fix-tx-l4-checksum.patch b/queue-6.14/net-libwx-fix-tx-l4-checksum.patch
new file mode 100644 (file)
index 0000000..e0b2743
--- /dev/null
@@ -0,0 +1,47 @@
+From bc72ff4f67cb0b0e876ff20777156bd12dd28888 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Mar 2025 18:32:35 +0800
+Subject: net: libwx: fix Tx L4 checksum
+
+From: Jiawen Wu <jiawenwu@trustnetic.com>
+
+[ Upstream commit c7d82913d5f9e97860772ee4051eaa66b56a6273 ]
+
+The hardware only supports L4 checksum offload for TCP/UDP/SCTP protocol.
+There was a bug to set Tx checksum flag for the other protocol that results
+in Tx ring hang. Fix to compute software checksum for these packets.
+
+Fixes: 3403960cdf86 ("net: wangxun: libwx add tx offload functions")
+Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
+Link: https://patch.msgid.link/20250324103235.823096-2-jiawenwu@trustnetic.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/wangxun/libwx/wx_lib.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/wangxun/libwx/wx_lib.c b/drivers/net/ethernet/wangxun/libwx/wx_lib.c
+index 9294a9d8c5541..497abf2723a5e 100644
+--- a/drivers/net/ethernet/wangxun/libwx/wx_lib.c
++++ b/drivers/net/ethernet/wangxun/libwx/wx_lib.c
+@@ -1337,6 +1337,7 @@ static void wx_tx_csum(struct wx_ring *tx_ring, struct wx_tx_buffer *first,
+       u8 tun_prot = 0;
+       if (skb->ip_summed != CHECKSUM_PARTIAL) {
++csum_failed:
+               if (!(first->tx_flags & WX_TX_FLAGS_HW_VLAN) &&
+                   !(first->tx_flags & WX_TX_FLAGS_CC))
+                       return;
+@@ -1441,7 +1442,8 @@ static void wx_tx_csum(struct wx_ring *tx_ring, struct wx_tx_buffer *first,
+                                       WX_TXD_L4LEN_SHIFT;
+                       break;
+               default:
+-                      break;
++                      skb_checksum_help(skb);
++                      goto csum_failed;
+               }
+               /* update TX checksum flag */
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-mlx5-lag-reload-representors-on-lag-creation-fai.patch b/queue-6.14/net-mlx5-lag-reload-representors-on-lag-creation-fai.patch
new file mode 100644 (file)
index 0000000..9675764
--- /dev/null
@@ -0,0 +1,44 @@
+From c59f94be2341e84ce4c76200b9cde9e355e9d45f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Mar 2025 22:51:16 +0200
+Subject: net/mlx5: LAG, reload representors on LAG creation failure
+
+From: Mark Bloch <mbloch@nvidia.com>
+
+[ Upstream commit bdf549a7a4d738838d50833168881a0b6247446a ]
+
+When LAG creation fails, the driver reloads the RDMA devices. If RDMA
+representors are present, they should also be reloaded. This step was
+missed in the cited commit.
+
+Fixes: 598fe77df855 ("net/mlx5: Lag, Create shared FDB when in switchdev mode")
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Reviewed-by: Shay Drori <shayd@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
+Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Link: https://patch.msgid.link/1742331077-102038-2-git-send-email-tariqt@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
+index ed2ba272946b9..6c9737c537348 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
+@@ -1052,6 +1052,10 @@ static void mlx5_do_bond(struct mlx5_lag *ldev)
+               if (err) {
+                       if (shared_fdb || roce_lag)
+                               mlx5_lag_add_devices(ldev);
++                      if (shared_fdb) {
++                              mlx5_ldev_for_each(i, 0, ldev)
++                                      mlx5_eswitch_reload_ib_reps(ldev->pf[i].dev->priv.eswitch);
++                      }
+                       return;
+               } else if (roce_lag) {
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-mlx5-start-health-poll-after-enable-hca.patch b/queue-6.14/net-mlx5-start-health-poll-after-enable-hca.patch
new file mode 100644 (file)
index 0000000..f18b2cc
--- /dev/null
@@ -0,0 +1,87 @@
+From ff275d2935c9e0de5456d8b14da9f23455137b9b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Mar 2025 22:51:17 +0200
+Subject: net/mlx5: Start health poll after enable hca
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 1726ad035cb0c93cc5c3f2227ec71322ccd7c2f8 ]
+
+The health poll mechanism performs periodic checks to detect firmware
+errors. One of the checks verifies the function is still enabled on
+firmware side, but the function is enabled only after enable_hca command
+completed. Start health poll after enable_hca command to avoid a race
+between function enabled and first health polling.
+
+Fixes: 9b98d395b85d ("net/mlx5: Start health poll at earlier stage of driver load")
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Reviewed-by: Shay Drori <shayd@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
+Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Link: https://patch.msgid.link/1742331077-102038-3-git-send-email-tariqt@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/main.c | 15 +++++++--------
+ 1 file changed, 7 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+index ec956c4bcebdb..7c3312d6aed9b 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+@@ -1205,24 +1205,24 @@ static int mlx5_function_enable(struct mlx5_core_dev *dev, bool boot, u64 timeou
+       dev->caps.embedded_cpu = mlx5_read_embedded_cpu(dev);
+       mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_UP);
+-      mlx5_start_health_poll(dev);
+-
+       err = mlx5_core_enable_hca(dev, 0);
+       if (err) {
+               mlx5_core_err(dev, "enable hca failed\n");
+-              goto stop_health_poll;
++              goto err_cmd_cleanup;
+       }
++      mlx5_start_health_poll(dev);
++
+       err = mlx5_core_set_issi(dev);
+       if (err) {
+               mlx5_core_err(dev, "failed to set issi\n");
+-              goto err_disable_hca;
++              goto stop_health_poll;
+       }
+       err = mlx5_satisfy_startup_pages(dev, 1);
+       if (err) {
+               mlx5_core_err(dev, "failed to allocate boot pages\n");
+-              goto err_disable_hca;
++              goto stop_health_poll;
+       }
+       err = mlx5_tout_query_dtor(dev);
+@@ -1235,10 +1235,9 @@ static int mlx5_function_enable(struct mlx5_core_dev *dev, bool boot, u64 timeou
+ reclaim_boot_pages:
+       mlx5_reclaim_startup_pages(dev);
+-err_disable_hca:
+-      mlx5_core_disable_hca(dev, 0);
+ stop_health_poll:
+       mlx5_stop_health_poll(dev, boot);
++      mlx5_core_disable_hca(dev, 0);
+ err_cmd_cleanup:
+       mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_DOWN);
+       mlx5_cmd_disable(dev);
+@@ -1249,8 +1248,8 @@ static int mlx5_function_enable(struct mlx5_core_dev *dev, bool boot, u64 timeou
+ static void mlx5_function_disable(struct mlx5_core_dev *dev, bool boot)
+ {
+       mlx5_reclaim_startup_pages(dev);
+-      mlx5_core_disable_hca(dev, 0);
+       mlx5_stop_health_poll(dev, boot);
++      mlx5_core_disable_hca(dev, 0);
+       mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_DOWN);
+       mlx5_cmd_disable(dev);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-mlx5e-fix-ethtool-n-flow-type-ip4-to-rss-context.patch b/queue-6.14/net-mlx5e-fix-ethtool-n-flow-type-ip4-to-rss-context.patch
new file mode 100644 (file)
index 0000000..bc32617
--- /dev/null
@@ -0,0 +1,71 @@
+From ae678e481c00f2aad3ad6e4fe4ce09860f76c752 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Mar 2025 14:45:08 +0200
+Subject: net/mlx5e: Fix ethtool -N flow-type ip4 to RSS context
+
+From: Maxim Mikityanskiy <maxtram95@gmail.com>
+
+[ Upstream commit 3865bec60683b86d39a5d8d6c34a1d269adaa84c ]
+
+There commands can be used to add an RSS context and steer some traffic
+into it:
+
+    # ethtool -X eth0 context new
+    New RSS context is 1
+    # ethtool -N eth0 flow-type ip4 dst-ip 1.1.1.1 context 1
+    Added rule with ID 1023
+
+However, the second command fails with EINVAL on mlx5e:
+
+    # ethtool -N eth0 flow-type ip4 dst-ip 1.1.1.1 context 1
+    rmgr: Cannot insert RX class rule: Invalid argument
+    Cannot insert classification rule
+
+It happens when flow_get_tirn calls flow_type_to_traffic_type with
+flow_type = IP_USER_FLOW or IPV6_USER_FLOW. That function only handles
+IPV4_FLOW and IPV6_FLOW cases, but unlike all other cases which are
+common for hash and spec, IPv4 and IPv6 defines different contants for
+hash and for spec:
+
+    #define    TCP_V4_FLOW     0x01    /* hash or spec (tcp_ip4_spec) */
+    #define    UDP_V4_FLOW     0x02    /* hash or spec (udp_ip4_spec) */
+    ...
+    #define    IPV4_USER_FLOW  0x0d    /* spec only (usr_ip4_spec) */
+    #define    IP_USER_FLOW    IPV4_USER_FLOW
+    #define    IPV6_USER_FLOW  0x0e    /* spec only (usr_ip6_spec; nfc only) */
+    #define    IPV4_FLOW       0x10    /* hash only */
+    #define    IPV6_FLOW       0x11    /* hash only */
+
+Extend the switch in flow_type_to_traffic_type to support both, which
+fixes the failing ethtool -N command with flow-type ip4 or ip6.
+
+Fixes: 248d3b4c9a39 ("net/mlx5e: Support flow classification into RSS contexts")
+Signed-off-by: Maxim Mikityanskiy <maxim@isovalent.com>
+Tested-by: Daniel Borkmann <daniel@iogearbox.net>
+Reviewed-by: Joe Damato <jdamato@fastly.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/20250319124508.3979818-1-maxim@isovalent.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c
+index 773624bb2c5d5..d68230a7b9f46 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c
+@@ -884,8 +884,10 @@ static int flow_type_to_traffic_type(u32 flow_type)
+       case ESP_V6_FLOW:
+               return MLX5_TT_IPV6_IPSEC_ESP;
+       case IPV4_FLOW:
++      case IP_USER_FLOW:
+               return MLX5_TT_IPV4;
+       case IPV6_FLOW:
++      case IPV6_USER_FLOW:
+               return MLX5_TT_IPV6;
+       default:
+               return -EINVAL;
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-mlx5e-shampo-make-reserved-size-independent-of-p.patch b/queue-6.14/net-mlx5e-shampo-make-reserved-size-independent-of-p.patch
new file mode 100644 (file)
index 0000000..bc5c4e0
--- /dev/null
@@ -0,0 +1,77 @@
+From b6d0b42c317e4bc31a3375aa766706dfe574792a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 Mar 2025 14:28:26 +0200
+Subject: net/mlx5e: SHAMPO, Make reserved size independent of page size
+
+From: Lama Kayal <lkayal@nvidia.com>
+
+[ Upstream commit fab05835688526f9de123d1e98e4d1f838da4e22 ]
+
+When hw-gro is enabled, the maximum number of header entries that are
+needed per wqe (hd_per_wqe) is calculated based on the size of the
+reservations among other parameters.
+
+Miscalculation of the size of reservations leads to incorrect
+calculation of hd_per_wqe as 0, particularly in the case of large page
+size like in aarch64, this prevents the SHAMPO header from being
+correctly initialized in the device, ultimately causing the following
+cqe err that indicates a violation of PD.
+
+ mlx5_core 0000:00:08.0 eth2: ERR CQE on RQ: 0x1180
+ mlx5_core 0000:00:08.0 eth2: Error cqe on cqn 0x510, ci 0x0, qn 0x1180, opcode 0xe, syndrome  0x4, vendor syndrome 0x32
+ 00000000: 00 00 00 00 04 4a 00 00 00 00 00 00 20 00 93 32
+ 00000010: 55 00 00 00 fb cc 00 00 00 00 00 00 07 18 00 00
+ 00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 4a
+ 00000030: 00 00 00 9a 93 00 32 04 00 00 00 00 00 00 da e1
+
+Use the correct formula for calculating the size of reservations,
+precisely it shouldn't be dependent on page size, instead use the
+correct multiply of MLX5E_SHAMPO_WQ_BASE_RESRV_SIZE.
+
+Fixes: e5ca8fb08ab2 ("net/mlx5e: Add control path for SHAMPO feature")
+Signed-off-by: Lama Kayal <lkayal@nvidia.com>
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1742732906-166564-1-git-send-email-tariqt@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en/params.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/params.c b/drivers/net/ethernet/mellanox/mlx5/core/en/params.c
+index 64b62ed17b07a..31eb99f09c63c 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/params.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/params.c
+@@ -423,7 +423,7 @@ u8 mlx5e_shampo_get_log_pkt_per_rsrv(struct mlx5_core_dev *mdev,
+                                    struct mlx5e_params *params)
+ {
+       u32 resrv_size = BIT(mlx5e_shampo_get_log_rsrv_size(mdev, params)) *
+-                       PAGE_SIZE;
++                       MLX5E_SHAMPO_WQ_BASE_RESRV_SIZE;
+       return order_base_2(DIV_ROUND_UP(resrv_size, params->sw_mtu));
+ }
+@@ -827,7 +827,8 @@ static u32 mlx5e_shampo_get_log_cq_size(struct mlx5_core_dev *mdev,
+                                       struct mlx5e_params *params,
+                                       struct mlx5e_xsk_param *xsk)
+ {
+-      int rsrv_size = BIT(mlx5e_shampo_get_log_rsrv_size(mdev, params)) * PAGE_SIZE;
++      int rsrv_size = BIT(mlx5e_shampo_get_log_rsrv_size(mdev, params)) *
++              MLX5E_SHAMPO_WQ_BASE_RESRV_SIZE;
+       u16 num_strides = BIT(mlx5e_mpwqe_get_log_num_strides(mdev, params, xsk));
+       int pkt_per_rsrv = BIT(mlx5e_shampo_get_log_pkt_per_rsrv(mdev, params));
+       u8 log_stride_sz = mlx5e_mpwqe_get_log_stride_size(mdev, params, xsk);
+@@ -1036,7 +1037,8 @@ u32 mlx5e_shampo_hd_per_wqe(struct mlx5_core_dev *mdev,
+                           struct mlx5e_params *params,
+                           struct mlx5e_rq_param *rq_param)
+ {
+-      int resv_size = BIT(mlx5e_shampo_get_log_rsrv_size(mdev, params)) * PAGE_SIZE;
++      int resv_size = BIT(mlx5e_shampo_get_log_rsrv_size(mdev, params)) *
++              MLX5E_SHAMPO_WQ_BASE_RESRV_SIZE;
+       u16 num_strides = BIT(mlx5e_mpwqe_get_log_num_strides(mdev, params, NULL));
+       int pkt_per_resv = BIT(mlx5e_shampo_get_log_pkt_per_rsrv(mdev, params));
+       u8 log_stride_sz = mlx5e_mpwqe_get_log_stride_size(mdev, params, NULL);
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-mvpp2-prevent-parser-tcam-memory-corruption.patch b/queue-6.14/net-mvpp2-prevent-parser-tcam-memory-corruption.patch
new file mode 100644 (file)
index 0000000..6e1c4fd
--- /dev/null
@@ -0,0 +1,659 @@
+From 7f5a28b049a23ef58066a4b1e26c359d2eb007c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 08:58:04 +0200
+Subject: net: mvpp2: Prevent parser TCAM memory corruption
+
+From: Tobias Waldekranz <tobias@waldekranz.com>
+
+[ Upstream commit 96844075226b49af25a69a1d084b648ec2d9b08d ]
+
+Protect the parser TCAM/SRAM memory, and the cached (shadow) SRAM
+information, from concurrent modifications.
+
+Both the TCAM and SRAM tables are indirectly accessed by configuring
+an index register that selects the row to read or write to. This means
+that operations must be atomic in order to, e.g., avoid spreading
+writes across multiple rows. Since the shadow SRAM array is used to
+find free rows in the hardware table, it must also be protected in
+order to avoid TOCTOU errors where multiple cores allocate the same
+row.
+
+This issue was detected in a situation where `mvpp2_set_rx_mode()` ran
+concurrently on two CPUs. In this particular case the
+MVPP2_PE_MAC_UC_PROMISCUOUS entry was corrupted, causing the
+classifier unit to drop all incoming unicast - indicated by the
+`rx_classifier_drops` counter.
+
+Fixes: 3f518509dedc ("ethernet: Add new driver for Marvell Armada 375 network unit")
+Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Tested-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20250401065855.3113635-1-tobias@waldekranz.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/mvpp2/mvpp2.h    |   3 +
+ .../net/ethernet/marvell/mvpp2/mvpp2_main.c   |   3 +-
+ .../net/ethernet/marvell/mvpp2/mvpp2_prs.c    | 201 ++++++++++++------
+ 3 files changed, 140 insertions(+), 67 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
+index 44fe9b68d1c22..061fcd444d503 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
+@@ -1113,6 +1113,9 @@ struct mvpp2 {
+       /* Spinlocks for CM3 shared memory configuration */
+       spinlock_t mss_spinlock;
++
++      /* Spinlock for shared PRS parser memory and shadow table */
++      spinlock_t prs_spinlock;
+ };
+ struct mvpp2_pcpu_stats {
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index dd76c1b7ed3a1..c63e5f1b168a9 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -7722,8 +7722,9 @@ static int mvpp2_probe(struct platform_device *pdev)
+       if (mvpp2_read(priv, MVPP2_VER_ID_REG) == MVPP2_VER_PP23)
+               priv->hw_version = MVPP23;
+-      /* Init mss lock */
++      /* Init locks for shared packet processor resources */
+       spin_lock_init(&priv->mss_spinlock);
++      spin_lock_init(&priv->prs_spinlock);
+       /* Initialize network controller */
+       err = mvpp2_init(pdev, priv);
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.c
+index 9af22f497a40f..93e978bdf303c 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.c
+@@ -23,6 +23,8 @@ static int mvpp2_prs_hw_write(struct mvpp2 *priv, struct mvpp2_prs_entry *pe)
+ {
+       int i;
++      lockdep_assert_held(&priv->prs_spinlock);
++
+       if (pe->index > MVPP2_PRS_TCAM_SRAM_SIZE - 1)
+               return -EINVAL;
+@@ -43,11 +45,13 @@ static int mvpp2_prs_hw_write(struct mvpp2 *priv, struct mvpp2_prs_entry *pe)
+ }
+ /* Initialize tcam entry from hw */
+-int mvpp2_prs_init_from_hw(struct mvpp2 *priv, struct mvpp2_prs_entry *pe,
+-                         int tid)
++static int __mvpp2_prs_init_from_hw(struct mvpp2 *priv,
++                                  struct mvpp2_prs_entry *pe, int tid)
+ {
+       int i;
++      lockdep_assert_held(&priv->prs_spinlock);
++
+       if (tid > MVPP2_PRS_TCAM_SRAM_SIZE - 1)
+               return -EINVAL;
+@@ -73,6 +77,18 @@ int mvpp2_prs_init_from_hw(struct mvpp2 *priv, struct mvpp2_prs_entry *pe,
+       return 0;
+ }
++int mvpp2_prs_init_from_hw(struct mvpp2 *priv, struct mvpp2_prs_entry *pe,
++                         int tid)
++{
++      int err;
++
++      spin_lock_bh(&priv->prs_spinlock);
++      err = __mvpp2_prs_init_from_hw(priv, pe, tid);
++      spin_unlock_bh(&priv->prs_spinlock);
++
++      return err;
++}
++
+ /* Invalidate tcam hw entry */
+ static void mvpp2_prs_hw_inv(struct mvpp2 *priv, int index)
+ {
+@@ -374,7 +390,7 @@ static int mvpp2_prs_flow_find(struct mvpp2 *priv, int flow)
+                   priv->prs_shadow[tid].lu != MVPP2_PRS_LU_FLOWS)
+                       continue;
+-              mvpp2_prs_init_from_hw(priv, &pe, tid);
++              __mvpp2_prs_init_from_hw(priv, &pe, tid);
+               bits = mvpp2_prs_sram_ai_get(&pe);
+               /* Sram store classification lookup ID in AI bits [5:0] */
+@@ -441,7 +457,7 @@ static void mvpp2_prs_mac_drop_all_set(struct mvpp2 *priv, int port, bool add)
+       if (priv->prs_shadow[MVPP2_PE_DROP_ALL].valid) {
+               /* Entry exist - update port only */
+-              mvpp2_prs_init_from_hw(priv, &pe, MVPP2_PE_DROP_ALL);
++              __mvpp2_prs_init_from_hw(priv, &pe, MVPP2_PE_DROP_ALL);
+       } else {
+               /* Entry doesn't exist - create new */
+               memset(&pe, 0, sizeof(pe));
+@@ -469,14 +485,17 @@ static void mvpp2_prs_mac_drop_all_set(struct mvpp2 *priv, int port, bool add)
+ }
+ /* Set port to unicast or multicast promiscuous mode */
+-void mvpp2_prs_mac_promisc_set(struct mvpp2 *priv, int port,
+-                             enum mvpp2_prs_l2_cast l2_cast, bool add)
++static void __mvpp2_prs_mac_promisc_set(struct mvpp2 *priv, int port,
++                                      enum mvpp2_prs_l2_cast l2_cast,
++                                      bool add)
+ {
+       struct mvpp2_prs_entry pe;
+       unsigned char cast_match;
+       unsigned int ri;
+       int tid;
++      lockdep_assert_held(&priv->prs_spinlock);
++
+       if (l2_cast == MVPP2_PRS_L2_UNI_CAST) {
+               cast_match = MVPP2_PRS_UCAST_VAL;
+               tid = MVPP2_PE_MAC_UC_PROMISCUOUS;
+@@ -489,7 +508,7 @@ void mvpp2_prs_mac_promisc_set(struct mvpp2 *priv, int port,
+       /* promiscuous mode - Accept unknown unicast or multicast packets */
+       if (priv->prs_shadow[tid].valid) {
+-              mvpp2_prs_init_from_hw(priv, &pe, tid);
++              __mvpp2_prs_init_from_hw(priv, &pe, tid);
+       } else {
+               memset(&pe, 0, sizeof(pe));
+               mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC);
+@@ -522,6 +541,14 @@ void mvpp2_prs_mac_promisc_set(struct mvpp2 *priv, int port,
+       mvpp2_prs_hw_write(priv, &pe);
+ }
++void mvpp2_prs_mac_promisc_set(struct mvpp2 *priv, int port,
++                             enum mvpp2_prs_l2_cast l2_cast, bool add)
++{
++      spin_lock_bh(&priv->prs_spinlock);
++      __mvpp2_prs_mac_promisc_set(priv, port, l2_cast, add);
++      spin_unlock_bh(&priv->prs_spinlock);
++}
++
+ /* Set entry for dsa packets */
+ static void mvpp2_prs_dsa_tag_set(struct mvpp2 *priv, int port, bool add,
+                                 bool tagged, bool extend)
+@@ -539,7 +566,7 @@ static void mvpp2_prs_dsa_tag_set(struct mvpp2 *priv, int port, bool add,
+       if (priv->prs_shadow[tid].valid) {
+               /* Entry exist - update port only */
+-              mvpp2_prs_init_from_hw(priv, &pe, tid);
++              __mvpp2_prs_init_from_hw(priv, &pe, tid);
+       } else {
+               /* Entry doesn't exist - create new */
+               memset(&pe, 0, sizeof(pe));
+@@ -610,7 +637,7 @@ static void mvpp2_prs_dsa_tag_ethertype_set(struct mvpp2 *priv, int port,
+       if (priv->prs_shadow[tid].valid) {
+               /* Entry exist - update port only */
+-              mvpp2_prs_init_from_hw(priv, &pe, tid);
++              __mvpp2_prs_init_from_hw(priv, &pe, tid);
+       } else {
+               /* Entry doesn't exist - create new */
+               memset(&pe, 0, sizeof(pe));
+@@ -673,7 +700,7 @@ static int mvpp2_prs_vlan_find(struct mvpp2 *priv, unsigned short tpid, int ai)
+                   priv->prs_shadow[tid].lu != MVPP2_PRS_LU_VLAN)
+                       continue;
+-              mvpp2_prs_init_from_hw(priv, &pe, tid);
++              __mvpp2_prs_init_from_hw(priv, &pe, tid);
+               match = mvpp2_prs_tcam_data_cmp(&pe, 0, tpid);
+               if (!match)
+                       continue;
+@@ -726,7 +753,7 @@ static int mvpp2_prs_vlan_add(struct mvpp2 *priv, unsigned short tpid, int ai,
+                           priv->prs_shadow[tid_aux].lu != MVPP2_PRS_LU_VLAN)
+                               continue;
+-                      mvpp2_prs_init_from_hw(priv, &pe, tid_aux);
++                      __mvpp2_prs_init_from_hw(priv, &pe, tid_aux);
+                       ri_bits = mvpp2_prs_sram_ri_get(&pe);
+                       if ((ri_bits & MVPP2_PRS_RI_VLAN_MASK) ==
+                           MVPP2_PRS_RI_VLAN_DOUBLE)
+@@ -760,7 +787,7 @@ static int mvpp2_prs_vlan_add(struct mvpp2 *priv, unsigned short tpid, int ai,
+               mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_VLAN);
+       } else {
+-              mvpp2_prs_init_from_hw(priv, &pe, tid);
++              __mvpp2_prs_init_from_hw(priv, &pe, tid);
+       }
+       /* Update ports' mask */
+       mvpp2_prs_tcam_port_map_set(&pe, port_map);
+@@ -800,7 +827,7 @@ static int mvpp2_prs_double_vlan_find(struct mvpp2 *priv, unsigned short tpid1,
+                   priv->prs_shadow[tid].lu != MVPP2_PRS_LU_VLAN)
+                       continue;
+-              mvpp2_prs_init_from_hw(priv, &pe, tid);
++              __mvpp2_prs_init_from_hw(priv, &pe, tid);
+               match = mvpp2_prs_tcam_data_cmp(&pe, 0, tpid1) &&
+                       mvpp2_prs_tcam_data_cmp(&pe, 4, tpid2);
+@@ -849,7 +876,7 @@ static int mvpp2_prs_double_vlan_add(struct mvpp2 *priv, unsigned short tpid1,
+                           priv->prs_shadow[tid_aux].lu != MVPP2_PRS_LU_VLAN)
+                               continue;
+-                      mvpp2_prs_init_from_hw(priv, &pe, tid_aux);
++                      __mvpp2_prs_init_from_hw(priv, &pe, tid_aux);
+                       ri_bits = mvpp2_prs_sram_ri_get(&pe);
+                       ri_bits &= MVPP2_PRS_RI_VLAN_MASK;
+                       if (ri_bits == MVPP2_PRS_RI_VLAN_SINGLE ||
+@@ -880,7 +907,7 @@ static int mvpp2_prs_double_vlan_add(struct mvpp2 *priv, unsigned short tpid1,
+               mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_VLAN);
+       } else {
+-              mvpp2_prs_init_from_hw(priv, &pe, tid);
++              __mvpp2_prs_init_from_hw(priv, &pe, tid);
+       }
+       /* Update ports' mask */
+@@ -1213,8 +1240,8 @@ static void mvpp2_prs_mac_init(struct mvpp2 *priv)
+       /* Create dummy entries for drop all and promiscuous modes */
+       mvpp2_prs_drop_fc(priv);
+       mvpp2_prs_mac_drop_all_set(priv, 0, false);
+-      mvpp2_prs_mac_promisc_set(priv, 0, MVPP2_PRS_L2_UNI_CAST, false);
+-      mvpp2_prs_mac_promisc_set(priv, 0, MVPP2_PRS_L2_MULTI_CAST, false);
++      __mvpp2_prs_mac_promisc_set(priv, 0, MVPP2_PRS_L2_UNI_CAST, false);
++      __mvpp2_prs_mac_promisc_set(priv, 0, MVPP2_PRS_L2_MULTI_CAST, false);
+ }
+ /* Set default entries for various types of dsa packets */
+@@ -1533,12 +1560,6 @@ static int mvpp2_prs_vlan_init(struct platform_device *pdev, struct mvpp2 *priv)
+       struct mvpp2_prs_entry pe;
+       int err;
+-      priv->prs_double_vlans = devm_kcalloc(&pdev->dev, sizeof(bool),
+-                                            MVPP2_PRS_DBL_VLANS_MAX,
+-                                            GFP_KERNEL);
+-      if (!priv->prs_double_vlans)
+-              return -ENOMEM;
+-
+       /* Double VLAN: 0x88A8, 0x8100 */
+       err = mvpp2_prs_double_vlan_add(priv, ETH_P_8021AD, ETH_P_8021Q,
+                                       MVPP2_PRS_PORT_MASK);
+@@ -1941,7 +1962,7 @@ static int mvpp2_prs_vid_range_find(struct mvpp2_port *port, u16 vid, u16 mask)
+                   port->priv->prs_shadow[tid].lu != MVPP2_PRS_LU_VID)
+                       continue;
+-              mvpp2_prs_init_from_hw(port->priv, &pe, tid);
++              __mvpp2_prs_init_from_hw(port->priv, &pe, tid);
+               mvpp2_prs_tcam_data_byte_get(&pe, 2, &byte[0], &enable[0]);
+               mvpp2_prs_tcam_data_byte_get(&pe, 3, &byte[1], &enable[1]);
+@@ -1970,6 +1991,8 @@ int mvpp2_prs_vid_entry_add(struct mvpp2_port *port, u16 vid)
+       memset(&pe, 0, sizeof(pe));
++      spin_lock_bh(&priv->prs_spinlock);
++
+       /* Scan TCAM and see if entry with this <vid,port> already exist */
+       tid = mvpp2_prs_vid_range_find(port, vid, mask);
+@@ -1988,8 +2011,10 @@ int mvpp2_prs_vid_entry_add(struct mvpp2_port *port, u16 vid)
+                                               MVPP2_PRS_VLAN_FILT_MAX_ENTRY);
+               /* There isn't room for a new VID filter */
+-              if (tid < 0)
++              if (tid < 0) {
++                      spin_unlock_bh(&priv->prs_spinlock);
+                       return tid;
++              }
+               mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_VID);
+               pe.index = tid;
+@@ -1997,7 +2022,7 @@ int mvpp2_prs_vid_entry_add(struct mvpp2_port *port, u16 vid)
+               /* Mask all ports */
+               mvpp2_prs_tcam_port_map_set(&pe, 0);
+       } else {
+-              mvpp2_prs_init_from_hw(priv, &pe, tid);
++              __mvpp2_prs_init_from_hw(priv, &pe, tid);
+       }
+       /* Enable the current port */
+@@ -2019,6 +2044,7 @@ int mvpp2_prs_vid_entry_add(struct mvpp2_port *port, u16 vid)
+       mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_VID);
+       mvpp2_prs_hw_write(priv, &pe);
++      spin_unlock_bh(&priv->prs_spinlock);
+       return 0;
+ }
+@@ -2028,15 +2054,16 @@ void mvpp2_prs_vid_entry_remove(struct mvpp2_port *port, u16 vid)
+       struct mvpp2 *priv = port->priv;
+       int tid;
+-      /* Scan TCAM and see if entry with this <vid,port> already exist */
+-      tid = mvpp2_prs_vid_range_find(port, vid, 0xfff);
++      spin_lock_bh(&priv->prs_spinlock);
+-      /* No such entry */
+-      if (tid < 0)
+-              return;
++      /* Invalidate TCAM entry with this <vid,port>, if it exists */
++      tid = mvpp2_prs_vid_range_find(port, vid, 0xfff);
++      if (tid >= 0) {
++              mvpp2_prs_hw_inv(priv, tid);
++              priv->prs_shadow[tid].valid = false;
++      }
+-      mvpp2_prs_hw_inv(priv, tid);
+-      priv->prs_shadow[tid].valid = false;
++      spin_unlock_bh(&priv->prs_spinlock);
+ }
+ /* Remove all existing VID filters on this port */
+@@ -2045,6 +2072,8 @@ void mvpp2_prs_vid_remove_all(struct mvpp2_port *port)
+       struct mvpp2 *priv = port->priv;
+       int tid;
++      spin_lock_bh(&priv->prs_spinlock);
++
+       for (tid = MVPP2_PRS_VID_PORT_FIRST(port->id);
+            tid <= MVPP2_PRS_VID_PORT_LAST(port->id); tid++) {
+               if (priv->prs_shadow[tid].valid) {
+@@ -2052,6 +2081,8 @@ void mvpp2_prs_vid_remove_all(struct mvpp2_port *port)
+                       priv->prs_shadow[tid].valid = false;
+               }
+       }
++
++      spin_unlock_bh(&priv->prs_spinlock);
+ }
+ /* Remove VID filering entry for this port */
+@@ -2060,10 +2091,14 @@ void mvpp2_prs_vid_disable_filtering(struct mvpp2_port *port)
+       unsigned int tid = MVPP2_PRS_VID_PORT_DFLT(port->id);
+       struct mvpp2 *priv = port->priv;
++      spin_lock_bh(&priv->prs_spinlock);
++
+       /* Invalidate the guard entry */
+       mvpp2_prs_hw_inv(priv, tid);
+       priv->prs_shadow[tid].valid = false;
++
++      spin_unlock_bh(&priv->prs_spinlock);
+ }
+ /* Add guard entry that drops packets when no VID is matched on this port */
+@@ -2079,6 +2114,8 @@ void mvpp2_prs_vid_enable_filtering(struct mvpp2_port *port)
+       memset(&pe, 0, sizeof(pe));
++      spin_lock_bh(&priv->prs_spinlock);
++
+       pe.index = tid;
+       reg_val = mvpp2_read(priv, MVPP2_MH_REG(port->id));
+@@ -2111,6 +2148,8 @@ void mvpp2_prs_vid_enable_filtering(struct mvpp2_port *port)
+       /* Update shadow table */
+       mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_VID);
+       mvpp2_prs_hw_write(priv, &pe);
++
++      spin_unlock_bh(&priv->prs_spinlock);
+ }
+ /* Parser default initialization */
+@@ -2118,6 +2157,20 @@ int mvpp2_prs_default_init(struct platform_device *pdev, struct mvpp2 *priv)
+ {
+       int err, index, i;
++      priv->prs_shadow = devm_kcalloc(&pdev->dev, MVPP2_PRS_TCAM_SRAM_SIZE,
++                                      sizeof(*priv->prs_shadow),
++                                      GFP_KERNEL);
++      if (!priv->prs_shadow)
++              return -ENOMEM;
++
++      priv->prs_double_vlans = devm_kcalloc(&pdev->dev, sizeof(bool),
++                                            MVPP2_PRS_DBL_VLANS_MAX,
++                                            GFP_KERNEL);
++      if (!priv->prs_double_vlans)
++              return -ENOMEM;
++
++      spin_lock_bh(&priv->prs_spinlock);
++
+       /* Enable tcam table */
+       mvpp2_write(priv, MVPP2_PRS_TCAM_CTRL_REG, MVPP2_PRS_TCAM_EN_MASK);
+@@ -2136,12 +2189,6 @@ int mvpp2_prs_default_init(struct platform_device *pdev, struct mvpp2 *priv)
+       for (index = 0; index < MVPP2_PRS_TCAM_SRAM_SIZE; index++)
+               mvpp2_prs_hw_inv(priv, index);
+-      priv->prs_shadow = devm_kcalloc(&pdev->dev, MVPP2_PRS_TCAM_SRAM_SIZE,
+-                                      sizeof(*priv->prs_shadow),
+-                                      GFP_KERNEL);
+-      if (!priv->prs_shadow)
+-              return -ENOMEM;
+-
+       /* Always start from lookup = 0 */
+       for (index = 0; index < MVPP2_MAX_PORTS; index++)
+               mvpp2_prs_hw_port_init(priv, index, MVPP2_PRS_LU_MH,
+@@ -2158,26 +2205,13 @@ int mvpp2_prs_default_init(struct platform_device *pdev, struct mvpp2 *priv)
+       mvpp2_prs_vid_init(priv);
+       err = mvpp2_prs_etype_init(priv);
+-      if (err)
+-              return err;
+-
+-      err = mvpp2_prs_vlan_init(pdev, priv);
+-      if (err)
+-              return err;
+-
+-      err = mvpp2_prs_pppoe_init(priv);
+-      if (err)
+-              return err;
+-
+-      err = mvpp2_prs_ip6_init(priv);
+-      if (err)
+-              return err;
+-
+-      err = mvpp2_prs_ip4_init(priv);
+-      if (err)
+-              return err;
++      err = err ? : mvpp2_prs_vlan_init(pdev, priv);
++      err = err ? : mvpp2_prs_pppoe_init(priv);
++      err = err ? : mvpp2_prs_ip6_init(priv);
++      err = err ? : mvpp2_prs_ip4_init(priv);
+-      return 0;
++      spin_unlock_bh(&priv->prs_spinlock);
++      return err;
+ }
+ /* Compare MAC DA with tcam entry data */
+@@ -2217,7 +2251,7 @@ mvpp2_prs_mac_da_range_find(struct mvpp2 *priv, int pmap, const u8 *da,
+                   (priv->prs_shadow[tid].udf != udf_type))
+                       continue;
+-              mvpp2_prs_init_from_hw(priv, &pe, tid);
++              __mvpp2_prs_init_from_hw(priv, &pe, tid);
+               entry_pmap = mvpp2_prs_tcam_port_map_get(&pe);
+               if (mvpp2_prs_mac_range_equals(&pe, da, mask) &&
+@@ -2229,7 +2263,8 @@ mvpp2_prs_mac_da_range_find(struct mvpp2 *priv, int pmap, const u8 *da,
+ }
+ /* Update parser's mac da entry */
+-int mvpp2_prs_mac_da_accept(struct mvpp2_port *port, const u8 *da, bool add)
++static int __mvpp2_prs_mac_da_accept(struct mvpp2_port *port,
++                                   const u8 *da, bool add)
+ {
+       unsigned char mask[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+       struct mvpp2 *priv = port->priv;
+@@ -2261,7 +2296,7 @@ int mvpp2_prs_mac_da_accept(struct mvpp2_port *port, const u8 *da, bool add)
+               /* Mask all ports */
+               mvpp2_prs_tcam_port_map_set(&pe, 0);
+       } else {
+-              mvpp2_prs_init_from_hw(priv, &pe, tid);
++              __mvpp2_prs_init_from_hw(priv, &pe, tid);
+       }
+       mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC);
+@@ -2317,6 +2352,17 @@ int mvpp2_prs_mac_da_accept(struct mvpp2_port *port, const u8 *da, bool add)
+       return 0;
+ }
++int mvpp2_prs_mac_da_accept(struct mvpp2_port *port, const u8 *da, bool add)
++{
++      int err;
++
++      spin_lock_bh(&port->priv->prs_spinlock);
++      err = __mvpp2_prs_mac_da_accept(port, da, add);
++      spin_unlock_bh(&port->priv->prs_spinlock);
++
++      return err;
++}
++
+ int mvpp2_prs_update_mac_da(struct net_device *dev, const u8 *da)
+ {
+       struct mvpp2_port *port = netdev_priv(dev);
+@@ -2345,6 +2391,8 @@ void mvpp2_prs_mac_del_all(struct mvpp2_port *port)
+       unsigned long pmap;
+       int index, tid;
++      spin_lock_bh(&priv->prs_spinlock);
++
+       for (tid = MVPP2_PE_MAC_RANGE_START;
+            tid <= MVPP2_PE_MAC_RANGE_END; tid++) {
+               unsigned char da[ETH_ALEN], da_mask[ETH_ALEN];
+@@ -2354,7 +2402,7 @@ void mvpp2_prs_mac_del_all(struct mvpp2_port *port)
+                   (priv->prs_shadow[tid].udf != MVPP2_PRS_UDF_MAC_DEF))
+                       continue;
+-              mvpp2_prs_init_from_hw(priv, &pe, tid);
++              __mvpp2_prs_init_from_hw(priv, &pe, tid);
+               pmap = mvpp2_prs_tcam_port_map_get(&pe);
+@@ -2375,14 +2423,17 @@ void mvpp2_prs_mac_del_all(struct mvpp2_port *port)
+                       continue;
+               /* Remove entry from TCAM */
+-              mvpp2_prs_mac_da_accept(port, da, false);
++              __mvpp2_prs_mac_da_accept(port, da, false);
+       }
++
++      spin_unlock_bh(&priv->prs_spinlock);
+ }
+ int mvpp2_prs_tag_mode_set(struct mvpp2 *priv, int port, int type)
+ {
+       switch (type) {
+       case MVPP2_TAG_TYPE_EDSA:
++              spin_lock_bh(&priv->prs_spinlock);
+               /* Add port to EDSA entries */
+               mvpp2_prs_dsa_tag_set(priv, port, true,
+                                     MVPP2_PRS_TAGGED, MVPP2_PRS_EDSA);
+@@ -2393,9 +2444,11 @@ int mvpp2_prs_tag_mode_set(struct mvpp2 *priv, int port, int type)
+                                     MVPP2_PRS_TAGGED, MVPP2_PRS_DSA);
+               mvpp2_prs_dsa_tag_set(priv, port, false,
+                                     MVPP2_PRS_UNTAGGED, MVPP2_PRS_DSA);
++              spin_unlock_bh(&priv->prs_spinlock);
+               break;
+       case MVPP2_TAG_TYPE_DSA:
++              spin_lock_bh(&priv->prs_spinlock);
+               /* Add port to DSA entries */
+               mvpp2_prs_dsa_tag_set(priv, port, true,
+                                     MVPP2_PRS_TAGGED, MVPP2_PRS_DSA);
+@@ -2406,10 +2459,12 @@ int mvpp2_prs_tag_mode_set(struct mvpp2 *priv, int port, int type)
+                                     MVPP2_PRS_TAGGED, MVPP2_PRS_EDSA);
+               mvpp2_prs_dsa_tag_set(priv, port, false,
+                                     MVPP2_PRS_UNTAGGED, MVPP2_PRS_EDSA);
++              spin_unlock_bh(&priv->prs_spinlock);
+               break;
+       case MVPP2_TAG_TYPE_MH:
+       case MVPP2_TAG_TYPE_NONE:
++              spin_lock_bh(&priv->prs_spinlock);
+               /* Remove port form EDSA and DSA entries */
+               mvpp2_prs_dsa_tag_set(priv, port, false,
+                                     MVPP2_PRS_TAGGED, MVPP2_PRS_DSA);
+@@ -2419,6 +2474,7 @@ int mvpp2_prs_tag_mode_set(struct mvpp2 *priv, int port, int type)
+                                     MVPP2_PRS_TAGGED, MVPP2_PRS_EDSA);
+               mvpp2_prs_dsa_tag_set(priv, port, false,
+                                     MVPP2_PRS_UNTAGGED, MVPP2_PRS_EDSA);
++              spin_unlock_bh(&priv->prs_spinlock);
+               break;
+       default:
+@@ -2437,11 +2493,15 @@ int mvpp2_prs_add_flow(struct mvpp2 *priv, int flow, u32 ri, u32 ri_mask)
+       memset(&pe, 0, sizeof(pe));
++      spin_lock_bh(&priv->prs_spinlock);
++
+       tid = mvpp2_prs_tcam_first_free(priv,
+                                       MVPP2_PE_LAST_FREE_TID,
+                                       MVPP2_PE_FIRST_FREE_TID);
+-      if (tid < 0)
++      if (tid < 0) {
++              spin_unlock_bh(&priv->prs_spinlock);
+               return tid;
++      }
+       pe.index = tid;
+@@ -2461,6 +2521,7 @@ int mvpp2_prs_add_flow(struct mvpp2 *priv, int flow, u32 ri, u32 ri_mask)
+       mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
+       mvpp2_prs_hw_write(priv, &pe);
++      spin_unlock_bh(&priv->prs_spinlock);
+       return 0;
+ }
+@@ -2472,6 +2533,8 @@ int mvpp2_prs_def_flow(struct mvpp2_port *port)
+       memset(&pe, 0, sizeof(pe));
++      spin_lock_bh(&port->priv->prs_spinlock);
++
+       tid = mvpp2_prs_flow_find(port->priv, port->id);
+       /* Such entry not exist */
+@@ -2480,8 +2543,10 @@ int mvpp2_prs_def_flow(struct mvpp2_port *port)
+               tid = mvpp2_prs_tcam_first_free(port->priv,
+                                               MVPP2_PE_LAST_FREE_TID,
+                                              MVPP2_PE_FIRST_FREE_TID);
+-              if (tid < 0)
++              if (tid < 0) {
++                      spin_unlock_bh(&port->priv->prs_spinlock);
+                       return tid;
++              }
+               pe.index = tid;
+@@ -2492,13 +2557,14 @@ int mvpp2_prs_def_flow(struct mvpp2_port *port)
+               /* Update shadow table */
+               mvpp2_prs_shadow_set(port->priv, pe.index, MVPP2_PRS_LU_FLOWS);
+       } else {
+-              mvpp2_prs_init_from_hw(port->priv, &pe, tid);
++              __mvpp2_prs_init_from_hw(port->priv, &pe, tid);
+       }
+       mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_FLOWS);
+       mvpp2_prs_tcam_port_map_set(&pe, (1 << port->id));
+       mvpp2_prs_hw_write(port->priv, &pe);
++      spin_unlock_bh(&port->priv->prs_spinlock);
+       return 0;
+ }
+@@ -2509,11 +2575,14 @@ int mvpp2_prs_hits(struct mvpp2 *priv, int index)
+       if (index > MVPP2_PRS_TCAM_SRAM_SIZE)
+               return -EINVAL;
++      spin_lock_bh(&priv->prs_spinlock);
++
+       mvpp2_write(priv, MVPP2_PRS_TCAM_HIT_IDX_REG, index);
+       val = mvpp2_read(priv, MVPP2_PRS_TCAM_HIT_CNT_REG);
+       val &= MVPP2_PRS_TCAM_HIT_CNT_MASK;
++      spin_unlock_bh(&priv->prs_spinlock);
+       return val;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-phy-broadcom-correct-bcm5221-phy-model-detection.patch b/queue-6.14/net-phy-broadcom-correct-bcm5221-phy-model-detection.patch
new file mode 100644 (file)
index 0000000..63caa84
--- /dev/null
@@ -0,0 +1,55 @@
+From 0354ffe21f51a4fd8eef7d6f58c6d60d0afb9119 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Mar 2025 14:29:42 +0800
+Subject: net: phy: broadcom: Correct BCM5221 PHY model detection
+
+From: Jim Liu <jim.t90615@gmail.com>
+
+[ Upstream commit 4f1eaabb4b66a1f7473f584e14e15b2ac19dfaf3 ]
+
+Correct detect condition is applied to the entire 5221 family of PHYs.
+
+Fixes: 3abbd0699b67 ("net: phy: broadcom: add support for BCM5221 phy")
+Signed-off-by: Jim Liu <jim.t90615@gmail.com>
+Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
+Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/broadcom.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
+index 22edb7e4c1a1f..5a963b2b7ea78 100644
+--- a/drivers/net/phy/broadcom.c
++++ b/drivers/net/phy/broadcom.c
+@@ -859,7 +859,7 @@ static int brcm_fet_config_init(struct phy_device *phydev)
+               return reg;
+       /* Unmask events we are interested in and mask interrupts globally. */
+-      if (phydev->phy_id == PHY_ID_BCM5221)
++      if (phydev->drv->phy_id == PHY_ID_BCM5221)
+               reg = MII_BRCM_FET_IR_ENABLE |
+                     MII_BRCM_FET_IR_MASK;
+       else
+@@ -888,7 +888,7 @@ static int brcm_fet_config_init(struct phy_device *phydev)
+               return err;
+       }
+-      if (phydev->phy_id != PHY_ID_BCM5221) {
++      if (phydev->drv->phy_id != PHY_ID_BCM5221) {
+               /* Set the LED mode */
+               reg = __phy_read(phydev, MII_BRCM_FET_SHDW_AUXMODE4);
+               if (reg < 0) {
+@@ -1009,7 +1009,7 @@ static int brcm_fet_suspend(struct phy_device *phydev)
+               return err;
+       }
+-      if (phydev->phy_id == PHY_ID_BCM5221)
++      if (phydev->drv->phy_id == PHY_ID_BCM5221)
+               /* Force Low Power Mode with clock enabled */
+               reg = BCM5221_SHDW_AM4_EN_CLK_LPM | BCM5221_SHDW_AM4_FORCE_LPM;
+       else
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-remove-rtnl-dance-for-siocbraddif-and-siocbrdeli.patch b/queue-6.14/net-remove-rtnl-dance-for-siocbraddif-and-siocbrdeli.patch
new file mode 100644 (file)
index 0000000..42924a4
--- /dev/null
@@ -0,0 +1,311 @@
+From 9e9fa9d0fac08b4795d41b3213c752dbc089df89 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 16 Mar 2025 12:28:37 -0700
+Subject: net: Remove RTNL dance for SIOCBRADDIF and SIOCBRDELIF.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit ed3ba9b6e280e14cc3148c1b226ba453f02fa76c ]
+
+SIOCBRDELIF is passed to dev_ioctl() first and later forwarded to
+br_ioctl_call(), which causes unnecessary RTNL dance and the splat
+below [0] under RTNL pressure.
+
+Let's say Thread A is trying to detach a device from a bridge and
+Thread B is trying to remove the bridge.
+
+In dev_ioctl(), Thread A bumps the bridge device's refcnt by
+netdev_hold() and releases RTNL because the following br_ioctl_call()
+also re-acquires RTNL.
+
+In the race window, Thread B could acquire RTNL and try to remove
+the bridge device.  Then, rtnl_unlock() by Thread B will release RTNL
+and wait for netdev_put() by Thread A.
+
+Thread A, however, must hold RTNL after the unlock in dev_ifsioc(),
+which may take long under RTNL pressure, resulting in the splat by
+Thread B.
+
+  Thread A (SIOCBRDELIF)           Thread B (SIOCBRDELBR)
+  ----------------------           ----------------------
+  sock_ioctl                       sock_ioctl
+  `- sock_do_ioctl                 `- br_ioctl_call
+     `- dev_ioctl                     `- br_ioctl_stub
+        |- rtnl_lock                     |
+        |- dev_ifsioc                    '
+        '  |- dev = __dev_get_by_name(...)
+           |- netdev_hold(dev, ...)      .
+       /   |- rtnl_unlock  ------.       |
+       |   |- br_ioctl_call       `--->  |- rtnl_lock
+  Race |   |  `- br_ioctl_stub           |- br_del_bridge
+  Window   |     |                       |  |- dev = __dev_get_by_name(...)
+       |   |     |  May take long        |  `- br_dev_delete(dev, ...)
+       |   |     |  under RTNL pressure  |     `- unregister_netdevice_queue(dev, ...)
+       |   |     |               |       `- rtnl_unlock
+       \   |     |- rtnl_lock  <-'          `- netdev_run_todo
+           |     |- ...                        `- netdev_run_todo
+           |     `- rtnl_unlock                   |- __rtnl_unlock
+           |                                      |- netdev_wait_allrefs_any
+           |- netdev_put(dev, ...)  <----------------'
+                                                Wait refcnt decrement
+                                                and log splat below
+
+To avoid blocking SIOCBRDELBR unnecessarily, let's not call
+dev_ioctl() for SIOCBRADDIF and SIOCBRDELIF.
+
+In the dev_ioctl() path, we do the following:
+
+  1. Copy struct ifreq by get_user_ifreq in sock_do_ioctl()
+  2. Check CAP_NET_ADMIN in dev_ioctl()
+  3. Call dev_load() in dev_ioctl()
+  4. Fetch the master dev from ifr.ifr_name in dev_ifsioc()
+
+3. can be done by request_module() in br_ioctl_call(), so we move
+1., 2., and 4. to br_ioctl_stub().
+
+Note that 2. is also checked later in add_del_if(), but it's better
+performed before RTNL.
+
+SIOCBRADDIF and SIOCBRDELIF have been processed in dev_ioctl() since
+the pre-git era, and there seems to be no specific reason to process
+them there.
+
+[0]:
+unregister_netdevice: waiting for wpan3 to become free. Usage count = 2
+ref_tracker: wpan3@ffff8880662d8608 has 1/1 users at
+     __netdev_tracker_alloc include/linux/netdevice.h:4282 [inline]
+     netdev_hold include/linux/netdevice.h:4311 [inline]
+     dev_ifsioc+0xc6a/0x1160 net/core/dev_ioctl.c:624
+     dev_ioctl+0x255/0x10c0 net/core/dev_ioctl.c:826
+     sock_do_ioctl+0x1ca/0x260 net/socket.c:1213
+     sock_ioctl+0x23a/0x6c0 net/socket.c:1318
+     vfs_ioctl fs/ioctl.c:51 [inline]
+     __do_sys_ioctl fs/ioctl.c:906 [inline]
+     __se_sys_ioctl fs/ioctl.c:892 [inline]
+     __x64_sys_ioctl+0x1a4/0x210 fs/ioctl.c:892
+     do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+     do_syscall_64+0xcb/0x250 arch/x86/entry/common.c:83
+     entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Fixes: 893b19587534 ("net: bridge: fix ioctl locking")
+Reported-by: syzkaller <syzkaller@googlegroups.com>
+Reported-by: yan kang <kangyan91@outlook.com>
+Reported-by: yue sun <samsun1006219@gmail.com>
+Closes: https://lore.kernel.org/netdev/SY8P300MB0421225D54EB92762AE8F0F2A1D32@SY8P300MB0421.AUSP300.PROD.OUTLOOK.COM/
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Acked-by: Stanislav Fomichev <sdf@fomichev.me>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
+Link: https://patch.msgid.link/20250316192851.19781-1-kuniyu@amazon.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/if_bridge.h |  6 ++----
+ net/bridge/br_ioctl.c     | 36 +++++++++++++++++++++++++++++++++---
+ net/bridge/br_private.h   |  3 +--
+ net/core/dev_ioctl.c      | 19 -------------------
+ net/socket.c              | 19 +++++++++----------
+ 5 files changed, 45 insertions(+), 38 deletions(-)
+
+diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h
+index 3ff96ae31bf6d..c5fe3b2a53e82 100644
+--- a/include/linux/if_bridge.h
++++ b/include/linux/if_bridge.h
+@@ -65,11 +65,9 @@ struct br_ip_list {
+ #define BR_DEFAULT_AGEING_TIME        (300 * HZ)
+ struct net_bridge;
+-void brioctl_set(int (*hook)(struct net *net, struct net_bridge *br,
+-                           unsigned int cmd, struct ifreq *ifr,
++void brioctl_set(int (*hook)(struct net *net, unsigned int cmd,
+                            void __user *uarg));
+-int br_ioctl_call(struct net *net, struct net_bridge *br, unsigned int cmd,
+-                struct ifreq *ifr, void __user *uarg);
++int br_ioctl_call(struct net *net, unsigned int cmd, void __user *uarg);
+ #if IS_ENABLED(CONFIG_BRIDGE) && IS_ENABLED(CONFIG_BRIDGE_IGMP_SNOOPING)
+ int br_multicast_list_adjacent(struct net_device *dev,
+diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c
+index f213ed1083618..6bc0a11f2ed3e 100644
+--- a/net/bridge/br_ioctl.c
++++ b/net/bridge/br_ioctl.c
+@@ -394,10 +394,26 @@ static int old_deviceless(struct net *net, void __user *data)
+       return -EOPNOTSUPP;
+ }
+-int br_ioctl_stub(struct net *net, struct net_bridge *br, unsigned int cmd,
+-                struct ifreq *ifr, void __user *uarg)
++int br_ioctl_stub(struct net *net, unsigned int cmd, void __user *uarg)
+ {
+       int ret = -EOPNOTSUPP;
++      struct ifreq ifr;
++
++      if (cmd == SIOCBRADDIF || cmd == SIOCBRDELIF) {
++              void __user *data;
++              char *colon;
++
++              if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
++                      return -EPERM;
++
++              if (get_user_ifreq(&ifr, &data, uarg))
++                      return -EFAULT;
++
++              ifr.ifr_name[IFNAMSIZ - 1] = 0;
++              colon = strchr(ifr.ifr_name, ':');
++              if (colon)
++                      *colon = 0;
++      }
+       rtnl_lock();
+@@ -430,7 +446,21 @@ int br_ioctl_stub(struct net *net, struct net_bridge *br, unsigned int cmd,
+               break;
+       case SIOCBRADDIF:
+       case SIOCBRDELIF:
+-              ret = add_del_if(br, ifr->ifr_ifindex, cmd == SIOCBRADDIF);
++      {
++              struct net_device *dev;
++
++              dev = __dev_get_by_name(net, ifr.ifr_name);
++              if (!dev || !netif_device_present(dev)) {
++                      ret = -ENODEV;
++                      break;
++              }
++              if (!netif_is_bridge_master(dev)) {
++                      ret = -EOPNOTSUPP;
++                      break;
++              }
++
++              ret = add_del_if(netdev_priv(dev), ifr.ifr_ifindex, cmd == SIOCBRADDIF);
++      }
+               break;
+       }
+diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
+index 1054b8a88edc4..d5b3c5936a79e 100644
+--- a/net/bridge/br_private.h
++++ b/net/bridge/br_private.h
+@@ -949,8 +949,7 @@ br_port_get_check_rtnl(const struct net_device *dev)
+ /* br_ioctl.c */
+ int br_dev_siocdevprivate(struct net_device *dev, struct ifreq *rq,
+                         void __user *data, int cmd);
+-int br_ioctl_stub(struct net *net, struct net_bridge *br, unsigned int cmd,
+-                struct ifreq *ifr, void __user *uarg);
++int br_ioctl_stub(struct net *net, unsigned int cmd, void __user *uarg);
+ /* br_multicast.c */
+ #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
+diff --git a/net/core/dev_ioctl.c b/net/core/dev_ioctl.c
+index 4c2098ac9d724..57f79f8e84665 100644
+--- a/net/core/dev_ioctl.c
++++ b/net/core/dev_ioctl.c
+@@ -551,7 +551,6 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, void __user *data,
+       int err;
+       struct net_device *dev = __dev_get_by_name(net, ifr->ifr_name);
+       const struct net_device_ops *ops;
+-      netdevice_tracker dev_tracker;
+       if (!dev)
+               return -ENODEV;
+@@ -614,22 +613,6 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, void __user *data,
+       case SIOCWANDEV:
+               return dev_siocwandev(dev, &ifr->ifr_settings);
+-      case SIOCBRADDIF:
+-      case SIOCBRDELIF:
+-              if (!netif_device_present(dev))
+-                      return -ENODEV;
+-              if (!netif_is_bridge_master(dev))
+-                      return -EOPNOTSUPP;
+-
+-              netdev_hold(dev, &dev_tracker, GFP_KERNEL);
+-              rtnl_net_unlock(net);
+-
+-              err = br_ioctl_call(net, netdev_priv(dev), cmd, ifr, NULL);
+-
+-              netdev_put(dev, &dev_tracker);
+-              rtnl_net_lock(net);
+-              return err;
+-
+       case SIOCDEVPRIVATE ... SIOCDEVPRIVATE + 15:
+               return dev_siocdevprivate(dev, ifr, data, cmd);
+@@ -812,8 +795,6 @@ int dev_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr,
+       case SIOCBONDRELEASE:
+       case SIOCBONDSETHWADDR:
+       case SIOCBONDCHANGEACTIVE:
+-      case SIOCBRADDIF:
+-      case SIOCBRDELIF:
+       case SIOCSHWTSTAMP:
+               if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
+                       return -EPERM;
+diff --git a/net/socket.c b/net/socket.c
+index 28bae5a942341..38227d00d1987 100644
+--- a/net/socket.c
++++ b/net/socket.c
+@@ -1145,12 +1145,10 @@ static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from)
+  */
+ static DEFINE_MUTEX(br_ioctl_mutex);
+-static int (*br_ioctl_hook)(struct net *net, struct net_bridge *br,
+-                          unsigned int cmd, struct ifreq *ifr,
++static int (*br_ioctl_hook)(struct net *net, unsigned int cmd,
+                           void __user *uarg);
+-void brioctl_set(int (*hook)(struct net *net, struct net_bridge *br,
+-                           unsigned int cmd, struct ifreq *ifr,
++void brioctl_set(int (*hook)(struct net *net, unsigned int cmd,
+                            void __user *uarg))
+ {
+       mutex_lock(&br_ioctl_mutex);
+@@ -1159,8 +1157,7 @@ void brioctl_set(int (*hook)(struct net *net, struct net_bridge *br,
+ }
+ EXPORT_SYMBOL(brioctl_set);
+-int br_ioctl_call(struct net *net, struct net_bridge *br, unsigned int cmd,
+-                struct ifreq *ifr, void __user *uarg)
++int br_ioctl_call(struct net *net, unsigned int cmd, void __user *uarg)
+ {
+       int err = -ENOPKG;
+@@ -1169,7 +1166,7 @@ int br_ioctl_call(struct net *net, struct net_bridge *br, unsigned int cmd,
+       mutex_lock(&br_ioctl_mutex);
+       if (br_ioctl_hook)
+-              err = br_ioctl_hook(net, br, cmd, ifr, uarg);
++              err = br_ioctl_hook(net, cmd, uarg);
+       mutex_unlock(&br_ioctl_mutex);
+       return err;
+@@ -1269,7 +1266,9 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
+               case SIOCSIFBR:
+               case SIOCBRADDBR:
+               case SIOCBRDELBR:
+-                      err = br_ioctl_call(net, NULL, cmd, NULL, argp);
++              case SIOCBRADDIF:
++              case SIOCBRDELIF:
++                      err = br_ioctl_call(net, cmd, argp);
+                       break;
+               case SIOCGIFVLAN:
+               case SIOCSIFVLAN:
+@@ -3429,6 +3428,8 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
+       case SIOCGPGRP:
+       case SIOCBRADDBR:
+       case SIOCBRDELBR:
++      case SIOCBRADDIF:
++      case SIOCBRDELIF:
+       case SIOCGIFVLAN:
+       case SIOCSIFVLAN:
+       case SIOCGSKNS:
+@@ -3468,8 +3469,6 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
+       case SIOCGIFPFLAGS:
+       case SIOCGIFTXQLEN:
+       case SIOCSIFTXQLEN:
+-      case SIOCBRADDIF:
+-      case SIOCBRDELIF:
+       case SIOCGIFNAME:
+       case SIOCSIFNAME:
+       case SIOCGMIIPHY:
+-- 
+2.39.5
+
diff --git a/queue-6.14/net_sched-skbprio-remove-overly-strict-queue-asserti.patch b/queue-6.14/net_sched-skbprio-remove-overly-strict-queue-asserti.patch
new file mode 100644 (file)
index 0000000..c071b8c
--- /dev/null
@@ -0,0 +1,60 @@
+From f1085a31189fe6111a4bc28ceef7c19fcb388130 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 29 Mar 2025 15:25:35 -0700
+Subject: net_sched: skbprio: Remove overly strict queue assertions
+
+From: Cong Wang <xiyou.wangcong@gmail.com>
+
+[ Upstream commit ce8fe975fd99b49c29c42e50f2441ba53112b2e8 ]
+
+In the current implementation, skbprio enqueue/dequeue contains an assertion
+that fails under certain conditions when SKBPRIO is used as a child qdisc under
+TBF with specific parameters. The failure occurs because TBF sometimes peeks at
+packets in the child qdisc without actually dequeuing them when tokens are
+unavailable.
+
+This peek operation creates a discrepancy between the parent and child qdisc
+queue length counters. When TBF later receives a high-priority packet,
+SKBPRIO's queue length may show a different value than what's reflected in its
+internal priority queue tracking, triggering the assertion.
+
+The fix removes this overly strict assertions in SKBPRIO, they are not
+necessary at all.
+
+Reported-by: syzbot+a3422a19b05ea96bee18@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=a3422a19b05ea96bee18
+Fixes: aea5f654e6b7 ("net/sched: add skbprio scheduler")
+Cc: Nishanth Devarajan <ndev2021@gmail.com>
+Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
+Acked-by: Paolo Abeni <pabeni@redhat.com>
+Link: https://patch.msgid.link/20250329222536.696204-2-xiyou.wangcong@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_skbprio.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/net/sched/sch_skbprio.c b/net/sched/sch_skbprio.c
+index 20ff7386b74bd..f485f62ab721a 100644
+--- a/net/sched/sch_skbprio.c
++++ b/net/sched/sch_skbprio.c
+@@ -123,8 +123,6 @@ static int skbprio_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+       /* Check to update highest and lowest priorities. */
+       if (skb_queue_empty(lp_qdisc)) {
+               if (q->lowest_prio == q->highest_prio) {
+-                      /* The incoming packet is the only packet in queue. */
+-                      BUG_ON(sch->q.qlen != 1);
+                       q->lowest_prio = prio;
+                       q->highest_prio = prio;
+               } else {
+@@ -156,7 +154,6 @@ static struct sk_buff *skbprio_dequeue(struct Qdisc *sch)
+       /* Update highest priority field. */
+       if (skb_queue_empty(hpq)) {
+               if (q->lowest_prio == q->highest_prio) {
+-                      BUG_ON(sch->q.qlen);
+                       q->highest_prio = 0;
+                       q->lowest_prio = SKBPRIO_MAX_PRIORITY - 1;
+               } else {
+-- 
+2.39.5
+
diff --git a/queue-6.14/netfilter-nf_tables-don-t-unregister-hook-when-table.patch b/queue-6.14/netfilter-nf_tables-don-t-unregister-hook-when-table.patch
new file mode 100644 (file)
index 0000000..0615405
--- /dev/null
@@ -0,0 +1,48 @@
+From 9f16a61be7c5b148885004a6645bc0ca4552a772 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 14:36:47 +0200
+Subject: netfilter: nf_tables: don't unregister hook when table is dormant
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit 688c15017d5cd5aac882400782e7213d40dc3556 ]
+
+When nf_tables_updchain encounters an error, hook registration needs to
+be rolled back.
+
+This should only be done if the hook has been registered, which won't
+happen when the table is flagged as dormant (inactive).
+
+Just move the assignment into the registration block.
+
+Reported-by: syzbot+53ed3a6440173ddbf499@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=53ed3a6440173ddbf499
+Fixes: b9703ed44ffb ("netfilter: nf_tables: support for adding new devices to an existing netdev chain")
+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/nf_tables_api.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index c2df81b7e9505..a133e1c175ce9 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -2839,11 +2839,11 @@ static int nf_tables_updchain(struct nft_ctx *ctx, u8 genmask, u8 policy,
+                       err = nft_netdev_register_hooks(ctx->net, &hook.list);
+                       if (err < 0)
+                               goto err_hooks;
++
++                      unregister = true;
+               }
+       }
+-      unregister = true;
+-
+       if (nla[NFTA_CHAIN_COUNTERS]) {
+               if (!nft_is_base_chain(chain)) {
+                       err = -EOPNOTSUPP;
+-- 
+2.39.5
+
diff --git a/queue-6.14/netfilter-nf_tables-only-use-nf_skip_indirect_calls-.patch b/queue-6.14/netfilter-nf_tables-only-use-nf_skip_indirect_calls-.patch
new file mode 100644 (file)
index 0000000..5b0e773
--- /dev/null
@@ -0,0 +1,77 @@
+From 61f92995d2e0568223f4f7fddb5f44eebe6e6cd6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Mar 2025 22:01:47 +0800
+Subject: netfilter: nf_tables: Only use nf_skip_indirect_calls() when
+ MITIGATION_RETPOLINE
+
+From: WangYuli <wangyuli@uniontech.com>
+
+[ Upstream commit e3a4182edd1ae60e7e3539ff3b3784af9830d223 ]
+
+1. MITIGATION_RETPOLINE is x86-only (defined in arch/x86/Kconfig),
+so no need to AND with CONFIG_X86 when checking if enabled.
+
+2. Remove unused declaration of nf_skip_indirect_calls() when
+MITIGATION_RETPOLINE is disabled to avoid warnings.
+
+3. Declare nf_skip_indirect_calls() and nf_skip_indirect_calls_enable()
+as inline when MITIGATION_RETPOLINE is enabled, as they are called
+only once and have simple logic.
+
+Fix follow error with clang-21 when W=1e:
+  net/netfilter/nf_tables_core.c:39:20: error: unused function 'nf_skip_indirect_calls' [-Werror,-Wunused-function]
+     39 | static inline bool nf_skip_indirect_calls(void) { return false; }
+        |                    ^~~~~~~~~~~~~~~~~~~~~~
+  1 error generated.
+  make[4]: *** [scripts/Makefile.build:207: net/netfilter/nf_tables_core.o] Error 1
+  make[3]: *** [scripts/Makefile.build:465: net/netfilter] Error 2
+  make[3]: *** Waiting for unfinished jobs....
+
+Fixes: d8d760627855 ("netfilter: nf_tables: add static key to skip retpoline workarounds")
+Co-developed-by: Wentao Guan <guanwentao@uniontech.com>
+Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
+Signed-off-by: WangYuli <wangyuli@uniontech.com>
+Acked-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/nf_tables_core.c | 11 ++++-------
+ 1 file changed, 4 insertions(+), 7 deletions(-)
+
+diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c
+index 75598520b0fa0..6557a4018c099 100644
+--- a/net/netfilter/nf_tables_core.c
++++ b/net/netfilter/nf_tables_core.c
+@@ -21,25 +21,22 @@
+ #include <net/netfilter/nf_log.h>
+ #include <net/netfilter/nft_meta.h>
+-#if defined(CONFIG_MITIGATION_RETPOLINE) && defined(CONFIG_X86)
+-
++#ifdef CONFIG_MITIGATION_RETPOLINE
+ static struct static_key_false nf_tables_skip_direct_calls;
+-static bool nf_skip_indirect_calls(void)
++static inline bool nf_skip_indirect_calls(void)
+ {
+       return static_branch_likely(&nf_tables_skip_direct_calls);
+ }
+-static void __init nf_skip_indirect_calls_enable(void)
++static inline void __init nf_skip_indirect_calls_enable(void)
+ {
+       if (!cpu_feature_enabled(X86_FEATURE_RETPOLINE))
+               static_branch_enable(&nf_tables_skip_direct_calls);
+ }
+ #else
+-static inline bool nf_skip_indirect_calls(void) { return false; }
+-
+ static inline void nf_skip_indirect_calls_enable(void) { }
+-#endif
++#endif /* CONFIG_MITIGATION_RETPOLINE */
+ static noinline void __nft_trace_packet(const struct nft_pktinfo *pkt,
+                                       const struct nft_verdict *verdict,
+-- 
+2.39.5
+
diff --git a/queue-6.14/netfilter-nfnetlink_queue-initialize-ctx-to-avoid-me.patch b/queue-6.14/netfilter-nfnetlink_queue-initialize-ctx-to-avoid-me.patch
new file mode 100644 (file)
index 0000000..11196d2
--- /dev/null
@@ -0,0 +1,44 @@
+From 5ca0eab51fc25ecf2a730d0237c3f1cd34d75ab3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Mar 2025 14:54:41 -0500
+Subject: netfilter: nfnetlink_queue: Initialize ctx to avoid memory allocation
+ error
+
+From: Chenyuan Yang <chenyuan0y@gmail.com>
+
+[ Upstream commit 778b09d91baafb13408470c721d034d6515cfa5a ]
+
+It is possible that ctx in nfqnl_build_packet_message() could be used
+before it is properly initialize, which is only initialized
+by nfqnl_get_sk_secctx().
+
+This patch corrects this problem by initializing the lsmctx to a safe
+value when it is declared.
+
+This is similar to the commit 35fcac7a7c25
+("audit: Initialize lsmctx to avoid memory allocation error").
+
+Fixes: 2d470c778120 ("lsm: replace context+len with lsm_context")
+Signed-off-by: Chenyuan Yang <chenyuan0y@gmail.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nfnetlink_queue.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
+index 5c913987901ab..8b7b39d8a1091 100644
+--- a/net/netfilter/nfnetlink_queue.c
++++ b/net/netfilter/nfnetlink_queue.c
+@@ -567,7 +567,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
+       enum ip_conntrack_info ctinfo = 0;
+       const struct nfnl_ct_hook *nfnl_ct;
+       bool csum_verify;
+-      struct lsm_context ctx;
++      struct lsm_context ctx = { NULL, 0, 0 };
+       int seclen = 0;
+       ktime_t tstamp;
+-- 
+2.39.5
+
diff --git a/queue-6.14/netfilter-nft_set_hash-gc-reaps-elements-with-connco.patch b/queue-6.14/netfilter-nft_set_hash-gc-reaps-elements-with-connco.patch
new file mode 100644 (file)
index 0000000..79cd3ce
--- /dev/null
@@ -0,0 +1,40 @@
+From e04bba514ca0b87680190ba7b74cfa31c467a881 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Mar 2025 23:24:20 +0100
+Subject: netfilter: nft_set_hash: GC reaps elements with conncount for dynamic
+ sets only
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 9d74da1177c800eb3d51c13f9821b7b0683845a5 ]
+
+conncount has its own GC handler which determines when to reap stale
+elements, this is convenient for dynamic sets. However, this also reaps
+non-dynamic sets with static configurations coming from control plane.
+Always run connlimit gc handler but honor feedback to reap element if
+this set is dynamic.
+
+Fixes: 290180e2448c ("netfilter: nf_tables: add connlimit support")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_set_hash.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/net/netfilter/nft_set_hash.c b/net/netfilter/nft_set_hash.c
+index 8bfac4185ac79..abb0c8ec63719 100644
+--- a/net/netfilter/nft_set_hash.c
++++ b/net/netfilter/nft_set_hash.c
+@@ -309,7 +309,8 @@ static bool nft_rhash_expr_needs_gc_run(const struct nft_set *set,
+       nft_setelem_expr_foreach(expr, elem_expr, size) {
+               if (expr->ops->gc &&
+-                  expr->ops->gc(read_pnet(&set->net), expr))
++                  expr->ops->gc(read_pnet(&set->net), expr) &&
++                  set->flags & NFT_SET_EVAL)
+                       return true;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/netfilter-nft_tunnel-fix-geneve_opt-type-confusion-a.patch b/queue-6.14/netfilter-nft_tunnel-fix-geneve_opt-type-confusion-a.patch
new file mode 100644 (file)
index 0000000..593cb83
--- /dev/null
@@ -0,0 +1,88 @@
+From 66f8fc68e7b330086029913efc8db0532f0cb25f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Apr 2025 01:00:26 +0800
+Subject: netfilter: nft_tunnel: fix geneve_opt type confusion addition
+
+From: Lin Ma <linma@zju.edu.cn>
+
+[ Upstream commit 1b755d8eb1ace3870789d48fbd94f386ad6e30be ]
+
+When handling multiple NFTA_TUNNEL_KEY_OPTS_GENEVE attributes, the
+parsing logic should place every geneve_opt structure one by one
+compactly. Hence, when deciding the next geneve_opt position, the
+pointer addition should be in units of char *.
+
+However, the current implementation erroneously does type conversion
+before the addition, which will lead to heap out-of-bounds write.
+
+[    6.989857] ==================================================================
+[    6.990293] BUG: KASAN: slab-out-of-bounds in nft_tunnel_obj_init+0x977/0xa70
+[    6.990725] Write of size 124 at addr ffff888005f18974 by task poc/178
+[    6.991162]
+[    6.991259] CPU: 0 PID: 178 Comm: poc-oob-write Not tainted 6.1.132 #1
+[    6.991655] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014
+[    6.992281] Call Trace:
+[    6.992423]  <TASK>
+[    6.992586]  dump_stack_lvl+0x44/0x5c
+[    6.992801]  print_report+0x184/0x4be
+[    6.993790]  kasan_report+0xc5/0x100
+[    6.994252]  kasan_check_range+0xf3/0x1a0
+[    6.994486]  memcpy+0x38/0x60
+[    6.994692]  nft_tunnel_obj_init+0x977/0xa70
+[    6.995677]  nft_obj_init+0x10c/0x1b0
+[    6.995891]  nf_tables_newobj+0x585/0x950
+[    6.996922]  nfnetlink_rcv_batch+0xdf9/0x1020
+[    6.998997]  nfnetlink_rcv+0x1df/0x220
+[    6.999537]  netlink_unicast+0x395/0x530
+[    7.000771]  netlink_sendmsg+0x3d0/0x6d0
+[    7.001462]  __sock_sendmsg+0x99/0xa0
+[    7.001707]  ____sys_sendmsg+0x409/0x450
+[    7.002391]  ___sys_sendmsg+0xfd/0x170
+[    7.003145]  __sys_sendmsg+0xea/0x170
+[    7.004359]  do_syscall_64+0x5e/0x90
+[    7.005817]  entry_SYSCALL_64_after_hwframe+0x6e/0xd8
+[    7.006127] RIP: 0033:0x7ec756d4e407
+[    7.006339] Code: 48 89 fa 4c 89 df e8 38 aa 00 00 8b 93 08 03 00 00 59 5e 48 83 f8 fc 74 1a 5b c3 0f 1f 84 00 00 00 00 00 48 8b 44 24 10 0f 05 <5b> c3 0f 1f 80 00 00 00 00 83 e2 39 83 faf
+[    7.007364] RSP: 002b:00007ffed5d46760 EFLAGS: 00000202 ORIG_RAX: 000000000000002e
+[    7.007827] RAX: ffffffffffffffda RBX: 00007ec756cc4740 RCX: 00007ec756d4e407
+[    7.008223] RDX: 0000000000000000 RSI: 00007ffed5d467f0 RDI: 0000000000000003
+[    7.008620] RBP: 00007ffed5d468a0 R08: 0000000000000000 R09: 0000000000000000
+[    7.009039] R10: 0000000000000000 R11: 0000000000000202 R12: 0000000000000000
+[    7.009429] R13: 00007ffed5d478b0 R14: 00007ec756ee5000 R15: 00005cbd4e655cb8
+
+Fix this bug with correct pointer addition and conversion in parse
+and dump code.
+
+Fixes: 925d844696d9 ("netfilter: nft_tunnel: add support for geneve opts")
+Signed-off-by: Lin Ma <linma@zju.edu.cn>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_tunnel.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/netfilter/nft_tunnel.c b/net/netfilter/nft_tunnel.c
+index 681301b46aa40..2e40f575aed9f 100644
+--- a/net/netfilter/nft_tunnel.c
++++ b/net/netfilter/nft_tunnel.c
+@@ -341,7 +341,7 @@ static const struct nla_policy nft_tunnel_opts_geneve_policy[NFTA_TUNNEL_KEY_GEN
+ static int nft_tunnel_obj_geneve_init(const struct nlattr *attr,
+                                     struct nft_tunnel_opts *opts)
+ {
+-      struct geneve_opt *opt = (struct geneve_opt *)opts->u.data + opts->len;
++      struct geneve_opt *opt = (struct geneve_opt *)(opts->u.data + opts->len);
+       struct nlattr *tb[NFTA_TUNNEL_KEY_GENEVE_MAX + 1];
+       int err, data_len;
+@@ -625,7 +625,7 @@ static int nft_tunnel_opts_dump(struct sk_buff *skb,
+               if (!inner)
+                       goto failure;
+               while (opts->len > offset) {
+-                      opt = (struct geneve_opt *)opts->u.data + offset;
++                      opt = (struct geneve_opt *)(opts->u.data + offset);
+                       if (nla_put_be16(skb, NFTA_TUNNEL_KEY_GENEVE_CLASS,
+                                        opt->opt_class) ||
+                           nla_put_u8(skb, NFTA_TUNNEL_KEY_GENEVE_TYPE,
+-- 
+2.39.5
+
diff --git a/queue-6.14/netlabel-fix-null-pointer-exception-caused-by-calips.patch b/queue-6.14/netlabel-fix-null-pointer-exception-caused-by-calips.patch
new file mode 100644 (file)
index 0000000..6ba6f36
--- /dev/null
@@ -0,0 +1,87 @@
+From a82444a72916ca60ee3405034c118ab4306e753d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 20:40:18 +0800
+Subject: netlabel: Fix NULL pointer exception caused by CALIPSO on IPv4
+ sockets
+
+From: Debin Zhu <mowenroot@163.com>
+
+[ Upstream commit 078aabd567de3d63d37d7673f714e309d369e6e2 ]
+
+When calling netlbl_conn_setattr(), addr->sa_family is used
+to determine the function behavior. If sk is an IPv4 socket,
+but the connect function is called with an IPv6 address,
+the function calipso_sock_setattr() is triggered.
+Inside this function, the following code is executed:
+
+sk_fullsock(__sk) ? inet_sk(__sk)->pinet6 : NULL;
+
+Since sk is an IPv4 socket, pinet6 is NULL, leading to a
+null pointer dereference.
+
+This patch fixes the issue by checking if inet6_sk(sk)
+returns a NULL pointer before accessing pinet6.
+
+Signed-off-by: Debin Zhu <mowenroot@163.com>
+Signed-off-by: Bitao Ouyang <1985755126@qq.com>
+Acked-by: Paul Moore <paul@paul-moore.com>
+Fixes: ceba1832b1b2 ("calipso: Set the calipso socket label to match the secattr.")
+Link: https://patch.msgid.link/20250401124018.4763-1-mowenroot@163.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/calipso.c | 21 ++++++++++++++++++---
+ 1 file changed, 18 insertions(+), 3 deletions(-)
+
+diff --git a/net/ipv6/calipso.c b/net/ipv6/calipso.c
+index dbcea9fee6262..62618a058b8fa 100644
+--- a/net/ipv6/calipso.c
++++ b/net/ipv6/calipso.c
+@@ -1072,8 +1072,13 @@ static int calipso_sock_getattr(struct sock *sk,
+       struct ipv6_opt_hdr *hop;
+       int opt_len, len, ret_val = -ENOMSG, offset;
+       unsigned char *opt;
+-      struct ipv6_txoptions *txopts = txopt_get(inet6_sk(sk));
++      struct ipv6_pinfo *pinfo = inet6_sk(sk);
++      struct ipv6_txoptions *txopts;
++
++      if (!pinfo)
++              return -EAFNOSUPPORT;
++      txopts = txopt_get(pinfo);
+       if (!txopts || !txopts->hopopt)
+               goto done;
+@@ -1125,8 +1130,13 @@ static int calipso_sock_setattr(struct sock *sk,
+ {
+       int ret_val;
+       struct ipv6_opt_hdr *old, *new;
+-      struct ipv6_txoptions *txopts = txopt_get(inet6_sk(sk));
++      struct ipv6_pinfo *pinfo = inet6_sk(sk);
++      struct ipv6_txoptions *txopts;
++
++      if (!pinfo)
++              return -EAFNOSUPPORT;
++      txopts = txopt_get(pinfo);
+       old = NULL;
+       if (txopts)
+               old = txopts->hopopt;
+@@ -1153,8 +1163,13 @@ static int calipso_sock_setattr(struct sock *sk,
+ static void calipso_sock_delattr(struct sock *sk)
+ {
+       struct ipv6_opt_hdr *new_hop;
+-      struct ipv6_txoptions *txopts = txopt_get(inet6_sk(sk));
++      struct ipv6_pinfo *pinfo = inet6_sk(sk);
++      struct ipv6_txoptions *txopts;
++
++      if (!pinfo)
++              return;
++      txopts = txopt_get(pinfo);
+       if (!txopts || !txopts->hopopt)
+               goto done;
+-- 
+2.39.5
+
diff --git a/queue-6.14/netlink-specs-rt_route-pull-the-ifa-prefix-out-of-th.patch b/queue-6.14/netlink-specs-rt_route-pull-the-ifa-prefix-out-of-th.patch
new file mode 100644 (file)
index 0000000..72b2961
--- /dev/null
@@ -0,0 +1,342 @@
+From 3b4c0e06426e336d139aecf7da324d986009e7e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Apr 2025 18:37:06 -0700
+Subject: netlink: specs: rt_route: pull the ifa- prefix out of the names
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 1a1eba0e9899c286914032c78708c614b016704b ]
+
+YAML specs don't normally include the C prefix name in the name
+of the YAML attr. Remove the ifa- prefix from all attributes
+in route-attrs and metrics and specify name-prefix instead.
+
+This is a bit risky, hopefully there aren't many users out there.
+
+Fixes: 023289b4f582 ("doc/netlink: Add spec for rt route messages")
+Reviewed-by: Donald Hunter <donald.hunter@gmail.com>
+Link: https://patch.msgid.link/20250403013706.2828322-5-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/netlink/specs/rt_route.yaml | 180 +++++++++++-----------
+ 1 file changed, 91 insertions(+), 89 deletions(-)
+
+diff --git a/Documentation/netlink/specs/rt_route.yaml b/Documentation/netlink/specs/rt_route.yaml
+index a674103e5bc4e..292469c7d4b9f 100644
+--- a/Documentation/netlink/specs/rt_route.yaml
++++ b/Documentation/netlink/specs/rt_route.yaml
+@@ -80,165 +80,167 @@ definitions:
+ attribute-sets:
+   -
+     name: route-attrs
++    name-prefix: rta-
+     attributes:
+       -
+-        name: rta-dst
++        name: dst
+         type: binary
+         display-hint: ipv4
+       -
+-        name: rta-src
++        name: src
+         type: binary
+         display-hint: ipv4
+       -
+-        name: rta-iif
++        name: iif
+         type: u32
+       -
+-        name: rta-oif
++        name: oif
+         type: u32
+       -
+-        name: rta-gateway
++        name: gateway
+         type: binary
+         display-hint: ipv4
+       -
+-        name: rta-priority
++        name: priority
+         type: u32
+       -
+-        name: rta-prefsrc
++        name: prefsrc
+         type: binary
+         display-hint: ipv4
+       -
+-        name: rta-metrics
++        name: metrics
+         type: nest
+-        nested-attributes: rta-metrics
++        nested-attributes: metrics
+       -
+-        name: rta-multipath
++        name: multipath
+         type: binary
+       -
+-        name: rta-protoinfo # not used
++        name: protoinfo # not used
+         type: binary
+       -
+-        name: rta-flow
++        name: flow
+         type: u32
+       -
+-        name: rta-cacheinfo
++        name: cacheinfo
+         type: binary
+         struct: rta-cacheinfo
+       -
+-        name: rta-session # not used
++        name: session # not used
+         type: binary
+       -
+-        name: rta-mp-algo # not used
++        name: mp-algo # not used
+         type: binary
+       -
+-        name: rta-table
++        name: table
+         type: u32
+       -
+-        name: rta-mark
++        name: mark
+         type: u32
+       -
+-        name: rta-mfc-stats
++        name: mfc-stats
+         type: binary
+       -
+-        name: rta-via
++        name: via
+         type: binary
+       -
+-        name: rta-newdst
++        name: newdst
+         type: binary
+       -
+-        name: rta-pref
++        name: pref
+         type: u8
+       -
+-        name: rta-encap-type
++        name: encap-type
+         type: u16
+       -
+-        name: rta-encap
++        name: encap
+         type: binary # tunnel specific nest
+       -
+-        name: rta-expires
++        name: expires
+         type: u32
+       -
+-        name: rta-pad
++        name: pad
+         type: binary
+       -
+-        name: rta-uid
++        name: uid
+         type: u32
+       -
+-        name: rta-ttl-propagate
++        name: ttl-propagate
+         type: u8
+       -
+-        name: rta-ip-proto
++        name: ip-proto
+         type: u8
+       -
+-        name: rta-sport
++        name: sport
+         type: u16
+       -
+-        name: rta-dport
++        name: dport
+         type: u16
+       -
+-        name: rta-nh-id
++        name: nh-id
+         type: u32
+       -
+-        name: rta-flowlabel
++        name: flowlabel
+         type: u32
+         byte-order: big-endian
+         display-hint: hex
+   -
+-    name: rta-metrics
++    name: metrics
++    name-prefix: rtax-
+     attributes:
+       -
+-        name: rtax-unspec
++        name: unspec
+         type: unused
+         value: 0
+       -
+-        name: rtax-lock
++        name: lock
+         type: u32
+       -
+-        name: rtax-mtu
++        name: mtu
+         type: u32
+       -
+-        name: rtax-window
++        name: window
+         type: u32
+       -
+-        name: rtax-rtt
++        name: rtt
+         type: u32
+       -
+-        name: rtax-rttvar
++        name: rttvar
+         type: u32
+       -
+-        name: rtax-ssthresh
++        name: ssthresh
+         type: u32
+       -
+-        name: rtax-cwnd
++        name: cwnd
+         type: u32
+       -
+-        name: rtax-advmss
++        name: advmss
+         type: u32
+       -
+-        name: rtax-reordering
++        name: reordering
+         type: u32
+       -
+-        name: rtax-hoplimit
++        name: hoplimit
+         type: u32
+       -
+-        name: rtax-initcwnd
++        name: initcwnd
+         type: u32
+       -
+-        name: rtax-features
++        name: features
+         type: u32
+       -
+-        name: rtax-rto-min
++        name: rto-min
+         type: u32
+       -
+-        name: rtax-initrwnd
++        name: initrwnd
+         type: u32
+       -
+-        name: rtax-quickack
++        name: quickack
+         type: u32
+       -
+-        name: rtax-cc-algo
++        name: cc-algo
+         type: string
+       -
+-        name: rtax-fastopen-no-cookie
++        name: fastopen-no-cookie
+         type: u32
+ operations:
+@@ -254,18 +256,18 @@ operations:
+           value: 26
+           attributes:
+             - rtm-family
+-            - rta-src
++            - src
+             - rtm-src-len
+-            - rta-dst
++            - dst
+             - rtm-dst-len
+-            - rta-iif
+-            - rta-oif
+-            - rta-ip-proto
+-            - rta-sport
+-            - rta-dport
+-            - rta-mark
+-            - rta-uid
+-            - rta-flowlabel
++            - iif
++            - oif
++            - ip-proto
++            - sport
++            - dport
++            - mark
++            - uid
++            - flowlabel
+         reply:
+           value: 24
+           attributes: &all-route-attrs
+@@ -278,34 +280,34 @@ operations:
+             - rtm-scope
+             - rtm-type
+             - rtm-flags
+-            - rta-dst
+-            - rta-src
+-            - rta-iif
+-            - rta-oif
+-            - rta-gateway
+-            - rta-priority
+-            - rta-prefsrc
+-            - rta-metrics
+-            - rta-multipath
+-            - rta-flow
+-            - rta-cacheinfo
+-            - rta-table
+-            - rta-mark
+-            - rta-mfc-stats
+-            - rta-via
+-            - rta-newdst
+-            - rta-pref
+-            - rta-encap-type
+-            - rta-encap
+-            - rta-expires
+-            - rta-pad
+-            - rta-uid
+-            - rta-ttl-propagate
+-            - rta-ip-proto
+-            - rta-sport
+-            - rta-dport
+-            - rta-nh-id
+-            - rta-flowlabel
++            - dst
++            - src
++            - iif
++            - oif
++            - gateway
++            - priority
++            - prefsrc
++            - metrics
++            - multipath
++            - flow
++            - cacheinfo
++            - table
++            - mark
++            - mfc-stats
++            - via
++            - newdst
++            - pref
++            - encap-type
++            - encap
++            - expires
++            - pad
++            - uid
++            - ttl-propagate
++            - ip-proto
++            - sport
++            - dport
++            - nh-id
++            - flowlabel
+       dump:
+         request:
+           value: 26
+-- 
+2.39.5
+
diff --git a/queue-6.14/nfs-add-missing-release-on-error-in-nfs_lock_and_joi.patch b/queue-6.14/nfs-add-missing-release-on-error-in-nfs_lock_and_joi.patch
new file mode 100644 (file)
index 0000000..15b24da
--- /dev/null
@@ -0,0 +1,39 @@
+From a7fef49891bb5564300c6f997e7879270fb29bdd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Apr 2025 14:02:40 +0300
+Subject: nfs: Add missing release on error in nfs_lock_and_join_requests()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 8e5419d6542fdf2dca9a0acdef2b8255f0e4ba69 ]
+
+Call nfs_release_request() on this error path before returning.
+
+Fixes: c3f2235782c3 ("nfs: fold nfs_folio_find_and_lock_request into nfs_lock_and_join_requests")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://lore.kernel.org/r/3aaaa3d5-1c8a-41e4-98c7-717801ddd171@stanley.mountain
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/write.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/fs/nfs/write.c b/fs/nfs/write.c
+index aa3d8bea3ec06..23df8b214474f 100644
+--- a/fs/nfs/write.c
++++ b/fs/nfs/write.c
+@@ -579,8 +579,10 @@ static struct nfs_page *nfs_lock_and_join_requests(struct folio *folio)
+       while (!nfs_lock_request(head)) {
+               ret = nfs_wait_on_request(head);
+-              if (ret < 0)
++              if (ret < 0) {
++                      nfs_release_request(head);
+                       return ERR_PTR(ret);
++              }
+       }
+       /* Ensure that nobody removed the request before we locked it */
+-- 
+2.39.5
+
diff --git a/queue-6.14/nfs-fix-open_owner_id_maxsz-and-related-fields.patch b/queue-6.14/nfs-fix-open_owner_id_maxsz-and-related-fields.patch
new file mode 100644 (file)
index 0000000..097c0aa
--- /dev/null
@@ -0,0 +1,100 @@
+From eccd76691bbf571aeaf92519d946d8fd437a63d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Dec 2024 13:53:09 +1100
+Subject: NFS: fix open_owner_id_maxsz and related fields.
+
+From: NeilBrown <neilb@suse.de>
+
+[ Upstream commit 43502f6e8d1e767d6736ea0676cc784025cf6eeb ]
+
+A recent change increased the size of an NFSv4 open owner, but didn't
+increase the corresponding max_sz defines.  This is not know to have
+caused failure, but should be fixed.
+
+This patch also fixes some relates _maxsz fields that are wrong.
+
+Note that the XXX_owner_id_maxsz values now are only the size of the id
+and do NOT include the len field that will always preceed the id in xdr
+encoding.  I think this is clearer.
+
+Reported-by: David Disseldorp <ddiss@suse.com>
+Fixes: d98f72272500 ("nfs: simplify and guarantee owner uniqueness.")
+Signed-off-by: NeilBrown <neilb@suse.de>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/nfs4xdr.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
+index e8ac3f615f932..71f45cc0ca74d 100644
+--- a/fs/nfs/nfs4xdr.c
++++ b/fs/nfs/nfs4xdr.c
+@@ -82,9 +82,8 @@ static int decode_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req,
+  * we currently use size 2 (u64) out of (NFS4_OPAQUE_LIMIT  >> 2)
+  */
+ #define pagepad_maxsz         (1)
+-#define open_owner_id_maxsz   (1 + 2 + 1 + 1 + 2)
+-#define lock_owner_id_maxsz   (1 + 1 + 4)
+-#define decode_lockowner_maxsz        (1 + XDR_QUADLEN(IDMAP_NAMESZ))
++#define open_owner_id_maxsz   (2 + 1 + 2 + 2)
++#define lock_owner_id_maxsz   (2 + 1 + 2)
+ #define compound_encode_hdr_maxsz     (3 + (NFS4_MAXTAGLEN >> 2))
+ #define compound_decode_hdr_maxsz     (3 + (NFS4_MAXTAGLEN >> 2))
+ #define op_encode_hdr_maxsz   (1)
+@@ -185,7 +184,7 @@ static int decode_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req,
+ #define encode_claim_null_maxsz       (1 + nfs4_name_maxsz)
+ #define encode_open_maxsz     (op_encode_hdr_maxsz + \
+                               2 + encode_share_access_maxsz + 2 + \
+-                              open_owner_id_maxsz + \
++                              1 + open_owner_id_maxsz + \
+                               encode_opentype_maxsz + \
+                               encode_claim_null_maxsz)
+ #define decode_space_limit_maxsz      (3)
+@@ -255,13 +254,14 @@ static int decode_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req,
+ #define encode_link_maxsz     (op_encode_hdr_maxsz + \
+                               nfs4_name_maxsz)
+ #define decode_link_maxsz     (op_decode_hdr_maxsz + decode_change_info_maxsz)
+-#define encode_lockowner_maxsz        (7)
++#define encode_lockowner_maxsz        (2 + 1 + lock_owner_id_maxsz)
++
+ #define encode_lock_maxsz     (op_encode_hdr_maxsz + \
+                                7 + \
+                                1 + encode_stateid_maxsz + 1 + \
+                                encode_lockowner_maxsz)
+ #define decode_lock_denied_maxsz \
+-                              (8 + decode_lockowner_maxsz)
++                              (2 + 2 + 1 + 2 + 1 + lock_owner_id_maxsz)
+ #define decode_lock_maxsz     (op_decode_hdr_maxsz + \
+                                decode_lock_denied_maxsz)
+ #define encode_lockt_maxsz    (op_encode_hdr_maxsz + 5 + \
+@@ -617,7 +617,7 @@ static int decode_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req,
+                                encode_lockowner_maxsz)
+ #define NFS4_dec_release_lockowner_sz \
+                               (compound_decode_hdr_maxsz + \
+-                               decode_lockowner_maxsz)
++                               decode_release_lockowner_maxsz)
+ #define NFS4_enc_access_sz    (compound_encode_hdr_maxsz + \
+                               encode_sequence_maxsz + \
+                               encode_putfh_maxsz + \
+@@ -1412,7 +1412,7 @@ static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_opena
+       __be32 *p;
+  /*
+  * opcode 4, seqid 4, share_access 4, share_deny 4, clientid 8, ownerlen 4,
+- * owner 4 = 32
++ * owner 28
+  */
+       encode_nfs4_seqid(xdr, arg->seqid);
+       encode_share_access(xdr, arg->share_access);
+@@ -5077,7 +5077,7 @@ static int decode_link(struct xdr_stream *xdr, struct nfs4_change_info *cinfo)
+ /*
+  * We create the owner, so we know a proper owner.id length is 4.
+  */
+-static int decode_lock_denied (struct xdr_stream *xdr, struct file_lock *fl)
++static int decode_lock_denied(struct xdr_stream *xdr, struct file_lock *fl)
+ {
+       uint64_t offset, length, clientid;
+       __be32 *p;
+-- 
+2.39.5
+
diff --git a/queue-6.14/nfs-shut-down-the-nfs_client-only-after-all-the-supe.patch b/queue-6.14/nfs-shut-down-the-nfs_client-only-after-all-the-supe.patch
new file mode 100644 (file)
index 0000000..08b3b1f
--- /dev/null
@@ -0,0 +1,78 @@
+From 098bf8ca8c15b04aef6e92d815ee6f78901e9c2b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Mar 2025 17:58:50 -0400
+Subject: NFS: Shut down the nfs_client only after all the superblocks
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit 2d3e998a0bc7fe26a724f87a8ce217848040520e ]
+
+The nfs_client manages state for all the superblocks in the
+"cl_superblocks" list, so it must not be shut down until all of them are
+gone.
+
+Fixes: 7d3e26a054c8 ("NFS: Cancel all existing RPC tasks when shutdown")
+Reviewed-by: Benjamin Coddington <bcodding@redhat.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/sysfs.c | 22 +++++++++++++++++++++-
+ 1 file changed, 21 insertions(+), 1 deletion(-)
+
+diff --git a/fs/nfs/sysfs.c b/fs/nfs/sysfs.c
+index 7b59a40d40c06..784f7c1d003bf 100644
+--- a/fs/nfs/sysfs.c
++++ b/fs/nfs/sysfs.c
+@@ -14,6 +14,7 @@
+ #include <linux/rcupdate.h>
+ #include <linux/lockd/lockd.h>
++#include "internal.h"
+ #include "nfs4_fs.h"
+ #include "netns.h"
+ #include "sysfs.h"
+@@ -228,6 +229,25 @@ static void shutdown_client(struct rpc_clnt *clnt)
+       rpc_cancel_tasks(clnt, -EIO, shutdown_match_client, NULL);
+ }
++/*
++ * Shut down the nfs_client only once all the superblocks
++ * have been shut down.
++ */
++static void shutdown_nfs_client(struct nfs_client *clp)
++{
++      struct nfs_server *server;
++      rcu_read_lock();
++      list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
++              if (!(server->flags & NFS_MOUNT_SHUTDOWN)) {
++                      rcu_read_unlock();
++                      return;
++              }
++      }
++      rcu_read_unlock();
++      nfs_mark_client_ready(clp, -EIO);
++      shutdown_client(clp->cl_rpcclient);
++}
++
+ static ssize_t
+ shutdown_show(struct kobject *kobj, struct kobj_attribute *attr,
+                               char *buf)
+@@ -259,7 +279,6 @@ shutdown_store(struct kobject *kobj, struct kobj_attribute *attr,
+       server->flags |= NFS_MOUNT_SHUTDOWN;
+       shutdown_client(server->client);
+-      shutdown_client(server->nfs_client->cl_rpcclient);
+       if (!IS_ERR(server->client_acl))
+               shutdown_client(server->client_acl);
+@@ -267,6 +286,7 @@ shutdown_store(struct kobject *kobj, struct kobj_attribute *attr,
+       if (server->nlm_host)
+               shutdown_client(server->nlm_host->h_rpcclnt);
+ out:
++      shutdown_nfs_client(server->nfs_client);
+       return count;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/nfsd-fix-callback-decoder-status-codes.patch b/queue-6.14/nfsd-fix-callback-decoder-status-codes.patch
new file mode 100644 (file)
index 0000000..cc2d0ec
--- /dev/null
@@ -0,0 +1,82 @@
+From 568d44cb669a6640e09778695184c3b435475c50 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Feb 2025 12:03:32 -0500
+Subject: NFSD: Fix callback decoder status codes
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+[ Upstream commit 8ce35dcaf3aed7113cd692759dc0a26cec8cd0c3 ]
+
+fs/nfsd/nfs4callback.c implements a callback client. Thus its XDR
+decoders are decoding replies, not calls.
+
+NFS4ERR_BAD_XDR is an on-the-wire status code that reports that the
+client sent a corrupted RPC /call/. It's not used as the internal
+error code when a /reply/ can't be decoded, since that kind of
+failure is never reported to the sender of that RPC message.
+
+Instead, a reply decoder should return -EIO, as the reply decoders
+in the NFS client do.
+
+Fixes: 6487a13b5c6b ("NFSD: add support for CB_GETATTR callback")
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/nfs4callback.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
+index 484077200c5d7..d649a3d65a3a5 100644
+--- a/fs/nfsd/nfs4callback.c
++++ b/fs/nfsd/nfs4callback.c
+@@ -101,15 +101,15 @@ static int decode_cb_fattr4(struct xdr_stream *xdr, uint32_t *bitmap,
+       if (bitmap[0] & FATTR4_WORD0_CHANGE)
+               if (xdr_stream_decode_u64(xdr, &fattr->ncf_cb_change) < 0)
+-                      return -NFSERR_BAD_XDR;
++                      return -EIO;
+       if (bitmap[0] & FATTR4_WORD0_SIZE)
+               if (xdr_stream_decode_u64(xdr, &fattr->ncf_cb_fsize) < 0)
+-                      return -NFSERR_BAD_XDR;
++                      return -EIO;
+       if (bitmap[2] & FATTR4_WORD2_TIME_DELEG_ACCESS) {
+               fattr4_time_deleg_access access;
+               if (!xdrgen_decode_fattr4_time_deleg_access(xdr, &access))
+-                      return -NFSERR_BAD_XDR;
++                      return -EIO;
+               fattr->ncf_cb_atime.tv_sec = access.seconds;
+               fattr->ncf_cb_atime.tv_nsec = access.nseconds;
+@@ -118,7 +118,7 @@ static int decode_cb_fattr4(struct xdr_stream *xdr, uint32_t *bitmap,
+               fattr4_time_deleg_modify modify;
+               if (!xdrgen_decode_fattr4_time_deleg_modify(xdr, &modify))
+-                      return -NFSERR_BAD_XDR;
++                      return -EIO;
+               fattr->ncf_cb_mtime.tv_sec = modify.seconds;
+               fattr->ncf_cb_mtime.tv_nsec = modify.nseconds;
+@@ -682,15 +682,15 @@ static int nfs4_xdr_dec_cb_getattr(struct rpc_rqst *rqstp,
+       if (unlikely(status || cb->cb_status))
+               return status;
+       if (xdr_stream_decode_uint32_array(xdr, bitmap, 3) < 0)
+-              return -NFSERR_BAD_XDR;
++              return -EIO;
+       if (xdr_stream_decode_u32(xdr, &attrlen) < 0)
+-              return -NFSERR_BAD_XDR;
++              return -EIO;
+       maxlen = sizeof(ncf->ncf_cb_change) + sizeof(ncf->ncf_cb_fsize);
+       if (bitmap[2] != 0)
+               maxlen += (sizeof(ncf->ncf_cb_mtime.tv_sec) +
+                          sizeof(ncf->ncf_cb_mtime.tv_nsec)) * 2;
+       if (attrlen > maxlen)
+-              return -NFSERR_BAD_XDR;
++              return -EIO;
+       status = decode_cb_fattr4(xdr, bitmap, ncf);
+       return status;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/nfsv4-avoid-unnecessary-scans-of-filesystems-for-del.patch b/queue-6.14/nfsv4-avoid-unnecessary-scans-of-filesystems-for-del.patch
new file mode 100644 (file)
index 0000000..17720cf
--- /dev/null
@@ -0,0 +1,102 @@
+From 7341ed38ac3e8da4d0c19e64f8825f31f9e6f383 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Feb 2025 18:37:51 -0500
+Subject: NFSv4: Avoid unnecessary scans of filesystems for delayed delegations
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit e767b59e29b8327d25edde65efc743f479f30d0a ]
+
+The amount of looping through the list of delegations is occasionally
+leading to soft lockups. If the state manager was asked to manage the
+delayed return of delegations, then only scan those filesystems
+containing delegations that were marked as being delayed.
+
+Fixes: be20037725d1 ("NFSv4: Fix delegation return in cases where we have to retry")
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/delegation.c       | 18 ++++++++++++------
+ include/linux/nfs_fs_sb.h |  1 +
+ 2 files changed, 13 insertions(+), 6 deletions(-)
+
+diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
+index abd952cc47e4b..325ba0663a6de 100644
+--- a/fs/nfs/delegation.c
++++ b/fs/nfs/delegation.c
+@@ -331,14 +331,16 @@ nfs_start_delegation_return(struct nfs_inode *nfsi)
+ }
+ static void nfs_abort_delegation_return(struct nfs_delegation *delegation,
+-                                      struct nfs_client *clp, int err)
++                                      struct nfs_server *server, int err)
+ {
+-
+       spin_lock(&delegation->lock);
+       clear_bit(NFS_DELEGATION_RETURNING, &delegation->flags);
+       if (err == -EAGAIN) {
+               set_bit(NFS_DELEGATION_RETURN_DELAYED, &delegation->flags);
+-              set_bit(NFS4CLNT_DELEGRETURN_DELAYED, &clp->cl_state);
++              set_bit(NFS4SERV_DELEGRETURN_DELAYED,
++                      &server->delegation_flags);
++              set_bit(NFS4CLNT_DELEGRETURN_DELAYED,
++                      &server->nfs_client->cl_state);
+       }
+       spin_unlock(&delegation->lock);
+ }
+@@ -548,7 +550,7 @@ int nfs_inode_set_delegation(struct inode *inode, const struct cred *cred,
+  */
+ static int nfs_end_delegation_return(struct inode *inode, struct nfs_delegation *delegation, int issync)
+ {
+-      struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
++      struct nfs_server *server = NFS_SERVER(inode);
+       unsigned int mode = O_WRONLY | O_RDWR;
+       int err = 0;
+@@ -570,11 +572,11 @@ static int nfs_end_delegation_return(struct inode *inode, struct nfs_delegation
+               /*
+                * Guard against state recovery
+                */
+-              err = nfs4_wait_clnt_recover(clp);
++              err = nfs4_wait_clnt_recover(server->nfs_client);
+       }
+       if (err) {
+-              nfs_abort_delegation_return(delegation, clp, err);
++              nfs_abort_delegation_return(delegation, server, err);
+               goto out;
+       }
+@@ -678,6 +680,9 @@ static bool nfs_server_clear_delayed_delegations(struct nfs_server *server)
+       struct nfs_delegation *d;
+       bool ret = false;
++      if (!test_and_clear_bit(NFS4SERV_DELEGRETURN_DELAYED,
++                              &server->delegation_flags))
++              goto out;
+       list_for_each_entry_rcu (d, &server->delegations, super_list) {
+               if (!test_bit(NFS_DELEGATION_RETURN_DELAYED, &d->flags))
+                       continue;
+@@ -685,6 +690,7 @@ static bool nfs_server_clear_delayed_delegations(struct nfs_server *server)
+               clear_bit(NFS_DELEGATION_RETURN_DELAYED, &d->flags);
+               ret = true;
+       }
++out:
+       return ret;
+ }
+diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
+index 7d6f164036fac..108862d81b579 100644
+--- a/include/linux/nfs_fs_sb.h
++++ b/include/linux/nfs_fs_sb.h
+@@ -253,6 +253,7 @@ struct nfs_server {
+       unsigned long           delegation_flags;
+ #define NFS4SERV_DELEGRETURN          (1)
+ #define NFS4SERV_DELEGATION_EXPIRED   (2)
++#define NFS4SERV_DELEGRETURN_DELAYED  (3)
+       unsigned long           delegation_gen;
+       unsigned long           mig_gen;
+       unsigned long           mig_status;
+-- 
+2.39.5
+
diff --git a/queue-6.14/nfsv4-avoid-unnecessary-scans-of-filesystems-for-exp.patch b/queue-6.14/nfsv4-avoid-unnecessary-scans-of-filesystems-for-exp.patch
new file mode 100644 (file)
index 0000000..e86b090
--- /dev/null
@@ -0,0 +1,69 @@
+From 357e5a298a29879766e42963624041b8c62f5609 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Feb 2025 19:03:21 -0500
+Subject: NFSv4: Avoid unnecessary scans of filesystems for expired delegations
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit f163aa81a799e2d46d7f8f0b42a0e7770eaa0d06 ]
+
+The amount of looping through the list of delegations is occasionally
+leading to soft lockups.  If the state manager was asked to reap the
+expired delegations, it should scan only those filesystems that hold
+delegations that need to be reaped.
+
+Fixes: 7f156ef0bf45 ("NFSv4: Clean up nfs_delegation_reap_expired()")
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/delegation.c       | 7 +++++++
+ include/linux/nfs_fs_sb.h | 1 +
+ 2 files changed, 8 insertions(+)
+
+diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
+index d1f5e497729c3..abd952cc47e4b 100644
+--- a/fs/nfs/delegation.c
++++ b/fs/nfs/delegation.c
+@@ -1284,6 +1284,7 @@ static void nfs_mark_test_expired_delegation(struct nfs_server *server,
+               return;
+       clear_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags);
+       set_bit(NFS_DELEGATION_TEST_EXPIRED, &delegation->flags);
++      set_bit(NFS4SERV_DELEGATION_EXPIRED, &server->delegation_flags);
+       set_bit(NFS4CLNT_DELEGATION_EXPIRED, &server->nfs_client->cl_state);
+ }
+@@ -1362,6 +1363,9 @@ static int nfs_server_reap_expired_delegations(struct nfs_server *server,
+       nfs4_stateid stateid;
+       unsigned long gen = ++server->delegation_gen;
++      if (!test_and_clear_bit(NFS4SERV_DELEGATION_EXPIRED,
++                              &server->delegation_flags))
++              return 0;
+ restart:
+       rcu_read_lock();
+       list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
+@@ -1391,6 +1395,9 @@ static int nfs_server_reap_expired_delegations(struct nfs_server *server,
+                       goto restart;
+               }
+               nfs_inode_mark_test_expired_delegation(server,inode);
++              set_bit(NFS4SERV_DELEGATION_EXPIRED, &server->delegation_flags);
++              set_bit(NFS4CLNT_DELEGATION_EXPIRED,
++                      &server->nfs_client->cl_state);
+               iput(inode);
+               return -EAGAIN;
+       }
+diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
+index 4e9ad6f6e9073..7d6f164036fac 100644
+--- a/include/linux/nfs_fs_sb.h
++++ b/include/linux/nfs_fs_sb.h
+@@ -252,6 +252,7 @@ struct nfs_server {
+       unsigned long           delegation_flags;
+ #define NFS4SERV_DELEGRETURN          (1)
++#define NFS4SERV_DELEGATION_EXPIRED   (2)
+       unsigned long           delegation_gen;
+       unsigned long           mig_gen;
+       unsigned long           mig_status;
+-- 
+2.39.5
+
diff --git a/queue-6.14/nfsv4-avoid-unnecessary-scans-of-filesystems-for-ret.patch b/queue-6.14/nfsv4-avoid-unnecessary-scans-of-filesystems-for-ret.patch
new file mode 100644 (file)
index 0000000..f533c13
--- /dev/null
@@ -0,0 +1,69 @@
+From a41df55372959244ea27825e4ebb903e0c4c4e36 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Feb 2025 18:14:26 -0500
+Subject: NFSv4: Avoid unnecessary scans of filesystems for returning
+ delegations
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit 35a566a24e58f1b5f89737edf60b77de58719ed0 ]
+
+The amount of looping through the list of delegations is occasionally
+leading to soft lockups. If the state manager was asked to return
+delegations asynchronously, it should only scan those filesystems that
+hold delegations that need to be returned.
+
+Fixes: af3b61bf6131 ("NFSv4: Clean up nfs_client_return_marked_delegations()")
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/delegation.c       | 5 +++++
+ include/linux/nfs_fs_sb.h | 2 ++
+ 2 files changed, 7 insertions(+)
+
+diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
+index df77d68d9ff99..d1f5e497729c3 100644
+--- a/fs/nfs/delegation.c
++++ b/fs/nfs/delegation.c
+@@ -79,6 +79,7 @@ static void nfs_mark_return_delegation(struct nfs_server *server,
+                                      struct nfs_delegation *delegation)
+ {
+       set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
++      set_bit(NFS4SERV_DELEGRETURN, &server->delegation_flags);
+       set_bit(NFS4CLNT_DELEGRETURN, &server->nfs_client->cl_state);
+ }
+@@ -608,6 +609,9 @@ static int nfs_server_return_marked_delegations(struct nfs_server *server,
+       struct nfs_delegation *place_holder_deleg = NULL;
+       int err = 0;
++      if (!test_and_clear_bit(NFS4SERV_DELEGRETURN,
++                              &server->delegation_flags))
++              return 0;
+ restart:
+       /*
+        * To avoid quadratic looping we hold a reference
+@@ -659,6 +663,7 @@ static int nfs_server_return_marked_delegations(struct nfs_server *server,
+               cond_resched();
+               if (!err)
+                       goto restart;
++              set_bit(NFS4SERV_DELEGRETURN, &server->delegation_flags);
+               set_bit(NFS4CLNT_DELEGRETURN, &server->nfs_client->cl_state);
+               goto out;
+       }
+diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
+index f00bfcee7120e..4e9ad6f6e9073 100644
+--- a/include/linux/nfs_fs_sb.h
++++ b/include/linux/nfs_fs_sb.h
+@@ -250,6 +250,8 @@ struct nfs_server {
+       struct list_head        ss_copies;
+       struct list_head        ss_src_copies;
++      unsigned long           delegation_flags;
++#define NFS4SERV_DELEGRETURN          (1)
+       unsigned long           delegation_gen;
+       unsigned long           mig_gen;
+       unsigned long           mig_status;
+-- 
+2.39.5
+
diff --git a/queue-6.14/nfsv4-don-t-trigger-uneccessary-scans-for-return-on-.patch b/queue-6.14/nfsv4-don-t-trigger-uneccessary-scans-for-return-on-.patch
new file mode 100644 (file)
index 0000000..65aa73c
--- /dev/null
@@ -0,0 +1,79 @@
+From e4f5cd400257ce90846acd83252b640d87a26ebd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Feb 2025 16:50:30 -0500
+Subject: NFSv4: Don't trigger uneccessary scans for return-on-close
+ delegations
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit 47acca884f714f41d95dc654f802845544554784 ]
+
+The amount of looping through the list of delegations is occasionally
+leading to soft lockups. Avoid at least some loops by not requiring the
+NFSv4 state manager to scan for delegations that are marked for
+return-on-close. Instead, either mark them for immediate return (if
+possible) or else leave it up to nfs4_inode_return_delegation_on_close()
+to return them once the file is closed by the application.
+
+Fixes: b757144fd77c ("NFSv4: Be less aggressive about returning delegations for open files")
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/delegation.c | 33 ++++++++++++++++++---------------
+ 1 file changed, 18 insertions(+), 15 deletions(-)
+
+diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
+index 4db912f562305..df77d68d9ff99 100644
+--- a/fs/nfs/delegation.c
++++ b/fs/nfs/delegation.c
+@@ -590,17 +590,6 @@ static bool nfs_delegation_need_return(struct nfs_delegation *delegation)
+       if (test_and_clear_bit(NFS_DELEGATION_RETURN, &delegation->flags))
+               ret = true;
+-      else if (test_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags)) {
+-              struct inode *inode;
+-
+-              spin_lock(&delegation->lock);
+-              inode = delegation->inode;
+-              if (inode && list_empty(&NFS_I(inode)->open_files))
+-                      ret = true;
+-              spin_unlock(&delegation->lock);
+-      }
+-      if (ret)
+-              clear_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags);
+       if (test_bit(NFS_DELEGATION_RETURNING, &delegation->flags) ||
+           test_bit(NFS_DELEGATION_RETURN_DELAYED, &delegation->flags) ||
+           test_bit(NFS_DELEGATION_REVOKED, &delegation->flags))
+@@ -878,11 +867,25 @@ int nfs4_inode_make_writeable(struct inode *inode)
+       return nfs4_inode_return_delegation(inode);
+ }
+-static void nfs_mark_return_if_closed_delegation(struct nfs_server *server,
+-              struct nfs_delegation *delegation)
++static void
++nfs_mark_return_if_closed_delegation(struct nfs_server *server,
++                                   struct nfs_delegation *delegation)
+ {
+-      set_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags);
+-      set_bit(NFS4CLNT_DELEGRETURN, &server->nfs_client->cl_state);
++      struct inode *inode;
++
++      if (test_bit(NFS_DELEGATION_RETURN, &delegation->flags) ||
++          test_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags))
++              return;
++      spin_lock(&delegation->lock);
++      inode = delegation->inode;
++      if (!inode)
++              goto out;
++      if (list_empty(&NFS_I(inode)->open_files))
++              nfs_mark_return_delegation(server, delegation);
++      else
++              set_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags);
++out:
++      spin_unlock(&delegation->lock);
+ }
+ static bool nfs_server_mark_return_all_delegations(struct nfs_server *server)
+-- 
+2.39.5
+
diff --git a/queue-6.14/ntb-intel-fix-using-link-status-db-s.patch b/queue-6.14/ntb-intel-fix-using-link-status-db-s.patch
new file mode 100644 (file)
index 0000000..86a97a4
--- /dev/null
@@ -0,0 +1,37 @@
+From e406a898836f2d787ba8861993030ddec41d84bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Jun 2024 11:15:19 +0300
+Subject: ntb: intel: Fix using link status DB's
+
+From: Nikita Shubin <n.shubin@yadro.com>
+
+[ Upstream commit 8144e9c8f30fb23bb736a5d24d5c9d46965563c4 ]
+
+Make sure we are not using DB's which were remapped for link status.
+
+Fixes: f6e51c354b60 ("ntb: intel: split out the gen3 code")
+Signed-off-by: Nikita Shubin <n.shubin@yadro.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Signed-off-by: Jon Mason <jdmason@kudzu.us>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ntb/hw/intel/ntb_hw_gen3.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/ntb/hw/intel/ntb_hw_gen3.c b/drivers/ntb/hw/intel/ntb_hw_gen3.c
+index ffcfc3e02c353..a5aa96a31f4a6 100644
+--- a/drivers/ntb/hw/intel/ntb_hw_gen3.c
++++ b/drivers/ntb/hw/intel/ntb_hw_gen3.c
+@@ -215,6 +215,9 @@ static int gen3_init_ntb(struct intel_ntb_dev *ndev)
+       }
+       ndev->db_valid_mask = BIT_ULL(ndev->db_count) - 1;
++      /* Make sure we are not using DB's used for link status */
++      if (ndev->hwerr_flags & NTB_HWERR_MSIX_VECTOR32_BAD)
++              ndev->db_valid_mask &= ~ndev->db_link_mask;
+       ndev->reg->db_iowrite(ndev->db_valid_mask,
+                             ndev->self_mmio +
+-- 
+2.39.5
+
diff --git a/queue-6.14/ntb_hw_switchtec-fix-shift-out-of-bounds-in-switchte.patch b/queue-6.14/ntb_hw_switchtec-fix-shift-out-of-bounds-in-switchte.patch
new file mode 100644 (file)
index 0000000..1ecb5e4
--- /dev/null
@@ -0,0 +1,45 @@
+From 90154437738305da7bb6e4d6ca12300f47d8286d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Aug 2023 16:33:05 +0800
+Subject: ntb_hw_switchtec: Fix shift-out-of-bounds in
+ switchtec_ntb_mw_set_trans
+
+From: Yajun Deng <yajun.deng@linux.dev>
+
+[ Upstream commit de203da734fae00e75be50220ba5391e7beecdf9 ]
+
+There is a kernel API ntb_mw_clear_trans() would pass 0 to both addr and
+size. This would make xlate_pos negative.
+
+[   23.734156] switchtec switchtec0: MW 0: part 0 addr 0x0000000000000000 size 0x0000000000000000
+[   23.734158] ================================================================================
+[   23.734172] UBSAN: shift-out-of-bounds in drivers/ntb/hw/mscc/ntb_hw_switchtec.c:293:7
+[   23.734418] shift exponent -1 is negative
+
+Ensuring xlate_pos is a positive or zero before BIT.
+
+Fixes: 1e2fd202f859 ("ntb_hw_switchtec: Check for alignment of the buffer in mw_set_trans()")
+Signed-off-by: Yajun Deng <yajun.deng@linux.dev>
+Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
+Signed-off-by: Jon Mason <jdmason@kudzu.us>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ntb/hw/mscc/ntb_hw_switchtec.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/ntb/hw/mscc/ntb_hw_switchtec.c b/drivers/ntb/hw/mscc/ntb_hw_switchtec.c
+index ad1786be2554b..f851397b65d6e 100644
+--- a/drivers/ntb/hw/mscc/ntb_hw_switchtec.c
++++ b/drivers/ntb/hw/mscc/ntb_hw_switchtec.c
+@@ -288,7 +288,7 @@ static int switchtec_ntb_mw_set_trans(struct ntb_dev *ntb, int pidx, int widx,
+       if (size != 0 && xlate_pos < 12)
+               return -EINVAL;
+-      if (!IS_ALIGNED(addr, BIT_ULL(xlate_pos))) {
++      if (xlate_pos >= 0 && !IS_ALIGNED(addr, BIT_ULL(xlate_pos))) {
+               /*
+                * In certain circumstances we can get a buffer that is
+                * not aligned to its size. (Most of the time
+-- 
+2.39.5
+
diff --git a/queue-6.14/null_blk-do-partial-io-for-bad-blocks.patch b/queue-6.14/null_blk-do-partial-io-for-bad-blocks.patch
new file mode 100644 (file)
index 0000000..a8f6f40
--- /dev/null
@@ -0,0 +1,190 @@
+From 32000fec7c7f3a5b813eb3317e48ebd84d78ed75 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Feb 2025 19:06:13 +0900
+Subject: null_blk: do partial IO for bad blocks
+
+From: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+
+[ Upstream commit 567abc989e3c74c7f4e245492707208c37d27693 ]
+
+The current null_blk implementation checks if any bad blocks exist in
+the target blocks of each IO. If so, the IO fails and data is not
+transferred for all of the IO target blocks. However, when real storage
+devices have bad blocks, the devices may transfer data partially up to
+the first bad blocks (e.g., SAS drives). Especially, when the IO is a
+write operation, such partial IO leaves partially written data on the
+device.
+
+To simulate such partial IO using null_blk, introduce the new parameter
+'badblocks_partial_io'. When this parameter is set,
+null_handle_badblocks() returns the number of the sectors for the
+partial IO as its third pointer argument. Pass the returned number of
+sectors to the following calls to null_handle_memory_backend() in
+null_process_cmd() and null_zone_write().
+
+Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
+Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+Link: https://lore.kernel.org/r/20250226100613.1622564-6-shinichiro.kawasaki@wdc.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Stable-dep-of: d301f164c3fb ("badblocks: use sector_t instead of int to avoid truncation of badblocks length")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/null_blk/main.c     | 40 ++++++++++++++++++++++++-------
+ drivers/block/null_blk/null_blk.h |  4 ++--
+ drivers/block/null_blk/zoned.c    |  9 ++++---
+ 3 files changed, 40 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c
+index b0b009b1136d5..cca278f1d2ce7 100644
+--- a/drivers/block/null_blk/main.c
++++ b/drivers/block/null_blk/main.c
+@@ -474,6 +474,7 @@ NULLB_DEVICE_ATTR(shared_tag_bitmap, bool, NULL);
+ NULLB_DEVICE_ATTR(fua, bool, NULL);
+ NULLB_DEVICE_ATTR(rotational, bool, NULL);
+ NULLB_DEVICE_ATTR(badblocks_once, bool, NULL);
++NULLB_DEVICE_ATTR(badblocks_partial_io, bool, NULL);
+ static ssize_t nullb_device_power_show(struct config_item *item, char *page)
+ {
+@@ -595,6 +596,7 @@ CONFIGFS_ATTR_WO(nullb_device_, zone_offline);
+ static struct configfs_attribute *nullb_device_attrs[] = {
+       &nullb_device_attr_badblocks,
+       &nullb_device_attr_badblocks_once,
++      &nullb_device_attr_badblocks_partial_io,
+       &nullb_device_attr_blocking,
+       &nullb_device_attr_blocksize,
+       &nullb_device_attr_cache_size,
+@@ -1309,19 +1311,40 @@ static inline blk_status_t null_handle_throttled(struct nullb_cmd *cmd)
+       return sts;
+ }
++/*
++ * Check if the command should fail for the badblocks. If so, return
++ * BLK_STS_IOERR and return number of partial I/O sectors to be written or read,
++ * which may be less than the requested number of sectors.
++ *
++ * @cmd:        The command to handle.
++ * @sector:     The start sector for I/O.
++ * @nr_sectors: Specifies number of sectors to write or read, and returns the
++ *              number of sectors to be written or read.
++ */
+ blk_status_t null_handle_badblocks(struct nullb_cmd *cmd, sector_t sector,
+-                                 sector_t nr_sectors)
++                                 unsigned int *nr_sectors)
+ {
+       struct badblocks *bb = &cmd->nq->dev->badblocks;
++      struct nullb_device *dev = cmd->nq->dev;
++      unsigned int block_sectors = dev->blocksize >> SECTOR_SHIFT;
+       sector_t first_bad;
+       int bad_sectors;
++      unsigned int partial_io_sectors = 0;
+-      if (!badblocks_check(bb, sector, nr_sectors, &first_bad, &bad_sectors))
++      if (!badblocks_check(bb, sector, *nr_sectors, &first_bad, &bad_sectors))
+               return BLK_STS_OK;
+       if (cmd->nq->dev->badblocks_once)
+               badblocks_clear(bb, first_bad, bad_sectors);
++      if (cmd->nq->dev->badblocks_partial_io) {
++              if (!IS_ALIGNED(first_bad, block_sectors))
++                      first_bad = ALIGN_DOWN(first_bad, block_sectors);
++              if (sector < first_bad)
++                      partial_io_sectors = first_bad - sector;
++      }
++      *nr_sectors = partial_io_sectors;
++
+       return BLK_STS_IOERR;
+ }
+@@ -1380,18 +1403,19 @@ blk_status_t null_process_cmd(struct nullb_cmd *cmd, enum req_op op,
+                             sector_t sector, unsigned int nr_sectors)
+ {
+       struct nullb_device *dev = cmd->nq->dev;
++      blk_status_t badblocks_ret = BLK_STS_OK;
+       blk_status_t ret;
+-      if (dev->badblocks.shift != -1) {
+-              ret = null_handle_badblocks(cmd, sector, nr_sectors);
++      if (dev->badblocks.shift != -1)
++              badblocks_ret = null_handle_badblocks(cmd, sector, &nr_sectors);
++
++      if (dev->memory_backed && nr_sectors) {
++              ret = null_handle_memory_backed(cmd, op, sector, nr_sectors);
+               if (ret != BLK_STS_OK)
+                       return ret;
+       }
+-      if (dev->memory_backed)
+-              return null_handle_memory_backed(cmd, op, sector, nr_sectors);
+-
+-      return BLK_STS_OK;
++      return badblocks_ret;
+ }
+ static void null_handle_cmd(struct nullb_cmd *cmd, sector_t sector,
+diff --git a/drivers/block/null_blk/null_blk.h b/drivers/block/null_blk/null_blk.h
+index ee60f3a887967..7bb6128dbaafb 100644
+--- a/drivers/block/null_blk/null_blk.h
++++ b/drivers/block/null_blk/null_blk.h
+@@ -64,6 +64,7 @@ struct nullb_device {
+       unsigned int curr_cache;
+       struct badblocks badblocks;
+       bool badblocks_once;
++      bool badblocks_partial_io;
+       unsigned int nr_zones;
+       unsigned int nr_zones_imp_open;
+@@ -133,11 +134,10 @@ blk_status_t null_handle_discard(struct nullb_device *dev, sector_t sector,
+ blk_status_t null_process_cmd(struct nullb_cmd *cmd, enum req_op op,
+                             sector_t sector, unsigned int nr_sectors);
+ blk_status_t null_handle_badblocks(struct nullb_cmd *cmd, sector_t sector,
+-                                 sector_t nr_sectors);
++                                 unsigned int *nr_sectors);
+ blk_status_t null_handle_memory_backed(struct nullb_cmd *cmd, enum req_op op,
+                                      sector_t sector, sector_t nr_sectors);
+-
+ #ifdef CONFIG_BLK_DEV_ZONED
+ int null_init_zoned_dev(struct nullb_device *dev, struct queue_limits *lim);
+ int null_register_zoned_dev(struct nullb *nullb);
+diff --git a/drivers/block/null_blk/zoned.c b/drivers/block/null_blk/zoned.c
+index 7677f6cf23f46..4e5728f459899 100644
+--- a/drivers/block/null_blk/zoned.c
++++ b/drivers/block/null_blk/zoned.c
+@@ -353,6 +353,7 @@ static blk_status_t null_zone_write(struct nullb_cmd *cmd, sector_t sector,
+       struct nullb_device *dev = cmd->nq->dev;
+       unsigned int zno = null_zone_no(dev, sector);
+       struct nullb_zone *zone = &dev->zones[zno];
++      blk_status_t badblocks_ret = BLK_STS_OK;
+       blk_status_t ret;
+       trace_nullb_zone_op(cmd, zno, zone->cond);
+@@ -413,9 +414,11 @@ static blk_status_t null_zone_write(struct nullb_cmd *cmd, sector_t sector,
+       }
+       if (dev->badblocks.shift != -1) {
+-              ret = null_handle_badblocks(cmd, sector, nr_sectors);
+-              if (ret != BLK_STS_OK)
++              badblocks_ret = null_handle_badblocks(cmd, sector, &nr_sectors);
++              if (badblocks_ret != BLK_STS_OK && !nr_sectors) {
++                      ret = badblocks_ret;
+                       goto unlock_zone;
++              }
+       }
+       if (dev->memory_backed) {
+@@ -438,7 +441,7 @@ static blk_status_t null_zone_write(struct nullb_cmd *cmd, sector_t sector,
+               zone->cond = BLK_ZONE_COND_FULL;
+       }
+-      ret = BLK_STS_OK;
++      ret = badblocks_ret;
+ unlock_zone:
+       null_unlock_zone(dev, zone);
+-- 
+2.39.5
+
diff --git a/queue-6.14/null_blk-generate-null_blk-configfs-features-string.patch b/queue-6.14/null_blk-generate-null_blk-configfs-features-string.patch
new file mode 100644 (file)
index 0000000..dd91c34
--- /dev/null
@@ -0,0 +1,152 @@
+From 1a23a8372e02346183b027cf5a4939d7e19a961c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Feb 2025 19:06:09 +0900
+Subject: null_blk: generate null_blk configfs features string
+
+From: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+
+[ Upstream commit 2cadb8ef25a6157b5bd3e8fe0d3e23f32defec25 ]
+
+The null_blk configfs file 'features' provides a string that lists
+available null_blk features for userspace programs to reference.
+The string is defined as a long constant in the code, which tends to be
+forgotten for updates. It also causes checkpatch.pl to report
+"WARNING: quoted string split across lines".
+
+To avoid these drawbacks, generate the feature string on the fly. Refer
+to the ca_name field of each element in the nullb_device_attrs table and
+concatenate them in the given buffer. Also, sorted nullb_device_attrs
+table elements in alphabetical order.
+
+Of note is that the feature "index" was missing before this commit.
+This commit adds it to the generated string.
+
+Suggested-by: Bart Van Assche <bvanassche@acm.org>
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
+Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
+Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+Link: https://lore.kernel.org/r/20250226100613.1622564-2-shinichiro.kawasaki@wdc.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Stable-dep-of: d301f164c3fb ("badblocks: use sector_t instead of int to avoid truncation of badblocks length")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/null_blk/main.c | 86 ++++++++++++++++++++---------------
+ 1 file changed, 49 insertions(+), 37 deletions(-)
+
+diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c
+index fdc7a0b2af109..18520d0e38c61 100644
+--- a/drivers/block/null_blk/main.c
++++ b/drivers/block/null_blk/main.c
+@@ -592,41 +592,41 @@ static ssize_t nullb_device_zone_offline_store(struct config_item *item,
+ CONFIGFS_ATTR_WO(nullb_device_, zone_offline);
+ static struct configfs_attribute *nullb_device_attrs[] = {
+-      &nullb_device_attr_size,
++      &nullb_device_attr_badblocks,
++      &nullb_device_attr_blocking,
++      &nullb_device_attr_blocksize,
++      &nullb_device_attr_cache_size,
+       &nullb_device_attr_completion_nsec,
+-      &nullb_device_attr_submit_queues,
+-      &nullb_device_attr_poll_queues,
++      &nullb_device_attr_discard,
++      &nullb_device_attr_fua,
+       &nullb_device_attr_home_node,
+-      &nullb_device_attr_queue_mode,
+-      &nullb_device_attr_blocksize,
+-      &nullb_device_attr_max_sectors,
+-      &nullb_device_attr_irqmode,
+       &nullb_device_attr_hw_queue_depth,
+       &nullb_device_attr_index,
+-      &nullb_device_attr_blocking,
+-      &nullb_device_attr_use_per_node_hctx,
+-      &nullb_device_attr_power,
+-      &nullb_device_attr_memory_backed,
+-      &nullb_device_attr_discard,
++      &nullb_device_attr_irqmode,
++      &nullb_device_attr_max_sectors,
+       &nullb_device_attr_mbps,
+-      &nullb_device_attr_cache_size,
+-      &nullb_device_attr_badblocks,
+-      &nullb_device_attr_zoned,
+-      &nullb_device_attr_zone_size,
++      &nullb_device_attr_memory_backed,
++      &nullb_device_attr_no_sched,
++      &nullb_device_attr_poll_queues,
++      &nullb_device_attr_power,
++      &nullb_device_attr_queue_mode,
++      &nullb_device_attr_rotational,
++      &nullb_device_attr_shared_tag_bitmap,
++      &nullb_device_attr_shared_tags,
++      &nullb_device_attr_size,
++      &nullb_device_attr_submit_queues,
++      &nullb_device_attr_use_per_node_hctx,
++      &nullb_device_attr_virt_boundary,
++      &nullb_device_attr_zone_append_max_sectors,
+       &nullb_device_attr_zone_capacity,
+-      &nullb_device_attr_zone_nr_conv,
+-      &nullb_device_attr_zone_max_open,
++      &nullb_device_attr_zone_full,
+       &nullb_device_attr_zone_max_active,
+-      &nullb_device_attr_zone_append_max_sectors,
+-      &nullb_device_attr_zone_readonly,
++      &nullb_device_attr_zone_max_open,
++      &nullb_device_attr_zone_nr_conv,
+       &nullb_device_attr_zone_offline,
+-      &nullb_device_attr_zone_full,
+-      &nullb_device_attr_virt_boundary,
+-      &nullb_device_attr_no_sched,
+-      &nullb_device_attr_shared_tags,
+-      &nullb_device_attr_shared_tag_bitmap,
+-      &nullb_device_attr_fua,
+-      &nullb_device_attr_rotational,
++      &nullb_device_attr_zone_readonly,
++      &nullb_device_attr_zone_size,
++      &nullb_device_attr_zoned,
+       NULL,
+ };
+@@ -704,16 +704,28 @@ nullb_group_drop_item(struct config_group *group, struct config_item *item)
+ static ssize_t memb_group_features_show(struct config_item *item, char *page)
+ {
+-      return snprintf(page, PAGE_SIZE,
+-                      "badblocks,blocking,blocksize,cache_size,fua,"
+-                      "completion_nsec,discard,home_node,hw_queue_depth,"
+-                      "irqmode,max_sectors,mbps,memory_backed,no_sched,"
+-                      "poll_queues,power,queue_mode,shared_tag_bitmap,"
+-                      "shared_tags,size,submit_queues,use_per_node_hctx,"
+-                      "virt_boundary,zoned,zone_capacity,zone_max_active,"
+-                      "zone_max_open,zone_nr_conv,zone_offline,zone_readonly,"
+-                      "zone_size,zone_append_max_sectors,zone_full,"
+-                      "rotational\n");
++
++      struct configfs_attribute **entry;
++      char delimiter = ',';
++      size_t left = PAGE_SIZE;
++      size_t written = 0;
++      int ret;
++
++      for (entry = &nullb_device_attrs[0]; *entry && left > 0; entry++) {
++              if (!*(entry + 1))
++                      delimiter = '\n';
++              ret = snprintf(page + written, left, "%s%c", (*entry)->ca_name,
++                             delimiter);
++              if (ret >= left) {
++                      WARN_ONCE(1, "Too many null_blk features to print\n");
++                      memzero_explicit(page, PAGE_SIZE);
++                      return -ENOBUFS;
++              }
++              left -= ret;
++              written += ret;
++      }
++
++      return written;
+ }
+ CONFIGFS_ATTR_RO(memb_group_, features);
+-- 
+2.39.5
+
diff --git a/queue-6.14/null_blk-introduce-badblocks_once-parameter.patch b/queue-6.14/null_blk-introduce-badblocks_once-parameter.patch
new file mode 100644 (file)
index 0000000..effc950
--- /dev/null
@@ -0,0 +1,81 @@
+From 275d2fac17595f39a6998537703606dead1e9481 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Feb 2025 19:06:10 +0900
+Subject: null_blk: introduce badblocks_once parameter
+
+From: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+
+[ Upstream commit 800c24391676143695d284f70af297b28a809886 ]
+
+When IO errors happen on real storage devices, the IOs repeated to the
+same target range can success by virtue of recovery features by devices,
+such as reserved block assignment. To simulate such IO errors and
+recoveries, introduce the new parameter badblocks_once parameter. When
+this parameter is set to 1, the specified badblocks are cleared after
+the first IO error, so that the next IO to the blocks succeed.
+
+Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
+Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+Link: https://lore.kernel.org/r/20250226100613.1622564-3-shinichiro.kawasaki@wdc.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Stable-dep-of: d301f164c3fb ("badblocks: use sector_t instead of int to avoid truncation of badblocks length")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/null_blk/main.c     | 11 ++++++++---
+ drivers/block/null_blk/null_blk.h |  1 +
+ 2 files changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c
+index 18520d0e38c61..164c62f20f109 100644
+--- a/drivers/block/null_blk/main.c
++++ b/drivers/block/null_blk/main.c
+@@ -473,6 +473,7 @@ NULLB_DEVICE_ATTR(shared_tags, bool, NULL);
+ NULLB_DEVICE_ATTR(shared_tag_bitmap, bool, NULL);
+ NULLB_DEVICE_ATTR(fua, bool, NULL);
+ NULLB_DEVICE_ATTR(rotational, bool, NULL);
++NULLB_DEVICE_ATTR(badblocks_once, bool, NULL);
+ static ssize_t nullb_device_power_show(struct config_item *item, char *page)
+ {
+@@ -593,6 +594,7 @@ CONFIGFS_ATTR_WO(nullb_device_, zone_offline);
+ static struct configfs_attribute *nullb_device_attrs[] = {
+       &nullb_device_attr_badblocks,
++      &nullb_device_attr_badblocks_once,
+       &nullb_device_attr_blocking,
+       &nullb_device_attr_blocksize,
+       &nullb_device_attr_cache_size,
+@@ -1315,10 +1317,13 @@ static inline blk_status_t null_handle_badblocks(struct nullb_cmd *cmd,
+       sector_t first_bad;
+       int bad_sectors;
+-      if (badblocks_check(bb, sector, nr_sectors, &first_bad, &bad_sectors))
+-              return BLK_STS_IOERR;
++      if (!badblocks_check(bb, sector, nr_sectors, &first_bad, &bad_sectors))
++              return BLK_STS_OK;
+-      return BLK_STS_OK;
++      if (cmd->nq->dev->badblocks_once)
++              badblocks_clear(bb, first_bad, bad_sectors);
++
++      return BLK_STS_IOERR;
+ }
+ static inline blk_status_t null_handle_memory_backed(struct nullb_cmd *cmd,
+diff --git a/drivers/block/null_blk/null_blk.h b/drivers/block/null_blk/null_blk.h
+index 6f9fe61710870..3c4c07f0418b0 100644
+--- a/drivers/block/null_blk/null_blk.h
++++ b/drivers/block/null_blk/null_blk.h
+@@ -63,6 +63,7 @@ struct nullb_device {
+       unsigned long flags; /* device flags */
+       unsigned int curr_cache;
+       struct badblocks badblocks;
++      bool badblocks_once;
+       unsigned int nr_zones;
+       unsigned int nr_zones_imp_open;
+-- 
+2.39.5
+
diff --git a/queue-6.14/null_blk-replace-null_process_cmd-call-in-null_zone_.patch b/queue-6.14/null_blk-replace-null_process_cmd-call-in-null_zone_.patch
new file mode 100644 (file)
index 0000000..a7c0a6f
--- /dev/null
@@ -0,0 +1,103 @@
+From 79be7fe7f31f9ae02a9eeb31f6ac2087f256ad78 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Feb 2025 19:06:11 +0900
+Subject: null_blk: replace null_process_cmd() call in null_zone_write()
+
+From: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+
+[ Upstream commit 4f235000b1e88934d1e6117dc43ed814710ef4e2 ]
+
+As a preparation to support partial data transfer due to badblocks,
+replace the null_process_cmd() call in null_zone_write() with equivalent
+calls to null_handle_badblocks() and null_handle_memory_backed(). This
+commit does not change behavior. It will enable null_handle_badblocks()
+to return the size of partial data transfer in the following commit,
+allowing null_zone_write() to move write pointers appropriately.
+
+Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+Link: https://lore.kernel.org/r/20250226100613.1622564-4-shinichiro.kawasaki@wdc.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Stable-dep-of: d301f164c3fb ("badblocks: use sector_t instead of int to avoid truncation of badblocks length")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/null_blk/main.c     | 11 ++++-------
+ drivers/block/null_blk/null_blk.h |  5 +++++
+ drivers/block/null_blk/zoned.c    | 15 ++++++++++++---
+ 3 files changed, 21 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c
+index 164c62f20f109..b0b009b1136d5 100644
+--- a/drivers/block/null_blk/main.c
++++ b/drivers/block/null_blk/main.c
+@@ -1309,9 +1309,8 @@ static inline blk_status_t null_handle_throttled(struct nullb_cmd *cmd)
+       return sts;
+ }
+-static inline blk_status_t null_handle_badblocks(struct nullb_cmd *cmd,
+-                                               sector_t sector,
+-                                               sector_t nr_sectors)
++blk_status_t null_handle_badblocks(struct nullb_cmd *cmd, sector_t sector,
++                                 sector_t nr_sectors)
+ {
+       struct badblocks *bb = &cmd->nq->dev->badblocks;
+       sector_t first_bad;
+@@ -1326,10 +1325,8 @@ static inline blk_status_t null_handle_badblocks(struct nullb_cmd *cmd,
+       return BLK_STS_IOERR;
+ }
+-static inline blk_status_t null_handle_memory_backed(struct nullb_cmd *cmd,
+-                                                   enum req_op op,
+-                                                   sector_t sector,
+-                                                   sector_t nr_sectors)
++blk_status_t null_handle_memory_backed(struct nullb_cmd *cmd, enum req_op op,
++                                     sector_t sector, sector_t nr_sectors)
+ {
+       struct nullb_device *dev = cmd->nq->dev;
+diff --git a/drivers/block/null_blk/null_blk.h b/drivers/block/null_blk/null_blk.h
+index 3c4c07f0418b0..ee60f3a887967 100644
+--- a/drivers/block/null_blk/null_blk.h
++++ b/drivers/block/null_blk/null_blk.h
+@@ -132,6 +132,11 @@ blk_status_t null_handle_discard(struct nullb_device *dev, sector_t sector,
+                                sector_t nr_sectors);
+ blk_status_t null_process_cmd(struct nullb_cmd *cmd, enum req_op op,
+                             sector_t sector, unsigned int nr_sectors);
++blk_status_t null_handle_badblocks(struct nullb_cmd *cmd, sector_t sector,
++                                 sector_t nr_sectors);
++blk_status_t null_handle_memory_backed(struct nullb_cmd *cmd, enum req_op op,
++                                     sector_t sector, sector_t nr_sectors);
++
+ #ifdef CONFIG_BLK_DEV_ZONED
+ int null_init_zoned_dev(struct nullb_device *dev, struct queue_limits *lim);
+diff --git a/drivers/block/null_blk/zoned.c b/drivers/block/null_blk/zoned.c
+index 0d5f9bf952292..7677f6cf23f46 100644
+--- a/drivers/block/null_blk/zoned.c
++++ b/drivers/block/null_blk/zoned.c
+@@ -412,9 +412,18 @@ static blk_status_t null_zone_write(struct nullb_cmd *cmd, sector_t sector,
+               zone->cond = BLK_ZONE_COND_IMP_OPEN;
+       }
+-      ret = null_process_cmd(cmd, REQ_OP_WRITE, sector, nr_sectors);
+-      if (ret != BLK_STS_OK)
+-              goto unlock_zone;
++      if (dev->badblocks.shift != -1) {
++              ret = null_handle_badblocks(cmd, sector, nr_sectors);
++              if (ret != BLK_STS_OK)
++                      goto unlock_zone;
++      }
++
++      if (dev->memory_backed) {
++              ret = null_handle_memory_backed(cmd, REQ_OP_WRITE, sector,
++                                              nr_sectors);
++              if (ret != BLK_STS_OK)
++                      goto unlock_zone;
++      }
+       zone->wp += nr_sectors;
+       if (zone->wp == zone->start + zone->capacity) {
+-- 
+2.39.5
+
diff --git a/queue-6.14/nvme-ioctl-don-t-warn-on-vectorized-uring_cmd-with-f.patch b/queue-6.14/nvme-ioctl-don-t-warn-on-vectorized-uring_cmd-with-f.patch
new file mode 100644 (file)
index 0000000..b68716b
--- /dev/null
@@ -0,0 +1,40 @@
+From 513c59d1806253c6907c9c81c4cf60afd01a61de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Mar 2025 09:46:45 -0600
+Subject: nvme/ioctl: don't warn on vectorized uring_cmd with fixed buffer
+
+From: Caleb Sander Mateos <csander@purestorage.com>
+
+[ Upstream commit eada75467fca0b016b9b22212637c07216135c20 ]
+
+The vectorized io_uring NVMe passthru opcodes don't yet support fixed
+buffers. But since userspace can trigger this condition based on the
+io_uring SQE parameters, it shouldn't cause a kernel warning.
+
+Signed-off-by: Caleb Sander Mateos <csander@purestorage.com>
+Reviewed-by: Jens Axboe <axboe@kernel.dk>
+Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Fixes: 23fd22e55b76 ("nvme: wire up fixed buffer support for nvme passthrough")
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+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 24e2c702da7a2..fed6b29098ad3 100644
+--- a/drivers/nvme/host/ioctl.c
++++ b/drivers/nvme/host/ioctl.c
+@@ -141,7 +141,7 @@ static int nvme_map_user_request(struct request *req, u64 ubuffer,
+               struct iov_iter iter;
+               /* fixedbufs is only for non-vectored io */
+-              if (WARN_ON_ONCE(flags & NVME_IOCTL_VEC)) {
++              if (flags & NVME_IOCTL_VEC) {
+                       ret = -EINVAL;
+                       goto out;
+               }
+-- 
+2.39.5
+
diff --git a/queue-6.14/nvme-pci-skip-nvme_write_sq_db-on-empty-rqlist.patch b/queue-6.14/nvme-pci-skip-nvme_write_sq_db-on-empty-rqlist.patch
new file mode 100644 (file)
index 0000000..a166576
--- /dev/null
@@ -0,0 +1,37 @@
+From e07f23eb7b103eb25132b2a01a2816401132a179 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Mar 2025 18:28:59 +0200
+Subject: nvme-pci: skip nvme_write_sq_db on empty rqlist
+
+From: Maurizio Lombardi <mlombard@redhat.com>
+
+[ Upstream commit 288ff0d10beb069355036355d5f7612579dc869c ]
+
+nvme_submit_cmds() should check the rqlist before calling
+nvme_write_sq_db(); if the list is empty, it must return immediately.
+
+Fixes: beadf0088501 ("nvme-pci: reverse request order in nvme_queue_rqs")
+Signed-off-by: Maurizio Lombardi <mlombard@redhat.com>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/pci.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
+index 3ad7f197c8087..1dc12784efafc 100644
+--- a/drivers/nvme/host/pci.c
++++ b/drivers/nvme/host/pci.c
+@@ -989,6 +989,9 @@ static void nvme_submit_cmds(struct nvme_queue *nvmeq, struct rq_list *rqlist)
+ {
+       struct request *req;
++      if (rq_list_empty(rqlist))
++              return;
++
+       spin_lock(&nvmeq->sq_lock);
+       while ((req = rq_list_pop(rqlist))) {
+               struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
+-- 
+2.39.5
+
diff --git a/queue-6.14/nvmet-pci-epf-always-configure-bar0-as-64-bit.patch b/queue-6.14/nvmet-pci-epf-always-configure-bar0-as-64-bit.patch
new file mode 100644 (file)
index 0000000..e34b27e
--- /dev/null
@@ -0,0 +1,61 @@
+From 90bd6773db3fc58c1bd4d6ed42ec1eb0382b12c1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Mar 2025 10:57:04 +0100
+Subject: nvmet: pci-epf: Always configure BAR0 as 64-bit
+
+From: Niklas Cassel <cassel@kernel.org>
+
+[ Upstream commit 1cf0184c0ac4f1e936bb3b089894bbeb0a9eb2bc ]
+
+NVMe PCIe Transport Specification 1.1, section 2.1.10, claims that the
+BAR0 type is Implementation Specific.
+
+However, in NVMe 1.1, the type is required to be 64-bit.
+
+Thus, to make our PCI EPF work on as many host systems as possible,
+always configure the BAR0 type to be 64-bit.
+
+In the rare case that the underlying PCI EPC does not support configuring
+BAR0 as 64-bit, the call to pci_epc_set_bar() will fail, and we will
+return a failure back to the user.
+
+This should not be a problem, as most PCI EPCs support configuring a BAR
+as 64-bit (and those EPCs with .only_64bit set to true in epc_features
+only support configuring the BAR as 64-bit).
+
+Tested-by: Damien Le Moal <dlemoal@kernel.org>
+Fixes: 0faa0fe6f90e ("nvmet: New NVMe PCI endpoint function target driver")
+Signed-off-by: Niklas Cassel <cassel@kernel.org>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/target/pci-epf.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/nvme/target/pci-epf.c b/drivers/nvme/target/pci-epf.c
+index b1e31483f1574..99563648c318f 100644
+--- a/drivers/nvme/target/pci-epf.c
++++ b/drivers/nvme/target/pci-epf.c
+@@ -2129,8 +2129,15 @@ static int nvmet_pci_epf_configure_bar(struct nvmet_pci_epf *nvme_epf)
+               return -ENODEV;
+       }
+-      if (epc_features->bar[BAR_0].only_64bit)
+-              epf->bar[BAR_0].flags |= PCI_BASE_ADDRESS_MEM_TYPE_64;
++      /*
++       * While NVMe PCIe Transport Specification 1.1, section 2.1.10, claims
++       * that the BAR0 type is Implementation Specific, in NVMe 1.1, the type
++       * is required to be 64-bit. Thus, for interoperability, always set the
++       * type to 64-bit. In the rare case that the PCI EPC does not support
++       * configuring BAR0 as 64-bit, the call to pci_epc_set_bar() will fail,
++       * and we will return failure back to the user.
++       */
++      epf->bar[BAR_0].flags |= PCI_BASE_ADDRESS_MEM_TYPE_64;
+       /*
+        * Calculate the size of the register bar: NVMe registers first with
+-- 
+2.39.5
+
diff --git a/queue-6.14/objtool-fix-detection-of-consecutive-jump-tables-on-.patch b/queue-6.14/objtool-fix-detection-of-consecutive-jump-tables-on-.patch
new file mode 100644 (file)
index 0000000..ba77384
--- /dev/null
@@ -0,0 +1,188 @@
+From c7329abf977f548041d034092851340b7a102b34 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Mar 2025 14:55:51 -0700
+Subject: objtool: Fix detection of consecutive jump tables on Clang 20
+
+From: Josh Poimboeuf <jpoimboe@kernel.org>
+
+[ Upstream commit ef753d66051ca03bee1982ce047f9eaf90f81ab4 ]
+
+The jump table detection code assumes jump tables are in the same order
+as their corresponding indirect branches.  That's apparently not always
+true with Clang 20.
+
+Fix that by changing how multiple jump tables are detected.  In the
+first detection pass, mark the beginning of each jump table so the
+second pass can tell where one ends and the next one begins.
+
+Fixes the following warnings:
+
+  vmlinux.o: warning: objtool: SiS_GetCRT2Ptr+0x1ad: stack state mismatch: cfa1=4+8 cfa2=5+16
+  sound/core/seq/snd-seq.o: warning: objtool: cc_ev_to_ump_midi2+0x589: return with modified stack frame
+
+Fixes: be2f0b1e1264 ("objtool: Get rid of reloc->jump_table_start")
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Cc: Nick Desaulniers <ndesaulniers@google.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Link: https://lore.kernel.org/r/141752fff614eab962dba6bdfaa54aa67ff03bba.1742852846.git.jpoimboe@kernel.org
+Closes: https://lore.kernel.org/oe-kbuild-all/202503171547.LlCTJLQL-lkp@intel.com/
+Closes: https://lore.kernel.org/oe-kbuild-all/202503200535.J3hAvcjw-lkp@intel.com/
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/objtool/check.c               | 26 ++++++++------------------
+ tools/objtool/elf.c                 |  6 +++---
+ tools/objtool/include/objtool/elf.h | 27 ++++++++++++++++++++++++++-
+ 3 files changed, 37 insertions(+), 22 deletions(-)
+
+diff --git a/tools/objtool/check.c b/tools/objtool/check.c
+index 12bf6c1f5071d..813e708c16499 100644
+--- a/tools/objtool/check.c
++++ b/tools/objtool/check.c
+@@ -1949,8 +1949,7 @@ __weak unsigned long arch_jump_table_sym_offset(struct reloc *reloc, struct relo
+       return reloc->sym->offset + reloc_addend(reloc);
+ }
+-static int add_jump_table(struct objtool_file *file, struct instruction *insn,
+-                        struct reloc *next_table)
++static int add_jump_table(struct objtool_file *file, struct instruction *insn)
+ {
+       unsigned long table_size = insn_jump_table_size(insn);
+       struct symbol *pfunc = insn_func(insn)->pfunc;
+@@ -1970,7 +1969,7 @@ static int add_jump_table(struct objtool_file *file, struct instruction *insn,
+               /* Check for the end of the table: */
+               if (table_size && reloc_offset(reloc) - reloc_offset(table) >= table_size)
+                       break;
+-              if (reloc != table && reloc == next_table)
++              if (reloc != table && is_jump_table(reloc))
+                       break;
+               /* Make sure the table entries are consecutive: */
+@@ -2061,8 +2060,10 @@ static void find_jump_table(struct objtool_file *file, struct symbol *func,
+               if (!dest_insn || !insn_func(dest_insn) || insn_func(dest_insn)->pfunc != func)
+                       continue;
++              set_jump_table(table_reloc);
+               orig_insn->_jump_table = table_reloc;
+               orig_insn->_jump_table_size = table_size;
++
+               break;
+       }
+ }
+@@ -2104,31 +2105,20 @@ static void mark_func_jump_tables(struct objtool_file *file,
+ static int add_func_jump_tables(struct objtool_file *file,
+                                 struct symbol *func)
+ {
+-      struct instruction *insn, *insn_t1 = NULL, *insn_t2;
+-      int ret = 0;
++      struct instruction *insn;
++      int ret;
+       func_for_each_insn(file, func, insn) {
+               if (!insn_jump_table(insn))
+                       continue;
+-              if (!insn_t1) {
+-                      insn_t1 = insn;
+-                      continue;
+-              }
+-
+-              insn_t2 = insn;
+-              ret = add_jump_table(file, insn_t1, insn_jump_table(insn_t2));
++              ret = add_jump_table(file, insn);
+               if (ret)
+                       return ret;
+-
+-              insn_t1 = insn_t2;
+       }
+-      if (insn_t1)
+-              ret = add_jump_table(file, insn_t1, NULL);
+-
+-      return ret;
++      return 0;
+ }
+ /*
+diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
+index 6f64d611faea9..934855be631c0 100644
+--- a/tools/objtool/elf.c
++++ b/tools/objtool/elf.c
+@@ -583,7 +583,7 @@ static int elf_update_sym_relocs(struct elf *elf, struct symbol *sym)
+ {
+       struct reloc *reloc;
+-      for (reloc = sym->relocs; reloc; reloc = reloc->sym_next_reloc)
++      for (reloc = sym->relocs; reloc; reloc = sym_next_reloc(reloc))
+               set_reloc_sym(elf, reloc, reloc->sym->idx);
+       return 0;
+@@ -880,7 +880,7 @@ static struct reloc *elf_init_reloc(struct elf *elf, struct section *rsec,
+       set_reloc_addend(elf, reloc, addend);
+       elf_hash_add(reloc, &reloc->hash, reloc_hash(reloc));
+-      reloc->sym_next_reloc = sym->relocs;
++      set_sym_next_reloc(reloc, sym->relocs);
+       sym->relocs = reloc;
+       return reloc;
+@@ -979,7 +979,7 @@ static int read_relocs(struct elf *elf)
+                       }
+                       elf_hash_add(reloc, &reloc->hash, reloc_hash(reloc));
+-                      reloc->sym_next_reloc = sym->relocs;
++                      set_sym_next_reloc(reloc, sym->relocs);
+                       sym->relocs = reloc;
+                       nr_reloc++;
+diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/objtool/elf.h
+index d7e815c2fd156..764cba535f22e 100644
+--- a/tools/objtool/include/objtool/elf.h
++++ b/tools/objtool/include/objtool/elf.h
+@@ -77,7 +77,7 @@ struct reloc {
+       struct elf_hash_node hash;
+       struct section *sec;
+       struct symbol *sym;
+-      struct reloc *sym_next_reloc;
++      unsigned long _sym_next_reloc;
+ };
+ struct elf {
+@@ -297,6 +297,31 @@ static inline void set_reloc_type(struct elf *elf, struct reloc *reloc, unsigned
+       mark_sec_changed(elf, reloc->sec, true);
+ }
++#define RELOC_JUMP_TABLE_BIT 1UL
++
++/* Does reloc mark the beginning of a jump table? */
++static inline bool is_jump_table(struct reloc *reloc)
++{
++      return reloc->_sym_next_reloc & RELOC_JUMP_TABLE_BIT;
++}
++
++static inline void set_jump_table(struct reloc *reloc)
++{
++      reloc->_sym_next_reloc |= RELOC_JUMP_TABLE_BIT;
++}
++
++static inline struct reloc *sym_next_reloc(struct reloc *reloc)
++{
++      return (struct reloc *)(reloc->_sym_next_reloc & ~RELOC_JUMP_TABLE_BIT);
++}
++
++static inline void set_sym_next_reloc(struct reloc *reloc, struct reloc *next)
++{
++      unsigned long bit = reloc->_sym_next_reloc & RELOC_JUMP_TABLE_BIT;
++
++      reloc->_sym_next_reloc = (unsigned long)next | bit;
++}
++
+ #define for_each_sec(file, sec)                                               \
+       list_for_each_entry(sec, &file->elf->sections, list)
+-- 
+2.39.5
+
diff --git a/queue-6.14/objtool-fix-segfault-in-ignore_unreachable_insn.patch b/queue-6.14/objtool-fix-segfault-in-ignore_unreachable_insn.patch
new file mode 100644 (file)
index 0000000..9ae552f
--- /dev/null
@@ -0,0 +1,41 @@
+From fa7361d986866a83ee808332e2f4e76b1bb7b062 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Mar 2025 22:04:21 -0700
+Subject: objtool: Fix segfault in ignore_unreachable_insn()
+
+From: Josh Poimboeuf <jpoimboe@kernel.org>
+
+[ Upstream commit 69d41d6dafff0967565b971d950bd10443e4076c ]
+
+Check 'prev_insn' before dereferencing it.
+
+Fixes: bd841d6154f5 ("objtool: Fix CONFIG_UBSAN_TRAP unreachable warnings")
+Reported-by: Arnd Bergmann <arnd@arndb.de>
+Reported-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Link: https://lore.kernel.org/r/5df4ff89c9e4b9e788b77b0531234ffa7ba03e9e.1743136205.git.jpoimboe@kernel.org
+
+Closes: https://lore.kernel.org/d86b4cc6-0b97-4095-8793-a7384410b8ab@app.fastmail.com
+Closes: https://lore.kernel.org/Z-V_rruKY0-36pqA@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/objtool/check.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/objtool/check.c b/tools/objtool/check.c
+index 813e708c16499..aa071017c325c 100644
+--- a/tools/objtool/check.c
++++ b/tools/objtool/check.c
+@@ -4009,7 +4009,7 @@ static bool ignore_unreachable_insn(struct objtool_file *file, struct instructio
+        * It may also insert a UD2 after calling a __noreturn function.
+        */
+       prev_insn = prev_insn_same_sec(file, insn);
+-      if (prev_insn->dead_end &&
++      if (prev_insn && prev_insn->dead_end &&
+           (insn->type == INSN_BUG ||
+            (insn->type == INSN_JUMP_UNCONDITIONAL &&
+             insn->jump_dest && insn->jump_dest->type == INSN_BUG)))
+-- 
+2.39.5
+
diff --git a/queue-6.14/objtool-fix-verbose-disassembly-if-cross_compile-isn.patch b/queue-6.14/objtool-fix-verbose-disassembly-if-cross_compile-isn.patch
new file mode 100644 (file)
index 0000000..6e0a60a
--- /dev/null
@@ -0,0 +1,46 @@
+From c868f5d2c496c5e00d49eca4279e8edaa40ca874 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Mar 2025 21:26:42 -0700
+Subject: objtool: Fix verbose disassembly if CROSS_COMPILE isn't set
+
+From: David Laight <david.laight.linux@gmail.com>
+
+[ Upstream commit e77956e4e5c11218e60a1fe8cdbccd02476f2e56 ]
+
+In verbose mode, when printing the disassembly of affected functions, if
+CROSS_COMPILE isn't set, the objdump command string gets prefixed with
+"(null)".
+
+Somehow this worked before.  Maybe some versions of glibc return an
+empty string instead of NULL.  Fix it regardless.
+
+[ jpoimboe: Rewrite commit log. ]
+
+Fixes: ca653464dd097 ("objtool: Add verbose option for disassembling affected functions")
+Signed-off-by: David Laight <david.laight.linux@gmail.com>
+Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Link: https://lore.kernel.org/r/20250215142321.14081-1-david.laight.linux@gmail.com
+Link: https://lore.kernel.org/r/b931a4786bc0127aa4c94e8b35ed617dcbd3d3da.1743481539.git.jpoimboe@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/objtool/check.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/tools/objtool/check.c b/tools/objtool/check.c
+index aa071017c325c..159fb130e2827 100644
+--- a/tools/objtool/check.c
++++ b/tools/objtool/check.c
+@@ -4489,6 +4489,8 @@ static int disas_funcs(const char *funcs)
+       char *cmd;
+       cross_compile = getenv("CROSS_COMPILE");
++      if (!cross_compile)
++              cross_compile = "";
+       objdump_str = "%sobjdump -wdr %s | gawk -M -v _funcs='%s' '"
+                       "BEGIN { split(_funcs, funcs); }"
+-- 
+2.39.5
+
diff --git a/queue-6.14/objtool-handle-different-entry-size-of-rodata.patch b/queue-6.14/objtool-handle-different-entry-size-of-rodata.patch
new file mode 100644 (file)
index 0000000..dd4c4d6
--- /dev/null
@@ -0,0 +1,119 @@
+From a5960469e972944f694526a3fc7677cdb480c83f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Feb 2025 19:50:11 +0800
+Subject: objtool: Handle different entry size of rodata
+
+From: Tiezhu Yang <yangtiezhu@loongson.cn>
+
+[ Upstream commit 091bf313f8a852a7f30c3a8dcef569edfd06f5dc ]
+
+In the most cases, the entry size of rodata is 8 bytes because the
+relocation type is 64 bit. There are also 32 bit relocation types,
+the entry size of rodata should be 4 bytes in this case.
+
+Add an arch-specific function arch_reloc_size() to assign the entry
+size of rodata for x86, powerpc and LoongArch.
+
+Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
+Link: https://lore.kernel.org/r/20250211115016.26913-3-yangtiezhu@loongson.cn
+Acked-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
+Stable-dep-of: ef753d66051c ("objtool: Fix detection of consecutive jump tables on Clang 20")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/objtool/arch/loongarch/decode.c | 11 +++++++++++
+ tools/objtool/arch/powerpc/decode.c   | 14 ++++++++++++++
+ tools/objtool/arch/x86/decode.c       | 13 +++++++++++++
+ tools/objtool/check.c                 |  2 +-
+ tools/objtool/include/objtool/arch.h  |  2 ++
+ 5 files changed, 41 insertions(+), 1 deletion(-)
+
+diff --git a/tools/objtool/arch/loongarch/decode.c b/tools/objtool/arch/loongarch/decode.c
+index 69b66994f2a15..b64205b89f6b4 100644
+--- a/tools/objtool/arch/loongarch/decode.c
++++ b/tools/objtool/arch/loongarch/decode.c
+@@ -363,3 +363,14 @@ void arch_initial_func_cfi_state(struct cfi_init_state *state)
+       state->cfa.base = CFI_SP;
+       state->cfa.offset = 0;
+ }
++
++unsigned int arch_reloc_size(struct reloc *reloc)
++{
++      switch (reloc_type(reloc)) {
++      case R_LARCH_32:
++      case R_LARCH_32_PCREL:
++              return 4;
++      default:
++              return 8;
++      }
++}
+diff --git a/tools/objtool/arch/powerpc/decode.c b/tools/objtool/arch/powerpc/decode.c
+index 53b55690f3204..7c0bf24290675 100644
+--- a/tools/objtool/arch/powerpc/decode.c
++++ b/tools/objtool/arch/powerpc/decode.c
+@@ -106,3 +106,17 @@ void arch_initial_func_cfi_state(struct cfi_init_state *state)
+       state->regs[CFI_RA].base = CFI_CFA;
+       state->regs[CFI_RA].offset = 0;
+ }
++
++unsigned int arch_reloc_size(struct reloc *reloc)
++{
++      switch (reloc_type(reloc)) {
++      case R_PPC_REL32:
++      case R_PPC_ADDR32:
++      case R_PPC_UADDR32:
++      case R_PPC_PLT32:
++      case R_PPC_PLTREL32:
++              return 4;
++      default:
++              return 8;
++      }
++}
+diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c
+index fe1362c345647..fb9691a34d926 100644
+--- a/tools/objtool/arch/x86/decode.c
++++ b/tools/objtool/arch/x86/decode.c
+@@ -852,3 +852,16 @@ bool arch_is_embedded_insn(struct symbol *sym)
+       return !strcmp(sym->name, "retbleed_return_thunk") ||
+              !strcmp(sym->name, "srso_safe_ret");
+ }
++
++unsigned int arch_reloc_size(struct reloc *reloc)
++{
++      switch (reloc_type(reloc)) {
++      case R_X86_64_32:
++      case R_X86_64_32S:
++      case R_X86_64_PC32:
++      case R_X86_64_PLT32:
++              return 4;
++      default:
++              return 8;
++      }
++}
+diff --git a/tools/objtool/check.c b/tools/objtool/check.c
+index 79c49c75b429b..4b9f01a11792f 100644
+--- a/tools/objtool/check.c
++++ b/tools/objtool/check.c
+@@ -1969,7 +1969,7 @@ static int add_jump_table(struct objtool_file *file, struct instruction *insn,
+                       break;
+               /* Make sure the table entries are consecutive: */
+-              if (prev_offset && reloc_offset(reloc) != prev_offset + 8)
++              if (prev_offset && reloc_offset(reloc) != prev_offset + arch_reloc_size(reloc))
+                       break;
+               sym_offset = reloc->sym->offset + reloc_addend(reloc);
+diff --git a/tools/objtool/include/objtool/arch.h b/tools/objtool/include/objtool/arch.h
+index d63b46a19f397..396f7c6c81c0f 100644
+--- a/tools/objtool/include/objtool/arch.h
++++ b/tools/objtool/include/objtool/arch.h
+@@ -97,4 +97,6 @@ int arch_rewrite_retpolines(struct objtool_file *file);
+ bool arch_pc_relative_reloc(struct reloc *reloc);
++unsigned int arch_reloc_size(struct reloc *reloc);
++
+ #endif /* _ARCH_H */
+-- 
+2.39.5
+
diff --git a/queue-6.14/objtool-handle-pc-relative-relocation-type.patch b/queue-6.14/objtool-handle-pc-relative-relocation-type.patch
new file mode 100644 (file)
index 0000000..71a48db
--- /dev/null
@@ -0,0 +1,141 @@
+From 7f6b8e0797ef3f276827eedacbf5b0e27e5f63e7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Feb 2025 19:50:12 +0800
+Subject: objtool: Handle PC relative relocation type
+
+From: Tiezhu Yang <yangtiezhu@loongson.cn>
+
+[ Upstream commit c4b93b06230ae49870187189d9f7342f6ad4f14e ]
+
+For the most part, an absolute relocation type is used for rodata.
+In the case of STT_SECTION, reloc->sym->offset is always zero, for
+the other symbol types, reloc_addend(reloc) is always zero, thus it
+can use a simple statement "reloc->sym->offset + reloc_addend(reloc)"
+to obtain the symbol offset for various symbol types.
+
+When compiling on LoongArch, there exist PC relative relocation types
+for rodata, it needs to calculate the symbol offset with "S + A - PC"
+according to the spec of "ELF for the LoongArch Architecture".
+
+If there is only one jump table in the rodata, the "PC" is the entry
+address which is equal with the value of reloc_offset(reloc), at this
+time, reloc_offset(table) is 0.
+
+If there are many jump tables in the rodata, the "PC" is the offset
+of the jump table's base address which is equal with the value of
+reloc_offset(reloc) - reloc_offset(table).
+
+So for LoongArch, if the relocation type is PC relative, it can use a
+statement "reloc_offset(reloc) - reloc_offset(table)" to get the "PC"
+value when calculating the symbol offset with "S + A - PC" for one or
+many jump tables in the rodata.
+
+Add an arch-specific function arch_jump_table_sym_offset() to assign
+the symbol offset, for the most part that is an absolute relocation,
+the default value is "reloc->sym->offset + reloc_addend(reloc)" in
+the weak definition, it can be overridden by each architecture that
+has different requirements.
+
+Link: https://github.com/loongson/la-abi-specs/blob/release/laelf.adoc
+Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
+Link: https://lore.kernel.org/r/20250211115016.26913-4-yangtiezhu@loongson.cn
+Acked-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
+Stable-dep-of: ef753d66051c ("objtool: Fix detection of consecutive jump tables on Clang 20")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/objtool/arch/loongarch/decode.c           | 17 +++++++++++++----
+ tools/objtool/arch/loongarch/include/arch/elf.h |  7 +++++++
+ tools/objtool/check.c                           |  7 ++++++-
+ tools/objtool/include/objtool/arch.h            |  1 +
+ 4 files changed, 27 insertions(+), 5 deletions(-)
+
+diff --git a/tools/objtool/arch/loongarch/decode.c b/tools/objtool/arch/loongarch/decode.c
+index b64205b89f6b4..02e4905559667 100644
+--- a/tools/objtool/arch/loongarch/decode.c
++++ b/tools/objtool/arch/loongarch/decode.c
+@@ -5,10 +5,7 @@
+ #include <asm/inst.h>
+ #include <asm/orc_types.h>
+ #include <linux/objtool_types.h>
+-
+-#ifndef EM_LOONGARCH
+-#define EM_LOONGARCH  258
+-#endif
++#include <arch/elf.h>
+ int arch_ftrace_match(char *name)
+ {
+@@ -374,3 +371,15 @@ unsigned int arch_reloc_size(struct reloc *reloc)
+               return 8;
+       }
+ }
++
++unsigned long arch_jump_table_sym_offset(struct reloc *reloc, struct reloc *table)
++{
++      switch (reloc_type(reloc)) {
++      case R_LARCH_32_PCREL:
++      case R_LARCH_64_PCREL:
++              return reloc->sym->offset + reloc_addend(reloc) -
++                     (reloc_offset(reloc) - reloc_offset(table));
++      default:
++              return reloc->sym->offset + reloc_addend(reloc);
++      }
++}
+diff --git a/tools/objtool/arch/loongarch/include/arch/elf.h b/tools/objtool/arch/loongarch/include/arch/elf.h
+index 9623d663220ef..ec79062c9554d 100644
+--- a/tools/objtool/arch/loongarch/include/arch/elf.h
++++ b/tools/objtool/arch/loongarch/include/arch/elf.h
+@@ -18,6 +18,13 @@
+ #ifndef R_LARCH_32_PCREL
+ #define R_LARCH_32_PCREL      99
+ #endif
++#ifndef R_LARCH_64_PCREL
++#define R_LARCH_64_PCREL      109
++#endif
++
++#ifndef EM_LOONGARCH
++#define EM_LOONGARCH          258
++#endif
+ #define R_NONE                        R_LARCH_NONE
+ #define R_ABS32                       R_LARCH_32
+diff --git a/tools/objtool/check.c b/tools/objtool/check.c
+index 4b9f01a11792f..12bf6c1f5071d 100644
+--- a/tools/objtool/check.c
++++ b/tools/objtool/check.c
+@@ -1944,6 +1944,11 @@ static int add_special_section_alts(struct objtool_file *file)
+       return ret;
+ }
++__weak unsigned long arch_jump_table_sym_offset(struct reloc *reloc, struct reloc *table)
++{
++      return reloc->sym->offset + reloc_addend(reloc);
++}
++
+ static int add_jump_table(struct objtool_file *file, struct instruction *insn,
+                         struct reloc *next_table)
+ {
+@@ -1972,7 +1977,7 @@ static int add_jump_table(struct objtool_file *file, struct instruction *insn,
+               if (prev_offset && reloc_offset(reloc) != prev_offset + arch_reloc_size(reloc))
+                       break;
+-              sym_offset = reloc->sym->offset + reloc_addend(reloc);
++              sym_offset = arch_jump_table_sym_offset(reloc, table);
+               /* Detect function pointers from contiguous objects: */
+               if (reloc->sym->sec == pfunc->sec && sym_offset == pfunc->offset)
+diff --git a/tools/objtool/include/objtool/arch.h b/tools/objtool/include/objtool/arch.h
+index 396f7c6c81c0f..089a1acc48a8d 100644
+--- a/tools/objtool/include/objtool/arch.h
++++ b/tools/objtool/include/objtool/arch.h
+@@ -98,5 +98,6 @@ int arch_rewrite_retpolines(struct objtool_file *file);
+ bool arch_pc_relative_reloc(struct reloc *reloc);
+ unsigned int arch_reloc_size(struct reloc *reloc);
++unsigned long arch_jump_table_sym_offset(struct reloc *reloc, struct reloc *table);
+ #endif /* _ARCH_H */
+-- 
+2.39.5
+
diff --git a/queue-6.14/objtool-handle-various-symbol-types-of-rodata.patch b/queue-6.14/objtool-handle-various-symbol-types-of-rodata.patch
new file mode 100644 (file)
index 0000000..e0c88b1
--- /dev/null
@@ -0,0 +1,92 @@
+From e6efe415670d8d341acd0fd4ee5dc5493a9ba0d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Feb 2025 19:50:10 +0800
+Subject: objtool: Handle various symbol types of rodata
+
+From: Tiezhu Yang <yangtiezhu@loongson.cn>
+
+[ Upstream commit ab6ce22b789622ca732e91cbb3a5cb5ba370cbd0 ]
+
+In the relocation section ".rela.rodata" of each .o file compiled with
+LoongArch toolchain, there are various symbol types such as STT_NOTYPE,
+STT_OBJECT, STT_FUNC in addition to the usual STT_SECTION, it needs to
+use reloc symbol offset instead of reloc addend to find the destination
+instruction in find_jump_table() and add_jump_table().
+
+For the most part, an absolute relocation type is used for rodata. In the
+case of STT_SECTION, reloc->sym->offset is always zero, and for the other
+symbol types, reloc_addend(reloc) is always zero, thus it can use a simple
+statement "reloc->sym->offset + reloc_addend(reloc)" to obtain the symbol
+offset for various symbol types.
+
+Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
+Link: https://lore.kernel.org/r/20250211115016.26913-2-yangtiezhu@loongson.cn
+Acked-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
+Stable-dep-of: ef753d66051c ("objtool: Fix detection of consecutive jump tables on Clang 20")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/objtool/check.c | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+diff --git a/tools/objtool/check.c b/tools/objtool/check.c
+index c1fa0220f33de..79c49c75b429b 100644
+--- a/tools/objtool/check.c
++++ b/tools/objtool/check.c
+@@ -1954,6 +1954,7 @@ static int add_jump_table(struct objtool_file *file, struct instruction *insn,
+       unsigned int prev_offset = 0;
+       struct reloc *reloc = table;
+       struct alternative *alt;
++      unsigned long sym_offset;
+       /*
+        * Each @reloc is a switch table relocation which points to the target
+@@ -1971,9 +1972,10 @@ static int add_jump_table(struct objtool_file *file, struct instruction *insn,
+               if (prev_offset && reloc_offset(reloc) != prev_offset + 8)
+                       break;
++              sym_offset = reloc->sym->offset + reloc_addend(reloc);
++
+               /* Detect function pointers from contiguous objects: */
+-              if (reloc->sym->sec == pfunc->sec &&
+-                  reloc_addend(reloc) == pfunc->offset)
++              if (reloc->sym->sec == pfunc->sec && sym_offset == pfunc->offset)
+                       break;
+               /*
+@@ -1981,10 +1983,10 @@ static int add_jump_table(struct objtool_file *file, struct instruction *insn,
+                * which point to the end of the function.  Ignore them.
+                */
+               if (reloc->sym->sec == pfunc->sec &&
+-                  reloc_addend(reloc) == pfunc->offset + pfunc->len)
++                  sym_offset == pfunc->offset + pfunc->len)
+                       goto next;
+-              dest_insn = find_insn(file, reloc->sym->sec, reloc_addend(reloc));
++              dest_insn = find_insn(file, reloc->sym->sec, sym_offset);
+               if (!dest_insn)
+                       break;
+@@ -2023,6 +2025,7 @@ static void find_jump_table(struct objtool_file *file, struct symbol *func,
+       struct reloc *table_reloc;
+       struct instruction *dest_insn, *orig_insn = insn;
+       unsigned long table_size;
++      unsigned long sym_offset;
+       /*
+        * Backward search using the @first_jump_src links, these help avoid
+@@ -2046,7 +2049,10 @@ static void find_jump_table(struct objtool_file *file, struct symbol *func,
+               table_reloc = arch_find_switch_table(file, insn, &table_size);
+               if (!table_reloc)
+                       continue;
+-              dest_insn = find_insn(file, table_reloc->sym->sec, reloc_addend(table_reloc));
++
++              sym_offset = table_reloc->sym->offset + reloc_addend(table_reloc);
++
++              dest_insn = find_insn(file, table_reloc->sym->sec, sym_offset);
+               if (!dest_insn || !insn_func(dest_insn) || insn_func(dest_insn)->pfunc != func)
+                       continue;
+-- 
+2.39.5
+
diff --git a/queue-6.14/objtool-loongarch-add-unwind-hints-in-prepare_framet.patch b/queue-6.14/objtool-loongarch-add-unwind-hints-in-prepare_framet.patch
new file mode 100644 (file)
index 0000000..bde5c76
--- /dev/null
@@ -0,0 +1,86 @@
+From 025debc85eaf79293136822f14707189e9c565a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Mar 2025 21:26:43 -0700
+Subject: objtool/loongarch: Add unwind hints in prepare_frametrace()
+
+From: Josh Poimboeuf <jpoimboe@kernel.org>
+
+[ Upstream commit 7c977393b8277ed319e92e4b598b26598c9d30c0 ]
+
+If 'regs' points to a local stack variable, prepare_frametrace() stores
+all registers to the stack.  This confuses objtool as it expects them to
+be restored from the stack later.
+
+The stores don't affect stack tracing, so use unwind hints to hide them
+from objtool.
+
+Fixes the following warnings:
+
+  arch/loongarch/kernel/traps.o: warning: objtool: show_stack+0xe0: stack state mismatch: reg1[22]=-1+0 reg2[22]=-2-160
+  arch/loongarch/kernel/traps.o: warning: objtool: show_stack+0xe0: stack state mismatch: reg1[23]=-1+0 reg2[23]=-2-152
+
+Fixes: cb8a2ef0848c ("LoongArch: Add ORC stack unwinder support")
+Reported-by: kernel test robot <lkp@intel.com>
+Tested-by: Tiezhu Yang <yangtiezhu@loongson.cn>
+Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Link: https://lore.kernel.org/r/270cadd8040dda74db2307f23497bb68e65db98d.1743481539.git.jpoimboe@kernel.org
+Closes: https://lore.kernel.org/oe-kbuild-all/202503280703.OARM8SrY-lkp@intel.com/
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/loongarch/include/asm/stacktrace.h   |  3 +++
+ arch/loongarch/include/asm/unwind_hints.h | 10 +++++++++-
+ 2 files changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/arch/loongarch/include/asm/stacktrace.h b/arch/loongarch/include/asm/stacktrace.h
+index f23adb15f418f..fc8b64773794a 100644
+--- a/arch/loongarch/include/asm/stacktrace.h
++++ b/arch/loongarch/include/asm/stacktrace.h
+@@ -8,6 +8,7 @@
+ #include <asm/asm.h>
+ #include <asm/ptrace.h>
+ #include <asm/loongarch.h>
++#include <asm/unwind_hints.h>
+ #include <linux/stringify.h>
+ enum stack_type {
+@@ -43,6 +44,7 @@ int get_stack_info(unsigned long stack, struct task_struct *task, struct stack_i
+ static __always_inline void prepare_frametrace(struct pt_regs *regs)
+ {
+       __asm__ __volatile__(
++              UNWIND_HINT_SAVE
+               /* Save $ra */
+               STORE_ONE_REG(1)
+               /* Use $ra to save PC */
+@@ -80,6 +82,7 @@ static __always_inline void prepare_frametrace(struct pt_regs *regs)
+               STORE_ONE_REG(29)
+               STORE_ONE_REG(30)
+               STORE_ONE_REG(31)
++              UNWIND_HINT_RESTORE
+               : "=m" (regs->csr_era)
+               : "r" (regs->regs)
+               : "memory");
+diff --git a/arch/loongarch/include/asm/unwind_hints.h b/arch/loongarch/include/asm/unwind_hints.h
+index a01086ad9ddea..2c68bc72736c9 100644
+--- a/arch/loongarch/include/asm/unwind_hints.h
++++ b/arch/loongarch/include/asm/unwind_hints.h
+@@ -23,6 +23,14 @@
+       UNWIND_HINT sp_reg=ORC_REG_SP type=UNWIND_HINT_TYPE_CALL
+ .endm
+-#endif /* __ASSEMBLY__ */
++#else /* !__ASSEMBLY__ */
++
++#define UNWIND_HINT_SAVE \
++      UNWIND_HINT(UNWIND_HINT_TYPE_SAVE, 0, 0, 0)
++
++#define UNWIND_HINT_RESTORE \
++      UNWIND_HINT(UNWIND_HINT_TYPE_RESTORE, 0, 0, 0)
++
++#endif /* !__ASSEMBLY__ */
+ #endif /* _ASM_LOONGARCH_UNWIND_HINTS_H */
+-- 
+2.39.5
+
diff --git a/queue-6.14/objtool-media-dib8000-prevent-divide-by-zero-in-dib8.patch b/queue-6.14/objtool-media-dib8000-prevent-divide-by-zero-in-dib8.patch
new file mode 100644 (file)
index 0000000..b06cedf
--- /dev/null
@@ -0,0 +1,49 @@
+From c66e2f743e403c69214bba41776a831b01f88226 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Mar 2025 14:56:06 -0700
+Subject: objtool, media: dib8000: Prevent divide-by-zero in dib8000_set_dds()
+
+From: Josh Poimboeuf <jpoimboe@kernel.org>
+
+[ Upstream commit e63d465f59011dede0a0f1d21718b59a64c3ff5c ]
+
+If dib8000_set_dds()'s call to dib8000_read32() returns zero, the result
+is a divide-by-zero.  Prevent that from happening.
+
+Fixes the following warning with an UBSAN kernel:
+
+  drivers/media/dvb-frontends/dib8000.o: warning: objtool: dib8000_tune() falls through to next function dib8096p_cfg_DibRx()
+
+Fixes: 173a64cb3fcf ("[media] dib8000: enhancement")
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Link: https://lore.kernel.org/r/bd1d504d930ae3f073b1e071bcf62cae7708773c.1742852847.git.jpoimboe@kernel.org
+Closes: https://lore.kernel.org/r/202503210602.fvH5DO1i-lkp@intel.com/
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/dvb-frontends/dib8000.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/dvb-frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c
+index 2f5165918163d..cfe59c3255f70 100644
+--- a/drivers/media/dvb-frontends/dib8000.c
++++ b/drivers/media/dvb-frontends/dib8000.c
+@@ -2701,8 +2701,11 @@ static void dib8000_set_dds(struct dib8000_state *state, s32 offset_khz)
+       u8 ratio;
+       if (state->revision == 0x8090) {
++              u32 internal = dib8000_read32(state, 23) / 1000;
++
+               ratio = 4;
+-              unit_khz_dds_val = (1<<26) / (dib8000_read32(state, 23) / 1000);
++
++              unit_khz_dds_val = (1<<26) / (internal ?: 1);
+               if (offset_khz < 0)
+                       dds = (1 << 26) - (abs_offset_khz * unit_khz_dds_val);
+               else
+-- 
+2.39.5
+
diff --git a/queue-6.14/objtool-nvmet-fix-out-of-bounds-stack-access-in-nvme.patch b/queue-6.14/objtool-nvmet-fix-out-of-bounds-stack-access-in-nvme.patch
new file mode 100644 (file)
index 0000000..f2447b1
--- /dev/null
@@ -0,0 +1,49 @@
+From 26843688c456c5e6ed7d9e09034adcabfc4d8746 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Mar 2025 14:56:05 -0700
+Subject: objtool, nvmet: Fix out-of-bounds stack access in
+ nvmet_ctrl_state_show()
+
+From: Josh Poimboeuf <jpoimboe@kernel.org>
+
+[ Upstream commit 107a23185d990e3df6638d9a84c835f963fe30a6 ]
+
+The csts_state_names[] array only has six sparse entries, but the
+iteration code in nvmet_ctrl_state_show() iterates seven, resulting in a
+potential out-of-bounds stack read.  Fix that.
+
+Fixes the following warning with an UBSAN kernel:
+
+  vmlinux.o: warning: objtool: .text.nvmet_ctrl_state_show: unexpected end of section
+
+Fixes: 649fd41420a8 ("nvmet: add debugfs support")
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Sagi Grimberg <sagi@grimberg.me>
+Cc: Chaitanya Kulkarni <kch@nvidia.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Link: https://lore.kernel.org/r/f1f60858ee7a941863dc7f5506c540cb9f97b5f6.1742852847.git.jpoimboe@kernel.org
+Closes: https://lore.kernel.org/oe-kbuild-all/202503171547.LlCTJLQL-lkp@intel.com/
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/target/debugfs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/nvme/target/debugfs.c b/drivers/nvme/target/debugfs.c
+index 220c7391fc19a..c6571fbd35e30 100644
+--- a/drivers/nvme/target/debugfs.c
++++ b/drivers/nvme/target/debugfs.c
+@@ -78,7 +78,7 @@ static int nvmet_ctrl_state_show(struct seq_file *m, void *p)
+       bool sep = false;
+       int i;
+-      for (i = 0; i < 7; i++) {
++      for (i = 0; i < ARRAY_SIZE(csts_state_names); i++) {
+               int state = BIT(i);
+               if (!(ctrl->csts & state))
+-- 
+2.39.5
+
diff --git a/queue-6.14/objtool-spi-amd-fix-out-of-bounds-stack-access-in-am.patch b/queue-6.14/objtool-spi-amd-fix-out-of-bounds-stack-access-in-am.patch
new file mode 100644 (file)
index 0000000..a1c0aff
--- /dev/null
@@ -0,0 +1,51 @@
+From 13bca3630831efd54ef6bc603888d15acf3d3536 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Mar 2025 14:56:04 -0700
+Subject: objtool, spi: amd: Fix out-of-bounds stack access in
+ amd_set_spi_freq()
+
+From: Josh Poimboeuf <jpoimboe@kernel.org>
+
+[ Upstream commit 76e51db43fe4aaaebcc5ddda67b0807f7c9bdecc ]
+
+If speed_hz < AMD_SPI_MIN_HZ, amd_set_spi_freq() iterates over the
+entire amd_spi_freq array without breaking out early, causing 'i' to go
+beyond the array bounds.
+
+Fix that by stopping the loop when it gets to the last entry, so the low
+speed_hz value gets clamped up to AMD_SPI_MIN_HZ.
+
+Fixes the following warning with an UBSAN kernel:
+
+  drivers/spi/spi-amd.o: error: objtool: amd_set_spi_freq() falls through to next function amd_spi_set_opcode()
+
+Fixes: 3fe26121dc3a ("spi: amd: Configure device speed")
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Mark Brown <broonie@kernel.org>
+Cc: Raju Rangoju <Raju.Rangoju@amd.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Link: https://lore.kernel.org/r/78fef0f2434f35be9095bcc9ffa23dd8cab667b9.1742852847.git.jpoimboe@kernel.org
+Closes: https://lore.kernel.org/r/202503161828.RUk9EhWx-lkp@intel.com/
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-amd.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-amd.c b/drivers/spi/spi-amd.c
+index c85997478b819..17fc0b17e756d 100644
+--- a/drivers/spi/spi-amd.c
++++ b/drivers/spi/spi-amd.c
+@@ -302,7 +302,7 @@ static void amd_set_spi_freq(struct amd_spi *amd_spi, u32 speed_hz)
+ {
+       unsigned int i, spd7_val, alt_spd;
+-      for (i = 0; i < ARRAY_SIZE(amd_spi_freq); i++)
++      for (i = 0; i < ARRAY_SIZE(amd_spi_freq)-1; i++)
+               if (speed_hz >= amd_spi_freq[i].speed_hz)
+                       break;
+-- 
+2.39.5
+
diff --git a/queue-6.14/ocfs2-validate-l_tree_depth-to-avoid-out-of-bounds-a.patch b/queue-6.14/ocfs2-validate-l_tree_depth-to-avoid-out-of-bounds-a.patch
new file mode 100644 (file)
index 0000000..a066234
--- /dev/null
@@ -0,0 +1,56 @@
+From d290ad05f2e587a0830ab902c0fdc7d032499264 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Feb 2025 11:49:08 +0300
+Subject: ocfs2: validate l_tree_depth to avoid out-of-bounds access
+
+From: Vasiliy Kovalev <kovalev@altlinux.org>
+
+[ Upstream commit a406aff8c05115119127c962cbbbbd202e1973ef ]
+
+The l_tree_depth field is 16-bit (__le16), but the actual maximum depth is
+limited to OCFS2_MAX_PATH_DEPTH.
+
+Add a check to prevent out-of-bounds access if l_tree_depth has an invalid
+value, which may occur when reading from a corrupted mounted disk [1].
+
+Link: https://lkml.kernel.org/r/20250214084908.736528-1-kovalev@altlinux.org
+Fixes: ccd979bdbce9 ("[PATCH] OCFS2: The Second Oracle Cluster Filesystem")
+Signed-off-by: Vasiliy Kovalev <kovalev@altlinux.org>
+Reported-by: syzbot+66c146268dc88f4341fd@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=66c146268dc88f4341fd [1]
+Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.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>
+Cc: Kurt Hackel <kurt.hackel@oracle.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: Vasiliy Kovalev <kovalev@altlinux.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ocfs2/alloc.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
+index 4414743b638e8..b8ac85b548c7e 100644
+--- a/fs/ocfs2/alloc.c
++++ b/fs/ocfs2/alloc.c
+@@ -1803,6 +1803,14 @@ static int __ocfs2_find_path(struct ocfs2_caching_info *ci,
+       el = root_el;
+       while (el->l_tree_depth) {
++              if (unlikely(le16_to_cpu(el->l_tree_depth) >= OCFS2_MAX_PATH_DEPTH)) {
++                      ocfs2_error(ocfs2_metadata_cache_get_super(ci),
++                                  "Owner %llu has invalid tree depth %u in extent list\n",
++                                  (unsigned long long)ocfs2_metadata_cache_owner(ci),
++                                  le16_to_cpu(el->l_tree_depth));
++                      ret = -EROFS;
++                      goto out;
++              }
+               if (le16_to_cpu(el->l_next_free_rec) == 0) {
+                       ocfs2_error(ocfs2_metadata_cache_get_super(ci),
+                                   "Owner %llu has empty extent list at depth %u\n",
+-- 
+2.39.5
+
diff --git a/queue-6.14/octeontx2-af-fix-mbox-intr-handler-when-num-vfs-64.patch b/queue-6.14/octeontx2-af-fix-mbox-intr-handler-when-num-vfs-64.patch
new file mode 100644 (file)
index 0000000..852bd65
--- /dev/null
@@ -0,0 +1,39 @@
+From fb6e60c6db2c33ff39b26a36d11adb9f13dd9329 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Mar 2025 14:44:41 +0530
+Subject: octeontx2-af: Fix mbox INTR handler when num VFs > 64
+
+From: Geetha sowjanya <gakula@marvell.com>
+
+[ Upstream commit 0fdba88a211508984eb5df62008c29688692b134 ]
+
+When number of RVU VFs > 64, the vfs value passed to "rvu_queue_work"
+function is incorrect. Due to which mbox workqueue entries for
+VFs 0 to 63 never gets added to workqueue.
+
+Fixes: 9bdc47a6e328 ("octeontx2-af: Mbox communication support btw AF and it's VFs")
+Signed-off-by: Geetha sowjanya <gakula@marvell.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250327091441.1284-1-gakula@marvell.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/octeontx2/af/rvu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
+index cd0d7b7774f1a..6575c422635b7 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
+@@ -2634,7 +2634,7 @@ static irqreturn_t rvu_mbox_intr_handler(int irq, void *rvu_irq)
+               rvupf_write64(rvu, RVU_PF_VFPF_MBOX_INTX(1), intr);
+               rvu_queue_work(&rvu->afvf_wq_info, 64, vfs, intr);
+-              vfs -= 64;
++              vfs = 64;
+       }
+       intr = rvupf_read64(rvu, RVU_PF_VFPF_MBOX_INTX(0));
+-- 
+2.39.5
+
diff --git a/queue-6.14/octeontx2-af-free-nix_af_int_vec_gen-irq.patch b/queue-6.14/octeontx2-af-free-nix_af_int_vec_gen-irq.patch
new file mode 100644 (file)
index 0000000..d22cf40
--- /dev/null
@@ -0,0 +1,40 @@
+From cfaba7e83534f97f7ae969fd37b5ffe015c12eb9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Mar 2025 15:10:54 +0530
+Subject: octeontx2-af: Free NIX_AF_INT_VEC_GEN irq
+
+From: Geetha sowjanya <gakula@marvell.com>
+
+[ Upstream commit 323d6db6dc7decb06f2545efb9496259ddacd4f4 ]
+
+Due to the incorrect initial vector number in
+rvu_nix_unregister_interrupts(), NIX_AF_INT_VEC_GEN is not
+geeting free. Fix the vector number to include NIX_AF_INT_VEC_GEN
+irq.
+
+Fixes: 5ed66306eab6 ("octeontx2-af: Add devlink health reporters for NIX")
+Signed-off-by: Geetha sowjanya <gakula@marvell.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250327094054.2312-1-gakula@marvell.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c
+index dab4deca893f5..27c3a2daaaa95 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c
+@@ -207,7 +207,7 @@ static void rvu_nix_unregister_interrupts(struct rvu *rvu)
+               rvu->irq_allocated[offs + NIX_AF_INT_VEC_RVU] = false;
+       }
+-      for (i = NIX_AF_INT_VEC_AF_ERR; i < NIX_AF_INT_VEC_CNT; i++)
++      for (i = NIX_AF_INT_VEC_GEN; i < NIX_AF_INT_VEC_CNT; i++)
+               if (rvu->irq_allocated[offs + i]) {
+                       free_irq(pci_irq_vector(rvu->pdev, offs + i), rvu_dl);
+                       rvu->irq_allocated[offs + i] = false;
+-- 
+2.39.5
+
diff --git a/queue-6.14/of-property-increase-nr_fwnode_reference_args.patch b/queue-6.14/of-property-increase-nr_fwnode_reference_args.patch
new file mode 100644 (file)
index 0000000..6548864
--- /dev/null
@@ -0,0 +1,52 @@
+From 57c3526427f037857be4a2d03f14ca5b19680052 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Feb 2025 21:58:06 +0800
+Subject: of: property: Increase NR_FWNODE_REFERENCE_ARGS
+
+From: Zijun Hu <quic_zijuhu@quicinc.com>
+
+[ Upstream commit eb50844d728f11e87491f7c7af15a4a737f1159d ]
+
+Currently, the following two macros have different values:
+
+// The maximal argument count for firmware node reference
+ #define NR_FWNODE_REFERENCE_ARGS      8
+// The maximal argument count for DT node reference
+ #define MAX_PHANDLE_ARGS 16
+
+It may cause firmware node reference's argument count out of range if
+directly assign DT node reference's argument count to firmware's.
+
+drivers/of/property.c:of_fwnode_get_reference_args() is doing the direct
+assignment, so may cause firmware's argument count @args->nargs got out
+of range, namely, in [9, 16].
+
+Fix by increasing NR_FWNODE_REFERENCE_ARGS to 16 to meet DT requirement.
+Will align both macros later to avoid such inconsistency.
+
+Fixes: 3e3119d3088f ("device property: Introduce fwnode_property_get_reference_args")
+Signed-off-by: Zijun Hu <quic_zijuhu@quicinc.com>
+Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Link: https://lore.kernel.org/r/20250225-fix_arg_count-v4-1-13cdc519eb31@quicinc.com
+Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/fwnode.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h
+index 0731994b9d7c8..6fa0a268d5382 100644
+--- a/include/linux/fwnode.h
++++ b/include/linux/fwnode.h
+@@ -91,7 +91,7 @@ struct fwnode_endpoint {
+ #define SWNODE_GRAPH_PORT_NAME_FMT            "port@%u"
+ #define SWNODE_GRAPH_ENDPOINT_NAME_FMT                "endpoint@%u"
+-#define NR_FWNODE_REFERENCE_ARGS      8
++#define NR_FWNODE_REFERENCE_ARGS      16
+ /**
+  * struct fwnode_reference_args - Fwnode reference with additional arguments
+-- 
+2.39.5
+
diff --git a/queue-6.14/pci-acs-fix-pci-config_acs-parameter.patch b/queue-6.14/pci-acs-fix-pci-config_acs-parameter.patch
new file mode 100644 (file)
index 0000000..edd4340
--- /dev/null
@@ -0,0 +1,143 @@
+From eaf950b03e2755e77cf3019af104d3ba9dbc6fd6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Feb 2025 19:03:38 -0800
+Subject: PCI/ACS: Fix 'pci=config_acs=' parameter
+
+From: Tushar Dave <tdave@nvidia.com>
+
+[ Upstream commit 9cf8a952d57b422d3ff8a9a0163f8adf694f4b2b ]
+
+Commit 47c8846a49ba ("PCI: Extend ACS configurability") introduced bugs
+that fail to configure ACS ctrl to the value specified by the kernel
+parameter. Essentially there are two bugs:
+
+1) When ACS is configured for multiple PCI devices using 'config_acs'
+   kernel parameter, it results into error "PCI: Can't parse ACS command
+   line parameter". This is due to a bug that doesn't preserve the ACS
+   mask, but instead overwrites the mask with value 0.
+
+   For example, using 'config_acs' to configure ACS ctrl for multiple BDFs
+   fails:
+
+      Kernel command line: pci=config_acs=1111011@0020:02:00.0;101xxxx@0039:00:00.0 "dyndbg=file drivers/pci/pci.c +p"
+      PCI: Can't parse ACS command line parameter
+      pci 0020:02:00.0: ACS mask  = 0x007f
+      pci 0020:02:00.0: ACS flags = 0x007b
+      pci 0020:02:00.0: Configured ACS to 0x007b
+
+   After this fix:
+
+      Kernel command line: pci=config_acs=1111011@0020:02:00.0;101xxxx@0039:00:00.0 "dyndbg=file drivers/pci/pci.c +p"
+      pci 0020:02:00.0: ACS mask  = 0x007f
+      pci 0020:02:00.0: ACS flags = 0x007b
+      pci 0020:02:00.0: ACS control = 0x005f
+      pci 0020:02:00.0: ACS fw_ctrl = 0x0053
+      pci 0020:02:00.0: Configured ACS to 0x007b
+      pci 0039:00:00.0: ACS mask  = 0x0070
+      pci 0039:00:00.0: ACS flags = 0x0050
+      pci 0039:00:00.0: ACS control = 0x001d
+      pci 0039:00:00.0: ACS fw_ctrl = 0x0000
+      pci 0039:00:00.0: Configured ACS to 0x0050
+
+2) In the bit manipulation logic, we copy the bit from the firmware
+   settings when mask bit 0.
+
+   For example, 'disable_acs_redir' fails to clear all three ACS P2P redir
+   bits due to the wrong bit fiddling:
+
+      Kernel command line: pci=disable_acs_redir=0020:02:00.0;0030:02:00.0;0039:00:00.0 "dyndbg=file drivers/pci/pci.c +p"
+      pci 0020:02:00.0: ACS mask  = 0x002c
+      pci 0020:02:00.0: ACS flags = 0xffd3
+      pci 0020:02:00.0: Configured ACS to 0xfffb
+      pci 0030:02:00.0: ACS mask  = 0x002c
+      pci 0030:02:00.0: ACS flags = 0xffd3
+      pci 0030:02:00.0: Configured ACS to 0xffdf
+      pci 0039:00:00.0: ACS mask  = 0x002c
+      pci 0039:00:00.0: ACS flags = 0xffd3
+      pci 0039:00:00.0: Configured ACS to 0xffd3
+
+   After this fix:
+
+      Kernel command line: pci=disable_acs_redir=0020:02:00.0;0030:02:00.0;0039:00:00.0 "dyndbg=file drivers/pci/pci.c +p"
+      pci 0020:02:00.0: ACS mask  = 0x002c
+      pci 0020:02:00.0: ACS flags = 0xffd3
+      pci 0020:02:00.0: ACS control = 0x007f
+      pci 0020:02:00.0: ACS fw_ctrl = 0x007b
+      pci 0020:02:00.0: Configured ACS to 0x0053
+      pci 0030:02:00.0: ACS mask  = 0x002c
+      pci 0030:02:00.0: ACS flags = 0xffd3
+      pci 0030:02:00.0: ACS control = 0x005f
+      pci 0030:02:00.0: ACS fw_ctrl = 0x005f
+      pci 0030:02:00.0: Configured ACS to 0x0053
+      pci 0039:00:00.0: ACS mask  = 0x002c
+      pci 0039:00:00.0: ACS flags = 0xffd3
+      pci 0039:00:00.0: ACS control = 0x001d
+      pci 0039:00:00.0: ACS fw_ctrl = 0x0000
+      pci 0039:00:00.0: Configured ACS to 0x0000
+
+Link: https://lore.kernel.org/r/20250207030338.456887-1-tdave@nvidia.com
+Fixes: 47c8846a49ba ("PCI: Extend ACS configurability")
+Signed-off-by: Tushar Dave <tdave@nvidia.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
+Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pci.c | 18 +++++++++++++-----
+ 1 file changed, 13 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
+index 869d204a70a37..23609dd123f95 100644
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -954,8 +954,10 @@ struct pci_acs {
+ };
+ static void __pci_config_acs(struct pci_dev *dev, struct pci_acs *caps,
+-                           const char *p, u16 mask, u16 flags)
++                           const char *p, const u16 acs_mask, const u16 acs_flags)
+ {
++      u16 flags = acs_flags;
++      u16 mask = acs_mask;
+       char *delimit;
+       int ret = 0;
+@@ -963,7 +965,7 @@ static void __pci_config_acs(struct pci_dev *dev, struct pci_acs *caps,
+               return;
+       while (*p) {
+-              if (!mask) {
++              if (!acs_mask) {
+                       /* Check for ACS flags */
+                       delimit = strstr(p, "@");
+                       if (delimit) {
+@@ -971,6 +973,8 @@ static void __pci_config_acs(struct pci_dev *dev, struct pci_acs *caps,
+                               u32 shift = 0;
+                               end = delimit - p - 1;
++                              mask = 0;
++                              flags = 0;
+                               while (end > -1) {
+                                       if (*(p + end) == '0') {
+@@ -1027,10 +1031,14 @@ static void __pci_config_acs(struct pci_dev *dev, struct pci_acs *caps,
+       pci_dbg(dev, "ACS mask  = %#06x\n", mask);
+       pci_dbg(dev, "ACS flags = %#06x\n", flags);
++      pci_dbg(dev, "ACS control = %#06x\n", caps->ctrl);
++      pci_dbg(dev, "ACS fw_ctrl = %#06x\n", caps->fw_ctrl);
+-      /* If mask is 0 then we copy the bit from the firmware setting. */
+-      caps->ctrl = (caps->ctrl & ~mask) | (caps->fw_ctrl & mask);
+-      caps->ctrl |= flags;
++      /*
++       * For mask bits that are 0, copy them from the firmware setting
++       * and apply flags for all the mask bits that are 1.
++       */
++      caps->ctrl = (caps->fw_ctrl & ~mask) | (flags & mask);
+       pci_info(dev, "Configured ACS to %#06x\n", caps->ctrl);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/pci-allow-relaxed-bridge-window-tail-sizing-for-opti.patch b/queue-6.14/pci-allow-relaxed-bridge-window-tail-sizing-for-opti.patch
new file mode 100644 (file)
index 0000000..219d3cd
--- /dev/null
@@ -0,0 +1,76 @@
+From 836751174dd6f299e1f6c7fba078f97bb41a0119 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Dec 2024 19:56:11 +0200
+Subject: PCI: Allow relaxed bridge window tail sizing for optional resources
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit 67f9085596ee55dd27b540ca6088ba0717ee511c ]
+
+Commit 566f1dd52816 ("PCI: Relax bridge window tail sizing rules")
+relaxed the bridge window requirements for non-optional size (size0)
+but pbus_size_mem() also handles optional sizes (IOV resources) using
+size1. This can manifest, e.g., as a failure to resize a BAR back to
+its original size after it was first shrunk when device has a VF BAR
+resource because the bridge window (size1) is enlarged beyond what is
+strictly required to fit the downstream resources.
+
+Allow using relaxed bridge window tail sizing rules also with the optional
+resources (size1) so that the remove/realloc cycle during BAR resize
+(smaller and back to the original size) does not fail unexpectedly due to
+increase in bridge window size demand.
+
+Also move add_align calculation to more logical place next to size1
+assignment as they are strongly related to each other.
+
+Link: https://lore.kernel.org/r/20241216175632.4175-5-ilpo.jarvinen@linux.intel.com
+Fixes: 566f1dd52816 ("PCI: Relax bridge window tail sizing rules")
+Reported-by: Michał Winiarski <michal.winiarski@intel.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Tested-by: Xiaochun Lee <lixc17@lenovo.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/setup-bus.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
+index d9f129a7735a5..8707c5b08cf34 100644
+--- a/drivers/pci/setup-bus.c
++++ b/drivers/pci/setup-bus.c
+@@ -1146,7 +1146,6 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
+       min_align = calculate_mem_align(aligns, max_order);
+       min_align = max(min_align, win_align);
+       size0 = calculate_memsize(size, min_size, 0, 0, resource_size(b_res), min_align);
+-      add_align = max(min_align, add_align);
+       if (bus->self && size0 &&
+           !pbus_upstream_space_available(bus, mask | IORESOURCE_PREFETCH, type,
+@@ -1159,8 +1158,21 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
+       }
+       if (realloc_head && (add_size > 0 || children_add_size > 0)) {
++              add_align = max(min_align, add_align);
+               size1 = calculate_memsize(size, min_size, add_size, children_add_size,
+                                         resource_size(b_res), add_align);
++
++              if (bus->self && size1 &&
++                  !pbus_upstream_space_available(bus, mask | IORESOURCE_PREFETCH, type,
++                                                 size1, add_align)) {
++                      min_align = 1ULL << (max_order + __ffs(SZ_1M));
++                      min_align = max(min_align, win_align);
++                      size1 = calculate_memsize(size, min_size, add_size, children_add_size,
++                                                resource_size(b_res), win_align);
++                      pci_info(bus->self,
++                               "bridge window %pR to %pR requires relaxed alignment rules\n",
++                               b_res, &bus->busn_res);
++              }
+       }
+       if (!size0 && !size1) {
+-- 
+2.39.5
+
diff --git a/queue-6.14/pci-aspm-fix-link-state-exit-during-switch-upstream-.patch b/queue-6.14/pci-aspm-fix-link-state-exit-during-switch-upstream-.patch
new file mode 100644 (file)
index 0000000..de7a64d
--- /dev/null
@@ -0,0 +1,84 @@
+From 5f629cfd9694bd0b95729e8671744d9fa9fec0e5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 22 Dec 2024 19:39:08 -0800
+Subject: PCI/ASPM: Fix link state exit during switch upstream function removal
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Daniel Stodden <daniel.stodden@gmail.com>
+
+[ Upstream commit cbf937dcadfd571a434f8074d057b32cd14fbea5 ]
+
+Before 456d8aa37d0f ("PCI/ASPM: Disable ASPM on MFD function removal to
+avoid use-after-free"), we would free the ASPM link only after the last
+function on the bus pertaining to the given link was removed.
+
+That was too late. If function 0 is removed before sibling function,
+link->downstream would point to free'd memory after.
+
+After above change, we freed the ASPM parent link state upon any function
+removal on the bus pertaining to a given link.
+
+That is too early. If the link is to a PCIe switch with MFD on the upstream
+port, then removing functions other than 0 first would free a link which
+still remains parent_link to the remaining downstream ports.
+
+The resulting GPFs are especially frequent during hot-unplug, because
+pciehp removes devices on the link bus in reverse order.
+
+On that switch, function 0 is the virtual P2P bridge to the internal bus.
+Free exactly when function 0 is removed -- before the parent link is
+obsolete, but after all subordinate links are gone.
+
+Link: https://lore.kernel.org/r/e12898835f25234561c9d7de4435590d957b85d9.1734924854.git.dns@arista.com
+Fixes: 456d8aa37d0f ("PCI/ASPM: Disable ASPM on MFD function removal to avoid use-after-free")
+Signed-off-by: Daniel Stodden <dns@arista.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+[kwilczynski: commit log]
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pcie/aspm.c | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
+index da3e7edcf49d9..29fcb0689a918 100644
+--- a/drivers/pci/pcie/aspm.c
++++ b/drivers/pci/pcie/aspm.c
+@@ -1270,16 +1270,16 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev)
+       parent_link = link->parent;
+       /*
+-       * link->downstream is a pointer to the pci_dev of function 0.  If
+-       * we remove that function, the pci_dev is about to be deallocated,
+-       * so we can't use link->downstream again.  Free the link state to
+-       * avoid this.
++       * Free the parent link state, no later than function 0 (i.e.
++       * link->downstream) being removed.
+        *
+-       * If we're removing a non-0 function, it's possible we could
+-       * retain the link state, but PCIe r6.0, sec 7.5.3.7, recommends
+-       * programming the same ASPM Control value for all functions of
+-       * multi-function devices, so disable ASPM for all of them.
++       * Do not free the link state any earlier. If function 0 is a
++       * switch upstream port, this link state is parent_link to all
++       * subordinate ones.
+        */
++      if (pdev != link->downstream)
++              goto out;
++
+       pcie_config_aspm_link(link, 0);
+       list_del(&link->sibling);
+       free_link_state(link);
+@@ -1290,6 +1290,7 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev)
+               pcie_config_aspm_path(parent_link);
+       }
++ out:
+       mutex_unlock(&aspm_lock);
+       up_read(&pci_bus_sem);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/pci-avoid-reset-when-disabled-via-sysfs.patch b/queue-6.14/pci-avoid-reset-when-disabled-via-sysfs.patch
new file mode 100644 (file)
index 0000000..8139065
--- /dev/null
@@ -0,0 +1,67 @@
+From 7b6100a6efe07d75094632952dd7b5300391d1e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Feb 2025 14:56:00 -0600
+Subject: PCI: Avoid reset when disabled via sysfs
+
+From: Nishanth Aravamudan <naravamudan@nvidia.com>
+
+[ Upstream commit 479380efe1625e251008d24b2810283db60d6fcd ]
+
+After d88f521da3ef ("PCI: Allow userspace to query and set device reset
+mechanism"), userspace can disable reset of specific PCI devices by writing
+an empty string to the sysfs reset_method file.
+
+However, pci_slot_resettable() does not check pci_reset_supported(), which
+means that pci_reset_function() will still reset the device even if
+userspace has disabled all the reset methods.
+
+I was able to reproduce this issue with a vfio device passed to a qemu
+guest, where I had disabled PCI reset via sysfs.
+
+Add an explicit check of pci_reset_supported() in both
+pci_slot_resettable() and pci_bus_resettable() to ensure both the reset
+status and reset execution are bypassed if an administrator disables it for
+a device.
+
+Link: https://lore.kernel.org/r/20250207205600.1846178-1-naravamudan@nvidia.com
+Fixes: d88f521da3ef ("PCI: Allow userspace to query and set device reset mechanism")
+Signed-off-by: Nishanth Aravamudan <naravamudan@nvidia.com>
+[bhelgaas: commit log]
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Cc: Alex Williamson <alex.williamson@redhat.com>
+Cc: Raphael Norwitz <raphael.norwitz@nutanix.com>
+Cc: Amey Narkhede <ameynarkhede03@gmail.com>
+Cc: Jason Gunthorpe <jgg@nvidia.com>
+Cc: Yishai Hadas <yishaih@nvidia.com>
+Cc: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
+Cc: Kevin Tian <kevin.tian@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pci.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
+index 23609dd123f95..3e78cf86ef03b 100644
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -5413,6 +5413,8 @@ static bool pci_bus_resettable(struct pci_bus *bus)
+               return false;
+       list_for_each_entry(dev, &bus->devices, bus_list) {
++              if (!pci_reset_supported(dev))
++                      return false;
+               if (dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET ||
+                   (dev->subordinate && !pci_bus_resettable(dev->subordinate)))
+                       return false;
+@@ -5489,6 +5491,8 @@ static bool pci_slot_resettable(struct pci_slot *slot)
+       list_for_each_entry(dev, &slot->bus->devices, bus_list) {
+               if (!dev->slot || dev->slot != slot)
+                       continue;
++              if (!pci_reset_supported(dev))
++                      return false;
+               if (dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET ||
+                   (dev->subordinate && !pci_bus_resettable(dev->subordinate)))
+                       return false;
+-- 
+2.39.5
+
diff --git a/queue-6.14/pci-brcmstb-fix-error-path-after-a-call-to-regulator.patch b/queue-6.14/pci-brcmstb-fix-error-path-after-a-call-to-regulator.patch
new file mode 100644 (file)
index 0000000..ada0278
--- /dev/null
@@ -0,0 +1,50 @@
+From b970ceb339d43fe9be244d1487cb59da6c91db98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Feb 2025 12:39:32 -0500
+Subject: PCI: brcmstb: Fix error path after a call to regulator_bulk_get()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jim Quinlan <james.quinlan@broadcom.com>
+
+[ Upstream commit 3651ad5249c51cf7eee078e12612557040a6bdb4 ]
+
+If the regulator_bulk_get() returns an error and no regulators
+are created, we need to set their number to zero.
+
+If we don't do this and the PCIe link up fails, a call to the
+regulator_bulk_free() will result in a kernel panic.
+
+While at it, print the error value, as we cannot return an error
+upwards as the kernel will WARN() on an error from add_bus().
+
+Fixes: 9e6be018b263 ("PCI: brcmstb: Enable child bus device regulators from DT")
+Signed-off-by: Jim Quinlan <james.quinlan@broadcom.com>
+Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Link: https://lore.kernel.org/r/20250214173944.47506-5-james.quinlan@broadcom.com
+[kwilczynski: commit log, use comma in the message to match style with
+other similar messages]
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/pcie-brcmstb.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
+index 8b728c0f7f421..1495d770b4c2c 100644
+--- a/drivers/pci/controller/pcie-brcmstb.c
++++ b/drivers/pci/controller/pcie-brcmstb.c
+@@ -1368,7 +1368,8 @@ static int brcm_pcie_add_bus(struct pci_bus *bus)
+               ret = regulator_bulk_get(dev, sr->num_supplies, sr->supplies);
+               if (ret) {
+-                      dev_info(dev, "No regulators for downstream device\n");
++                      dev_info(dev, "Did not get regulators, err=%d\n", ret);
++                      pcie->sr = NULL;
+                       goto no_regulators;
+               }
+-- 
+2.39.5
+
diff --git a/queue-6.14/pci-brcmstb-fix-potential-premature-regulator-disabl.patch b/queue-6.14/pci-brcmstb-fix-potential-premature-regulator-disabl.patch
new file mode 100644 (file)
index 0000000..bad5e93
--- /dev/null
@@ -0,0 +1,47 @@
+From 3ab4a3dc24ea2b947f4de002fb38a628c12f78d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Feb 2025 12:39:33 -0500
+Subject: PCI: brcmstb: Fix potential premature regulator disabling
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jim Quinlan <james.quinlan@broadcom.com>
+
+[ Upstream commit b7de1b60ecab2f7b6f05d8116e93228a0bbb8563 ]
+
+The platform supports enabling and disabling regulators only on
+ports below the Root Complex.
+
+Thus, we need to verify this both when adding and removing the bus,
+otherwise regulators may be disabled prematurely when a bus further
+down the topology is removed.
+
+Fixes: 9e6be018b263 ("PCI: brcmstb: Enable child bus device regulators from DT")
+Signed-off-by: Jim Quinlan <james.quinlan@broadcom.com>
+Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/20250214173944.47506-6-james.quinlan@broadcom.com
+[kwilczynski: commit log]
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/pcie-brcmstb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
+index 1495d770b4c2c..3d7dbfcd689e3 100644
+--- a/drivers/pci/controller/pcie-brcmstb.c
++++ b/drivers/pci/controller/pcie-brcmstb.c
+@@ -1392,7 +1392,7 @@ static void brcm_pcie_remove_bus(struct pci_bus *bus)
+       struct subdev_regulators *sr = pcie->sr;
+       struct device *dev = &bus->dev;
+-      if (!sr)
++      if (!sr || !bus->parent || !pci_is_root_bus(bus->parent))
+               return;
+       if (regulator_bulk_disable(sr->num_supplies, sr->supplies))
+-- 
+2.39.5
+
diff --git a/queue-6.14/pci-brcmstb-set-generation-limit-before-pcie-link-up.patch b/queue-6.14/pci-brcmstb-set-generation-limit-before-pcie-link-up.patch
new file mode 100644 (file)
index 0000000..2efb273
--- /dev/null
@@ -0,0 +1,56 @@
+From f47809b0a85128a4716e0127d84aee1667587090 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Feb 2025 12:39:29 -0500
+Subject: PCI: brcmstb: Set generation limit before PCIe link up
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jim Quinlan <james.quinlan@broadcom.com>
+
+[ Upstream commit 72d36589c6b7bef6b30eb99fcb7082f72faca37f ]
+
+When the user elects to limit the PCIe generation via the appropriate
+devicetree property, apply the settings before the PCIe link up, not
+after.
+
+Fixes: c0452137034b ("PCI: brcmstb: Add Broadcom STB PCIe host controller driver")
+Signed-off-by: Jim Quinlan <james.quinlan@broadcom.com>
+Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/20250214173944.47506-2-james.quinlan@broadcom.com
+[kwilczynski: commit log]
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/pcie-brcmstb.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
+index e733a27dc8df8..b2d523e268b3c 100644
+--- a/drivers/pci/controller/pcie-brcmstb.c
++++ b/drivers/pci/controller/pcie-brcmstb.c
+@@ -1276,6 +1276,10 @@ static int brcm_pcie_start_link(struct brcm_pcie *pcie)
+       bool ssc_good = false;
+       int ret, i;
++      /* Limit the generation if specified */
++      if (pcie->gen)
++              brcm_pcie_set_gen(pcie, pcie->gen);
++
+       /* Unassert the fundamental reset */
+       ret = pcie->perst_set(pcie, 0);
+       if (ret)
+@@ -1302,9 +1306,6 @@ static int brcm_pcie_start_link(struct brcm_pcie *pcie)
+       brcm_config_clkreq(pcie);
+-      if (pcie->gen)
+-              brcm_pcie_set_gen(pcie, pcie->gen);
+-
+       if (pcie->ssc) {
+               ret = brcm_pcie_set_ssc(pcie);
+               if (ret == 0)
+-- 
+2.39.5
+
diff --git a/queue-6.14/pci-brcmstb-use-internal-register-to-change-link-cap.patch b/queue-6.14/pci-brcmstb-use-internal-register-to-change-link-cap.patch
new file mode 100644 (file)
index 0000000..beacb6a
--- /dev/null
@@ -0,0 +1,54 @@
+From 424ef1d7f0b3d7ed8b6884400aa4d6f172e09d5b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Feb 2025 12:39:30 -0500
+Subject: PCI: brcmstb: Use internal register to change link capability
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jim Quinlan <james.quinlan@broadcom.com>
+
+[ Upstream commit 0c97321e11e0e9e18546f828492758f6aaecec59 ]
+
+The driver has been mistakenly writing to a read-only (RO)
+configuration space register (PCI_EXP_LNKCAP) to change the
+PCIe link capability.
+
+Although harmless in this case, the proper write destination
+is an internal register that is reflected by PCI_EXP_LNKCAP.
+
+Thus, fix the brcm_pcie_set_gen() function to correctly update
+the link capability.
+
+Fixes: c0452137034b ("PCI: brcmstb: Add Broadcom STB PCIe host controller driver")
+Signed-off-by: Jim Quinlan <james.quinlan@broadcom.com>
+Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/20250214173944.47506-3-james.quinlan@broadcom.com
+[kwilczynski: commit log]
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/pcie-brcmstb.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
+index b2d523e268b3c..8b728c0f7f421 100644
+--- a/drivers/pci/controller/pcie-brcmstb.c
++++ b/drivers/pci/controller/pcie-brcmstb.c
+@@ -403,10 +403,10 @@ static int brcm_pcie_set_ssc(struct brcm_pcie *pcie)
+ static void brcm_pcie_set_gen(struct brcm_pcie *pcie, int gen)
+ {
+       u16 lnkctl2 = readw(pcie->base + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKCTL2);
+-      u32 lnkcap = readl(pcie->base + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKCAP);
++      u32 lnkcap = readl(pcie->base + PCIE_RC_CFG_PRIV1_LINK_CAPABILITY);
+       lnkcap = (lnkcap & ~PCI_EXP_LNKCAP_SLS) | gen;
+-      writel(lnkcap, pcie->base + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKCAP);
++      writel(lnkcap, pcie->base + PCIE_RC_CFG_PRIV1_LINK_CAPABILITY);
+       lnkctl2 = (lnkctl2 & ~0xf) | gen;
+       writew(lnkctl2, pcie->base + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKCTL2);
+-- 
+2.39.5
+
diff --git a/queue-6.14/pci-bwctrl-fix-pcie_bwctrl_select_speed-return-type.patch b/queue-6.14/pci-bwctrl-fix-pcie_bwctrl_select_speed-return-type.patch
new file mode 100644 (file)
index 0000000..52074d0
--- /dev/null
@@ -0,0 +1,50 @@
+From 2207118a2333ffc867db92718c82c06808e77407 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Mar 2025 18:31:03 +0200
+Subject: PCI/bwctrl: Fix pcie_bwctrl_select_speed() return type
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit 026e4bffb0af9632f5a0bbf8d594f2aace44cf07 ]
+
+pcie_bwctrl_select_speed() should take __fls() of the speed bit, not return
+it as a raw value. Instead of directly returning 2.5GT/s speed bit, simply
+assign the fallback speed (2.5GT/s) into supported_speeds variable to share
+the normal return path that calls pcie_supported_speeds2target_speed() to
+calculate __fls().
+
+This code path is not very likely to execute because
+pcie_get_supported_speeds() should provide valid ->supported_speeds but a
+spec violating device could fail to synthesize any speed in
+pcie_get_supported_speeds(). It could also happen in case the
+supported_speeds intersection is empty (also a violation of the current
+PCIe specs).
+
+Link: https://lore.kernel.org/r/20250321163103.5145-1-ilpo.jarvinen@linux.intel.com
+Fixes: de9a6c8d5dbf ("PCI/bwctrl: Add pcie_set_target_speed() to set PCIe Link Speed")
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pcie/bwctrl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pci/pcie/bwctrl.c b/drivers/pci/pcie/bwctrl.c
+index 0a5e7efbce2cc..58ba8142c9a31 100644
+--- a/drivers/pci/pcie/bwctrl.c
++++ b/drivers/pci/pcie/bwctrl.c
+@@ -113,7 +113,7 @@ static u16 pcie_bwctrl_select_speed(struct pci_dev *port, enum pci_bus_speed spe
+               up_read(&pci_bus_sem);
+       }
+       if (!supported_speeds)
+-              return PCI_EXP_LNKCAP2_SLS_2_5GB;
++              supported_speeds = PCI_EXP_LNKCAP2_SLS_2_5GB;
+       return pcie_supported_speeds2target_speed(supported_speeds & desired_speeds);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/pci-cadence-ep-fix-the-driver-to-send-msg-tlp-for-in.patch b/queue-6.14/pci-cadence-ep-fix-the-driver-to-send-msg-tlp-for-in.patch
new file mode 100644 (file)
index 0000000..c2c0f16
--- /dev/null
@@ -0,0 +1,67 @@
+From 36d48a34d1b1f026bed89c026d58cc43ac050ace Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 15 Feb 2025 00:57:24 +0800
+Subject: PCI: cadence-ep: Fix the driver to send MSG TLP for INTx without data
+ payload
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Hans Zhang <18255117159@163.com>
+
+[ Upstream commit 3ac47fbf4f6e8c3a7c3855fac68cc3246f90f850 ]
+
+Per the Cadence's "PCIe Controller IP for AX14" user guide, Version
+1.04, Section 9.1.7.1, "AXI Subordinate to PCIe Address Translation
+Registers", Table 9.4, the bit 16 of the AXI Subordinate Address
+(axi_s_awaddr) when set corresponds to MSG with data, and when not set,
+to MSG without data.
+
+However, the driver is currently doing the opposite and due to this,
+the INTx is never received on the host.
+
+So, fix the driver to reflect the documentation and also make INTx work.
+
+Fixes: 37dddf14f1ae ("PCI: cadence: Add EndPoint Controller driver for Cadence PCIe controller")
+Signed-off-by: Hans Zhang <18255117159@163.com>
+Signed-off-by: Hans Zhang <hans.zhang@cixtech.com>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/20250214165724.184599-1-18255117159@163.com
+[kwilczynski: commit log]
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/cadence/pcie-cadence-ep.c | 3 +--
+ drivers/pci/controller/cadence/pcie-cadence.h    | 2 +-
+ 2 files changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c
+index e0cc4560dfde7..0bf4cde34f517 100644
+--- a/drivers/pci/controller/cadence/pcie-cadence-ep.c
++++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c
+@@ -352,8 +352,7 @@ static void cdns_pcie_ep_assert_intx(struct cdns_pcie_ep *ep, u8 fn, u8 intx,
+       spin_unlock_irqrestore(&ep->lock, flags);
+       offset = CDNS_PCIE_NORMAL_MSG_ROUTING(MSG_ROUTING_LOCAL) |
+-               CDNS_PCIE_NORMAL_MSG_CODE(msg_code) |
+-               CDNS_PCIE_MSG_NO_DATA;
++               CDNS_PCIE_NORMAL_MSG_CODE(msg_code);
+       writel(0, ep->irq_cpu_addr + offset);
+ }
+diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
+index f5eeff834ec19..39ee9945c903e 100644
+--- a/drivers/pci/controller/cadence/pcie-cadence.h
++++ b/drivers/pci/controller/cadence/pcie-cadence.h
+@@ -246,7 +246,7 @@ struct cdns_pcie_rp_ib_bar {
+ #define CDNS_PCIE_NORMAL_MSG_CODE_MASK                GENMASK(15, 8)
+ #define CDNS_PCIE_NORMAL_MSG_CODE(code) \
+       (((code) << 8) & CDNS_PCIE_NORMAL_MSG_CODE_MASK)
+-#define CDNS_PCIE_MSG_NO_DATA                 BIT(16)
++#define CDNS_PCIE_MSG_DATA                    BIT(16)
+ struct cdns_pcie;
+-- 
+2.39.5
+
diff --git a/queue-6.14/pci-dwc-ep-return-enomem-for-allocation-failures.patch b/queue-6.14/pci-dwc-ep-return-enomem-for-allocation-failures.patch
new file mode 100644 (file)
index 0000000..ad8a3e3
--- /dev/null
@@ -0,0 +1,44 @@
+From 59437a80ad7b326c8746391b575bcb1f547a307a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Mar 2025 18:00:07 +0300
+Subject: PCI: dwc: ep: Return -ENOMEM for allocation failures
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 8189aa56dbed0bfb46b7b30d4d231f57ab17b3f4 ]
+
+If the bitmap or memory allocations fail, then dw_pcie_ep_init_registers()
+will incorrectly return a success.
+
+Return -ENOMEM instead.
+
+Fixes: 869bc5253406 ("PCI: dwc: ep: Fix DBI access failure for drivers requiring refclk from host")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+[kwilczynski: commit log]
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Reviewed-by: Krzysztof Wilczyński <kw@linux.com>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/36dcb6fc-f292-4dd5-bd45-a8c6f9dc3df7@stanley.mountain
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pcie-designware-ep.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
+index 8e07d432e74f2..e41479a9ca027 100644
+--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
++++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
+@@ -773,6 +773,7 @@ int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep)
+       if (ret)
+               return ret;
++      ret = -ENOMEM;
+       if (!ep->ib_window_map) {
+               ep->ib_window_map = devm_bitmap_zalloc(dev, pci->num_ib_windows,
+                                                      GFP_KERNEL);
+-- 
+2.39.5
+
diff --git a/queue-6.14/pci-endpoint-pci-epf-test-handle-endianness-properly.patch b/queue-6.14/pci-endpoint-pci-epf-test-handle-endianness-properly.patch
new file mode 100644 (file)
index 0000000..f6b9175
--- /dev/null
@@ -0,0 +1,351 @@
+From 0050734e99b6c67017b6f69c5c7a942f5921d9ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 27 Jan 2025 17:12:42 +0100
+Subject: PCI: endpoint: pci-epf-test: Handle endianness properly
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Niklas Cassel <cassel@kernel.org>
+
+[ Upstream commit 3c936e0ec0e412a3ce6072883da8682fb723d573 ]
+
+The struct pci_epf_test_reg is the actual data in pci-epf-test's test_reg
+BAR (usually BAR0), which the host uses to send commands (etc.), and which
+pci-epf-test uses to send back status codes.
+
+pci-epf-test currently reads and writes this data without any endianness
+conversion functions, which means that pci-epf-test is completely broken
+on big-endian endpoint systems.
+
+PCI devices are inherently little-endian, and the data stored in the PCI
+BARs should be in little-endian.
+
+Use endianness conversion functions when reading and writing data to
+struct pci_epf_test_reg so that pci-epf-test will behave correctly on
+big-endian endpoint systems.
+
+Fixes: 349e7a85b25f ("PCI: endpoint: functions: Add an EP function to test PCI")
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Niklas Cassel <cassel@kernel.org>
+Link: https://lore.kernel.org/r/20250127161242.104651-2-cassel@kernel.org
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/endpoint/functions/pci-epf-test.c | 126 ++++++++++--------
+ 1 file changed, 73 insertions(+), 53 deletions(-)
+
+diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
+index b94e205ae10b9..2409787cf56d9 100644
+--- a/drivers/pci/endpoint/functions/pci-epf-test.c
++++ b/drivers/pci/endpoint/functions/pci-epf-test.c
+@@ -66,17 +66,17 @@ struct pci_epf_test {
+ };
+ struct pci_epf_test_reg {
+-      u32     magic;
+-      u32     command;
+-      u32     status;
+-      u64     src_addr;
+-      u64     dst_addr;
+-      u32     size;
+-      u32     checksum;
+-      u32     irq_type;
+-      u32     irq_number;
+-      u32     flags;
+-      u32     caps;
++      __le32 magic;
++      __le32 command;
++      __le32 status;
++      __le64 src_addr;
++      __le64 dst_addr;
++      __le32 size;
++      __le32 checksum;
++      __le32 irq_type;
++      __le32 irq_number;
++      __le32 flags;
++      __le32 caps;
+ } __packed;
+ static struct pci_epf_header test_header = {
+@@ -324,13 +324,17 @@ static void pci_epf_test_copy(struct pci_epf_test *epf_test,
+       struct pci_epc *epc = epf->epc;
+       struct device *dev = &epf->dev;
+       struct pci_epc_map src_map, dst_map;
+-      u64 src_addr = reg->src_addr;
+-      u64 dst_addr = reg->dst_addr;
+-      size_t copy_size = reg->size;
++      u64 src_addr = le64_to_cpu(reg->src_addr);
++      u64 dst_addr = le64_to_cpu(reg->dst_addr);
++      size_t orig_size, copy_size;
+       ssize_t map_size = 0;
++      u32 flags = le32_to_cpu(reg->flags);
++      u32 status = 0;
+       void *copy_buf = NULL, *buf;
+-      if (reg->flags & FLAG_USE_DMA) {
++      orig_size = copy_size = le32_to_cpu(reg->size);
++
++      if (flags & FLAG_USE_DMA) {
+               if (!dma_has_cap(DMA_MEMCPY, epf_test->dma_chan_tx->device->cap_mask)) {
+                       dev_err(dev, "DMA controller doesn't support MEMCPY\n");
+                       ret = -EINVAL;
+@@ -350,7 +354,7 @@ static void pci_epf_test_copy(struct pci_epf_test *epf_test,
+                                     src_addr, copy_size, &src_map);
+               if (ret) {
+                       dev_err(dev, "Failed to map source address\n");
+-                      reg->status = STATUS_SRC_ADDR_INVALID;
++                      status = STATUS_SRC_ADDR_INVALID;
+                       goto free_buf;
+               }
+@@ -358,7 +362,7 @@ static void pci_epf_test_copy(struct pci_epf_test *epf_test,
+                                          dst_addr, copy_size, &dst_map);
+               if (ret) {
+                       dev_err(dev, "Failed to map destination address\n");
+-                      reg->status = STATUS_DST_ADDR_INVALID;
++                      status = STATUS_DST_ADDR_INVALID;
+                       pci_epc_mem_unmap(epc, epf->func_no, epf->vfunc_no,
+                                         &src_map);
+                       goto free_buf;
+@@ -367,7 +371,7 @@ static void pci_epf_test_copy(struct pci_epf_test *epf_test,
+               map_size = min_t(size_t, dst_map.pci_size, src_map.pci_size);
+               ktime_get_ts64(&start);
+-              if (reg->flags & FLAG_USE_DMA) {
++              if (flags & FLAG_USE_DMA) {
+                       ret = pci_epf_test_data_transfer(epf_test,
+                                       dst_map.phys_addr, src_map.phys_addr,
+                                       map_size, 0, DMA_MEM_TO_MEM);
+@@ -391,8 +395,8 @@ static void pci_epf_test_copy(struct pci_epf_test *epf_test,
+               map_size = 0;
+       }
+-      pci_epf_test_print_rate(epf_test, "COPY", reg->size, &start,
+-                              &end, reg->flags & FLAG_USE_DMA);
++      pci_epf_test_print_rate(epf_test, "COPY", orig_size, &start, &end,
++                              flags & FLAG_USE_DMA);
+ unmap:
+       if (map_size) {
+@@ -405,9 +409,10 @@ static void pci_epf_test_copy(struct pci_epf_test *epf_test,
+ set_status:
+       if (!ret)
+-              reg->status |= STATUS_COPY_SUCCESS;
++              status |= STATUS_COPY_SUCCESS;
+       else
+-              reg->status |= STATUS_COPY_FAIL;
++              status |= STATUS_COPY_FAIL;
++      reg->status = cpu_to_le32(status);
+ }
+ static void pci_epf_test_read(struct pci_epf_test *epf_test,
+@@ -423,9 +428,14 @@ static void pci_epf_test_read(struct pci_epf_test *epf_test,
+       struct pci_epc *epc = epf->epc;
+       struct device *dev = &epf->dev;
+       struct device *dma_dev = epf->epc->dev.parent;
+-      u64 src_addr = reg->src_addr;
+-      size_t src_size = reg->size;
++      u64 src_addr = le64_to_cpu(reg->src_addr);
++      size_t orig_size, src_size;
+       ssize_t map_size = 0;
++      u32 flags = le32_to_cpu(reg->flags);
++      u32 checksum = le32_to_cpu(reg->checksum);
++      u32 status = 0;
++
++      orig_size = src_size = le32_to_cpu(reg->size);
+       src_buf = kzalloc(src_size, GFP_KERNEL);
+       if (!src_buf) {
+@@ -439,12 +449,12 @@ static void pci_epf_test_read(struct pci_epf_test *epf_test,
+                                          src_addr, src_size, &map);
+               if (ret) {
+                       dev_err(dev, "Failed to map address\n");
+-                      reg->status = STATUS_SRC_ADDR_INVALID;
++                      status = STATUS_SRC_ADDR_INVALID;
+                       goto free_buf;
+               }
+               map_size = map.pci_size;
+-              if (reg->flags & FLAG_USE_DMA) {
++              if (flags & FLAG_USE_DMA) {
+                       dst_phys_addr = dma_map_single(dma_dev, buf, map_size,
+                                                      DMA_FROM_DEVICE);
+                       if (dma_mapping_error(dma_dev, dst_phys_addr)) {
+@@ -481,11 +491,11 @@ static void pci_epf_test_read(struct pci_epf_test *epf_test,
+               map_size = 0;
+       }
+-      pci_epf_test_print_rate(epf_test, "READ", reg->size, &start,
+-                              &end, reg->flags & FLAG_USE_DMA);
++      pci_epf_test_print_rate(epf_test, "READ", orig_size, &start, &end,
++                              flags & FLAG_USE_DMA);
+-      crc32 = crc32_le(~0, src_buf, reg->size);
+-      if (crc32 != reg->checksum)
++      crc32 = crc32_le(~0, src_buf, orig_size);
++      if (crc32 != checksum)
+               ret = -EIO;
+ unmap:
+@@ -497,9 +507,10 @@ static void pci_epf_test_read(struct pci_epf_test *epf_test,
+ set_status:
+       if (!ret)
+-              reg->status |= STATUS_READ_SUCCESS;
++              status |= STATUS_READ_SUCCESS;
+       else
+-              reg->status |= STATUS_READ_FAIL;
++              status |= STATUS_READ_FAIL;
++      reg->status = cpu_to_le32(status);
+ }
+ static void pci_epf_test_write(struct pci_epf_test *epf_test,
+@@ -514,9 +525,13 @@ static void pci_epf_test_write(struct pci_epf_test *epf_test,
+       struct pci_epc *epc = epf->epc;
+       struct device *dev = &epf->dev;
+       struct device *dma_dev = epf->epc->dev.parent;
+-      u64 dst_addr = reg->dst_addr;
+-      size_t dst_size = reg->size;
++      u64 dst_addr = le64_to_cpu(reg->dst_addr);
++      size_t orig_size, dst_size;
+       ssize_t map_size = 0;
++      u32 flags = le32_to_cpu(reg->flags);
++      u32 status = 0;
++
++      orig_size = dst_size = le32_to_cpu(reg->size);
+       dst_buf = kzalloc(dst_size, GFP_KERNEL);
+       if (!dst_buf) {
+@@ -524,7 +539,7 @@ static void pci_epf_test_write(struct pci_epf_test *epf_test,
+               goto set_status;
+       }
+       get_random_bytes(dst_buf, dst_size);
+-      reg->checksum = crc32_le(~0, dst_buf, dst_size);
++      reg->checksum = cpu_to_le32(crc32_le(~0, dst_buf, dst_size));
+       buf = dst_buf;
+       while (dst_size) {
+@@ -532,12 +547,12 @@ static void pci_epf_test_write(struct pci_epf_test *epf_test,
+                                          dst_addr, dst_size, &map);
+               if (ret) {
+                       dev_err(dev, "Failed to map address\n");
+-                      reg->status = STATUS_DST_ADDR_INVALID;
++                      status = STATUS_DST_ADDR_INVALID;
+                       goto free_buf;
+               }
+               map_size = map.pci_size;
+-              if (reg->flags & FLAG_USE_DMA) {
++              if (flags & FLAG_USE_DMA) {
+                       src_phys_addr = dma_map_single(dma_dev, buf, map_size,
+                                                      DMA_TO_DEVICE);
+                       if (dma_mapping_error(dma_dev, src_phys_addr)) {
+@@ -576,8 +591,8 @@ static void pci_epf_test_write(struct pci_epf_test *epf_test,
+               map_size = 0;
+       }
+-      pci_epf_test_print_rate(epf_test, "WRITE", reg->size, &start,
+-                              &end, reg->flags & FLAG_USE_DMA);
++      pci_epf_test_print_rate(epf_test, "WRITE", orig_size, &start, &end,
++                              flags & FLAG_USE_DMA);
+       /*
+        * wait 1ms inorder for the write to complete. Without this delay L3
+@@ -594,9 +609,10 @@ static void pci_epf_test_write(struct pci_epf_test *epf_test,
+ set_status:
+       if (!ret)
+-              reg->status |= STATUS_WRITE_SUCCESS;
++              status |= STATUS_WRITE_SUCCESS;
+       else
+-              reg->status |= STATUS_WRITE_FAIL;
++              status |= STATUS_WRITE_FAIL;
++      reg->status = cpu_to_le32(status);
+ }
+ static void pci_epf_test_raise_irq(struct pci_epf_test *epf_test,
+@@ -605,39 +621,42 @@ static void pci_epf_test_raise_irq(struct pci_epf_test *epf_test,
+       struct pci_epf *epf = epf_test->epf;
+       struct device *dev = &epf->dev;
+       struct pci_epc *epc = epf->epc;
+-      u32 status = reg->status | STATUS_IRQ_RAISED;
++      u32 status = le32_to_cpu(reg->status);
++      u32 irq_number = le32_to_cpu(reg->irq_number);
++      u32 irq_type = le32_to_cpu(reg->irq_type);
+       int count;
+       /*
+        * Set the status before raising the IRQ to ensure that the host sees
+        * the updated value when it gets the IRQ.
+        */
+-      WRITE_ONCE(reg->status, status);
++      status |= STATUS_IRQ_RAISED;
++      WRITE_ONCE(reg->status, cpu_to_le32(status));
+-      switch (reg->irq_type) {
++      switch (irq_type) {
+       case IRQ_TYPE_INTX:
+               pci_epc_raise_irq(epc, epf->func_no, epf->vfunc_no,
+                                 PCI_IRQ_INTX, 0);
+               break;
+       case IRQ_TYPE_MSI:
+               count = pci_epc_get_msi(epc, epf->func_no, epf->vfunc_no);
+-              if (reg->irq_number > count || count <= 0) {
++              if (irq_number > count || count <= 0) {
+                       dev_err(dev, "Invalid MSI IRQ number %d / %d\n",
+-                              reg->irq_number, count);
++                              irq_number, count);
+                       return;
+               }
+               pci_epc_raise_irq(epc, epf->func_no, epf->vfunc_no,
+-                                PCI_IRQ_MSI, reg->irq_number);
++                                PCI_IRQ_MSI, irq_number);
+               break;
+       case IRQ_TYPE_MSIX:
+               count = pci_epc_get_msix(epc, epf->func_no, epf->vfunc_no);
+-              if (reg->irq_number > count || count <= 0) {
++              if (irq_number > count || count <= 0) {
+                       dev_err(dev, "Invalid MSIX IRQ number %d / %d\n",
+-                              reg->irq_number, count);
++                              irq_number, count);
+                       return;
+               }
+               pci_epc_raise_irq(epc, epf->func_no, epf->vfunc_no,
+-                                PCI_IRQ_MSIX, reg->irq_number);
++                                PCI_IRQ_MSIX, irq_number);
+               break;
+       default:
+               dev_err(dev, "Failed to raise IRQ, unknown type\n");
+@@ -654,21 +673,22 @@ static void pci_epf_test_cmd_handler(struct work_struct *work)
+       struct device *dev = &epf->dev;
+       enum pci_barno test_reg_bar = epf_test->test_reg_bar;
+       struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar];
++      u32 irq_type = le32_to_cpu(reg->irq_type);
+-      command = READ_ONCE(reg->command);
++      command = le32_to_cpu(READ_ONCE(reg->command));
+       if (!command)
+               goto reset_handler;
+       WRITE_ONCE(reg->command, 0);
+       WRITE_ONCE(reg->status, 0);
+-      if ((READ_ONCE(reg->flags) & FLAG_USE_DMA) &&
++      if ((le32_to_cpu(READ_ONCE(reg->flags)) & FLAG_USE_DMA) &&
+           !epf_test->dma_supported) {
+               dev_err(dev, "Cannot transfer data using DMA\n");
+               goto reset_handler;
+       }
+-      if (reg->irq_type > IRQ_TYPE_MSIX) {
++      if (irq_type > IRQ_TYPE_MSIX) {
+               dev_err(dev, "Failed to detect IRQ type\n");
+               goto reset_handler;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/pci-fix-bar-resizing-when-vf-bars-are-assigned.patch b/queue-6.14/pci-fix-bar-resizing-when-vf-bars-are-assigned.patch
new file mode 100644 (file)
index 0000000..126a6ba
--- /dev/null
@@ -0,0 +1,62 @@
+From 90fc6e30ea79a190c7171a0a331933cb2d3f9c97 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Mar 2025 16:28:37 +0200
+Subject: PCI: Fix BAR resizing when VF BARs are assigned
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit 9ec19bfa78bd788945e2445b09de7b4482dee432 ]
+
+__resource_resize_store() attempts to release all resources of the device
+before attempting the resize. The loop, however, only covers standard BARs
+(< PCI_STD_NUM_BARS). If a device has VF BARs that are assigned,
+pci_reassign_bridge_resources() finds the bridge window still has some
+assigned child resources and returns -NOENT which makes
+pci_resize_resource() to detect an error and abort the resize.
+
+Change the release loop to cover all resources up to VF BARs which allows
+the resize operation to release the bridge windows and attempt to assigned
+them again with the different size.
+
+If SR-IOV is enabled, disallow resize as it requires releasing also IOV
+resources.
+
+Link: https://lore.kernel.org/r/20250320142837.8027-1-ilpo.jarvinen@linux.intel.com
+Fixes: 91fa127794ac ("PCI: Expose PCIe Resizable BAR support via sysfs")
+Reported-by: Michał Winiarski <michal.winiarski@intel.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pci-sysfs.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
+index b46ce1a2c5542..0e7eb2a42d88d 100644
+--- a/drivers/pci/pci-sysfs.c
++++ b/drivers/pci/pci-sysfs.c
+@@ -1556,7 +1556,7 @@ static ssize_t __resource_resize_store(struct device *dev, int n,
+               return -EINVAL;
+       device_lock(dev);
+-      if (dev->driver) {
++      if (dev->driver || pci_num_vf(pdev)) {
+               ret = -EBUSY;
+               goto unlock;
+       }
+@@ -1578,7 +1578,7 @@ static ssize_t __resource_resize_store(struct device *dev, int n,
+       pci_remove_resource_files(pdev);
+-      for (i = 0; i < PCI_STD_NUM_BARS; i++) {
++      for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) {
+               if (pci_resource_len(pdev, i) &&
+                   pci_resource_flags(pdev, i) == flags)
+                       pci_release_resource(pdev, i);
+-- 
+2.39.5
+
diff --git a/queue-6.14/pci-fix-null-dereference-in-sr-iov-vf-creation-error.patch b/queue-6.14/pci-fix-null-dereference-in-sr-iov-vf-creation-error.patch
new file mode 100644 (file)
index 0000000..15f1342
--- /dev/null
@@ -0,0 +1,112 @@
+From f3fd07228b519149bfd48dc810ad78d54f245ef5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Mar 2025 10:45:24 +0200
+Subject: PCI: Fix NULL dereference in SR-IOV VF creation error path
+
+From: Shay Drory <shayd@nvidia.com>
+
+[ Upstream commit 04d50d953ab46d96b0b32d5ad955fceaa28622db ]
+
+Clean up when virtfn setup fails to prevent NULL pointer dereference
+during device removal. The kernel oops below occurred due to incorrect
+error handling flow when pci_setup_device() fails.
+
+Add pci_iov_scan_device(), which handles virtfn allocation and setup and
+cleans up if pci_setup_device() fails, so pci_iov_add_virtfn() doesn't need
+to call pci_stop_and_remove_bus_device().  This prevents accessing
+partially initialized virtfn devices during removal.
+
+  BUG: kernel NULL pointer dereference, address: 00000000000000d0
+  RIP: 0010:device_del+0x3d/0x3d0
+  Call Trace:
+   pci_remove_bus_device+0x7c/0x100
+   pci_iov_add_virtfn+0xfa/0x200
+   sriov_enable+0x208/0x420
+   mlx5_core_sriov_configure+0x6a/0x160 [mlx5_core]
+   sriov_numvfs_store+0xae/0x1a0
+
+Link: https://lore.kernel.org/r/20250310084524.599225-1-shayd@nvidia.com
+Fixes: e3f30d563a38 ("PCI: Make pci_destroy_dev() concurrent safe")
+Signed-off-by: Shay Drory <shayd@nvidia.com>
+[bhelgaas: commit log, return ERR_PTR(-ENOMEM) directly]
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Cc: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/iov.c | 48 +++++++++++++++++++++++++++++++++--------------
+ 1 file changed, 34 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
+index 9e4770cdd4d5a..a964c66b42950 100644
+--- a/drivers/pci/iov.c
++++ b/drivers/pci/iov.c
+@@ -285,23 +285,16 @@ const struct attribute_group sriov_vf_dev_attr_group = {
+       .is_visible = sriov_vf_attrs_are_visible,
+ };
+-int pci_iov_add_virtfn(struct pci_dev *dev, int id)
++static struct pci_dev *pci_iov_scan_device(struct pci_dev *dev, int id,
++                                         struct pci_bus *bus)
+ {
+-      int i;
+-      int rc = -ENOMEM;
+-      u64 size;
+-      struct pci_dev *virtfn;
+-      struct resource *res;
+       struct pci_sriov *iov = dev->sriov;
+-      struct pci_bus *bus;
+-
+-      bus = virtfn_add_bus(dev->bus, pci_iov_virtfn_bus(dev, id));
+-      if (!bus)
+-              goto failed;
++      struct pci_dev *virtfn;
++      int rc;
+       virtfn = pci_alloc_dev(bus);
+       if (!virtfn)
+-              goto failed0;
++              return ERR_PTR(-ENOMEM);
+       virtfn->devfn = pci_iov_virtfn_devfn(dev, id);
+       virtfn->vendor = dev->vendor;
+@@ -314,8 +307,35 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id)
+               pci_read_vf_config_common(virtfn);
+       rc = pci_setup_device(virtfn);
+-      if (rc)
+-              goto failed1;
++      if (rc) {
++              pci_dev_put(dev);
++              pci_bus_put(virtfn->bus);
++              kfree(virtfn);
++              return ERR_PTR(rc);
++      }
++
++      return virtfn;
++}
++
++int pci_iov_add_virtfn(struct pci_dev *dev, int id)
++{
++      struct pci_bus *bus;
++      struct pci_dev *virtfn;
++      struct resource *res;
++      int rc, i;
++      u64 size;
++
++      bus = virtfn_add_bus(dev->bus, pci_iov_virtfn_bus(dev, id));
++      if (!bus) {
++              rc = -ENOMEM;
++              goto failed;
++      }
++
++      virtfn = pci_iov_scan_device(dev, id, bus);
++      if (IS_ERR(virtfn)) {
++              rc = PTR_ERR(virtfn);
++              goto failed0;
++      }
+       virtfn->dev.parent = dev->dev.parent;
+       virtfn->multifunction = 0;
+-- 
+2.39.5
+
diff --git a/queue-6.14/pci-histb-fix-an-error-handling-path-in-histb_pcie_p.patch b/queue-6.14/pci-histb-fix-an-error-handling-path-in-histb_pcie_p.patch
new file mode 100644 (file)
index 0000000..b3bc5a1
--- /dev/null
@@ -0,0 +1,71 @@
+From 36963495a6f647b94f8611a6ca80eaaa1866a304 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 Mar 2025 19:42:54 +0100
+Subject: PCI: histb: Fix an error handling path in histb_pcie_probe()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit b36fb50701619efca5f5450b355d42575cf532ed ]
+
+If an error occurs after a successful phy_init() call, then phy_exit()
+should be called.
+
+Add the missing call, as already done in the remove function.
+
+Fixes: bbd11bddb398 ("PCI: hisi: Add HiSilicon STB SoC PCIe controller driver")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+[kwilczynski: remove unnecessary hipcie->phy NULL check from
+histb_pcie_probe() and squash a patch that removes similar NULL
+check for hipcie-phy from histb_pcie_remove() from
+https://lore.kernel.org/linux-pci/c369b5d25e17a44984ae5a889ccc28a59a0737f7.1742058005.git.christophe.jaillet@wanadoo.fr]
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Link: https://lore.kernel.org/r/8301fc15cdea5d2dac21f57613e8e6922fb1ad95.1740854531.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pcie-histb.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pcie-histb.c b/drivers/pci/controller/dwc/pcie-histb.c
+index 615a0e3e6d7eb..1f2f4c28a9495 100644
+--- a/drivers/pci/controller/dwc/pcie-histb.c
++++ b/drivers/pci/controller/dwc/pcie-histb.c
+@@ -409,16 +409,21 @@ static int histb_pcie_probe(struct platform_device *pdev)
+       ret = histb_pcie_host_enable(pp);
+       if (ret) {
+               dev_err(dev, "failed to enable host\n");
+-              return ret;
++              goto err_exit_phy;
+       }
+       ret = dw_pcie_host_init(pp);
+       if (ret) {
+               dev_err(dev, "failed to initialize host\n");
+-              return ret;
++              goto err_exit_phy;
+       }
+       return 0;
++
++err_exit_phy:
++      phy_exit(hipcie->phy);
++
++      return ret;
+ }
+ static void histb_pcie_remove(struct platform_device *pdev)
+@@ -427,8 +432,7 @@ static void histb_pcie_remove(struct platform_device *pdev)
+       histb_pcie_host_disable(hipcie);
+-      if (hipcie->phy)
+-              phy_exit(hipcie->phy);
++      phy_exit(hipcie->phy);
+ }
+ static const struct of_device_id histb_pcie_of_match[] = {
+-- 
+2.39.5
+
diff --git a/queue-6.14/pci-mediatek-gen3-configure-pbus_csr-registers-for-e.patch b/queue-6.14/pci-mediatek-gen3-configure-pbus_csr-registers-for-e.patch
new file mode 100644 (file)
index 0000000..18f4aa2
--- /dev/null
@@ -0,0 +1,90 @@
+From 91bc769b064d6c3c272a6695b67b95e5ac0f2341 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Feb 2025 09:04:07 +0100
+Subject: PCI: mediatek-gen3: Configure PBUS_CSR registers for EN7581 SoC
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit 249b78298078448a699c39356d27d8183af4b281 ]
+
+Configure PBus base address and address mask to allow the hw
+to detect if a given address is accessible on PCIe controller.
+
+Fixes: f6ab898356dd ("PCI: mediatek-gen3: Add Airoha EN7581 support")
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://lore.kernel.org/r/20250225-en7581-pcie-pbus-csr-v4-2-24324382424a@kernel.org
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/pcie-mediatek-gen3.c | 28 ++++++++++++++++++++-
+ 1 file changed, 27 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c
+index aa24ac9aaecc7..d0cc7f3b4b520 100644
+--- a/drivers/pci/controller/pcie-mediatek-gen3.c
++++ b/drivers/pci/controller/pcie-mediatek-gen3.c
+@@ -15,6 +15,7 @@
+ #include <linux/irqchip/chained_irq.h>
+ #include <linux/irqdomain.h>
+ #include <linux/kernel.h>
++#include <linux/mfd/syscon.h>
+ #include <linux/module.h>
+ #include <linux/msi.h>
+ #include <linux/of_device.h>
+@@ -24,6 +25,7 @@
+ #include <linux/platform_device.h>
+ #include <linux/pm_domain.h>
+ #include <linux/pm_runtime.h>
++#include <linux/regmap.h>
+ #include <linux/reset.h>
+ #include "../pci.h"
+@@ -930,9 +932,13 @@ static int mtk_pcie_parse_port(struct mtk_gen3_pcie *pcie)
+ static int mtk_pcie_en7581_power_up(struct mtk_gen3_pcie *pcie)
+ {
++      struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
+       struct device *dev = pcie->dev;
++      struct resource_entry *entry;
++      struct regmap *pbus_regmap;
++      u32 val, args[2], size;
++      resource_size_t addr;
+       int err;
+-      u32 val;
+       /*
+        * The controller may have been left out of reset by the bootloader
+@@ -945,6 +951,26 @@ static int mtk_pcie_en7581_power_up(struct mtk_gen3_pcie *pcie)
+       /* Wait for the time needed to complete the reset lines assert. */
+       msleep(PCIE_EN7581_RESET_TIME_MS);
++      /*
++       * Configure PBus base address and base address mask to allow the
++       * hw to detect if a given address is accessible on PCIe controller.
++       */
++      pbus_regmap = syscon_regmap_lookup_by_phandle_args(dev->of_node,
++                                                         "mediatek,pbus-csr",
++                                                         ARRAY_SIZE(args),
++                                                         args);
++      if (IS_ERR(pbus_regmap))
++              return PTR_ERR(pbus_regmap);
++
++      entry = resource_list_first_type(&host->windows, IORESOURCE_MEM);
++      if (!entry)
++              return -ENODEV;
++
++      addr = entry->res->start - entry->offset;
++      regmap_write(pbus_regmap, args[0], lower_32_bits(addr));
++      size = lower_32_bits(resource_size(entry->res));
++      regmap_write(pbus_regmap, args[1], GENMASK(31, __fls(size)));
++
+       /*
+        * Unlike the other MediaTek Gen3 controllers, the Airoha EN7581
+        * requires PHY initialization and power-on before PHY reset deassert.
+-- 
+2.39.5
+
diff --git a/queue-6.14/pci-pciehp-don-t-enable-hpie-when-resuming-in-poll-m.patch b/queue-6.14/pci-pciehp-don-t-enable-hpie-when-resuming-in-poll-m.patch
new file mode 100644 (file)
index 0000000..4cecbf1
--- /dev/null
@@ -0,0 +1,49 @@
+From 70aff1ff2d96bd3c85487c3db4d4e44c876ba7d6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Mar 2025 18:21:14 +0200
+Subject: PCI: pciehp: Don't enable HPIE when resuming in poll mode
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit 527664f738afb6f2c58022cd35e63801e5dc7aec ]
+
+PCIe hotplug can operate in poll mode without interrupt handlers using a
+polling kthread only.  eb34da60edee ("PCI: pciehp: Disable hotplug
+interrupt during suspend") failed to consider that and enables HPIE
+(Hot-Plug Interrupt Enable) unconditionally when resuming the Port.
+
+Only set HPIE if non-poll mode is in use. This makes
+pcie_enable_interrupt() match how pcie_enable_notification() already
+handles HPIE.
+
+Link: https://lore.kernel.org/r/20250321162114.3939-1-ilpo.jarvinen@linux.intel.com
+Fixes: eb34da60edee ("PCI: pciehp: Disable hotplug interrupt during suspend")
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Lukas Wunner <lukas@wunner.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/hotplug/pciehp_hpc.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
+index bb5a8d9f03ad9..28ab393af1c04 100644
+--- a/drivers/pci/hotplug/pciehp_hpc.c
++++ b/drivers/pci/hotplug/pciehp_hpc.c
+@@ -842,7 +842,9 @@ void pcie_enable_interrupt(struct controller *ctrl)
+ {
+       u16 mask;
+-      mask = PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_DLLSCE;
++      mask = PCI_EXP_SLTCTL_DLLSCE;
++      if (!pciehp_poll_mode)
++              mask |= PCI_EXP_SLTCTL_HPIE;
+       pcie_write_cmd(ctrl, mask, mask);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/pci-portdrv-only-disable-pciehp-interrupts-early-whe.patch b/queue-6.14/pci-portdrv-only-disable-pciehp-interrupts-early-whe.patch
new file mode 100644 (file)
index 0000000..81d1cfc
--- /dev/null
@@ -0,0 +1,60 @@
+From 88fc452ed913cffb7ee8c53422ac581bfbcf08ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Mar 2025 10:36:30 +0800
+Subject: PCI/portdrv: Only disable pciehp interrupts early when needed
+
+From: Feng Tang <feng.tang@linux.alibaba.com>
+
+[ Upstream commit 9d7db4db19827380e225914618c0c1bf435ed2f5 ]
+
+Firmware developers reported that Linux issues two PCIe hotplug commands in
+very short intervals on an ARM server, which doesn't comply with the PCIe
+spec.  According to PCIe r6.1, sec 6.7.3.2, if the Command Completed event
+is supported, software must wait for a command to complete or wait at
+least 1 second before sending a new command.
+
+In the failure case, the first PCIe hotplug command is from
+get_port_device_capability(), which sends a command to disable PCIe hotplug
+interrupts without waiting for its completion, and the second command comes
+from pcie_enable_notification() of pciehp driver, which enables hotplug
+interrupts again.
+
+Fix this by only disabling the hotplug interrupts when the pciehp driver is
+not enabled.
+
+Link: https://lore.kernel.org/r/20250303023630.78397-1-feng.tang@linux.alibaba.com
+Fixes: 2bd50dd800b5 ("PCI: PCIe: Disable PCIe port services during port initialization")
+Suggested-by: Lukas Wunner <lukas@wunner.de>
+Signed-off-by: Feng Tang <feng.tang@linux.alibaba.com>
+[bhelgaas: commit log]
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Lukas Wunner <lukas@wunner.de>
+Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pcie/portdrv.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/pci/pcie/portdrv.c b/drivers/pci/pcie/portdrv.c
+index 02e73099bad05..e8318fd5f6ed5 100644
+--- a/drivers/pci/pcie/portdrv.c
++++ b/drivers/pci/pcie/portdrv.c
+@@ -228,10 +228,12 @@ static int get_port_device_capability(struct pci_dev *dev)
+               /*
+                * Disable hot-plug interrupts in case they have been enabled
+-               * by the BIOS and the hot-plug service driver is not loaded.
++               * by the BIOS and the hot-plug service driver won't be loaded
++               * to handle them.
+                */
+-              pcie_capability_clear_word(dev, PCI_EXP_SLTCTL,
+-                        PCI_EXP_SLTCTL_CCIE | PCI_EXP_SLTCTL_HPIE);
++              if (!IS_ENABLED(CONFIG_HOTPLUG_PCI_PCIE))
++                      pcie_capability_clear_word(dev, PCI_EXP_SLTCTL,
++                              PCI_EXP_SLTCTL_CCIE | PCI_EXP_SLTCTL_HPIE);
+       }
+ #ifdef CONFIG_PCIEAER
+-- 
+2.39.5
+
diff --git a/queue-6.14/pci-remove-add_align-overwrite-unrelated-to-size0.patch b/queue-6.14/pci-remove-add_align-overwrite-unrelated-to-size0.patch
new file mode 100644 (file)
index 0000000..8612001
--- /dev/null
@@ -0,0 +1,45 @@
+From b5970add3fe71a1950687f8f69fac5815703be5a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Dec 2024 19:56:08 +0200
+Subject: PCI: Remove add_align overwrite unrelated to size0
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit d06cc1e3809040e8250f69a4c656e3717e6b963c ]
+
+Commit 566f1dd52816 ("PCI: Relax bridge window tail sizing rules")
+relaxed bridge window tail alignment rule for the non-optional part
+(size0, no add_size/add_align). The change, however, also overwrote
+add_align, which is only related to case where optional size1 related
+entry is added into realloc head.
+
+Correct this by removing the add_align overwrite.
+
+Link: https://lore.kernel.org/r/20241216175632.4175-2-ilpo.jarvinen@linux.intel.com
+Fixes: 566f1dd52816 ("PCI: Relax bridge window tail sizing rules")
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Tested-by: Xiaochun Lee <lixc17@lenovo.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/setup-bus.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
+index 3d876d493faf2..3a1fcaad142a4 100644
+--- a/drivers/pci/setup-bus.c
++++ b/drivers/pci/setup-bus.c
+@@ -1149,7 +1149,6 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
+               min_align = 1ULL << (max_order + __ffs(SZ_1M));
+               min_align = max(min_align, win_align);
+               size0 = calculate_memsize(size, min_size, 0, 0, resource_size(b_res), win_align);
+-              add_align = win_align;
+               pci_info(bus->self, "bridge window %pR to %pR requires relaxed alignment rules\n",
+                        b_res, &bus->busn_res);
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/pci-remove-stray-put_device-in-pci_register_host_bri.patch b/queue-6.14/pci-remove-stray-put_device-in-pci_register_host_bri.patch
new file mode 100644 (file)
index 0000000..fa19c38
--- /dev/null
@@ -0,0 +1,41 @@
+From f3b0526a33ac038a6ea908aef08d738bc8582754 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Mar 2025 11:46:34 +0300
+Subject: PCI: Remove stray put_device() in pci_register_host_bridge()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 6e8d06e5096c80cbf41313b4a204f43071ca42be ]
+
+This put_device() was accidentally left over from when we changed the code
+from using device_register() to calling device_add().  Delete it.
+
+Link: https://lore.kernel.org/r/55b24870-89fb-4c91-b85d-744e35db53c2@stanley.mountain
+Fixes: 9885440b16b8 ("PCI: Fix pci_host_bridge struct device release/free handling")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/probe.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
+index 246744d8d268a..0154b48bfbd7b 100644
+--- a/drivers/pci/probe.c
++++ b/drivers/pci/probe.c
+@@ -996,10 +996,9 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
+       /* Temporarily move resources off the list */
+       list_splice_init(&bridge->windows, &resources);
+       err = device_add(&bridge->dev);
+-      if (err) {
+-              put_device(&bridge->dev);
++      if (err)
+               goto free;
+-      }
++
+       bus->bridge = get_device(&bridge->dev);
+       device_enable_async_suspend(bus->bridge);
+       pci_set_bus_of_node(bus);
+-- 
+2.39.5
+
diff --git a/queue-6.14/pci-simplify-size1-assignment-logic.patch b/queue-6.14/pci-simplify-size1-assignment-logic.patch
new file mode 100644 (file)
index 0000000..58c7540
--- /dev/null
@@ -0,0 +1,77 @@
+From 4f9a0f857946025ee0ed8c2006f5774c662ad8de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Dec 2024 19:56:10 +0200
+Subject: PCI: Simplify size1 assignment logic
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit a55bf64b30e4ee04c8f690e2c3d0924beb7fbd62 ]
+
+In pbus_size_io() and pbus_size_mem(), a complex ?: operation is performed
+to set size1.  Decompose this so it's easier to read.
+
+In the case of pbus_size_mem(), simply initializing size1 to zero ensures
+the size1 checks work as expected.
+
+Link: https://lore.kernel.org/r/20241216175632.4175-4-ilpo.jarvinen@linux.intel.com
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Tested-by: Xiaochun Lee <lixc17@lenovo.com>
+Stable-dep-of: 67f9085596ee ("PCI: Allow relaxed bridge window tail sizing for optional resources")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/setup-bus.c | 21 ++++++++++++++-------
+ 1 file changed, 14 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
+index 3a1fcaad142a4..d9f129a7735a5 100644
+--- a/drivers/pci/setup-bus.c
++++ b/drivers/pci/setup-bus.c
+@@ -927,9 +927,14 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
+       size0 = calculate_iosize(size, min_size, size1, 0, 0,
+                       resource_size(b_res), min_align);
+-      size1 = (!realloc_head || (realloc_head && !add_size && !children_add_size)) ? size0 :
+-              calculate_iosize(size, min_size, size1, add_size, children_add_size,
+-                      resource_size(b_res), min_align);
++
++      size1 = size0;
++      if (realloc_head && (add_size > 0 || children_add_size > 0)) {
++              size1 = calculate_iosize(size, min_size, size1, add_size,
++                                       children_add_size, resource_size(b_res),
++                                       min_align);
++      }
++
+       if (!size0 && !size1) {
+               if (bus->self && (b_res->start || b_res->end))
+                       pci_info(bus->self, "disabling bridge window %pR to %pR (unused)\n",
+@@ -1058,7 +1063,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
+                        struct list_head *realloc_head)
+ {
+       struct pci_dev *dev;
+-      resource_size_t min_align, win_align, align, size, size0, size1;
++      resource_size_t min_align, win_align, align, size, size0, size1 = 0;
+       resource_size_t aligns[24]; /* Alignments from 1MB to 8TB */
+       int order, max_order;
+       struct resource *b_res = find_bus_resource_of_type(bus,
+@@ -1153,9 +1158,11 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
+                        b_res, &bus->busn_res);
+       }
+-      size1 = (!realloc_head || (realloc_head && !add_size && !children_add_size)) ? size0 :
+-              calculate_memsize(size, min_size, add_size, children_add_size,
+-                              resource_size(b_res), add_align);
++      if (realloc_head && (add_size > 0 || children_add_size > 0)) {
++              size1 = calculate_memsize(size, min_size, add_size, children_add_size,
++                                        resource_size(b_res), add_align);
++      }
++
+       if (!size0 && !size1) {
+               if (bus->self && (b_res->start || b_res->end))
+                       pci_info(bus->self, "disabling bridge window %pR to %pR (unused)\n",
+-- 
+2.39.5
+
diff --git a/queue-6.14/pci-use-downstream-bridges-for-distributing-resource.patch b/queue-6.14/pci-use-downstream-bridges-for-distributing-resource.patch
new file mode 100644 (file)
index 0000000..105c2e1
--- /dev/null
@@ -0,0 +1,96 @@
+From 1c7bc6a41e1651f9098c6a9ae249aeb796b05194 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Dec 2024 10:24:57 +0800
+Subject: PCI: Use downstream bridges for distributing resources
+
+From: Kai-Heng Feng <kaihengf@nvidia.com>
+
+[ Upstream commit 1a596ad00ffe9b37fc60a93cbdd4daead3bf95f3 ]
+
+7180c1d08639 ("PCI: Distribute available resources for root buses, too")
+breaks BAR assignment on some devices:
+
+  pci 0006:03:00.0: BAR 0 [mem 0x6300c0000000-0x6300c1ffffff 64bit pref]: assigned
+  pci 0006:03:00.1: BAR 0 [mem 0x6300c2000000-0x6300c3ffffff 64bit pref]: assigned
+  pci 0006:03:00.2: BAR 0 [mem size 0x00800000 64bit pref]: can't assign; no space
+  pci 0006:03:00.0: VF BAR 0 [mem size 0x02000000 64bit pref]: can't assign; no space
+  pci 0006:03:00.1: VF BAR 0 [mem size 0x02000000 64bit pref]: can't assign; no space
+
+The apertures of domain 0006 before 7180c1d08639:
+
+  6300c0000000-63ffffffffff : PCI Bus 0006:00
+    6300c0000000-6300c9ffffff : PCI Bus 0006:01
+      6300c0000000-6300c9ffffff : PCI Bus 0006:02        # 160MB
+        6300c0000000-6300c8ffffff : PCI Bus 0006:03      #   144MB
+          6300c0000000-6300c1ffffff : 0006:03:00.0       #     32MB
+          6300c2000000-6300c3ffffff : 0006:03:00.1       #     32MB
+          6300c4000000-6300c47fffff : 0006:03:00.2       #      8MB
+          6300c4800000-6300c67fffff : 0006:03:00.0       #     32MB
+          6300c6800000-6300c87fffff : 0006:03:00.1       #     32MB
+        6300c9000000-6300c9bfffff : PCI Bus 0006:04      #    12MB
+          6300c9000000-6300c9bfffff : PCI Bus 0006:05    #    12MB
+            6300c9000000-6300c91fffff : PCI Bus 0006:06  #      2MB
+            6300c9200000-6300c93fffff : PCI Bus 0006:07  #      2MB
+            6300c9400000-6300c95fffff : PCI Bus 0006:08  #      2MB
+            6300c9600000-6300c97fffff : PCI Bus 0006:09  #      2MB
+
+After 7180c1d08639:
+
+  6300c0000000-63ffffffffff : PCI Bus 0006:00
+    6300c0000000-6300c9ffffff : PCI Bus 0006:01
+      6300c0000000-6300c9ffffff : PCI Bus 0006:02        # 160MB
+        6300c0000000-6300c43fffff : PCI Bus 0006:03      #    68MB
+          6300c0000000-6300c1ffffff : 0006:03:00.0       #      32MB
+          6300c2000000-6300c3ffffff : 0006:03:00.1       #      32MB
+              --- no space ---      : 0006:03:00.2       #       8MB
+              --- no space ---      : 0006:03:00.0       #      32MB
+              --- no space ---      : 0006:03:00.1       #      32MB
+        6300c4400000-6300c4dfffff : PCI Bus 0006:04      #    10MB
+          6300c4400000-6300c4dfffff : PCI Bus 0006:05    #      10MB
+            6300c4400000-6300c45fffff : PCI Bus 0006:06  #        2MB
+            6300c4600000-6300c47fffff : PCI Bus 0006:07  #        2MB
+            6300c4800000-6300c49fffff : PCI Bus 0006:08  #        2MB
+            6300c4a00000-6300c4bfffff : PCI Bus 0006:09  #        2MB
+
+We can see that the window to 0006:03 gets shrunken too much and 0006:04
+eats away the window for 0006:03:00.2.
+
+The offending commit distributes the upstream bridge's resources multiple
+times to every downstream bridge, hence makes the aperture smaller than
+desired because calculation of io_per_b, mmio_per_b and mmio_pref_per_b
+becomes incorrect.
+
+Instead, distribute downstream bridges' own resources to resolve the issue.
+
+Link: https://lore.kernel.org/r/20241204022457.51322-1-kaihengf@nvidia.com
+Fixes: 7180c1d08639 ("PCI: Distribute available resources for root buses, too")
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=219540
+Signed-off-by: Kai-Heng Feng <kaihengf@nvidia.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Tested-by: Chia-Lin Kao (AceLan) <acelan.kao@canonical.com>
+Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Cc: Carol Soto <csoto@nvidia.com>
+Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Chris Chiu <chris.chiu@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/setup-bus.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
+index 5e00cecf1f1af..3d876d493faf2 100644
+--- a/drivers/pci/setup-bus.c
++++ b/drivers/pci/setup-bus.c
+@@ -2102,8 +2102,7 @@ pci_root_bus_distribute_available_resources(struct pci_bus *bus,
+                * in case of root bus.
+                */
+               if (bridge && pci_bridge_resources_not_assigned(dev))
+-                      pci_bridge_distribute_available_resources(bridge,
+-                                                                add_list);
++                      pci_bridge_distribute_available_resources(dev, add_list);
+               else
+                       pci_root_bus_distribute_available_resources(b, add_list);
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/pci-xilinx-cpm-fix-irq-domain-leak-in-error-path-of-.patch b/queue-6.14/pci-xilinx-cpm-fix-irq-domain-leak-in-error-path-of-.patch
new file mode 100644 (file)
index 0000000..6670ce1
--- /dev/null
@@ -0,0 +1,65 @@
+From 18ffd29ea42f8dd7377e1b2e70b4e28194089ded Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Feb 2025 21:20:22 +0530
+Subject: PCI: xilinx-cpm: Fix IRQ domain leak in error path of probe
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Thippeswamy Havalige <thippeswamy.havalige@amd.com>
+
+[ Upstream commit 57b0302240741e73fe51f88404b3866e0d2933ad ]
+
+The IRQ domain allocated for the PCIe controller is not freed if
+resource_list_first_type() returns NULL, leading to a resource leak.
+
+This fix ensures properly cleaning up the allocated IRQ domain in
+the error path.
+
+Fixes: 49e427e6bdd1 ("Merge branch 'pci/host-probe-refactor'")
+Signed-off-by: Thippeswamy Havalige <thippeswamy.havalige@amd.com>
+[kwilczynski: added missing Fixes: tag, refactored to use one of the goto labels]
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Link: https://lore.kernel.org/r/20250224155025.782179-2-thippeswamy.havalige@amd.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/pcie-xilinx-cpm.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/pci/controller/pcie-xilinx-cpm.c b/drivers/pci/controller/pcie-xilinx-cpm.c
+index 81e8bfae53d00..dc8ecdbee56c8 100644
+--- a/drivers/pci/controller/pcie-xilinx-cpm.c
++++ b/drivers/pci/controller/pcie-xilinx-cpm.c
+@@ -583,15 +583,17 @@ static int xilinx_cpm_pcie_probe(struct platform_device *pdev)
+               return err;
+       bus = resource_list_first_type(&bridge->windows, IORESOURCE_BUS);
+-      if (!bus)
+-              return -ENODEV;
++      if (!bus) {
++              err = -ENODEV;
++              goto err_free_irq_domains;
++      }
+       port->variant = of_device_get_match_data(dev);
+       err = xilinx_cpm_pcie_parse_dt(port, bus->res);
+       if (err) {
+               dev_err(dev, "Parsing DT failed\n");
+-              goto err_parse_dt;
++              goto err_free_irq_domains;
+       }
+       xilinx_cpm_pcie_init_port(port);
+@@ -615,7 +617,7 @@ static int xilinx_cpm_pcie_probe(struct platform_device *pdev)
+       xilinx_cpm_free_interrupts(port);
+ err_setup_irq:
+       pci_ecam_free(port->cfg);
+-err_parse_dt:
++err_free_irq_domains:
+       xilinx_cpm_free_irq_domains(port);
+       return err;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-always-feature-test-reallocarray.patch b/queue-6.14/perf-always-feature-test-reallocarray.patch
new file mode 100644 (file)
index 0000000..8e089fb
--- /dev/null
@@ -0,0 +1,86 @@
+From 9697b5e0996a53e781f29001534c9a3cbd0636af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Jan 2025 15:44:05 +0000
+Subject: perf: Always feature test reallocarray
+
+From: James Clark <james.clark@linaro.org>
+
+[ Upstream commit 4c4c0724d6521a8092b7c16f8f210c5869d95b17 ]
+
+This is also used in util/comm.c now, so instead of selectively doing
+the feature test, always do it. If it's ever used anywhere else it's
+less likely to cause another build failure.
+
+This doesn't remove the need to manually include libc_compat.h, and
+missing that will still cause an error for glibc < 2.26. There isn't a
+way to fix that without poisoning reallocarray like libbpf did, but that
+has other downsides like making memory debugging tools less useful. So
+for Perf keep it like this and we'll have to fix up any missed includes.
+
+Fixes the following build error:
+
+  util/comm.c:152:31: error: implicit declaration of function
+                      'reallocarray' [-Wimplicit-function-declaration]
+  152 |                         tmp = reallocarray(comm_strs->strs,
+      |                               ^~~~~~~~~~~~
+
+Fixes: 13ca628716c6 ("perf comm: Add reference count checking to 'struct comm_str'")
+Reported-by: Ali Utku Selen <ali.utku.selen@arm.com>
+Signed-off-by: James Clark <james.clark@linaro.org>
+Reviewed-by: Ian Rogers <irogers@google.com>
+Link: https://lore.kernel.org/r/20250129154405.777533-1-james.clark@linaro.org
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/Makefile.config | 10 ++++------
+ tools/perf/util/comm.c     |  2 ++
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
+index a148ca9efca91..23dbb6bb91cf8 100644
+--- a/tools/perf/Makefile.config
++++ b/tools/perf/Makefile.config
+@@ -497,13 +497,14 @@ ifeq ($(feature-setns), 1)
+   $(call detected,CONFIG_SETNS)
+ endif
++ifeq ($(feature-reallocarray), 0)
++  CFLAGS += -DCOMPAT_NEED_REALLOCARRAY
++endif
++
+ ifdef CORESIGHT
+   $(call feature_check,libopencsd)
+   ifeq ($(feature-libopencsd), 1)
+     CFLAGS += -DHAVE_CSTRACE_SUPPORT $(LIBOPENCSD_CFLAGS)
+-    ifeq ($(feature-reallocarray), 0)
+-      CFLAGS += -DCOMPAT_NEED_REALLOCARRAY
+-    endif
+     LDFLAGS += $(LIBOPENCSD_LDFLAGS)
+     EXTLIBS += $(OPENCSDLIBS)
+     $(call detected,CONFIG_LIBOPENCSD)
+@@ -1103,9 +1104,6 @@ ifndef NO_AUXTRACE
+   ifndef NO_AUXTRACE
+     $(call detected,CONFIG_AUXTRACE)
+     CFLAGS += -DHAVE_AUXTRACE_SUPPORT
+-    ifeq ($(feature-reallocarray), 0)
+-      CFLAGS += -DCOMPAT_NEED_REALLOCARRAY
+-    endif
+   endif
+ endif
+diff --git a/tools/perf/util/comm.c b/tools/perf/util/comm.c
+index 49b79cf0c5cc5..8aa456d7c2cd2 100644
+--- a/tools/perf/util/comm.c
++++ b/tools/perf/util/comm.c
+@@ -5,6 +5,8 @@
+ #include <internal/rc_check.h>
+ #include <linux/refcount.h>
+ #include <linux/zalloc.h>
++#include <tools/libc_compat.h> // reallocarray
++
+ #include "rwsem.h"
+ DECLARE_RC_STRUCT(comm_str) {
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-arm-spe-fix-load-store-operation-checking.patch b/queue-6.14/perf-arm-spe-fix-load-store-operation-checking.patch
new file mode 100644 (file)
index 0000000..e14ffd9
--- /dev/null
@@ -0,0 +1,64 @@
+From 9229fc8f1b7c158c821917f1812aa33d74e8e271 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Mar 2025 11:12:34 +0000
+Subject: perf arm-spe: Fix load-store operation checking
+
+From: Leo Yan <leo.yan@arm.com>
+
+[ Upstream commit e1d47850bbf79a541c9b3bacdd562f5e0112274d ]
+
+The ARM_SPE_OP_LD and ARM_SPE_OP_ST operations are secondary operation
+type, they are overlapping with other second level's operation types
+belonging to SVE and branch operations.  As a result, a non load-store
+operation can be parsed for data source and memory sample.
+
+To fix the issue, this commit introduces a is_ldst_op() macro for
+checking LDST operation, and apply the checking when synthesize data
+source and memory samples.
+
+Fixes: a89dbc9b988f ("perf arm-spe: Set sample's data source field")
+Signed-off-by: Leo Yan <leo.yan@arm.com>
+Reviewed-by: James Clark <james.clark@linaro.org>
+Link: https://lore.kernel.org/r/20250304111240.3378214-7-leo.yan@arm.com
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/arm-spe.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c
+index 12761c39788f8..f1365ce69ba08 100644
+--- a/tools/perf/util/arm-spe.c
++++ b/tools/perf/util/arm-spe.c
+@@ -37,6 +37,8 @@
+ #include "../../arch/arm64/include/asm/cputype.h"
+ #define MAX_TIMESTAMP (~0ULL)
++#define is_ldst_op(op)                (!!((op) & ARM_SPE_OP_LDST))
++
+ struct arm_spe {
+       struct auxtrace                 auxtrace;
+       struct auxtrace_queues          queues;
+@@ -669,6 +671,10 @@ static u64 arm_spe__synth_data_source(struct arm_spe_queue *speq,
+ {
+       union perf_mem_data_src data_src = { .mem_op = PERF_MEM_OP_NA };
++      /* Only synthesize data source for LDST operations */
++      if (!is_ldst_op(record->op))
++              return 0;
++
+       if (record->op & ARM_SPE_OP_LD)
+               data_src.mem_op = PERF_MEM_OP_LOAD;
+       else if (record->op & ARM_SPE_OP_ST)
+@@ -767,7 +773,7 @@ static int arm_spe_sample(struct arm_spe_queue *speq)
+        * When data_src is zero it means the record is not a memory operation,
+        * skip to synthesize memory sample for this case.
+        */
+-      if (spe->sample_memory && data_src) {
++      if (spe->sample_memory && is_ldst_op(record->op)) {
+               err = arm_spe__synth_mem_sample(speq, spe->memory_id, data_src);
+               if (err)
+                       return err;
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-bench-fix-perf-bench-syscall-loop-count.patch b/queue-6.14/perf-bench-fix-perf-bench-syscall-loop-count.patch
new file mode 100644 (file)
index 0000000..a728a75
--- /dev/null
@@ -0,0 +1,104 @@
+From 447e5a46663329296a118ac17ea5c54e1309fc8f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Mar 2025 10:23:49 +0100
+Subject: perf bench: Fix perf bench syscall loop count
+
+From: Thomas Richter <tmricht@linux.ibm.com>
+
+[ Upstream commit 957d194163bf983da98bf7ec7e4f86caff8cd0eb ]
+
+Command 'perf bench syscall fork -l 100000' offers option -l to run for
+a specified number of iterations. However this option is not always
+observed. The number is silently limited to 10000 iterations as can be
+seen:
+
+Output before:
+ # perf bench syscall fork -l 100000
+ # Running 'syscall/fork' benchmark:
+ # Executed 10,000 fork() calls
+     Total time: 23.388 [sec]
+
+    2338.809800 usecs/op
+            427 ops/sec
+ #
+
+When explicitly specified with option -l or --loops, also observe
+higher number of iterations:
+
+Output after:
+ # perf bench syscall fork -l 100000
+ # Running 'syscall/fork' benchmark:
+ # Executed 100,000 fork() calls
+     Total time: 716.982 [sec]
+
+    7169.829510 usecs/op
+            139 ops/sec
+ #
+
+This patch fixes the issue for basic execve fork and getpgid.
+
+Fixes: ece7f7c0507c ("perf bench syscall: Add fork syscall benchmark")
+Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
+Acked-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
+Tested-by: Athira Rajeev <atrajeev@linux.ibm.com>
+Cc: Tiezhu Yang <yangtiezhu@loongson.cn>
+Link: https://lore.kernel.org/r/20250304092349.2618082-1-tmricht@linux.ibm.com
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/bench/syscall.c | 22 +++++++++++++---------
+ 1 file changed, 13 insertions(+), 9 deletions(-)
+
+diff --git a/tools/perf/bench/syscall.c b/tools/perf/bench/syscall.c
+index ea4dfc07cbd6b..e7dc216f717f5 100644
+--- a/tools/perf/bench/syscall.c
++++ b/tools/perf/bench/syscall.c
+@@ -22,8 +22,7 @@
+ #define __NR_fork -1
+ #endif
+-#define LOOPS_DEFAULT 10000000
+-static        int loops = LOOPS_DEFAULT;
++static        int loops;
+ static const struct option options[] = {
+       OPT_INTEGER('l', "loop",        &loops,         "Specify number of loops"),
+@@ -80,6 +79,18 @@ static int bench_syscall_common(int argc, const char **argv, int syscall)
+       const char *name = NULL;
+       int i;
++      switch (syscall) {
++      case __NR_fork:
++      case __NR_execve:
++              /* Limit default loop to 10000 times to save time */
++              loops = 10000;
++              break;
++      default:
++              loops = 10000000;
++              break;
++      }
++
++      /* Options -l and --loops override default above */
+       argc = parse_options(argc, argv, options, bench_syscall_usage, 0);
+       gettimeofday(&start, NULL);
+@@ -94,16 +105,9 @@ static int bench_syscall_common(int argc, const char **argv, int syscall)
+                       break;
+               case __NR_fork:
+                       test_fork();
+-                      /* Only loop 10000 times to save time */
+-                      if (i == 10000)
+-                              loops = 10000;
+                       break;
+               case __NR_execve:
+                       test_execve();
+-                      /* Only loop 10000 times to save time */
+-                      if (i == 10000)
+-                              loops = 10000;
+-                      break;
+               default:
+                       break;
+               }
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-bpf-filter-fix-a-parsing-error-with-comma.patch b/queue-6.14/perf-bpf-filter-fix-a-parsing-error-with-comma.patch
new file mode 100644 (file)
index 0000000..8cce19b
--- /dev/null
@@ -0,0 +1,81 @@
+From 79b2ca3bb34c255cfcd72995c4bc8d006caa09c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Mar 2025 14:09:21 -0800
+Subject: perf bpf-filter: Fix a parsing error with comma
+
+From: Namhyung Kim <namhyung@kernel.org>
+
+[ Upstream commit 35d13f841a3d8159ef20d5e32a9ed3faa27875bc ]
+
+The previous change to support cgroup filters introduced a bug that
+pathname can include commas.  It confused the lexer to treat an item and
+the trailing comma as a single token.  And it resulted in a parse error:
+
+  $ sudo perf record -e cycles:P --filter 'period > 0, ip > 64' -- true
+  perf_bpf_filter: Error: Unexpected item: 0,
+  perf_bpf_filter: syntax error, unexpected BFT_ERROR, expecting BFT_NUM
+
+   Usage: perf record [<options>] [<command>]
+      or: perf record [<options>] -- <command> [<options>]
+
+          --filter <filter>
+                            event filter
+
+It should get "0" and "," separately.
+
+An easiest fix would be to remove "," from the possible pathname
+characters.  As it's for cgroup names, probably ok to assume it won't
+have commas in the pathname.
+
+I found that the existing BPF filtering test didn't have any complex
+filter condition with commas.  Let's update the group filter test which
+is supposed to test filter combinations like this.
+
+Link: https://lore.kernel.org/r/20250307220922.434319-1-namhyung@kernel.org
+Fixes: 91e88437d5156b20 ("perf bpf-filter: Support filtering on cgroups")
+Reported-by: Sally Shi <sshii@google.com>
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/tests/shell/record_bpf_filter.sh | 4 ++--
+ tools/perf/util/bpf-filter.l                | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/tools/perf/tests/shell/record_bpf_filter.sh b/tools/perf/tests/shell/record_bpf_filter.sh
+index 1b58ccc1fd882..4d6c3c1b7fb92 100755
+--- a/tools/perf/tests/shell/record_bpf_filter.sh
++++ b/tools/perf/tests/shell/record_bpf_filter.sh
+@@ -89,7 +89,7 @@ test_bpf_filter_fail() {
+ test_bpf_filter_group() {
+   echo "Group bpf-filter test"
+-  if ! perf record -e task-clock --filter 'period > 1000 || ip > 0' \
++  if ! perf record -e task-clock --filter 'period > 1000, ip > 0' \
+         -o /dev/null true 2>/dev/null
+   then
+     echo "Group bpf-filter test [Failed should succeed]"
+@@ -97,7 +97,7 @@ test_bpf_filter_group() {
+     return
+   fi
+-  if ! perf record -e task-clock --filter 'cpu > 0 || ip > 0' \
++  if ! perf record -e task-clock --filter 'period > 1000 , cpu > 0 || ip > 0' \
+         -o /dev/null true 2>&1 | grep -q PERF_SAMPLE_CPU
+   then
+     echo "Group bpf-filter test [Failed forbidden CPU]"
+diff --git a/tools/perf/util/bpf-filter.l b/tools/perf/util/bpf-filter.l
+index f313404f95a90..6aa65ade33851 100644
+--- a/tools/perf/util/bpf-filter.l
++++ b/tools/perf/util/bpf-filter.l
+@@ -76,7 +76,7 @@ static int path_or_error(void)
+ num_dec               [0-9]+
+ num_hex               0[Xx][0-9a-fA-F]+
+ space         [ \t]+
+-path          [^ \t\n]+
++path          [^ \t\n,]+
+ ident         [_a-zA-Z][_a-zA-Z0-9]+
+ %%
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-build-fix-in-tree-build-due-to-symbolic-link.patch b/queue-6.14/perf-build-fix-in-tree-build-due-to-symbolic-link.patch
new file mode 100644 (file)
index 0000000..7d7a481
--- /dev/null
@@ -0,0 +1,80 @@
+From 1f7c527356926c62b491887005ae51635184b6ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jan 2025 14:06:08 +0100
+Subject: perf build: Fix in-tree build due to symbolic link
+
+From: Luca Ceresoli <luca.ceresoli@bootlin.com>
+
+[ Upstream commit 75100d848ef4b8ca39bb6dd3a21181e37dea27e2 ]
+
+Building perf in-tree is broken after commit 890a1961c812 ("perf tools:
+Create source symlink in perf object dir") which added a 'source' symlink
+in the output dir pointing to the source dir.
+
+With in-tree builds, the added 'SOURCE = ...' line is executed multiple
+times (I observed 2 during the build plus 2 during installation). This is a
+minor inefficiency, in theory not harmful because symlink creation is
+assumed to be idempotent. But it is not.
+
+Considering with in-tree builds:
+
+  srctree=/absolute/path/to/linux
+   OUTPUT=/absolute/path/to/linux/tools/perf
+
+here's what happens:
+
+ 1. ln -sf $(srctree)/tools/perf $(OUTPUT)/source
+    -> creates /absolute/path/to/linux/tools/perf/source
+       link to /absolute/path/to/linux/tools/perf
+    => OK, that's what was intended
+ 2. ln -sf $(srctree)/tools/perf $(OUTPUT)/source   # same command as 1
+    -> creates /absolute/path/to/linux/tools/perf/perf
+       link to /absolute/path/to/linux/tools/perf
+    => Not what was intended, not idempotent
+ 3. Now the build _should_ create the 'perf' executable, but it fails
+
+The reason is the tricky 'ln' command line. At the first invocation 'ln'
+uses the 1st form:
+
+       ln [OPTION]... [-T] TARGET LINK_NAME
+
+and creates a link to TARGET *called LINK_NAME*.
+
+At the second invocation $(OUTPUT)/source exists, so 'ln' uses the 3rd
+form:
+
+       ln [OPTION]... TARGET... DIRECTORY
+
+and creates a link to TARGET *called TARGET* inside DIRECTORY.
+
+Fix by adding -n/--no-dereference to "treat LINK_NAME as a normal file
+if it is a symbolic link to a directory", as the manpage says.
+
+Closes: https://lore.kernel.org/all/20241125182506.38af9907@booty/
+Fixes: 890a1961c812 ("perf tools: Create source symlink in perf object dir")
+Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
+Reviewed-by: Charlie Jenkins <charlie@rivosinc.com>
+Tested-by: Charlie Jenkins <charlie@rivosinc.com>
+Link: https://lore.kernel.org/r/20250124-perf-fix-intree-build-v1-1-485dd7a855e4@bootlin.com
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/Makefile.perf | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
+index 05c083bb11220..eea8877c7cba3 100644
+--- a/tools/perf/Makefile.perf
++++ b/tools/perf/Makefile.perf
+@@ -158,7 +158,7 @@ ifneq ($(OUTPUT),)
+ VPATH += $(OUTPUT)
+ export VPATH
+ # create symlink to the original source
+-SOURCE := $(shell ln -sf $(srctree)/tools/perf $(OUTPUT)/source)
++SOURCE := $(shell ln -sfn $(srctree)/tools/perf $(OUTPUT)/source)
+ endif
+ # Do not use make's built-in rules
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-debug-avoid-stack-overflow-in-recursive-error-m.patch b/queue-6.14/perf-debug-avoid-stack-overflow-in-recursive-error-m.patch
new file mode 100644 (file)
index 0000000..43b9f47
--- /dev/null
@@ -0,0 +1,41 @@
+From 088e63bd3546eb886cbc707398b135a7b9e2e955 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Feb 2025 14:22:58 -0800
+Subject: perf debug: Avoid stack overflow in recursive error message
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit bda840191d2aae3b7cadc3ac21835dcf29487191 ]
+
+In debug_file, pr_warning_once is called on error. As that function
+calls debug_file the function will yield a stack overflow. Switch the
+location of the call so the recursion is avoided.
+
+Reviewed-by: Howard Chu <howardchu95@gmail.com>
+Signed-off-by: Ian Rogers <irogers@google.com>
+Reviewed-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Link: https://lore.kernel.org/r/20250228222308.626803-2-irogers@google.com
+Fixes: ec49230cf6dda704 ("perf debug: Expose debug file")
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/debug.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c
+index 995f6bb05b5f8..f9ef7d045c92e 100644
+--- a/tools/perf/util/debug.c
++++ b/tools/perf/util/debug.c
+@@ -46,8 +46,8 @@ int debug_type_profile;
+ FILE *debug_file(void)
+ {
+       if (!_debug_file) {
+-              pr_warning_once("debug_file not set");
+               debug_set_file(stderr);
++              pr_warning_once("debug_file not set");
+       }
+       return _debug_file;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-dso-fix-dso__is_kallsyms-check.patch b/queue-6.14/perf-dso-fix-dso__is_kallsyms-check.patch
new file mode 100644 (file)
index 0000000..e2e4114
--- /dev/null
@@ -0,0 +1,63 @@
+From 8d3ba02c275ec9d2725d557d011b8a68ec784343 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Mar 2025 16:00:11 -0700
+Subject: perf dso: fix dso__is_kallsyms() check
+
+From: Stephen Brennan <stephen.s.brennan@oracle.com>
+
+[ Upstream commit ebf0b332732dcc64239119e554faa946562b0b93 ]
+
+Kernel modules for which we cannot find a file on-disk will have a
+dso->long_name that looks like "[module_name]". Prior to the commit
+listed in the fixes, the dso->kernel field would be zero (for user
+space), so dso__is_kallsyms() would return false. After the commit,
+kernel module DSOs are correctly labeled, but the result is that
+dso__is_kallsyms() erroneously returns true for those modules without a
+filesystem path.
+
+Later, build_id_cache__add() consults this value of is_kallsyms, and
+when true, it copies /proc/kallsyms into the cache. Users with many
+kernel modules without a filesystem path (e.g. ksplice or possibly
+kernel live patch modules) have reported excessive disk space usage in
+the build ID cache directory due to this behavior.
+
+To reproduce the issue, it's enough to build a trivial out-of-tree hello
+world kernel module, load it using insmod, and then use:
+
+   perf record -ag -- sleep 1
+
+In the build ID directory, there will be a directory for your module
+name containing a kallsyms file.
+
+Fix this up by changing dso__is_kallsyms() to consult the
+dso_binary_type enumeration, which is also symmetric to the above checks
+for dso__is_vmlinux() and dso__is_kcore(). With this change, kallsyms is
+not cached in the build-id cache for out-of-tree modules.
+
+Fixes: 02213cec64bbe ("perf maps: Mark module DSOs with kernel type")
+Signed-off-by: Stephen Brennan <stephen.s.brennan@oracle.com>
+Link: https://lore.kernel.org/r/20250318230012.2038790-1-stephen.s.brennan@oracle.com
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/dso.h | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
+index bb8e8f444054d..c0472a41147c3 100644
+--- a/tools/perf/util/dso.h
++++ b/tools/perf/util/dso.h
+@@ -808,7 +808,9 @@ static inline bool dso__is_kcore(const struct dso *dso)
+ static inline bool dso__is_kallsyms(const struct dso *dso)
+ {
+-      return RC_CHK_ACCESS(dso)->kernel && RC_CHK_ACCESS(dso)->long_name[0] != '/';
++      enum dso_binary_type bt = dso__binary_type(dso);
++
++      return bt == DSO_BINARY_TYPE__KALLSYMS || bt == DSO_BINARY_TYPE__GUEST_KALLSYMS;
+ }
+ bool dso__is_object_file(const struct dso *dso);
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-evlist-add-success-path-to-evlist__create_syswi.patch b/queue-6.14/perf-evlist-add-success-path-to-evlist__create_syswi.patch
new file mode 100644 (file)
index 0000000..57143ff
--- /dev/null
@@ -0,0 +1,57 @@
+From 756ecb1c93287330bdec868702c03917a7684e99 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Feb 2025 14:22:59 -0800
+Subject: perf evlist: Add success path to evlist__create_syswide_maps
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit fe0ce8a9d85a48642880c9b78944cb0d23e779c5 ]
+
+Over various refactorings evlist__create_syswide_maps has been made to
+only ever return with -ENOMEM. Fix this so that when
+perf_evlist__set_maps is successfully called, 0 is returned.
+
+Reviewed-by: Howard Chu <howardchu95@gmail.com>
+Signed-off-by: Ian Rogers <irogers@google.com>
+Reviewed-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Link: https://lore.kernel.org/r/20250228222308.626803-3-irogers@google.com
+Fixes: 8c0498b6891d7ca5 ("perf evlist: Fix create_syswide_maps() not propagating maps")
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/evlist.c | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
+index f0dd174e2debd..633df7d9204c2 100644
+--- a/tools/perf/util/evlist.c
++++ b/tools/perf/util/evlist.c
+@@ -1373,19 +1373,18 @@ static int evlist__create_syswide_maps(struct evlist *evlist)
+        */
+       cpus = perf_cpu_map__new_online_cpus();
+       if (!cpus)
+-              goto out;
++              return -ENOMEM;
+       threads = perf_thread_map__new_dummy();
+-      if (!threads)
+-              goto out_put;
++      if (!threads) {
++              perf_cpu_map__put(cpus);
++              return -ENOMEM;
++      }
+       perf_evlist__set_maps(&evlist->core, cpus, threads);
+-
+       perf_thread_map__put(threads);
+-out_put:
+       perf_cpu_map__put(cpus);
+-out:
+-      return -ENOMEM;
++      return 0;
+ }
+ int evlist__open(struct evlist *evlist)
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-evsel-tp_format-accessing-improvements.patch b/queue-6.14/perf-evsel-tp_format-accessing-improvements.patch
new file mode 100644 (file)
index 0000000..e989f14
--- /dev/null
@@ -0,0 +1,62 @@
+From 698c69d6eec877f4082eb3f02c7dda65a2ac3cd3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Feb 2025 14:23:00 -0800
+Subject: perf evsel: tp_format accessing improvements
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit eb7e83a7ca2dba01671c711e1711705e1a15626d ]
+
+Ensure evsel__clone copies the tp_sys and tp_name variables.
+In evsel__tp_format, if tp_sys isn't set, use the config value to find
+the tp_format. This succeeds in python code where pyrf__tracepoint has
+already found the format.
+
+Reviewed-by: Howard Chu <howardchu95@gmail.com>
+Signed-off-by: Ian Rogers <irogers@google.com>
+Reviewed-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Link: https://lore.kernel.org/r/20250228222308.626803-4-irogers@google.com
+Fixes: 6c8310e8380d472c ("perf evsel: Allow evsel__newtp without libtraceevent")
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/evsel.c | 16 +++++++++++++++-
+ 1 file changed, 15 insertions(+), 1 deletion(-)
+
+diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
+index bc144388f8929..9cd78cdee6282 100644
+--- a/tools/perf/util/evsel.c
++++ b/tools/perf/util/evsel.c
+@@ -511,6 +511,16 @@ struct evsel *evsel__clone(struct evsel *dest, struct evsel *orig)
+       }
+       evsel->cgrp = cgroup__get(orig->cgrp);
+ #ifdef HAVE_LIBTRACEEVENT
++      if (orig->tp_sys) {
++              evsel->tp_sys = strdup(orig->tp_sys);
++              if (evsel->tp_sys == NULL)
++                      goto out_err;
++      }
++      if (orig->tp_name) {
++              evsel->tp_name = strdup(orig->tp_name);
++              if (evsel->tp_name == NULL)
++                      goto out_err;
++      }
+       evsel->tp_format = orig->tp_format;
+ #endif
+       evsel->handler = orig->handler;
+@@ -634,7 +644,11 @@ struct tep_event *evsel__tp_format(struct evsel *evsel)
+       if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT)
+               return NULL;
+-      tp_format = trace_event__tp_format(evsel->tp_sys, evsel->tp_name);
++      if (!evsel->tp_sys)
++              tp_format = trace_event__tp_format_id(evsel->core.attr.config);
++      else
++              tp_format = trace_event__tp_format(evsel->tp_sys, evsel->tp_name);
++
+       if (IS_ERR(tp_format)) {
+               int err = -PTR_ERR(evsel->tp_format);
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-intel-tpebs-fix-incorrect-usage-of-zfree.patch b/queue-6.14/perf-intel-tpebs-fix-incorrect-usage-of-zfree.patch
new file mode 100644 (file)
index 0000000..ff5a727
--- /dev/null
@@ -0,0 +1,39 @@
+From b66199ec3475c25185cd920958ba7edbb4e70f68 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Mar 2025 10:16:10 +0000
+Subject: perf: intel-tpebs: Fix incorrect usage of zfree()
+
+From: James Clark <james.clark@linaro.org>
+
+[ Upstream commit 6d2dcd635204c023eb5328ad7d38b198a5558c9b ]
+
+zfree() requires an address otherwise it frees what's in name, rather
+than name itself. Pass the address of name to fix it.
+
+This was the only incorrect occurrence in Perf found using a search.
+
+Fixes: 8db5cabcf1b6 ("perf stat: Fork and launch 'perf record' when 'perf stat' needs to get retire latency value for a metric.")
+Signed-off-by: James Clark <james.clark@linaro.org>
+Link: https://lore.kernel.org/r/20250319101614.190922-1-james.clark@linaro.org
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/intel-tpebs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/util/intel-tpebs.c b/tools/perf/util/intel-tpebs.c
+index 50a3c3e071606..2c421b475b3b8 100644
+--- a/tools/perf/util/intel-tpebs.c
++++ b/tools/perf/util/intel-tpebs.c
+@@ -254,7 +254,7 @@ int tpebs_start(struct evlist *evsel_list)
+               new = zalloc(sizeof(*new));
+               if (!new) {
+                       ret = -1;
+-                      zfree(name);
++                      zfree(&name);
+                       goto err;
+               }
+               new->name = name;
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-machine-fixup-kernel-maps-ends-after-adding-ext.patch b/queue-6.14/perf-machine-fixup-kernel-maps-ends-after-adding-ext.patch
new file mode 100644 (file)
index 0000000..e826fbc
--- /dev/null
@@ -0,0 +1,51 @@
+From 12baa545c8f606621e68677d3088a7ccbe7f24d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Feb 2025 18:17:31 -0300
+Subject: perf machine: Fixup kernel maps ends after adding extra maps
+
+From: Namhyung Kim <namhyung@kernel.org>
+
+[ Upstream commit f7a46e028c394cd422326caa7a2ad6ba0cd87915 ]
+
+I just noticed it would add extra kernel maps after modules.  I think it
+should fixup end address of the kernel maps after adding all maps first.
+
+Fixes: 876e80cf83d10585 ("perf tools: Fixup end address of modules")
+Reported-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Reviewed-by: Ian Rogers <irogers@google.com>
+Link: https://lore.kernel.org/lkml/Z7TvZGjVix2asYWI@x1
+Link: https://lore.kernel.org/lkml/Z712hzvv22Ni63f1@google.com
+Link: https://lore.kernel.org/r/20250228211734.33781-4-acme@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/machine.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
+index 2d51badfbf2e2..9c7bf17bcbe86 100644
+--- a/tools/perf/util/machine.c
++++ b/tools/perf/util/machine.c
+@@ -1468,8 +1468,6 @@ static int machine__create_modules(struct machine *machine)
+       if (modules__parse(modules, machine, machine__create_module))
+               return -1;
+-      maps__fixup_end(machine__kernel_maps(machine));
+-
+       if (!machine__set_modules_path(machine))
+               return 0;
+@@ -1563,6 +1561,8 @@ int machine__create_kernel_maps(struct machine *machine)
+               }
+       }
++      maps__fixup_end(machine__kernel_maps(machine));
++
+ out_put:
+       dso__put(kernel);
+       return ret;
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-pmu-don-t-double-count-common-sysfs-and-json-ev.patch b/queue-6.14/perf-pmu-don-t-double-count-common-sysfs-and-json-ev.patch
new file mode 100644 (file)
index 0000000..d436289
--- /dev/null
@@ -0,0 +1,81 @@
+From c97516c33509a5ad3ddbe5ed796c873d3a1c59f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Feb 2025 10:41:01 +0000
+Subject: perf pmu: Don't double count common sysfs and json events
+
+From: James Clark <james.clark@linaro.org>
+
+[ Upstream commit c9d699e10fa6c0cdabcddcf991e7ff42af6b2503 ]
+
+After pmu_add_cpu_aliases() is called, perf_pmu__num_events() returns an
+incorrect value that double counts common events and doesn't match the
+actual count of events in the alias list. This is because after
+'cpu_aliases_added == true', the number of events returned is
+'sysfs_aliases + cpu_json_aliases'. But when adding 'case
+EVENT_SRC_SYSFS' events, 'sysfs_aliases' and 'cpu_json_aliases' are both
+incremented together, failing to account that these ones overlap and
+only add a single item to the list. Fix it by adding another counter for
+overlapping events which doesn't influence 'cpu_json_aliases'.
+
+There doesn't seem to be a current issue because it's used in perf list
+before pmu_add_cpu_aliases() so the correct value is returned. Other
+uses in tests may also miss it for other reasons like only looking at
+uncore events. However it's marked as a fixes commit in case any new fix
+with new uses of perf_pmu__num_events() is backported.
+
+Fixes: d9c5f5f94c2d ("perf pmu: Count sys and cpuid JSON events separately")
+Reviewed-by: Ian Rogers <irogers@google.com>
+Signed-off-by: James Clark <james.clark@linaro.org>
+Link: https://lore.kernel.org/r/20250226104111.564443-3-james.clark@linaro.org
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/pmu.c | 7 ++++---
+ tools/perf/util/pmu.h | 5 +++++
+ 2 files changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
+index a8193ac8f2e7d..98cc525dc9ded 100644
+--- a/tools/perf/util/pmu.c
++++ b/tools/perf/util/pmu.c
+@@ -596,7 +596,7 @@ static int perf_pmu__new_alias(struct perf_pmu *pmu, const char *name,
+                       };
+                       if (pmu_events_table__find_event(pmu->events_table, pmu, name,
+                                                        update_alias, &data) == 0)
+-                              pmu->cpu_json_aliases++;
++                              pmu->cpu_common_json_aliases++;
+               }
+               pmu->sysfs_aliases++;
+               break;
+@@ -1851,9 +1851,10 @@ size_t perf_pmu__num_events(struct perf_pmu *pmu)
+       if (pmu->cpu_aliases_added)
+                nr += pmu->cpu_json_aliases;
+       else if (pmu->events_table)
+-              nr += pmu_events_table__num_events(pmu->events_table, pmu) - pmu->cpu_json_aliases;
++              nr += pmu_events_table__num_events(pmu->events_table, pmu) -
++                      pmu->cpu_common_json_aliases;
+       else
+-              assert(pmu->cpu_json_aliases == 0);
++              assert(pmu->cpu_json_aliases == 0 && pmu->cpu_common_json_aliases == 0);
+       if (perf_pmu__is_tool(pmu))
+               nr -= tool_pmu__num_skip_events();
+diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
+index edd36c20aedc2..deaf9c268ed13 100644
+--- a/tools/perf/util/pmu.h
++++ b/tools/perf/util/pmu.h
+@@ -136,6 +136,11 @@ struct perf_pmu {
+       uint32_t cpu_json_aliases;
+       /** @sys_json_aliases: Number of json event aliases loaded matching the PMU's identifier. */
+       uint32_t sys_json_aliases;
++      /**
++       * @cpu_common_json_aliases: Number of json events that overlapped with sysfs when
++       * loading all sysfs events.
++       */
++      uint32_t cpu_common_json_aliases;
+       /** @sysfs_aliases_loaded: Are sysfs aliases loaded from disk? */
+       bool sysfs_aliases_loaded;
+       /**
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-pmu-dynamically-allocate-tool-pmu.patch b/queue-6.14/perf-pmu-dynamically-allocate-tool-pmu.patch
new file mode 100644 (file)
index 0000000..7641872
--- /dev/null
@@ -0,0 +1,101 @@
+From 94ee44495c0084c916d7d11de1bb4b44bd040aa4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Feb 2025 10:41:00 +0000
+Subject: perf pmu: Dynamically allocate tool PMU
+
+From: James Clark <james.clark@linaro.org>
+
+[ Upstream commit 72c6f57a4193f2eadceb52261315438719c4c1ad ]
+
+perf_pmus__destroy() treats all PMUs as allocated and free's them so we
+can't have any static PMUs that are added to the PMU lists. Fix it by
+allocating the tool PMU in the same way as the others. Current users of
+the tool PMU already use find_pmu() and not perf_pmus__tool_pmu(), so
+rename the function to add 'new' to avoid it being misused in the
+future.
+
+perf_pmus__fake_pmu() can remain as static as it's not added to the
+PMU lists.
+
+Fixes the following error:
+
+  $ perf bench internals pmu-scan
+
+  # Running 'internals/pmu-scan' benchmark:
+  Computing performance of sysfs PMU event scan for 100 times
+  munmap_chunk(): invalid pointer
+  Aborted (core dumped)
+
+Fixes: 240505b2d0ad ("perf tool_pmu: Factor tool events into their own PMU")
+Reviewed-by: Ian Rogers <irogers@google.com>
+Signed-off-by: James Clark <james.clark@linaro.org>
+Link: https://lore.kernel.org/r/20250226104111.564443-2-james.clark@linaro.org
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/pmus.c     |  2 +-
+ tools/perf/util/tool_pmu.c | 23 +++++++++++------------
+ tools/perf/util/tool_pmu.h |  2 +-
+ 3 files changed, 13 insertions(+), 14 deletions(-)
+
+diff --git a/tools/perf/util/pmus.c b/tools/perf/util/pmus.c
+index 8a0a919415d49..6498021acef01 100644
+--- a/tools/perf/util/pmus.c
++++ b/tools/perf/util/pmus.c
+@@ -268,7 +268,7 @@ static void pmu_read_sysfs(unsigned int to_read_types)
+       if ((to_read_types & PERF_TOOL_PMU_TYPE_TOOL_MASK) != 0 &&
+           (read_pmu_types & PERF_TOOL_PMU_TYPE_TOOL_MASK) == 0) {
+-              tool_pmu = perf_pmus__tool_pmu();
++              tool_pmu = tool_pmu__new();
+               list_add_tail(&tool_pmu->list, &other_pmus);
+       }
+       if ((to_read_types & PERF_TOOL_PMU_TYPE_HWMON_MASK) != 0 &&
+diff --git a/tools/perf/util/tool_pmu.c b/tools/perf/util/tool_pmu.c
+index 3a68debe71437..9156745ea180d 100644
+--- a/tools/perf/util/tool_pmu.c
++++ b/tools/perf/util/tool_pmu.c
+@@ -490,17 +490,16 @@ int evsel__tool_pmu_read(struct evsel *evsel, int cpu_map_idx, int thread)
+       return 0;
+ }
+-struct perf_pmu *perf_pmus__tool_pmu(void)
++struct perf_pmu *tool_pmu__new(void)
+ {
+-      static struct perf_pmu tool = {
+-              .name = "tool",
+-              .type = PERF_PMU_TYPE_TOOL,
+-              .aliases = LIST_HEAD_INIT(tool.aliases),
+-              .caps = LIST_HEAD_INIT(tool.caps),
+-              .format = LIST_HEAD_INIT(tool.format),
+-      };
+-      if (!tool.events_table)
+-              tool.events_table = find_core_events_table("common", "common");
+-
+-      return &tool;
++      struct perf_pmu *tool = zalloc(sizeof(struct perf_pmu));
++
++      tool->name = strdup("tool");
++      tool->type = PERF_PMU_TYPE_TOOL;
++      INIT_LIST_HEAD(&tool->aliases);
++      INIT_LIST_HEAD(&tool->caps);
++      INIT_LIST_HEAD(&tool->format);
++      tool->events_table = find_core_events_table("common", "common");
++
++      return tool;
+ }
+diff --git a/tools/perf/util/tool_pmu.h b/tools/perf/util/tool_pmu.h
+index a60184859080f..c6ad1dd90a56d 100644
+--- a/tools/perf/util/tool_pmu.h
++++ b/tools/perf/util/tool_pmu.h
+@@ -51,6 +51,6 @@ int evsel__tool_pmu_open(struct evsel *evsel,
+                        int start_cpu_map_idx, int end_cpu_map_idx);
+ int evsel__tool_pmu_read(struct evsel *evsel, int cpu_map_idx, int thread);
+-struct perf_pmu *perf_pmus__tool_pmu(void);
++struct perf_pmu *tool_pmu__new(void);
+ #endif /* __TOOL_PMU_H */
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-pmu-handle-memory-failure-in-tool_pmu__new.patch b/queue-6.14/perf-pmu-handle-memory-failure-in-tool_pmu__new.patch
new file mode 100644 (file)
index 0000000..268988c
--- /dev/null
@@ -0,0 +1,69 @@
+From f1b1270e1aebda08a2bd3a861d5409463724d8df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Mar 2025 13:28:20 +0100
+Subject: perf pmu: Handle memory failure in tool_pmu__new()
+
+From: Thomas Richter <tmricht@linux.ibm.com>
+
+[ Upstream commit 431db90a7303cb394c5a881b4479946f64052727 ]
+
+On linux-next
+commit 72c6f57a4193 ("perf pmu: Dynamically allocate tool PMU")
+allocated PMU named "tool" dynamicly. However that allocation
+can fail and a NULL pointer is returned. That case is currently
+not handled and would result in an invalid address reference.
+Add a check for NULL pointer.
+
+Fixes: 72c6f57a4193 ("perf pmu: Dynamically allocate tool PMU")
+Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
+Reviewed-by: James Clark <james.clark@linaro.org>
+Link: https://lore.kernel.org/r/20250319122820.2898333-1-tmricht@linux.ibm.com
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/pmus.c     | 3 ++-
+ tools/perf/util/tool_pmu.c | 8 ++++++++
+ 2 files changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/tools/perf/util/pmus.c b/tools/perf/util/pmus.c
+index 6498021acef01..7959af59908c2 100644
+--- a/tools/perf/util/pmus.c
++++ b/tools/perf/util/pmus.c
+@@ -269,7 +269,8 @@ static void pmu_read_sysfs(unsigned int to_read_types)
+       if ((to_read_types & PERF_TOOL_PMU_TYPE_TOOL_MASK) != 0 &&
+           (read_pmu_types & PERF_TOOL_PMU_TYPE_TOOL_MASK) == 0) {
+               tool_pmu = tool_pmu__new();
+-              list_add_tail(&tool_pmu->list, &other_pmus);
++              if (tool_pmu)
++                      list_add_tail(&tool_pmu->list, &other_pmus);
+       }
+       if ((to_read_types & PERF_TOOL_PMU_TYPE_HWMON_MASK) != 0 &&
+           (read_pmu_types & PERF_TOOL_PMU_TYPE_HWMON_MASK) == 0)
+diff --git a/tools/perf/util/tool_pmu.c b/tools/perf/util/tool_pmu.c
+index 9156745ea180d..d43d6cf6e4a20 100644
+--- a/tools/perf/util/tool_pmu.c
++++ b/tools/perf/util/tool_pmu.c
+@@ -494,12 +494,20 @@ struct perf_pmu *tool_pmu__new(void)
+ {
+       struct perf_pmu *tool = zalloc(sizeof(struct perf_pmu));
++      if (!tool)
++              goto out;
+       tool->name = strdup("tool");
++      if (!tool->name) {
++              zfree(&tool);
++              goto out;
++      }
++
+       tool->type = PERF_PMU_TYPE_TOOL;
+       INIT_LIST_HEAD(&tool->aliases);
+       INIT_LIST_HEAD(&tool->caps);
+       INIT_LIST_HEAD(&tool->format);
+       tool->events_table = find_core_events_table("common", "common");
++out:
+       return tool;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-pmus-restructure-pmu_read_sysfs-to-scan-fewer-p.patch b/queue-6.14/perf-pmus-restructure-pmu_read_sysfs-to-scan-fewer-p.patch
new file mode 100644 (file)
index 0000000..3dd5653
--- /dev/null
@@ -0,0 +1,302 @@
+From a0b6bb7120284aa209a604059c833a509da21c41 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Jan 2025 23:43:17 -0800
+Subject: perf pmus: Restructure pmu_read_sysfs to scan fewer PMUs
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 57e13264dcea670d5f42a067562f02aa923219e2 ]
+
+Rather than scanning core or all PMUs, allow pmu_read_sysfs to read
+some combination of core, other, hwmon and tool PMUs. The PMUs that
+should be read and are already read are held as bitmaps. It is known
+that a "hwmon_" prefix is necessary for a hwmon PMU's name, similarly
+with "tool", so only scan those PMUs in situations the PMU name or the
+PMU's type number make sense to.
+
+The number of openat system calls reduces from 276 to 98 for a hwmon
+event. The number of openats for regular perf events isn't changed.
+
+Signed-off-by: Ian Rogers <irogers@google.com>
+Reviewed-by: Kan Liang <kan.liang@linux.intel.com>
+Link: https://lore.kernel.org/r/20250201074320.746259-3-irogers@google.com
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Stable-dep-of: 72c6f57a4193 ("perf pmu: Dynamically allocate tool PMU")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/pmu.h  |   2 +
+ tools/perf/util/pmus.c | 146 +++++++++++++++++++++++++++--------------
+ 2 files changed, 97 insertions(+), 51 deletions(-)
+
+diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
+index dbed6c243a5ef..edd36c20aedc2 100644
+--- a/tools/perf/util/pmu.h
++++ b/tools/perf/util/pmu.h
+@@ -37,6 +37,8 @@ struct perf_pmu_caps {
+ };
+ enum {
++      PERF_PMU_TYPE_PE_START    = 0,
++      PERF_PMU_TYPE_PE_END      = 0xFFFEFFFF,
+       PERF_PMU_TYPE_HWMON_START = 0xFFFF0000,
+       PERF_PMU_TYPE_HWMON_END   = 0xFFFFFFFD,
+       PERF_PMU_TYPE_TOOL = 0xFFFFFFFE,
+diff --git a/tools/perf/util/pmus.c b/tools/perf/util/pmus.c
+index 60d81d69503e3..8a0a919415d49 100644
+--- a/tools/perf/util/pmus.c
++++ b/tools/perf/util/pmus.c
+@@ -37,10 +37,25 @@
+  */
+ static LIST_HEAD(core_pmus);
+ static LIST_HEAD(other_pmus);
+-static bool read_sysfs_core_pmus;
+-static bool read_sysfs_all_pmus;
++enum perf_tool_pmu_type {
++      PERF_TOOL_PMU_TYPE_PE_CORE,
++      PERF_TOOL_PMU_TYPE_PE_OTHER,
++      PERF_TOOL_PMU_TYPE_TOOL,
++      PERF_TOOL_PMU_TYPE_HWMON,
++
++#define PERF_TOOL_PMU_TYPE_PE_CORE_MASK (1 << PERF_TOOL_PMU_TYPE_PE_CORE)
++#define PERF_TOOL_PMU_TYPE_PE_OTHER_MASK (1 << PERF_TOOL_PMU_TYPE_PE_OTHER)
++#define PERF_TOOL_PMU_TYPE_TOOL_MASK (1 << PERF_TOOL_PMU_TYPE_TOOL)
++#define PERF_TOOL_PMU_TYPE_HWMON_MASK (1 << PERF_TOOL_PMU_TYPE_HWMON)
++
++#define PERF_TOOL_PMU_TYPE_ALL_MASK (PERF_TOOL_PMU_TYPE_PE_CORE_MASK |        \
++                                      PERF_TOOL_PMU_TYPE_PE_OTHER_MASK | \
++                                      PERF_TOOL_PMU_TYPE_TOOL_MASK |  \
++                                      PERF_TOOL_PMU_TYPE_HWMON_MASK)
++};
++static unsigned int read_pmu_types;
+-static void pmu_read_sysfs(bool core_only);
++static void pmu_read_sysfs(unsigned int to_read_pmus);
+ size_t pmu_name_len_no_suffix(const char *str)
+ {
+@@ -102,8 +117,7 @@ void perf_pmus__destroy(void)
+               perf_pmu__delete(pmu);
+       }
+-      read_sysfs_core_pmus = false;
+-      read_sysfs_all_pmus = false;
++      read_pmu_types = 0;
+ }
+ static struct perf_pmu *pmu_find(const char *name)
+@@ -129,6 +143,7 @@ struct perf_pmu *perf_pmus__find(const char *name)
+       struct perf_pmu *pmu;
+       int dirfd;
+       bool core_pmu;
++      unsigned int to_read_pmus = 0;
+       /*
+        * Once PMU is loaded it stays in the list,
+@@ -139,11 +154,11 @@ struct perf_pmu *perf_pmus__find(const char *name)
+       if (pmu)
+               return pmu;
+-      if (read_sysfs_all_pmus)
++      if (read_pmu_types == PERF_TOOL_PMU_TYPE_ALL_MASK)
+               return NULL;
+       core_pmu = is_pmu_core(name);
+-      if (core_pmu && read_sysfs_core_pmus)
++      if (core_pmu && (read_pmu_types & PERF_TOOL_PMU_TYPE_PE_CORE_MASK))
+               return NULL;
+       dirfd = perf_pmu__event_source_devices_fd();
+@@ -151,15 +166,27 @@ struct perf_pmu *perf_pmus__find(const char *name)
+                              /*eager_load=*/false);
+       close(dirfd);
+-      if (!pmu) {
+-              /*
+-               * Looking up an inidividual PMU failed. This may mean name is
+-               * an alias, so read the PMUs from sysfs and try to find again.
+-               */
+-              pmu_read_sysfs(core_pmu);
++      if (pmu)
++              return pmu;
++
++      /* Looking up an individual perf event PMU failed, check if a tool PMU should be read. */
++      if (!strncmp(name, "hwmon_", 6))
++              to_read_pmus |= PERF_TOOL_PMU_TYPE_HWMON_MASK;
++      else if (!strcmp(name, "tool"))
++              to_read_pmus |= PERF_TOOL_PMU_TYPE_TOOL_MASK;
++
++      if (to_read_pmus) {
++              pmu_read_sysfs(to_read_pmus);
+               pmu = pmu_find(name);
++              if (pmu)
++                      return pmu;
+       }
+-      return pmu;
++      /* Read all necessary PMUs from sysfs and see if the PMU is found. */
++      to_read_pmus = PERF_TOOL_PMU_TYPE_PE_CORE_MASK;
++      if (!core_pmu)
++              to_read_pmus |= PERF_TOOL_PMU_TYPE_PE_OTHER_MASK;
++      pmu_read_sysfs(to_read_pmus);
++      return pmu_find(name);
+ }
+ static struct perf_pmu *perf_pmu__find2(int dirfd, const char *name)
+@@ -176,11 +203,11 @@ static struct perf_pmu *perf_pmu__find2(int dirfd, const char *name)
+       if (pmu)
+               return pmu;
+-      if (read_sysfs_all_pmus)
++      if (read_pmu_types == PERF_TOOL_PMU_TYPE_ALL_MASK)
+               return NULL;
+       core_pmu = is_pmu_core(name);
+-      if (core_pmu && read_sysfs_core_pmus)
++      if (core_pmu && (read_pmu_types & PERF_TOOL_PMU_TYPE_PE_CORE_MASK))
+               return NULL;
+       return perf_pmu__lookup(core_pmu ? &core_pmus : &other_pmus, dirfd, name,
+@@ -197,52 +224,60 @@ static int pmus_cmp(void *priv __maybe_unused,
+ }
+ /* Add all pmus in sysfs to pmu list: */
+-static void pmu_read_sysfs(bool core_only)
++static void pmu_read_sysfs(unsigned int to_read_types)
+ {
+-      int fd;
+-      DIR *dir;
+-      struct dirent *dent;
+       struct perf_pmu *tool_pmu;
+-      if (read_sysfs_all_pmus || (core_only && read_sysfs_core_pmus))
++      if ((read_pmu_types & to_read_types) == to_read_types) {
++              /* All requested PMU types have been read. */
+               return;
++      }
+-      fd = perf_pmu__event_source_devices_fd();
+-      if (fd < 0)
+-              return;
++      if (to_read_types & (PERF_TOOL_PMU_TYPE_PE_CORE_MASK | PERF_TOOL_PMU_TYPE_PE_OTHER_MASK)) {
++              int fd = perf_pmu__event_source_devices_fd();
++              DIR *dir;
++              struct dirent *dent;
++              bool core_only = (to_read_types & PERF_TOOL_PMU_TYPE_PE_OTHER_MASK) == 0;
+-      dir = fdopendir(fd);
+-      if (!dir) {
+-              close(fd);
+-              return;
+-      }
++              if (fd < 0)
++                      goto skip_pe_pmus;
+-      while ((dent = readdir(dir))) {
+-              if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
+-                      continue;
+-              if (core_only && !is_pmu_core(dent->d_name))
+-                      continue;
+-              /* add to static LIST_HEAD(core_pmus) or LIST_HEAD(other_pmus): */
+-              perf_pmu__find2(fd, dent->d_name);
+-      }
++              dir = fdopendir(fd);
++              if (!dir) {
++                      close(fd);
++                      goto skip_pe_pmus;
++              }
+-      closedir(dir);
+-      if (list_empty(&core_pmus)) {
++              while ((dent = readdir(dir))) {
++                      if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
++                              continue;
++                      if (core_only && !is_pmu_core(dent->d_name))
++                              continue;
++                      /* add to static LIST_HEAD(core_pmus) or LIST_HEAD(other_pmus): */
++                      perf_pmu__find2(fd, dent->d_name);
++              }
++
++              closedir(dir);
++      }
++skip_pe_pmus:
++      if ((to_read_types & PERF_TOOL_PMU_TYPE_PE_CORE_MASK) && list_empty(&core_pmus)) {
+               if (!perf_pmu__create_placeholder_core_pmu(&core_pmus))
+                       pr_err("Failure to set up any core PMUs\n");
+       }
+       list_sort(NULL, &core_pmus, pmus_cmp);
+-      if (!core_only) {
++
++      if ((to_read_types & PERF_TOOL_PMU_TYPE_TOOL_MASK) != 0 &&
++          (read_pmu_types & PERF_TOOL_PMU_TYPE_TOOL_MASK) == 0) {
+               tool_pmu = perf_pmus__tool_pmu();
+               list_add_tail(&tool_pmu->list, &other_pmus);
+-              perf_pmus__read_hwmon_pmus(&other_pmus);
+       }
++      if ((to_read_types & PERF_TOOL_PMU_TYPE_HWMON_MASK) != 0 &&
++          (read_pmu_types & PERF_TOOL_PMU_TYPE_HWMON_MASK) == 0)
++              perf_pmus__read_hwmon_pmus(&other_pmus);
++
+       list_sort(NULL, &other_pmus, pmus_cmp);
+-      if (!list_empty(&core_pmus)) {
+-              read_sysfs_core_pmus = true;
+-              if (!core_only)
+-                      read_sysfs_all_pmus = true;
+-      }
++
++      read_pmu_types |= to_read_types;
+ }
+ static struct perf_pmu *__perf_pmus__find_by_type(unsigned int type)
+@@ -263,12 +298,21 @@ static struct perf_pmu *__perf_pmus__find_by_type(unsigned int type)
+ struct perf_pmu *perf_pmus__find_by_type(unsigned int type)
+ {
++      unsigned int to_read_pmus;
+       struct perf_pmu *pmu = __perf_pmus__find_by_type(type);
+-      if (pmu || read_sysfs_all_pmus)
++      if (pmu || (read_pmu_types == PERF_TOOL_PMU_TYPE_ALL_MASK))
+               return pmu;
+-      pmu_read_sysfs(/*core_only=*/false);
++      if (type >= PERF_PMU_TYPE_PE_START && type <= PERF_PMU_TYPE_PE_END) {
++              to_read_pmus = PERF_TOOL_PMU_TYPE_PE_CORE_MASK |
++                      PERF_TOOL_PMU_TYPE_PE_OTHER_MASK;
++      } else if (type >= PERF_PMU_TYPE_HWMON_START && type <= PERF_PMU_TYPE_HWMON_END) {
++              to_read_pmus = PERF_TOOL_PMU_TYPE_HWMON_MASK;
++      } else {
++              to_read_pmus = PERF_TOOL_PMU_TYPE_TOOL_MASK;
++      }
++      pmu_read_sysfs(to_read_pmus);
+       pmu = __perf_pmus__find_by_type(type);
+       return pmu;
+ }
+@@ -282,7 +326,7 @@ struct perf_pmu *perf_pmus__scan(struct perf_pmu *pmu)
+       bool use_core_pmus = !pmu || pmu->is_core;
+       if (!pmu) {
+-              pmu_read_sysfs(/*core_only=*/false);
++              pmu_read_sysfs(PERF_TOOL_PMU_TYPE_ALL_MASK);
+               pmu = list_prepare_entry(pmu, &core_pmus, list);
+       }
+       if (use_core_pmus) {
+@@ -300,7 +344,7 @@ struct perf_pmu *perf_pmus__scan(struct perf_pmu *pmu)
+ struct perf_pmu *perf_pmus__scan_core(struct perf_pmu *pmu)
+ {
+       if (!pmu) {
+-              pmu_read_sysfs(/*core_only=*/true);
++              pmu_read_sysfs(PERF_TOOL_PMU_TYPE_PE_CORE_MASK);
+               return list_first_entry_or_null(&core_pmus, typeof(*pmu), list);
+       }
+       list_for_each_entry_continue(pmu, &core_pmus, list)
+@@ -316,7 +360,7 @@ static struct perf_pmu *perf_pmus__scan_skip_duplicates(struct perf_pmu *pmu)
+       const char *last_pmu_name = (pmu && pmu->name) ? pmu->name : "";
+       if (!pmu) {
+-              pmu_read_sysfs(/*core_only=*/false);
++              pmu_read_sysfs(PERF_TOOL_PMU_TYPE_ALL_MASK);
+               pmu = list_prepare_entry(pmu, &core_pmus, list);
+       } else
+               last_pmu_name_len = pmu_name_len_no_suffix(pmu->name ?: "");
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-python-check-if-there-is-space-to-copy-all-the-.patch b/queue-6.14/perf-python-check-if-there-is-space-to-copy-all-the-.patch
new file mode 100644 (file)
index 0000000..fb7fbdd
--- /dev/null
@@ -0,0 +1,68 @@
+From db475438df7ea70f083e37e8aa558d16929214f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Mar 2025 17:31:41 -0300
+Subject: perf python: Check if there is space to copy all the event
+
+From: Arnaldo Carvalho de Melo <acme@redhat.com>
+
+[ Upstream commit 89aaeaf84231157288035b366cb6300c1c6cac64 ]
+
+The pyrf_event__new() method copies the event obtained from the perf
+ring buffer to a structure that will then be turned into a python object
+for further consumption, so it copies perf_event.header.size bytes to
+its 'event' member:
+
+  $ pahole -C pyrf_event /tmp/build/perf-tools-next/python/perf.cpython-312-x86_64-linux-gnu.so
+  struct pyrf_event {
+       PyObject                   ob_base;              /*     0    16 */
+       struct evsel *             evsel;                /*    16     8 */
+       struct perf_sample         sample;               /*    24   312 */
+
+       /* XXX last struct has 7 bytes of padding, 2 holes */
+
+       /* --- cacheline 5 boundary (320 bytes) was 16 bytes ago --- */
+       union perf_event           event;                /*   336  4168 */
+
+       /* size: 4504, cachelines: 71, members: 4 */
+       /* member types with holes: 1, total: 2 */
+       /* paddings: 1, sum paddings: 7 */
+       /* last cacheline: 24 bytes */
+  };
+
+  $
+
+It was doing so without checking if the event just obtained has more
+than that space, fix it.
+
+This isn't a proper, final solution, as we need to support larger
+events, but for the time being we at least bounds check and document it.
+
+Fixes: 877108e42b1b9ba6 ("perf tools: Initial python binding")
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Reviewed-by: Ian Rogers <irogers@google.com>
+Link: https://lore.kernel.org/r/20250312203141.285263-7-acme@kernel.org
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/python.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
+index 016d7ac956d2e..a23fa5d953943 100644
+--- a/tools/perf/util/python.c
++++ b/tools/perf/util/python.c
+@@ -481,6 +481,11 @@ static PyObject *pyrf_event__new(const union perf_event *event)
+             event->header.type == PERF_RECORD_SWITCH_CPU_WIDE))
+               return NULL;
++      // FIXME this better be dynamic or we need to parse everything
++      // before calling perf_mmap__consume(), including tracepoint fields.
++      if (sizeof(pevent->event) < event->header.size)
++              return NULL;
++
+       ptype = pyrf_event__type[event->header.type];
+       pevent = PyObject_New(struct pyrf_event, ptype);
+       if (pevent != NULL)
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-python-decrement-the-refcount-of-just-created-e.patch b/queue-6.14/perf-python-decrement-the-refcount-of-just-created-e.patch
new file mode 100644 (file)
index 0000000..cf8f19c
--- /dev/null
@@ -0,0 +1,52 @@
+From 35078afe2f0a4fb751b7a855707b753afe963616 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Mar 2025 17:31:39 -0300
+Subject: perf python: Decrement the refcount of just created event on failure
+
+From: Arnaldo Carvalho de Melo <acme@redhat.com>
+
+[ Upstream commit 3de5a2bf5b4847f7a59a184568f969f8fe05d57f ]
+
+To avoid a leak if we have the python object but then something happens
+and we need to return the operation, decrement the offset of the newly
+created object.
+
+Fixes: 377f698db12150a1 ("perf python: Add struct evsel into struct pyrf_event")
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Reviewed-by: Ian Rogers <irogers@google.com>
+Link: https://lore.kernel.org/r/20250312203141.285263-5-acme@kernel.org
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/python.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
+index ae6bcd39a2001..5370fff2525f5 100644
+--- a/tools/perf/util/python.c
++++ b/tools/perf/util/python.c
+@@ -984,6 +984,7 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
+               evsel = evlist__event2evsel(evlist, event);
+               if (!evsel) {
++                      Py_DECREF(pyevent);
+                       Py_INCREF(Py_None);
+                       return Py_None;
+               }
+@@ -995,9 +996,12 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
+               /* Consume the even only after we parsed it out. */
+               perf_mmap__consume(&md->core);
+-              if (err)
++              if (err) {
++                      Py_DECREF(pyevent);
+                       return PyErr_Format(PyExc_OSError,
+                                           "perf: can't parse sample, err=%d", err);
++              }
++
+               return pyevent;
+       }
+ end:
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-python-don-t-keep-a-raw_data-pointer-to-consume.patch b/queue-6.14/perf-python-don-t-keep-a-raw_data-pointer-to-consume.patch
new file mode 100644 (file)
index 0000000..a3cbb9c
--- /dev/null
@@ -0,0 +1,86 @@
+From c4869ce287e96816a05f54517c13a4e7bf0acb5d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Mar 2025 17:31:40 -0300
+Subject: perf python: Don't keep a raw_data pointer to consumed ring buffer
+ space
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Arnaldo Carvalho de Melo <acme@redhat.com>
+
+[ Upstream commit f3fed3ae34d606819d87a63d970cc3092a5be7ab ]
+
+When processing tracepoints the perf python binding was parsing the
+event before calling perf_mmap__consume(&md->core) in
+pyrf_evlist__read_on_cpu().
+
+But part of this event parsing was to set the perf_sample->raw_data
+pointer to the payload of the event, which then could be overwritten by
+other event before tracepoint fields were asked for via event.prev_comm
+in a python program, for instance.
+
+This also happened with other fields, but strings were were problems
+were surfacing, as there is UTF-8 validation for the potentially garbled
+data.
+
+This ended up showing up as (with some added debugging messages):
+
+  ( field 'prev_comm' ret=0x7f7c31f65110, raw_size=68 )  ( field 'prev_pid' ret=0x7f7c23b1bed0, raw_size=68 )  ( field 'prev_prio' ret=0x7f7c239c0030, raw_size=68 )  ( field 'prev_state' ret=0x7f7c239c0250, raw_size=68 ) time 14771421785867 prev_comm= prev_pid=1919907691 prev_prio=796026219 prev_state=0x303a32313175 ==>
+  ( XXX '��' len=16, raw_size=68)  ( field 'next_comm' ret=(nil), raw_size=68 ) Traceback (most recent call last):
+   File "/home/acme/git/perf-tools-next/tools/perf/python/tracepoint.py", line 51, in <module>
+     main()
+   File "/home/acme/git/perf-tools-next/tools/perf/python/tracepoint.py", line 46, in main
+     event.next_comm,
+     ^^^^^^^^^^^^^^^
+  AttributeError: 'perf.sample_event' object has no attribute 'next_comm'
+
+When event.next_comm was asked for, the PyUnicode_FromString() python
+API would fail and that tracepoint field wouldn't be available, stopping
+the tools/perf/python/tracepoint.py test tool.
+
+But, since we already do a copy of the whole event in pyrf_event__new,
+just use it and while at it remove what was done in in e8968e654191390a
+("perf python: Fix pyrf_evlist__read_on_cpu event consuming") because we
+don't really need to wait for parsing the sample before declaring the
+event as consumed.
+
+This copy is questionable as is now, as it limits the maximum event +
+sample_type and tracepoint payload to sizeof(union perf_event), this all
+has been "working" because 'struct perf_event_mmap2', the largest entry
+in 'union perf_event' is:
+
+  $ pahole -C perf_event ~/bin/perf | grep mmap2
+       struct perf_record_mmap2   mmap2;              /*     0  4168 */
+  $
+
+Fixes: bae57e3825a3dded ("perf python: Add support to resolve tracepoint fields")
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Reviewed-by: Ian Rogers <irogers@google.com>
+Link: https://lore.kernel.org/r/20250312203141.285263-6-acme@kernel.org
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/python.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
+index 5370fff2525f5..016d7ac956d2e 100644
+--- a/tools/perf/util/python.c
++++ b/tools/perf/util/python.c
+@@ -991,11 +991,9 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
+               pevent->evsel = evsel;
+-              err = evsel__parse_sample(evsel, event, &pevent->sample);
+-
+-              /* Consume the even only after we parsed it out. */
+               perf_mmap__consume(&md->core);
++              err = evsel__parse_sample(evsel, &pevent->event, &pevent->sample);
+               if (err) {
+                       Py_DECREF(pyevent);
+                       return PyErr_Format(PyExc_OSError,
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-python-fixup-description-of-sample.id-event-mem.patch b/queue-6.14/perf-python-fixup-description-of-sample.id-event-mem.patch
new file mode 100644 (file)
index 0000000..12ebdec
--- /dev/null
@@ -0,0 +1,38 @@
+From 4a0d8b4d32e256fcbc7414a72b904085b74b7bfd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Mar 2025 17:31:36 -0300
+Subject: perf python: Fixup description of sample.id event member
+
+From: Arnaldo Carvalho de Melo <acme@redhat.com>
+
+[ Upstream commit 1376c195e8ad327bb9f2d32e0acc5ac39e7cb30a ]
+
+Some old cut'n'paste error, its "ip", so the description should be
+"event ip", not "event type".
+
+Fixes: 877108e42b1b9ba6 ("perf tools: Initial python binding")
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Reviewed-by: Ian Rogers <irogers@google.com>
+Link: https://lore.kernel.org/r/20250312203141.285263-2-acme@kernel.org
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/python.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
+index b4bc57859f730..ae6bcd39a2001 100644
+--- a/tools/perf/util/python.c
++++ b/tools/perf/util/python.c
+@@ -47,7 +47,7 @@ struct pyrf_event {
+ };
+ #define sample_members \
+-      sample_member_def(sample_ip, ip, T_ULONGLONG, "event type"),                     \
++      sample_member_def(sample_ip, ip, T_ULONGLONG, "event ip"),                       \
+       sample_member_def(sample_pid, pid, T_INT, "event pid"),                  \
+       sample_member_def(sample_tid, tid, T_INT, "event tid"),                  \
+       sample_member_def(sample_time, time, T_ULONGLONG, "event timestamp"),            \
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-report-add-parallelism-sort-key.patch b/queue-6.14/perf-report-add-parallelism-sort-key.patch
new file mode 100644 (file)
index 0000000..8cae308
--- /dev/null
@@ -0,0 +1,195 @@
+From 57a34683ceced28522efd04a896ac031b1138064 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Feb 2025 10:08:15 +0100
+Subject: perf report: Add parallelism sort key
+
+From: Dmitry Vyukov <dvyukov@google.com>
+
+[ Upstream commit 7ae1972e748863b0aa04983caf847d4dd5b7e136 ]
+
+Show parallelism level in profiles if requested by user.
+
+Signed-off-by: Dmitry Vyukov <dvyukov@google.com>
+Reviewed-by: Andi Kleen <ak@linux.intel.com>
+Link: https://lore.kernel.org/r/7f7bb87cbaa51bf1fb008a0d68b687423ce4bad4.1739437531.git.dvyukov@google.com
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Stable-dep-of: 6353255e7cfa ("perf report: Fix input reload/switch with symbol sort key")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-report.c | 11 +++++++++++
+ tools/perf/util/hist.c      |  2 ++
+ tools/perf/util/hist.h      |  3 +++
+ tools/perf/util/session.c   | 12 ++++++++++++
+ tools/perf/util/session.h   |  1 +
+ tools/perf/util/sort.c      | 23 +++++++++++++++++++++++
+ tools/perf/util/sort.h      |  1 +
+ 7 files changed, 53 insertions(+)
+
+diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
+index c99b14a852dbd..66b8b1c32e00a 100644
+--- a/tools/perf/builtin-report.c
++++ b/tools/perf/builtin-report.c
+@@ -1719,6 +1719,17 @@ int cmd_report(int argc, const char **argv)
+               symbol_conf.annotate_data_sample = true;
+       }
++      if (report.disable_order || !perf_session__has_switch_events(session)) {
++              if ((sort_order && strstr(sort_order, "parallelism")) ||
++                              (field_order && strstr(field_order, "parallelism"))) {
++                      if (report.disable_order)
++                              ui__error("Use of parallelism is incompatible with --disable-order.\n");
++                      else
++                              ui__error("Use of parallelism requires --switch-events during record.\n");
++                      return -1;
++              }
++      }
++
+       if (sort_order && strstr(sort_order, "ipc")) {
+               parse_options_usage(report_usage, options, "s", 1);
+               goto error;
+diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
+index 0f30f843c566d..cafd693568189 100644
+--- a/tools/perf/util/hist.c
++++ b/tools/perf/util/hist.c
+@@ -207,6 +207,7 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
+       hists__new_col_len(hists, HISTC_CGROUP, 6);
+       hists__new_col_len(hists, HISTC_CGROUP_ID, 20);
++      hists__new_col_len(hists, HISTC_PARALLELISM, 11);
+       hists__new_col_len(hists, HISTC_CPU, 3);
+       hists__new_col_len(hists, HISTC_SOCKET, 6);
+       hists__new_col_len(hists, HISTC_MEM_LOCKED, 6);
+@@ -741,6 +742,7 @@ __hists__add_entry(struct hists *hists,
+               .ip      = al->addr,
+               .level   = al->level,
+               .code_page_size = sample->code_page_size,
++              .parallelism    = al->parallelism,
+               .stat = {
+                       .nr_events = 1,
+                       .period = sample->period,
+diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
+index 46c8373e31465..a6e662d77dc24 100644
+--- a/tools/perf/util/hist.h
++++ b/tools/perf/util/hist.h
+@@ -42,6 +42,7 @@ enum hist_column {
+       HISTC_CGROUP_ID,
+       HISTC_CGROUP,
+       HISTC_PARENT,
++      HISTC_PARALLELISM,
+       HISTC_CPU,
+       HISTC_SOCKET,
+       HISTC_SRCLINE,
+@@ -228,6 +229,7 @@ struct hist_entry {
+       u64                     transaction;
+       s32                     socket;
+       s32                     cpu;
++      int                     parallelism;
+       u64                     code_page_size;
+       u64                     weight;
+       u64                     ins_lat;
+@@ -580,6 +582,7 @@ bool perf_hpp__is_thread_entry(struct perf_hpp_fmt *fmt);
+ bool perf_hpp__is_comm_entry(struct perf_hpp_fmt *fmt);
+ bool perf_hpp__is_dso_entry(struct perf_hpp_fmt *fmt);
+ bool perf_hpp__is_sym_entry(struct perf_hpp_fmt *fmt);
++bool perf_hpp__is_parallelism_entry(struct perf_hpp_fmt *fmt);
+ struct perf_hpp_fmt *perf_hpp_fmt__dup(struct perf_hpp_fmt *fmt);
+diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
+index c06e3020a9769..00fcf8d8ac255 100644
+--- a/tools/perf/util/session.c
++++ b/tools/perf/util/session.c
+@@ -2403,6 +2403,18 @@ bool perf_session__has_traces(struct perf_session *session, const char *msg)
+       return false;
+ }
++bool perf_session__has_switch_events(struct perf_session *session)
++{
++      struct evsel *evsel;
++
++      evlist__for_each_entry(session->evlist, evsel) {
++              if (evsel->core.attr.context_switch)
++                      return true;
++      }
++
++      return false;
++}
++
+ int map__set_kallsyms_ref_reloc_sym(struct map *map, const char *symbol_name, u64 addr)
+ {
+       char *bracket;
+diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
+index bcf1bcf06959b..db1c120a9e67f 100644
+--- a/tools/perf/util/session.h
++++ b/tools/perf/util/session.h
+@@ -141,6 +141,7 @@ int perf_session__resolve_callchain(struct perf_session *session,
+                                   struct symbol **parent);
+ bool perf_session__has_traces(struct perf_session *session, const char *msg);
++bool perf_session__has_switch_events(struct perf_session *session);
+ void perf_event__attr_swap(struct perf_event_attr *attr);
+diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
+index 3dd33721823f3..7eef43f5be360 100644
+--- a/tools/perf/util/sort.c
++++ b/tools/perf/util/sort.c
+@@ -892,6 +892,27 @@ struct sort_entry sort_cpu = {
+       .se_width_idx   = HISTC_CPU,
+ };
++/* --sort parallelism */
++
++static int64_t
++sort__parallelism_cmp(struct hist_entry *left, struct hist_entry *right)
++{
++      return right->parallelism - left->parallelism;
++}
++
++static int hist_entry__parallelism_snprintf(struct hist_entry *he, char *bf,
++                                  size_t size, unsigned int width)
++{
++      return repsep_snprintf(bf, size, "%*d", width, he->parallelism);
++}
++
++struct sort_entry sort_parallelism = {
++      .se_header      = "Parallelism",
++      .se_cmp         = sort__parallelism_cmp,
++      .se_snprintf    = hist_entry__parallelism_snprintf,
++      .se_width_idx   = HISTC_PARALLELISM,
++};
++
+ /* --sort cgroup_id */
+ static int64_t _sort__cgroup_dev_cmp(u64 left_dev, u64 right_dev)
+@@ -2534,6 +2555,7 @@ static struct sort_dimension common_sort_dimensions[] = {
+       DIM(SORT_ANNOTATE_DATA_TYPE_OFFSET, "typeoff", sort_type_offset),
+       DIM(SORT_SYM_OFFSET, "symoff", sort_sym_offset),
+       DIM(SORT_ANNOTATE_DATA_TYPE_CACHELINE, "typecln", sort_type_cacheline),
++      DIM(SORT_PARALLELISM, "parallelism", sort_parallelism),
+ };
+ #undef DIM
+@@ -2735,6 +2757,7 @@ MK_SORT_ENTRY_CHK(thread)
+ MK_SORT_ENTRY_CHK(comm)
+ MK_SORT_ENTRY_CHK(dso)
+ MK_SORT_ENTRY_CHK(sym)
++MK_SORT_ENTRY_CHK(parallelism)
+ static bool __sort__hpp_equal(struct perf_hpp_fmt *a, struct perf_hpp_fmt *b)
+diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
+index a8572574e1686..11fb15f914093 100644
+--- a/tools/perf/util/sort.h
++++ b/tools/perf/util/sort.h
+@@ -72,6 +72,7 @@ enum sort_type {
+       SORT_ANNOTATE_DATA_TYPE_OFFSET,
+       SORT_SYM_OFFSET,
+       SORT_ANNOTATE_DATA_TYPE_CACHELINE,
++      SORT_PARALLELISM,
+       /* branch stack specific sort keys */
+       __SORT_BRANCH_STACK,
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-report-fix-input-reload-switch-with-symbol-sort.patch b/queue-6.14/perf-report-fix-input-reload-switch-with-symbol-sort.patch
new file mode 100644 (file)
index 0000000..deb195c
--- /dev/null
@@ -0,0 +1,69 @@
+From 6f38743deaeb22c04bb2d98f5a9fe105b086ed5f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jan 2025 07:36:23 +0100
+Subject: perf report: Fix input reload/switch with symbol sort key
+
+From: Dmitry Vyukov <dvyukov@google.com>
+
+[ Upstream commit 6353255e7cfab568058580424fa0967bf4504fe5 ]
+
+Currently the code checks that there is no "ipc" in the sort order
+and add an ipc string. This will always error out on the second pass
+after input reload/switch, since the sort order already contains "ipc".
+Do the ipc check/fixup only on the first pass.
+
+Signed-off-by: Dmitry Vyukov <dvyukov@google.com>
+Link: https://lore.kernel.org/r/20250108063628.215577-1-dvyukov@google.com
+Fixes: ec6ae74fe8f0 ("perf report: Display average IPC and IPC coverage per symbol")
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-report.c | 30 ++++++++++++++++--------------
+ 1 file changed, 16 insertions(+), 14 deletions(-)
+
+diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
+index 66b8b1c32e00a..e74d8a6cfa5ae 100644
+--- a/tools/perf/builtin-report.c
++++ b/tools/perf/builtin-report.c
+@@ -1730,22 +1730,24 @@ int cmd_report(int argc, const char **argv)
+               }
+       }
+-      if (sort_order && strstr(sort_order, "ipc")) {
+-              parse_options_usage(report_usage, options, "s", 1);
+-              goto error;
+-      }
+-
+-      if (sort_order && strstr(sort_order, "symbol")) {
+-              if (sort__mode == SORT_MODE__BRANCH) {
+-                      snprintf(sort_tmp, sizeof(sort_tmp), "%s,%s",
+-                               sort_order, "ipc_lbr");
+-                      report.symbol_ipc = true;
+-              } else {
+-                      snprintf(sort_tmp, sizeof(sort_tmp), "%s,%s",
+-                               sort_order, "ipc_null");
++      if (last_key != K_SWITCH_INPUT_DATA) {
++              if (sort_order && strstr(sort_order, "ipc")) {
++                      parse_options_usage(report_usage, options, "s", 1);
++                      goto error;
+               }
+-              sort_order = sort_tmp;
++              if (sort_order && strstr(sort_order, "symbol")) {
++                      if (sort__mode == SORT_MODE__BRANCH) {
++                              snprintf(sort_tmp, sizeof(sort_tmp), "%s,%s",
++                                       sort_order, "ipc_lbr");
++                              report.symbol_ipc = true;
++                      } else {
++                              snprintf(sort_tmp, sizeof(sort_tmp), "%s,%s",
++                                       sort_order, "ipc_null");
++                      }
++
++                      sort_order = sort_tmp;
++              }
+       }
+       if ((last_key != K_SWITCH_INPUT_DATA && last_key != K_RELOAD) &&
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-report-switch-data-file-correctly-in-tui.patch b/queue-6.14/perf-report-switch-data-file-correctly-in-tui.patch
new file mode 100644 (file)
index 0000000..4356950
--- /dev/null
@@ -0,0 +1,48 @@
+From 4d4a4c92e9cbbd5f93bebf4a3dc36c1d0d41cc90 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Feb 2025 22:07:44 -0800
+Subject: perf report: Switch data file correctly in TUI
+
+From: Namhyung Kim <namhyung@kernel.org>
+
+[ Upstream commit 43c2b6139b188d8a756130147f7efd5ddf99f88d ]
+
+The 's' key is to switch to a new data file and load the data in the
+same window.  The switch_data_file() will show a popup menu to select
+which data file user wants and update the 'input_name' global variable.
+
+But in the cmd_report(), it didn't update the data.path using the new
+'input_name' and keep usng the old file.  This is fairly an old bug and
+I assume people don't use this feature much. :)
+
+Link: https://lore.kernel.org/r/20250211060745.294289-1-namhyung@kernel.org
+Closes: https://lore.kernel.org/linux-perf-users/89e678bc-f0af-4929-a8a6-a2666f1294a4@linaro.org
+Fixes: f5fc14124c5cefdd ("perf tools: Add data object to handle perf data file")
+Reported-by: James Clark <james.clark@linaro.org>
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-report.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
+index f5fbd670d619a..c99b14a852dbd 100644
+--- a/tools/perf/builtin-report.c
++++ b/tools/perf/builtin-report.c
+@@ -1553,12 +1553,12 @@ int cmd_report(int argc, const char **argv)
+                       input_name = "perf.data";
+       }
++repeat:
+       data.path  = input_name;
+       data.force = symbol_conf.force;
+       symbol_conf.skip_empty = report.skip_empty;
+-repeat:
+       perf_tool__init(&report.tool, ordered_events);
+       report.tool.sample               = process_sample_event;
+       report.tool.mmap                 = perf_event__process_mmap;
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-ring_buffer-allow-the-epollrdnorm-flag-for-poll.patch b/queue-6.14/perf-ring_buffer-allow-the-epollrdnorm-flag-for-poll.patch
new file mode 100644 (file)
index 0000000..661e497
--- /dev/null
@@ -0,0 +1,43 @@
+From 2671e79f1df562890d6c2769c42575b5ebc5731d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Mar 2025 11:00:36 +0800
+Subject: perf/ring_buffer: Allow the EPOLLRDNORM flag for poll
+
+From: Tao Chen <chen.dylane@linux.dev>
+
+[ Upstream commit c96fff391c095c11dc87dab35be72dee7d217cde ]
+
+The poll man page says POLLRDNORM is equivalent to POLLIN. For poll(),
+it seems that if user sets pollfd with POLLRDNORM in userspace, perf_poll
+will not return until timeout even if perf_output_wakeup called,
+whereas POLLIN returns.
+
+Fixes: 76369139ceb9 ("perf: Split up buffer handling from core code")
+Signed-off-by: Tao Chen <chen.dylane@linux.dev>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
+Cc: "H. Peter Anvin" <hpa@zytor.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Link: https://lore.kernel.org/r/20250314030036.2543180-1-chen.dylane@linux.dev
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/events/ring_buffer.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c
+index 180509132d4b6..09459647cb822 100644
+--- a/kernel/events/ring_buffer.c
++++ b/kernel/events/ring_buffer.c
+@@ -19,7 +19,7 @@
+ static void perf_output_wakeup(struct perf_output_handle *handle)
+ {
+-      atomic_set(&handle->rb->poll, EPOLLIN);
++      atomic_set(&handle->rb->poll, EPOLLIN | EPOLLRDNORM);
+       handle->event->pending_wakeup = 1;
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-save-pmu-specific-data-in-task_struct.patch b/queue-6.14/perf-save-pmu-specific-data-in-task_struct.patch
new file mode 100644 (file)
index 0000000..68b420e
--- /dev/null
@@ -0,0 +1,170 @@
+From 6ca13247c58250525645a5ec2bb0e2a61b7b16ca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Mar 2025 10:26:54 -0700
+Subject: perf: Save PMU specific data in task_struct
+
+From: Kan Liang <kan.liang@linux.intel.com>
+
+[ Upstream commit cb4369129339060218baca718a578bb0b826e734 ]
+
+Some PMU specific data has to be saved/restored during context switch,
+e.g. LBR call stack data. Currently, the data is saved in event context
+structure, but only for per-process event. For system-wide event,
+because of missing the LBR call stack data after context switch, LBR
+callstacks are always shorter in comparison to per-process mode.
+
+For example,
+  Per-process mode:
+  $perf record --call-graph lbr -- taskset -c 0 ./tchain_edit
+
+  -   99.90%    99.86%  tchain_edit  tchain_edit       [.] f3
+       99.86% _start
+          __libc_start_main
+          generic_start_main
+          main
+          f1
+        - f2
+             f3
+
+  System-wide mode:
+  $perf record --call-graph lbr -a -- taskset -c 0 ./tchain_edit
+
+  -   99.88%    99.82%  tchain_edit  tchain_edit        [.] f3
+   - 62.02% main
+        f1
+        f2
+        f3
+   - 28.83% f1
+      - f2
+        f3
+   - 28.83% f1
+      - f2
+           f3
+   - 8.88% generic_start_main
+        main
+        f1
+        f2
+        f3
+
+It isn't practical to simply allocate the data for system-wide event in
+CPU context structure for all tasks. We have no idea which CPU a task
+will be scheduled to. The duplicated LBR data has to be maintained on
+every CPU context structure. That's a huge waste. Otherwise, the LBR
+data still lost if the task is scheduled to another CPU.
+
+Save the pmu specific data in task_struct. The size of pmu specific data
+is 788 bytes for LBR call stack. Usually, the overall amount of threads
+doesn't exceed a few thousands. For 10K threads, keeping LBR data would
+consume additional ~8MB. The additional space will only be allocated
+during LBR call stack monitoring. It will be released when the
+monitoring is finished.
+
+Furthermore, moving task_ctx_data from perf_event_context to task_struct
+can reduce complexity and make things clearer. E.g. perf doesn't need to
+swap task_ctx_data on optimized context switch path.
+This patch set is just the first step. There could be other
+optimization/extension on top of this patch set. E.g. for cgroup
+profiling, perf just needs to save/store the LBR call stack information
+for tasks in specific cgroup. That could reduce the additional space.
+Also, the LBR call stack can be available for software events, or allow
+even debugging use cases, like LBRs on crash later.
+
+Because of the alignment requirement of Intel Arch LBR, the Kmem cache
+is used to allocate the PMU specific data. It's required when child task
+allocates the space. Save it in struct perf_ctx_data.
+The refcount in struct perf_ctx_data is used to track the users of pmu
+specific data.
+
+Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Alexey Budankov <alexey.budankov@linux.intel.com>
+Link: https://lore.kernel.org/r/20250314172700.438923-1-kan.liang@linux.intel.com
+Stable-dep-of: 3cec9fd03543 ("perf/x86/lbr: Fix shorter LBRs call stacks for the system-wide mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/perf_event.h | 35 +++++++++++++++++++++++++++++++++++
+ include/linux/sched.h      |  2 ++
+ kernel/events/core.c       |  1 +
+ 3 files changed, 38 insertions(+)
+
+diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
+index 8333f132f4a96..852ea843bca27 100644
+--- a/include/linux/perf_event.h
++++ b/include/linux/perf_event.h
+@@ -1020,6 +1020,41 @@ struct perf_event_context {
+       local_t                         nr_no_switch_fast;
+ };
++/**
++ * struct perf_ctx_data - PMU specific data for a task
++ * @rcu_head:  To avoid the race on free PMU specific data
++ * @refcount:  To track users
++ * @global:    To track system-wide users
++ * @ctx_cache: Kmem cache of PMU specific data
++ * @data:      PMU specific data
++ *
++ * Currently, the struct is only used in Intel LBR call stack mode to
++ * save/restore the call stack of a task on context switches.
++ *
++ * The rcu_head is used to prevent the race on free the data.
++ * The data only be allocated when Intel LBR call stack mode is enabled.
++ * The data will be freed when the mode is disabled.
++ * The content of the data will only be accessed in context switch, which
++ * should be protected by rcu_read_lock().
++ *
++ * Because of the alignment requirement of Intel Arch LBR, the Kmem cache
++ * is used to allocate the PMU specific data. The ctx_cache is to track
++ * the Kmem cache.
++ *
++ * Careful: Struct perf_ctx_data is added as a pointer in struct task_struct.
++ * When system-wide Intel LBR call stack mode is enabled, a buffer with
++ * constant size will be allocated for each task.
++ * Also, system memory consumption can further grow when the size of
++ * struct perf_ctx_data enlarges.
++ */
++struct perf_ctx_data {
++      struct rcu_head                 rcu_head;
++      refcount_t                      refcount;
++      int                             global;
++      struct kmem_cache               *ctx_cache;
++      void                            *data;
++};
++
+ struct perf_cpu_pmu_context {
+       struct perf_event_pmu_context   epc;
+       struct perf_event_pmu_context   *task_epc;
+diff --git a/include/linux/sched.h b/include/linux/sched.h
+index 9c15365a30c08..b13c9545d5d67 100644
+--- a/include/linux/sched.h
++++ b/include/linux/sched.h
+@@ -65,6 +65,7 @@ struct mempolicy;
+ struct nameidata;
+ struct nsproxy;
+ struct perf_event_context;
++struct perf_ctx_data;
+ struct pid_namespace;
+ struct pipe_inode_info;
+ struct rcu_node;
+@@ -1311,6 +1312,7 @@ struct task_struct {
+       struct perf_event_context       *perf_event_ctxp;
+       struct mutex                    perf_event_mutex;
+       struct list_head                perf_event_list;
++      struct perf_ctx_data __rcu      *perf_ctx_data;
+ #endif
+ #ifdef CONFIG_DEBUG_PREEMPT
+       unsigned long                   preempt_disable_ip;
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index 823aa08249161..eb359be7ec793 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -14002,6 +14002,7 @@ int perf_event_init_task(struct task_struct *child, u64 clone_flags)
+       child->perf_event_ctxp = NULL;
+       mutex_init(&child->perf_event_mutex);
+       INIT_LIST_HEAD(&child->perf_event_list);
++      child->perf_ctx_data = NULL;
+       ret = perf_event_init_context(child, clone_flags);
+       if (ret) {
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-stat-don-t-merge-counters-purely-on-name.patch b/queue-6.14/perf-stat-don-t-merge-counters-purely-on-name.patch
new file mode 100644 (file)
index 0000000..f90c084
--- /dev/null
@@ -0,0 +1,70 @@
+From 4052f6b655c2ae9cb2de448fcc9c0a2a44284577 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Jan 2025 23:43:19 -0800
+Subject: perf stat: Don't merge counters purely on name
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 2d9961c690d299893735783a2077e866f2d46a56 ]
+
+Counter merging was added in commit 942c5593393d ("perf stat: Add
+perf_stat_merge_counters()"), however, it merges events with the same
+name on different PMUs regardless of whether the different PMUs are
+actually of the same type (ie they differ only in the suffix on the
+PMU). For hwmon events there may be a temp1 event on every PMU, but
+the PMU names are all unique and don't differ just by a suffix. The
+merging is over eager and will merge all the hwmon counters together
+meaning an aggregated and very large temp1 value is shown. The same
+would be true for say cache events and memory controller events where
+the PMUs differ but the event names are the same.
+
+Fix the problem by correctly saying two PMUs alias when they differ
+only by suffix.
+
+Note, there is an overlap with evsel's merged_stat with aggregation
+and the evsel's metric_leader where aggregation happens for metrics.
+
+Fixes: 942c5593393d ("perf stat: Add perf_stat_merge_counters()")
+Signed-off-by: Ian Rogers <irogers@google.com>
+Reviewed-by: Kan Liang <kan.liang@linux.intel.com>
+Link: https://lore.kernel.org/r/20250201074320.746259-5-irogers@google.com
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/stat.c | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
+index 7c2ccdcc3fdba..1f7abd8754c75 100644
+--- a/tools/perf/util/stat.c
++++ b/tools/perf/util/stat.c
+@@ -535,7 +535,10 @@ static int evsel__merge_aggr_counters(struct evsel *evsel, struct evsel *alias)
+       return 0;
+ }
+-/* events should have the same name, scale, unit, cgroup but on different PMUs */
++/*
++ * Events should have the same name, scale, unit, cgroup but on different core
++ * PMUs or on different but matching uncore PMUs.
++ */
+ static bool evsel__is_alias(struct evsel *evsel_a, struct evsel *evsel_b)
+ {
+       if (strcmp(evsel__name(evsel_a), evsel__name(evsel_b)))
+@@ -553,7 +556,13 @@ static bool evsel__is_alias(struct evsel *evsel_a, struct evsel *evsel_b)
+       if (evsel__is_clock(evsel_a) != evsel__is_clock(evsel_b))
+               return false;
+-      return evsel_a->pmu != evsel_b->pmu;
++      if (evsel_a->pmu == evsel_b->pmu || evsel_a->pmu == NULL || evsel_b->pmu == NULL)
++              return false;
++
++      if (evsel_a->pmu->is_core)
++              return evsel_b->pmu->is_core;
++
++      return perf_pmu__name_no_suffix_match(evsel_a->pmu, evsel_b->pmu->name);
+ }
+ static void evsel__merge_aliases(struct evsel *evsel)
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-stat-fix-find_stat-for-mixed-legacy-non-legacy-.patch b/queue-6.14/perf-stat-fix-find_stat-for-mixed-legacy-non-legacy-.patch
new file mode 100644 (file)
index 0000000..f22abaa
--- /dev/null
@@ -0,0 +1,107 @@
+From 1845cef5516f3bead678011f532e286602d8db3b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jan 2025 14:21:07 -0800
+Subject: perf stat: Fix find_stat for mixed legacy/non-legacy events
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 8ce0d2da14d3fb62844dd0e95982c194326b1a5f ]
+
+Legacy events typically don't have a PMU when added leading to
+mismatched legacy/non-legacy cases in find_stat. Use evsel__find_pmu
+to make sure the evsel PMU is looked up. Update the evsel__find_pmu
+code to look for the PMU using the extended config type or, for legacy
+hardware/hw_cache events on non-hybrid systems, just use the core PMU.
+
+Before:
+```
+$ perf stat -e cycles,cpu/instructions/ -a sleep 1
+ Performance counter stats for 'system wide':
+
+       215,309,764      cycles
+        44,326,491      cpu/instructions/
+
+       1.002555314 seconds time elapsed
+```
+After:
+```
+$ perf stat -e cycles,cpu/instructions/ -a sleep 1
+
+ Performance counter stats for 'system wide':
+
+       990,676,332      cycles
+     1,235,762,487      cpu/instructions/                #    1.25  insn per cycle
+
+       1.002667198 seconds time elapsed
+```
+
+Fixes: 3612ca8e2935 ("perf stat: Fix the hard-coded metrics calculation on the hybrid")
+Signed-off-by: Ian Rogers <irogers@google.com>
+Tested-by: James Clark <james.clark@linaro.org>
+Tested-by: Leo Yan <leo.yan@arm.com>
+Tested-by: Atish Patra <atishp@rivosinc.com>
+Link: https://lore.kernel.org/r/20250109222109.567031-3-irogers@google.com
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/pmus.c        | 20 +++++++++++++++++---
+ tools/perf/util/stat-shadow.c |  3 ++-
+ 2 files changed, 19 insertions(+), 4 deletions(-)
+
+diff --git a/tools/perf/util/pmus.c b/tools/perf/util/pmus.c
+index b493da0d22ef7..60d81d69503e3 100644
+--- a/tools/perf/util/pmus.c
++++ b/tools/perf/util/pmus.c
+@@ -710,11 +710,25 @@ char *perf_pmus__default_pmu_name(void)
+ struct perf_pmu *evsel__find_pmu(const struct evsel *evsel)
+ {
+       struct perf_pmu *pmu = evsel->pmu;
++      bool legacy_core_type;
+-      if (!pmu) {
+-              pmu = perf_pmus__find_by_type(evsel->core.attr.type);
+-              ((struct evsel *)evsel)->pmu = pmu;
++      if (pmu)
++              return pmu;
++
++      pmu = perf_pmus__find_by_type(evsel->core.attr.type);
++      legacy_core_type =
++              evsel->core.attr.type == PERF_TYPE_HARDWARE ||
++              evsel->core.attr.type == PERF_TYPE_HW_CACHE;
++      if (!pmu && legacy_core_type) {
++              if (perf_pmus__supports_extended_type()) {
++                      u32 type = evsel->core.attr.config >> PERF_PMU_TYPE_SHIFT;
++
++                      pmu = perf_pmus__find_by_type(type);
++              } else {
++                      pmu = perf_pmus__find_core_pmu();
++              }
+       }
++      ((struct evsel *)evsel)->pmu = pmu;
+       return pmu;
+ }
+diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
+index fa8b2a1048ff9..d83bda5824d22 100644
+--- a/tools/perf/util/stat-shadow.c
++++ b/tools/perf/util/stat-shadow.c
+@@ -151,6 +151,7 @@ static double find_stat(const struct evsel *evsel, int aggr_idx, enum stat_type
+ {
+       struct evsel *cur;
+       int evsel_ctx = evsel_context(evsel);
++      struct perf_pmu *evsel_pmu = evsel__find_pmu(evsel);
+       evlist__for_each_entry(evsel->evlist, cur) {
+               struct perf_stat_aggr *aggr;
+@@ -177,7 +178,7 @@ static double find_stat(const struct evsel *evsel, int aggr_idx, enum stat_type
+                * Except the SW CLOCK events,
+                * ignore if not the PMU we're looking for.
+                */
+-              if ((type != STAT_NSECS) && (evsel->pmu != cur->pmu))
++              if ((type != STAT_NSECS) && (evsel_pmu != evsel__find_pmu(cur)))
+                       continue;
+               aggr = &cur->stats->aggr[aggr_idx];
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-supply-task-information-to-sched_task.patch b/queue-6.14/perf-supply-task-information-to-sched_task.patch
new file mode 100644 (file)
index 0000000..ee1888f
--- /dev/null
@@ -0,0 +1,323 @@
+From 3f9eb283032f1fe38c0cbd41d1083d895ee8d5a9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Mar 2025 10:26:57 -0700
+Subject: perf: Supply task information to sched_task()
+
+From: Kan Liang <kan.liang@linux.intel.com>
+
+[ Upstream commit d57e94f5b891925e4f2796266eba31edd5a01903 ]
+
+To save/restore LBR call stack data in system-wide mode, the task_struct
+information is required.
+
+Extend the parameters of sched_task() to supply task_struct information.
+
+When schedule in, the LBR call stack data for new task will be restored.
+When schedule out, the LBR call stack data for old task will be saved.
+Only need to pass the required task_struct information.
+
+Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20250314172700.438923-4-kan.liang@linux.intel.com
+Stable-dep-of: 3cec9fd03543 ("perf/x86/lbr: Fix shorter LBRs call stacks for the system-wide mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/perf/core-book3s.c    |  8 ++++++--
+ arch/s390/kernel/perf_pai_crypto.c |  3 ++-
+ arch/s390/kernel/perf_pai_ext.c    |  3 ++-
+ arch/x86/events/amd/brs.c          |  3 ++-
+ arch/x86/events/amd/lbr.c          |  3 ++-
+ arch/x86/events/core.c             |  5 +++--
+ arch/x86/events/intel/core.c       |  4 ++--
+ arch/x86/events/intel/lbr.c        |  3 ++-
+ arch/x86/events/perf_event.h       | 14 +++++++++-----
+ include/linux/perf_event.h         |  2 +-
+ kernel/events/core.c               | 20 +++++++++++---------
+ 11 files changed, 42 insertions(+), 26 deletions(-)
+
+diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
+index 2b79171ee185b..f4e03aaabb4c3 100644
+--- a/arch/powerpc/perf/core-book3s.c
++++ b/arch/powerpc/perf/core-book3s.c
+@@ -132,7 +132,10 @@ static unsigned long ebb_switch_in(bool ebb, struct cpu_hw_events *cpuhw)
+ static inline void power_pmu_bhrb_enable(struct perf_event *event) {}
+ static inline void power_pmu_bhrb_disable(struct perf_event *event) {}
+-static void power_pmu_sched_task(struct perf_event_pmu_context *pmu_ctx, bool sched_in) {}
++static void power_pmu_sched_task(struct perf_event_pmu_context *pmu_ctx,
++                               struct task_struct *task, bool sched_in)
++{
++}
+ static inline void power_pmu_bhrb_read(struct perf_event *event, struct cpu_hw_events *cpuhw) {}
+ static void pmao_restore_workaround(bool ebb) { }
+ #endif /* CONFIG_PPC32 */
+@@ -444,7 +447,8 @@ static void power_pmu_bhrb_disable(struct perf_event *event)
+ /* Called from ctxsw to prevent one process's branch entries to
+  * mingle with the other process's entries during context switch.
+  */
+-static void power_pmu_sched_task(struct perf_event_pmu_context *pmu_ctx, bool sched_in)
++static void power_pmu_sched_task(struct perf_event_pmu_context *pmu_ctx,
++                               struct task_struct *task, bool sched_in)
+ {
+       if (!ppmu->bhrb_nr)
+               return;
+diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c
+index 10725f5a6f0fd..63875270941bc 100644
+--- a/arch/s390/kernel/perf_pai_crypto.c
++++ b/arch/s390/kernel/perf_pai_crypto.c
+@@ -518,7 +518,8 @@ static void paicrypt_have_samples(void)
+ /* Called on schedule-in and schedule-out. No access to event structure,
+  * but for sampling only event CRYPTO_ALL is allowed.
+  */
+-static void paicrypt_sched_task(struct perf_event_pmu_context *pmu_ctx, bool sched_in)
++static void paicrypt_sched_task(struct perf_event_pmu_context *pmu_ctx,
++                              struct task_struct *task, bool sched_in)
+ {
+       /* We started with a clean page on event installation. So read out
+        * results on schedule_out and if page was dirty, save old values.
+diff --git a/arch/s390/kernel/perf_pai_ext.c b/arch/s390/kernel/perf_pai_ext.c
+index a8f0bad99cf04..fd14d5ebccbca 100644
+--- a/arch/s390/kernel/perf_pai_ext.c
++++ b/arch/s390/kernel/perf_pai_ext.c
+@@ -542,7 +542,8 @@ static void paiext_have_samples(void)
+ /* Called on schedule-in and schedule-out. No access to event structure,
+  * but for sampling only event NNPA_ALL is allowed.
+  */
+-static void paiext_sched_task(struct perf_event_pmu_context *pmu_ctx, bool sched_in)
++static void paiext_sched_task(struct perf_event_pmu_context *pmu_ctx,
++                            struct task_struct *task, bool sched_in)
+ {
+       /* We started with a clean page on event installation. So read out
+        * results on schedule_out and if page was dirty, save old values.
+diff --git a/arch/x86/events/amd/brs.c b/arch/x86/events/amd/brs.c
+index 780acd3dff22a..ec34274633824 100644
+--- a/arch/x86/events/amd/brs.c
++++ b/arch/x86/events/amd/brs.c
+@@ -381,7 +381,8 @@ static void amd_brs_poison_buffer(void)
+  * On ctxswin, sched_in = true, called after the PMU has started
+  * On ctxswout, sched_in = false, called before the PMU is stopped
+  */
+-void amd_pmu_brs_sched_task(struct perf_event_pmu_context *pmu_ctx, bool sched_in)
++void amd_pmu_brs_sched_task(struct perf_event_pmu_context *pmu_ctx,
++                          struct task_struct *task, bool sched_in)
+ {
+       struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+diff --git a/arch/x86/events/amd/lbr.c b/arch/x86/events/amd/lbr.c
+index 19c7b76e21bcb..c06ccca96851f 100644
+--- a/arch/x86/events/amd/lbr.c
++++ b/arch/x86/events/amd/lbr.c
+@@ -371,7 +371,8 @@ void amd_pmu_lbr_del(struct perf_event *event)
+       perf_sched_cb_dec(event->pmu);
+ }
+-void amd_pmu_lbr_sched_task(struct perf_event_pmu_context *pmu_ctx, bool sched_in)
++void amd_pmu_lbr_sched_task(struct perf_event_pmu_context *pmu_ctx,
++                          struct task_struct *task, bool sched_in)
+ {
+       struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
+index 2092d615333da..3a27c50080f4f 100644
+--- a/arch/x86/events/core.c
++++ b/arch/x86/events/core.c
+@@ -2625,9 +2625,10 @@ static const struct attribute_group *x86_pmu_attr_groups[] = {
+       NULL,
+ };
+-static void x86_pmu_sched_task(struct perf_event_pmu_context *pmu_ctx, bool sched_in)
++static void x86_pmu_sched_task(struct perf_event_pmu_context *pmu_ctx,
++                             struct task_struct *task, bool sched_in)
+ {
+-      static_call_cond(x86_pmu_sched_task)(pmu_ctx, sched_in);
++      static_call_cond(x86_pmu_sched_task)(pmu_ctx, task, sched_in);
+ }
+ static void x86_pmu_swap_task_ctx(struct perf_event_pmu_context *prev_epc,
+diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
+index cdb19e3ba3aa3..f5eea63013b9b 100644
+--- a/arch/x86/events/intel/core.c
++++ b/arch/x86/events/intel/core.c
+@@ -5244,10 +5244,10 @@ static void intel_pmu_cpu_dead(int cpu)
+ }
+ static void intel_pmu_sched_task(struct perf_event_pmu_context *pmu_ctx,
+-                               bool sched_in)
++                               struct task_struct *task, bool sched_in)
+ {
+       intel_pmu_pebs_sched_task(pmu_ctx, sched_in);
+-      intel_pmu_lbr_sched_task(pmu_ctx, sched_in);
++      intel_pmu_lbr_sched_task(pmu_ctx, task, sched_in);
+ }
+ static void intel_pmu_swap_task_ctx(struct perf_event_pmu_context *prev_epc,
+diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
+index dc641b50814e2..dafeee216f3b6 100644
+--- a/arch/x86/events/intel/lbr.c
++++ b/arch/x86/events/intel/lbr.c
+@@ -539,7 +539,8 @@ void intel_pmu_lbr_swap_task_ctx(struct perf_event_pmu_context *prev_epc,
+            task_context_opt(next_ctx_data)->lbr_callstack_users);
+ }
+-void intel_pmu_lbr_sched_task(struct perf_event_pmu_context *pmu_ctx, bool sched_in)
++void intel_pmu_lbr_sched_task(struct perf_event_pmu_context *pmu_ctx,
++                            struct task_struct *task, bool sched_in)
+ {
+       struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+       void *task_ctx;
+diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
+index 31c2771545a6c..ce7c98364d5b6 100644
+--- a/arch/x86/events/perf_event.h
++++ b/arch/x86/events/perf_event.h
+@@ -869,7 +869,7 @@ struct x86_pmu {
+       void            (*check_microcode)(void);
+       void            (*sched_task)(struct perf_event_pmu_context *pmu_ctx,
+-                                    bool sched_in);
++                                    struct task_struct *task, bool sched_in);
+       /*
+        * Intel Arch Perfmon v2+
+@@ -1394,7 +1394,8 @@ void amd_pmu_lbr_reset(void);
+ void amd_pmu_lbr_read(void);
+ void amd_pmu_lbr_add(struct perf_event *event);
+ void amd_pmu_lbr_del(struct perf_event *event);
+-void amd_pmu_lbr_sched_task(struct perf_event_pmu_context *pmu_ctx, bool sched_in);
++void amd_pmu_lbr_sched_task(struct perf_event_pmu_context *pmu_ctx,
++                          struct task_struct *task, bool sched_in);
+ void amd_pmu_lbr_enable_all(void);
+ void amd_pmu_lbr_disable_all(void);
+ int amd_pmu_lbr_hw_config(struct perf_event *event);
+@@ -1448,7 +1449,8 @@ static inline void amd_pmu_brs_del(struct perf_event *event)
+       perf_sched_cb_dec(event->pmu);
+ }
+-void amd_pmu_brs_sched_task(struct perf_event_pmu_context *pmu_ctx, bool sched_in);
++void amd_pmu_brs_sched_task(struct perf_event_pmu_context *pmu_ctx,
++                          struct task_struct *task, bool sched_in);
+ #else
+ static inline int amd_brs_init(void)
+ {
+@@ -1473,7 +1475,8 @@ static inline void amd_pmu_brs_del(struct perf_event *event)
+ {
+ }
+-static inline void amd_pmu_brs_sched_task(struct perf_event_pmu_context *pmu_ctx, bool sched_in)
++static inline void amd_pmu_brs_sched_task(struct perf_event_pmu_context *pmu_ctx,
++                                        struct task_struct *task, bool sched_in)
+ {
+ }
+@@ -1656,7 +1659,8 @@ void intel_pmu_lbr_save_brstack(struct perf_sample_data *data,
+ void intel_pmu_lbr_swap_task_ctx(struct perf_event_pmu_context *prev_epc,
+                                struct perf_event_pmu_context *next_epc);
+-void intel_pmu_lbr_sched_task(struct perf_event_pmu_context *pmu_ctx, bool sched_in);
++void intel_pmu_lbr_sched_task(struct perf_event_pmu_context *pmu_ctx,
++                            struct task_struct *task, bool sched_in);
+ u64 lbr_from_signext_quirk_wr(u64 val);
+diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
+index 852ea843bca27..bcb764c3a8034 100644
+--- a/include/linux/perf_event.h
++++ b/include/linux/perf_event.h
+@@ -495,7 +495,7 @@ struct pmu {
+        * context-switches callback
+        */
+       void (*sched_task)              (struct perf_event_pmu_context *pmu_ctx,
+-                                      bool sched_in);
++                                       struct task_struct *task, bool sched_in);
+       /*
+        * Kmem cache of PMU specific data
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index eb359be7ec793..03c27754aef8b 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -3558,7 +3558,8 @@ static void perf_event_swap_task_ctx_data(struct perf_event_context *prev_ctx,
+       }
+ }
+-static void perf_ctx_sched_task_cb(struct perf_event_context *ctx, bool sched_in)
++static void perf_ctx_sched_task_cb(struct perf_event_context *ctx,
++                                 struct task_struct *task, bool sched_in)
+ {
+       struct perf_event_pmu_context *pmu_ctx;
+       struct perf_cpu_pmu_context *cpc;
+@@ -3567,7 +3568,7 @@ static void perf_ctx_sched_task_cb(struct perf_event_context *ctx, bool sched_in
+               cpc = this_cpu_ptr(pmu_ctx->pmu->cpu_pmu_context);
+               if (cpc->sched_cb_usage && pmu_ctx->pmu->sched_task)
+-                      pmu_ctx->pmu->sched_task(pmu_ctx, sched_in);
++                      pmu_ctx->pmu->sched_task(pmu_ctx, task, sched_in);
+       }
+ }
+@@ -3630,7 +3631,7 @@ perf_event_context_sched_out(struct task_struct *task, struct task_struct *next)
+                       WRITE_ONCE(ctx->task, next);
+                       WRITE_ONCE(next_ctx->task, task);
+-                      perf_ctx_sched_task_cb(ctx, false);
++                      perf_ctx_sched_task_cb(ctx, task, false);
+                       perf_event_swap_task_ctx_data(ctx, next_ctx);
+                       perf_ctx_enable(ctx, false);
+@@ -3660,7 +3661,7 @@ perf_event_context_sched_out(struct task_struct *task, struct task_struct *next)
+               perf_ctx_disable(ctx, false);
+ inside_switch:
+-              perf_ctx_sched_task_cb(ctx, false);
++              perf_ctx_sched_task_cb(ctx, task, false);
+               task_ctx_sched_out(ctx, NULL, EVENT_ALL);
+               perf_ctx_enable(ctx, false);
+@@ -3702,7 +3703,8 @@ void perf_sched_cb_inc(struct pmu *pmu)
+  * PEBS requires this to provide PID/TID information. This requires we flush
+  * all queued PEBS records before we context switch to a new task.
+  */
+-static void __perf_pmu_sched_task(struct perf_cpu_pmu_context *cpc, bool sched_in)
++static void __perf_pmu_sched_task(struct perf_cpu_pmu_context *cpc,
++                                struct task_struct *task, bool sched_in)
+ {
+       struct perf_cpu_context *cpuctx = this_cpu_ptr(&perf_cpu_context);
+       struct pmu *pmu;
+@@ -3716,7 +3718,7 @@ static void __perf_pmu_sched_task(struct perf_cpu_pmu_context *cpc, bool sched_i
+       perf_ctx_lock(cpuctx, cpuctx->task_ctx);
+       perf_pmu_disable(pmu);
+-      pmu->sched_task(cpc->task_epc, sched_in);
++      pmu->sched_task(cpc->task_epc, task, sched_in);
+       perf_pmu_enable(pmu);
+       perf_ctx_unlock(cpuctx, cpuctx->task_ctx);
+@@ -3734,7 +3736,7 @@ static void perf_pmu_sched_task(struct task_struct *prev,
+               return;
+       list_for_each_entry(cpc, this_cpu_ptr(&sched_cb_list), sched_cb_entry)
+-              __perf_pmu_sched_task(cpc, sched_in);
++              __perf_pmu_sched_task(cpc, sched_in ? next : prev, sched_in);
+ }
+ static void perf_event_switch(struct task_struct *task,
+@@ -4029,7 +4031,7 @@ static void perf_event_context_sched_in(struct task_struct *task)
+               perf_ctx_lock(cpuctx, ctx);
+               perf_ctx_disable(ctx, false);
+-              perf_ctx_sched_task_cb(ctx, true);
++              perf_ctx_sched_task_cb(ctx, task, true);
+               perf_ctx_enable(ctx, false);
+               perf_ctx_unlock(cpuctx, ctx);
+@@ -4060,7 +4062,7 @@ static void perf_event_context_sched_in(struct task_struct *task)
+       perf_event_sched_in(cpuctx, ctx, NULL);
+-      perf_ctx_sched_task_cb(cpuctx->task_ctx, true);
++      perf_ctx_sched_task_cb(cpuctx->task_ctx, task, true);
+       if (!RB_EMPTY_ROOT(&ctx->pinned_groups.tree))
+               perf_ctx_enable(&cpuctx->ctx, false);
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-test-add-timeout-to-datasym-workload.patch b/queue-6.14/perf-test-add-timeout-to-datasym-workload.patch
new file mode 100644 (file)
index 0000000..dfacd68
--- /dev/null
@@ -0,0 +1,68 @@
+From 48e68512e124afee1472e212da60be36b3fd94c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Mar 2025 18:28:36 -0800
+Subject: perf test: Add timeout to datasym workload
+
+From: Namhyung Kim <namhyung@kernel.org>
+
+[ Upstream commit f04c7ef35256beea57a598a7ea06dd2242ae9ae6 ]
+
+Unlike others it has an infinite loop that make it annoying to call.
+Make it finish after 1 second and handle command-line argument to change
+the setting.
+
+Reviewed-by: Leo Yan <leo.yan@arm.com>
+Tested-by: Thomas Richter <tmricht@linux.ibm.com>
+Tested-by: Thomas Falcon <thomas.falcon@intel.com>
+Cc: Thomas Richter <tmricht@linux.ibm.com>
+Cc: Leo Yan <leo.yan@arm.com>
+Link: https://lore.kernel.org/r/20250304022837.1877845-6-namhyung@kernel.org
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Stable-dep-of: 36e7748d33bf ("perf tests: Fix data symbol test with LTO builds")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/tests/workloads/datasym.c | 23 +++++++++++++++++++++--
+ 1 file changed, 21 insertions(+), 2 deletions(-)
+
+diff --git a/tools/perf/tests/workloads/datasym.c b/tools/perf/tests/workloads/datasym.c
+index 8e08fc75a973e..8ddb2aa6a049e 100644
+--- a/tools/perf/tests/workloads/datasym.c
++++ b/tools/perf/tests/workloads/datasym.c
+@@ -1,3 +1,6 @@
++#include <stdlib.h>
++#include <signal.h>
++#include <unistd.h>
+ #include <linux/compiler.h>
+ #include "../tests.h"
+@@ -12,9 +15,25 @@ static buf buf1 = {
+       .reserved[0] = 1,
+ };
+-static int datasym(int argc __maybe_unused, const char **argv __maybe_unused)
++static volatile sig_atomic_t done;
++
++static void sighandler(int sig __maybe_unused)
++{
++      done = 1;
++}
++
++static int datasym(int argc, const char **argv)
+ {
+-      for (;;) {
++      int sec = 1;
++
++      if (argc > 0)
++              sec = atoi(argv[0]);
++
++      signal(SIGINT, sighandler);
++      signal(SIGALRM, sighandler);
++      alarm(sec);
++
++      while (!done) {
+               buf1.data1++;
+               if (buf1.data1 == 123) {
+                       /*
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-test-fix-hwmon-pmu-test-endianess-issue.patch b/queue-6.14/perf-test-fix-hwmon-pmu-test-endianess-issue.patch
new file mode 100644 (file)
index 0000000..2538cd0
--- /dev/null
@@ -0,0 +1,219 @@
+From 9db927aaf94b57a87ce198f6fcf8ba31fe5ae382 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Jan 2025 12:24:00 +0100
+Subject: perf test: Fix Hwmon PMU test endianess issue
+
+From: Thomas Richter <tmricht@linux.ibm.com>
+
+[ Upstream commit 888751e4d0e948d0364eee6fb47e21f090b2b5e4 ]
+
+perf test 11 hwmon fails on s390 with this error
+
+ # ./perf test -Fv 11
+ --- start ---
+ ---- end ----
+ 11.1: Basic parsing test             : Ok
+ --- start ---
+ Testing 'temp_test_hwmon_event1'
+ Using CPUID IBM,3931,704,A01,3.7,002f
+ temp_test_hwmon_event1 -> hwmon_a_test_hwmon_pmu/temp_test_hwmon_event1/
+ FAILED tests/hwmon_pmu.c:189 Unexpected config for
+    'temp_test_hwmon_event1', 292470092988416 != 655361
+ ---- end ----
+ 11.2: Parsing without PMU name       : FAILED!
+ --- start ---
+ Testing 'hwmon_a_test_hwmon_pmu/temp_test_hwmon_event1/'
+ FAILED tests/hwmon_pmu.c:189 Unexpected config for
+    'hwmon_a_test_hwmon_pmu/temp_test_hwmon_event1/',
+    292470092988416 != 655361
+ ---- end ----
+ 11.3: Parsing with PMU name          : FAILED!
+ #
+
+The root cause is in member test_event::config which is initialized
+to 0xA0001 or 655361. During event parsing a long list event parsing
+functions are called and end up with this gdb call stack:
+
+ #0  hwmon_pmu__config_term (hwm=0x168dfd0, attr=0x3ffffff5ee8,
+       term=0x168db60, err=0x3ffffff81c8) at util/hwmon_pmu.c:623
+ #1  hwmon_pmu__config_terms (pmu=0x168dfd0, attr=0x3ffffff5ee8,
+       terms=0x3ffffff5ea8, err=0x3ffffff81c8) at util/hwmon_pmu.c:662
+ #2  0x00000000012f870c in perf_pmu__config_terms (pmu=0x168dfd0,
+       attr=0x3ffffff5ee8, terms=0x3ffffff5ea8, zero=false,
+       apply_hardcoded=false, err=0x3ffffff81c8) at util/pmu.c:1519
+ #3  0x00000000012f88a4 in perf_pmu__config (pmu=0x168dfd0, attr=0x3ffffff5ee8,
+       head_terms=0x3ffffff5ea8, apply_hardcoded=false, err=0x3ffffff81c8)
+       at util/pmu.c:1545
+ #4  0x00000000012680c4 in parse_events_add_pmu (parse_state=0x3ffffff7fb8,
+       list=0x168dc00, pmu=0x168dfd0, const_parsed_terms=0x3ffffff6090,
+       auto_merge_stats=true, alternate_hw_config=10)
+       at util/parse-events.c:1508
+ #5  0x00000000012684c6 in parse_events_multi_pmu_add (parse_state=0x3ffffff7fb8,
+       event_name=0x168ec10 "temp_test_hwmon_event1", hw_config=10,
+       const_parsed_terms=0x0, listp=0x3ffffff6230, loc_=0x3ffffff70e0)
+       at util/parse-events.c:1592
+ #6  0x00000000012f0e4e in parse_events_parse (_parse_state=0x3ffffff7fb8,
+       scanner=0x16878c0) at util/parse-events.y:293
+ #7  0x00000000012695a0 in parse_events__scanner (str=0x3ffffff81d8
+       "temp_test_hwmon_event1", input=0x0, parse_state=0x3ffffff7fb8)
+       at util/parse-events.c:1867
+ #8  0x000000000126a1e8 in __parse_events (evlist=0x168b580,
+       str=0x3ffffff81d8 "temp_test_hwmon_event1", pmu_filter=0x0,
+       err=0x3ffffff81c8, fake_pmu=false, warn_if_reordered=true,
+       fake_tp=false) at util/parse-events.c:2136
+ #9  0x00000000011e36aa in parse_events (evlist=0x168b580,
+       str=0x3ffffff81d8 "temp_test_hwmon_event1", err=0x3ffffff81c8)
+       at /root/linux/tools/perf/util/parse-events.h:41
+ #10 0x00000000011e3e64 in do_test (i=0, with_pmu=false, with_alias=false)
+       at tests/hwmon_pmu.c:164
+ #11 0x00000000011e422c in test__hwmon_pmu (with_pmu=false)
+       at tests/hwmon_pmu.c:219
+ #12 0x00000000011e431c in test__hwmon_pmu_without_pmu (test=0x1610368
+       <suite.hwmon_pmu>, subtest=1) at tests/hwmon_pmu.c:23
+
+where the attr::config is set to value 292470092988416 or 0x10a0000000000
+in line 625 of file ./util/hwmon_pmu.c:
+
+   attr->config = key.type_and_num;
+
+However member key::type_and_num is defined as union and bit field:
+
+   union hwmon_pmu_event_key {
+        long type_and_num;
+        struct {
+                int num :16;
+                enum hwmon_type type :8;
+        };
+   };
+
+s390 is big endian and Intel is little endian architecture.
+The events for the hwmon dummy pmu have num = 1 or num = 2 and
+type is set to HWMON_TYPE_TEMP (which is 10).
+On s390 this assignes member key::type_and_num the value of
+0x10a0000000000 (which is 292470092988416) as shown in above
+trace output.
+
+Fix this and export the structure/union hwmon_pmu_event_key
+so the test shares the same implementation as the event parsing
+functions for union and bit fields. This should avoid
+endianess issues on all platforms.
+
+Output after:
+ # ./perf test -F 11
+ 11.1: Basic parsing test         : Ok
+ 11.2: Parsing without PMU name   : Ok
+ 11.3: Parsing with PMU name      : Ok
+ #
+
+Fixes: 531ee0fd4836 ("perf test: Add hwmon "PMU" test")
+Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
+Reviewed-by: Ian Rogers <irogers@google.com>
+Link: https://lore.kernel.org/r/20250131112400.568975-1-tmricht@linux.ibm.com
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/tests/hwmon_pmu.c | 16 +++++++++++-----
+ tools/perf/util/hwmon_pmu.c  | 14 --------------
+ tools/perf/util/hwmon_pmu.h  | 16 ++++++++++++++++
+ 3 files changed, 27 insertions(+), 19 deletions(-)
+
+diff --git a/tools/perf/tests/hwmon_pmu.c b/tools/perf/tests/hwmon_pmu.c
+index d2b066a2b557a..0837aca1cdfa7 100644
+--- a/tools/perf/tests/hwmon_pmu.c
++++ b/tools/perf/tests/hwmon_pmu.c
+@@ -13,17 +13,23 @@
+ static const struct test_event {
+       const char *name;
+       const char *alias;
+-      long config;
++      union hwmon_pmu_event_key key;
+ } test_events[] = {
+       {
+               "temp_test_hwmon_event1",
+               "temp1",
+-              0xA0001,
++              .key = {
++                      .num = 1,
++                      .type = 10
++              },
+       },
+       {
+               "temp_test_hwmon_event2",
+               "temp2",
+-              0xA0002,
++              .key = {
++                      .num = 2,
++                      .type = 10
++              },
+       },
+ };
+@@ -183,11 +189,11 @@ static int do_test(size_t i, bool with_pmu, bool with_alias)
+                   strcmp(evsel->pmu->name, "hwmon_a_test_hwmon_pmu"))
+                       continue;
+-              if (evsel->core.attr.config != (u64)test_events[i].config) {
++              if (evsel->core.attr.config != (u64)test_events[i].key.type_and_num) {
+                       pr_debug("FAILED %s:%d Unexpected config for '%s', %lld != %ld\n",
+                               __FILE__, __LINE__, str,
+                               evsel->core.attr.config,
+-                              test_events[i].config);
++                              test_events[i].key.type_and_num);
+                       ret = TEST_FAIL;
+                       goto out;
+               }
+diff --git a/tools/perf/util/hwmon_pmu.c b/tools/perf/util/hwmon_pmu.c
+index 4acb9bb19b846..acd889b2462f6 100644
+--- a/tools/perf/util/hwmon_pmu.c
++++ b/tools/perf/util/hwmon_pmu.c
+@@ -107,20 +107,6 @@ struct hwmon_pmu {
+       int hwmon_dir_fd;
+ };
+-/**
+- * union hwmon_pmu_event_key: Key for hwmon_pmu->events as such each key
+- * represents an event.
+- *
+- * Related hwmon files start <type><number> that this key represents.
+- */
+-union hwmon_pmu_event_key {
+-      long type_and_num;
+-      struct {
+-              int num :16;
+-              enum hwmon_type type :8;
+-      };
+-};
+-
+ /**
+  * struct hwmon_pmu_event_value: Value in hwmon_pmu->events.
+  *
+diff --git a/tools/perf/util/hwmon_pmu.h b/tools/perf/util/hwmon_pmu.h
+index 882566846df46..b3329774d2b22 100644
+--- a/tools/perf/util/hwmon_pmu.h
++++ b/tools/perf/util/hwmon_pmu.h
+@@ -91,6 +91,22 @@ enum hwmon_item {
+       HWMON_ITEM__MAX,
+ };
++/**
++ * union hwmon_pmu_event_key: Key for hwmon_pmu->events as such each key
++ * represents an event.
++ * union is exposed for testing to ensure problems are avoided on big
++ * endian machines.
++ *
++ * Related hwmon files start <type><number> that this key represents.
++ */
++union hwmon_pmu_event_key {
++      long type_and_num;
++      struct {
++              int num :16;
++              enum hwmon_type type :8;
++      };
++};
++
+ bool perf_pmu__is_hwmon(const struct perf_pmu *pmu);
+ bool evsel__is_hwmon(const struct evsel *evsel);
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-test-stat_all_pmu.sh-correctly-check-perf-stat-.patch b/queue-6.14/perf-test-stat_all_pmu.sh-correctly-check-perf-stat-.patch
new file mode 100644 (file)
index 0000000..bdee538
--- /dev/null
@@ -0,0 +1,126 @@
+From 945305bcfa9a28a6efd97985826ad7ed746f63d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Nov 2024 00:12:33 +0100
+Subject: perf test stat_all_pmu.sh: Correctly check 'perf stat' result
+
+From: Veronika Molnarova <vmolnaro@redhat.com>
+
+[ Upstream commit 02ba09c8ab9406f30c5c63b7cfd4b300c3c2c32c ]
+
+Test case "stat_all_pmu.sh" is not correctly checking 'perf stat' output
+due to a poor design. Firstly, having the 'set -e' option with a trap
+catching the sigexit causes the shell to exit immediately if 'perf stat' ends
+with any non-zero value, which is then caught by the trap reporting an
+unexpected signal. This causes events that should be parsed by the if-else
+statement to be caught by the trap handler and are reported as errors:
+
+    $ perf test -vv "perf all pmu"
+    Testing i915/actual-frequency/
+    Unexpected signal in main
+    Error:
+    Access to performance monitoring and observability operations is limited.
+
+Secondly, the if-else branches are not exclusive as the checking if the
+event is present in the output log covers also the "<not supported>"
+events, which should be accepted, and also the "Bad name events", which
+should be rejected.
+
+Remove the "set -e" option from the test case, correctly parse the
+"perf stat" output log and check its return value. Add the missing
+outputs for the 'perf stat' result and also add logs messages to
+report the branch that parsed the event for more info.
+
+Fixes: 7e73ea40295620e7 ("perf test: Ignore security failures in all PMU test")
+Signed-off-by: Veronika Molnarova <vmolnaro@redhat.com>
+Tested-by: Qiao Zhao <qzhao@redhat.com>
+Link: https://lore.kernel.org/r/20241122231233.79509-1-vmolnaro@redhat.com
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/tests/shell/stat_all_pmu.sh | 48 ++++++++++++++++++--------
+ 1 file changed, 34 insertions(+), 14 deletions(-)
+
+diff --git a/tools/perf/tests/shell/stat_all_pmu.sh b/tools/perf/tests/shell/stat_all_pmu.sh
+index 8b148b300be11..9c466c0efa857 100755
+--- a/tools/perf/tests/shell/stat_all_pmu.sh
++++ b/tools/perf/tests/shell/stat_all_pmu.sh
+@@ -2,7 +2,6 @@
+ # perf all PMU test (exclusive)
+ # SPDX-License-Identifier: GPL-2.0
+-set -e
+ err=0
+ result=""
+@@ -16,34 +15,55 @@ trap trap_cleanup EXIT TERM INT
+ # Test all PMU events; however exclude parameterized ones (name contains '?')
+ for p in $(perf list --raw-dump pmu | sed 's/[[:graph:]]\+?[[:graph:]]\+[[:space:]]//g')
+ do
+-  echo "Testing $p"
+-  result=$(perf stat -e "$p" true 2>&1)
+-  if echo "$result" | grep -q "$p"
++  echo -n "Testing $p -- "
++  output=$(perf stat -e "$p" true 2>&1)
++  stat_result=$?
++  if echo "$output" | grep -q "$p"
+   then
+     # Event seen in output.
+-    continue
+-  fi
+-  if echo "$result" | grep -q "<not supported>"
+-  then
+-    # Event not supported, so ignore.
+-    continue
++    if [ $stat_result -eq 0 ] && ! echo "$output" | grep -q "<not supported>"
++    then
++      # Event supported.
++      echo "supported"
++      continue
++    elif echo "$output" | grep -q "<not supported>"
++    then
++      # Event not supported, so ignore.
++      echo "not supported"
++      continue
++    elif echo "$output" | grep -q "No permission to enable"
++    then
++      # No permissions, so ignore.
++      echo "no permission to enable"
++      continue
++    elif echo "$output" | grep -q "Bad event name"
++    then
++      # Non-existent event.
++      echo "Error: Bad event name"
++      echo "$output"
++      err=1
++      continue
++    fi
+   fi
+-  if echo "$result" | grep -q "Access to performance monitoring and observability operations is limited."
++
++  if echo "$output" | grep -q "Access to performance monitoring and observability operations is limited."
+   then
+     # Access is limited, so ignore.
++    echo "access limited"
+     continue
+   fi
+   # We failed to see the event and it is supported. Possibly the workload was
+   # too small so retry with something longer.
+-  result=$(perf stat -e "$p" perf bench internals synthesize 2>&1)
+-  if echo "$result" | grep -q "$p"
++  output=$(perf stat -e "$p" perf bench internals synthesize 2>&1)
++  if echo "$output" | grep -q "$p"
+   then
+     # Event seen in output.
++    echo "supported"
+     continue
+   fi
+   echo "Error: event '$p' not printed in:"
+-  echo "$result"
++  echo "$output"
+   err=1
+ done
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-tests-fix-data-symbol-test-with-lto-builds.patch b/queue-6.14/perf-tests-fix-data-symbol-test-with-lto-builds.patch
new file mode 100644 (file)
index 0000000..6d33171
--- /dev/null
@@ -0,0 +1,138 @@
+From 015821a9ad626f6356ac52939ac8f90a776bc2cf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Feb 2025 15:01:09 -0800
+Subject: perf tests: Fix data symbol test with LTO builds
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 36e7748d33bf6a82e558009e03448e9321465e05 ]
+
+With LTO builds, although regular builds could also see this as
+all the code is in one file, the datasym workload can realize the
+buf1.reserved data is never accessed. The compiler moves the
+variable to bss and only keeps the data1 and data2 parts as
+separate variables. This causes the symbol check to fail in the
+test. Make the variable volatile to disable the more aggressive
+optimization. Rename the variable to make which buf1 in perf is
+being referred to.
+
+Before:
+
+  $ perf test -vv "data symbol"
+  126: Test data symbol:
+  --- start ---
+  test child forked, pid 299808
+  perf does not have symbol 'buf1'
+  perf is missing symbols - skipping test
+  ---- end(-2) ----
+  126: Test data symbol                                                : Skip
+  $ nm perf|grep buf1
+  0000000000a5fa40 b buf1.0
+  0000000000a5fa48 b buf1.1
+
+After:
+
+  $ nm perf|grep buf1
+  0000000000a53a00 d buf1
+  $ perf test -vv "data symbol"126: Test data symbol:
+  --- start ---
+  test child forked, pid 302166
+   a53a00-a53a39 l buf1
+  perf does have symbol 'buf1'
+  Recording workload...
+  Waiting for "perf record has started" message
+  OK
+  Cleaning up files...
+  ---- end(0) ----
+  126: Test data symbol                                                : Ok
+
+Fixes: 3dfc01fe9d12 ("perf test: Add 'datasym' test workload")
+Signed-off-by: Ian Rogers <irogers@google.com>
+Link: https://lore.kernel.org/r/20250226230109.314580-1-irogers@google.com
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/tests/shell/test_data_symbol.sh | 17 +++++++++--------
+ tools/perf/tests/workloads/datasym.c       | 11 ++++++-----
+ 2 files changed, 15 insertions(+), 13 deletions(-)
+
+diff --git a/tools/perf/tests/shell/test_data_symbol.sh b/tools/perf/tests/shell/test_data_symbol.sh
+index c86da02350596..7da606db97cb4 100755
+--- a/tools/perf/tests/shell/test_data_symbol.sh
++++ b/tools/perf/tests/shell/test_data_symbol.sh
+@@ -18,7 +18,7 @@ skip_if_no_mem_event() {
+ skip_if_no_mem_event || exit 2
+-skip_test_missing_symbol buf1
++skip_test_missing_symbol workload_datasym_buf1
+ TEST_PROGRAM="perf test -w datasym"
+ PERF_DATA=$(mktemp /tmp/__perf_test.perf.data.XXXXX)
+@@ -26,18 +26,19 @@ ERR_FILE=$(mktemp /tmp/__perf_test.stderr.XXXXX)
+ check_result() {
+       # The memory report format is as below:
+-      #    99.92%  ...  [.] buf1+0x38
++      #    99.92%  ...  [.] workload_datasym_buf1+0x38
+       result=$(perf mem report -i ${PERF_DATA} -s symbol_daddr -q 2>&1 |
+-               awk '/buf1/ { print $4 }')
++               awk '/workload_datasym_buf1/ { print $4 }')
+-      # Testing is failed if has no any sample for "buf1"
++      # Testing is failed if has no any sample for "workload_datasym_buf1"
+       [ -z "$result" ] && return 1
+       while IFS= read -r line; do
+-              # The "data1" and "data2" fields in structure "buf1" have
+-              # offset "0x0" and "0x38", returns failure if detect any
+-              # other offset value.
+-              if [ "$line" != "buf1+0x0" ] && [ "$line" != "buf1+0x38" ]; then
++              # The "data1" and "data2" fields in structure
++              # "workload_datasym_buf1" have offset "0x0" and "0x38", returns
++              # failure if detect any other offset value.
++              if [ "$line" != "workload_datasym_buf1+0x0" ] && \
++                 [ "$line" != "workload_datasym_buf1+0x38" ]; then
+                       return 1
+               fi
+       done <<< "$result"
+diff --git a/tools/perf/tests/workloads/datasym.c b/tools/perf/tests/workloads/datasym.c
+index 8ddb2aa6a049e..1d0b7d64e1ba1 100644
+--- a/tools/perf/tests/workloads/datasym.c
++++ b/tools/perf/tests/workloads/datasym.c
+@@ -10,7 +10,8 @@ typedef struct _buf {
+       char data2;
+ } buf __attribute__((aligned(64)));
+-static buf buf1 = {
++/* volatile to try to avoid the compiler seeing reserved as unused. */
++static volatile buf workload_datasym_buf1 = {
+       /* to have this in the data section */
+       .reserved[0] = 1,
+ };
+@@ -34,8 +35,8 @@ static int datasym(int argc, const char **argv)
+       alarm(sec);
+       while (!done) {
+-              buf1.data1++;
+-              if (buf1.data1 == 123) {
++              workload_datasym_buf1.data1++;
++              if (workload_datasym_buf1.data1 == 123) {
+                       /*
+                        * Add some 'noise' in the loop to work around errata
+                        * 1694299 on Arm N1.
+@@ -49,9 +50,9 @@ static int datasym(int argc, const char **argv)
+                        * longer a continuous repeating pattern that interacts
+                        * badly with the bias.
+                        */
+-                      buf1.data1++;
++                      workload_datasym_buf1.data1++;
+               }
+-              buf1.data2 += buf1.data1;
++              workload_datasym_buf1.data2 += workload_datasym_buf1.data1;
+       }
+       return 0;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-tests-fix-tool-pmu-test-segfault.patch b/queue-6.14/perf-tests-fix-tool-pmu-test-segfault.patch
new file mode 100644 (file)
index 0000000..7177735
--- /dev/null
@@ -0,0 +1,58 @@
+From 39b9c8e5d8809d2243411c83b5d34fa907178afa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Feb 2025 16:38:56 +0000
+Subject: perf tests: Fix Tool PMU test segfault
+
+From: James Clark <james.clark@linaro.org>
+
+[ Upstream commit 615ec00b06f78912c370b372426190768402a5b9 ]
+
+tool_pmu__event_to_str() now handles skipped events by returning NULL,
+so it's wrong to re-check for a skip on the resulting string. Calling
+tool_pmu__skip_event() with a NULL string results in a segfault so
+remove the unnecessary skip to fix it:
+
+  $ perf test -vv "parsing with PMU name"
+
+  12.2: Parsing with PMU name:
+  ...
+  ---- unexpected signal (11) ----
+  12.2: Parsing with PMU name         : FAILED!
+
+Fixes: ee8aef2d2321 ("perf tools: Add skip check in tool_pmu__event_to_str()")
+Signed-off-by: James Clark <james.clark@linaro.org>
+Reported-by: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
+Acked-by: Kan Liang <kan.liang@linux.intel.com>
+Tested-by: Ian Rogers <irogers@google.com>
+Link: https://lore.kernel.org/r/20250212163859.1489916-1-james.clark@linaro.org
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/tests/tool_pmu.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/perf/tests/tool_pmu.c b/tools/perf/tests/tool_pmu.c
+index 187942b749b7c..1e900ef92e378 100644
+--- a/tools/perf/tests/tool_pmu.c
++++ b/tools/perf/tests/tool_pmu.c
+@@ -27,7 +27,7 @@ static int do_test(enum tool_pmu_event ev, bool with_pmu)
+       parse_events_error__init(&err);
+       ret = parse_events(evlist, str, &err);
+       if (ret) {
+-              if (tool_pmu__skip_event(tool_pmu__event_to_str(ev))) {
++              if (!tool_pmu__event_to_str(ev)) {
+                       ret = TEST_OK;
+                       goto out;
+               }
+@@ -59,7 +59,7 @@ static int do_test(enum tool_pmu_event ev, bool with_pmu)
+               }
+       }
+-      if (!found && !tool_pmu__skip_event(tool_pmu__event_to_str(ev))) {
++      if (!found && tool_pmu__event_to_str(ev)) {
+               pr_debug("FAILED %s:%d Didn't find tool event '%s' in parsed evsels\n",
+                        __FILE__, __LINE__, str);
+               ret = TEST_FAIL;
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-tools-add-skip-check-in-tool_pmu__event_to_str.patch b/queue-6.14/perf-tools-add-skip-check-in-tool_pmu__event_to_str.patch
new file mode 100644 (file)
index 0000000..a280137
--- /dev/null
@@ -0,0 +1,71 @@
+From ff5976feb66fdd33962fbff321a5d85e1e1aa227 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Feb 2025 07:28:44 -0800
+Subject: perf tools: Add skip check in tool_pmu__event_to_str()
+
+From: Kan Liang <kan.liang@linux.intel.com>
+
+[ Upstream commit ee8aef2d232142e5fdfed9c16132815969a0bf81 ]
+
+Some topdown related metrics may fail on hybrid machines.
+
+ $ perf stat -M tma_frontend_bound
+ Cannot resolve IDs for tma_frontend_bound:
+ cpu_atom@TOPDOWN_FE_BOUND.ALL@ / (8 * cpu_atom@CPU_CLK_UNHALTED.CORE@)
+
+In the find_tool_events(), the tool_pmu__event_to_str() is used to
+compare the tool_events. It only checks the event name, no PMU or arch.
+So the tool_events[TOOL_PMU__EVENT_SLOTS] is set to true, because the
+p-core Topdown metrics has "slots" event.
+The tool_events is shared. So when parsing the e-core metrics, the
+"slots" is automatically added.
+
+The "slots" event as a tool event should only be available on arm64. It
+has a different meaning on X86. The tool_pmu__skip_event() intends
+handle the case. Apply it for tool_pmu__event_to_str() as well.
+
+There is a lack of sanity check in the expr__get_id(). Add the check.
+
+Closes: https://lore.kernel.org/lkml/608077bc-4139-4a97-8dc4-7997177d95c4@linux.intel.com/
+Fixes: 069057239a67 ("perf tool_pmu: Move expr literals to tool_pmu")
+Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
+Reviewed-by: Ian Rogers <irogers@google.com>
+Cc: thomas.falcon@intel.com
+Link: https://lore.kernel.org/r/20250207152844.302167-1-kan.liang@linux.intel.com
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/expr.c     | 2 ++
+ tools/perf/util/tool_pmu.c | 3 ++-
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c
+index c221dcce66660..6413537442aa8 100644
+--- a/tools/perf/util/expr.c
++++ b/tools/perf/util/expr.c
+@@ -215,6 +215,8 @@ int expr__add_ref(struct expr_parse_ctx *ctx, struct metric_ref *ref)
+ int expr__get_id(struct expr_parse_ctx *ctx, const char *id,
+                struct expr_id_data **data)
+ {
++      if (!ctx || !id)
++              return -1;
+       return hashmap__find(ctx->ids, id, data) ? 0 : -1;
+ }
+diff --git a/tools/perf/util/tool_pmu.c b/tools/perf/util/tool_pmu.c
+index 4fb0975784794..3a68debe71437 100644
+--- a/tools/perf/util/tool_pmu.c
++++ b/tools/perf/util/tool_pmu.c
+@@ -62,7 +62,8 @@ int tool_pmu__num_skip_events(void)
+ const char *tool_pmu__event_to_str(enum tool_pmu_event ev)
+ {
+-      if (ev > TOOL_PMU__EVENT_NONE && ev < TOOL_PMU__EVENT_MAX)
++      if ((ev > TOOL_PMU__EVENT_NONE && ev < TOOL_PMU__EVENT_MAX) &&
++          !tool_pmu__skip_event(tool_pmu__event_names[ev]))
+               return tool_pmu__event_names[ev];
+       return NULL;
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-tools-annotate-asm_pure_loop.s.patch b/queue-6.14/perf-tools-annotate-asm_pure_loop.s.patch
new file mode 100644 (file)
index 0000000..4dab72e
--- /dev/null
@@ -0,0 +1,34 @@
+From 97ab8d398fedd198a7994ff966368f09cfb9a0c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 Mar 2025 09:53:45 +0100
+Subject: perf tools: annotate asm_pure_loop.S
+
+From: Marcus Meissner <meissner@suse.de>
+
+[ Upstream commit 9a352a90e88a041f4b26d359493e12a7f5ae1a6a ]
+
+Annotate so it is built with non-executable stack.
+
+Fixes: 8b97519711c3 ("perf test: Add asm pureloop test tool")
+Signed-off-by: Marcus Meissner <meissner@suse.de>
+Reviewed-by: Leo Yan <leo.yan@arm.com>
+Link: https://lore.kernel.org/r/20250323085410.23751-1-meissner@suse.de
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/tests/shell/coresight/asm_pure_loop/asm_pure_loop.S | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/tools/perf/tests/shell/coresight/asm_pure_loop/asm_pure_loop.S b/tools/perf/tests/shell/coresight/asm_pure_loop/asm_pure_loop.S
+index 75cf084a927d3..5777600467723 100644
+--- a/tools/perf/tests/shell/coresight/asm_pure_loop/asm_pure_loop.S
++++ b/tools/perf/tests/shell/coresight/asm_pure_loop/asm_pure_loop.S
+@@ -26,3 +26,5 @@ skip:
+       mov     x0, #0
+       mov     x8, #93 // __NR_exit syscall
+       svc     #0
++
++.section .note.GNU-stack, "", @progbits
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-tools-fix-is_compat_mode-build-break-in-ppc64.patch b/queue-6.14/perf-tools-fix-is_compat_mode-build-break-in-ppc64.patch
new file mode 100644 (file)
index 0000000..0ec53d6
--- /dev/null
@@ -0,0 +1,58 @@
+From ff68b1da7dc501e2e6418bc2fe3eb829a8ac70ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Mar 2025 15:37:26 +0530
+Subject: perf tools: Fix is_compat_mode build break in ppc64
+
+From: Likhitha Korrapati <likhitha@linux.ibm.com>
+
+[ Upstream commit 7e442be7015af524d2b5fb84f0ff04a44501542b ]
+
+Commit 54f9aa1092457 ("tools/perf/powerpc/util: Add support to
+handle compatible mode PVR for perf json events") introduced
+to select proper JSON events in case of compat mode using
+auxiliary vector. But this caused a compilation error in ppc64
+Big Endian.
+
+arch/powerpc/util/header.c: In function 'is_compat_mode':
+arch/powerpc/util/header.c:20:21: error: cast to pointer from
+integer of different size [-Werror=int-to-pointer-cast]
+   20 |         if (!strcmp((char *)platform, (char *)base_platform))
+      |                     ^
+arch/powerpc/util/header.c:20:39: error: cast to pointer from
+integer of different size [-Werror=int-to-pointer-cast]
+   20 |         if (!strcmp((char *)platform, (char *)base_platform))
+      |
+
+Commit saved the getauxval(AT_BASE_PLATFORM) and getauxval(AT_PLATFORM)
+return values in u64 which causes the compilation error.
+
+Patch fixes this issue by changing u64 to "unsigned long".
+
+Fixes: 54f9aa1092457 ("tools/perf/powerpc/util: Add support to handle compatible mode PVR for perf json events")
+Signed-off-by: Likhitha Korrapati <likhitha@linux.ibm.com>
+Reviewed-by: Athira Rajeev <atrajeev@linux.ibm.com>
+Link: https://lore.kernel.org/r/20250321100726.699956-1-likhitha@linux.ibm.com
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/arch/powerpc/util/header.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/perf/arch/powerpc/util/header.c b/tools/perf/arch/powerpc/util/header.c
+index c7df534dbf8f8..0be74f048f964 100644
+--- a/tools/perf/arch/powerpc/util/header.c
++++ b/tools/perf/arch/powerpc/util/header.c
+@@ -14,8 +14,8 @@
+ static bool is_compat_mode(void)
+ {
+-      u64 base_platform = getauxval(AT_BASE_PLATFORM);
+-      u64 platform = getauxval(AT_PLATFORM);
++      unsigned long base_platform = getauxval(AT_BASE_PLATFORM);
++      unsigned long platform = getauxval(AT_PLATFORM);
+       if (!strcmp((char *)platform, (char *)base_platform))
+               return false;
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-units-fix-insufficient-array-space.patch b/queue-6.14/perf-units-fix-insufficient-array-space.patch
new file mode 100644 (file)
index 0000000..7108cdd
--- /dev/null
@@ -0,0 +1,46 @@
+From 43e40bf3879ed6547a7f1df6982880534c044cba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Mar 2025 16:45:32 -0300
+Subject: perf units: Fix insufficient array space
+
+From: Arnaldo Carvalho de Melo <acme@redhat.com>
+
+[ Upstream commit cf67629f7f637fb988228abdb3aae46d0c1748fe ]
+
+No need to specify the array size, let the compiler figure that out.
+
+This addresses this compiler warning that was noticed while build
+testing on fedora rawhide:
+
+  31    15.81 fedora:rawhide                : FAIL gcc version 15.0.1 20250225 (Red Hat 15.0.1-0) (GCC)
+    util/units.c: In function 'unit_number__scnprintf':
+    util/units.c:67:24: error: initializer-string for array of 'char' is too long [-Werror=unterminated-string-initialization]
+       67 |         char unit[4] = "BKMG";
+          |                        ^~~~~~
+    cc1: all warnings being treated as errors
+
+Fixes: 9808143ba2e54818 ("perf tools: Add unit_number__scnprintf function")
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Link: https://lore.kernel.org/r/20250310194534.265487-3-acme@kernel.org
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/units.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/util/units.c b/tools/perf/util/units.c
+index 32c39cfe209b3..4c6a86e1cb54b 100644
+--- a/tools/perf/util/units.c
++++ b/tools/perf/util/units.c
+@@ -64,7 +64,7 @@ unsigned long convert_unit(unsigned long value, char *unit)
+ int unit_number__scnprintf(char *buf, size_t size, u64 n)
+ {
+-      char unit[4] = "BKMG";
++      char unit[] = "BKMG";
+       int i = 0;
+       while (((n / 1024) > 1) && (i < 3)) {
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-vendor-events-arm64-ampereonex-fix-frontend_bou.patch b/queue-6.14/perf-vendor-events-arm64-ampereonex-fix-frontend_bou.patch
new file mode 100644 (file)
index 0000000..ac3a154
--- /dev/null
@@ -0,0 +1,63 @@
+From bb62e8214a26c458298e30e9d34ceace780b9c80 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Mar 2025 20:15:59 +0000
+Subject: perf vendor events arm64 AmpereOneX: Fix frontend_bound calculation
+
+From: Ilkka Koskinen <ilkka@os.amperecomputing.com>
+
+[ Upstream commit 182f12f3193341c3400ae719a34c00a8a1204cff ]
+
+frontend_bound metrics was miscalculated due to different scaling in
+a couple of metrics it depends on. Change the scaling to match with
+AmpereOne.
+
+Fixes: 16438b652b46 ("perf vendor events arm64 AmpereOneX: Add core PMU events and metrics")
+Signed-off-by: Ilkka Koskinen <ilkka@os.amperecomputing.com>
+Reviewed-by: James Clark <james.clark@linaro.org>
+Link: https://lore.kernel.org/r/20250313201559.11332-3-ilkka@os.amperecomputing.com
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../arch/arm64/ampere/ampereonex/metrics.json          | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/tools/perf/pmu-events/arch/arm64/ampere/ampereonex/metrics.json b/tools/perf/pmu-events/arch/arm64/ampere/ampereonex/metrics.json
+index c5d1d22bd034b..5228f94a793f9 100644
+--- a/tools/perf/pmu-events/arch/arm64/ampere/ampereonex/metrics.json
++++ b/tools/perf/pmu-events/arch/arm64/ampere/ampereonex/metrics.json
+@@ -229,19 +229,19 @@
+     },
+     {
+         "MetricName": "slots_lost_misspeculation_fraction",
+-        "MetricExpr": "(OP_SPEC - OP_RETIRED) / (CPU_CYCLES * #slots)",
++        "MetricExpr": "100 * (OP_SPEC - OP_RETIRED) / (CPU_CYCLES * #slots)",
+         "BriefDescription": "Fraction of slots lost due to misspeculation",
+         "DefaultMetricgroupName": "TopdownL1",
+         "MetricGroup": "Default;TopdownL1",
+-        "ScaleUnit": "100percent of slots"
++        "ScaleUnit": "1percent of slots"
+     },
+     {
+         "MetricName": "retired_fraction",
+-        "MetricExpr": "OP_RETIRED / (CPU_CYCLES * #slots)",
++        "MetricExpr": "100 * OP_RETIRED / (CPU_CYCLES * #slots)",
+         "BriefDescription": "Fraction of slots retiring, useful work",
+         "DefaultMetricgroupName": "TopdownL1",
+         "MetricGroup": "Default;TopdownL1",
+-        "ScaleUnit": "100percent of slots"
++        "ScaleUnit": "1percent of slots"
+     },
+     {
+         "MetricName": "backend_core",
+@@ -266,7 +266,7 @@
+     },
+     {
+         "MetricName": "frontend_bandwidth",
+-        "MetricExpr": "frontend_bound - frontend_latency",
++        "MetricExpr": "frontend_bound - 100 * frontend_latency",
+         "BriefDescription": "Fraction of slots the CPU did not dispatch at full bandwidth - able to dispatch partial slots only (1, 2, or 3 uops)",
+         "MetricGroup": "TopdownL2",
+         "ScaleUnit": "1percent of slots"
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-x86-lbr-fix-shorter-lbrs-call-stacks-for-the-sy.patch b/queue-6.14/perf-x86-lbr-fix-shorter-lbrs-call-stacks-for-the-sy.patch
new file mode 100644 (file)
index 0000000..b2e1892
--- /dev/null
@@ -0,0 +1,155 @@
+From 692127c5b9c2629d7125371b9699ef5805d4ecd6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Mar 2025 10:26:58 -0700
+Subject: perf/x86/lbr: Fix shorter LBRs call stacks for the system-wide mode
+
+From: Kan Liang <kan.liang@linux.intel.com>
+
+[ Upstream commit 3cec9fd03543c1e2919f906353e5cba079ae0a7c ]
+
+In the system-wide mode, LBR callstacks are shorter in comparison to
+the per-process mode.
+
+LBR MSRs are reset during a context switch in the system-wide mode. For
+the LBR call stack, the LBRs should be always saved/restored during a
+context switch.
+
+Use the space in task_struct to save/restore the LBR call stack data.
+
+For a system-wide event, it's unnecessagy to update the
+lbr_callstack_users for each threads. Add a variable in x86_pmu to
+indicate whether the system-wide event is active.
+
+Fixes: 76cb2c617f12 ("perf/x86/intel: Save/restore LBR stack during context switch")
+Reported-by: Andi Kleen <ak@linux.intel.com>
+Reported-by: Alexey Budankov <alexey.budankov@linux.intel.com>
+Debugged-by: Alexey Budankov <alexey.budankov@linux.intel.com>
+Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20250314172700.438923-5-kan.liang@linux.intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/events/intel/lbr.c  | 47 ++++++++++++++++++++++++++++++------
+ arch/x86/events/perf_event.h |  1 +
+ 2 files changed, 40 insertions(+), 8 deletions(-)
+
+diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
+index dafeee216f3b6..24719adbcd7ea 100644
+--- a/arch/x86/events/intel/lbr.c
++++ b/arch/x86/events/intel/lbr.c
+@@ -422,11 +422,17 @@ static __always_inline bool lbr_is_reset_in_cstate(void *ctx)
+       return !rdlbr_from(((struct x86_perf_task_context *)ctx)->tos, NULL);
+ }
++static inline bool has_lbr_callstack_users(void *ctx)
++{
++      return task_context_opt(ctx)->lbr_callstack_users ||
++             x86_pmu.lbr_callstack_users;
++}
++
+ static void __intel_pmu_lbr_restore(void *ctx)
+ {
+       struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+-      if (task_context_opt(ctx)->lbr_callstack_users == 0 ||
++      if (!has_lbr_callstack_users(ctx) ||
+           task_context_opt(ctx)->lbr_stack_state == LBR_NONE) {
+               intel_pmu_lbr_reset();
+               return;
+@@ -503,7 +509,7 @@ static void __intel_pmu_lbr_save(void *ctx)
+ {
+       struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+-      if (task_context_opt(ctx)->lbr_callstack_users == 0) {
++      if (!has_lbr_callstack_users(ctx)) {
+               task_context_opt(ctx)->lbr_stack_state = LBR_NONE;
+               return;
+       }
+@@ -543,6 +549,7 @@ void intel_pmu_lbr_sched_task(struct perf_event_pmu_context *pmu_ctx,
+                             struct task_struct *task, bool sched_in)
+ {
+       struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
++      struct perf_ctx_data *ctx_data;
+       void *task_ctx;
+       if (!cpuc->lbr_users)
+@@ -553,14 +560,18 @@ void intel_pmu_lbr_sched_task(struct perf_event_pmu_context *pmu_ctx,
+        * the task was scheduled out, restore the stack. Otherwise flush
+        * the LBR stack.
+        */
+-      task_ctx = pmu_ctx ? pmu_ctx->task_ctx_data : NULL;
++      rcu_read_lock();
++      ctx_data = rcu_dereference(task->perf_ctx_data);
++      task_ctx = ctx_data ? ctx_data->data : NULL;
+       if (task_ctx) {
+               if (sched_in)
+                       __intel_pmu_lbr_restore(task_ctx);
+               else
+                       __intel_pmu_lbr_save(task_ctx);
++              rcu_read_unlock();
+               return;
+       }
++      rcu_read_unlock();
+       /*
+        * Since a context switch can flip the address space and LBR entries
+@@ -589,9 +600,19 @@ void intel_pmu_lbr_add(struct perf_event *event)
+       cpuc->br_sel = event->hw.branch_reg.reg;
+-      if (branch_user_callstack(cpuc->br_sel) && event->pmu_ctx->task_ctx_data)
+-              task_context_opt(event->pmu_ctx->task_ctx_data)->lbr_callstack_users++;
++      if (branch_user_callstack(cpuc->br_sel)) {
++              if (event->attach_state & PERF_ATTACH_TASK) {
++                      struct task_struct *task = event->hw.target;
++                      struct perf_ctx_data *ctx_data;
++                      rcu_read_lock();
++                      ctx_data = rcu_dereference(task->perf_ctx_data);
++                      if (ctx_data)
++                              task_context_opt(ctx_data->data)->lbr_callstack_users++;
++                      rcu_read_unlock();
++              } else
++                      x86_pmu.lbr_callstack_users++;
++      }
+       /*
+        * Request pmu::sched_task() callback, which will fire inside the
+        * regular perf event scheduling, so that call will:
+@@ -665,9 +686,19 @@ void intel_pmu_lbr_del(struct perf_event *event)
+       if (!x86_pmu.lbr_nr)
+               return;
+-      if (branch_user_callstack(cpuc->br_sel) &&
+-          event->pmu_ctx->task_ctx_data)
+-              task_context_opt(event->pmu_ctx->task_ctx_data)->lbr_callstack_users--;
++      if (branch_user_callstack(cpuc->br_sel)) {
++              if (event->attach_state & PERF_ATTACH_TASK) {
++                      struct task_struct *task = event->hw.target;
++                      struct perf_ctx_data *ctx_data;
++
++                      rcu_read_lock();
++                      ctx_data = rcu_dereference(task->perf_ctx_data);
++                      if (ctx_data)
++                              task_context_opt(ctx_data->data)->lbr_callstack_users--;
++                      rcu_read_unlock();
++              } else
++                      x86_pmu.lbr_callstack_users--;
++      }
+       if (event->hw.flags & PERF_X86_EVENT_LBR_SELECT)
+               cpuc->lbr_select = 0;
+diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
+index ce7c98364d5b6..b93b526d6834a 100644
+--- a/arch/x86/events/perf_event.h
++++ b/arch/x86/events/perf_event.h
+@@ -914,6 +914,7 @@ struct x86_pmu {
+               const int       *lbr_sel_map;      /* lbr_select mappings */
+               int             *lbr_ctl_map;      /* LBR_CTL mappings */
+       };
++      u64             lbr_callstack_users;       /* lbr callstack system wide users */
+       bool            lbr_double_abort;          /* duplicated lbr aborts */
+       bool            lbr_pt_coexist;            /* (LBR|BTS) may coexist with PT */
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-x86-topdown-fix-topdown-leader-sampling-test-er.patch b/queue-6.14/perf-x86-topdown-fix-topdown-leader-sampling-test-er.patch
new file mode 100644 (file)
index 0000000..7ccb484
--- /dev/null
@@ -0,0 +1,67 @@
+From a66f487c03c9b51c68fde8791b6413139a6dc337 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Mar 2025 18:39:03 -0800
+Subject: perf x86/topdown: Fix topdown leader sampling test error on hybrid
+
+From: Dapeng Mi <dapeng1.mi@linux.intel.com>
+
+[ Upstream commit b74683b3bb224eccb644cf260753dfc82e802d92 ]
+
+When running topdown leader smapling test on Intel hybrid platforms,
+such as LNL/ARL, we see the below error.
+
+Topdown leader sampling test
+Topdown leader sampling [Failed topdown events not reordered correctly]
+
+It indciates the below command fails.
+
+perf record -o "${perfdata}" -e "{instructions,slots,topdown-retiring}:S" true
+
+The root cause is that perf tool creats a perf event for each PMU type
+if it can create.
+
+As for this command, there would be 5 perf events created,
+cpu_atom/instructions/,cpu_atom/topdown_retiring/,
+cpu_core/slots/,cpu_core/instructions/,cpu_core/topdown-retiring/
+
+For these 5 events, the 2 cpu_atom events are in a group and the other 3
+cpu_core events are in another group.
+
+When arch_topdown_sample_read() traverses all these 5 events, events
+cpu_atom/instructions/ and cpu_core/slots/ don't have a same group
+leade, and then return false directly and lead to cpu_core/slots/ event
+is used to sample and this is not allowed by PMU driver.
+
+It's a overkill to return false directly if "evsel->core.leader !=
+ leader->core.leader" since there could be multiple groups in the event
+list.
+
+Just "continue" instead of "return false" to fix this issue.
+
+Fixes: 1e53e9d1787b ("perf x86/topdown: Correct leader selection with sample_read enabled")
+Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
+Tested-by: Thomas Falcon <thomas.falcon@intel.com>
+Tested-by: Ian Rogers <irogers@google.com>
+Link: https://lore.kernel.org/r/20250307023906.1135613-2-irogers@google.com
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/arch/x86/util/topdown.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/arch/x86/util/topdown.c b/tools/perf/arch/x86/util/topdown.c
+index f63747d0abdf9..d1c6548390496 100644
+--- a/tools/perf/arch/x86/util/topdown.c
++++ b/tools/perf/arch/x86/util/topdown.c
+@@ -81,7 +81,7 @@ bool arch_topdown_sample_read(struct evsel *leader)
+        */
+       evlist__for_each_entry(leader->evlist, evsel) {
+               if (evsel->core.leader != leader->core.leader)
+-                      return false;
++                      continue;
+               if (evsel != leader && arch_is_topdown_metrics(evsel))
+                       return true;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/phy-phy-rockchip-samsung-hdptx-don-t-use-dt-aliases-.patch b/queue-6.14/phy-phy-rockchip-samsung-hdptx-don-t-use-dt-aliases-.patch
new file mode 100644 (file)
index 0000000..fc8bbaa
--- /dev/null
@@ -0,0 +1,139 @@
+From dabbb791dc54d49db1010f63fd15443122bcbd91 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Dec 2024 11:34:01 +0100
+Subject: phy: phy-rockchip-samsung-hdptx: Don't use dt aliases to determine
+ phy-id
+
+From: Heiko Stuebner <heiko.stuebner@cherry.de>
+
+[ Upstream commit f08d1c08563846f9be79a4859e912c8795d690fd ]
+
+The phy needs to know its identity in the system (phy0 or phy1 on rk3588)
+for some actions and the driver currently contains code abusing of_alias
+for that.
+
+Devicetree aliases are always optional and should not be used for core
+device functionality, so instead keep a list of phys on a soc in the
+of_device_data and find the phy-id by comparing against the mapped
+register-base.
+
+Fixes: c4b09c562086 ("phy: phy-rockchip-samsung-hdptx: Add clock provider support")
+Signed-off-by: Heiko Stuebner <heiko.stuebner@cherry.de>
+Reviewed-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
+Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20241206103401.1780416-3-heiko@sntech.de
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../phy/rockchip/phy-rockchip-samsung-hdptx.c | 50 ++++++++++++++++---
+ 1 file changed, 44 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+index 0965b9d4f9cf1..2fb4f297fda3d 100644
+--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
++++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+@@ -263,11 +263,22 @@ enum rk_hdptx_reset {
+       RST_MAX
+ };
++#define MAX_HDPTX_PHY_NUM     2
++
++struct rk_hdptx_phy_cfg {
++      unsigned int num_phys;
++      unsigned int phy_ids[MAX_HDPTX_PHY_NUM];
++};
++
+ struct rk_hdptx_phy {
+       struct device *dev;
+       struct regmap *regmap;
+       struct regmap *grf;
++      /* PHY const config */
++      const struct rk_hdptx_phy_cfg *cfgs;
++      int phy_id;
++
+       struct phy *phy;
+       struct phy_config *phy_cfg;
+       struct clk_bulk_data *clks;
+@@ -1007,15 +1018,14 @@ static int rk_hdptx_phy_clk_register(struct rk_hdptx_phy *hdptx)
+       struct device *dev = hdptx->dev;
+       const char *name, *pname;
+       struct clk *refclk;
+-      int ret, id;
++      int ret;
+       refclk = devm_clk_get(dev, "ref");
+       if (IS_ERR(refclk))
+               return dev_err_probe(dev, PTR_ERR(refclk),
+                                    "Failed to get ref clock\n");
+-      id = of_alias_get_id(dev->of_node, "hdptxphy");
+-      name = id > 0 ? "clk_hdmiphy_pixel1" : "clk_hdmiphy_pixel0";
++      name = hdptx->phy_id > 0 ? "clk_hdmiphy_pixel1" : "clk_hdmiphy_pixel0";
+       pname = __clk_get_name(refclk);
+       hdptx->hw.init = CLK_HW_INIT(name, pname, &hdptx_phy_clk_ops,
+@@ -1058,8 +1068,9 @@ static int rk_hdptx_phy_probe(struct platform_device *pdev)
+       struct phy_provider *phy_provider;
+       struct device *dev = &pdev->dev;
+       struct rk_hdptx_phy *hdptx;
++      struct resource *res;
+       void __iomem *regs;
+-      int ret;
++      int ret, id;
+       hdptx = devm_kzalloc(dev, sizeof(*hdptx), GFP_KERNEL);
+       if (!hdptx)
+@@ -1067,11 +1078,27 @@ static int rk_hdptx_phy_probe(struct platform_device *pdev)
+       hdptx->dev = dev;
+-      regs = devm_platform_ioremap_resource(pdev, 0);
++      regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+       if (IS_ERR(regs))
+               return dev_err_probe(dev, PTR_ERR(regs),
+                                    "Failed to ioremap resource\n");
++      hdptx->cfgs = device_get_match_data(dev);
++      if (!hdptx->cfgs)
++              return dev_err_probe(dev, -EINVAL, "missing match data\n");
++
++      /* find the phy-id from the io address */
++      hdptx->phy_id = -ENODEV;
++      for (id = 0; id < hdptx->cfgs->num_phys; id++) {
++              if (res->start == hdptx->cfgs->phy_ids[id]) {
++                      hdptx->phy_id = id;
++                      break;
++              }
++      }
++
++      if (hdptx->phy_id < 0)
++              return dev_err_probe(dev, -ENODEV, "no matching device found\n");
++
+       ret = devm_clk_bulk_get_all(dev, &hdptx->clks);
+       if (ret < 0)
+               return dev_err_probe(dev, ret, "Failed to get clocks\n");
+@@ -1132,8 +1159,19 @@ static const struct dev_pm_ops rk_hdptx_phy_pm_ops = {
+                      rk_hdptx_phy_runtime_resume, NULL)
+ };
++static const struct rk_hdptx_phy_cfg rk3588_hdptx_phy_cfgs = {
++      .num_phys = 2,
++      .phy_ids = {
++              0xfed60000,
++              0xfed70000,
++      },
++};
++
+ static const struct of_device_id rk_hdptx_phy_of_match[] = {
+-      { .compatible = "rockchip,rk3588-hdptx-phy", },
++      {
++              .compatible = "rockchip,rk3588-hdptx-phy",
++              .data = &rk3588_hdptx_phy_cfgs
++      },
+       {}
+ };
+ MODULE_DEVICE_TABLE(of, rk_hdptx_phy_of_match);
+-- 
+2.39.5
+
diff --git a/queue-6.14/pinctrl-bcm2835-don-t-einval-on-alternate-funcs-from.patch b/queue-6.14/pinctrl-bcm2835-don-t-einval-on-alternate-funcs-from.patch
new file mode 100644 (file)
index 0000000..42e1344
--- /dev/null
@@ -0,0 +1,61 @@
+From 224a68176909cb4e8228bcb0c2ab2e0d65ed8df5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Feb 2025 11:27:50 +0100
+Subject: pinctrl: bcm2835: don't -EINVAL on alternate funcs from
+ get_direction()
+
+From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+
+[ Upstream commit 75f87f5d04f73645136d7a603c331d844fc5704a ]
+
+Since commit 9d846b1aebbe ("gpiolib: check the return value of
+gpio_chip::get_direction()") we check the return value of the
+get_direction() callback as per its API contract. This driver returns
+-EINVAL if the pin in question is set to one of the alternative
+(non-GPIO) functions. This isn't really an error that should be
+communicated to GPIOLIB so default to returning the "safe" value of
+INPUT in this case. The GPIO subsystem does not have the notion of
+"unknown" direction.
+
+Fixes: 9d846b1aebbe ("gpiolib: check the return value of gpio_chip::get_direction()")
+Reported-by: Mark Brown <broonie@kernel.org>
+Closes: https://lore.kernel.org/all/Z7VFB1nST6lbmBIo@finisterre.sirena.org.uk/
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Reviewed-by: Stefan Wahren <wahrenst@gmx.net>
+Link: https://lore.kernel.org/20250219102750.38519-1-brgl@bgdev.pl
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/bcm/pinctrl-bcm2835.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+index cc1fe0555e196..eaeec096bc9a9 100644
+--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c
++++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+@@ -346,14 +346,14 @@ static int bcm2835_gpio_get_direction(struct gpio_chip *chip, unsigned int offse
+       struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
+       enum bcm2835_fsel fsel = bcm2835_pinctrl_fsel_get(pc, offset);
+-      /* Alternative function doesn't clearly provide a direction */
+-      if (fsel > BCM2835_FSEL_GPIO_OUT)
+-              return -EINVAL;
+-
+-      if (fsel == BCM2835_FSEL_GPIO_IN)
+-              return GPIO_LINE_DIRECTION_IN;
++      if (fsel == BCM2835_FSEL_GPIO_OUT)
++              return GPIO_LINE_DIRECTION_OUT;
+-      return GPIO_LINE_DIRECTION_OUT;
++      /*
++       * Alternative function doesn't clearly provide a direction. Default
++       * to INPUT.
++       */
++      return GPIO_LINE_DIRECTION_IN;
+ }
+ static void bcm2835_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+-- 
+2.39.5
+
diff --git a/queue-6.14/pinctrl-intel-fix-wrong-bypass-assignment-in-intel_p.patch b/queue-6.14/pinctrl-intel-fix-wrong-bypass-assignment-in-intel_p.patch
new file mode 100644 (file)
index 0000000..1c535a0
--- /dev/null
@@ -0,0 +1,39 @@
+From 4d05af4c9d23e52e5469ff58242f5849ce46e43b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Feb 2025 21:44:51 +0200
+Subject: pinctrl: intel: Fix wrong bypass assignment in
+ intel_pinctrl_probe_pwm()
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 0eee258cdf172763502f142d85e967f27a573be0 ]
+
+When instantiating PWM, the bypass should be set to false. The field
+is used for the selected Intel SoCs that do not have PWM feature enabled
+in their pin control IPs.
+
+Fixes: eb78d3604d6b ("pinctrl: intel: Enumerate PWM device when community has a capability")
+Reported-by: Alexis GUILLEMET <alexis.guillemet@dunasys.com>
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Tested-by: Alexis GUILLEMET <alexis.guillemet@dunasys.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/intel/pinctrl-intel.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c
+index 527e4b87ae52e..f8b0221055e4a 100644
+--- a/drivers/pinctrl/intel/pinctrl-intel.c
++++ b/drivers/pinctrl/intel/pinctrl-intel.c
+@@ -1543,7 +1543,6 @@ static int intel_pinctrl_probe_pwm(struct intel_pinctrl *pctrl,
+               .clk_rate = 19200000,
+               .npwm = 1,
+               .base_unit_bits = 22,
+-              .bypass = true,
+       };
+       struct pwm_chip *chip;
+-- 
+2.39.5
+
diff --git a/queue-6.14/pinctrl-npcm8xx-fix-incorrect-struct-npcm8xx_pincfg-.patch b/queue-6.14/pinctrl-npcm8xx-fix-incorrect-struct-npcm8xx_pincfg-.patch
new file mode 100644 (file)
index 0000000..1917a35
--- /dev/null
@@ -0,0 +1,57 @@
+From 953d1178bcd80d1f59f4d348877ff865d599796e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Mar 2025 12:57:14 +0200
+Subject: pinctrl: npcm8xx: Fix incorrect struct npcm8xx_pincfg assignment
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 113ec87b0f26a17b02c58aa2714a9b8f1020eed9 ]
+
+Sparse is not happy about implementation of the NPCM8XX_PINCFG()
+
+ pinctrl-npcm8xx.c:1314:9: warning: obsolete array initializer, use C99 syntax
+ pinctrl-npcm8xx.c:1315:9: warning: obsolete array initializer, use C99 syntax
+ ...
+ pinctrl-npcm8xx.c:1412:9: warning: obsolete array initializer, use C99 syntax
+ pinctrl-npcm8xx.c:1413:9: warning: too many warnings
+
+which uses index-based assignment in a wrong way, i.e. it missed
+the equal sign and hence the index is simply ignored, while the
+entries are indexed naturally. This is not a problem as the pin
+numbering repeats the natural order, but it might be in case of
+shuffling the entries. Fix this by adding missed equal sign and
+reformat a bit for better readability.
+
+Fixes: acf4884a5717 ("pinctrl: nuvoton: add NPCM8XX pinctrl and GPIO driver")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/20250318105932.2090926-2-andriy.shevchenko@linux.intel.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/nuvoton/pinctrl-npcm8xx.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pinctrl/nuvoton/pinctrl-npcm8xx.c b/drivers/pinctrl/nuvoton/pinctrl-npcm8xx.c
+index 17825bbe14213..f6a1e684a3864 100644
+--- a/drivers/pinctrl/nuvoton/pinctrl-npcm8xx.c
++++ b/drivers/pinctrl/nuvoton/pinctrl-npcm8xx.c
+@@ -1290,12 +1290,14 @@ static struct npcm8xx_func npcm8xx_funcs[] = {
+ };
+ #define NPCM8XX_PINCFG(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q) \
+-      [a] { .fn0 = fn_ ## b, .reg0 = NPCM8XX_GCR_ ## c, .bit0 = d, \
++      [a] = {                                                           \
++                      .flag = q,                                        \
++                      .fn0 = fn_ ## b, .reg0 = NPCM8XX_GCR_ ## c, .bit0 = d, \
+                       .fn1 = fn_ ## e, .reg1 = NPCM8XX_GCR_ ## f, .bit1 = g, \
+                       .fn2 = fn_ ## h, .reg2 = NPCM8XX_GCR_ ## i, .bit2 = j, \
+                       .fn3 = fn_ ## k, .reg3 = NPCM8XX_GCR_ ## l, .bit3 = m, \
+                       .fn4 = fn_ ## n, .reg4 = NPCM8XX_GCR_ ## o, .bit4 = p, \
+-                      .flag = q }
++      }
+ /* Drive strength controlled by NPCM8XX_GP_N_ODSC */
+ #define DRIVE_STRENGTH_LO_SHIFT               8
+-- 
+2.39.5
+
diff --git a/queue-6.14/pinctrl-nuvoton-npcm8xx-fix-error-handling-in-npcm8x.patch b/queue-6.14/pinctrl-nuvoton-npcm8xx-fix-error-handling-in-npcm8x.patch
new file mode 100644 (file)
index 0000000..422aeb4
--- /dev/null
@@ -0,0 +1,39 @@
+From 31b47361065b2ccc885b59256e97061423ded14a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Jan 2025 11:13:34 +0800
+Subject: pinctrl: nuvoton: npcm8xx: Fix error handling in npcm8xx_gpio_fw()
+
+From: Yue Haibing <yuehaibing@huawei.com>
+
+[ Upstream commit d6c6fd77e5816e3f6689a2767cdd777797506f24 ]
+
+fwnode_irq_get() was changed to not return 0, fix this by checking
+for negative error, also update the error log.
+
+Fixes: acf4884a5717 ("pinctrl: nuvoton: add NPCM8XX pinctrl and GPIO driver")
+Signed-off-by: Yue Haibing <yuehaibing@huawei.com>
+Link: https://lore.kernel.org/20250118031334.243324-1-yuehaibing@huawei.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/nuvoton/pinctrl-npcm8xx.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pinctrl/nuvoton/pinctrl-npcm8xx.c b/drivers/pinctrl/nuvoton/pinctrl-npcm8xx.c
+index d09a5e9b2eca5..17825bbe14213 100644
+--- a/drivers/pinctrl/nuvoton/pinctrl-npcm8xx.c
++++ b/drivers/pinctrl/nuvoton/pinctrl-npcm8xx.c
+@@ -2361,8 +2361,8 @@ static int npcm8xx_gpio_fw(struct npcm8xx_pinctrl *pctrl)
+                       return dev_err_probe(dev, ret, "gpio-ranges fail for GPIO bank %u\n", id);
+               ret = fwnode_irq_get(child, 0);
+-              if (!ret)
+-                      return dev_err_probe(dev, ret, "No IRQ for GPIO bank %u\n", id);
++              if (ret < 0)
++                      return dev_err_probe(dev, ret, "Failed to retrieve IRQ for bank %u\n", id);
+               pctrl->gpio_bank[id].irq = ret;
+               pctrl->gpio_bank[id].irq_chip = npcmgpio_irqchip;
+-- 
+2.39.5
+
diff --git a/queue-6.14/pinctrl-renesas-rza2-fix-missing-of_node_put-call.patch b/queue-6.14/pinctrl-renesas-rza2-fix-missing-of_node_put-call.patch
new file mode 100644 (file)
index 0000000..316935d
--- /dev/null
@@ -0,0 +1,42 @@
+From df9283bcbb6baf5eedf9c0a4ee6ad379faa76bfc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Mar 2025 16:37:53 +0000
+Subject: pinctrl: renesas: rza2: Fix missing of_node_put() call
+
+From: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
+
+[ Upstream commit abcdeb4e299a11ecb5a3ea0cce00e68e8f540375 ]
+
+of_parse_phandle_with_fixed_args() requires its caller to
+call into of_node_put() on the node pointer from the output
+structure, but such a call is currently missing.
+
+Call into of_node_put() to rectify that.
+
+Fixes: b59d0e782706 ("pinctrl: Add RZ/A2 pin and gpio controller")
+Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
+Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/20250305163753.34913-5-fabrizio.castro.jz@renesas.com
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/renesas/pinctrl-rza2.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/pinctrl/renesas/pinctrl-rza2.c b/drivers/pinctrl/renesas/pinctrl-rza2.c
+index dd1f8c29d3e75..8b36161c7c502 100644
+--- a/drivers/pinctrl/renesas/pinctrl-rza2.c
++++ b/drivers/pinctrl/renesas/pinctrl-rza2.c
+@@ -256,6 +256,8 @@ static int rza2_gpio_register(struct rza2_pinctrl_priv *priv)
+               return ret;
+       }
++      of_node_put(of_args.np);
++
+       if ((of_args.args[0] != 0) ||
+           (of_args.args[1] != 0) ||
+           (of_args.args[2] != priv->npins)) {
+-- 
+2.39.5
+
diff --git a/queue-6.14/pinctrl-renesas-rzg2l-fix-missing-of_node_put-call.patch b/queue-6.14/pinctrl-renesas-rzg2l-fix-missing-of_node_put-call.patch
new file mode 100644 (file)
index 0000000..479be04
--- /dev/null
@@ -0,0 +1,42 @@
+From 6065eeb07b0354500c7333ba5114f90a3b57c1e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Mar 2025 16:37:51 +0000
+Subject: pinctrl: renesas: rzg2l: Fix missing of_node_put() call
+
+From: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
+
+[ Upstream commit a5779e625e2b377f16a6675c432aaf299ce5028c ]
+
+of_parse_phandle_with_fixed_args() requires its caller to
+call into of_node_put() on the node pointer from the output
+structure, but such a call is currently missing.
+
+Call into of_node_put() to rectify that.
+
+Fixes: c4c4637eb57f ("pinctrl: renesas: Add RZ/G2L pin and gpio controller driver")
+Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
+Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/20250305163753.34913-3-fabrizio.castro.jz@renesas.com
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/renesas/pinctrl-rzg2l.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+index 5f006a059d9c2..d1da7f53fc600 100644
+--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
++++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+@@ -2756,6 +2756,8 @@ static int rzg2l_gpio_register(struct rzg2l_pinctrl *pctrl)
+       if (ret)
+               return dev_err_probe(pctrl->dev, ret, "Unable to parse gpio-ranges\n");
++      of_node_put(of_args.np);
++
+       if (of_args.args[0] != 0 || of_args.args[1] != 0 ||
+           of_args.args[2] != pctrl->data->n_port_pins)
+               return dev_err_probe(pctrl->dev, -EINVAL,
+-- 
+2.39.5
+
diff --git a/queue-6.14/pinctrl-renesas-rzg2l-suppress-binding-attributes.patch b/queue-6.14/pinctrl-renesas-rzg2l-suppress-binding-attributes.patch
new file mode 100644 (file)
index 0000000..9cbcd04
--- /dev/null
@@ -0,0 +1,40 @@
+From 15939d967b711d8033e83418d3b365390c15ebb6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 15 Feb 2025 15:12:35 +0200
+Subject: pinctrl: renesas: rzg2l: Suppress binding attributes
+
+From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+
+[ Upstream commit ea4065345643f3163e812e58ed8add2c75c3ee46 ]
+
+Suppress binding attributes for the rzg2l pinctrl driver, as it is an
+essential block for Renesas SoCs.  Unbinding the driver leads to
+warnings from __device_links_no_driver() and can eventually render the
+system inaccessible.
+
+Fixes: c4c4637eb57f ("pinctrl: renesas: Add RZ/G2L pin and gpio controller driver")
+Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/20250215131235.228274-1-claudiu.beznea.uj@bp.renesas.com
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/renesas/pinctrl-rzg2l.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+index ce4a07a3df49a..5f006a059d9c2 100644
+--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
++++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+@@ -3386,6 +3386,7 @@ static struct platform_driver rzg2l_pinctrl_driver = {
+               .name = DRV_NAME,
+               .of_match_table = of_match_ptr(rzg2l_pinctrl_of_table),
+               .pm = pm_sleep_ptr(&rzg2l_pinctrl_pm_ops),
++              .suppress_bind_attrs = true,
+       },
+       .probe = rzg2l_pinctrl_probe,
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.14/pinctrl-renesas-rzv2m-fix-missing-of_node_put-call.patch b/queue-6.14/pinctrl-renesas-rzv2m-fix-missing-of_node_put-call.patch
new file mode 100644 (file)
index 0000000..be1ec33
--- /dev/null
@@ -0,0 +1,42 @@
+From 29756efaee1f9d817bdcbcbbd0d5266f3429317d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Mar 2025 16:37:52 +0000
+Subject: pinctrl: renesas: rzv2m: Fix missing of_node_put() call
+
+From: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
+
+[ Upstream commit 5a550b00704d3a2cd9d766a9427b0f8166da37df ]
+
+of_parse_phandle_with_fixed_args() requires its caller to
+call into of_node_put() on the node pointer from the output
+structure, but such a call is currently missing.
+
+Call into of_node_put() to rectify that.
+
+Fixes: 92a9b8252576 ("pinctrl: renesas: Add RZ/V2M pin and gpio controller driver")
+Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
+Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/20250305163753.34913-4-fabrizio.castro.jz@renesas.com
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/renesas/pinctrl-rzv2m.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/pinctrl/renesas/pinctrl-rzv2m.c b/drivers/pinctrl/renesas/pinctrl-rzv2m.c
+index 4062c56619f59..8c7169db4fcce 100644
+--- a/drivers/pinctrl/renesas/pinctrl-rzv2m.c
++++ b/drivers/pinctrl/renesas/pinctrl-rzv2m.c
+@@ -940,6 +940,8 @@ static int rzv2m_gpio_register(struct rzv2m_pinctrl *pctrl)
+               return ret;
+       }
++      of_node_put(of_args.np);
++
+       if (of_args.args[0] != 0 || of_args.args[1] != 0 ||
+           of_args.args[2] != pctrl->data->n_port_pins) {
+               dev_err(pctrl->dev, "gpio-ranges does not match selected SOC\n");
+-- 
+2.39.5
+
diff --git a/queue-6.14/pinctrl-tegra-set-sfio-mode-to-mux-register.patch b/queue-6.14/pinctrl-tegra-set-sfio-mode-to-mux-register.patch
new file mode 100644 (file)
index 0000000..63505b3
--- /dev/null
@@ -0,0 +1,49 @@
+From 791469d26f64adeef96b9be300fca7a4d46496f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Mar 2025 10:35:42 +0530
+Subject: pinctrl: tegra: Set SFIO mode to Mux Register
+
+From: Prathamesh Shete <pshete@nvidia.com>
+
+[ Upstream commit 17013f0acb322e5052ff9b9d0fab0ab5a4bfd828 ]
+
+Tegra devices have an 'sfsel' bit field that determines whether a pin
+operates in SFIO (Special Function I/O) or GPIO mode. Currently,
+tegra_pinctrl_gpio_disable_free() sets this bit when releasing a GPIO.
+
+However, tegra_pinctrl_set_mux() can be called independently in certain
+code paths where gpio_disable_free() is not invoked. In such cases, failing
+to set the SFIO mode could lead to incorrect pin configurations, resulting
+in functional issues for peripherals relying on SFIO.
+
+This patch ensures that whenever set_mux() is called, the SFIO mode is
+correctly set in the Mux Register if the 'sfsel' bit is present. This
+prevents situations where the pin remains in GPIO mode despite being
+configured for SFIO use.
+
+Fixes: 971dac7123c7 ("pinctrl: add a driver for NVIDIA Tegra")
+Signed-off-by: Prathamesh Shete <pshete@nvidia.com>
+Link: https://lore.kernel.org/20250306050542.16335-1-pshete@nvidia.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/tegra/pinctrl-tegra.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/pinctrl/tegra/pinctrl-tegra.c b/drivers/pinctrl/tegra/pinctrl-tegra.c
+index c83e5a65e6801..3b046450bd3ff 100644
+--- a/drivers/pinctrl/tegra/pinctrl-tegra.c
++++ b/drivers/pinctrl/tegra/pinctrl-tegra.c
+@@ -270,6 +270,9 @@ static int tegra_pinctrl_set_mux(struct pinctrl_dev *pctldev,
+       val = pmx_readl(pmx, g->mux_bank, g->mux_reg);
+       val &= ~(0x3 << g->mux_bit);
+       val |= i << g->mux_bit;
++      /* Set the SFIO/GPIO selection to SFIO when under pinmux control*/
++      if (pmx->soc->sfsel_in_mux)
++              val |= (1 << g->sfsel_bit);
+       pmx_writel(pmx, val, g->mux_bank, g->mux_reg);
+       return 0;
+-- 
+2.39.5
+
diff --git a/queue-6.14/platform-x86-dell-ddv-fix-temperature-calculation.patch b/queue-6.14/platform-x86-dell-ddv-fix-temperature-calculation.patch
new file mode 100644 (file)
index 0000000..34a84ec
--- /dev/null
@@ -0,0 +1,50 @@
+From 27c30ccdc047966851d9fedc2f73a024b418b0b8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Mar 2025 06:30:07 +0100
+Subject: platform/x86: dell-ddv: Fix temperature calculation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Armin Wolf <W_Armin@gmx.de>
+
+[ Upstream commit 7a248294a3145bc65eb0d8980a0a8edbb1b92db4 ]
+
+On the Dell Inspiron 3505 the battery temperature is always
+0.1 degrees larger than the temperature show inside the OEM
+application.
+
+Emulate this behaviour to avoid showing strange looking values
+like 29.1 degrees.
+
+Fixes: 0331b1b0ba653 ("platform/x86: dell-ddv: Fix temperature scaling")
+Signed-off-by: Armin Wolf <W_Armin@gmx.de>
+Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20250305053009.378609-2-W_Armin@gmx.de
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/dell/dell-wmi-ddv.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/platform/x86/dell/dell-wmi-ddv.c b/drivers/platform/x86/dell/dell-wmi-ddv.c
+index e75cd6e1efe6a..ab5f7d3ab8249 100644
+--- a/drivers/platform/x86/dell/dell-wmi-ddv.c
++++ b/drivers/platform/x86/dell/dell-wmi-ddv.c
+@@ -665,8 +665,10 @@ static ssize_t temp_show(struct device *dev, struct device_attribute *attr, char
+       if (ret < 0)
+               return ret;
+-      /* Use 2731 instead of 2731.5 to avoid unnecessary rounding */
+-      return sysfs_emit(buf, "%d\n", value - 2731);
++      /* Use 2732 instead of 2731.5 to avoid unnecessary rounding and to emulate
++       * the behaviour of the OEM application which seems to round down the result.
++       */
++      return sysfs_emit(buf, "%d\n", value - 2732);
+ }
+ static ssize_t eppid_show(struct device *dev, struct device_attribute *attr, char *buf)
+-- 
+2.39.5
+
diff --git a/queue-6.14/platform-x86-dell-uart-backlight-make-dell_uart_bl_s.patch b/queue-6.14/platform-x86-dell-uart-backlight-make-dell_uart_bl_s.patch
new file mode 100644 (file)
index 0000000..0d823e3
--- /dev/null
@@ -0,0 +1,47 @@
+From 6a818e2c31843e5685d357b022ddd2497ee5a34e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Mar 2025 18:06:39 +0200
+Subject: platform/x86: dell-uart-backlight: Make dell_uart_bl_serdev_driver
+ static
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit 4878e0b14c3e31a87ab147bd2dae443394cb5a2c ]
+
+Sparse reports:
+
+dell-uart-backlight.c:328:29: warning: symbol
+'dell_uart_bl_serdev_driver' was not declared. Should it be static?
+
+Fix it by making the symbol static.
+
+Fixes: 484bae9e4d6ac ("platform/x86: Add new Dell UART backlight driver")
+Reviewed-by: Mario Limonciello <maroi.limonciello@amd.com>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/20250304160639.4295-2-ilpo.jarvinen@linux.intel.com
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/dell/dell-uart-backlight.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/platform/x86/dell/dell-uart-backlight.c b/drivers/platform/x86/dell/dell-uart-backlight.c
+index 50002ef13d5d4..8f868f845350a 100644
+--- a/drivers/platform/x86/dell/dell-uart-backlight.c
++++ b/drivers/platform/x86/dell/dell-uart-backlight.c
+@@ -325,7 +325,7 @@ static int dell_uart_bl_serdev_probe(struct serdev_device *serdev)
+       return PTR_ERR_OR_ZERO(dell_bl->bl);
+ }
+-struct serdev_device_driver dell_uart_bl_serdev_driver = {
++static struct serdev_device_driver dell_uart_bl_serdev_driver = {
+       .probe = dell_uart_bl_serdev_probe,
+       .driver = {
+               .name = KBUILD_MODNAME,
+-- 
+2.39.5
+
diff --git a/queue-6.14/platform-x86-lenovo-yoga-tab2-pro-1380-fastcharger-m.patch b/queue-6.14/platform-x86-lenovo-yoga-tab2-pro-1380-fastcharger-m.patch
new file mode 100644 (file)
index 0000000..14ec0fa
--- /dev/null
@@ -0,0 +1,47 @@
+From 7af41486776275a0d49a6822ea94c2631b120f62 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Mar 2025 18:06:38 +0200
+Subject: platform/x86: lenovo-yoga-tab2-pro-1380-fastcharger: Make symbol
+ static
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit 886ca11a0c70efe5627a18557062e8a44370d78f ]
+
+Sparse reports:
+
+lenovo-yoga-tab2-pro-1380-fastcharger.c:222:29: warning: symbol
+'yt2_1380_fc_serdev_driver' was not declared. Should it be static?
+
+Fix that by making the symbol static.
+
+Fixes: b2ed33e8d486a ("platform/x86: Add  lenovo-yoga-tab2-pro-1380-fastcharger driver")
+Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/20250304160639.4295-1-ilpo.jarvinen@linux.intel.com
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/lenovo-yoga-tab2-pro-1380-fastcharger.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/platform/x86/lenovo-yoga-tab2-pro-1380-fastcharger.c b/drivers/platform/x86/lenovo-yoga-tab2-pro-1380-fastcharger.c
+index a96b215cd2c5e..25933cd018d17 100644
+--- a/drivers/platform/x86/lenovo-yoga-tab2-pro-1380-fastcharger.c
++++ b/drivers/platform/x86/lenovo-yoga-tab2-pro-1380-fastcharger.c
+@@ -219,7 +219,7 @@ static int yt2_1380_fc_serdev_probe(struct serdev_device *serdev)
+       return 0;
+ }
+-struct serdev_device_driver yt2_1380_fc_serdev_driver = {
++static struct serdev_device_driver yt2_1380_fc_serdev_driver = {
+       .probe = yt2_1380_fc_serdev_probe,
+       .driver = {
+               .name = KBUILD_MODNAME,
+-- 
+2.39.5
+
diff --git a/queue-6.14/pm-sleep-adjust-check-before-setting-power.must_resu.patch b/queue-6.14/pm-sleep-adjust-check-before-setting-power.must_resu.patch
new file mode 100644 (file)
index 0000000..0bf1283
--- /dev/null
@@ -0,0 +1,86 @@
+From a64c5e409591be70a98621518124c0e8c15f1b11 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 11:53:50 +0100
+Subject: PM: sleep: Adjust check before setting power.must_resume
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit eeb87d17aceab7803a5a5bcb6cf2817b745157cf ]
+
+The check before setting power.must_resume in device_suspend_noirq()
+does not take power.child_count into account, but it should do that, so
+use pm_runtime_need_not_resume() in it for this purpose and adjust the
+comment next to it accordingly.
+
+Fixes: 107d47b2b95e ("PM: sleep: core: Simplify the SMART_SUSPEND flag handling")
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
+Link: https://patch.msgid.link/3353728.44csPzL39Z@rjwysocki.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/power/main.c    | 13 ++++++-------
+ drivers/base/power/runtime.c |  2 +-
+ include/linux/pm_runtime.h   |  2 ++
+ 3 files changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
+index 40e1d8d8a5893..5afafd4e13dff 100644
+--- a/drivers/base/power/main.c
++++ b/drivers/base/power/main.c
+@@ -1270,14 +1270,13 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state, bool asy
+       dev->power.is_noirq_suspended = true;
+       /*
+-       * Skipping the resume of devices that were in use right before the
+-       * system suspend (as indicated by their PM-runtime usage counters)
+-       * would be suboptimal.  Also resume them if doing that is not allowed
+-       * to be skipped.
++       * Devices must be resumed unless they are explicitly allowed to be left
++       * in suspend, but even in that case skipping the resume of devices that
++       * were in use right before the system suspend (as indicated by their
++       * runtime PM usage counters and child counters) would be suboptimal.
+        */
+-      if (atomic_read(&dev->power.usage_count) > 1 ||
+-          !(dev_pm_test_driver_flags(dev, DPM_FLAG_MAY_SKIP_RESUME) &&
+-            dev->power.may_skip_resume))
++      if (!(dev_pm_test_driver_flags(dev, DPM_FLAG_MAY_SKIP_RESUME) &&
++            dev->power.may_skip_resume) || !pm_runtime_need_not_resume(dev))
+               dev->power.must_resume = true;
+       if (dev->power.must_resume) {
+diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
+index 2ee45841486bc..04113adb092b5 100644
+--- a/drivers/base/power/runtime.c
++++ b/drivers/base/power/runtime.c
+@@ -1874,7 +1874,7 @@ void pm_runtime_drop_link(struct device_link *link)
+       pm_request_idle(link->supplier);
+ }
+-static bool pm_runtime_need_not_resume(struct device *dev)
++bool pm_runtime_need_not_resume(struct device *dev)
+ {
+       return atomic_read(&dev->power.usage_count) <= 1 &&
+               (atomic_read(&dev->power.child_count) == 0 ||
+diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h
+index d39dc863f612f..d0b29cd1fd204 100644
+--- a/include/linux/pm_runtime.h
++++ b/include/linux/pm_runtime.h
+@@ -66,6 +66,7 @@ static inline bool queue_pm_work(struct work_struct *work)
+ extern int pm_generic_runtime_suspend(struct device *dev);
+ extern int pm_generic_runtime_resume(struct device *dev);
++extern bool pm_runtime_need_not_resume(struct device *dev);
+ extern int pm_runtime_force_suspend(struct device *dev);
+ extern int pm_runtime_force_resume(struct device *dev);
+@@ -241,6 +242,7 @@ static inline bool queue_pm_work(struct work_struct *work) { return false; }
+ static inline int pm_generic_runtime_suspend(struct device *dev) { return 0; }
+ static inline int pm_generic_runtime_resume(struct device *dev) { return 0; }
++static inline bool pm_runtime_need_not_resume(struct device *dev) {return true; }
+ static inline int pm_runtime_force_suspend(struct device *dev) { return 0; }
+ static inline int pm_runtime_force_resume(struct device *dev) { return 0; }
+-- 
+2.39.5
+
diff --git a/queue-6.14/pm-sleep-fix-handling-devices-with-direct_complete-s.patch b/queue-6.14/pm-sleep-fix-handling-devices-with-direct_complete-s.patch
new file mode 100644 (file)
index 0000000..6a3301d
--- /dev/null
@@ -0,0 +1,91 @@
+From 34c9fb2182dbd19c496ba1a0247274f4388480cc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Mar 2025 17:00:00 +0100
+Subject: PM: sleep: Fix handling devices with direct_complete set on errors
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 03f1444016b71feffa1dfb8a51f15ba592f94b13 ]
+
+When dpm_suspend() fails, some devices with power.direct_complete set
+may not have been handled by device_suspend() yet, so runtime PM has
+not been disabled for them yet even though power.direct_complete is set.
+
+Since device_resume() expects that runtime PM has been disabled for all
+devices with power.direct_complete set, it will attempt to reenable
+runtime PM for the devices that have not been processed by device_suspend()
+which does not make sense.  Had those devices had runtime PM disabled
+before device_suspend() had run, device_resume() would have inadvertently
+enable runtime PM for them, but this is not expected to happen because
+it would require ->prepare() callbacks to return positive values for
+devices with runtime PM disabled, which would be invalid.
+
+In practice, this issue is most likely benign because pm_runtime_enable()
+will not allow the "disable depth" counter to underflow, but it causes a
+warning message to be printed for each affected device.
+
+To allow device_resume() to distinguish the "direct complete" devices
+that have been processed by device_suspend() from those which have not
+been handled by it, make device_suspend() set power.is_suspended for
+"direct complete" devices.
+
+Next, move the power.is_suspended check in device_resume() before the
+power.direct_complete check in it to make it skip the "direct complete"
+devices that have not been handled by device_suspend().
+
+This change is based on a preliminary patch from Saravana Kannan.
+
+Fixes: aae4518b3124 ("PM / sleep: Mechanism to avoid resuming runtime-suspended devices unnecessarily")
+Link: https://lore.kernel.org/linux-pm/20241114220921.2529905-2-saravanak@google.com/
+Reported-by: Saravana Kannan <saravanak@google.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Reviewed-by: Saravana Kannan <saravanak@google.com>
+Link: https://patch.msgid.link/12627587.O9o76ZdvQC@rjwysocki.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/power/main.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
+index 5afafd4e13dff..23be2d1b04079 100644
+--- a/drivers/base/power/main.c
++++ b/drivers/base/power/main.c
+@@ -929,6 +929,9 @@ static void device_resume(struct device *dev, pm_message_t state, bool async)
+       if (dev->power.syscore)
+               goto Complete;
++      if (!dev->power.is_suspended)
++              goto Complete;
++
+       if (dev->power.direct_complete) {
+               /* Match the pm_runtime_disable() in device_suspend(). */
+               pm_runtime_enable(dev);
+@@ -947,9 +950,6 @@ static void device_resume(struct device *dev, pm_message_t state, bool async)
+        */
+       dev->power.is_prepared = false;
+-      if (!dev->power.is_suspended)
+-              goto Unlock;
+-
+       if (dev->pm_domain) {
+               info = "power domain ";
+               callback = pm_op(&dev->pm_domain->ops, state);
+@@ -989,7 +989,6 @@ static void device_resume(struct device *dev, pm_message_t state, bool async)
+       error = dpm_run_callback(callback, dev, state, info);
+       dev->power.is_suspended = false;
+- Unlock:
+       device_unlock(dev);
+       dpm_watchdog_clear(&wd);
+@@ -1649,6 +1648,7 @@ static int device_suspend(struct device *dev, pm_message_t state, bool async)
+                       pm_runtime_disable(dev);
+                       if (pm_runtime_status_suspended(dev)) {
+                               pm_dev_dbg(dev, state, "direct-complete ");
++                              dev->power.is_suspended = true;
+                               goto Complete;
+                       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/power-supply-bq27xxx_battery-do-not-update-cached-fl.patch b/queue-6.14/power-supply-bq27xxx_battery-do-not-update-cached-fl.patch
new file mode 100644 (file)
index 0000000..4e699ce
--- /dev/null
@@ -0,0 +1,40 @@
+From a992418cbebd06ce81c51c47a9a89deeee8c4b5b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Nov 2024 17:29:30 +0200
+Subject: power: supply: bq27xxx_battery: do not update cached flags
+ prematurely
+
+From: Sicelo A. Mhlongo <absicsz@gmail.com>
+
+[ Upstream commit 45291874a762dbb12a619dc2efaf84598859007a ]
+
+Commit 243f8ffc883a1 ("power: supply: bq27xxx_battery: Notify also about
+status changes") intended to notify userspace when the status changes,
+based on the flags register. However, the cached state is updated too
+early, before the flags are tested for any changes. Remove the premature
+update.
+
+Fixes: 243f8ffc883a1 ("power: supply: bq27xxx_battery: Notify also about status changes")
+Signed-off-by: Sicelo A. Mhlongo <absicsz@gmail.com>
+Link: https://lore.kernel.org/r/20241125152945.47937-1-absicsz@gmail.com
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/bq27xxx_battery.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
+index 90a5bccfc6b9b..a8d8bcaace2f0 100644
+--- a/drivers/power/supply/bq27xxx_battery.c
++++ b/drivers/power/supply/bq27xxx_battery.c
+@@ -1918,7 +1918,6 @@ static void bq27xxx_battery_update_unlocked(struct bq27xxx_device_info *di)
+               cache.flags = -1; /* read error */
+       if (cache.flags >= 0) {
+               cache.capacity = bq27xxx_battery_read_soc(di);
+-              di->cache.flags = cache.flags;
+               /*
+                * On gauges with signed current reporting the current must be
+-- 
+2.39.5
+
diff --git a/queue-6.14/power-supply-max77693-fix-wrong-conversion-of-charge.patch b/queue-6.14/power-supply-max77693-fix-wrong-conversion-of-charge.patch
new file mode 100644 (file)
index 0000000..0ce8dd8
--- /dev/null
@@ -0,0 +1,46 @@
+From f23da0295e496ac89aef07543c1258d2ae4ecc72 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 16 Mar 2025 21:11:49 +0100
+Subject: power: supply: max77693: Fix wrong conversion of charge input
+ threshold value
+
+From: Artur Weber <aweber.kernel@gmail.com>
+
+[ Upstream commit 30cc7b0d0e9341d419eb7da15fb5c22406dbe499 ]
+
+The charge input threshold voltage register on the MAX77693 PMIC accepts
+four values: 0x0 for 4.3v, 0x1 for 4.7v, 0x2 for 4.8v and 0x3 for 4.9v.
+Due to an oversight, the driver calculated the values for 4.7v and above
+starting from 0x0, rather than from 0x1 ([(4700000 - 4700000) / 100000]
+gives 0).
+
+Add 1 to the calculation to ensure that 4.7v is converted to a register
+value of 0x1 and that the other two voltages are converted correctly as
+well.
+
+Fixes: 87c2d9067893 ("power: max77693: Add charger driver for Maxim 77693")
+Signed-off-by: Artur Weber <aweber.kernel@gmail.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20250316-max77693-charger-input-threshold-fix-v1-1-2b037d0ac722@gmail.com
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/max77693_charger.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/power/supply/max77693_charger.c b/drivers/power/supply/max77693_charger.c
+index cdea35c0d1de1..027d6a539b65a 100644
+--- a/drivers/power/supply/max77693_charger.c
++++ b/drivers/power/supply/max77693_charger.c
+@@ -608,7 +608,7 @@ static int max77693_set_charge_input_threshold_volt(struct max77693_charger *chg
+       case 4700000:
+       case 4800000:
+       case 4900000:
+-              data = (uvolt - 4700000) / 100000;
++              data = ((uvolt - 4700000) / 100000) + 1;
+               break;
+       default:
+               dev_err(chg->dev, "Wrong value for charge input voltage regulation threshold\n");
+-- 
+2.39.5
+
diff --git a/queue-6.14/powerpc-kexec-fix-physical-address-calculation-in-cl.patch b/queue-6.14/powerpc-kexec-fix-physical-address-calculation-in-cl.patch
new file mode 100644 (file)
index 0000000..73b3ba0
--- /dev/null
@@ -0,0 +1,57 @@
+From 979f84138c447176a33b160396b59361c8dee4db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Mar 2025 11:24:28 +0100
+Subject: powerpc/kexec: fix physical address calculation in clear_utlb_entry()
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+[ Upstream commit 861efb8a48ee8b73ae4e8817509cd4e82fd52bc4 ]
+
+In relocate_32.S, function clear_utlb_entry() goes into real mode. To
+do so, it has to calculate the physical address based on the virtual
+address. To get the virtual address it uses 'bl' which is problematic
+(see commit c974809a26a1 ("powerpc/vdso: Avoid link stack corruption
+in __get_datapage()")). In addition, the calculation is done on a
+wrong address because 'bl' loads LR with the address of the following
+instruction, not the address of the target. So when the target is not
+the instruction following the 'bl' instruction, it may lead to
+unexpected behaviour.
+
+Fix it by re-writing the code so that is goes via another path which
+is based 'bcl 20,31,.+4' which is the right instruction to use for that.
+
+Fixes: 683430200315 ("powerpc/47x: Kernel support for KEXEC")
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/dc4f9616fba9c05c5dbf9b4b5480eb1c362adc17.1741256651.git.christophe.leroy@csgroup.eu
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kexec/relocate_32.S | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/arch/powerpc/kexec/relocate_32.S b/arch/powerpc/kexec/relocate_32.S
+index 104c9911f4061..dd86e338307d3 100644
+--- a/arch/powerpc/kexec/relocate_32.S
++++ b/arch/powerpc/kexec/relocate_32.S
+@@ -348,16 +348,13 @@ write_utlb:
+       rlwinm  r10, r24, 0, 22, 27
+       cmpwi   r10, PPC47x_TLB0_4K
+-      bne     0f
+       li      r10, 0x1000                     /* r10 = 4k */
+-      ANNOTATE_INTRA_FUNCTION_CALL
+-      bl      1f
++      beq     0f
+-0:
+       /* Defaults to 256M */
+       lis     r10, 0x1000
+-      bcl     20,31,$+4
++0:    bcl     20,31,$+4
+ 1:    mflr    r4
+       addi    r4, r4, (2f-1b)                 /* virtual address  of 2f */
+-- 
+2.39.5
+
diff --git a/queue-6.14/powerpc-perf-fix-ref-counting-on-the-pmu-vpa_pmu.patch b/queue-6.14/powerpc-perf-fix-ref-counting-on-the-pmu-vpa_pmu.patch
new file mode 100644 (file)
index 0000000..12ab6e4
--- /dev/null
@@ -0,0 +1,57 @@
+From f3b59f412cb78f06db160ca90d5ef85220c82a99 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Feb 2025 21:05:26 +0530
+Subject: powerpc/perf: Fix ref-counting on the PMU 'vpa_pmu'
+
+From: Vaibhav Jain <vaibhav@linux.ibm.com>
+
+[ Upstream commit ff99d5b6a246715f2257123cdf6c4a29cb33aa78 ]
+
+Commit 176cda0619b6 ("powerpc/perf: Add perf interface to expose vpa
+counters") introduced 'vpa_pmu' to expose Book3s-HV nested APIv2 provided
+L1<->L2 context switch latency counters to L1 user-space via
+perf-events. However the newly introduced PMU named 'vpa_pmu' doesn't
+assign ownership of the PMU to the module 'vpa_pmu'. Consequently the
+module 'vpa_pmu' can be unloaded while one of the perf-events are still
+active, which can lead to kernel oops and panic of the form below on a
+Pseries-LPAR:
+
+BUG: Kernel NULL pointer dereference on read at 0x00000058
+<snip>
+ NIP [c000000000506cb8] event_sched_out+0x40/0x258
+ LR [c00000000050e8a4] __perf_remove_from_context+0x7c/0x2b0
+ Call Trace:
+ [c00000025fc3fc30] [c00000025f8457a8] 0xc00000025f8457a8 (unreliable)
+ [c00000025fc3fc80] [fffffffffffffee0] 0xfffffffffffffee0
+ [c00000025fc3fcd0] [c000000000501e70] event_function+0xa8/0x120
+<snip>
+ Kernel panic - not syncing: Aiee, killing interrupt handler!
+
+Fix this by adding the module ownership to 'vpa_pmu' so that the module
+'vpa_pmu' is ref-counted and prevented from being unloaded when perf-events
+are initialized.
+
+Fixes: 176cda0619b6 ("powerpc/perf: Add perf interface to expose vpa counters")
+Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20250204153527.125491-1-vaibhav@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/perf/vpa-pmu.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/powerpc/perf/vpa-pmu.c b/arch/powerpc/perf/vpa-pmu.c
+index 6a5bfd2a13b5a..8407334689596 100644
+--- a/arch/powerpc/perf/vpa-pmu.c
++++ b/arch/powerpc/perf/vpa-pmu.c
+@@ -156,6 +156,7 @@ static void vpa_pmu_del(struct perf_event *event, int flags)
+ }
+ static struct pmu vpa_pmu = {
++      .module         = THIS_MODULE,
+       .task_ctx_nr    = perf_sw_context,
+       .name           = "vpa_pmu",
+       .event_init     = vpa_pmu_event_init,
+-- 
+2.39.5
+
diff --git a/queue-6.14/ptp-ocp-reject-unsupported-periodic-output-flags.patch b/queue-6.14/ptp-ocp-reject-unsupported-periodic-output-flags.patch
new file mode 100644 (file)
index 0000000..f523ae7
--- /dev/null
@@ -0,0 +1,45 @@
+From 431089d4d0c3adc64a74b288fc2f18443309cf33 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Mar 2025 15:15:54 -0700
+Subject: ptp: ocp: reject unsupported periodic output flags
+
+From: Jacob Keller <jacob.e.keller@intel.com>
+
+[ Upstream commit 8dcfc910a81d8b53f59f8b23211e81f2a91f84f9 ]
+
+The ptp_ocp_signal_from_perout() function supports PTP_PEROUT_DUTY_CYCLE
+and PTP_PEROUT_PHASE. It does not support PTP_PEROUT_ONE_SHOT, but does not
+reject a request with such an unsupported flag.
+
+Add the appropriate check to ensure that unsupported requests are rejected
+both for PTP_PEROUT_ONE_SHOT as well as any future flags.
+
+Fixes: 1aa66a3a135a ("ptp: ocp: Program the signal generators via PTP_CLK_REQ_PEROUT")
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250312-jk-net-fixes-supported-extts-flags-v2-5-ea930ba82459@intel.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ptp/ptp_ocp.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c
+index b651087f426f5..4a87af0980d69 100644
+--- a/drivers/ptp/ptp_ocp.c
++++ b/drivers/ptp/ptp_ocp.c
+@@ -2090,6 +2090,10 @@ ptp_ocp_signal_from_perout(struct ptp_ocp *bp, int gen,
+ {
+       struct ptp_ocp_signal s = { };
++      if (req->flags & ~(PTP_PEROUT_DUTY_CYCLE |
++                         PTP_PEROUT_PHASE))
++              return -EOPNOTSUPP;
++
+       s.polarity = bp->signal[gen].polarity;
+       s.period = ktime_set(req->period.sec, req->period.nsec);
+       if (!s.period)
+-- 
+2.39.5
+
diff --git a/queue-6.14/rcu-tasks-always-inline-rcu_irq_work_resched.patch b/queue-6.14/rcu-tasks-always-inline-rcu_irq_work_resched.patch
new file mode 100644 (file)
index 0000000..6000987
--- /dev/null
@@ -0,0 +1,43 @@
+From f2e38fa21e2fbf989fcf8bb48c891ff542489d6b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Mar 2025 21:26:46 -0700
+Subject: rcu-tasks: Always inline rcu_irq_work_resched()
+
+From: Josh Poimboeuf <jpoimboe@kernel.org>
+
+[ Upstream commit 6309a5c43b0dc629851f25b2e5ef8beff61d08e5 ]
+
+Thanks to CONFIG_DEBUG_SECTION_MISMATCH, empty functions can be
+generated out of line.  rcu_irq_work_resched() can be called from
+noinstr code, so make sure it's always inlined.
+
+Fixes: 564506495ca9 ("rcu/context-tracking: Move deferred nocb resched to context tracking")
+Reported-by: Randy Dunlap <rdunlap@infradead.org>
+Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Cc: Frederic Weisbecker <frederic@kernel.org>
+Cc: Paul E. McKenney <paulmck@kernel.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Link: https://lore.kernel.org/r/e84f15f013c07e4c410d972e75620c53b62c1b3e.1743481539.git.jpoimboe@kernel.org
+Closes: https://lore.kernel.org/d1eca076-fdde-484a-b33e-70e0d167c36d@infradead.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/rcupdate.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
+index 48e5c03df1dd8..bd69ddc102fbc 100644
+--- a/include/linux/rcupdate.h
++++ b/include/linux/rcupdate.h
+@@ -138,7 +138,7 @@ static inline void rcu_sysrq_end(void) { }
+ #if defined(CONFIG_NO_HZ_FULL) && (!defined(CONFIG_GENERIC_ENTRY) || !defined(CONFIG_KVM_XFER_TO_GUEST_WORK))
+ void rcu_irq_work_resched(void);
+ #else
+-static inline void rcu_irq_work_resched(void) { }
++static __always_inline void rcu_irq_work_resched(void) { }
+ #endif
+ #ifdef CONFIG_RCU_NOCB_CPU
+-- 
+2.39.5
+
diff --git a/queue-6.14/rdma-core-don-t-expose-hw_counters-outside-of-init-n.patch b/queue-6.14/rdma-core-don-t-expose-hw_counters-outside-of-init-n.patch
new file mode 100644 (file)
index 0000000..58adc31
--- /dev/null
@@ -0,0 +1,150 @@
+From 94cfd22b952acb3a5d82dec13480544310331a46 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 16:54:20 +0000
+Subject: RDMA/core: Don't expose hw_counters outside of init net namespace
+
+From: Roman Gushchin <roman.gushchin@linux.dev>
+
+[ Upstream commit a1ecb30f90856b0be4168ad51b8875148e285c1f ]
+
+Commit 467f432a521a ("RDMA/core: Split port and device counter sysfs
+attributes") accidentally almost exposed hw counters to non-init net
+namespaces. It didn't expose them fully, as an attempt to read any of
+those counters leads to a crash like this one:
+
+[42021.807566] BUG: kernel NULL pointer dereference, address: 0000000000000028
+[42021.814463] #PF: supervisor read access in kernel mode
+[42021.819549] #PF: error_code(0x0000) - not-present page
+[42021.824636] PGD 0 P4D 0
+[42021.827145] Oops: 0000 [#1] SMP PTI
+[42021.830598] CPU: 82 PID: 2843922 Comm: switchto-defaul Kdump: loaded Tainted: G S      W I        XXX
+[42021.841697] Hardware name: XXX
+[42021.849619] RIP: 0010:hw_stat_device_show+0x1e/0x40 [ib_core]
+[42021.855362] Code: 90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa 0f 1f 44 00 00 49 89 d0 4c 8b 5e 20 48 8b 8f b8 04 00 00 48 81 c7 f0 fa ff ff <48> 8b 41 28 48 29 ce 48 83 c6 d0 48 c1 ee 04 69 d6 ab aa aa aa 48
+[42021.873931] RSP: 0018:ffff97fe90f03da0 EFLAGS: 00010287
+[42021.879108] RAX: ffff9406988a8c60 RBX: ffff940e1072d438 RCX: 0000000000000000
+[42021.886169] RDX: ffff94085f1aa000 RSI: ffff93c6cbbdbcb0 RDI: ffff940c7517aef0
+[42021.893230] RBP: ffff97fe90f03e70 R08: ffff94085f1aa000 R09: 0000000000000000
+[42021.900294] R10: ffff94085f1aa000 R11: ffffffffc0775680 R12: ffffffff87ca2530
+[42021.907355] R13: ffff940651602840 R14: ffff93c6cbbdbcb0 R15: ffff94085f1aa000
+[42021.914418] FS:  00007fda1a3b9700(0000) GS:ffff94453fb80000(0000) knlGS:0000000000000000
+[42021.922423] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[42021.928130] CR2: 0000000000000028 CR3: 00000042dcfb8003 CR4: 00000000003726f0
+[42021.935194] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+[42021.942257] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+[42021.949324] Call Trace:
+[42021.951756]  <TASK>
+[42021.953842]  [<ffffffff86c58674>] ? show_regs+0x64/0x70
+[42021.959030]  [<ffffffff86c58468>] ? __die+0x78/0xc0
+[42021.963874]  [<ffffffff86c9ef75>] ? page_fault_oops+0x2b5/0x3b0
+[42021.969749]  [<ffffffff87674b92>] ? exc_page_fault+0x1a2/0x3c0
+[42021.975549]  [<ffffffff87801326>] ? asm_exc_page_fault+0x26/0x30
+[42021.981517]  [<ffffffffc0775680>] ? __pfx_show_hw_stats+0x10/0x10 [ib_core]
+[42021.988482]  [<ffffffffc077564e>] ? hw_stat_device_show+0x1e/0x40 [ib_core]
+[42021.995438]  [<ffffffff86ac7f8e>] dev_attr_show+0x1e/0x50
+[42022.000803]  [<ffffffff86a3eeb1>] sysfs_kf_seq_show+0x81/0xe0
+[42022.006508]  [<ffffffff86a11134>] seq_read_iter+0xf4/0x410
+[42022.011954]  [<ffffffff869f4b2e>] vfs_read+0x16e/0x2f0
+[42022.017058]  [<ffffffff869f50ee>] ksys_read+0x6e/0xe0
+[42022.022073]  [<ffffffff8766f1ca>] do_syscall_64+0x6a/0xa0
+[42022.027441]  [<ffffffff8780013b>] entry_SYSCALL_64_after_hwframe+0x78/0xe2
+
+The problem can be reproduced using the following steps:
+  ip netns add foo
+  ip netns exec foo bash
+  cat /sys/class/infiniband/mlx4_0/hw_counters/*
+
+The panic occurs because of casting the device pointer into an
+ib_device pointer using container_of() in hw_stat_device_show() is
+wrong and leads to a memory corruption.
+
+However the real problem is that hw counters should never been exposed
+outside of the non-init net namespace.
+
+Fix this by saving the index of the corresponding attribute group
+(it might be 1 or 2 depending on the presence of driver-specific
+attributes) and zeroing the pointer to hw_counters group for compat
+devices during the initialization.
+
+With this fix applied hw_counters are not available in a non-init
+net namespace:
+  find /sys/class/infiniband/mlx4_0/ -name hw_counters
+    /sys/class/infiniband/mlx4_0/ports/1/hw_counters
+    /sys/class/infiniband/mlx4_0/ports/2/hw_counters
+    /sys/class/infiniband/mlx4_0/hw_counters
+
+  ip netns add foo
+  ip netns exec foo bash
+  find /sys/class/infiniband/mlx4_0/ -name hw_counters
+
+Fixes: 467f432a521a ("RDMA/core: Split port and device counter sysfs attributes")
+Signed-off-by: Roman Gushchin <roman.gushchin@linux.dev>
+Cc: Jason Gunthorpe <jgg@ziepe.ca>
+Cc: Leon Romanovsky <leon@kernel.org>
+Cc: Maher Sanalla <msanalla@nvidia.com>
+Cc: linux-rdma@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org
+Link: https://patch.msgid.link/20250227165420.3430301-1-roman.gushchin@linux.dev
+Reviewed-by: Parav Pandit <parav@nvidia.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/device.c | 9 +++++++++
+ drivers/infiniband/core/sysfs.c  | 1 +
+ include/rdma/ib_verbs.h          | 1 +
+ 3 files changed, 11 insertions(+)
+
+diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
+index 0ded91f056f39..8feb22089cbbd 100644
+--- a/drivers/infiniband/core/device.c
++++ b/drivers/infiniband/core/device.c
+@@ -528,6 +528,8 @@ static struct class ib_class = {
+ static void rdma_init_coredev(struct ib_core_device *coredev,
+                             struct ib_device *dev, struct net *net)
+ {
++      bool is_full_dev = &dev->coredev == coredev;
++
+       /* This BUILD_BUG_ON is intended to catch layout change
+        * of union of ib_core_device and device.
+        * dev must be the first element as ib_core and providers
+@@ -539,6 +541,13 @@ static void rdma_init_coredev(struct ib_core_device *coredev,
+       coredev->dev.class = &ib_class;
+       coredev->dev.groups = dev->groups;
++
++      /*
++       * Don't expose hw counters outside of the init namespace.
++       */
++      if (!is_full_dev && dev->hw_stats_attr_index)
++              coredev->dev.groups[dev->hw_stats_attr_index] = NULL;
++
+       device_initialize(&coredev->dev);
+       coredev->owner = dev;
+       INIT_LIST_HEAD(&coredev->port_list);
+diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
+index 9f97bef021497..210092b9bf17d 100644
+--- a/drivers/infiniband/core/sysfs.c
++++ b/drivers/infiniband/core/sysfs.c
+@@ -988,6 +988,7 @@ int ib_setup_device_attrs(struct ib_device *ibdev)
+       for (i = 0; i != ARRAY_SIZE(ibdev->groups); i++)
+               if (!ibdev->groups[i]) {
+                       ibdev->groups[i] = &data->group;
++                      ibdev->hw_stats_attr_index = i;
+                       return 0;
+               }
+       WARN(true, "struct ib_device->groups is too small");
+diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
+index 0ad104dae2539..43954bb0475a7 100644
+--- a/include/rdma/ib_verbs.h
++++ b/include/rdma/ib_verbs.h
+@@ -2750,6 +2750,7 @@ struct ib_device {
+        * It is a NULL terminated array.
+        */
+       const struct attribute_group    *groups[4];
++      u8                              hw_stats_attr_index;
+       u64                          uverbs_cmd_mask;
+-- 
+2.39.5
+
diff --git a/queue-6.14/rdma-core-fix-use-after-free-when-rename-device-name.patch b/queue-6.14/rdma-core-fix-use-after-free-when-rename-device-name.patch
new file mode 100644 (file)
index 0000000..a16fb69
--- /dev/null
@@ -0,0 +1,171 @@
+From 2d3c44a14de54530688bc77574ae3d88d73a26c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Mar 2025 17:24:21 +0800
+Subject: RDMA/core: Fix use-after-free when rename device name
+
+From: Wang Liang <wangliang74@huawei.com>
+
+[ Upstream commit 1d6a9e7449e2a0c1e2934eee7880ba8bd1e464cd ]
+
+Syzbot reported a slab-use-after-free with the following call trace:
+
+==================================================================
+BUG: KASAN: slab-use-after-free in nla_put+0xd3/0x150 lib/nlattr.c:1099
+Read of size 5 at addr ffff888140ea1c60 by task syz.0.988/10025
+
+CPU: 0 UID: 0 PID: 10025 Comm: syz.0.988
+Not tainted 6.14.0-rc4-syzkaller-00859-gf77f12010f67 #0
+Hardware name: Google Compute Engine, BIOS Google 02/12/2025
+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:408 [inline]
+ print_report+0x16e/0x5b0 mm/kasan/report.c:521
+ kasan_report+0x143/0x180 mm/kasan/report.c:634
+ kasan_check_range+0x282/0x290 mm/kasan/generic.c:189
+ __asan_memcpy+0x29/0x70 mm/kasan/shadow.c:105
+ nla_put+0xd3/0x150 lib/nlattr.c:1099
+ nla_put_string include/net/netlink.h:1621 [inline]
+ fill_nldev_handle+0x16e/0x200 drivers/infiniband/core/nldev.c:265
+ rdma_nl_notify_event+0x561/0xef0 drivers/infiniband/core/nldev.c:2857
+ ib_device_notify_register+0x22/0x230 drivers/infiniband/core/device.c:1344
+ ib_register_device+0x1292/0x1460 drivers/infiniband/core/device.c:1460
+ rxe_register_device+0x233/0x350 drivers/infiniband/sw/rxe/rxe_verbs.c:1540
+ rxe_net_add+0x74/0xf0 drivers/infiniband/sw/rxe/rxe_net.c:550
+ rxe_newlink+0xde/0x1a0 drivers/infiniband/sw/rxe/rxe.c:212
+ nldev_newlink+0x5ea/0x680 drivers/infiniband/core/nldev.c:1795
+ rdma_nl_rcv_skb drivers/infiniband/core/netlink.c:239 [inline]
+ rdma_nl_rcv+0x6dd/0x9e0 drivers/infiniband/core/netlink.c:259
+ netlink_unicast_kernel net/netlink/af_netlink.c:1313 [inline]
+ netlink_unicast+0x7f6/0x990 net/netlink/af_netlink.c:1339
+ netlink_sendmsg+0x8de/0xcb0 net/netlink/af_netlink.c:1883
+ sock_sendmsg_nosec net/socket.c:709 [inline]
+ __sock_sendmsg+0x221/0x270 net/socket.c:724
+ ____sys_sendmsg+0x53a/0x860 net/socket.c:2564
+ ___sys_sendmsg net/socket.c:2618 [inline]
+ __sys_sendmsg+0x269/0x350 net/socket.c:2650
+ do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+ do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+RIP: 0033:0x7f42d1b8d169
+Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 ...
+RSP: 002b:00007f42d2960038 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+RAX: ffffffffffffffda RBX: 00007f42d1da6320 RCX: 00007f42d1b8d169
+RDX: 0000000000000000 RSI: 00004000000002c0 RDI: 000000000000000c
+RBP: 00007f42d1c0e2a0 R08: 0000000000000000 R09: 0000000000000000
+R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
+R13: 0000000000000000 R14: 00007f42d1da6320 R15: 00007ffe399344a8
+ </TASK>
+
+Allocated by task 10025:
+ kasan_save_stack mm/kasan/common.c:47 [inline]
+ kasan_save_track+0x3f/0x80 mm/kasan/common.c:68
+ poison_kmalloc_redzone mm/kasan/common.c:377 [inline]
+ __kasan_kmalloc+0x98/0xb0 mm/kasan/common.c:394
+ kasan_kmalloc include/linux/kasan.h:260 [inline]
+ __do_kmalloc_node mm/slub.c:4294 [inline]
+ __kmalloc_node_track_caller_noprof+0x28b/0x4c0 mm/slub.c:4313
+ __kmemdup_nul mm/util.c:61 [inline]
+ kstrdup+0x42/0x100 mm/util.c:81
+ kobject_set_name_vargs+0x61/0x120 lib/kobject.c:274
+ dev_set_name+0xd5/0x120 drivers/base/core.c:3468
+ assign_name drivers/infiniband/core/device.c:1202 [inline]
+ ib_register_device+0x178/0x1460 drivers/infiniband/core/device.c:1384
+ rxe_register_device+0x233/0x350 drivers/infiniband/sw/rxe/rxe_verbs.c:1540
+ rxe_net_add+0x74/0xf0 drivers/infiniband/sw/rxe/rxe_net.c:550
+ rxe_newlink+0xde/0x1a0 drivers/infiniband/sw/rxe/rxe.c:212
+ nldev_newlink+0x5ea/0x680 drivers/infiniband/core/nldev.c:1795
+ rdma_nl_rcv_skb drivers/infiniband/core/netlink.c:239 [inline]
+ rdma_nl_rcv+0x6dd/0x9e0 drivers/infiniband/core/netlink.c:259
+ netlink_unicast_kernel net/netlink/af_netlink.c:1313 [inline]
+ netlink_unicast+0x7f6/0x990 net/netlink/af_netlink.c:1339
+ netlink_sendmsg+0x8de/0xcb0 net/netlink/af_netlink.c:1883
+ sock_sendmsg_nosec net/socket.c:709 [inline]
+ __sock_sendmsg+0x221/0x270 net/socket.c:724
+ ____sys_sendmsg+0x53a/0x860 net/socket.c:2564
+ ___sys_sendmsg net/socket.c:2618 [inline]
+ __sys_sendmsg+0x269/0x350 net/socket.c:2650
+ do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+ do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Freed by task 10035:
+ kasan_save_stack mm/kasan/common.c:47 [inline]
+ kasan_save_track+0x3f/0x80 mm/kasan/common.c:68
+ kasan_save_free_info+0x40/0x50 mm/kasan/generic.c:576
+ poison_slab_object mm/kasan/common.c:247 [inline]
+ __kasan_slab_free+0x59/0x70 mm/kasan/common.c:264
+ kasan_slab_free include/linux/kasan.h:233 [inline]
+ slab_free_hook mm/slub.c:2353 [inline]
+ slab_free mm/slub.c:4609 [inline]
+ kfree+0x196/0x430 mm/slub.c:4757
+ kobject_rename+0x38f/0x410 lib/kobject.c:524
+ device_rename+0x16a/0x200 drivers/base/core.c:4525
+ ib_device_rename+0x270/0x710 drivers/infiniband/core/device.c:402
+ nldev_set_doit+0x30e/0x4c0 drivers/infiniband/core/nldev.c:1146
+ rdma_nl_rcv_skb drivers/infiniband/core/netlink.c:239 [inline]
+ rdma_nl_rcv+0x6dd/0x9e0 drivers/infiniband/core/netlink.c:259
+ netlink_unicast_kernel net/netlink/af_netlink.c:1313 [inline]
+ netlink_unicast+0x7f6/0x990 net/netlink/af_netlink.c:1339
+ netlink_sendmsg+0x8de/0xcb0 net/netlink/af_netlink.c:1883
+ sock_sendmsg_nosec net/socket.c:709 [inline]
+ __sock_sendmsg+0x221/0x270 net/socket.c:724
+ ____sys_sendmsg+0x53a/0x860 net/socket.c:2564
+ ___sys_sendmsg net/socket.c:2618 [inline]
+ __sys_sendmsg+0x269/0x350 net/socket.c:2650
+ do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+ do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+This is because if rename device happens, the old name is freed in
+ib_device_rename() with lock, but ib_device_notify_register() may visit
+the dev name locklessly by event RDMA_REGISTER_EVENT or
+RDMA_NETDEV_ATTACH_EVENT.
+
+Fix this by hold devices_rwsem in ib_device_notify_register().
+
+Reported-by: syzbot+f60349ba1f9f08df349f@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=25bc6f0ed2b88b9eb9b8
+Fixes: 9cbed5aab5ae ("RDMA/nldev: Add support for RDMA monitoring")
+Signed-off-by: Wang Liang <wangliang74@huawei.com>
+Link: https://patch.msgid.link/20250313092421.944658-1-wangliang74@huawei.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/device.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
+index 8feb22089cbbd..ee75b99f84bcc 100644
+--- a/drivers/infiniband/core/device.c
++++ b/drivers/infiniband/core/device.c
+@@ -1350,9 +1350,11 @@ static void ib_device_notify_register(struct ib_device *device)
+       u32 port;
+       int ret;
++      down_read(&devices_rwsem);
++
+       ret = rdma_nl_notify_event(device, 0, RDMA_REGISTER_EVENT);
+       if (ret)
+-              return;
++              goto out;
+       rdma_for_each_port(device, port) {
+               netdev = ib_device_get_netdev(device, port);
+@@ -1363,8 +1365,11 @@ static void ib_device_notify_register(struct ib_device *device)
+                                          RDMA_NETDEV_ATTACH_EVENT);
+               dev_put(netdev);
+               if (ret)
+-                      return;
++                      goto out;
+       }
++
++out:
++      up_read(&devices_rwsem);
+ }
+ /**
+-- 
+2.39.5
+
diff --git a/queue-6.14/rdma-erdma-prevent-use-after-free-in-erdma_accept_ne.patch b/queue-6.14/rdma-erdma-prevent-use-after-free-in-erdma_accept_ne.patch
new file mode 100644 (file)
index 0000000..eb0d21d
--- /dev/null
@@ -0,0 +1,36 @@
+From 60fa719d89d296afc562e192d802d48c7f577a19 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Mar 2025 20:04:40 +0800
+Subject: RDMA/erdma: Prevent use-after-free in erdma_accept_newconn()
+
+From: Cheng Xu <chengyou@linux.alibaba.com>
+
+[ Upstream commit 83437689249e6a17b25e27712fbee292e42e7855 ]
+
+After the erdma_cep_put(new_cep) being called, new_cep will be freed,
+and the following dereference will cause a UAF problem. Fix this issue.
+
+Fixes: 920d93eac8b9 ("RDMA/erdma: Add connection management (CM) support")
+Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
+Signed-off-by: Cheng Xu <chengyou@linux.alibaba.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/erdma/erdma_cm.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/erdma/erdma_cm.c b/drivers/infiniband/hw/erdma/erdma_cm.c
+index 1b23c698ec25c..e0acc185e7193 100644
+--- a/drivers/infiniband/hw/erdma/erdma_cm.c
++++ b/drivers/infiniband/hw/erdma/erdma_cm.c
+@@ -709,7 +709,6 @@ static void erdma_accept_newconn(struct erdma_cep *cep)
+               erdma_cancel_mpatimer(new_cep);
+               erdma_cep_put(new_cep);
+-              new_cep->sock = NULL;
+       }
+       if (new_s) {
+-- 
+2.39.5
+
diff --git a/queue-6.14/rdma-mana_ib-ensure-variable-err-is-initialized.patch b/queue-6.14/rdma-mana_ib-ensure-variable-err-is-initialized.patch
new file mode 100644 (file)
index 0000000..831590d
--- /dev/null
@@ -0,0 +1,38 @@
+From d67c7e99de965fa823903ca55ba3d0ef99bcd271 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Feb 2025 20:39:03 +0100
+Subject: RDMA/mana_ib: Ensure variable err is initialized
+
+From: Kees Bakker <kees@ijzerbout.nl>
+
+[ Upstream commit be35a3127d60964b338da95c7bfaaf4a01b330d4 ]
+
+In the function mana_ib_gd_create_dma_region if there are no dma blocks
+to process the variable `err` remains uninitialized.
+
+Fixes: 0266a177631d ("RDMA/mana_ib: Add a driver for Microsoft Azure Network Adapter")
+Signed-off-by: Kees Bakker <kees@ijzerbout.nl>
+Link: https://patch.msgid.link/20250221195833.7516C16290A@bout3.ijzerbout.nl
+Reviewed-by: Long Li <longli@microsoft.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/mana/main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/mana/main.c b/drivers/infiniband/hw/mana/main.c
+index 457cea6d99095..f6bf289041bfe 100644
+--- a/drivers/infiniband/hw/mana/main.c
++++ b/drivers/infiniband/hw/mana/main.c
+@@ -358,7 +358,7 @@ static int mana_ib_gd_create_dma_region(struct mana_ib_dev *dev, struct ib_umem
+       unsigned int tail = 0;
+       u64 *page_addr_list;
+       void *request_buf;
+-      int err;
++      int err = 0;
+       gc = mdev_to_gc(dev);
+       hwc = gc->hwc.driver_data;
+-- 
+2.39.5
+
diff --git a/queue-6.14/rdma-mlx5-fix-calculation-of-total-invalidated-pages.patch b/queue-6.14/rdma-mlx5-fix-calculation-of-total-invalidated-pages.patch
new file mode 100644 (file)
index 0000000..548935d
--- /dev/null
@@ -0,0 +1,65 @@
+From 36f45d7fc4e04c547505bfdd55c4cb9197d689c1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Mar 2025 16:29:54 +0200
+Subject: RDMA/mlx5: Fix calculation of total invalidated pages
+
+From: Chiara Meiohas <cmeiohas@nvidia.com>
+
+[ Upstream commit 79195147644653ebffadece31a42181e4c48c07d ]
+
+When invalidating an address range in mlx5, there is an optimization to
+do UMR operations in chunks.
+Previously, the invalidation counter was incorrectly updated for the
+same indexes within a chunk. Now, the invalidation counter is updated
+only when a chunk is complete and mlx5r_umr_update_xlt() is called.
+This ensures that the counter accurately represents the number of pages
+invalidated using UMR.
+
+Fixes: a3de94e3d61e ("IB/mlx5: Introduce ODP diagnostic counters")
+Signed-off-by: Chiara Meiohas <cmeiohas@nvidia.com>
+Reviewed-by: Michael Guralnik <michaelgur@nvidia.com>
+Link: https://patch.msgid.link/560deb2433318e5947282b070c915f3c81fef77f.1741875692.git.leon@kernel.org
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/mlx5/odp.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/infiniband/hw/mlx5/odp.c b/drivers/infiniband/hw/mlx5/odp.c
+index e77c9280c07e4..86d8fa63bf691 100644
+--- a/drivers/infiniband/hw/mlx5/odp.c
++++ b/drivers/infiniband/hw/mlx5/odp.c
+@@ -309,9 +309,6 @@ static bool mlx5_ib_invalidate_range(struct mmu_interval_notifier *mni,
+                               blk_start_idx = idx;
+                               in_block = 1;
+                       }
+-
+-                      /* Count page invalidations */
+-                      invalidations += idx - blk_start_idx + 1;
+               } else {
+                       u64 umr_offset = idx & umr_block_mask;
+@@ -321,14 +318,19 @@ static bool mlx5_ib_invalidate_range(struct mmu_interval_notifier *mni,
+                                                    MLX5_IB_UPD_XLT_ZAP |
+                                                    MLX5_IB_UPD_XLT_ATOMIC);
+                               in_block = 0;
++                              /* Count page invalidations */
++                              invalidations += idx - blk_start_idx + 1;
+                       }
+               }
+       }
+-      if (in_block)
++      if (in_block) {
+               mlx5r_umr_update_xlt(mr, blk_start_idx,
+                                    idx - blk_start_idx + 1, 0,
+                                    MLX5_IB_UPD_XLT_ZAP |
+                                    MLX5_IB_UPD_XLT_ATOMIC);
++              /* Count page invalidations */
++              invalidations += idx - blk_start_idx + 1;
++      }
+       mlx5_update_odp_stats_with_handled(mr, invalidations, invalidations);
+-- 
+2.39.5
+
diff --git a/queue-6.14/rdma-mlx5-fix-mlx5_poll_one-cur_qp-update-flow.patch b/queue-6.14/rdma-mlx5-fix-mlx5_poll_one-cur_qp-update-flow.patch
new file mode 100644 (file)
index 0000000..17ce8e5
--- /dev/null
@@ -0,0 +1,91 @@
+From a6873b8c42c7bb65e8d9a71b5c8cfb0548261a2d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Mar 2025 16:29:53 +0200
+Subject: RDMA/mlx5: Fix mlx5_poll_one() cur_qp update flow
+
+From: Patrisious Haddad <phaddad@nvidia.com>
+
+[ Upstream commit 5ed3b0cb3f827072e93b4c5b6e2b8106fd7cccbd ]
+
+When cur_qp isn't NULL, in order to avoid fetching the QP from
+the radix tree again we check if the next cqe QP is identical to
+the one we already have.
+
+The bug however is that we are checking if the QP is identical by
+checking the QP number inside the CQE against the QP number inside the
+mlx5_ib_qp, but that's wrong since the QP number from the CQE is from
+FW so it should be matched against mlx5_core_qp which is our FW QP
+number.
+
+Otherwise we could use the wrong QP when handling a CQE which could
+cause the kernel trace below.
+
+This issue is mainly noticeable over QPs 0 & 1, since for now they are
+the only QPs in our driver whereas the QP number inside mlx5_ib_qp
+doesn't match the QP number inside mlx5_core_qp.
+
+BUG: kernel NULL pointer dereference, address: 0000000000000012
+ #PF: supervisor read access in kernel mode
+ #PF: error_code(0x0000) - not-present page
+ PGD 0 P4D 0
+ Oops: Oops: 0000 [#1] SMP
+ CPU: 0 UID: 0 PID: 7927 Comm: kworker/u62:1 Not tainted 6.14.0-rc3+ #189
+ Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014
+ Workqueue: ib-comp-unb-wq ib_cq_poll_work [ib_core]
+ RIP: 0010:mlx5_ib_poll_cq+0x4c7/0xd90 [mlx5_ib]
+ Code: 03 00 00 8d 58 ff 21 cb 66 39 d3 74 39 48 c7 c7 3c 89 6e a0 0f b7 db e8 b7 d2 b3 e0 49 8b 86 60 03 00 00 48 c7 c7 4a 89 6e a0 <0f> b7 5c 98 02 e8 9f d2 b3 e0 41 0f b7 86 78 03 00 00 83 e8 01 21
+ RSP: 0018:ffff88810511bd60 EFLAGS: 00010046
+ RAX: 0000000000000010 RBX: 0000000000000000 RCX: 0000000000000000
+ RDX: 0000000000000000 RSI: ffff88885fa1b3c0 RDI: ffffffffa06e894a
+ RBP: 00000000000000b0 R08: 0000000000000000 R09: ffff88810511bc10
+ R10: 0000000000000001 R11: 0000000000000001 R12: ffff88810d593000
+ R13: ffff88810e579108 R14: ffff888105146000 R15: 00000000000000b0
+ FS:  0000000000000000(0000) GS:ffff88885fa00000(0000) knlGS:0000000000000000
+ CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 0000000000000012 CR3: 00000001077e6001 CR4: 0000000000370eb0
+ Call Trace:
+  <TASK>
+  ? __die+0x20/0x60
+  ? page_fault_oops+0x150/0x3e0
+  ? exc_page_fault+0x74/0x130
+  ? asm_exc_page_fault+0x22/0x30
+  ? mlx5_ib_poll_cq+0x4c7/0xd90 [mlx5_ib]
+  __ib_process_cq+0x5a/0x150 [ib_core]
+  ib_cq_poll_work+0x31/0x90 [ib_core]
+  process_one_work+0x169/0x320
+  worker_thread+0x288/0x3a0
+  ? work_busy+0xb0/0xb0
+  kthread+0xd7/0x1f0
+  ? kthreads_online_cpu+0x130/0x130
+  ? kthreads_online_cpu+0x130/0x130
+  ret_from_fork+0x2d/0x50
+  ? kthreads_online_cpu+0x130/0x130
+  ret_from_fork_asm+0x11/0x20
+  </TASK>
+
+Fixes: e126ba97dba9 ("mlx5: Add driver for Mellanox Connect-IB adapters")
+Signed-off-by: Patrisious Haddad <phaddad@nvidia.com>
+Reviewed-by: Edward Srouji <edwards@nvidia.com>
+Link: https://patch.msgid.link/4ada09d41f1e36db62c44a9b25c209ea5f054316.1741875692.git.leon@kernel.org
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/mlx5/cq.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c
+index 4c54dc5780690..1aa5311b03e9f 100644
+--- a/drivers/infiniband/hw/mlx5/cq.c
++++ b/drivers/infiniband/hw/mlx5/cq.c
+@@ -490,7 +490,7 @@ static int mlx5_poll_one(struct mlx5_ib_cq *cq,
+       }
+       qpn = ntohl(cqe64->sop_drop_qpn) & 0xffffff;
+-      if (!*cur_qp || (qpn != (*cur_qp)->ibqp.qp_num)) {
++      if (!*cur_qp || (qpn != (*cur_qp)->trans_qp.base.mqp.qpn)) {
+               /* We do not have to take the QP table lock here,
+                * because CQs will be locked while QPs are removed
+                * from the table.
+-- 
+2.39.5
+
diff --git a/queue-6.14/rdma-mlx5-fix-mr-cache-initialization-error-flow.patch b/queue-6.14/rdma-mlx5-fix-mr-cache-initialization-error-flow.patch
new file mode 100644 (file)
index 0000000..d88157d
--- /dev/null
@@ -0,0 +1,83 @@
+From acb75bc2868ae672dd6a67b469580319a59e591c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Mar 2025 16:29:48 +0200
+Subject: RDMA/mlx5: Fix MR cache initialization error flow
+
+From: Michael Guralnik <michaelgur@nvidia.com>
+
+[ Upstream commit a0130ef84b00c68ba0b79ee974a0f01459741421 ]
+
+Destroy all previously created cache entries and work queue when rolling
+back the MR cache initialization upon an error.
+
+Fixes: 73d09b2fe833 ("RDMA/mlx5: Introduce mlx5r_cache_rb_key")
+Signed-off-by: Michael Guralnik <michaelgur@nvidia.com>
+Reviewed-by: Yishai Hadas <yishaih@nvidia.com>
+Link: https://patch.msgid.link/c41d525fb3c72e28dd38511bf3aaccb5d584063e.1741875692.git.leon@kernel.org
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/mlx5/mr.c | 33 ++++++++++++++++++++++-----------
+ 1 file changed, 22 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
+index eeb94d1ae60d9..068eac3bdb50b 100644
+--- a/drivers/infiniband/hw/mlx5/mr.c
++++ b/drivers/infiniband/hw/mlx5/mr.c
+@@ -919,6 +919,25 @@ mlx5r_cache_create_ent_locked(struct mlx5_ib_dev *dev,
+       return ERR_PTR(ret);
+ }
++static void mlx5r_destroy_cache_entries(struct mlx5_ib_dev *dev)
++{
++      struct rb_root *root = &dev->cache.rb_root;
++      struct mlx5_cache_ent *ent;
++      struct rb_node *node;
++
++      mutex_lock(&dev->cache.rb_lock);
++      node = rb_first(root);
++      while (node) {
++              ent = rb_entry(node, struct mlx5_cache_ent, node);
++              node = rb_next(node);
++              clean_keys(dev, ent);
++              rb_erase(&ent->node, root);
++              mlx5r_mkeys_uninit(ent);
++              kfree(ent);
++      }
++      mutex_unlock(&dev->cache.rb_lock);
++}
++
+ int mlx5_mkey_cache_init(struct mlx5_ib_dev *dev)
+ {
+       struct mlx5_mkey_cache *cache = &dev->cache;
+@@ -970,6 +989,8 @@ int mlx5_mkey_cache_init(struct mlx5_ib_dev *dev)
+ err:
+       mutex_unlock(&cache->rb_lock);
+       mlx5_mkey_cache_debugfs_cleanup(dev);
++      mlx5r_destroy_cache_entries(dev);
++      destroy_workqueue(cache->wq);
+       mlx5_ib_warn(dev, "failed to create mkey cache entry\n");
+       return ret;
+ }
+@@ -1003,17 +1024,7 @@ void mlx5_mkey_cache_cleanup(struct mlx5_ib_dev *dev)
+       mlx5_cmd_cleanup_async_ctx(&dev->async_ctx);
+       /* At this point all entries are disabled and have no concurrent work. */
+-      mutex_lock(&dev->cache.rb_lock);
+-      node = rb_first(root);
+-      while (node) {
+-              ent = rb_entry(node, struct mlx5_cache_ent, node);
+-              node = rb_next(node);
+-              clean_keys(dev, ent);
+-              rb_erase(&ent->node, root);
+-              mlx5r_mkeys_uninit(ent);
+-              kfree(ent);
+-      }
+-      mutex_unlock(&dev->cache.rb_lock);
++      mlx5r_destroy_cache_entries(dev);
+       destroy_workqueue(dev->cache.wq);
+       del_timer_sync(&dev->delay_timer);
+-- 
+2.39.5
+
diff --git a/queue-6.14/rdma-mlx5-fix-page_size-variable-overflow.patch b/queue-6.14/rdma-mlx5-fix-page_size-variable-overflow.patch
new file mode 100644 (file)
index 0000000..9db1710
--- /dev/null
@@ -0,0 +1,121 @@
+From a3231e474ff9d00eae1c4acb14d126bdde704658 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Mar 2025 16:29:51 +0200
+Subject: RDMA/mlx5: Fix page_size variable overflow
+
+From: Michael Guralnik <michaelgur@nvidia.com>
+
+[ Upstream commit f0c2427412b43cdf1b7b0944749ea17ddb97d5a5 ]
+
+Change all variables storing mlx5_umem_mkc_find_best_pgsz() result to
+unsigned long to support values larger than 31 and avoid overflow.
+
+For example: If we try to register 4GB of memory that is contiguous in
+physical memory, the driver will optimize the page_size and try to use
+an mkey with 4GB entity size. The 'unsigned int' page_size variable will
+overflow to '0' and we'll hit the WARN_ON() in alloc_cacheable_mr().
+
+WARNING: CPU: 2 PID: 1203 at drivers/infiniband/hw/mlx5/mr.c:1124 alloc_cacheable_mr+0x22/0x580 [mlx5_ib]
+Modules linked in: mlx5_ib mlx5_core bonding ip6_gre ip6_tunnel tunnel6 ip_gre gre rdma_rxe rdma_ucm ib_uverbs ib_ipoib ib_umad rpcrdma ib_iser libiscsi scsi_transport_iscsi rdma_cm iw_cm ib_cm fuse ib_core [last unloaded: mlx5_core]
+CPU: 2 UID: 70878 PID: 1203 Comm: rdma_resource_l Tainted: G        W          6.14.0-rc4-dirty #43
+Tainted: [W]=WARN
+Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
+RIP: 0010:alloc_cacheable_mr+0x22/0x580 [mlx5_ib]
+Code: 90 90 90 90 90 90 90 90 0f 1f 44 00 00 55 48 89 e5 41 57 41 56 41 55 41 54 41 52 53 48 83 ec 30 f6 46 28 04 4c 8b 77 08 75 21 <0f> 0b 49 c7 c2 ea ff ff ff 48 8d 65 d0 4c 89 d0 5b 41 5a 41 5c 41
+RSP: 0018:ffffc900006ffac8 EFLAGS: 00010246
+RAX: 0000000004c0d0d0 RBX: ffff888217a22000 RCX: 0000000000100001
+RDX: 00007fb7ac480000 RSI: ffff8882037b1240 RDI: ffff8882046f0600
+RBP: ffffc900006ffb28 R08: 0000000000000001 R09: 0000000000000000
+R10: 00000000000007e0 R11: ffffea0008011d40 R12: ffff8882037b1240
+R13: ffff8882046f0600 R14: ffff888217a22000 R15: ffffc900006ffe00
+FS:  00007fb7ed013340(0000) GS:ffff88885fd00000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00007fb7ed1d8000 CR3: 00000001fd8f6006 CR4: 0000000000772eb0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+PKRU: 55555554
+Call Trace:
+ <TASK>
+ ? __warn+0x81/0x130
+ ? alloc_cacheable_mr+0x22/0x580 [mlx5_ib]
+ ? report_bug+0xfc/0x1e0
+ ? handle_bug+0x55/0x90
+ ? exc_invalid_op+0x17/0x70
+ ? asm_exc_invalid_op+0x1a/0x20
+ ? alloc_cacheable_mr+0x22/0x580 [mlx5_ib]
+ create_real_mr+0x54/0x150 [mlx5_ib]
+ ib_uverbs_reg_mr+0x17f/0x2a0 [ib_uverbs]
+ ib_uverbs_handler_UVERBS_METHOD_INVOKE_WRITE+0xca/0x140 [ib_uverbs]
+ ib_uverbs_run_method+0x6d0/0x780 [ib_uverbs]
+ ? __pfx_ib_uverbs_handler_UVERBS_METHOD_INVOKE_WRITE+0x10/0x10 [ib_uverbs]
+ ib_uverbs_cmd_verbs+0x19b/0x360 [ib_uverbs]
+ ? walk_system_ram_range+0x79/0xd0
+ ? ___pte_offset_map+0x1b/0x110
+ ? __pte_offset_map_lock+0x80/0x100
+ ib_uverbs_ioctl+0xac/0x110 [ib_uverbs]
+ __x64_sys_ioctl+0x94/0xb0
+ do_syscall_64+0x50/0x110
+ entry_SYSCALL_64_after_hwframe+0x76/0x7e
+RIP: 0033:0x7fb7ecf0737b
+Code: ff ff ff 85 c0 79 9b 49 c7 c4 ff ff ff ff 5b 5d 4c 89 e0 41 5c c3 66 0f 1f 84 00 00 00 00 00 f3 0f 1e fa b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 7d 2a 0f 00 f7 d8 64 89 01 48
+RSP: 002b:00007ffdbe03ecc8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
+RAX: ffffffffffffffda RBX: 00007ffdbe03edb8 RCX: 00007fb7ecf0737b
+RDX: 00007ffdbe03eda0 RSI: 00000000c0181b01 RDI: 0000000000000003
+RBP: 00007ffdbe03ed80 R08: 00007fb7ecc84010 R09: 00007ffdbe03eed4
+R10: 0000000000000009 R11: 0000000000000246 R12: 00007ffdbe03eed4
+R13: 000000000000000c R14: 000000000000000c R15: 00007fb7ecc84150
+ </TASK>
+
+Fixes: cef7dde8836a ("net/mlx5: Expand mkey page size to support 6 bits")
+Signed-off-by: Michael Guralnik <michaelgur@nvidia.com>
+Reviewed-by: Yishai Hadas <yishaih@nvidia.com>
+Link: https://patch.msgid.link/2479a4a3f6fd9bd032e1b6d396274a89c4c5e22f.1741875692.git.leon@kernel.org
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/mlx5/mr.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
+index 753faa9ad06a8..eeb94d1ae60d9 100644
+--- a/drivers/infiniband/hw/mlx5/mr.c
++++ b/drivers/infiniband/hw/mlx5/mr.c
+@@ -56,7 +56,7 @@ static void
+ create_mkey_callback(int status, struct mlx5_async_work *context);
+ static struct mlx5_ib_mr *reg_create(struct ib_pd *pd, struct ib_umem *umem,
+                                    u64 iova, int access_flags,
+-                                   unsigned int page_size, bool populate,
++                                   unsigned long page_size, bool populate,
+                                    int access_mode);
+ static int __mlx5_ib_dereg_mr(struct ib_mr *ibmr);
+@@ -1115,7 +1115,7 @@ static struct mlx5_ib_mr *alloc_cacheable_mr(struct ib_pd *pd,
+       struct mlx5r_cache_rb_key rb_key = {};
+       struct mlx5_cache_ent *ent;
+       struct mlx5_ib_mr *mr;
+-      unsigned int page_size;
++      unsigned long page_size;
+       if (umem->is_dmabuf)
+               page_size = mlx5_umem_dmabuf_default_pgsz(umem, iova);
+@@ -1219,7 +1219,7 @@ reg_create_crossing_vhca_mr(struct ib_pd *pd, u64 iova, u64 length, int access_f
+  */
+ static struct mlx5_ib_mr *reg_create(struct ib_pd *pd, struct ib_umem *umem,
+                                    u64 iova, int access_flags,
+-                                   unsigned int page_size, bool populate,
++                                   unsigned long page_size, bool populate,
+                                    int access_mode)
+ {
+       struct mlx5_ib_dev *dev = to_mdev(pd->device);
+@@ -1425,7 +1425,7 @@ static struct ib_mr *create_real_mr(struct ib_pd *pd, struct ib_umem *umem,
+               mr = alloc_cacheable_mr(pd, umem, iova, access_flags,
+                                       MLX5_MKC_ACCESS_MODE_MTT);
+       } else {
+-              unsigned int page_size =
++              unsigned long page_size =
+                       mlx5_umem_mkc_find_best_pgsz(dev, umem, iova);
+               mutex_lock(&dev->slow_path_mutex);
+-- 
+2.39.5
+
diff --git a/queue-6.14/reboot-reboot-not-shutdown-on-hw_protection_reboot-t.patch b/queue-6.14/reboot-reboot-not-shutdown-on-hw_protection_reboot-t.patch
new file mode 100644 (file)
index 0000000..7bf7344
--- /dev/null
@@ -0,0 +1,163 @@
+From e068e7a7e3cf40db47c4a6caac20477ee8f0a06e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 21:39:42 +0100
+Subject: reboot: reboot, not shutdown, on hw_protection_reboot timeout
+
+From: Ahmad Fatoum <a.fatoum@pengutronix.de>
+
+[ Upstream commit bbf0ec4f57e0a34983ca25f00ec90f4765572d78 ]
+
+hw_protection_shutdown() will kick off an orderly shutdown and if that
+takes longer than a configurable amount of time, an emergency shutdown
+will occur.
+
+Recently, hw_protection_reboot() was added for those systems that don't
+implement a proper shutdown and are better served by rebooting and having
+the boot firmware worry about doing something about the critical
+condition.
+
+On timeout of the orderly reboot of hw_protection_reboot(), the system
+would go into shutdown, instead of reboot.  This is not a good idea, as
+going into shutdown was explicitly not asked for.
+
+Fix this by always doing an emergency reboot if hw_protection_reboot() is
+called and the orderly reboot takes too long.
+
+Link: https://lkml.kernel.org/r/20250217-hw_protection-reboot-v3-2-e1c09b090c0c@pengutronix.de
+Fixes: 79fa723ba84c ("reboot: Introduce thermal_zone_device_critical_reboot()")
+Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
+Reviewed-by: Tzung-Bi Shih <tzungbi@kernel.org>
+Reviewed-by: Matti Vaittinen <mazziesaccount@gmail.com>
+Cc: Benson Leung <bleung@chromium.org>
+Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
+Cc: Fabio Estevam <festevam@denx.de>
+Cc: Guenter Roeck <groeck@chromium.org>
+Cc: Jonathan Corbet <corbet@lwn.net>
+Cc: Liam Girdwood <lgirdwood@gmail.com>
+Cc: Lukasz Luba <lukasz.luba@arm.com>
+Cc: Mark Brown <broonie@kernel.org>
+Cc: Matteo Croce <teknoraver@meta.com>
+Cc: "Rafael J. Wysocki" <rafael@kernel.org>
+Cc: Rob Herring (Arm) <robh@kernel.org>
+Cc: Rui Zhang <rui.zhang@intel.com>
+Cc: Sascha Hauer <kernel@pengutronix.de>
+Cc: "Serge E. Hallyn" <serge@hallyn.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/reboot.c | 70 ++++++++++++++++++++++++++++++++++---------------
+ 1 file changed, 49 insertions(+), 21 deletions(-)
+
+diff --git a/kernel/reboot.c b/kernel/reboot.c
+index b20b53f08648d..f348f1ba9e226 100644
+--- a/kernel/reboot.c
++++ b/kernel/reboot.c
+@@ -932,48 +932,76 @@ void orderly_reboot(void)
+ }
+ EXPORT_SYMBOL_GPL(orderly_reboot);
++static const char *hw_protection_action_str(enum hw_protection_action action)
++{
++      switch (action) {
++      case HWPROT_ACT_SHUTDOWN:
++              return "shutdown";
++      case HWPROT_ACT_REBOOT:
++              return "reboot";
++      default:
++              return "undefined";
++      }
++}
++
++static enum hw_protection_action hw_failure_emergency_action;
++
+ /**
+- * hw_failure_emergency_poweroff_func - emergency poweroff work after a known delay
+- * @work: work_struct associated with the emergency poweroff function
++ * hw_failure_emergency_action_func - emergency action work after a known delay
++ * @work: work_struct associated with the emergency action function
+  *
+  * This function is called in very critical situations to force
+- * a kernel poweroff after a configurable timeout value.
++ * a kernel poweroff or reboot after a configurable timeout value.
+  */
+-static void hw_failure_emergency_poweroff_func(struct work_struct *work)
++static void hw_failure_emergency_action_func(struct work_struct *work)
+ {
++      const char *action_str = hw_protection_action_str(hw_failure_emergency_action);
++
++      pr_emerg("Hardware protection timed-out. Trying forced %s\n",
++               action_str);
++
+       /*
+-       * We have reached here after the emergency shutdown waiting period has
+-       * expired. This means orderly_poweroff has not been able to shut off
+-       * the system for some reason.
++       * We have reached here after the emergency action waiting period has
++       * expired. This means orderly_poweroff/reboot has not been able to
++       * shut off the system for some reason.
+        *
+-       * Try to shut down the system immediately using kernel_power_off
+-       * if populated
++       * Try to shut off the system immediately if possible
+        */
+-      pr_emerg("Hardware protection timed-out. Trying forced poweroff\n");
+-      kernel_power_off();
++
++      if (hw_failure_emergency_action == HWPROT_ACT_REBOOT)
++              kernel_restart(NULL);
++      else
++              kernel_power_off();
+       /*
+        * Worst of the worst case trigger emergency restart
+        */
+-      pr_emerg("Hardware protection shutdown failed. Trying emergency restart\n");
++      pr_emerg("Hardware protection %s failed. Trying emergency restart\n",
++               action_str);
+       emergency_restart();
+ }
+-static DECLARE_DELAYED_WORK(hw_failure_emergency_poweroff_work,
+-                          hw_failure_emergency_poweroff_func);
++static DECLARE_DELAYED_WORK(hw_failure_emergency_action_work,
++                          hw_failure_emergency_action_func);
+ /**
+- * hw_failure_emergency_poweroff - Trigger an emergency system poweroff
++ * hw_failure_emergency_schedule - Schedule an emergency system shutdown or reboot
++ *
++ * @action:           The hardware protection action to be taken
++ * @action_delay_ms:  Time in milliseconds to elapse before triggering action
+  *
+  * This may be called from any critical situation to trigger a system shutdown
+- * after a given period of time. If time is negative this is not scheduled.
++ * or reboot after a given period of time.
++ * If time is negative this is not scheduled.
+  */
+-static void hw_failure_emergency_poweroff(int poweroff_delay_ms)
++static void hw_failure_emergency_schedule(enum hw_protection_action action,
++                                        int action_delay_ms)
+ {
+-      if (poweroff_delay_ms <= 0)
++      if (action_delay_ms <= 0)
+               return;
+-      schedule_delayed_work(&hw_failure_emergency_poweroff_work,
+-                            msecs_to_jiffies(poweroff_delay_ms));
++      hw_failure_emergency_action = action;
++      schedule_delayed_work(&hw_failure_emergency_action_work,
++                            msecs_to_jiffies(action_delay_ms));
+ }
+ /**
+@@ -1006,7 +1034,7 @@ void __hw_protection_shutdown(const char *reason, int ms_until_forced,
+        * Queue a backup emergency shutdown in the event of
+        * orderly_poweroff failure
+        */
+-      hw_failure_emergency_poweroff(ms_until_forced);
++      hw_failure_emergency_schedule(action, ms_until_forced);
+       if (action == HWPROT_ACT_REBOOT)
+               orderly_reboot();
+       else
+-- 
+2.39.5
+
diff --git a/queue-6.14/reboot-replace-__hw_protection_shutdown-bool-action-.patch b/queue-6.14/reboot-replace-__hw_protection_shutdown-bool-action-.patch
new file mode 100644 (file)
index 0000000..1117133
--- /dev/null
@@ -0,0 +1,163 @@
+From 5fcd3b3a72e0b163e889efa538d1aeb785c97579 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 21:39:41 +0100
+Subject: reboot: replace __hw_protection_shutdown bool action parameter with
+ an enum
+
+From: Ahmad Fatoum <a.fatoum@pengutronix.de>
+
+[ Upstream commit 318f05a057157c400a92f17c5f2fa3dd96f57c7e ]
+
+Patch series "reboot: support runtime configuration of emergency
+hw_protection action", v3.
+
+We currently leave the decision of whether to shutdown or reboot to
+protect hardware in an emergency situation to the individual drivers.
+
+This works out in some cases, where the driver detecting the critical
+failure has inside knowledge: It binds to the system management controller
+for example or is guided by hardware description that defines what to do.
+
+This is inadequate in the general case though as a driver reporting e.g.
+an imminent power failure can't know whether a shutdown or a reboot would
+be more appropriate for a given hardware platform.
+
+To address this, this series adds a hw_protection kernel parameter and
+sysfs toggle that can be used to change the action from the shutdown
+default to reboot.  A new hw_protection_trigger API then makes use of this
+default action.
+
+My particular use case is unattended embedded systems that don't have
+support for shutdown and that power on automatically when power is
+supplied:
+
+  - A brief power cycle gets detected by the driver
+  - The kernel powers down the system and SoC goes into shutdown mode
+  - Power is restored
+  - The system remains oblivious to the restored power
+  - System needs to be manually power cycled for a duration long enough
+    to drain the capacitors
+
+With this series, such systems can configure the kernel with
+hw_protection=reboot to have the boot firmware worry about critical
+conditions.
+
+This patch (of 12):
+
+Currently __hw_protection_shutdown() either reboots or shuts down the
+system according to its shutdown argument.
+
+To make the logic easier to follow, both inside __hw_protection_shutdown
+and at caller sites, lets replace the bool parameter with an enum.
+
+This will be extra useful, when in a later commit, a third action is added
+to the enumeration.
+
+No functional change.
+
+Link: https://lkml.kernel.org/r/20250217-hw_protection-reboot-v3-0-e1c09b090c0c@pengutronix.de
+Link: https://lkml.kernel.org/r/20250217-hw_protection-reboot-v3-1-e1c09b090c0c@pengutronix.de
+Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
+Reviewed-by: Tzung-Bi Shih <tzungbi@kernel.org>
+Cc: Benson Leung <bleung@chromium.org>
+Cc: Mark Brown <broonie@kernel.org>
+Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
+Cc: Fabio Estevam <festevam@denx.de>
+Cc: Guenter Roeck <groeck@chromium.org>
+Cc: Jonathan Corbet <corbet@lwn.net>
+Cc: Liam Girdwood <lgirdwood@gmail.com>
+Cc: Lukasz Luba <lukasz.luba@arm.com>
+Cc: Matteo Croce <teknoraver@meta.com>
+Cc: Matti Vaittinen <mazziesaccount@gmail.com>
+Cc: "Rafael J. Wysocki" <rafael@kernel.org>
+Cc: Rob Herring <robh@kernel.org>
+Cc: Rui Zhang <rui.zhang@intel.com>
+Cc: Sascha Hauer <kernel@pengutronix.de>
+Cc: "Serge E. Hallyn" <serge@hallyn.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Stable-dep-of: bbf0ec4f57e0 ("reboot: reboot, not shutdown, on hw_protection_reboot timeout")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/reboot.h | 18 +++++++++++++++---
+ kernel/reboot.c        | 14 ++++++--------
+ 2 files changed, 21 insertions(+), 11 deletions(-)
+
+diff --git a/include/linux/reboot.h b/include/linux/reboot.h
+index abcdde4df6979..e97f6b8e85868 100644
+--- a/include/linux/reboot.h
++++ b/include/linux/reboot.h
+@@ -177,16 +177,28 @@ void ctrl_alt_del(void);
+ extern void orderly_poweroff(bool force);
+ extern void orderly_reboot(void);
+-void __hw_protection_shutdown(const char *reason, int ms_until_forced, bool shutdown);
++
++/**
++ * enum hw_protection_action - Hardware protection action
++ *
++ * @HWPROT_ACT_SHUTDOWN:
++ *    The system should be shut down (powered off) for HW protection.
++ * @HWPROT_ACT_REBOOT:
++ *    The system should be rebooted for HW protection.
++ */
++enum hw_protection_action { HWPROT_ACT_SHUTDOWN, HWPROT_ACT_REBOOT };
++
++void __hw_protection_shutdown(const char *reason, int ms_until_forced,
++                            enum hw_protection_action action);
+ static inline void hw_protection_reboot(const char *reason, int ms_until_forced)
+ {
+-      __hw_protection_shutdown(reason, ms_until_forced, false);
++      __hw_protection_shutdown(reason, ms_until_forced, HWPROT_ACT_REBOOT);
+ }
+ static inline void hw_protection_shutdown(const char *reason, int ms_until_forced)
+ {
+-      __hw_protection_shutdown(reason, ms_until_forced, true);
++      __hw_protection_shutdown(reason, ms_until_forced, HWPROT_ACT_SHUTDOWN);
+ }
+ /*
+diff --git a/kernel/reboot.c b/kernel/reboot.c
+index b5a8569e5d81f..b20b53f08648d 100644
+--- a/kernel/reboot.c
++++ b/kernel/reboot.c
+@@ -983,10 +983,7 @@ static void hw_failure_emergency_poweroff(int poweroff_delay_ms)
+  * @ms_until_forced:  Time to wait for orderly shutdown or reboot before
+  *                    triggering it. Negative value disables the forced
+  *                    shutdown or reboot.
+- * @shutdown:         If true, indicates that a shutdown will happen
+- *                    after the critical tempeature is reached.
+- *                    If false, indicates that a reboot will happen
+- *                    after the critical tempeature is reached.
++ * @action:           The hardware protection action to be taken.
+  *
+  * Initiate an emergency system shutdown or reboot in order to protect
+  * hardware from further damage. Usage examples include a thermal protection.
+@@ -994,7 +991,8 @@ static void hw_failure_emergency_poweroff(int poweroff_delay_ms)
+  * pending even if the previous request has given a large timeout for forced
+  * shutdown/reboot.
+  */
+-void __hw_protection_shutdown(const char *reason, int ms_until_forced, bool shutdown)
++void __hw_protection_shutdown(const char *reason, int ms_until_forced,
++                            enum hw_protection_action action)
+ {
+       static atomic_t allow_proceed = ATOMIC_INIT(1);
+@@ -1009,10 +1007,10 @@ void __hw_protection_shutdown(const char *reason, int ms_until_forced, bool shut
+        * orderly_poweroff failure
+        */
+       hw_failure_emergency_poweroff(ms_until_forced);
+-      if (shutdown)
+-              orderly_poweroff(true);
+-      else
++      if (action == HWPROT_ACT_REBOOT)
+               orderly_reboot();
++      else
++              orderly_poweroff(true);
+ }
+ EXPORT_SYMBOL_GPL(__hw_protection_shutdown);
+-- 
+2.39.5
+
diff --git a/queue-6.14/regulator-pca9450-fix-enable-register-for-ldo5.patch b/queue-6.14/regulator-pca9450-fix-enable-register-for-ldo5.patch
new file mode 100644 (file)
index 0000000..a8c7499
--- /dev/null
@@ -0,0 +1,56 @@
+From 3ae272dc1e43584b4c8ea413b2a1c066e0ff163b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Dec 2024 16:27:28 +0100
+Subject: regulator: pca9450: Fix enable register for LDO5
+
+From: Frieder Schrempf <frieder.schrempf@kontron.de>
+
+[ Upstream commit f5aab0438ef17f01c5ecd25e61ae6a03f82a4586 ]
+
+The LDO5 regulator has two configuration registers, but only
+LDO5CTRL_L contains the bits for enabling/disabling the regulator.
+
+Fixes: 0935ff5f1f0a ("regulator: pca9450: add pca9450 pmic driver")
+Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
+Reviewed-by: Marek Vasut <marex@denx.de>
+Link: https://patch.msgid.link/20241218152842.97483-6-frieder@fris.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/pca9450-regulator.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/regulator/pca9450-regulator.c b/drivers/regulator/pca9450-regulator.c
+index faa6b79c27d75..dfe1dd93d56f5 100644
+--- a/drivers/regulator/pca9450-regulator.c
++++ b/drivers/regulator/pca9450-regulator.c
+@@ -460,7 +460,7 @@ static const struct pca9450_regulator_desc pca9450a_regulators[] = {
+                       .n_linear_ranges = ARRAY_SIZE(pca9450_ldo5_volts),
+                       .vsel_reg = PCA9450_REG_LDO5CTRL_H,
+                       .vsel_mask = LDO5HOUT_MASK,
+-                      .enable_reg = PCA9450_REG_LDO5CTRL_H,
++                      .enable_reg = PCA9450_REG_LDO5CTRL_L,
+                       .enable_mask = LDO5H_EN_MASK,
+                       .owner = THIS_MODULE,
+               },
+@@ -674,7 +674,7 @@ static const struct pca9450_regulator_desc pca9450bc_regulators[] = {
+                       .n_linear_ranges = ARRAY_SIZE(pca9450_ldo5_volts),
+                       .vsel_reg = PCA9450_REG_LDO5CTRL_H,
+                       .vsel_mask = LDO5HOUT_MASK,
+-                      .enable_reg = PCA9450_REG_LDO5CTRL_H,
++                      .enable_reg = PCA9450_REG_LDO5CTRL_L,
+                       .enable_mask = LDO5H_EN_MASK,
+                       .owner = THIS_MODULE,
+               },
+@@ -864,7 +864,7 @@ static const struct pca9450_regulator_desc pca9451a_regulators[] = {
+                       .n_linear_ranges = ARRAY_SIZE(pca9450_ldo5_volts),
+                       .vsel_reg = PCA9450_REG_LDO5CTRL_H,
+                       .vsel_mask = LDO5HOUT_MASK,
+-                      .enable_reg = PCA9450_REG_LDO5CTRL_H,
++                      .enable_reg = PCA9450_REG_LDO5CTRL_L,
+                       .enable_mask = LDO5H_EN_MASK,
+                       .owner = THIS_MODULE,
+               },
+-- 
+2.39.5
+
diff --git a/queue-6.14/remoteproc-core-clear-table_sz-when-rproc_shutdown.patch b/queue-6.14/remoteproc-core-clear-table_sz-when-rproc_shutdown.patch
new file mode 100644 (file)
index 0000000..352e22d
--- /dev/null
@@ -0,0 +1,86 @@
+From 03548ac7dacba2057f32d2bdc2286d855c76328a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Mar 2025 18:01:05 +0800
+Subject: remoteproc: core: Clear table_sz when rproc_shutdown
+
+From: Peng Fan <peng.fan@nxp.com>
+
+[ Upstream commit efdde3d73ab25cef4ff2d06783b0aad8b093c0e4 ]
+
+There is case as below could trigger kernel dump:
+Use U-Boot to start remote processor(rproc) with resource table
+published to a fixed address by rproc. After Kernel boots up,
+stop the rproc, load a new firmware which doesn't have resource table
+,and start rproc.
+
+When starting rproc with a firmware not have resource table,
+`memcpy(loaded_table, rproc->cached_table, rproc->table_sz)` will
+trigger dump, because rproc->cache_table is set to NULL during the last
+stop operation, but rproc->table_sz is still valid.
+
+This issue is found on i.MX8MP and i.MX9.
+
+Dump as below:
+Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
+Mem abort info:
+  ESR = 0x0000000096000004
+  EC = 0x25: DABT (current EL), IL = 32 bits
+  SET = 0, FnV = 0
+  EA = 0, S1PTW = 0
+  FSC = 0x04: level 0 translation fault
+Data abort info:
+  ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
+  CM = 0, WnR = 0, TnD = 0, TagAccess = 0
+  GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
+user pgtable: 4k pages, 48-bit VAs, pgdp=000000010af63000
+[0000000000000000] pgd=0000000000000000, p4d=0000000000000000
+Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP
+Modules linked in:
+CPU: 2 UID: 0 PID: 1060 Comm: sh Not tainted 6.14.0-rc7-next-20250317-dirty #38
+Hardware name: NXP i.MX8MPlus EVK board (DT)
+pstate: a0000005 (NzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+pc : __pi_memcpy_generic+0x110/0x22c
+lr : rproc_start+0x88/0x1e0
+Call trace:
+ __pi_memcpy_generic+0x110/0x22c (P)
+ rproc_boot+0x198/0x57c
+ state_store+0x40/0x104
+ dev_attr_store+0x18/0x2c
+ sysfs_kf_write+0x7c/0x94
+ kernfs_fop_write_iter+0x120/0x1cc
+ vfs_write+0x240/0x378
+ ksys_write+0x70/0x108
+ __arm64_sys_write+0x1c/0x28
+ invoke_syscall+0x48/0x10c
+ el0_svc_common.constprop.0+0xc0/0xe0
+ do_el0_svc+0x1c/0x28
+ el0_svc+0x30/0xcc
+ el0t_64_sync_handler+0x10c/0x138
+ el0t_64_sync+0x198/0x19c
+
+Clear rproc->table_sz to address the issue.
+
+Fixes: 9dc9507f1880 ("remoteproc: Properly deal with the resource table when detaching")
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Link: https://lore.kernel.org/r/20250319100106.3622619-1-peng.fan@oss.nxp.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/remoteproc_core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
+index c2cf0d2777296..b21eedefff877 100644
+--- a/drivers/remoteproc/remoteproc_core.c
++++ b/drivers/remoteproc/remoteproc_core.c
+@@ -2025,6 +2025,7 @@ int rproc_shutdown(struct rproc *rproc)
+       kfree(rproc->cached_table);
+       rproc->cached_table = NULL;
+       rproc->table_ptr = NULL;
++      rproc->table_sz = 0;
+ out:
+       mutex_unlock(&rproc->lock);
+       return ret;
+-- 
+2.39.5
+
diff --git a/queue-6.14/remoteproc-qcom-pas-add-minidump_id-to-sc7280-wpss.patch b/queue-6.14/remoteproc-qcom-pas-add-minidump_id-to-sc7280-wpss.patch
new file mode 100644 (file)
index 0000000..4274fa5
--- /dev/null
@@ -0,0 +1,35 @@
+From a59243e01971196c157066afd71868e2334badbb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Mar 2025 09:24:31 +0100
+Subject: remoteproc: qcom: pas: add minidump_id to SC7280 WPSS
+
+From: Luca Weiss <luca.weiss@fairphone.com>
+
+[ Upstream commit d2909538bff0189d4d038f4e903c70be5f5c2bfc ]
+
+Add the minidump ID to the wpss resources, based on msm-5.4 devicetree.
+
+Fixes: 300ed425dfa9 ("remoteproc: qcom_q6v5_pas: Add SC7280 ADSP, CDSP & WPSS")
+Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
+Link: https://lore.kernel.org/r/20250314-sc7280-wpss-minidump-v1-1-d869d53fd432@fairphone.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/qcom_q6v5_pas.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
+index 78484ed9b6c85..9f2d9b4be2790 100644
+--- a/drivers/remoteproc/qcom_q6v5_pas.c
++++ b/drivers/remoteproc/qcom_q6v5_pas.c
+@@ -1348,6 +1348,7 @@ static const struct adsp_data sc7280_wpss_resource = {
+       .crash_reason_smem = 626,
+       .firmware_name = "wpss.mdt",
+       .pas_id = 6,
++      .minidump_id = 4,
+       .auto_boot = false,
+       .proxy_pd_names = (char*[]){
+               "cx",
+-- 
+2.39.5
+
diff --git a/queue-6.14/remoteproc-qcom_q6v5_mss-handle-platforms-with-one-p.patch b/queue-6.14/remoteproc-qcom_q6v5_mss-handle-platforms-with-one-p.patch
new file mode 100644 (file)
index 0000000..0025e72
--- /dev/null
@@ -0,0 +1,90 @@
+From 9c7e625d24af257cdefc05f4253e62cfd52e44ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 23:05:18 +0100
+Subject: remoteproc: qcom_q6v5_mss: Handle platforms with one power domain
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Luca Weiss <luca@lucaweiss.eu>
+
+[ Upstream commit 4641840341f37dc8231e0840ec1514b4061b4322 ]
+
+For example MSM8974 has mx voltage rail exposed as regulator and only cx
+voltage rail is exposed as power domain. This power domain (cx) is
+attached internally in power domain and cannot be attached in this driver.
+
+Fixes: 8750cf392394 ("remoteproc: qcom_q6v5_mss: Allow replacing regulators with power domains")
+Co-developed-by: Matti Lehtimäki <matti.lehtimaki@gmail.com>
+Signed-off-by: Matti Lehtimäki <matti.lehtimaki@gmail.com>
+Reviewed-by: Stephan Gerhold <stephan.gerhold@linaro.org>
+Signed-off-by: Luca Weiss <luca@lucaweiss.eu>
+Link: https://lore.kernel.org/r/20250217-msm8226-modem-v5-4-2bc74b80e0ae@lucaweiss.eu
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/qcom_q6v5_mss.c | 21 +++++++++++++++++----
+ 1 file changed, 17 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c
+index e78bd986dc3f2..2c80d7fe39f8e 100644
+--- a/drivers/remoteproc/qcom_q6v5_mss.c
++++ b/drivers/remoteproc/qcom_q6v5_mss.c
+@@ -1831,6 +1831,13 @@ static int q6v5_pds_attach(struct device *dev, struct device **devs,
+       while (pd_names[num_pds])
+               num_pds++;
++      /* Handle single power domain */
++      if (num_pds == 1 && dev->pm_domain) {
++              devs[0] = dev;
++              pm_runtime_enable(dev);
++              return 1;
++      }
++
+       for (i = 0; i < num_pds; i++) {
+               devs[i] = dev_pm_domain_attach_by_name(dev, pd_names[i]);
+               if (IS_ERR_OR_NULL(devs[i])) {
+@@ -1851,8 +1858,15 @@ static int q6v5_pds_attach(struct device *dev, struct device **devs,
+ static void q6v5_pds_detach(struct q6v5 *qproc, struct device **pds,
+                           size_t pd_count)
+ {
++      struct device *dev = qproc->dev;
+       int i;
++      /* Handle single power domain */
++      if (pd_count == 1 && dev->pm_domain) {
++              pm_runtime_disable(dev);
++              return;
++      }
++
+       for (i = 0; i < pd_count; i++)
+               dev_pm_domain_detach(pds[i], false);
+ }
+@@ -2449,13 +2463,13 @@ static const struct rproc_hexagon_res msm8974_mss = {
+                       .supply = "pll",
+                       .uA = 100000,
+               },
+-              {}
+-      },
+-      .fallback_proxy_supply = (struct qcom_mss_reg_res[]) {
+               {
+                       .supply = "mx",
+                       .uV = 1050000,
+               },
++              {}
++      },
++      .fallback_proxy_supply = (struct qcom_mss_reg_res[]) {
+               {
+                       .supply = "cx",
+                       .uA = 100000,
+@@ -2481,7 +2495,6 @@ static const struct rproc_hexagon_res msm8974_mss = {
+               NULL
+       },
+       .proxy_pd_names = (char*[]){
+-              "mx",
+               "cx",
+               NULL
+       },
+-- 
+2.39.5
+
diff --git a/queue-6.14/remoteproc-qcom_q6v5_pas-make-single-pd-handling-mor.patch b/queue-6.14/remoteproc-qcom_q6v5_pas-make-single-pd-handling-mor.patch
new file mode 100644 (file)
index 0000000..d8b3b50
--- /dev/null
@@ -0,0 +1,63 @@
+From 176372e04d484164528fbf61690719e62589158f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Jan 2025 22:54:00 +0100
+Subject: remoteproc: qcom_q6v5_pas: Make single-PD handling more robust
+
+From: Luca Weiss <luca@lucaweiss.eu>
+
+[ Upstream commit e917b73234b02aa4966325e7380d2559bf127ba9 ]
+
+Only go into the if condition for single-PD handling when there's
+actually just one power domain specified there. Otherwise it'll be an
+issue in the dts and we should fail in the regular code path.
+
+This also mirrors the latest changes in the qcom_q6v5_mss driver.
+
+Suggested-by: Stephan Gerhold <stephan.gerhold@linaro.org>
+Fixes: 17ee2fb4e856 ("remoteproc: qcom: pas: Vote for active/proxy power domains")
+Signed-off-by: Luca Weiss <luca@lucaweiss.eu>
+Reviewed-by: Stephan Gerhold <stephan.gerhold@linaro.org>
+Link: https://lore.kernel.org/r/20250128-pas-singlepd-v1-2-85d9ae4b0093@lucaweiss.eu
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/qcom_q6v5_pas.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
+index 97c4bdd9222a8..78484ed9b6c85 100644
+--- a/drivers/remoteproc/qcom_q6v5_pas.c
++++ b/drivers/remoteproc/qcom_q6v5_pas.c
+@@ -501,16 +501,16 @@ static int adsp_pds_attach(struct device *dev, struct device **devs,
+       if (!pd_names)
+               return 0;
++      while (pd_names[num_pds])
++              num_pds++;
++
+       /* Handle single power domain */
+-      if (dev->pm_domain) {
++      if (num_pds == 1 && dev->pm_domain) {
+               devs[0] = dev;
+               pm_runtime_enable(dev);
+               return 1;
+       }
+-      while (pd_names[num_pds])
+-              num_pds++;
+-
+       for (i = 0; i < num_pds; i++) {
+               devs[i] = dev_pm_domain_attach_by_name(dev, pd_names[i]);
+               if (IS_ERR_OR_NULL(devs[i])) {
+@@ -535,7 +535,7 @@ static void adsp_pds_detach(struct qcom_adsp *adsp, struct device **pds,
+       int i;
+       /* Handle single power domain */
+-      if (dev->pm_domain && pd_count) {
++      if (pd_count == 1 && dev->pm_domain) {
+               pm_runtime_disable(dev);
+               return;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/remoteproc-qcom_q6v5_pas-use-resource-with-cx-pd-for.patch b/queue-6.14/remoteproc-qcom_q6v5_pas-use-resource-with-cx-pd-for.patch
new file mode 100644 (file)
index 0000000..36adffb
--- /dev/null
@@ -0,0 +1,39 @@
+From 3d65b5946c2f2b816b51bcae2ff2bdf40812c2ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Jan 2025 22:53:59 +0100
+Subject: remoteproc: qcom_q6v5_pas: Use resource with CX PD for MSM8226
+
+From: Luca Weiss <luca@lucaweiss.eu>
+
+[ Upstream commit ba785ff4162a65f18ed501019637a998b752b5ad ]
+
+MSM8226 requires the CX power domain, so use the msm8996_adsp_resource
+which has cx under proxy_pd_names and is otherwise equivalent.
+
+Suggested-by: Stephan Gerhold <stephan.gerhold@linaro.org>
+Fixes: fb4f07cc9399 ("remoteproc: qcom: pas: Add MSM8226 ADSP support")
+Signed-off-by: Luca Weiss <luca@lucaweiss.eu>
+Reviewed-by: Stephan Gerhold <stephan.gerhold@linaro.org>
+Link: https://lore.kernel.org/r/20250128-pas-singlepd-v1-1-85d9ae4b0093@lucaweiss.eu
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/qcom_q6v5_pas.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
+index 9f2d9b4be2790..60923ed129049 100644
+--- a/drivers/remoteproc/qcom_q6v5_pas.c
++++ b/drivers/remoteproc/qcom_q6v5_pas.c
+@@ -1411,7 +1411,7 @@ static const struct adsp_data sm8650_mpss_resource = {
+ };
+ static const struct of_device_id adsp_of_match[] = {
+-      { .compatible = "qcom,msm8226-adsp-pil", .data = &adsp_resource_init},
++      { .compatible = "qcom,msm8226-adsp-pil", .data = &msm8996_adsp_resource},
+       { .compatible = "qcom,msm8953-adsp-pil", .data = &msm8996_adsp_resource},
+       { .compatible = "qcom,msm8974-adsp-pil", .data = &adsp_resource_init},
+       { .compatible = "qcom,msm8996-adsp-pil", .data = &msm8996_adsp_resource},
+-- 
+2.39.5
+
diff --git a/queue-6.14/renesas-reject-ptp_strict_flags-as-unsupported.patch b/queue-6.14/renesas-reject-ptp_strict_flags-as-unsupported.patch
new file mode 100644 (file)
index 0000000..775c2e6
--- /dev/null
@@ -0,0 +1,61 @@
+From 85d54d82083097138a75f3a9a02ce48603107b4f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Mar 2025 15:15:51 -0700
+Subject: renesas: reject PTP_STRICT_FLAGS as unsupported
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jacob Keller <jacob.e.keller@intel.com>
+
+[ Upstream commit 51d58c0c7921d3c93c44099b90dc46720d095bde ]
+
+The ravb_ptp_extts() function checks the flags coming from the
+PTP_EXTTS_REQUEST ioctl, to ensure that future flags are not accepted on
+accident.
+
+This was updated to 'honor' the PTP_STRICT_FLAGS in commit 6138e687c7b6
+("ptp: Introduce strict checking of external time stamp options.").
+However, the driver does not *actually* validate the flags.
+
+I originally fixed this driver to reject future flags in commit
+592025a03b34 ("renesas: reject unsupported external timestamp flags"). It
+is still unclear whether this hardware timestamps the rising, falling, or
+both edges of the input signal.
+
+Accepting requests with PTP_STRICT_FLAGS is a bug, as this could lead to
+users mistakenly assuming a request with PTP_RISING_EDGE actually
+timestamps the rising edge only.
+
+Reject requests with PTP_STRICT_FLAGS (and hence all PTP_EXTTS_REQUEST2
+requests) until someone with access to the datasheet or hardware knowledge
+can confirm the timestamping behavior and update this driver.
+
+Fixes: 6138e687c7b6 ("ptp: Introduce strict checking of external time stamp options.")
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250312-jk-net-fixes-supported-extts-flags-v2-2-ea930ba82459@intel.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/renesas/ravb_ptp.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/renesas/ravb_ptp.c b/drivers/net/ethernet/renesas/ravb_ptp.c
+index 6e4ef7af27bf3..b4365906669f3 100644
+--- a/drivers/net/ethernet/renesas/ravb_ptp.c
++++ b/drivers/net/ethernet/renesas/ravb_ptp.c
+@@ -179,8 +179,7 @@ static int ravb_ptp_extts(struct ptp_clock_info *ptp,
+       /* Reject requests with unsupported flags */
+       if (req->flags & ~(PTP_ENABLE_FEATURE |
+                          PTP_RISING_EDGE |
+-                         PTP_FALLING_EDGE |
+-                         PTP_STRICT_FLAGS))
++                         PTP_FALLING_EDGE))
+               return -EOPNOTSUPP;
+       if (req->index)
+-- 
+2.39.5
+
diff --git a/queue-6.14/ring-buffer-fix-bytes_dropped-calculation-issue.patch b/queue-6.14/ring-buffer-fix-bytes_dropped-calculation-issue.patch
new file mode 100644 (file)
index 0000000..69669fc
--- /dev/null
@@ -0,0 +1,41 @@
+From d355f6c8855ef275c89ef2c4e97923a04e2c3b93 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 Feb 2025 15:01:06 +0800
+Subject: ring-buffer: Fix bytes_dropped calculation issue
+
+From: Feng Yang <yangfeng@kylinos.cn>
+
+[ Upstream commit c73f0b69648501978e8b3e8fa7eef7f4197d0481 ]
+
+The calculation of bytes-dropped and bytes_dropped_nested is reversed.
+Although it does not affect the final calculation of total_dropped,
+it should still be modified.
+
+Link: https://lore.kernel.org/20250223070106.6781-1-yangfeng59949@163.com
+Fixes: 6c43e554a2a5 ("ring-buffer: Add ring buffer startup selftest")
+Signed-off-by: Feng Yang <yangfeng@kylinos.cn>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/ring_buffer.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
+index bb6089c2951e5..510409f979923 100644
+--- a/kernel/trace/ring_buffer.c
++++ b/kernel/trace/ring_buffer.c
+@@ -7411,9 +7411,9 @@ static __init int rb_write_something(struct rb_test_data *data, bool nested)
+               /* Ignore dropped events before test starts. */
+               if (started) {
+                       if (nested)
+-                              data->bytes_dropped += len;
+-                      else
+                               data->bytes_dropped_nested += len;
++                      else
++                              data->bytes_dropped += len;
+               }
+               return len;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/risc-v-errata-use-medany-for-relocatable-builds.patch b/queue-6.14/risc-v-errata-use-medany-for-relocatable-builds.patch
new file mode 100644 (file)
index 0000000..666d4ed
--- /dev/null
@@ -0,0 +1,42 @@
+From c55c0669a3446ef499b3bb5e0a7531c98e23df59 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Mar 2025 15:45:07 -0700
+Subject: RISC-V: errata: Use medany for relocatable builds
+
+From: Palmer Dabbelt <palmer@rivosinc.com>
+
+[ Upstream commit bb58e1579f431d42469b6aed0f03eff383ba6db5 ]
+
+We're trying to mix non-PIC/PIE objects into the otherwise-PIE
+relocatable kernels, to avoid GOT/PLT references during early boot
+alternative resolution (which happens before the GOT/PLT are set up).
+
+riscv64-unknown-linux-gnu-ld: arch/riscv/errata/sifive/errata.o: relocation R_RISCV_HI20 against `tlb_flush_all_threshold' can not be used when making a shared object; recompile with -fPIC
+riscv64-unknown-linux-gnu-ld: arch/riscv/errata/thead/errata.o: relocation R_RISCV_HI20 against `riscv_cbom_block_size' can not be used when making a shared object; recompile with -fPIC
+
+Fixes: 8dc2a7e8027f ("riscv: Fix relocatable kernels with early alternatives using -fno-pie")
+Link: https://lore.kernel.org/r/20250326224506.27165-2-palmer@rivosinc.com
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/errata/Makefile | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/arch/riscv/errata/Makefile b/arch/riscv/errata/Makefile
+index f0da9d7b39c37..bc6c77ba837d2 100644
+--- a/arch/riscv/errata/Makefile
++++ b/arch/riscv/errata/Makefile
+@@ -1,5 +1,9 @@
+ ifdef CONFIG_RELOCATABLE
+-KBUILD_CFLAGS += -fno-pie
++# We can't use PIC/PIE when handling early-boot errata parsing, as the kernel
++# doesn't have a GOT setup at that point.  So instead just use medany: it's
++# usually position-independent, so it should be good enough for the errata
++# handling.
++KBUILD_CFLAGS += -fno-pie -mcmodel=medany
+ endif
+ ifdef CONFIG_RISCV_ALTERNATIVE_EARLY
+-- 
+2.39.5
+
diff --git a/queue-6.14/risc-v-kvm-disable-the-kernel-perf-counter-during-co.patch b/queue-6.14/risc-v-kvm-disable-the-kernel-perf-counter-during-co.patch
new file mode 100644 (file)
index 0000000..9e7fdc4
--- /dev/null
@@ -0,0 +1,42 @@
+From 2de7c470dea137d40ad48bed7b214deef9bf1395 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Mar 2025 14:53:06 -0800
+Subject: RISC-V: KVM: Disable the kernel perf counter during configure
+
+From: Atish Patra <atishp@rivosinc.com>
+
+[ Upstream commit bbb622488749478955485765ddff9d56be4a7e4b ]
+
+The perf event should be marked disabled during the creation as
+it is not ready to be scheduled until there is SBI PMU start call
+or config matching is called with auto start. Otherwise, event add/start
+gets called during perf_event_create_kernel_counter function.
+It will be enabled and scheduled to run via perf_event_enable during
+either the above mentioned scenario.
+
+Fixes: 0cb74b65d2e5 ("RISC-V: KVM: Implement perf support without sampling")
+
+Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
+Signed-off-by: Atish Patra <atishp@rivosinc.com>
+Link: https://lore.kernel.org/r/20250303-kvm_pmu_improve-v2-1-41d177e45929@rivosinc.com
+Signed-off-by: Anup Patel <anup@brainfault.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kvm/vcpu_pmu.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/riscv/kvm/vcpu_pmu.c b/arch/riscv/kvm/vcpu_pmu.c
+index 2707a51b082ca..78ac3216a54dd 100644
+--- a/arch/riscv/kvm/vcpu_pmu.c
++++ b/arch/riscv/kvm/vcpu_pmu.c
+@@ -666,6 +666,7 @@ int kvm_riscv_vcpu_pmu_ctr_cfg_match(struct kvm_vcpu *vcpu, unsigned long ctr_ba
+               .type = etype,
+               .size = sizeof(struct perf_event_attr),
+               .pinned = true,
++              .disabled = true,
+               /*
+                * It should never reach here if the platform doesn't support the sscofpmf
+                * extension as mode filtering won't work without it.
+-- 
+2.39.5
+
diff --git a/queue-6.14/risc-v-kvm-teardown-riscv-specific-bits-after-kvm_ex.patch b/queue-6.14/risc-v-kvm-teardown-riscv-specific-bits-after-kvm_ex.patch
new file mode 100644 (file)
index 0000000..ef57e73
--- /dev/null
@@ -0,0 +1,75 @@
+From e6b7e13d0967d4366aebc279f843d02507004a4c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Mar 2025 00:41:44 -0700
+Subject: RISC-V: KVM: Teardown riscv specific bits after kvm_exit
+
+From: Atish Patra <atishp@rivosinc.com>
+
+[ Upstream commit 2d117e67f318303f6ab699a5511d1fac3f170545 ]
+
+During a module removal, kvm_exit invokes arch specific disable
+call which disables AIA. However, we invoke aia_exit before kvm_exit
+resulting in the following warning. KVM kernel module can't be inserted
+afterwards due to inconsistent state of IRQ.
+
+[25469.031389] percpu IRQ 31 still enabled on CPU0!
+[25469.031732] WARNING: CPU: 3 PID: 943 at kernel/irq/manage.c:2476 __free_percpu_irq+0xa2/0x150
+[25469.031804] Modules linked in: kvm(-)
+[25469.031848] CPU: 3 UID: 0 PID: 943 Comm: rmmod Not tainted 6.14.0-rc5-06947-g91c763118f47-dirty #2
+[25469.031905] Hardware name: riscv-virtio,qemu (DT)
+[25469.031928] epc : __free_percpu_irq+0xa2/0x150
+[25469.031976]  ra : __free_percpu_irq+0xa2/0x150
+[25469.032197] epc : ffffffff8007db1e ra : ffffffff8007db1e sp : ff2000000088bd50
+[25469.032241]  gp : ffffffff8131cef8 tp : ff60000080b96400 t0 : ff2000000088baf8
+[25469.032285]  t1 : fffffffffffffffc t2 : 5249207570637265 s0 : ff2000000088bd90
+[25469.032329]  s1 : ff60000098b21080 a0 : 037d527a15eb4f00 a1 : 037d527a15eb4f00
+[25469.032372]  a2 : 0000000000000023 a3 : 0000000000000001 a4 : ffffffff8122dbf8
+[25469.032410]  a5 : 0000000000000fff a6 : 0000000000000000 a7 : ffffffff8122dc10
+[25469.032448]  s2 : ff60000080c22eb0 s3 : 0000000200000022 s4 : 000000000000001f
+[25469.032488]  s5 : ff60000080c22e00 s6 : ffffffff80c351c0 s7 : 0000000000000000
+[25469.032582]  s8 : 0000000000000003 s9 : 000055556b7fb490 s10: 00007ffff0e12fa0
+[25469.032621]  s11: 00007ffff0e13e9a t3 : ffffffff81354ac7 t4 : ffffffff81354ac7
+[25469.032664]  t5 : ffffffff81354ac8 t6 : ffffffff81354ac7
+[25469.032698] status: 0000000200000100 badaddr: ffffffff8007db1e cause: 0000000000000003
+[25469.032738] [<ffffffff8007db1e>] __free_percpu_irq+0xa2/0x150
+[25469.032797] [<ffffffff8007dbfc>] free_percpu_irq+0x30/0x5e
+[25469.032856] [<ffffffff013a57dc>] kvm_riscv_aia_exit+0x40/0x42 [kvm]
+[25469.033947] [<ffffffff013b4e82>] cleanup_module+0x10/0x32 [kvm]
+[25469.035300] [<ffffffff8009b150>] __riscv_sys_delete_module+0x18e/0x1fc
+[25469.035374] [<ffffffff8000c1ca>] syscall_handler+0x3a/0x46
+[25469.035456] [<ffffffff809ec9a4>] do_trap_ecall_u+0x72/0x134
+[25469.035536] [<ffffffff809f5e18>] handle_exception+0x148/0x156
+
+Invoke aia_exit and other arch specific cleanup functions after kvm_exit
+so that disable gets a chance to be called first before exit.
+
+Fixes: 54e43320c2ba ("RISC-V: KVM: Initial skeletal support for AIA")
+Fixes: eded6754f398 ("riscv: KVM: add basic support for host vs guest profiling")
+Signed-off-by: Atish Patra <atishp@rivosinc.com>
+Reviewed-by: Anup Patel <anup@brainfault.org>
+Reviewed-by: Sean Christopherson <seanjc@google.com>
+Link: https://lore.kernel.org/r/20250317-kvm_exit_fix-v1-1-aa5240c5dbd2@rivosinc.com
+Signed-off-by: Anup Patel <anup@brainfault.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kvm/main.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/riscv/kvm/main.c b/arch/riscv/kvm/main.c
+index 1fa8be5ee5097..4b24705dc63a9 100644
+--- a/arch/riscv/kvm/main.c
++++ b/arch/riscv/kvm/main.c
+@@ -172,8 +172,8 @@ module_init(riscv_kvm_init);
+ static void __exit riscv_kvm_exit(void)
+ {
+-      kvm_riscv_teardown();
+-
+       kvm_exit();
++
++      kvm_riscv_teardown();
+ }
+ module_exit(riscv_kvm_exit);
+-- 
+2.39.5
+
diff --git a/queue-6.14/riscv-annotate-unaligned-access-init-functions.patch b/queue-6.14/riscv-annotate-unaligned-access-init-functions.patch
new file mode 100644 (file)
index 0000000..0601dc5
--- /dev/null
@@ -0,0 +1,154 @@
+From 79c55833317d09267353df056a2678fb3d6a47c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Mar 2025 13:00:16 +0100
+Subject: riscv: Annotate unaligned access init functions
+
+From: Andrew Jones <ajones@ventanamicro.com>
+
+[ Upstream commit a00e022be5315c5a1f47521a1cc6d3b71c8e9c44 ]
+
+Several functions used in unaligned access probing are only run at
+init time. Annotate them appropriately.
+
+Fixes: f413aae96cda ("riscv: Set unaligned access speed at compile time")
+Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
+Link: https://lore.kernel.org/r/20250304120014.143628-11-ajones@ventanamicro.com
+Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/include/asm/cpufeature.h        |  4 ++--
+ arch/riscv/kernel/traps_misaligned.c       |  8 ++++----
+ arch/riscv/kernel/unaligned_access_speed.c | 14 +++++++-------
+ 3 files changed, 13 insertions(+), 13 deletions(-)
+
+diff --git a/arch/riscv/include/asm/cpufeature.h b/arch/riscv/include/asm/cpufeature.h
+index 569140d6e6399..19defdc2002d8 100644
+--- a/arch/riscv/include/asm/cpufeature.h
++++ b/arch/riscv/include/asm/cpufeature.h
+@@ -63,7 +63,7 @@ void __init riscv_user_isa_enable(void);
+ #define __RISCV_ISA_EXT_SUPERSET_VALIDATE(_name, _id, _sub_exts, _validate) \
+       _RISCV_ISA_EXT_DATA(_name, _id, _sub_exts, ARRAY_SIZE(_sub_exts), _validate)
+-bool check_unaligned_access_emulated_all_cpus(void);
++bool __init check_unaligned_access_emulated_all_cpus(void);
+ #if defined(CONFIG_RISCV_SCALAR_MISALIGNED)
+ void check_unaligned_access_emulated(struct work_struct *work __always_unused);
+ void unaligned_emulation_finish(void);
+@@ -76,7 +76,7 @@ static inline bool unaligned_ctl_available(void)
+ }
+ #endif
+-bool check_vector_unaligned_access_emulated_all_cpus(void);
++bool __init check_vector_unaligned_access_emulated_all_cpus(void);
+ #if defined(CONFIG_RISCV_VECTOR_MISALIGNED)
+ void check_vector_unaligned_access_emulated(struct work_struct *work __always_unused);
+ DECLARE_PER_CPU(long, vector_misaligned_access);
+diff --git a/arch/riscv/kernel/traps_misaligned.c b/arch/riscv/kernel/traps_misaligned.c
+index 7cc108aed74e8..aacbd9d7196e7 100644
+--- a/arch/riscv/kernel/traps_misaligned.c
++++ b/arch/riscv/kernel/traps_misaligned.c
+@@ -605,7 +605,7 @@ void check_vector_unaligned_access_emulated(struct work_struct *work __always_un
+       kernel_vector_end();
+ }
+-bool check_vector_unaligned_access_emulated_all_cpus(void)
++bool __init check_vector_unaligned_access_emulated_all_cpus(void)
+ {
+       int cpu;
+@@ -625,7 +625,7 @@ bool check_vector_unaligned_access_emulated_all_cpus(void)
+       return true;
+ }
+ #else
+-bool check_vector_unaligned_access_emulated_all_cpus(void)
++bool __init check_vector_unaligned_access_emulated_all_cpus(void)
+ {
+       return false;
+ }
+@@ -659,7 +659,7 @@ void check_unaligned_access_emulated(struct work_struct *work __always_unused)
+       }
+ }
+-bool check_unaligned_access_emulated_all_cpus(void)
++bool __init check_unaligned_access_emulated_all_cpus(void)
+ {
+       int cpu;
+@@ -684,7 +684,7 @@ bool unaligned_ctl_available(void)
+       return unaligned_ctl;
+ }
+ #else
+-bool check_unaligned_access_emulated_all_cpus(void)
++bool __init check_unaligned_access_emulated_all_cpus(void)
+ {
+       return false;
+ }
+diff --git a/arch/riscv/kernel/unaligned_access_speed.c b/arch/riscv/kernel/unaligned_access_speed.c
+index 074ac4abd023e..85c868a8cee63 100644
+--- a/arch/riscv/kernel/unaligned_access_speed.c
++++ b/arch/riscv/kernel/unaligned_access_speed.c
+@@ -121,7 +121,7 @@ static int check_unaligned_access(void *param)
+       return 0;
+ }
+-static void check_unaligned_access_nonboot_cpu(void *param)
++static void __init check_unaligned_access_nonboot_cpu(void *param)
+ {
+       unsigned int cpu = smp_processor_id();
+       struct page **pages = param;
+@@ -175,7 +175,7 @@ static void set_unaligned_access_static_branches(void)
+       modify_unaligned_access_branches(&fast_and_online, num_online_cpus());
+ }
+-static int lock_and_set_unaligned_access_static_branch(void)
++static int __init lock_and_set_unaligned_access_static_branch(void)
+ {
+       cpus_read_lock();
+       set_unaligned_access_static_branches();
+@@ -218,7 +218,7 @@ static int riscv_offline_cpu(unsigned int cpu)
+ }
+ /* Measure unaligned access speed on all CPUs present at boot in parallel. */
+-static int check_unaligned_access_speed_all_cpus(void)
++static int __init check_unaligned_access_speed_all_cpus(void)
+ {
+       unsigned int cpu;
+       unsigned int cpu_count = num_possible_cpus();
+@@ -264,7 +264,7 @@ static int check_unaligned_access_speed_all_cpus(void)
+       return 0;
+ }
+ #else /* CONFIG_RISCV_PROBE_UNALIGNED_ACCESS */
+-static int check_unaligned_access_speed_all_cpus(void)
++static int __init check_unaligned_access_speed_all_cpus(void)
+ {
+       return 0;
+ }
+@@ -382,7 +382,7 @@ static int riscv_online_cpu_vec(unsigned int cpu)
+ }
+ /* Measure unaligned access speed on all CPUs present at boot in parallel. */
+-static int vec_check_unaligned_access_speed_all_cpus(void *unused __always_unused)
++static int __init vec_check_unaligned_access_speed_all_cpus(void *unused __always_unused)
+ {
+       schedule_on_each_cpu(check_vector_unaligned_access);
+@@ -396,13 +396,13 @@ static int vec_check_unaligned_access_speed_all_cpus(void *unused __always_unuse
+       return 0;
+ }
+ #else /* CONFIG_RISCV_PROBE_VECTOR_UNALIGNED_ACCESS */
+-static int vec_check_unaligned_access_speed_all_cpus(void *unused __always_unused)
++static int __init vec_check_unaligned_access_speed_all_cpus(void *unused __always_unused)
+ {
+       return 0;
+ }
+ #endif
+-static int check_unaligned_access_all_cpus(void)
++static int __init check_unaligned_access_all_cpus(void)
+ {
+       bool all_cpus_emulated, all_cpus_vec_unsupported;
+-- 
+2.39.5
+
diff --git a/queue-6.14/riscv-change-check_unaligned_access_speed_all_cpus-t.patch b/queue-6.14/riscv-change-check_unaligned_access_speed_all_cpus-t.patch
new file mode 100644 (file)
index 0000000..ea95f4a
--- /dev/null
@@ -0,0 +1,90 @@
+From 6b5398627c7e07dd84d8d562643cf7678197eb82 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Mar 2025 13:00:19 +0100
+Subject: riscv: Change check_unaligned_access_speed_all_cpus to void
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Andrew Jones <ajones@ventanamicro.com>
+
+[ Upstream commit 813d39baee3229d31420af61460b97f4fafdd352 ]
+
+The return value of check_unaligned_access_speed_all_cpus() is always
+zero, so make the function void so we don't need to concern ourselves
+with it. The change also allows us to tidy up
+check_unaligned_access_all_cpus() a bit.
+
+Reviewed-by: Clément Léger <cleger@rivosinc.com>
+Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
+Link: https://lore.kernel.org/r/20250304120014.143628-14-ajones@ventanamicro.com
+Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Stable-dep-of: 05ee21f0fcb8 ("riscv: Fix set up of cpu hotplug callbacks")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/unaligned_access_speed.c | 15 +++++----------
+ 1 file changed, 5 insertions(+), 10 deletions(-)
+
+diff --git a/arch/riscv/kernel/unaligned_access_speed.c b/arch/riscv/kernel/unaligned_access_speed.c
+index 78ab4cb2ab050..bca798153e37d 100644
+--- a/arch/riscv/kernel/unaligned_access_speed.c
++++ b/arch/riscv/kernel/unaligned_access_speed.c
+@@ -218,7 +218,7 @@ static int riscv_offline_cpu(unsigned int cpu)
+ }
+ /* Measure unaligned access speed on all CPUs present at boot in parallel. */
+-static int __init check_unaligned_access_speed_all_cpus(void)
++static void __init check_unaligned_access_speed_all_cpus(void)
+ {
+       unsigned int cpu;
+       unsigned int cpu_count = num_possible_cpus();
+@@ -226,7 +226,7 @@ static int __init check_unaligned_access_speed_all_cpus(void)
+       if (!bufs) {
+               pr_warn("Allocation failure, not measuring misaligned performance\n");
+-              return 0;
++              return;
+       }
+       /*
+@@ -261,12 +261,10 @@ static int __init check_unaligned_access_speed_all_cpus(void)
+       }
+       kfree(bufs);
+-      return 0;
+ }
+ #else /* CONFIG_RISCV_PROBE_UNALIGNED_ACCESS */
+-static int __init check_unaligned_access_speed_all_cpus(void)
++static void __init check_unaligned_access_speed_all_cpus(void)
+ {
+-      return 0;
+ }
+ #endif
+@@ -406,10 +404,10 @@ static int __init vec_check_unaligned_access_speed_all_cpus(void *unused __alway
+ static int __init check_unaligned_access_all_cpus(void)
+ {
+-      bool all_cpus_emulated;
+       int cpu;
+-      all_cpus_emulated = check_unaligned_access_emulated_all_cpus();
++      if (!check_unaligned_access_emulated_all_cpus())
++              check_unaligned_access_speed_all_cpus();
+       if (!has_vector()) {
+               for_each_online_cpu(cpu)
+@@ -420,9 +418,6 @@ static int __init check_unaligned_access_all_cpus(void)
+                           NULL, "vec_check_unaligned_access_speed_all_cpus");
+       }
+-      if (!all_cpus_emulated)
+-              return check_unaligned_access_speed_all_cpus();
+-
+       return 0;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/riscv-fgraph-fix-stack-layout-to-match-__arch_ftrace.patch b/queue-6.14/riscv-fgraph-fix-stack-layout-to-match-__arch_ftrace.patch
new file mode 100644 (file)
index 0000000..e5111c3
--- /dev/null
@@ -0,0 +1,127 @@
+From 87d4b04edf75dfcb0e1d35eb9a4145c370c91814 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Mar 2025 03:12:14 +0000
+Subject: riscv: fgraph: Fix stack layout to match __arch_ftrace_regs argument
+ of ftrace_return_to_handler
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pu Lehui <pulehui@huawei.com>
+
+[ Upstream commit 67a5ba8f742f247bc83e46dd2313c142b1383276 ]
+
+Naresh Kamboju reported a "Bad frame pointer" kernel warning while
+running LTP trace ftrace_stress_test.sh in riscv. We can reproduce the
+same issue with the following command:
+
+```
+$ cd /sys/kernel/debug/tracing
+$ echo 'f:myprobe do_nanosleep%return args1=$retval' > dynamic_events
+$ echo 1 > events/fprobes/enable
+$ echo 1 > tracing_on
+$ sleep 1
+```
+
+And we can get the following kernel warning:
+
+[  127.692888] ------------[ cut here ]------------
+[  127.693755] Bad frame pointer: expected ff2000000065be50, received ba34c141e9594000
+[  127.693755]   from func do_nanosleep return to ffffffff800ccb16
+[  127.698699] WARNING: CPU: 1 PID: 129 at kernel/trace/fgraph.c:755 ftrace_return_to_handler+0x1b2/0x1be
+[  127.699894] Modules linked in:
+[  127.700908] CPU: 1 UID: 0 PID: 129 Comm: sleep Not tainted 6.14.0-rc3-g0ab191c74642 #32
+[  127.701453] Hardware name: riscv-virtio,qemu (DT)
+[  127.701859] epc : ftrace_return_to_handler+0x1b2/0x1be
+[  127.702032]  ra : ftrace_return_to_handler+0x1b2/0x1be
+[  127.702151] epc : ffffffff8013b5e0 ra : ffffffff8013b5e0 sp : ff2000000065bd10
+[  127.702221]  gp : ffffffff819c12f8 tp : ff60000080853100 t0 : 6e00000000000000
+[  127.702284]  t1 : 0000000000000020 t2 : 6e7566206d6f7266 s0 : ff2000000065bd80
+[  127.702346]  s1 : ff60000081262000 a0 : 000000000000007b a1 : ffffffff81894f20
+[  127.702408]  a2 : 0000000000000010 a3 : fffffffffffffffe a4 : 0000000000000000
+[  127.702470]  a5 : 0000000000000000 a6 : 0000000000000008 a7 : 0000000000000038
+[  127.702530]  s2 : ba34c141e9594000 s3 : 0000000000000000 s4 : ff2000000065bdd0
+[  127.702591]  s5 : 00007fff8adcf400 s6 : 000055556dc1d8c0 s7 : 0000000000000068
+[  127.702651]  s8 : 00007fff8adf5d10 s9 : 000000000000006d s10: 0000000000000001
+[  127.702710]  s11: 00005555737377c8 t3 : ffffffff819d899e t4 : ffffffff819d899e
+[  127.702769]  t5 : ffffffff819d89a0 t6 : ff2000000065bb18
+[  127.702826] status: 0000000200000120 badaddr: 0000000000000000 cause: 0000000000000003
+[  127.703292] [<ffffffff8013b5e0>] ftrace_return_to_handler+0x1b2/0x1be
+[  127.703760] [<ffffffff80017bce>] return_to_handler+0x16/0x26
+[  127.704009] [<ffffffff80017bb8>] return_to_handler+0x0/0x26
+[  127.704057] [<ffffffff800d3352>] common_nsleep+0x42/0x54
+[  127.704117] [<ffffffff800d44a2>] __riscv_sys_clock_nanosleep+0xba/0x10a
+[  127.704176] [<ffffffff80901c56>] do_trap_ecall_u+0x188/0x218
+[  127.704295] [<ffffffff8090cc3e>] handle_exception+0x14a/0x156
+[  127.705436] ---[ end trace 0000000000000000 ]---
+
+The reason is that the stack layout for constructing argument for the
+ftrace_return_to_handler in the return_to_handler does not match the
+__arch_ftrace_regs structure of riscv, leading to unexpected results.
+
+Fixes: a3ed4157b7d8 ("fgraph: Replace fgraph_ret_regs with ftrace_regs")
+Reported-by: Linux Kernel Functional Testing <lkft@linaro.org>
+Closes: https://lore.kernel.org/all/CA+G9fYvp_oAxeDFj88Tk2rfEZ7jtYKAKSwfYS66=57Db9TBdyA@mail.gmail.com
+Signed-off-by: Pu Lehui <pulehui@huawei.com>
+Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Tested-by: Björn Töpel <bjorn@rivosinc.com>
+Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Link: https://lore.kernel.org/r/20250317031214.4138436-2-pulehui@huaweicloud.com
+Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/mcount.S | 24 +++++++++++-------------
+ 1 file changed, 11 insertions(+), 13 deletions(-)
+
+diff --git a/arch/riscv/kernel/mcount.S b/arch/riscv/kernel/mcount.S
+index 068168046e0ef..da4a4000e57ea 100644
+--- a/arch/riscv/kernel/mcount.S
++++ b/arch/riscv/kernel/mcount.S
+@@ -12,8 +12,6 @@
+ #include <asm/asm-offsets.h>
+ #include <asm/ftrace.h>
+-#define ABI_SIZE_ON_STACK     80
+-
+       .text
+       .macro SAVE_ABI_STATE
+@@ -28,12 +26,12 @@
+        * register if a0 was not saved.
+        */
+       .macro SAVE_RET_ABI_STATE
+-      addi    sp, sp, -ABI_SIZE_ON_STACK
+-      REG_S   ra, 1*SZREG(sp)
+-      REG_S   s0, 8*SZREG(sp)
+-      REG_S   a0, 10*SZREG(sp)
+-      REG_S   a1, 11*SZREG(sp)
+-      addi    s0, sp, ABI_SIZE_ON_STACK
++      addi    sp, sp, -FREGS_SIZE_ON_STACK
++      REG_S   ra, FREGS_RA(sp)
++      REG_S   s0, FREGS_S0(sp)
++      REG_S   a0, FREGS_A0(sp)
++      REG_S   a1, FREGS_A1(sp)
++      addi    s0, sp, FREGS_SIZE_ON_STACK
+       .endm
+       .macro RESTORE_ABI_STATE
+@@ -43,11 +41,11 @@
+       .endm
+       .macro RESTORE_RET_ABI_STATE
+-      REG_L   ra, 1*SZREG(sp)
+-      REG_L   s0, 8*SZREG(sp)
+-      REG_L   a0, 10*SZREG(sp)
+-      REG_L   a1, 11*SZREG(sp)
+-      addi    sp, sp, ABI_SIZE_ON_STACK
++      REG_L   ra, FREGS_RA(sp)
++      REG_L   s0, FREGS_S0(sp)
++      REG_L   a0, FREGS_A0(sp)
++      REG_L   a1, FREGS_A1(sp)
++      addi    sp, sp, FREGS_SIZE_ON_STACK
+       .endm
+ SYM_TYPED_FUNC_START(ftrace_stub)
+-- 
+2.39.5
+
diff --git a/queue-6.14/riscv-fgraph-select-have_function_graph_tracer-depen.patch b/queue-6.14/riscv-fgraph-select-have_function_graph_tracer-depen.patch
new file mode 100644 (file)
index 0000000..a79f72a
--- /dev/null
@@ -0,0 +1,47 @@
+From a5bb6f4efdad4106634c4cc4441b7b8ea3eca9c4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Mar 2025 03:12:13 +0000
+Subject: riscv: fgraph: Select HAVE_FUNCTION_GRAPH_TRACER depends on
+ HAVE_DYNAMIC_FTRACE_WITH_ARGS
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pu Lehui <pulehui@huawei.com>
+
+[ Upstream commit e8eb8e1bdae94b9e003f5909519fd311d0936890 ]
+
+Currently, fgraph on riscv relies on the infrastructure of
+DYNAMIC_FTRACE_WITH_ARGS. However, DYNAMIC_FTRACE_WITH_ARGS may be
+turned off on riscv, which will cause the enabled fgraph to be abnormal.
+Therefore, let's select HAVE_FUNCTION_GRAPH_TRACER depends on
+HAVE_DYNAMIC_FTRACE_WITH_ARGS.
+
+Fixes: a3ed4157b7d8 ("fgraph: Replace fgraph_ret_regs with ftrace_regs")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202503160820.dvqMpH0g-lkp@intel.com/
+Signed-off-by: Pu Lehui <pulehui@huawei.com>
+Reviewed-by: Björn Töpel <bjorn@rivosinc.com>
+Link: https://lore.kernel.org/r/20250317031214.4138436-1-pulehui@huaweicloud.com
+Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
+index 7612c52e9b1e3..5d63abc499ce7 100644
+--- a/arch/riscv/Kconfig
++++ b/arch/riscv/Kconfig
+@@ -149,7 +149,7 @@ config RISCV
+       select HAVE_DYNAMIC_FTRACE_WITH_ARGS if HAVE_DYNAMIC_FTRACE
+       select HAVE_FTRACE_GRAPH_FUNC
+       select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL
+-      select HAVE_FUNCTION_GRAPH_TRACER
++      select HAVE_FUNCTION_GRAPH_TRACER if HAVE_DYNAMIC_FTRACE_WITH_ARGS
+       select HAVE_FUNCTION_GRAPH_FREGS
+       select HAVE_FUNCTION_TRACER if !XIP_KERNEL && !PREEMPTION
+       select HAVE_EBPF_JIT if MMU
+-- 
+2.39.5
+
diff --git a/queue-6.14/riscv-fix-check_unaligned_access_all_cpus.patch b/queue-6.14/riscv-fix-check_unaligned_access_all_cpus.patch
new file mode 100644 (file)
index 0000000..d1da0e3
--- /dev/null
@@ -0,0 +1,77 @@
+From 756818f07a8bba02f7d341feb1cf6f1083ad25ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Mar 2025 13:00:18 +0100
+Subject: riscv: Fix check_unaligned_access_all_cpus
+
+From: Andrew Jones <ajones@ventanamicro.com>
+
+[ Upstream commit e6d0adf2eb5bb3244cb21a7a15899aa058bd384f ]
+
+check_vector_unaligned_access_emulated_all_cpus(), like its name
+suggests, will return true when all cpus emulate unaligned vector
+accesses. If the function returned false it may have been because
+vector isn't supported at all (!has_vector()) or because at least
+one cpu doesn't emulate unaligned vector accesses. Since false may
+be returned for two cases, checking for it isn't sufficient when
+attempting to determine if we should proceed with the vector speed
+check. Move the !has_vector() functionality to
+check_unaligned_access_all_cpus() in order for
+check_vector_unaligned_access_emulated_all_cpus() to return false
+for a single case.
+
+Fixes: e7c9d66e313b ("RISC-V: Report vector unaligned access speed hwprobe")
+Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
+Link: https://lore.kernel.org/r/20250304120014.143628-13-ajones@ventanamicro.com
+Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/traps_misaligned.c       |  6 ------
+ arch/riscv/kernel/unaligned_access_speed.c | 11 +++++++----
+ 2 files changed, 7 insertions(+), 10 deletions(-)
+
+diff --git a/arch/riscv/kernel/traps_misaligned.c b/arch/riscv/kernel/traps_misaligned.c
+index aacbd9d7196e7..4354c87c0376f 100644
+--- a/arch/riscv/kernel/traps_misaligned.c
++++ b/arch/riscv/kernel/traps_misaligned.c
+@@ -609,12 +609,6 @@ bool __init check_vector_unaligned_access_emulated_all_cpus(void)
+ {
+       int cpu;
+-      if (!has_vector()) {
+-              for_each_online_cpu(cpu)
+-                      per_cpu(vector_misaligned_access, cpu) = RISCV_HWPROBE_MISALIGNED_VECTOR_UNSUPPORTED;
+-              return false;
+-      }
+-
+       schedule_on_each_cpu(check_vector_unaligned_access_emulated);
+       for_each_online_cpu(cpu)
+diff --git a/arch/riscv/kernel/unaligned_access_speed.c b/arch/riscv/kernel/unaligned_access_speed.c
+index 2e41b42498c76..78ab4cb2ab050 100644
+--- a/arch/riscv/kernel/unaligned_access_speed.c
++++ b/arch/riscv/kernel/unaligned_access_speed.c
+@@ -406,13 +406,16 @@ static int __init vec_check_unaligned_access_speed_all_cpus(void *unused __alway
+ static int __init check_unaligned_access_all_cpus(void)
+ {
+-      bool all_cpus_emulated, all_cpus_vec_unsupported;
++      bool all_cpus_emulated;
++      int cpu;
+       all_cpus_emulated = check_unaligned_access_emulated_all_cpus();
+-      all_cpus_vec_unsupported = check_vector_unaligned_access_emulated_all_cpus();
+-      if (!all_cpus_vec_unsupported &&
+-          IS_ENABLED(CONFIG_RISCV_PROBE_VECTOR_UNALIGNED_ACCESS)) {
++      if (!has_vector()) {
++              for_each_online_cpu(cpu)
++                      per_cpu(vector_misaligned_access, cpu) = RISCV_HWPROBE_MISALIGNED_VECTOR_UNSUPPORTED;
++      } else if (!check_vector_unaligned_access_emulated_all_cpus() &&
++                 IS_ENABLED(CONFIG_RISCV_PROBE_VECTOR_UNALIGNED_ACCESS)) {
+               kthread_run(vec_check_unaligned_access_speed_all_cpus,
+                           NULL, "vec_check_unaligned_access_speed_all_cpus");
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/riscv-fix-hugetlb-retrieval-of-number-of-ptes-in-cas.patch b/queue-6.14/riscv-fix-hugetlb-retrieval-of-number-of-ptes-in-cas.patch
new file mode 100644 (file)
index 0000000..7d8f3df
--- /dev/null
@@ -0,0 +1,162 @@
+From 8905ee3a725f2b538a19cb73f00aa46b59989140 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Mar 2025 08:25:51 +0100
+Subject: riscv: Fix hugetlb retrieval of number of ptes in case of !present
+ pte
+
+From: Alexandre Ghiti <alexghiti@rivosinc.com>
+
+[ Upstream commit 83d78ac677b9fdd8ea763507c6fe02d6bf415f3a ]
+
+Ryan sent a fix [1] for arm64 that applies to riscv too: in some hugetlb
+functions, we must not use the pte value to get the size of a mapping
+because the pte may not be present.
+
+So use the already present size parameter for huge_pte_clear() and the
+newly introduced size parameter for huge_ptep_get_and_clear(). And make
+sure to gather A/D bits only on present ptes.
+
+Fixes: 82a1a1f3bfb6 ("riscv: mm: support Svnapot in hugetlb page")
+Link: https://lore.kernel.org/all/20250217140419.1702389-1-ryan.roberts@arm.com/ [1]
+Link: https://lore.kernel.org/r/20250317072551.572169-1-alexghiti@rivosinc.com
+Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/mm/hugetlbpage.c | 76 ++++++++++++++++++++++---------------
+ 1 file changed, 45 insertions(+), 31 deletions(-)
+
+diff --git a/arch/riscv/mm/hugetlbpage.c b/arch/riscv/mm/hugetlbpage.c
+index b4a78a4b35cff..375dd96bb4a0d 100644
+--- a/arch/riscv/mm/hugetlbpage.c
++++ b/arch/riscv/mm/hugetlbpage.c
+@@ -148,22 +148,25 @@ unsigned long hugetlb_mask_last_page(struct hstate *h)
+ static pte_t get_clear_contig(struct mm_struct *mm,
+                             unsigned long addr,
+                             pte_t *ptep,
+-                            unsigned long pte_num)
++                            unsigned long ncontig)
+ {
+-      pte_t orig_pte = ptep_get(ptep);
+-      unsigned long i;
+-
+-      for (i = 0; i < pte_num; i++, addr += PAGE_SIZE, ptep++) {
+-              pte_t pte = ptep_get_and_clear(mm, addr, ptep);
+-
+-              if (pte_dirty(pte))
+-                      orig_pte = pte_mkdirty(orig_pte);
+-
+-              if (pte_young(pte))
+-                      orig_pte = pte_mkyoung(orig_pte);
++      pte_t pte, tmp_pte;
++      bool present;
++
++      pte = ptep_get_and_clear(mm, addr, ptep);
++      present = pte_present(pte);
++      while (--ncontig) {
++              ptep++;
++              addr += PAGE_SIZE;
++              tmp_pte = ptep_get_and_clear(mm, addr, ptep);
++              if (present) {
++                      if (pte_dirty(tmp_pte))
++                              pte = pte_mkdirty(pte);
++                      if (pte_young(tmp_pte))
++                              pte = pte_mkyoung(pte);
++              }
+       }
+-
+-      return orig_pte;
++      return pte;
+ }
+ static pte_t get_clear_contig_flush(struct mm_struct *mm,
+@@ -212,6 +215,26 @@ static void clear_flush(struct mm_struct *mm,
+       flush_tlb_range(&vma, saddr, addr);
+ }
++static int num_contig_ptes_from_size(unsigned long sz, size_t *pgsize)
++{
++      unsigned long hugepage_shift;
++
++      if (sz >= PGDIR_SIZE)
++              hugepage_shift = PGDIR_SHIFT;
++      else if (sz >= P4D_SIZE)
++              hugepage_shift = P4D_SHIFT;
++      else if (sz >= PUD_SIZE)
++              hugepage_shift = PUD_SHIFT;
++      else if (sz >= PMD_SIZE)
++              hugepage_shift = PMD_SHIFT;
++      else
++              hugepage_shift = PAGE_SHIFT;
++
++      *pgsize = 1 << hugepage_shift;
++
++      return sz >> hugepage_shift;
++}
++
+ /*
+  * When dealing with NAPOT mappings, the privileged specification indicates that
+  * "if an update needs to be made, the OS generally should first mark all of the
+@@ -226,22 +249,10 @@ void set_huge_pte_at(struct mm_struct *mm,
+                    pte_t pte,
+                    unsigned long sz)
+ {
+-      unsigned long hugepage_shift, pgsize;
++      size_t pgsize;
+       int i, pte_num;
+-      if (sz >= PGDIR_SIZE)
+-              hugepage_shift = PGDIR_SHIFT;
+-      else if (sz >= P4D_SIZE)
+-              hugepage_shift = P4D_SHIFT;
+-      else if (sz >= PUD_SIZE)
+-              hugepage_shift = PUD_SHIFT;
+-      else if (sz >= PMD_SIZE)
+-              hugepage_shift = PMD_SHIFT;
+-      else
+-              hugepage_shift = PAGE_SHIFT;
+-
+-      pte_num = sz >> hugepage_shift;
+-      pgsize = 1 << hugepage_shift;
++      pte_num = num_contig_ptes_from_size(sz, &pgsize);
+       if (!pte_present(pte)) {
+               for (i = 0; i < pte_num; i++, ptep++, addr += pgsize)
+@@ -295,13 +306,14 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+                             unsigned long addr,
+                             pte_t *ptep, unsigned long sz)
+ {
++      size_t pgsize;
+       pte_t orig_pte = ptep_get(ptep);
+       int pte_num;
+       if (!pte_napot(orig_pte))
+               return ptep_get_and_clear(mm, addr, ptep);
+-      pte_num = napot_pte_num(napot_cont_order(orig_pte));
++      pte_num = num_contig_ptes_from_size(sz, &pgsize);
+       return get_clear_contig(mm, addr, ptep, pte_num);
+ }
+@@ -351,6 +363,7 @@ void huge_pte_clear(struct mm_struct *mm,
+                   pte_t *ptep,
+                   unsigned long sz)
+ {
++      size_t pgsize;
+       pte_t pte = ptep_get(ptep);
+       int i, pte_num;
+@@ -359,8 +372,9 @@ void huge_pte_clear(struct mm_struct *mm,
+               return;
+       }
+-      pte_num = napot_pte_num(napot_cont_order(pte));
+-      for (i = 0; i < pte_num; i++, addr += PAGE_SIZE, ptep++)
++      pte_num = num_contig_ptes_from_size(sz, &pgsize);
++
++      for (i = 0; i < pte_num; i++, addr += pgsize, ptep++)
+               pte_clear(mm, addr, ptep);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/riscv-fix-missing-__free_pages-in-check_vector_unali.patch b/queue-6.14/riscv-fix-missing-__free_pages-in-check_vector_unali.patch
new file mode 100644 (file)
index 0000000..6034476
--- /dev/null
@@ -0,0 +1,46 @@
+From 4216e172bf91e72e4f4b9e3a40ea9afa978189c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Feb 2025 10:06:13 +0100
+Subject: riscv: Fix missing __free_pages() in check_vector_unaligned_access()
+
+From: Alexandre Ghiti <alexghiti@rivosinc.com>
+
+[ Upstream commit 33981b1c4e499021421686dcfa7b3d23a430d00e ]
+
+The locally allocated pages are never freed up, so add the corresponding
+__free_pages().
+
+Fixes: e7c9d66e313b ("RISC-V: Report vector unaligned access speed hwprobe")
+Link: https://lore.kernel.org/r/20250228090613.345309-1-alexghiti@rivosinc.com
+Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/unaligned_access_speed.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/arch/riscv/kernel/unaligned_access_speed.c b/arch/riscv/kernel/unaligned_access_speed.c
+index 91f189cf16113..074ac4abd023e 100644
+--- a/arch/riscv/kernel/unaligned_access_speed.c
++++ b/arch/riscv/kernel/unaligned_access_speed.c
+@@ -349,7 +349,7 @@ static void check_vector_unaligned_access(struct work_struct *work __always_unus
+               pr_warn("cpu%d: rdtime lacks granularity needed to measure unaligned vector access speed\n",
+                       cpu);
+-              return;
++              goto free;
+       }
+       if (word_cycles < byte_cycles)
+@@ -363,6 +363,9 @@ static void check_vector_unaligned_access(struct work_struct *work __always_unus
+               (speed ==  RISCV_HWPROBE_MISALIGNED_VECTOR_FAST) ? "fast" : "slow");
+       per_cpu(vector_misaligned_access, cpu) = speed;
++
++free:
++      __free_pages(page, MISALIGNED_BUFFER_ORDER);
+ }
+ static int riscv_online_cpu_vec(unsigned int cpu)
+-- 
+2.39.5
+
diff --git a/queue-6.14/riscv-fix-riscv_online_cpu_vec.patch b/queue-6.14/riscv-fix-riscv_online_cpu_vec.patch
new file mode 100644 (file)
index 0000000..aa96c9c
--- /dev/null
@@ -0,0 +1,46 @@
+From 8483214a8dd409e7edd118c2783aab932b5f2556 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Mar 2025 13:00:17 +0100
+Subject: riscv: Fix riscv_online_cpu_vec
+
+From: Andrew Jones <ajones@ventanamicro.com>
+
+[ Upstream commit 5af72a818612332a11171b16f27a62ec0a0f91d7 ]
+
+We shouldn't probe when we already know vector is unsupported and
+we should probe when we see we don't yet know whether it's supported.
+Furthermore, we should ensure we've set the access type to
+unsupported when we don't have vector at all.
+
+Fixes: e7c9d66e313b ("RISC-V: Report vector unaligned access speed hwprobe")
+Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
+Link: https://lore.kernel.org/r/20250304120014.143628-12-ajones@ventanamicro.com
+Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/unaligned_access_speed.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/arch/riscv/kernel/unaligned_access_speed.c b/arch/riscv/kernel/unaligned_access_speed.c
+index 85c868a8cee63..2e41b42498c76 100644
+--- a/arch/riscv/kernel/unaligned_access_speed.c
++++ b/arch/riscv/kernel/unaligned_access_speed.c
+@@ -370,10 +370,12 @@ static void check_vector_unaligned_access(struct work_struct *work __always_unus
+ static int riscv_online_cpu_vec(unsigned int cpu)
+ {
+-      if (!has_vector())
++      if (!has_vector()) {
++              per_cpu(vector_misaligned_access, cpu) = RISCV_HWPROBE_MISALIGNED_VECTOR_UNSUPPORTED;
+               return 0;
++      }
+-      if (per_cpu(vector_misaligned_access, cpu) != RISCV_HWPROBE_MISALIGNED_VECTOR_UNSUPPORTED)
++      if (per_cpu(vector_misaligned_access, cpu) != RISCV_HWPROBE_MISALIGNED_VECTOR_UNKNOWN)
+               return 0;
+       check_vector_unaligned_access_emulated(NULL);
+-- 
+2.39.5
+
diff --git a/queue-6.14/riscv-fix-set-up-of-cpu-hotplug-callbacks.patch b/queue-6.14/riscv-fix-set-up-of-cpu-hotplug-callbacks.patch
new file mode 100644 (file)
index 0000000..2b4b3a7
--- /dev/null
@@ -0,0 +1,83 @@
+From a4f06d506a6e1d4b5f43098a4710857c514e3367 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Mar 2025 13:00:20 +0100
+Subject: riscv: Fix set up of cpu hotplug callbacks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Andrew Jones <ajones@ventanamicro.com>
+
+[ Upstream commit 05ee21f0fcb8ca29bf42bd6cbce109f2e49c167f ]
+
+CPU hotplug callbacks should be set up even if we detected all
+current cpus emulate misaligned accesses, since we want to
+ensure our expectations of all cpus emulating is maintained.
+
+Fixes: 6e5ce7f2eae3 ("riscv: Decouple emulated unaligned accesses from access speed")
+Fixes: e7c9d66e313b ("RISC-V: Report vector unaligned access speed hwprobe")
+Reviewed-by: Clément Léger <cleger@rivosinc.com>
+Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
+Link: https://lore.kernel.org/r/20250304120014.143628-15-ajones@ventanamicro.com
+Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/unaligned_access_speed.c | 27 +++++++++++-----------
+ 1 file changed, 13 insertions(+), 14 deletions(-)
+
+diff --git a/arch/riscv/kernel/unaligned_access_speed.c b/arch/riscv/kernel/unaligned_access_speed.c
+index bca798153e37d..84694a44f3da4 100644
+--- a/arch/riscv/kernel/unaligned_access_speed.c
++++ b/arch/riscv/kernel/unaligned_access_speed.c
+@@ -247,13 +247,6 @@ static void __init check_unaligned_access_speed_all_cpus(void)
+       /* Check core 0. */
+       smp_call_on_cpu(0, check_unaligned_access, bufs[0], true);
+-      /*
+-       * Setup hotplug callbacks for any new CPUs that come online or go
+-       * offline.
+-       */
+-      cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "riscv:online",
+-                                riscv_online_cpu, riscv_offline_cpu);
+-
+ out:
+       for_each_cpu(cpu, cpu_online_mask) {
+               if (bufs[cpu])
+@@ -386,13 +379,6 @@ static int __init vec_check_unaligned_access_speed_all_cpus(void *unused __alway
+ {
+       schedule_on_each_cpu(check_vector_unaligned_access);
+-      /*
+-       * Setup hotplug callbacks for any new CPUs that come online or go
+-       * offline.
+-       */
+-      cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "riscv:online",
+-                                riscv_online_cpu_vec, NULL);
+-
+       return 0;
+ }
+ #else /* CONFIG_RISCV_PROBE_VECTOR_UNALIGNED_ACCESS */
+@@ -418,6 +404,19 @@ static int __init check_unaligned_access_all_cpus(void)
+                           NULL, "vec_check_unaligned_access_speed_all_cpus");
+       }
++      /*
++       * Setup hotplug callbacks for any new CPUs that come online or go
++       * offline.
++       */
++#ifdef CONFIG_RISCV_PROBE_UNALIGNED_ACCESS
++      cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "riscv:online",
++                                riscv_online_cpu, riscv_offline_cpu);
++#endif
++#ifdef CONFIG_RISCV_PROBE_VECTOR_UNALIGNED_ACCESS
++      cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "riscv:online",
++                                riscv_online_cpu_vec, NULL);
++#endif
++
+       return 0;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/riscv-fix-set-up-of-vector-cpu-hotplug-callback.patch b/queue-6.14/riscv-fix-set-up-of-vector-cpu-hotplug-callback.patch
new file mode 100644 (file)
index 0000000..571e1fd
--- /dev/null
@@ -0,0 +1,94 @@
+From d0795006384749d350750864f475cf2166235b2c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Mar 2025 13:00:21 +0100
+Subject: riscv: Fix set up of vector cpu hotplug callback
+
+From: Andrew Jones <ajones@ventanamicro.com>
+
+[ Upstream commit 2744ec472de31141ad354907ff98843dd6040917 ]
+
+Whether or not we have RISCV_PROBE_VECTOR_UNALIGNED_ACCESS we need to
+set up a cpu hotplug callback to check if we have vector at all,
+since, when we don't have vector, we need to set
+vector_misaligned_access to unsupported rather than leave it the
+default of unknown.
+
+Fixes: e7c9d66e313b ("RISC-V: Report vector unaligned access speed hwprobe")
+Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
+Link: https://lore.kernel.org/r/20250304120014.143628-16-ajones@ventanamicro.com
+Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/unaligned_access_speed.c | 31 +++++++++++-----------
+ 1 file changed, 16 insertions(+), 15 deletions(-)
+
+diff --git a/arch/riscv/kernel/unaligned_access_speed.c b/arch/riscv/kernel/unaligned_access_speed.c
+index 84694a44f3da4..a42115fbdeb89 100644
+--- a/arch/riscv/kernel/unaligned_access_speed.c
++++ b/arch/riscv/kernel/unaligned_access_speed.c
+@@ -359,6 +359,20 @@ static void check_vector_unaligned_access(struct work_struct *work __always_unus
+       __free_pages(page, MISALIGNED_BUFFER_ORDER);
+ }
++/* Measure unaligned access speed on all CPUs present at boot in parallel. */
++static int __init vec_check_unaligned_access_speed_all_cpus(void *unused __always_unused)
++{
++      schedule_on_each_cpu(check_vector_unaligned_access);
++
++      return 0;
++}
++#else /* CONFIG_RISCV_PROBE_VECTOR_UNALIGNED_ACCESS */
++static int __init vec_check_unaligned_access_speed_all_cpus(void *unused __always_unused)
++{
++      return 0;
++}
++#endif
++
+ static int riscv_online_cpu_vec(unsigned int cpu)
+ {
+       if (!has_vector()) {
+@@ -366,27 +380,16 @@ static int riscv_online_cpu_vec(unsigned int cpu)
+               return 0;
+       }
++#ifdef CONFIG_RISCV_PROBE_VECTOR_UNALIGNED_ACCESS
+       if (per_cpu(vector_misaligned_access, cpu) != RISCV_HWPROBE_MISALIGNED_VECTOR_UNKNOWN)
+               return 0;
+       check_vector_unaligned_access_emulated(NULL);
+       check_vector_unaligned_access(NULL);
+-      return 0;
+-}
+-
+-/* Measure unaligned access speed on all CPUs present at boot in parallel. */
+-static int __init vec_check_unaligned_access_speed_all_cpus(void *unused __always_unused)
+-{
+-      schedule_on_each_cpu(check_vector_unaligned_access);
++#endif
+       return 0;
+ }
+-#else /* CONFIG_RISCV_PROBE_VECTOR_UNALIGNED_ACCESS */
+-static int __init vec_check_unaligned_access_speed_all_cpus(void *unused __always_unused)
+-{
+-      return 0;
+-}
+-#endif
+ static int __init check_unaligned_access_all_cpus(void)
+ {
+@@ -412,10 +415,8 @@ static int __init check_unaligned_access_all_cpus(void)
+       cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "riscv:online",
+                                 riscv_online_cpu, riscv_offline_cpu);
+ #endif
+-#ifdef CONFIG_RISCV_PROBE_VECTOR_UNALIGNED_ACCESS
+       cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "riscv:online",
+                                 riscv_online_cpu_vec, NULL);
+-#endif
+       return 0;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/riscv-fix-the-__riscv_copy_vec_words_unaligned-imple.patch b/queue-6.14/riscv-fix-the-__riscv_copy_vec_words_unaligned-imple.patch
new file mode 100644 (file)
index 0000000..d97124c
--- /dev/null
@@ -0,0 +1,38 @@
+From ca8633c42558b48bad67a684f326524a6f5fbe87 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Feb 2025 01:08:01 -0800
+Subject: riscv: Fix the __riscv_copy_vec_words_unaligned implementation
+
+From: Tingbo Liao <tingbo.liao@starfivetech.com>
+
+[ Upstream commit 475afa39b123699e910c61ad9a51cedce4a0d310 ]
+
+Correct the VEC_S macro definition to fix the implementation
+of vector words copy in the case of unalignment in RISC-V.
+
+Fixes: e7c9d66e313b ("RISC-V: Report vector unaligned access speed hwprobe")
+Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Signed-off-by: Tingbo Liao <tingbo.liao@starfivetech.com>
+Link: https://lore.kernel.org/r/20250228090801.8334-1-tingbo.liao@starfivetech.com
+Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/vec-copy-unaligned.S | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/riscv/kernel/vec-copy-unaligned.S b/arch/riscv/kernel/vec-copy-unaligned.S
+index d16f19f1b3b65..7ce4de6f6e694 100644
+--- a/arch/riscv/kernel/vec-copy-unaligned.S
++++ b/arch/riscv/kernel/vec-copy-unaligned.S
+@@ -11,7 +11,7 @@
+ #define WORD_SEW CONCATENATE(e, WORD_EEW)
+ #define VEC_L CONCATENATE(vle, WORD_EEW).v
+-#define VEC_S CONCATENATE(vle, WORD_EEW).v
++#define VEC_S CONCATENATE(vse, WORD_EEW).v
+ /* void __riscv_copy_vec_words_unaligned(void *, const void *, size_t) */
+ /* Performs a memcpy without aligning buffers, using word loads and stores. */
+-- 
+2.39.5
+
diff --git a/queue-6.14/riscv-ftrace-add-parentheses-in-macro-definitions-of.patch b/queue-6.14/riscv-ftrace-add-parentheses-in-macro-definitions-of.patch
new file mode 100644 (file)
index 0000000..237c803
--- /dev/null
@@ -0,0 +1,63 @@
+From 72856b93c8432eeaa645945f72921751887697d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Feb 2025 13:28:36 -0600
+Subject: riscv: ftrace: Add parentheses in macro definitions of make_call_t0
+ and make_call_ra
+
+From: Juhan Jin <juhan.jin@foxmail.com>
+
+[ Upstream commit 5f1a58ed91a040d4625d854f9bb3dd4995919202 ]
+
+This patch adds parentheses to parameters caller and callee of macros
+make_call_t0 and make_call_ra. Every existing invocation of these two
+macros uses a single variable for each argument, so the absence of the
+parentheses seems okay. However, future invocations might use more
+complex expressions as arguments. For example, a future invocation might
+look like this: make_call_t0(a - b, c, call). Without parentheses in the
+macro definition, the macro invocation expands to:
+
+...
+unsigned int offset = (unsigned long) c - (unsigned long) a - b;
+...
+
+which is clearly wrong.
+
+The use of parentheses ensures arguments are correctly evaluated and
+potentially saves future users of make_call_t0 and make_call_ra debugging
+trouble.
+
+Fixes: 6724a76cff85 ("riscv: ftrace: Reduce the detour code size to half")
+Signed-off-by: Juhan Jin <juhan.jin@foxmail.com>
+Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Link: https://lore.kernel.org/r/tencent_AE90AA59903A628E87E9F80E563DA5BA5508@qq.com
+Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/include/asm/ftrace.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/riscv/include/asm/ftrace.h b/arch/riscv/include/asm/ftrace.h
+index c4721ce44ca47..2636ee00ccf0f 100644
+--- a/arch/riscv/include/asm/ftrace.h
++++ b/arch/riscv/include/asm/ftrace.h
+@@ -92,7 +92,7 @@ struct dyn_arch_ftrace {
+ #define make_call_t0(caller, callee, call)                            \
+ do {                                                                  \
+       unsigned int offset =                                           \
+-              (unsigned long) callee - (unsigned long) caller;        \
++              (unsigned long) (callee) - (unsigned long) (caller);    \
+       call[0] = to_auipc_t0(offset);                                  \
+       call[1] = to_jalr_t0(offset);                                   \
+ } while (0)
+@@ -108,7 +108,7 @@ do {                                                                       \
+ #define make_call_ra(caller, callee, call)                            \
+ do {                                                                  \
+       unsigned int offset =                                           \
+-              (unsigned long) callee - (unsigned long) caller;        \
++              (unsigned long) (callee) - (unsigned long) (caller);    \
+       call[0] = to_auipc_ra(offset);                                  \
+       call[1] = to_jalr_ra(offset);                                   \
+ } while (0)
+-- 
+2.39.5
+
diff --git a/queue-6.14/riscv-kexec_file-handle-r_riscv_64-in-purgatory-relo.patch b/queue-6.14/riscv-kexec_file-handle-r_riscv_64-in-purgatory-relo.patch
new file mode 100644 (file)
index 0000000..1c5d36a
--- /dev/null
@@ -0,0 +1,54 @@
+From 9aba7e22aca1cbc3892de9d623680598be3a9458 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Mar 2025 05:14:46 +0000
+Subject: riscv/kexec_file: Handle R_RISCV_64 in purgatory relocator
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Yao Zi <ziyao@disroot.org>
+
+[ Upstream commit 28093cfef5dd62f4cbd537f2bdf6f0bf85309c45 ]
+
+Commit 58ff537109ac ("riscv: Omit optimized string routines when
+using KASAN") introduced calls to EXPORT_SYMBOL() in assembly string
+routines, which result in R_RISCV_64 relocations against
+.export_symbol section. As these rountines are reused by RISC-V
+purgatory and our relocator doesn't recognize these relocations, this
+fails kexec-file-load with dmesg like
+
+       [   11.344251] kexec_image: Unknown rela relocation: 2
+       [   11.345972] kexec_image: Error loading purgatory ret=-8
+
+Let's support R_RISCV_64 relocation to fix kexec on 64-bit RISC-V.
+32-bit variant isn't covered since KEXEC_FILE and KEXEC_PURGATORY isn't
+available.
+
+Fixes: 58ff537109ac ("riscv: Omit optimized string routines when using KASAN")
+Signed-off-by: Yao Zi <ziyao@disroot.org>
+Tested-by: Björn Töpel <bjorn@rivosinc.com>
+Reviewed-by: Björn Töpel <bjorn@rivosinc.com>
+Link: https://lore.kernel.org/r/20250326051445.55131-2-ziyao@disroot.org
+Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/elf_kexec.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/arch/riscv/kernel/elf_kexec.c b/arch/riscv/kernel/elf_kexec.c
+index 3c37661801f95..e783a72d051f4 100644
+--- a/arch/riscv/kernel/elf_kexec.c
++++ b/arch/riscv/kernel/elf_kexec.c
+@@ -468,6 +468,9 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
+               case R_RISCV_ALIGN:
+               case R_RISCV_RELAX:
+                       break;
++              case R_RISCV_64:
++                      *(u64 *)loc = val;
++                      break;
+               default:
+                       pr_err("Unknown rela relocation: %d\n", r_type);
+                       return -ENOEXEC;
+-- 
+2.39.5
+
diff --git a/queue-6.14/riscv-purgatory-4b-align-purgatory_start.patch b/queue-6.14/riscv-purgatory-4b-align-purgatory_start.patch
new file mode 100644 (file)
index 0000000..f23779a
--- /dev/null
@@ -0,0 +1,63 @@
+From 374d76691474ee0440c58aac8f9b66f9e34bc91d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Mar 2025 09:53:11 +0100
+Subject: riscv/purgatory: 4B align purgatory_start
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Björn Töpel <bjorn@rivosinc.com>
+
+[ Upstream commit 3f7023171df43641a8a8a1c9a12124501e589010 ]
+
+When a crashkernel is launched on RISC-V, the entry to purgatory is
+done by trapping via the stvec CSR. From riscv_kexec_norelocate():
+
+  |  ...
+  |  /*
+  |   * Switch to physical addressing
+  |   * This will also trigger a jump to CSR_STVEC
+  |   * which in this case is the address of the new
+  |   * kernel.
+  |   */
+  |  csrw    CSR_STVEC, a2
+  |  csrw    CSR_SATP, zero
+
+stvec requires that the address is 4B aligned, which was not the case,
+e.g.:
+
+  | Loaded purgatory at 0xffffc000
+  | kexec_file: kexec_file_load: type:1, start:0xffffd232 head:0x4 flags:0x6
+
+The address 0xffffd232 not 4B aligned.
+
+Correct by adding proper function alignment.
+
+With this change, crashkernels loaded with kexec-file will be able to
+properly enter the purgatory.
+
+Fixes: 736e30af583fb ("RISC-V: Add purgatory")
+Signed-off-by: Björn Töpel <bjorn@rivosinc.com>
+Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Link: https://lore.kernel.org/r/20250328085313.1193815-1-bjorn@kernel.org
+Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/purgatory/entry.S | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/riscv/purgatory/entry.S b/arch/riscv/purgatory/entry.S
+index 0e6ca6d5ae4b4..c5db2f072c341 100644
+--- a/arch/riscv/purgatory/entry.S
++++ b/arch/riscv/purgatory/entry.S
+@@ -12,6 +12,7 @@
+ .text
++.align        2
+ SYM_CODE_START(purgatory_start)
+       lla     sp, .Lstack
+-- 
+2.39.5
+
diff --git a/queue-6.14/rndis_host-flag-rndis-modems-as-wwan-devices.patch b/queue-6.14/rndis_host-flag-rndis-modems-as-wwan-devices.patch
new file mode 100644 (file)
index 0000000..121751f
--- /dev/null
@@ -0,0 +1,70 @@
+From d4b6ac22656526cfed6203880ff42fea855f6212 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Mar 2025 10:58:41 +0100
+Subject: rndis_host: Flag RNDIS modems as WWAN devices
+
+From: Lubomir Rintel <lkundrak@v3.sk>
+
+[ Upstream commit 67d1a8956d2d62fe6b4c13ebabb57806098511d8 ]
+
+Set FLAG_WWAN instead of FLAG_ETHERNET for RNDIS interfaces on Mobile
+Broadband Modems, as opposed to regular Ethernet adapters.
+
+Otherwise NetworkManager gets confused, misjudges the device type,
+and wouldn't know it should connect a modem to get the device to work.
+What would be the result depends on ModemManager version -- older
+ModemManager would end up disconnecting a device after an unsuccessful
+probe attempt (if it connected without needing to unlock a SIM), while
+a newer one might spawn a separate PPP connection over a tty interface
+instead, resulting in a general confusion and no end of chaos.
+
+The only way to get this work reliably is to fix the device type
+and have good enough version ModemManager (or equivalent).
+
+Fixes: 63ba395cd7a5 ("rndis_host: support Novatel Verizon USB730L")
+Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
+Link: https://patch.msgid.link/20250325095842.1567999-1-lkundrak@v3.sk
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/rndis_host.c | 16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
+index 7b3739b29c8f7..bb0bf14158727 100644
+--- a/drivers/net/usb/rndis_host.c
++++ b/drivers/net/usb/rndis_host.c
+@@ -630,6 +630,16 @@ static const struct driver_info   zte_rndis_info = {
+       .tx_fixup =     rndis_tx_fixup,
+ };
++static const struct driver_info       wwan_rndis_info = {
++      .description =  "Mobile Broadband RNDIS device",
++      .flags =        FLAG_WWAN | FLAG_POINTTOPOINT | FLAG_FRAMING_RN | FLAG_NO_SETINT,
++      .bind =         rndis_bind,
++      .unbind =       rndis_unbind,
++      .status =       rndis_status,
++      .rx_fixup =     rndis_rx_fixup,
++      .tx_fixup =     rndis_tx_fixup,
++};
++
+ /*-------------------------------------------------------------------------*/
+ static const struct usb_device_id     products [] = {
+@@ -666,9 +676,11 @@ static const struct usb_device_id products [] = {
+       USB_INTERFACE_INFO(USB_CLASS_WIRELESS_CONTROLLER, 1, 3),
+       .driver_info = (unsigned long) &rndis_info,
+ }, {
+-      /* Novatel Verizon USB730L */
++      /* Mobile Broadband Modem, seen in Novatel Verizon USB730L and
++       * Telit FN990A (RNDIS)
++       */
+       USB_INTERFACE_INFO(USB_CLASS_MISC, 4, 1),
+-      .driver_info = (unsigned long) &rndis_info,
++      .driver_info = (unsigned long)&wwan_rndis_info,
+ },
+       { },            // END
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.14/rseq-update-kernel-fields-in-lockstep-with-config_de.patch b/queue-6.14/rseq-update-kernel-fields-in-lockstep-with-config_de.patch
new file mode 100644 (file)
index 0000000..2570070
--- /dev/null
@@ -0,0 +1,159 @@
+From c47afbd27f11a7cf6fe070eae86e6fb844a34251 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Feb 2025 15:24:46 -0500
+Subject: rseq: Update kernel fields in lockstep with CONFIG_DEBUG_RSEQ=y
+
+From: Michael Jeanson <mjeanson@efficios.com>
+
+[ Upstream commit 79e10dad1ce3feac7937bedf911d92f486a9e76a ]
+
+With CONFIG_DEBUG_RSEQ=y, an in-kernel copy of the read-only fields is
+kept synchronized with the user-space fields. Ensure the updates are
+done in lockstep in case we error out on a write to user-space.
+
+Fixes: 7d5265ffcd8b ("rseq: Validate read-only fields under DEBUG_RSEQ config")
+Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Link: https://lore.kernel.org/r/20250225202500.731245-1-mjeanson@efficios.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/rseq.c | 80 +++++++++++++++++++++++++--------------------------
+ 1 file changed, 40 insertions(+), 40 deletions(-)
+
+diff --git a/kernel/rseq.c b/kernel/rseq.c
+index 2cb16091ec0ae..a7d81229eda04 100644
+--- a/kernel/rseq.c
++++ b/kernel/rseq.c
+@@ -78,24 +78,24 @@ static int rseq_validate_ro_fields(struct task_struct *t)
+       return -EFAULT;
+ }
+-static void rseq_set_ro_fields(struct task_struct *t, u32 cpu_id_start, u32 cpu_id,
+-                             u32 node_id, u32 mm_cid)
+-{
+-      rseq_kernel_fields(t)->cpu_id_start = cpu_id;
+-      rseq_kernel_fields(t)->cpu_id = cpu_id;
+-      rseq_kernel_fields(t)->node_id = node_id;
+-      rseq_kernel_fields(t)->mm_cid = mm_cid;
+-}
++/*
++ * Update an rseq field and its in-kernel copy in lock-step to keep a coherent
++ * state.
++ */
++#define rseq_unsafe_put_user(t, value, field, error_label)            \
++      do {                                                            \
++              unsafe_put_user(value, &t->rseq->field, error_label);   \
++              rseq_kernel_fields(t)->field = value;                   \
++      } while (0)
++
+ #else
+ static int rseq_validate_ro_fields(struct task_struct *t)
+ {
+       return 0;
+ }
+-static void rseq_set_ro_fields(struct task_struct *t, u32 cpu_id_start, u32 cpu_id,
+-                             u32 node_id, u32 mm_cid)
+-{
+-}
++#define rseq_unsafe_put_user(t, value, field, error_label)            \
++      unsafe_put_user(value, &t->rseq->field, error_label)
+ #endif
+ /*
+@@ -173,17 +173,18 @@ static int rseq_update_cpu_node_id(struct task_struct *t)
+       WARN_ON_ONCE((int) mm_cid < 0);
+       if (!user_write_access_begin(rseq, t->rseq_len))
+               goto efault;
+-      unsafe_put_user(cpu_id, &rseq->cpu_id_start, efault_end);
+-      unsafe_put_user(cpu_id, &rseq->cpu_id, efault_end);
+-      unsafe_put_user(node_id, &rseq->node_id, efault_end);
+-      unsafe_put_user(mm_cid, &rseq->mm_cid, efault_end);
++
++      rseq_unsafe_put_user(t, cpu_id, cpu_id_start, efault_end);
++      rseq_unsafe_put_user(t, cpu_id, cpu_id, efault_end);
++      rseq_unsafe_put_user(t, node_id, node_id, efault_end);
++      rseq_unsafe_put_user(t, mm_cid, mm_cid, efault_end);
++
+       /*
+        * Additional feature fields added after ORIG_RSEQ_SIZE
+        * need to be conditionally updated only if
+        * t->rseq_len != ORIG_RSEQ_SIZE.
+        */
+       user_write_access_end();
+-      rseq_set_ro_fields(t, cpu_id, cpu_id, node_id, mm_cid);
+       trace_rseq_update(t);
+       return 0;
+@@ -195,6 +196,7 @@ static int rseq_update_cpu_node_id(struct task_struct *t)
+ static int rseq_reset_rseq_cpu_node_id(struct task_struct *t)
+ {
++      struct rseq __user *rseq = t->rseq;
+       u32 cpu_id_start = 0, cpu_id = RSEQ_CPU_ID_UNINITIALIZED, node_id = 0,
+           mm_cid = 0;
+@@ -202,38 +204,36 @@ static int rseq_reset_rseq_cpu_node_id(struct task_struct *t)
+        * Validate read-only rseq fields.
+        */
+       if (rseq_validate_ro_fields(t))
+-              return -EFAULT;
+-      /*
+-       * Reset cpu_id_start to its initial state (0).
+-       */
+-      if (put_user(cpu_id_start, &t->rseq->cpu_id_start))
+-              return -EFAULT;
+-      /*
+-       * Reset cpu_id to RSEQ_CPU_ID_UNINITIALIZED, so any user coming
+-       * in after unregistration can figure out that rseq needs to be
+-       * registered again.
+-       */
+-      if (put_user(cpu_id, &t->rseq->cpu_id))
+-              return -EFAULT;
+-      /*
+-       * Reset node_id to its initial state (0).
+-       */
+-      if (put_user(node_id, &t->rseq->node_id))
+-              return -EFAULT;
++              goto efault;
++
++      if (!user_write_access_begin(rseq, t->rseq_len))
++              goto efault;
++
+       /*
+-       * Reset mm_cid to its initial state (0).
++       * Reset all fields to their initial state.
++       *
++       * All fields have an initial state of 0 except cpu_id which is set to
++       * RSEQ_CPU_ID_UNINITIALIZED, so that any user coming in after
++       * unregistration can figure out that rseq needs to be registered
++       * again.
+        */
+-      if (put_user(mm_cid, &t->rseq->mm_cid))
+-              return -EFAULT;
+-
+-      rseq_set_ro_fields(t, cpu_id_start, cpu_id, node_id, mm_cid);
++      rseq_unsafe_put_user(t, cpu_id_start, cpu_id_start, efault_end);
++      rseq_unsafe_put_user(t, cpu_id, cpu_id, efault_end);
++      rseq_unsafe_put_user(t, node_id, node_id, efault_end);
++      rseq_unsafe_put_user(t, mm_cid, mm_cid, efault_end);
+       /*
+        * Additional feature fields added after ORIG_RSEQ_SIZE
+        * need to be conditionally reset only if
+        * t->rseq_len != ORIG_RSEQ_SIZE.
+        */
++      user_write_access_end();
+       return 0;
++
++efault_end:
++      user_write_access_end();
++efault:
++      return -EFAULT;
+ }
+ static int rseq_get_rseq_cs(struct task_struct *t, struct rseq_cs *rseq_cs)
+-- 
+2.39.5
+
diff --git a/queue-6.14/rtc-renesas-rtca3-disable-interrupts-only-if-the-rtc.patch b/queue-6.14/rtc-renesas-rtca3-disable-interrupts-only-if-the-rtc.patch
new file mode 100644 (file)
index 0000000..69fbb0f
--- /dev/null
@@ -0,0 +1,58 @@
+From 77b7d26de01f80f8d1c0369b9f69cfdf93c7811c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Feb 2025 11:55:19 +0200
+Subject: rtc: renesas-rtca3: Disable interrupts only if the RTC is enabled
+
+From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+
+[ Upstream commit 27b2fcbd6b98204b0dce62e9aa9540ca0a2b70f1 ]
+
+If the RTC is not enabled and the code attempts to disable the interrupt,
+the readb_poll_timeout_atomic() function in the
+rtca3_alarm_irq_set_helper() may timeout, leading to probe failures.
+This issue is reproducible on some devices because the initial values of
+the PIE and AIE bits in the RCR1 register are undefined.
+
+To prevent probe failures in this scenario, disable RTC interrupts only
+when the RTC is actually enabled.
+
+Fixes: d4488377609e ("rtc: renesas-rtca3: Add driver for RTCA-3 available on Renesas RZ/G3S SoC")
+Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Link: https://lore.kernel.org/r/20250205095519.2031742-1-claudiu.beznea.uj@bp.renesas.com
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rtc/rtc-renesas-rtca3.c | 15 ++++++---------
+ 1 file changed, 6 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/rtc/rtc-renesas-rtca3.c b/drivers/rtc/rtc-renesas-rtca3.c
+index a056291d38876..ab816bdf0d776 100644
+--- a/drivers/rtc/rtc-renesas-rtca3.c
++++ b/drivers/rtc/rtc-renesas-rtca3.c
+@@ -586,17 +586,14 @@ static int rtca3_initial_setup(struct clk *clk, struct rtca3_priv *priv)
+        */
+       usleep_range(sleep_us, sleep_us + 10);
+-      /* Disable all interrupts. */
+-      mask = RTCA3_RCR1_AIE | RTCA3_RCR1_CIE | RTCA3_RCR1_PIE;
+-      ret = rtca3_alarm_irq_set_helper(priv, mask, 0);
+-      if (ret)
+-              return ret;
+-
+       mask = RTCA3_RCR2_START | RTCA3_RCR2_HR24;
+       val = readb(priv->base + RTCA3_RCR2);
+-      /* Nothing to do if already started in 24 hours and calendar count mode. */
+-      if ((val & mask) == mask)
+-              return 0;
++      /* Only disable the interrupts if already started in 24 hours and calendar count mode. */
++      if ((val & mask) == mask) {
++              /* Disable all interrupts. */
++              mask = RTCA3_RCR1_AIE | RTCA3_RCR1_CIE | RTCA3_RCR1_PIE;
++              return rtca3_alarm_irq_set_helper(priv, mask, 0);
++      }
+       /* Reconfigure the RTC in 24 hours and calendar count mode. */
+       mask = RTCA3_RCR2_START | RTCA3_RCR2_CNTMD;
+-- 
+2.39.5
+
diff --git a/queue-6.14/rtnetlink-allocate-vfinfo-size-for-vf-guids-when-sup.patch b/queue-6.14/rtnetlink-allocate-vfinfo-size-for-vf-guids-when-sup.patch
new file mode 100644 (file)
index 0000000..f7340ad
--- /dev/null
@@ -0,0 +1,163 @@
+From 7f58e24cc182f84ff282a413ce57f57b9bd68653 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Mar 2025 11:02:26 +0200
+Subject: rtnetlink: Allocate vfinfo size for VF GUIDs when supported
+
+From: Mark Zhang <markzhang@nvidia.com>
+
+[ Upstream commit 23f00807619d15063d676218f36c5dfeda1eb420 ]
+
+Commit 30aad41721e0 ("net/core: Add support for getting VF GUIDs")
+added support for getting VF port and node GUIDs in netlink ifinfo
+messages, but their size was not taken into consideration in the
+function that allocates the netlink message, causing the following
+warning when a netlink message is filled with many VF port and node
+GUIDs:
+ # echo 64 > /sys/bus/pci/devices/0000\:08\:00.0/sriov_numvfs
+ # ip link show dev ib0
+ RTNETLINK answers: Message too long
+ Cannot send link get request: Message too long
+
+Kernel warning:
+
+ ------------[ cut here ]------------
+ WARNING: CPU: 2 PID: 1930 at net/core/rtnetlink.c:4151 rtnl_getlink+0x586/0x5a0
+ Modules linked in: xt_conntrack xt_MASQUERADE nfnetlink xt_addrtype iptable_nat nf_nat br_netfilter overlay mlx5_ib macsec mlx5_core tls rpcrdma rdma_ucm ib_uverbs ib_iser libiscsi scsi_transport_iscsi ib_umad rdma_cm iw_cm ib_ipoib fuse ib_cm ib_core
+ CPU: 2 UID: 0 PID: 1930 Comm: ip Not tainted 6.14.0-rc2+ #1
+ Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
+ RIP: 0010:rtnl_getlink+0x586/0x5a0
+ Code: cb 82 e8 3d af 0a 00 4d 85 ff 0f 84 08 ff ff ff 4c 89 ff 41 be ea ff ff ff e8 66 63 5b ff 49 c7 07 80 4f cb 82 e9 36 fc ff ff <0f> 0b e9 16 fe ff ff e8 de a0 56 00 66 66 2e 0f 1f 84 00 00 00 00
+ RSP: 0018:ffff888113557348 EFLAGS: 00010246
+ RAX: 00000000ffffffa6 RBX: ffff88817e87aa34 RCX: dffffc0000000000
+ RDX: 0000000000000003 RSI: 0000000000000000 RDI: ffff88817e87afb8
+ RBP: 0000000000000009 R08: ffffffff821f44aa R09: 0000000000000000
+ R10: ffff8881260f79a8 R11: ffff88817e87af00 R12: ffff88817e87aa00
+ R13: ffffffff8563d300 R14: 00000000ffffffa6 R15: 00000000ffffffff
+ FS:  00007f63a5dbf280(0000) GS:ffff88881ee00000(0000) knlGS:0000000000000000
+ CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 00007f63a5ba4493 CR3: 00000001700fe002 CR4: 0000000000772eb0
+ DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+ DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+ PKRU: 55555554
+ Call Trace:
+  <TASK>
+  ? __warn+0xa5/0x230
+  ? rtnl_getlink+0x586/0x5a0
+  ? report_bug+0x22d/0x240
+  ? handle_bug+0x53/0xa0
+  ? exc_invalid_op+0x14/0x50
+  ? asm_exc_invalid_op+0x16/0x20
+  ? skb_trim+0x6a/0x80
+  ? rtnl_getlink+0x586/0x5a0
+  ? __pfx_rtnl_getlink+0x10/0x10
+  ? rtnetlink_rcv_msg+0x1e5/0x860
+  ? __pfx___mutex_lock+0x10/0x10
+  ? rcu_is_watching+0x34/0x60
+  ? __pfx_lock_acquire+0x10/0x10
+  ? stack_trace_save+0x90/0xd0
+  ? filter_irq_stacks+0x1d/0x70
+  ? kasan_save_stack+0x30/0x40
+  ? kasan_save_stack+0x20/0x40
+  ? kasan_save_track+0x10/0x30
+  rtnetlink_rcv_msg+0x21c/0x860
+  ? entry_SYSCALL_64_after_hwframe+0x76/0x7e
+  ? __pfx_rtnetlink_rcv_msg+0x10/0x10
+  ? arch_stack_walk+0x9e/0xf0
+  ? rcu_is_watching+0x34/0x60
+  ? lock_acquire+0xd5/0x410
+  ? rcu_is_watching+0x34/0x60
+  netlink_rcv_skb+0xe0/0x210
+  ? __pfx_rtnetlink_rcv_msg+0x10/0x10
+  ? __pfx_netlink_rcv_skb+0x10/0x10
+  ? rcu_is_watching+0x34/0x60
+  ? __pfx___netlink_lookup+0x10/0x10
+  ? lock_release+0x62/0x200
+  ? netlink_deliver_tap+0xfd/0x290
+  ? rcu_is_watching+0x34/0x60
+  ? lock_release+0x62/0x200
+  ? netlink_deliver_tap+0x95/0x290
+  netlink_unicast+0x31f/0x480
+  ? __pfx_netlink_unicast+0x10/0x10
+  ? rcu_is_watching+0x34/0x60
+  ? lock_acquire+0xd5/0x410
+  netlink_sendmsg+0x369/0x660
+  ? lock_release+0x62/0x200
+  ? __pfx_netlink_sendmsg+0x10/0x10
+  ? import_ubuf+0xb9/0xf0
+  ? __import_iovec+0x254/0x2b0
+  ? lock_release+0x62/0x200
+  ? __pfx_netlink_sendmsg+0x10/0x10
+  ____sys_sendmsg+0x559/0x5a0
+  ? __pfx_____sys_sendmsg+0x10/0x10
+  ? __pfx_copy_msghdr_from_user+0x10/0x10
+  ? rcu_is_watching+0x34/0x60
+  ? do_read_fault+0x213/0x4a0
+  ? rcu_is_watching+0x34/0x60
+  ___sys_sendmsg+0xe4/0x150
+  ? __pfx____sys_sendmsg+0x10/0x10
+  ? do_fault+0x2cc/0x6f0
+  ? handle_pte_fault+0x2e3/0x3d0
+  ? __pfx_handle_pte_fault+0x10/0x10
+  ? preempt_count_sub+0x14/0xc0
+  ? __down_read_trylock+0x150/0x270
+  ? __handle_mm_fault+0x404/0x8e0
+  ? __pfx___handle_mm_fault+0x10/0x10
+  ? lock_release+0x62/0x200
+  ? __rcu_read_unlock+0x65/0x90
+  ? rcu_is_watching+0x34/0x60
+  __sys_sendmsg+0xd5/0x150
+  ? __pfx___sys_sendmsg+0x10/0x10
+  ? __up_read+0x192/0x480
+  ? lock_release+0x62/0x200
+  ? __rcu_read_unlock+0x65/0x90
+  ? rcu_is_watching+0x34/0x60
+  do_syscall_64+0x6d/0x140
+  entry_SYSCALL_64_after_hwframe+0x76/0x7e
+ RIP: 0033:0x7f63a5b13367
+ Code: 0e 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b9 0f 1f 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 b8 2e 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 51 c3 48 83 ec 28 89 54 24 1c 48 89 74 24 10
+ RSP: 002b:00007fff8c726bc8 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+ RAX: ffffffffffffffda RBX: 0000000067b687c2 RCX: 00007f63a5b13367
+ RDX: 0000000000000000 RSI: 00007fff8c726c30 RDI: 0000000000000004
+ RBP: 00007fff8c726cb8 R08: 0000000000000000 R09: 0000000000000034
+ R10: 00007fff8c726c7c R11: 0000000000000246 R12: 0000000000000001
+ R13: 0000000000000000 R14: 00007fff8c726cd0 R15: 00007fff8c726cd0
+  </TASK>
+ irq event stamp: 0
+ hardirqs last  enabled at (0): [<0000000000000000>] 0x0
+ hardirqs last disabled at (0): [<ffffffff813f9e58>] copy_process+0xd08/0x2830
+ softirqs last  enabled at (0): [<ffffffff813f9e58>] copy_process+0xd08/0x2830
+ softirqs last disabled at (0): [<0000000000000000>] 0x0
+ ---[ end trace 0000000000000000 ]---
+
+Thus, when calculating ifinfo message size, take VF GUIDs sizes into
+account when supported.
+
+Fixes: 30aad41721e0 ("net/core: Add support for getting VF GUIDs")
+Signed-off-by: Mark Zhang <markzhang@nvidia.com>
+Reviewed-by: Maher Sanalla <msanalla@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
+Link: https://patch.msgid.link/20250325090226.749730-1-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/rtnetlink.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
+index d1e559fce918d..80e006940f51a 100644
+--- a/net/core/rtnetlink.c
++++ b/net/core/rtnetlink.c
+@@ -1171,6 +1171,9 @@ static inline int rtnl_vfinfo_size(const struct net_device *dev,
+                                /* IFLA_VF_STATS_TX_DROPPED */
+                                nla_total_size_64bit(sizeof(__u64)));
+               }
++              if (dev->netdev_ops->ndo_get_vf_guid)
++                      size += num_vfs * 2 *
++                              nla_total_size(sizeof(struct ifla_vf_guid));
+               return size;
+       } else
+               return 0;
+-- 
+2.39.5
+
diff --git a/queue-6.14/rtnetlink-use-register_pernet_subsys-in-rtnl_net_deb.patch b/queue-6.14/rtnetlink-use-register_pernet_subsys-in-rtnl_net_deb.patch
new file mode 100644 (file)
index 0000000..f5d2852
--- /dev/null
@@ -0,0 +1,48 @@
+From 4ae5168dc4f76ff9aaa6b9ffceaed5ee45471327 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 12:07:08 -0700
+Subject: rtnetlink: Use register_pernet_subsys() in rtnl_net_debug_init().
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 1b7fdc702c031134c619b74c4f311c590e50ca3d ]
+
+rtnl_net_debug_init() registers rtnl_net_debug_net_ops by
+register_pernet_device() but calls unregister_pernet_subsys()
+in case register_netdevice_notifier() fails.
+
+It corrupts pernet_list because first_device is updated in
+register_pernet_device() but not unregister_pernet_subsys().
+
+Let's fix it by calling register_pernet_subsys() instead.
+
+The _subsys() one fits better for the use case because it keeps
+the notifier alive until default_device_exit_net(), giving it
+more chance to test NETDEV_UNREGISTER.
+
+Fixes: 03fa53485659 ("rtnetlink: Add ASSERT_RTNL_NET() placeholder for netdev notifier.")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250401190716.70437-1-kuniyu@amazon.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/rtnl_net_debug.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/core/rtnl_net_debug.c b/net/core/rtnl_net_debug.c
+index 7ecd28cc1c225..f3272b09c2556 100644
+--- a/net/core/rtnl_net_debug.c
++++ b/net/core/rtnl_net_debug.c
+@@ -102,7 +102,7 @@ static int __init rtnl_net_debug_init(void)
+ {
+       int ret;
+-      ret = register_pernet_device(&rtnl_net_debug_net_ops);
++      ret = register_pernet_subsys(&rtnl_net_debug_net_ops);
+       if (ret)
+               return ret;
+-- 
+2.39.5
+
diff --git a/queue-6.14/rust-fix-signature-of-rust_fmt_argument.patch b/queue-6.14/rust-fix-signature-of-rust_fmt_argument.patch
new file mode 100644 (file)
index 0000000..73908b1
--- /dev/null
@@ -0,0 +1,78 @@
+From dcac389c75d05930a6ba09a1f8f2cb0b1d3d1850 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Mar 2025 08:45:12 +0000
+Subject: rust: fix signature of rust_fmt_argument
+
+From: Alice Ryhl <aliceryhl@google.com>
+
+[ Upstream commit 901b3290bd4dc35e613d13abd03c129e754dd3dd ]
+
+Without this change, the rest of this series will emit the following
+error message:
+
+error[E0308]: `if` and `else` have incompatible types
+  --> <linux>/rust/kernel/print.rs:22:22
+   |
+21 | #[export]
+   | --------- expected because of this
+22 | unsafe extern "C" fn rust_fmt_argument(
+   |                      ^^^^^^^^^^^^^^^^^ expected `u8`, found `i8`
+   |
+   = note: expected fn item `unsafe extern "C" fn(*mut u8, *mut u8, *mut c_void) -> *mut u8 {bindings::rust_fmt_argument}`
+              found fn item `unsafe extern "C" fn(*mut i8, *mut i8, *const c_void) -> *mut i8 {print::rust_fmt_argument}`
+
+The error may be different depending on the architecture.
+
+To fix this, change the void pointer argument to use a const pointer,
+and change the imports to use crate::ffi instead of core::ffi for
+integer types.
+
+Fixes: 787983da7718 ("vsprintf: add new `%pA` format specifier")
+Reviewed-by: Tamir Duberstein <tamird@gmail.com>
+Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Alice Ryhl <aliceryhl@google.com>
+Acked-by: Petr Mladek <pmladek@suse.com>
+Link: https://lore.kernel.org/r/20250303-export-macro-v3-1-41fbad85a27f@google.com
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/vsprintf.c       | 2 +-
+ rust/kernel/print.rs | 7 +++----
+ 2 files changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/lib/vsprintf.c b/lib/vsprintf.c
+index 56fe963192926..a8ac4c4fffcf2 100644
+--- a/lib/vsprintf.c
++++ b/lib/vsprintf.c
+@@ -2285,7 +2285,7 @@ int __init no_hash_pointers_enable(char *str)
+ early_param("no_hash_pointers", no_hash_pointers_enable);
+ /* Used for Rust formatting ('%pA'). */
+-char *rust_fmt_argument(char *buf, char *end, void *ptr);
++char *rust_fmt_argument(char *buf, char *end, const void *ptr);
+ /*
+  * Show a '%p' thing.  A kernel extension is that the '%p' is followed
+diff --git a/rust/kernel/print.rs b/rust/kernel/print.rs
+index b19ee490be58f..61ee36c5e5f5d 100644
+--- a/rust/kernel/print.rs
++++ b/rust/kernel/print.rs
+@@ -6,12 +6,11 @@
+ //!
+ //! Reference: <https://docs.kernel.org/core-api/printk-basics.html>
+-use core::{
++use crate::{
+     ffi::{c_char, c_void},
+-    fmt,
++    str::RawFormatter,
+ };
+-
+-use crate::str::RawFormatter;
++use core::fmt;
+ // Called from `vsprintf` with format specifier `%pA`.
+ #[expect(clippy::missing_safety_doc)]
+-- 
+2.39.5
+
diff --git a/queue-6.14/rust-pci-fix-unrestricted-mut-pci-device.patch b/queue-6.14/rust-pci-fix-unrestricted-mut-pci-device.patch
new file mode 100644 (file)
index 0000000..e871cd1
--- /dev/null
@@ -0,0 +1,334 @@
+From 59cba79ebad5ec8c5936a4e0941da198ff414d77 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Mar 2025 17:09:06 +0100
+Subject: rust: pci: fix unrestricted &mut pci::Device
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+[ Upstream commit 7b948a2af6b5d64a25c14da8f63d8084ea527cd9 ]
+
+As by now, pci::Device is implemented as:
+
+       #[derive(Clone)]
+       pub struct Device(ARef<device::Device>);
+
+This may be convenient, but has the implication that drivers can call
+device methods that require a mutable reference concurrently at any
+point of time.
+
+Instead define pci::Device as
+
+       pub struct Device<Ctx: DeviceContext = Normal>(
+               Opaque<bindings::pci_dev>,
+               PhantomData<Ctx>,
+       );
+
+and manually implement the AlwaysRefCounted trait.
+
+With this we can implement methods that should only be called from
+bus callbacks (such as probe()) for pci::Device<Core>. Consequently, we
+make this type accessible in bus callbacks only.
+
+Arbitrary references taken by the driver are still of type
+ARef<pci::Device> and hence don't provide access to methods that are
+reserved for bus callbacks.
+
+Fixes: 1bd8b6b2c5d3 ("rust: pci: add basic PCI device / driver abstractions")
+Reviewed-by: Benno Lossin <benno.lossin@proton.me>
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Acked-by: Boqun Feng <boqun.feng@gmail.com>
+Link: https://lore.kernel.org/r/20250314160932.100165-4-dakr@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ rust/kernel/pci.rs              | 132 ++++++++++++++++++++------------
+ samples/rust/rust_driver_pci.rs |   8 +-
+ 2 files changed, 89 insertions(+), 51 deletions(-)
+
+diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs
+index 386484dcf36eb..0ac6cef74f815 100644
+--- a/rust/kernel/pci.rs
++++ b/rust/kernel/pci.rs
+@@ -6,7 +6,7 @@
+ use crate::{
+     alloc::flags::*,
+-    bindings, container_of, device,
++    bindings, device,
+     device_id::RawDeviceId,
+     devres::Devres,
+     driver,
+@@ -17,7 +17,11 @@ use crate::{
+     types::{ARef, ForeignOwnable, Opaque},
+     ThisModule,
+ };
+-use core::{ops::Deref, ptr::addr_of_mut};
++use core::{
++    marker::PhantomData,
++    ops::Deref,
++    ptr::{addr_of_mut, NonNull},
++};
+ use kernel::prelude::*;
+ /// An adapter for the registration of PCI drivers.
+@@ -60,17 +64,16 @@ impl<T: Driver + 'static> Adapter<T> {
+     ) -> kernel::ffi::c_int {
+         // SAFETY: The PCI bus only ever calls the probe callback with a valid pointer to a
+         // `struct pci_dev`.
+-        let dev = unsafe { device::Device::get_device(addr_of_mut!((*pdev).dev)) };
+-        // SAFETY: `dev` is guaranteed to be embedded in a valid `struct pci_dev` by the call
+-        // above.
+-        let mut pdev = unsafe { Device::from_dev(dev) };
++        //
++        // INVARIANT: `pdev` is valid for the duration of `probe_callback()`.
++        let pdev = unsafe { &*pdev.cast::<Device<device::Core>>() };
+         // SAFETY: `DeviceId` is a `#[repr(transparent)` wrapper of `struct pci_device_id` and
+         // does not add additional invariants, so it's safe to transmute.
+         let id = unsafe { &*id.cast::<DeviceId>() };
+         let info = T::ID_TABLE.info(id.index());
+-        match T::probe(&mut pdev, info) {
++        match T::probe(pdev, info) {
+             Ok(data) => {
+                 // Let the `struct pci_dev` own a reference of the driver's private data.
+                 // SAFETY: By the type invariant `pdev.as_raw` returns a valid pointer to a
+@@ -192,7 +195,7 @@ macro_rules! pci_device_table {
+ /// # Example
+ ///
+ ///```
+-/// # use kernel::{bindings, pci};
++/// # use kernel::{bindings, device::Core, pci};
+ ///
+ /// struct MyDriver;
+ ///
+@@ -210,7 +213,7 @@ macro_rules! pci_device_table {
+ ///     const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;
+ ///
+ ///     fn probe(
+-///         _pdev: &mut pci::Device,
++///         _pdev: &pci::Device<Core>,
+ ///         _id_info: &Self::IdInfo,
+ ///     ) -> Result<Pin<KBox<Self>>> {
+ ///         Err(ENODEV)
+@@ -234,20 +237,23 @@ pub trait Driver {
+     ///
+     /// Called when a new platform device is added or discovered.
+     /// Implementers should attempt to initialize the device here.
+-    fn probe(dev: &mut Device, id_info: &Self::IdInfo) -> Result<Pin<KBox<Self>>>;
++    fn probe(dev: &Device<device::Core>, id_info: &Self::IdInfo) -> Result<Pin<KBox<Self>>>;
+ }
+ /// The PCI device representation.
+ ///
+-/// A PCI device is based on an always reference counted `device:Device` instance. Cloning a PCI
+-/// device, hence, also increments the base device' reference count.
++/// This structure represents the Rust abstraction for a C `struct pci_dev`. The implementation
++/// abstracts the usage of an already existing C `struct pci_dev` within Rust code that we get
++/// passed from the C side.
+ ///
+ /// # Invariants
+ ///
+-/// `Device` hold a valid reference of `ARef<device::Device>` whose underlying `struct device` is a
+-/// member of a `struct pci_dev`.
+-#[derive(Clone)]
+-pub struct Device(ARef<device::Device>);
++/// A [`Device`] instance represents a valid `struct device` created by the C portion of the kernel.
++#[repr(transparent)]
++pub struct Device<Ctx: device::DeviceContext = device::Normal>(
++    Opaque<bindings::pci_dev>,
++    PhantomData<Ctx>,
++);
+ /// A PCI BAR to perform I/O-Operations on.
+ ///
+@@ -256,13 +262,13 @@ pub struct Device(ARef<device::Device>);
+ /// `Bar` always holds an `IoRaw` inststance that holds a valid pointer to the start of the I/O
+ /// memory mapped PCI bar and its size.
+ pub struct Bar<const SIZE: usize = 0> {
+-    pdev: Device,
++    pdev: ARef<Device>,
+     io: IoRaw<SIZE>,
+     num: i32,
+ }
+ impl<const SIZE: usize> Bar<SIZE> {
+-    fn new(pdev: Device, num: u32, name: &CStr) -> Result<Self> {
++    fn new(pdev: &Device, num: u32, name: &CStr) -> Result<Self> {
+         let len = pdev.resource_len(num)?;
+         if len == 0 {
+             return Err(ENOMEM);
+@@ -300,12 +306,16 @@ impl<const SIZE: usize> Bar<SIZE> {
+                 // `pdev` is valid by the invariants of `Device`.
+                 // `ioptr` is guaranteed to be the start of a valid I/O mapped memory region.
+                 // `num` is checked for validity by a previous call to `Device::resource_len`.
+-                unsafe { Self::do_release(&pdev, ioptr, num) };
++                unsafe { Self::do_release(pdev, ioptr, num) };
+                 return Err(err);
+             }
+         };
+-        Ok(Bar { pdev, io, num })
++        Ok(Bar {
++            pdev: pdev.into(),
++            io,
++            num,
++        })
+     }
+     /// # Safety
+@@ -351,20 +361,8 @@ impl<const SIZE: usize> Deref for Bar<SIZE> {
+ }
+ impl Device {
+-    /// Create a PCI Device instance from an existing `device::Device`.
+-    ///
+-    /// # Safety
+-    ///
+-    /// `dev` must be an `ARef<device::Device>` whose underlying `bindings::device` is a member of
+-    /// a `bindings::pci_dev`.
+-    pub unsafe fn from_dev(dev: ARef<device::Device>) -> Self {
+-        Self(dev)
+-    }
+-
+     fn as_raw(&self) -> *mut bindings::pci_dev {
+-        // SAFETY: By the type invariant `self.0.as_raw` is a pointer to the `struct device`
+-        // embedded in `struct pci_dev`.
+-        unsafe { container_of!(self.0.as_raw(), bindings::pci_dev, dev) as _ }
++        self.0.get()
+     }
+     /// Returns the PCI vendor ID.
+@@ -379,18 +377,6 @@ impl Device {
+         unsafe { (*self.as_raw()).device }
+     }
+-    /// Enable memory resources for this device.
+-    pub fn enable_device_mem(&self) -> Result {
+-        // SAFETY: `self.as_raw` is guaranteed to be a pointer to a valid `struct pci_dev`.
+-        to_result(unsafe { bindings::pci_enable_device_mem(self.as_raw()) })
+-    }
+-
+-    /// Enable bus-mastering for this device.
+-    pub fn set_master(&self) {
+-        // SAFETY: `self.as_raw` is guaranteed to be a pointer to a valid `struct pci_dev`.
+-        unsafe { bindings::pci_set_master(self.as_raw()) };
+-    }
+-
+     /// Returns the size of the given PCI bar resource.
+     pub fn resource_len(&self, bar: u32) -> Result<bindings::resource_size_t> {
+         if !Bar::index_is_valid(bar) {
+@@ -410,7 +396,7 @@ impl Device {
+         bar: u32,
+         name: &CStr,
+     ) -> Result<Devres<Bar<SIZE>>> {
+-        let bar = Bar::<SIZE>::new(self.clone(), bar, name)?;
++        let bar = Bar::<SIZE>::new(self, bar, name)?;
+         let devres = Devres::new(self.as_ref(), bar, GFP_KERNEL)?;
+         Ok(devres)
+@@ -422,8 +408,60 @@ impl Device {
+     }
+ }
++impl Device<device::Core> {
++    /// Enable memory resources for this device.
++    pub fn enable_device_mem(&self) -> Result {
++        // SAFETY: `self.as_raw` is guaranteed to be a pointer to a valid `struct pci_dev`.
++        to_result(unsafe { bindings::pci_enable_device_mem(self.as_raw()) })
++    }
++
++    /// Enable bus-mastering for this device.
++    pub fn set_master(&self) {
++        // SAFETY: `self.as_raw` is guaranteed to be a pointer to a valid `struct pci_dev`.
++        unsafe { bindings::pci_set_master(self.as_raw()) };
++    }
++}
++
++impl Deref for Device<device::Core> {
++    type Target = Device;
++
++    fn deref(&self) -> &Self::Target {
++        let ptr: *const Self = self;
++
++        // CAST: `Device<Ctx>` is a transparent wrapper of `Opaque<bindings::pci_dev>`.
++        let ptr = ptr.cast::<Device>();
++
++        // SAFETY: `ptr` was derived from `&self`.
++        unsafe { &*ptr }
++    }
++}
++
++impl From<&Device<device::Core>> for ARef<Device> {
++    fn from(dev: &Device<device::Core>) -> Self {
++        (&**dev).into()
++    }
++}
++
++// SAFETY: Instances of `Device` are always reference-counted.
++unsafe impl crate::types::AlwaysRefCounted for Device {
++    fn inc_ref(&self) {
++        // SAFETY: The existence of a shared reference guarantees that the refcount is non-zero.
++        unsafe { bindings::pci_dev_get(self.as_raw()) };
++    }
++
++    unsafe fn dec_ref(obj: NonNull<Self>) {
++        // SAFETY: The safety requirements guarantee that the refcount is non-zero.
++        unsafe { bindings::pci_dev_put(obj.cast().as_ptr()) }
++    }
++}
++
+ impl AsRef<device::Device> for Device {
+     fn as_ref(&self) -> &device::Device {
+-        &self.0
++        // SAFETY: By the type invariant of `Self`, `self.as_raw()` is a pointer to a valid
++        // `struct pci_dev`.
++        let dev = unsafe { addr_of_mut!((*self.as_raw()).dev) };
++
++        // SAFETY: `dev` points to a valid `struct device`.
++        unsafe { device::Device::as_ref(dev) }
+     }
+ }
+diff --git a/samples/rust/rust_driver_pci.rs b/samples/rust/rust_driver_pci.rs
+index 1fb6e44f33951..4f14e63f323e9 100644
+--- a/samples/rust/rust_driver_pci.rs
++++ b/samples/rust/rust_driver_pci.rs
+@@ -4,7 +4,7 @@
+ //!
+ //! To make this driver probe, QEMU must be run with `-device pci-testdev`.
+-use kernel::{bindings, c_str, devres::Devres, pci, prelude::*};
++use kernel::{bindings, c_str, device::Core, devres::Devres, pci, prelude::*, types::ARef};
+ struct Regs;
+@@ -26,7 +26,7 @@ impl TestIndex {
+ }
+ struct SampleDriver {
+-    pdev: pci::Device,
++    pdev: ARef<pci::Device>,
+     bar: Devres<Bar0>,
+ }
+@@ -62,7 +62,7 @@ impl pci::Driver for SampleDriver {
+     const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;
+-    fn probe(pdev: &mut pci::Device, info: &Self::IdInfo) -> Result<Pin<KBox<Self>>> {
++    fn probe(pdev: &pci::Device<Core>, info: &Self::IdInfo) -> Result<Pin<KBox<Self>>> {
+         dev_dbg!(
+             pdev.as_ref(),
+             "Probe Rust PCI driver sample (PCI ID: 0x{:x}, 0x{:x}).\n",
+@@ -77,7 +77,7 @@ impl pci::Driver for SampleDriver {
+         let drvdata = KBox::new(
+             Self {
+-                pdev: pdev.clone(),
++                pdev: pdev.into(),
+                 bar,
+             },
+             GFP_KERNEL,
+-- 
+2.39.5
+
diff --git a/queue-6.14/rust-pci-use-to_result-in-enable_device_mem.patch b/queue-6.14/rust-pci-use-to_result-in-enable_device_mem.patch
new file mode 100644 (file)
index 0000000..37febc1
--- /dev/null
@@ -0,0 +1,44 @@
+From f6a539ed57d190c8990587d7db7b3ec06ec6bb0e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Mar 2025 17:09:04 +0100
+Subject: rust: pci: use to_result() in enable_device_mem()
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+[ Upstream commit d1f6d6c537d488b1a8f04091c7751124985a0ab9 ]
+
+Simplify enable_device_mem() by using to_result() to handle the return
+value of the corresponding FFI call.
+
+Reviewed-by: Benno Lossin <benno.lossin@proton.me>
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Acked-by: Boqun Feng <boqun.feng@gmail.com>
+Link: https://lore.kernel.org/r/20250314160932.100165-2-dakr@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 7b948a2af6b5 ("rust: pci: fix unrestricted &mut pci::Device")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ rust/kernel/pci.rs | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs
+index 4c98b5b9aa1e9..386484dcf36eb 100644
+--- a/rust/kernel/pci.rs
++++ b/rust/kernel/pci.rs
+@@ -382,12 +382,7 @@ impl Device {
+     /// Enable memory resources for this device.
+     pub fn enable_device_mem(&self) -> Result {
+         // SAFETY: `self.as_raw` is guaranteed to be a pointer to a valid `struct pci_dev`.
+-        let ret = unsafe { bindings::pci_enable_device_mem(self.as_raw()) };
+-        if ret != 0 {
+-            Err(Error::from_errno(ret))
+-        } else {
+-            Ok(())
+-        }
++        to_result(unsafe { bindings::pci_enable_device_mem(self.as_raw()) })
+     }
+     /// Enable bus-mastering for this device.
+-- 
+2.39.5
+
diff --git a/queue-6.14/rust-platform-fix-unrestricted-mut-platform-device.patch b/queue-6.14/rust-platform-fix-unrestricted-mut-platform-device.patch
new file mode 100644 (file)
index 0000000..3b009cd
--- /dev/null
@@ -0,0 +1,245 @@
+From 818139a93eb0e8f6bc0f874ae474ab674e419b6a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Mar 2025 17:09:07 +0100
+Subject: rust: platform: fix unrestricted &mut platform::Device
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+[ Upstream commit 4d320e30ee04c25c660eca2bb33e846ebb71a79a ]
+
+As by now, platform::Device is implemented as:
+
+       #[derive(Clone)]
+       pub struct Device(ARef<device::Device>);
+
+This may be convenient, but has the implication that drivers can call
+device methods that require a mutable reference concurrently at any
+point of time.
+
+Instead define platform::Device as
+
+       pub struct Device<Ctx: DeviceContext = Normal>(
+               Opaque<bindings::platform_dev>,
+               PhantomData<Ctx>,
+       );
+
+and manually implement the AlwaysRefCounted trait.
+
+With this we can implement methods that should only be called from
+bus callbacks (such as probe()) for platform::Device<Core>. Consequently,
+we make this type accessible in bus callbacks only.
+
+Arbitrary references taken by the driver are still of type
+ARef<platform::Device> and hence don't provide access to methods that are
+reserved for bus callbacks.
+
+Fixes: 683a63befc73 ("rust: platform: add basic platform device / driver abstractions")
+Reviewed-by: Benno Lossin <benno.lossin@proton.me>
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Acked-by: Boqun Feng <boqun.feng@gmail.com>
+Link: https://lore.kernel.org/r/20250314160932.100165-5-dakr@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ rust/kernel/platform.rs              | 95 +++++++++++++++++++---------
+ samples/rust/rust_driver_platform.rs | 11 ++--
+ 2 files changed, 72 insertions(+), 34 deletions(-)
+
+diff --git a/rust/kernel/platform.rs b/rust/kernel/platform.rs
+index 50e6b04218132..c77c9f2e9aea1 100644
+--- a/rust/kernel/platform.rs
++++ b/rust/kernel/platform.rs
+@@ -5,7 +5,7 @@
+ //! C header: [`include/linux/platform_device.h`](srctree/include/linux/platform_device.h)
+ use crate::{
+-    bindings, container_of, device, driver,
++    bindings, device, driver,
+     error::{to_result, Result},
+     of,
+     prelude::*,
+@@ -14,7 +14,11 @@ use crate::{
+     ThisModule,
+ };
+-use core::ptr::addr_of_mut;
++use core::{
++    marker::PhantomData,
++    ops::Deref,
++    ptr::{addr_of_mut, NonNull},
++};
+ /// An adapter for the registration of platform drivers.
+ pub struct Adapter<T: Driver>(T);
+@@ -54,14 +58,14 @@ unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> {
+ impl<T: Driver + 'static> Adapter<T> {
+     extern "C" fn probe_callback(pdev: *mut bindings::platform_device) -> kernel::ffi::c_int {
+-        // SAFETY: The platform bus only ever calls the probe callback with a valid `pdev`.
+-        let dev = unsafe { device::Device::get_device(addr_of_mut!((*pdev).dev)) };
+-        // SAFETY: `dev` is guaranteed to be embedded in a valid `struct platform_device` by the
+-        // call above.
+-        let mut pdev = unsafe { Device::from_dev(dev) };
++        // SAFETY: The platform bus only ever calls the probe callback with a valid pointer to a
++        // `struct platform_device`.
++        //
++        // INVARIANT: `pdev` is valid for the duration of `probe_callback()`.
++        let pdev = unsafe { &*pdev.cast::<Device<device::Core>>() };
+         let info = <Self as driver::Adapter>::id_info(pdev.as_ref());
+-        match T::probe(&mut pdev, info) {
++        match T::probe(pdev, info) {
+             Ok(data) => {
+                 // Let the `struct platform_device` own a reference of the driver's private data.
+                 // SAFETY: By the type invariant `pdev.as_raw` returns a valid pointer to a
+@@ -120,7 +124,7 @@ macro_rules! module_platform_driver {
+ /// # Example
+ ///
+ ///```
+-/// # use kernel::{bindings, c_str, of, platform};
++/// # use kernel::{bindings, c_str, device::Core, of, platform};
+ ///
+ /// struct MyDriver;
+ ///
+@@ -138,7 +142,7 @@ macro_rules! module_platform_driver {
+ ///     const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
+ ///
+ ///     fn probe(
+-///         _pdev: &mut platform::Device,
++///         _pdev: &platform::Device<Core>,
+ ///         _id_info: Option<&Self::IdInfo>,
+ ///     ) -> Result<Pin<KBox<Self>>> {
+ ///         Err(ENODEV)
+@@ -160,41 +164,72 @@ pub trait Driver {
+     ///
+     /// Called when a new platform device is added or discovered.
+     /// Implementers should attempt to initialize the device here.
+-    fn probe(dev: &mut Device, id_info: Option<&Self::IdInfo>) -> Result<Pin<KBox<Self>>>;
++    fn probe(dev: &Device<device::Core>, id_info: Option<&Self::IdInfo>)
++        -> Result<Pin<KBox<Self>>>;
+ }
+ /// The platform device representation.
+ ///
+-/// A platform device is based on an always reference counted `device:Device` instance. Cloning a
+-/// platform device, hence, also increments the base device' reference count.
++/// This structure represents the Rust abstraction for a C `struct platform_device`. The
++/// implementation abstracts the usage of an already existing C `struct platform_device` within Rust
++/// code that we get passed from the C side.
+ ///
+ /// # Invariants
+ ///
+-/// `Device` holds a valid reference of `ARef<device::Device>` whose underlying `struct device` is a
+-/// member of a `struct platform_device`.
+-#[derive(Clone)]
+-pub struct Device(ARef<device::Device>);
++/// A [`Device`] instance represents a valid `struct platform_device` created by the C portion of
++/// the kernel.
++#[repr(transparent)]
++pub struct Device<Ctx: device::DeviceContext = device::Normal>(
++    Opaque<bindings::platform_device>,
++    PhantomData<Ctx>,
++);
+ impl Device {
+-    /// Convert a raw kernel device into a `Device`
+-    ///
+-    /// # Safety
+-    ///
+-    /// `dev` must be an `Aref<device::Device>` whose underlying `bindings::device` is a member of a
+-    /// `bindings::platform_device`.
+-    unsafe fn from_dev(dev: ARef<device::Device>) -> Self {
+-        Self(dev)
++    fn as_raw(&self) -> *mut bindings::platform_device {
++        self.0.get()
+     }
++}
+-    fn as_raw(&self) -> *mut bindings::platform_device {
+-        // SAFETY: By the type invariant `self.0.as_raw` is a pointer to the `struct device`
+-        // embedded in `struct platform_device`.
+-        unsafe { container_of!(self.0.as_raw(), bindings::platform_device, dev) }.cast_mut()
++impl Deref for Device<device::Core> {
++    type Target = Device;
++
++    fn deref(&self) -> &Self::Target {
++        let ptr: *const Self = self;
++
++        // CAST: `Device<Ctx>` is a transparent wrapper of `Opaque<bindings::platform_device>`.
++        let ptr = ptr.cast::<Device>();
++
++        // SAFETY: `ptr` was derived from `&self`.
++        unsafe { &*ptr }
++    }
++}
++
++impl From<&Device<device::Core>> for ARef<Device> {
++    fn from(dev: &Device<device::Core>) -> Self {
++        (&**dev).into()
++    }
++}
++
++// SAFETY: Instances of `Device` are always reference-counted.
++unsafe impl crate::types::AlwaysRefCounted for Device {
++    fn inc_ref(&self) {
++        // SAFETY: The existence of a shared reference guarantees that the refcount is non-zero.
++        unsafe { bindings::get_device(self.as_ref().as_raw()) };
++    }
++
++    unsafe fn dec_ref(obj: NonNull<Self>) {
++        // SAFETY: The safety requirements guarantee that the refcount is non-zero.
++        unsafe { bindings::platform_device_put(obj.cast().as_ptr()) }
+     }
+ }
+ impl AsRef<device::Device> for Device {
+     fn as_ref(&self) -> &device::Device {
+-        &self.0
++        // SAFETY: By the type invariant of `Self`, `self.as_raw()` is a pointer to a valid
++        // `struct platform_device`.
++        let dev = unsafe { addr_of_mut!((*self.as_raw()).dev) };
++
++        // SAFETY: `dev` points to a valid `struct device`.
++        unsafe { device::Device::as_ref(dev) }
+     }
+ }
+diff --git a/samples/rust/rust_driver_platform.rs b/samples/rust/rust_driver_platform.rs
+index 8120609e29402..9bb66db0a4f43 100644
+--- a/samples/rust/rust_driver_platform.rs
++++ b/samples/rust/rust_driver_platform.rs
+@@ -2,10 +2,10 @@
+ //! Rust Platform driver sample.
+-use kernel::{c_str, of, platform, prelude::*};
++use kernel::{c_str, device::Core, of, platform, prelude::*, types::ARef};
+ struct SampleDriver {
+-    pdev: platform::Device,
++    pdev: ARef<platform::Device>,
+ }
+ struct Info(u32);
+@@ -21,14 +21,17 @@ impl platform::Driver for SampleDriver {
+     type IdInfo = Info;
+     const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
+-    fn probe(pdev: &mut platform::Device, info: Option<&Self::IdInfo>) -> Result<Pin<KBox<Self>>> {
++    fn probe(
++        pdev: &platform::Device<Core>,
++        info: Option<&Self::IdInfo>,
++    ) -> Result<Pin<KBox<Self>>> {
+         dev_dbg!(pdev.as_ref(), "Probe Rust Platform driver sample.\n");
+         if let Some(info) = info {
+             dev_info!(pdev.as_ref(), "Probed with info: '{}'.\n", info.0);
+         }
+-        let drvdata = KBox::new(Self { pdev: pdev.clone() }, GFP_KERNEL)?;
++        let drvdata = KBox::new(Self { pdev: pdev.into() }, GFP_KERNEL)?;
+         Ok(drvdata.into())
+     }
+-- 
+2.39.5
+
diff --git a/queue-6.14/rwonce-fix-crash-by-removing-read_once-for-unaligned.patch b/queue-6.14/rwonce-fix-crash-by-removing-read_once-for-unaligned.patch
new file mode 100644 (file)
index 0000000..539aa6d
--- /dev/null
@@ -0,0 +1,50 @@
+From 465750d3aab3a885afbbe5cbd7150bd52ae7ea3a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Mar 2025 22:04:36 +0100
+Subject: rwonce: fix crash by removing READ_ONCE() for unaligned read
+
+From: Jann Horn <jannh@google.com>
+
+[ Upstream commit 47a60391ae0ed04ffbb9bd8dcd94ad9d08b41288 ]
+
+When arm64 is built with LTO, it upgrades READ_ONCE() to ldar / ldapr
+(load-acquire) to avoid issues that can be caused by the compiler
+optimizing away implicit address dependencies.
+
+Unlike plain loads, these load-acquire instructions actually require an
+aligned address.
+
+For now, fix it by removing the READ_ONCE() that the buggy commit
+introduced.
+
+Fixes: ece69af2ede1 ("rwonce: handle KCSAN like KASAN in read_word_at_a_time()")
+Reported-by: Nathan Chancellor <nathan@kernel.org>
+Closes: https://lore.kernel.org/r/20250326203926.GA10484@ax162
+Signed-off-by: Jann Horn <jannh@google.com>
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/asm-generic/rwonce.h | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/include/asm-generic/rwonce.h b/include/asm-generic/rwonce.h
+index e9f2b84d2338c..52b969c7cef93 100644
+--- a/include/asm-generic/rwonce.h
++++ b/include/asm-generic/rwonce.h
+@@ -86,7 +86,12 @@ unsigned long read_word_at_a_time(const void *addr)
+       kasan_check_read(addr, 1);
+       kcsan_check_read(addr, 1);
+-      return READ_ONCE(*(unsigned long *)addr);
++      /*
++       * This load can race with concurrent stores to out-of-bounds memory,
++       * but READ_ONCE() can't be used because it requires higher alignment
++       * than plain loads in arm64 builds with LTO.
++       */
++      return *(unsigned long *)addr;
+ }
+ #endif /* __ASSEMBLY__ */
+-- 
+2.39.5
+
diff --git a/queue-6.14/rwonce-handle-kcsan-like-kasan-in-read_word_at_a_tim.patch b/queue-6.14/rwonce-handle-kcsan-like-kasan-in-read_word_at_a_tim.patch
new file mode 100644 (file)
index 0000000..219eff8
--- /dev/null
@@ -0,0 +1,64 @@
+From b5c082982b69836ef3951ad22ce59abd18edcbf9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Mar 2025 17:01:34 +0100
+Subject: rwonce: handle KCSAN like KASAN in read_word_at_a_time()
+
+From: Jann Horn <jannh@google.com>
+
+[ Upstream commit ece69af2ede103e190ffdfccd9f9ec850606ab5e ]
+
+read_word_at_a_time() is allowed to read out of bounds by straddling the
+end of an allocation (and the caller is expected to then mask off
+out-of-bounds data). This works as long as the caller guarantees that the
+access won't hit a pagefault (either by ensuring that addr is aligned or by
+explicitly checking where the next page boundary is).
+
+Such out-of-bounds data could include things like KASAN redzones, adjacent
+allocations that are concurrently written to, or simply an adjacent struct
+field that is concurrently updated. KCSAN should ignore racy reads of OOB
+data that is not actually used, just like KASAN, so (similar to the code
+above) change read_word_at_a_time() to use __no_sanitize_or_inline instead
+of __no_kasan_or_inline, and explicitly inform KCSAN that we're reading
+the first byte.
+
+We do have an instrument_read() helper that calls into both KASAN and
+KCSAN, but I'm instead open-coding that here to avoid having to pull the
+entire instrumented.h header into rwonce.h.
+
+Also, since this read can be racy by design, we should technically do
+READ_ONCE(), so add that.
+
+Fixes: dfd402a4c4ba ("kcsan: Add Kernel Concurrency Sanitizer infrastructure")
+Signed-off-by: Jann Horn <jannh@google.com>
+Acked-by: Arnd Bergmann <arnd@arndb.de>
+Acked-by: Marco Elver <elver@google.com>
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/asm-generic/rwonce.h | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/include/asm-generic/rwonce.h b/include/asm-generic/rwonce.h
+index 8d0a6280e9824..e9f2b84d2338c 100644
+--- a/include/asm-generic/rwonce.h
++++ b/include/asm-generic/rwonce.h
+@@ -79,11 +79,14 @@ unsigned long __read_once_word_nocheck(const void *addr)
+       (typeof(x))__read_once_word_nocheck(&(x));                      \
+ })
+-static __no_kasan_or_inline
++static __no_sanitize_or_inline
+ unsigned long read_word_at_a_time(const void *addr)
+ {
++      /* open-coded instrument_read(addr, 1) */
+       kasan_check_read(addr, 1);
+-      return *(unsigned long *)addr;
++      kcsan_check_read(addr, 1);
++
++      return READ_ONCE(*(unsigned long *)addr);
+ }
+ #endif /* __ASSEMBLY__ */
+-- 
+2.39.5
+
diff --git a/queue-6.14/s390-entry-fix-setting-_cif_mcck_guest-with-lowcore-.patch b/queue-6.14/s390-entry-fix-setting-_cif_mcck_guest-with-lowcore-.patch
new file mode 100644 (file)
index 0000000..57c8285
--- /dev/null
@@ -0,0 +1,39 @@
+From e78432cc22292c4b182d0e4873259364a7a97d37 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Mar 2025 13:25:38 +0100
+Subject: s390/entry: Fix setting _CIF_MCCK_GUEST with lowcore relocation
+
+From: Sven Schnelle <svens@linux.ibm.com>
+
+[ Upstream commit 121df45b37a1016ee6828c2ca3ba825f3e18a8c1 ]
+
+When lowcore relocation is enabled, the machine check handler doesn't
+use the lowcore address when setting _CIF_MCCK_GUEST. Fix this by
+adding the missing base register.
+
+Fixes: 0001b7bbc53a ("s390/entry: Make mchk_int_handler() ready for lowcore relocation")
+Reported-by: Heiko Carstens <hca@linux.ibm.com>
+Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/kernel/entry.S | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
+index 4cc3408c4dacf..88e09a650d2df 100644
+--- a/arch/s390/kernel/entry.S
++++ b/arch/s390/kernel/entry.S
+@@ -467,7 +467,7 @@ SYM_CODE_START(mcck_int_handler)
+       clgrjl  %r9,%r14, 4f
+       larl    %r14,.Lsie_leave
+       clgrjhe %r9,%r14, 4f
+-      lg      %r10,__LC_PCPU
++      lg      %r10,__LC_PCPU(%r13)
+       oi      __PCPU_FLAGS+7(%r10), _CIF_MCCK_GUEST
+ 4:    BPENTER __SF_SIE_FLAGS(%r15),_TIF_ISOLATE_BP_GUEST
+       SIEEXIT __SF_SIE_CONTROL(%r15),%r13
+-- 
+2.39.5
+
diff --git a/queue-6.14/s390-remove-ioremap_wt-and-pgprot_writethrough.patch b/queue-6.14/s390-remove-ioremap_wt-and-pgprot_writethrough.patch
new file mode 100644 (file)
index 0000000..34f47ef
--- /dev/null
@@ -0,0 +1,89 @@
+From 5404ece582ee25065fbbd6bbb6003807e2a14854 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Feb 2025 12:51:48 +0100
+Subject: s390: Remove ioremap_wt() and pgprot_writethrough()
+
+From: Niklas Schnelle <schnelle@linux.ibm.com>
+
+[ Upstream commit c94bff63e49302d4ce36502a85a2710a67332a4f ]
+
+It turns out that while s390 architecture calls its memory-I/O mapping
+variants write-through and write-back the implementation of ioremap_wt()
+and pgprot_writethrough() does not match Linux notion of ioremap_wt().
+
+In particular Linux expects ioremap_wt() to be weaker still than
+ioremap_wc(), allowing not just gathering and re-ordering but also reads
+to be served from cache. Instead s390's implementation is equivalent to
+normal ioremap() while its ioremap_wc() allows re-ordering.
+
+Note that there are no known users of ioremap_wt() on s390 and the
+resulting behavior is in line with asm-generic defining ioremap_wt() as
+ioremap(), if undefined, so no breakage is expected.
+
+As s390 does not have a mapping type matching the Linux notion of
+ioremap_wt() and pgprot_writethrough(), simply drop them and rely on the
+asm-generic fallbacks instead.
+
+Fixes: b02002cc4c0f ("s390/pci: Implement ioremap_wc/prot() with MIO")
+Fixes: b43b3fff042d ("s390: mm: convert to GENERIC_IOREMAP")
+Acked-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/include/asm/io.h      |  2 --
+ arch/s390/include/asm/pgtable.h |  3 ---
+ arch/s390/mm/pgtable.c          | 10 ----------
+ 3 files changed, 15 deletions(-)
+
+diff --git a/arch/s390/include/asm/io.h b/arch/s390/include/asm/io.h
+index fc9933a743d69..251e0372ccbd0 100644
+--- a/arch/s390/include/asm/io.h
++++ b/arch/s390/include/asm/io.h
+@@ -34,8 +34,6 @@ void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr);
+ #define ioremap_wc(addr, size)  \
+       ioremap_prot((addr), (size), pgprot_val(pgprot_writecombine(PAGE_KERNEL)))
+-#define ioremap_wt(addr, size)  \
+-      ioremap_prot((addr), (size), pgprot_val(pgprot_writethrough(PAGE_KERNEL)))
+ static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
+ {
+diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
+index 3ca5af4cfe432..2467e521e1c0f 100644
+--- a/arch/s390/include/asm/pgtable.h
++++ b/arch/s390/include/asm/pgtable.h
+@@ -1402,9 +1402,6 @@ void gmap_pmdp_idte_global(struct mm_struct *mm, unsigned long vmaddr);
+ #define pgprot_writecombine   pgprot_writecombine
+ pgprot_t pgprot_writecombine(pgprot_t prot);
+-#define pgprot_writethrough   pgprot_writethrough
+-pgprot_t pgprot_writethrough(pgprot_t prot);
+-
+ #define PFN_PTE_SHIFT         PAGE_SHIFT
+ /*
+diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
+index f05e62e037c28..a248764ad9586 100644
+--- a/arch/s390/mm/pgtable.c
++++ b/arch/s390/mm/pgtable.c
+@@ -34,16 +34,6 @@ pgprot_t pgprot_writecombine(pgprot_t prot)
+ }
+ EXPORT_SYMBOL_GPL(pgprot_writecombine);
+-pgprot_t pgprot_writethrough(pgprot_t prot)
+-{
+-      /*
+-       * mio_wb_bit_mask may be set on a different CPU, but it is only set
+-       * once at init and only read afterwards.
+-       */
+-      return __pgprot(pgprot_val(prot) & ~mio_wb_bit_mask);
+-}
+-EXPORT_SYMBOL_GPL(pgprot_writethrough);
+-
+ static inline void ptep_ipte_local(struct mm_struct *mm, unsigned long addr,
+                                  pte_t *ptep, int nodat)
+ {
+-- 
+2.39.5
+
diff --git a/queue-6.14/samples-bpf-fix-broken-vmlinux-path-for-vmlinux_btf.patch b/queue-6.14/samples-bpf-fix-broken-vmlinux-path-for-vmlinux_btf.patch
new file mode 100644 (file)
index 0000000..c5b3849
--- /dev/null
@@ -0,0 +1,45 @@
+From 482fb096daffe338832010c3126f7785936e238b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Feb 2025 02:55:05 -0600
+Subject: samples/bpf: Fix broken vmlinux path for VMLINUX_BTF
+
+From: Jinghao Jia <jinghao7@illinois.edu>
+
+[ Upstream commit 94f53edc64e19640b5245721cd6d0c4a84f52587 ]
+
+Commit 13b25489b6f8 ("kbuild: change working directory to external
+module directory with M=") changed kbuild working directory of bpf
+sample programs to samples/bpf, which broke the vmlinux path for
+VMLINUX_BTF, as the Makefiles assume the current work directory to be
+the kernel output directory and use a relative path (i.e., ./vmlinux):
+
+  Makefile:316: *** Cannot find a vmlinux for VMLINUX_BTF at any of "  /path/to/linux/samples/bpf/vmlinux", build the kernel or set VMLINUX_BTF like "VMLINUX_BTF=/sys/kernel/btf/vmlinux" or VMLINUX_H variable.  Stop.
+
+Correctly refer to the kernel output directory using $(objtree).
+
+Fixes: 13b25489b6f8 ("kbuild: change working directory to external module directory with M=")
+Signed-off-by: Jinghao Jia <jinghao7@illinois.edu>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Tested-by: Ruowen Qin <ruqin@redhat.com>
+Link: https://lore.kernel.org/bpf/20250203085506.220297-3-jinghao7@illinois.edu
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ samples/bpf/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
+index dd9944a97b7e6..5b632635e00dd 100644
+--- a/samples/bpf/Makefile
++++ b/samples/bpf/Makefile
+@@ -307,7 +307,7 @@ $(obj)/$(TRACE_HELPERS): TPROGS_CFLAGS := $(TPROGS_CFLAGS) -D__must_check=
+ VMLINUX_BTF_PATHS ?= $(abspath $(if $(O),$(O)/vmlinux))                               \
+                    $(abspath $(if $(KBUILD_OUTPUT),$(KBUILD_OUTPUT)/vmlinux)) \
+-                   $(abspath ./vmlinux)
++                   $(abspath $(objtree)/vmlinux)
+ VMLINUX_BTF ?= $(abspath $(firstword $(wildcard $(VMLINUX_BTF_PATHS))))
+ $(obj)/vmlinux.h: $(VMLINUX_BTF) $(BPFTOOL)
+-- 
+2.39.5
+
diff --git a/queue-6.14/sched-cancel-the-slice-protection-of-the-idle-entity.patch b/queue-6.14/sched-cancel-the-slice-protection-of-the-idle-entity.patch
new file mode 100644 (file)
index 0000000..105af89
--- /dev/null
@@ -0,0 +1,122 @@
+From fac3662d5fac40de36333ecf9874d63686a82da6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Feb 2025 16:08:52 +0800
+Subject: sched: Cancel the slice protection of the idle entity
+
+From: zihan zhou <15645113830zzh@gmail.com>
+
+[ Upstream commit f553741ac8c0e467a3b873e305f34b902e50b86d ]
+
+A wakeup non-idle entity should preempt idle entity at any time,
+but because of the slice protection of the idle entity, the non-idle
+entity has to wait, so just cancel it.
+
+This patch is aimed at minimizing the impact of SCHED_IDLE on
+SCHED_NORMAL. For example, a task with SCHED_IDLE policy that sleeps for
+1s and then runs for 3 ms, running cyclictest on the same cpu, has a
+maximum latency of 3 ms, which is caused by the slice protection of the
+idle entity. It is unreasonable. With this patch, the cyclictest latency
+under the same conditions is basically the same on the cpu with idle
+processes and on empty cpu.
+
+[peterz: add helpers]
+Fixes: 63304558ba5d ("sched/eevdf: Curb wakeup-preemption")
+Signed-off-by: zihan zhou <15645113830zzh@gmail.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Vincent Guittot <vincent.guittot@linaro.org>
+Tested-by: Vincent Guittot <vincent.guittot@linaro.org>
+Link: https://lkml.kernel.org/r/20250208080850.16300-1-15645113830zzh@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/fair.c | 46 ++++++++++++++++++++++++++++++++-------------
+ 1 file changed, 33 insertions(+), 13 deletions(-)
+
+diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
+index c798d27952431..61a5d08ac3324 100644
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -883,6 +883,26 @@ struct sched_entity *__pick_first_entity(struct cfs_rq *cfs_rq)
+       return __node_2_se(left);
+ }
++/*
++ * HACK, stash a copy of deadline at the point of pick in vlag,
++ * which isn't used until dequeue.
++ */
++static inline void set_protect_slice(struct sched_entity *se)
++{
++      se->vlag = se->deadline;
++}
++
++static inline bool protect_slice(struct sched_entity *se)
++{
++      return se->vlag == se->deadline;
++}
++
++static inline void cancel_protect_slice(struct sched_entity *se)
++{
++      if (protect_slice(se))
++              se->vlag = se->deadline + 1;
++}
++
+ /*
+  * Earliest Eligible Virtual Deadline First
+  *
+@@ -919,11 +939,7 @@ static struct sched_entity *pick_eevdf(struct cfs_rq *cfs_rq)
+       if (curr && (!curr->on_rq || !entity_eligible(cfs_rq, curr)))
+               curr = NULL;
+-      /*
+-       * Once selected, run a task until it either becomes non-eligible or
+-       * until it gets a new slice. See the HACK in set_next_entity().
+-       */
+-      if (sched_feat(RUN_TO_PARITY) && curr && curr->vlag == curr->deadline)
++      if (sched_feat(RUN_TO_PARITY) && curr && protect_slice(curr))
+               return curr;
+       /* Pick the leftmost entity if it's eligible */
+@@ -5530,11 +5546,8 @@ set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
+               update_stats_wait_end_fair(cfs_rq, se);
+               __dequeue_entity(cfs_rq, se);
+               update_load_avg(cfs_rq, se, UPDATE_TG);
+-              /*
+-               * HACK, stash a copy of deadline at the point of pick in vlag,
+-               * which isn't used until dequeue.
+-               */
+-              se->vlag = se->deadline;
++
++              set_protect_slice(se);
+       }
+       update_stats_curr_start(cfs_rq, se);
+@@ -8783,8 +8796,15 @@ static void check_preempt_wakeup_fair(struct rq *rq, struct task_struct *p, int
+        * Preempt an idle entity in favor of a non-idle entity (and don't preempt
+        * in the inverse case).
+        */
+-      if (cse_is_idle && !pse_is_idle)
++      if (cse_is_idle && !pse_is_idle) {
++              /*
++               * When non-idle entity preempt an idle entity,
++               * don't give idle entity slice protection.
++               */
++              cancel_protect_slice(se);
+               goto preempt;
++      }
++
+       if (cse_is_idle != pse_is_idle)
+               return;
+@@ -8803,8 +8823,8 @@ static void check_preempt_wakeup_fair(struct rq *rq, struct task_struct *p, int
+        * Note that even if @p does not turn out to be the most eligible
+        * task at this moment, current's slice protection will be lost.
+        */
+-      if (do_preempt_short(cfs_rq, pse, se) && se->vlag == se->deadline)
+-              se->vlag = se->deadline + 1;
++      if (do_preempt_short(cfs_rq, pse, se))
++              cancel_protect_slice(se);
+       /*
+        * If @p has become the most eligible task, force preemption.
+-- 
+2.39.5
+
diff --git a/queue-6.14/sched-deadline-generalize-unique-visiting-of-root-do.patch b/queue-6.14/sched-deadline-generalize-unique-visiting-of-root-do.patch
new file mode 100644 (file)
index 0000000..32fa11b
--- /dev/null
@@ -0,0 +1,178 @@
+From 7be559207be61d4a61078dffcde5dcb68135cfd3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Mar 2025 18:05:46 +0100
+Subject: sched/deadline: Generalize unique visiting of root domains
+
+From: Juri Lelli <juri.lelli@redhat.com>
+
+[ Upstream commit 45007c6fb5860cf63556a9cadc87c8984927e23d ]
+
+Bandwidth checks and updates that work on root domains currently employ
+a cookie mechanism for efficiency. This mechanism is very much tied to
+when root domains are first created and initialized.
+
+Generalize the cookie mechanism so that it can be used also later at
+runtime while updating root domains. Also, additionally guard it with
+sched_domains_mutex, since domains need to be stable while updating them
+(and it will be required for further dynamic changes).
+
+Fixes: 53916d5fd3c0 ("sched/deadline: Check bandwidth overflow earlier for hotplug")
+Reported-by: Jon Hunter <jonathanh@nvidia.com>
+Signed-off-by: Juri Lelli <juri.lelli@redhat.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Valentin Schneider <vschneid@redhat.com>
+Reviewed-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
+Tested-by: Waiman Long <longman@redhat.com>
+Tested-by: Jon Hunter <jonathanh@nvidia.com>
+Tested-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
+Link: https://lore.kernel.org/r/Z9MQaiXPvEeW_v7x@jlelli-thinkpadt14gen4.remote.csb
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/sched/deadline.h |  3 +++
+ kernel/sched/deadline.c        | 23 +++++++++++++----------
+ kernel/sched/rt.c              |  2 ++
+ kernel/sched/sched.h           |  2 +-
+ kernel/sched/topology.c        |  2 +-
+ 5 files changed, 20 insertions(+), 12 deletions(-)
+
+diff --git a/include/linux/sched/deadline.h b/include/linux/sched/deadline.h
+index 3a912ab42bb55..6ec578600b24c 100644
+--- a/include/linux/sched/deadline.h
++++ b/include/linux/sched/deadline.h
+@@ -37,4 +37,7 @@ extern void dl_clear_root_domain(struct root_domain *rd);
+ #endif /* CONFIG_SMP */
++extern u64 dl_cookie;
++extern bool dl_bw_visited(int cpu, u64 cookie);
++
+ #endif /* _LINUX_SCHED_DEADLINE_H */
+diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
+index 1a041c1fc0d1e..3e05032e9e0eb 100644
+--- a/kernel/sched/deadline.c
++++ b/kernel/sched/deadline.c
+@@ -166,14 +166,14 @@ static inline unsigned long dl_bw_capacity(int i)
+       }
+ }
+-static inline bool dl_bw_visited(int cpu, u64 gen)
++static inline bool dl_bw_visited(int cpu, u64 cookie)
+ {
+       struct root_domain *rd = cpu_rq(cpu)->rd;
+-      if (rd->visit_gen == gen)
++      if (rd->visit_cookie == cookie)
+               return true;
+-      rd->visit_gen = gen;
++      rd->visit_cookie = cookie;
+       return false;
+ }
+@@ -207,7 +207,7 @@ static inline unsigned long dl_bw_capacity(int i)
+       return SCHED_CAPACITY_SCALE;
+ }
+-static inline bool dl_bw_visited(int cpu, u64 gen)
++static inline bool dl_bw_visited(int cpu, u64 cookie)
+ {
+       return false;
+ }
+@@ -3171,15 +3171,18 @@ DEFINE_SCHED_CLASS(dl) = {
+ #endif
+ };
+-/* Used for dl_bw check and update, used under sched_rt_handler()::mutex */
+-static u64 dl_generation;
++/*
++ * Used for dl_bw check and update, used under sched_rt_handler()::mutex and
++ * sched_domains_mutex.
++ */
++u64 dl_cookie;
+ int sched_dl_global_validate(void)
+ {
+       u64 runtime = global_rt_runtime();
+       u64 period = global_rt_period();
+       u64 new_bw = to_ratio(period, runtime);
+-      u64 gen = ++dl_generation;
++      u64 cookie = ++dl_cookie;
+       struct dl_bw *dl_b;
+       int cpu, cpus, ret = 0;
+       unsigned long flags;
+@@ -3192,7 +3195,7 @@ int sched_dl_global_validate(void)
+       for_each_online_cpu(cpu) {
+               rcu_read_lock_sched();
+-              if (dl_bw_visited(cpu, gen))
++              if (dl_bw_visited(cpu, cookie))
+                       goto next;
+               dl_b = dl_bw_of(cpu);
+@@ -3229,7 +3232,7 @@ static void init_dl_rq_bw_ratio(struct dl_rq *dl_rq)
+ void sched_dl_do_global(void)
+ {
+       u64 new_bw = -1;
+-      u64 gen = ++dl_generation;
++      u64 cookie = ++dl_cookie;
+       struct dl_bw *dl_b;
+       int cpu;
+       unsigned long flags;
+@@ -3240,7 +3243,7 @@ void sched_dl_do_global(void)
+       for_each_possible_cpu(cpu) {
+               rcu_read_lock_sched();
+-              if (dl_bw_visited(cpu, gen)) {
++              if (dl_bw_visited(cpu, cookie)) {
+                       rcu_read_unlock_sched();
+                       continue;
+               }
+diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
+index 4b8e33c615b12..8cebe71d2bb16 100644
+--- a/kernel/sched/rt.c
++++ b/kernel/sched/rt.c
+@@ -2910,6 +2910,7 @@ static int sched_rt_handler(const struct ctl_table *table, int write, void *buff
+       int ret;
+       mutex_lock(&mutex);
++      sched_domains_mutex_lock();
+       old_period = sysctl_sched_rt_period;
+       old_runtime = sysctl_sched_rt_runtime;
+@@ -2936,6 +2937,7 @@ static int sched_rt_handler(const struct ctl_table *table, int write, void *buff
+               sysctl_sched_rt_period = old_period;
+               sysctl_sched_rt_runtime = old_runtime;
+       }
++      sched_domains_mutex_unlock();
+       mutex_unlock(&mutex);
+       return ret;
+diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
+index 023b844159c94..1aa65a0ac5864 100644
+--- a/kernel/sched/sched.h
++++ b/kernel/sched/sched.h
+@@ -998,7 +998,7 @@ struct root_domain {
+        * Also, some corner cases, like 'wrap around' is dangerous, but given
+        * that u64 is 'big enough'. So that shouldn't be a concern.
+        */
+-      u64 visit_gen;
++      u64 visit_cookie;
+ #ifdef HAVE_RT_PUSH_IPI
+       /*
+diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c
+index 296ff2acfd321..44093339761c9 100644
+--- a/kernel/sched/topology.c
++++ b/kernel/sched/topology.c
+@@ -568,7 +568,7 @@ static int init_rootdomain(struct root_domain *rd)
+       rd->rto_push_work = IRQ_WORK_INIT_HARD(rto_push_irq_work_func);
+ #endif
+-      rd->visit_gen = 0;
++      rd->visit_cookie = 0;
+       init_dl_bw(&rd->dl_bw);
+       if (cpudl_init(&rd->cpudl) != 0)
+               goto free_rto_mask;
+-- 
+2.39.5
+
diff --git a/queue-6.14/sched-deadline-ignore-special-tasks-when-rebuilding-.patch b/queue-6.14/sched-deadline-ignore-special-tasks-when-rebuilding-.patch
new file mode 100644 (file)
index 0000000..6fbd2c0
--- /dev/null
@@ -0,0 +1,46 @@
+From 9d244e2638d26f426e9628839e421a02108119d1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Mar 2025 18:00:04 +0100
+Subject: sched/deadline: Ignore special tasks when rebuilding domains
+
+From: Juri Lelli <juri.lelli@redhat.com>
+
+[ Upstream commit f6147af176eaa4027b692fdbb1a0a60dfaa1e9b6 ]
+
+SCHED_DEADLINE special tasks get a fake bandwidth that is only used to
+make sure sleeping and priority inheritance 'work', but it is ignored
+for runtime enforcement and admission control.
+
+Be consistent with it also when rebuilding root domains.
+
+Fixes: 53916d5fd3c0 ("sched/deadline: Check bandwidth overflow earlier for hotplug")
+Reported-by: Jon Hunter <jonathanh@nvidia.com>
+Signed-off-by: Juri Lelli <juri.lelli@redhat.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Valentin Schneider <vschneid@redhat.com>
+Reviewed-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
+Tested-by: Waiman Long <longman@redhat.com>
+Tested-by: Jon Hunter <jonathanh@nvidia.com>
+Tested-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
+Link: https://lore.kernel.org/r/20250313170011.357208-2-juri.lelli@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/deadline.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
+index ff4df16b5186d..1a041c1fc0d1e 100644
+--- a/kernel/sched/deadline.c
++++ b/kernel/sched/deadline.c
+@@ -2956,7 +2956,7 @@ void dl_add_task_root_domain(struct task_struct *p)
+       struct dl_bw *dl_b;
+       raw_spin_lock_irqsave(&p->pi_lock, rf.flags);
+-      if (!dl_task(p)) {
++      if (!dl_task(p) || dl_entity_is_special(&p->dl)) {
+               raw_spin_unlock_irqrestore(&p->pi_lock, rf.flags);
+               return;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/sched-deadline-rebuild-root-domain-accounting-after-.patch b/queue-6.14/sched-deadline-rebuild-root-domain-accounting-after-.patch
new file mode 100644 (file)
index 0000000..b5d079f
--- /dev/null
@@ -0,0 +1,234 @@
+From 5c8caaa13f60a2e10b381b6490882b573c07b9ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Mar 2025 18:10:21 +0100
+Subject: sched/deadline: Rebuild root domain accounting after every update
+
+From: Juri Lelli <juri.lelli@redhat.com>
+
+[ Upstream commit 2ff899e3516437354204423ef0a94994717b8e6a ]
+
+Rebuilding of root domains accounting information (total_bw) is
+currently broken on some cases, e.g. suspend/resume on aarch64. Problem
+is that the way we keep track of domain changes and try to add bandwidth
+back is convoluted and fragile.
+
+Fix it by simplify things by making sure bandwidth accounting is cleared
+and completely restored after root domains changes (after root domains
+are again stable).
+
+To be sure we always call dl_rebuild_rd_accounting while holding
+cpuset_mutex we also add cpuset_reset_sched_domains() wrapper.
+
+Fixes: 53916d5fd3c0 ("sched/deadline: Check bandwidth overflow earlier for hotplug")
+Reported-by: Jon Hunter <jonathanh@nvidia.com>
+Co-developed-by: Waiman Long <llong@redhat.com>
+Signed-off-by: Waiman Long <llong@redhat.com>
+Signed-off-by: Juri Lelli <juri.lelli@redhat.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
+Tested-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
+Link: https://lore.kernel.org/r/Z9MRfeJKJUOyUSto@jlelli-thinkpadt14gen4.remote.csb
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/cpuset.h         |  6 ++++++
+ include/linux/sched/deadline.h |  1 +
+ include/linux/sched/topology.h |  2 ++
+ kernel/cgroup/cpuset.c         | 23 ++++++++++++++++-------
+ kernel/sched/core.c            |  4 ++--
+ kernel/sched/deadline.c        | 16 ++++++++++------
+ kernel/sched/topology.c        |  1 +
+ 7 files changed, 38 insertions(+), 15 deletions(-)
+
+diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h
+index 835e7b793f6a3..17cc90d900f96 100644
+--- a/include/linux/cpuset.h
++++ b/include/linux/cpuset.h
+@@ -128,6 +128,7 @@ extern bool current_cpuset_is_being_rebound(void);
+ extern void rebuild_sched_domains(void);
+ extern void cpuset_print_current_mems_allowed(void);
++extern void cpuset_reset_sched_domains(void);
+ /*
+  * read_mems_allowed_begin is required when making decisions involving
+@@ -264,6 +265,11 @@ static inline void rebuild_sched_domains(void)
+       partition_sched_domains(1, NULL, NULL);
+ }
++static inline void cpuset_reset_sched_domains(void)
++{
++      partition_sched_domains(1, NULL, NULL);
++}
++
+ static inline void cpuset_print_current_mems_allowed(void)
+ {
+ }
+diff --git a/include/linux/sched/deadline.h b/include/linux/sched/deadline.h
+index 6ec578600b24c..f9aabbc9d22ef 100644
+--- a/include/linux/sched/deadline.h
++++ b/include/linux/sched/deadline.h
+@@ -34,6 +34,7 @@ static inline bool dl_time_before(u64 a, u64 b)
+ struct root_domain;
+ extern void dl_add_task_root_domain(struct task_struct *p);
+ extern void dl_clear_root_domain(struct root_domain *rd);
++extern void dl_clear_root_domain_cpu(int cpu);
+ #endif /* CONFIG_SMP */
+diff --git a/include/linux/sched/topology.h b/include/linux/sched/topology.h
+index 7f3dbafe18177..1622232bd08b9 100644
+--- a/include/linux/sched/topology.h
++++ b/include/linux/sched/topology.h
+@@ -166,6 +166,8 @@ static inline struct cpumask *sched_domain_span(struct sched_domain *sd)
+       return to_cpumask(sd->span);
+ }
++extern void dl_rebuild_rd_accounting(void);
++
+ extern void partition_sched_domains_locked(int ndoms_new,
+                                          cpumask_var_t doms_new[],
+                                          struct sched_domain_attr *dattr_new);
+diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
+index f87526edb2a46..1892dc8cd2119 100644
+--- a/kernel/cgroup/cpuset.c
++++ b/kernel/cgroup/cpuset.c
+@@ -954,10 +954,12 @@ static void dl_update_tasks_root_domain(struct cpuset *cs)
+       css_task_iter_end(&it);
+ }
+-static void dl_rebuild_rd_accounting(void)
++void dl_rebuild_rd_accounting(void)
+ {
+       struct cpuset *cs = NULL;
+       struct cgroup_subsys_state *pos_css;
++      int cpu;
++      u64 cookie = ++dl_cookie;
+       lockdep_assert_held(&cpuset_mutex);
+       lockdep_assert_cpus_held();
+@@ -965,11 +967,12 @@ static void dl_rebuild_rd_accounting(void)
+       rcu_read_lock();
+-      /*
+-       * Clear default root domain DL accounting, it will be computed again
+-       * if a task belongs to it.
+-       */
+-      dl_clear_root_domain(&def_root_domain);
++      for_each_possible_cpu(cpu) {
++              if (dl_bw_visited(cpu, cookie))
++                      continue;
++
++              dl_clear_root_domain_cpu(cpu);
++      }
+       cpuset_for_each_descendant_pre(cs, pos_css, &top_cpuset) {
+@@ -996,7 +999,6 @@ partition_and_rebuild_sched_domains(int ndoms_new, cpumask_var_t doms_new[],
+ {
+       sched_domains_mutex_lock();
+       partition_sched_domains_locked(ndoms_new, doms_new, dattr_new);
+-      dl_rebuild_rd_accounting();
+       sched_domains_mutex_unlock();
+ }
+@@ -1083,6 +1085,13 @@ void rebuild_sched_domains(void)
+       cpus_read_unlock();
+ }
++void cpuset_reset_sched_domains(void)
++{
++      mutex_lock(&cpuset_mutex);
++      partition_sched_domains(1, NULL, NULL);
++      mutex_unlock(&cpuset_mutex);
++}
++
+ /**
+  * cpuset_update_tasks_cpumask - Update the cpumasks of tasks in the cpuset.
+  * @cs: the cpuset in which each task's cpus_allowed mask needs to be changed
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index 8adf495491179..3c7c942c7c429 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -8183,7 +8183,7 @@ static void cpuset_cpu_active(void)
+                * operation in the resume sequence, just build a single sched
+                * domain, ignoring cpusets.
+                */
+-              partition_sched_domains(1, NULL, NULL);
++              cpuset_reset_sched_domains();
+               if (--num_cpus_frozen)
+                       return;
+               /*
+@@ -8202,7 +8202,7 @@ static void cpuset_cpu_inactive(unsigned int cpu)
+               cpuset_update_active_cpus();
+       } else {
+               num_cpus_frozen++;
+-              partition_sched_domains(1, NULL, NULL);
++              cpuset_reset_sched_domains();
+       }
+ }
+diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
+index 3e05032e9e0eb..5dca336cdd7ca 100644
+--- a/kernel/sched/deadline.c
++++ b/kernel/sched/deadline.c
+@@ -166,7 +166,7 @@ static inline unsigned long dl_bw_capacity(int i)
+       }
+ }
+-static inline bool dl_bw_visited(int cpu, u64 cookie)
++bool dl_bw_visited(int cpu, u64 cookie)
+ {
+       struct root_domain *rd = cpu_rq(cpu)->rd;
+@@ -207,7 +207,7 @@ static inline unsigned long dl_bw_capacity(int i)
+       return SCHED_CAPACITY_SCALE;
+ }
+-static inline bool dl_bw_visited(int cpu, u64 cookie)
++bool dl_bw_visited(int cpu, u64 cookie)
+ {
+       return false;
+ }
+@@ -2981,18 +2981,22 @@ void dl_clear_root_domain(struct root_domain *rd)
+       rd->dl_bw.total_bw = 0;
+       /*
+-       * dl_server bandwidth is only restored when CPUs are attached to root
+-       * domains (after domains are created or CPUs moved back to the
+-       * default root doamin).
++       * dl_servers are not tasks. Since dl_add_task_root_domain ignores
++       * them, we need to account for them here explicitly.
+        */
+       for_each_cpu(i, rd->span) {
+               struct sched_dl_entity *dl_se = &cpu_rq(i)->fair_server;
+               if (dl_server(dl_se) && cpu_active(i))
+-                      rd->dl_bw.total_bw += dl_se->dl_bw;
++                      __dl_add(&rd->dl_bw, dl_se->dl_bw, dl_bw_cpus(i));
+       }
+ }
++void dl_clear_root_domain_cpu(int cpu)
++{
++      dl_clear_root_domain(cpu_rq(cpu)->rd);
++}
++
+ #endif /* CONFIG_SMP */
+ static void switched_from_dl(struct rq *rq, struct task_struct *p)
+diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c
+index 44093339761c9..363ad268a25b0 100644
+--- a/kernel/sched/topology.c
++++ b/kernel/sched/topology.c
+@@ -2791,6 +2791,7 @@ void partition_sched_domains_locked(int ndoms_new, cpumask_var_t doms_new[],
+       ndoms_cur = ndoms_new;
+       update_sched_domain_debugfs();
++      dl_rebuild_rd_accounting();
+ }
+ /*
+-- 
+2.39.5
+
diff --git a/queue-6.14/sched-eevdf-force-propagating-min_slice-of-cfs_rq-wh.patch b/queue-6.14/sched-eevdf-force-propagating-min_slice-of-cfs_rq-wh.patch
new file mode 100644 (file)
index 0000000..6d642c2
--- /dev/null
@@ -0,0 +1,53 @@
+From 337aaaf9918909dcfe54fa9376be74b91a073f72 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Feb 2025 14:36:59 +0800
+Subject: sched/eevdf: Force propagating min_slice of cfs_rq when {en,de}queue
+ tasks
+
+From: Tianchen Ding <dtcccc@linux.alibaba.com>
+
+[ Upstream commit 563bc2161b94571ea425bbe2cf69fd38e24cdedf ]
+
+When a task is enqueued and its parent cgroup se is already on_rq, this
+parent cgroup se will not be enqueued again, and hence the root->min_slice
+leaves unchanged. The same issue happens when a task is dequeued and its
+parent cgroup se has other runnable entities, and the parent cgroup se
+will not be dequeued.
+
+Force propagating min_slice when se doesn't need to be enqueued or
+dequeued. Ensure the se hierarchy always get the latest min_slice.
+
+Fixes: aef6987d8954 ("sched/eevdf: Propagate min_slice up the cgroup hierarchy")
+Signed-off-by: Tianchen Ding <dtcccc@linux.alibaba.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/20250211063659.7180-1-dtcccc@linux.alibaba.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/fair.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
+index 61a5d08ac3324..89c7260103e18 100644
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -7004,6 +7004,8 @@ enqueue_task_fair(struct rq *rq, struct task_struct *p, int flags)
+               update_cfs_group(se);
+               se->slice = slice;
++              if (se != cfs_rq->curr)
++                      min_vruntime_cb_propagate(&se->run_node, NULL);
+               slice = cfs_rq_min_slice(cfs_rq);
+               cfs_rq->h_nr_runnable += h_nr_runnable;
+@@ -7133,6 +7135,8 @@ static int dequeue_entities(struct rq *rq, struct sched_entity *se, int flags)
+               update_cfs_group(se);
+               se->slice = slice;
++              if (se != cfs_rq->curr)
++                      min_vruntime_cb_propagate(&se->run_node, NULL);
+               slice = cfs_rq_min_slice(cfs_rq);
+               cfs_rq->h_nr_runnable -= h_nr_runnable;
+-- 
+2.39.5
+
diff --git a/queue-6.14/sched-smt-always-inline-sched_smt_active.patch b/queue-6.14/sched-smt-always-inline-sched_smt_active.patch
new file mode 100644 (file)
index 0000000..cc8d6da
--- /dev/null
@@ -0,0 +1,45 @@
+From b5ff0bfab76f41e654998f3b4caf98e757aeb617 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Mar 2025 21:26:44 -0700
+Subject: sched/smt: Always inline sched_smt_active()
+
+From: Josh Poimboeuf <jpoimboe@kernel.org>
+
+[ Upstream commit 09f37f2d7b21ff35b8b533f9ab8cfad2fe8f72f6 ]
+
+sched_smt_active() can be called from noinstr code, so it should always
+be inlined.  The CONFIG_SCHED_SMT version already has __always_inline.
+Do the same for its !CONFIG_SCHED_SMT counterpart.
+
+Fixes the following warning:
+
+  vmlinux.o: error: objtool: intel_idle_ibrs+0x13: call to sched_smt_active() leaves .noinstr.text section
+
+Fixes: 321a874a7ef8 ("sched/smt: Expose sched_smt_present static key")
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Link: https://lore.kernel.org/r/1d03907b0a247cf7fb5c1d518de378864f603060.1743481539.git.jpoimboe@kernel.org
+Closes: https://lore.kernel.org/r/202503311434.lyw2Tveh-lkp@intel.com/
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/sched/smt.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/linux/sched/smt.h b/include/linux/sched/smt.h
+index fb1e295e7e63e..166b19af956f8 100644
+--- a/include/linux/sched/smt.h
++++ b/include/linux/sched/smt.h
+@@ -12,7 +12,7 @@ static __always_inline bool sched_smt_active(void)
+       return static_branch_likely(&sched_smt_present);
+ }
+ #else
+-static inline bool sched_smt_active(void) { return false; }
++static __always_inline bool sched_smt_active(void) { return false; }
+ #endif
+ void arch_smt_update(void);
+-- 
+2.39.5
+
diff --git a/queue-6.14/sched-topology-wrappers-for-sched_domains_mutex.patch b/queue-6.14/sched-topology-wrappers-for-sched_domains_mutex.patch
new file mode 100644 (file)
index 0000000..fe94dfd
--- /dev/null
@@ -0,0 +1,147 @@
+From 4f582264c66c2b62705ee4bf376c4226718dd3bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Mar 2025 18:03:32 +0100
+Subject: sched/topology: Wrappers for sched_domains_mutex
+
+From: Juri Lelli <juri.lelli@redhat.com>
+
+[ Upstream commit 56209334dda1832c0a919e1d74768c6d0f3b2ca9 ]
+
+Create wrappers for sched_domains_mutex so that it can transparently be
+used on both CONFIG_SMP and !CONFIG_SMP, as some function will need to
+do.
+
+Fixes: 53916d5fd3c0 ("sched/deadline: Check bandwidth overflow earlier for hotplug")
+Reported-by: Jon Hunter <jonathanh@nvidia.com>
+Signed-off-by: Juri Lelli <juri.lelli@redhat.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Valentin Schneider <vschneid@redhat.com>
+Reviewed-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
+Tested-by: Waiman Long <longman@redhat.com>
+Tested-by: Jon Hunter <jonathanh@nvidia.com>
+Tested-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
+Link: https://lore.kernel.org/r/Z9MP5Oq9RB8jBs3y@jlelli-thinkpadt14gen4.remote.csb
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/sched.h   |  5 +++++
+ kernel/cgroup/cpuset.c  |  4 ++--
+ kernel/sched/core.c     |  4 ++--
+ kernel/sched/debug.c    |  8 ++++----
+ kernel/sched/topology.c | 12 ++++++++++--
+ 5 files changed, 23 insertions(+), 10 deletions(-)
+
+diff --git a/include/linux/sched.h b/include/linux/sched.h
+index b13c9545d5d67..6e5c38718ff56 100644
+--- a/include/linux/sched.h
++++ b/include/linux/sched.h
+@@ -383,6 +383,11 @@ enum uclamp_id {
+ #ifdef CONFIG_SMP
+ extern struct root_domain def_root_domain;
+ extern struct mutex sched_domains_mutex;
++extern void sched_domains_mutex_lock(void);
++extern void sched_domains_mutex_unlock(void);
++#else
++static inline void sched_domains_mutex_lock(void) { }
++static inline void sched_domains_mutex_unlock(void) { }
+ #endif
+ struct sched_param {
+diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
+index 0f910c828973a..f87526edb2a46 100644
+--- a/kernel/cgroup/cpuset.c
++++ b/kernel/cgroup/cpuset.c
+@@ -994,10 +994,10 @@ static void
+ partition_and_rebuild_sched_domains(int ndoms_new, cpumask_var_t doms_new[],
+                                   struct sched_domain_attr *dattr_new)
+ {
+-      mutex_lock(&sched_domains_mutex);
++      sched_domains_mutex_lock();
+       partition_sched_domains_locked(ndoms_new, doms_new, dattr_new);
+       dl_rebuild_rd_accounting();
+-      mutex_unlock(&sched_domains_mutex);
++      sched_domains_mutex_unlock();
+ }
+ /*
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index 042351c7afce7..8adf495491179 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -8424,9 +8424,9 @@ void __init sched_init_smp(void)
+        * CPU masks are stable and all blatant races in the below code cannot
+        * happen.
+        */
+-      mutex_lock(&sched_domains_mutex);
++      sched_domains_mutex_lock();
+       sched_init_domains(cpu_active_mask);
+-      mutex_unlock(&sched_domains_mutex);
++      sched_domains_mutex_unlock();
+       /* Move init over to a non-isolated CPU */
+       if (set_cpus_allowed_ptr(current, housekeeping_cpumask(HK_TYPE_DOMAIN)) < 0)
+diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c
+index ef047add7f9e6..a0893a483d35d 100644
+--- a/kernel/sched/debug.c
++++ b/kernel/sched/debug.c
+@@ -292,7 +292,7 @@ static ssize_t sched_verbose_write(struct file *filp, const char __user *ubuf,
+       bool orig;
+       cpus_read_lock();
+-      mutex_lock(&sched_domains_mutex);
++      sched_domains_mutex_lock();
+       orig = sched_debug_verbose;
+       result = debugfs_write_file_bool(filp, ubuf, cnt, ppos);
+@@ -304,7 +304,7 @@ static ssize_t sched_verbose_write(struct file *filp, const char __user *ubuf,
+               sd_dentry = NULL;
+       }
+-      mutex_unlock(&sched_domains_mutex);
++      sched_domains_mutex_unlock();
+       cpus_read_unlock();
+       return result;
+@@ -515,9 +515,9 @@ static __init int sched_init_debug(void)
+       debugfs_create_u32("migration_cost_ns", 0644, debugfs_sched, &sysctl_sched_migration_cost);
+       debugfs_create_u32("nr_migrate", 0644, debugfs_sched, &sysctl_sched_nr_migrate);
+-      mutex_lock(&sched_domains_mutex);
++      sched_domains_mutex_lock();
+       update_sched_domain_debugfs();
+-      mutex_unlock(&sched_domains_mutex);
++      sched_domains_mutex_unlock();
+ #endif
+ #ifdef CONFIG_NUMA_BALANCING
+diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c
+index c49aea8c10254..296ff2acfd321 100644
+--- a/kernel/sched/topology.c
++++ b/kernel/sched/topology.c
+@@ -6,6 +6,14 @@
+ #include <linux/bsearch.h>
+ DEFINE_MUTEX(sched_domains_mutex);
++void sched_domains_mutex_lock(void)
++{
++      mutex_lock(&sched_domains_mutex);
++}
++void sched_domains_mutex_unlock(void)
++{
++      mutex_unlock(&sched_domains_mutex);
++}
+ /* Protected by sched_domains_mutex: */
+ static cpumask_var_t sched_domains_tmpmask;
+@@ -2791,7 +2799,7 @@ void partition_sched_domains_locked(int ndoms_new, cpumask_var_t doms_new[],
+ void partition_sched_domains(int ndoms_new, cpumask_var_t doms_new[],
+                            struct sched_domain_attr *dattr_new)
+ {
+-      mutex_lock(&sched_domains_mutex);
++      sched_domains_mutex_lock();
+       partition_sched_domains_locked(ndoms_new, doms_new, dattr_new);
+-      mutex_unlock(&sched_domains_mutex);
++      sched_domains_mutex_unlock();
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/scripts-gdb-linux-symbols.py-address-changes-to-modu.patch b/queue-6.14/scripts-gdb-linux-symbols.py-address-changes-to-modu.patch
new file mode 100644 (file)
index 0000000..295dc1c
--- /dev/null
@@ -0,0 +1,76 @@
+From 8221cb6460dce0253cba437e959f740a01775ce0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Feb 2025 21:40:34 +0100
+Subject: scripts/gdb/linux/symbols.py: address changes to module_sect_attrs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Antonio Quartulli <antonio@mandelbit.com>
+
+[ Upstream commit e0349c46cb4fbbb507fa34476bd70f9c82bad359 ]
+
+When loading symbols from kernel modules we used to iterate
+from 0 to module_sect_attrs::nsections, in order to
+retrieve their name and address.
+
+However module_sect_attrs::nsections has been removed from
+the struct by a previous commit.
+
+Re-arrange the iteration by accessing all items in
+module_sect_attrs::grp::bin_attrs[] until NULL is found
+(it's a NULL terminated array).
+
+At the same time the symbol address cannot be extracted
+from module_sect_attrs::attrs[]::address anymore because
+it has also been deleted. Fetch it from
+module_sect_attrs::grp::bin_attrs[]::private as described
+in 4b2c11e4aaf7.
+
+Link: https://lkml.kernel.org/r/20250221204034.4430-1-antonio@mandelbit.com
+Fixes: d8959b947a8d ("module: sysfs: Drop member 'module_sect_attrs::nsections'")
+Fixes: 4b2c11e4aaf7 ("module: sysfs: Drop member 'module_sect_attr::address'")
+Signed-off-by: Antonio Quartulli <antonio@mandelbit.com>
+Reviewed-by: Jan Kiszka <jan.kiszka@siemens.com>
+Cc: Thomas Weißschuh <linux@weissschuh.net>
+Cc: Kieran Bingham <kbingham@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/gdb/linux/symbols.py | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/scripts/gdb/linux/symbols.py b/scripts/gdb/linux/symbols.py
+index f6c1b063775a7..15d76f7d8ebce 100644
+--- a/scripts/gdb/linux/symbols.py
++++ b/scripts/gdb/linux/symbols.py
+@@ -15,6 +15,7 @@ import gdb
+ import os
+ import re
++from itertools import count
+ from linux import modules, utils, constants
+@@ -95,10 +96,14 @@ lx-symbols command."""
+         except gdb.error:
+             return str(module_addr)
+-        attrs = sect_attrs['attrs']
+-        section_name_to_address = {
+-            attrs[n]['battr']['attr']['name'].string(): attrs[n]['address']
+-            for n in range(int(sect_attrs['nsections']))}
++        section_name_to_address = {}
++        for i in count():
++            # this is a NULL terminated array
++            if sect_attrs['grp']['bin_attrs'][i] == 0x0:
++                break
++
++            attr = sect_attrs['grp']['bin_attrs'][i].dereference()
++            section_name_to_address[attr['attr']['name'].string()] = attr['private']
+         textaddr = section_name_to_address.get(".text", module_addr)
+         args = []
+-- 
+2.39.5
+
diff --git a/queue-6.14/scsi-hisi_sas-fixed-failure-to-issue-vendor-specific.patch b/queue-6.14/scsi-hisi_sas-fixed-failure-to-issue-vendor-specific.patch
new file mode 100644 (file)
index 0000000..884d07c
--- /dev/null
@@ -0,0 +1,122 @@
+From ee438a3ecbec53b6bc4e1d6f9bdc5c14f951b6e5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Feb 2025 17:00:11 +0800
+Subject: scsi: hisi_sas: Fixed failure to issue vendor specific commands
+
+From: Xingui Yang <yangxingui@huawei.com>
+
+[ Upstream commit 750d4fbe2c20e65d764c70afe2c9e6cfa874b044 ]
+
+At present, we determine the protocol through the cmd type, but other cmd
+types, such as vendor-specific commands, default to the PIO protocol.  This
+strategy often causes the execution of different vendor-specific commands
+to fail. In fact, for these commands, a better way is to use the protocol
+configured by the command's tf to determine its protocol.
+
+Fixes: 6f2ff1a1311e ("hisi_sas: add v2 path to send ATA command")
+Signed-off-by: Xingui Yang <yangxingui@huawei.com>
+Link: https://lore.kernel.org/r/20250220090011.313848-1-liyihang9@huawei.com
+Reviewed-by: Yihang Li <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.h       |  3 +--
+ drivers/scsi/hisi_sas/hisi_sas_main.c  | 28 ++++++++++++++++++++++++--
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c |  4 +---
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c |  4 +---
+ 4 files changed, 29 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
+index 2d438d722d0b4..e17f5d8226bf2 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas.h
++++ b/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -633,8 +633,7 @@ extern struct dentry *hisi_sas_debugfs_dir;
+ extern void hisi_sas_stop_phys(struct hisi_hba *hisi_hba);
+ extern int hisi_sas_alloc(struct hisi_hba *hisi_hba);
+ extern void hisi_sas_free(struct hisi_hba *hisi_hba);
+-extern u8 hisi_sas_get_ata_protocol(struct host_to_dev_fis *fis,
+-                              int direction);
++extern u8 hisi_sas_get_ata_protocol(struct sas_task *task);
+ extern struct hisi_sas_port *to_hisi_sas_port(struct asd_sas_port *sas_port);
+ extern void hisi_sas_sata_done(struct sas_task *task,
+                           struct hisi_sas_slot *slot);
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index da4a2ed8ee863..3596414d970b2 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -21,8 +21,32 @@ struct hisi_sas_internal_abort_data {
+       bool rst_ha_timeout; /* reset the HA for timeout */
+ };
+-u8 hisi_sas_get_ata_protocol(struct host_to_dev_fis *fis, int direction)
++static u8 hisi_sas_get_ata_protocol_from_tf(struct ata_queued_cmd *qc)
+ {
++      if (!qc)
++              return HISI_SAS_SATA_PROTOCOL_PIO;
++
++      switch (qc->tf.protocol) {
++      case ATA_PROT_NODATA:
++              return HISI_SAS_SATA_PROTOCOL_NONDATA;
++      case ATA_PROT_PIO:
++              return HISI_SAS_SATA_PROTOCOL_PIO;
++      case ATA_PROT_DMA:
++              return HISI_SAS_SATA_PROTOCOL_DMA;
++      case ATA_PROT_NCQ_NODATA:
++      case ATA_PROT_NCQ:
++              return HISI_SAS_SATA_PROTOCOL_FPDMA;
++      default:
++              return HISI_SAS_SATA_PROTOCOL_PIO;
++      }
++}
++
++u8 hisi_sas_get_ata_protocol(struct sas_task *task)
++{
++      struct host_to_dev_fis *fis = &task->ata_task.fis;
++      struct ata_queued_cmd *qc = task->uldd_task;
++      int direction = task->data_dir;
++
+       switch (fis->command) {
+       case ATA_CMD_FPDMA_WRITE:
+       case ATA_CMD_FPDMA_READ:
+@@ -93,7 +117,7 @@ u8 hisi_sas_get_ata_protocol(struct host_to_dev_fis *fis, int direction)
+       {
+               if (direction == DMA_NONE)
+                       return HISI_SAS_SATA_PROTOCOL_NONDATA;
+-              return HISI_SAS_SATA_PROTOCOL_PIO;
++              return hisi_sas_get_ata_protocol_from_tf(qc);
+       }
+       }
+ }
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+index 71cd5b4450c2b..6e7f99fcc8247 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -2538,9 +2538,7 @@ static void prep_ata_v2_hw(struct hisi_hba *hisi_hba,
+                       (task->ata_task.fis.control & ATA_SRST))
+               dw1 |= 1 << CMD_HDR_RESET_OFF;
+-      dw1 |= (hisi_sas_get_ata_protocol(
+-              &task->ata_task.fis, task->data_dir))
+-              << CMD_HDR_FRAME_TYPE_OFF;
++      dw1 |= (hisi_sas_get_ata_protocol(task)) << CMD_HDR_FRAME_TYPE_OFF;
+       dw1 |= sas_dev->device_id << CMD_HDR_DEV_ID_OFF;
+       hdr->dw1 = cpu_to_le32(dw1);
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 48b95d9a79275..095bbf80c34ef 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -1456,9 +1456,7 @@ static void prep_ata_v3_hw(struct hisi_hba *hisi_hba,
+                       (task->ata_task.fis.control & ATA_SRST))
+               dw1 |= 1 << CMD_HDR_RESET_OFF;
+-      dw1 |= (hisi_sas_get_ata_protocol(
+-              &task->ata_task.fis, task->data_dir))
+-              << CMD_HDR_FRAME_TYPE_OFF;
++      dw1 |= (hisi_sas_get_ata_protocol(task)) << CMD_HDR_FRAME_TYPE_OFF;
+       dw1 |= sas_dev->device_id << CMD_HDR_DEV_ID_OFF;
+       if (FIS_CMD_IS_UNCONSTRAINED(task->ata_task.fis))
+-- 
+2.39.5
+
diff --git a/queue-6.14/scsi-mpi3mr-fix-locking-in-an-error-path.patch b/queue-6.14/scsi-mpi3mr-fix-locking-in-an-error-path.patch
new file mode 100644 (file)
index 0000000..5023afb
--- /dev/null
@@ -0,0 +1,48 @@
+From 70a9505c919497cfbe7342b507b298a6ac34207b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Feb 2025 12:39:35 -0800
+Subject: scsi: mpi3mr: Fix locking in an error path
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit c733741ae1c3a5927f72664b0d760d5f4c14f96b ]
+
+Make all error paths unlock rioc->bsg_cmds.mutex.
+
+This patch fixes the following Clang -Wthread-safety errors:
+
+drivers/scsi/mpi3mr/mpi3mr_app.c:2835:1: error: mutex 'mrioc->bsg_cmds.mutex' is not held on every path through here [-Werror,-Wthread-safety-analysis]
+ 2835 | }
+      | ^
+drivers/scsi/mpi3mr/mpi3mr_app.c:2332:6: note: mutex acquired here
+ 2332 |         if (mutex_lock_interruptible(&mrioc->bsg_cmds.mutex))
+      |             ^
+./include/linux/mutex.h:172:40: note: expanded from macro 'mutex_lock_interruptible'
+  172 | #define mutex_lock_interruptible(lock) mutex_lock_interruptible_nested(lock, 0)
+      |                                        ^
+
+Cc: Sathya Prakash <sathya.prakash@broadcom.com>
+Fixes: fb231d7deffb ("scsi: mpi3mr: Support for preallocation of SGL BSG data buffers part-2")
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Link: https://lore.kernel.org/r/20250210203936.2946494-2-bvanassche@acm.org
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/mpi3mr/mpi3mr_app.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/scsi/mpi3mr/mpi3mr_app.c b/drivers/scsi/mpi3mr/mpi3mr_app.c
+index 7589f48aebc80..f4b5813e6fc4c 100644
+--- a/drivers/scsi/mpi3mr/mpi3mr_app.c
++++ b/drivers/scsi/mpi3mr/mpi3mr_app.c
+@@ -2339,6 +2339,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
+       }
+       if (!mrioc->ioctl_sges_allocated) {
++              mutex_unlock(&mrioc->bsg_cmds.mutex);
+               dprint_bsg_err(mrioc, "%s: DMA memory was not allocated\n",
+                              __func__);
+               return -ENOMEM;
+-- 
+2.39.5
+
diff --git a/queue-6.14/scsi-mpt3sas-fix-a-locking-bug-in-an-error-path.patch b/queue-6.14/scsi-mpt3sas-fix-a-locking-bug-in-an-error-path.patch
new file mode 100644 (file)
index 0000000..e650d19
--- /dev/null
@@ -0,0 +1,94 @@
+From 43aa1bad7ca5aec22139a1d2c158dc9c984d417b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Feb 2025 12:39:36 -0800
+Subject: scsi: mpt3sas: Fix a locking bug in an error path
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit 38afcf0660f5c408ba6c2f0ba3a9729e0102fe2e ]
+
+Call mutex_unlock(&ioc->hostdiag_unlock_mutex) once from error paths
+instead of twice.
+
+This patch fixes the following Clang -Wthread-safety errors:
+
+drivers/scsi/mpt3sas/mpt3sas_base.c:8085:2: error: mutex 'ioc->hostdiag_unlock_mutex' is not held on every path through here [-Werror,-Wthread-safety-analysis]
+ 8085 |         pci_cfg_access_unlock(ioc->pdev);
+      |         ^
+drivers/scsi/mpt3sas/mpt3sas_base.c:8019:2: note: mutex acquired here
+ 8019 |         mutex_lock(&ioc->hostdiag_unlock_mutex);
+      |         ^
+./include/linux/mutex.h:171:26: note: expanded from macro 'mutex_lock'
+  171 | #define mutex_lock(lock) mutex_lock_nested(lock, 0)
+      |                          ^
+drivers/scsi/mpt3sas/mpt3sas_base.c:8085:2: error: mutex 'ioc->hostdiag_unlock_mutex' is not held on every path through here [-Werror,-Wthread-safety-analysis]
+ 8085 |         pci_cfg_access_unlock(ioc->pdev);
+      |         ^
+drivers/scsi/mpt3sas/mpt3sas_base.c:8019:2: note: mutex acquired here
+ 8019 |         mutex_lock(&ioc->hostdiag_unlock_mutex);
+      |         ^
+./include/linux/mutex.h:171:26: note: expanded from macro 'mutex_lock'
+  171 | #define mutex_lock(lock) mutex_lock_nested(lock, 0)
+      |                          ^
+drivers/scsi/mpt3sas/mpt3sas_base.c:8087:2: error: releasing mutex 'ioc->hostdiag_unlock_mutex' that was not held [-Werror,-Wthread-safety-analysis]
+ 8087 |         mutex_unlock(&ioc->hostdiag_unlock_mutex);
+      |         ^
+
+Cc: Ranjan Kumar <ranjan.kumar@broadcom.com>
+Fixes: c0767560b012 ("scsi: mpt3sas: Reload SBR without rebooting HBA")
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Link: https://lore.kernel.org/r/20250210203936.2946494-3-bvanassche@acm.org
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/mpt3sas/mpt3sas_base.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c
+index dc43cfa83088b..212e3b86bb817 100644
+--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
++++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
+@@ -8018,7 +8018,7 @@ _base_diag_reset(struct MPT3SAS_ADAPTER *ioc)
+       mutex_lock(&ioc->hostdiag_unlock_mutex);
+       if (mpt3sas_base_unlock_and_get_host_diagnostic(ioc, &host_diagnostic))
+-              goto out;
++              goto unlock;
+       hcb_size = ioc->base_readl(&ioc->chip->HCBSize);
+       drsprintk(ioc, ioc_info(ioc, "diag reset: issued\n"));
+@@ -8038,7 +8038,7 @@ _base_diag_reset(struct MPT3SAS_ADAPTER *ioc)
+                       ioc_info(ioc,
+                           "Invalid host diagnostic register value\n");
+                       _base_dump_reg_set(ioc);
+-                      goto out;
++                      goto unlock;
+               }
+               if (!(host_diagnostic & MPI2_DIAG_RESET_ADAPTER))
+                       break;
+@@ -8074,17 +8074,19 @@ _base_diag_reset(struct MPT3SAS_ADAPTER *ioc)
+               ioc_err(ioc, "%s: failed going to ready state (ioc_state=0x%x)\n",
+                       __func__, ioc_state);
+               _base_dump_reg_set(ioc);
+-              goto out;
++              goto fail;
+       }
+       pci_cfg_access_unlock(ioc->pdev);
+       ioc_info(ioc, "diag reset: SUCCESS\n");
+       return 0;
+- out:
++unlock:
++      mutex_unlock(&ioc->hostdiag_unlock_mutex);
++
++fail:
+       pci_cfg_access_unlock(ioc->pdev);
+       ioc_err(ioc, "diag reset: FAILED\n");
+-      mutex_unlock(&ioc->hostdiag_unlock_mutex);
+       return -EFAULT;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/scsi-mpt3sas-reduce-log-level-of-ignore_delay_remove.patch b/queue-6.14/scsi-mpt3sas-reduce-log-level-of-ignore_delay_remove.patch
new file mode 100644 (file)
index 0000000..b122487
--- /dev/null
@@ -0,0 +1,67 @@
+From 61cfed482212d298fbdd3ecfd0569fe2415d79b6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Jan 2025 18:16:40 +0100
+Subject: scsi: mpt3sas: Reduce log level of ignore_delay_remove message to
+ KERN_INFO
+
+From: Paul Menzel <pmenzel@molgen.mpg.de>
+
+[ Upstream commit fb27da6e06a0869d2e36255bb7e0b6102daf712f ]
+
+On several systems with Dell HBA controller Linux prints the warning below:
+
+    $ dmesg | grep -e "Linux version" -e "DMI: Dell"  -e "ignore_delay_remove"
+    [    0.000000] Linux version 6.12.11.mx64.479 (root@lucy.molgen.mpg.de) (gcc (GCC) 12.3.0, GNU ld (GNU Binutils) 2.41) #1 SMP PREEMPT_DYNAMIC Fri Jan 24 13:30:47 CET 2025
+    [    0.000000] DMI: Dell Inc. PowerEdge R7625/0M7YXP, BIOS 1.10.6 12/06/2024
+    [    9.386551] scsi 0:0:4:0: set ignore_delay_remove for handle(0x0012)
+
+A user does not know, what to do about it, and everything seems to work as
+expected. Therefore, remove the log level from warning to info.
+
+Device information:
+
+    $ dmesg | grep -e 0:4:0 -e '12)'
+    [    8.857606] mpt3sas_cm0: config page(0x00000000db0e4179) - dma(0xfd5f6000): size(512)
+    [    9.133856] scsi 0:0:0:0: SATA: handle(0x0017), sas_addr(0x3c0470e0d40cc20c), phy(12), device_name(0x5000039db8d2284b)
+    [    9.366341] mpt3sas_cm0: handle(0x12) sas_address(0x3c0570e0d40cc208) port_type(0x0)
+    [    9.378867] scsi 0:0:4:0: Enclosure         DP       BP_PSV           7.10 PQ: 0 ANSI: 7
+    [    9.386551] scsi 0:0:4:0: set ignore_delay_remove for handle(0x0012)
+    [    9.387465] scsi 0:0:4:0: SES: handle(0x0012), sas_addr(0x3c0570e0d40cc208), phy(17), device_name(0x3c0570e0d40cc208)
+    [    9.387465] scsi 0:0:4:0: enclosure logical id (0x3c0470e0d4092108), slot(8)
+    [    9.387465] scsi 0:0:4:0: enclosure level(0x0001), connector name( C0  )
+    [    9.390495] scsi 0:0:4:0: qdepth(1), tagged(0), scsi_level(8), cmd_que(0)
+    [    9.401700]  end_device-0:4: add: handle(0x0012), sas_addr(0x3c0570e0d40cc208)
+    [    9.471916] ses 0:0:4:0: Attached Enclosure device
+    [    9.480088] ses 0:0:4:0: Attached scsi generic sg4 type 13
+    $ lspci -nn -k -s 41:
+    41:00.0 Serial Attached SCSI controller [0107]: Broadcom / LSI Fusion-MPT 12GSAS/PCIe Secure SAS38xx [1000:00e6]
+       DeviceName: SL3 NonRAID
+       Subsystem: Dell HBA355i Front [1028:200c]
+       Kernel driver in use: mpt3sas
+
+Fixes: 30158dc9bbc9 ("mpt3sas: Never block the Enclosure device")
+Cc: Tomas Henzl <thenzl@redhat.com>
+Signed-off-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Link: https://lore.kernel.org/r/20250131171640.30721-1-pmenzel@molgen.mpg.de
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/mpt3sas/mpt3sas_scsih.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+index a456e5ec74d88..9c2d3178f3844 100644
+--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+@@ -2703,7 +2703,7 @@ scsih_sdev_configure(struct scsi_device *sdev, struct queue_limits *lim)
+               ssp_target = 1;
+               if (sas_device->device_info &
+                               MPI2_SAS_DEVICE_INFO_SEP) {
+-                      sdev_printk(KERN_WARNING, sdev,
++                      sdev_printk(KERN_INFO, sdev,
+                       "set ignore_delay_remove for handle(0x%04x)\n",
+                       sas_device_priv_data->sas_target->handle);
+                       sas_device_priv_data->ignore_delay_remove = 1;
+-- 
+2.39.5
+
diff --git a/queue-6.14/scsi-target-tcm_loop-fix-wrong-abort-tag.patch b/queue-6.14/scsi-target-tcm_loop-fix-wrong-abort-tag.patch
new file mode 100644 (file)
index 0000000..a390072
--- /dev/null
@@ -0,0 +1,50 @@
+From 8143e7517ed5442b9fbcca0c4e5e063b157e0ae9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Mar 2025 09:47:27 +0800
+Subject: scsi: target: tcm_loop: Fix wrong abort tag
+
+From: Guixin Liu <kanie@linux.alibaba.com>
+
+[ Upstream commit 1909b643034ef741af9f24a57ab735440c4b5d1a ]
+
+When the tcm_loop_nr_hw_queues is set to a value greater than 1, the
+tags of requests in the block layer are no longer unique. This may lead
+to erroneous aborting of commands with the same tag. The issue can be
+resolved by using blk_mq_unique_tag to generate globally unique
+identifiers by combining the hardware queue index and per-queue tags.
+
+Fixes: 6375f8908255 ("tcm_loop: Fixup tag handling")
+Signed-off-by: Guixin Liu <kanie@linux.alibaba.com>
+Link: https://lore.kernel.org/r/20250313014728.105849-1-kanie@linux.alibaba.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/target/loopback/tcm_loop.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
+index 761c511aea07c..c7b7da6297418 100644
+--- a/drivers/target/loopback/tcm_loop.c
++++ b/drivers/target/loopback/tcm_loop.c
+@@ -176,7 +176,7 @@ static int tcm_loop_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *sc)
+       memset(tl_cmd, 0, sizeof(*tl_cmd));
+       tl_cmd->sc = sc;
+-      tl_cmd->sc_cmd_tag = scsi_cmd_to_rq(sc)->tag;
++      tl_cmd->sc_cmd_tag = blk_mq_unique_tag(scsi_cmd_to_rq(sc));
+       tcm_loop_target_queue_cmd(tl_cmd);
+       return 0;
+@@ -242,7 +242,8 @@ static int tcm_loop_abort_task(struct scsi_cmnd *sc)
+       tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host);
+       tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id];
+       ret = tcm_loop_issue_tmr(tl_tpg, sc->device->lun,
+-                               scsi_cmd_to_rq(sc)->tag, TMR_ABORT_TASK);
++                               blk_mq_unique_tag(scsi_cmd_to_rq(sc)),
++                               TMR_ABORT_TASK);
+       return (ret == TMR_FUNCTION_COMPLETE) ? SUCCESS : FAILED;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/sctp-add-mutual-exclusion-in-proc_sctp_do_udp_port.patch b/queue-6.14/sctp-add-mutual-exclusion-in-proc_sctp_do_udp_port.patch
new file mode 100644 (file)
index 0000000..ae5440a
--- /dev/null
@@ -0,0 +1,80 @@
+From 438213eef0357721df99417477018c248293cf20 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Mar 2025 09:15:32 +0000
+Subject: sctp: add mutual exclusion in proc_sctp_do_udp_port()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 10206302af856791fbcc27a33ed3c3eb09b2793d ]
+
+We must serialize calls to sctp_udp_sock_stop() and sctp_udp_sock_start()
+or risk a crash as syzbot reported:
+
+Oops: general protection fault, probably for non-canonical address 0xdffffc000000000d: 0000 [#1] SMP KASAN PTI
+KASAN: null-ptr-deref in range [0x0000000000000068-0x000000000000006f]
+CPU: 1 UID: 0 PID: 6551 Comm: syz.1.44 Not tainted 6.14.0-syzkaller-g7f2ff7b62617 #0 PREEMPT(full)
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2025
+ RIP: 0010:kernel_sock_shutdown+0x47/0x70 net/socket.c:3653
+Call Trace:
+ <TASK>
+  udp_tunnel_sock_release+0x68/0x80 net/ipv4/udp_tunnel_core.c:181
+  sctp_udp_sock_stop+0x71/0x160 net/sctp/protocol.c:930
+  proc_sctp_do_udp_port+0x264/0x450 net/sctp/sysctl.c:553
+  proc_sys_call_handler+0x3d0/0x5b0 fs/proc/proc_sysctl.c:601
+  iter_file_splice_write+0x91c/0x1150 fs/splice.c:738
+  do_splice_from fs/splice.c:935 [inline]
+  direct_splice_actor+0x18f/0x6c0 fs/splice.c:1158
+  splice_direct_to_actor+0x342/0xa30 fs/splice.c:1102
+  do_splice_direct_actor fs/splice.c:1201 [inline]
+  do_splice_direct+0x174/0x240 fs/splice.c:1227
+  do_sendfile+0xafd/0xe50 fs/read_write.c:1368
+  __do_sys_sendfile64 fs/read_write.c:1429 [inline]
+  __se_sys_sendfile64 fs/read_write.c:1415 [inline]
+  __x64_sys_sendfile64+0x1d8/0x220 fs/read_write.c:1415
+  do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+
+Fixes: 046c052b475e ("sctp: enable udp tunneling socks")
+Reported-by: syzbot+fae49d997eb56fa7c74d@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/67ea5c01.050a0220.1547ec.012b.GAE@google.com/T/#u
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20250331091532.224982-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/sysctl.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
+index 8e1e97be4df79..ee3eac338a9de 100644
+--- a/net/sctp/sysctl.c
++++ b/net/sctp/sysctl.c
+@@ -525,6 +525,8 @@ static int proc_sctp_do_auth(const struct ctl_table *ctl, int write,
+       return ret;
+ }
++static DEFINE_MUTEX(sctp_sysctl_mutex);
++
+ static int proc_sctp_do_udp_port(const struct ctl_table *ctl, int write,
+                                void *buffer, size_t *lenp, loff_t *ppos)
+ {
+@@ -549,6 +551,7 @@ static int proc_sctp_do_udp_port(const struct ctl_table *ctl, int write,
+               if (new_value > max || new_value < min)
+                       return -EINVAL;
++              mutex_lock(&sctp_sysctl_mutex);
+               net->sctp.udp_port = new_value;
+               sctp_udp_sock_stop(net);
+               if (new_value) {
+@@ -561,6 +564,7 @@ static int proc_sctp_do_udp_port(const struct ctl_table *ctl, int write,
+               lock_sock(sk);
+               sctp_sk(sk)->udp_port = htons(net->sctp.udp_port);
+               release_sock(sk);
++              mutex_unlock(&sctp_sysctl_mutex);
+       }
+       return ret;
+-- 
+2.39.5
+
diff --git a/queue-6.14/seccomp-fix-the-__secure_computing-stub-for-have_arc.patch b/queue-6.14/seccomp-fix-the-__secure_computing-stub-for-have_arc.patch
new file mode 100644 (file)
index 0000000..5cfc09a
--- /dev/null
@@ -0,0 +1,98 @@
+From 37d91ef961b9373cb069e6e91ceb27d8366a4825 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Jan 2025 16:03:07 +0100
+Subject: seccomp: fix the __secure_computing() stub for
+ !HAVE_ARCH_SECCOMP_FILTER
+
+From: Oleg Nesterov <oleg@redhat.com>
+
+[ Upstream commit b37778bec82ba82058912ca069881397197cd3d5 ]
+
+Depending on CONFIG_HAVE_ARCH_SECCOMP_FILTER, __secure_computing(NULL)
+will crash or not. This is not consistent/safe, especially considering
+that after the previous change __secure_computing(sd) is always called
+with sd == NULL.
+
+Fortunately, if CONFIG_HAVE_ARCH_SECCOMP_FILTER=n, __secure_computing()
+has no callers, these architectures use secure_computing_strict(). Yet
+it make sense make __secure_computing(NULL) safe in this case.
+
+Note also that with this change we can unexport secure_computing_strict()
+and change the current callers to use __secure_computing(NULL).
+
+Fixes: 8cf8dfceebda ("seccomp: Stub for !HAVE_ARCH_SECCOMP_FILTER")
+Signed-off-by: Oleg Nesterov <oleg@redhat.com>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Link: https://lore.kernel.org/r/20250128150307.GA15325@redhat.com
+Signed-off-by: Kees Cook <kees@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/seccomp.h |  8 ++------
+ kernel/seccomp.c        | 14 ++++++++++----
+ 2 files changed, 12 insertions(+), 10 deletions(-)
+
+diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
+index e45531455d3bb..d55949071c30e 100644
+--- a/include/linux/seccomp.h
++++ b/include/linux/seccomp.h
+@@ -22,8 +22,9 @@
+ #include <linux/atomic.h>
+ #include <asm/seccomp.h>
+-#ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER
+ extern int __secure_computing(const struct seccomp_data *sd);
++
++#ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER
+ static inline int secure_computing(void)
+ {
+       if (unlikely(test_syscall_work(SECCOMP)))
+@@ -32,11 +33,6 @@ static inline int secure_computing(void)
+ }
+ #else
+ extern void secure_computing_strict(int this_syscall);
+-static inline int __secure_computing(const struct seccomp_data *sd)
+-{
+-      secure_computing_strict(sd->nr);
+-      return 0;
+-}
+ #endif
+ extern long prctl_get_seccomp(void);
+diff --git a/kernel/seccomp.c b/kernel/seccomp.c
+index 7bbb408431ebc..3231f63d93d89 100644
+--- a/kernel/seccomp.c
++++ b/kernel/seccomp.c
+@@ -29,13 +29,11 @@
+ #include <linux/syscalls.h>
+ #include <linux/sysctl.h>
++#include <asm/syscall.h>
++
+ /* Not exposed in headers: strictly internal use only. */
+ #define SECCOMP_MODE_DEAD     (SECCOMP_MODE_FILTER + 1)
+-#ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER
+-#include <asm/syscall.h>
+-#endif
+-
+ #ifdef CONFIG_SECCOMP_FILTER
+ #include <linux/file.h>
+ #include <linux/filter.h>
+@@ -1074,6 +1072,14 @@ void secure_computing_strict(int this_syscall)
+       else
+               BUG();
+ }
++int __secure_computing(const struct seccomp_data *sd)
++{
++      int this_syscall = sd ? sd->nr :
++              syscall_get_nr(current, current_pt_regs());
++
++      secure_computing_strict(this_syscall);
++      return 0;
++}
+ #else
+ #ifdef CONFIG_SECCOMP_FILTER
+-- 
+2.39.5
+
diff --git a/queue-6.14/selftests-bpf-fix-freplace_link-segfault-in-tailcall.patch b/queue-6.14/selftests-bpf-fix-freplace_link-segfault-in-tailcall.patch
new file mode 100644 (file)
index 0000000..606bb21
--- /dev/null
@@ -0,0 +1,44 @@
+From dcf0d3a771635db202cfc27fcc4c0c7ed5b81573 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jan 2025 10:28:38 +0800
+Subject: selftests/bpf: Fix freplace_link segfault in tailcalls prog test
+
+From: Tengda Wu <wutengda@huaweicloud.com>
+
+[ Upstream commit a63a631c9b5cb25a1c17dd2cb18c63df91e978b1 ]
+
+There are two bpf_link__destroy(freplace_link) calls in
+test_tailcall_bpf2bpf_freplace(). After the first bpf_link__destroy()
+is called, if the following bpf_map_{update,delete}_elem() throws an
+exception, it will jump to the "out" label and call bpf_link__destroy()
+again, causing double free and eventually leading to a segfault.
+
+Fix it by directly resetting freplace_link to NULL after the first
+bpf_link__destroy() call.
+
+Fixes: 021611d33e78 ("selftests/bpf: Add test to verify tailcall and freplace restrictions")
+Signed-off-by: Tengda Wu <wutengda@huaweicloud.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Reviewed-by: Leon Hwang <leon.hwang@linux.dev>
+Link: https://lore.kernel.org/bpf/20250122022838.1079157-1-wutengda@huaweicloud.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/prog_tests/tailcalls.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/tailcalls.c b/tools/testing/selftests/bpf/prog_tests/tailcalls.c
+index 544144620ca61..66a900327f912 100644
+--- a/tools/testing/selftests/bpf/prog_tests/tailcalls.c
++++ b/tools/testing/selftests/bpf/prog_tests/tailcalls.c
+@@ -1600,6 +1600,7 @@ static void test_tailcall_bpf2bpf_freplace(void)
+               goto out;
+       err = bpf_link__destroy(freplace_link);
++      freplace_link = NULL;
+       if (!ASSERT_OK(err, "destroy link"))
+               goto out;
+-- 
+2.39.5
+
diff --git a/queue-6.14/selftests-bpf-fix-runqslower-cross-endian-build.patch b/queue-6.14/selftests-bpf-fix-runqslower-cross-endian-build.patch
new file mode 100644 (file)
index 0000000..639534e
--- /dev/null
@@ -0,0 +1,60 @@
+From 266e8b101b75a2cd38286c278a99b116923e5b03 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jan 2025 23:14:23 -0800
+Subject: selftests/bpf: Fix runqslower cross-endian build
+
+From: Tony Ambardar <tony.ambardar@gmail.com>
+
+[ Upstream commit cb3ade567816a03d1ac1c33bf86073574efcfcaf ]
+
+The runqslower binary from a cross-endian build currently fails to run
+because the included skeleton has host endianness. Fix this by passing the
+target BPF endianness to the runqslower sub-make.
+
+Fixes: 5a63c33d6f00 ("selftests/bpf: Support cross-endian building")
+Signed-off-by: Tony Ambardar <tony.ambardar@gmail.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20250125071423.2603588-1-itugrok@yahoo.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/bpf/runqslower/Makefile        | 3 ++-
+ tools/testing/selftests/bpf/Makefile | 1 +
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/tools/bpf/runqslower/Makefile b/tools/bpf/runqslower/Makefile
+index e49203ebd48c1..78a436c4072e3 100644
+--- a/tools/bpf/runqslower/Makefile
++++ b/tools/bpf/runqslower/Makefile
+@@ -6,6 +6,7 @@ OUTPUT ?= $(abspath .output)/
+ BPFTOOL_OUTPUT := $(OUTPUT)bpftool/
+ DEFAULT_BPFTOOL := $(BPFTOOL_OUTPUT)bootstrap/bpftool
+ BPFTOOL ?= $(DEFAULT_BPFTOOL)
++BPF_TARGET_ENDIAN ?= --target=bpf
+ LIBBPF_SRC := $(abspath ../../lib/bpf)
+ BPFOBJ_OUTPUT := $(OUTPUT)libbpf/
+ BPFOBJ := $(BPFOBJ_OUTPUT)libbpf.a
+@@ -60,7 +61,7 @@ $(OUTPUT)/%.skel.h: $(OUTPUT)/%.bpf.o | $(BPFTOOL)
+       $(QUIET_GEN)$(BPFTOOL) gen skeleton $< > $@
+ $(OUTPUT)/%.bpf.o: %.bpf.c $(BPFOBJ) | $(OUTPUT)
+-      $(QUIET_GEN)$(CLANG) -g -O2 --target=bpf $(INCLUDES)                  \
++      $(QUIET_GEN)$(CLANG) -g -O2 $(BPF_TARGET_ENDIAN) $(INCLUDES)          \
+                -c $(filter %.c,$^) -o $@ &&                                 \
+       $(LLVM_STRIP) -g $@
+diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
+index 87551628e1129..6722080b2107a 100644
+--- a/tools/testing/selftests/bpf/Makefile
++++ b/tools/testing/selftests/bpf/Makefile
+@@ -306,6 +306,7 @@ $(OUTPUT)/runqslower: $(BPFOBJ) | $(DEFAULT_BPFTOOL) $(RUNQSLOWER_OUTPUT)
+                   BPFTOOL_OUTPUT=$(HOST_BUILD_DIR)/bpftool/                  \
+                   BPFOBJ_OUTPUT=$(BUILD_DIR)/libbpf/                         \
+                   BPFOBJ=$(BPFOBJ) BPF_INCLUDE=$(INCLUDE_DIR)                \
++                  BPF_TARGET_ENDIAN=$(BPF_TARGET_ENDIAN)                     \
+                   EXTRA_CFLAGS='-g $(OPT_FLAGS) $(SAN_CFLAGS) $(EXTRA_CFLAGS)' \
+                   EXTRA_LDFLAGS='$(SAN_LDFLAGS) $(EXTRA_LDFLAGS)' &&         \
+                   cp $(RUNQSLOWER_OUTPUT)runqslower $@
+-- 
+2.39.5
+
diff --git a/queue-6.14/selftests-bpf-fix-string-read-in-strncmp-benchmark.patch b/queue-6.14/selftests-bpf-fix-string-read-in-strncmp-benchmark.patch
new file mode 100644 (file)
index 0000000..1207d31
--- /dev/null
@@ -0,0 +1,83 @@
+From a5901ce10ccad4fa9282ef1be5ae177cc64c4adf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Mar 2025 13:28:52 +0100
+Subject: selftests/bpf: Fix string read in strncmp benchmark
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Viktor Malik <vmalik@redhat.com>
+
+[ Upstream commit de07b182899227d5fd1ca7a1a7d495ecd453d49c ]
+
+The strncmp benchmark uses the bpf_strncmp helper and a hand-written
+loop to compare two strings. The values of the strings are filled from
+userspace. One of the strings is non-const (in .bss) while the other is
+const (in .rodata) since that is the requirement of bpf_strncmp.
+
+The problem is that in the hand-written loop, Clang optimizes the reads
+from the const string to always return 0 which breaks the benchmark.
+
+Use barrier_var to prevent the optimization.
+
+The effect can be seen on the strncmp-no-helper variant.
+
+Before this change:
+
+    # ./bench strncmp-no-helper
+    Setting up benchmark 'strncmp-no-helper'...
+    Benchmark 'strncmp-no-helper' started.
+    Iter   0 (112.309us): hits    0.000M/s (  0.000M/prod), drops    0.000M/s, total operations    0.000M/s
+    Iter   1 (-23.238us): hits    0.000M/s (  0.000M/prod), drops    0.000M/s, total operations    0.000M/s
+    Iter   2 ( 58.994us): hits    0.000M/s (  0.000M/prod), drops    0.000M/s, total operations    0.000M/s
+    Iter   3 (-30.466us): hits    0.000M/s (  0.000M/prod), drops    0.000M/s, total operations    0.000M/s
+    Iter   4 ( 29.996us): hits    0.000M/s (  0.000M/prod), drops    0.000M/s, total operations    0.000M/s
+    Iter   5 ( 16.949us): hits    0.000M/s (  0.000M/prod), drops    0.000M/s, total operations    0.000M/s
+    Iter   6 (-60.035us): hits    0.000M/s (  0.000M/prod), drops    0.000M/s, total operations    0.000M/s
+    Summary: hits    0.000 ± 0.000M/s (  0.000M/prod), drops    0.000 ± 0.000M/s, total operations    0.000 ± 0.000M/s
+
+After this change:
+
+    # ./bench strncmp-no-helper
+    Setting up benchmark 'strncmp-no-helper'...
+    Benchmark 'strncmp-no-helper' started.
+    Iter   0 ( 77.711us): hits    5.534M/s (  5.534M/prod), drops    0.000M/s, total operations    5.534M/s
+    Iter   1 ( 11.215us): hits    6.006M/s (  6.006M/prod), drops    0.000M/s, total operations    6.006M/s
+    Iter   2 (-14.253us): hits    5.931M/s (  5.931M/prod), drops    0.000M/s, total operations    5.931M/s
+    Iter   3 ( 59.087us): hits    6.005M/s (  6.005M/prod), drops    0.000M/s, total operations    6.005M/s
+    Iter   4 (-21.379us): hits    6.010M/s (  6.010M/prod), drops    0.000M/s, total operations    6.010M/s
+    Iter   5 (-20.310us): hits    5.861M/s (  5.861M/prod), drops    0.000M/s, total operations    5.861M/s
+    Iter   6 ( 53.937us): hits    6.004M/s (  6.004M/prod), drops    0.000M/s, total operations    6.004M/s
+    Summary: hits    5.969 ± 0.061M/s (  5.969M/prod), drops    0.000 ± 0.000M/s, total operations    5.969 ± 0.061M/s
+
+Fixes: 9c42652f8be3 ("selftests/bpf: Add benchmark for bpf_strncmp() helper")
+Suggested-by: Andrii Nakryiko <andrii@kernel.org>
+Signed-off-by: Viktor Malik <vmalik@redhat.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Acked-by: Hou Tao <houtao1@huawei.com>
+Link: https://lore.kernel.org/bpf/20250313122852.1365202-1-vmalik@redhat.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/progs/strncmp_bench.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/bpf/progs/strncmp_bench.c b/tools/testing/selftests/bpf/progs/strncmp_bench.c
+index 18373a7df76e6..f47bf88f8d2a7 100644
+--- a/tools/testing/selftests/bpf/progs/strncmp_bench.c
++++ b/tools/testing/selftests/bpf/progs/strncmp_bench.c
+@@ -35,7 +35,10 @@ static __always_inline int local_strncmp(const char *s1, unsigned int sz,
+ SEC("tp/syscalls/sys_enter_getpgid")
+ int strncmp_no_helper(void *ctx)
+ {
+-      if (local_strncmp(str, cmp_str_len + 1, target) < 0)
++      const char *target_str = target;
++
++      barrier_var(target_str);
++      if (local_strncmp(str, cmp_str_len + 1, target_str) < 0)
+               __sync_add_and_fetch(&hits, 1);
+       return 0;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/selftests-bpf-select-numa_no_node-to-create-map.patch b/queue-6.14/selftests-bpf-select-numa_no_node-to-create-map.patch
new file mode 100644 (file)
index 0000000..cba6d83
--- /dev/null
@@ -0,0 +1,55 @@
+From 4e754e976e73947dcaf8e37f1d01dc0d04eb4997 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Jan 2025 12:35:22 +0530
+Subject: selftests/bpf: Select NUMA_NO_NODE to create map
+
+From: Saket Kumar Bhaskar <skb99@linux.ibm.com>
+
+[ Upstream commit 4107a1aeb20ed4cdad6a0d49de92ea0f933c71b7 ]
+
+On powerpc, a CPU does not necessarily originate from NUMA node 0.
+This contrasts with architectures like x86, where CPU 0 is not
+hot-pluggable, making NUMA node 0 a consistently valid node.
+This discrepancy can lead to failures when creating a map on NUMA
+node 0, which is initialized by default, if no CPUs are allocated
+from NUMA node 0.
+
+This patch fixes the issue by setting NUMA_NO_NODE (-1) for map
+creation for this selftest.
+
+Fixes: 96eabe7a40aa ("bpf: Allow selecting numa node during map creation")
+Signed-off-by: Saket Kumar Bhaskar <skb99@linux.ibm.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Acked-by: Yonghong Song <yonghong.song@linux.dev>
+Link: https://lore.kernel.org/bpf/cf1f61468b47425ecf3728689bc9636ddd1d910e.1738302337.git.skb99@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/prog_tests/bloom_filter_map.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/bloom_filter_map.c b/tools/testing/selftests/bpf/prog_tests/bloom_filter_map.c
+index cc184e4420f6e..67557cda22083 100644
+--- a/tools/testing/selftests/bpf/prog_tests/bloom_filter_map.c
++++ b/tools/testing/selftests/bpf/prog_tests/bloom_filter_map.c
+@@ -6,6 +6,10 @@
+ #include <test_progs.h>
+ #include "bloom_filter_map.skel.h"
++#ifndef NUMA_NO_NODE
++#define NUMA_NO_NODE  (-1)
++#endif
++
+ static void test_fail_cases(void)
+ {
+       LIBBPF_OPTS(bpf_map_create_opts, opts);
+@@ -69,6 +73,7 @@ static void test_success_cases(void)
+       /* Create a map */
+       opts.map_flags = BPF_F_ZERO_SEED | BPF_F_NUMA_NODE;
++      opts.numa_node = NUMA_NO_NODE;
+       fd = bpf_map_create(BPF_MAP_TYPE_BLOOM_FILTER, NULL, 0, sizeof(value), 100, &opts);
+       if (!ASSERT_GE(fd, 0, "bpf_map_create bloom filter success case"))
+               return;
+-- 
+2.39.5
+
diff --git a/queue-6.14/selftests-mm-cow-fix-the-incorrect-error-handling.patch b/queue-6.14/selftests-mm-cow-fix-the-incorrect-error-handling.patch
new file mode 100644 (file)
index 0000000..b797e4e
--- /dev/null
@@ -0,0 +1,41 @@
+From 9168b43f383494a231dffca960306e0a7a9d023a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Mar 2025 12:38:40 +0800
+Subject: selftests/mm/cow: fix the incorrect error handling
+
+From: Cyan Yang <cyan.yang@sifive.com>
+
+[ Upstream commit f841ad9ca5007167c02de143980c9dc703f90b3d ]
+
+Error handling doesn't check the correct return value.  This patch will
+fix it.
+
+Link: https://lkml.kernel.org/r/20250312043840.71799-1-cyan.yang@sifive.com
+Fixes: f4b5fd6946e2 ("selftests/vm: anon_cow: THP tests")
+Signed-off-by: Cyan Yang <cyan.yang@sifive.com>
+Reviewed-by: Dev Jain <dev.jain@arm.com>
+Reviewed-by: Muhammad Usama Anjum <usama.anjum@collabora.com>
+Cc: David Hildenbrand <david@redhat.com>
+Cc: Shuah Khan <shuah@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/mm/cow.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/mm/cow.c b/tools/testing/selftests/mm/cow.c
+index 9446673645eba..f0cb14ea86084 100644
+--- a/tools/testing/selftests/mm/cow.c
++++ b/tools/testing/selftests/mm/cow.c
+@@ -876,7 +876,7 @@ static void do_run_with_thp(test_fn fn, enum thp_run thp_run, size_t thpsize)
+               mremap_size = thpsize / 2;
+               mremap_mem = mmap(NULL, mremap_size, PROT_NONE,
+                                 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+-              if (mem == MAP_FAILED) {
++              if (mremap_mem == MAP_FAILED) {
+                       ksft_test_result_fail("mmap() failed\n");
+                       goto munmap;
+               }
+-- 
+2.39.5
+
diff --git a/queue-6.14/selftests-pcie_bwctrl-add-set_pcie_speed.sh-to-test_.patch b/queue-6.14/selftests-pcie_bwctrl-add-set_pcie_speed.sh-to-test_.patch
new file mode 100644 (file)
index 0000000..1318d36
--- /dev/null
@@ -0,0 +1,36 @@
+From dee123bf970d85449f6784121f444e4d8b139bff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Feb 2025 15:00:59 +0800
+Subject: selftests/pcie_bwctrl: Add 'set_pcie_speed.sh' to TEST_PROGS
+
+From: Yi Lai <yi1.lai@intel.com>
+
+[ Upstream commit df6f8c4d72aebaf66aaa8658c723fd360c272e59 ]
+
+The test shell script "set_pcie_speed.sh" is not installed in INSTALL_PATH.
+Attempting to execute set_pcie_cooling_state.sh shows warning:
+
+  ./set_pcie_cooling_state.sh: line 119: ./set_pcie_speed.sh: No such file or directory
+
+Add "set_pcie_speed.sh" to TEST_PROGS.
+
+Link: https://lore.kernel.org/r/Z8FfK8rN30lKzvVV@ly-workstation
+Fixes: 838f12c3d551 ("selftests/pcie_bwctrl: Create selftests")
+Signed-off-by: Yi Lai <yi1.lai@intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/pcie_bwctrl/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/pcie_bwctrl/Makefile b/tools/testing/selftests/pcie_bwctrl/Makefile
+index 3e84e26341d1c..48ec048f47afd 100644
+--- a/tools/testing/selftests/pcie_bwctrl/Makefile
++++ b/tools/testing/selftests/pcie_bwctrl/Makefile
+@@ -1,2 +1,2 @@
+-TEST_PROGS = set_pcie_cooling_state.sh
++TEST_PROGS = set_pcie_cooling_state.sh set_pcie_speed.sh
+ include ../lib.mk
+-- 
+2.39.5
+
diff --git a/queue-6.14/selinux-chain-up-tool-resolving-errors-in-install_po.patch b/queue-6.14/selinux-chain-up-tool-resolving-errors-in-install_po.patch
new file mode 100644 (file)
index 0000000..34dfd15
--- /dev/null
@@ -0,0 +1,66 @@
+From dff19f3035f357f79c2747127b3853346d92c7a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Mar 2025 10:56:43 +0100
+Subject: selinux: Chain up tool resolving errors in install_policy.sh
+
+From: Tim Schumacher <tim.schumacher1@huawei.com>
+
+[ Upstream commit 6ae0042f4d3f331e841495eb0a3d51598e593ec2 ]
+
+Subshell evaluations are not exempt from errexit, so if a command is
+not available, `which` will fail and exit the script as a whole.
+This causes the helpful error messages to not be printed if they are
+tacked on using a `$?` comparison.
+
+Resolve the issue by using chains of logical operators, which are not
+subject to the effects of errexit.
+
+Fixes: e37c1877ba5b1 ("scripts/selinux: modernize mdp")
+Signed-off-by: Tim Schumacher <tim.schumacher1@huawei.com>
+Signed-off-by: Paul Moore <paul@paul-moore.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/selinux/install_policy.sh | 15 ++++++---------
+ 1 file changed, 6 insertions(+), 9 deletions(-)
+
+diff --git a/scripts/selinux/install_policy.sh b/scripts/selinux/install_policy.sh
+index 24086793b0d8d..db40237e60ce7 100755
+--- a/scripts/selinux/install_policy.sh
++++ b/scripts/selinux/install_policy.sh
+@@ -6,27 +6,24 @@ if [ `id -u` -ne 0 ]; then
+       exit 1
+ fi
+-SF=`which setfiles`
+-if [ $? -eq 1 ]; then
++SF=`which setfiles` || {
+       echo "Could not find setfiles"
+       echo "Do you have policycoreutils installed?"
+       exit 1
+-fi
++}
+-CP=`which checkpolicy`
+-if [ $? -eq 1 ]; then
++CP=`which checkpolicy` || {
+       echo "Could not find checkpolicy"
+       echo "Do you have checkpolicy installed?"
+       exit 1
+-fi
++}
+ VERS=`$CP -V | awk '{print $1}'`
+-ENABLED=`which selinuxenabled`
+-if [ $? -eq 1 ]; then
++ENABLED=`which selinuxenabled` || {
+       echo "Could not find selinuxenabled"
+       echo "Do you have libselinux-utils installed?"
+       exit 1
+-fi
++}
+ if selinuxenabled; then
+     echo "SELinux is already enabled"
+-- 
+2.39.5
+
diff --git a/queue-6.14/series b/queue-6.14/series
new file mode 100644 (file)
index 0000000..f67715a
--- /dev/null
@@ -0,0 +1,644 @@
+fs-support-o_path-fds-with-fsconfig_set_fd.patch
+watch_queue-fix-pipe-accounting-mismatch.patch
+x86-mm-pat-cpa-test-fix-length-for-cpa_array-test.patch
+m68k-sun3-use-str_read_write-helper-in-mmu_emu_handl.patch
+m68k-sun3-fix-debug_mmu_emu-build.patch
+cpufreq-scpi-compare-khz-instead-of-hz.patch
+seccomp-fix-the-__secure_computing-stub-for-have_arc.patch
+smack-dont-compile-ipv6-code-unless-ipv6-is-configur.patch
+smack-ipv4-ipv6-tcp-dccp-sctp-fix-incorrect-child-so.patch
+sched-cancel-the-slice-protection-of-the-idle-entity.patch
+sched-eevdf-force-propagating-min_slice-of-cfs_rq-wh.patch
+cpufreq-governor-fix-negative-idle_time-handling-in-.patch
+edac-igen6-fix-the-flood-of-invalid-error-reports.patch
+edac-skx_common-i10nm-fix-some-missing-error-reports.patch
+x86-vdso-fix-latent-bug-in-vclock_pages-calculation.patch
+x86-fpu-fix-guest-fpu-state-buffer-allocation-size.patch
+cpufreq-amd-pstate-modify-the-min_perf-calculation-i.patch
+cpufreq-amd-pstate-pass-min-max_limit_perf-as-min-ma.patch
+cpufreq-amd-pstate-convert-all-perf-values-to-u8.patch
+cpufreq-amd-pstate-add-missing-null-ptr-check-in-amd.patch
+x86-fpu-avoid-copying-dynamic-fp-state-from-init_tas.patch
+rseq-update-kernel-fields-in-lockstep-with-config_de.patch
+x86-platform-only-allow-config_eisa-for-32-bit.patch
+x86-sev-add-missing-rip_rel_ref-invocations-during-s.patch
+lockdep-mm-fix-might_fault-lockdep-check-of-current-.patch
+pm-sleep-adjust-check-before-setting-power.must_resu.patch
+cpufreq-tegra194-allow-building-for-tegra234.patch
+risc-v-kvm-disable-the-kernel-perf-counter-during-co.patch
+kunit-stackinit-use-fill-byte-different-from-clang-i.patch
+watchdog-hardlockup-perf-fix-perf_event-memory-leak.patch
+x86-split_lock-fix-the-delayed-detection-logic.patch
+selinux-chain-up-tool-resolving-errors-in-install_po.patch
+edac-ie31200-fix-the-size-of-edac_mc_layer_chip_sele.patch
+edac-ie31200-fix-the-dimm-size-mask-for-several-socs.patch
+edac-ie31200-fix-the-error-path-order-of-ie31200_ini.patch
+dma-fix-encryption-bit-clearing-for-dma_to_phys.patch
+dma-introduce-generic-dma_addr_-crypted-helpers.patch
+arm64-realm-use-aliased-addresses-for-device-dma-to-.patch
+x86-resctrl-fix-allocation-of-cleanest-closid-on-pla.patch
+cpuidle-init-cpuidle-only-for-present-cpus.patch
+thermal-int340x-add-null-check-for-adev.patch
+pm-sleep-fix-handling-devices-with-direct_complete-s.patch
+lockdep-don-t-disable-interrupts-on-rt-in-disable_ir.patch
+cpufreq-init-cpufreq-only-for-present-cpus.patch
+perf-ring_buffer-allow-the-epollrdnorm-flag-for-poll.patch
+perf-save-pmu-specific-data-in-task_struct.patch
+perf-supply-task-information-to-sched_task.patch
+perf-x86-lbr-fix-shorter-lbrs-call-stacks-for-the-sy.patch
+sched-deadline-ignore-special-tasks-when-rebuilding-.patch
+sched-topology-wrappers-for-sched_domains_mutex.patch
+sched-deadline-generalize-unique-visiting-of-root-do.patch
+sched-deadline-rebuild-root-domain-accounting-after-.patch
+x86-traps-make-exc_double_fault-consistently-noretur.patch
+x86-fpu-xstate-fix-inconsistencies-in-guest-fpu-xfea.patch
+x86-entry-add-__init-to-ia32_emulation_override_cmdl.patch
+risc-v-kvm-teardown-riscv-specific-bits-after-kvm_ex.patch
+timekeeping-fix-possible-inconsistencies-in-_coarse-.patch
+regulator-pca9450-fix-enable-register-for-ldo5.patch
+auxdisplay-max6959-should-select-bitreverse.patch
+media-verisilicon-hevc-initialize-start_bit-field.patch
+media-platform-allgro-dvt-unregister-v4l2_device-on-.patch
+auxdisplay-panel-fix-an-api-misuse-in-panel.c.patch
+platform-x86-lenovo-yoga-tab2-pro-1380-fastcharger-m.patch
+platform-x86-dell-uart-backlight-make-dell_uart_bl_s.patch
+platform-x86-dell-ddv-fix-temperature-calculation.patch
+asoc-cs35l41-check-the-return-value-from-spi_setup.patch
+asoc-amd-acp-fix-for-enabling-dmic-on-acp-platforms-.patch
+hid-remove-superfluous-and-wrong-makefile-entry-for-.patch
+asoc-simple-card-utils-don-t-use-__free-device_node-.patch
+dt-bindings-vendor-prefixes-add-gocontroll.patch
+alsa-hda-realtek-always-honor-no_shutup_pins.patch
+asoc-tegra-use-non-atomic-timeout-for-adx-status-reg.patch
+asoc-ti-j721e-evm-fix-clock-configuration-for-ti-j72.patch
+alsa-usb-audio-separate-djm-a9-cap-lvl-options.patch
+alsa-timer-don-t-take-register_mutex-with-copy_from-.patch
+alsa-hda-realtek-fix-built-in-mic-assignment-on-asus.patch
+wifi-rtw89-correct-immediate-cfg_len-calculation-for.patch
+wifi-ath12k-fix-skb_ext_desc-leak-in-ath12k_dp_tx-er.patch
+wifi-ath12k-encode-max-tx-power-in-scan-channel-list.patch
+wifi-ath12k-fix-pdev-lookup-in-wbm-error-processing.patch
+wifi-ath9k-do-not-submit-zero-bytes-to-the-entropy-p.patch
+wifi-ath11k-fix-wrong-overriding-for-vht-beamformee-.patch
+arm64-dts-mediatek-mt8173-elm-drop-pmic-s-address-ce.patch
+arm64-dts-mediatek-mt8173-fix-some-node-names.patch
+wifi-ath11k-update-channel-list-in-reg-notifier-inst.patch
+arm-dts-omap4-panda-a4-add-missing-model-and-compati.patch
+f2fs-quota-fix-to-avoid-warning-in-dquot_writeback_d.patch
+dlm-prevent-npd-when-writing-a-positive-value-to-eve.patch
+wifi-ath11k-fix-rcu-stall-while-reaping-monitor-dest.patch
+wifi-ath11k-add-srng-lock-for-ath11k_hal_srng_-in-mo.patch
+wifi-ath12k-fix-locking-in-qmi-firmware-ready-error-.patch
+f2fs-fix-to-avoid-panic-once-fallocation-fails-for-p.patch
+scsi-mpt3sas-reduce-log-level-of-ignore_delay_remove.patch
+md-ensure-resync-is-prioritized-over-recovery.patch
+md-raid1-fix-memory-leak-in-raid1_run-if-no-active-r.patch
+coredump-fixes-core_pipe_limit-sysctl-proc_handler.patch
+io_uring-io-wq-eliminate-redundant-io_work_get_acct-.patch
+io_uring-io-wq-cache-work-flags-in-variable.patch
+io_uring-io-wq-do-not-use-bogus-hash-value.patch
+io_uring-check-for-iowq-alloc_workqueue-failure.patch
+io_uring-net-improve-recv-bundles.patch
+firmware-arm_ffa-refactor-addition-of-partition-info.patch
+firmware-arm_ffa-unregister-the-ff-a-devices-when-cl.patch
+arm64-dts-mediatek-mt6359-fix-dtbs_check-error-for-a.patch
+scsi-mpi3mr-fix-locking-in-an-error-path.patch
+scsi-mpt3sas-fix-a-locking-bug-in-an-error-path.patch
+can-rockchip_canfd-rkcanfd_chip_fifo_setup-remove-du.patch
+jfs-reject-on-disk-inodes-of-an-unsupported-type.patch
+jfs-add-check-read-only-before-txbeginanon-call.patch
+jfs-add-check-read-only-before-truncation-in-jfs_tru.patch
+wifi-ath12k-add-missing-htt_metadata-flag-in-ath12k_.patch
+wifi-rtw89-rtw8852b-t-fix-tssi-debug-timestamps.patch
+xfrm-delay-initialization-of-offload-path-till-its-a.patch
+iommu-io-pgtable-dart-only-set-subpage-protection-di.patch
+firmware-arm_ffa-explicitly-cast-return-value-from-f.patch
+firmware-arm_ffa-explicitly-cast-return-value-from-n.patch
+arm64-dts-renesas-r8a774c0-re-add-voltages-to-opp-ta.patch
+arm64-dts-renesas-r8a77990-re-add-voltages-to-opp-ta.patch
+firmware-arm_ffa-skip-the-first-partition-id-when-pa.patch
+arm64-dts-ti-k3-j722s-evm-fix-usb2.0_mux_sel-to-sele.patch
+wifi-ath12k-use-link-specific-bss_conf-as-well-in-at.patch
+arm64-dts-imx8mp-skov-correct-pmic-board-limits.patch
+arm64-dts-imx8mp-skov-operate-cpu-at-850-mv-by-defau.patch
+arm64-dts-mediatek-mt8390-genio-700-evk-move-common-.patch
+arm64-dts-mediatek-mt8390-genio-common-fix-duplicate.patch
+wifi-ath11k-clear-affinity-hint-before-calling-ath11.patch
+wifi-ath12k-clear-affinity-hint-before-calling-ath12.patch
+f2fs-fix-to-set-.discard_granularity-correctly.patch
+f2fs-add-check-for-deleted-inode.patch
+arm64-dts-ti-k3-am62-verdin-dahlia-add-microphone-ja.patch
+f2fs-fix-potential-deadloop-in-prepare_compress_over.patch
+f2fs-fix-to-call-f2fs_recover_quota_end-correctly.patch
+md-fix-mddev-uaf-while-iterating-all_mddevs-list.patch
+md-raid1-raid10-don-t-ignore-io-flags.patch
+md-md-bitmap-fix-wrong-bitmap_limit-for-clustermd-wh.patch
+tracing-fix-declare_trace_condition.patch
+tools-rv-keep-user-ldflags-in-build.patch
+arm64-dts-ti-k3-am62p-enable-audio_refclkx.patch
+arm64-dts-ti-k3-am62p-fix-pinctrl-settings.patch
+arm64-dts-ti-k3-j722s-fix-pinctrl-settings.patch
+wifi-rtw89-fw-correct-debug-message-format-in-rtw89_.patch
+wifi-rtw89-pci-correct-isr-rdu-bit-for-8922ae.patch
+blk-throttle-fix-lower-bps-rate-by-throtl_trim_slice.patch
+soc-mediatek-mtk-mmsys-fix-mt8188-vdo1-dpi1-output-s.patch
+soc-mediatek-mt8167-mmsys-fix-missing-regval-in-all-.patch
+soc-mediatek-mt8365-mmsys-fix-routing-table-masks-an.patch
+md-raid10-wait-barrier-before-returning-discard-requ.patch
+block-ensure-correct-integrity-capability-propagatio.patch
+block-correctly-initialize-blk_integrity_nogenerate-.patch
+badblocks-fix-error-shitf-ops.patch
+badblocks-factor-out-a-helper-try_adjacent_combine.patch
+badblocks-attempt-to-merge-adjacent-badblocks-during.patch
+badblocks-return-error-directly-when-setting-badbloc.patch
+badblocks-return-error-if-any-badblock-set-fails.patch
+badblocks-fix-the-using-of-max_badblocks.patch
+badblocks-fix-merge-issue-when-new-badblocks-align-w.patch
+badblocks-fix-missing-bad-blocks-on-retry-in-_badblo.patch
+null_blk-generate-null_blk-configfs-features-string.patch
+null_blk-introduce-badblocks_once-parameter.patch
+null_blk-replace-null_process_cmd-call-in-null_zone_.patch
+null_blk-do-partial-io-for-bad-blocks.patch
+badblocks-return-boolean-from-badblocks_set-and-badb.patch
+badblocks-use-sector_t-instead-of-int-to-avoid-trunc.patch
+firmware-arm_scmi-use-ioread64-instead-of-ioread64_h.patch
+net-airoha-fix-lan4-support-in-airoha_qdma_get_gdm_p.patch
+iommu-amd-fix-header-file.patch
+iommu-vt-d-fix-system-hang-on-reboot-f.patch
+memory-mtk-smi-add-ostd-setting-for-mt8192.patch
+gfs2-minor-evict-fix.patch
+gfs2-skip-if-we-cannot-defer-delete.patch
+arm-dts-imx6ul-tqma6ul1-change-include-order-to-disa.patch
+arm64-dts-imx8mp-add-audio_axi_clk_root-to-audiomix-.patch
+arm64-dts-imx8mp-change-audio_axi_clk_root-freq.-to-.patch
+f2fs-fix-to-avoid-accessing-uninitialized-curseg.patch
+iommu-handle-race-with-default-domain-setup.patch
+wifi-mac80211-remove-ssid-from-ml-reconf.patch
+f2fs-fix-to-avoid-running-out-of-free-segments.patch
+block-fix-adding-folio-to-bio.patch
+ext4-fix-potential-null-dereference-in-ext4-kunit-te.patch
+ext4-convert-ext4_flags_-defines-to-enum.patch
+ext4-add-ext4_flags_emergency_ro-bit.patch
+ext4-correct-behavior-under-errors-remount-ro-mode.patch
+ext4-show-emergency_ro-when-ext4_flags_emergency_ro-.patch
+arm64-dts-rockchip-move-rk356x-scmi-shmem-to-reserve.patch
+arm64-dts-rockchip-remove-bluetooth-node-from-rock-3.patch
+bus-qcom-ssc-block-bus-remove-some-duplicated-iounma.patch
+bus-qcom-ssc-block-bus-fix-the-error-handling-path-o.patch
+arm64-dts-rockchip-fix-pcie-reset-gpio-on-orange-pi-.patch
+arm64-dts-rockchip-fix-pwm-pinctrl-names.patch
+arm64-dts-rockchip-remove-ethm0_clk0_25m_out-from-si.patch
+erofs-allow-16-byte-volume-name-again.patch
+ext4-add-missing-brelse-for-bh2-in-ext4_dx_add_entry.patch
+ext4-verify-fast-symlink-length.patch
+f2fs-fix-missing-discard-for-active-segments.patch
+scsi-hisi_sas-fixed-failure-to-issue-vendor-specific.patch
+scsi-target-tcm_loop-fix-wrong-abort-tag.patch
+ext4-introduce-itail-helper.patch
+ext4-fix-out-of-bound-read-in-ext4_xattr_inode_dec_r.patch
+ext4-goto-right-label-out_mmap_sem-in-ext4_setattr.patch
+jbd2-fix-off-by-one-while-erasing-journal.patch
+ata-libata-fix-ncq-non-data-log-not-supported-print.patch
+wifi-nl80211-store-chandef-on-the-correct-link-when-.patch
+wifi-mac80211-check-basic-rates-validity-in-sta_link.patch
+wifi-cfg80211-init-wiphy_work-before-allocating-rfki.patch
+wifi-mwifiex-fix-premature-release-of-rf-calibration.patch
+wifi-mwifiex-fix-rf-calibration-data-download-from-f.patch
+ice-health.c-fix-compilation-on-gcc-7.5.patch
+ice-ensure-periodic-output-start-time-is-in-the-futu.patch
+ice-fix-reservation-of-resources-for-rdma-when-disab.patch
+virtchnl-make-proto-and-filter-action-count-unsigned.patch
+ice-stop-truncating-queue-ids-when-checking.patch
+ice-validate-queue-quanta-parameters-to-prevent-oob-.patch
+ice-fix-input-validation-for-virtchnl-bw.patch
+ice-fix-using-untrusted-value-of-pkt_len-in-ice_vc_f.patch
+idpf-check-error-for-register_netdev-on-init.patch
+btrfs-get-used-bytes-while-holding-lock-at-btrfs_rec.patch
+btrfs-fix-reclaimed-bytes-accounting-after-automatic.patch
+btrfs-fix-block-group-refcount-race-in-btrfs_create_.patch
+btrfs-don-t-clobber-ret-in-btrfs_validate_super.patch
+wifi-mt76-mt7915-fix-possible-integer-overflows-in-m.patch
+igb-reject-invalid-external-timestamp-requests-for-8.patch
+renesas-reject-ptp_strict_flags-as-unsupported.patch
+net-lan743x-reject-unsupported-external-timestamp-re.patch
+broadcom-fix-supported-flag-check-in-periodic-output.patch
+ptp-ocp-reject-unsupported-periodic-output-flags.patch
+nvmet-pci-epf-always-configure-bar0-as-64-bit.patch
+jbd2-add-a-missing-data-flush-during-file-and-fs-syn.patch
+ext4-define-ext4_journal_destroy-wrapper.patch
+ext4-avoid-journaling-sb-update-on-error-if-journal-.patch
+eth-bnxt-fix-out-of-range-access-of-vnic_info-array.patch
+net-remove-rtnl-dance-for-siocbraddif-and-siocbrdeli.patch
+netfilter-nfnetlink_queue-initialize-ctx-to-avoid-me.patch
+netfilter-nf_tables-only-use-nf_skip_indirect_calls-.patch
+ax25-remove-broken-autobind.patch
+net-mlx5e-fix-ethtool-n-flow-type-ip4-to-rss-context.patch
+bnxt_en-mask-the-bd_cnt-field-in-the-tx-bd-properly.patch
+bnxt_en-linearize-tx-skb-if-the-fragments-exceed-the.patch
+net-dsa-mv88e6xxx-fix-atu_move_port_mask-for-6341-fa.patch
+net-dsa-mv88e6xxx-enable-pvt-for-6321-switch.patch
+net-dsa-mv88e6xxx-enable-.port_set_policy-for-6320-f.patch
+net-dsa-mv88e6xxx-fix-vtu-methods-for-6320-family.patch
+net-dsa-mv88e6xxx-enable-stu-methods-for-6320-family.patch
+mlxsw-spectrum_acl_bloom_filter-workaround-for-some-.patch
+net-dsa-sja1105-fix-displaced-ethtool-statistics-cou.patch
+net-dsa-sja1105-reject-other-rx-filters-than-hwtstam.patch
+net-dsa-sja1105-fix-kasan-out-of-bounds-warning-in-s.patch
+net-mlx5-lag-reload-representors-on-lag-creation-fai.patch
+net-mlx5-start-health-poll-after-enable-hca.patch
+vmxnet3-unregister-xdp-rxq-info-in-the-reset-path.patch
+bonding-check-xdp-prog-when-set-bond-mode.patch
+ibmvnic-use-kernel-helpers-for-hex-dumps.patch
+net-fix-null-pointer-dereference-in-l3mdev_l3_rcv.patch
+virtio_net-fix-endian-with-virtio_net_ctrl_rss.patch
+bluetooth-add-quirk-for-broken-read_voice_setting.patch
+bluetooth-add-quirk-for-broken-read_page_scan_type.patch
+bluetooth-btusb-fix-regression-in-the-initialization.patch
+bluetooth-hci_core-enable-buffer-flow-control-for-sc.patch
+bluetooth-hci-add-definition-of-hci_rp_remote_name_r.patch
+rwonce-handle-kcsan-like-kasan-in-read_word_at_a_tim.patch
+net-dsa-microchip-fix-dcb-apptrust-configuration-on-.patch
+bluetooth-btnxpuart-fix-kernel-panic-during-fw-relea.patch
+bluetooth-hci_event-fix-handling-of-hci_ev_le_direct.patch
+net-fix-the-devmem-sock-opts-and-msgs-for-parisc.patch
+net-libwx-fix-tx-descriptor-content-for-some-tunnel-.patch
+net-libwx-fix-tx-l4-checksum.patch
+rwonce-fix-crash-by-removing-read_once-for-unaligned.patch
+drm-bridge-ti-sn65dsi86-fix-multiple-instances.patch
+drm-ssd130x-set-spi-.id_table-to-prevent-an-spi-core.patch
+accel-amdxdna-return-error-when-setting-clock-failed.patch
+drm-panthor-fix-a-race-between-the-reset-and-suspend.patch
+drm-ssd130x-fix-ssd132x-encoding.patch
+drm-ssd130x-ensure-ssd132x-pitch-is-correct.patch
+drm-dp_mst-fix-drm-rad-print.patch
+drm-bridge-it6505-fix-hdcp-v-match-check-is-not-perf.patch
+drm-panthor-fix-race-condition-when-gathering-fdinfo.patch
+drm-xlnx-zynqmp-fix-max-dma-segment-size.patch
+drm-xlnx-zynqmp_dpsub-add-null-check-in-zynqmp_audio.patch
+drm-zynqmp_dp-fix-a-deadlock-in-zynqmp_dp_ignore_hpd.patch
+drm-vkms-fix-use-after-free-and-double-free-on-init-.patch
+gpu-cdns-mhdp8546-fix-call-balance-of-mhdp-clk-handl.patch
+drm-amdgpu-refine-smu-send-msg-debug-log-format.patch
+drm-amdgpu-umsch-remove-vpe-test-from-umsch.patch
+drm-amdgpu-umsch-declare-umsch-firmware.patch
+drm-amdgpu-umsch-fix-ucode-check.patch
+drm-amdgpu-vcn5.0.1-use-correct-dpm-helper.patch
+pci-use-downstream-bridges-for-distributing-resource.patch
+pci-remove-add_align-overwrite-unrelated-to-size0.patch
+pci-simplify-size1-assignment-logic.patch
+pci-allow-relaxed-bridge-window-tail-sizing-for-opti.patch
+drm-mediatek-mtk_hdmi-unregister-audio-platform-devi.patch
+drm-mediatek-mtk_hdmi-fix-typo-for-aud_sampe_size-me.patch
+drm-amdgpu-replace-mutex-with-spinlock-for-rlcg-regi.patch
+pci-aspm-fix-link-state-exit-during-switch-upstream-.patch
+drm-panel-ilitek-ili9882t-fix-gpio-name-in-error-mes.patch
+pci-acs-fix-pci-config_acs-parameter.patch
+drm-amd-display-fix-an-indent-issue-in-dml21.patch
+drm-msm-dpu-don-t-use-active-in-atomic_check.patch
+drm-msm-dsi-phy-program-clock-inverters-in-correct-r.patch
+drm-msm-dsi-use-existing-per-interface-slice-count-i.patch
+drm-msm-dsi-set-phy-usescase-and-mode-before-registe.patch
+drm-msm-dpu-fall-back-to-a-single-dsc-encoder-1-1-1-.patch
+drm-msm-dpu-remove-arbitrary-limit-of-1-interface-in.patch
+drm-msm-gem-fix-error-code-msm_parse_deps.patch
+drm-amdkfd-fix-circular-locking-dependency-in-svm_ra.patch
+pci-mediatek-gen3-configure-pbus_csr-registers-for-e.patch
+pci-cadence-ep-fix-the-driver-to-send-msg-tlp-for-in.patch
+pci-brcmstb-set-generation-limit-before-pcie-link-up.patch
+pci-brcmstb-use-internal-register-to-change-link-cap.patch
+pci-brcmstb-fix-error-path-after-a-call-to-regulator.patch
+pci-brcmstb-fix-potential-premature-regulator-disabl.patch
+selftests-pcie_bwctrl-add-set_pcie_speed.sh-to-test_.patch
+pci-portdrv-only-disable-pciehp-interrupts-early-whe.patch
+pci-avoid-reset-when-disabled-via-sysfs.patch
+drm-msm-dpu-move-needs_cdm-setting-to-dpu_encoder_ge.patch
+drm-msm-dpu-simplify-dpu_encoder_get_topology-interf.patch
+drm-msm-dpu-don-t-set-crtc_state-mode_changed-from-a.patch
+drm-panthor-update-cs_status_-defines-to-correct-val.patch
+drm-file-add-fdinfo-helper-for-printing-regions-with.patch
+drm-panthor-expose-size-of-driver-internal-bo-s-over.patch
+drm-panthor-replace-sleep-locks-with-spinlocks-in-fd.patch
+drm-panthor-avoid-sleep-locking-in-the-internal-bo-s.patch
+drm-panthor-clean-up-fw-version-information-display.patch
+drm-amd-display-fix-type-mismatch-in-calculatedynami.patch
+drm-msm-a6xx-fix-a6xx-indexed-regs-in-devcoreduump.patch
+powerpc-perf-fix-ref-counting-on-the-pmu-vpa_pmu.patch
+misc-pci_endpoint_test-fix-pci_endpoint_test_bars_re.patch
+misc-pci_endpoint_test-handle-bar-sizes-larger-than-.patch
+pci-endpoint-pci-epf-test-handle-endianness-properly.patch
+crypto-powerpc-mark-ghashp8-ppc.o-as-an-object_files.patch
+powerpc-kexec-fix-physical-address-calculation-in-cl.patch
+pci-remove-stray-put_device-in-pci_register_host_bri.patch
+pci-xilinx-cpm-fix-irq-domain-leak-in-error-path-of-.patch
+drm-mediatek-fix-config_updating-flag-never-false-wh.patch
+drm-mediatek-dp-drm_err-dev_err-in-hpd-path-to-avoid.patch
+drm-mediatek-dsi-fix-error-codes-in-mtk_dsi_host_tra.patch
+drm-amd-display-avoid-npd-when-asic-does-not-support.patch
+pci-dwc-ep-return-enomem-for-allocation-failures.patch
+pci-histb-fix-an-error-handling-path-in-histb_pcie_p.patch
+pci-fix-bar-resizing-when-vf-bars-are-assigned.patch
+drm-amdgpu-mes-optimize-compute-loop-handling.patch
+drm-amdgpu-mes-enable-compute-pipes-across-all-mec.patch
+pci-pciehp-don-t-enable-hpie-when-resuming-in-poll-m.patch
+pci-bwctrl-fix-pcie_bwctrl_select_speed-return-type.patch
+io_uring-net-only-import-send_zc-buffer-once.patch
+pci-fix-null-dereference-in-sr-iov-vf-creation-error.patch
+io_uring-use-lockless_cq-flag-in-io_req_complete_pos.patch
+io_uring-fix-retry-handling-off-iowq.patch
+fbdev-au1100fb-move-a-variable-assignment-behind-a-n.patch
+dummycon-fix-default-rows-cols.patch
+mdacon-rework-dependency-list.patch
+fbdev-sm501fb-add-some-geometry-checks.patch
+crypto-iaa-test-the-correct-request-flag.patch
+crypto-qat-set-parity-error-mask-for-qat_420xx.patch
+crypto-tegra-use-separate-buffer-for-setkey.patch
+crypto-tegra-do-not-use-fixed-size-buffers.patch
+crypto-tegra-check-return-value-for-hash-do_one_req.patch
+crypto-tegra-transfer-hash-init-function-to-crypto-e.patch
+crypto-tegra-fix-hash-intermediate-result-handling.patch
+crypto-bpf-add-module_description-for-skcipher.patch
+crypto-tegra-use-hmac-fallback-when-keyslots-are-ful.patch
+clk-amlogic-gxbb-drop-incorrect-flag-on-32k-clock.patch
+crypto-hisilicon-sec2-fix-for-aead-authsize-alignmen.patch
+crypto-hisilicon-sec2-fix-for-sec-spec-check.patch
+rdma-mlx5-fix-page_size-variable-overflow.patch
+remoteproc-core-clear-table_sz-when-rproc_shutdown.patch
+of-property-increase-nr_fwnode_reference_args.patch
+pinctrl-renesas-rzg2l-suppress-binding-attributes.patch
+remoteproc-qcom_q6v5_pas-make-single-pd-handling-mor.patch
+libbpf-fix-hypothetical-stt_section-extern-null-dere.patch
+drivers-clk-qcom-ipq5424-fix-the-freq-table-of-sdcc1.patch
+selftests-bpf-fix-string-read-in-strncmp-benchmark.patch
+x86-mm-pat-fix-vm_pat-handling-when-fork-fails-in-co.patch
+clk-renesas-r8a08g045-check-the-source-of-the-cpu-pl.patch
+remoteproc-qcom-pas-add-minidump_id-to-sc7280-wpss.patch
+clk-samsung-fix-ubsan-panic-in-samsung_clk_init.patch
+pinctrl-nuvoton-npcm8xx-fix-error-handling-in-npcm8x.patch
+crypto-tegra-fix-cmac-intermediate-result-handling.patch
+clk-qcom-gcc-msm8953-fix-stuck-venus0_core0-clock.patch
+selftests-bpf-fix-runqslower-cross-endian-build.patch
+s390-remove-ioremap_wt-and-pgprot_writethrough.patch
+rdma-mana_ib-ensure-variable-err-is-initialized.patch
+crypto-tegra-set-iv-to-null-explicitly-for-aes-ecb.patch
+remoteproc-qcom_q6v5_pas-use-resource-with-cx-pd-for.patch
+clk-qcom-gcc-x1e80100-unregister-gcc_gpu_cfg_ahb_clk.patch
+crypto-tegra-finalize-crypto-req-on-error.patch
+crypto-tegra-reserve-keyslots-to-allocate-dynamicall.patch
+bpf-use-preempt_count-directly-in-bpf_send_signal_co.patch
+lib-842-improve-error-handling-in-sw842_compress.patch
+pinctrl-renesas-rza2-fix-missing-of_node_put-call.patch
+pinctrl-renesas-rzg2l-fix-missing-of_node_put-call.patch
+rdma-mlx5-fix-mr-cache-initialization-error-flow.patch
+selftests-bpf-fix-freplace_link-segfault-in-tailcall.patch
+clk-rockchip-rk3328-fix-wrong-clk_ref_usb3otg-parent.patch
+rdma-core-don-t-expose-hw_counters-outside-of-init-n.patch
+rdma-mlx5-fix-calculation-of-total-invalidated-pages.patch
+rdma-erdma-prevent-use-after-free-in-erdma_accept_ne.patch
+remoteproc-qcom_q6v5_mss-handle-platforms-with-one-p.patch
+power-supply-bq27xxx_battery-do-not-update-cached-fl.patch
+leds-st1202-check-for-error-code-from-devm_mutex_ini.patch
+crypto-api-fix-larval-relookup-type-and-mask.patch
+ib-mad-check-available-slots-before-posting-receive-.patch
+pinctrl-tegra-set-sfio-mode-to-mux-register.patch
+clk-amlogic-g12b-fix-cluster-a-parent-data.patch
+clk-amlogic-gxbb-drop-non-existing-32k-clock-parent.patch
+selftests-bpf-select-numa_no_node-to-create-map.patch
+rust-fix-signature-of-rust_fmt_argument.patch
+crypto-tegra-fix-format-specifier-in-tegra_sha_prep_.patch
+libbpf-add-namespace-for-errstr-making-it-libbpf_err.patch
+clk-mmp-fix-null-vs-is_err-check.patch
+pinctrl-npcm8xx-fix-incorrect-struct-npcm8xx_pincfg-.patch
+samples-bpf-fix-broken-vmlinux-path-for-vmlinux_btf.patch
+crypto-qat-remove-access-to-parity-register-for-qat-.patch
+clk-clk-imx8mp-audiomix-fix-dsp-ocram_a-clock-parent.patch
+clk-amlogic-g12a-fix-mmc-a-peripheral-clock.patch
+pinctrl-bcm2835-don-t-einval-on-alternate-funcs-from.patch
+x86-entry-fix-orc-unwinder-for-push_regs-with-save_r.patch
+power-supply-max77693-fix-wrong-conversion-of-charge.patch
+crypto-api-call-crypto_alg_put-in-crypto_unregister_.patch
+clk-stm32f4-fix-an-uninitialized-variable.patch
+crypto-nx-fix-uninitialised-hv_nxc-on-error.patch
+clk-qcom-gcc-sm8650-do-not-turn-off-usb-gdscs-during.patch
+bpf-fix-array-bounds-error-with-may_goto.patch
+rdma-mlx5-fix-mlx5_poll_one-cur_qp-update-flow.patch
+pinctrl-renesas-rzv2m-fix-missing-of_node_put-call.patch
+clk-qcom-ipq5424-fix-software-and-hardware-flow-cont.patch
+mfd-sm501-switch-to-bit-to-mitigate-integer-overflow.patch
+leds-fix-led_off-brightness-race.patch
+x86-dumpstack-fix-inaccurate-unwinding-from-exceptio.patch
+rdma-core-fix-use-after-free-when-rename-device-name.patch
+crypto-hisilicon-sec2-fix-for-aead-auth-key-length.patch
+pinctrl-intel-fix-wrong-bypass-assignment-in-intel_p.patch
+clk-qcom-mmcc-sdm660-fix-stuck-video_subcore0-clock.patch
+libbpf-fix-accessing-btf.ext-core_relo-header.patch
+perf-stat-fix-find_stat-for-mixed-legacy-non-legacy-.patch
+perf-always-feature-test-reallocarray.patch
+w1-fix-null-pointer-dereference-in-probe.patch
+staging-gpib-add-missing-interface-entry-point.patch
+staging-gpib-fix-pr_err-format-warning.patch
+usb-typec-thunderbolt-fix-loops-that-iterate-typec_p.patch
+usb-typec-thunderbolt-remove-is_err-check-for-plug.patch
+iio-dac-adi-axi-dac-modify-stream-enable.patch
+perf-test-fix-hwmon-pmu-test-endianess-issue.patch
+perf-stat-don-t-merge-counters-purely-on-name.patch
+fs-ntfs3-factor-out-ntfs_-create-remove-_procdir.patch
+fs-ntfs3-factor-out-ntfs_-create-remove-_proc_root.patch
+fs-ntfs3-fix-proc_info_root-leak-when-init-ntfs-fail.patch
+fs-ntfs3-update-inode-i_mapping-a_ops-on-compression.patch
+iio-light-veml6030-extend-regmap-to-support-regfield.patch
+iio-gts-helper-export-iio_gts_get_total_gain.patch
+iio-light-veml6030-fix-scale-to-conform-to-abi.patch
+iio-adc-ad7124-micro-optimize-channel-disabling.patch
+iio-adc-ad7124-really-disable-all-channels-at-probe-.patch
+phy-phy-rockchip-samsung-hdptx-don-t-use-dt-aliases-.patch
+perf-tools-add-skip-check-in-tool_pmu__event_to_str.patch
+isofs-fix-kmsan-uninit-value-bug-in-do_isofs_readdir.patch
+perf-tests-fix-tool-pmu-test-segfault.patch
+soundwire-slave-fix-an-of-node-reference-leak-in-sou.patch
+staging-gpib-fix-cb7210-pcmcia-oops.patch
+perf-report-switch-data-file-correctly-in-tui.patch
+perf-report-add-parallelism-sort-key.patch
+perf-report-fix-input-reload-switch-with-symbol-sort.patch
+greybus-gb-beagleplay-add-error-handling-for-gb_grey.patch
+coresight-catu-fix-number-of-pages-while-using-64k-p.patch
+vhost-scsi-fix-handling-of-multiple-calls-to-vhost_s.patch
+coresight-etm4x-add-isb-before-reading-the-trcstatr.patch
+perf-pmus-restructure-pmu_read_sysfs-to-scan-fewer-p.patch
+perf-pmu-dynamically-allocate-tool-pmu.patch
+perf-pmu-don-t-double-count-common-sysfs-and-json-ev.patch
+tools-x86-fix-linux-unaligned.h-include-path-in-lib-.patch
+perf-build-fix-in-tree-build-due-to-symbolic-link.patch
+ucsi_ccg-don-t-show-failed-to-get-fw-build-informati.patch
+iio-accel-mma8452-ensure-error-return-on-failure-to-.patch
+iio-accel-msa311-fix-failure-to-release-runtime-pm-i.patch
+iio-backend-make-sure-to-null-terminate-stack-buffer.patch
+iio-core-rework-claim-and-release-of-direct-mode-to-.patch
+iio-adc-ad7173-grab-direct-mode-for-calibration.patch
+iio-adc-ad7192-grab-direct-mode-for-calibration.patch
+perf-arm-spe-fix-load-store-operation-checking.patch
+perf-bench-fix-perf-bench-syscall-loop-count.patch
+perf-machine-fixup-kernel-maps-ends-after-adding-ext.patch
+usb-xhci-correct-debug-message-page-size-calculation.patch
+fs-ntfs3-fix-a-couple-integer-overflows-on-32bit-sys.patch
+fs-ntfs3-prevent-integer-overflow-in-hdr_first_de.patch
+perf-test-add-timeout-to-datasym-workload.patch
+perf-tests-fix-data-symbol-test-with-lto-builds.patch
+nfsd-fix-callback-decoder-status-codes.patch
+soundwire-take-in-count-the-bandwidth-of-a-prepared-.patch
+dmaengine-fsl-edma-cleanup-chan-after-dma_async_devi.patch
+dmaengine-fsl-edma-free-irq-correctly-in-remove-path.patch
+dmaengine-ae4dma-use-the-msi-count-and-its-correspon.patch
+dmaengine-ptdma-utilize-the-ae4dma-engine-s-multi-qu.patch
+iio-adc-ad_sigma_delta-disable-channel-after-calibra.patch
+iio-adc-ad4130-fix-comparison-of-channel-setups.patch
+iio-adc-ad7124-fix-comparison-of-channel-configs.patch
+iio-adc-ad7173-fix-comparison-of-channel-configs.patch
+iio-adc-ad7768-1-set-mosi-idle-state-to-prevent-acci.patch
+iio-light-add-check-for-array-bounds-in-veml6075_rea.patch
+perf-debug-avoid-stack-overflow-in-recursive-error-m.patch
+perf-evlist-add-success-path-to-evlist__create_syswi.patch
+perf-evsel-tp_format-accessing-improvements.patch
+perf-x86-topdown-fix-topdown-leader-sampling-test-er.patch
+perf-units-fix-insufficient-array-space.patch
+perf-test-stat_all_pmu.sh-correctly-check-perf-stat-.patch
+kernel-events-uprobes-handle-device-exclusive-entrie.patch
+kexec-initialize-elf-lowest-address-to-ulong_max.patch
+ocfs2-validate-l_tree_depth-to-avoid-out-of-bounds-a.patch
+reboot-replace-__hw_protection_shutdown-bool-action-.patch
+reboot-reboot-not-shutdown-on-hw_protection_reboot-t.patch
+rust-pci-use-to_result-in-enable_device_mem.patch
+rust-pci-fix-unrestricted-mut-pci-device.patch
+rust-platform-fix-unrestricted-mut-platform-device.patch
+arch-powerpc-drop-generic_ptdump-from-mpc885_ads_def.patch
+writeback-let-trace_balance_dirty_pages-take-struct-.patch
+writeback-fix-calculations-in-trace_balance_dirty_pa.patch
+scripts-gdb-linux-symbols.py-address-changes-to-modu.patch
+nfsv4-don-t-trigger-uneccessary-scans-for-return-on-.patch
+nfsv4-avoid-unnecessary-scans-of-filesystems-for-ret.patch
+nfsv4-avoid-unnecessary-scans-of-filesystems-for-exp.patch
+nfsv4-avoid-unnecessary-scans-of-filesystems-for-del.patch
+nfs-fix-open_owner_id_maxsz-and-related-fields.patch
+fuse-fix-dax-truncate-punch_hole-fault-path.patch
+selftests-mm-cow-fix-the-incorrect-error-handling.patch
+um-pass-the-correct-rust-target-and-options-with-gcc.patch
+um-remove-copy_from_kernel_nofault_allowed.patch
+um-hostfs-avoid-issues-on-inode-number-reuse-by-host.patch
+i3c-master-svc-fix-missing-the-ibi-rules.patch
+perf-python-fixup-description-of-sample.id-event-mem.patch
+perf-python-decrement-the-refcount-of-just-created-e.patch
+perf-python-don-t-keep-a-raw_data-pointer-to-consume.patch
+perf-python-check-if-there-is-space-to-copy-all-the-.patch
+perf-dso-fix-dso__is_kallsyms-check.patch
+perf-intel-tpebs-fix-incorrect-usage-of-zfree.patch
+perf-pmu-handle-memory-failure-in-tool_pmu__new.patch
+staging-rtl8723bs-select-config_crypto_lib_aes.patch
+staging-vchiq_arm-register-debugfs-after-cdev.patch
+staging-vchiq_arm-fix-possible-npr-of-keep-alive-thr.patch
+staging-vchiq_arm-stop-kthreads-if-vchiq-cdev-regist.patch
+tty-n_tty-use-uint-for-space-returned-by-tty_write_r.patch
+perf-vendor-events-arm64-ampereonex-fix-frontend_bou.patch
+fs-procfs-fix-the-comment-above-proc_pid_wchan.patch
+perf-tools-fix-is_compat_mode-build-break-in-ppc64.patch
+perf-tools-annotate-asm_pure_loop.s.patch
+perf-bpf-filter-fix-a-parsing-error-with-comma.patch
+objtool-handle-various-symbol-types-of-rodata.patch
+objtool-handle-different-entry-size-of-rodata.patch
+objtool-handle-pc-relative-relocation-type.patch
+objtool-fix-detection-of-consecutive-jump-tables-on-.patch
+thermal-core-remove-duplicate-struct-declaration.patch
+objtool-spi-amd-fix-out-of-bounds-stack-access-in-am.patch
+objtool-nvmet-fix-out-of-bounds-stack-access-in-nvme.patch
+objtool-media-dib8000-prevent-divide-by-zero-in-dib8.patch
+nfs-shut-down-the-nfs_client-only-after-all-the-supe.patch
+smb-client-fix-netns-refcount-imbalance-causing-leak.patch
+exfat-fix-the-infinite-loop-in-exfat_find_last_clust.patch
+exfat-fix-missing-shutdown-check.patch
+rtnetlink-allocate-vfinfo-size-for-vf-guids-when-sup.patch
+rndis_host-flag-rndis-modems-as-wwan-devices.patch
+ksmbd-use-aead_request_free-to-match-aead_request_al.patch
+ksmbd-fix-multichannel-connection-failure.patch
+ksmbd-fix-r_count-dec-increment-mismatch.patch
+net-mlx5e-shampo-make-reserved-size-independent-of-p.patch
+ring-buffer-fix-bytes_dropped-calculation-issue.patch
+objtool-fix-segfault-in-ignore_unreachable_insn.patch
+loongarch-fix-help-text-of-cmdline_extend-in-kconfig.patch
+loongarch-fix-device-node-refcount-leak-in-fdt_cpu_c.patch
+loongarch-rework-the-arch_kgdb_breakpoint-implementa.patch
+acpi-processor-idle-return-an-error-if-both-p_lvl-2-.patch
+net-phy-broadcom-correct-bcm5221-phy-model-detection.patch
+octeontx2-af-fix-mbox-intr-handler-when-num-vfs-64.patch
+octeontx2-af-free-nix_af_int_vec_gen-irq.patch
+objtool-fix-verbose-disassembly-if-cross_compile-isn.patch
+sched-smt-always-inline-sched_smt_active.patch
+context_tracking-always-inline-ct_-nmi-irq-_-enter-e.patch
+rcu-tasks-always-inline-rcu_irq_work_resched.patch
+objtool-loongarch-add-unwind-hints-in-prepare_framet.patch
+nfs-add-missing-release-on-error-in-nfs_lock_and_joi.patch
+rtc-renesas-rtca3-disable-interrupts-only-if-the-rtc.patch
+spufs-fix-a-leak-on-spufs_new_file-failure.patch
+spufs-fix-gang-directory-lifetimes.patch
+spufs-fix-a-leak-in-spufs_create_context.patch
+fs-9p-fix-null-pointer-dereference-on-mkdir.patch
+riscv-ftrace-add-parentheses-in-macro-definitions-of.patch
+riscv-fix-the-__riscv_copy_vec_words_unaligned-imple.patch
+riscv-fix-missing-__free_pages-in-check_vector_unali.patch
+riscv-fgraph-select-have_function_graph_tracer-depen.patch
+ntb_hw_switchtec-fix-shift-out-of-bounds-in-switchte.patch
+ntb-intel-fix-using-link-status-db-s.patch
+riscv-fgraph-fix-stack-layout-to-match-__arch_ftrace.patch
+riscv-annotate-unaligned-access-init-functions.patch
+riscv-fix-riscv_online_cpu_vec.patch
+riscv-fix-check_unaligned_access_all_cpus.patch
+riscv-change-check_unaligned_access_speed_all_cpus-t.patch
+riscv-fix-set-up-of-cpu-hotplug-callbacks.patch
+riscv-fix-set-up-of-vector-cpu-hotplug-callback.patch
+firmware-cs_dsp-ensure-cs_dsp_load-_coeff-returns-0-.patch
+alsa-hda-realtek-fix-built-in-mic-breakage-on-asus-v.patch
+risc-v-errata-use-medany-for-relocatable-builds.patch
+x86-uaccess-improve-performance-by-aligning-writes-t.patch
+ublk-make-sure-ubq-canceling-is-set-when-queue-is-fr.patch
+s390-entry-fix-setting-_cif_mcck_guest-with-lowcore-.patch
+asoc-codecs-rt5665-fix-some-error-handling-paths-in-.patch
+spi-cadence-fix-out-of-bounds-array-access-in-cdns_m.patch
+riscv-fix-hugetlb-retrieval-of-number-of-ptes-in-cas.patch
+riscv-kexec_file-handle-r_riscv_64-in-purgatory-relo.patch
+riscv-purgatory-4b-align-purgatory_start.patch
+nvme-ioctl-don-t-warn-on-vectorized-uring_cmd-with-f.patch
+nvme-pci-skip-nvme_write_sq_db-on-empty-rqlist.patch
+asoc-imx-card-add-null-check-in-imx_card_probe.patch
+spi-bcm2835-do-not-call-gpiod_put-on-invalid-descrip.patch
+alsa-hda-realtek-fix-built-in-mic-on-another-asus-vi.patch
+spi-bcm2835-restore-native-cs-probing-when-pinctrl-b.patch
+xsk-add-launch-time-hardware-offload-support-to-xdp-.patch
+igc-refactor-empty-frame-insertion-for-launch-time-s.patch
+igc-add-launch-time-support-to-xdp-zc.patch
+igc-fix-tx-drops-in-xdp-zc.patch
+e1000e-change-k1-configuration-on-mtp-and-later-plat.patch
+ixgbe-fix-media-type-detection-for-e610-device.patch
+idpf-fix-adapter-null-pointer-dereference-on-reboot.patch
+netfilter-nft_set_hash-gc-reaps-elements-with-connco.patch
+netfilter-nf_tables-don-t-unregister-hook-when-table.patch
+netlabel-fix-null-pointer-exception-caused-by-calips.patch
+net_sched-skbprio-remove-overly-strict-queue-asserti.patch
+sctp-add-mutual-exclusion-in-proc_sctp_do_udp_port.patch
+net-airoha-fix-qid-report-in-airoha_tc_get_htb_get_l.patch
+net-airoha-fix-ets-priomap-validation.patch
+net-mvpp2-prevent-parser-tcam-memory-corruption.patch
+rtnetlink-use-register_pernet_subsys-in-rtnl_net_deb.patch
+udp-fix-multiple-wraparounds-of-sk-sk_rmem_alloc.patch
+udp-fix-memory-accounting-leak.patch
+vsock-avoid-timeout-during-connect-if-the-socket-is-.patch
+tunnels-accept-packet_host-in-skb_tunnel_check_pmtu.patch
+xsk-fix-__xsk_generic_xmit-error-code-when-cq-is-ful.patch
+net-decrease-cached-dst-counters-in-dst_release.patch
+netfilter-nft_tunnel-fix-geneve_opt-type-confusion-a.patch
+sfc-rip-out-mdio-support.patch
+sfc-fix-null-dereferences-in-ef100_process_design_pa.patch
+ipv6-fix-omitted-netlink-attributes-when-using-rtext.patch
+net-dsa-mv88e6xxx-propperly-shutdown-ppu-re-enable-t.patch
+net-fix-geneve_opt-length-integer-overflow.patch
+ipv6-start-path-selection-from-the-first-nexthop.patch
+ipv6-do-not-consider-link-down-nexthops-in-path-sele.patch
+arcnet-add-null-check-in-com20020pci_probe.patch
+net-ibmveth-make-veth_pool_store-stop-hanging.patch
+netlink-specs-rt_route-pull-the-ifa-prefix-out-of-th.patch
diff --git a/queue-6.14/sfc-fix-null-dereferences-in-ef100_process_design_pa.patch b/queue-6.14/sfc-fix-null-dereferences-in-ef100_process_design_pa.patch
new file mode 100644 (file)
index 0000000..08aec8e
--- /dev/null
@@ -0,0 +1,157 @@
+From 76562363602df8f06a4e2489547657642c030762 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 23:54:39 +0100
+Subject: sfc: fix NULL dereferences in ef100_process_design_param()
+
+From: Edward Cree <ecree.xilinx@gmail.com>
+
+[ Upstream commit 8241ecec1cdc6699ae197d52d58e76bddd995fa5 ]
+
+Since cited commit, ef100_probe_main() and hence also
+ ef100_check_design_params() run before efx->net_dev is created;
+ consequently, we cannot netif_set_tso_max_size() or _segs() at this
+ point.
+Move those netif calls to ef100_probe_netdev(), and also replace
+ netif_err within the design params code with pci_err.
+
+Reported-by: Kyungwook Boo <bookyungwook@gmail.com>
+Fixes: 98ff4c7c8ac7 ("sfc: Separate netdev probe/remove from PCI probe/remove")
+Signed-off-by: Edward Cree <ecree.xilinx@gmail.com>
+Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
+Link: https://patch.msgid.link/20250401225439.2401047-1-edward.cree@amd.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/sfc/ef100_netdev.c |  6 ++--
+ drivers/net/ethernet/sfc/ef100_nic.c    | 47 +++++++++++--------------
+ 2 files changed, 24 insertions(+), 29 deletions(-)
+
+diff --git a/drivers/net/ethernet/sfc/ef100_netdev.c b/drivers/net/ethernet/sfc/ef100_netdev.c
+index d941f073f1ebf..3a06e3b1bd6bf 100644
+--- a/drivers/net/ethernet/sfc/ef100_netdev.c
++++ b/drivers/net/ethernet/sfc/ef100_netdev.c
+@@ -450,8 +450,9 @@ int ef100_probe_netdev(struct efx_probe_data *probe_data)
+       net_dev->hw_enc_features |= efx->type->offload_features;
+       net_dev->vlan_features |= NETIF_F_HW_CSUM | NETIF_F_SG |
+                                 NETIF_F_HIGHDMA | NETIF_F_ALL_TSO;
+-      netif_set_tso_max_segs(net_dev,
+-                             ESE_EF100_DP_GZ_TSO_MAX_HDR_NUM_SEGS_DEFAULT);
++      nic_data = efx->nic_data;
++      netif_set_tso_max_size(efx->net_dev, nic_data->tso_max_payload_len);
++      netif_set_tso_max_segs(efx->net_dev, nic_data->tso_max_payload_num_segs);
+       rc = efx_ef100_init_datapath_caps(efx);
+       if (rc < 0)
+@@ -477,7 +478,6 @@ int ef100_probe_netdev(struct efx_probe_data *probe_data)
+       /* Don't fail init if RSS setup doesn't work. */
+       efx_mcdi_push_default_indir_table(efx, efx->n_rx_channels);
+-      nic_data = efx->nic_data;
+       rc = ef100_get_mac_address(efx, net_dev->perm_addr, CLIENT_HANDLE_SELF,
+                                  efx->type->is_vf);
+       if (rc)
+diff --git a/drivers/net/ethernet/sfc/ef100_nic.c b/drivers/net/ethernet/sfc/ef100_nic.c
+index 62e674d6ff60c..3ad95a4c8af2d 100644
+--- a/drivers/net/ethernet/sfc/ef100_nic.c
++++ b/drivers/net/ethernet/sfc/ef100_nic.c
+@@ -887,8 +887,7 @@ static int ef100_process_design_param(struct efx_nic *efx,
+       case ESE_EF100_DP_GZ_TSO_MAX_HDR_NUM_SEGS:
+               /* We always put HDR_NUM_SEGS=1 in our TSO descriptors */
+               if (!reader->value) {
+-                      netif_err(efx, probe, efx->net_dev,
+-                                "TSO_MAX_HDR_NUM_SEGS < 1\n");
++                      pci_err(efx->pci_dev, "TSO_MAX_HDR_NUM_SEGS < 1\n");
+                       return -EOPNOTSUPP;
+               }
+               return 0;
+@@ -901,32 +900,28 @@ static int ef100_process_design_param(struct efx_nic *efx,
+                */
+               if (!reader->value || reader->value > EFX_MIN_DMAQ_SIZE ||
+                   EFX_MIN_DMAQ_SIZE % (u32)reader->value) {
+-                      netif_err(efx, probe, efx->net_dev,
+-                                "%s size granularity is %llu, can't guarantee safety\n",
+-                                reader->type == ESE_EF100_DP_GZ_RXQ_SIZE_GRANULARITY ? "RXQ" : "TXQ",
+-                                reader->value);
++                      pci_err(efx->pci_dev,
++                              "%s size granularity is %llu, can't guarantee safety\n",
++                              reader->type == ESE_EF100_DP_GZ_RXQ_SIZE_GRANULARITY ? "RXQ" : "TXQ",
++                              reader->value);
+                       return -EOPNOTSUPP;
+               }
+               return 0;
+       case ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_LEN:
+               nic_data->tso_max_payload_len = min_t(u64, reader->value,
+                                                     GSO_LEGACY_MAX_SIZE);
+-              netif_set_tso_max_size(efx->net_dev,
+-                                     nic_data->tso_max_payload_len);
+               return 0;
+       case ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_NUM_SEGS:
+               nic_data->tso_max_payload_num_segs = min_t(u64, reader->value, 0xffff);
+-              netif_set_tso_max_segs(efx->net_dev,
+-                                     nic_data->tso_max_payload_num_segs);
+               return 0;
+       case ESE_EF100_DP_GZ_TSO_MAX_NUM_FRAMES:
+               nic_data->tso_max_frames = min_t(u64, reader->value, 0xffff);
+               return 0;
+       case ESE_EF100_DP_GZ_COMPAT:
+               if (reader->value) {
+-                      netif_err(efx, probe, efx->net_dev,
+-                                "DP_COMPAT has unknown bits %#llx, driver not compatible with this hw\n",
+-                                reader->value);
++                      pci_err(efx->pci_dev,
++                              "DP_COMPAT has unknown bits %#llx, driver not compatible with this hw\n",
++                              reader->value);
+                       return -EOPNOTSUPP;
+               }
+               return 0;
+@@ -946,10 +941,10 @@ static int ef100_process_design_param(struct efx_nic *efx,
+                * So the value of this shouldn't matter.
+                */
+               if (reader->value != ESE_EF100_DP_GZ_VI_STRIDES_DEFAULT)
+-                      netif_dbg(efx, probe, efx->net_dev,
+-                                "NIC has other than default VI_STRIDES (mask "
+-                                "%#llx), early probing might use wrong one\n",
+-                                reader->value);
++                      pci_dbg(efx->pci_dev,
++                              "NIC has other than default VI_STRIDES (mask "
++                              "%#llx), early probing might use wrong one\n",
++                              reader->value);
+               return 0;
+       case ESE_EF100_DP_GZ_RX_MAX_RUNT:
+               /* Driver doesn't look at L2_STATUS:LEN_ERR bit, so we don't
+@@ -961,9 +956,9 @@ static int ef100_process_design_param(struct efx_nic *efx,
+               /* Host interface says "Drivers should ignore design parameters
+                * that they do not recognise."
+                */
+-              netif_dbg(efx, probe, efx->net_dev,
+-                        "Ignoring unrecognised design parameter %u\n",
+-                        reader->type);
++              pci_dbg(efx->pci_dev,
++                      "Ignoring unrecognised design parameter %u\n",
++                      reader->type);
+               return 0;
+       }
+ }
+@@ -999,13 +994,13 @@ static int ef100_check_design_params(struct efx_nic *efx)
+        */
+       if (reader.state != EF100_TLV_TYPE) {
+               if (reader.state == EF100_TLV_TYPE_CONT)
+-                      netif_err(efx, probe, efx->net_dev,
+-                                "truncated design parameter (incomplete type %u)\n",
+-                                reader.type);
++                      pci_err(efx->pci_dev,
++                              "truncated design parameter (incomplete type %u)\n",
++                              reader.type);
+               else
+-                      netif_err(efx, probe, efx->net_dev,
+-                                "truncated design parameter %u\n",
+-                                reader.type);
++                      pci_err(efx->pci_dev,
++                              "truncated design parameter %u\n",
++                              reader.type);
+               rc = -EIO;
+       }
+ out:
+-- 
+2.39.5
+
diff --git a/queue-6.14/sfc-rip-out-mdio-support.patch b/queue-6.14/sfc-rip-out-mdio-support.patch
new file mode 100644 (file)
index 0000000..c4f7af1
--- /dev/null
@@ -0,0 +1,228 @@
+From 1feeb1552aaf3242d2259df5f7268a86152fadc5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Mar 2025 17:57:10 +0000
+Subject: sfc: rip out MDIO support
+
+From: Edward Cree <ecree.xilinx@gmail.com>
+
+[ Upstream commit c339fcdd738be78c540407ae78fef5601ba5092a ]
+
+Unlike Siena, no EF10 board ever had an external PHY, and consequently
+ MDIO handling isn't even built into the firmware.  Since Siena has
+ been split out into its own driver, the MDIO code can be deleted from
+ the sfc driver.
+
+Signed-off-by: Edward Cree <ecree.xilinx@gmail.com>
+Link: https://patch.msgid.link/aa689d192ddaef7abe82709316c2be648a7bd66e.1742493017.git.ecree.xilinx@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 8241ecec1cdc ("sfc: fix NULL dereferences in ef100_process_design_param()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/sfc/ef100_netdev.c     |  1 -
+ drivers/net/ethernet/sfc/efx.c              | 24 ---------
+ drivers/net/ethernet/sfc/mcdi_port.c        | 59 +--------------------
+ drivers/net/ethernet/sfc/mcdi_port_common.c | 11 ----
+ drivers/net/ethernet/sfc/net_driver.h       |  6 +--
+ 5 files changed, 2 insertions(+), 99 deletions(-)
+
+diff --git a/drivers/net/ethernet/sfc/ef100_netdev.c b/drivers/net/ethernet/sfc/ef100_netdev.c
+index 7f7d560cb2b4c..d941f073f1ebf 100644
+--- a/drivers/net/ethernet/sfc/ef100_netdev.c
++++ b/drivers/net/ethernet/sfc/ef100_netdev.c
+@@ -452,7 +452,6 @@ int ef100_probe_netdev(struct efx_probe_data *probe_data)
+                                 NETIF_F_HIGHDMA | NETIF_F_ALL_TSO;
+       netif_set_tso_max_segs(net_dev,
+                              ESE_EF100_DP_GZ_TSO_MAX_HDR_NUM_SEGS_DEFAULT);
+-      efx->mdio.dev = net_dev;
+       rc = efx_ef100_init_datapath_caps(efx);
+       if (rc < 0)
+diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
+index 650136dfc642f..112e55b98ed3b 100644
+--- a/drivers/net/ethernet/sfc/efx.c
++++ b/drivers/net/ethernet/sfc/efx.c
+@@ -474,28 +474,6 @@ void efx_get_irq_moderation(struct efx_nic *efx, unsigned int *tx_usecs,
+       }
+ }
+-/**************************************************************************
+- *
+- * ioctls
+- *
+- *************************************************************************/
+-
+-/* Net device ioctl
+- * Context: process, rtnl_lock() held.
+- */
+-static int efx_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd)
+-{
+-      struct efx_nic *efx = efx_netdev_priv(net_dev);
+-      struct mii_ioctl_data *data = if_mii(ifr);
+-
+-      /* Convert phy_id from older PRTAD/DEVAD format */
+-      if ((cmd == SIOCGMIIREG || cmd == SIOCSMIIREG) &&
+-          (data->phy_id & 0xfc00) == 0x0400)
+-              data->phy_id ^= MDIO_PHY_ID_C45 | 0x0400;
+-
+-      return mdio_mii_ioctl(&efx->mdio, data, cmd);
+-}
+-
+ /**************************************************************************
+  *
+  * Kernel net device interface
+@@ -593,7 +571,6 @@ static const struct net_device_ops efx_netdev_ops = {
+       .ndo_tx_timeout         = efx_watchdog,
+       .ndo_start_xmit         = efx_hard_start_xmit,
+       .ndo_validate_addr      = eth_validate_addr,
+-      .ndo_eth_ioctl          = efx_ioctl,
+       .ndo_change_mtu         = efx_change_mtu,
+       .ndo_set_mac_address    = efx_set_mac_address,
+       .ndo_set_rx_mode        = efx_set_rx_mode,
+@@ -1201,7 +1178,6 @@ static int efx_pci_probe(struct pci_dev *pci_dev,
+       rc = efx_init_struct(efx, pci_dev);
+       if (rc)
+               goto fail1;
+-      efx->mdio.dev = net_dev;
+       pci_info(pci_dev, "Solarflare NIC detected\n");
+diff --git a/drivers/net/ethernet/sfc/mcdi_port.c b/drivers/net/ethernet/sfc/mcdi_port.c
+index ad4694fa3ddae..7b236d291d8c2 100644
+--- a/drivers/net/ethernet/sfc/mcdi_port.c
++++ b/drivers/net/ethernet/sfc/mcdi_port.c
+@@ -17,58 +17,6 @@
+ #include "selftest.h"
+ #include "mcdi_port_common.h"
+-static int efx_mcdi_mdio_read(struct net_device *net_dev,
+-                            int prtad, int devad, u16 addr)
+-{
+-      struct efx_nic *efx = efx_netdev_priv(net_dev);
+-      MCDI_DECLARE_BUF(inbuf, MC_CMD_MDIO_READ_IN_LEN);
+-      MCDI_DECLARE_BUF(outbuf, MC_CMD_MDIO_READ_OUT_LEN);
+-      size_t outlen;
+-      int rc;
+-
+-      MCDI_SET_DWORD(inbuf, MDIO_READ_IN_BUS, efx->mdio_bus);
+-      MCDI_SET_DWORD(inbuf, MDIO_READ_IN_PRTAD, prtad);
+-      MCDI_SET_DWORD(inbuf, MDIO_READ_IN_DEVAD, devad);
+-      MCDI_SET_DWORD(inbuf, MDIO_READ_IN_ADDR, addr);
+-
+-      rc = efx_mcdi_rpc(efx, MC_CMD_MDIO_READ, inbuf, sizeof(inbuf),
+-                        outbuf, sizeof(outbuf), &outlen);
+-      if (rc)
+-              return rc;
+-
+-      if (MCDI_DWORD(outbuf, MDIO_READ_OUT_STATUS) !=
+-          MC_CMD_MDIO_STATUS_GOOD)
+-              return -EIO;
+-
+-      return (u16)MCDI_DWORD(outbuf, MDIO_READ_OUT_VALUE);
+-}
+-
+-static int efx_mcdi_mdio_write(struct net_device *net_dev,
+-                             int prtad, int devad, u16 addr, u16 value)
+-{
+-      struct efx_nic *efx = efx_netdev_priv(net_dev);
+-      MCDI_DECLARE_BUF(inbuf, MC_CMD_MDIO_WRITE_IN_LEN);
+-      MCDI_DECLARE_BUF(outbuf, MC_CMD_MDIO_WRITE_OUT_LEN);
+-      size_t outlen;
+-      int rc;
+-
+-      MCDI_SET_DWORD(inbuf, MDIO_WRITE_IN_BUS, efx->mdio_bus);
+-      MCDI_SET_DWORD(inbuf, MDIO_WRITE_IN_PRTAD, prtad);
+-      MCDI_SET_DWORD(inbuf, MDIO_WRITE_IN_DEVAD, devad);
+-      MCDI_SET_DWORD(inbuf, MDIO_WRITE_IN_ADDR, addr);
+-      MCDI_SET_DWORD(inbuf, MDIO_WRITE_IN_VALUE, value);
+-
+-      rc = efx_mcdi_rpc(efx, MC_CMD_MDIO_WRITE, inbuf, sizeof(inbuf),
+-                        outbuf, sizeof(outbuf), &outlen);
+-      if (rc)
+-              return rc;
+-
+-      if (MCDI_DWORD(outbuf, MDIO_WRITE_OUT_STATUS) !=
+-          MC_CMD_MDIO_STATUS_GOOD)
+-              return -EIO;
+-
+-      return 0;
+-}
+ u32 efx_mcdi_phy_get_caps(struct efx_nic *efx)
+ {
+@@ -97,12 +45,7 @@ int efx_mcdi_port_probe(struct efx_nic *efx)
+ {
+       int rc;
+-      /* Set up MDIO structure for PHY */
+-      efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
+-      efx->mdio.mdio_read = efx_mcdi_mdio_read;
+-      efx->mdio.mdio_write = efx_mcdi_mdio_write;
+-
+-      /* Fill out MDIO structure, loopback modes, and initial link state */
++      /* Fill out loopback modes and initial link state */
+       rc = efx_mcdi_phy_probe(efx);
+       if (rc != 0)
+               return rc;
+diff --git a/drivers/net/ethernet/sfc/mcdi_port_common.c b/drivers/net/ethernet/sfc/mcdi_port_common.c
+index 76ea26722ca46..dae684194ac8c 100644
+--- a/drivers/net/ethernet/sfc/mcdi_port_common.c
++++ b/drivers/net/ethernet/sfc/mcdi_port_common.c
+@@ -448,15 +448,6 @@ int efx_mcdi_phy_probe(struct efx_nic *efx)
+       efx->phy_data = phy_data;
+       efx->phy_type = phy_data->type;
+-      efx->mdio_bus = phy_data->channel;
+-      efx->mdio.prtad = phy_data->port;
+-      efx->mdio.mmds = phy_data->mmd_mask & ~(1 << MC_CMD_MMD_CLAUSE22);
+-      efx->mdio.mode_support = 0;
+-      if (phy_data->mmd_mask & (1 << MC_CMD_MMD_CLAUSE22))
+-              efx->mdio.mode_support |= MDIO_SUPPORTS_C22;
+-      if (phy_data->mmd_mask & ~(1 << MC_CMD_MMD_CLAUSE22))
+-              efx->mdio.mode_support |= MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
+-
+       caps = MCDI_DWORD(outbuf, GET_LINK_OUT_CAP);
+       if (caps & (1 << MC_CMD_PHY_CAP_AN_LBN))
+               mcdi_to_ethtool_linkset(phy_data->media, caps,
+@@ -546,8 +537,6 @@ void efx_mcdi_phy_get_link_ksettings(struct efx_nic *efx, struct ethtool_link_ks
+       cmd->base.port = mcdi_to_ethtool_media(phy_cfg->media);
+       cmd->base.phy_address = phy_cfg->port;
+       cmd->base.autoneg = !!(efx->link_advertising[0] & ADVERTISED_Autoneg);
+-      cmd->base.mdio_support = (efx->mdio.mode_support &
+-                            (MDIO_SUPPORTS_C45 | MDIO_SUPPORTS_C22));
+       mcdi_to_ethtool_linkset(phy_cfg->media, phy_cfg->supported_cap,
+                               cmd->link_modes.supported);
+diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
+index f70a7b7d6345c..1d3e0f3101d4f 100644
+--- a/drivers/net/ethernet/sfc/net_driver.h
++++ b/drivers/net/ethernet/sfc/net_driver.h
+@@ -15,7 +15,7 @@
+ #include <linux/ethtool.h>
+ #include <linux/if_vlan.h>
+ #include <linux/timer.h>
+-#include <linux/mdio.h>
++#include <linux/mii.h>
+ #include <linux/list.h>
+ #include <linux/pci.h>
+ #include <linux/device.h>
+@@ -956,8 +956,6 @@ struct efx_mae;
+  * @stats_buffer: DMA buffer for statistics
+  * @phy_type: PHY type
+  * @phy_data: PHY private data (including PHY-specific stats)
+- * @mdio: PHY MDIO interface
+- * @mdio_bus: PHY MDIO bus ID (only used by Siena)
+  * @phy_mode: PHY operating mode. Serialised by @mac_lock.
+  * @link_advertising: Autonegotiation advertising flags
+  * @fec_config: Forward Error Correction configuration flags.  For bit positions
+@@ -1131,8 +1129,6 @@ struct efx_nic {
+       unsigned int phy_type;
+       void *phy_data;
+-      struct mdio_if_info mdio;
+-      unsigned int mdio_bus;
+       enum efx_phy_mode phy_mode;
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(link_advertising);
+-- 
+2.39.5
+
diff --git a/queue-6.14/smack-dont-compile-ipv6-code-unless-ipv6-is-configur.patch b/queue-6.14/smack-dont-compile-ipv6-code-unless-ipv6-is-configur.patch
new file mode 100644 (file)
index 0000000..5e12091
--- /dev/null
@@ -0,0 +1,133 @@
+From b856c7eeffb4b44c33c40fc8db7252297354d22f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jan 2025 19:36:42 +0300
+Subject: smack: dont compile ipv6 code unless ipv6 is configured
+
+From: Konstantin Andreev <andreev@swemel.ru>
+
+[ Upstream commit bfcf4004bcbce2cb674b4e8dbd31ce0891766bac ]
+
+I want to be sure that ipv6-specific code
+is not compiled in kernel binaries
+if ipv6 is not configured.
+
+[1] was getting rid of "unused variable" warning, but,
+with that, it also mandated compilation of a handful ipv6-
+specific functions in ipv4-only kernel configurations:
+
+smk_ipv6_localhost, smack_ipv6host_label, smk_ipv6_check.
+
+Their compiled bodies are likely to be removed by compiler
+from the resulting binary, but, to be on the safe side,
+I remove them from the compiler view.
+
+[1]
+Fixes: 00720f0e7f28 ("smack: avoid unused 'sip' variable warning")
+
+Signed-off-by: Konstantin Andreev <andreev@swemel.ru>
+Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/smack/smack.h     |  6 ++++++
+ security/smack/smack_lsm.c | 10 +++++++++-
+ 2 files changed, 15 insertions(+), 1 deletion(-)
+
+diff --git a/security/smack/smack.h b/security/smack/smack.h
+index 4608b07607a3d..c4d998972ba56 100644
+--- a/security/smack/smack.h
++++ b/security/smack/smack.h
+@@ -152,6 +152,7 @@ struct smk_net4addr {
+       struct smack_known      *smk_label;     /* label */
+ };
++#if IS_ENABLED(CONFIG_IPV6)
+ /*
+  * An entry in the table identifying IPv6 hosts.
+  */
+@@ -162,7 +163,9 @@ struct smk_net6addr {
+       int                     smk_masks;      /* mask size */
+       struct smack_known      *smk_label;     /* label */
+ };
++#endif /* CONFIG_IPV6 */
++#ifdef SMACK_IPV6_PORT_LABELING
+ /*
+  * An entry in the table identifying ports.
+  */
+@@ -175,6 +178,7 @@ struct smk_port_label {
+       short                   smk_sock_type;  /* Socket type */
+       short                   smk_can_reuse;
+ };
++#endif /* SMACK_IPV6_PORT_LABELING */
+ struct smack_known_list_elem {
+       struct list_head        list;
+@@ -315,7 +319,9 @@ extern struct smack_known smack_known_web;
+ extern struct mutex   smack_known_lock;
+ extern struct list_head smack_known_list;
+ extern struct list_head smk_net4addr_list;
++#if IS_ENABLED(CONFIG_IPV6)
+ extern struct list_head smk_net6addr_list;
++#endif /* CONFIG_IPV6 */
+ extern struct mutex     smack_onlycap_lock;
+ extern struct list_head smack_onlycap_list;
+diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
+index 239773cdcdcf4..85f3d4337ca19 100644
+--- a/security/smack/smack_lsm.c
++++ b/security/smack/smack_lsm.c
+@@ -2492,6 +2492,7 @@ static struct smack_known *smack_ipv4host_label(struct sockaddr_in *sip)
+       return NULL;
+ }
++#if IS_ENABLED(CONFIG_IPV6)
+ /*
+  * smk_ipv6_localhost - Check for local ipv6 host address
+  * @sip: the address
+@@ -2559,6 +2560,7 @@ static struct smack_known *smack_ipv6host_label(struct sockaddr_in6 *sip)
+       return NULL;
+ }
++#endif /* CONFIG_IPV6 */
+ /**
+  * smack_netlbl_add - Set the secattr on a socket
+@@ -2663,6 +2665,7 @@ static int smk_ipv4_check(struct sock *sk, struct sockaddr_in *sap)
+       return rc;
+ }
++#if IS_ENABLED(CONFIG_IPV6)
+ /**
+  * smk_ipv6_check - check Smack access
+  * @subject: subject Smack label
+@@ -2695,6 +2698,7 @@ static int smk_ipv6_check(struct smack_known *subject,
+       rc = smk_bu_note("IPv6 check", subject, object, MAY_WRITE, rc);
+       return rc;
+ }
++#endif /* CONFIG_IPV6 */
+ #ifdef SMACK_IPV6_PORT_LABELING
+ /**
+@@ -3027,7 +3031,9 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap,
+               return 0;
+       if (addrlen < offsetofend(struct sockaddr, sa_family))
+               return 0;
+-      if (IS_ENABLED(CONFIG_IPV6) && sap->sa_family == AF_INET6) {
++
++#if IS_ENABLED(CONFIG_IPV6)
++      if (sap->sa_family == AF_INET6) {
+               struct sockaddr_in6 *sip = (struct sockaddr_in6 *)sap;
+               struct smack_known *rsp = NULL;
+@@ -3047,6 +3053,8 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap,
+               return rc;
+       }
++#endif /* CONFIG_IPV6 */
++
+       if (sap->sa_family != AF_INET || addrlen < sizeof(struct sockaddr_in))
+               return 0;
+       rc = smk_ipv4_check(sock->sk, (struct sockaddr_in *)sap);
+-- 
+2.39.5
+
diff --git a/queue-6.14/smack-ipv4-ipv6-tcp-dccp-sctp-fix-incorrect-child-so.patch b/queue-6.14/smack-ipv4-ipv6-tcp-dccp-sctp-fix-incorrect-child-so.patch
new file mode 100644 (file)
index 0000000..f9e5872
--- /dev/null
@@ -0,0 +1,181 @@
+From 68480fcbb91b7474332696173b40b6c1b055fafb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 26 Jan 2025 17:07:27 +0300
+Subject: smack: ipv4/ipv6: tcp/dccp/sctp: fix incorrect child socket label
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Konstantin Andreev <andreev@swemel.ru>
+
+[ Upstream commit 6cce0cc3861337b3ad8d4ac131d6e47efa0954ec ]
+
+Since inception [1], SMACK initializes ipv* child socket security
+for connection-oriented communications (tcp/sctp/dccp)
+during accept() syscall, in the security_sock_graft() hook:
+
+| void smack_sock_graft(struct sock *sk, ...)
+| {
+|     // only ipv4 and ipv6 are eligible here
+|     // ...
+|     ssp = sk->sk_security; // socket security
+|     ssp->smk_in = skp;     // process label: smk_of_current()
+|     ssp->smk_out = skp;    // process label: smk_of_current()
+| }
+
+This approach is incorrect for two reasons:
+
+A) initialization occurs too late for child socket security:
+
+   The child socket is created by the kernel once the handshake
+   completes (e.g., for tcp: after receiving ack for syn+ack).
+
+   Data can legitimately start arriving to the child socket
+   immediately, long before the application calls accept()
+   on the socket.
+
+   Those data are (currently — were) processed by SMACK using
+   incorrect child socket security attributes.
+
+B) Incoming connection requests are handled using the listening
+   socket's security, hence, the child socket must inherit the
+   listening socket's security attributes.
+
+   smack_sock_graft() initilizes the child socket's security with
+   a process label, as is done for a new socket()
+
+   But ... the process label is not necessarily the same as the
+   listening socket label. A privileged application may legitimately
+   set other in/out labels for a listening socket.
+
+   When this happens, SMACK processes incoming packets using
+   incorrect socket security attributes.
+
+In [2] Michael Lontke noticed (A) and fixed it in [3] by adding
+socket initialization into security_sk_clone_security() hook like
+
+| void smack_sk_clone_security(struct sock *oldsk, struct sock *newsk)
+| {
+|    *(struct socket_smack *)newsk->sk_security =
+|    *(struct socket_smack *)oldsk->sk_security;
+| }
+
+This initializes the child socket security with the parent (listening)
+socket security at the appropriate time.
+
+I was forced to revisit this old story because
+
+smack_sock_graft() was left in place by [3] and continues overwriting
+the child socket's labels with the process label,
+and there might be a reason for this, so I undertook a study.
+
+If the process label differs from the listening socket's labels,
+the following occurs for ipv4:
+
+assigning the smk_out is not accompanied by netlbl_sock_setattr,
+so the outgoing packet's cipso label does not change.
+
+So, the only effect of this assignment for interhost communications
+is a divergence between the program-visible “out” socket label and
+the cipso network label. For intrahost communications this label,
+however, becomes visible via secmark netfilter marking, and is
+checked for access rights by the client, receiving side.
+
+Assigning the smk_in affects both interhost and intrahost
+communications: the server begins to check access rights against
+an wrong label.
+
+Access check against wrong label (smk_in or smk_out),
+unsurprisingly fails, breaking the connection.
+
+The above affects protocols that calls security_sock_graft()
+during accept(), namely: {tcp,dccp,sctp}/{ipv4,ipv6}
+One extra security_sock_graft() caller, crypto/af_alg.c`af_alg_accept
+is not affected, because smack_sock_graft() does nothing for PF_ALG.
+
+To reproduce, assign non-default in/out labels to a listening socket,
+setup rules between these labels and client label, attempt to connect
+and send some data.
+
+Ipv6 specific: ipv6 packets do not convey SMACK labels. To reproduce
+the issue in interhost communications set opposite labels in
+/smack/ipv6host on both hosts.
+Ipv6 intrahost communications do not require tricking, because SMACK
+labels are conveyed via secmark netfilter marking.
+
+So, currently smack_sock_graft() is not useful, but harmful,
+therefore, I have removed it.
+
+This fixes the issue for {tcp,dccp}/{ipv4,ipv6},
+but not sctp/{ipv4,ipv6}.
+
+Although this change is necessary for sctp+smack to function
+correctly, it is not sufficient because:
+sctp/ipv4 does not call security_sk_clone() and
+sctp/ipv6 ignores SMACK completely.
+
+These are separate issues, belong to other subsystem,
+and should be addressed separately.
+
+[1] 2008-02-04,
+Fixes: e114e473771c ("Smack: Simplified Mandatory Access Control Kernel")
+
+[2] Michael Lontke, 2022-08-31, SMACK LSM checks wrong object label
+                                during ingress network traffic
+Link: https://lore.kernel.org/linux-security-module/6324997ce4fc092c5020a4add075257f9c5f6442.camel@elektrobit.com/
+
+[3] 2022-08-31, michael.lontke,
+    commit 4ca165fc6c49 ("SMACK: Add sk_clone_security LSM hook")
+
+Signed-off-by: Konstantin Andreev <andreev@swemel.ru>
+Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/smack/smack_lsm.c | 24 ------------------------
+ 1 file changed, 24 deletions(-)
+
+diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
+index 85f3d4337ca19..e68c982e499eb 100644
+--- a/security/smack/smack_lsm.c
++++ b/security/smack/smack_lsm.c
+@@ -4350,29 +4350,6 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
+       return 0;
+ }
+-/**
+- * smack_sock_graft - Initialize a newly created socket with an existing sock
+- * @sk: child sock
+- * @parent: parent socket
+- *
+- * Set the smk_{in,out} state of an existing sock based on the process that
+- * is creating the new socket.
+- */
+-static void smack_sock_graft(struct sock *sk, struct socket *parent)
+-{
+-      struct socket_smack *ssp;
+-      struct smack_known *skp = smk_of_current();
+-
+-      if (sk == NULL ||
+-          (sk->sk_family != PF_INET && sk->sk_family != PF_INET6))
+-              return;
+-
+-      ssp = smack_sock(sk);
+-      ssp->smk_in = skp;
+-      ssp->smk_out = skp;
+-      /* cssp->smk_packet is already set in smack_inet_csk_clone() */
+-}
+-
+ /**
+  * smack_inet_conn_request - Smack access check on connect
+  * @sk: socket involved
+@@ -5187,7 +5164,6 @@ static struct security_hook_list smack_hooks[] __ro_after_init = {
+       LSM_HOOK_INIT(sk_free_security, smack_sk_free_security),
+ #endif
+       LSM_HOOK_INIT(sk_clone_security, smack_sk_clone_security),
+-      LSM_HOOK_INIT(sock_graft, smack_sock_graft),
+       LSM_HOOK_INIT(inet_conn_request, smack_inet_conn_request),
+       LSM_HOOK_INIT(inet_csk_clone, smack_inet_csk_clone),
+-- 
+2.39.5
+
diff --git a/queue-6.14/smb-client-fix-netns-refcount-imbalance-causing-leak.patch b/queue-6.14/smb-client-fix-netns-refcount-imbalance-causing-leak.patch
new file mode 100644 (file)
index 0000000..94df939
--- /dev/null
@@ -0,0 +1,175 @@
+From 1804af0a24ba4e230e76db0e2867e500182c325c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Feb 2025 22:30:05 +0800
+Subject: smb: client: Fix netns refcount imbalance causing leaks and
+ use-after-free
+
+From: Wang Zhaolong <wangzhaolong1@huawei.com>
+
+[ Upstream commit 4e7f1644f2ac6d01dc584f6301c3b1d5aac4eaef ]
+
+Commit ef7134c7fc48 ("smb: client: Fix use-after-free of network
+namespace.") attempted to fix a netns use-after-free issue by manually
+adjusting reference counts via sk->sk_net_refcnt and sock_inuse_add().
+
+However, a later commit e9f2517a3e18 ("smb: client: fix TCP timers deadlock
+after rmmod") pointed out that the approach of manually setting
+sk->sk_net_refcnt in the first commit was technically incorrect, as
+sk->sk_net_refcnt should only be set for user sockets. It led to issues
+like TCP timers not being cleared properly on close. The second commit
+moved to a model of just holding an extra netns reference for
+server->ssocket using get_net(), and dropping it when the server is torn
+down.
+
+But there remain some gaps in the get_net()/put_net() balancing added by
+these commits. The incomplete reference handling in these fixes results
+in two issues:
+
+1. Netns refcount leaks[1]
+
+The problem process is as follows:
+
+```
+mount.cifs                        cifsd
+
+cifs_do_mount
+  cifs_mount
+    cifs_mount_get_session
+      cifs_get_tcp_session
+        get_net()  /* First get net. */
+        ip_connect
+          generic_ip_connect /* Try port 445 */
+            get_net()
+            ->connect() /* Failed */
+            put_net()
+          generic_ip_connect /* Try port 139 */
+            get_net() /* Missing matching put_net() for this get_net().*/
+      cifs_get_smb_ses
+        cifs_negotiate_protocol
+          smb2_negotiate
+            SMB2_negotiate
+              cifs_send_recv
+                wait_for_response
+                                 cifs_demultiplex_thread
+                                   cifs_read_from_socket
+                                     cifs_readv_from_socket
+                                       cifs_reconnect
+                                         cifs_abort_connection
+                                           sock_release();
+                                           server->ssocket = NULL;
+                                           /* Missing put_net() here. */
+                                           generic_ip_connect
+                                             get_net()
+                                             ->connect() /* Failed */
+                                             put_net()
+                                             sock_release();
+                                             server->ssocket = NULL;
+          free_rsp_buf
+    ...
+                                   clean_demultiplex_info
+                                     /* It's only called once here. */
+                                     put_net()
+```
+
+When cifs_reconnect() is triggered, the server->ssocket is released
+without a corresponding put_net() for the reference acquired in
+generic_ip_connect() before. it ends up calling generic_ip_connect()
+again to retry get_net(). After that, server->ssocket is set to NULL
+in the error path of generic_ip_connect(), and the net count cannot be
+released in the final clean_demultiplex_info() function.
+
+2. Potential use-after-free
+
+The current refcounting scheme can lead to a potential use-after-free issue
+in the following scenario:
+
+```
+ cifs_do_mount
+   cifs_mount
+     cifs_mount_get_session
+       cifs_get_tcp_session
+         get_net()  /* First get net */
+           ip_connect
+             generic_ip_connect
+               get_net()
+               bind_socket
+                kernel_bind /* failed */
+               put_net()
+         /* after out_err_crypto_release label */
+         put_net()
+         /* after out_err label */
+         put_net()
+```
+
+In the exception handling process where binding the socket fails, the
+get_net() and put_net() calls are unbalanced, which may cause the
+server->net reference count to drop to zero and be prematurely released.
+
+To address both issues, this patch ties the netns reference counting to
+the server->ssocket and server lifecycles. The extra reference is now
+acquired when the server or socket is created, and released when the
+socket is destroyed or the server is torn down.
+
+[1]: https://bugzilla.kernel.org/show_bug.cgi?id=219792
+
+Fixes: ef7134c7fc48 ("smb: client: Fix use-after-free of network namespace.")
+Fixes: e9f2517a3e18 ("smb: client: fix TCP timers deadlock after rmmod")
+Signed-off-by: Wang Zhaolong <wangzhaolong1@huawei.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/connect.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
+index 73f93a35eeddb..cb14a6828c501 100644
+--- a/fs/smb/client/connect.c
++++ b/fs/smb/client/connect.c
+@@ -300,6 +300,7 @@ cifs_abort_connection(struct TCP_Server_Info *server)
+                        server->ssocket->flags);
+               sock_release(server->ssocket);
+               server->ssocket = NULL;
++              put_net(cifs_net_ns(server));
+       }
+       server->sequence_number = 0;
+       server->session_estab = false;
+@@ -3123,8 +3124,12 @@ generic_ip_connect(struct TCP_Server_Info *server)
+               /*
+                * Grab netns reference for the socket.
+                *
+-               * It'll be released here, on error, or in clean_demultiplex_info() upon server
+-               * teardown.
++               * This reference will be released in several situations:
++               * - In the failure path before the cifsd thread is started.
++               * - In the all place where server->socket is released, it is
++               *   also set to NULL.
++               * - Ultimately in clean_demultiplex_info(), during the final
++               *   teardown.
+                */
+               get_net(net);
+@@ -3140,10 +3145,8 @@ generic_ip_connect(struct TCP_Server_Info *server)
+       }
+       rc = bind_socket(server);
+-      if (rc < 0) {
+-              put_net(cifs_net_ns(server));
++      if (rc < 0)
+               return rc;
+-      }
+       /*
+        * Eventually check for other socket options to change from
+@@ -3189,9 +3192,6 @@ generic_ip_connect(struct TCP_Server_Info *server)
+       if (sport == htons(RFC1001_PORT))
+               rc = ip_rfc1001_connect(server);
+-      if (rc < 0)
+-              put_net(cifs_net_ns(server));
+-
+       return rc;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/soc-mediatek-mt8167-mmsys-fix-missing-regval-in-all-.patch b/queue-6.14/soc-mediatek-mt8167-mmsys-fix-missing-regval-in-all-.patch
new file mode 100644 (file)
index 0000000..25dcf84
--- /dev/null
@@ -0,0 +1,60 @@
+From 3359dfeaad6be3e4bd62ee14437b1b31ce4535b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Feb 2025 11:00:09 +0100
+Subject: soc: mediatek: mt8167-mmsys: Fix missing regval in all entries
+
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+[ Upstream commit 5424793452d134ec1a173bd748c757144f25b1e2 ]
+
+The mmsys routing table for this SoC was effectively missing
+initialization of the val variable of struct mtk_mmsys_routes:
+this means that `val` was incorrectly initialized to zero,
+hence the registers were wrongly initialized.
+
+Add the required regval to all of the entries of the routing
+table for this SoC to fix display controller functionality.
+
+Fixes: 060f7875bd23 ("soc: mediatek: mmsys: Add support for MT8167 SoC")
+Link: https://lore.kernel.org/r/20250212100012.33001-6-angelogioacchino.delregno@collabora.com
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/mediatek/mt8167-mmsys.h | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/soc/mediatek/mt8167-mmsys.h b/drivers/soc/mediatek/mt8167-mmsys.h
+index f7a35b3656bb1..655ef962abe9f 100644
+--- a/drivers/soc/mediatek/mt8167-mmsys.h
++++ b/drivers/soc/mediatek/mt8167-mmsys.h
+@@ -17,18 +17,23 @@ static const struct mtk_mmsys_routes mt8167_mmsys_routing_table[] = {
+       {
+               DDP_COMPONENT_OVL0, DDP_COMPONENT_COLOR0,
+               MT8167_DISP_REG_CONFIG_DISP_OVL0_MOUT_EN, OVL0_MOUT_EN_COLOR0,
++              OVL0_MOUT_EN_COLOR0
+       }, {
+               DDP_COMPONENT_DITHER0, DDP_COMPONENT_RDMA0,
+-              MT8167_DISP_REG_CONFIG_DISP_DITHER_MOUT_EN, MT8167_DITHER_MOUT_EN_RDMA0
++              MT8167_DISP_REG_CONFIG_DISP_DITHER_MOUT_EN, MT8167_DITHER_MOUT_EN_RDMA0,
++              MT8167_DITHER_MOUT_EN_RDMA0
+       }, {
+               DDP_COMPONENT_OVL0, DDP_COMPONENT_COLOR0,
+-              MT8167_DISP_REG_CONFIG_DISP_COLOR0_SEL_IN, COLOR0_SEL_IN_OVL0
++              MT8167_DISP_REG_CONFIG_DISP_COLOR0_SEL_IN, COLOR0_SEL_IN_OVL0,
++              COLOR0_SEL_IN_OVL0
+       }, {
+               DDP_COMPONENT_RDMA0, DDP_COMPONENT_DSI0,
+-              MT8167_DISP_REG_CONFIG_DISP_DSI0_SEL_IN, MT8167_DSI0_SEL_IN_RDMA0
++              MT8167_DISP_REG_CONFIG_DISP_DSI0_SEL_IN, MT8167_DSI0_SEL_IN_RDMA0,
++              MT8167_DSI0_SEL_IN_RDMA0
+       }, {
+               DDP_COMPONENT_RDMA0, DDP_COMPONENT_DSI0,
+-              MT8167_DISP_REG_CONFIG_DISP_RDMA0_SOUT_SEL_IN, MT8167_RDMA0_SOUT_DSI0
++              MT8167_DISP_REG_CONFIG_DISP_RDMA0_SOUT_SEL_IN, MT8167_RDMA0_SOUT_DSI0,
++              MT8167_RDMA0_SOUT_DSI0
+       },
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.14/soc-mediatek-mt8365-mmsys-fix-routing-table-masks-an.patch b/queue-6.14/soc-mediatek-mt8365-mmsys-fix-routing-table-masks-an.patch
new file mode 100644 (file)
index 0000000..5ba1860
--- /dev/null
@@ -0,0 +1,127 @@
+From f7a34c8b1f18ef8df86a3243011a3941e7970c77 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Feb 2025 11:00:10 +0100
+Subject: soc: mediatek: mt8365-mmsys: Fix routing table masks and values
+
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+[ Upstream commit d294d56cb9462e918421fe2bbe5f52a8da82603a ]
+
+The mmsys driver reads the routing table and writes to the
+hardware `val & mask`, but multiple entries in the mmsys
+routing table for the MT8365 SoC are setting a 0x0 mask:
+this effectively writes .. nothing .. to the hardware.
+
+That would never work, and if the display controller was
+actually working with the mmsys doing no routing at all,
+that was only because the bootloader was correctly setting
+the display controller routing registers before booting the
+kernel, and the mmsys was never reset.
+
+Make this table to actually set the routing by adding the
+correct register masks to it.
+
+While at it, also change MOUT val definitions to BIT(x), as
+the MOUT registers are effectively checking for each bit to
+enable output to the corresponding HW.
+Please note that, for this SoC, only the MOUT registers are
+checking bits (as those can enable multiple outputs), while
+the others are purely reading a number to select an input.
+
+Fixes: bc3fc5c05100 ("soc: mediatek: mmsys: add MT8365 support")
+Link: https://lore.kernel.org/r/20250212100012.33001-7-angelogioacchino.delregno@collabora.com
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/mediatek/mt8365-mmsys.h | 48 ++++++++++++-----------------
+ 1 file changed, 20 insertions(+), 28 deletions(-)
+
+diff --git a/drivers/soc/mediatek/mt8365-mmsys.h b/drivers/soc/mediatek/mt8365-mmsys.h
+index 7abaf048d91e8..ae37945e6c67c 100644
+--- a/drivers/soc/mediatek/mt8365-mmsys.h
++++ b/drivers/soc/mediatek/mt8365-mmsys.h
+@@ -14,8 +14,9 @@
+ #define MT8365_DISP_REG_CONFIG_DISP_DPI0_SEL_IN               0xfd8
+ #define MT8365_DISP_REG_CONFIG_DISP_LVDS_SYS_CFG_00   0xfdc
++#define MT8365_DISP_MS_IN_OUT_MASK                    GENMASK(3, 0)
+ #define MT8365_RDMA0_SOUT_COLOR0                      0x1
+-#define MT8365_DITHER_MOUT_EN_DSI0                    0x1
++#define MT8365_DITHER_MOUT_EN_DSI0                    BIT(0)
+ #define MT8365_DSI0_SEL_IN_DITHER                     0x1
+ #define MT8365_RDMA0_SEL_IN_OVL0                      0x0
+ #define MT8365_RDMA0_RSZ0_SEL_IN_RDMA0                        0x0
+@@ -30,52 +31,43 @@ static const struct mtk_mmsys_routes mt8365_mmsys_routing_table[] = {
+       {
+               DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
+               MT8365_DISP_REG_CONFIG_DISP_OVL0_MOUT_EN,
+-              MT8365_OVL0_MOUT_PATH0_SEL, MT8365_OVL0_MOUT_PATH0_SEL
+-      },
+-      {
++              MT8365_DISP_MS_IN_OUT_MASK, MT8365_OVL0_MOUT_PATH0_SEL
++      }, {
+               DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
+               MT8365_DISP_REG_CONFIG_DISP_RDMA0_SEL_IN,
+-              MT8365_RDMA0_SEL_IN_OVL0, MT8365_RDMA0_SEL_IN_OVL0
+-      },
+-      {
++              MT8365_DISP_MS_IN_OUT_MASK, MT8365_RDMA0_SEL_IN_OVL0
++      }, {
+               DDP_COMPONENT_RDMA0, DDP_COMPONENT_COLOR0,
+               MT8365_DISP_REG_CONFIG_DISP_RDMA0_SOUT_SEL,
+-              MT8365_RDMA0_SOUT_COLOR0, MT8365_RDMA0_SOUT_COLOR0
+-      },
+-      {
++              MT8365_DISP_MS_IN_OUT_MASK, MT8365_RDMA0_SOUT_COLOR0
++      }, {
+               DDP_COMPONENT_COLOR0, DDP_COMPONENT_CCORR,
+               MT8365_DISP_REG_CONFIG_DISP_COLOR0_SEL_IN,
+-              MT8365_DISP_COLOR_SEL_IN_COLOR0,MT8365_DISP_COLOR_SEL_IN_COLOR0
+-      },
+-      {
++              MT8365_DISP_MS_IN_OUT_MASK, MT8365_DISP_COLOR_SEL_IN_COLOR0
++      }, {
+               DDP_COMPONENT_DITHER0, DDP_COMPONENT_DSI0,
+               MT8365_DISP_REG_CONFIG_DISP_DITHER0_MOUT_EN,
+-              MT8365_DITHER_MOUT_EN_DSI0, MT8365_DITHER_MOUT_EN_DSI0
+-      },
+-      {
++              MT8365_DISP_MS_IN_OUT_MASK, MT8365_DITHER_MOUT_EN_DSI0
++      }, {
+               DDP_COMPONENT_DITHER0, DDP_COMPONENT_DSI0,
+               MT8365_DISP_REG_CONFIG_DISP_DSI0_SEL_IN,
+-              MT8365_DSI0_SEL_IN_DITHER, MT8365_DSI0_SEL_IN_DITHER
+-      },
+-      {
++              MT8365_DISP_MS_IN_OUT_MASK, MT8365_DSI0_SEL_IN_DITHER
++      }, {
+               DDP_COMPONENT_RDMA0, DDP_COMPONENT_COLOR0,
+               MT8365_DISP_REG_CONFIG_DISP_RDMA0_RSZ0_SEL_IN,
+-              MT8365_RDMA0_RSZ0_SEL_IN_RDMA0, MT8365_RDMA0_RSZ0_SEL_IN_RDMA0
+-      },
+-      {
++              MT8365_DISP_MS_IN_OUT_MASK, MT8365_RDMA0_RSZ0_SEL_IN_RDMA0
++      }, {
+               DDP_COMPONENT_RDMA1, DDP_COMPONENT_DPI0,
+               MT8365_DISP_REG_CONFIG_DISP_LVDS_SYS_CFG_00,
+               MT8365_LVDS_SYS_CFG_00_SEL_LVDS_PXL_CLK, MT8365_LVDS_SYS_CFG_00_SEL_LVDS_PXL_CLK
+-      },
+-      {
++      }, {
+               DDP_COMPONENT_RDMA1, DDP_COMPONENT_DPI0,
+               MT8365_DISP_REG_CONFIG_DISP_DPI0_SEL_IN,
+-              MT8365_DPI0_SEL_IN_RDMA1, MT8365_DPI0_SEL_IN_RDMA1
+-      },
+-      {
++              MT8365_DISP_MS_IN_OUT_MASK, MT8365_DPI0_SEL_IN_RDMA1
++      }, {
+               DDP_COMPONENT_RDMA1, DDP_COMPONENT_DPI0,
+               MT8365_DISP_REG_CONFIG_DISP_RDMA1_SOUT_SEL,
+-              MT8365_RDMA1_SOUT_DPI0, MT8365_RDMA1_SOUT_DPI0
++              MT8365_DISP_MS_IN_OUT_MASK, MT8365_RDMA1_SOUT_DPI0
+       },
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.14/soc-mediatek-mtk-mmsys-fix-mt8188-vdo1-dpi1-output-s.patch b/queue-6.14/soc-mediatek-mtk-mmsys-fix-mt8188-vdo1-dpi1-output-s.patch
new file mode 100644 (file)
index 0000000..7b733eb
--- /dev/null
@@ -0,0 +1,43 @@
+From 337f09dcb6b3b3d299f601cd916f2554343f4f84 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Feb 2025 11:00:06 +0100
+Subject: soc: mediatek: mtk-mmsys: Fix MT8188 VDO1 DPI1 output selection
+
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+[ Upstream commit 881d5094b138d002aab14922d41ec2058b9570c7 ]
+
+The VDO1_MERGE4 hardware (merge5 software component) should be
+set to enable output to DPI1_SEL by setting BIT(2) but, despite
+the intention being exactly that, this won't work because the
+declared register mask is wrong as it is set as GENMASK(1, 0).
+
+Register MERGE4_MOUT_EN in VDO1 has four used bits [3, 0] so
+fix the mask to reflect that.
+That, in turn, allows the mmsys driver to actually set BIT(2)
+in this register, fixing the MERGE4 output to DPI1 selection.
+
+Fixes: c0349314d5a0 ("soc: mediatek: Support MT8188 VDOSYS1 in mtk-mmsys")
+Link: https://lore.kernel.org/r/20250212100012.33001-3-angelogioacchino.delregno@collabora.com
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/mediatek/mt8188-mmsys.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/soc/mediatek/mt8188-mmsys.h b/drivers/soc/mediatek/mt8188-mmsys.h
+index 6bebf1a69fc07..a1d63be0a73dc 100644
+--- a/drivers/soc/mediatek/mt8188-mmsys.h
++++ b/drivers/soc/mediatek/mt8188-mmsys.h
+@@ -343,7 +343,7 @@ static const struct mtk_mmsys_routes mmsys_mt8188_vdo1_routing_table[] = {
+               MT8188_DISP_DPI1_SEL_IN_FROM_VPP_MERGE4_MOUT
+       }, {
+               DDP_COMPONENT_MERGE5, DDP_COMPONENT_DPI1,
+-              MT8188_VDO1_MERGE4_SOUT_SEL, GENMASK(1, 0),
++              MT8188_VDO1_MERGE4_SOUT_SEL, GENMASK(3, 0),
+               MT8188_MERGE4_SOUT_TO_DPI1_SEL
+       }, {
+               DDP_COMPONENT_MERGE5, DDP_COMPONENT_DP_INTF1,
+-- 
+2.39.5
+
diff --git a/queue-6.14/soundwire-slave-fix-an-of-node-reference-leak-in-sou.patch b/queue-6.14/soundwire-slave-fix-an-of-node-reference-leak-in-sou.patch
new file mode 100644 (file)
index 0000000..96e41d1
--- /dev/null
@@ -0,0 +1,40 @@
+From d9a327274d4d4ddba87fdb7c9f170dd65c482f11 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Dec 2024 12:48:44 +0900
+Subject: soundwire: slave: fix an OF node reference leak in soundwire slave
+ device
+
+From: Joe Hattori <joe@pf.is.s.u-tokyo.ac.jp>
+
+[ Upstream commit aac2f8363f773ae1f65aab140e06e2084ac6b787 ]
+
+When initializing a soundwire slave device, an OF node is stored to the
+device with refcount incremented. However, the refcount is not
+decremented in .release(), thus call of_node_put() in
+sdw_slave_release().
+
+Fixes: a2e484585ad3 ("soundwire: core: add device tree support for slave devices")
+Signed-off-by: Joe Hattori <joe@pf.is.s.u-tokyo.ac.jp>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20241205034844.2784964-1-joe@pf.is.s.u-tokyo.ac.jp
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soundwire/slave.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/soundwire/slave.c b/drivers/soundwire/slave.c
+index 4869b073b11c2..d2d99555ec5a5 100644
+--- a/drivers/soundwire/slave.c
++++ b/drivers/soundwire/slave.c
+@@ -13,6 +13,7 @@ static void sdw_slave_release(struct device *dev)
+ {
+       struct sdw_slave *slave = dev_to_sdw_dev(dev);
++      of_node_put(slave->dev.of_node);
+       mutex_destroy(&slave->sdw_dev_lock);
+       kfree(slave);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/soundwire-take-in-count-the-bandwidth-of-a-prepared-.patch b/queue-6.14/soundwire-take-in-count-the-bandwidth-of-a-prepared-.patch
new file mode 100644 (file)
index 0000000..25f2f91
--- /dev/null
@@ -0,0 +1,46 @@
+From 456ce3d1ce56ee009c1a06ada3103458df90a241 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Mar 2025 15:36:53 +0800
+Subject: soundwire: take in count the bandwidth of a prepared stream
+
+From: Bard Liao <yung-chuan.liao@linux.intel.com>
+
+[ Upstream commit 08ae0d61c3d79bb5d52ae30ad4fc12442e966a23 ]
+
+When a stream's state is marked as prepared, it is ready for
+playback/capture. Therefore, we need to include the stream's bandwidth
+when we calculate the required bandwidth of a bus.
+
+Fixes: 25befdf32aa40 ("soundwire: generic_bandwidth_allocation: count the bandwidth of active streams only")
+Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Link: https://github.com/thesofproject/linux/issues/5334
+Reviewed-by: Richard Fitzgerald <rf@opensource.cirrus.com>
+Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+Link: https://lore.kernel.org/r/20250310073653.56476-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 | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/soundwire/generic_bandwidth_allocation.c b/drivers/soundwire/generic_bandwidth_allocation.c
+index 59965f43c2fb0..f78a2a16581a7 100644
+--- a/drivers/soundwire/generic_bandwidth_allocation.c
++++ b/drivers/soundwire/generic_bandwidth_allocation.c
+@@ -194,10 +194,11 @@ static int sdw_compute_group_params(struct sdw_bus *bus,
+                               continue;
+               } else {
+                       /*
+-                       * Include runtimes with running (ENABLED state) and paused (DISABLED state)
+-                       * streams
++                       * Include runtimes with running (ENABLED/PREPARED state) and
++                       * paused (DISABLED state) streams
+                        */
+                       if (m_rt->stream->state != SDW_STREAM_ENABLED &&
++                          m_rt->stream->state != SDW_STREAM_PREPARED &&
+                           m_rt->stream->state != SDW_STREAM_DISABLED)
+                               continue;
+               }
+-- 
+2.39.5
+
diff --git a/queue-6.14/spi-bcm2835-do-not-call-gpiod_put-on-invalid-descrip.patch b/queue-6.14/spi-bcm2835-do-not-call-gpiod_put-on-invalid-descrip.patch
new file mode 100644 (file)
index 0000000..cbef891
--- /dev/null
@@ -0,0 +1,39 @@
+From 8e969a73a07d07d13f4a4cd9436d8ea712adf201 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 15:42:38 -0700
+Subject: spi: bcm2835: Do not call gpiod_put() on invalid descriptor
+
+From: Florian Fainelli <florian.fainelli@broadcom.com>
+
+[ Upstream commit d6691010523fe1016f482a1e1defcc6289eeea48 ]
+
+If we are unable to lookup the chip-select GPIO, the error path will
+call bcm2835_spi_cleanup() which unconditionally calls gpiod_put() on
+the cs->gpio variable which we just determined was invalid.
+
+Fixes: 21f252cd29f0 ("spi: bcm2835: reduce the abuse of the GPIO API")
+Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Link: https://patch.msgid.link/20250401224238.2854256-1-florian.fainelli@broadcom.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-bcm2835.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c
+index 0d1aa65924846..06a81727d74dd 100644
+--- a/drivers/spi/spi-bcm2835.c
++++ b/drivers/spi/spi-bcm2835.c
+@@ -1162,7 +1162,8 @@ static void bcm2835_spi_cleanup(struct spi_device *spi)
+                                sizeof(u32),
+                                DMA_TO_DEVICE);
+-      gpiod_put(bs->cs_gpio);
++      if (!IS_ERR(bs->cs_gpio))
++              gpiod_put(bs->cs_gpio);
+       spi_set_csgpiod(spi, 0, NULL);
+       kfree(target);
+-- 
+2.39.5
+
diff --git a/queue-6.14/spi-bcm2835-restore-native-cs-probing-when-pinctrl-b.patch b/queue-6.14/spi-bcm2835-restore-native-cs-probing-when-pinctrl-b.patch
new file mode 100644 (file)
index 0000000..e3b9ca8
--- /dev/null
@@ -0,0 +1,76 @@
+From bb1c94f7f3806f05dec0046d27d142920a4ff61f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 16:36:03 -0700
+Subject: spi: bcm2835: Restore native CS probing when pinctrl-bcm2835 is
+ absent
+
+From: Florian Fainelli <florian.fainelli@broadcom.com>
+
+[ Upstream commit e19c1272c80a5ecce387c1b0c3b995f4edf9c525 ]
+
+The lookup table forces the use of the "pinctrl-bcm2835" GPIO chip
+provider and essentially assumes that there is going to be such a
+provider, and if not, we will fail to set-up the SPI device.
+
+While this is true on Raspberry Pi based systems (2835/36/37, 2711,
+2712), this is not true on 7712/77122 Broadcom STB systems which use the
+SPI driver, but not the GPIO driver.
+
+There used to be an early check:
+
+       chip = gpiochip_find("pinctrl-bcm2835", chip_match_name);
+       if (!chip)
+               return 0;
+
+which would accomplish that nicely, bring something similar back by
+checking for the compatible strings matched by the pinctrl-bcm2835.c
+driver, if there is no Device Tree node matching those compatible
+strings, then we won't find any GPIO provider registered by the
+"pinctrl-bcm2835" driver.
+
+Fixes: 21f252cd29f0 ("spi: bcm2835: reduce the abuse of the GPIO API")
+Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Link: https://patch.msgid.link/20250401233603.2938955-1-florian.fainelli@broadcom.com
+Acked-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-bcm2835.c | 15 ++++++++++++++-
+ 1 file changed, 14 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c
+index 06a81727d74dd..77de5a07639af 100644
+--- a/drivers/spi/spi-bcm2835.c
++++ b/drivers/spi/spi-bcm2835.c
+@@ -1226,7 +1226,12 @@ static int bcm2835_spi_setup(struct spi_device *spi)
+       struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
+       struct bcm2835_spidev *target = spi_get_ctldata(spi);
+       struct gpiod_lookup_table *lookup __free(kfree) = NULL;
+-      int ret;
++      const char *pinctrl_compats[] = {
++              "brcm,bcm2835-gpio",
++              "brcm,bcm2711-gpio",
++              "brcm,bcm7211-gpio",
++      };
++      int ret, i;
+       u32 cs;
+       if (!target) {
+@@ -1291,6 +1296,14 @@ static int bcm2835_spi_setup(struct spi_device *spi)
+               goto err_cleanup;
+       }
++      for (i = 0; i < ARRAY_SIZE(pinctrl_compats); i++) {
++              if (of_find_compatible_node(NULL, NULL, pinctrl_compats[i]))
++                      break;
++      }
++
++      if (i == ARRAY_SIZE(pinctrl_compats))
++              return 0;
++
+       /*
+        * TODO: The code below is a slightly better alternative to the utter
+        * abuse of the GPIO API that I found here before. It creates a
+-- 
+2.39.5
+
diff --git a/queue-6.14/spi-cadence-fix-out-of-bounds-array-access-in-cdns_m.patch b/queue-6.14/spi-cadence-fix-out-of-bounds-array-access-in-cdns_m.patch
new file mode 100644 (file)
index 0000000..7d47e7b
--- /dev/null
@@ -0,0 +1,49 @@
+From 2179f4325e554f6c2dd360dbf872510c0e60a185 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Mar 2025 08:33:32 -0700
+Subject: spi: cadence: Fix out-of-bounds array access in
+ cdns_mrvl_xspi_setup_clock()
+
+From: Josh Poimboeuf <jpoimboe@kernel.org>
+
+[ Upstream commit 7ba0847fa1c22e7801cebfe5f7b75aee4fae317e ]
+
+If requested_clk > 128, cdns_mrvl_xspi_setup_clock() iterates over the
+entire cdns_mrvl_xspi_clk_div_list array without breaking out early,
+causing 'i' to go beyond the array bounds.
+
+Fix that by stopping the loop when it gets to the last entry, clamping
+the clock to the minimum 6.25 MHz.
+
+Fixes the following warning with an UBSAN kernel:
+
+  vmlinux.o: warning: objtool: cdns_mrvl_xspi_setup_clock: unexpected end of section .text.cdns_mrvl_xspi_setup_clock
+
+Fixes: 26d34fdc4971 ("spi: cadence: Add clock configuration for Marvell xSPI overlay")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202503282236.UhfRsF3B-lkp@intel.com/
+Link: https://lore.kernel.org/r/gs2ooxfkblnee6cc5yfcxh7nu4wvoqnuv4lrllkhccxgcac2jg@7snmwd73jkhs
+Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
+Link: https://patch.msgid.link/h6bef6wof6zpjfp3jbhrkigqsnykdfy6j4qmmvb6gsabhianhj@k57a7hwpa3bj
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-cadence-xspi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-cadence-xspi.c b/drivers/spi/spi-cadence-xspi.c
+index aed98ab143346..6dcba0e0ddaa3 100644
+--- a/drivers/spi/spi-cadence-xspi.c
++++ b/drivers/spi/spi-cadence-xspi.c
+@@ -432,7 +432,7 @@ static bool cdns_mrvl_xspi_setup_clock(struct cdns_xspi_dev *cdns_xspi,
+       u32 clk_reg;
+       bool update_clk = false;
+-      while (i < ARRAY_SIZE(cdns_mrvl_xspi_clk_div_list)) {
++      while (i < (ARRAY_SIZE(cdns_mrvl_xspi_clk_div_list) - 1)) {
+               clk_val = MRVL_XSPI_CLOCK_DIVIDED(
+                               cdns_mrvl_xspi_clk_div_list[i]);
+               if (clk_val <= requested_clk)
+-- 
+2.39.5
+
diff --git a/queue-6.14/spufs-fix-a-leak-in-spufs_create_context.patch b/queue-6.14/spufs-fix-a-leak-in-spufs_create_context.patch
new file mode 100644 (file)
index 0000000..e7b22d2
--- /dev/null
@@ -0,0 +1,39 @@
+From 61c62a81da3f68150692440fe99a48e8af0d64a4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Mar 2025 19:38:28 -0400
+Subject: spufs: fix a leak in spufs_create_context()
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+[ Upstream commit 0f5cce3fc55b08ee4da3372baccf4bcd36a98396 ]
+
+Leak fixes back in 2008 missed one case - if we are trying to set affinity
+and spufs_mkdir() fails, we need to drop the reference to neighbor.
+
+Fixes: 58119068cb27 "[POWERPC] spufs: Fix memory leak on SPU affinity"
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/cell/spufs/inode.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
+index c566e7997f2c1..9f9e4b8716278 100644
+--- a/arch/powerpc/platforms/cell/spufs/inode.c
++++ b/arch/powerpc/platforms/cell/spufs/inode.c
+@@ -460,8 +460,11 @@ spufs_create_context(struct inode *inode, struct dentry *dentry,
+       }
+       ret = spufs_mkdir(inode, dentry, flags, mode & 0777);
+-      if (ret)
++      if (ret) {
++              if (neighbor)
++                      put_spu_context(neighbor);
+               goto out_aff_unlock;
++      }
+       if (affinity) {
+               spufs_set_affinity(flags, SPUFS_I(d_inode(dentry))->i_ctx,
+-- 
+2.39.5
+
diff --git a/queue-6.14/spufs-fix-a-leak-on-spufs_new_file-failure.patch b/queue-6.14/spufs-fix-a-leak-on-spufs_new_file-failure.patch
new file mode 100644 (file)
index 0000000..408c62a
--- /dev/null
@@ -0,0 +1,40 @@
+From d673f2c311897cde5d354cbb57928d175ed9b92e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Mar 2025 19:26:31 -0500
+Subject: spufs: fix a leak on spufs_new_file() failure
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+[ Upstream commit d1ca8698ca1332625d83ea0d753747be66f9906d ]
+
+It's called from spufs_fill_dir(), and caller of that will do
+spufs_rmdir() in case of failure.  That does remove everything
+we'd managed to create, but... the problem dentry is still
+negative.  IOW, it needs to be explicitly dropped.
+
+Fixes: 3f51dd91c807 "[PATCH] spufs: fix spufs_fill_dir error path"
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/cell/spufs/inode.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
+index 70236d1df3d3e..793c005607cf0 100644
+--- a/arch/powerpc/platforms/cell/spufs/inode.c
++++ b/arch/powerpc/platforms/cell/spufs/inode.c
+@@ -192,8 +192,10 @@ static int spufs_fill_dir(struct dentry *dir,
+                       return -ENOMEM;
+               ret = spufs_new_file(dir->d_sb, dentry, files->ops,
+                                       files->mode & mode, files->size, ctx);
+-              if (ret)
++              if (ret) {
++                      dput(dentry);
+                       return ret;
++              }
+               files++;
+       }
+       return 0;
+-- 
+2.39.5
+
diff --git a/queue-6.14/spufs-fix-gang-directory-lifetimes.patch b/queue-6.14/spufs-fix-gang-directory-lifetimes.patch
new file mode 100644 (file)
index 0000000..e260c96
--- /dev/null
@@ -0,0 +1,195 @@
+From 6dc1c5f87051adc8cc7fcfbcef387da465a58fe2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Mar 2025 19:18:39 -0400
+Subject: spufs: fix gang directory lifetimes
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+[ Upstream commit c134deabf4784e155d360744d4a6a835b9de4dd4 ]
+
+prior to "[POWERPC] spufs: Fix gang destroy leaks" we used to have
+a problem with gang lifetimes - creation of a gang returns opened
+gang directory, which normally gets removed when that gets closed,
+but if somebody has created a context belonging to that gang and
+kept it alive until the gang got closed, removal failed and we
+ended up with a leak.
+
+Unfortunately, it had been fixed the wrong way.  Dentry of gang
+directory was no longer pinned, and rmdir on close was gone.
+One problem was that failure of open kept calling simple_rmdir()
+as cleanup, which meant an unbalanced dput().  Another bug was
+in the success case - gang creation incremented link count on
+root directory, but that was no longer undone when gang got
+destroyed.
+
+Fix consists of
+       * reverting the commit in question
+       * adding a counter to gang, protected by ->i_rwsem
+of gang directory inode.
+       * having it set to 1 at creation time, dropped
+in both spufs_dir_close() and spufs_gang_close() and bumped
+in spufs_create_context(), provided that it's not 0.
+       * using simple_recursive_removal() to take the gang
+directory out when counter reaches zero.
+
+Fixes: 877907d37da9 "[POWERPC] spufs: Fix gang destroy leaks"
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/cell/spufs/gang.c  |  1 +
+ arch/powerpc/platforms/cell/spufs/inode.c | 54 +++++++++++++++++++----
+ arch/powerpc/platforms/cell/spufs/spufs.h |  2 +
+ 3 files changed, 49 insertions(+), 8 deletions(-)
+
+diff --git a/arch/powerpc/platforms/cell/spufs/gang.c b/arch/powerpc/platforms/cell/spufs/gang.c
+index 827d338deaf4c..2c2999de6bfa2 100644
+--- a/arch/powerpc/platforms/cell/spufs/gang.c
++++ b/arch/powerpc/platforms/cell/spufs/gang.c
+@@ -25,6 +25,7 @@ struct spu_gang *alloc_spu_gang(void)
+       mutex_init(&gang->aff_mutex);
+       INIT_LIST_HEAD(&gang->list);
+       INIT_LIST_HEAD(&gang->aff_list_head);
++      gang->alive = 1;
+ out:
+       return gang;
+diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
+index 793c005607cf0..c566e7997f2c1 100644
+--- a/arch/powerpc/platforms/cell/spufs/inode.c
++++ b/arch/powerpc/platforms/cell/spufs/inode.c
+@@ -201,6 +201,23 @@ static int spufs_fill_dir(struct dentry *dir,
+       return 0;
+ }
++static void unuse_gang(struct dentry *dir)
++{
++      struct inode *inode = dir->d_inode;
++      struct spu_gang *gang = SPUFS_I(inode)->i_gang;
++
++      if (gang) {
++              bool dead;
++
++              inode_lock(inode); // exclusion with spufs_create_context()
++              dead = !--gang->alive;
++              inode_unlock(inode);
++
++              if (dead)
++                      simple_recursive_removal(dir, NULL);
++      }
++}
++
+ static int spufs_dir_close(struct inode *inode, struct file *file)
+ {
+       struct inode *parent;
+@@ -215,6 +232,7 @@ static int spufs_dir_close(struct inode *inode, struct file *file)
+       inode_unlock(parent);
+       WARN_ON(ret);
++      unuse_gang(dir->d_parent);
+       return dcache_dir_close(inode, file);
+ }
+@@ -407,7 +425,7 @@ spufs_create_context(struct inode *inode, struct dentry *dentry,
+ {
+       int ret;
+       int affinity;
+-      struct spu_gang *gang;
++      struct spu_gang *gang = SPUFS_I(inode)->i_gang;
+       struct spu_context *neighbor;
+       struct path path = {.mnt = mnt, .dentry = dentry};
+@@ -422,11 +440,15 @@ spufs_create_context(struct inode *inode, struct dentry *dentry,
+       if ((flags & SPU_CREATE_ISOLATE) && !isolated_loader)
+               return -ENODEV;
+-      gang = NULL;
++      if (gang) {
++              if (!gang->alive)
++                      return -ENOENT;
++              gang->alive++;
++      }
++
+       neighbor = NULL;
+       affinity = flags & (SPU_CREATE_AFFINITY_MEM | SPU_CREATE_AFFINITY_SPU);
+       if (affinity) {
+-              gang = SPUFS_I(inode)->i_gang;
+               if (!gang)
+                       return -EINVAL;
+               mutex_lock(&gang->aff_mutex);
+@@ -455,6 +477,8 @@ spufs_create_context(struct inode *inode, struct dentry *dentry,
+ out_aff_unlock:
+       if (affinity)
+               mutex_unlock(&gang->aff_mutex);
++      if (ret && gang)
++              gang->alive--; // can't reach 0
+       return ret;
+ }
+@@ -484,6 +508,7 @@ spufs_mkgang(struct inode *dir, struct dentry *dentry, umode_t mode)
+       inode->i_fop = &simple_dir_operations;
+       d_instantiate(dentry, inode);
++      dget(dentry);
+       inc_nlink(dir);
+       inc_nlink(d_inode(dentry));
+       return ret;
+@@ -494,6 +519,21 @@ spufs_mkgang(struct inode *dir, struct dentry *dentry, umode_t mode)
+       return ret;
+ }
++static int spufs_gang_close(struct inode *inode, struct file *file)
++{
++      unuse_gang(file->f_path.dentry);
++      return dcache_dir_close(inode, file);
++}
++
++static const struct file_operations spufs_gang_fops = {
++      .open           = dcache_dir_open,
++      .release        = spufs_gang_close,
++      .llseek         = dcache_dir_lseek,
++      .read           = generic_read_dir,
++      .iterate_shared = dcache_readdir,
++      .fsync          = noop_fsync,
++};
++
+ static int spufs_gang_open(const struct path *path)
+ {
+       int ret;
+@@ -513,7 +553,7 @@ static int spufs_gang_open(const struct path *path)
+               return PTR_ERR(filp);
+       }
+-      filp->f_op = &simple_dir_operations;
++      filp->f_op = &spufs_gang_fops;
+       fd_install(ret, filp);
+       return ret;
+ }
+@@ -528,10 +568,8 @@ static int spufs_create_gang(struct inode *inode,
+       ret = spufs_mkgang(inode, dentry, mode & 0777);
+       if (!ret) {
+               ret = spufs_gang_open(&path);
+-              if (ret < 0) {
+-                      int err = simple_rmdir(inode, dentry);
+-                      WARN_ON(err);
+-              }
++              if (ret < 0)
++                      unuse_gang(dentry);
+       }
+       return ret;
+ }
+diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
+index 84958487f696a..d33787c57c39a 100644
+--- a/arch/powerpc/platforms/cell/spufs/spufs.h
++++ b/arch/powerpc/platforms/cell/spufs/spufs.h
+@@ -151,6 +151,8 @@ struct spu_gang {
+       int aff_flags;
+       struct spu *aff_ref_spu;
+       atomic_t aff_sched_count;
++
++      int alive;
+ };
+ /* Flag bits for spu_gang aff_flags */
+-- 
+2.39.5
+
diff --git a/queue-6.14/staging-gpib-add-missing-interface-entry-point.patch b/queue-6.14/staging-gpib-add-missing-interface-entry-point.patch
new file mode 100644 (file)
index 0000000..8674961
--- /dev/null
@@ -0,0 +1,49 @@
+From 0b44ed6cb829054e42e9d6d2f404d01cef9d8a4b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jan 2025 11:38:58 +0100
+Subject: staging: gpib: Add missing interface entry point
+
+From: Dave Penkler <dpenkler@gmail.com>
+
+[ Upstream commit 2f548210a5a5d4cb5f20af39b684a9f6de58cd0e ]
+
+Declaring the driver entry points as static caused a warning
+that the serial_poll_status function of the agilent_82350b driver
+was unused.
+
+Add the entry point to the corresponding interface structure
+initializations where it was missing.
+
+Fixes: 09a4655ee1eb ("staging: gpib: Add HP/Agilent/Keysight 8235xx PCI GPIB driver")
+Signed-off-by: Dave Penkler <dpenkler@gmail.com>
+Reviewed-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://lore.kernel.org/r/20250122103859.25499-2-dpenkler@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/gpib/agilent_82350b/agilent_82350b.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/staging/gpib/agilent_82350b/agilent_82350b.c b/drivers/staging/gpib/agilent_82350b/agilent_82350b.c
+index 3f4f95b7fe34a..c62407077d37f 100644
+--- a/drivers/staging/gpib/agilent_82350b/agilent_82350b.c
++++ b/drivers/staging/gpib/agilent_82350b/agilent_82350b.c
+@@ -848,6 +848,7 @@ static gpib_interface_t agilent_82350b_unaccel_interface = {
+       .primary_address = agilent_82350b_primary_address,
+       .secondary_address = agilent_82350b_secondary_address,
+       .serial_poll_response = agilent_82350b_serial_poll_response,
++      .serial_poll_status = agilent_82350b_serial_poll_status,
+       .t1_delay = agilent_82350b_t1_delay,
+       .return_to_local = agilent_82350b_return_to_local,
+ };
+@@ -875,6 +876,7 @@ static gpib_interface_t agilent_82350b_interface = {
+       .primary_address = agilent_82350b_primary_address,
+       .secondary_address = agilent_82350b_secondary_address,
+       .serial_poll_response = agilent_82350b_serial_poll_response,
++      .serial_poll_status = agilent_82350b_serial_poll_status,
+       .t1_delay = agilent_82350b_t1_delay,
+       .return_to_local = agilent_82350b_return_to_local,
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.14/staging-gpib-fix-cb7210-pcmcia-oops.patch b/queue-6.14/staging-gpib-fix-cb7210-pcmcia-oops.patch
new file mode 100644 (file)
index 0000000..cc47ee6
--- /dev/null
@@ -0,0 +1,43 @@
+From de8c0eb0bf6dd048ead7270e9b169ab08d9c8d64 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Feb 2025 11:31:12 +0100
+Subject: staging: gpib: Fix cb7210 pcmcia Oops
+
+From: Dave Penkler <dpenkler@gmail.com>
+
+[ Upstream commit c1baf6528bcfd6a86842093ff3f8ff8caf309c12 ]
+
+The  pcmcia_driver struct was still only using the old .name
+initialization in the drv field. This led to a NULL pointer
+deref Oops in strcmp called from pcmcia_register_driver.
+
+Initialize the pcmcia_driver struct name field.
+
+Reported-by: kernel test robot <oliver.sang@intel.com>
+Closes: https://lore.kernel.org/oe-lkp/202502131453.cb6d2e4a-lkp@intel.com
+Fixes: e9dc69956d4d ("staging: gpib: Add Computer Boards GPIB driver")
+Signed-off-by: Dave Penkler <dpenkler@gmail.com>
+Link: https://lore.kernel.org/r/20250213103112.4415-1-dpenkler@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/gpib/cb7210/cb7210.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/staging/gpib/cb7210/cb7210.c b/drivers/staging/gpib/cb7210/cb7210.c
+index 4d22f647a453f..ab93061263bfe 100644
+--- a/drivers/staging/gpib/cb7210/cb7210.c
++++ b/drivers/staging/gpib/cb7210/cb7210.c
+@@ -1342,8 +1342,8 @@ static struct pcmcia_device_id cb_pcmcia_ids[] = {
+ MODULE_DEVICE_TABLE(pcmcia, cb_pcmcia_ids);
+ static struct pcmcia_driver cb_gpib_cs_driver = {
++      .name           = "cb_gpib_cs",
+       .owner          = THIS_MODULE,
+-      .drv = { .name = "cb_gpib_cs", },
+       .id_table       = cb_pcmcia_ids,
+       .probe          = cb_gpib_probe,
+       .remove         = cb_gpib_remove,
+-- 
+2.39.5
+
diff --git a/queue-6.14/staging-gpib-fix-pr_err-format-warning.patch b/queue-6.14/staging-gpib-fix-pr_err-format-warning.patch
new file mode 100644 (file)
index 0000000..12bcd07
--- /dev/null
@@ -0,0 +1,45 @@
+From 88d4826eb47bf41daaa31ad3bb74617952a1f49e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jan 2025 11:58:58 +0100
+Subject: staging: gpib: Fix pr_err format warning
+
+From: Dave Penkler <dpenkler@gmail.com>
+
+[ Upstream commit 03ec050c437bb4e7c5d215bbeedaa93932f13b35 ]
+
+This patch fixes the following compile warning:
+
+drivers/staging/gpib/hp_82341/hp_82341.c: In function 'hp_82341_attach':
+./include/linux/kern_levels.h:5:25: warning: format '%lx' expects argument of type 'long unsigned int', but argument 2 has type 'u32' {aka 'unsigned int'} [-Wformat=]
+
+It was introduced in
+
+commit baf8855c9160 ("staging: gpib: fix address space mixup")
+
+but was not detected as the build of the driver depended on BROKEN.
+
+Fixes: baf8855c9160 ("staging: gpib: fix address space mixup")
+Signed-off-by: Dave Penkler <dpenkler@gmail.com>
+Link: https://lore.kernel.org/r/20250124105900.27592-2-dpenkler@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/gpib/hp_82341/hp_82341.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/staging/gpib/hp_82341/hp_82341.c b/drivers/staging/gpib/hp_82341/hp_82341.c
+index 0ddae295912fa..589c4fee1d562 100644
+--- a/drivers/staging/gpib/hp_82341/hp_82341.c
++++ b/drivers/staging/gpib/hp_82341/hp_82341.c
+@@ -718,7 +718,7 @@ int hp_82341_attach(gpib_board_t *board, const gpib_board_config_t *config)
+       for (i = 0; i < hp_82341_num_io_regions; ++i) {
+               start_addr = iobase + i * hp_priv->io_region_offset;
+               if (!request_region(start_addr, hp_82341_region_iosize, "hp_82341")) {
+-                      pr_err("hp_82341: failed to allocate io ports 0x%lx-0x%lx\n",
++                      pr_err("hp_82341: failed to allocate io ports 0x%x-0x%x\n",
+                              start_addr,
+                              start_addr + hp_82341_region_iosize - 1);
+                       return -EIO;
+-- 
+2.39.5
+
diff --git a/queue-6.14/staging-rtl8723bs-select-config_crypto_lib_aes.patch b/queue-6.14/staging-rtl8723bs-select-config_crypto_lib_aes.patch
new file mode 100644 (file)
index 0000000..46892a3
--- /dev/null
@@ -0,0 +1,44 @@
+From 308288efa4218c7346d2ca4f098450420e64ad41 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 22 Feb 2025 19:36:17 +0000
+Subject: staging: rtl8723bs: select CONFIG_CRYPTO_LIB_AES
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: 谢致邦 (XIE Zhibang) <Yeking@Red54.com>
+
+[ Upstream commit b2a9a6a26b7e954297e51822e396572026480bad ]
+
+This fixes the following issue:
+ERROR: modpost: "aes_expandkey" [drivers/staging/rtl8723bs/r8723bs.ko]
+undefined!
+ERROR: modpost: "aes_encrypt" [drivers/staging/rtl8723bs/r8723bs.ko]
+undefined!
+
+Fixes: 7d40753d8820 ("staging: rtl8723bs: use in-kernel aes encryption in OMAC1 routines")
+Fixes: 3d3a170f6d80 ("staging: rtl8723bs: use in-kernel aes encryption")
+Signed-off-by: 谢致邦 (XIE Zhibang) <Yeking@Red54.com>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/tencent_0BDDF3A721708D16A2E7C3DAFF0FEC79A105@qq.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/rtl8723bs/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/staging/rtl8723bs/Kconfig b/drivers/staging/rtl8723bs/Kconfig
+index 8d48c61961a6b..353e6ee2c1450 100644
+--- a/drivers/staging/rtl8723bs/Kconfig
++++ b/drivers/staging/rtl8723bs/Kconfig
+@@ -4,6 +4,7 @@ config RTL8723BS
+       depends on WLAN && MMC && CFG80211
+       depends on m
+       select CRYPTO
++      select CRYPTO_LIB_AES
+       select CRYPTO_LIB_ARC4
+       help
+       This option enables support for RTL8723BS SDIO drivers, such as
+-- 
+2.39.5
+
diff --git a/queue-6.14/staging-vchiq_arm-fix-possible-npr-of-keep-alive-thr.patch b/queue-6.14/staging-vchiq_arm-fix-possible-npr-of-keep-alive-thr.patch
new file mode 100644 (file)
index 0000000..1270ea4
--- /dev/null
@@ -0,0 +1,39 @@
+From 3468fdebebf0a7eeae5db2957519e99e09c0b723 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Mar 2025 13:50:11 +0100
+Subject: staging: vchiq_arm: Fix possible NPR of keep-alive thread
+
+From: Stefan Wahren <wahrenst@gmx.net>
+
+[ Upstream commit 3db89bc6d973e2bcaa852f6409c98c228f39a926 ]
+
+In case vchiq_platform_conn_state_changed() is never called or fails before
+driver removal, ka_thread won't be a valid pointer to a task_struct. So
+do the necessary checks before calling kthread_stop to avoid a crash.
+
+Fixes: 863a756aaf49 ("staging: vc04_services: vchiq_core: Stop kthreads on vchiq module unload")
+Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
+Link: https://lore.kernel.org/r/20250309125014.37166-3-wahrenst@gmx.net
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+index e2e80e90b555b..d3b7d1227d7d6 100644
+--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+@@ -1422,7 +1422,8 @@ static void vchiq_remove(struct platform_device *pdev)
+       kthread_stop(mgmt->state.slot_handler_thread);
+       arm_state = vchiq_platform_get_arm_state(&mgmt->state);
+-      kthread_stop(arm_state->ka_thread);
++      if (!IS_ERR_OR_NULL(arm_state->ka_thread))
++              kthread_stop(arm_state->ka_thread);
+ }
+ static struct platform_driver vchiq_driver = {
+-- 
+2.39.5
+
diff --git a/queue-6.14/staging-vchiq_arm-register-debugfs-after-cdev.patch b/queue-6.14/staging-vchiq_arm-register-debugfs-after-cdev.patch
new file mode 100644 (file)
index 0000000..dedf6a7
--- /dev/null
@@ -0,0 +1,48 @@
+From f338f3283d47f25510eff930e75e804b277fe191 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Mar 2025 13:50:10 +0100
+Subject: staging: vchiq_arm: Register debugfs after cdev
+
+From: Stefan Wahren <wahrenst@gmx.net>
+
+[ Upstream commit 63f4dbb196db60a8536ba3d1b835d597a83f6cbb ]
+
+The commit 2a4d15a4ae98 ("staging: vchiq: Refactor vchiq cdev code")
+moved the debugfs directory creation before vchiq character device
+registration. In case the latter fails, the debugfs directory won't
+be cleaned up.
+
+Fixes: 2a4d15a4ae98 ("staging: vchiq: Refactor vchiq cdev code")
+Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
+Link: https://lore.kernel.org/r/20250309125014.37166-2-wahrenst@gmx.net
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+index a4e83e5d619bc..e2e80e90b555b 100644
+--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+@@ -1386,8 +1386,6 @@ static int vchiq_probe(struct platform_device *pdev)
+               return ret;
+       }
+-      vchiq_debugfs_init(&mgmt->state);
+-
+       dev_dbg(&pdev->dev, "arm: platform initialised - version %d (min %d)\n",
+               VCHIQ_VERSION, VCHIQ_VERSION_MIN);
+@@ -1401,6 +1399,8 @@ static int vchiq_probe(struct platform_device *pdev)
+               return ret;
+       }
++      vchiq_debugfs_init(&mgmt->state);
++
+       bcm2835_audio = vchiq_device_register(&pdev->dev, "bcm2835-audio");
+       bcm2835_camera = vchiq_device_register(&pdev->dev, "bcm2835-camera");
+-- 
+2.39.5
+
diff --git a/queue-6.14/staging-vchiq_arm-stop-kthreads-if-vchiq-cdev-regist.patch b/queue-6.14/staging-vchiq_arm-stop-kthreads-if-vchiq-cdev-regist.patch
new file mode 100644 (file)
index 0000000..26c4b29
--- /dev/null
@@ -0,0 +1,79 @@
+From e9519c498dcb8a9bdd9fe1b33d56ba4134513f3d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Mar 2025 13:50:12 +0100
+Subject: staging: vchiq_arm: Stop kthreads if vchiq cdev register fails
+
+From: Stefan Wahren <wahrenst@gmx.net>
+
+[ Upstream commit cfb320d990919836b49bd090c6c232c6c4d90b41 ]
+
+In case the vchiq character device cannot be registered during probe,
+all kthreads needs to be stopped to avoid resource leaks.
+
+Fixes: 863a756aaf49 ("staging: vc04_services: vchiq_core: Stop kthreads on vchiq module unload")
+Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
+Link: https://lore.kernel.org/r/20250309125014.37166-4-wahrenst@gmx.net
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../interface/vchiq_arm/vchiq_arm.c           | 25 ++++++++++++-------
+ 1 file changed, 16 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+index d3b7d1227d7d6..0c7ea2d0ee85e 100644
+--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+@@ -308,6 +308,20 @@ static struct vchiq_arm_state *vchiq_platform_get_arm_state(struct vchiq_state *
+       return (struct vchiq_arm_state *)state->platform_state;
+ }
++static void
++vchiq_platform_uninit(struct vchiq_drv_mgmt *mgmt)
++{
++      struct vchiq_arm_state *arm_state;
++
++      kthread_stop(mgmt->state.sync_thread);
++      kthread_stop(mgmt->state.recycle_thread);
++      kthread_stop(mgmt->state.slot_handler_thread);
++
++      arm_state = vchiq_platform_get_arm_state(&mgmt->state);
++      if (!IS_ERR_OR_NULL(arm_state->ka_thread))
++              kthread_stop(arm_state->ka_thread);
++}
++
+ void vchiq_dump_platform_state(struct seq_file *f)
+ {
+       seq_puts(f, "  Platform: 2835 (VC master)\n");
+@@ -1396,6 +1410,7 @@ static int vchiq_probe(struct platform_device *pdev)
+       ret = vchiq_register_chrdev(&pdev->dev);
+       if (ret) {
+               dev_err(&pdev->dev, "arm: Failed to initialize vchiq cdev\n");
++              vchiq_platform_uninit(mgmt);
+               return ret;
+       }
+@@ -1410,20 +1425,12 @@ static int vchiq_probe(struct platform_device *pdev)
+ static void vchiq_remove(struct platform_device *pdev)
+ {
+       struct vchiq_drv_mgmt *mgmt = dev_get_drvdata(&pdev->dev);
+-      struct vchiq_arm_state *arm_state;
+       vchiq_device_unregister(bcm2835_audio);
+       vchiq_device_unregister(bcm2835_camera);
+       vchiq_debugfs_deinit();
+       vchiq_deregister_chrdev();
+-
+-      kthread_stop(mgmt->state.sync_thread);
+-      kthread_stop(mgmt->state.recycle_thread);
+-      kthread_stop(mgmt->state.slot_handler_thread);
+-
+-      arm_state = vchiq_platform_get_arm_state(&mgmt->state);
+-      if (!IS_ERR_OR_NULL(arm_state->ka_thread))
+-              kthread_stop(arm_state->ka_thread);
++      vchiq_platform_uninit(mgmt);
+ }
+ static struct platform_driver vchiq_driver = {
+-- 
+2.39.5
+
diff --git a/queue-6.14/thermal-core-remove-duplicate-struct-declaration.patch b/queue-6.14/thermal-core-remove-duplicate-struct-declaration.patch
new file mode 100644 (file)
index 0000000..867e2a3
--- /dev/null
@@ -0,0 +1,37 @@
+From ac01b360172bdc26b975e93b6715cf0aa9571d33 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Feb 2025 16:14:36 +0800
+Subject: thermal: core: Remove duplicate struct declaration
+
+From: xueqin Luo <luoxueqin@kylinos.cn>
+
+[ Upstream commit 9e6ec8cf64e2973f0ec74f09023988cabd218426 ]
+
+The struct thermal_zone_device is already declared on line 32, so the
+duplicate declaration has been removed.
+
+Fixes: b1ae92dcfa8e ("thermal: core: Make struct thermal_zone_device definition internal")
+Signed-off-by: xueqin Luo <luoxueqin@kylinos.cn>
+Link: https://lore.kernel.org/r/20250206081436.51785-1-luoxueqin@kylinos.cn
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/thermal.h | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/include/linux/thermal.h b/include/linux/thermal.h
+index 69f9bedd0ee88..0b5ed68210807 100644
+--- a/include/linux/thermal.h
++++ b/include/linux/thermal.h
+@@ -86,8 +86,6 @@ struct thermal_trip {
+ #define THERMAL_TRIP_PRIV_TO_INT(_val_)       (uintptr_t)(_val_)
+ #define THERMAL_INT_TO_TRIP_PRIV(_val_)       (void *)(uintptr_t)(_val_)
+-struct thermal_zone_device;
+-
+ struct cooling_spec {
+       unsigned long upper;    /* Highest cooling state  */
+       unsigned long lower;    /* Lowest cooling state  */
+-- 
+2.39.5
+
diff --git a/queue-6.14/thermal-int340x-add-null-check-for-adev.patch b/queue-6.14/thermal-int340x-add-null-check-for-adev.patch
new file mode 100644 (file)
index 0000000..d620abd
--- /dev/null
@@ -0,0 +1,50 @@
+From 34c9849f7670046d8b667eb69f6091e7a3d7d2da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Mar 2025 23:36:11 -0500
+Subject: thermal: int340x: Add NULL check for adev
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Chenyuan Yang <chenyuan0y@gmail.com>
+
+[ Upstream commit 2542a3f70e563a9e70e7ded314286535a3321bdb ]
+
+Not all devices have an ACPI companion fwnode, so adev might be NULL.
+This is similar to the commit cd2fd6eab480
+("platform/x86: int3472: Check for adev == NULL").
+
+Add a check for adev not being set and return -ENODEV in that case to
+avoid a possible NULL pointer deref in int3402_thermal_probe().
+
+Note, under the same directory, int3400_thermal_probe() has such a
+check.
+
+Fixes: 77e337c6e23e ("Thermal: introduce INT3402 thermal driver")
+Signed-off-by: Chenyuan Yang <chenyuan0y@gmail.com>
+Acked-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
+Link: https://patch.msgid.link/20250313043611.1212116-1-chenyuan0y@gmail.com
+[ rjw: Subject edit, added Fixes: ]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/intel/int340x_thermal/int3402_thermal.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/thermal/intel/int340x_thermal/int3402_thermal.c b/drivers/thermal/intel/int340x_thermal/int3402_thermal.c
+index 543b03960e992..57b90005888a3 100644
+--- a/drivers/thermal/intel/int340x_thermal/int3402_thermal.c
++++ b/drivers/thermal/intel/int340x_thermal/int3402_thermal.c
+@@ -45,6 +45,9 @@ static int int3402_thermal_probe(struct platform_device *pdev)
+       struct int3402_thermal_data *d;
+       int ret;
++      if (!adev)
++              return -ENODEV;
++
+       if (!acpi_has_method(adev->handle, "_TMP"))
+               return -ENODEV;
+-- 
+2.39.5
+
diff --git a/queue-6.14/timekeeping-fix-possible-inconsistencies-in-_coarse-.patch b/queue-6.14/timekeeping-fix-possible-inconsistencies-in-_coarse-.patch
new file mode 100644 (file)
index 0000000..7a26769
--- /dev/null
@@ -0,0 +1,219 @@
+From cb6ae383145403c779d9dd8dc6fdfc2bcdc42d32 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Mar 2025 13:03:00 -0700
+Subject: timekeeping: Fix possible inconsistencies in _COARSE clockids
+
+From: John Stultz <jstultz@google.com>
+
+[ Upstream commit 757b000f7b936edf79311ab0971fe465bbda75ea ]
+
+Lei Chen raised an issue with CLOCK_MONOTONIC_COARSE seeing time
+inconsistencies.
+
+Lei tracked down that this was being caused by the adjustment
+
+    tk->tkr_mono.xtime_nsec -= offset;
+
+which is made to compensate for the unaccumulated cycles in offset when the
+multiplicator is adjusted forward, so that the non-_COARSE clockids don't
+see inconsistencies.
+
+However, the _COARSE clockid getter functions use the adjusted xtime_nsec
+value directly and do not compensate the negative offset via the
+clocksource delta multiplied with the new multiplicator. In that case the
+caller can observe time going backwards in consecutive calls.
+
+By design, this negative adjustment should be fine, because the logic run
+from timekeeping_adjust() is done after it accumulated approximately
+
+     multiplicator * interval_cycles
+
+into xtime_nsec.  The accumulated value is always larger then the
+
+     mult_adj * offset
+
+value, which is subtracted from xtime_nsec. Both operations are done
+together under the tk_core.lock, so the net change to xtime_nsec is always
+always be positive.
+
+However, do_adjtimex() calls into timekeeping_advance() as well, to to
+apply the NTP frequency adjustment immediately. In this case,
+timekeeping_advance() does not return early when the offset is smaller then
+interval_cycles. In that case there is no time accumulated into
+xtime_nsec. But the subsequent call into timekeeping_adjust(), which
+modifies the multiplicator, subtracts from xtime_nsec to correct
+for the new multiplicator.
+
+Here because there was no accumulation, xtime_nsec becomes smaller than
+before, which opens a window up to the next accumulation, where the _COARSE
+clockid getters, which don't compensate for the offset, can observe the
+inconsistency.
+
+To fix this, rework the timekeeping_advance() logic so that when invoked
+from do_adjtimex(), the time is immediately forwarded to accumulate also
+the sub-interval portion into xtime. That means the remaining offset
+becomes zero and the subsequent multiplier adjustment therefore does not
+modify xtime_nsec.
+
+There is another related inconsistency. If xtime is forwarded due to the
+instantaneous multiplier adjustment, the NTP error, which was accumulated
+with the previous setting, becomes meaningless.
+
+Therefore clear the NTP error as well, after forwarding the clock for the
+instantaneous multiplier update.
+
+Fixes: da15cfdae033 ("time: Introduce CLOCK_REALTIME_COARSE")
+Reported-by: Lei Chen <lei.chen@smartx.com>
+Signed-off-by: John Stultz <jstultz@google.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Link: https://lore.kernel.org/all/20250320200306.1712599-1-jstultz@google.com
+Closes: https://lore.kernel.org/lkml/20250310030004.3705801-1-lei.chen@smartx.com/
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/time/timekeeping.c | 94 ++++++++++++++++++++++++++++-----------
+ 1 file changed, 69 insertions(+), 25 deletions(-)
+
+diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
+index 1e67d076f1955..929846b8b45ab 100644
+--- a/kernel/time/timekeeping.c
++++ b/kernel/time/timekeeping.c
+@@ -682,20 +682,19 @@ static void timekeeping_update_from_shadow(struct tk_data *tkd, unsigned int act
+ }
+ /**
+- * timekeeping_forward_now - update clock to the current time
++ * timekeeping_forward - update clock to given cycle now value
+  * @tk:               Pointer to the timekeeper to update
++ * @cycle_now:  Current clocksource read value
+  *
+  * Forward the current clock to update its state since the last call to
+  * update_wall_time(). This is useful before significant clock changes,
+  * as it avoids having to deal with this time offset explicitly.
+  */
+-static void timekeeping_forward_now(struct timekeeper *tk)
++static void timekeeping_forward(struct timekeeper *tk, u64 cycle_now)
+ {
+-      u64 cycle_now, delta;
++      u64 delta = clocksource_delta(cycle_now, tk->tkr_mono.cycle_last, tk->tkr_mono.mask,
++                                    tk->tkr_mono.clock->max_raw_delta);
+-      cycle_now = tk_clock_read(&tk->tkr_mono);
+-      delta = clocksource_delta(cycle_now, tk->tkr_mono.cycle_last, tk->tkr_mono.mask,
+-                                tk->tkr_mono.clock->max_raw_delta);
+       tk->tkr_mono.cycle_last = cycle_now;
+       tk->tkr_raw.cycle_last  = cycle_now;
+@@ -710,6 +709,21 @@ static void timekeeping_forward_now(struct timekeeper *tk)
+       }
+ }
++/**
++ * timekeeping_forward_now - update clock to the current time
++ * @tk:               Pointer to the timekeeper to update
++ *
++ * Forward the current clock to update its state since the last call to
++ * update_wall_time(). This is useful before significant clock changes,
++ * as it avoids having to deal with this time offset explicitly.
++ */
++static void timekeeping_forward_now(struct timekeeper *tk)
++{
++      u64 cycle_now = tk_clock_read(&tk->tkr_mono);
++
++      timekeeping_forward(tk, cycle_now);
++}
++
+ /**
+  * ktime_get_real_ts64 - Returns the time of day in a timespec64.
+  * @ts:               pointer to the timespec to be set
+@@ -2151,6 +2165,54 @@ static u64 logarithmic_accumulation(struct timekeeper *tk, u64 offset,
+       return offset;
+ }
++static u64 timekeeping_accumulate(struct timekeeper *tk, u64 offset,
++                                enum timekeeping_adv_mode mode,
++                                unsigned int *clock_set)
++{
++      int shift = 0, maxshift;
++
++      /*
++       * TK_ADV_FREQ indicates that adjtimex(2) directly set the
++       * frequency or the tick length.
++       *
++       * Accumulate the offset, so that the new multiplier starts from
++       * now. This is required as otherwise for offsets, which are
++       * smaller than tk::cycle_interval, timekeeping_adjust() could set
++       * xtime_nsec backwards, which subsequently causes time going
++       * backwards in the coarse time getters. But even for the case
++       * where offset is greater than tk::cycle_interval the periodic
++       * accumulation does not have much value.
++       *
++       * Also reset tk::ntp_error as it does not make sense to keep the
++       * old accumulated error around in this case.
++       */
++      if (mode == TK_ADV_FREQ) {
++              timekeeping_forward(tk, tk->tkr_mono.cycle_last + offset);
++              tk->ntp_error = 0;
++              return 0;
++      }
++
++      /*
++       * With NO_HZ we may have to accumulate many cycle_intervals
++       * (think "ticks") worth of time at once. To do this efficiently,
++       * we calculate the largest doubling multiple of cycle_intervals
++       * that is smaller than the offset.  We then accumulate that
++       * chunk in one go, and then try to consume the next smaller
++       * doubled multiple.
++       */
++      shift = ilog2(offset) - ilog2(tk->cycle_interval);
++      shift = max(0, shift);
++      /* Bound shift to one less than what overflows tick_length */
++      maxshift = (64 - (ilog2(ntp_tick_length()) + 1)) - 1;
++      shift = min(shift, maxshift);
++      while (offset >= tk->cycle_interval) {
++              offset = logarithmic_accumulation(tk, offset, shift, clock_set);
++              if (offset < tk->cycle_interval << shift)
++                      shift--;
++      }
++      return offset;
++}
++
+ /*
+  * timekeeping_advance - Updates the timekeeper to the current time and
+  * current NTP tick length
+@@ -2160,7 +2222,6 @@ static bool timekeeping_advance(enum timekeeping_adv_mode mode)
+       struct timekeeper *tk = &tk_core.shadow_timekeeper;
+       struct timekeeper *real_tk = &tk_core.timekeeper;
+       unsigned int clock_set = 0;
+-      int shift = 0, maxshift;
+       u64 offset;
+       guard(raw_spinlock_irqsave)(&tk_core.lock);
+@@ -2177,24 +2238,7 @@ static bool timekeeping_advance(enum timekeeping_adv_mode mode)
+       if (offset < real_tk->cycle_interval && mode == TK_ADV_TICK)
+               return false;
+-      /*
+-       * With NO_HZ we may have to accumulate many cycle_intervals
+-       * (think "ticks") worth of time at once. To do this efficiently,
+-       * we calculate the largest doubling multiple of cycle_intervals
+-       * that is smaller than the offset.  We then accumulate that
+-       * chunk in one go, and then try to consume the next smaller
+-       * doubled multiple.
+-       */
+-      shift = ilog2(offset) - ilog2(tk->cycle_interval);
+-      shift = max(0, shift);
+-      /* Bound shift to one less than what overflows tick_length */
+-      maxshift = (64 - (ilog2(ntp_tick_length())+1)) - 1;
+-      shift = min(shift, maxshift);
+-      while (offset >= tk->cycle_interval) {
+-              offset = logarithmic_accumulation(tk, offset, shift, &clock_set);
+-              if (offset < tk->cycle_interval<<shift)
+-                      shift--;
+-      }
++      offset = timekeeping_accumulate(tk, offset, mode, &clock_set);
+       /* Adjust the multiplier to correct NTP error */
+       timekeeping_adjust(tk, offset);
+-- 
+2.39.5
+
diff --git a/queue-6.14/tools-rv-keep-user-ldflags-in-build.patch b/queue-6.14/tools-rv-keep-user-ldflags-in-build.patch
new file mode 100644 (file)
index 0000000..33436fc
--- /dev/null
@@ -0,0 +1,51 @@
+From d164167bf297dfa49cb850e475f8d55e5316f0ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Mar 2025 15:22:28 +0100
+Subject: tools/rv: Keep user LDFLAGS in build
+
+From: Tomas Glozar <tglozar@redhat.com>
+
+[ Upstream commit e82c78afa3d48f6512570e7d39258cd68e7bae0a ]
+
+rv, unlike rtla and perf, drops LDFLAGS supplied by the user and honors
+only EXTRA_LDFLAGS. This is inconsistent with both perf and rtla and
+can lead to all kinds of unexpected behavior.
+
+For example, on Fedora and RHEL, it causes rv to be build without
+PIE, unlike the aforementioned perf and rtla:
+
+$ file /usr/bin/{rv,rtla,perf}
+/usr/bin/rv:   ELF 64-bit LSB executable, ...
+/usr/bin/rtla: ELF 64-bit LSB pie executable, ...
+/usr/bin/perf: ELF 64-bit LSB pie executable, ...
+
+Keep both LDFLAGS and EXTRA_LDFLAGS for the build.
+
+Cc: John Kacur <jkacur@redhat.com>
+Cc: Luis Goncalves <lgoncalv@redhat.com>
+Cc: Gabriele Monaco <gmonaco@redhat.com>
+Link: https://lore.kernel.org/20250304142228.767658-1-tglozar@redhat.com
+Fixes: 012e4e77df73 ("tools/verification: Use tools/build makefiles on rv")
+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/verification/rv/Makefile.rv | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/verification/rv/Makefile.rv b/tools/verification/rv/Makefile.rv
+index 161baa29eb86c..2497fb96c83d2 100644
+--- a/tools/verification/rv/Makefile.rv
++++ b/tools/verification/rv/Makefile.rv
+@@ -27,7 +27,7 @@ endif
+ INCLUDE               := -Iinclude/
+ CFLAGS                := -g -DVERSION=\"$(VERSION)\" $(FOPTS) $(WOPTS) $(EXTRA_CFLAGS) $(INCLUDE)
+-LDFLAGS               := -ggdb $(EXTRA_LDFLAGS)
++LDFLAGS               := -ggdb $(LDFLAGS) $(EXTRA_LDFLAGS)
+ INSTALL               := install
+ MKDIR         := mkdir
+-- 
+2.39.5
+
diff --git a/queue-6.14/tools-x86-fix-linux-unaligned.h-include-path-in-lib-.patch b/queue-6.14/tools-x86-fix-linux-unaligned.h-include-path-in-lib-.patch
new file mode 100644 (file)
index 0000000..c8e6b1d
--- /dev/null
@@ -0,0 +1,40 @@
+From dbf31150669296d59072e7f1ce19979dba760b6e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Feb 2025 11:36:00 -0800
+Subject: tools/x86: Fix linux/unaligned.h include path in lib/insn.c
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit fad07a5c0f07ad0884e1cb4362fe28c083b5b811 ]
+
+tools/arch/x86/include/linux doesn't exist but building is working by
+virtue of a -I. Building using bazel this fails. Use angle brackets to
+include unaligned.h so there isn't an invalid relative include.
+
+Fixes: 5f60d5f6bbc1 ("move asm/unaligned.h to linux/unaligned.h")
+Signed-off-by: Ian Rogers <irogers@google.com>
+Acked-by: Josh Poimboeuf <jpoimboe@kernel.org>
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Link: https://lore.kernel.org/r/20250225193600.90037-1-irogers@google.com
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/arch/x86/lib/insn.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/arch/x86/lib/insn.c b/tools/arch/x86/lib/insn.c
+index ab5cdc3337dac..e91d4c4e1c162 100644
+--- a/tools/arch/x86/lib/insn.c
++++ b/tools/arch/x86/lib/insn.c
+@@ -13,7 +13,7 @@
+ #endif
+ #include "../include/asm/inat.h" /* __ignore_sync_check__ */
+ #include "../include/asm/insn.h" /* __ignore_sync_check__ */
+-#include "../include/linux/unaligned.h" /* __ignore_sync_check__ */
++#include <linux/unaligned.h> /* __ignore_sync_check__ */
+ #include <linux/errno.h>
+ #include <linux/kconfig.h>
+-- 
+2.39.5
+
diff --git a/queue-6.14/tracing-fix-declare_trace_condition.patch b/queue-6.14/tracing-fix-declare_trace_condition.patch
new file mode 100644 (file)
index 0000000..6113df1
--- /dev/null
@@ -0,0 +1,68 @@
+From fe78bc87aa35f40b6e00a7c7d9ec3f0a0138ff42 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Feb 2025 13:31:06 +0100
+Subject: tracing: Fix DECLARE_TRACE_CONDITION
+
+From: Gabriele Monaco <gmonaco@redhat.com>
+
+[ Upstream commit 486df3466daf7b185f534a7408fa6f9dbb16dbeb ]
+
+Commit 287050d39026 ("tracing: Add TRACE_EVENT_CONDITIONAL()") adds
+macros to define conditional trace events (TRACE_EVENT_CONDITIONAL) and
+tracepoints (DECLARE_TRACE_CONDITION), but sets up functionality for
+direct use only for the former.
+
+Add preprocessor bits in define_trace.h to allow usage of
+DECLARE_TRACE_CONDITION just like DECLARE_TRACE.
+
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Juri Lelli <juri.lelli@redhat.com>
+Link: https://lore.kernel.org/20250218123121.253551-2-gmonaco@redhat.com
+Fixes: 287050d39026 ("tracing: Add TRACE_EVENT_CONDITIONAL()")
+Link: https://lore.kernel.org/linux-trace-kernel/20250128111926.303093-1-gmonaco@redhat.com
+Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Signed-off-by: Gabriele Monaco <gmonaco@redhat.com>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/trace/define_trace.h | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/include/trace/define_trace.h b/include/trace/define_trace.h
+index e1c1079f8c8db..ed52d0506c69f 100644
+--- a/include/trace/define_trace.h
++++ b/include/trace/define_trace.h
+@@ -76,6 +76,10 @@
+ #define DECLARE_TRACE(name, proto, args)      \
+       DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
++#undef DECLARE_TRACE_CONDITION
++#define DECLARE_TRACE_CONDITION(name, proto, args, cond)      \
++      DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
++
+ /* If requested, create helpers for calling these tracepoints from Rust. */
+ #ifdef CREATE_RUST_TRACE_POINTS
+ #undef DEFINE_RUST_DO_TRACE
+@@ -108,6 +112,8 @@
+ /* Make all open coded DECLARE_TRACE nops */
+ #undef DECLARE_TRACE
+ #define DECLARE_TRACE(name, proto, args)
++#undef DECLARE_TRACE_CONDITION
++#define DECLARE_TRACE_CONDITION(name, proto, args, cond)
+ #ifdef TRACEPOINTS_ENABLED
+ #include <trace/trace_events.h>
+@@ -129,6 +135,7 @@
+ #undef DEFINE_EVENT_CONDITION
+ #undef TRACE_HEADER_MULTI_READ
+ #undef DECLARE_TRACE
++#undef DECLARE_TRACE_CONDITION
+ /* Only undef what we defined in this file */
+ #ifdef UNDEF_TRACE_INCLUDE_FILE
+-- 
+2.39.5
+
diff --git a/queue-6.14/tty-n_tty-use-uint-for-space-returned-by-tty_write_r.patch b/queue-6.14/tty-n_tty-use-uint-for-space-returned-by-tty_write_r.patch
new file mode 100644 (file)
index 0000000..9d27a69
--- /dev/null
@@ -0,0 +1,85 @@
+From 3fdbc0e5b910331099e0fe19f6baafa19f16c4f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Mar 2025 08:00:20 +0100
+Subject: tty: n_tty: use uint for space returned by tty_write_room()
+
+From: Jiri Slaby (SUSE) <jirislaby@kernel.org>
+
+[ Upstream commit d97aa066678bd1e2951ee93db9690835dfe57ab6 ]
+
+tty_write_room() returns an "unsigned int". So in case some insane
+driver (like my tty test driver) returns (legitimate) UINT_MAX from its
+tty_operations::write_room(), n_tty is confused on several places.
+
+For example, in process_output_block(), the result of tty_write_room()
+is stored into (signed) "int". So this UINT_MAX suddenly becomes -1. And
+that is extended to ssize_t and returned from process_output_block().
+This causes a write() to such a node to receive -EPERM (which is -1).
+
+Fix that by using proper "unsigned int" and proper "== 0" test. And
+return 0 constant directly in that "if", so that it is immediately clear
+what is returned ("space" equals to 0 at that point).
+
+Similarly for process_output() and __process_echoes().
+
+Note this does not fix any in-tree driver as of now.
+
+If you want "Fixes: something", it would be commit 03b3b1a2405c ("tty:
+make tty_operations::write_room return uint"). I intentionally do not
+mark this patch by a real tag below.
+
+Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
+Link: https://lore.kernel.org/r/20250317070046.24386-6-jirislaby@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/n_tty.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
+index 5e9ca4376d686..94fa981081fdb 100644
+--- a/drivers/tty/n_tty.c
++++ b/drivers/tty/n_tty.c
+@@ -486,7 +486,8 @@ static int do_output_char(u8 c, struct tty_struct *tty, int space)
+ static int process_output(u8 c, struct tty_struct *tty)
+ {
+       struct n_tty_data *ldata = tty->disc_data;
+-      int     space, retval;
++      unsigned int space;
++      int retval;
+       mutex_lock(&ldata->output_lock);
+@@ -522,16 +523,16 @@ static ssize_t process_output_block(struct tty_struct *tty,
+                                   const u8 *buf, unsigned int nr)
+ {
+       struct n_tty_data *ldata = tty->disc_data;
+-      int     space;
+-      int     i;
++      unsigned int space;
++      int i;
+       const u8 *cp;
+       mutex_lock(&ldata->output_lock);
+       space = tty_write_room(tty);
+-      if (space <= 0) {
++      if (space == 0) {
+               mutex_unlock(&ldata->output_lock);
+-              return space;
++              return 0;
+       }
+       if (nr > space)
+               nr = space;
+@@ -696,7 +697,7 @@ static int n_tty_process_echo_ops(struct tty_struct *tty, size_t *tail,
+ static size_t __process_echoes(struct tty_struct *tty)
+ {
+       struct n_tty_data *ldata = tty->disc_data;
+-      int     space, old_space;
++      unsigned int space, old_space;
+       size_t tail;
+       u8 c;
+-- 
+2.39.5
+
diff --git a/queue-6.14/tunnels-accept-packet_host-in-skb_tunnel_check_pmtu.patch b/queue-6.14/tunnels-accept-packet_host-in-skb_tunnel_check_pmtu.patch
new file mode 100644 (file)
index 0000000..1d3a569
--- /dev/null
@@ -0,0 +1,83 @@
+From 76beeead62dad30cc36b8a21be779fb021b4539f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 29 Mar 2025 01:33:44 +0100
+Subject: tunnels: Accept PACKET_HOST in skb_tunnel_check_pmtu().
+
+From: Guillaume Nault <gnault@redhat.com>
+
+[ Upstream commit 8930424777e43257f5bf6f0f0f53defd0d30415c ]
+
+Because skb_tunnel_check_pmtu() doesn't handle PACKET_HOST packets,
+commit 30a92c9e3d6b ("openvswitch: Set the skbuff pkt_type for proper
+pmtud support.") forced skb->pkt_type to PACKET_OUTGOING for
+openvswitch packets that are sent using the OVS_ACTION_ATTR_OUTPUT
+action. This allowed such packets to invoke the
+iptunnel_pmtud_check_icmp() or iptunnel_pmtud_check_icmpv6() helpers
+and thus trigger PMTU update on the input device.
+
+However, this also broke other parts of PMTU discovery. Since these
+packets don't have the PACKET_HOST type anymore, they won't trigger the
+sending of ICMP Fragmentation Needed or Packet Too Big messages to
+remote hosts when oversized (see the skb_in->pkt_type condition in
+__icmp_send() for example).
+
+These two skb->pkt_type checks are therefore incompatible as one
+requires skb->pkt_type to be PACKET_HOST, while the other requires it
+to be anything but PACKET_HOST.
+
+It makes sense to not trigger ICMP messages for non-PACKET_HOST packets
+as these messages should be generated only for incoming l2-unicast
+packets. However there doesn't seem to be any reason for
+skb_tunnel_check_pmtu() to ignore PACKET_HOST packets.
+
+Allow both cases to work by allowing skb_tunnel_check_pmtu() to work on
+PACKET_HOST packets and not overriding skb->pkt_type in openvswitch
+anymore.
+
+Fixes: 30a92c9e3d6b ("openvswitch: Set the skbuff pkt_type for proper pmtud support.")
+Fixes: 4cb47a8644cc ("tunnels: PMTU discovery support for directly bridged IP packets")
+Signed-off-by: Guillaume Nault <gnault@redhat.com>
+Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
+Reviewed-by: Aaron Conole <aconole@redhat.com>
+Tested-by: Aaron Conole <aconole@redhat.com>
+Link: https://patch.msgid.link/eac941652b86fddf8909df9b3bf0d97bc9444793.1743208264.git.gnault@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/ip_tunnel_core.c | 2 +-
+ net/openvswitch/actions.c | 6 ------
+ 2 files changed, 1 insertion(+), 7 deletions(-)
+
+diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
+index a3676155be78b..364ea798511ea 100644
+--- a/net/ipv4/ip_tunnel_core.c
++++ b/net/ipv4/ip_tunnel_core.c
+@@ -416,7 +416,7 @@ int skb_tunnel_check_pmtu(struct sk_buff *skb, struct dst_entry *encap_dst,
+       skb_dst_update_pmtu_no_confirm(skb, mtu);
+-      if (!reply || skb->pkt_type == PACKET_HOST)
++      if (!reply)
+               return 0;
+       if (skb->protocol == htons(ETH_P_IP))
+diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
+index 704c858cf2093..61fea7baae5d5 100644
+--- a/net/openvswitch/actions.c
++++ b/net/openvswitch/actions.c
+@@ -947,12 +947,6 @@ static void do_output(struct datapath *dp, struct sk_buff *skb, int out_port,
+                               pskb_trim(skb, ovs_mac_header_len(key));
+               }
+-              /* Need to set the pkt_type to involve the routing layer.  The
+-               * packet movement through the OVS datapath doesn't generally
+-               * use routing, but this is needed for tunnel cases.
+-               */
+-              skb->pkt_type = PACKET_OUTGOING;
+-
+               if (likely(!mru ||
+                          (skb->len <= mru + vport->dev->hard_header_len))) {
+                       ovs_vport_send(vport, skb, ovs_key_mac_proto(key));
+-- 
+2.39.5
+
diff --git a/queue-6.14/ublk-make-sure-ubq-canceling-is-set-when-queue-is-fr.patch b/queue-6.14/ublk-make-sure-ubq-canceling-is-set-when-queue-is-fr.patch
new file mode 100644 (file)
index 0000000..68d72ac
--- /dev/null
@@ -0,0 +1,97 @@
+From 96a654dd9bb5a688f20c7122a897c3b91f780bb2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Mar 2025 17:51:10 +0800
+Subject: ublk: make sure ubq->canceling is set when queue is frozen
+
+From: Ming Lei <ming.lei@redhat.com>
+
+[ Upstream commit 8741d0737921ec1c03cf59aebf4d01400c2b461a ]
+
+Now ublk driver depends on `ubq->canceling` for deciding if the request
+can be dispatched via uring_cmd & io_uring_cmd_complete_in_task().
+
+Once ubq->canceling is set, the uring_cmd can be done via ublk_cancel_cmd()
+and io_uring_cmd_done().
+
+So set ubq->canceling when queue is frozen, this way makes sure that the
+flag can be observed from ublk_queue_rq() reliably, and avoids
+use-after-free on uring_cmd.
+
+Fixes: 216c8f5ef0f2 ("ublk: replace monitor with cancelable uring_cmd")
+Signed-off-by: Ming Lei <ming.lei@redhat.com>
+Link: https://lore.kernel.org/r/20250327095123.179113-2-ming.lei@redhat.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/ublk_drv.c | 39 +++++++++++++++++++++++++++++----------
+ 1 file changed, 29 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
+index ca9a67b5b537a..b7adfaddc3abb 100644
+--- a/drivers/block/ublk_drv.c
++++ b/drivers/block/ublk_drv.c
+@@ -1452,17 +1452,27 @@ static void ublk_abort_queue(struct ublk_device *ub, struct ublk_queue *ubq)
+       }
+ }
++/* Must be called when queue is frozen */
++static bool ublk_mark_queue_canceling(struct ublk_queue *ubq)
++{
++      bool canceled;
++
++      spin_lock(&ubq->cancel_lock);
++      canceled = ubq->canceling;
++      if (!canceled)
++              ubq->canceling = true;
++      spin_unlock(&ubq->cancel_lock);
++
++      return canceled;
++}
++
+ static bool ublk_abort_requests(struct ublk_device *ub, struct ublk_queue *ubq)
+ {
++      bool was_canceled = ubq->canceling;
+       struct gendisk *disk;
+-      spin_lock(&ubq->cancel_lock);
+-      if (ubq->canceling) {
+-              spin_unlock(&ubq->cancel_lock);
++      if (was_canceled)
+               return false;
+-      }
+-      ubq->canceling = true;
+-      spin_unlock(&ubq->cancel_lock);
+       spin_lock(&ub->lock);
+       disk = ub->ub_disk;
+@@ -1474,14 +1484,23 @@ static bool ublk_abort_requests(struct ublk_device *ub, struct ublk_queue *ubq)
+       if (!disk)
+               return false;
+-      /* Now we are serialized with ublk_queue_rq() */
++      /*
++       * Now we are serialized with ublk_queue_rq()
++       *
++       * Make sure that ubq->canceling is set when queue is frozen,
++       * because ublk_queue_rq() has to rely on this flag for avoiding to
++       * touch completed uring_cmd
++       */
+       blk_mq_quiesce_queue(disk->queue);
+-      /* abort queue is for making forward progress */
+-      ublk_abort_queue(ub, ubq);
++      was_canceled = ublk_mark_queue_canceling(ubq);
++      if (!was_canceled) {
++              /* abort queue is for making forward progress */
++              ublk_abort_queue(ub, ubq);
++      }
+       blk_mq_unquiesce_queue(disk->queue);
+       put_device(disk_to_dev(disk));
+-      return true;
++      return !was_canceled;
+ }
+ static void ublk_cancel_cmd(struct ublk_queue *ubq, struct ublk_io *io,
+-- 
+2.39.5
+
diff --git a/queue-6.14/ucsi_ccg-don-t-show-failed-to-get-fw-build-informati.patch b/queue-6.14/ucsi_ccg-don-t-show-failed-to-get-fw-build-informati.patch
new file mode 100644 (file)
index 0000000..cf3aa1f
--- /dev/null
@@ -0,0 +1,47 @@
+From d2b2da74e868bb8ccdede6be6e82146999923fc3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Feb 2025 23:40:03 -0600
+Subject: ucsi_ccg: Don't show failed to get FW build information error
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+[ Upstream commit c16006852732dc4fe37c14b81f9b4458df05b832 ]
+
+The error `failed to get FW build information` is added for what looks
+to be for misdetection of the device property firmware-name.
+
+If the property is missing (such as on non-nvidia HW) this error shows up.
+Move the error into the scope of the property parser for "firmware-name"
+to avoid showing errors on systems without the firmware-name property.
+
+Fixes: 5c9ae5a87573d ("usb: typec: ucsi: ccg: add firmware flashing support")
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20250221054137.1631765-2-superm1@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/typec/ucsi/ucsi_ccg.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/usb/typec/ucsi/ucsi_ccg.c b/drivers/usb/typec/ucsi/ucsi_ccg.c
+index 4b1668733a4be..511dd1b224ae5 100644
+--- a/drivers/usb/typec/ucsi/ucsi_ccg.c
++++ b/drivers/usb/typec/ucsi/ucsi_ccg.c
+@@ -1433,11 +1433,10 @@ static int ucsi_ccg_probe(struct i2c_client *client)
+                       uc->fw_build = CCG_FW_BUILD_NVIDIA_TEGRA;
+               else if (!strcmp(fw_name, "nvidia,gpu"))
+                       uc->fw_build = CCG_FW_BUILD_NVIDIA;
++              if (!uc->fw_build)
++                      dev_err(uc->dev, "failed to get FW build information\n");
+       }
+-      if (!uc->fw_build)
+-              dev_err(uc->dev, "failed to get FW build information\n");
+-
+       /* reset ccg device and initialize ucsi */
+       status = ucsi_ccg_init(uc);
+       if (status < 0) {
+-- 
+2.39.5
+
diff --git a/queue-6.14/udp-fix-memory-accounting-leak.patch b/queue-6.14/udp-fix-memory-accounting-leak.patch
new file mode 100644 (file)
index 0000000..e4fd945
--- /dev/null
@@ -0,0 +1,171 @@
+From 602205618f23aecfbd0b8b789546cb53e80f2d5d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 11:44:43 -0700
+Subject: udp: Fix memory accounting leak.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit df207de9d9e7a4d92f8567e2c539d9c8c12fd99d ]
+
+Matt Dowling reported a weird UDP memory usage issue.
+
+Under normal operation, the UDP memory usage reported in /proc/net/sockstat
+remains close to zero.  However, it occasionally spiked to 524,288 pages
+and never dropped.  Moreover, the value doubled when the application was
+terminated.  Finally, it caused intermittent packet drops.
+
+We can reproduce the issue with the script below [0]:
+
+  1. /proc/net/sockstat reports 0 pages
+
+    # cat /proc/net/sockstat | grep UDP:
+    UDP: inuse 1 mem 0
+
+  2. Run the script till the report reaches 524,288
+
+    # python3 test.py & sleep 5
+    # cat /proc/net/sockstat | grep UDP:
+    UDP: inuse 3 mem 524288  <-- (INT_MAX + 1) >> PAGE_SHIFT
+
+  3. Kill the socket and confirm the number never drops
+
+    # pkill python3 && sleep 5
+    # cat /proc/net/sockstat | grep UDP:
+    UDP: inuse 1 mem 524288
+
+  4. (necessary since v6.0) Trigger proto_memory_pcpu_drain()
+
+    # python3 test.py & sleep 1 && pkill python3
+
+  5. The number doubles
+
+    # cat /proc/net/sockstat | grep UDP:
+    UDP: inuse 1 mem 1048577
+
+The application set INT_MAX to SO_RCVBUF, which triggered an integer
+overflow in udp_rmem_release().
+
+When a socket is close()d, udp_destruct_common() purges its receive
+queue and sums up skb->truesize in the queue.  This total is calculated
+and stored in a local unsigned integer variable.
+
+The total size is then passed to udp_rmem_release() to adjust memory
+accounting.  However, because the function takes a signed integer
+argument, the total size can wrap around, causing an overflow.
+
+Then, the released amount is calculated as follows:
+
+  1) Add size to sk->sk_forward_alloc.
+  2) Round down sk->sk_forward_alloc to the nearest lower multiple of
+      PAGE_SIZE and assign it to amount.
+  3) Subtract amount from sk->sk_forward_alloc.
+  4) Pass amount >> PAGE_SHIFT to __sk_mem_reduce_allocated().
+
+When the issue occurred, the total in udp_destruct_common() was 2147484480
+(INT_MAX + 833), which was cast to -2147482816 in udp_rmem_release().
+
+At 1) sk->sk_forward_alloc is changed from 3264 to -2147479552, and
+2) sets -2147479552 to amount.  3) reverts the wraparound, so we don't
+see a warning in inet_sock_destruct().  However, udp_memory_allocated
+ends up doubling at 4).
+
+Since commit 3cd3399dd7a8 ("net: implement per-cpu reserves for
+memory_allocated"), memory usage no longer doubles immediately after
+a socket is close()d because __sk_mem_reduce_allocated() caches the
+amount in udp_memory_per_cpu_fw_alloc.  However, the next time a UDP
+socket receives a packet, the subtraction takes effect, causing UDP
+memory usage to double.
+
+This issue makes further memory allocation fail once the socket's
+sk->sk_rmem_alloc exceeds net.ipv4.udp_rmem_min, resulting in packet
+drops.
+
+To prevent this issue, let's use unsigned int for the calculation and
+call sk_forward_alloc_add() only once for the small delta.
+
+Note that first_packet_length() also potentially has the same problem.
+
+[0]:
+from socket import *
+
+SO_RCVBUFFORCE = 33
+INT_MAX = (2 ** 31) - 1
+
+s = socket(AF_INET, SOCK_DGRAM)
+s.bind(('', 0))
+s.setsockopt(SOL_SOCKET, SO_RCVBUFFORCE, INT_MAX)
+
+c = socket(AF_INET, SOCK_DGRAM)
+c.connect(s.getsockname())
+
+data = b'a' * 100
+
+while True:
+    c.send(data)
+
+Fixes: f970bd9e3a06 ("udp: implement memory accounting helpers")
+Reported-by: Matt Dowling <madowlin@amazon.com>
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20250401184501.67377-3-kuniyu@amazon.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/udp.c | 16 +++++++---------
+ 1 file changed, 7 insertions(+), 9 deletions(-)
+
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index 31f7bfec23590..3fe85ecec2361 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -1626,12 +1626,12 @@ static bool udp_skb_has_head_state(struct sk_buff *skb)
+ }
+ /* fully reclaim rmem/fwd memory allocated for skb */
+-static void udp_rmem_release(struct sock *sk, int size, int partial,
+-                           bool rx_queue_lock_held)
++static void udp_rmem_release(struct sock *sk, unsigned int size,
++                           int partial, bool rx_queue_lock_held)
+ {
+       struct udp_sock *up = udp_sk(sk);
+       struct sk_buff_head *sk_queue;
+-      int amt;
++      unsigned int amt;
+       if (likely(partial)) {
+               up->forward_deficit += size;
+@@ -1651,10 +1651,8 @@ static void udp_rmem_release(struct sock *sk, int size, int partial,
+       if (!rx_queue_lock_held)
+               spin_lock(&sk_queue->lock);
+-
+-      sk_forward_alloc_add(sk, size);
+-      amt = (sk->sk_forward_alloc - partial) & ~(PAGE_SIZE - 1);
+-      sk_forward_alloc_add(sk, -amt);
++      amt = (size + sk->sk_forward_alloc - partial) & ~(PAGE_SIZE - 1);
++      sk_forward_alloc_add(sk, size - amt);
+       if (amt)
+               __sk_mem_reduce_allocated(sk, amt >> PAGE_SHIFT);
+@@ -1844,7 +1842,7 @@ EXPORT_SYMBOL_GPL(skb_consume_udp);
+ static struct sk_buff *__first_packet_length(struct sock *sk,
+                                            struct sk_buff_head *rcvq,
+-                                           int *total)
++                                           unsigned int *total)
+ {
+       struct sk_buff *skb;
+@@ -1877,8 +1875,8 @@ static int first_packet_length(struct sock *sk)
+ {
+       struct sk_buff_head *rcvq = &udp_sk(sk)->reader_queue;
+       struct sk_buff_head *sk_queue = &sk->sk_receive_queue;
++      unsigned int total = 0;
+       struct sk_buff *skb;
+-      int total = 0;
+       int res;
+       spin_lock_bh(&rcvq->lock);
+-- 
+2.39.5
+
diff --git a/queue-6.14/udp-fix-multiple-wraparounds-of-sk-sk_rmem_alloc.patch b/queue-6.14/udp-fix-multiple-wraparounds-of-sk-sk_rmem_alloc.patch
new file mode 100644 (file)
index 0000000..d2a9fdb
--- /dev/null
@@ -0,0 +1,138 @@
+From 937ff7aa0714714869c32d0e329eab955964e562 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 11:44:42 -0700
+Subject: udp: Fix multiple wraparounds of sk->sk_rmem_alloc.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 5a465a0da13ee9fbd7d3cd0b2893309b0fe4b7e3 ]
+
+__udp_enqueue_schedule_skb() has the following condition:
+
+  if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf)
+          goto drop;
+
+sk->sk_rcvbuf is initialised by net.core.rmem_default and later can
+be configured by SO_RCVBUF, which is limited by net.core.rmem_max,
+or SO_RCVBUFFORCE.
+
+If we set INT_MAX to sk->sk_rcvbuf, the condition is always false
+as sk->sk_rmem_alloc is also signed int.
+
+Then, the size of the incoming skb is added to sk->sk_rmem_alloc
+unconditionally.
+
+This results in integer overflow (possibly multiple times) on
+sk->sk_rmem_alloc and allows a single socket to have skb up to
+net.core.udp_mem[1].
+
+For example, if we set a large value to udp_mem[1] and INT_MAX to
+sk->sk_rcvbuf and flood packets to the socket, we can see multiple
+overflows:
+
+  # cat /proc/net/sockstat | grep UDP:
+  UDP: inuse 3 mem 7956736  <-- (7956736 << 12) bytes > INT_MAX * 15
+                                             ^- PAGE_SHIFT
+  # ss -uam
+  State  Recv-Q      ...
+  UNCONN -1757018048 ...    <-- flipping the sign repeatedly
+         skmem:(r2537949248,rb2147483646,t0,tb212992,f1984,w0,o0,bl0,d0)
+
+Previously, we had a boundary check for INT_MAX, which was removed by
+commit 6a1f12dd85a8 ("udp: relax atomic operation on sk->sk_rmem_alloc").
+
+A complete fix would be to revert it and cap the right operand by
+INT_MAX:
+
+  rmem = atomic_add_return(size, &sk->sk_rmem_alloc);
+  if (rmem > min(size + (unsigned int)sk->sk_rcvbuf, INT_MAX))
+          goto uncharge_drop;
+
+but we do not want to add the expensive atomic_add_return() back just
+for the corner case.
+
+Casting rmem to unsigned int prevents multiple wraparounds, but we still
+allow a single wraparound.
+
+  # cat /proc/net/sockstat | grep UDP:
+  UDP: inuse 3 mem 524288  <-- (INT_MAX + 1) >> 12
+
+  # ss -uam
+  State  Recv-Q      ...
+  UNCONN -2147482816 ...   <-- INT_MAX + 831 bytes
+         skmem:(r2147484480,rb2147483646,t0,tb212992,f3264,w0,o0,bl0,d14468947)
+
+So, let's define rmem and rcvbuf as unsigned int and check skb->truesize
+only when rcvbuf is large enough to lower the overflow possibility.
+
+Note that we still have a small chance to see overflow if multiple skbs
+to the same socket are processed on different core at the same time and
+each size does not exceed the limit but the total size does.
+
+Note also that we must ignore skb->truesize for a small buffer as
+explained in commit 363dc73acacb ("udp: be less conservative with
+sock rmem accounting").
+
+Fixes: 6a1f12dd85a8 ("udp: relax atomic operation on sk->sk_rmem_alloc")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20250401184501.67377-2-kuniyu@amazon.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/udp.c | 26 +++++++++++++++++---------
+ 1 file changed, 17 insertions(+), 9 deletions(-)
+
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index a9bb9ce5438ea..31f7bfec23590 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -1726,17 +1726,25 @@ static int udp_rmem_schedule(struct sock *sk, int size)
+ int __udp_enqueue_schedule_skb(struct sock *sk, struct sk_buff *skb)
+ {
+       struct sk_buff_head *list = &sk->sk_receive_queue;
+-      int rmem, err = -ENOMEM;
++      unsigned int rmem, rcvbuf;
+       spinlock_t *busy = NULL;
+-      int size, rcvbuf;
++      int size, err = -ENOMEM;
+-      /* Immediately drop when the receive queue is full.
+-       * Always allow at least one packet.
+-       */
+       rmem = atomic_read(&sk->sk_rmem_alloc);
+       rcvbuf = READ_ONCE(sk->sk_rcvbuf);
+-      if (rmem > rcvbuf)
+-              goto drop;
++      size = skb->truesize;
++
++      /* Immediately drop when the receive queue is full.
++       * Cast to unsigned int performs the boundary check for INT_MAX.
++       */
++      if (rmem + size > rcvbuf) {
++              if (rcvbuf > INT_MAX >> 1)
++                      goto drop;
++
++              /* Always allow at least one packet for small buffer. */
++              if (rmem > rcvbuf)
++                      goto drop;
++      }
+       /* Under mem pressure, it might be helpful to help udp_recvmsg()
+        * having linear skbs :
+@@ -1746,10 +1754,10 @@ int __udp_enqueue_schedule_skb(struct sock *sk, struct sk_buff *skb)
+        */
+       if (rmem > (rcvbuf >> 1)) {
+               skb_condense(skb);
+-
++              size = skb->truesize;
+               busy = busylock_acquire(sk);
+       }
+-      size = skb->truesize;
++
+       udp_set_dev_scratch(skb);
+       atomic_add(size, &sk->sk_rmem_alloc);
+-- 
+2.39.5
+
diff --git a/queue-6.14/um-hostfs-avoid-issues-on-inode-number-reuse-by-host.patch b/queue-6.14/um-hostfs-avoid-issues-on-inode-number-reuse-by-host.patch
new file mode 100644 (file)
index 0000000..7dcfdbb
--- /dev/null
@@ -0,0 +1,172 @@
+From bec083e14d8780df43f6f350e0aed23135a9879f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Feb 2025 10:28:22 +0100
+Subject: um: hostfs: avoid issues on inode number reuse by host
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Benjamin Berg <benjamin.berg@intel.com>
+
+[ Upstream commit 0bc754d1e31f40f4a343b692096d9e092ccc0370 ]
+
+Some file systems (e.g. ext4) may reuse inode numbers once the inode is
+not in use anymore. Usually hostfs will keep an FD open for each inode,
+but this is not always the case. In the case of sockets, this cannot
+even be done properly.
+
+As such, the following sequence of events was possible:
+ * application creates and deletes a socket
+ * hostfs creates/deletes the socket on the host
+ * inode is still in the hostfs cache
+ * hostfs creates a new file
+ * ext4 on the outside reuses the inode number
+ * hostfs finds the socket inode for the newly created file
+ * application receives -ENXIO when opening the file
+
+As mentioned, this can only happen if the deleted file is a special file
+that is never opened on the host (i.e. no .open fop).
+
+As such, to prevent issues, it is sufficient to check that the inode
+has the expected type. That said, also add a check for the inode birth
+time, just to be on the safe side.
+
+Fixes: 74ce793bcbde ("hostfs: Fix ephemeral inodes")
+Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
+Reviewed-by: Mickaël Salaün <mic@digikod.net>
+Tested-by: Mickaël Salaün <mic@digikod.net>
+Link: https://patch.msgid.link/20250214092822.1241575-1-benjamin@sipsolutions.net
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/hostfs/hostfs.h      |  2 +-
+ fs/hostfs/hostfs_kern.c |  7 ++++-
+ fs/hostfs/hostfs_user.c | 59 ++++++++++++++++++++++++-----------------
+ 3 files changed, 41 insertions(+), 27 deletions(-)
+
+diff --git a/fs/hostfs/hostfs.h b/fs/hostfs/hostfs.h
+index 8b39c15c408cc..15b2f094d36ef 100644
+--- a/fs/hostfs/hostfs.h
++++ b/fs/hostfs/hostfs.h
+@@ -60,7 +60,7 @@ struct hostfs_stat {
+       unsigned int uid;
+       unsigned int gid;
+       unsigned long long size;
+-      struct hostfs_timespec atime, mtime, ctime;
++      struct hostfs_timespec atime, mtime, ctime, btime;
+       unsigned int blksize;
+       unsigned long long blocks;
+       struct {
+diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
+index e0741e468956d..e6e2472357282 100644
+--- a/fs/hostfs/hostfs_kern.c
++++ b/fs/hostfs/hostfs_kern.c
+@@ -33,6 +33,7 @@ struct hostfs_inode_info {
+       struct inode vfs_inode;
+       struct mutex open_mutex;
+       dev_t dev;
++      struct hostfs_timespec btime;
+ };
+ static inline struct hostfs_inode_info *HOSTFS_I(struct inode *inode)
+@@ -547,6 +548,7 @@ static int hostfs_inode_set(struct inode *ino, void *data)
+       }
+       HOSTFS_I(ino)->dev = dev;
++      HOSTFS_I(ino)->btime = st->btime;
+       ino->i_ino = st->ino;
+       ino->i_mode = st->mode;
+       return hostfs_inode_update(ino, st);
+@@ -557,7 +559,10 @@ static int hostfs_inode_test(struct inode *inode, void *data)
+       const struct hostfs_stat *st = data;
+       dev_t dev = MKDEV(st->dev.maj, st->dev.min);
+-      return inode->i_ino == st->ino && HOSTFS_I(inode)->dev == dev;
++      return inode->i_ino == st->ino && HOSTFS_I(inode)->dev == dev &&
++             (inode->i_mode & S_IFMT) == (st->mode & S_IFMT) &&
++             HOSTFS_I(inode)->btime.tv_sec == st->btime.tv_sec &&
++             HOSTFS_I(inode)->btime.tv_nsec == st->btime.tv_nsec;
+ }
+ static struct inode *hostfs_iget(struct super_block *sb, char *name)
+diff --git a/fs/hostfs/hostfs_user.c b/fs/hostfs/hostfs_user.c
+index 97e9c40a94488..3bcd9f35e70b2 100644
+--- a/fs/hostfs/hostfs_user.c
++++ b/fs/hostfs/hostfs_user.c
+@@ -18,39 +18,48 @@
+ #include "hostfs.h"
+ #include <utime.h>
+-static void stat64_to_hostfs(const struct stat64 *buf, struct hostfs_stat *p)
++static void statx_to_hostfs(const struct statx *buf, struct hostfs_stat *p)
+ {
+-      p->ino = buf->st_ino;
+-      p->mode = buf->st_mode;
+-      p->nlink = buf->st_nlink;
+-      p->uid = buf->st_uid;
+-      p->gid = buf->st_gid;
+-      p->size = buf->st_size;
+-      p->atime.tv_sec = buf->st_atime;
+-      p->atime.tv_nsec = 0;
+-      p->ctime.tv_sec = buf->st_ctime;
+-      p->ctime.tv_nsec = 0;
+-      p->mtime.tv_sec = buf->st_mtime;
+-      p->mtime.tv_nsec = 0;
+-      p->blksize = buf->st_blksize;
+-      p->blocks = buf->st_blocks;
+-      p->rdev.maj = os_major(buf->st_rdev);
+-      p->rdev.min = os_minor(buf->st_rdev);
+-      p->dev.maj = os_major(buf->st_dev);
+-      p->dev.min = os_minor(buf->st_dev);
++      p->ino = buf->stx_ino;
++      p->mode = buf->stx_mode;
++      p->nlink = buf->stx_nlink;
++      p->uid = buf->stx_uid;
++      p->gid = buf->stx_gid;
++      p->size = buf->stx_size;
++      p->atime.tv_sec = buf->stx_atime.tv_sec;
++      p->atime.tv_nsec = buf->stx_atime.tv_nsec;
++      p->ctime.tv_sec = buf->stx_ctime.tv_sec;
++      p->ctime.tv_nsec = buf->stx_ctime.tv_nsec;
++      p->mtime.tv_sec = buf->stx_mtime.tv_sec;
++      p->mtime.tv_nsec = buf->stx_mtime.tv_nsec;
++      if (buf->stx_mask & STATX_BTIME) {
++              p->btime.tv_sec = buf->stx_btime.tv_sec;
++              p->btime.tv_nsec = buf->stx_btime.tv_nsec;
++      } else {
++              memset(&p->btime, 0, sizeof(p->btime));
++      }
++      p->blksize = buf->stx_blksize;
++      p->blocks = buf->stx_blocks;
++      p->rdev.maj = buf->stx_rdev_major;
++      p->rdev.min = buf->stx_rdev_minor;
++      p->dev.maj = buf->stx_dev_major;
++      p->dev.min = buf->stx_dev_minor;
+ }
+ int stat_file(const char *path, struct hostfs_stat *p, int fd)
+ {
+-      struct stat64 buf;
++      struct statx buf;
++      int flags = AT_SYMLINK_NOFOLLOW;
+       if (fd >= 0) {
+-              if (fstat64(fd, &buf) < 0)
+-                      return -errno;
+-      } else if (lstat64(path, &buf) < 0) {
+-              return -errno;
++              flags |= AT_EMPTY_PATH;
++              path = "";
+       }
+-      stat64_to_hostfs(&buf, p);
++
++      if ((statx(fd, path, flags, STATX_BASIC_STATS | STATX_BTIME, &buf)) < 0)
++              return -errno;
++
++      statx_to_hostfs(&buf, p);
+       return 0;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/um-pass-the-correct-rust-target-and-options-with-gcc.patch b/queue-6.14/um-pass-the-correct-rust-target-and-options-with-gcc.patch
new file mode 100644 (file)
index 0000000..fc8dffd
--- /dev/null
@@ -0,0 +1,57 @@
+From f8d8be0357d81998d9b7d5e358819bb09ffd7a34 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Feb 2025 18:53:51 +0800
+Subject: um: Pass the correct Rust target and options with gcc
+
+From: David Gow <davidgow@google.com>
+
+[ Upstream commit 5550187c4c21740942c32a9ae56f9f472a104cb4 ]
+
+In order to work around some issues with disabling SSE on older versions
+of gcc (compilation would fail upon seeing a function declaration
+containing a float, even if it was never called or defined), the
+corresponding CFLAGS and RUSTFLAGS were only set when using clang.
+
+However, this led to two problems:
+- Newer gcc versions also wouldn't get the correct flags, despite not
+  having the bug.
+- The RUSTFLAGS for setting the rust target definition were not set,
+  despite being unrelated. This works by chance for x86_64, as the
+  built-in default target is close enough, but not for 32-bit x86.
+
+Move the target definition outside the conditional block, and update the
+condition to take into account the gcc version.
+
+Fixes: a3046a618a28 ("um: Only disable SSE on clang to work around old GCC bugs")
+Signed-off-by: David Gow <davidgow@google.com>
+Link: https://patch.msgid.link/20250210105353.2238769-2-davidgow@google.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/Makefile.um | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/arch/x86/Makefile.um b/arch/x86/Makefile.um
+index a46b1397ad01c..c86cbd9cbba38 100644
+--- a/arch/x86/Makefile.um
++++ b/arch/x86/Makefile.um
+@@ -7,12 +7,13 @@ core-y += arch/x86/crypto/
+ # GCC versions < 11. See:
+ # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99652
+ #
+-ifeq ($(CONFIG_CC_IS_CLANG),y)
+-KBUILD_CFLAGS += -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx
+-KBUILD_RUSTFLAGS += --target=$(objtree)/scripts/target.json
++ifeq ($(call gcc-min-version, 110000)$(CONFIG_CC_IS_CLANG),y)
++KBUILD_CFLAGS +=  -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx
+ KBUILD_RUSTFLAGS += -Ctarget-feature=-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-avx,-avx2
+ endif
++KBUILD_RUSTFLAGS += --target=$(objtree)/scripts/target.json
++
+ ifeq ($(CONFIG_X86_32),y)
+ START := 0x8048000
+-- 
+2.39.5
+
diff --git a/queue-6.14/um-remove-copy_from_kernel_nofault_allowed.patch b/queue-6.14/um-remove-copy_from_kernel_nofault_allowed.patch
new file mode 100644 (file)
index 0000000..eb881e7
--- /dev/null
@@ -0,0 +1,144 @@
+From 0924236862703fa63f527aeceb8ea374f1b81d25 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Feb 2025 17:09:26 +0100
+Subject: um: remove copy_from_kernel_nofault_allowed
+
+From: Benjamin Berg <benjamin.berg@intel.com>
+
+[ Upstream commit 84a6fc378471fbeaf48f8604566a5a33a3d63c18 ]
+
+There is no need to override the default version of this function
+anymore as UML now has proper _nofault memory access functions.
+
+Doing this also fixes the fact that the implementation was incorrect as
+using mincore() will incorrectly flag pages as inaccessible if they were
+swapped out by the host.
+
+Fixes: f75b1b1bedfb ("um: Implement probe_kernel_read()")
+Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
+Link: https://patch.msgid.link/20250210160926.420133-3-benjamin@sipsolutions.net
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/um/include/shared/os.h |  1 -
+ arch/um/kernel/Makefile     |  2 +-
+ arch/um/kernel/maccess.c    | 19 --------------
+ arch/um/os-Linux/process.c  | 51 -------------------------------------
+ 4 files changed, 1 insertion(+), 72 deletions(-)
+ delete mode 100644 arch/um/kernel/maccess.c
+
+diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h
+index 5babad8c5f75e..bc02767f06397 100644
+--- a/arch/um/include/shared/os.h
++++ b/arch/um/include/shared/os.h
+@@ -213,7 +213,6 @@ extern int os_protect_memory(void *addr, unsigned long len,
+ extern int os_unmap_memory(void *addr, int len);
+ extern int os_drop_memory(void *addr, int length);
+ extern int can_drop_memory(void);
+-extern int os_mincore(void *addr, unsigned long len);
+ void os_set_pdeathsig(void);
+diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
+index f8567b933ffaa..4df1cd0d20179 100644
+--- a/arch/um/kernel/Makefile
++++ b/arch/um/kernel/Makefile
+@@ -17,7 +17,7 @@ extra-y := vmlinux.lds
+ obj-y = config.o exec.o exitcode.o irq.o ksyms.o mem.o \
+       physmem.o process.o ptrace.o reboot.o sigio.o \
+       signal.o sysrq.o time.o tlb.o trap.o \
+-      um_arch.o umid.o maccess.o kmsg_dump.o capflags.o skas/
++      um_arch.o umid.o kmsg_dump.o capflags.o skas/
+ obj-y += load_file.o
+ obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
+diff --git a/arch/um/kernel/maccess.c b/arch/um/kernel/maccess.c
+deleted file mode 100644
+index 8ccd56813f684..0000000000000
+--- a/arch/um/kernel/maccess.c
++++ /dev/null
+@@ -1,19 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0-only
+-/*
+- * Copyright (C) 2013 Richard Weinberger <richrd@nod.at>
+- */
+-
+-#include <linux/uaccess.h>
+-#include <linux/kernel.h>
+-#include <os.h>
+-
+-bool copy_from_kernel_nofault_allowed(const void *src, size_t size)
+-{
+-      void *psrc = (void *)rounddown((unsigned long)src, PAGE_SIZE);
+-
+-      if ((unsigned long)src < PAGE_SIZE || size <= 0)
+-              return false;
+-      if (os_mincore(psrc, size + src - psrc) <= 0)
+-              return false;
+-      return true;
+-}
+diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
+index 9f086f9394202..184566edeee99 100644
+--- a/arch/um/os-Linux/process.c
++++ b/arch/um/os-Linux/process.c
+@@ -142,57 +142,6 @@ int __init can_drop_memory(void)
+       return ok;
+ }
+-static int os_page_mincore(void *addr)
+-{
+-      char vec[2];
+-      int ret;
+-
+-      ret = mincore(addr, UM_KERN_PAGE_SIZE, vec);
+-      if (ret < 0) {
+-              if (errno == ENOMEM || errno == EINVAL)
+-                      return 0;
+-              else
+-                      return -errno;
+-      }
+-
+-      return vec[0] & 1;
+-}
+-
+-int os_mincore(void *addr, unsigned long len)
+-{
+-      char *vec;
+-      int ret, i;
+-
+-      if (len <= UM_KERN_PAGE_SIZE)
+-              return os_page_mincore(addr);
+-
+-      vec = calloc(1, (len + UM_KERN_PAGE_SIZE - 1) / UM_KERN_PAGE_SIZE);
+-      if (!vec)
+-              return -ENOMEM;
+-
+-      ret = mincore(addr, UM_KERN_PAGE_SIZE, vec);
+-      if (ret < 0) {
+-              if (errno == ENOMEM || errno == EINVAL)
+-                      ret = 0;
+-              else
+-                      ret = -errno;
+-
+-              goto out;
+-      }
+-
+-      for (i = 0; i < ((len + UM_KERN_PAGE_SIZE - 1) / UM_KERN_PAGE_SIZE); i++) {
+-              if (!(vec[i] & 1)) {
+-                      ret = 0;
+-                      goto out;
+-              }
+-      }
+-
+-      ret = 1;
+-out:
+-      free(vec);
+-      return ret;
+-}
+-
+ void init_new_thread_signals(void)
+ {
+       set_handler(SIGSEGV);
+-- 
+2.39.5
+
diff --git a/queue-6.14/usb-typec-thunderbolt-fix-loops-that-iterate-typec_p.patch b/queue-6.14/usb-typec-thunderbolt-fix-loops-that-iterate-typec_p.patch
new file mode 100644 (file)
index 0000000..21b1fad
--- /dev/null
@@ -0,0 +1,60 @@
+From 97e2aa7a98097fde3fe6075934281458eebf7ecf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jan 2025 19:40:23 +0000
+Subject: usb: typec: thunderbolt: Fix loops that iterate TYPEC_PLUG_SOP_P and
+ TYPEC_PLUG_SOP_PP
+
+From: Benson Leung <bleung@chromium.org>
+
+[ Upstream commit b51c1e8d2f49342b2087338c72511326fdb7b172 ]
+
+Fixes these Smatch static checker warnings:
+drivers/usb/typec/altmodes/thunderbolt.c:116 tbt_altmode_work() warn: why is zero skipped 'i'
+drivers/usb/typec/altmodes/thunderbolt.c:147 tbt_enter_modes_ordered() warn: why is zero skipped 'i'
+drivers/usb/typec/altmodes/thunderbolt.c:328 tbt_altmode_remove() warn: why is zero skipped 'i'
+
+Fixes: 100e25738659 ("usb: typec: Add driver for Thunderbolt 3 Alternate Mode")
+Signed-off-by: Benson Leung <bleung@chromium.org>
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/Z5Psp615abaaId6J@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/typec/altmodes/thunderbolt.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/usb/typec/altmodes/thunderbolt.c b/drivers/usb/typec/altmodes/thunderbolt.c
+index 1b475b1d98e78..94e47d30e5989 100644
+--- a/drivers/usb/typec/altmodes/thunderbolt.c
++++ b/drivers/usb/typec/altmodes/thunderbolt.c
+@@ -112,7 +112,7 @@ static void tbt_altmode_work(struct work_struct *work)
+       return;
+ disable_plugs:
+-      for (int i = TYPEC_PLUG_SOP_PP; i > 0; --i) {
++      for (int i = TYPEC_PLUG_SOP_PP; i >= 0; --i) {
+               if (tbt->plug[i])
+                       typec_altmode_put_plug(tbt->plug[i]);
+@@ -143,7 +143,7 @@ static int tbt_enter_modes_ordered(struct typec_altmode *alt)
+       if (tbt->plug[TYPEC_PLUG_SOP_P]) {
+               ret = typec_cable_altmode_enter(alt, TYPEC_PLUG_SOP_P, NULL);
+               if (ret < 0) {
+-                      for (int i = TYPEC_PLUG_SOP_PP; i > 0; --i) {
++                      for (int i = TYPEC_PLUG_SOP_PP; i >= 0; --i) {
+                               if (tbt->plug[i])
+                                       typec_altmode_put_plug(tbt->plug[i]);
+@@ -324,7 +324,7 @@ static void tbt_altmode_remove(struct typec_altmode *alt)
+ {
+       struct tbt_altmode *tbt = typec_altmode_get_drvdata(alt);
+-      for (int i = TYPEC_PLUG_SOP_PP; i > 0; --i) {
++      for (int i = TYPEC_PLUG_SOP_PP; i >= 0; --i) {
+               if (tbt->plug[i])
+                       typec_altmode_put_plug(tbt->plug[i]);
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/usb-typec-thunderbolt-remove-is_err-check-for-plug.patch b/queue-6.14/usb-typec-thunderbolt-remove-is_err-check-for-plug.patch
new file mode 100644 (file)
index 0000000..c9c8169
--- /dev/null
@@ -0,0 +1,43 @@
+From adc1c8868f522ad28ede942e4c7189dfbe074e29 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jan 2025 19:40:38 +0000
+Subject: usb: typec: thunderbolt: Remove IS_ERR check for plug
+
+From: Benson Leung <bleung@chromium.org>
+
+[ Upstream commit 9682c35ff6ecd76d9462d4749b8b413d3e8e605e ]
+
+Fixes these Smatch static checker warnings:
+drivers/usb/typec/altmodes/thunderbolt.c:354 tbt_ready() warn: 'plug' is not an error pointer
+
+Fixes: 100e25738659 ("usb: typec: Add driver for Thunderbolt 3 Alternate Mode")
+Signed-off-by: Benson Leung <bleung@chromium.org>
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/Z5PstnlA52Z1F2SU@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/typec/altmodes/thunderbolt.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/typec/altmodes/thunderbolt.c b/drivers/usb/typec/altmodes/thunderbolt.c
+index 94e47d30e5989..6eadf7835f8f6 100644
+--- a/drivers/usb/typec/altmodes/thunderbolt.c
++++ b/drivers/usb/typec/altmodes/thunderbolt.c
+@@ -351,10 +351,10 @@ static bool tbt_ready(struct typec_altmode *alt)
+        */
+       for (int i = 0; i < TYPEC_PLUG_SOP_PP + 1; i++) {
+               plug = typec_altmode_get_plug(tbt->alt, i);
+-              if (IS_ERR(plug))
++              if (!plug)
+                       continue;
+-              if (!plug || plug->svid != USB_TYPEC_TBT_SID)
++              if (plug->svid != USB_TYPEC_TBT_SID)
+                       break;
+               plug->desc = "Thunderbolt3";
+-- 
+2.39.5
+
diff --git a/queue-6.14/usb-xhci-correct-debug-message-page-size-calculation.patch b/queue-6.14/usb-xhci-correct-debug-message-page-size-calculation.patch
new file mode 100644 (file)
index 0000000..6da504c
--- /dev/null
@@ -0,0 +1,52 @@
+From 5e51f431e8946c1e89e34b4c2cc78444295676aa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Mar 2025 16:49:47 +0200
+Subject: usb: xhci: correct debug message page size calculation
+
+From: Niklas Neronin <niklas.neronin@linux.intel.com>
+
+[ Upstream commit 55741c723318905e6d5161bf1e12749020b161e3 ]
+
+The ffs() function returns the index of the first set bit, starting from 1.
+If no bits are set, it returns zero. This behavior causes an off-by-one
+page size in the debug message, as the page size calculation [1]
+is zero-based, while ffs() is one-based.
+
+Fix this by subtracting one from the result of ffs(). Note that since
+variable 'val' is unsigned, subtracting one from zero will result in the
+maximum unsigned integer value. Consequently, the condition 'if (val < 16)'
+will still function correctly.
+
+[1], Page size: (2^(n+12)), where 'n' is the set page size bit.
+
+Fixes: 81720ec5320c ("usb: host: xhci: use ffs() in xhci_mem_init()")
+Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20250306144954.3507700-9-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/xhci-mem.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
+index fdf0c1008225a..9aa7e2a876ec1 100644
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -2391,10 +2391,10 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
+       page_size = readl(&xhci->op_regs->page_size);
+       xhci_dbg_trace(xhci, trace_xhci_dbg_init,
+                       "Supported page size register = 0x%x", page_size);
+-      i = ffs(page_size);
+-      if (i < 16)
++      val = ffs(page_size) - 1;
++      if (val < 16)
+               xhci_dbg_trace(xhci, trace_xhci_dbg_init,
+-                      "Supported page size of %iK", (1 << (i+12)) / 1024);
++                      "Supported page size of %iK", (1 << (val + 12)) / 1024);
+       else
+               xhci_warn(xhci, "WARN: no supported page size\n");
+       /* Use 4K pages, since that's common and the minimum the HC supports */
+-- 
+2.39.5
+
diff --git a/queue-6.14/vhost-scsi-fix-handling-of-multiple-calls-to-vhost_s.patch b/queue-6.14/vhost-scsi-fix-handling-of-multiple-calls-to-vhost_s.patch
new file mode 100644 (file)
index 0000000..c0a7192
--- /dev/null
@@ -0,0 +1,176 @@
+From e5b3522c692c8c2a5df548e911b538f804e841fd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Jan 2025 15:09:22 -0600
+Subject: vhost-scsi: Fix handling of multiple calls to vhost_scsi_set_endpoint
+
+From: Mike Christie <michael.christie@oracle.com>
+
+[ Upstream commit 5dd639a1646ef5fe8f4bf270fad47c5c3755b9b6 ]
+
+If vhost_scsi_set_endpoint is called multiple times without a
+vhost_scsi_clear_endpoint between them, we can hit multiple bugs
+found by Haoran Zhang:
+
+1. Use-after-free when no tpgs are found:
+
+This fixes a use after free that occurs when vhost_scsi_set_endpoint is
+called more than once and calls after the first call do not find any
+tpgs to add to the vs_tpg. When vhost_scsi_set_endpoint first finds
+tpgs to add to the vs_tpg array match=true, so we will do:
+
+vhost_vq_set_backend(vq, vs_tpg);
+...
+
+kfree(vs->vs_tpg);
+vs->vs_tpg = vs_tpg;
+
+If vhost_scsi_set_endpoint is called again and no tpgs are found
+match=false so we skip the vhost_vq_set_backend call leaving the
+pointer to the vs_tpg we then free via:
+
+kfree(vs->vs_tpg);
+vs->vs_tpg = vs_tpg;
+
+If a scsi request is then sent we do:
+
+vhost_scsi_handle_vq -> vhost_scsi_get_req -> vhost_vq_get_backend
+
+which sees the vs_tpg we just did a kfree on.
+
+2. Tpg dir removal hang:
+
+This patch fixes an issue where we cannot remove a LIO/target layer
+tpg (and structs above it like the target) dir due to the refcount
+dropping to -1.
+
+The problem is that if vhost_scsi_set_endpoint detects a tpg is already
+in the vs->vs_tpg array or if the tpg has been removed so
+target_depend_item fails, the undepend goto handler will do
+target_undepend_item on all tpgs in the vs_tpg array dropping their
+refcount to 0. At this time vs_tpg contains both the tpgs we have added
+in the current vhost_scsi_set_endpoint call as well as tpgs we added in
+previous calls which are also in vs->vs_tpg.
+
+Later, when vhost_scsi_clear_endpoint runs it will do
+target_undepend_item on all the tpgs in the vs->vs_tpg which will drop
+their refcount to -1. Userspace will then not be able to remove the tpg
+and will hang when it tries to do rmdir on the tpg dir.
+
+3. Tpg leak:
+
+This fixes a bug where we can leak tpgs and cause them to be
+un-removable because the target name is overwritten when
+vhost_scsi_set_endpoint is called multiple times but with different
+target names.
+
+The bug occurs if a user has called VHOST_SCSI_SET_ENDPOINT and setup
+a vhost-scsi device to target/tpg mapping, then calls
+VHOST_SCSI_SET_ENDPOINT again with a new target name that has tpgs we
+haven't seen before (target1 has tpg1 but target2 has tpg2). When this
+happens we don't teardown the old target tpg mapping and just overwrite
+the target name and the vs->vs_tpg array. Later when we do
+vhost_scsi_clear_endpoint, we are passed in either target1 or target2's
+name and we will only match that target's tpgs when we loop over the
+vs->vs_tpg. We will then return from the function without doing
+target_undepend_item on the tpgs.
+
+Because of all these bugs, it looks like being able to call
+vhost_scsi_set_endpoint multiple times was never supported. The major
+user, QEMU, already has checks to prevent this use case. So to fix the
+issues, this patch prevents vhost_scsi_set_endpoint from being called
+if it's already successfully added tpgs. To add, remove or change the
+tpg config or target name, you must do a vhost_scsi_clear_endpoint
+first.
+
+Fixes: 25b98b64e284 ("vhost scsi: alloc cmds per vq instead of session")
+Fixes: 4f7f46d32c98 ("tcm_vhost: Use vq->private_data to indicate if the endpoint is setup")
+Reported-by: Haoran Zhang <wh1sper@zju.edu.cn>
+Closes: https://lore.kernel.org/virtualization/e418a5ee-45ca-4d18-9b5d-6f8b6b1add8e@oracle.com/T/#me6c0041ce376677419b9b2563494172a01487ecb
+Signed-off-by: Mike Christie <michael.christie@oracle.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Message-Id: <20250129210922.121533-1-michael.christie@oracle.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/vhost/scsi.c | 25 +++++++++++++------------
+ 1 file changed, 13 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
+index 718fa4e0b31ec..7aeff435c1d87 100644
+--- a/drivers/vhost/scsi.c
++++ b/drivers/vhost/scsi.c
+@@ -1699,14 +1699,19 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs,
+               }
+       }
++      if (vs->vs_tpg) {
++              pr_err("vhost-scsi endpoint already set for %s.\n",
++                     vs->vs_vhost_wwpn);
++              ret = -EEXIST;
++              goto out;
++      }
++
+       len = sizeof(vs_tpg[0]) * VHOST_SCSI_MAX_TARGET;
+       vs_tpg = kzalloc(len, GFP_KERNEL);
+       if (!vs_tpg) {
+               ret = -ENOMEM;
+               goto out;
+       }
+-      if (vs->vs_tpg)
+-              memcpy(vs_tpg, vs->vs_tpg, len);
+       mutex_lock(&vhost_scsi_mutex);
+       list_for_each_entry(tpg, &vhost_scsi_list, tv_tpg_list) {
+@@ -1722,12 +1727,6 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs,
+               tv_tport = tpg->tport;
+               if (!strcmp(tv_tport->tport_name, t->vhost_wwpn)) {
+-                      if (vs->vs_tpg && vs->vs_tpg[tpg->tport_tpgt]) {
+-                              mutex_unlock(&tpg->tv_tpg_mutex);
+-                              mutex_unlock(&vhost_scsi_mutex);
+-                              ret = -EEXIST;
+-                              goto undepend;
+-                      }
+                       /*
+                        * In order to ensure individual vhost-scsi configfs
+                        * groups cannot be removed while in use by vhost ioctl,
+@@ -1774,15 +1773,15 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs,
+               }
+               ret = 0;
+       } else {
+-              ret = -EEXIST;
++              ret = -ENODEV;
++              goto free_tpg;
+       }
+       /*
+-       * Act as synchronize_rcu to make sure access to
+-       * old vs->vs_tpg is finished.
++       * Act as synchronize_rcu to make sure requests after this point
++       * see a fully setup device.
+        */
+       vhost_scsi_flush(vs);
+-      kfree(vs->vs_tpg);
+       vs->vs_tpg = vs_tpg;
+       goto out;
+@@ -1802,6 +1801,7 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs,
+                       target_undepend_item(&tpg->se_tpg.tpg_group.cg_item);
+               }
+       }
++free_tpg:
+       kfree(vs_tpg);
+ out:
+       mutex_unlock(&vs->dev.mutex);
+@@ -1904,6 +1904,7 @@ vhost_scsi_clear_endpoint(struct vhost_scsi *vs,
+       vhost_scsi_flush(vs);
+       kfree(vs->vs_tpg);
+       vs->vs_tpg = NULL;
++      memset(vs->vs_vhost_wwpn, 0, sizeof(vs->vs_vhost_wwpn));
+       WARN_ON(vs->vs_events_nr);
+       mutex_unlock(&vs->dev.mutex);
+       return 0;
+-- 
+2.39.5
+
diff --git a/queue-6.14/virtchnl-make-proto-and-filter-action-count-unsigned.patch b/queue-6.14/virtchnl-make-proto-and-filter-action-count-unsigned.patch
new file mode 100644 (file)
index 0000000..bfacc6e
--- /dev/null
@@ -0,0 +1,56 @@
+From 3959a94a4f4011c7a04a82502ba0cf81a6fcbcad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Mar 2025 12:08:31 +0100
+Subject: virtchnl: make proto and filter action count unsigned
+
+From: Jan Glaza <jan.glaza@intel.com>
+
+[ Upstream commit db5e8ea155fc1d89c87cb81f0e4a681a77b9b03f ]
+
+The count field in virtchnl_proto_hdrs and virtchnl_filter_action_set
+should never be negative while still being valid. Changing it from
+int to u32 ensures proper handling of values in virtchnl messages in
+driverrs and prevents unintended behavior.
+In its current signed form, a negative count does not trigger
+an error in ice driver but instead results in it being treated as 0.
+This can lead to unexpected outcomes when processing messages.
+By using u32, any invalid values will correctly trigger -EINVAL,
+making error detection more robust.
+
+Fixes: 1f7ea1cd6a374 ("ice: Enable FDIR Configure for AVF")
+Reviewed-by: Jedrzej Jagielski <jedrzej.jagielski@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Jan Glaza <jan.glaza@intel.com>
+Signed-off-by: Martyna Szapar-Mudlaw <martyna.szapar-mudlaw@linux.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>
+---
+ include/linux/avf/virtchnl.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/include/linux/avf/virtchnl.h b/include/linux/avf/virtchnl.h
+index 13a11f3c09b87..aca06f300f833 100644
+--- a/include/linux/avf/virtchnl.h
++++ b/include/linux/avf/virtchnl.h
+@@ -1283,7 +1283,7 @@ struct virtchnl_proto_hdrs {
+        * 2 - from the second inner layer
+        * ....
+        **/
+-      int count; /* the proto layers must < VIRTCHNL_MAX_NUM_PROTO_HDRS */
++      u32 count; /* the proto layers must < VIRTCHNL_MAX_NUM_PROTO_HDRS */
+       union {
+               struct virtchnl_proto_hdr
+                       proto_hdr[VIRTCHNL_MAX_NUM_PROTO_HDRS];
+@@ -1335,7 +1335,7 @@ VIRTCHNL_CHECK_STRUCT_LEN(36, virtchnl_filter_action);
+ struct virtchnl_filter_action_set {
+       /* action number must be less then VIRTCHNL_MAX_NUM_ACTIONS */
+-      int count;
++      u32 count;
+       struct virtchnl_filter_action actions[VIRTCHNL_MAX_NUM_ACTIONS];
+ };
+-- 
+2.39.5
+
diff --git a/queue-6.14/virtio_net-fix-endian-with-virtio_net_ctrl_rss.patch b/queue-6.14/virtio_net-fix-endian-with-virtio_net_ctrl_rss.patch
new file mode 100644 (file)
index 0000000..e0636c8
--- /dev/null
@@ -0,0 +1,118 @@
+From daab4cb50b8189c0264de5b310134f2a615c54b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Mar 2025 15:48:33 +0900
+Subject: virtio_net: Fix endian with virtio_net_ctrl_rss
+
+From: Akihiko Odaki <akihiko.odaki@daynix.com>
+
+[ Upstream commit 97841341e302eac13d54eb5e968570b5626196a7 ]
+
+Mark the fields of struct virtio_net_ctrl_rss as little endian as
+they are in struct virtio_net_rss_config, which it follows.
+
+Fixes: c7114b1249fa ("drivers/net/virtio_net: Added basic RSS support.")
+Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
+Acked-by: Jason Wang <jasowang@redhat.com>
+Reviewed-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
+Acked-by: Michael S. Tsirkin <mst@redhat.com>
+Tested-by: Lei Yang <leiyang@redhat.com>
+Link: https://patch.msgid.link/20250321-virtio-v2-2-33afb8f4640b@daynix.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/virtio_net.c | 30 +++++++++++++++---------------
+ 1 file changed, 15 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
+index 7646ddd9bef70..d1ed544ba03ac 100644
+--- a/drivers/net/virtio_net.c
++++ b/drivers/net/virtio_net.c
+@@ -368,15 +368,15 @@ struct receive_queue {
+  */
+ #define VIRTIO_NET_RSS_MAX_KEY_SIZE     40
+ struct virtio_net_ctrl_rss {
+-      u32 hash_types;
+-      u16 indirection_table_mask;
+-      u16 unclassified_queue;
+-      u16 hash_cfg_reserved; /* for HASH_CONFIG (see virtio_net_hash_config for details) */
+-      u16 max_tx_vq;
++      __le32 hash_types;
++      __le16 indirection_table_mask;
++      __le16 unclassified_queue;
++      __le16 hash_cfg_reserved; /* for HASH_CONFIG (see virtio_net_hash_config for details) */
++      __le16 max_tx_vq;
+       u8 hash_key_length;
+       u8 key[VIRTIO_NET_RSS_MAX_KEY_SIZE];
+-      u16 *indirection_table;
++      __le16 *indirection_table;
+ };
+ /* Control VQ buffers: protected by the rtnl lock */
+@@ -3576,9 +3576,9 @@ static void virtnet_rss_update_by_qpairs(struct virtnet_info *vi, u16 queue_pair
+       for (; i < vi->rss_indir_table_size; ++i) {
+               indir_val = ethtool_rxfh_indir_default(i, queue_pairs);
+-              vi->rss.indirection_table[i] = indir_val;
++              vi->rss.indirection_table[i] = cpu_to_le16(indir_val);
+       }
+-      vi->rss.max_tx_vq = queue_pairs;
++      vi->rss.max_tx_vq = cpu_to_le16(queue_pairs);
+ }
+ static int virtnet_set_queues(struct virtnet_info *vi, u16 queue_pairs)
+@@ -4097,10 +4097,10 @@ static bool virtnet_commit_rss_command(struct virtnet_info *vi)
+ static void virtnet_init_default_rss(struct virtnet_info *vi)
+ {
+-      vi->rss.hash_types = vi->rss_hash_types_supported;
++      vi->rss.hash_types = cpu_to_le32(vi->rss_hash_types_supported);
+       vi->rss_hash_types_saved = vi->rss_hash_types_supported;
+       vi->rss.indirection_table_mask = vi->rss_indir_table_size
+-                                              ? vi->rss_indir_table_size - 1 : 0;
++                                              ? cpu_to_le16(vi->rss_indir_table_size - 1) : 0;
+       vi->rss.unclassified_queue = 0;
+       virtnet_rss_update_by_qpairs(vi, vi->curr_queue_pairs);
+@@ -4218,7 +4218,7 @@ static bool virtnet_set_hashflow(struct virtnet_info *vi, struct ethtool_rxnfc *
+       if (new_hashtypes != vi->rss_hash_types_saved) {
+               vi->rss_hash_types_saved = new_hashtypes;
+-              vi->rss.hash_types = vi->rss_hash_types_saved;
++              vi->rss.hash_types = cpu_to_le32(vi->rss_hash_types_saved);
+               if (vi->dev->features & NETIF_F_RXHASH)
+                       return virtnet_commit_rss_command(vi);
+       }
+@@ -5398,7 +5398,7 @@ static int virtnet_get_rxfh(struct net_device *dev,
+       if (rxfh->indir) {
+               for (i = 0; i < vi->rss_indir_table_size; ++i)
+-                      rxfh->indir[i] = vi->rss.indirection_table[i];
++                      rxfh->indir[i] = le16_to_cpu(vi->rss.indirection_table[i]);
+       }
+       if (rxfh->key)
+@@ -5426,7 +5426,7 @@ static int virtnet_set_rxfh(struct net_device *dev,
+                       return -EOPNOTSUPP;
+               for (i = 0; i < vi->rss_indir_table_size; ++i)
+-                      vi->rss.indirection_table[i] = rxfh->indir[i];
++                      vi->rss.indirection_table[i] = cpu_to_le16(rxfh->indir[i]);
+               update = true;
+       }
+@@ -6044,9 +6044,9 @@ static int virtnet_set_features(struct net_device *dev,
+       if ((dev->features ^ features) & NETIF_F_RXHASH) {
+               if (features & NETIF_F_RXHASH)
+-                      vi->rss.hash_types = vi->rss_hash_types_saved;
++                      vi->rss.hash_types = cpu_to_le32(vi->rss_hash_types_saved);
+               else
+-                      vi->rss.hash_types = VIRTIO_NET_HASH_REPORT_NONE;
++                      vi->rss.hash_types = cpu_to_le32(VIRTIO_NET_HASH_REPORT_NONE);
+               if (!virtnet_commit_rss_command(vi))
+                       return -EINVAL;
+-- 
+2.39.5
+
diff --git a/queue-6.14/vmxnet3-unregister-xdp-rxq-info-in-the-reset-path.patch b/queue-6.14/vmxnet3-unregister-xdp-rxq-info-in-the-reset-path.patch
new file mode 100644 (file)
index 0000000..1e6eee9
--- /dev/null
@@ -0,0 +1,62 @@
+From 666a1e2c6c3f3f2ea6db0eee9999acff71ad9850 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Mar 2025 10:25:22 +0530
+Subject: vmxnet3: unregister xdp rxq info in the reset path
+
+From: Sankararaman Jayaraman <sankararaman.jayaraman@broadcom.com>
+
+[ Upstream commit 0dd765fae295832934bf28e45dd5a355e0891ed4 ]
+
+vmxnet3 does not unregister xdp rxq info in the
+vmxnet3_reset_work() code path as vmxnet3_rq_destroy()
+is not invoked in this code path. So, we get below message with a
+backtrace.
+
+Missing unregister, handled but fix driver
+WARNING: CPU:48 PID: 500 at net/core/xdp.c:182
+__xdp_rxq_info_reg+0x93/0xf0
+
+This patch fixes the problem by moving the unregister
+code of XDP from vmxnet3_rq_destroy() to vmxnet3_rq_cleanup().
+
+Fixes: 54f00cce1178 ("vmxnet3: Add XDP support.")
+Signed-off-by: Sankararaman Jayaraman <sankararaman.jayaraman@broadcom.com>
+Signed-off-by: Ronak Doshi <ronak.doshi@broadcom.com>
+Link: https://patch.msgid.link/20250320045522.57892-1-sankararaman.jayaraman@broadcom.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/vmxnet3/vmxnet3_drv.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
+index 6793fa09f9d1a..3df6aabc7e339 100644
+--- a/drivers/net/vmxnet3/vmxnet3_drv.c
++++ b/drivers/net/vmxnet3/vmxnet3_drv.c
+@@ -2033,6 +2033,11 @@ vmxnet3_rq_cleanup(struct vmxnet3_rx_queue *rq,
+       rq->comp_ring.gen = VMXNET3_INIT_GEN;
+       rq->comp_ring.next2proc = 0;
++
++      if (xdp_rxq_info_is_reg(&rq->xdp_rxq))
++              xdp_rxq_info_unreg(&rq->xdp_rxq);
++      page_pool_destroy(rq->page_pool);
++      rq->page_pool = NULL;
+ }
+@@ -2073,11 +2078,6 @@ static void vmxnet3_rq_destroy(struct vmxnet3_rx_queue *rq,
+               }
+       }
+-      if (xdp_rxq_info_is_reg(&rq->xdp_rxq))
+-              xdp_rxq_info_unreg(&rq->xdp_rxq);
+-      page_pool_destroy(rq->page_pool);
+-      rq->page_pool = NULL;
+-
+       if (rq->data_ring.base) {
+               dma_free_coherent(&adapter->pdev->dev,
+                                 rq->rx_ring[0].size * rq->data_ring.desc_size,
+-- 
+2.39.5
+
diff --git a/queue-6.14/vsock-avoid-timeout-during-connect-if-the-socket-is-.patch b/queue-6.14/vsock-avoid-timeout-during-connect-if-the-socket-is-.patch
new file mode 100644 (file)
index 0000000..4af8e4c
--- /dev/null
@@ -0,0 +1,62 @@
+From 2f13422603abd895f97349fc021a64003be9d19c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Mar 2025 15:15:28 +0100
+Subject: vsock: avoid timeout during connect() if the socket is closing
+
+From: Stefano Garzarella <sgarzare@redhat.com>
+
+[ Upstream commit fccd2b711d9628c7ce0111d5e4938652101ee30a ]
+
+When a peer attempts to establish a connection, vsock_connect() contains
+a loop that waits for the state to be TCP_ESTABLISHED. However, the
+other peer can be fast enough to accept the connection and close it
+immediately, thus moving the state to TCP_CLOSING.
+
+When this happens, the peer in the vsock_connect() is properly woken up,
+but since the state is not TCP_ESTABLISHED, it goes back to sleep
+until the timeout expires, returning -ETIMEDOUT.
+
+If the socket state is TCP_CLOSING, waiting for the timeout is pointless.
+vsock_connect() can return immediately without errors or delay since the
+connection actually happened. The socket will be in a closing state,
+but this is not an issue, and subsequent calls will fail as expected.
+
+We discovered this issue while developing a test that accepts and
+immediately closes connections to stress the transport switch between
+two connect() calls, where the first one was interrupted by a signal
+(see Closes link).
+
+Reported-by: Luigi Leonardi <leonardi@redhat.com>
+Closes: https://lore.kernel.org/virtualization/bq6hxrolno2vmtqwcvb5bljfpb7mvwb3kohrvaed6auz5vxrfv@ijmd2f3grobn/
+Fixes: d021c344051a ("VSOCK: Introduce VM Sockets")
+Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
+Acked-by: Paolo Abeni <pabeni@redhat.com>
+Tested-by: Luigi Leonardi <leonardi@redhat.com>
+Reviewed-by: Luigi Leonardi <leonardi@redhat.com>
+Link: https://patch.msgid.link/20250328141528.420719-1-sgarzare@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/vmw_vsock/af_vsock.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
+index 7e3db87ae4333..fc6afbc8d6806 100644
+--- a/net/vmw_vsock/af_vsock.c
++++ b/net/vmw_vsock/af_vsock.c
+@@ -1551,7 +1551,11 @@ static int vsock_connect(struct socket *sock, struct sockaddr *addr,
+       timeout = vsk->connect_timeout;
+       prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
+-      while (sk->sk_state != TCP_ESTABLISHED && sk->sk_err == 0) {
++      /* If the socket is already closing or it is in an error state, there
++       * is no point in waiting.
++       */
++      while (sk->sk_state != TCP_ESTABLISHED &&
++             sk->sk_state != TCP_CLOSING && sk->sk_err == 0) {
+               if (flags & O_NONBLOCK) {
+                       /* If we're not going to block, we schedule a timeout
+                        * function to generate a timeout on the connection
+-- 
+2.39.5
+
diff --git a/queue-6.14/w1-fix-null-pointer-dereference-in-probe.patch b/queue-6.14/w1-fix-null-pointer-dereference-in-probe.patch
new file mode 100644 (file)
index 0000000..b14f5a9
--- /dev/null
@@ -0,0 +1,54 @@
+From 0b8090141ecb2c6a11fca92867bb473bb4a7976f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Jan 2025 12:18:03 -0600
+Subject: w1: fix NULL pointer dereference in probe
+
+From: Chenyuan Yang <chenyuan0y@gmail.com>
+
+[ Upstream commit 0dd6770a72f138dabea9eae87f3da6ffa68f0d06 ]
+
+The w1_uart_probe() function calls w1_uart_serdev_open() (which includes
+devm_serdev_device_open()) before setting the client ops via
+serdev_device_set_client_ops(). This ordering can trigger a NULL pointer
+dereference in the serdev controller's receive_buf handler, as it assumes
+serdev->ops is valid when SERPORT_ACTIVE is set.
+
+This is similar to the issue fixed in commit 5e700b384ec1
+("platform/chrome: cros_ec_uart: properly fix race condition") where
+devm_serdev_device_open() was called before fully initializing the
+device.
+
+Fix the race by ensuring client ops are set before enabling the port via
+w1_uart_serdev_open().
+
+Fixes: a3c08804364e ("w1: add UART w1 bus driver")
+Signed-off-by: Chenyuan Yang <chenyuan0y@gmail.com>
+Acked-by: Christoph Winklhofer <cj.winklhofer@gmail.com>
+Link: https://lore.kernel.org/r/20250111181803.2283611-1-chenyuan0y@gmail.com
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/w1/masters/w1-uart.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/w1/masters/w1-uart.c b/drivers/w1/masters/w1-uart.c
+index a31782e56ba75..c87eea3478067 100644
+--- a/drivers/w1/masters/w1-uart.c
++++ b/drivers/w1/masters/w1-uart.c
+@@ -372,11 +372,11 @@ static int w1_uart_probe(struct serdev_device *serdev)
+       init_completion(&w1dev->rx_byte_received);
+       mutex_init(&w1dev->rx_mutex);
++      serdev_device_set_drvdata(serdev, w1dev);
++      serdev_device_set_client_ops(serdev, &w1_uart_serdev_ops);
+       ret = w1_uart_serdev_open(w1dev);
+       if (ret < 0)
+               return ret;
+-      serdev_device_set_drvdata(serdev, w1dev);
+-      serdev_device_set_client_ops(serdev, &w1_uart_serdev_ops);
+       return w1_add_master_device(&w1dev->bus);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/watch_queue-fix-pipe-accounting-mismatch.patch b/queue-6.14/watch_queue-fix-pipe-accounting-mismatch.patch
new file mode 100644 (file)
index 0000000..6571a81
--- /dev/null
@@ -0,0 +1,55 @@
+From 743efdc6a0626ad9365b7a6226d5db4ab0122da2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 11:41:08 -0600
+Subject: watch_queue: fix pipe accounting mismatch
+
+From: Eric Sandeen <sandeen@redhat.com>
+
+[ Upstream commit f13abc1e8e1a3b7455511c4e122750127f6bc9b0 ]
+
+Currently, watch_queue_set_size() modifies the pipe buffers charged to
+user->pipe_bufs without updating the pipe->nr_accounted on the pipe
+itself, due to the if (!pipe_has_watch_queue()) test in
+pipe_resize_ring(). This means that when the pipe is ultimately freed,
+we decrement user->pipe_bufs by something other than what than we had
+charged to it, potentially leading to an underflow. This in turn can
+cause subsequent too_many_pipe_buffers_soft() tests to fail with -EPERM.
+
+To remedy this, explicitly account for the pipe usage in
+watch_queue_set_size() to match the number set via account_pipe_buffers()
+
+(It's unclear why watch_queue_set_size() does not update nr_accounted;
+it may be due to intentional overprovisioning in watch_queue_set_size()?)
+
+Fixes: e95aada4cb93d ("pipe: wakeup wr_wait after setting max_usage")
+Signed-off-by: Eric Sandeen <sandeen@redhat.com>
+Link: https://lore.kernel.org/r/206682a8-0604-49e5-8224-fdbe0c12b460@redhat.com
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/watch_queue.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/kernel/watch_queue.c b/kernel/watch_queue.c
+index 5267adeaa4034..41e4e8070923a 100644
+--- a/kernel/watch_queue.c
++++ b/kernel/watch_queue.c
+@@ -269,6 +269,15 @@ long watch_queue_set_size(struct pipe_inode_info *pipe, unsigned int nr_notes)
+       if (ret < 0)
+               goto error;
++      /*
++       * pipe_resize_ring() does not update nr_accounted for watch_queue
++       * pipes, because the above vastly overprovisions. Set nr_accounted on
++       * and max_usage this pipe to the number that was actually charged to
++       * the user above via account_pipe_buffers.
++       */
++      pipe->max_usage = nr_pages;
++      pipe->nr_accounted = nr_pages;
++
+       ret = -ENOMEM;
+       pages = kcalloc(nr_pages, sizeof(struct page *), GFP_KERNEL);
+       if (!pages)
+-- 
+2.39.5
+
diff --git a/queue-6.14/watchdog-hardlockup-perf-fix-perf_event-memory-leak.patch b/queue-6.14/watchdog-hardlockup-perf-fix-perf_event-memory-leak.patch
new file mode 100644 (file)
index 0000000..b784e27
--- /dev/null
@@ -0,0 +1,288 @@
+From 601bb99e52a9462a6f873f07b224467629d790af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Oct 2024 03:30:03 +0800
+Subject: watchdog/hardlockup/perf: Fix perf_event memory leak
+
+From: Li Huafei <lihuafei1@huawei.com>
+
+[ Upstream commit d6834d9c990333bfa433bc1816e2417f268eebbe ]
+
+During stress-testing, we found a kmemleak report for perf_event:
+
+  unreferenced object 0xff110001410a33e0 (size 1328):
+    comm "kworker/4:11", pid 288, jiffies 4294916004
+    hex dump (first 32 bytes):
+      b8 be c2 3b 02 00 11 ff 22 01 00 00 00 00 ad de  ...;....".......
+      f0 33 0a 41 01 00 11 ff f0 33 0a 41 01 00 11 ff  .3.A.....3.A....
+    backtrace (crc 24eb7b3a):
+      [<00000000e211b653>] kmem_cache_alloc_node_noprof+0x269/0x2e0
+      [<000000009d0985fa>] perf_event_alloc+0x5f/0xcf0
+      [<00000000084ad4a2>] perf_event_create_kernel_counter+0x38/0x1b0
+      [<00000000fde96401>] hardlockup_detector_event_create+0x50/0xe0
+      [<0000000051183158>] watchdog_hardlockup_enable+0x17/0x70
+      [<00000000ac89727f>] softlockup_start_fn+0x15/0x40
+      ...
+
+Our stress test includes CPU online and offline cycles, and updating the
+watchdog configuration.
+
+After reading the code, I found that there may be a race between cleaning up
+perf_event after updating watchdog and disabling event when the CPU goes offline:
+
+  CPU0                          CPU1                           CPU2
+  (update watchdog)                                            (hotplug offline CPU1)
+
+  ...                                                          _cpu_down(CPU1)
+  cpus_read_lock()                                             // waiting for cpu lock
+    softlockup_start_all
+      smp_call_on_cpu(CPU1)
+                                softlockup_start_fn
+                                ...
+                                  watchdog_hardlockup_enable(CPU1)
+                                    perf create E1
+                                    watchdog_ev[CPU1] = E1
+  cpus_read_unlock()
+                                                               cpus_write_lock()
+                                                               cpuhp_kick_ap_work(CPU1)
+                                cpuhp_thread_fun
+                                ...
+                                  watchdog_hardlockup_disable(CPU1)
+                                    watchdog_ev[CPU1] = NULL
+                                    dead_event[CPU1] = E1
+  __lockup_detector_cleanup
+    for each dead_events_mask
+      release each dead_event
+      /*
+       * CPU1 has not been added to
+       * dead_events_mask, then E1
+       * will not be released
+       */
+                                    CPU1 -> dead_events_mask
+    cpumask_clear(&dead_events_mask)
+    // dead_events_mask is cleared, E1 is leaked
+
+In this case, the leaked perf_event E1 matches the perf_event leak
+reported by kmemleak. Due to the low probability of problem recurrence
+(only reported once), I added some hack delays in the code:
+
+  static void __lockup_detector_reconfigure(void)
+  {
+    ...
+          watchdog_hardlockup_start();
+          cpus_read_unlock();
+  +       mdelay(100);
+          /*
+           * Must be called outside the cpus locked section to prevent
+           * recursive locking in the perf code.
+    ...
+  }
+
+  void watchdog_hardlockup_disable(unsigned int cpu)
+  {
+    ...
+                  perf_event_disable(event);
+                  this_cpu_write(watchdog_ev, NULL);
+                  this_cpu_write(dead_event, event);
+  +               mdelay(100);
+                  cpumask_set_cpu(smp_processor_id(), &dead_events_mask);
+                  atomic_dec(&watchdog_cpus);
+    ...
+  }
+
+  void hardlockup_detector_perf_cleanup(void)
+  {
+    ...
+                          perf_event_release_kernel(event);
+                  per_cpu(dead_event, cpu) = NULL;
+          }
+  +       mdelay(100);
+          cpumask_clear(&dead_events_mask);
+  }
+
+Then, simultaneously performing CPU on/off and switching watchdog, it is
+almost certain to reproduce this leak.
+
+The problem here is that releasing perf_event is not within the CPU
+hotplug read-write lock. Commit:
+
+  941154bd6937 ("watchdog/hardlockup/perf: Prevent CPU hotplug deadlock")
+
+introduced deferred release to solve the deadlock caused by calling
+get_online_cpus() when releasing perf_event. Later, commit:
+
+  efe951d3de91 ("perf/x86: Fix perf,x86,cpuhp deadlock")
+
+removed the get_online_cpus() call on the perf_event release path to solve
+another deadlock problem.
+
+Therefore, it is now possible to move the release of perf_event back
+into the CPU hotplug read-write lock, and release the event immediately
+after disabling it.
+
+Fixes: 941154bd6937 ("watchdog/hardlockup/perf: Prevent CPU hotplug deadlock")
+Signed-off-by: Li Huafei <lihuafei1@huawei.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20241021193004.308303-1-lihuafei1@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/nmi.h    |  4 ----
+ kernel/cpu.c           |  5 -----
+ kernel/watchdog.c      | 25 -------------------------
+ kernel/watchdog_perf.c | 28 +---------------------------
+ 4 files changed, 1 insertion(+), 61 deletions(-)
+
+diff --git a/include/linux/nmi.h b/include/linux/nmi.h
+index a8dfb38c9bb6f..e78fa535f61dd 100644
+--- a/include/linux/nmi.h
++++ b/include/linux/nmi.h
+@@ -17,7 +17,6 @@
+ void lockup_detector_init(void);
+ void lockup_detector_retry_init(void);
+ void lockup_detector_soft_poweroff(void);
+-void lockup_detector_cleanup(void);
+ extern int watchdog_user_enabled;
+ extern int watchdog_thresh;
+@@ -37,7 +36,6 @@ extern int sysctl_hardlockup_all_cpu_backtrace;
+ static inline void lockup_detector_init(void) { }
+ static inline void lockup_detector_retry_init(void) { }
+ static inline void lockup_detector_soft_poweroff(void) { }
+-static inline void lockup_detector_cleanup(void) { }
+ #endif /* !CONFIG_LOCKUP_DETECTOR */
+ #ifdef CONFIG_SOFTLOCKUP_DETECTOR
+@@ -104,12 +102,10 @@ void watchdog_hardlockup_check(unsigned int cpu, struct pt_regs *regs);
+ #if defined(CONFIG_HARDLOCKUP_DETECTOR_PERF)
+ extern void hardlockup_detector_perf_stop(void);
+ extern void hardlockup_detector_perf_restart(void);
+-extern void hardlockup_detector_perf_cleanup(void);
+ extern void hardlockup_config_perf_event(const char *str);
+ #else
+ static inline void hardlockup_detector_perf_stop(void) { }
+ static inline void hardlockup_detector_perf_restart(void) { }
+-static inline void hardlockup_detector_perf_cleanup(void) { }
+ static inline void hardlockup_config_perf_event(const char *str) { }
+ #endif
+diff --git a/kernel/cpu.c b/kernel/cpu.c
+index 07455d25329c9..ad755db29efd4 100644
+--- a/kernel/cpu.c
++++ b/kernel/cpu.c
+@@ -1453,11 +1453,6 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen,
+ out:
+       cpus_write_unlock();
+-      /*
+-       * Do post unplug cleanup. This is still protected against
+-       * concurrent CPU hotplug via cpu_add_remove_lock.
+-       */
+-      lockup_detector_cleanup();
+       arch_smt_update();
+       return ret;
+ }
+diff --git a/kernel/watchdog.c b/kernel/watchdog.c
+index b2da7de39d06d..18156023e4614 100644
+--- a/kernel/watchdog.c
++++ b/kernel/watchdog.c
+@@ -347,8 +347,6 @@ static int __init watchdog_thresh_setup(char *str)
+ }
+ __setup("watchdog_thresh=", watchdog_thresh_setup);
+-static void __lockup_detector_cleanup(void);
+-
+ #ifdef CONFIG_SOFTLOCKUP_DETECTOR_INTR_STORM
+ enum stats_per_group {
+       STATS_SYSTEM,
+@@ -886,11 +884,6 @@ static void __lockup_detector_reconfigure(void)
+       watchdog_hardlockup_start();
+       cpus_read_unlock();
+-      /*
+-       * Must be called outside the cpus locked section to prevent
+-       * recursive locking in the perf code.
+-       */
+-      __lockup_detector_cleanup();
+ }
+ void lockup_detector_reconfigure(void)
+@@ -940,24 +933,6 @@ static inline void lockup_detector_setup(void)
+ }
+ #endif /* !CONFIG_SOFTLOCKUP_DETECTOR */
+-static void __lockup_detector_cleanup(void)
+-{
+-      lockdep_assert_held(&watchdog_mutex);
+-      hardlockup_detector_perf_cleanup();
+-}
+-
+-/**
+- * lockup_detector_cleanup - Cleanup after cpu hotplug or sysctl changes
+- *
+- * Caller must not hold the cpu hotplug rwsem.
+- */
+-void lockup_detector_cleanup(void)
+-{
+-      mutex_lock(&watchdog_mutex);
+-      __lockup_detector_cleanup();
+-      mutex_unlock(&watchdog_mutex);
+-}
+-
+ /**
+  * lockup_detector_soft_poweroff - Interface to stop lockup detector(s)
+  *
+diff --git a/kernel/watchdog_perf.c b/kernel/watchdog_perf.c
+index 59c1d86a73a24..2fdb96eaf4933 100644
+--- a/kernel/watchdog_perf.c
++++ b/kernel/watchdog_perf.c
+@@ -21,8 +21,6 @@
+ #include <linux/perf_event.h>
+ static DEFINE_PER_CPU(struct perf_event *, watchdog_ev);
+-static DEFINE_PER_CPU(struct perf_event *, dead_event);
+-static struct cpumask dead_events_mask;
+ static atomic_t watchdog_cpus = ATOMIC_INIT(0);
+@@ -181,36 +179,12 @@ void watchdog_hardlockup_disable(unsigned int cpu)
+       if (event) {
+               perf_event_disable(event);
++              perf_event_release_kernel(event);
+               this_cpu_write(watchdog_ev, NULL);
+-              this_cpu_write(dead_event, event);
+-              cpumask_set_cpu(smp_processor_id(), &dead_events_mask);
+               atomic_dec(&watchdog_cpus);
+       }
+ }
+-/**
+- * hardlockup_detector_perf_cleanup - Cleanup disabled events and destroy them
+- *
+- * Called from lockup_detector_cleanup(). Serialized by the caller.
+- */
+-void hardlockup_detector_perf_cleanup(void)
+-{
+-      int cpu;
+-
+-      for_each_cpu(cpu, &dead_events_mask) {
+-              struct perf_event *event = per_cpu(dead_event, cpu);
+-
+-              /*
+-               * Required because for_each_cpu() reports  unconditionally
+-               * CPU0 as set on UP kernels. Sigh.
+-               */
+-              if (event)
+-                      perf_event_release_kernel(event);
+-              per_cpu(dead_event, cpu) = NULL;
+-      }
+-      cpumask_clear(&dead_events_mask);
+-}
+-
+ /**
+  * hardlockup_detector_perf_stop - Globally stop watchdog events
+  *
+-- 
+2.39.5
+
diff --git a/queue-6.14/wifi-ath11k-add-srng-lock-for-ath11k_hal_srng_-in-mo.patch b/queue-6.14/wifi-ath11k-add-srng-lock-for-ath11k_hal_srng_-in-mo.patch
new file mode 100644 (file)
index 0000000..52a78a2
--- /dev/null
@@ -0,0 +1,106 @@
+From dcb00c3fd6f68b9034abaefff042c138435ceb66 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 19 Dec 2024 19:05:31 +0800
+Subject: wifi: ath11k: add srng->lock for ath11k_hal_srng_* in monitor mode
+
+From: Kang Yang <quic_kangyang@quicinc.com>
+
+[ Upstream commit 63b7af49496d0e32f7a748b6af3361ec138b1bd3 ]
+
+ath11k_hal_srng_* should be used with srng->lock to protect srng data.
+
+For ath11k_dp_rx_mon_dest_process() and ath11k_dp_full_mon_process_rx(),
+they use ath11k_hal_srng_* for many times but never call srng->lock.
+
+So when running (full) monitor mode, warning will occur:
+RIP: 0010:ath11k_hal_srng_dst_peek+0x18/0x30 [ath11k]
+Call Trace:
+ ? ath11k_hal_srng_dst_peek+0x18/0x30 [ath11k]
+ ath11k_dp_rx_process_mon_status+0xc45/0x1190 [ath11k]
+ ? idr_alloc_u32+0x97/0xd0
+ ath11k_dp_rx_process_mon_rings+0x32a/0x550 [ath11k]
+ ath11k_dp_service_srng+0x289/0x5a0 [ath11k]
+ ath11k_pcic_ext_grp_napi_poll+0x30/0xd0 [ath11k]
+ __napi_poll+0x30/0x1f0
+ net_rx_action+0x198/0x320
+ __do_softirq+0xdd/0x319
+
+So add srng->lock for them to avoid such warnings.
+
+Inorder to fetch the srng->lock, should change srng's definition from
+'void' to 'struct hal_srng'. And initialize them elsewhere to prevent
+one line of code from being too long. This is consistent with other ring
+process functions, such as ath11k_dp_process_rx().
+
+Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.30
+Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
+
+Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
+Signed-off-by: Kang Yang <quic_kangyang@quicinc.com>
+Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
+Link: https://patch.msgid.link/20241219110531.2096-3-quic_kangyang@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/dp_rx.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
+index 07cd336ee01b1..b8b3dce9cdb53 100644
+--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
+@@ -5148,7 +5148,7 @@ static void ath11k_dp_rx_mon_dest_process(struct ath11k *ar, int mac_id,
+       struct ath11k_mon_data *pmon = (struct ath11k_mon_data *)&dp->mon_data;
+       const struct ath11k_hw_hal_params *hal_params;
+       void *ring_entry;
+-      void *mon_dst_srng;
++      struct hal_srng *mon_dst_srng;
+       u32 ppdu_id;
+       u32 rx_bufs_used;
+       u32 ring_id;
+@@ -5165,6 +5165,7 @@ static void ath11k_dp_rx_mon_dest_process(struct ath11k *ar, int mac_id,
+       spin_lock_bh(&pmon->mon_lock);
++      spin_lock_bh(&mon_dst_srng->lock);
+       ath11k_hal_srng_access_begin(ar->ab, mon_dst_srng);
+       ppdu_id = pmon->mon_ppdu_info.ppdu_id;
+@@ -5223,6 +5224,7 @@ static void ath11k_dp_rx_mon_dest_process(struct ath11k *ar, int mac_id,
+                                                               mon_dst_srng);
+       }
+       ath11k_hal_srng_access_end(ar->ab, mon_dst_srng);
++      spin_unlock_bh(&mon_dst_srng->lock);
+       spin_unlock_bh(&pmon->mon_lock);
+@@ -5612,7 +5614,7 @@ static int ath11k_dp_full_mon_process_rx(struct ath11k_base *ab, int mac_id,
+       struct hal_sw_mon_ring_entries *sw_mon_entries;
+       struct ath11k_pdev_mon_stats *rx_mon_stats;
+       struct sk_buff *head_msdu, *tail_msdu;
+-      void *mon_dst_srng = &ar->ab->hal.srng_list[dp->rxdma_mon_dst_ring.ring_id];
++      struct hal_srng *mon_dst_srng;
+       void *ring_entry;
+       u32 rx_bufs_used = 0, mpdu_rx_bufs_used;
+       int quota = 0, ret;
+@@ -5628,6 +5630,9 @@ static int ath11k_dp_full_mon_process_rx(struct ath11k_base *ab, int mac_id,
+               goto reap_status_ring;
+       }
++      mon_dst_srng = &ar->ab->hal.srng_list[dp->rxdma_mon_dst_ring.ring_id];
++      spin_lock_bh(&mon_dst_srng->lock);
++
+       ath11k_hal_srng_access_begin(ar->ab, mon_dst_srng);
+       while ((ring_entry = ath11k_hal_srng_dst_peek(ar->ab, mon_dst_srng))) {
+               head_msdu = NULL;
+@@ -5671,6 +5676,7 @@ static int ath11k_dp_full_mon_process_rx(struct ath11k_base *ab, int mac_id,
+       }
+       ath11k_hal_srng_access_end(ar->ab, mon_dst_srng);
++      spin_unlock_bh(&mon_dst_srng->lock);
+       spin_unlock_bh(&pmon->mon_lock);
+       if (rx_bufs_used) {
+-- 
+2.39.5
+
diff --git a/queue-6.14/wifi-ath11k-clear-affinity-hint-before-calling-ath11.patch b/queue-6.14/wifi-ath11k-clear-affinity-hint-before-calling-ath11.patch
new file mode 100644 (file)
index 0000000..ce9ed58
--- /dev/null
@@ -0,0 +1,60 @@
+From 0b3826c8a21a4f184221fc1b74d03bdb93105e76 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Feb 2025 11:04:45 +0530
+Subject: wifi: ath11k: Clear affinity hint before calling
+ ath11k_pcic_free_irq() in error path
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit 68410c5bd381a81bcc92b808e7dc4e6b9ed25d11 ]
+
+If a shared IRQ is used by the driver due to platform limitation, then the
+IRQ affinity hint is set right after the allocation of IRQ vectors in
+ath11k_pci_alloc_msi(). This does no harm unless one of the functions
+requesting the IRQ fails and attempt to free the IRQ. This results in the
+below warning:
+
+WARNING: CPU: 7 PID: 349 at kernel/irq/manage.c:1929 free_irq+0x278/0x29c
+Call trace:
+ free_irq+0x278/0x29c
+ ath11k_pcic_free_irq+0x70/0x10c [ath11k]
+ ath11k_pci_probe+0x800/0x820 [ath11k_pci]
+ local_pci_probe+0x40/0xbc
+
+The warning is due to not clearing the affinity hint before freeing the
+IRQs.
+
+So to fix this issue, clear the IRQ affinity hint before calling
+ath11k_pcic_free_irq() in the error path. The affinity will be cleared once
+again further down the error path due to code organization, but that does
+no harm.
+
+Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-05266-QCAHSTSWPLZ_V2_TO_X86-1
+
+Cc: Baochen Qiang <quic_bqiang@quicinc.com>
+Fixes: 39564b475ac5 ("wifi: ath11k: fix boot failure with one MSI vector")
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Reviewed-by: Baochen Qiang <quic_bqiang@quicinc.com>
+Link: https://patch.msgid.link/20250225053447.16824-2-manivannan.sadhasivam@linaro.org
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/pci.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c
+index b93f04973ad79..eaac9eabcc70a 100644
+--- a/drivers/net/wireless/ath/ath11k/pci.c
++++ b/drivers/net/wireless/ath/ath11k/pci.c
+@@ -939,6 +939,8 @@ static int ath11k_pci_probe(struct pci_dev *pdev,
+       return 0;
+ err_free_irq:
++      /* __free_irq() expects the caller to have cleared the affinity hint */
++      ath11k_pci_set_irq_affinity_hint(ab_pci, NULL);
+       ath11k_pcic_free_irq(ab);
+ err_ce_free:
+-- 
+2.39.5
+
diff --git a/queue-6.14/wifi-ath11k-fix-rcu-stall-while-reaping-monitor-dest.patch b/queue-6.14/wifi-ath11k-fix-rcu-stall-while-reaping-monitor-dest.patch
new file mode 100644 (file)
index 0000000..42fcfe7
--- /dev/null
@@ -0,0 +1,65 @@
+From b8e77986c47107bdf3df7b9a8ceb38cfd47229ca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 19 Dec 2024 19:05:30 +0800
+Subject: wifi: ath11k: fix RCU stall while reaping monitor destination ring
+
+From: P Praneesh <quic_ppranees@quicinc.com>
+
+[ Upstream commit 16c6c35c03ea73054a1f6d3302a4ce4a331b427d ]
+
+While processing the monitor destination ring, MSDUs are reaped from the
+link descriptor based on the corresponding buf_id.
+
+However, sometimes the driver cannot obtain a valid buffer corresponding
+to the buf_id received from the hardware. This causes an infinite loop
+in the destination processing, resulting in a kernel crash.
+
+kernel log:
+ath11k_pci 0000:58:00.0: data msdu_pop: invalid buf_id 309
+ath11k_pci 0000:58:00.0: data dp_rx_monitor_link_desc_return failed
+ath11k_pci 0000:58:00.0: data msdu_pop: invalid buf_id 309
+ath11k_pci 0000:58:00.0: data dp_rx_monitor_link_desc_return failed
+
+Fix this by skipping the problematic buf_id and reaping the next entry,
+replacing the break with the next MSDU processing.
+
+Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.30
+Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
+
+Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
+Signed-off-by: P Praneesh <quic_ppranees@quicinc.com>
+Signed-off-by: Kang Yang <quic_kangyang@quicinc.com>
+Acked-by: Kalle Valo <kvalo@kernel.org>
+Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
+Link: https://patch.msgid.link/20241219110531.2096-2-quic_kangyang@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/dp_rx.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
+index 029ecf51c9efd..07cd336ee01b1 100644
+--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
+@@ -4783,7 +4783,7 @@ u32 ath11k_dp_rx_mon_mpdu_pop(struct ath11k *ar, int mac_id,
+                       if (!msdu) {
+                               ath11k_dbg(ar->ab, ATH11K_DBG_DATA,
+                                          "msdu_pop: invalid buf_id %d\n", buf_id);
+-                              break;
++                              goto next_msdu;
+                       }
+                       rxcb = ATH11K_SKB_RXCB(msdu);
+                       if (!rxcb->unmapped) {
+@@ -5410,7 +5410,7 @@ ath11k_dp_rx_full_mon_mpdu_pop(struct ath11k *ar,
+                                          "full mon msdu_pop: invalid buf_id %d\n",
+                                           buf_id);
+                               spin_unlock_bh(&rx_ring->idr_lock);
+-                              break;
++                              goto next_msdu;
+                       }
+                       idr_remove(&rx_ring->bufs_idr, buf_id);
+                       spin_unlock_bh(&rx_ring->idr_lock);
+-- 
+2.39.5
+
diff --git a/queue-6.14/wifi-ath11k-fix-wrong-overriding-for-vht-beamformee-.patch b/queue-6.14/wifi-ath11k-fix-wrong-overriding-for-vht-beamformee-.patch
new file mode 100644 (file)
index 0000000..4cbb829
--- /dev/null
@@ -0,0 +1,67 @@
+From 6ae5b5a7bbaf4b55c9471b89a4a3c08035e79de1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jan 2025 15:59:53 +0800
+Subject: wifi: ath11k: fix wrong overriding for VHT Beamformee STS Capability
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Yu Zhang(Yuriy) <quic_yuzha@quicinc.com>
+
+[ Upstream commit 9d13950acb2a51342c93c69f1a5bf285adb90d88 ]
+
+Current code in ath11k_mac_set_txbf_conf overrides nsts, which is
+incorrect as it confuses nss and nsts. nss is Number of Spatial
+Streams,nsts is Number of Space-Time Streams.
+
+As mentioned in Fixes: 55b5ee3357d7, the nss used when acting as a
+beamformee in VHT mode should be reported by the firmware and should not
+be greater than the number of receiving antennas - 1. The num_rx_chains
+related nss rather than nsts.
+
+If STBC is enabled, nsts is greater than nss. About nss are mapped to
+nsts, refer to IEEE Std 802.11-2020: 19.3.11.9.2 Space-time block coding
+(STBC), Table 19-18—Constellation mapper output to spatial mapper input
+for STBC.
+
+Remove wrong overriding for nsts of VHT Beamformee STS Capability,
+acting DL MU-MIMO in VHT mode is working properly.
+
+Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-04479-QCAHSPSWPL_V1_V2_SILICONZ_IOE-1
+
+Fixes: 55b5ee3357d7 ("wifi: ath11k: fix number of VHT beamformee spatial streams")
+Signed-off-by: Yu Zhang (Yuriy) <quic_yuzha@quicinc.com>
+Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
+Link: https://patch.msgid.link/20250124075953.2282354-1-quic_yuzha@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/mac.c | 5 -----
+ 1 file changed, 5 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
+index 1556392f7ad48..1298a3190a3c5 100644
+--- a/drivers/net/wireless/ath/ath11k/mac.c
++++ b/drivers/net/wireless/ath/ath11k/mac.c
+@@ -5336,8 +5336,6 @@ static int ath11k_mac_set_txbf_conf(struct ath11k_vif *arvif)
+       if (vht_cap & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)) {
+               nsts = vht_cap & IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
+               nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
+-              if (nsts > (ar->num_rx_chains - 1))
+-                      nsts = ar->num_rx_chains - 1;
+               value |= SM(nsts, WMI_TXBF_STS_CAP_OFFSET);
+       }
+@@ -5421,9 +5419,6 @@ static void ath11k_set_vht_txbf_cap(struct ath11k *ar, u32 *vht_cap)
+       /* Enable Beamformee STS Field only if SU BF is enabled */
+       if (subfee) {
+-              if (nsts > (ar->num_rx_chains - 1))
+-                      nsts = ar->num_rx_chains - 1;
+-
+               nsts <<= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
+               nsts &=  IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
+               *vht_cap |= nsts;
+-- 
+2.39.5
+
diff --git a/queue-6.14/wifi-ath11k-update-channel-list-in-reg-notifier-inst.patch b/queue-6.14/wifi-ath11k-update-channel-list-in-reg-notifier-inst.patch
new file mode 100644 (file)
index 0000000..35270d7
--- /dev/null
@@ -0,0 +1,108 @@
+From b9b7e8f7609d0f5cd3807565d18feb8ccebe67a7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jan 2025 14:17:36 +0800
+Subject: wifi: ath11k: update channel list in reg notifier instead reg worker
+
+From: Wen Gong <quic_wgong@quicinc.com>
+
+[ Upstream commit 933ab187e679e6fbdeea1835ae39efcc59c022d2 ]
+
+Currently when ath11k gets a new channel list, it will be processed
+according to the following steps:
+1. update new channel list to cfg80211 and queue reg_work.
+2. cfg80211 handles new channel list during reg_work.
+3. update cfg80211's handled channel list to firmware by
+ath11k_reg_update_chan_list().
+
+But ath11k will immediately execute step 3 after reg_work is just
+queued. Since step 2 is asynchronous, cfg80211 may not have completed
+handling the new channel list, which may leading to an out-of-bounds
+write error:
+BUG: KASAN: slab-out-of-bounds in ath11k_reg_update_chan_list
+Call Trace:
+    ath11k_reg_update_chan_list+0xbfe/0xfe0 [ath11k]
+    kfree+0x109/0x3a0
+    ath11k_regd_update+0x1cf/0x350 [ath11k]
+    ath11k_regd_update_work+0x14/0x20 [ath11k]
+    process_one_work+0xe35/0x14c0
+
+Should ensure step 2 is completely done before executing step 3. Thus
+Wen raised patch[1]. When flag NL80211_REGDOM_SET_BY_DRIVER is set,
+cfg80211 will notify ath11k after step 2 is done.
+
+So enable the flag NL80211_REGDOM_SET_BY_DRIVER then cfg80211 will
+notify ath11k after step 2 is done. At this time, there will be no
+KASAN bug during the execution of the step 3.
+
+[1] https://patchwork.kernel.org/project/linux-wireless/patch/20230201065313.27203-1-quic_wgong@quicinc.com/
+
+Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3
+
+Fixes: f45cb6b29cd3 ("wifi: ath11k: avoid deadlock during regulatory update in ath11k_regd_update()")
+Signed-off-by: Wen Gong <quic_wgong@quicinc.com>
+Signed-off-by: Kang Yang <quic_kangyang@quicinc.com>
+Reviewed-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
+Link: https://patch.msgid.link/20250117061737.1921-2-quic_kangyang@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/reg.c | 22 +++++++++++++++-------
+ 1 file changed, 15 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath11k/reg.c b/drivers/net/wireless/ath/ath11k/reg.c
+index b0f289784dd3a..7bfe47ad62a07 100644
+--- a/drivers/net/wireless/ath/ath11k/reg.c
++++ b/drivers/net/wireless/ath/ath11k/reg.c
+@@ -1,7 +1,7 @@
+ // SPDX-License-Identifier: BSD-3-Clause-Clear
+ /*
+  * Copyright (c) 2018-2019 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/rtnetlink.h>
+@@ -55,6 +55,19 @@ ath11k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
+       ath11k_dbg(ar->ab, ATH11K_DBG_REG,
+                  "Regulatory Notification received for %s\n", wiphy_name(wiphy));
++      if (request->initiator == NL80211_REGDOM_SET_BY_DRIVER) {
++              ath11k_dbg(ar->ab, ATH11K_DBG_REG,
++                         "driver initiated regd update\n");
++              if (ar->state != ATH11K_STATE_ON)
++                      return;
++
++              ret = ath11k_reg_update_chan_list(ar, true);
++              if (ret)
++                      ath11k_warn(ar->ab, "failed to update channel list: %d\n", ret);
++
++              return;
++      }
++
+       /* Currently supporting only General User Hints. Cell base user
+        * hints to be handled later.
+        * Hints from other sources like Core, Beacons are not expected for
+@@ -293,12 +306,6 @@ int ath11k_regd_update(struct ath11k *ar)
+       if (ret)
+               goto err;
+-      if (ar->state == ATH11K_STATE_ON) {
+-              ret = ath11k_reg_update_chan_list(ar, true);
+-              if (ret)
+-                      goto err;
+-      }
+-
+       return 0;
+ err:
+       ath11k_warn(ab, "failed to perform regd update : %d\n", ret);
+@@ -977,6 +984,7 @@ void ath11k_regd_update_work(struct work_struct *work)
+ void ath11k_reg_init(struct ath11k *ar)
+ {
+       ar->hw->wiphy->regulatory_flags = REGULATORY_WIPHY_SELF_MANAGED;
++      ar->hw->wiphy->flags |= WIPHY_FLAG_NOTIFY_REGDOM_BY_DRIVER;
+       ar->hw->wiphy->reg_notifier = ath11k_reg_notifier;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/wifi-ath12k-add-missing-htt_metadata-flag-in-ath12k_.patch b/queue-6.14/wifi-ath12k-add-missing-htt_metadata-flag-in-ath12k_.patch
new file mode 100644 (file)
index 0000000..a254141
--- /dev/null
@@ -0,0 +1,41 @@
+From b5880ca972956aa1a3415c5f7988178df27182cb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jan 2025 12:33:31 +0100
+Subject: wifi: ath12k: Add missing htt_metadata flag in ath12k_dp_tx()
+
+From: Nicolas Escande <nico.escande@gmail.com>
+
+[ Upstream commit af1c6007a64e78b729eb5a8d149637a820077bee ]
+
+When AP-VLAN support was added, the HTT_TCL_META_DATA_VALID_HTT flag
+was not added to the tx_info's meta_data_flags. Without this flag the
+firmware seems to reject all the broadcast (ap-vlan) frames. So add
+the flag, just as ath11k did it in the downstream QSDK project[1].
+
+Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
+
+Fixes: 26dd8ccdba4d ("wifi: ath12k: dynamic VLAN support")
+Signed-off-by: Nicolas Escande <nico.escande@gmail.com>
+Link: https://git.codelinaro.org/clo/qsdk/oss/system/feeds/wlan-open/-/blob/win.wlan_host_opensource.3.0.r24/patches/ath11k/207-ath11k-Add-support-for-dynamic-vlan.patch # [1]
+Link: https://patch.msgid.link/20250124113331.93476-1-nico.escande@gmail.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 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.c b/drivers/net/wireless/ath/ath12k/dp_tx.c
+index e0b85f959cd4a..1fffabaca527a 100644
+--- a/drivers/net/wireless/ath/ath12k/dp_tx.c
++++ b/drivers/net/wireless/ath/ath12k/dp_tx.c
+@@ -368,6 +368,7 @@ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif,
+               add_htt_metadata = true;
+               msdu_ext_desc = true;
+               ti.flags0 |= u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_TO_FW);
++              ti.meta_data_flags |= HTT_TCL_META_DATA_VALID_HTT;
+               ti.encap_type = HAL_TCL_ENCAP_TYPE_RAW;
+               ti.encrypt_type = HAL_ENCRYPT_TYPE_OPEN;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/wifi-ath12k-clear-affinity-hint-before-calling-ath12.patch b/queue-6.14/wifi-ath12k-clear-affinity-hint-before-calling-ath12.patch
new file mode 100644 (file)
index 0000000..4aed773
--- /dev/null
@@ -0,0 +1,55 @@
+From d95fb4eb0cc825851b9b046968b7444ad1c5e9f3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Feb 2025 11:04:46 +0530
+Subject: wifi: ath12k: Clear affinity hint before calling
+ ath12k_pci_free_irq() in error path
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit b43b1e2c52db77c872bd60d30cdcc72c47df70c7 ]
+
+If a shared IRQ is used by the driver due to platform limitation, then the
+IRQ affinity hint is set right after the allocation of IRQ vectors in
+ath12k_pci_msi_alloc(). This does no harm unless one of the functions
+requesting the IRQ fails and attempt to free the IRQ.
+
+This may end up with a warning from the IRQ core that is expecting the
+affinity hint to be cleared before freeing the IRQ:
+
+kernel/irq/manage.c:
+
+       /* make sure affinity_hint is cleaned up */
+       if (WARN_ON_ONCE(desc->affinity_hint))
+               desc->affinity_hint = NULL;
+
+So to fix this issue, clear the IRQ affinity hint before calling
+ath12k_pci_free_irq() in the error path. The affinity will be cleared once
+again further down the error path due to code organization, but that does
+no harm.
+
+Fixes: a3012f206d07 ("wifi: ath12k: set IRQ affinity to CPU0 in case of one MSI vector")
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Reviewed-by: Baochen Qiang <quic_bqiang@quicinc.com>
+Link: https://patch.msgid.link/20250225053447.16824-3-manivannan.sadhasivam@linaro.org
+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 | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c
+index 06cff3849ab8d..2851f6944b864 100644
+--- a/drivers/net/wireless/ath/ath12k/pci.c
++++ b/drivers/net/wireless/ath/ath12k/pci.c
+@@ -1689,6 +1689,8 @@ static int ath12k_pci_probe(struct pci_dev *pdev,
+       return 0;
+ err_free_irq:
++      /* __free_irq() expects the caller to have cleared the affinity hint */
++      ath12k_pci_set_irq_affinity_hint(ab_pci, NULL);
+       ath12k_pci_free_irq(ab);
+ err_ce_free:
+-- 
+2.39.5
+
diff --git a/queue-6.14/wifi-ath12k-encode-max-tx-power-in-scan-channel-list.patch b/queue-6.14/wifi-ath12k-encode-max-tx-power-in-scan-channel-list.patch
new file mode 100644 (file)
index 0000000..4d66632
--- /dev/null
@@ -0,0 +1,47 @@
+From 0883f642fde5db41a4f19fe29895858ff5acad19 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jan 2025 09:31:39 +0530
+Subject: wifi: ath12k: encode max Tx power in scan channel list command
+
+From: Sathishkumar Muruganandam <quic_murugana@quicinc.com>
+
+[ Upstream commit 07c34cad10ab0ac8b06ede8a7fbc55ecf2efa3e6 ]
+
+Currently, when sending the scan channel list command to the firmware, the
+maximum Tx power is not encoded in the reg2 member. This omission causes
+the firmware to be unaware of the host's maximum Tx power, leading to
+incorrect Tx power derivation at firmware level.
+
+To resolve this issue, encode the maximum Tx power in the scan channel list
+command before sending it to firmware.
+
+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: Sathishkumar Muruganandam <quic_murugana@quicinc.com>
+Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
+Tested-by: Nicolas Escande <nico.escande@gmail.com>
+Link: https://patch.msgid.link/20250107-add_max_reg_pwr_in_scan_ch_list_cmd-v1-1-70d9963a21e4@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 | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
+index abb510d235a52..7a87777e0a047 100644
+--- a/drivers/net/wireless/ath/ath12k/wmi.c
++++ b/drivers/net/wireless/ath/ath12k/wmi.c
+@@ -2794,6 +2794,8 @@ int ath12k_wmi_send_scan_chan_list_cmd(struct ath12k *ar,
+                                                 WMI_CHAN_REG_INFO1_REG_CLS);
+                       *reg2 |= le32_encode_bits(channel_arg->antennamax,
+                                                 WMI_CHAN_REG_INFO2_ANT_MAX);
++                      *reg2 |= le32_encode_bits(channel_arg->maxregpower,
++                                                WMI_CHAN_REG_INFO2_MAX_TX_PWR);
+                       ath12k_dbg(ar->ab, ATH12K_DBG_WMI,
+                                  "WMI chan scan list chan[%d] = %u, chan_info->info %8x\n",
+-- 
+2.39.5
+
diff --git a/queue-6.14/wifi-ath12k-fix-locking-in-qmi-firmware-ready-error-.patch b/queue-6.14/wifi-ath12k-fix-locking-in-qmi-firmware-ready-error-.patch
new file mode 100644 (file)
index 0000000..58e25b7
--- /dev/null
@@ -0,0 +1,52 @@
+From 70bcf4f613ce834610c3f810ec237ce1786007e7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Feb 2025 14:13:17 -0800
+Subject: wifi: ath12k: Fix locking in "QMI firmware ready" error paths
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit b9c7299a3341a737622e4de45b9c27e60ad01e3b ]
+
+If ag->mutex has been locked, unlock it before returning. If it has not
+been locked, do not unlock it before returning. These bugs have been
+detected by the Clang thread-safety analyzer.
+
+Cc: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
+Cc: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Fixes: ee146e11b4d9 ("wifi: ath12k: refactor core start based on hardware group")
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Reviewed-by: Aditya Kumar Singh <aditya.kumar.singh@oss.qualcomm.com>
+Link: https://patch.msgid.link/20250206221317.3845663-1-bvanassche@acm.org
+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 | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
+index 0606116d6b9c4..212cd935e60a0 100644
+--- a/drivers/net/wireless/ath/ath12k/core.c
++++ b/drivers/net/wireless/ath/ath12k/core.c
+@@ -1122,16 +1122,18 @@ int ath12k_core_qmi_firmware_ready(struct ath12k_base *ab)
+               ath12k_core_stop(ab);
+               mutex_unlock(&ab->core_lock);
+       }
++      mutex_unlock(&ag->mutex);
+       goto exit;
+ err_dp_free:
+       ath12k_dp_free(ab);
+       mutex_unlock(&ab->core_lock);
++      mutex_unlock(&ag->mutex);
++
+ err_firmware_stop:
+       ath12k_qmi_firmware_stop(ab);
+ exit:
+-      mutex_unlock(&ag->mutex);
+       return ret;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/wifi-ath12k-fix-pdev-lookup-in-wbm-error-processing.patch b/queue-6.14/wifi-ath12k-fix-pdev-lookup-in-wbm-error-processing.patch
new file mode 100644 (file)
index 0000000..5adec33
--- /dev/null
@@ -0,0 +1,49 @@
+From 1b252edaf1105466e88f4c75bd0ab709d0d71e27 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jan 2025 10:00:48 +0530
+Subject: wifi: ath12k: Fix pdev lookup in WBM error processing
+
+From: Rameshkumar Sundaram <quic_ramess@quicinc.com>
+
+[ Upstream commit 4e635b81db9d69bbb836afae8cb402978ff966a4 ]
+
+Currently in ath12k_dp_rx_process_wbm_err(), when processing packets
+received on the WBM error ring, pdev validation is done based upon the
+hw_link_id. But hw_link_id corresponds to link id of a given partner pdev
+in a MLO hardware group, and is not the correct index to use to lookup a
+pdev in an SoC(ab). As a result, pdev validation fails, and the reaped
+packets are dropped instead of being processed.
+
+The correct index to use is the pdev_id, which is already derived in the
+function. So update the logic to validate the pdev based upon the pdev_id
+instead of the hw_link_id. This matches the logic used in other Rx ring
+processing functions.
+
+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: 1a73acb5fba4 ("wifi: ath12k: move to HW link id based receive handling")
+Signed-off-by: Rameshkumar Sundaram <quic_ramess@quicinc.com>
+Link: https://patch.msgid.link/20250102043048.2596791-1-quic_ramess@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 | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
+index dad35bfd83f62..68d609f2ac60e 100644
+--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
++++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
+@@ -4032,7 +4032,7 @@ int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab,
+                                                     hw_links[hw_link_id].pdev_idx);
+               ar = partner_ab->pdevs[pdev_id].ar;
+-              if (!ar || !rcu_dereference(ar->ab->pdevs_active[hw_link_id])) {
++              if (!ar || !rcu_dereference(ar->ab->pdevs_active[pdev_id])) {
+                       dev_kfree_skb_any(msdu);
+                       continue;
+               }
+-- 
+2.39.5
+
diff --git a/queue-6.14/wifi-ath12k-fix-skb_ext_desc-leak-in-ath12k_dp_tx-er.patch b/queue-6.14/wifi-ath12k-fix-skb_ext_desc-leak-in-ath12k_dp_tx-er.patch
new file mode 100644 (file)
index 0000000..8db8a46
--- /dev/null
@@ -0,0 +1,40 @@
+From 8f8eee6dcf2544224744ab627ef564717690f889 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jan 2025 17:01:12 +0100
+Subject: wifi: ath12k: fix skb_ext_desc leak in ath12k_dp_tx() error path
+
+From: Nicolas Escande <nico.escande@gmail.com>
+
+[ Upstream commit 28a9972e0f0693cd4d08f431c992fa6be39c788c ]
+
+When vlan support was added, we missed that when
+ath12k_dp_prepare_htt_metadata() returns an error we also need to free
+the skb holding the metadata before going on with the cleanup process.
+
+Compile tested only.
+
+Fixes: 26dd8ccdba4d ("wifi: ath12k: dynamic VLAN support")
+Signed-off-by: Nicolas Escande <nico.escande@gmail.com>
+Reviewed-by: Aditya Kumar Singh <aditya.kumar.singh@oss.qualcomm.com>
+Link: https://patch.msgid.link/20250122160112.3234558-1-nico.escande@gmail.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 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.c b/drivers/net/wireless/ath/ath12k/dp_tx.c
+index a8d341a6df01e..e0b85f959cd4a 100644
+--- a/drivers/net/wireless/ath/ath12k/dp_tx.c
++++ b/drivers/net/wireless/ath/ath12k/dp_tx.c
+@@ -398,6 +398,7 @@ 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;
+                       }
+               }
+-- 
+2.39.5
+
diff --git a/queue-6.14/wifi-ath12k-use-link-specific-bss_conf-as-well-in-at.patch b/queue-6.14/wifi-ath12k-use-link-specific-bss_conf-as-well-in-at.patch
new file mode 100644 (file)
index 0000000..00b1335
--- /dev/null
@@ -0,0 +1,60 @@
+From ef21a8caf67a87bfb5ab7ae583a6e1dee4a63ce7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Dec 2024 10:41:46 +0800
+Subject: wifi: ath12k: use link specific bss_conf as well in
+ ath12k_mac_vif_cache_flush()
+
+From: Baochen Qiang <quic_bqiang@quicinc.com>
+
+[ Upstream commit 11d963d44c77261d6a948f3745bbd678eef4b83b ]
+
+Commit 3952657848c0 ("wifi: ath12k: Use mac80211 vif's link_conf instead of
+bss_conf") aims at, where applicable, replacing all usage of vif's bss_conf
+with link specific bss_conff, but missed one instance in
+ath12k_mac_vif_cache_flush(). This results in wrong configurations passed
+to ath12k_mac_bss_info_changed() when the link in question is not the default
+link.
+
+Change to use the link specific bss_conf to fix this issue.
+
+Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4
+
+Fixes: 3952657848c0 ("wifi: ath12k: Use mac80211 vif's link_conf instead of bss_conf")
+Signed-off-by: Baochen Qiang <quic_bqiang@quicinc.com>
+Link: https://patch.msgid.link/20241209024146.3282-1-quic_bqiang@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 | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
+index 2d062b5904a8e..9c3e66dbe0c3b 100644
+--- a/drivers/net/wireless/ath/ath12k/mac.c
++++ b/drivers/net/wireless/ath/ath12k/mac.c
+@@ -8066,6 +8066,7 @@ static void ath12k_mac_vif_cache_flush(struct ath12k *ar, struct ath12k_link_vif
+       struct ieee80211_vif *vif = ath12k_ahvif_to_vif(ahvif);
+       struct ath12k_vif_cache *cache = ahvif->cache[arvif->link_id];
+       struct ath12k_base *ab = ar->ab;
++      struct ieee80211_bss_conf *link_conf;
+       int ret;
+@@ -8084,7 +8085,13 @@ static void ath12k_mac_vif_cache_flush(struct ath12k *ar, struct ath12k_link_vif
+       }
+       if (cache->bss_conf_changed) {
+-              ath12k_mac_bss_info_changed(ar, arvif, &vif->bss_conf,
++              link_conf = ath12k_mac_get_link_bss_conf(arvif);
++              if (!link_conf) {
++                      ath12k_warn(ar->ab, "unable to access bss link conf in cache flush for vif %pM link %u\n",
++                                  vif->addr, arvif->link_id);
++                      return;
++              }
++              ath12k_mac_bss_info_changed(ar, arvif, link_conf,
+                                           cache->bss_conf_changed);
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/wifi-ath9k-do-not-submit-zero-bytes-to-the-entropy-p.patch b/queue-6.14/wifi-ath9k-do-not-submit-zero-bytes-to-the-entropy-p.patch
new file mode 100644 (file)
index 0000000..b7f86af
--- /dev/null
@@ -0,0 +1,49 @@
+From 39dff6eb61c5e9e53d1350b55aad78795453d6cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jan 2025 17:10:58 +0300
+Subject: wifi: ath9k: do not submit zero bytes to the entropy pool
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Dmitry Antipov <dmantipov@yandex.ru>
+
+[ Upstream commit 0f2b59a98027a781eee1cbd48c7c8fdf87cb73f6 ]
+
+In 'ath_cmn_process_fft()', it doesn't make too much sense to
+add zero bytes in attempt to improve randomness. So swap calls
+to 'memset()' and 'add_device_randomness()' to feed the pool
+with actual FFT results rather than zeroes. Compile tested only.
+
+Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
+Fixes: 2aa56cca3571 ("ath9k: Mix the received FFT bins to the random pool")
+Acked-by: Toke Høiland-Jørgensen <toke@toke.dk>
+Link: https://patch.msgid.link/20250123141058.1696502-1-dmantipov@yandex.ru
+Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath9k/common-spectral.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath9k/common-spectral.c b/drivers/net/wireless/ath/ath9k/common-spectral.c
+index 628eeec4b82fe..300d178830adf 100644
+--- a/drivers/net/wireless/ath/ath9k/common-spectral.c
++++ b/drivers/net/wireless/ath/ath9k/common-spectral.c
+@@ -628,12 +628,12 @@ int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_h
+                               else
+                                       RX_STAT_INC(sc, rx_spectral_sample_err);
+-                              memset(sample_buf, 0, SPECTRAL_SAMPLE_MAX_LEN);
+-
+                               /* Mix the received bins to the /dev/random
+                                * pool
+                                */
+                               add_device_randomness(sample_buf, num_bins);
++
++                              memset(sample_buf, 0, SPECTRAL_SAMPLE_MAX_LEN);
+                       }
+                       /* Process a normal frame */
+-- 
+2.39.5
+
diff --git a/queue-6.14/wifi-cfg80211-init-wiphy_work-before-allocating-rfki.patch b/queue-6.14/wifi-cfg80211-init-wiphy_work-before-allocating-rfki.patch
new file mode 100644 (file)
index 0000000..4afb190
--- /dev/null
@@ -0,0 +1,102 @@
+From 8a233cc96129532631e35584068ec464fe470c0f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Mar 2025 11:13:45 +0800
+Subject: wifi: cfg80211: init wiphy_work before allocating rfkill fails
+
+From: Edward Adam Davis <eadavis@qq.com>
+
+[ Upstream commit fc88dee89d7b63eeb17699393eb659aadf9d9b7c ]
+
+syzbort reported a uninitialize wiphy_work_lock in cfg80211_dev_free. [1]
+
+After rfkill allocation fails, the wiphy release process will be performed,
+which will cause cfg80211_dev_free to access the uninitialized wiphy_work
+related data.
+
+Move the initialization of wiphy_work to before rfkill initialization to
+avoid this issue.
+
+[1]
+INFO: trying to register non-static key.
+The code is fine but needs lockdep annotation, or maybe
+you didn't initialize this object before use?
+turning off the locking correctness validator.
+CPU: 0 UID: 0 PID: 5935 Comm: syz-executor550 Not tainted 6.14.0-rc6-syzkaller-00103-g4003c9e78778 #0
+Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014
+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:983 [inline]
+ register_lock_class+0xc39/0x1240 kernel/locking/lockdep.c:1297
+ __lock_acquire+0x135/0x3c40 kernel/locking/lockdep.c:5103
+ lock_acquire.part.0+0x11b/0x380 kernel/locking/lockdep.c:5851
+ __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline]
+ _raw_spin_lock_irqsave+0x3a/0x60 kernel/locking/spinlock.c:162
+ cfg80211_dev_free+0x30/0x3d0 net/wireless/core.c:1196
+ device_release+0xa1/0x240 drivers/base/core.c:2568
+ kobject_cleanup lib/kobject.c:689 [inline]
+ kobject_release lib/kobject.c:720 [inline]
+ kref_put include/linux/kref.h:65 [inline]
+ kobject_put+0x1e4/0x5a0 lib/kobject.c:737
+ put_device+0x1f/0x30 drivers/base/core.c:3774
+ wiphy_free net/wireless/core.c:1224 [inline]
+ wiphy_new_nm+0x1c1f/0x2160 net/wireless/core.c:562
+ ieee80211_alloc_hw_nm+0x1b7a/0x2260 net/mac80211/main.c:835
+ mac80211_hwsim_new_radio+0x1d6/0x54e0 drivers/net/wireless/virtual/mac80211_hwsim.c:5185
+ hwsim_new_radio_nl+0xb42/0x12b0 drivers/net/wireless/virtual/mac80211_hwsim.c:6242
+ genl_family_rcv_msg_doit+0x202/0x2f0 net/netlink/genetlink.c:1115
+ genl_family_rcv_msg net/netlink/genetlink.c:1195 [inline]
+ genl_rcv_msg+0x565/0x800 net/netlink/genetlink.c:1210
+ netlink_rcv_skb+0x16b/0x440 net/netlink/af_netlink.c:2533
+ genl_rcv+0x28/0x40 net/netlink/genetlink.c:1219
+ netlink_unicast_kernel net/netlink/af_netlink.c:1312 [inline]
+ netlink_unicast+0x53c/0x7f0 net/netlink/af_netlink.c:1338
+ netlink_sendmsg+0x8b8/0xd70 net/netlink/af_netlink.c:1882
+ sock_sendmsg_nosec net/socket.c:718 [inline]
+ __sock_sendmsg net/socket.c:733 [inline]
+ ____sys_sendmsg+0xaaf/0xc90 net/socket.c:2573
+ ___sys_sendmsg+0x135/0x1e0 net/socket.c:2627
+ __sys_sendmsg+0x16e/0x220 net/socket.c:2659
+ do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+ do_syscall_64+0xcd/0x250 arch/x86/entry/common.c:83
+
+Fixes: 72d520476a2f ("wifi: cfg80211: cancel wiphy_work before freeing wiphy")
+Reported-by: syzbot+aaf0488c83d1d5f4f029@syzkaller.appspotmail.com
+Close: https://syzkaller.appspot.com/bug?extid=aaf0488c83d1d5f4f029
+Tested-by: syzbot+aaf0488c83d1d5f4f029@syzkaller.appspotmail.com
+Signed-off-by: Edward Adam Davis <eadavis@qq.com>
+Link: https://patch.msgid.link/tencent_258DD9121DDDB9DD9A1939CFAA0D8625B107@qq.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/core.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/net/wireless/core.c b/net/wireless/core.c
+index 828e298726335..ceb768925b850 100644
+--- a/net/wireless/core.c
++++ b/net/wireless/core.c
+@@ -546,6 +546,9 @@ struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv,
+       INIT_WORK(&rdev->mgmt_registrations_update_wk,
+                 cfg80211_mgmt_registrations_update_wk);
+       spin_lock_init(&rdev->mgmt_registrations_lock);
++      INIT_WORK(&rdev->wiphy_work, cfg80211_wiphy_work);
++      INIT_LIST_HEAD(&rdev->wiphy_work_list);
++      spin_lock_init(&rdev->wiphy_work_lock);
+ #ifdef CONFIG_CFG80211_DEFAULT_PS
+       rdev->wiphy.flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
+@@ -563,9 +566,6 @@ struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv,
+               return NULL;
+       }
+-      INIT_WORK(&rdev->wiphy_work, cfg80211_wiphy_work);
+-      INIT_LIST_HEAD(&rdev->wiphy_work_list);
+-      spin_lock_init(&rdev->wiphy_work_lock);
+       INIT_WORK(&rdev->rfkill_block, cfg80211_rfkill_block_work);
+       INIT_WORK(&rdev->conn_work, cfg80211_conn_work);
+       INIT_WORK(&rdev->event_work, cfg80211_event_work);
+-- 
+2.39.5
+
diff --git a/queue-6.14/wifi-mac80211-check-basic-rates-validity-in-sta_link.patch b/queue-6.14/wifi-mac80211-check-basic-rates-validity-in-sta_link.patch
new file mode 100644 (file)
index 0000000..a8016ba
--- /dev/null
@@ -0,0 +1,59 @@
+From c9d92e4dcd0ba66d604e635bc21c4efb5d0e20c4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Mar 2025 13:31:37 +0300
+Subject: wifi: mac80211: check basic rates validity in
+ sta_link_apply_parameters
+
+From: Mikhail Lobanov <m.lobanov@rosa.ru>
+
+[ Upstream commit 16ee3ea8faef8ff042acc15867a6c458c573de61 ]
+
+When userspace sets supported rates for a new station via
+NL80211_CMD_NEW_STATION, it might send a list that's empty
+or contains only invalid values. Currently, we process these
+values in sta_link_apply_parameters() without checking the result of
+ieee80211_parse_bitrates(), which can lead to an empty rates bitmap.
+
+A similar issue was addressed for NL80211_CMD_SET_BSS in commit
+ce04abc3fcc6 ("wifi: mac80211: check basic rates validity").
+This patch applies the same approach in sta_link_apply_parameters()
+for NL80211_CMD_NEW_STATION, ensuring there is at least one valid
+rate by inspecting the result of ieee80211_parse_bitrates().
+
+Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
+
+Fixes: b95eb7f0eee4 ("wifi: cfg80211/mac80211: separate link params from station params")
+Signed-off-by: Mikhail Lobanov <m.lobanov@rosa.ru>
+Link: https://patch.msgid.link/20250317103139.17625-1-m.lobanov@rosa.ru
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/cfg.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index 9351c64608a99..b766472703b12 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -1908,12 +1908,12 @@ static int sta_link_apply_parameters(struct ieee80211_local *local,
+       }
+       if (params->supported_rates &&
+-          params->supported_rates_len) {
+-              ieee80211_parse_bitrates(link->conf->chanreq.oper.width,
+-                                       sband, params->supported_rates,
+-                                       params->supported_rates_len,
+-                                       &link_sta->pub->supp_rates[sband->band]);
+-      }
++          params->supported_rates_len &&
++          !ieee80211_parse_bitrates(link->conf->chanreq.oper.width,
++                                    sband, params->supported_rates,
++                                    params->supported_rates_len,
++                                    &link_sta->pub->supp_rates[sband->band]))
++              return -EINVAL;
+       if (params->ht_capa)
+               ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
+-- 
+2.39.5
+
diff --git a/queue-6.14/wifi-mac80211-remove-ssid-from-ml-reconf.patch b/queue-6.14/wifi-mac80211-remove-ssid-from-ml-reconf.patch
new file mode 100644 (file)
index 0000000..e7aabd8
--- /dev/null
@@ -0,0 +1,51 @@
+From 0348083224d2b2ae529cc2013e570f7245eeb89d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Mar 2025 12:10:03 +0100
+Subject: wifi: mac80211: remove SSID from ML reconf
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit 899da1830db112e6bd54ed4573ace753eae6ef22 ]
+
+The ML reconfiguration frame shouldn't contain an SSID,
+remove it.
+
+Fixes: 36e05b0b8390 ("wifi: mac80211: Support dynamic link addition and removal")
+Reviewed-by: Ilan Peer <ilan.peer@intel.com>
+Link: https://patch.msgid.link/20250311121004.fdf08f90bc30.I07f88d3a6f592a0df65d48f55d65c46a4d261007@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/mlme.c | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index 36a9be9a66c8e..da2c2e6035be8 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -9946,8 +9946,8 @@ ieee80211_build_ml_reconf_req(struct ieee80211_sub_if_data *sdata,
+               size += 2 + sizeof(struct ieee80211_mle_per_sta_profile) +
+                       ETH_ALEN;
+-              /* SSID element + WMM */
+-              size += 2 + sdata->vif.cfg.ssid_len + 9;
++              /* WMM */
++              size += 9;
+               size += ieee80211_link_common_elems_size(sdata, iftype, cbss,
+                                                        elems_len);
+       }
+@@ -10053,11 +10053,6 @@ ieee80211_build_ml_reconf_req(struct ieee80211_sub_if_data *sdata,
+                       capab_pos = skb_put(skb, 2);
+-                      skb_put_u8(skb, WLAN_EID_SSID);
+-                      skb_put_u8(skb, sdata->vif.cfg.ssid_len);
+-                      skb_put_data(skb, sdata->vif.cfg.ssid,
+-                                   sdata->vif.cfg.ssid_len);
+-
+                       extra_used =
+                               ieee80211_add_link_elems(sdata, skb, &capab, NULL,
+                                                        add_links_data->link[link_id].elems,
+-- 
+2.39.5
+
diff --git a/queue-6.14/wifi-mt76-mt7915-fix-possible-integer-overflows-in-m.patch b/queue-6.14/wifi-mt76-mt7915-fix-possible-integer-overflows-in-m.patch
new file mode 100644 (file)
index 0000000..aff1d5d
--- /dev/null
@@ -0,0 +1,118 @@
+From 5b0e3976f3482ab322e45f57b6ae1e8ba02a06d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jan 2025 07:44:41 -0800
+Subject: wifi: mt76: mt7915: fix possible integer overflows in
+ mt7915_muru_stats_show()
+
+From: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+
+[ Upstream commit 77b749520cac06d000d9923f79ffa632cdea6113 ]
+
+Assuming sums of values stored in variables such as sub_total_cnt
+and total_ppdu_cnt are big enough to warrant their u64 type, it
+makes sense to ensure that their calculation takes into account
+possible integer overflow issues.
+
+Play it safe and fix the problem by casting right hand expressions
+to u64 as well. Also, slightly adjust tabulation.
+
+Found by Linux Verification Center (linuxtesting.org) with static
+analysis tool SVACE.
+
+Fixes: 1966a5078f2d ("mt76: mt7915: add mu-mimo and ofdma debugfs knobs")
+Signed-off-by: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+Link: https://patch.msgid.link/20250114154441.16920-1-n.zhandarovich@fintech.ru
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../wireless/mediatek/mt76/mt7915/debugfs.c   | 45 ++++++++++---------
+ 1 file changed, 23 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
+index 578013884e438..4fec7d000a631 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
+@@ -303,9 +303,9 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data)
+                  phy->mib.dl_vht_3mu_cnt,
+                  phy->mib.dl_vht_4mu_cnt);
+-      sub_total_cnt = phy->mib.dl_vht_2mu_cnt +
+-                      phy->mib.dl_vht_3mu_cnt +
+-                      phy->mib.dl_vht_4mu_cnt;
++      sub_total_cnt = (u64)phy->mib.dl_vht_2mu_cnt +
++                           phy->mib.dl_vht_3mu_cnt +
++                           phy->mib.dl_vht_4mu_cnt;
+       seq_printf(file, "\nTotal non-HE MU-MIMO DL PPDU count: %lld",
+                  sub_total_cnt);
+@@ -353,26 +353,27 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data)
+                  phy->mib.dl_he_9to16ru_cnt,
+                  phy->mib.dl_he_gtr16ru_cnt);
+-      sub_total_cnt = phy->mib.dl_he_2mu_cnt +
+-                      phy->mib.dl_he_3mu_cnt +
+-                      phy->mib.dl_he_4mu_cnt;
++      sub_total_cnt = (u64)phy->mib.dl_he_2mu_cnt +
++                           phy->mib.dl_he_3mu_cnt +
++                           phy->mib.dl_he_4mu_cnt;
+       total_ppdu_cnt = sub_total_cnt;
+       seq_printf(file, "\nTotal HE MU-MIMO DL PPDU count: %lld",
+                  sub_total_cnt);
+-      sub_total_cnt = phy->mib.dl_he_2ru_cnt +
+-                      phy->mib.dl_he_3ru_cnt +
+-                      phy->mib.dl_he_4ru_cnt +
+-                      phy->mib.dl_he_5to8ru_cnt +
+-                      phy->mib.dl_he_9to16ru_cnt +
+-                      phy->mib.dl_he_gtr16ru_cnt;
++      sub_total_cnt = (u64)phy->mib.dl_he_2ru_cnt +
++                           phy->mib.dl_he_3ru_cnt +
++                           phy->mib.dl_he_4ru_cnt +
++                           phy->mib.dl_he_5to8ru_cnt +
++                           phy->mib.dl_he_9to16ru_cnt +
++                           phy->mib.dl_he_gtr16ru_cnt;
+       total_ppdu_cnt += sub_total_cnt;
+       seq_printf(file, "\nTotal HE OFDMA DL PPDU count: %lld",
+                  sub_total_cnt);
+-      total_ppdu_cnt += phy->mib.dl_he_su_cnt + phy->mib.dl_he_ext_su_cnt;
++      total_ppdu_cnt += (u64)phy->mib.dl_he_su_cnt +
++                             phy->mib.dl_he_ext_su_cnt;
+       seq_printf(file, "\nAll HE DL PPDU count: %lld", total_ppdu_cnt);
+@@ -404,20 +405,20 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data)
+                  phy->mib.ul_hetrig_9to16ru_cnt,
+                  phy->mib.ul_hetrig_gtr16ru_cnt);
+-      sub_total_cnt = phy->mib.ul_hetrig_2mu_cnt +
+-                      phy->mib.ul_hetrig_3mu_cnt +
+-                      phy->mib.ul_hetrig_4mu_cnt;
++      sub_total_cnt = (u64)phy->mib.ul_hetrig_2mu_cnt +
++                           phy->mib.ul_hetrig_3mu_cnt +
++                           phy->mib.ul_hetrig_4mu_cnt;
+       total_ppdu_cnt = sub_total_cnt;
+       seq_printf(file, "\nTotal HE MU-MIMO UL TB PPDU count: %lld",
+                  sub_total_cnt);
+-      sub_total_cnt = phy->mib.ul_hetrig_2ru_cnt +
+-                      phy->mib.ul_hetrig_3ru_cnt +
+-                      phy->mib.ul_hetrig_4ru_cnt +
+-                      phy->mib.ul_hetrig_5to8ru_cnt +
+-                      phy->mib.ul_hetrig_9to16ru_cnt +
+-                      phy->mib.ul_hetrig_gtr16ru_cnt;
++      sub_total_cnt = (u64)phy->mib.ul_hetrig_2ru_cnt +
++                           phy->mib.ul_hetrig_3ru_cnt +
++                           phy->mib.ul_hetrig_4ru_cnt +
++                           phy->mib.ul_hetrig_5to8ru_cnt +
++                           phy->mib.ul_hetrig_9to16ru_cnt +
++                           phy->mib.ul_hetrig_gtr16ru_cnt;
+       total_ppdu_cnt += sub_total_cnt;
+       seq_printf(file, "\nTotal HE OFDMA UL TB PPDU count: %lld",
+-- 
+2.39.5
+
diff --git a/queue-6.14/wifi-mwifiex-fix-premature-release-of-rf-calibration.patch b/queue-6.14/wifi-mwifiex-fix-premature-release-of-rf-calibration.patch
new file mode 100644 (file)
index 0000000..0c18295
--- /dev/null
@@ -0,0 +1,61 @@
+From 70898ff8c56b71e9a755fec89b063c70e2f4bb22 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Mar 2025 13:07:38 +0800
+Subject: wifi: mwifiex: Fix premature release of RF calibration data.
+
+From: Jeff Chen <jeff.chen_1@nxp.com>
+
+[ Upstream commit 69ae7e1f73abae20f26e3536ca4a980b90eafeb7 ]
+
+This patch resolves an issue where RF calibration data was being
+released before the download process. Without this fix, the
+external calibration data file would not be downloaded
+at all.
+
+Fixes: d39fbc88956e ("mwifiex: remove cfg_data construction")
+Signed-off-by: Jeff Chen <jeff.chen_1@nxp.com>
+Link: https://patch.msgid.link/20250318050739.2239376-2-jeff.chen_1@nxp.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/marvell/mwifiex/main.c    | 4 ----
+ drivers/net/wireless/marvell/mwifiex/sta_cmd.c | 6 +++++-
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c
+index 855019fe54858..80fc6d5afe860 100644
+--- a/drivers/net/wireless/marvell/mwifiex/main.c
++++ b/drivers/net/wireless/marvell/mwifiex/main.c
+@@ -691,10 +691,6 @@ static int _mwifiex_fw_dpc(const struct firmware *firmware, void *context)
+       init_failed = true;
+ done:
+-      if (adapter->cal_data) {
+-              release_firmware(adapter->cal_data);
+-              adapter->cal_data = NULL;
+-      }
+       if (adapter->firmware) {
+               release_firmware(adapter->firmware);
+               adapter->firmware = NULL;
+diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
+index e2800a831c8ed..c0e6ce1a82fed 100644
+--- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
++++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
+@@ -2293,9 +2293,13 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init)
+                                               "marvell,caldata");
+               }
+-              if (adapter->cal_data)
++              if (adapter->cal_data) {
+                       mwifiex_send_cmd(priv, HostCmd_CMD_CFG_DATA,
+                                        HostCmd_ACT_GEN_SET, 0, NULL, true);
++                      release_firmware(adapter->cal_data);
++                      adapter->cal_data = NULL;
++              }
++
+               /* Read MAC address from HW */
+               ret = mwifiex_send_cmd(priv, HostCmd_CMD_GET_HW_SPEC,
+-- 
+2.39.5
+
diff --git a/queue-6.14/wifi-mwifiex-fix-rf-calibration-data-download-from-f.patch b/queue-6.14/wifi-mwifiex-fix-rf-calibration-data-download-from-f.patch
new file mode 100644 (file)
index 0000000..121493f
--- /dev/null
@@ -0,0 +1,118 @@
+From ca074d2592a8a84711dd313ff53f6d65ba9d3734 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Mar 2025 13:07:39 +0800
+Subject: wifi: mwifiex: Fix RF calibration data download from file
+
+From: Jeff Chen <jeff.chen_1@nxp.com>
+
+[ Upstream commit 9868c4ce9481043d6c11f7421fe2b9637aa0feee ]
+
+This patch resolves an issue where RF calibration data from a
+file could not be downloaded to the firmware. The feature to
+download calibration data from a file was broken by the commit:
+d39fbc88956e.
+
+The issue arose because the function `mwifiex_cmd_cfg_data()`
+was modified in a way that prevented proper handling of
+file-based calibration data. While this patch restores the ability
+to download RF calibration data from a file, it may inadvertently
+break the feature to download calibration data from the device
+tree. This is because the function `mwifiex_dnld_dt_cfgdata()`,
+which also relies on `mwifiex_cmd_cfg_data()`, is still used for
+device tree-based calibration data downloads.
+
+Fixes: d39fbc88956e ("mwifiex: remove cfg_data construction")
+Signed-off-by: Jeff Chen <jeff.chen_1@nxp.com>
+Link: https://patch.msgid.link/20250318050739.2239376-3-jeff.chen_1@nxp.com
+[add newline for shorter lines]
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/marvell/mwifiex/fw.h      | 14 ++++++++++++++
+ drivers/net/wireless/marvell/mwifiex/sta_cmd.c | 12 ++++++++++--
+ 2 files changed, 24 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h b/drivers/net/wireless/marvell/mwifiex/fw.h
+index 4a96281792cc1..91458f3bd14a5 100644
+--- a/drivers/net/wireless/marvell/mwifiex/fw.h
++++ b/drivers/net/wireless/marvell/mwifiex/fw.h
+@@ -454,6 +454,11 @@ enum mwifiex_channel_flags {
+ #define HostCmd_RET_BIT                       0x8000
+ #define HostCmd_ACT_GEN_GET                   0x0000
+ #define HostCmd_ACT_GEN_SET                   0x0001
++#define HOST_CMD_ACT_GEN_SET                  0x0001
++/* Add this non-CamelCase-style macro to comply with checkpatch requirements.
++ *  This macro will eventually replace all existing CamelCase-style macros in
++ *  the future for consistency.
++ */
+ #define HostCmd_ACT_GEN_REMOVE                0x0004
+ #define HostCmd_ACT_BITWISE_SET               0x0002
+ #define HostCmd_ACT_BITWISE_CLR               0x0003
+@@ -2352,6 +2357,14 @@ struct host_cmd_ds_add_station {
+       u8 tlv[];
+ } __packed;
++#define MWIFIEX_CFG_TYPE_CAL 0x2
++
++struct host_cmd_ds_802_11_cfg_data {
++      __le16 action;
++      __le16 type;
++      __le16 data_len;
++} __packed;
++
+ struct host_cmd_ds_command {
+       __le16 command;
+       __le16 size;
+@@ -2431,6 +2444,7 @@ struct host_cmd_ds_command {
+               struct host_cmd_ds_pkt_aggr_ctrl pkt_aggr_ctrl;
+               struct host_cmd_ds_sta_configure sta_cfg;
+               struct host_cmd_ds_add_station sta_info;
++              struct host_cmd_ds_802_11_cfg_data cfg_data;
+       } params;
+ } __packed;
+diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
+index c0e6ce1a82fed..c4689f5a1acc8 100644
+--- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
++++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
+@@ -1507,6 +1507,7 @@ static int mwifiex_cmd_cfg_data(struct mwifiex_private *priv,
+       u32 len;
+       u8 *data = (u8 *)cmd + S_DS_GEN;
+       int ret;
++      struct host_cmd_ds_802_11_cfg_data *pcfg_data;
+       if (prop) {
+               len = prop->length;
+@@ -1514,12 +1515,20 @@ static int mwifiex_cmd_cfg_data(struct mwifiex_private *priv,
+                                               data, len);
+               if (ret)
+                       return ret;
++
++              cmd->size = cpu_to_le16(S_DS_GEN + len);
+               mwifiex_dbg(adapter, INFO,
+                           "download cfg_data from device tree: %s\n",
+                           prop->name);
+       } else if (adapter->cal_data->data && adapter->cal_data->size > 0) {
+               len = mwifiex_parse_cal_cfg((u8 *)adapter->cal_data->data,
+-                                          adapter->cal_data->size, data);
++                                          adapter->cal_data->size,
++                                          data + sizeof(*pcfg_data));
++              pcfg_data = &cmd->params.cfg_data;
++              pcfg_data->action = cpu_to_le16(HOST_CMD_ACT_GEN_SET);
++              pcfg_data->type = cpu_to_le16(MWIFIEX_CFG_TYPE_CAL);
++              pcfg_data->data_len = cpu_to_le16(len);
++              cmd->size = cpu_to_le16(S_DS_GEN + sizeof(*pcfg_data) + len);
+               mwifiex_dbg(adapter, INFO,
+                           "download cfg_data from config file\n");
+       } else {
+@@ -1527,7 +1536,6 @@ static int mwifiex_cmd_cfg_data(struct mwifiex_private *priv,
+       }
+       cmd->command = cpu_to_le16(HostCmd_CMD_CFG_DATA);
+-      cmd->size = cpu_to_le16(S_DS_GEN + len);
+       return 0;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/wifi-nl80211-store-chandef-on-the-correct-link-when-.patch b/queue-6.14/wifi-nl80211-store-chandef-on-the-correct-link-when-.patch
new file mode 100644 (file)
index 0000000..e32ae83
--- /dev/null
@@ -0,0 +1,38 @@
+From d37109b307a1c98b57af7fb79e75c0865bff45ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Mar 2025 09:38:53 +0530
+Subject: wifi: nl80211: store chandef on the correct link when starting CAC
+
+From: Aditya Kumar Singh <aditya.kumar.singh@oss.qualcomm.com>
+
+[ Upstream commit ea841520c50f5f7c72c8070e3b79e1927b94fabf ]
+
+Link ID to store chandef is still being used as 0 even in case of MLO which
+is incorrect. This leads to issue during CAC completion where link 0 as well
+gets stopped.
+
+Fixes: 0b7798232eee ("wifi: cfg80211/mac80211: use proper link ID for DFS")
+Signed-off-by: Aditya Kumar Singh <aditya.kumar.singh@oss.qualcomm.com>
+Link: https://patch.msgid.link/20250314-fix_starting_cac_during_mlo-v1-1-3b51617d7ea5@oss.qualcomm.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/nl80211.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index aac0e7298dc7a..b457fe78672b7 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -10172,7 +10172,7 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
+       switch (wdev->iftype) {
+       case NL80211_IFTYPE_AP:
+       case NL80211_IFTYPE_P2P_GO:
+-              wdev->links[0].ap.chandef = chandef;
++              wdev->links[link_id].ap.chandef = chandef;
+               break;
+       case NL80211_IFTYPE_ADHOC:
+               wdev->u.ibss.chandef = chandef;
+-- 
+2.39.5
+
diff --git a/queue-6.14/wifi-rtw89-correct-immediate-cfg_len-calculation-for.patch b/queue-6.14/wifi-rtw89-correct-immediate-cfg_len-calculation-for.patch
new file mode 100644 (file)
index 0000000..94cf47b
--- /dev/null
@@ -0,0 +1,73 @@
+From 5eaab707646c8ebda061147694c8ca50a6ff31ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jan 2025 18:51:44 +0800
+Subject: wifi: rtw89: Correct immediate cfg_len calculation for
+ scan_offload_be
+
+From: Liang Jie <liangjie@lixiang.com>
+
+[ Upstream commit 361cb056e2468be534f47c1a6745f96581a721e3 ]
+
+Ensures the correct calculation of `cfg_len` prior to the allocation of
+the skb in the `rtw89_fw_h2c_scan_offload_be` function, particularly when
+the `SCAN_OFFLOAD_BE_V0` firmware feature is enabled. It addresses an
+issue where an incorrect skb size might be allocated due to a delayed
+setting of `cfg_len`, potentially leading to memory inefficiencies.
+
+By moving the conditional check and assignment of `cfg_len` before skb
+allocation, the patch guarantees that `len`, which depends on `cfg_len`,
+is accurately computed, ensuring proper skb size and preventing any
+unnecessary memory reservation for firmware operations not supporting
+beyond the `w8` member of the command data structure.
+
+This correction helps to optimize memory usage and maintain consistent
+behavior across different firmware versions.
+
+Fixes: 6ca6b918f280 ("wifi: rtw89: 8922a: Add new fields for scan offload H2C command")
+Signed-off-by: Liang Jie <liangjie@lixiang.com>
+Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
+Link: https://patch.msgid.link/20250112105144.615474-1-buaajxlj@163.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtw89/fw.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
+index 5d4ad23cc3bd4..5cc9ab78c09f7 100644
+--- a/drivers/net/wireless/realtek/rtw89/fw.c
++++ b/drivers/net/wireless/realtek/rtw89/fw.c
+@@ -5311,6 +5311,7 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
+       u8 macc_role_size = sizeof(*macc_role) * option->num_macc_role;
+       u8 opch_size = sizeof(*opch) * option->num_opch;
+       u8 probe_id[NUM_NL80211_BANDS];
++      u8 scan_offload_ver = U8_MAX;
+       u8 cfg_len = sizeof(*h2c);
+       unsigned int cond;
+       u8 ver = U8_MAX;
+@@ -5321,6 +5322,11 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
+       rtw89_scan_get_6g_disabled_chan(rtwdev, option);
++      if (RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_BE_V0, &rtwdev->fw)) {
++              cfg_len = offsetofend(typeof(*h2c), w8);
++              scan_offload_ver = 0;
++      }
++
+       len = cfg_len + macc_role_size + opch_size;
+       skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
+       if (!skb) {
+@@ -5392,10 +5398,8 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
+                                          RTW89_H2C_SCANOFLD_BE_W8_PROBE_RATE_6GHZ);
+       }
+-      if (RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_BE_V0, &rtwdev->fw)) {
+-              cfg_len = offsetofend(typeof(*h2c), w8);
++      if (scan_offload_ver == 0)
+               goto flex_member;
+-      }
+       h2c->w9 = le32_encode_bits(sizeof(*h2c) / sizeof(h2c->w0),
+                                  RTW89_H2C_SCANOFLD_BE_W9_SIZE_CFG) |
+-- 
+2.39.5
+
diff --git a/queue-6.14/wifi-rtw89-fw-correct-debug-message-format-in-rtw89_.patch b/queue-6.14/wifi-rtw89-fw-correct-debug-message-format-in-rtw89_.patch
new file mode 100644 (file)
index 0000000..b05610a
--- /dev/null
@@ -0,0 +1,36 @@
+From 104122dc111f10adbbb4984c5569721c062ae9c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 21:12:27 +0800
+Subject: wifi: rtw89: fw: correct debug message format in
+ rtw89_build_txpwr_trk_tbl_from_elm()
+
+From: Ping-Ke Shih <pkshih@realtek.com>
+
+[ Upstream commit 88b46320fc9d915aa0c1c765db5ccd2db12fe92e ]
+
+The format should be "%08x". Fix the mistakes.
+
+Fixes: d60e73e5dd70 ("wifi: rtw89: fw: load TX power track tables from fw_element")
+Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
+Link: https://patch.msgid.link/20250227131228.8457-4-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 5cc9ab78c09f7..2f3869c700696 100644
+--- a/drivers/net/wireless/realtek/rtw89/fw.c
++++ b/drivers/net/wireless/realtek/rtw89/fw.c
+@@ -988,7 +988,7 @@ int rtw89_build_txpwr_trk_tbl_from_elm(struct rtw89_dev *rtwdev,
+       bitmap = le32_to_cpu(elm->u.txpwr_trk.bitmap);
+       if ((bitmap & needed_bitmap) != needed_bitmap) {
+-              rtw89_warn(rtwdev, "needed txpwr trk bitmap %08x but %0x8x\n",
++              rtw89_warn(rtwdev, "needed txpwr trk bitmap %08x but %08x\n",
+                          needed_bitmap, bitmap);
+               return -ENOENT;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/wifi-rtw89-pci-correct-isr-rdu-bit-for-8922ae.patch b/queue-6.14/wifi-rtw89-pci-correct-isr-rdu-bit-for-8922ae.patch
new file mode 100644 (file)
index 0000000..7d78db9
--- /dev/null
@@ -0,0 +1,107 @@
+From 8161ad377ca715d39b8f70b65fb2e812399bbcd7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 21:19:07 +0800
+Subject: wifi: rtw89: pci: correct ISR RDU bit for 8922AE
+
+From: Ping-Ke Shih <pkshih@realtek.com>
+
+[ Upstream commit 3218f5bd8e2e4abc156493f8121b8db53b49ee9e ]
+
+The interrupt status (ISR) bits of RX desc unavailable (RDU) for 8922AE
+are B_BE_RDU_CH1_INT_V1 and B_BE_RDU_CH0_INT_V1. With wrong bits, if it
+happens, driver can't recognize the situation and prompt a message.
+Fix the definition accordingly.
+
+Fixes: aa70f76120ee ("wifi: rtw89: pci: generalize interrupt status bits of interrupt handlers")
+Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
+Link: https://patch.msgid.link/20250227131907.9864-1-pkshih@realtek.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtw89/pci.h    | 56 +++++++++++----------
+ drivers/net/wireless/realtek/rtw89/pci_be.c |  2 +-
+ 2 files changed, 30 insertions(+), 28 deletions(-)
+
+diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h
+index 4d11c3dd60a5d..79fef5f901408 100644
+--- a/drivers/net/wireless/realtek/rtw89/pci.h
++++ b/drivers/net/wireless/realtek/rtw89/pci.h
+@@ -455,34 +455,36 @@
+ #define B_BE_RX0DMA_INT_EN BIT(0)
+ #define R_BE_HAXI_HISR00 0xB0B4
+-#define B_BE_RDU_CH6_INT BIT(28)
+-#define B_BE_RDU_CH5_INT BIT(27)
+-#define B_BE_RDU_CH4_INT BIT(26)
+-#define B_BE_RDU_CH2_INT BIT(25)
+-#define B_BE_RDU_CH1_INT BIT(24)
+-#define B_BE_RDU_CH0_INT BIT(23)
+-#define B_BE_RXDMA_STUCK_INT BIT(22)
+-#define B_BE_TXDMA_STUCK_INT BIT(21)
+-#define B_BE_TXDMA_CH14_INT BIT(20)
+-#define B_BE_TXDMA_CH13_INT BIT(19)
+-#define B_BE_TXDMA_CH12_INT BIT(18)
+-#define B_BE_TXDMA_CH11_INT BIT(17)
+-#define B_BE_TXDMA_CH10_INT BIT(16)
+-#define B_BE_TXDMA_CH9_INT BIT(15)
+-#define B_BE_TXDMA_CH8_INT BIT(14)
+-#define B_BE_TXDMA_CH7_INT BIT(13)
+-#define B_BE_TXDMA_CH6_INT BIT(12)
+-#define B_BE_TXDMA_CH5_INT BIT(11)
+-#define B_BE_TXDMA_CH4_INT BIT(10)
+-#define B_BE_TXDMA_CH3_INT BIT(9)
+-#define B_BE_TXDMA_CH2_INT BIT(8)
+-#define B_BE_TXDMA_CH1_INT BIT(7)
+-#define B_BE_TXDMA_CH0_INT BIT(6)
+-#define B_BE_RPQ1DMA_INT BIT(5)
+-#define B_BE_RX1P1DMA_INT BIT(4)
++#define B_BE_RDU_CH5_INT_V1 BIT(30)
++#define B_BE_RDU_CH4_INT_V1 BIT(29)
++#define B_BE_RDU_CH3_INT_V1 BIT(28)
++#define B_BE_RDU_CH2_INT_V1 BIT(27)
++#define B_BE_RDU_CH1_INT_V1 BIT(26)
++#define B_BE_RDU_CH0_INT_V1 BIT(25)
++#define B_BE_RXDMA_STUCK_INT_V1 BIT(24)
++#define B_BE_TXDMA_STUCK_INT_V1 BIT(23)
++#define B_BE_TXDMA_CH14_INT_V1 BIT(22)
++#define B_BE_TXDMA_CH13_INT_V1 BIT(21)
++#define B_BE_TXDMA_CH12_INT_V1 BIT(20)
++#define B_BE_TXDMA_CH11_INT_V1 BIT(19)
++#define B_BE_TXDMA_CH10_INT_V1 BIT(18)
++#define B_BE_TXDMA_CH9_INT_V1 BIT(17)
++#define B_BE_TXDMA_CH8_INT_V1 BIT(16)
++#define B_BE_TXDMA_CH7_INT_V1 BIT(15)
++#define B_BE_TXDMA_CH6_INT_V1 BIT(14)
++#define B_BE_TXDMA_CH5_INT_V1 BIT(13)
++#define B_BE_TXDMA_CH4_INT_V1 BIT(12)
++#define B_BE_TXDMA_CH3_INT_V1 BIT(11)
++#define B_BE_TXDMA_CH2_INT_V1 BIT(10)
++#define B_BE_TXDMA_CH1_INT_V1 BIT(9)
++#define B_BE_TXDMA_CH0_INT_V1 BIT(8)
++#define B_BE_RX1P1DMA_INT_V1 BIT(7)
++#define B_BE_RX0P1DMA_INT_V1 BIT(6)
++#define B_BE_RO1DMA_INT BIT(5)
++#define B_BE_RP1DMA_INT BIT(4)
+ #define B_BE_RX1DMA_INT BIT(3)
+-#define B_BE_RPQ0DMA_INT BIT(2)
+-#define B_BE_RX0P1DMA_INT BIT(1)
++#define B_BE_RO0DMA_INT BIT(2)
++#define B_BE_RP0DMA_INT BIT(1)
+ #define B_BE_RX0DMA_INT BIT(0)
+ /* TX/RX */
+diff --git a/drivers/net/wireless/realtek/rtw89/pci_be.c b/drivers/net/wireless/realtek/rtw89/pci_be.c
+index cd39eebe81861..12e6a0cbb889b 100644
+--- a/drivers/net/wireless/realtek/rtw89/pci_be.c
++++ b/drivers/net/wireless/realtek/rtw89/pci_be.c
+@@ -666,7 +666,7 @@ SIMPLE_DEV_PM_OPS(rtw89_pm_ops_be, rtw89_pci_suspend_be, rtw89_pci_resume_be);
+ EXPORT_SYMBOL(rtw89_pm_ops_be);
+ const struct rtw89_pci_gen_def rtw89_pci_gen_be = {
+-      .isr_rdu = B_BE_RDU_CH1_INT | B_BE_RDU_CH0_INT,
++      .isr_rdu = B_BE_RDU_CH1_INT_V1 | B_BE_RDU_CH0_INT_V1,
+       .isr_halt_c2h = B_BE_HALT_C2H_INT,
+       .isr_wdt_timeout = B_BE_WDT_TIMEOUT_INT,
+       .isr_clear_rpq = {R_BE_PCIE_DMA_ISR, B_BE_PCIE_RX_RPQ0_ISR_V1},
+-- 
+2.39.5
+
diff --git a/queue-6.14/wifi-rtw89-rtw8852b-t-fix-tssi-debug-timestamps.patch b/queue-6.14/wifi-rtw89-rtw8852b-t-fix-tssi-debug-timestamps.patch
new file mode 100644 (file)
index 0000000..e1d326f
--- /dev/null
@@ -0,0 +1,125 @@
+From fa2b24dc9ce9d0c06fe2a30c3f85af78e5ebeb50 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Feb 2025 12:50:06 +0300
+Subject: wifi: rtw89: rtw8852b{t}: fix TSSI debug timestamps
+
+From: Dmitry Antipov <dmantipov@yandex.ru>
+
+[ Upstream commit bfc8e71ef6b7913f0129aff47951cab73a175259 ]
+
+Since the vendor driver is claimed to measure 'tssi_alimk_time' of
+'struct rtw89_tssi_info' in microseconds, adjust rtw8852b{t}-specific
+'_tssi_alimentk()' to not mess the former with nanoseconds and print
+both per-call and accumulated times. Compile tested only.
+
+Fixes: 7f18a70d7b4d ("wifi: rtw89: 8852b: rfk: add TSSI")
+Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
+Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
+Link: https://patch.msgid.link/20250213095006.1308810-1-dmantipov@yandex.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtw89/core.h          |  2 +-
+ drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c  | 13 +++++++------
+ drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk.c | 13 +++++++------
+ 3 files changed, 15 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
+index ff4894c7fa8a5..93e41def81b40 100644
+--- a/drivers/net/wireless/realtek/rtw89/core.h
++++ b/drivers/net/wireless/realtek/rtw89/core.h
+@@ -5135,7 +5135,7 @@ struct rtw89_tssi_info {
+       u32 alignment_backup_by_ch[RF_PATH_MAX][TSSI_MAX_CH_NUM][TSSI_ALIMK_VALUE_NUM];
+       u32 alignment_value[RF_PATH_MAX][TSSI_ALIMK_MAX][TSSI_ALIMK_VALUE_NUM];
+       bool alignment_done[RF_PATH_MAX][TSSI_ALIMK_MAX];
+-      u32 tssi_alimk_time;
++      u64 tssi_alimk_time;
+ };
+ struct rtw89_power_trim_info {
+diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c
+index ef47a5facc836..fbf82d42687ba 100644
+--- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c
++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c
+@@ -3585,9 +3585,10 @@ static void _tssi_alimentk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+       u8 ch_idx = _tssi_ch_to_idx(rtwdev, channel);
+       struct rtw8852bx_bb_tssi_bak tssi_bak;
+       s32 aliment_diff, tssi_cw_default;
+-      u32 start_time, finish_time;
+       u32 bb_reg_backup[8] = {0};
++      ktime_t start_time;
+       const s16 *power;
++      s64 this_time;
+       u8 band;
+       bool ok;
+       u32 tmp;
+@@ -3613,7 +3614,7 @@ static void _tssi_alimentk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+               return;
+       }
+-      start_time = ktime_get_ns();
++      start_time = ktime_get();
+       if (chan->band_type == RTW89_BAND_2G)
+               power = power_2g;
+@@ -3738,12 +3739,12 @@ static void _tssi_alimentk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+       rtw8852bx_bb_restore_tssi(rtwdev, phy, &tssi_bak);
+       rtw8852bx_bb_tx_mode_switch(rtwdev, phy, 0);
+-      finish_time = ktime_get_ns();
+-      tssi_info->tssi_alimk_time += finish_time - start_time;
++      this_time = ktime_us_delta(ktime_get(), start_time);
++      tssi_info->tssi_alimk_time += this_time;
+       rtw89_debug(rtwdev, RTW89_DBG_RFK,
+-                  "[TSSI PA K] %s processing time = %d ms\n", __func__,
+-                  tssi_info->tssi_alimk_time);
++                  "[TSSI PA K] %s processing time = %lld us (acc = %llu us)\n",
++                  __func__, this_time, tssi_info->tssi_alimk_time);
+ }
+ void rtw8852b_dpk_init(struct rtw89_dev *rtwdev)
+diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk.c
+index 336a83e1d46be..6e6889eea9a0d 100644
+--- a/drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk.c
++++ b/drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk.c
+@@ -3663,9 +3663,10 @@ static void _tssi_alimentk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+       u8 ch_idx = _tssi_ch_to_idx(rtwdev, channel);
+       struct rtw8852bx_bb_tssi_bak tssi_bak;
+       s32 aliment_diff, tssi_cw_default;
+-      u32 start_time, finish_time;
+       u32 bb_reg_backup[8] = {};
++      ktime_t start_time;
+       const s16 *power;
++      s64 this_time;
+       u8 band;
+       bool ok;
+       u32 tmp;
+@@ -3675,7 +3676,7 @@ static void _tssi_alimentk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+                   "======> %s   channel=%d   path=%d\n", __func__, channel,
+                   path);
+-      start_time = ktime_get_ns();
++      start_time = ktime_get();
+       if (chan->band_type == RTW89_BAND_2G)
+               power = power_2g;
+@@ -3802,12 +3803,12 @@ static void _tssi_alimentk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
+       rtw8852bx_bb_restore_tssi(rtwdev, phy, &tssi_bak);
+       rtw8852bx_bb_tx_mode_switch(rtwdev, phy, 0);
+-      finish_time = ktime_get_ns();
+-      tssi_info->tssi_alimk_time += finish_time - start_time;
++      this_time = ktime_us_delta(ktime_get(), start_time);
++      tssi_info->tssi_alimk_time += this_time;
+       rtw89_debug(rtwdev, RTW89_DBG_RFK,
+-                  "[TSSI PA K] %s processing time = %d ms\n", __func__,
+-                  tssi_info->tssi_alimk_time);
++                  "[TSSI PA K] %s processing time = %lld us (acc = %llu us)\n",
++                  __func__, this_time, tssi_info->tssi_alimk_time);
+ }
+ void rtw8852bt_dpk_init(struct rtw89_dev *rtwdev)
+-- 
+2.39.5
+
diff --git a/queue-6.14/writeback-fix-calculations-in-trace_balance_dirty_pa.patch b/queue-6.14/writeback-fix-calculations-in-trace_balance_dirty_pa.patch
new file mode 100644 (file)
index 0000000..709678f
--- /dev/null
@@ -0,0 +1,88 @@
+From b805e90575d4f8ef8c7a1c7b5d6f427c1f19810e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Mar 2025 19:03:18 +0800
+Subject: writeback: fix calculations in trace_balance_dirty_pages() for cgwb
+
+From: Tang Yizhou <yizhou.tang@shopee.com>
+
+[ Upstream commit 6cc4c3aa714bc58ec5d20f3054ca5f23534984d1 ]
+
+In the commit dcc25ae76eb7 ("writeback: move global_dirty_limit into
+wb_domain") of the cgroup writeback backpressure propagation patchset,
+Tejun made some adaptations to trace_balance_dirty_pages() for cgroup
+writeback.  However, this adaptation was incomplete and Tejun missed
+further adaptation in the subsequent patches.
+
+In the cgroup writeback scenario, if sdtc in balance_dirty_pages() is
+assigned to mdtc, then upon entering trace_balance_dirty_pages(),
+__entry->limit should be assigned based on the dirty_limit of the
+corresponding memcg's wb_domain, rather than global_wb_domain.
+
+To address this issue and simplify the implementation, introduce a 'limit'
+field in struct dirty_throttle_control to store the hard_limit value
+computed in wb_position_ratio() by calling hard_dirty_limit().  This field
+will then be used in trace_balance_dirty_pages() to assign the value to
+__entry->limit.
+
+Link: https://lkml.kernel.org/r/20250304110318.159567-4-yizhou.tang@shopee.com
+Fixes: dcc25ae76eb7 ("writeback: move global_dirty_limit into wb_domain")
+Signed-off-by: Tang Yizhou <yizhou.tang@shopee.com>
+Acked-by: Tejun Heo <tj@kernel.org>
+Cc: Alexei Starovoitov <ast@kernel.org>
+Cc: Christian Brauner <brauner@kernel.org>
+Cc: Jan Kara <jack@suse.cz>
+Cc: "Masami Hiramatsu (Google)" <mhiramat@kernel.org>
+Cc: Matthew Wilcow (Oracle) <willy@infradead.org>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/writeback.h        | 1 +
+ include/trace/events/writeback.h | 5 ++---
+ mm/page-writeback.c              | 2 +-
+ 3 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/include/linux/writeback.h b/include/linux/writeback.h
+index 32095928365ce..58bda33479146 100644
+--- a/include/linux/writeback.h
++++ b/include/linux/writeback.h
+@@ -326,6 +326,7 @@ struct dirty_throttle_control {
+       unsigned long           dirty;          /* file_dirty + write + nfs */
+       unsigned long           thresh;         /* dirty threshold */
+       unsigned long           bg_thresh;      /* dirty background threshold */
++      unsigned long           limit;          /* hard dirty limit */
+       unsigned long           wb_dirty;       /* per-wb counterparts */
+       unsigned long           wb_thresh;
+diff --git a/include/trace/events/writeback.h b/include/trace/events/writeback.h
+index 3213b90237944..5755c2a569e16 100644
+--- a/include/trace/events/writeback.h
++++ b/include/trace/events/writeback.h
+@@ -663,9 +663,8 @@ TRACE_EVENT(balance_dirty_pages,
+               unsigned long freerun = (dtc->thresh + dtc->bg_thresh) / 2;
+               strscpy_pad(__entry->bdi, bdi_dev_name(wb->bdi), 32);
+-              __entry->limit          = global_wb_domain.dirty_limit;
+-              __entry->setpoint       = (global_wb_domain.dirty_limit +
+-                                              freerun) / 2;
++              __entry->limit          = dtc->limit;
++              __entry->setpoint       = (dtc->limit + freerun) / 2;
+               __entry->dirty          = dtc->dirty;
+               __entry->bdi_setpoint   = __entry->setpoint *
+                                               dtc->wb_thresh / (dtc->thresh + 1);
+diff --git a/mm/page-writeback.c b/mm/page-writeback.c
+index e980b2aec3529..3147119a9a042 100644
+--- a/mm/page-writeback.c
++++ b/mm/page-writeback.c
+@@ -1072,7 +1072,7 @@ static void wb_position_ratio(struct dirty_throttle_control *dtc)
+       struct bdi_writeback *wb = dtc->wb;
+       unsigned long write_bw = READ_ONCE(wb->avg_write_bandwidth);
+       unsigned long freerun = dirty_freerun_ceiling(dtc->thresh, dtc->bg_thresh);
+-      unsigned long limit = hard_dirty_limit(dtc_dom(dtc), dtc->thresh);
++      unsigned long limit = dtc->limit = hard_dirty_limit(dtc_dom(dtc), dtc->thresh);
+       unsigned long wb_thresh = dtc->wb_thresh;
+       unsigned long x_intercept;
+       unsigned long setpoint;         /* dirty pages' target balance point */
+-- 
+2.39.5
+
diff --git a/queue-6.14/writeback-let-trace_balance_dirty_pages-take-struct-.patch b/queue-6.14/writeback-let-trace_balance_dirty_pages-take-struct-.patch
new file mode 100644 (file)
index 0000000..4789acf
--- /dev/null
@@ -0,0 +1,199 @@
+From 839e5561590ffd665de5b5319f5b57f42c802a95 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Mar 2025 19:03:16 +0800
+Subject: writeback: let trace_balance_dirty_pages() take struct dtc as
+ parameter
+
+From: Tang Yizhou <yizhou.tang@shopee.com>
+
+[ Upstream commit f1ab2831e2a4312046bca79256b2efc41d373eaf ]
+
+Patch series "Fix calculations in trace_balance_dirty_pages() for cgwb", v2.
+
+In my experiment, I found that the output of trace_balance_dirty_pages()
+in the cgroup writeback scenario was strange because
+trace_balance_dirty_pages() always uses global_wb_domain.dirty_limit for
+related calculations instead of the dirty_limit of the corresponding
+memcg's wb_domain.
+
+The basic idea of the fix is to store the hard dirty limit value computed
+in wb_position_ratio() into struct dirty_throttle_control and use it for
+calculations in trace_balance_dirty_pages().
+
+This patch (of 3):
+
+Currently, trace_balance_dirty_pages() already has 12 parameters.  In the
+patch #3, I initially attempted to introduce an additional parameter.
+However, in include/linux/trace_events.h, bpf_trace_run12() only supports
+up to 12 parameters and bpf_trace_run13() does not exist.
+
+To reduce the number of parameters in trace_balance_dirty_pages(), we can
+make it accept a pointer to struct dirty_throttle_control as a parameter.
+To achieve this, we need to move the definition of struct
+dirty_throttle_control from mm/page-writeback.c to
+include/linux/writeback.h.
+
+Link: https://lkml.kernel.org/r/20250304110318.159567-1-yizhou.tang@shopee.com
+Link: https://lkml.kernel.org/r/20250304110318.159567-2-yizhou.tang@shopee.com
+Signed-off-by: Tang Yizhou <yizhou.tang@shopee.com>
+Cc: Alexei Starovoitov <ast@kernel.org>
+Cc: Christian Brauner <brauner@kernel.org>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Cc: Jan Kara <jack@suse.cz>
+Cc: "Masami Hiramatsu (Google)" <mhiramat@kernel.org>
+Cc: Matthew Wilcow (Oracle) <willy@infradead.org>
+Cc: Tang Yizhou <yizhou.tang@shopee.com>
+Cc: Tejun Heo <tj@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Stable-dep-of: 6cc4c3aa714b ("writeback: fix calculations in trace_balance_dirty_pages() for cgwb")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/writeback.h        | 23 +++++++++++++++++++++
+ include/trace/events/writeback.h | 16 ++++++---------
+ mm/page-writeback.c              | 35 ++------------------------------
+ 3 files changed, 31 insertions(+), 43 deletions(-)
+
+diff --git a/include/linux/writeback.h b/include/linux/writeback.h
+index d11b903c2edb8..32095928365ce 100644
+--- a/include/linux/writeback.h
++++ b/include/linux/writeback.h
+@@ -313,6 +313,29 @@ static inline void cgroup_writeback_umount(struct super_block *sb)
+ /*
+  * mm/page-writeback.c
+  */
++/* consolidated parameters for balance_dirty_pages() and its subroutines */
++struct dirty_throttle_control {
++#ifdef CONFIG_CGROUP_WRITEBACK
++      struct wb_domain        *dom;
++      struct dirty_throttle_control *gdtc;    /* only set in memcg dtc's */
++#endif
++      struct bdi_writeback    *wb;
++      struct fprop_local_percpu *wb_completions;
++
++      unsigned long           avail;          /* dirtyable */
++      unsigned long           dirty;          /* file_dirty + write + nfs */
++      unsigned long           thresh;         /* dirty threshold */
++      unsigned long           bg_thresh;      /* dirty background threshold */
++
++      unsigned long           wb_dirty;       /* per-wb counterparts */
++      unsigned long           wb_thresh;
++      unsigned long           wb_bg_thresh;
++
++      unsigned long           pos_ratio;
++      bool                    freerun;
++      bool                    dirty_exceeded;
++};
++
+ void laptop_io_completion(struct backing_dev_info *info);
+ void laptop_sync_completion(void);
+ void laptop_mode_timer_fn(struct timer_list *t);
+diff --git a/include/trace/events/writeback.h b/include/trace/events/writeback.h
+index a261e86e61fac..3213b90237944 100644
+--- a/include/trace/events/writeback.h
++++ b/include/trace/events/writeback.h
+@@ -629,11 +629,7 @@ TRACE_EVENT(bdi_dirty_ratelimit,
+ TRACE_EVENT(balance_dirty_pages,
+       TP_PROTO(struct bdi_writeback *wb,
+-               unsigned long thresh,
+-               unsigned long bg_thresh,
+-               unsigned long dirty,
+-               unsigned long bdi_thresh,
+-               unsigned long bdi_dirty,
++               struct dirty_throttle_control *dtc,
+                unsigned long dirty_ratelimit,
+                unsigned long task_ratelimit,
+                unsigned long dirtied,
+@@ -641,7 +637,7 @@ TRACE_EVENT(balance_dirty_pages,
+                long pause,
+                unsigned long start_time),
+-      TP_ARGS(wb, thresh, bg_thresh, dirty, bdi_thresh, bdi_dirty,
++      TP_ARGS(wb, dtc,
+               dirty_ratelimit, task_ratelimit,
+               dirtied, period, pause, start_time),
+@@ -664,16 +660,16 @@ TRACE_EVENT(balance_dirty_pages,
+       ),
+       TP_fast_assign(
+-              unsigned long freerun = (thresh + bg_thresh) / 2;
++              unsigned long freerun = (dtc->thresh + dtc->bg_thresh) / 2;
+               strscpy_pad(__entry->bdi, bdi_dev_name(wb->bdi), 32);
+               __entry->limit          = global_wb_domain.dirty_limit;
+               __entry->setpoint       = (global_wb_domain.dirty_limit +
+                                               freerun) / 2;
+-              __entry->dirty          = dirty;
++              __entry->dirty          = dtc->dirty;
+               __entry->bdi_setpoint   = __entry->setpoint *
+-                                              bdi_thresh / (thresh + 1);
+-              __entry->bdi_dirty      = bdi_dirty;
++                                              dtc->wb_thresh / (dtc->thresh + 1);
++              __entry->bdi_dirty      = dtc->wb_dirty;
+               __entry->dirty_ratelimit = KBps(dirty_ratelimit);
+               __entry->task_ratelimit = KBps(task_ratelimit);
+               __entry->dirtied        = dirtied;
+diff --git a/mm/page-writeback.c b/mm/page-writeback.c
+index eb55ece39c565..e980b2aec3529 100644
+--- a/mm/page-writeback.c
++++ b/mm/page-writeback.c
+@@ -120,29 +120,6 @@ EXPORT_SYMBOL(laptop_mode);
+ struct wb_domain global_wb_domain;
+-/* consolidated parameters for balance_dirty_pages() and its subroutines */
+-struct dirty_throttle_control {
+-#ifdef CONFIG_CGROUP_WRITEBACK
+-      struct wb_domain        *dom;
+-      struct dirty_throttle_control *gdtc;    /* only set in memcg dtc's */
+-#endif
+-      struct bdi_writeback    *wb;
+-      struct fprop_local_percpu *wb_completions;
+-
+-      unsigned long           avail;          /* dirtyable */
+-      unsigned long           dirty;          /* file_dirty + write + nfs */
+-      unsigned long           thresh;         /* dirty threshold */
+-      unsigned long           bg_thresh;      /* dirty background threshold */
+-
+-      unsigned long           wb_dirty;       /* per-wb counterparts */
+-      unsigned long           wb_thresh;
+-      unsigned long           wb_bg_thresh;
+-
+-      unsigned long           pos_ratio;
+-      bool                    freerun;
+-      bool                    dirty_exceeded;
+-};
+-
+ /*
+  * Length of period for aging writeout fractions of bdis. This is an
+  * arbitrarily chosen number. The longer the period, the slower fractions will
+@@ -1962,11 +1939,7 @@ static int balance_dirty_pages(struct bdi_writeback *wb,
+                */
+               if (pause < min_pause) {
+                       trace_balance_dirty_pages(wb,
+-                                                sdtc->thresh,
+-                                                sdtc->bg_thresh,
+-                                                sdtc->dirty,
+-                                                sdtc->wb_thresh,
+-                                                sdtc->wb_dirty,
++                                                sdtc,
+                                                 dirty_ratelimit,
+                                                 task_ratelimit,
+                                                 pages_dirtied,
+@@ -1991,11 +1964,7 @@ static int balance_dirty_pages(struct bdi_writeback *wb,
+ pause:
+               trace_balance_dirty_pages(wb,
+-                                        sdtc->thresh,
+-                                        sdtc->bg_thresh,
+-                                        sdtc->dirty,
+-                                        sdtc->wb_thresh,
+-                                        sdtc->wb_dirty,
++                                        sdtc,
+                                         dirty_ratelimit,
+                                         task_ratelimit,
+                                         pages_dirtied,
+-- 
+2.39.5
+
diff --git a/queue-6.14/x86-dumpstack-fix-inaccurate-unwinding-from-exceptio.patch b/queue-6.14/x86-dumpstack-fix-inaccurate-unwinding-from-exceptio.patch
new file mode 100644 (file)
index 0000000..99bfbd1
--- /dev/null
@@ -0,0 +1,69 @@
+From 8c4f87a7f68c12a77fadfd8781cbb7aca116ef5d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Mar 2025 03:01:23 +0100
+Subject: x86/dumpstack: Fix inaccurate unwinding from exception stacks due to
+ misplaced assignment
+
+From: Jann Horn <jannh@google.com>
+
+[ Upstream commit 2c118f50d7fd4d9aefc4533a26f83338b2906b7a ]
+
+Commit:
+
+  2e4be0d011f2 ("x86/show_trace_log_lvl: Ensure stack pointer is aligned, again")
+
+was intended to ensure alignment of the stack pointer; but it also moved
+the initialization of the "stack" variable down into the loop header.
+
+This was likely intended as a no-op cleanup, since the commit
+message does not mention it; however, this caused a behavioral change
+because the value of "regs" is different between the two places.
+
+Originally, get_stack_pointer() used the regs provided by the caller; after
+that commit, get_stack_pointer() instead uses the regs at the top of the
+stack frame the unwinder is looking at. Often, there are no such regs at
+all, and "regs" is NULL, causing get_stack_pointer() to fall back to the
+task's current stack pointer, which is not what we want here, but probably
+happens to mostly work. Other times, the original regs will point to
+another regs frame - in that case, the linear guess unwind logic in
+show_trace_log_lvl() will start unwinding too far up the stack, causing the
+first frame found by the proper unwinder to never be visited, resulting in
+a stack trace consisting purely of guess lines.
+
+Fix it by moving the "stack = " assignment back where it belongs.
+
+Fixes: 2e4be0d011f2 ("x86/show_trace_log_lvl: Ensure stack pointer is aligned, again")
+Signed-off-by: Jann Horn <jannh@google.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Link: https://lore.kernel.org/r/20250325-2025-03-unwind-fixes-v1-2-acd774364768@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/dumpstack.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c
+index a7d562697e50e..b2b118a8c09be 100644
+--- a/arch/x86/kernel/dumpstack.c
++++ b/arch/x86/kernel/dumpstack.c
+@@ -195,6 +195,7 @@ static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
+       printk("%sCall Trace:\n", log_lvl);
+       unwind_start(&state, task, regs, stack);
++      stack = stack ?: get_stack_pointer(task, regs);
+       regs = unwind_get_entry_regs(&state, &partial);
+       /*
+@@ -213,9 +214,7 @@ static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
+        * - hardirq stack
+        * - entry stack
+        */
+-      for (stack = stack ?: get_stack_pointer(task, regs);
+-           stack;
+-           stack = stack_info.next_sp) {
++      for (; stack; stack = stack_info.next_sp) {
+               const char *stack_name;
+               stack = PTR_ALIGN(stack, sizeof(long));
+-- 
+2.39.5
+
diff --git a/queue-6.14/x86-entry-add-__init-to-ia32_emulation_override_cmdl.patch b/queue-6.14/x86-entry-add-__init-to-ia32_emulation_override_cmdl.patch
new file mode 100644 (file)
index 0000000..d2ead3d
--- /dev/null
@@ -0,0 +1,41 @@
+From 95cae8252a1326a1dfe8ca217ddad13bca30fcb8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Dec 2024 16:16:50 +0100
+Subject: x86/entry: Add __init to ia32_emulation_override_cmdline()
+
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+
+[ Upstream commit d55f31e29047f2f987286d55928ae75775111fe7 ]
+
+ia32_emulation_override_cmdline() is an early_param() arg and these
+are only needed at boot time. In fact, all other early_param() functions
+in arch/x86 seem to have '__init' annotation and
+ia32_emulation_override_cmdline() is the only exception.
+
+Fixes: a11e097504ac ("x86: Make IA32_EMULATION boot time configurable")
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Reviewed-by: Nikolay Borisov <nik.borisov@suse.com>
+Link: https://lore.kernel.org/all/20241210151650.1746022-1-vkuznets%40redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/entry/common.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c
+index 14db5b85114c1..3514bf2978eed 100644
+--- a/arch/x86/entry/common.c
++++ b/arch/x86/entry/common.c
+@@ -142,7 +142,7 @@ static __always_inline int syscall_32_enter(struct pt_regs *regs)
+ #ifdef CONFIG_IA32_EMULATION
+ bool __ia32_enabled __ro_after_init = !IS_ENABLED(CONFIG_IA32_EMULATION_DEFAULT_DISABLED);
+-static int ia32_emulation_override_cmdline(char *arg)
++static int __init ia32_emulation_override_cmdline(char *arg)
+ {
+       return kstrtobool(arg, &__ia32_enabled);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/x86-entry-fix-orc-unwinder-for-push_regs-with-save_r.patch b/queue-6.14/x86-entry-fix-orc-unwinder-for-push_regs-with-save_r.patch
new file mode 100644 (file)
index 0000000..1e6ce70
--- /dev/null
@@ -0,0 +1,55 @@
+From b8eabdcd88fa3bdc1fc24286174cd7575840086d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Mar 2025 03:01:22 +0100
+Subject: x86/entry: Fix ORC unwinder for PUSH_REGS with save_ret=1
+
+From: Jann Horn <jannh@google.com>
+
+[ Upstream commit 57e2428f8df8263275344566e02c277648a4b7f1 ]
+
+PUSH_REGS with save_ret=1 is used by interrupt entry helper functions that
+initially start with a UNWIND_HINT_FUNC ORC state.
+
+However, save_ret=1 means that we clobber the helper function's return
+address (and then later restore the return address further down on the
+stack); after that point, the only thing on the stack we can unwind through
+is the IRET frame, so use UNWIND_HINT_IRET_REGS until we have a full
+pt_regs frame.
+
+( An alternate approach would be to move the pt_regs->di overwrite down
+  such that it is the final step of pt_regs setup; but I don't want to
+  rearrange entry code just to make unwinding a tiny bit more elegant. )
+
+Fixes: 9e809d15d6b6 ("x86/entry: Reduce the code footprint of the 'idtentry' macro")
+Signed-off-by: Jann Horn <jannh@google.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: Brian Gerst <brgerst@gmail.com>
+Cc: Juergen Gross <jgross@suse.com>
+Cc: H. Peter Anvin <hpa@zytor.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Kees Cook <keescook@chromium.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Link: https://lore.kernel.org/r/20250325-2025-03-unwind-fixes-v1-1-acd774364768@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/entry/calling.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h
+index ea81770629eea..626a81c6015bd 100644
+--- a/arch/x86/entry/calling.h
++++ b/arch/x86/entry/calling.h
+@@ -70,6 +70,8 @@ For 32-bit we have the following conventions - kernel is built with
+       pushq   %rsi            /* pt_regs->si */
+       movq    8(%rsp), %rsi   /* temporarily store the return address in %rsi */
+       movq    %rdi, 8(%rsp)   /* pt_regs->di (overwriting original return address) */
++      /* We just clobbered the return address - use the IRET frame for unwinding: */
++      UNWIND_HINT_IRET_REGS offset=3*8
+       .else
+       pushq   %rdi            /* pt_regs->di */
+       pushq   %rsi            /* pt_regs->si */
+-- 
+2.39.5
+
diff --git a/queue-6.14/x86-fpu-avoid-copying-dynamic-fp-state-from-init_tas.patch b/queue-6.14/x86-fpu-avoid-copying-dynamic-fp-state-from-init_tas.patch
new file mode 100644 (file)
index 0000000..74af303
--- /dev/null
@@ -0,0 +1,57 @@
+From 2f682ea754482b5ff6156a830eb68791f78e9711 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Feb 2025 14:31:36 +0100
+Subject: x86/fpu: Avoid copying dynamic FP state from init_task in
+ arch_dup_task_struct()
+
+From: Benjamin Berg <benjamin.berg@intel.com>
+
+[ Upstream commit 5d3b81d4d8520efe888536b6906dc10fd1a228a8 ]
+
+The init_task instance of struct task_struct is statically allocated and
+may not contain the full FP state for userspace. As such, limit the copy
+to the valid area of both init_task and 'dst' and ensure all memory is
+initialized.
+
+Note that the FP state is only needed for userspace, and as such it is
+entirely reasonable for init_task to not contain parts of it.
+
+Fixes: 5aaeb5c01c5b ("x86/fpu, sched: Introduce CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT and use it on x86")
+Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: H. Peter Anvin <hpa@zytor.com>
+Cc: Oleg Nesterov <oleg@redhat.com>
+Link: https://lore.kernel.org/r/20250226133136.816901-1-benjamin@sipsolutions.net
+----
+
+v2:
+- Fix code if arch_task_struct_size < sizeof(init_task) by using
+  memcpy_and_pad.
+
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/process.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
+index 6da6769d7254a..7cb52f84cb0c2 100644
+--- a/arch/x86/kernel/process.c
++++ b/arch/x86/kernel/process.c
+@@ -93,7 +93,12 @@ EXPORT_PER_CPU_SYMBOL_GPL(__tss_limit_invalid);
+  */
+ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
+ {
+-      memcpy(dst, src, arch_task_struct_size);
++      /* init_task is not dynamically sized (incomplete FPU state) */
++      if (unlikely(src == &init_task))
++              memcpy_and_pad(dst, arch_task_struct_size, src, sizeof(init_task), 0);
++      else
++              memcpy(dst, src, arch_task_struct_size);
++
+ #ifdef CONFIG_VM86
+       dst->thread.vm86 = NULL;
+ #endif
+-- 
+2.39.5
+
diff --git a/queue-6.14/x86-fpu-fix-guest-fpu-state-buffer-allocation-size.patch b/queue-6.14/x86-fpu-fix-guest-fpu-state-buffer-allocation-size.patch
new file mode 100644 (file)
index 0000000..9ff7cbd
--- /dev/null
@@ -0,0 +1,49 @@
+From 8c254852164c228803ce7a79b140a4e4de692fc8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Feb 2025 14:10:45 +0000
+Subject: x86/fpu: Fix guest FPU state buffer allocation size
+
+From: Stanislav Spassov <stanspas@amazon.de>
+
+[ Upstream commit 1937e18cc3cf27e2b3ef70e8c161437051ab7608 ]
+
+Ongoing work on an optimization to batch-preallocate vCPU state buffers
+for KVM revealed a mismatch between the allocation sizes used in
+fpu_alloc_guest_fpstate() and fpstate_realloc(). While the former
+allocates a buffer sized to fit the default set of XSAVE features
+in UABI form (as per fpu_user_cfg), the latter uses its ksize argument
+derived (for the requested set of features) in the same way as the sizes
+found in fpu_kernel_cfg, i.e. using the compacted in-kernel
+representation.
+
+The correct size to use for guest FPU state should indeed be the
+kernel one as seen in fpstate_realloc(). The original issue likely
+went unnoticed through a combination of UABI size typically being
+larger than or equal to kernel size, and/or both amounting to the
+same number of allocated 4K pages.
+
+Fixes: 69f6ed1d14c6 ("x86/fpu: Provide infrastructure for KVM FPU cleanup")
+Signed-off-by: Stanislav Spassov <stanspas@amazon.de>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Link: https://lore.kernel.org/r/20250218141045.85201-1-stanspas@amazon.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/fpu/core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c
+index 1209c7aebb211..36df548acc403 100644
+--- a/arch/x86/kernel/fpu/core.c
++++ b/arch/x86/kernel/fpu/core.c
+@@ -220,7 +220,7 @@ bool fpu_alloc_guest_fpstate(struct fpu_guest *gfpu)
+       struct fpstate *fpstate;
+       unsigned int size;
+-      size = fpu_user_cfg.default_size + ALIGN(offsetof(struct fpstate, regs), 64);
++      size = fpu_kernel_cfg.default_size + ALIGN(offsetof(struct fpstate, regs), 64);
+       fpstate = vzalloc(size);
+       if (!fpstate)
+               return false;
+-- 
+2.39.5
+
diff --git a/queue-6.14/x86-fpu-xstate-fix-inconsistencies-in-guest-fpu-xfea.patch b/queue-6.14/x86-fpu-xstate-fix-inconsistencies-in-guest-fpu-xfea.patch
new file mode 100644 (file)
index 0000000..2a7fd74
--- /dev/null
@@ -0,0 +1,86 @@
+From fcefc7b385a241178b73f5b839ddb8eda9e3fcc5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Mar 2025 22:06:11 +0800
+Subject: x86/fpu/xstate: Fix inconsistencies in guest FPU xfeatures
+
+From: Chao Gao <chao.gao@intel.com>
+
+[ Upstream commit dda366083e5ff307a4a728757db874bbfe7550be ]
+
+Guest FPUs manage vCPU FPU states. They are allocated via
+fpu_alloc_guest_fpstate() and are resized in fpstate_realloc() when XFD
+features are enabled.
+
+Since the introduction of guest FPUs, there have been inconsistencies in
+the kernel buffer size and xfeatures:
+
+ 1. fpu_alloc_guest_fpstate() uses fpu_user_cfg since its introduction. See:
+
+    69f6ed1d14c6 ("x86/fpu: Provide infrastructure for KVM FPU cleanup")
+    36487e6228c4 ("x86/fpu: Prepare guest FPU for dynamically enabled FPU features")
+
+ 2. __fpstate_reset() references fpu_kernel_cfg to set storage attributes.
+
+ 3. fpu->guest_perm uses fpu_kernel_cfg, affecting fpstate_realloc().
+
+A recent commit in the tip:x86/fpu tree partially addressed the inconsistency
+between (1) and (3) by using fpu_kernel_cfg for size calculation in (1),
+but left fpu_guest->xfeatures and fpu_guest->perm still referencing
+fpu_user_cfg:
+
+  https://lore.kernel.org/all/20250218141045.85201-1-stanspas@amazon.de/
+
+  1937e18cc3cf ("x86/fpu: Fix guest FPU state buffer allocation size")
+
+The inconsistencies within fpu_alloc_guest_fpstate() and across the
+mentioned functions cause confusion.
+
+Fix them by using fpu_kernel_cfg consistently in fpu_alloc_guest_fpstate(),
+except for fields related to the UABI buffer. Referencing fpu_kernel_cfg
+won't impact functionalities, as:
+
+ 1. fpu_guest->perm is overwritten shortly in fpu_init_guest_permissions()
+    with fpstate->guest_perm, which already uses fpu_kernel_cfg.
+
+ 2. fpu_guest->xfeatures is solely used to check if XFD features are enabled.
+    Including supervisor xfeatures doesn't affect the check.
+
+Fixes: 36487e6228c4 ("x86/fpu: Prepare guest FPU for dynamically enabled FPU features")
+Suggested-by: Chang S. Bae <chang.seok.bae@intel.com>
+Signed-off-by: Chao Gao <chao.gao@intel.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: H. Peter Anvin <hpa@zytor.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Oleg Nesterov <oleg@redhat.com>
+Cc: Dave Hansen <dave.hansen@linux.intel.com>
+Cc: Juergen Gross <jgross@suse.com>
+Cc: Stefano Stabellini <sstabellini@kernel.org>
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Cc: Vitaly Kuznetsov <vkuznets@redhat.com>
+Cc: Sean Christopherson <seanjc@google.com>
+Cc: David Woodhouse <dwmw2@infradead.org>
+Link: https://lore.kernel.org/r/20250317140613.1761633-1-chao.gao@intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/fpu/core.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c
+index 36df548acc403..dcac3c058fb76 100644
+--- a/arch/x86/kernel/fpu/core.c
++++ b/arch/x86/kernel/fpu/core.c
+@@ -232,8 +232,8 @@ bool fpu_alloc_guest_fpstate(struct fpu_guest *gfpu)
+       fpstate->is_guest       = true;
+       gfpu->fpstate           = fpstate;
+-      gfpu->xfeatures         = fpu_user_cfg.default_features;
+-      gfpu->perm              = fpu_user_cfg.default_features;
++      gfpu->xfeatures         = fpu_kernel_cfg.default_features;
++      gfpu->perm              = fpu_kernel_cfg.default_features;
+       /*
+        * KVM sets the FP+SSE bits in the XSAVE header when copying FPU state
+-- 
+2.39.5
+
diff --git a/queue-6.14/x86-mm-pat-cpa-test-fix-length-for-cpa_array-test.patch b/queue-6.14/x86-mm-pat-cpa-test-fix-length-for-cpa_array-test.patch
new file mode 100644 (file)
index 0000000..392d84f
--- /dev/null
@@ -0,0 +1,40 @@
+From 5b4f6b8d95d806633b7fd0fcdaafd355c689a289 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 26 Jan 2025 09:47:25 +0200
+Subject: x86/mm/pat: cpa-test: fix length for CPA_ARRAY test
+
+From: Mike Rapoport (Microsoft) <rppt@kernel.org>
+
+[ Upstream commit 33ea120582a638b2f2e380a50686c2b1d7cce795 ]
+
+The CPA_ARRAY test always uses len[1] as numpages argument to
+change_page_attr_set() although the addresses array is different each
+iteration of the test loop.
+
+Replace len[1] with len[i] to have numpages matching the addresses array.
+
+Fixes: ecc729f1f471 ("x86/mm/cpa: Add ARRAY and PAGES_ARRAY selftests")
+Signed-off-by: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20250126074733.1384926-2-rppt@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/mm/pat/cpa-test.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/x86/mm/pat/cpa-test.c b/arch/x86/mm/pat/cpa-test.c
+index 3d2f7f0a6ed14..ad3c1feec990d 100644
+--- a/arch/x86/mm/pat/cpa-test.c
++++ b/arch/x86/mm/pat/cpa-test.c
+@@ -183,7 +183,7 @@ static int pageattr_test(void)
+                       break;
+               case 1:
+-                      err = change_page_attr_set(addrs, len[1], PAGE_CPA_TEST, 1);
++                      err = change_page_attr_set(addrs, len[i], PAGE_CPA_TEST, 1);
+                       break;
+               case 2:
+-- 
+2.39.5
+
diff --git a/queue-6.14/x86-mm-pat-fix-vm_pat-handling-when-fork-fails-in-co.patch b/queue-6.14/x86-mm-pat-fix-vm_pat-handling-when-fork-fails-in-co.patch
new file mode 100644 (file)
index 0000000..f41f1bf
--- /dev/null
@@ -0,0 +1,297 @@
+From ff71cd468634374f6f9de93277bce237f353fa0b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Mar 2025 12:23:23 +0100
+Subject: x86/mm/pat: Fix VM_PAT handling when fork() fails in
+ copy_page_range()
+
+From: David Hildenbrand <david@redhat.com>
+
+[ Upstream commit dc84bc2aba85a1508f04a936f9f9a15f64ebfb31 ]
+
+If track_pfn_copy() fails, we already added the dst VMA to the maple
+tree. As fork() fails, we'll cleanup the maple tree, and stumble over
+the dst VMA for which we neither performed any reservation nor copied
+any page tables.
+
+Consequently untrack_pfn() will see VM_PAT and try obtaining the
+PAT information from the page table -- which fails because the page
+table was not copied.
+
+The easiest fix would be to simply clear the VM_PAT flag of the dst VMA
+if track_pfn_copy() fails. However, the whole thing is about "simply"
+clearing the VM_PAT flag is shaky as well: if we passed track_pfn_copy()
+and performed a reservation, but copying the page tables fails, we'll
+simply clear the VM_PAT flag, not properly undoing the reservation ...
+which is also wrong.
+
+So let's fix it properly: set the VM_PAT flag only if the reservation
+succeeded (leaving it clear initially), and undo the reservation if
+anything goes wrong while copying the page tables: clearing the VM_PAT
+flag after undoing the reservation.
+
+Note that any copied page table entries will get zapped when the VMA will
+get removed later, after copy_page_range() succeeded; as VM_PAT is not set
+then, we won't try cleaning VM_PAT up once more and untrack_pfn() will be
+happy. Note that leaving these page tables in place without a reservation
+is not a problem, as we are aborting fork(); this process will never run.
+
+A reproducer can trigger this usually at the first try:
+
+  https://gitlab.com/davidhildenbrand/scratchspace/-/raw/main/reproducers/pat_fork.c
+
+  WARNING: CPU: 26 PID: 11650 at arch/x86/mm/pat/memtype.c:983 get_pat_info+0xf6/0x110
+  Modules linked in: ...
+  CPU: 26 UID: 0 PID: 11650 Comm: repro3 Not tainted 6.12.0-rc5+ #92
+  Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-2.fc40 04/01/2014
+  RIP: 0010:get_pat_info+0xf6/0x110
+  ...
+  Call Trace:
+   <TASK>
+   ...
+   untrack_pfn+0x52/0x110
+   unmap_single_vma+0xa6/0xe0
+   unmap_vmas+0x105/0x1f0
+   exit_mmap+0xf6/0x460
+   __mmput+0x4b/0x120
+   copy_process+0x1bf6/0x2aa0
+   kernel_clone+0xab/0x440
+   __do_sys_clone+0x66/0x90
+   do_syscall_64+0x95/0x180
+
+Likely this case was missed in:
+
+  d155df53f310 ("x86/mm/pat: clear VM_PAT if copy_p4d_range failed")
+
+... and instead of undoing the reservation we simply cleared the VM_PAT flag.
+
+Keep the documentation of these functions in include/linux/pgtable.h,
+one place is more than sufficient -- we should clean that up for the other
+functions like track_pfn_remap/untrack_pfn separately.
+
+Fixes: d155df53f310 ("x86/mm/pat: clear VM_PAT if copy_p4d_range failed")
+Fixes: 2ab640379a0a ("x86: PAT: hooks in generic vm code to help archs to track pfnmap regions - v3")
+Reported-by: xingwei lee <xrivendell7@gmail.com>
+Reported-by: yuxin wang <wang1315768607@163.com>
+Reported-by: Marius Fleischer <fleischermarius@gmail.com>
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Rik van Riel <riel@surriel.com>
+Cc: "H. Peter Anvin" <hpa@zytor.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: linux-mm@kvack.org
+Link: https://lore.kernel.org/r/20250321112323.153741-1-david@redhat.com
+Closes: https://lore.kernel.org/lkml/CABOYnLx_dnqzpCW99G81DmOr+2UzdmZMk=T3uxwNxwz+R1RAwg@mail.gmail.com/
+Closes: https://lore.kernel.org/lkml/CAJg=8jwijTP5fre8woS4JVJQ8iUA6v+iNcsOgtj9Zfpc3obDOQ@mail.gmail.com/
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/mm/pat/memtype.c | 52 +++++++++++++++++++++------------------
+ include/linux/pgtable.h   | 28 ++++++++++++++++-----
+ kernel/fork.c             |  4 +++
+ mm/memory.c               | 11 +++------
+ 4 files changed, 58 insertions(+), 37 deletions(-)
+
+diff --git a/arch/x86/mm/pat/memtype.c b/arch/x86/mm/pat/memtype.c
+index feb8cc6a12bf2..d721cc19addbd 100644
+--- a/arch/x86/mm/pat/memtype.c
++++ b/arch/x86/mm/pat/memtype.c
+@@ -984,29 +984,42 @@ static int get_pat_info(struct vm_area_struct *vma, resource_size_t *paddr,
+       return -EINVAL;
+ }
+-/*
+- * track_pfn_copy is called when vma that is covering the pfnmap gets
+- * copied through copy_page_range().
+- *
+- * If the vma has a linear pfn mapping for the entire range, we get the prot
+- * from pte and reserve the entire vma range with single reserve_pfn_range call.
+- */
+-int track_pfn_copy(struct vm_area_struct *vma)
++int track_pfn_copy(struct vm_area_struct *dst_vma,
++              struct vm_area_struct *src_vma, unsigned long *pfn)
+ {
++      const unsigned long vma_size = src_vma->vm_end - src_vma->vm_start;
+       resource_size_t paddr;
+-      unsigned long vma_size = vma->vm_end - vma->vm_start;
+       pgprot_t pgprot;
++      int rc;
+-      if (vma->vm_flags & VM_PAT) {
+-              if (get_pat_info(vma, &paddr, &pgprot))
+-                      return -EINVAL;
+-              /* reserve the whole chunk covered by vma. */
+-              return reserve_pfn_range(paddr, vma_size, &pgprot, 1);
+-      }
++      if (!(src_vma->vm_flags & VM_PAT))
++              return 0;
++
++      /*
++       * Duplicate the PAT information for the dst VMA based on the src
++       * VMA.
++       */
++      if (get_pat_info(src_vma, &paddr, &pgprot))
++              return -EINVAL;
++      rc = reserve_pfn_range(paddr, vma_size, &pgprot, 1);
++      if (rc)
++              return rc;
++      /* Reservation for the destination VMA succeeded. */
++      vm_flags_set(dst_vma, VM_PAT);
++      *pfn = PHYS_PFN(paddr);
+       return 0;
+ }
++void untrack_pfn_copy(struct vm_area_struct *dst_vma, unsigned long pfn)
++{
++      untrack_pfn(dst_vma, pfn, dst_vma->vm_end - dst_vma->vm_start, true);
++      /*
++       * Reservation was freed, any copied page tables will get cleaned
++       * up later, but without getting PAT involved again.
++       */
++}
++
+ /*
+  * prot is passed in as a parameter for the new mapping. If the vma has
+  * a linear pfn mapping for the entire range, or no vma is provided,
+@@ -1095,15 +1108,6 @@ void untrack_pfn(struct vm_area_struct *vma, unsigned long pfn,
+       }
+ }
+-/*
+- * untrack_pfn_clear is called if the following situation fits:
+- *
+- * 1) while mremapping a pfnmap for a new region,  with the old vma after
+- * its pfnmap page table has been removed.  The new vma has a new pfnmap
+- * to the same pfn & cache type with VM_PAT set.
+- * 2) while duplicating vm area, the new vma fails to copy the pgtable from
+- * old vma.
+- */
+ void untrack_pfn_clear(struct vm_area_struct *vma)
+ {
+       vm_flags_clear(vma, VM_PAT);
+diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
+index 94d267d02372e..4c107e17c547e 100644
+--- a/include/linux/pgtable.h
++++ b/include/linux/pgtable.h
+@@ -1508,14 +1508,25 @@ static inline void track_pfn_insert(struct vm_area_struct *vma, pgprot_t *prot,
+ }
+ /*
+- * track_pfn_copy is called when vma that is covering the pfnmap gets
+- * copied through copy_page_range().
++ * track_pfn_copy is called when a VM_PFNMAP VMA is about to get the page
++ * tables copied during copy_page_range(). On success, stores the pfn to be
++ * passed to untrack_pfn_copy().
+  */
+-static inline int track_pfn_copy(struct vm_area_struct *vma)
++static inline int track_pfn_copy(struct vm_area_struct *dst_vma,
++              struct vm_area_struct *src_vma, unsigned long *pfn)
+ {
+       return 0;
+ }
++/*
++ * untrack_pfn_copy is called when a VM_PFNMAP VMA failed to copy during
++ * copy_page_range(), but after track_pfn_copy() was already called.
++ */
++static inline void untrack_pfn_copy(struct vm_area_struct *dst_vma,
++              unsigned long pfn)
++{
++}
++
+ /*
+  * untrack_pfn is called while unmapping a pfnmap for a region.
+  * untrack can be called for a specific region indicated by pfn and size or
+@@ -1528,8 +1539,10 @@ static inline void untrack_pfn(struct vm_area_struct *vma,
+ }
+ /*
+- * untrack_pfn_clear is called while mremapping a pfnmap for a new region
+- * or fails to copy pgtable during duplicate vm area.
++ * untrack_pfn_clear is called in the following cases on a VM_PFNMAP VMA:
++ *
++ * 1) During mremap() on the src VMA after the page tables were moved.
++ * 2) During fork() on the dst VMA, immediately after duplicating the src VMA.
+  */
+ static inline void untrack_pfn_clear(struct vm_area_struct *vma)
+ {
+@@ -1540,7 +1553,10 @@ extern int track_pfn_remap(struct vm_area_struct *vma, pgprot_t *prot,
+                          unsigned long size);
+ extern void track_pfn_insert(struct vm_area_struct *vma, pgprot_t *prot,
+                            pfn_t pfn);
+-extern int track_pfn_copy(struct vm_area_struct *vma);
++extern int track_pfn_copy(struct vm_area_struct *dst_vma,
++              struct vm_area_struct *src_vma, unsigned long *pfn);
++extern void untrack_pfn_copy(struct vm_area_struct *dst_vma,
++              unsigned long pfn);
+ extern void untrack_pfn(struct vm_area_struct *vma, unsigned long pfn,
+                       unsigned long size, bool mm_wr_locked);
+ extern void untrack_pfn_clear(struct vm_area_struct *vma);
+diff --git a/kernel/fork.c b/kernel/fork.c
+index 735405a9c5f32..ca2ca3884f763 100644
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -504,6 +504,10 @@ struct vm_area_struct *vm_area_dup(struct vm_area_struct *orig)
+       vma_numab_state_init(new);
+       dup_anon_vma_name(orig, new);
++      /* track_pfn_copy() will later take care of copying internal state. */
++      if (unlikely(new->vm_flags & VM_PFNMAP))
++              untrack_pfn_clear(new);
++
+       return new;
+ }
+diff --git a/mm/memory.c b/mm/memory.c
+index 4f6d9766a0460..53f7b0aaf2a33 100644
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -1362,12 +1362,12 @@ int
+ copy_page_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma)
+ {
+       pgd_t *src_pgd, *dst_pgd;
+-      unsigned long next;
+       unsigned long addr = src_vma->vm_start;
+       unsigned long end = src_vma->vm_end;
+       struct mm_struct *dst_mm = dst_vma->vm_mm;
+       struct mm_struct *src_mm = src_vma->vm_mm;
+       struct mmu_notifier_range range;
++      unsigned long next, pfn;
+       bool is_cow;
+       int ret;
+@@ -1378,11 +1378,7 @@ copy_page_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma)
+               return copy_hugetlb_page_range(dst_mm, src_mm, dst_vma, src_vma);
+       if (unlikely(src_vma->vm_flags & VM_PFNMAP)) {
+-              /*
+-               * We do not free on error cases below as remove_vma
+-               * gets called on error from higher level routine
+-               */
+-              ret = track_pfn_copy(src_vma);
++              ret = track_pfn_copy(dst_vma, src_vma, &pfn);
+               if (ret)
+                       return ret;
+       }
+@@ -1419,7 +1415,6 @@ copy_page_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma)
+                       continue;
+               if (unlikely(copy_p4d_range(dst_vma, src_vma, dst_pgd, src_pgd,
+                                           addr, next))) {
+-                      untrack_pfn_clear(dst_vma);
+                       ret = -ENOMEM;
+                       break;
+               }
+@@ -1429,6 +1424,8 @@ copy_page_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma)
+               raw_write_seqcount_end(&src_mm->write_protect_seq);
+               mmu_notifier_invalidate_range_end(&range);
+       }
++      if (ret && unlikely(src_vma->vm_flags & VM_PFNMAP))
++              untrack_pfn_copy(dst_vma, pfn);
+       return ret;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/x86-platform-only-allow-config_eisa-for-32-bit.patch b/queue-6.14/x86-platform-only-allow-config_eisa-for-32-bit.patch
new file mode 100644 (file)
index 0000000..5d5ee3e
--- /dev/null
@@ -0,0 +1,43 @@
+From 1d98659d75e6e285ceab4b01020d3a5e8dd3ff4f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Feb 2025 22:37:14 +0100
+Subject: x86/platform: Only allow CONFIG_EISA for 32-bit
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 976ba8da2f3c2f1e997f4f620da83ae65c0e3728 ]
+
+The CONFIG_EISA menu was cleaned up in 2018, but this inadvertently
+brought the option back on 64-bit machines: ISA remains guarded by
+a CONFIG_X86_32 check, but EISA no longer depends on ISA.
+
+The last Intel machines ith EISA support used a 82375EB PCI/EISA bridge
+from 1993 that could be paired with the 440FX chipset on early Pentium-II
+CPUs, long before the first x86-64 products.
+
+Fixes: 6630a8e50105 ("eisa: consolidate EISA Kconfig entry in drivers/eisa")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Link: https://lore.kernel.org/r/20250226213714.4040853-11-arnd@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
+index 0e27ebd7e36a9..cf79f973023f1 100644
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -232,7 +232,7 @@ config X86
+       select HAVE_SAMPLE_FTRACE_DIRECT_MULTI  if X86_64
+       select HAVE_EBPF_JIT
+       select HAVE_EFFICIENT_UNALIGNED_ACCESS
+-      select HAVE_EISA
++      select HAVE_EISA                        if X86_32
+       select HAVE_EXIT_THREAD
+       select HAVE_GUP_FAST
+       select HAVE_FENTRY                      if X86_64 || DYNAMIC_FTRACE
+-- 
+2.39.5
+
diff --git a/queue-6.14/x86-resctrl-fix-allocation-of-cleanest-closid-on-pla.patch b/queue-6.14/x86-resctrl-fix-allocation-of-cleanest-closid-on-pla.patch
new file mode 100644 (file)
index 0000000..89c7585
--- /dev/null
@@ -0,0 +1,67 @@
+From 5c8b87d5317571159872b4315996206bf807b271 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Mar 2025 18:36:46 +0000
+Subject: x86/resctrl: Fix allocation of cleanest CLOSID on platforms with no
+ monitors
+
+From: James Morse <james.morse@arm.com>
+
+[ Upstream commit a121798ae669351ec0697c94f71c3a692b2a755b ]
+
+Commit
+
+  6eac36bb9eb0 ("x86/resctrl: Allocate the cleanest CLOSID by searching closid_num_dirty_rmid")
+
+added logic that causes resctrl to search for the CLOSID with the fewest dirty
+cache lines when creating a new control group, if requested by the arch code.
+This depends on the values read from the llc_occupancy counters. The logic is
+applicable to architectures where the CLOSID effectively forms part of the
+monitoring identifier and so do not allow complete freedom to choose an unused
+monitoring identifier for a given CLOSID.
+
+This support missed that some platforms may not have these counters.  This
+causes a NULL pointer dereference when creating a new control group as the
+array was not allocated by dom_data_init().
+
+As this feature isn't necessary on platforms that don't have cache occupancy
+monitors, add this to the check that occurs when a new control group is
+allocated.
+
+Fixes: 6eac36bb9eb0 ("x86/resctrl: Allocate the cleanest CLOSID by searching closid_num_dirty_rmid")
+Signed-off-by: James Morse <james.morse@arm.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Reviewed-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
+Reviewed-by: Tony Luck <tony.luck@intel.com>
+Reviewed-by: Fenghua Yu <fenghuay@nvidia.com>
+Reviewed-by: Babu Moger <babu.moger@amd.com>
+Tested-by: Carl Worth <carl@os.amperecomputing.com> # arm64
+Tested-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com>
+Tested-by: Peter Newman <peternewman@google.com>
+Tested-by: Amit Singh Tomar <amitsinght@marvell.com> # arm64
+Tested-by: Shanker Donthineni <sdonthineni@nvidia.com> # arm64
+Tested-by: Babu Moger <babu.moger@amd.com>
+Link: https://lore.kernel.org/r/20250311183715.16445-2-james.morse@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/cpu/resctrl/rdtgroup.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/resctrl/rdtgroup.c
+index 6419e04d8a7b2..04b653d613e88 100644
+--- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c
++++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c
+@@ -157,7 +157,8 @@ static int closid_alloc(void)
+       lockdep_assert_held(&rdtgroup_mutex);
+-      if (IS_ENABLED(CONFIG_RESCTRL_RMID_DEPENDS_ON_CLOSID)) {
++      if (IS_ENABLED(CONFIG_RESCTRL_RMID_DEPENDS_ON_CLOSID) &&
++          is_llc_occupancy_enabled()) {
+               cleanest_closid = resctrl_find_cleanest_closid();
+               if (cleanest_closid < 0)
+                       return cleanest_closid;
+-- 
+2.39.5
+
diff --git a/queue-6.14/x86-sev-add-missing-rip_rel_ref-invocations-during-s.patch b/queue-6.14/x86-sev-add-missing-rip_rel_ref-invocations-during-s.patch
new file mode 100644 (file)
index 0000000..eed5b56
--- /dev/null
@@ -0,0 +1,52 @@
+From c1a8403bb7e98c7e05818dd490d31fa61fe7c183 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Nov 2024 20:23:22 +0000
+Subject: x86/sev: Add missing RIP_REL_REF() invocations during sme_enable()
+
+From: Kevin Loughlin <kevinloughlin@google.com>
+
+[ Upstream commit 72dafb567760320f2de7447cd6e979bf9d4e5d17 ]
+
+The following commit:
+
+  1c811d403afd ("x86/sev: Fix position dependent variable references in startup code")
+
+introduced RIP_REL_REF() to force RIP-relative accesses to global variables,
+as needed to prevent crashes during early SEV/SME startup code.
+
+For completeness, RIP_REL_REF() should be used with additional variables during
+sme_enable():
+
+  https://lore.kernel.org/all/CAMj1kXHnA0fJu6zh634=fbJswp59kSRAbhW+ubDGj1+NYwZJ-Q@mail.gmail.com/
+
+Access these vars with RIP_REL_REF() to prevent problem reoccurence.
+
+Fixes: 1c811d403afd ("x86/sev: Fix position dependent variable references in startup code")
+Signed-off-by: Kevin Loughlin <kevinloughlin@google.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
+Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
+Cc: Dave Hansen <dave.hansen@linux.intel.com>
+Link: https://lore.kernel.org/r/20241122202322.977678-1-kevinloughlin@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/mm/mem_encrypt_identity.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/x86/mm/mem_encrypt_identity.c b/arch/x86/mm/mem_encrypt_identity.c
+index e6c7686f443a0..9fce5b87b8c50 100644
+--- a/arch/x86/mm/mem_encrypt_identity.c
++++ b/arch/x86/mm/mem_encrypt_identity.c
+@@ -565,7 +565,7 @@ void __head sme_enable(struct boot_params *bp)
+       }
+       RIP_REL_REF(sme_me_mask) = me_mask;
+-      physical_mask &= ~me_mask;
+-      cc_vendor = CC_VENDOR_AMD;
++      RIP_REL_REF(physical_mask) &= ~me_mask;
++      RIP_REL_REF(cc_vendor) = CC_VENDOR_AMD;
+       cc_set_mask(me_mask);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/x86-split_lock-fix-the-delayed-detection-logic.patch b/queue-6.14/x86-split_lock-fix-the-delayed-detection-logic.patch
new file mode 100644 (file)
index 0000000..e4e2920
--- /dev/null
@@ -0,0 +1,161 @@
+From 0f37747df0229dffbd0a837fcf76e6a1ee89d935 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jan 2025 16:17:04 +0300
+Subject: x86/split_lock: Fix the delayed detection logic
+
+From: Maksim Davydov <davydov-max@yandex-team.ru>
+
+[ Upstream commit c929d08df8bee855528b9d15b853c892c54e1eee ]
+
+If the warning mode with disabled mitigation mode is used, then on each
+CPU where the split lock occurred detection will be disabled in order to
+make progress and delayed work will be scheduled, which then will enable
+detection back.
+
+Now it turns out that all CPUs use one global delayed work structure.
+This leads to the fact that if a split lock occurs on several CPUs
+at the same time (within 2 jiffies), only one CPU will schedule delayed
+work, but the rest will not.
+
+The return value of schedule_delayed_work_on() would have shown this,
+but it is not checked in the code.
+
+A diagram that can help to understand the bug reproduction:
+
+ - sld_update_msr() enables/disables SLD on both CPUs on the same core
+
+ - schedule_delayed_work_on() internally checks WORK_STRUCT_PENDING_BIT.
+   If a work has the 'pending' status, then schedule_delayed_work_on()
+   will return an error code and, most importantly, the work will not
+   be placed in the workqueue.
+
+Let's say we have a multicore system on which split_lock_mitigate=0 and
+a multithreaded application is running that calls splitlock in multiple
+threads. Due to the fact that sld_update_msr() affects the entire core
+(both CPUs), we will consider 2 CPUs from different cores. Let the 2
+threads of this application schedule to CPU0 (core 0) and to CPU 2
+(core 1), then:
+
+|                                 ||                                   |
+|             CPU 0 (core 0)      ||          CPU 2 (core 1)           |
+|_________________________________||___________________________________|
+|                                 ||                                   |
+| 1) SPLIT LOCK occured           ||                                   |
+|                                 ||                                   |
+| 2) split_lock_warn()            ||                                   |
+|                                 ||                                   |
+| 3) sysctl_sld_mitigate == 0     ||                                   |
+|    (work = &sl_reenable)        ||                                   |
+|                                 ||                                   |
+| 4) schedule_delayed_work_on()   ||                                   |
+|    (reenable will be called     ||                                   |
+|     after 2 jiffies on CPU 0)   ||                                   |
+|                                 ||                                   |
+| 5) disable SLD for core 0       ||                                   |
+|                                 ||                                   |
+|    -------------------------    ||                                   |
+|                                 ||                                   |
+|                                 || 6) SPLIT LOCK occured             |
+|                                 ||                                   |
+|                                 || 7) split_lock_warn()              |
+|                                 ||                                   |
+|                                 || 8) sysctl_sld_mitigate == 0       |
+|                                 ||    (work = &sl_reenable,          |
+|                                 ||     the same address as in 3) )   |
+|                                 ||                                   |
+|            2 jiffies            || 9) schedule_delayed_work_on()     |
+|                                 ||    fials because the work is in   |
+|                                 ||    the pending state since 4).    |
+|                                 ||    The work wasn't placed to the  |
+|                                 ||    workqueue. reenable won't be   |
+|                                 ||    called on CPU 2                |
+|                                 ||                                   |
+|                                 || 10) disable SLD for core 0        |
+|                                 ||                                   |
+|                                 ||     From now on SLD will          |
+|                                 ||     never be reenabled on core 1  |
+|                                 ||                                   |
+|    -------------------------    ||                                   |
+|                                 ||                                   |
+|    11) enable SLD for core 0 by ||                                   |
+|        __split_lock_reenable    ||                                   |
+|                                 ||                                   |
+
+If the application threads can be scheduled to all processor cores,
+then over time there will be only one core left, on which SLD will be
+enabled and split lock will be able to be detected; and on all other
+cores SLD will be disabled all the time.
+
+Most likely, this bug has not been noticed for so long because
+sysctl_sld_mitigate default value is 1, and in this case a semaphore
+is used that does not allow 2 different cores to have SLD disabled at
+the same time, that is, strictly only one work is placed in the
+workqueue.
+
+In order to fix the warning mode with disabled mitigation mode,
+delayed work has to be per-CPU. Implement it.
+
+Fixes: 727209376f49 ("x86/split_lock: Add sysctl to control the misery mode")
+Signed-off-by: Maksim Davydov <davydov-max@yandex-team.ru>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Tested-by: Guilherme G. Piccoli <gpiccoli@igalia.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Ravi Bangoria <ravi.bangoria@amd.com>
+Cc: Tom Lendacky <thomas.lendacky@amd.com>
+Link: https://lore.kernel.org/r/20250115131704.132609-1-davydov-max@yandex-team.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/cpu/bus_lock.c | 20 ++++++++++++++++----
+ 1 file changed, 16 insertions(+), 4 deletions(-)
+
+diff --git a/arch/x86/kernel/cpu/bus_lock.c b/arch/x86/kernel/cpu/bus_lock.c
+index 6cba85c79d42d..97222efb4d2a6 100644
+--- a/arch/x86/kernel/cpu/bus_lock.c
++++ b/arch/x86/kernel/cpu/bus_lock.c
+@@ -192,7 +192,13 @@ static void __split_lock_reenable(struct work_struct *work)
+ {
+       sld_update_msr(true);
+ }
+-static DECLARE_DELAYED_WORK(sl_reenable, __split_lock_reenable);
++/*
++ * In order for each CPU to schedule its delayed work independently of the
++ * others, delayed work struct must be per-CPU. This is not required when
++ * sysctl_sld_mitigate is enabled because of the semaphore that limits
++ * the number of simultaneously scheduled delayed works to 1.
++ */
++static DEFINE_PER_CPU(struct delayed_work, sl_reenable);
+ /*
+  * If a CPU goes offline with pending delayed work to re-enable split lock
+@@ -213,7 +219,7 @@ static int splitlock_cpu_offline(unsigned int cpu)
+ static void split_lock_warn(unsigned long ip)
+ {
+-      struct delayed_work *work;
++      struct delayed_work *work = NULL;
+       int cpu;
+       if (!current->reported_split_lock)
+@@ -235,11 +241,17 @@ static void split_lock_warn(unsigned long ip)
+               if (down_interruptible(&buslock_sem) == -EINTR)
+                       return;
+               work = &sl_reenable_unlock;
+-      } else {
+-              work = &sl_reenable;
+       }
+       cpu = get_cpu();
++
++      if (!work) {
++              work = this_cpu_ptr(&sl_reenable);
++              /* Deferred initialization of per-CPU struct */
++              if (!work->work.func)
++                      INIT_DELAYED_WORK(work, __split_lock_reenable);
++      }
++
+       schedule_delayed_work_on(cpu, work, 2);
+       /* Disable split lock detection on this CPU to make progress */
+-- 
+2.39.5
+
diff --git a/queue-6.14/x86-traps-make-exc_double_fault-consistently-noretur.patch b/queue-6.14/x86-traps-make-exc_double_fault-consistently-noretur.patch
new file mode 100644 (file)
index 0000000..c639c8f
--- /dev/null
@@ -0,0 +1,127 @@
+From c78c9a37a59b47ffe3c2e5d446ef927ed7ba2f6b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Mar 2025 12:28:59 -0700
+Subject: x86/traps: Make exc_double_fault() consistently noreturn
+
+From: Josh Poimboeuf <jpoimboe@kernel.org>
+
+[ Upstream commit 8085fcd78c1a3dbdf2278732579009d41ce0bc4e ]
+
+The CONFIG_X86_ESPFIX64 version of exc_double_fault() can return to its
+caller, but the !CONFIG_X86_ESPFIX64 version never does.  In the latter
+case the compiler and/or objtool may consider it to be implicitly
+noreturn.
+
+However, due to the currently inflexible way objtool detects noreturns,
+a function's noreturn status needs to be consistent across configs.
+
+The current workaround for this issue is to suppress unreachable
+warnings for exc_double_fault()'s callers.  Unfortunately that can
+result in ORC coverage gaps and potentially worse issues like inert
+static calls and silently disabled CPU mitigations.
+
+Instead, prevent exc_double_fault() from ever being implicitly marked
+noreturn by forcing a return behind a never-taken conditional.
+
+Until a more integrated noreturn detection method exists, this is likely
+the least objectionable workaround.
+
+Fixes: 55eeab2a8a11 ("objtool: Ignore exc_double_fault() __noreturn warnings")
+Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Brendan Jackman <jackmanb@google.com>
+Link: https://lore.kernel.org/r/d1f4026f8dc35d0de6cc61f2684e0cb6484009d1.1741975349.git.jpoimboe@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/traps.c | 18 +++++++++++++++++-
+ tools/objtool/check.c   | 31 +------------------------------
+ 2 files changed, 18 insertions(+), 31 deletions(-)
+
+diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
+index 2dbadf347b5f4..5e3e036e6e537 100644
+--- a/arch/x86/kernel/traps.c
++++ b/arch/x86/kernel/traps.c
+@@ -379,6 +379,21 @@ __visible void __noreturn handle_stack_overflow(struct pt_regs *regs,
+ }
+ #endif
++/*
++ * Prevent the compiler and/or objtool from marking the !CONFIG_X86_ESPFIX64
++ * version of exc_double_fault() as noreturn.  Otherwise the noreturn mismatch
++ * between configs triggers objtool warnings.
++ *
++ * This is a temporary hack until we have compiler or plugin support for
++ * annotating noreturns.
++ */
++#ifdef CONFIG_X86_ESPFIX64
++#define always_true() true
++#else
++bool always_true(void);
++bool __weak always_true(void) { return true; }
++#endif
++
+ /*
+  * Runs on an IST stack for x86_64 and on a special task stack for x86_32.
+  *
+@@ -514,7 +529,8 @@ DEFINE_IDTENTRY_DF(exc_double_fault)
+       pr_emerg("PANIC: double fault, error_code: 0x%lx\n", error_code);
+       die("double fault", regs, error_code);
+-      panic("Machine halted.");
++      if (always_true())
++              panic("Machine halted.");
+       instrumentation_end();
+ }
+diff --git a/tools/objtool/check.c b/tools/objtool/check.c
+index ce973d9d8e6d8..c1fa0220f33de 100644
+--- a/tools/objtool/check.c
++++ b/tools/objtool/check.c
+@@ -4449,35 +4449,6 @@ static int validate_sls(struct objtool_file *file)
+       return warnings;
+ }
+-static bool ignore_noreturn_call(struct instruction *insn)
+-{
+-      struct symbol *call_dest = insn_call_dest(insn);
+-
+-      /*
+-       * FIXME: hack, we need a real noreturn solution
+-       *
+-       * Problem is, exc_double_fault() may or may not return, depending on
+-       * whether CONFIG_X86_ESPFIX64 is set.  But objtool has no visibility
+-       * to the kernel config.
+-       *
+-       * Other potential ways to fix it:
+-       *
+-       *   - have compiler communicate __noreturn functions somehow
+-       *   - remove CONFIG_X86_ESPFIX64
+-       *   - read the .config file
+-       *   - add a cmdline option
+-       *   - create a generic objtool annotation format (vs a bunch of custom
+-       *     formats) and annotate it
+-       */
+-      if (!strcmp(call_dest->name, "exc_double_fault")) {
+-              /* prevent further unreachable warnings for the caller */
+-              insn->sym->warned = 1;
+-              return true;
+-      }
+-
+-      return false;
+-}
+-
+ static int validate_reachable_instructions(struct objtool_file *file)
+ {
+       struct instruction *insn, *prev_insn;
+@@ -4494,7 +4465,7 @@ static int validate_reachable_instructions(struct objtool_file *file)
+               prev_insn = prev_insn_same_sec(file, insn);
+               if (prev_insn && prev_insn->dead_end) {
+                       call_dest = insn_call_dest(prev_insn);
+-                      if (call_dest && !ignore_noreturn_call(prev_insn)) {
++                      if (call_dest) {
+                               WARN_INSN(insn, "%s() is missing a __noreturn annotation",
+                                         call_dest->name);
+                               warnings++;
+-- 
+2.39.5
+
diff --git a/queue-6.14/x86-uaccess-improve-performance-by-aligning-writes-t.patch b/queue-6.14/x86-uaccess-improve-performance-by-aligning-writes-t.patch
new file mode 100644 (file)
index 0000000..c845cdc
--- /dev/null
@@ -0,0 +1,190 @@
+From de70e543d840bd87c2abdfdbbb81f9f3c8b07790 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Mar 2025 11:22:13 -0300
+Subject: x86/uaccess: Improve performance by aligning writes to 8 bytes in
+ copy_user_generic(), on non-FSRM/ERMS CPUs
+
+From: Herton R. Krzesinski <herton@redhat.com>
+
+[ Upstream commit b5322b6ec06a6c58650f52abcd2492000396363b ]
+
+History of the performance regression:
+======================================
+
+Since the following series of user copy updates were merged upstream
+~2 years ago via:
+
+  a5624566431d ("Merge branch 'x86-rep-insns': x86 user copy clarifications")
+
+.. copy_user_generic() on x86_64 stopped doing alignment of the
+writes to the destination to a 8 byte boundary for the non FSRM case.
+
+Previously, this was done through the ALIGN_DESTINATION macro that
+was used in the now removed copy_user_generic_unrolled function.
+
+Turns out this change causes some loss of performance/throughput on
+some use cases and specific CPU/platforms without FSRM and ERMS.
+
+Lately I got two reports of performance/throughput issues after a
+RHEL 9 kernel pulled the same upstream series with updates to user
+copy functions. Both reports consisted of running specific
+networking/TCP related testing using iperf3.
+
+Partial upstream fix
+====================
+
+The first report was related to a Linux Bridge testing using VMs on a
+specific machine with an AMD CPU (EPYC 7402), and after a brief
+investigation it turned out that the later change via:
+
+  ca96b162bfd2 ("x86: bring back rep movsq for user access on CPUs without ERMS")
+
+... helped/fixed the performance issue.
+
+However, after the later commit/fix was applied, then I got another
+regression reported in a multistream TCP test on a 100Gbit mlx5 nic, also
+running on an AMD based platform (AMD EPYC 7302 CPU), again that was using
+iperf3 to run the test. That regression was after applying the later
+fix/commit, but only this didn't help in telling the whole history.
+
+Testing performed to pinpoint residual regression
+=================================================
+
+So I narrowed down the second regression use case, but running it
+without traffic through a NIC, on localhost, in trying to narrow down
+CPU usage and not being limited by other factor like network bandwidth.
+I used another system also with an AMD CPU (AMD EPYC 7742). Basically,
+I run iperf3 in server and client mode in the same system, for example:
+
+ - Start the server binding it to CPU core/thread 19:
+   $ taskset -c 19 iperf3 -D -s -B 127.0.0.1 -p 12000
+
+ - Start the client always binding/running on CPU core/thread 17, using
+   perf to get statistics:
+   $ perf stat -o stat.txt taskset -c 17 iperf3 -c 127.0.0.1 -b 0/1000 -V \
+       -n 50G --repeating-payload -l 16384 -p 12000 --cport 12001 2>&1 \
+       > stat-19.txt
+
+For the client, always running/pinned to CPU 17. But for the iperf3 in
+server mode, I did test runs using CPUs 19, 21, 23 or not pinned to any
+specific CPU. So it basically consisted with four runs of the same
+commands, just changing the CPU which the server is pinned, or without
+pinning by removing the taskset call before the server command. The CPUs
+were chosen based on NUMA node they were on, this is the relevant output
+of lscpu on the system:
+
+  $ lscpu
+  ...
+    Model name:             AMD EPYC 7742 64-Core Processor
+  ...
+  Caches (sum of all):
+    L1d:                    2 MiB (64 instances)
+    L1i:                    2 MiB (64 instances)
+    L2:                     32 MiB (64 instances)
+    L3:                     256 MiB (16 instances)
+  NUMA:
+    NUMA node(s):           4
+    NUMA node0 CPU(s):      0,1,8,9,16,17,24,25,32,33,40,41,48,49,56,57,64,65,72,73,80,81,88,89,96,97,104,105,112,113,120,121
+    NUMA node1 CPU(s):      2,3,10,11,18,19,26,27,34,35,42,43,50,51,58,59,66,67,74,75,82,83,90,91,98,99,106,107,114,115,122,123
+    NUMA node2 CPU(s):      4,5,12,13,20,21,28,29,36,37,44,45,52,53,60,61,68,69,76,77,84,85,92,93,100,101,108,109,116,117,124,125
+    NUMA node3 CPU(s):      6,7,14,15,22,23,30,31,38,39,46,47,54,55,62,63,70,71,78,79,86,87,94,95,102,103,110,111,118,119,126,127
+  ...
+
+So for the server run, when picking a CPU, I chose CPUs to be not on the same
+node. The reason is with that I was able to get/measure relevant
+performance differences when changing the alignment of the writes to the
+destination in copy_user_generic.
+
+Testing shows up to +81% performance improvement under iperf3
+=============================================================
+
+Here's a summary of the iperf3 runs:
+
+  # Vanilla upstream alignment:
+
+                    CPU      RATE          SYS          TIME     sender-receiver
+       Server bind   19: 13.0Gbits/sec 28.371851000 33.233499566 86.9%-70.8%
+       Server bind   21: 12.9Gbits/sec 28.283381000 33.586486621 85.8%-69.9%
+       Server bind   23: 11.1Gbits/sec 33.660190000 39.012243176 87.7%-64.5%
+       Server bind none: 18.9Gbits/sec 19.215339000 22.875117865 86.0%-80.5%
+
+  # With the attached patch (aligning writes in non ERMS/FSRM case):
+
+                    CPU      RATE          SYS          TIME     sender-receiver
+       Server bind   19: 20.8Gbits/sec 14.897284000 20.811101382 75.7%-89.0%
+       Server bind   21: 20.4Gbits/sec 15.205055000 21.263165909 75.4%-89.7%
+       Server bind   23: 20.2Gbits/sec 15.433801000 21.456175000 75.5%-89.8%
+       Server bind none: 26.1Gbits/sec 12.534022000 16.632447315 79.8%-89.6%
+
+So I consistently got better results when aligning the write. The
+results above were run on 6.14.0-rc6/rc7 based kernels. The sys is sys
+time and then the total time to run/transfer 50G of data. The last
+field is the CPU usage of sender/receiver iperf3 process. It's also
+worth to note that each pair of iperf3 runs may get slightly different
+results on each run, but I always got consistent higher results with
+the write alignment for this specific test of running the processes
+on CPUs in different NUMA nodes.
+
+Linus Torvalds helped/provided this version of the patch. Initially I
+proposed a version which aligned writes for all cases in
+rep_movs_alternative, however it used two extra registers and thus
+Linus provided an enhanced version that only aligns the write on the
+large_movsq case, which is sufficient since the problem happens only
+on those AMD CPUs like ones mentioned above without ERMS/FSRM, and
+also doesn't require using extra registers. Also, I validated that
+aligning only on large_movsq case is really enough for getting the
+performance back.
+
+I also tested this patch on an old Intel based non-ERMS/FRMS system
+(with Xeon E5-2667 - Sandy Bridge based) and didn't get any problems:
+no performance enhancement but also no regression either, using the
+same iperf3 based benchmark. Also newer Intel processors after
+Sandy Bridge usually have ERMS and should not be affected by this change.
+
+[ mingo: Updated the changelog. ]
+
+Fixes: ca96b162bfd2 ("x86: bring back rep movsq for user access on CPUs without ERMS")
+Fixes: 034ff37d3407 ("x86: rewrite '__copy_user_nocache' function")
+Reported-by: Ondrej Lichtner <olichtne@redhat.com>
+Co-developed-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Herton R. Krzesinski <herton@redhat.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Link: https://lore.kernel.org/r/20250320142213.2623518-1-herton@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/lib/copy_user_64.S | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/arch/x86/lib/copy_user_64.S b/arch/x86/lib/copy_user_64.S
+index fc9fb5d061744..b8f74d80f35c6 100644
+--- a/arch/x86/lib/copy_user_64.S
++++ b/arch/x86/lib/copy_user_64.S
+@@ -74,6 +74,24 @@ SYM_FUNC_START(rep_movs_alternative)
+       _ASM_EXTABLE_UA( 0b, 1b)
+ .Llarge_movsq:
++      /* Do the first possibly unaligned word */
++0:    movq (%rsi),%rax
++1:    movq %rax,(%rdi)
++
++      _ASM_EXTABLE_UA( 0b, .Lcopy_user_tail)
++      _ASM_EXTABLE_UA( 1b, .Lcopy_user_tail)
++
++      /* What would be the offset to the aligned destination? */
++      leaq 8(%rdi),%rax
++      andq $-8,%rax
++      subq %rdi,%rax
++
++      /* .. and update pointers and count to match */
++      addq %rax,%rdi
++      addq %rax,%rsi
++      subq %rax,%rcx
++
++      /* make %rcx contain the number of words, %rax the remainder */
+       movq %rcx,%rax
+       shrq $3,%rcx
+       andl $7,%eax
+-- 
+2.39.5
+
diff --git a/queue-6.14/x86-vdso-fix-latent-bug-in-vclock_pages-calculation.patch b/queue-6.14/x86-vdso-fix-latent-bug-in-vclock_pages-calculation.patch
new file mode 100644 (file)
index 0000000..d72220a
--- /dev/null
@@ -0,0 +1,73 @@
+From 701d8e123ed4a266653cbb14a8b1d2abcc63b5be Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Feb 2025 13:05:33 +0100
+Subject: x86/vdso: Fix latent bug in vclock_pages calculation
+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 3ef32d90cdaa0cfa6c4ffd18f8d646a658163e3d ]
+
+The vclock pages are *after* the non-vclock pages. Currently there are both
+two vclock and two non-vclock pages so the existing logic works by
+accident.  As soon as the number of pages changes it will break however.
+This will be the case with the introduction of the generic vDSO data
+storage.
+
+Use a macro to keep the calculation understandable and in sync between
+the linker script and mapping code.
+
+Fixes: e93d2521b27f ("x86/vdso: Split virtual clock pages into dedicated mapping")
+Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Link: https://lore.kernel.org/all/20250204-vdso-store-rng-v3-1-13a4669dfc8c@linutronix.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/entry/vdso/vdso-layout.lds.S | 2 +-
+ arch/x86/entry/vdso/vma.c             | 2 +-
+ arch/x86/include/asm/vdso/vsyscall.h  | 1 +
+ 3 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/arch/x86/entry/vdso/vdso-layout.lds.S b/arch/x86/entry/vdso/vdso-layout.lds.S
+index 872947c1004c3..918606ff92a98 100644
+--- a/arch/x86/entry/vdso/vdso-layout.lds.S
++++ b/arch/x86/entry/vdso/vdso-layout.lds.S
+@@ -24,7 +24,7 @@ SECTIONS
+       timens_page  = vvar_start + PAGE_SIZE;
+-      vclock_pages = vvar_start + VDSO_NR_VCLOCK_PAGES * PAGE_SIZE;
++      vclock_pages = VDSO_VCLOCK_PAGES_START(vvar_start);
+       pvclock_page = vclock_pages + VDSO_PAGE_PVCLOCK_OFFSET * PAGE_SIZE;
+       hvclock_page = vclock_pages + VDSO_PAGE_HVCLOCK_OFFSET * PAGE_SIZE;
+diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c
+index 39e6efc1a9cab..aa62949335ece 100644
+--- a/arch/x86/entry/vdso/vma.c
++++ b/arch/x86/entry/vdso/vma.c
+@@ -290,7 +290,7 @@ static int map_vdso(const struct vdso_image *image, unsigned long addr)
+       }
+       vma = _install_special_mapping(mm,
+-                                     addr + (__VVAR_PAGES - VDSO_NR_VCLOCK_PAGES) * PAGE_SIZE,
++                                     VDSO_VCLOCK_PAGES_START(addr),
+                                      VDSO_NR_VCLOCK_PAGES * PAGE_SIZE,
+                                      VM_READ|VM_MAYREAD|VM_IO|VM_DONTDUMP|
+                                      VM_PFNMAP,
+diff --git a/arch/x86/include/asm/vdso/vsyscall.h b/arch/x86/include/asm/vdso/vsyscall.h
+index 37b4a70559a82..88b31d4cdfaf3 100644
+--- a/arch/x86/include/asm/vdso/vsyscall.h
++++ b/arch/x86/include/asm/vdso/vsyscall.h
+@@ -6,6 +6,7 @@
+ #define __VVAR_PAGES  4
+ #define VDSO_NR_VCLOCK_PAGES  2
++#define VDSO_VCLOCK_PAGES_START(_b)   ((_b) + (__VVAR_PAGES - VDSO_NR_VCLOCK_PAGES) * PAGE_SIZE)
+ #define VDSO_PAGE_PVCLOCK_OFFSET      0
+ #define VDSO_PAGE_HVCLOCK_OFFSET      1
+-- 
+2.39.5
+
diff --git a/queue-6.14/xfrm-delay-initialization-of-offload-path-till-its-a.patch b/queue-6.14/xfrm-delay-initialization-of-offload-path-till-its-a.patch
new file mode 100644 (file)
index 0000000..acbb074
--- /dev/null
@@ -0,0 +1,205 @@
+From 16b6be5eea74dfb291653ad3b16187f1cafde7ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Feb 2025 15:50:57 +0200
+Subject: xfrm: delay initialization of offload path till its actually
+ requested
+
+From: Leon Romanovsky <leonro@nvidia.com>
+
+[ Upstream commit 585b64f5a62089ef42889b106b063d089feb6599 ]
+
+XFRM offload path is probed even if offload isn't needed at all. Let's
+make sure that x->type_offload pointer stays NULL for such path to
+reduce ambiguity.
+
+Fixes: 9d389d7f84bb ("xfrm: Add a xfrm type offload.")
+Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/xfrm.h     | 11 ++++++++++-
+ net/xfrm/xfrm_device.c | 13 ++++++++-----
+ net/xfrm/xfrm_state.c  | 32 ++++++++++++++------------------
+ net/xfrm/xfrm_user.c   |  2 +-
+ 4 files changed, 33 insertions(+), 25 deletions(-)
+
+diff --git a/include/net/xfrm.h b/include/net/xfrm.h
+index ed4b83696c77f..e1eed5d47d072 100644
+--- a/include/net/xfrm.h
++++ b/include/net/xfrm.h
+@@ -464,6 +464,15 @@ struct xfrm_type_offload {
+ int xfrm_register_type_offload(const struct xfrm_type_offload *type, unsigned short family);
+ void xfrm_unregister_type_offload(const struct xfrm_type_offload *type, unsigned short family);
++void xfrm_set_type_offload(struct xfrm_state *x);
++static inline void xfrm_unset_type_offload(struct xfrm_state *x)
++{
++      if (!x->type_offload)
++              return;
++
++      module_put(x->type_offload->owner);
++      x->type_offload = NULL;
++}
+ /**
+  * struct xfrm_mode_cbs - XFRM mode callbacks
+@@ -1760,7 +1769,7 @@ void xfrm_spd_getinfo(struct net *net, struct xfrmk_spdinfo *si);
+ u32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq);
+ int xfrm_init_replay(struct xfrm_state *x, struct netlink_ext_ack *extack);
+ u32 xfrm_state_mtu(struct xfrm_state *x, int mtu);
+-int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload,
++int __xfrm_init_state(struct xfrm_state *x, bool init_replay,
+                     struct netlink_ext_ack *extack);
+ int xfrm_init_state(struct xfrm_state *x);
+ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type);
+diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
+index d1fa94e52ceae..97c8030cc4173 100644
+--- a/net/xfrm/xfrm_device.c
++++ b/net/xfrm/xfrm_device.c
+@@ -244,11 +244,6 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
+       xfrm_address_t *daddr;
+       bool is_packet_offload;
+-      if (!x->type_offload) {
+-              NL_SET_ERR_MSG(extack, "Type doesn't support offload");
+-              return -EINVAL;
+-      }
+-
+       if (xuo->flags &
+           ~(XFRM_OFFLOAD_IPV6 | XFRM_OFFLOAD_INBOUND | XFRM_OFFLOAD_PACKET)) {
+               NL_SET_ERR_MSG(extack, "Unrecognized flags in offload request");
+@@ -310,6 +305,13 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
+               return -EINVAL;
+       }
++      xfrm_set_type_offload(x);
++      if (!x->type_offload) {
++              NL_SET_ERR_MSG(extack, "Type doesn't support offload");
++              dev_put(dev);
++              return -EINVAL;
++      }
++
+       xso->dev = dev;
+       netdev_tracker_alloc(dev, &xso->dev_tracker, GFP_ATOMIC);
+       xso->real_dev = dev;
+@@ -332,6 +334,7 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
+               netdev_put(dev, &xso->dev_tracker);
+               xso->type = XFRM_DEV_OFFLOAD_UNSPECIFIED;
++              xfrm_unset_type_offload(x);
+               /* User explicitly requested packet offload mode and configured
+                * policy in addition to the XFRM state. So be civil to users,
+                * and return an error instead of taking fallback path.
+diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
+index ad2202fa82f34..69af5964c886c 100644
+--- a/net/xfrm/xfrm_state.c
++++ b/net/xfrm/xfrm_state.c
+@@ -424,18 +424,18 @@ void xfrm_unregister_type_offload(const struct xfrm_type_offload *type,
+ }
+ EXPORT_SYMBOL(xfrm_unregister_type_offload);
+-static const struct xfrm_type_offload *
+-xfrm_get_type_offload(u8 proto, unsigned short family, bool try_load)
++void xfrm_set_type_offload(struct xfrm_state *x)
+ {
+       const struct xfrm_type_offload *type = NULL;
+       struct xfrm_state_afinfo *afinfo;
++      bool try_load = true;
+ retry:
+-      afinfo = xfrm_state_get_afinfo(family);
++      afinfo = xfrm_state_get_afinfo(x->props.family);
+       if (unlikely(afinfo == NULL))
+-              return NULL;
++              goto out;
+-      switch (proto) {
++      switch (x->id.proto) {
+       case IPPROTO_ESP:
+               type = afinfo->type_offload_esp;
+               break;
+@@ -449,18 +449,16 @@ xfrm_get_type_offload(u8 proto, unsigned short family, bool try_load)
+       rcu_read_unlock();
+       if (!type && try_load) {
+-              request_module("xfrm-offload-%d-%d", family, proto);
++              request_module("xfrm-offload-%d-%d", x->props.family,
++                             x->id.proto);
+               try_load = false;
+               goto retry;
+       }
+-      return type;
+-}
+-
+-static void xfrm_put_type_offload(const struct xfrm_type_offload *type)
+-{
+-      module_put(type->owner);
++out:
++      x->type_offload = type;
+ }
++EXPORT_SYMBOL(xfrm_set_type_offload);
+ static const struct xfrm_mode xfrm4_mode_map[XFRM_MODE_MAX] = {
+       [XFRM_MODE_BEET] = {
+@@ -609,8 +607,6 @@ static void ___xfrm_state_destroy(struct xfrm_state *x)
+       kfree(x->coaddr);
+       kfree(x->replay_esn);
+       kfree(x->preplay_esn);
+-      if (x->type_offload)
+-              xfrm_put_type_offload(x->type_offload);
+       if (x->type) {
+               x->type->destructor(x);
+               xfrm_put_type(x->type);
+@@ -784,6 +780,8 @@ void xfrm_dev_state_free(struct xfrm_state *x)
+       struct xfrm_dev_offload *xso = &x->xso;
+       struct net_device *dev = READ_ONCE(xso->dev);
++      xfrm_unset_type_offload(x);
++
+       if (dev && dev->xfrmdev_ops) {
+               spin_lock_bh(&xfrm_state_dev_gc_lock);
+               if (!hlist_unhashed(&x->dev_gclist))
+@@ -3122,7 +3120,7 @@ u32 xfrm_state_mtu(struct xfrm_state *x, int mtu)
+ }
+ EXPORT_SYMBOL_GPL(xfrm_state_mtu);
+-int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload,
++int __xfrm_init_state(struct xfrm_state *x, bool init_replay,
+                     struct netlink_ext_ack *extack)
+ {
+       const struct xfrm_mode *inner_mode;
+@@ -3178,8 +3176,6 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload,
+               goto error;
+       }
+-      x->type_offload = xfrm_get_type_offload(x->id.proto, family, offload);
+-
+       err = x->type->init_state(x, extack);
+       if (err)
+               goto error;
+@@ -3229,7 +3225,7 @@ int xfrm_init_state(struct xfrm_state *x)
+ {
+       int err;
+-      err = __xfrm_init_state(x, true, false, NULL);
++      err = __xfrm_init_state(x, true, NULL);
+       if (!err)
+               x->km.state = XFRM_STATE_VALID;
+diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
+index 08c6d6f0179fb..82a768500999b 100644
+--- a/net/xfrm/xfrm_user.c
++++ b/net/xfrm/xfrm_user.c
+@@ -907,7 +907,7 @@ static struct xfrm_state *xfrm_state_construct(struct net *net,
+                       goto error;
+       }
+-      err = __xfrm_init_state(x, false, attrs[XFRMA_OFFLOAD_DEV], extack);
++      err = __xfrm_init_state(x, false, extack);
+       if (err)
+               goto error;
+-- 
+2.39.5
+
diff --git a/queue-6.14/xsk-add-launch-time-hardware-offload-support-to-xdp-.patch b/queue-6.14/xsk-add-launch-time-hardware-offload-support-to-xdp-.patch
new file mode 100644 (file)
index 0000000..016b15d
--- /dev/null
@@ -0,0 +1,305 @@
+From be8f0ca04a18729531cabc24b350ba33e1d4f507 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 16 Feb 2025 17:34:26 +0800
+Subject: xsk: Add launch time hardware offload support to XDP Tx metadata
+
+From: Song Yoong Siang <yoong.siang.song@intel.com>
+
+[ Upstream commit ca4419f15abd19ba8be1e109661b60f9f5b6c9f0 ]
+
+Extend the XDP Tx metadata framework so that user can requests launch time
+hardware offload, where the Ethernet device will schedule the packet for
+transmission at a pre-determined time called launch time. The value of
+launch time is communicated from user space to Ethernet driver via
+launch_time field of struct xsk_tx_metadata.
+
+Suggested-by: Stanislav Fomichev <sdf@fomichev.me>
+Signed-off-by: Song Yoong Siang <yoong.siang.song@intel.com>
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Acked-by: Stanislav Fomichev <sdf@fomichev.me>
+Acked-by: Jakub Kicinski <kuba@kernel.org>
+Link: https://patch.msgid.link/20250216093430.957880-2-yoong.siang.song@intel.com
+Stable-dep-of: d931cf9b38da ("igc: Fix TX drops in XDP ZC")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/netlink/specs/netdev.yaml      |  4 ++
+ Documentation/networking/xsk-tx-metadata.rst | 62 ++++++++++++++++++++
+ include/net/xdp_sock.h                       | 10 ++++
+ include/net/xdp_sock_drv.h                   |  1 +
+ include/uapi/linux/if_xdp.h                  | 10 ++++
+ include/uapi/linux/netdev.h                  |  3 +
+ net/core/netdev-genl.c                       |  2 +
+ net/xdp/xsk.c                                |  3 +
+ tools/include/uapi/linux/if_xdp.h            | 10 ++++
+ tools/include/uapi/linux/netdev.h            |  3 +
+ 10 files changed, 108 insertions(+)
+
+diff --git a/Documentation/netlink/specs/netdev.yaml b/Documentation/netlink/specs/netdev.yaml
+index cbb544bd6c848..901b5afb3df0d 100644
+--- a/Documentation/netlink/specs/netdev.yaml
++++ b/Documentation/netlink/specs/netdev.yaml
+@@ -70,6 +70,10 @@ definitions:
+         name: tx-checksum
+         doc:
+           L3 checksum HW offload is supported by the driver.
++      -
++        name: tx-launch-time-fifo
++        doc:
++          Launch time HW offload is supported by the driver.
+   -
+     name: queue-type
+     type: enum
+diff --git a/Documentation/networking/xsk-tx-metadata.rst b/Documentation/networking/xsk-tx-metadata.rst
+index e76b0cfc32f7d..df53a10ccac34 100644
+--- a/Documentation/networking/xsk-tx-metadata.rst
++++ b/Documentation/networking/xsk-tx-metadata.rst
+@@ -50,6 +50,10 @@ The flags field enables the particular offload:
+   checksum. ``csum_start`` specifies byte offset of where the checksumming
+   should start and ``csum_offset`` specifies byte offset where the
+   device should store the computed checksum.
++- ``XDP_TXMD_FLAGS_LAUNCH_TIME``: requests the device to schedule the
++  packet for transmission at a pre-determined time called launch time. The
++  value of launch time is indicated by ``launch_time`` field of
++  ``union xsk_tx_metadata``.
+ Besides the flags above, in order to trigger the offloads, the first
+ packet's ``struct xdp_desc`` descriptor should set ``XDP_TX_METADATA``
+@@ -65,6 +69,63 @@ In this case, when running in ``XDK_COPY`` mode, the TX checksum
+ is calculated on the CPU. Do not enable this option in production because
+ it will negatively affect performance.
++Launch Time
++===========
++
++The value of the requested launch time should be based on the device's PTP
++Hardware Clock (PHC) to ensure accuracy. AF_XDP takes a different data path
++compared to the ETF queuing discipline, which organizes packets and delays
++their transmission. Instead, AF_XDP immediately hands off the packets to
++the device driver without rearranging their order or holding them prior to
++transmission. Since the driver maintains FIFO behavior and does not perform
++packet reordering, a packet with a launch time request will block other
++packets in the same Tx Queue until it is sent. Therefore, it is recommended
++to allocate separate queue for scheduling traffic that is intended for
++future transmission.
++
++In scenarios where the launch time offload feature is disabled, the device
++driver is expected to disregard the launch time request. For correct
++interpretation and meaningful operation, the launch time should never be
++set to a value larger than the farthest programmable time in the future
++(the horizon). Different devices have different hardware limitations on the
++launch time offload feature.
++
++stmmac driver
++-------------
++
++For stmmac, TSO and launch time (TBS) features are mutually exclusive for
++each individual Tx Queue. By default, the driver configures Tx Queue 0 to
++support TSO and the rest of the Tx Queues to support TBS. The launch time
++hardware offload feature can be enabled or disabled by using the tc-etf
++command to call the driver's ndo_setup_tc() callback.
++
++The value of the launch time that is programmed in the Enhanced Normal
++Transmit Descriptors is a 32-bit value, where the most significant 8 bits
++represent the time in seconds and the remaining 24 bits represent the time
++in 256 ns increments. The programmed launch time is compared against the
++PTP time (bits[39:8]) and rolls over after 256 seconds. Therefore, the
++horizon of the launch time for dwmac4 and dwxlgmac2 is 128 seconds in the
++future.
++
++igc driver
++----------
++
++For igc, all four Tx Queues support the launch time feature. The launch
++time hardware offload feature can be enabled or disabled by using the
++tc-etf command to call the driver's ndo_setup_tc() callback. When entering
++TSN mode, the igc driver will reset the device and create a default Qbv
++schedule with a 1-second cycle time, with all Tx Queues open at all times.
++
++The value of the launch time that is programmed in the Advanced Transmit
++Context Descriptor is a relative offset to the starting time of the Qbv
++transmission window of the queue. The Frst flag of the descriptor can be
++set to schedule the packet for the next Qbv cycle. Therefore, the horizon
++of the launch time for i225 and i226 is the ending time of the next cycle
++of the Qbv transmission window of the queue. For example, when the Qbv
++cycle time is set to 1 second, the horizon of the launch time ranges
++from 1 second to 2 seconds, depending on where the Qbv cycle is currently
++running.
++
+ Querying Device Capabilities
+ ============================
+@@ -74,6 +135,7 @@ Refer to ``xsk-flags`` features bitmask in
+ - ``tx-timestamp``: device supports ``XDP_TXMD_FLAGS_TIMESTAMP``
+ - ``tx-checksum``: device supports ``XDP_TXMD_FLAGS_CHECKSUM``
++- ``tx-launch-time-fifo``: device supports ``XDP_TXMD_FLAGS_LAUNCH_TIME``
+ See ``tools/net/ynl/samples/netdev.c`` on how to query this information.
+diff --git a/include/net/xdp_sock.h b/include/net/xdp_sock.h
+index bfe625b55d55d..a58ae7589d121 100644
+--- a/include/net/xdp_sock.h
++++ b/include/net/xdp_sock.h
+@@ -110,11 +110,16 @@ struct xdp_sock {
+  *     indicates position where checksumming should start.
+  *     csum_offset indicates position where checksum should be stored.
+  *
++ * void (*tmo_request_launch_time)(u64 launch_time, void *priv)
++ *     Called when AF_XDP frame requested launch time HW offload support.
++ *     launch_time indicates the PTP time at which the device can schedule the
++ *     packet for transmission.
+  */
+ struct xsk_tx_metadata_ops {
+       void    (*tmo_request_timestamp)(void *priv);
+       u64     (*tmo_fill_timestamp)(void *priv);
+       void    (*tmo_request_checksum)(u16 csum_start, u16 csum_offset, void *priv);
++      void    (*tmo_request_launch_time)(u64 launch_time, void *priv);
+ };
+ #ifdef CONFIG_XDP_SOCKETS
+@@ -162,6 +167,11 @@ static inline void xsk_tx_metadata_request(const struct xsk_tx_metadata *meta,
+       if (!meta)
+               return;
++      if (ops->tmo_request_launch_time)
++              if (meta->flags & XDP_TXMD_FLAGS_LAUNCH_TIME)
++                      ops->tmo_request_launch_time(meta->request.launch_time,
++                                                   priv);
++
+       if (ops->tmo_request_timestamp)
+               if (meta->flags & XDP_TXMD_FLAGS_TIMESTAMP)
+                       ops->tmo_request_timestamp(priv);
+diff --git a/include/net/xdp_sock_drv.h b/include/net/xdp_sock_drv.h
+index 784cd34f5bba5..fe4afb2517197 100644
+--- a/include/net/xdp_sock_drv.h
++++ b/include/net/xdp_sock_drv.h
+@@ -199,6 +199,7 @@ static inline void *xsk_buff_raw_get_data(struct xsk_buff_pool *pool, u64 addr)
+ #define XDP_TXMD_FLAGS_VALID ( \
+               XDP_TXMD_FLAGS_TIMESTAMP | \
+               XDP_TXMD_FLAGS_CHECKSUM | \
++              XDP_TXMD_FLAGS_LAUNCH_TIME | \
+       0)
+ static inline bool
+diff --git a/include/uapi/linux/if_xdp.h b/include/uapi/linux/if_xdp.h
+index 42ec5ddaab8dc..42869770776ec 100644
+--- a/include/uapi/linux/if_xdp.h
++++ b/include/uapi/linux/if_xdp.h
+@@ -127,6 +127,12 @@ struct xdp_options {
+  */
+ #define XDP_TXMD_FLAGS_CHECKSUM                       (1 << 1)
++/* Request launch time hardware offload. The device will schedule the packet for
++ * transmission at a pre-determined time called launch time. The value of
++ * launch time is communicated via launch_time field of struct xsk_tx_metadata.
++ */
++#define XDP_TXMD_FLAGS_LAUNCH_TIME            (1 << 2)
++
+ /* AF_XDP offloads request. 'request' union member is consumed by the driver
+  * when the packet is being transmitted. 'completion' union member is
+  * filled by the driver when the transmit completion arrives.
+@@ -142,6 +148,10 @@ struct xsk_tx_metadata {
+                       __u16 csum_start;
+                       /* Offset from csum_start where checksum should be stored. */
+                       __u16 csum_offset;
++
++                      /* XDP_TXMD_FLAGS_LAUNCH_TIME */
++                      /* Launch time in nanosecond against the PTP HW Clock */
++                      __u64 launch_time;
+               } request;
+               struct {
+diff --git a/include/uapi/linux/netdev.h b/include/uapi/linux/netdev.h
+index e4be227d3ad64..4324e89a80261 100644
+--- a/include/uapi/linux/netdev.h
++++ b/include/uapi/linux/netdev.h
+@@ -59,10 +59,13 @@ enum netdev_xdp_rx_metadata {
+  *   by the driver.
+  * @NETDEV_XSK_FLAGS_TX_CHECKSUM: L3 checksum HW offload is supported by the
+  *   driver.
++ * @NETDEV_XSK_FLAGS_TX_LAUNCH_TIME_FIFO: Launch time HW offload is supported
++ *   by the driver.
+  */
+ enum netdev_xsk_flags {
+       NETDEV_XSK_FLAGS_TX_TIMESTAMP = 1,
+       NETDEV_XSK_FLAGS_TX_CHECKSUM = 2,
++      NETDEV_XSK_FLAGS_TX_LAUNCH_TIME_FIFO = 4,
+ };
+ enum netdev_queue_type {
+diff --git a/net/core/netdev-genl.c b/net/core/netdev-genl.c
+index 715f85c6b62ea..7832abc5ca6e2 100644
+--- a/net/core/netdev-genl.c
++++ b/net/core/netdev-genl.c
+@@ -52,6 +52,8 @@ XDP_METADATA_KFUNC_xxx
+                       xsk_features |= NETDEV_XSK_FLAGS_TX_TIMESTAMP;
+               if (netdev->xsk_tx_metadata_ops->tmo_request_checksum)
+                       xsk_features |= NETDEV_XSK_FLAGS_TX_CHECKSUM;
++              if (netdev->xsk_tx_metadata_ops->tmo_request_launch_time)
++                      xsk_features |= NETDEV_XSK_FLAGS_TX_LAUNCH_TIME_FIFO;
+       }
+       if (nla_put_u32(rsp, NETDEV_A_DEV_IFINDEX, netdev->ifindex) ||
+diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
+index 89d2bef964698..41093ea63700c 100644
+--- a/net/xdp/xsk.c
++++ b/net/xdp/xsk.c
+@@ -742,6 +742,9 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
+                                               goto free_err;
+                               }
+                       }
++
++                      if (meta->flags & XDP_TXMD_FLAGS_LAUNCH_TIME)
++                              skb->skb_mstamp_ns = meta->request.launch_time;
+               }
+       }
+diff --git a/tools/include/uapi/linux/if_xdp.h b/tools/include/uapi/linux/if_xdp.h
+index 42ec5ddaab8dc..42869770776ec 100644
+--- a/tools/include/uapi/linux/if_xdp.h
++++ b/tools/include/uapi/linux/if_xdp.h
+@@ -127,6 +127,12 @@ struct xdp_options {
+  */
+ #define XDP_TXMD_FLAGS_CHECKSUM                       (1 << 1)
++/* Request launch time hardware offload. The device will schedule the packet for
++ * transmission at a pre-determined time called launch time. The value of
++ * launch time is communicated via launch_time field of struct xsk_tx_metadata.
++ */
++#define XDP_TXMD_FLAGS_LAUNCH_TIME            (1 << 2)
++
+ /* AF_XDP offloads request. 'request' union member is consumed by the driver
+  * when the packet is being transmitted. 'completion' union member is
+  * filled by the driver when the transmit completion arrives.
+@@ -142,6 +148,10 @@ struct xsk_tx_metadata {
+                       __u16 csum_start;
+                       /* Offset from csum_start where checksum should be stored. */
+                       __u16 csum_offset;
++
++                      /* XDP_TXMD_FLAGS_LAUNCH_TIME */
++                      /* Launch time in nanosecond against the PTP HW Clock */
++                      __u64 launch_time;
+               } request;
+               struct {
+diff --git a/tools/include/uapi/linux/netdev.h b/tools/include/uapi/linux/netdev.h
+index e4be227d3ad64..4324e89a80261 100644
+--- a/tools/include/uapi/linux/netdev.h
++++ b/tools/include/uapi/linux/netdev.h
+@@ -59,10 +59,13 @@ enum netdev_xdp_rx_metadata {
+  *   by the driver.
+  * @NETDEV_XSK_FLAGS_TX_CHECKSUM: L3 checksum HW offload is supported by the
+  *   driver.
++ * @NETDEV_XSK_FLAGS_TX_LAUNCH_TIME_FIFO: Launch time HW offload is supported
++ *   by the driver.
+  */
+ enum netdev_xsk_flags {
+       NETDEV_XSK_FLAGS_TX_TIMESTAMP = 1,
+       NETDEV_XSK_FLAGS_TX_CHECKSUM = 2,
++      NETDEV_XSK_FLAGS_TX_LAUNCH_TIME_FIFO = 4,
+ };
+ enum netdev_queue_type {
+-- 
+2.39.5
+
diff --git a/queue-6.14/xsk-fix-__xsk_generic_xmit-error-code-when-cq-is-ful.patch b/queue-6.14/xsk-fix-__xsk_generic_xmit-error-code-when-cq-is-ful.patch
new file mode 100644 (file)
index 0000000..f4d64df
--- /dev/null
@@ -0,0 +1,53 @@
+From 39a40bdb93b989324d0c79be82059b141f5d5987 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2025 16:10:52 +0800
+Subject: xsk: Fix __xsk_generic_xmit() error code when cq is full
+
+From: Wang Liang <wangliang74@huawei.com>
+
+[ Upstream commit 5d0b204654de25615cf712be86c3192eca68ed80 ]
+
+When the cq reservation is failed, the error code is not set which is
+initialized to zero in __xsk_generic_xmit(). That means the packet is not
+send successfully but sendto() return ok.
+
+Considering the impact on uapi, return -EAGAIN is a good idea. The cq is
+full usually because it is not released in time, try to send msg again is
+appropriate.
+
+The bug was at the very early implementation of xsk, so the Fixes tag
+targets the commit that introduced the changes in
+xsk_cq_reserve_addr_locked where this fix depends on.
+
+Fixes: e6c4047f5122 ("xsk: Use xsk_buff_pool directly for cq functions")
+Suggested-by: Magnus Karlsson <magnus.karlsson@gmail.com>
+Signed-off-by: Wang Liang <wangliang74@huawei.com>
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Acked-by: Stanislav Fomichev <sdf@fomichev.me>
+Link: https://patch.msgid.link/20250227081052.4096337-1-wangliang74@huawei.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xdp/xsk.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
+index 41093ea63700c..a373a7130d757 100644
+--- a/net/xdp/xsk.c
++++ b/net/xdp/xsk.c
+@@ -805,8 +805,11 @@ static int __xsk_generic_xmit(struct sock *sk)
+                * if there is space in it. This avoids having to implement
+                * any buffering in the Tx path.
+                */
+-              if (xsk_cq_reserve_addr_locked(xs->pool, desc.addr))
++              err = xsk_cq_reserve_addr_locked(xs->pool, desc.addr);
++              if (err) {
++                      err = -EAGAIN;
+                       goto out;
++              }
+               skb = xsk_build_skb(xs, &desc);
+               if (IS_ERR(skb)) {
+-- 
+2.39.5
+