]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.15
authorSasha Levin <sashal@kernel.org>
Sat, 13 Aug 2022 20:26:02 +0000 (16:26 -0400)
committerSasha Levin <sashal@kernel.org>
Sat, 13 Aug 2022 20:26:02 +0000 (16:26 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
564 files changed:
queue-5.15/9p-add-client-parameter-to-p9_req_put.patch [new file with mode: 0644]
queue-5.15/9p-drop-kref-usage.patch [new file with mode: 0644]
queue-5.15/9p-fix-a-bunch-of-checkpatch-warnings.patch [new file with mode: 0644]
queue-5.15/acpi-apei-explicit-init-of-hest-and-ghes-in-apci_ini.patch [new file with mode: 0644]
queue-5.15/acpi-apei-fix-_einj-vs-efi_memory_sp.patch [new file with mode: 0644]
queue-5.15/acpi-ec-drop-the-ec_flags_ignore_dsdt_gpe-quirk.patch [new file with mode: 0644]
queue-5.15/acpi-ec-remove-duplicate-thinkpad-x1-carbon-6th-entr.patch [new file with mode: 0644]
queue-5.15/acpi-lpss-fix-missing-check-in-register_device_clock.patch [new file with mode: 0644]
queue-5.15/acpi-pm-save-nvs-memory-for-lenovo-g40-45.patch [new file with mode: 0644]
queue-5.15/acpi-processor-idle-annotate-more-functions-to-live-.patch [new file with mode: 0644]
queue-5.15/acpi-viot-fix-acs-setup.patch [new file with mode: 0644]
queue-5.15/android-binder-stop-saving-a-pointer-to-the-vma.patch [new file with mode: 0644]
queue-5.15/arch-make-trace_irqflags_nmi_support-generic.patch [new file with mode: 0644]
queue-5.15/arm-bcm-fix-refcount-leak-in-bcm_kona_smc_init.patch [new file with mode: 0644]
queue-5.15/arm-dts-ast2500-evb-fix-board-compatible.patch [new file with mode: 0644]
queue-5.15/arm-dts-ast2600-evb-a1-fix-board-compatible.patch [new file with mode: 0644]
queue-5.15/arm-dts-ast2600-evb-fix-board-compatible.patch [new file with mode: 0644]
queue-5.15/arm-dts-bcm5301x-add-dt-for-meraki-mr26.patch [new file with mode: 0644]
queue-5.15/arm-dts-imx6ul-add-missing-properties-for-sram.patch [new file with mode: 0644]
queue-5.15/arm-dts-imx6ul-change-operating-points-to-uint32-mat.patch [new file with mode: 0644]
queue-5.15/arm-dts-imx6ul-fix-csi-node-compatible.patch [new file with mode: 0644]
queue-5.15/arm-dts-imx6ul-fix-keypad-compatible.patch [new file with mode: 0644]
queue-5.15/arm-dts-imx6ul-fix-lcdif-node-compatible.patch [new file with mode: 0644]
queue-5.15/arm-dts-imx6ul-fix-qspi-node-compatible.patch [new file with mode: 0644]
queue-5.15/arm-dts-imx7d-colibri-emmc-add-cpu1-supply.patch [new file with mode: 0644]
queue-5.15/arm-dts-qcom-mdm9615-add-missing-pmic-gpio-reg.patch [new file with mode: 0644]
queue-5.15/arm-dts-qcom-msm8974-fix-irq-type-on-blsp2_uart1.patch [new file with mode: 0644]
queue-5.15/arm-dts-qcom-pm8841-add-required-thermal-sensor-cell.patch [new file with mode: 0644]
queue-5.15/arm-dts-qcom-replace-gcc-pxo-with-pxo_board-fixed-cl.patch [new file with mode: 0644]
queue-5.15/arm-dts-qcom-sdx55-fix-the-irq-trigger-type-for-uart.patch [new file with mode: 0644]
queue-5.15/arm-dts-ux500-fix-codina-accelerometer-mounting-matr.patch [new file with mode: 0644]
queue-5.15/arm-dts-ux500-fix-gavini-accelerometer-mounting-matr.patch [new file with mode: 0644]
queue-5.15/arm-findbit-fix-overflowing-offset.patch [new file with mode: 0644]
queue-5.15/arm-omap2-display-fix-refcount-leak-bug.patch [new file with mode: 0644]
queue-5.15/arm-omap2-fix-refcount-leak-in-omap3xxx_prm_late_ini.patch [new file with mode: 0644]
queue-5.15/arm-omap2-fix-refcount-leak-in-omapdss_init_of.patch [new file with mode: 0644]
queue-5.15/arm-omap2-pdata-quirks-fix-refcount-leak-bug.patch [new file with mode: 0644]
queue-5.15/arm-shmobile-rcar-gen2-increase-refcount-for-new-ref.patch [new file with mode: 0644]
queue-5.15/arm64-cpufeature-allow-different-pmu-versions-in-id_.patch [new file with mode: 0644]
queue-5.15/arm64-do-not-forget-syscall-when-starting-a-new-thre.patch [new file with mode: 0644]
queue-5.15/arm64-dts-allwinner-a64-orangepi-win-fix-led-node-na.patch [new file with mode: 0644]
queue-5.15/arm64-dts-mt7622-fix-bpi-r64-wps-button.patch [new file with mode: 0644]
queue-5.15/arm64-dts-mt8192-fix-idle-states-entry-method.patch [new file with mode: 0644]
queue-5.15/arm64-dts-mt8192-fix-idle-states-nodes-naming-scheme.patch [new file with mode: 0644]
queue-5.15/arm64-dts-qcom-ipq8074-fix-nand-node-name.patch [new file with mode: 0644]
queue-5.15/arm64-dts-qcom-msm8916-fix-typo-in-pronto-remoteproc.patch [new file with mode: 0644]
queue-5.15/arm64-dts-qcom-qcs404-fix-incorrect-usb2-phys-assign.patch [new file with mode: 0644]
queue-5.15/arm64-dts-qcom-sc7180-remove-ipa_fw_mem-node-on-trog.patch [new file with mode: 0644]
queue-5.15/arm64-dts-qcom-sdm630-disable-gpu-by-default.patch [new file with mode: 0644]
queue-5.15/arm64-dts-qcom-sdm630-fix-gpu-s-interconnect-path.patch [new file with mode: 0644]
queue-5.15/arm64-dts-qcom-sdm630-fix-the-qusb2phy-ref-clock.patch [new file with mode: 0644]
queue-5.15/arm64-dts-qcom-sdm636-sony-xperia-ganges-mermaid-cor.patch [new file with mode: 0644]
queue-5.15/arm64-dts-qcom-sm6125-append-state-suffix-to-pinctrl.patch [new file with mode: 0644]
queue-5.15/arm64-dts-qcom-sm6125-move-sdc2-pinctrl-from-seine-p.patch [new file with mode: 0644]
queue-5.15/arm64-dts-qcom-sm8250-add-missing-pcie-phy-clock-cel.patch [new file with mode: 0644]
queue-5.15/arm64-dts-renesas-beacon-fix-regulator-node-names.patch [new file with mode: 0644]
queue-5.15/arm64-dts-renesas-fix-thermal-sensors-on-single-zone.patch [new file with mode: 0644]
queue-5.15/arm64-fix-oops-in-concurrently-setting-insn_emulatio.patch [new file with mode: 0644]
queue-5.15/arm64-kasan-revert-arm64-mte-reset-the-page-tag-in-p.patch [new file with mode: 0644]
queue-5.15/arm64-select-trace_irqflags_nmi_support.patch [new file with mode: 0644]
queue-5.15/arm64-tegra-fix-sdmmc1-cd-on-p2888.patch [new file with mode: 0644]
queue-5.15/arm64-tegra-fixup-sysram-references.patch [new file with mode: 0644]
queue-5.15/arm64-tegra-mark-bpmp-channels-as-no-memory-wc.patch [new file with mode: 0644]
queue-5.15/arm64-tegra-update-tegra234-bpmp-channel-addresses.patch [new file with mode: 0644]
queue-5.15/asoc-audio-graph-card-add-of_node_put-in-fail-path.patch [new file with mode: 0644]
queue-5.15/asoc-codecs-da7210-add-check-for-i2c_add_driver.patch [new file with mode: 0644]
queue-5.15/asoc-codecs-msm8916-wcd-digital-move-gains-from-sx_t.patch [new file with mode: 0644]
queue-5.15/asoc-codecs-wcd9335-move-gains-from-sx_tlv-to-s8_tlv.patch [new file with mode: 0644]
queue-5.15/asoc-cros_ec_codec-fix-refcount-leak-in-cros_ec_code.patch [new file with mode: 0644]
queue-5.15/asoc-fsl-asoc-card-force-cast-the-asrc_format-type.patch [new file with mode: 0644]
queue-5.15/asoc-fsl_asrc-force-cast-the-asrc_format-type.patch [new file with mode: 0644]
queue-5.15/asoc-fsl_easrc-use-snd_pcm_format_t-type-for-sample_.patch [new file with mode: 0644]
queue-5.15/asoc-imx-audmux-silence-a-clang-warning.patch [new file with mode: 0644]
queue-5.15/asoc-imx-card-fix-dsd-pdm-mclk-frequency.patch [new file with mode: 0644]
queue-5.15/asoc-imx-card-use-snd_pcm_format_t-type-for-asrc_for.patch [new file with mode: 0644]
queue-5.15/asoc-mchp-spdifrx-disable-end-of-block-interrupt-on-.patch [new file with mode: 0644]
queue-5.15/asoc-mediatek-mt8173-fix-refcount-leak-in-mt8173_rt5.patch [new file with mode: 0644]
queue-5.15/asoc-mediatek-mt8173-rt5650-fix-refcount-leak-in-mt8.patch [new file with mode: 0644]
queue-5.15/asoc-mt6359-fix-refcount-leak-bug.patch [new file with mode: 0644]
queue-5.15/asoc-mt6797-mt6351-fix-refcount-leak-in-mt6797_mt635.patch [new file with mode: 0644]
queue-5.15/asoc-qcom-fix-missing-of_node_put-in-asoc_qcom_lpass.patch [new file with mode: 0644]
queue-5.15/asoc-qcom-q6dsp-fix-an-off-by-one-in-q6adm_alloc_cop.patch [new file with mode: 0644]
queue-5.15/asoc-samsung-change-gpiod_speaker_power-and-rx1950_a.patch [new file with mode: 0644]
queue-5.15/asoc-samsung-fix-error-handling-in-aries_audio_probe.patch [new file with mode: 0644]
queue-5.15/asoc-samsung-h1940_uda1380-include-proepr-gpio-consu.patch [new file with mode: 0644]
queue-5.15/ath10k-do-not-enforce-interrupt-trigger-type.patch [new file with mode: 0644]
queue-5.15/ath11k-fix-incorrect-debug_mask-mappings.patch [new file with mode: 0644]
queue-5.15/ath11k-fix-netdev-open-race.patch [new file with mode: 0644]
queue-5.15/ath9k-fix-use-after-free-in-ath9k_hif_usb_rx_cb.patch [new file with mode: 0644]
queue-5.15/binder-fix-redefinition-of-seq_file-attributes.patch [new file with mode: 0644]
queue-5.15/blk-mq-don-t-create-hctx-debugfs-dir-until-q-debugfs.patch [new file with mode: 0644]
queue-5.15/blktrace-trace-remapped-requests-correctly.patch [new file with mode: 0644]
queue-5.15/block-bio-remove-duplicate-append-pages-code.patch [new file with mode: 0644]
queue-5.15/block-ensure-iov_iter-advances-for-added-pages.patch [new file with mode: 0644]
queue-5.15/block-fix-infinite-loop-for-invalid-zone-append.patch [new file with mode: 0644]
queue-5.15/block-rnbd-srv-set-keep_id-to-true-after-mutex_trylo.patch [new file with mode: 0644]
queue-5.15/bluetooth-hci_intel-add-check-for-platform_driver_re.patch [new file with mode: 0644]
queue-5.15/bpf-fix-subprog-names-in-stack-traces.patch [new file with mode: 0644]
queue-5.15/bus-hisi_lpc-fix-missing-platform_device_put-in-hisi.patch [new file with mode: 0644]
queue-5.15/can-error-specify-the-values-of-data-5.7-of-can-erro.patch [new file with mode: 0644]
queue-5.15/can-hi311x-do-not-report-txerr-and-rxerr-during-bus-.patch [new file with mode: 0644]
queue-5.15/can-kvaser_usb_hydra-do-not-report-txerr-and-rxerr-d.patch [new file with mode: 0644]
queue-5.15/can-kvaser_usb_leaf-do-not-report-txerr-and-rxerr-du.patch [new file with mode: 0644]
queue-5.15/can-netlink-allow-configuring-of-fixed-bit-rates-wit.patch [new file with mode: 0644]
queue-5.15/can-netlink-allow-configuring-of-fixed-data-bit-rate.patch [new file with mode: 0644]
queue-5.15/can-pch_can-do-not-report-txerr-and-rxerr-during-bus.patch [new file with mode: 0644]
queue-5.15/can-pch_can-pch_can_error-initialize-errc-before-usi.patch [new file with mode: 0644]
queue-5.15/can-rcar_can-do-not-report-txerr-and-rxerr-during-bu.patch [new file with mode: 0644]
queue-5.15/can-sja1000-do-not-report-txerr-and-rxerr-during-bus.patch [new file with mode: 0644]
queue-5.15/can-sun4i_can-do-not-report-txerr-and-rxerr-during-b.patch [new file with mode: 0644]
queue-5.15/can-usb_8dev-do-not-report-txerr-and-rxerr-during-bu.patch [new file with mode: 0644]
queue-5.15/clk-mediatek-reset-fix-written-reset-bit-offset.patch [new file with mode: 0644]
queue-5.15/clk-qcom-camcc-sdm845-fix-topology-around-titan_top-.patch [new file with mode: 0644]
queue-5.15/clk-qcom-camcc-sm8250-fix-halt-on-boot-by-reducing-d.patch [new file with mode: 0644]
queue-5.15/clk-qcom-camcc-sm8250-fix-topology-around-titan_top-.patch [new file with mode: 0644]
queue-5.15/clk-qcom-clk-krait-unlock-spin-after-mux-completion.patch [new file with mode: 0644]
queue-5.15/clk-qcom-clk-rcg2-fail-duty-cycle-configuration-if-m.patch [new file with mode: 0644]
queue-5.15/clk-qcom-clk-rcg2-make-sure-to-not-write-d-0-to-the-.patch [new file with mode: 0644]
queue-5.15/clk-qcom-gcc-msm8939-add-missing-system_mm_noc_bfdcd.patch [new file with mode: 0644]
queue-5.15/clk-qcom-gcc-msm8939-add-missing-system_mm_noc_bfdcd.patch-18441 [new file with mode: 0644]
queue-5.15/clk-qcom-gcc-msm8939-fix-bimc_ddr_clk_src-rcgr-base-.patch [new file with mode: 0644]
queue-5.15/clk-qcom-gcc-msm8939-fix-weird-field-spacing-in-ftbl.patch [new file with mode: 0644]
queue-5.15/clk-qcom-gcc-msm8939-point-mm-peripherals-to-system_.patch [new file with mode: 0644]
queue-5.15/clk-qcom-ipq8074-fix-nss-core-pll-s.patch [new file with mode: 0644]
queue-5.15/clk-qcom-ipq8074-fix-nss-port-frequency-tables.patch [new file with mode: 0644]
queue-5.15/clk-qcom-ipq8074-set-branch_halt_delay-flag-for-ubi-.patch [new file with mode: 0644]
queue-5.15/clk-qcom-ipq8074-sw-workaround-for-ubi32-pll-lock.patch [new file with mode: 0644]
queue-5.15/clk-renesas-r9a06g032-fix-uart-clkgrp-bitsel.patch [new file with mode: 0644]
queue-5.15/cpufreq-zynq-fix-refcount-leak-in-zynq_get_revision.patch [new file with mode: 0644]
queue-5.15/crypto-arm64-gcm-select-aead-for-ghash_arm64_ce.patch [new file with mode: 0644]
queue-5.15/crypto-ccp-during-shutdown-check-sev-data-pointer-be.patch [new file with mode: 0644]
queue-5.15/crypto-hisilicon-hpre-don-t-use-gfp_kernel-to-alloc-.patch [new file with mode: 0644]
queue-5.15/crypto-hisilicon-kunpeng916-crypto-driver-don-t-slee.patch [new file with mode: 0644]
queue-5.15/crypto-hisilicon-sec-don-t-sleep-when-in-softirq.patch [new file with mode: 0644]
queue-5.15/crypto-hisilicon-sec-fix-auth-key-size-error.patch [new file with mode: 0644]
queue-5.15/crypto-inside-secure-add-missing-module_device_table.patch [new file with mode: 0644]
queue-5.15/crypto-sun8i-ss-do-not-allocate-memory-when-handling.patch [new file with mode: 0644]
queue-5.15/crypto-sun8i-ss-fix-error-codes-in-allocate_flows.patch [new file with mode: 0644]
queue-5.15/crypto-sun8i-ss-fix-infinite-loop-in-sun8i_ss_setup_.patch [new file with mode: 0644]
queue-5.15/dccp-put-dccp_qpolicy_full-and-dccp_qpolicy_push-in-.patch [new file with mode: 0644]
queue-5.15/dm-return-early-from-dm_pr_call-if-dm-device-is-susp.patch [new file with mode: 0644]
queue-5.15/dm-writecache-count-number-of-blocks-discarded-not-n.patch [new file with mode: 0644]
queue-5.15/dm-writecache-count-number-of-blocks-read-not-number.patch [new file with mode: 0644]
queue-5.15/dm-writecache-count-number-of-blocks-written-not-num.patch [new file with mode: 0644]
queue-5.15/dm-writecache-return-void-from-functions.patch [new file with mode: 0644]
queue-5.15/dmaengine-dw-edma-fix-edma-rd-wr-channels-and-dma-di.patch [new file with mode: 0644]
queue-5.15/dmaengine-imx-dma-cast-of_device_get_match_data-with.patch [new file with mode: 0644]
queue-5.15/dmaengine-sf-pdma-add-multithread-support-for-a-dma-.patch [new file with mode: 0644]
queue-5.15/driver-core-fix-potential-deadlock-in-__driver_attac.patch [new file with mode: 0644]
queue-5.15/drivers-iio-remove-all-strcpy-uses.patch [new file with mode: 0644]
queue-5.15/drivers-perf-arm_spe-fix-consistency-of-sys_pmscr_el.patch [new file with mode: 0644]
queue-5.15/drm-adv7511-override-i2c-address-of-cec-before-acces.patch [new file with mode: 0644]
queue-5.15/drm-amdgpu-remove-one-duplicated-ef-removal.patch [new file with mode: 0644]
queue-5.15/drm-bridge-add-a-function-to-abstract-away-panels.patch [new file with mode: 0644]
queue-5.15/drm-bridge-adv7511-add-check-for-mipi_dsi_driver_reg.patch [new file with mode: 0644]
queue-5.15/drm-bridge-lt9611uxc-cancel-only-driver-s-work.patch [new file with mode: 0644]
queue-5.15/drm-bridge-sii8620-fix-possible-off-by-one.patch [new file with mode: 0644]
queue-5.15/drm-bridge-tc358767-move-e-dp-bridge-endpoint-parsin.patch [new file with mode: 0644]
queue-5.15/drm-dp-export-symbol-kerneldoc-fixes-for-dp-aux-bus.patch [new file with mode: 0644]
queue-5.15/drm-exynos-exynos7_drm_decon-free-resources-when-clk.patch [new file with mode: 0644]
queue-5.15/drm-mcde-fix-refcount-leak-in-mcde_dsi_bind.patch [new file with mode: 0644]
queue-5.15/drm-mediatek-add-pull-down-mipi-operation-in-mtk_dsi.patch [new file with mode: 0644]
queue-5.15/drm-mediatek-dpi-only-enable-dpi-after-the-bridge-is.patch [new file with mode: 0644]
queue-5.15/drm-mediatek-dpi-remove-output-format-of-yuv.patch [new file with mode: 0644]
queue-5.15/drm-mediatek-modify-dsi-funcs-to-atomic-operations.patch [new file with mode: 0644]
queue-5.15/drm-mediatek-separate-poweron-poweroff-from-enable-d.patch [new file with mode: 0644]
queue-5.15/drm-meson-encoder_hdmi-fix-refcount-leak-in-meson_en.patch [new file with mode: 0644]
queue-5.15/drm-meson-encoder_hdmi-switch-to-bridge-drm_bridge_a.patch [new file with mode: 0644]
queue-5.15/drm-mipi-dbi-align-max_chunk-to-2-in-spi_transfer.patch [new file with mode: 0644]
queue-5.15/drm-msm-avoid-dirtyfb-stalls-on-video-mode-displays-.patch [new file with mode: 0644]
queue-5.15/drm-msm-dpu-fix-for-non-visible-planes.patch [new file with mode: 0644]
queue-5.15/drm-msm-hdmi-enable-core-vcc-core-vdda-supply-for-89.patch [new file with mode: 0644]
queue-5.15/drm-msm-mdp5-fix-global-state-lock-backoff.patch [new file with mode: 0644]
queue-5.15/drm-panel-fix-build-error-when-config_drm_panel_sams.patch [new file with mode: 0644]
queue-5.15/drm-radeon-fix-incorrrect-spdx-license-identifiers.patch [new file with mode: 0644]
queue-5.15/drm-radeon-fix-potential-buffer-overflow-in-ni_set_m.patch [new file with mode: 0644]
queue-5.15/drm-rockchip-fix-an-error-handling-path-rockchip_dp_.patch [new file with mode: 0644]
queue-5.15/drm-rockchip-vop-don-t-crash-for-invalid-duplicate_s.patch [new file with mode: 0644]
queue-5.15/drm-shmem-helper-export-dedicated-wrappers-for-gem-o.patch [new file with mode: 0644]
queue-5.15/drm-shmem-helper-pass-gem-shmem-object-in-public-int.patch [new file with mode: 0644]
queue-5.15/drm-shmem-helper-unexport-drm_gem_shmem_create_with_.patch [new file with mode: 0644]
queue-5.15/drm-st7735r-fix-module-autoloading-for-okaya-rh12812.patch [new file with mode: 0644]
queue-5.15/drm-vc4-dsi-add-correct-stop-condition-to-vc4_dsi_en.patch [new file with mode: 0644]
queue-5.15/drm-vc4-dsi-correct-dsi-divider-calculations.patch [new file with mode: 0644]
queue-5.15/drm-vc4-dsi-correct-pixel-order-for-dsi0.patch [new file with mode: 0644]
queue-5.15/drm-vc4-dsi-fix-dsi0-interrupt-support.patch [new file with mode: 0644]
queue-5.15/drm-vc4-dsi-register-dsi0-as-the-correct-vc4-encoder.patch [new file with mode: 0644]
queue-5.15/drm-vc4-dsi-release-workaround-buffer-and-dma.patch [new file with mode: 0644]
queue-5.15/drm-vc4-dsi-switch-to-devm_drm_of_get_bridge.patch [new file with mode: 0644]
queue-5.15/drm-vc4-hdmi-avoid-full-hdmi-audio-fifo-writes.patch [new file with mode: 0644]
queue-5.15/drm-vc4-hdmi-correct-hdmi-timing-registers-for-inter.patch [new file with mode: 0644]
queue-5.15/drm-vc4-hdmi-fix-hpd-gpio-detection.patch [new file with mode: 0644]
queue-5.15/drm-vc4-hdmi-fix-timings-for-interlaced-modes.patch [new file with mode: 0644]
queue-5.15/drm-vc4-hdmi-reset-hdmi-misc_control-register.patch [new file with mode: 0644]
queue-5.15/drm-vc4-plane-fix-margin-calculations-for-the-right-.patch [new file with mode: 0644]
queue-5.15/drm-vc4-plane-remove-subpixel-positioning-check.patch [new file with mode: 0644]
queue-5.15/drm-vc4-use-of_device_get_match_data.patch [new file with mode: 0644]
queue-5.15/drm-virtio-fix-null-vs-is_err-checking-in-virtio_gpu.patch [new file with mode: 0644]
queue-5.15/dt-bindings-iio-accel-add-dt-binding-doc-for-adxl355.patch [new file with mode: 0644]
queue-5.15/eeprom-idt_89hpesx-uninitialized-data-in-idt_dbgfs_c.patch [new file with mode: 0644]
queue-5.15/erofs-avoid-consecutive-detection-for-highmem-memory.patch [new file with mode: 0644]
queue-5.15/ext2-add-more-validity-checks-for-inode-counts.patch [new file with mode: 0644]
queue-5.15/ext4-recover-csum-seed-of-tmp_inode-after-migrating-.patch [new file with mode: 0644]
queue-5.15/f2fs-allow-compression-for-mmap-files-in-compress_mo.patch [new file with mode: 0644]
queue-5.15/f2fs-do-not-allow-to-decompress-files-have-fi_compre.patch [new file with mode: 0644]
queue-5.15/f2fs-fix-to-remove-f2fs_compr_fl-and-tag-f2fs_nocomp.patch [new file with mode: 0644]
queue-5.15/firmware-tegra-fix-error-check-return-value-of-debug.patch [new file with mode: 0644]
queue-5.15/fpga-altera-pr-ip-fix-unsigned-comparison-with-less-.patch [new file with mode: 0644]
queue-5.15/fs-check-fmode_lseek-to-control-internal-pipe-splici.patch [new file with mode: 0644]
queue-5.15/fuse-remove-the-control-interface-for-virtio-fs.patch [new file with mode: 0644]
queue-5.15/genelf-use-have_libcrypto_support-not-the-never-defi.patch [new file with mode: 0644]
queue-5.15/genirq-don-t-return-error-on-missing-optional-irq_re.patch [new file with mode: 0644]
queue-5.15/genirq-generic_irq_ipi-depends-on-smp.patch [new file with mode: 0644]
queue-5.15/gpio-gpiolib-of-fix-refcount-bugs-in-of_mm_gpiochip_.patch [new file with mode: 0644]
queue-5.15/hid-alps-declare-u1_unicorn_legacy-support.patch [new file with mode: 0644]
queue-5.15/hid-amd_sfh-add-null-check-for-hid-device.patch [new file with mode: 0644]
queue-5.15/hid-amd_sfh-don-t-show-client-init-failed-as-error-w.patch [new file with mode: 0644]
queue-5.15/hid-amd_sfh-handle-condition-of-no-sensors.patch [new file with mode: 0644]
queue-5.15/hid-cp2112-prevent-a-buffer-overflow-in-cp2112_xfer.patch [new file with mode: 0644]
queue-5.15/hid-mcp2221-prevent-a-buffer-overflow-in-mcp_smbus_w.patch [new file with mode: 0644]
queue-5.15/hinic-use-the-bitmap-api-when-applicable.patch [new file with mode: 0644]
queue-5.15/hwmon-dell-smm-add-dell-xps-13-7390-to-fan-control-w.patch [new file with mode: 0644]
queue-5.15/hwmon-drivetemp-add-module-alias.patch [new file with mode: 0644]
queue-5.15/hwmon-sht15-fix-wrong-assumptions-in-device-remove-c.patch [new file with mode: 0644]
queue-5.15/i2c-cadence-support-pec-for-smbus-block-read.patch [new file with mode: 0644]
queue-5.15/i2c-fix-a-potential-use-after-free.patch [new file with mode: 0644]
queue-5.15/i2c-mux-gpmux-add-of_node_put-when-breaking-out-of-l.patch [new file with mode: 0644]
queue-5.15/i2c-mxs-silence-a-clang-warning.patch [new file with mode: 0644]
queue-5.15/i2c-npcm-correct-slave-role-behavior.patch [new file with mode: 0644]
queue-5.15/i2c-npcm-remove-own-slave-addresses-2-10.patch [new file with mode: 0644]
queue-5.15/iavf-fix-max_rate-limiting.patch [new file with mode: 0644]
queue-5.15/iavf-fix-tc-qdisc-show-listing-too-many-queues.patch [new file with mode: 0644]
queue-5.15/ieee80211-add-eht-1k-aggregation-definitions.patch [new file with mode: 0644]
queue-5.15/iio-accel-bma400-fix-the-scale-min-and-max-macro-val.patch [new file with mode: 0644]
queue-5.15/iio-accel-bma400-reordering-of-header-files.patch [new file with mode: 0644]
queue-5.15/iio-cros-register-fifo-callback-after-sensor-is-regi.patch [new file with mode: 0644]
queue-5.15/inet-add-read_once-sk-sk_bound_dev_if-in-inet_match.patch [new file with mode: 0644]
queue-5.15/intel_th-fix-a-resource-leak-in-an-error-handling-pa.patch [new file with mode: 0644]
queue-5.15/intel_th-msu-fix-vmalloced-buffers.patch [new file with mode: 0644]
queue-5.15/intel_th-msu-sink-potential-dereference-of-null-poin.patch [new file with mode: 0644]
queue-5.15/interconnect-imx-fix-max_node_id.patch [new file with mode: 0644]
queue-5.15/iommu-arm-smmu-qcom_iommu-add-of_node_put-when-break.patch [new file with mode: 0644]
queue-5.15/iommu-exynos-handle-failed-iommu-device-registration.patch [new file with mode: 0644]
queue-5.15/ipv6-add-read_once-sk-sk_bound_dev_if-in-inet6_match.patch [new file with mode: 0644]
queue-5.15/irqchip-mips-gic-check-the-return-value-of-ioremap-i.patch [new file with mode: 0644]
queue-5.15/irqchip-mips-gic-only-register-ipi-domain-when-smp-i.patch [new file with mode: 0644]
queue-5.15/irqdomain-report-irq-number-for-nomap-domains.patch [new file with mode: 0644]
queue-5.15/jbd2-fix-assertion-jh-b_frozen_data-null-failure-whe.patch [new file with mode: 0644]
queue-5.15/jbd2-fix-outstanding-credits-assert-in-jbd2_journal_.patch [new file with mode: 0644]
queue-5.15/kasan-test-silence-gcc-12-warnings.patch [new file with mode: 0644]
queue-5.15/kfifo-fix-kfifo_to_user-return-type.patch [new file with mode: 0644]
queue-5.15/kprobes-forbid-probing-on-trampoline-and-bpf-code-ar.patch [new file with mode: 0644]
queue-5.15/kvm-arm64-don-t-return-from-void-function.patch [new file with mode: 0644]
queue-5.15/kvm-don-t-set-accessed-dirty-bits-for-zero_page.patch [new file with mode: 0644]
queue-5.15/kvm-nvmx-set-umip-bit-cr4_fixed1-msr-when-emulating-.patch [new file with mode: 0644]
queue-5.15/kvm-s390-pv-leak-the-topmost-page-table-when-destroy.patch [new file with mode: 0644]
queue-5.15/kvm-svm-stuff-next_rip-on-emulated-int3-injection-if.patch [new file with mode: 0644]
queue-5.15/kvm-svm-unwind-speculative-rip-advancement-if-intn-i.patch [new file with mode: 0644]
queue-5.15/lib-smp_processor_id-fix-imbalanced-instrumentation_.patch [new file with mode: 0644]
queue-5.15/lib-test_hmm-avoid-accessing-uninitialized-pages.patch [new file with mode: 0644]
queue-5.15/libbpf-fix-an-snprintf-overflow-check.patch [new file with mode: 0644]
queue-5.15/libbpf-fix-the-name-of-a-reused-map.patch [new file with mode: 0644]
queue-5.15/locking-lockdep-fix-lockdep_init_map_-confusion.patch [new file with mode: 0644]
queue-5.15/media-atmel-atmel-sama7g5-isc-fix-warning-in-configs.patch [new file with mode: 0644]
queue-5.15/media-cedrus-h265-fix-flag-name.patch [new file with mode: 0644]
queue-5.15/media-cedrus-hevc-add-check-for-invalid-timestamp.patch [new file with mode: 0644]
queue-5.15/media-driver-nxp-imx-jpeg-fix-a-unexpected-return-va.patch [new file with mode: 0644]
queue-5.15/media-hantro-postproc-fix-motion-vector-space-size.patch [new file with mode: 0644]
queue-5.15/media-hantro-simplify-postprocessor.patch [new file with mode: 0644]
queue-5.15/media-hdpvr-fix-error-value-returns-in-hdpvr_read.patch [new file with mode: 0644]
queue-5.15/media-hevc-embedded-indexes-in-rps.patch [new file with mode: 0644]
queue-5.15/media-imx-jpeg-add-pm-runtime-support-for-imx-jpeg.patch [new file with mode: 0644]
queue-5.15/media-imx-jpeg-align-upwards-buffer-size.patch [new file with mode: 0644]
queue-5.15/media-imx-jpeg-correct-some-definition-according-spe.patch [new file with mode: 0644]
queue-5.15/media-imx-jpeg-disable-slot-interrupt-when-frame-don.patch [new file with mode: 0644]
queue-5.15/media-imx-jpeg-handle-source-change-in-a-function.patch [new file with mode: 0644]
queue-5.15/media-imx-jpeg-identify-and-handle-precision-correct.patch [new file with mode: 0644]
queue-5.15/media-imx-jpeg-implement-drain-using-v4l2-mem2mem-he.patch [new file with mode: 0644]
queue-5.15/media-imx-jpeg-leave-a-blank-space-before-the-config.patch [new file with mode: 0644]
queue-5.15/media-imx-jpeg-refactor-function-mxc_jpeg_parse.patch [new file with mode: 0644]
queue-5.15/media-imx-jpeg-set-v4l2_buf_flag_last-at-eos.patch [new file with mode: 0644]
queue-5.15/media-imx-jpeg-support-dynamic-resolution-change.patch [new file with mode: 0644]
queue-5.15/media-imx-jpeg-use-nv12m-to-represent-non-contiguous.patch [new file with mode: 0644]
queue-5.15/media-platform-mtk-mdp-fix-mdp_ipi_comm-structure-al.patch [new file with mode: 0644]
queue-5.15/media-staging-media-hantro-fix-typos.patch [new file with mode: 0644]
queue-5.15/media-tw686x-fix-memory-leak-in-tw686x_video_init.patch [new file with mode: 0644]
queue-5.15/media-tw686x-register-the-irq-at-the-end-of-probe.patch [new file with mode: 0644]
queue-5.15/media-v4l2-mem2mem-prevent-pollerr-when-last_buffer_.patch [new file with mode: 0644]
queue-5.15/mediatek-mt76-eeprom-fix-missing-of_node_put-in-mt76.patch [new file with mode: 0644]
queue-5.15/mediatek-mt76-mac80211-fix-missing-of_node_put-in-mt.patch [new file with mode: 0644]
queue-5.15/memremap-remove-support-for-external-pgmap-refcounts.patch [new file with mode: 0644]
queue-5.15/memstick-ms_block-fix-a-memory-leak.patch [new file with mode: 0644]
queue-5.15/memstick-ms_block-fix-some-incorrect-memory-allocati.patch [new file with mode: 0644]
queue-5.15/meson-mx-socinfo-fix-refcount-leak-in-meson_mx_socin.patch [new file with mode: 0644]
queue-5.15/mfd-max77620-fix-refcount-leak-in-max77620_initialis.patch [new file with mode: 0644]
queue-5.15/mfd-t7l66xb-drop-platform-disable-callback.patch [new file with mode: 0644]
queue-5.15/mips-fixed-__debug_virt_addr_valid.patch [new file with mode: 0644]
queue-5.15/mips-vdso-utilize-__pa-for-gic_pfn.patch [new file with mode: 0644]
queue-5.15/misc-rtsx-fix-an-error-handling-path-in-rtsx_pci_pro.patch [new file with mode: 0644]
queue-5.15/mm-mempolicy-fix-get_nodes-out-of-bound-access.patch [new file with mode: 0644]
queue-5.15/mm-memremap-fix-memunmap_pages-race-with-get_dev_pag.patch [new file with mode: 0644]
queue-5.15/mm-mmap.c-fix-missing-call-to-vm_unacct_memory-in-mm.patch [new file with mode: 0644]
queue-5.15/mmc-block-add-single-read-for-4k-sector-cards.patch [new file with mode: 0644]
queue-5.15/mmc-cavium-octeon-add-of_node_put-when-breaking-out-.patch [new file with mode: 0644]
queue-5.15/mmc-cavium-thunderx-add-of_node_put-when-breaking-ou.patch [new file with mode: 0644]
queue-5.15/mmc-mxcmmc-silence-a-clang-warning.patch [new file with mode: 0644]
queue-5.15/mmc-renesas_sdhi-get-the-reset-handle-early-in-the-p.patch [new file with mode: 0644]
queue-5.15/mmc-renesas_sdhi-get-the-reset-handle-early-in-the-p.patch-12121 [new file with mode: 0644]
queue-5.15/mmc-sdhci-of-at91-fix-set_uhs_signaling-rewriting-of.patch [new file with mode: 0644]
queue-5.15/mmc-sdhci-of-esdhc-fix-refcount-leak-in-esdhc_signal.patch [new file with mode: 0644]
queue-5.15/mt76-mt7615-do-not-update-pm-stats-in-case-of-error.patch [new file with mode: 0644]
queue-5.15/mt76-mt76x02u-fix-possible-memory-leak-in-__mt76x02u.patch [new file with mode: 0644]
queue-5.15/mt76-mt7921-enlarge-maximum-vht-mpdu-length-to-11454.patch [new file with mode: 0644]
queue-5.15/mt76-mt7921-fix-aggregation-subframes-setting-to-he-.patch [new file with mode: 0644]
queue-5.15/mtd-dataflash-add-spi-id-table.patch [new file with mode: 0644]
queue-5.15/mtd-maps-fix-refcount-leak-in-ap_flash_init.patch [new file with mode: 0644]
queue-5.15/mtd-maps-fix-refcount-leak-in-of_flash_probe_versati.patch [new file with mode: 0644]
queue-5.15/mtd-parsers-ofpart-fix-refcount-leak-in-bcm4908_part.patch [new file with mode: 0644]
queue-5.15/mtd-partitions-fix-refcount-leak-in-parse_redboot_of.patch [new file with mode: 0644]
queue-5.15/mtd-rawnand-meson-fix-a-potential-double-free-issue.patch [new file with mode: 0644]
queue-5.15/mtd-sm_ftl-fix-deadlock-caused-by-cancel_work_sync-i.patch [new file with mode: 0644]
queue-5.15/mtd-spi-nor-fix-spi_nor_spimem_setup_op-call-in-spi_.patch [new file with mode: 0644]
queue-5.15/mtd-st_spi_fsm-add-a-clk_disable_unprepare-in-.probe.patch [new file with mode: 0644]
queue-5.15/mwifiex-fix-sleep-in-atomic-context-bugs-caused-by-d.patch [new file with mode: 0644]
queue-5.15/mwifiex-ignore-btcoex-events-from-the-88w8897-firmwa.patch [new file with mode: 0644]
queue-5.15/net-9p-fix-refcount-leak-in-p9_read_work-error-handl.patch [new file with mode: 0644]
queue-5.15/net-allow-unbound-socket-for-packets-in-vrf-when-tcp.patch [new file with mode: 0644]
queue-5.15/net-fix-sk_wmem_schedule-and-sk_rmem_schedule-errors.patch [new file with mode: 0644]
queue-5.15/net-hinic-avoid-kernel-hung-in-hinic_get_stats64.patch [new file with mode: 0644]
queue-5.15/net-hinic-fix-bug-that-ethtool-get-wrong-stats.patch [new file with mode: 0644]
queue-5.15/net-ionic-fix-error-check-for-vlan-flags-in-ionic_se.patch [new file with mode: 0644]
queue-5.15/net-mlx5-adjust-log_max_qp-to-be-18-at-most.patch [new file with mode: 0644]
queue-5.15/net-mlx5e-fix-the-value-of-mlx5e_max_rq_num_mtts.patch [new file with mode: 0644]
queue-5.15/net-mlx5e-remove-warn_on-when-trying-to-offload-an-u.patch [new file with mode: 0644]
queue-5.15/net-rose-fix-netdev-reference-changes.patch [new file with mode: 0644]
queue-5.15/net-usb-make-usb_rtl8153_ecm-non-user-configurable.patch [new file with mode: 0644]
queue-5.15/netdevsim-avoid-allocation-warnings-triggered-from-u.patch [new file with mode: 0644]
queue-5.15/netdevsim-fib-fix-reference-count-leak-on-route-dele.patch [new file with mode: 0644]
queue-5.15/netfilter-nf_tables-add-rescheduling-points-during-l.patch [new file with mode: 0644]
queue-5.15/netfilter-xtables-bring-spdx-identifier-back.patch [new file with mode: 0644]
queue-5.15/nohz-full-sched-rt-fix-missed-tick-reenabling-bug-in.patch [new file with mode: 0644]
queue-5.15/null_blk-fix-ida-error-handling-in-null_add_dev.patch [new file with mode: 0644]
queue-5.15/nvme-catch-enodev-from-nvme_revalidate_zones-again.patch [new file with mode: 0644]
queue-5.15/nvme-define-compat_ioctl-again-to-unbreak-32-bit-use.patch [new file with mode: 0644]
queue-5.15/nvme-disable-namespace-access-for-unsupported-metada.patch [new file with mode: 0644]
queue-5.15/nvme-don-t-return-an-error-from-nvme_configure_metad.patch [new file with mode: 0644]
queue-5.15/nvme-use-command_id-instead-of-req-tag-in-trace_nvme.patch [new file with mode: 0644]
queue-5.15/of-check-previous-kernel-s-ima-kexec-buffer-against-.patch [new file with mode: 0644]
queue-5.15/of-device-fix-missing-of_node_put-in-of_dma_set_rest.patch [new file with mode: 0644]
queue-5.15/of-fdt-declared-return-type-does-not-match-actual-re.patch [new file with mode: 0644]
queue-5.15/opp-fix-error-check-in-dev_pm_opp_attach_genpd.patch [new file with mode: 0644]
queue-5.15/pci-dwc-add-unroll-iatu-space-support-to-dw_pcie_dis.patch [new file with mode: 0644]
queue-5.15/pci-dwc-always-enable-cdm-check-if-snps-enable-cdm-c.patch [new file with mode: 0644]
queue-5.15/pci-dwc-deallocate-epc-memory-on-dw_pcie_ep_init-err.patch [new file with mode: 0644]
queue-5.15/pci-dwc-disable-outbound-windows-only-for-controller.patch [new file with mode: 0644]
queue-5.15/pci-dwc-set-increase_region_size-flag-based-on-limit.patch [new file with mode: 0644]
queue-5.15/pci-dwc-stop-link-on-host_init-errors-and-de-initial.patch [new file with mode: 0644]
queue-5.15/pci-endpoint-don-t-stop-controller-when-unbinding-en.patch [new file with mode: 0644]
queue-5.15/pci-mediatek-gen3-fix-refcount-leak-in-mtk_pcie_init.patch [new file with mode: 0644]
queue-5.15/pci-microchip-fix-refcount-leak-in-mc_pcie_init_irq_.patch [new file with mode: 0644]
queue-5.15/pci-portdrv-don-t-disable-aer-reporting-in-get_port_.patch [new file with mode: 0644]
queue-5.15/pci-qcom-set-up-rev-2.1.0-parf_phy-before-enabling-c.patch [new file with mode: 0644]
queue-5.15/pci-tegra194-fix-link-up-retry-sequence.patch [new file with mode: 0644]
queue-5.15/pci-tegra194-fix-pm-error-handling-in-tegra_pcie_con.patch [new file with mode: 0644]
queue-5.15/pci-tegra194-fix-root-port-interrupt-handling.patch [new file with mode: 0644]
queue-5.15/perf-symbol-fail-to-read-phdr-workaround.patch [new file with mode: 0644]
queue-5.15/perf-tools-fix-dso_id-inode-generation-comparison.patch [new file with mode: 0644]
queue-5.15/phy-samsung-exynosautov9-ufs-correct-tsrv-register-c.patch [new file with mode: 0644]
queue-5.15/phy-stm32-fix-error-return-in-stm32_usbphyc_phy_init.patch [new file with mode: 0644]
queue-5.15/platform-chrome-cros_ec-always-expose-last-resume-re.patch [new file with mode: 0644]
queue-5.15/platform-olpc-fix-uninitialized-data-in-debugfs-writ.patch [new file with mode: 0644]
queue-5.15/pm-domains-ensure-genpd_debugfs_dir-exists-before-re.patch [new file with mode: 0644]
queue-5.15/pm-hibernate-defer-device-probing-when-resuming-from.patch [new file with mode: 0644]
queue-5.15/powerpc-32-call-mmu_mark_initmem_nx-regardless-of-da.patch [new file with mode: 0644]
queue-5.15/powerpc-32-do-not-allow-selection-of-e5500-or-e6500-.patch [new file with mode: 0644]
queue-5.15/powerpc-64s-disable-stack-variable-initialisation-fo.patch [new file with mode: 0644]
queue-5.15/powerpc-cell-axon_msi-fix-refcount-leak-in-setup_msi.patch [new file with mode: 0644]
queue-5.15/powerpc-iommu-fix-iommu_table_in_use-for-a-small-def.patch [new file with mode: 0644]
queue-5.15/powerpc-pci-fix-phb-numbering-when-using-opal-phbid.patch [new file with mode: 0644]
queue-5.15/powerpc-pci-prefer-pci-domain-assignment-via-dt-linu.patch [new file with mode: 0644]
queue-5.15/powerpc-perf-optimize-clearing-the-pending-pmi-and-r.patch [new file with mode: 0644]
queue-5.15/powerpc-spufs-fix-refcount-leak-in-spufs_init_isolat.patch [new file with mode: 0644]
queue-5.15/powerpc-xive-fix-refcount-leak-in-xive_get_max_prio.patch [new file with mode: 0644]
queue-5.15/proc-fix-a-dentry-lock-race-between-release_task-and.patch [new file with mode: 0644]
queue-5.15/profiling-fix-shift-too-large-makes-kernel-panic.patch [new file with mode: 0644]
queue-5.15/pwm-lpc18xx-fix-period-handling.patch [new file with mode: 0644]
queue-5.15/pwm-lpc18xx-sct-reduce-number-of-devm-memory-allocat.patch [new file with mode: 0644]
queue-5.15/pwm-lpc18xx-sct-simplify-driver-by-not-using-pwm_-gs.patch [new file with mode: 0644]
queue-5.15/pwm-sifive-ensure-the-clk-is-enabled-exactly-once-pe.patch [new file with mode: 0644]
queue-5.15/pwm-sifive-shut-down-hardware-only-after-pwmchip_rem.patch [new file with mode: 0644]
queue-5.15/pwm-sifive-simplify-offset-calculation-for-pwmcmp-re.patch [new file with mode: 0644]
queue-5.15/rcutorture-don-t-cpuhp_remove_state-if-cpuhp_setup_s.patch [new file with mode: 0644]
queue-5.15/rcutorture-fix-ksoftirqd-boosting-timing-and-iterati.patch [new file with mode: 0644]
queue-5.15/rcutorture-warn-on-individual-rcu_torture_init-error.patch [new file with mode: 0644]
queue-5.15/rdma-hfi1-fix-potential-memory-leak-in-setup_base_ct.patch [new file with mode: 0644]
queue-5.15/rdma-hns-fix-incorrect-clearing-of-interrupt-status-.patch [new file with mode: 0644]
queue-5.15/rdma-irdma-fix-a-window-for-use-after-free.patch [new file with mode: 0644]
queue-5.15/rdma-irdma-fix-setting-of-qp-context-err_rq_idx_vali.patch [new file with mode: 0644]
queue-5.15/rdma-irdma-fix-vlan-connection-with-wildcard-address.patch [new file with mode: 0644]
queue-5.15/rdma-mlx5-add-missing-check-for-return-value-in-get-.patch [new file with mode: 0644]
queue-5.15/rdma-qedr-fix-potential-memory-leak-in-__qedr_alloc_.patch [new file with mode: 0644]
queue-5.15/rdma-rtrs-clt-rename-rtrs_clt_sess-to-rtrs_clt_path.patch [new file with mode: 0644]
queue-5.15/rdma-rtrs-clt-replace-list_next_or_null_rr_rcu-with-.patch [new file with mode: 0644]
queue-5.15/rdma-rtrs-do-not-allow-sessname-to-contain-special-s.patch [new file with mode: 0644]
queue-5.15/rdma-rtrs-fix-warning-when-use-poll-mode-on-client-s.patch [new file with mode: 0644]
queue-5.15/rdma-rtrs-introduce-destroy_cq-helper.patch [new file with mode: 0644]
queue-5.15/rdma-rtrs-rename-rtrs_sess-to-rtrs_path.patch [new file with mode: 0644]
queue-5.15/rdma-rtrs-replace-duplicate-check-with-is_pollqueue-.patch [new file with mode: 0644]
queue-5.15/rdma-rtrs-srv-fix-modinfo-output-for-stringify.patch [new file with mode: 0644]
queue-5.15/rdma-rtrs-srv-rename-rtrs_srv_sess-to-rtrs_srv_path.patch [new file with mode: 0644]
queue-5.15/rdma-rxe-add-memory-barriers-to-kernel-queues.patch [new file with mode: 0644]
queue-5.15/rdma-rxe-fix-deadlock-in-rxe_do_local_ops.patch [new file with mode: 0644]
queue-5.15/rdma-rxe-fix-error-unwind-in-rxe_create_qp.patch [new file with mode: 0644]
queue-5.15/rdma-rxe-fix-mw-bind-to-allow-any-consumer-key-porti.patch [new file with mode: 0644]
queue-5.15/rdma-rxe-for-invalidate-compare-according-to-set-key.patch [new file with mode: 0644]
queue-5.15/rdma-rxe-remove-the-is_user-members-of-struct-rxe_sq.patch [new file with mode: 0644]
queue-5.15/rdma-siw-fix-duplicated-reported-iw_cm_event_connect.patch [new file with mode: 0644]
queue-5.15/rdma-srpt-duplicate-port-name-members.patch [new file with mode: 0644]
queue-5.15/rdma-srpt-fix-a-use-after-free.patch [new file with mode: 0644]
queue-5.15/rdma-srpt-introduce-a-reference-count-in-struct-srpt.patch [new file with mode: 0644]
queue-5.15/regulator-of-fix-refcount-leak-bug-in-of_get_regulat.patch [new file with mode: 0644]
queue-5.15/regulator-qcom_smd-fix-pm8916_pldo-range.patch [new file with mode: 0644]
queue-5.15/remoteproc-imx_rproc-fix-refcount-leak-in-imx_rproc_.patch [new file with mode: 0644]
queue-5.15/remoteproc-k3-r5-fix-refcount-leak-in-k3_r5_cluster_.patch [new file with mode: 0644]
queue-5.15/remoteproc-qcom-pas-check-if-coredump-is-enabled.patch [new file with mode: 0644]
queue-5.15/remoteproc-qcom-wcnss-fix-handling-of-irqs.patch [new file with mode: 0644]
queue-5.15/remoteproc-sysmon-wait-for-ssctl-service-to-come-up.patch [new file with mode: 0644]
queue-5.15/rpmsg-char-add-mutex-protection-for-rpmsg_eptdev_ope.patch [new file with mode: 0644]
queue-5.15/rpmsg-mtk_rpmsg-fix-circular-locking-dependency.patch [new file with mode: 0644]
queue-5.15/rpmsg-qcom_smd-fix-refcount-leak-in-qcom_smd_parse_e.patch [new file with mode: 0644]
queue-5.15/s390-crash-fix-incorrect-number-of-bytes-to-copy-to-.patch [new file with mode: 0644]
queue-5.15/s390-dump-fix-old-lowcore-virtual-vs-physical-addres.patch [new file with mode: 0644]
queue-5.15/s390-dump-fix-os_info-virtual-vs-physical-address-co.patch [new file with mode: 0644]
queue-5.15/s390-maccess-fix-semantics-of-memcpy_real-and-its-ca.patch [new file with mode: 0644]
queue-5.15/s390-maccess-rework-absolute-lowcore-accessors.patch [new file with mode: 0644]
queue-5.15/s390-smp-cleanup-control-register-update-routines.patch [new file with mode: 0644]
queue-5.15/s390-smp-cleanup-target-cpu-callback-starting.patch [new file with mode: 0644]
queue-5.15/s390-smp-enforce-lowcore-protection-on-cpu-restart.patch [new file with mode: 0644]
queue-5.15/s390-zcore-fix-race-when-reading-from-hardware-syste.patch [new file with mode: 0644]
queue-5.15/sched-core-always-flush-pending-blk_plug.patch [new file with mode: 0644]
queue-5.15/sched-core-do-not-requeue-task-on-cpu-excluded-from-.patch [new file with mode: 0644]
queue-5.15/sched-cpuset-fix-dl_cpu_busy-panic-due-to-empty-cs-c.patch [new file with mode: 0644]
queue-5.15/sched-deadline-merge-dl_task_can_attach-and-dl_cpu_b.patch [new file with mode: 0644]
queue-5.15/sched-fair-introduce-sis_util-to-search-idle-cpu-bas.patch [new file with mode: 0644]
queue-5.15/sched-fix-the-check-of-nr_running-at-queue-wakelist.patch [new file with mode: 0644]
queue-5.15/sched-remove-the-limitation-of-wf_on_cpu-on-wakelist.patch [new file with mode: 0644]
queue-5.15/scripts-faddr2line-fix-vmlinux-detection-on-arm64.patch [new file with mode: 0644]
queue-5.15/scripts-gdb-fix-lx-dmesg-on-32-bits-arch.patch [new file with mode: 0644]
queue-5.15/scripts-gdb-lx-dmesg-read-records-individually.patch [new file with mode: 0644]
queue-5.15/scsi-hisi_sas-use-managed-pci-functions.patch [new file with mode: 0644]
queue-5.15/scsi-iscsi-add-helper-to-remove-a-session-from-the-k.patch [new file with mode: 0644]
queue-5.15/scsi-iscsi-allow-iscsi_if_stop_conn-to-be-called-fro.patch [new file with mode: 0644]
queue-5.15/scsi-iscsi-fix-session-removal-on-shutdown.patch [new file with mode: 0644]
queue-5.15/scsi-qla2xxx-check-correct-variable-in-qla24xx_async.patch [new file with mode: 0644]
queue-5.15/scsi-qla2xxx-edif-add-retry-for-els-passthrough.patch [new file with mode: 0644]
queue-5.15/scsi-qla2xxx-edif-fix-inconsistent-check-of-db_flags.patch [new file with mode: 0644]
queue-5.15/scsi-qla2xxx-edif-fix-n2n-discovery-issue-with-secur.patch [new file with mode: 0644]
queue-5.15/scsi-qla2xxx-edif-fix-n2n-login-retry-for-secure-dev.patch [new file with mode: 0644]
queue-5.15/scsi-qla2xxx-edif-fix-no-login-after-app-start.patch [new file with mode: 0644]
queue-5.15/scsi-qla2xxx-edif-fix-no-logout-on-delete-for-n2n.patch [new file with mode: 0644]
queue-5.15/scsi-qla2xxx-edif-fix-potential-stuck-session-in-sa-.patch [new file with mode: 0644]
queue-5.15/scsi-qla2xxx-edif-fix-session-thrash.patch [new file with mode: 0644]
queue-5.15/scsi-qla2xxx-edif-reduce-connection-thrash.patch [new file with mode: 0644]
queue-5.15/scsi-qla2xxx-edif-reduce-disruption-due-to-multiple-.patch [new file with mode: 0644]
queue-5.15/scsi-qla2xxx-edif-reduce-initiator-initiator-thrashi.patch [new file with mode: 0644]
queue-5.15/scsi-qla2xxx-edif-send-logo-for-unexpected-ike-messa.patch [new file with mode: 0644]
queue-5.15/scsi-qla2xxx-edif-synchronize-npiv-deletion-with-aut.patch [new file with mode: 0644]
queue-5.15/scsi-qla2xxx-edif-tear-down-session-if-keys-have-bee.patch [new file with mode: 0644]
queue-5.15/scsi-smartpqi-fix-dma-direction-for-raid-requests.patch [new file with mode: 0644]
queue-5.15/selftests-bpf-fix-a-test-for-snprintf-overflow.patch [new file with mode: 0644]
queue-5.15/selftests-kvm-set-rax-before-vmcall.patch [new file with mode: 0644]
queue-5.15/selftests-livepatch-better-synchronize-test_klp_call.patch [new file with mode: 0644]
queue-5.15/selftests-seccomp-fix-compile-warning-when-cc-clang.patch [new file with mode: 0644]
queue-5.15/selftests-timers-clocksource-switch-fix-passing-erro.patch [new file with mode: 0644]
queue-5.15/selftests-timers-valid-adjtimex-build-fix-for-newer-.patch [new file with mode: 0644]
queue-5.15/selftests-xsk-destroy-bpf-resources-only-when-ctx-re.patch [new file with mode: 0644]
queue-5.15/selinux-add-boundary-check-in-put_entry.patch [new file with mode: 0644]
queue-5.15/selinux-fix-memleak-in-security_read_state_kernel.patch [new file with mode: 0644]
queue-5.15/serial-8250-dma-allow-driver-operations-before-start.patch [new file with mode: 0644]
queue-5.15/serial-8250-export-icr-access-helpers-for-internal-u.patch [new file with mode: 0644]
queue-5.15/serial-8250_bcm7271-save-restore-rts-in-suspend-resu.patch [new file with mode: 0644]
queue-5.15/serial-8250_dw-store-lsr-into-lsr_saved_flags-in-dw8.patch [new file with mode: 0644]
queue-5.15/serial-8250_fsl-don-t-report-fe-pe-and-oe-twice.patch [new file with mode: 0644]
queue-5.15/serial-store-character-timing-information-to-uart_po.patch [new file with mode: 0644]
queue-5.15/series
queue-5.15/skbuff-don-t-mix-ubuf_info-from-different-sources.patch [new file with mode: 0644]
queue-5.15/skmsg-fix-invalid-last-sg-check-in-sk_msg_recvmsg.patch [new file with mode: 0644]
queue-5.15/soc-amlogic-fix-refcount-leak-in-meson-secure-pwrc.c.patch [new file with mode: 0644]
queue-5.15/soc-fsl-guts-machine-variable-might-be-unset.patch [new file with mode: 0644]
queue-5.15/soc-qcom-aoss-fix-refcount-leak-in-qmp_cooling_devic.patch [new file with mode: 0644]
queue-5.15/soc-qcom-make-qcom_rpmpd-depend-on-pm.patch [new file with mode: 0644]
queue-5.15/soc-qcom-ocmem-fix-refcount-leak-in-of_get_ocmem.patch [new file with mode: 0644]
queue-5.15/soc-renesas-r8a779a0-sysc-fix-a2dp1-and-a2cv-2357-pd.patch [new file with mode: 0644]
queue-5.15/soundwire-bus_type-fix-remove-and-shutdown-support.patch [new file with mode: 0644]
queue-5.15/soundwire-revisit-driver-bind-unbind-and-callbacks.patch [new file with mode: 0644]
queue-5.15/spi-fix-simplification-of-devm_spi_register_controll.patch [new file with mode: 0644]
queue-5.15/spi-spi-altera-dfl-fix-an-error-handling-path.patch [new file with mode: 0644]
queue-5.15/spi-spi-rspi-fix-pio-fallback-on-rz-platforms.patch [new file with mode: 0644]
queue-5.15/spi-synquacer-add-missing-clk_disable_unprepare.patch [new file with mode: 0644]
queue-5.15/spi-tegra20-slink-fix-uaf-in-tegra_slink_remove.patch [new file with mode: 0644]
queue-5.15/stack-declare-randomize_-kstack_offset-to-fix-sparse.patch [new file with mode: 0644]
queue-5.15/staging-rtl8192u-fix-sleep-in-atomic-context-bug-in-.patch [new file with mode: 0644]
queue-5.15/swiotlb-fail-map-correctly-with-failed-io_tlb_defaul.patch [new file with mode: 0644]
queue-5.15/tcp-make-retransmitted-skb-fit-into-the-send-window.patch [new file with mode: 0644]
queue-5.15/test_bpf-fix-incorrect-netdev-features.patch [new file with mode: 0644]
queue-5.15/thermal-tools-tmon-include-pthread-and-time-headers-.patch [new file with mode: 0644]
queue-5.15/tools-thermal-fix-possible-path-truncations.patch [new file with mode: 0644]
queue-5.15/tty-n_gsm-delete-gsmtty-open-sabm-frame-when-config-.patch [new file with mode: 0644]
queue-5.15/tty-n_gsm-fix-dm-command.patch [new file with mode: 0644]
queue-5.15/tty-n_gsm-fix-missing-corner-cases-in-gsmld_poll.patch [new file with mode: 0644]
queue-5.15/tty-n_gsm-fix-missing-timer-to-handle-stalled-links.patch [new file with mode: 0644]
queue-5.15/tty-n_gsm-fix-non-flow-control-frames-during-mux-flo.patch [new file with mode: 0644]
queue-5.15/tty-n_gsm-fix-packet-re-transmission-without-open-co.patch [new file with mode: 0644]
queue-5.15/tty-n_gsm-fix-race-condition-in-gsmld_write.patch [new file with mode: 0644]
queue-5.15/tty-n_gsm-fix-resource-allocation-order-in-gsm_activ.patch [new file with mode: 0644]
queue-5.15/tty-n_gsm-fix-tty-registration-before-control-channe.patch [new file with mode: 0644]
queue-5.15/tty-n_gsm-fix-user-open-not-possible-at-responder-un.patch [new file with mode: 0644]
queue-5.15/tty-n_gsm-fix-wrong-queuing-behavior-in-gsm_dlci_dat.patch [new file with mode: 0644]
queue-5.15/tty-n_gsm-fix-wrong-t1-retry-count-handling.patch [new file with mode: 0644]
queue-5.15/tty-serial-fsl_lpuart-correct-the-count-of-break-cha.patch [new file with mode: 0644]
queue-5.15/um-random-don-t-initialise-hwrng-struct-with-zero.patch [new file with mode: 0644]
queue-5.15/usb-aspeed-vhub-fix-refcount-leak-bug-in-ast_vhub_in.patch [new file with mode: 0644]
queue-5.15/usb-cdns3-change-place-of-priv_ep-assignment-in-cdns.patch [new file with mode: 0644]
queue-5.15/usb-cdns3-don-t-use-priv_dev-uninitialized-in-cdns3_.patch [new file with mode: 0644]
queue-5.15/usb-dwc3-core-deprecate-gctl.coresoftreset.patch [new file with mode: 0644]
queue-5.15/usb-dwc3-core-do-not-perform-gctl_core_softreset-dur.patch [new file with mode: 0644]
queue-5.15/usb-dwc3-qcom-fix-missing-optional-irq-warnings.patch [new file with mode: 0644]
queue-5.15/usb-gadget-tegra-xudc-fix-error-check-in-tegra_xudc_.patch [new file with mode: 0644]
queue-5.15/usb-gadget-udc-amd5536-depends-on-has_dma.patch [new file with mode: 0644]
queue-5.15/usb-host-fix-refcount-leak-in-ehci_hcd_ppc_of_probe.patch [new file with mode: 0644]
queue-5.15/usb-host-xhci-use-snprintf-in-xhci_decode_trb.patch [new file with mode: 0644]
queue-5.15/usb-ohci-nxp-fix-refcount-leak-in-ohci_hcd_nxp_probe.patch [new file with mode: 0644]
queue-5.15/usb-serial-fix-tty-port-initialized-comments.patch [new file with mode: 0644]
queue-5.15/usb-xhci-tegra-fix-error-check.patch [new file with mode: 0644]
queue-5.15/vfio-ccw-do-not-change-fsm-state-in-subchannel-event.patch [new file with mode: 0644]
queue-5.15/video-fbdev-amba-clcd-fix-refcount-leak-bugs.patch [new file with mode: 0644]
queue-5.15/video-fbdev-arkfb-check-the-size-of-screen-before-me.patch [new file with mode: 0644]
queue-5.15/video-fbdev-arkfb-fix-a-divide-by-zero-bug-in-ark_se.patch [new file with mode: 0644]
queue-5.15/video-fbdev-s3fb-check-the-size-of-screen-before-mem.patch [new file with mode: 0644]
queue-5.15/video-fbdev-sis-fix-typos-in-sis_getmodeid.patch [new file with mode: 0644]
queue-5.15/video-fbdev-vt8623fb-check-the-size-of-screen-before.patch [new file with mode: 0644]
queue-5.15/virtio-gpu-fix-a-missing-check-to-avoid-null-derefer.patch [new file with mode: 0644]
queue-5.15/wait-fix-__wait_event_hrtimeout-for-rt-dl-tasks.patch [new file with mode: 0644]
queue-5.15/watchdog-armada_37xx_wdt-check-the-return-value-of-d.patch [new file with mode: 0644]
queue-5.15/watchdog-sp5100_tco-fix-a-memory-leak-of-efch-mmio-r.patch [new file with mode: 0644]
queue-5.15/wifi-iwlegacy-4965-fix-potential-off-by-one-overflow.patch [new file with mode: 0644]
queue-5.15/wifi-iwlwifi-mvm-fix-double-list_add-at-iwl_mvm_mac_.patch [new file with mode: 0644]
queue-5.15/wifi-libertas-fix-possible-refcount-leak-in-if_usb_p.patch [new file with mode: 0644]
queue-5.15/wifi-p54-add-missing-parentheses-in-p54_flush.patch [new file with mode: 0644]
queue-5.15/wifi-p54-fix-an-error-handling-path-in-p54spi_probe.patch [new file with mode: 0644]
queue-5.15/wifi-rtlwifi-fix-error-codes-in-rtl_debugfs_set_writ.patch [new file with mode: 0644]
queue-5.15/wifi-rtw88-check-the-return-value-of-alloc_workqueue.patch [new file with mode: 0644]
queue-5.15/wifi-wil6210-debugfs-fix-info-leak-in-wil_write_file.patch [new file with mode: 0644]
queue-5.15/wifi-wil6210-debugfs-fix-uninitialized-variable-use-.patch [new file with mode: 0644]
queue-5.15/wireguard-allowedips-don-t-corrupt-stack-when-detect.patch [new file with mode: 0644]
queue-5.15/wireguard-ratelimiter-use-hrtimer-in-selftest.patch [new file with mode: 0644]
queue-5.15/x86-bus_lock-don-t-assume-the-init-value-of-debugctl.patch [new file with mode: 0644]
queue-5.15/x86-entry-build-thunk_-bits-only-if-config_preemptio.patch [new file with mode: 0644]
queue-5.15/x86-extable-fix-ex_handler_msr-print-condition.patch [new file with mode: 0644]
queue-5.15/x86-handle-idle-nomwait-cmdline-properly-for-x86_idl.patch [new file with mode: 0644]
queue-5.15/x86-numa-use-cpumask_available-instead-of-hardcoded-.patch [new file with mode: 0644]
queue-5.15/x86-pmem-fix-platform-device-leak-in-error-path.patch [new file with mode: 0644]
queue-5.15/xtensa-iss-fix-handling-error-cases-in-iss_net_confi.patch [new file with mode: 0644]
queue-5.15/xtensa-iss-network-provide-release-callback.patch [new file with mode: 0644]

diff --git a/queue-5.15/9p-add-client-parameter-to-p9_req_put.patch b/queue-5.15/9p-add-client-parameter-to-p9_req_put.patch
new file mode 100644 (file)
index 0000000..c703710
--- /dev/null
@@ -0,0 +1,198 @@
+From 8dcf085e03ead3a4d6a8cadf2b37f897d80a0ba2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 3 Jul 2022 21:08:18 -0400
+Subject: 9p: Add client parameter to p9_req_put()
+
+From: Kent Overstreet <kent.overstreet@gmail.com>
+
+[ Upstream commit 8b11ff098af42b1fa57fc817daadd53c8b244a0c ]
+
+This is to aid in adding mempools, in the next patch.
+
+Link: https://lkml.kernel.org/r/20220704014243.153050-2-kent.overstreet@gmail.com
+Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
+Cc: Eric Van Hensbergen <ericvh@gmail.com>
+Cc: Latchesar Ionkov <lucho@ionkov.net>
+Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/9p/client.h |  2 +-
+ net/9p/client.c         | 12 ++++++------
+ net/9p/trans_fd.c       | 12 ++++++------
+ net/9p/trans_rdma.c     |  2 +-
+ net/9p/trans_virtio.c   |  4 ++--
+ net/9p/trans_xen.c      |  2 +-
+ 6 files changed, 17 insertions(+), 17 deletions(-)
+
+diff --git a/include/net/9p/client.h b/include/net/9p/client.h
+index 67c854d07d7e..7060de84c559 100644
+--- a/include/net/9p/client.h
++++ b/include/net/9p/client.h
+@@ -237,7 +237,7 @@ static inline int p9_req_try_get(struct p9_req_t *r)
+       return refcount_inc_not_zero(&r->refcount);
+ }
+-int p9_req_put(struct p9_req_t *r);
++int p9_req_put(struct p9_client *c, struct p9_req_t *r);
+ void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status);
+diff --git a/net/9p/client.c b/net/9p/client.c
+index 5835fe4aebd7..866f02e88c79 100644
+--- a/net/9p/client.c
++++ b/net/9p/client.c
+@@ -343,7 +343,7 @@ struct p9_req_t *p9_tag_lookup(struct p9_client *c, u16 tag)
+               if (!p9_req_try_get(req))
+                       goto again;
+               if (req->tc.tag != tag) {
+-                      p9_req_put(req);
++                      p9_req_put(c, req);
+                       goto again;
+               }
+       }
+@@ -369,10 +369,10 @@ static int p9_tag_remove(struct p9_client *c, struct p9_req_t *r)
+       spin_lock_irqsave(&c->lock, flags);
+       idr_remove(&c->reqs, tag);
+       spin_unlock_irqrestore(&c->lock, flags);
+-      return p9_req_put(r);
++      return p9_req_put(c, r);
+ }
+-int p9_req_put(struct p9_req_t *r)
++int p9_req_put(struct p9_client *c, struct p9_req_t *r)
+ {
+       if (refcount_dec_and_test(&r->refcount)) {
+               p9_fcall_fini(&r->tc);
+@@ -425,7 +425,7 @@ void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status)
+       wake_up(&req->wq);
+       p9_debug(P9_DEBUG_MUX, "wakeup: %d\n", req->tc.tag);
+-      p9_req_put(req);
++      p9_req_put(c, req);
+ }
+ EXPORT_SYMBOL(p9_client_cb);
+@@ -708,7 +708,7 @@ static struct p9_req_t *p9_client_prepare_req(struct p9_client *c,
+ reterr:
+       p9_tag_remove(c, req);
+       /* We have to put also the 2nd reference as it won't be used */
+-      p9_req_put(req);
++      p9_req_put(c, req);
+       return ERR_PTR(err);
+ }
+@@ -745,7 +745,7 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
+       err = c->trans_mod->request(c, req);
+       if (err < 0) {
+               /* write won't happen */
+-              p9_req_put(req);
++              p9_req_put(c, req);
+               if (err != -ERESTARTSYS && err != -EFAULT)
+                       c->status = Disconnected;
+               goto recalc_sigpending;
+diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
+index 007bbcc68010..c55c8a608bc7 100644
+--- a/net/9p/trans_fd.c
++++ b/net/9p/trans_fd.c
+@@ -380,7 +380,7 @@ static void p9_read_work(struct work_struct *work)
+               m->rc.sdata = NULL;
+               m->rc.offset = 0;
+               m->rc.capacity = 0;
+-              p9_req_put(m->rreq);
++              p9_req_put(m->client, m->rreq);
+               m->rreq = NULL;
+       }
+@@ -494,7 +494,7 @@ static void p9_write_work(struct work_struct *work)
+       m->wpos += err;
+       if (m->wpos == m->wsize) {
+               m->wpos = m->wsize = 0;
+-              p9_req_put(m->wreq);
++              p9_req_put(m->client, m->wreq);
+               m->wreq = NULL;
+       }
+@@ -697,7 +697,7 @@ static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req)
+       if (req->status == REQ_STATUS_UNSENT) {
+               list_del(&req->req_list);
+               req->status = REQ_STATUS_FLSHD;
+-              p9_req_put(req);
++              p9_req_put(client, req);
+               ret = 0;
+       }
+       spin_unlock(&client->lock);
+@@ -724,7 +724,7 @@ static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req)
+       list_del(&req->req_list);
+       req->status = REQ_STATUS_FLSHD;
+       spin_unlock(&client->lock);
+-      p9_req_put(req);
++      p9_req_put(client, req);
+       return 0;
+ }
+@@ -885,12 +885,12 @@ static void p9_conn_destroy(struct p9_conn *m)
+       p9_mux_poll_stop(m);
+       cancel_work_sync(&m->rq);
+       if (m->rreq) {
+-              p9_req_put(m->rreq);
++              p9_req_put(m->client, m->rreq);
+               m->rreq = NULL;
+       }
+       cancel_work_sync(&m->wq);
+       if (m->wreq) {
+-              p9_req_put(m->wreq);
++              p9_req_put(m->client, m->wreq);
+               m->wreq = NULL;
+       }
+diff --git a/net/9p/trans_rdma.c b/net/9p/trans_rdma.c
+index af0a8a6cd3fd..f6d145873b49 100644
+--- a/net/9p/trans_rdma.c
++++ b/net/9p/trans_rdma.c
+@@ -352,7 +352,7 @@ send_done(struct ib_cq *cq, struct ib_wc *wc)
+                           c->busa, c->req->tc.size,
+                           DMA_TO_DEVICE);
+       up(&rdma->sq_sem);
+-      p9_req_put(c->req);
++      p9_req_put(client, c->req);
+       kfree(c);
+ }
+diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
+index 490a4c900339..d110df3cb4e1 100644
+--- a/net/9p/trans_virtio.c
++++ b/net/9p/trans_virtio.c
+@@ -199,7 +199,7 @@ static int p9_virtio_cancel(struct p9_client *client, struct p9_req_t *req)
+ /* Reply won't come, so drop req ref */
+ static int p9_virtio_cancelled(struct p9_client *client, struct p9_req_t *req)
+ {
+-      p9_req_put(req);
++      p9_req_put(client, req);
+       return 0;
+ }
+@@ -523,7 +523,7 @@ p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req,
+       kvfree(out_pages);
+       if (!kicked) {
+               /* reply won't come */
+-              p9_req_put(req);
++              p9_req_put(client, req);
+       }
+       return err;
+ }
+diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c
+index 432ac5a16f2e..427f6caefa29 100644
+--- a/net/9p/trans_xen.c
++++ b/net/9p/trans_xen.c
+@@ -186,7 +186,7 @@ static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req)
+       ring->intf->out_prod = prod;
+       spin_unlock_irqrestore(&ring->lock, flags);
+       notify_remote_via_irq(ring->irq);
+-      p9_req_put(p9_req);
++      p9_req_put(client, p9_req);
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/9p-drop-kref-usage.patch b/queue-5.15/9p-drop-kref-usage.patch
new file mode 100644 (file)
index 0000000..cf93845
--- /dev/null
@@ -0,0 +1,94 @@
+From a4136719b44e88e7359c74a634e709a4a88b12c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 3 Jul 2022 21:02:49 -0400
+Subject: 9p: Drop kref usage
+
+From: Kent Overstreet <kent.overstreet@gmail.com>
+
+[ Upstream commit 6cda12864cb0f99810a5809e11e3ee5b102c9a47 ]
+
+An upcoming patch is going to require passing the client through
+p9_req_put() -> p9_req_free(), but that's awkward with the kref
+indirection - so this patch switches to using refcount_t directly.
+
+Link: https://lkml.kernel.org/r/20220704014243.153050-1-kent.overstreet@gmail.com
+Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
+Cc: Eric Van Hensbergen <ericvh@gmail.com>
+Cc: Latchesar Ionkov <lucho@ionkov.net>
+Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/9p/client.h |  6 +++---
+ net/9p/client.c         | 19 ++++++++-----------
+ 2 files changed, 11 insertions(+), 14 deletions(-)
+
+diff --git a/include/net/9p/client.h b/include/net/9p/client.h
+index 334dc748fb3f..67c854d07d7e 100644
+--- a/include/net/9p/client.h
++++ b/include/net/9p/client.h
+@@ -78,7 +78,7 @@ enum p9_req_status_t {
+ struct p9_req_t {
+       int status;
+       int t_err;
+-      struct kref refcount;
++      refcount_t refcount;
+       wait_queue_head_t wq;
+       struct p9_fcall tc;
+       struct p9_fcall rc;
+@@ -229,12 +229,12 @@ struct p9_req_t *p9_tag_lookup(struct p9_client *c, u16 tag);
+ static inline void p9_req_get(struct p9_req_t *r)
+ {
+-      kref_get(&r->refcount);
++      refcount_inc(&r->refcount);
+ }
+ static inline int p9_req_try_get(struct p9_req_t *r)
+ {
+-      return kref_get_unless_zero(&r->refcount);
++      return refcount_inc_not_zero(&r->refcount);
+ }
+ int p9_req_put(struct p9_req_t *r);
+diff --git a/net/9p/client.c b/net/9p/client.c
+index 33a53f016e73..5835fe4aebd7 100644
+--- a/net/9p/client.c
++++ b/net/9p/client.c
+@@ -307,7 +307,7 @@ p9_tag_alloc(struct p9_client *c, int8_t type, unsigned int max_size)
+        * callback), so p9_client_cb eats the second ref there
+        * as the pointer is duplicated directly by virtqueue_add_sgs()
+        */
+-      refcount_set(&req->refcount.refcount, 2);
++      refcount_set(&req->refcount, 2);
+       return req;
+@@ -372,18 +372,15 @@ static int p9_tag_remove(struct p9_client *c, struct p9_req_t *r)
+       return p9_req_put(r);
+ }
+-static void p9_req_free(struct kref *ref)
+-{
+-      struct p9_req_t *r = container_of(ref, struct p9_req_t, refcount);
+-
+-      p9_fcall_fini(&r->tc);
+-      p9_fcall_fini(&r->rc);
+-      kmem_cache_free(p9_req_cache, r);
+-}
+-
+ int p9_req_put(struct p9_req_t *r)
+ {
+-      return kref_put(&r->refcount, p9_req_free);
++      if (refcount_dec_and_test(&r->refcount)) {
++              p9_fcall_fini(&r->tc);
++              p9_fcall_fini(&r->rc);
++              kmem_cache_free(p9_req_cache, r);
++              return 1;
++      }
++      return 0;
+ }
+ EXPORT_SYMBOL(p9_req_put);
+-- 
+2.35.1
+
diff --git a/queue-5.15/9p-fix-a-bunch-of-checkpatch-warnings.patch b/queue-5.15/9p-fix-a-bunch-of-checkpatch-warnings.patch
new file mode 100644 (file)
index 0000000..810786e
--- /dev/null
@@ -0,0 +1,1813 @@
+From e1bc4da50338ee5bc8a76ac048a9c95981b17d4c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Nov 2021 22:16:43 +0900
+Subject: 9p: fix a bunch of checkpatch warnings
+
+From: Dominique Martinet <asmadeus@codewreck.org>
+
+[ Upstream commit 6e195b0f7c8e50927fa31946369c22a0534ec7e2 ]
+
+Sohaib Mohamed started a serie of tiny and incomplete checkpatch fixes but
+seemingly stopped halfway -- take over and do most of it.
+This is still missing net/9p/trans* and net/9p/protocol.c for a later
+time...
+
+Link: http://lkml.kernel.org/r/20211102134608.1588018-3-dominique.martinet@atmark-techno.com
+Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/9p/acl.c                |   1 +
+ fs/9p/acl.h                |  17 +-
+ fs/9p/cache.c              |   4 +-
+ fs/9p/v9fs.c               |   4 +
+ fs/9p/v9fs_vfs.h           |  11 +-
+ fs/9p/vfs_addr.c           |   6 +-
+ fs/9p/vfs_dentry.c         |   2 +
+ fs/9p/vfs_file.c           |   1 +
+ fs/9p/vfs_inode.c          |  14 +-
+ fs/9p/vfs_inode_dotl.c     |   9 +-
+ fs/9p/vfs_super.c          |   7 +-
+ fs/9p/xattr.h              |  19 +-
+ include/net/9p/9p.h        |  10 +-
+ include/net/9p/client.h    |  22 +-
+ include/net/9p/transport.h |  18 +-
+ net/9p/client.c            | 432 ++++++++++++++++++-------------------
+ net/9p/error.c             |   2 +-
+ net/9p/mod.c               |   9 +-
+ net/9p/protocol.c          |  36 ++--
+ net/9p/protocol.h          |   2 +-
+ net/9p/trans_common.h      |   2 +-
+ 21 files changed, 323 insertions(+), 305 deletions(-)
+
+diff --git a/fs/9p/acl.c b/fs/9p/acl.c
+index c381499f5416..da22415ed036 100644
+--- a/fs/9p/acl.c
++++ b/fs/9p/acl.c
+@@ -123,6 +123,7 @@ static int v9fs_set_acl(struct p9_fid *fid, int type, struct posix_acl *acl)
+       char *name;
+       size_t size;
+       void *buffer;
++
+       if (!acl)
+               return 0;
+diff --git a/fs/9p/acl.h b/fs/9p/acl.h
+index d43c8949e807..bc87b36f529e 100644
+--- a/fs/9p/acl.h
++++ b/fs/9p/acl.h
+@@ -15,14 +15,15 @@
+ #define FS_9P_ACL_H
+ #ifdef CONFIG_9P_FS_POSIX_ACL
+-extern int v9fs_get_acl(struct inode *, struct p9_fid *);
+-extern struct posix_acl *v9fs_iop_get_acl(struct inode *inode, int type, bool rcu);
+-extern int v9fs_acl_chmod(struct inode *, struct p9_fid *);
+-extern int v9fs_set_create_acl(struct inode *, struct p9_fid *,
+-                             struct posix_acl *, struct posix_acl *);
+-extern int v9fs_acl_mode(struct inode *dir, umode_t *modep,
+-                       struct posix_acl **dpacl, struct posix_acl **pacl);
+-extern void v9fs_put_acl(struct posix_acl *dacl, struct posix_acl *acl);
++int v9fs_get_acl(struct inode *inode, struct p9_fid *fid);
++struct posix_acl *v9fs_iop_get_acl(struct inode *inode, int type,
++                                 bool rcu);
++int v9fs_acl_chmod(struct inode *inode, struct p9_fid *fid);
++int v9fs_set_create_acl(struct inode *inode, struct p9_fid *fid,
++                      struct posix_acl *dacl, struct posix_acl *acl);
++int v9fs_acl_mode(struct inode *dir, umode_t *modep,
++                struct posix_acl **dpacl, struct posix_acl **pacl);
++void v9fs_put_acl(struct posix_acl *dacl, struct posix_acl *acl);
+ #else
+ #define v9fs_iop_get_acl NULL
+ static inline int v9fs_get_acl(struct inode *inode, struct p9_fid *fid)
+diff --git a/fs/9p/cache.c b/fs/9p/cache.c
+index 1769a44f4819..41da71320482 100644
+--- a/fs/9p/cache.c
++++ b/fs/9p/cache.c
+@@ -19,8 +19,8 @@
+ #define CACHETAG_LEN  11
+ struct fscache_netfs v9fs_cache_netfs = {
+-      .name           = "9p",
+-      .version        = 0,
++      .name           = "9p",
++      .version        = 0,
+ };
+ /*
+diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
+index 2e0fa7c932db..141067379f5e 100644
+--- a/fs/9p/v9fs.c
++++ b/fs/9p/v9fs.c
+@@ -190,8 +190,10 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
+       while ((p = strsep(&options, ",")) != NULL) {
+               int token, r;
++
+               if (!*p)
+                       continue;
++
+               token = match_token(p, tokens, args);
+               switch (token) {
+               case Opt_debug:
+@@ -659,6 +661,7 @@ static void v9fs_destroy_inode_cache(void)
+ static int v9fs_cache_register(void)
+ {
+       int ret;
++
+       ret = v9fs_init_inode_cache();
+       if (ret < 0)
+               return ret;
+@@ -686,6 +689,7 @@ static void v9fs_cache_unregister(void)
+ static int __init init_v9fs(void)
+ {
+       int err;
++
+       pr_info("Installing v9fs 9p2000 file system support\n");
+       /* TODO: Setup list of registered trasnport modules */
+diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h
+index d44ade76966a..bc417da7e9c1 100644
+--- a/fs/9p/v9fs_vfs.h
++++ b/fs/9p/v9fs_vfs.h
+@@ -44,9 +44,10 @@ extern struct kmem_cache *v9fs_inode_cache;
+ struct inode *v9fs_alloc_inode(struct super_block *sb);
+ void v9fs_free_inode(struct inode *inode);
+-struct inode *v9fs_get_inode(struct super_block *sb, umode_t mode, dev_t);
++struct inode *v9fs_get_inode(struct super_block *sb, umode_t mode,
++                           dev_t rdev);
+ int v9fs_init_inode(struct v9fs_session_info *v9ses,
+-                  struct inode *inode, umode_t mode, dev_t);
++                  struct inode *inode, umode_t mode, dev_t rdev);
+ void v9fs_evict_inode(struct inode *inode);
+ ino_t v9fs_qid2ino(struct p9_qid *qid);
+ void v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode,
+@@ -59,8 +60,8 @@ void v9fs_inode2stat(struct inode *inode, struct p9_wstat *stat);
+ int v9fs_uflags2omode(int uflags, int extended);
+ void v9fs_blank_wstat(struct p9_wstat *wstat);
+-int v9fs_vfs_setattr_dotl(struct user_namespace *, struct dentry *,
+-                        struct iattr *);
++int v9fs_vfs_setattr_dotl(struct user_namespace *mnt_userns,
++                        struct dentry *dentry, struct iattr *iattr);
+ int v9fs_file_fsync_dotl(struct file *filp, loff_t start, loff_t end,
+                        int datasync);
+ int v9fs_refresh_inode(struct p9_fid *fid, struct inode *inode);
+@@ -68,9 +69,9 @@ int v9fs_refresh_inode_dotl(struct p9_fid *fid, struct inode *inode);
+ static inline void v9fs_invalidate_inode_attr(struct inode *inode)
+ {
+       struct v9fs_inode *v9inode;
++
+       v9inode = V9FS_I(inode);
+       v9inode->cache_validity |= V9FS_INO_INVALID_ATTR;
+-      return;
+ }
+ int v9fs_open_to_dotl_flags(int flags);
+diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c
+index 1c4f1b39cc95..606d33ef35c6 100644
+--- a/fs/9p/vfs_addr.c
++++ b/fs/9p/vfs_addr.c
+@@ -242,11 +242,13 @@ v9fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
+       loff_t pos = iocb->ki_pos;
+       ssize_t n;
+       int err = 0;
++
+       if (iov_iter_rw(iter) == WRITE) {
+               n = p9_client_write(file->private_data, pos, iter, &err);
+               if (n) {
+                       struct inode *inode = file_inode(file);
+                       loff_t i_size = i_size_read(inode);
++
+                       if (pos + n > i_size)
+                               inode_add_bytes(inode, pos + n - i_size);
+               }
+@@ -257,7 +259,7 @@ v9fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
+ }
+ static int v9fs_write_begin(struct file *filp, struct address_space *mapping,
+-                          loff_t pos, unsigned len, unsigned flags,
++                          loff_t pos, unsigned int len, unsigned int flags,
+                           struct page **pagep, void **fsdata)
+ {
+       int retval = 0;
+@@ -293,7 +295,7 @@ static int v9fs_write_begin(struct file *filp, struct address_space *mapping,
+ }
+ static int v9fs_write_end(struct file *filp, struct address_space *mapping,
+-                        loff_t pos, unsigned len, unsigned copied,
++                        loff_t pos, unsigned int len, unsigned int copied,
+                         struct page *page, void *fsdata)
+ {
+       loff_t last_pos = pos + copied;
+diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c
+index 4b4292123b3d..c2736af97884 100644
+--- a/fs/9p/vfs_dentry.c
++++ b/fs/9p/vfs_dentry.c
+@@ -52,6 +52,7 @@ static int v9fs_cached_dentry_delete(const struct dentry *dentry)
+ static void v9fs_dentry_release(struct dentry *dentry)
+ {
+       struct hlist_node *p, *n;
++
+       p9_debug(P9_DEBUG_VFS, " dentry: %pd (%p)\n",
+                dentry, dentry);
+       hlist_for_each_safe(p, n, (struct hlist_head *)&dentry->d_fsdata)
+@@ -76,6 +77,7 @@ static int v9fs_lookup_revalidate(struct dentry *dentry, unsigned int flags)
+       if (v9inode->cache_validity & V9FS_INO_INVALID_ATTR) {
+               int retval;
+               struct v9fs_session_info *v9ses;
++
+               fid = v9fs_fid_lookup(dentry);
+               if (IS_ERR(fid))
+                       return PTR_ERR(fid);
+diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
+index 246235ebdb70..7437b185fa8e 100644
+--- a/fs/9p/vfs_file.c
++++ b/fs/9p/vfs_file.c
+@@ -408,6 +408,7 @@ v9fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
+               struct inode *inode = file_inode(file);
+               loff_t i_size;
+               unsigned long pg_start, pg_end;
++
+               pg_start = origin >> PAGE_SHIFT;
+               pg_end = (origin + retval - 1) >> PAGE_SHIFT;
+               if (inode->i_mapping && inode->i_mapping->nrpages)
+diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
+index 15d9492536cf..0d9b7d453a87 100644
+--- a/fs/9p/vfs_inode.c
++++ b/fs/9p/vfs_inode.c
+@@ -49,6 +49,7 @@ static const struct inode_operations v9fs_symlink_inode_operations;
+ static u32 unixmode2p9mode(struct v9fs_session_info *v9ses, umode_t mode)
+ {
+       int res;
++
+       res = mode & 0777;
+       if (S_ISDIR(mode))
+               res |= P9_DMDIR;
+@@ -223,6 +224,7 @@ v9fs_blank_wstat(struct p9_wstat *wstat)
+ struct inode *v9fs_alloc_inode(struct super_block *sb)
+ {
+       struct v9fs_inode *v9inode;
++
+       v9inode = kmem_cache_alloc(v9fs_inode_cache, GFP_KERNEL);
+       if (!v9inode)
+               return NULL;
+@@ -251,7 +253,7 @@ int v9fs_init_inode(struct v9fs_session_info *v9ses,
+ {
+       int err = 0;
+-      inode_init_owner(&init_user_ns,inode,  NULL, mode);
++      inode_init_owner(&init_user_ns, inode, NULL, mode);
+       inode->i_blocks = 0;
+       inode->i_rdev = rdev;
+       inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
+@@ -440,7 +442,7 @@ static struct inode *v9fs_qid_iget(struct super_block *sb,
+       unsigned long i_ino;
+       struct inode *inode;
+       struct v9fs_session_info *v9ses = sb->s_fs_info;
+-      int (*test)(struct inode *, void *);
++      int (*test)(struct inode *inode, void *data);
+       if (new)
+               test = v9fs_test_new_inode;
+@@ -499,8 +501,10 @@ v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
+ static int v9fs_at_to_dotl_flags(int flags)
+ {
+       int rflags = 0;
++
+       if (flags & AT_REMOVEDIR)
+               rflags |= P9_DOTL_AT_REMOVEDIR;
++
+       return rflags;
+ }
+@@ -797,7 +801,7 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
+ static int
+ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry,
+-                   struct file *file, unsigned flags, umode_t mode)
++                   struct file *file, unsigned int flags, umode_t mode)
+ {
+       int err;
+       u32 perm;
+@@ -1084,7 +1088,7 @@ static int v9fs_vfs_setattr(struct user_namespace *mnt_userns,
+               fid = v9fs_fid_lookup(dentry);
+               use_dentry = 1;
+       }
+-      if(IS_ERR(fid))
++      if (IS_ERR(fid))
+               return PTR_ERR(fid);
+       v9fs_blank_wstat(&wstat);
+@@ -1364,7 +1368,7 @@ v9fs_vfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
+       char name[2 + U32_MAX_DIGITS + 1 + U32_MAX_DIGITS + 1];
+       u32 perm;
+-      p9_debug(P9_DEBUG_VFS, " %lu,%pd mode: %hx MAJOR: %u MINOR: %u\n",
++      p9_debug(P9_DEBUG_VFS, " %lu,%pd mode: %x MAJOR: %u MINOR: %u\n",
+                dir->i_ino, dentry, mode,
+                MAJOR(rdev), MINOR(rdev));
+diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c
+index 833c638437a7..0f73aa26ddf4 100644
+--- a/fs/9p/vfs_inode_dotl.c
++++ b/fs/9p/vfs_inode_dotl.c
+@@ -107,7 +107,7 @@ static struct inode *v9fs_qid_iget_dotl(struct super_block *sb,
+       unsigned long i_ino;
+       struct inode *inode;
+       struct v9fs_session_info *v9ses = sb->s_fs_info;
+-      int (*test)(struct inode *, void *);
++      int (*test)(struct inode *inode, void *data);
+       if (new)
+               test = v9fs_test_new_inode_dotl;
+@@ -230,7 +230,7 @@ v9fs_vfs_create_dotl(struct user_namespace *mnt_userns, struct inode *dir,
+ static int
+ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
+-                        struct file *file, unsigned flags, umode_t omode)
++                        struct file *file, unsigned int flags, umode_t omode)
+ {
+       int err = 0;
+       kgid_t gid;
+@@ -261,7 +261,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
+       v9ses = v9fs_inode2v9ses(dir);
+       name = dentry->d_name.name;
+-      p9_debug(P9_DEBUG_VFS, "name:%s flags:0x%x mode:0x%hx\n",
++      p9_debug(P9_DEBUG_VFS, "name:%s flags:0x%x mode:0x%x\n",
+                name, flags, omode);
+       dfid = v9fs_parent_fid(dentry);
+@@ -821,6 +821,7 @@ v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir,
+       if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
+               /* Get the latest stat info from server. */
+               struct p9_fid *fid;
++
+               fid = v9fs_fid_lookup(old_dentry);
+               if (IS_ERR(fid))
+                       return PTR_ERR(fid);
+@@ -857,7 +858,7 @@ v9fs_vfs_mknod_dotl(struct user_namespace *mnt_userns, struct inode *dir,
+       struct p9_qid qid;
+       struct posix_acl *dacl = NULL, *pacl = NULL;
+-      p9_debug(P9_DEBUG_VFS, " %lu,%pd mode: %hx MAJOR: %u MINOR: %u\n",
++      p9_debug(P9_DEBUG_VFS, " %lu,%pd mode: %x MAJOR: %u MINOR: %u\n",
+                dir->i_ino, dentry, omode,
+                MAJOR(rdev), MINOR(rdev));
+diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
+index 5fce6e30bc5a..7449f7fd47d2 100644
+--- a/fs/9p/vfs_super.c
++++ b/fs/9p/vfs_super.c
+@@ -113,7 +113,7 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags,
+       struct inode *inode = NULL;
+       struct dentry *root = NULL;
+       struct v9fs_session_info *v9ses = NULL;
+-      umode_t mode = S_IRWXUGO | S_ISVTX;
++      umode_t mode = 0777 | S_ISVTX;
+       struct p9_fid *fid;
+       int retval = 0;
+@@ -157,6 +157,7 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags,
+       sb->s_root = root;
+       if (v9fs_proto_dotl(v9ses)) {
+               struct p9_stat_dotl *st = NULL;
++
+               st = p9_client_getattr_dotl(fid, P9_STATS_BASIC);
+               if (IS_ERR(st)) {
+                       retval = PTR_ERR(st);
+@@ -167,6 +168,7 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags,
+               kfree(st);
+       } else {
+               struct p9_wstat *st = NULL;
++
+               st = p9_client_stat(fid);
+               if (IS_ERR(st)) {
+                       retval = PTR_ERR(st);
+@@ -275,12 +277,13 @@ static int v9fs_statfs(struct dentry *dentry, struct kstatfs *buf)
+ static int v9fs_drop_inode(struct inode *inode)
+ {
+       struct v9fs_session_info *v9ses;
++
+       v9ses = v9fs_inode2v9ses(inode);
+       if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
+               return generic_drop_inode(inode);
+       /*
+        * in case of non cached mode always drop the
+-       * the inode because we want the inode attribute
++       * inode because we want the inode attribute
+        * to always match that on the server.
+        */
+       return 1;
+diff --git a/fs/9p/xattr.h b/fs/9p/xattr.h
+index c63c3bea5de5..9b28842c6363 100644
+--- a/fs/9p/xattr.h
++++ b/fs/9p/xattr.h
+@@ -22,13 +22,14 @@ extern const struct xattr_handler *v9fs_xattr_handlers[];
+ extern const struct xattr_handler v9fs_xattr_acl_access_handler;
+ extern const struct xattr_handler v9fs_xattr_acl_default_handler;
+-extern ssize_t v9fs_fid_xattr_get(struct p9_fid *, const char *,
+-                                void *, size_t);
+-extern ssize_t v9fs_xattr_get(struct dentry *, const char *,
+-                            void *, size_t);
+-extern int v9fs_fid_xattr_set(struct p9_fid *, const char *,
+-                        const void *, size_t, int);
+-extern int v9fs_xattr_set(struct dentry *, const char *,
+-                        const void *, size_t, int);
+-extern ssize_t v9fs_listxattr(struct dentry *, char *, size_t);
++ssize_t v9fs_fid_xattr_get(struct p9_fid *fid, const char *name,
++                         void *buffer, size_t buffer_size);
++ssize_t v9fs_xattr_get(struct dentry *dentry, const char *name,
++                     void *buffer, size_t buffer_size);
++int v9fs_fid_xattr_set(struct p9_fid *fid, const char *name,
++                     const void *value, size_t value_len, int flags);
++int v9fs_xattr_set(struct dentry *dentry, const char *name,
++                 const void *value, size_t value_len, int flags);
++ssize_t v9fs_listxattr(struct dentry *dentry, char *buffer,
++                     size_t buffer_size);
+ #endif /* FS_9P_XATTR_H */
+diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h
+index 03614de86942..6d0615140dbc 100644
+--- a/include/net/9p/9p.h
++++ b/include/net/9p/9p.h
+@@ -32,13 +32,13 @@
+  */
+ enum p9_debug_flags {
+-      P9_DEBUG_ERROR =        (1<<0),
+-      P9_DEBUG_9P =           (1<<2),
++      P9_DEBUG_ERROR =        (1<<0),
++      P9_DEBUG_9P =           (1<<2),
+       P9_DEBUG_VFS =          (1<<3),
+       P9_DEBUG_CONV =         (1<<4),
+       P9_DEBUG_MUX =          (1<<5),
+       P9_DEBUG_TRANS =        (1<<6),
+-      P9_DEBUG_SLABS =        (1<<7),
++      P9_DEBUG_SLABS =        (1<<7),
+       P9_DEBUG_FCALL =        (1<<8),
+       P9_DEBUG_FID =          (1<<9),
+       P9_DEBUG_PKT =          (1<<10),
+@@ -317,8 +317,8 @@ enum p9_qid_t {
+ };
+ /* 9P Magic Numbers */
+-#define P9_NOTAG      (u16)(~0)
+-#define P9_NOFID      (u32)(~0)
++#define P9_NOTAG      ((u16)(~0))
++#define P9_NOFID      ((u32)(~0))
+ #define P9_MAXWELEM   16
+ /* Minimal header size: size[4] type[1] tag[2] */
+diff --git a/include/net/9p/client.h b/include/net/9p/client.h
+index e1c308d8d288..334dc748fb3f 100644
+--- a/include/net/9p/client.h
++++ b/include/net/9p/client.h
+@@ -23,7 +23,7 @@
+  * @p9_proto_2000L: 9P2000.L extension
+  */
+-enum p9_proto_versions{
++enum p9_proto_versions {
+       p9_proto_legacy,
+       p9_proto_2000u,
+       p9_proto_2000L,
+@@ -219,13 +219,13 @@ struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid,
+                                                       u64 request_mask);
+ int p9_client_mknod_dotl(struct p9_fid *oldfid, const char *name, int mode,
+-                      dev_t rdev, kgid_t gid, struct p9_qid *);
++                      dev_t rdev, kgid_t gid, struct p9_qid *qid);
+ int p9_client_mkdir_dotl(struct p9_fid *fid, const char *name, int mode,
+-                              kgid_t gid, struct p9_qid *);
++                              kgid_t gid, struct p9_qid *qid);
+ int p9_client_lock_dotl(struct p9_fid *fid, struct p9_flock *flock, u8 *status);
+ int p9_client_getlock_dotl(struct p9_fid *fid, struct p9_getlock *fl);
+ void p9_fcall_fini(struct p9_fcall *fc);
+-struct p9_req_t *p9_tag_lookup(struct p9_client *, u16);
++struct p9_req_t *p9_tag_lookup(struct p9_client *c, u16 tag);
+ static inline void p9_req_get(struct p9_req_t *r)
+ {
+@@ -241,14 +241,18 @@ int p9_req_put(struct p9_req_t *r);
+ void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status);
+-int p9_parse_header(struct p9_fcall *, int32_t *, int8_t *, int16_t *, int);
+-int p9stat_read(struct p9_client *, char *, int, struct p9_wstat *);
+-void p9stat_free(struct p9_wstat *);
++int p9_parse_header(struct p9_fcall *pdu, int32_t *size, int8_t *type,
++                  int16_t *tag, int rewind);
++int p9stat_read(struct p9_client *clnt, char *buf, int len,
++              struct p9_wstat *st);
++void p9stat_free(struct p9_wstat *stbuf);
+ int p9_is_proto_dotu(struct p9_client *clnt);
+ int p9_is_proto_dotl(struct p9_client *clnt);
+-struct p9_fid *p9_client_xattrwalk(struct p9_fid *, const char *, u64 *);
+-int p9_client_xattrcreate(struct p9_fid *, const char *, u64, int);
++struct p9_fid *p9_client_xattrwalk(struct p9_fid *file_fid,
++                                 const char *attr_name, u64 *attr_size);
++int p9_client_xattrcreate(struct p9_fid *fid, const char *name,
++                        u64 attr_size, int flags);
+ int p9_client_readlink(struct p9_fid *fid, char **target);
+ int p9_client_init(void);
+diff --git a/include/net/9p/transport.h b/include/net/9p/transport.h
+index 3eb4261b2958..721597611625 100644
+--- a/include/net/9p/transport.h
++++ b/include/net/9p/transport.h
+@@ -40,14 +40,16 @@ struct p9_trans_module {
+       int maxsize;            /* max message size of transport */
+       int def;                /* this transport should be default */
+       struct module *owner;
+-      int (*create)(struct p9_client *, const char *, char *);
+-      void (*close) (struct p9_client *);
+-      int (*request) (struct p9_client *, struct p9_req_t *req);
+-      int (*cancel) (struct p9_client *, struct p9_req_t *req);
+-      int (*cancelled)(struct p9_client *, struct p9_req_t *req);
+-      int (*zc_request)(struct p9_client *, struct p9_req_t *,
+-                        struct iov_iter *, struct iov_iter *, int , int, int);
+-      int (*show_options)(struct seq_file *, struct p9_client *);
++      int (*create)(struct p9_client *client,
++                    const char *devname, char *args);
++      void (*close)(struct p9_client *client);
++      int (*request)(struct p9_client *client, struct p9_req_t *req);
++      int (*cancel)(struct p9_client *client, struct p9_req_t *req);
++      int (*cancelled)(struct p9_client *client, struct p9_req_t *req);
++      int (*zc_request)(struct p9_client *client, struct p9_req_t *req,
++                        struct iov_iter *uidata, struct iov_iter *uodata,
++                        int inlen, int outlen, int in_hdr_len);
++      int (*show_options)(struct seq_file *m, struct p9_client *client);
+ };
+ void v9fs_register_trans(struct p9_trans_module *m);
+diff --git a/net/9p/client.c b/net/9p/client.c
+index 7973267ec846..33a53f016e73 100644
+--- a/net/9p/client.c
++++ b/net/9p/client.c
+@@ -32,10 +32,9 @@
+ #define DEFAULT_MSIZE (128 * 1024)
+-/*
+-  * Client Option Parsing (code inspired by NFS code)
+-  *  - a little lazy - parse all client options
+-  */
++/* Client Option Parsing (code inspired by NFS code)
++ *  - a little lazy - parse all client options
++ */
+ enum {
+       Opt_msize,
+@@ -89,20 +88,18 @@ int p9_show_client_options(struct seq_file *m, struct p9_client *clnt)
+ }
+ EXPORT_SYMBOL(p9_show_client_options);
+-/*
+- * Some error codes are taken directly from the server replies,
++/* Some error codes are taken directly from the server replies,
+  * make sure they are valid.
+  */
+ static int safe_errno(int err)
+ {
+-      if ((err > 0) || (err < -MAX_ERRNO)) {
++      if (err > 0 || err < -MAX_ERRNO) {
+               p9_debug(P9_DEBUG_ERROR, "Invalid error code %d\n", err);
+               return -EPROTO;
+       }
+       return err;
+ }
+-
+ /* Interpret mount option for protocol version */
+ static int get_protocol_version(char *s)
+ {
+@@ -117,8 +114,9 @@ static int get_protocol_version(char *s)
+       } else if (!strcmp(s, "9p2000.L")) {
+               version = p9_proto_2000L;
+               p9_debug(P9_DEBUG_9P, "Protocol version: 9P2000.L\n");
+-      } else
++      } else {
+               pr_info("Unknown protocol version %s\n", s);
++      }
+       return version;
+ }
+@@ -147,15 +145,13 @@ static int parse_opts(char *opts, struct p9_client *clnt)
+               return 0;
+       tmp_options = kstrdup(opts, GFP_KERNEL);
+-      if (!tmp_options) {
+-              p9_debug(P9_DEBUG_ERROR,
+-                       "failed to allocate copy of option string\n");
++      if (!tmp_options)
+               return -ENOMEM;
+-      }
+       options = tmp_options;
+       while ((p = strsep(&options, ",")) != NULL) {
+               int token, r;
++
+               if (!*p)
+                       continue;
+               token = match_token(p, tokens, args);
+@@ -187,7 +183,7 @@ static int parse_opts(char *opts, struct p9_client *clnt)
+                       v9fs_put_trans(clnt->trans_mod);
+                       clnt->trans_mod = v9fs_get_trans_by_name(s);
+-                      if (clnt->trans_mod == NULL) {
++                      if (!clnt->trans_mod) {
+                               pr_info("Could not find request transport: %s\n",
+                                       s);
+                               ret = -EINVAL;
+@@ -379,6 +375,7 @@ static int p9_tag_remove(struct p9_client *c, struct p9_req_t *r)
+ static void p9_req_free(struct kref *ref)
+ {
+       struct p9_req_t *r = container_of(ref, struct p9_req_t, refcount);
++
+       p9_fcall_fini(&r->tc);
+       p9_fcall_fini(&r->rc);
+       kmem_cache_free(p9_req_cache, r);
+@@ -423,8 +420,7 @@ void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status)
+ {
+       p9_debug(P9_DEBUG_MUX, " tag %d\n", req->tc.tag);
+-      /*
+-       * This barrier is needed to make sure any change made to req before
++      /* This barrier is needed to make sure any change made to req before
+        * the status change is visible to another thread
+        */
+       smp_wmb();
+@@ -446,12 +442,12 @@ EXPORT_SYMBOL(p9_client_cb);
+  */
+ int
+-p9_parse_header(struct p9_fcall *pdu, int32_t *size, int8_t *type, int16_t *tag,
+-                                                              int rewind)
++p9_parse_header(struct p9_fcall *pdu, int32_t *size, int8_t *type,
++              int16_t *tag, int rewind)
+ {
+-      int8_t r_type;
+-      int16_t r_tag;
+-      int32_t r_size;
++      s8 r_type;
++      s16 r_tag;
++      s32 r_size;
+       int offset = pdu->offset;
+       int err;
+@@ -499,7 +495,7 @@ EXPORT_SYMBOL(p9_parse_header);
+ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req)
+ {
+-      int8_t type;
++      s8 type;
+       int err;
+       int ecode;
+@@ -510,8 +506,7 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req)
+                        req->rc.size);
+               return -EIO;
+       }
+-      /*
+-       * dump the response from server
++      /* dump the response from server
+        * This should be after check errors which poplulate pdu_fcall.
+        */
+       trace_9p_protocol_dump(c, &req->rc);
+@@ -524,6 +519,7 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req)
+       if (!p9_is_proto_dotl(c)) {
+               char *ename;
++
+               err = p9pdu_readf(&req->rc, c->proto_version, "s?d",
+                                 &ename, &ecode);
+               if (err)
+@@ -574,12 +570,11 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req,
+ {
+       int err;
+       int ecode;
+-      int8_t type;
++      s8 type;
+       char *ename = NULL;
+       err = p9_parse_header(&req->rc, NULL, &type, NULL, 0);
+-      /*
+-       * dump the response from server
++      /* dump the response from server
+        * This should be after parse_header which poplulate pdu_fcall.
+        */
+       trace_9p_protocol_dump(c, &req->rc);
+@@ -607,7 +602,7 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req,
+               if (len > inline_len) {
+                       /* We have error in external buffer */
+                       if (!copy_from_iter_full(ename + inline_len,
+-                                           len - inline_len, uidata)) {
++                                               len - inline_len, uidata)) {
+                               err = -EFAULT;
+                               goto out_err;
+                       }
+@@ -659,7 +654,7 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...);
+ static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq)
+ {
+       struct p9_req_t *req;
+-      int16_t oldtag;
++      s16 oldtag;
+       int err;
+       err = p9_parse_header(&oldreq->tc, NULL, NULL, &oldtag, 1);
+@@ -672,8 +667,7 @@ static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq)
+       if (IS_ERR(req))
+               return PTR_ERR(req);
+-      /*
+-       * if we haven't received a response for oldreq,
++      /* if we haven't received a response for oldreq,
+        * remove it from the list
+        */
+       if (oldreq->status == REQ_STATUS_SENT) {
+@@ -699,7 +693,7 @@ static struct p9_req_t *p9_client_prepare_req(struct p9_client *c,
+               return ERR_PTR(-EIO);
+       /* if status is begin_disconnected we allow only clunk request */
+-      if ((c->status == BeginDisconnect) && (type != P9_TCLUNK))
++      if (c->status == BeginDisconnect && type != P9_TCLUNK)
+               return ERR_PTR(-EIO);
+       req = p9_tag_alloc(c, type, req_size);
+@@ -747,8 +741,9 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
+       if (signal_pending(current)) {
+               sigpending = 1;
+               clear_thread_flag(TIF_SIGPENDING);
+-      } else
++      } else {
+               sigpending = 0;
++      }
+       err = c->trans_mod->request(c, req);
+       if (err < 0) {
+@@ -762,14 +757,13 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
+       /* Wait for the response */
+       err = wait_event_killable(req->wq, req->status >= REQ_STATUS_RCVD);
+-      /*
+-       * Make sure our req is coherent with regard to updates in other
++      /* Make sure our req is coherent with regard to updates in other
+        * threads - echoes to wmb() in the callback
+        */
+       smp_rmb();
+-      if ((err == -ERESTARTSYS) && (c->status == Connected)
+-                                && (type == P9_TFLUSH)) {
++      if (err == -ERESTARTSYS && c->status == Connected &&
++          type == P9_TFLUSH) {
+               sigpending = 1;
+               clear_thread_flag(TIF_SIGPENDING);
+               goto again;
+@@ -779,7 +773,7 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
+               p9_debug(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err);
+               err = req->t_err;
+       }
+-      if ((err == -ERESTARTSYS) && (c->status == Connected)) {
++      if (err == -ERESTARTSYS && c->status == Connected) {
+               p9_debug(P9_DEBUG_MUX, "flushing\n");
+               sigpending = 1;
+               clear_thread_flag(TIF_SIGPENDING);
+@@ -834,8 +828,7 @@ static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type,
+       struct p9_req_t *req;
+       va_start(ap, fmt);
+-      /*
+-       * We allocate a inline protocol data of only 4k bytes.
++      /* We allocate a inline protocol data of only 4k bytes.
+        * The actual content is passed in zero-copy fashion.
+        */
+       req = p9_client_prepare_req(c, type, P9_ZC_HDR_SZ, fmt, ap);
+@@ -846,8 +839,9 @@ static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type,
+       if (signal_pending(current)) {
+               sigpending = 1;
+               clear_thread_flag(TIF_SIGPENDING);
+-      } else
++      } else {
+               sigpending = 0;
++      }
+       err = c->trans_mod->zc_request(c, req, uidata, uodata,
+                                      inlen, olen, in_hdrlen);
+@@ -861,7 +855,7 @@ static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type,
+               p9_debug(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err);
+               err = req->t_err;
+       }
+-      if ((err == -ERESTARTSYS) && (c->status == Connected)) {
++      if (err == -ERESTARTSYS && c->status == Connected) {
+               p9_debug(P9_DEBUG_MUX, "flushing\n");
+               sigpending = 1;
+               clear_thread_flag(TIF_SIGPENDING);
+@@ -897,11 +891,11 @@ static struct p9_fid *p9_fid_create(struct p9_client *clnt)
+       struct p9_fid *fid;
+       p9_debug(P9_DEBUG_FID, "clnt %p\n", clnt);
+-      fid = kmalloc(sizeof(struct p9_fid), GFP_KERNEL);
++      fid = kmalloc(sizeof(*fid), GFP_KERNEL);
+       if (!fid)
+               return NULL;
+-      memset(&fid->qid, 0, sizeof(struct p9_qid));
++      memset(&fid->qid, 0, sizeof(fid->qid));
+       fid->mode = -1;
+       fid->uid = current_fsuid();
+       fid->clnt = clnt;
+@@ -949,15 +943,15 @@ static int p9_client_version(struct p9_client *c)
+       switch (c->proto_version) {
+       case p9_proto_2000L:
+               req = p9_client_rpc(c, P9_TVERSION, "ds",
+-                                      c->msize, "9P2000.L");
++                                  c->msize, "9P2000.L");
+               break;
+       case p9_proto_2000u:
+               req = p9_client_rpc(c, P9_TVERSION, "ds",
+-                                      c->msize, "9P2000.u");
++                                  c->msize, "9P2000.u");
+               break;
+       case p9_proto_legacy:
+               req = p9_client_rpc(c, P9_TVERSION, "ds",
+-                                      c->msize, "9P2000");
++                                  c->msize, "9P2000");
+               break;
+       default:
+               return -EINVAL;
+@@ -974,13 +968,13 @@ static int p9_client_version(struct p9_client *c)
+       }
+       p9_debug(P9_DEBUG_9P, "<<< RVERSION msize %d %s\n", msize, version);
+-      if (!strncmp(version, "9P2000.L", 8))
++      if (!strncmp(version, "9P2000.L", 8)) {
+               c->proto_version = p9_proto_2000L;
+-      else if (!strncmp(version, "9P2000.u", 8))
++      } else if (!strncmp(version, "9P2000.u", 8)) {
+               c->proto_version = p9_proto_2000u;
+-      else if (!strncmp(version, "9P2000", 6))
++      } else if (!strncmp(version, "9P2000", 6)) {
+               c->proto_version = p9_proto_legacy;
+-      else {
++      } else {
+               p9_debug(P9_DEBUG_ERROR,
+                        "server returned an unknown version: %s\n", version);
+               err = -EREMOTEIO;
+@@ -1010,7 +1004,7 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
+       char *client_id;
+       err = 0;
+-      clnt = kmalloc(sizeof(struct p9_client), GFP_KERNEL);
++      clnt = kmalloc(sizeof(*clnt), GFP_KERNEL);
+       if (!clnt)
+               return ERR_PTR(-ENOMEM);
+@@ -1032,7 +1026,7 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
+       if (!clnt->trans_mod)
+               clnt->trans_mod = v9fs_get_default_trans();
+-      if (clnt->trans_mod == NULL) {
++      if (!clnt->trans_mod) {
+               err = -EPROTONOSUPPORT;
+               p9_debug(P9_DEBUG_ERROR,
+                        "No transport defined or default transport\n");
+@@ -1120,14 +1114,14 @@ void p9_client_begin_disconnect(struct p9_client *clnt)
+ EXPORT_SYMBOL(p9_client_begin_disconnect);
+ struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
+-      const char *uname, kuid_t n_uname, const char *aname)
++                              const char *uname, kuid_t n_uname,
++                              const char *aname)
+ {
+       int err = 0;
+       struct p9_req_t *req;
+       struct p9_fid *fid;
+       struct p9_qid qid;
+-
+       p9_debug(P9_DEBUG_9P, ">>> TATTACH afid %d uname %s aname %s\n",
+                afid ? afid->fid : -1, uname, aname);
+       fid = p9_fid_create(clnt);
+@@ -1138,7 +1132,7 @@ struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
+       fid->uid = n_uname;
+       req = p9_client_rpc(clnt, P9_TATTACH, "ddss?u", fid->fid,
+-                      afid ? afid->fid : P9_NOFID, uname, aname, n_uname);
++                          afid ? afid->fid : P9_NOFID, uname, aname, n_uname);
+       if (IS_ERR(req)) {
+               err = PTR_ERR(req);
+               goto error;
+@@ -1152,7 +1146,7 @@ struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
+       }
+       p9_debug(P9_DEBUG_9P, "<<< RATTACH qid %x.%llx.%x\n",
+-               qid.type, (unsigned long long)qid.path, qid.version);
++               qid.type, qid.path, qid.version);
+       memmove(&fid->qid, &qid, sizeof(struct p9_qid));
+@@ -1167,14 +1161,14 @@ struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
+ EXPORT_SYMBOL(p9_client_attach);
+ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, uint16_t nwname,
+-              const unsigned char * const *wnames, int clone)
++                            const unsigned char * const *wnames, int clone)
+ {
+       int err;
+       struct p9_client *clnt;
+       struct p9_fid *fid;
+       struct p9_qid *wqids;
+       struct p9_req_t *req;
+-      uint16_t nwqids, count;
++      u16 nwqids, count;
+       err = 0;
+       wqids = NULL;
+@@ -1187,14 +1181,14 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, uint16_t nwname,
+               }
+               fid->uid = oldfid->uid;
+-      } else
++      } else {
+               fid = oldfid;
+-
++      }
+       p9_debug(P9_DEBUG_9P, ">>> TWALK fids %d,%d nwname %ud wname[0] %s\n",
+                oldfid->fid, fid->fid, nwname, wnames ? wnames[0] : NULL);
+       req = p9_client_rpc(clnt, P9_TWALK, "ddT", oldfid->fid, fid->fid,
+-                                                              nwname, wnames);
++                          nwname, wnames);
+       if (IS_ERR(req)) {
+               err = PTR_ERR(req);
+               goto error;
+@@ -1217,9 +1211,9 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, uint16_t nwname,
+       for (count = 0; count < nwqids; count++)
+               p9_debug(P9_DEBUG_9P, "<<<     [%d] %x.%llx.%x\n",
+-                      count, wqids[count].type,
+-                      (unsigned long long)wqids[count].path,
+-                      wqids[count].version);
++                       count, wqids[count].type,
++                       wqids[count].path,
++                       wqids[count].version);
+       if (nwname)
+               memmove(&fid->qid, &wqids[nwqids - 1], sizeof(struct p9_qid));
+@@ -1235,7 +1229,7 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, uint16_t nwname,
+       fid = NULL;
+ error:
+-      if (fid && (fid != oldfid))
++      if (fid && fid != oldfid)
+               p9_fid_destroy(fid);
+       return ERR_PTR(err);
+@@ -1252,7 +1246,7 @@ int p9_client_open(struct p9_fid *fid, int mode)
+       clnt = fid->clnt;
+       p9_debug(P9_DEBUG_9P, ">>> %s fid %d mode %d\n",
+-              p9_is_proto_dotl(clnt) ? "TLOPEN" : "TOPEN", fid->fid, mode);
++               p9_is_proto_dotl(clnt) ? "TLOPEN" : "TOPEN", fid->fid, mode);
+       err = 0;
+       if (fid->mode != -1)
+@@ -1274,8 +1268,8 @@ int p9_client_open(struct p9_fid *fid, int mode)
+       }
+       p9_debug(P9_DEBUG_9P, "<<< %s qid %x.%llx.%x iounit %x\n",
+-              p9_is_proto_dotl(clnt) ? "RLOPEN" : "ROPEN",  qid.type,
+-              (unsigned long long)qid.path, qid.version, iounit);
++               p9_is_proto_dotl(clnt) ? "RLOPEN" : "ROPEN",  qid.type,
++               qid.path, qid.version, iounit);
+       memmove(&fid->qid, &qid, sizeof(struct p9_qid));
+       fid->mode = mode;
+@@ -1288,8 +1282,8 @@ int p9_client_open(struct p9_fid *fid, int mode)
+ }
+ EXPORT_SYMBOL(p9_client_open);
+-int p9_client_create_dotl(struct p9_fid *ofid, const char *name, u32 flags, u32 mode,
+-              kgid_t gid, struct p9_qid *qid)
++int p9_client_create_dotl(struct p9_fid *ofid, const char *name, u32 flags,
++                        u32 mode, kgid_t gid, struct p9_qid *qid)
+ {
+       int err = 0;
+       struct p9_client *clnt;
+@@ -1297,16 +1291,16 @@ int p9_client_create_dotl(struct p9_fid *ofid, const char *name, u32 flags, u32
+       int iounit;
+       p9_debug(P9_DEBUG_9P,
+-                      ">>> TLCREATE fid %d name %s flags %d mode %d gid %d\n",
+-                      ofid->fid, name, flags, mode,
+-                      from_kgid(&init_user_ns, gid));
++               ">>> TLCREATE fid %d name %s flags %d mode %d gid %d\n",
++               ofid->fid, name, flags, mode,
++               from_kgid(&init_user_ns, gid));
+       clnt = ofid->clnt;
+       if (ofid->mode != -1)
+               return -EINVAL;
+       req = p9_client_rpc(clnt, P9_TLCREATE, "dsddg", ofid->fid, name, flags,
+-                      mode, gid);
++                          mode, gid);
+       if (IS_ERR(req)) {
+               err = PTR_ERR(req);
+               goto error;
+@@ -1319,9 +1313,7 @@ int p9_client_create_dotl(struct p9_fid *ofid, const char *name, u32 flags, u32
+       }
+       p9_debug(P9_DEBUG_9P, "<<< RLCREATE qid %x.%llx.%x iounit %x\n",
+-                      qid->type,
+-                      (unsigned long long)qid->path,
+-                      qid->version, iounit);
++               qid->type, qid->path, qid->version, iounit);
+       memmove(&ofid->qid, qid, sizeof(struct p9_qid));
+       ofid->mode = mode;
+@@ -1344,7 +1336,7 @@ int p9_client_fcreate(struct p9_fid *fid, const char *name, u32 perm, int mode,
+       int iounit;
+       p9_debug(P9_DEBUG_9P, ">>> TCREATE fid %d name %s perm %d mode %d\n",
+-                                              fid->fid, name, perm, mode);
++               fid->fid, name, perm, mode);
+       err = 0;
+       clnt = fid->clnt;
+@@ -1352,7 +1344,7 @@ int p9_client_fcreate(struct p9_fid *fid, const char *name, u32 perm, int mode,
+               return -EINVAL;
+       req = p9_client_rpc(clnt, P9_TCREATE, "dsdb?s", fid->fid, name, perm,
+-                              mode, extension);
++                          mode, extension);
+       if (IS_ERR(req)) {
+               err = PTR_ERR(req);
+               goto error;
+@@ -1365,9 +1357,7 @@ int p9_client_fcreate(struct p9_fid *fid, const char *name, u32 perm, int mode,
+       }
+       p9_debug(P9_DEBUG_9P, "<<< RCREATE qid %x.%llx.%x iounit %x\n",
+-                              qid.type,
+-                              (unsigned long long)qid.path,
+-                              qid.version, iounit);
++               qid.type, qid.path, qid.version, iounit);
+       memmove(&fid->qid, &qid, sizeof(struct p9_qid));
+       fid->mode = mode;
+@@ -1381,18 +1371,18 @@ int p9_client_fcreate(struct p9_fid *fid, const char *name, u32 perm, int mode,
+ EXPORT_SYMBOL(p9_client_fcreate);
+ int p9_client_symlink(struct p9_fid *dfid, const char *name,
+-              const char *symtgt, kgid_t gid, struct p9_qid *qid)
++                    const char *symtgt, kgid_t gid, struct p9_qid *qid)
+ {
+       int err = 0;
+       struct p9_client *clnt;
+       struct p9_req_t *req;
+       p9_debug(P9_DEBUG_9P, ">>> TSYMLINK dfid %d name %s  symtgt %s\n",
+-                      dfid->fid, name, symtgt);
++               dfid->fid, name, symtgt);
+       clnt = dfid->clnt;
+       req = p9_client_rpc(clnt, P9_TSYMLINK, "dssg", dfid->fid, name, symtgt,
+-                      gid);
++                          gid);
+       if (IS_ERR(req)) {
+               err = PTR_ERR(req);
+               goto error;
+@@ -1405,7 +1395,7 @@ int p9_client_symlink(struct p9_fid *dfid, const char *name,
+       }
+       p9_debug(P9_DEBUG_9P, "<<< RSYMLINK qid %x.%llx.%x\n",
+-                      qid->type, (unsigned long long)qid->path, qid->version);
++               qid->type, qid->path, qid->version);
+ free_and_error:
+       p9_tag_remove(clnt, req);
+@@ -1420,10 +1410,10 @@ int p9_client_link(struct p9_fid *dfid, struct p9_fid *oldfid, const char *newna
+       struct p9_req_t *req;
+       p9_debug(P9_DEBUG_9P, ">>> TLINK dfid %d oldfid %d newname %s\n",
+-                      dfid->fid, oldfid->fid, newname);
++               dfid->fid, oldfid->fid, newname);
+       clnt = dfid->clnt;
+       req = p9_client_rpc(clnt, P9_TLINK, "dds", dfid->fid, oldfid->fid,
+-                      newname);
++                          newname);
+       if (IS_ERR(req))
+               return PTR_ERR(req);
+@@ -1440,7 +1430,7 @@ int p9_client_fsync(struct p9_fid *fid, int datasync)
+       struct p9_req_t *req;
+       p9_debug(P9_DEBUG_9P, ">>> TFSYNC fid %d datasync:%d\n",
+-                      fid->fid, datasync);
++               fid->fid, datasync);
+       err = 0;
+       clnt = fid->clnt;
+@@ -1476,8 +1466,8 @@ int p9_client_clunk(struct p9_fid *fid)
+               return 0;
+ again:
+-      p9_debug(P9_DEBUG_9P, ">>> TCLUNK fid %d (try %d)\n", fid->fid,
+-                                                              retries);
++      p9_debug(P9_DEBUG_9P, ">>> TCLUNK fid %d (try %d)\n",
++               fid->fid, retries);
+       err = 0;
+       clnt = fid->clnt;
+@@ -1491,16 +1481,16 @@ int p9_client_clunk(struct p9_fid *fid)
+       p9_tag_remove(clnt, req);
+ error:
+-      /*
+-       * Fid is not valid even after a failed clunk
++      /* Fid is not valid even after a failed clunk
+        * If interrupted, retry once then give up and
+        * leak fid until umount.
+        */
+       if (err == -ERESTARTSYS) {
+               if (retries++ == 0)
+                       goto again;
+-      } else
++      } else {
+               p9_fid_destroy(fid);
++      }
+       return err;
+ }
+ EXPORT_SYMBOL(p9_client_clunk);
+@@ -1540,7 +1530,7 @@ int p9_client_unlinkat(struct p9_fid *dfid, const char *name, int flags)
+       struct p9_client *clnt;
+       p9_debug(P9_DEBUG_9P, ">>> TUNLINKAT fid %d %s %d\n",
+-                 dfid->fid, name, flags);
++               dfid->fid, name, flags);
+       clnt = dfid->clnt;
+       req = p9_client_rpc(clnt, P9_TUNLINKAT, "dsd", dfid->fid, name, flags);
+@@ -1586,8 +1576,8 @@ p9_client_read_once(struct p9_fid *fid, u64 offset, struct iov_iter *to,
+       char *dataptr;
+       *err = 0;
+-      p9_debug(P9_DEBUG_9P, ">>> TREAD fid %d offset %llu %d\n",
+-                 fid->fid, (unsigned long long) offset, (int)iov_iter_count(to));
++      p9_debug(P9_DEBUG_9P, ">>> TREAD fid %d offset %llu %zu\n",
++               fid->fid, offset, iov_iter_count(to));
+       rsize = fid->iounit;
+       if (!rsize || rsize > clnt->msize - P9_IOHDRSZ)
+@@ -1653,13 +1643,13 @@ p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err)
+       *err = 0;
+       p9_debug(P9_DEBUG_9P, ">>> TWRITE fid %d offset %llu count %zd\n",
+-                              fid->fid, (unsigned long long) offset,
+-                              iov_iter_count(from));
++               fid->fid, offset, iov_iter_count(from));
+       while (iov_iter_count(from)) {
+               int count = iov_iter_count(from);
+               int rsize = fid->iounit;
+-              if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
++
++              if (!rsize || rsize > clnt->msize - P9_IOHDRSZ)
+                       rsize = clnt->msize - P9_IOHDRSZ;
+               if (count < rsize)
+@@ -1672,7 +1662,7 @@ p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err)
+                                              fid->fid, offset, rsize);
+               } else {
+                       req = p9_client_rpc(clnt, P9_TWRITE, "dqV", fid->fid,
+-                                                  offset, rsize, from);
++                                          offset, rsize, from);
+               }
+               if (IS_ERR(req)) {
+                       *err = PTR_ERR(req);
+@@ -1705,12 +1695,13 @@ struct p9_wstat *p9_client_stat(struct p9_fid *fid)
+ {
+       int err;
+       struct p9_client *clnt;
+-      struct p9_wstat *ret = kmalloc(sizeof(struct p9_wstat), GFP_KERNEL);
++      struct p9_wstat *ret;
+       struct p9_req_t *req;
+       u16 ignored;
+       p9_debug(P9_DEBUG_9P, ">>> TSTAT fid %d\n", fid->fid);
++      ret = kmalloc(sizeof(*ret), GFP_KERNEL);
+       if (!ret)
+               return ERR_PTR(-ENOMEM);
+@@ -1731,17 +1722,17 @@ struct p9_wstat *p9_client_stat(struct p9_fid *fid)
+       }
+       p9_debug(P9_DEBUG_9P,
+-              "<<< RSTAT sz=%x type=%x dev=%x qid=%x.%llx.%x\n"
+-              "<<<    mode=%8.8x atime=%8.8x mtime=%8.8x length=%llx\n"
+-              "<<<    name=%s uid=%s gid=%s muid=%s extension=(%s)\n"
+-              "<<<    uid=%d gid=%d n_muid=%d\n",
+-              ret->size, ret->type, ret->dev, ret->qid.type,
+-              (unsigned long long)ret->qid.path, ret->qid.version, ret->mode,
+-              ret->atime, ret->mtime, (unsigned long long)ret->length,
+-              ret->name, ret->uid, ret->gid, ret->muid, ret->extension,
+-              from_kuid(&init_user_ns, ret->n_uid),
+-              from_kgid(&init_user_ns, ret->n_gid),
+-              from_kuid(&init_user_ns, ret->n_muid));
++               "<<< RSTAT sz=%x type=%x dev=%x qid=%x.%llx.%x\n"
++               "<<<    mode=%8.8x atime=%8.8x mtime=%8.8x length=%llx\n"
++               "<<<    name=%s uid=%s gid=%s muid=%s extension=(%s)\n"
++               "<<<    uid=%d gid=%d n_muid=%d\n",
++               ret->size, ret->type, ret->dev, ret->qid.type, ret->qid.path,
++               ret->qid.version, ret->mode,
++               ret->atime, ret->mtime, ret->length,
++               ret->name, ret->uid, ret->gid, ret->muid, ret->extension,
++               from_kuid(&init_user_ns, ret->n_uid),
++               from_kgid(&init_user_ns, ret->n_gid),
++               from_kuid(&init_user_ns, ret->n_muid));
+       p9_tag_remove(clnt, req);
+       return ret;
+@@ -1753,17 +1744,17 @@ struct p9_wstat *p9_client_stat(struct p9_fid *fid)
+ EXPORT_SYMBOL(p9_client_stat);
+ struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid,
+-                                                      u64 request_mask)
++                                          u64 request_mask)
+ {
+       int err;
+       struct p9_client *clnt;
+-      struct p9_stat_dotl *ret = kmalloc(sizeof(struct p9_stat_dotl),
+-                                                              GFP_KERNEL);
++      struct p9_stat_dotl *ret;
+       struct p9_req_t *req;
+       p9_debug(P9_DEBUG_9P, ">>> TGETATTR fid %d, request_mask %lld\n",
+-                                                      fid->fid, request_mask);
++               fid->fid, request_mask);
++      ret = kmalloc(sizeof(*ret), GFP_KERNEL);
+       if (!ret)
+               return ERR_PTR(-ENOMEM);
+@@ -1783,26 +1774,27 @@ struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid,
+               goto error;
+       }
+-      p9_debug(P9_DEBUG_9P,
+-              "<<< RGETATTR st_result_mask=%lld\n"
+-              "<<< qid=%x.%llx.%x\n"
+-              "<<< st_mode=%8.8x st_nlink=%llu\n"
+-              "<<< st_uid=%d st_gid=%d\n"
+-              "<<< st_rdev=%llx st_size=%llx st_blksize=%llu st_blocks=%llu\n"
+-              "<<< st_atime_sec=%lld st_atime_nsec=%lld\n"
+-              "<<< st_mtime_sec=%lld st_mtime_nsec=%lld\n"
+-              "<<< st_ctime_sec=%lld st_ctime_nsec=%lld\n"
+-              "<<< st_btime_sec=%lld st_btime_nsec=%lld\n"
+-              "<<< st_gen=%lld st_data_version=%lld\n",
+-              ret->st_result_mask, ret->qid.type, ret->qid.path,
+-              ret->qid.version, ret->st_mode, ret->st_nlink,
+-              from_kuid(&init_user_ns, ret->st_uid),
+-              from_kgid(&init_user_ns, ret->st_gid),
+-              ret->st_rdev, ret->st_size, ret->st_blksize,
+-              ret->st_blocks, ret->st_atime_sec, ret->st_atime_nsec,
+-              ret->st_mtime_sec, ret->st_mtime_nsec, ret->st_ctime_sec,
+-              ret->st_ctime_nsec, ret->st_btime_sec, ret->st_btime_nsec,
+-              ret->st_gen, ret->st_data_version);
++      p9_debug(P9_DEBUG_9P, "<<< RGETATTR st_result_mask=%lld\n"
++               "<<< qid=%x.%llx.%x\n"
++               "<<< st_mode=%8.8x st_nlink=%llu\n"
++               "<<< st_uid=%d st_gid=%d\n"
++               "<<< st_rdev=%llx st_size=%llx st_blksize=%llu st_blocks=%llu\n"
++               "<<< st_atime_sec=%lld st_atime_nsec=%lld\n"
++               "<<< st_mtime_sec=%lld st_mtime_nsec=%lld\n"
++               "<<< st_ctime_sec=%lld st_ctime_nsec=%lld\n"
++               "<<< st_btime_sec=%lld st_btime_nsec=%lld\n"
++               "<<< st_gen=%lld st_data_version=%lld\n",
++               ret->st_result_mask,
++               ret->qid.type, ret->qid.path, ret->qid.version,
++               ret->st_mode, ret->st_nlink,
++               from_kuid(&init_user_ns, ret->st_uid),
++               from_kgid(&init_user_ns, ret->st_gid),
++               ret->st_rdev, ret->st_size, ret->st_blksize, ret->st_blocks,
++               ret->st_atime_sec, ret->st_atime_nsec,
++               ret->st_mtime_sec, ret->st_mtime_nsec,
++               ret->st_ctime_sec, ret->st_ctime_nsec,
++               ret->st_btime_sec, ret->st_btime_nsec,
++               ret->st_gen, ret->st_data_version);
+       p9_tag_remove(clnt, req);
+       return ret;
+@@ -1821,7 +1813,7 @@ static int p9_client_statsize(struct p9_wstat *wst, int proto_version)
+       /* size[2] type[2] dev[4] qid[13] */
+       /* mode[4] atime[4] mtime[4] length[8]*/
+       /* name[s] uid[s] gid[s] muid[s] */
+-      ret = 2+4+13+4+4+4+8+2+2+2+2;
++      ret = 2 + 4 + 13 + 4 + 4 + 4 + 8 + 2 + 2 + 2 + 2;
+       if (wst->name)
+               ret += strlen(wst->name);
+@@ -1832,9 +1824,10 @@ static int p9_client_statsize(struct p9_wstat *wst, int proto_version)
+       if (wst->muid)
+               ret += strlen(wst->muid);
+-      if ((proto_version == p9_proto_2000u) ||
+-              (proto_version == p9_proto_2000L)) {
+-              ret += 2+4+4+4; /* extension[s] n_uid[4] n_gid[4] n_muid[4] */
++      if (proto_version == p9_proto_2000u ||
++          proto_version == p9_proto_2000L) {
++              /* extension[s] n_uid[4] n_gid[4] n_muid[4] */
++              ret += 2 + 4 + 4 + 4;
+               if (wst->extension)
+                       ret += strlen(wst->extension);
+       }
+@@ -1851,21 +1844,23 @@ int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst)
+       err = 0;
+       clnt = fid->clnt;
+       wst->size = p9_client_statsize(wst, clnt->proto_version);
+-      p9_debug(P9_DEBUG_9P, ">>> TWSTAT fid %d\n", fid->fid);
++      p9_debug(P9_DEBUG_9P, ">>> TWSTAT fid %d\n",
++               fid->fid);
+       p9_debug(P9_DEBUG_9P,
+-              "     sz=%x type=%x dev=%x qid=%x.%llx.%x\n"
+-              "     mode=%8.8x atime=%8.8x mtime=%8.8x length=%llx\n"
+-              "     name=%s uid=%s gid=%s muid=%s extension=(%s)\n"
+-              "     uid=%d gid=%d n_muid=%d\n",
+-              wst->size, wst->type, wst->dev, wst->qid.type,
+-              (unsigned long long)wst->qid.path, wst->qid.version, wst->mode,
+-              wst->atime, wst->mtime, (unsigned long long)wst->length,
+-              wst->name, wst->uid, wst->gid, wst->muid, wst->extension,
+-              from_kuid(&init_user_ns, wst->n_uid),
+-              from_kgid(&init_user_ns, wst->n_gid),
+-              from_kuid(&init_user_ns, wst->n_muid));
+-
+-      req = p9_client_rpc(clnt, P9_TWSTAT, "dwS", fid->fid, wst->size+2, wst);
++               "     sz=%x type=%x dev=%x qid=%x.%llx.%x\n"
++               "     mode=%8.8x atime=%8.8x mtime=%8.8x length=%llx\n"
++               "     name=%s uid=%s gid=%s muid=%s extension=(%s)\n"
++               "     uid=%d gid=%d n_muid=%d\n",
++               wst->size, wst->type, wst->dev, wst->qid.type,
++               wst->qid.path, wst->qid.version,
++               wst->mode, wst->atime, wst->mtime, wst->length,
++               wst->name, wst->uid, wst->gid, wst->muid, wst->extension,
++               from_kuid(&init_user_ns, wst->n_uid),
++               from_kgid(&init_user_ns, wst->n_gid),
++               from_kuid(&init_user_ns, wst->n_muid));
++
++      req = p9_client_rpc(clnt, P9_TWSTAT, "dwS",
++                          fid->fid, wst->size + 2, wst);
+       if (IS_ERR(req)) {
+               err = PTR_ERR(req);
+               goto error;
+@@ -1888,15 +1883,15 @@ int p9_client_setattr(struct p9_fid *fid, struct p9_iattr_dotl *p9attr)
+       err = 0;
+       clnt = fid->clnt;
+       p9_debug(P9_DEBUG_9P, ">>> TSETATTR fid %d\n", fid->fid);
+-      p9_debug(P9_DEBUG_9P,
+-              "    valid=%x mode=%x uid=%d gid=%d size=%lld\n"
+-              "    atime_sec=%lld atime_nsec=%lld\n"
+-              "    mtime_sec=%lld mtime_nsec=%lld\n",
+-              p9attr->valid, p9attr->mode,
+-              from_kuid(&init_user_ns, p9attr->uid),
+-              from_kgid(&init_user_ns, p9attr->gid),
+-              p9attr->size, p9attr->atime_sec, p9attr->atime_nsec,
+-              p9attr->mtime_sec, p9attr->mtime_nsec);
++      p9_debug(P9_DEBUG_9P, "    valid=%x mode=%x uid=%d gid=%d size=%lld\n",
++               p9attr->valid, p9attr->mode,
++               from_kuid(&init_user_ns, p9attr->uid),
++               from_kgid(&init_user_ns, p9attr->gid),
++               p9attr->size);
++      p9_debug(P9_DEBUG_9P, "    atime_sec=%lld atime_nsec=%lld\n",
++               p9attr->atime_sec, p9attr->atime_nsec);
++      p9_debug(P9_DEBUG_9P, "    mtime_sec=%lld mtime_nsec=%lld\n",
++               p9attr->mtime_sec, p9attr->mtime_nsec);
+       req = p9_client_rpc(clnt, P9_TSETATTR, "dI", fid->fid, p9attr);
+@@ -1937,12 +1932,10 @@ int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb)
+               goto error;
+       }
+-      p9_debug(P9_DEBUG_9P, "<<< RSTATFS fid %d type 0x%lx bsize %ld "
+-              "blocks %llu bfree %llu bavail %llu files %llu ffree %llu "
+-              "fsid %llu namelen %ld\n",
+-              fid->fid, (long unsigned int)sb->type, (long int)sb->bsize,
+-              sb->blocks, sb->bfree, sb->bavail, sb->files,  sb->ffree,
+-              sb->fsid, (long int)sb->namelen);
++      p9_debug(P9_DEBUG_9P,
++               "<<< RSTATFS fid %d type 0x%x bsize %u blocks %llu bfree %llu bavail %llu files %llu ffree %llu fsid %llu namelen %u\n",
++               fid->fid, sb->type, sb->bsize, sb->blocks, sb->bfree,
++               sb->bavail, sb->files, sb->ffree, sb->fsid, sb->namelen);
+       p9_tag_remove(clnt, req);
+ error:
+@@ -1961,10 +1954,10 @@ int p9_client_rename(struct p9_fid *fid,
+       clnt = fid->clnt;
+       p9_debug(P9_DEBUG_9P, ">>> TRENAME fid %d newdirfid %d name %s\n",
+-                      fid->fid, newdirfid->fid, name);
++               fid->fid, newdirfid->fid, name);
+       req = p9_client_rpc(clnt, P9_TRENAME, "dds", fid->fid,
+-                      newdirfid->fid, name);
++                          newdirfid->fid, name);
+       if (IS_ERR(req)) {
+               err = PTR_ERR(req);
+               goto error;
+@@ -1988,9 +1981,9 @@ int p9_client_renameat(struct p9_fid *olddirfid, const char *old_name,
+       err = 0;
+       clnt = olddirfid->clnt;
+-      p9_debug(P9_DEBUG_9P, ">>> TRENAMEAT olddirfid %d old name %s"
+-                 " newdirfid %d new name %s\n", olddirfid->fid, old_name,
+-                 newdirfid->fid, new_name);
++      p9_debug(P9_DEBUG_9P,
++               ">>> TRENAMEAT olddirfid %d old name %s newdirfid %d new name %s\n",
++               olddirfid->fid, old_name, newdirfid->fid, new_name);
+       req = p9_client_rpc(clnt, P9_TRENAMEAT, "dsds", olddirfid->fid,
+                           old_name, newdirfid->fid, new_name);
+@@ -2000,7 +1993,7 @@ int p9_client_renameat(struct p9_fid *olddirfid, const char *old_name,
+       }
+       p9_debug(P9_DEBUG_9P, "<<< RRENAMEAT newdirfid %d new name %s\n",
+-                 newdirfid->fid, new_name);
++               newdirfid->fid, new_name);
+       p9_tag_remove(clnt, req);
+ error:
+@@ -2008,11 +2001,10 @@ int p9_client_renameat(struct p9_fid *olddirfid, const char *old_name,
+ }
+ EXPORT_SYMBOL(p9_client_renameat);
+-/*
+- * An xattrwalk without @attr_name gives the fid for the lisxattr namespace
++/* An xattrwalk without @attr_name gives the fid for the lisxattr namespace
+  */
+ struct p9_fid *p9_client_xattrwalk(struct p9_fid *file_fid,
+-                              const char *attr_name, u64 *attr_size)
++                                 const char *attr_name, u64 *attr_size)
+ {
+       int err;
+       struct p9_req_t *req;
+@@ -2027,11 +2019,11 @@ struct p9_fid *p9_client_xattrwalk(struct p9_fid *file_fid,
+               goto error;
+       }
+       p9_debug(P9_DEBUG_9P,
+-              ">>> TXATTRWALK file_fid %d, attr_fid %d name %s\n",
+-              file_fid->fid, attr_fid->fid, attr_name);
++               ">>> TXATTRWALK file_fid %d, attr_fid %d name %s\n",
++               file_fid->fid, attr_fid->fid, attr_name);
+       req = p9_client_rpc(clnt, P9_TXATTRWALK, "dds",
+-                      file_fid->fid, attr_fid->fid, attr_name);
++                          file_fid->fid, attr_fid->fid, attr_name);
+       if (IS_ERR(req)) {
+               err = PTR_ERR(req);
+               goto error;
+@@ -2044,13 +2036,13 @@ struct p9_fid *p9_client_xattrwalk(struct p9_fid *file_fid,
+       }
+       p9_tag_remove(clnt, req);
+       p9_debug(P9_DEBUG_9P, "<<<  RXATTRWALK fid %d size %llu\n",
+-              attr_fid->fid, *attr_size);
++               attr_fid->fid, *attr_size);
+       return attr_fid;
+ clunk_fid:
+       p9_client_clunk(attr_fid);
+       attr_fid = NULL;
+ error:
+-      if (attr_fid && (attr_fid != file_fid))
++      if (attr_fid && attr_fid != file_fid)
+               p9_fid_destroy(attr_fid);
+       return ERR_PTR(err);
+@@ -2058,19 +2050,19 @@ struct p9_fid *p9_client_xattrwalk(struct p9_fid *file_fid,
+ EXPORT_SYMBOL_GPL(p9_client_xattrwalk);
+ int p9_client_xattrcreate(struct p9_fid *fid, const char *name,
+-                      u64 attr_size, int flags)
++                        u64 attr_size, int flags)
+ {
+       int err;
+       struct p9_req_t *req;
+       struct p9_client *clnt;
+       p9_debug(P9_DEBUG_9P,
+-              ">>> TXATTRCREATE fid %d name  %s size %lld flag %d\n",
+-              fid->fid, name, (long long)attr_size, flags);
++               ">>> TXATTRCREATE fid %d name  %s size %llu flag %d\n",
++               fid->fid, name, attr_size, flags);
+       err = 0;
+       clnt = fid->clnt;
+       req = p9_client_rpc(clnt, P9_TXATTRCREATE, "dsqd",
+-                      fid->fid, name, attr_size, flags);
++                          fid->fid, name, attr_size, flags);
+       if (IS_ERR(req)) {
+               err = PTR_ERR(req);
+               goto error;
+@@ -2094,13 +2086,13 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
+       iov_iter_kvec(&to, READ, &kv, 1, count);
+       p9_debug(P9_DEBUG_9P, ">>> TREADDIR fid %d offset %llu count %d\n",
+-                              fid->fid, (unsigned long long) offset, count);
++               fid->fid, offset, count);
+       err = 0;
+       clnt = fid->clnt;
+       rsize = fid->iounit;
+-      if (!rsize || rsize > clnt->msize-P9_READDIRHDRSZ)
++      if (!rsize || rsize > clnt->msize - P9_READDIRHDRSZ)
+               rsize = clnt->msize - P9_READDIRHDRSZ;
+       if (count < rsize)
+@@ -2108,8 +2100,7 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
+       /* Don't bother zerocopy for small IO (< 1024) */
+       if (clnt->trans_mod->zc_request && rsize > 1024) {
+-              /*
+-               * response header len is 11
++              /* response header len is 11
+                * PDU Header(7) + IO Size (4)
+                */
+               req = p9_client_zc_rpc(clnt, P9_TREADDIR, &to, NULL, rsize, 0,
+@@ -2150,7 +2141,7 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
+ EXPORT_SYMBOL(p9_client_readdir);
+ int p9_client_mknod_dotl(struct p9_fid *fid, const char *name, int mode,
+-                      dev_t rdev, kgid_t gid, struct p9_qid *qid)
++                       dev_t rdev, kgid_t gid, struct p9_qid *qid)
+ {
+       int err;
+       struct p9_client *clnt;
+@@ -2158,10 +2149,11 @@ int p9_client_mknod_dotl(struct p9_fid *fid, const char *name, int mode,
+       err = 0;
+       clnt = fid->clnt;
+-      p9_debug(P9_DEBUG_9P, ">>> TMKNOD fid %d name %s mode %d major %d "
+-              "minor %d\n", fid->fid, name, mode, MAJOR(rdev), MINOR(rdev));
++      p9_debug(P9_DEBUG_9P,
++               ">>> TMKNOD fid %d name %s mode %d major %d minor %d\n",
++               fid->fid, name, mode, MAJOR(rdev), MINOR(rdev));
+       req = p9_client_rpc(clnt, P9_TMKNOD, "dsdddg", fid->fid, name, mode,
+-              MAJOR(rdev), MINOR(rdev), gid);
++                          MAJOR(rdev), MINOR(rdev), gid);
+       if (IS_ERR(req))
+               return PTR_ERR(req);
+@@ -2170,18 +2162,17 @@ int p9_client_mknod_dotl(struct p9_fid *fid, const char *name, int mode,
+               trace_9p_protocol_dump(clnt, &req->rc);
+               goto error;
+       }
+-      p9_debug(P9_DEBUG_9P, "<<< RMKNOD qid %x.%llx.%x\n", qid->type,
+-                              (unsigned long long)qid->path, qid->version);
++      p9_debug(P9_DEBUG_9P, "<<< RMKNOD qid %x.%llx.%x\n",
++               qid->type, qid->path, qid->version);
+ error:
+       p9_tag_remove(clnt, req);
+       return err;
+-
+ }
+ EXPORT_SYMBOL(p9_client_mknod_dotl);
+ int p9_client_mkdir_dotl(struct p9_fid *fid, const char *name, int mode,
+-                              kgid_t gid, struct p9_qid *qid)
++                       kgid_t gid, struct p9_qid *qid)
+ {
+       int err;
+       struct p9_client *clnt;
+@@ -2191,8 +2182,8 @@ int p9_client_mkdir_dotl(struct p9_fid *fid, const char *name, int mode,
+       clnt = fid->clnt;
+       p9_debug(P9_DEBUG_9P, ">>> TMKDIR fid %d name %s mode %d gid %d\n",
+                fid->fid, name, mode, from_kgid(&init_user_ns, gid));
+-      req = p9_client_rpc(clnt, P9_TMKDIR, "dsdg", fid->fid, name, mode,
+-              gid);
++      req = p9_client_rpc(clnt, P9_TMKDIR, "dsdg",
++                          fid->fid, name, mode, gid);
+       if (IS_ERR(req))
+               return PTR_ERR(req);
+@@ -2202,12 +2193,11 @@ int p9_client_mkdir_dotl(struct p9_fid *fid, const char *name, int mode,
+               goto error;
+       }
+       p9_debug(P9_DEBUG_9P, "<<< RMKDIR qid %x.%llx.%x\n", qid->type,
+-                              (unsigned long long)qid->path, qid->version);
++               qid->path, qid->version);
+ error:
+       p9_tag_remove(clnt, req);
+       return err;
+-
+ }
+ EXPORT_SYMBOL(p9_client_mkdir_dotl);
+@@ -2219,14 +2209,14 @@ int p9_client_lock_dotl(struct p9_fid *fid, struct p9_flock *flock, u8 *status)
+       err = 0;
+       clnt = fid->clnt;
+-      p9_debug(P9_DEBUG_9P, ">>> TLOCK fid %d type %i flags %d "
+-                      "start %lld length %lld proc_id %d client_id %s\n",
+-                      fid->fid, flock->type, flock->flags, flock->start,
+-                      flock->length, flock->proc_id, flock->client_id);
++      p9_debug(P9_DEBUG_9P,
++               ">>> TLOCK fid %d type %i flags %d start %lld length %lld proc_id %d client_id %s\n",
++               fid->fid, flock->type, flock->flags, flock->start,
++               flock->length, flock->proc_id, flock->client_id);
+       req = p9_client_rpc(clnt, P9_TLOCK, "dbdqqds", fid->fid, flock->type,
+-                              flock->flags, flock->start, flock->length,
+-                                      flock->proc_id, flock->client_id);
++                          flock->flags, flock->start, flock->length,
++                          flock->proc_id, flock->client_id);
+       if (IS_ERR(req))
+               return PTR_ERR(req);
+@@ -2240,7 +2230,6 @@ int p9_client_lock_dotl(struct p9_fid *fid, struct p9_flock *flock, u8 *status)
+ error:
+       p9_tag_remove(clnt, req);
+       return err;
+-
+ }
+ EXPORT_SYMBOL(p9_client_lock_dotl);
+@@ -2252,12 +2241,14 @@ int p9_client_getlock_dotl(struct p9_fid *fid, struct p9_getlock *glock)
+       err = 0;
+       clnt = fid->clnt;
+-      p9_debug(P9_DEBUG_9P, ">>> TGETLOCK fid %d, type %i start %lld "
+-              "length %lld proc_id %d client_id %s\n", fid->fid, glock->type,
+-              glock->start, glock->length, glock->proc_id, glock->client_id);
++      p9_debug(P9_DEBUG_9P,
++               ">>> TGETLOCK fid %d, type %i start %lld length %lld proc_id %d client_id %s\n",
++               fid->fid, glock->type, glock->start, glock->length,
++               glock->proc_id, glock->client_id);
+-      req = p9_client_rpc(clnt, P9_TGETLOCK, "dbqqds", fid->fid,  glock->type,
+-              glock->start, glock->length, glock->proc_id, glock->client_id);
++      req = p9_client_rpc(clnt, P9_TGETLOCK, "dbqqds", fid->fid,
++                          glock->type, glock->start, glock->length,
++                          glock->proc_id, glock->client_id);
+       if (IS_ERR(req))
+               return PTR_ERR(req);
+@@ -2269,9 +2260,10 @@ int p9_client_getlock_dotl(struct p9_fid *fid, struct p9_getlock *glock)
+               trace_9p_protocol_dump(clnt, &req->rc);
+               goto error;
+       }
+-      p9_debug(P9_DEBUG_9P, "<<< RGETLOCK type %i start %lld length %lld "
+-              "proc_id %d client_id %s\n", glock->type, glock->start,
+-              glock->length, glock->proc_id, glock->client_id);
++      p9_debug(P9_DEBUG_9P,
++               "<<< RGETLOCK type %i start %lld length %lld proc_id %d client_id %s\n",
++               glock->type, glock->start, glock->length,
++               glock->proc_id, glock->client_id);
+ error:
+       p9_tag_remove(clnt, req);
+       return err;
+diff --git a/net/9p/error.c b/net/9p/error.c
+index 61c18daf3050..ff935746754e 100644
+--- a/net/9p/error.c
++++ b/net/9p/error.c
+@@ -185,7 +185,7 @@ int p9_error_init(void)
+               INIT_HLIST_HEAD(&hash_errmap[bucket]);
+       /* load initial error map into hash table */
+-      for (c = errmap; c->name != NULL; c++) {
++      for (c = errmap; c->name; c++) {
+               c->namelen = strlen(c->name);
+               bucket = jhash(c->name, c->namelen, 0) % ERRHASHSZ;
+               INIT_HLIST_NODE(&c->list);
+diff --git a/net/9p/mod.c b/net/9p/mod.c
+index 5126566850bd..535cf016633c 100644
+--- a/net/9p/mod.c
++++ b/net/9p/mod.c
+@@ -24,13 +24,13 @@
+ #include <linux/spinlock.h>
+ #ifdef CONFIG_NET_9P_DEBUG
+-unsigned int p9_debug_level = 0;      /* feature-rific global debug level  */
++unsigned int p9_debug_level;  /* feature-rific global debug level  */
+ EXPORT_SYMBOL(p9_debug_level);
+ module_param_named(debug, p9_debug_level, uint, 0);
+ MODULE_PARM_DESC(debug, "9P debugging level");
+ void _p9_debug(enum p9_debug_flags level, const char *func,
+-              const char *fmt, ...)
++             const char *fmt, ...)
+ {
+       struct va_format vaf;
+       va_list args;
+@@ -53,10 +53,7 @@ void _p9_debug(enum p9_debug_flags level, const char *func,
+ EXPORT_SYMBOL(_p9_debug);
+ #endif
+-/*
+- * Dynamic Transport Registration Routines
+- *
+- */
++/* Dynamic Transport Registration Routines */
+ static DEFINE_SPINLOCK(v9fs_trans_lock);
+ static LIST_HEAD(v9fs_trans_list);
+diff --git a/net/9p/protocol.c b/net/9p/protocol.c
+index 03593eb240d8..59eb71f357fa 100644
+--- a/net/9p/protocol.c
++++ b/net/9p/protocol.c
+@@ -46,6 +46,7 @@ EXPORT_SYMBOL(p9stat_free);
+ size_t pdu_read(struct p9_fcall *pdu, void *data, size_t size)
+ {
+       size_t len = min(pdu->size - pdu->offset, size);
++
+       memcpy(data, &pdu->sdata[pdu->offset], len);
+       pdu->offset += len;
+       return size - len;
+@@ -54,6 +55,7 @@ size_t pdu_read(struct p9_fcall *pdu, void *data, size_t size)
+ static size_t pdu_write(struct p9_fcall *pdu, const void *data, size_t size)
+ {
+       size_t len = min(pdu->capacity - pdu->size, size);
++
+       memcpy(&pdu->sdata[pdu->size], data, len);
+       pdu->size += len;
+       return size - len;
+@@ -64,6 +66,7 @@ pdu_write_u(struct p9_fcall *pdu, struct iov_iter *from, size_t size)
+ {
+       size_t len = min(pdu->capacity - pdu->size, size);
+       struct iov_iter i = *from;
++
+       if (!copy_from_iter_full(&pdu->sdata[pdu->size], len, &i))
+               len = 0;
+@@ -71,26 +74,25 @@ pdu_write_u(struct p9_fcall *pdu, struct iov_iter *from, size_t size)
+       return size - len;
+ }
+-/*
+-      b - int8_t
+-      w - int16_t
+-      d - int32_t
+-      q - int64_t
+-      s - string
+-      u - numeric uid
+-      g - numeric gid
+-      S - stat
+-      Q - qid
+-      D - data blob (int32_t size followed by void *, results are not freed)
+-      T - array of strings (int16_t count, followed by strings)
+-      R - array of qids (int16_t count, followed by qids)
+-      A - stat for 9p2000.L (p9_stat_dotl)
+-      ? - if optional = 1, continue parsing
+-*/
++/*    b - int8_t
++ *    w - int16_t
++ *    d - int32_t
++ *    q - int64_t
++ *    s - string
++ *    u - numeric uid
++ *    g - numeric gid
++ *    S - stat
++ *    Q - qid
++ *    D - data blob (int32_t size followed by void *, results are not freed)
++ *    T - array of strings (int16_t count, followed by strings)
++ *    R - array of qids (int16_t count, followed by qids)
++ *    A - stat for 9p2000.L (p9_stat_dotl)
++ *    ? - if optional = 1, continue parsing
++ */
+ static int
+ p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt,
+-      va_list ap)
++           va_list ap)
+ {
+       const char *ptr;
+       int errcode = 0;
+diff --git a/net/9p/protocol.h b/net/9p/protocol.h
+index 6835f91cfda5..4a2f68651037 100644
+--- a/net/9p/protocol.h
++++ b/net/9p/protocol.h
+@@ -11,7 +11,7 @@
+  */
+ int p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
+-                                                              va_list ap);
++                va_list ap);
+ int p9pdu_readf(struct p9_fcall *pdu, int proto_version, const char *fmt, ...);
+ int p9pdu_prepare(struct p9_fcall *pdu, int16_t tag, int8_t type);
+ int p9pdu_finalize(struct p9_client *clnt, struct p9_fcall *pdu);
+diff --git a/net/9p/trans_common.h b/net/9p/trans_common.h
+index c43babb3f635..65c094c321a2 100644
+--- a/net/9p/trans_common.h
++++ b/net/9p/trans_common.h
+@@ -12,4 +12,4 @@
+  *
+  */
+-void p9_release_pages(struct page **, int);
++void p9_release_pages(struct page **pages, int nr_pages);
+-- 
+2.35.1
+
diff --git a/queue-5.15/acpi-apei-explicit-init-of-hest-and-ghes-in-apci_ini.patch b/queue-5.15/acpi-apei-explicit-init-of-hest-and-ghes-in-apci_ini.patch
new file mode 100644 (file)
index 0000000..f161996
--- /dev/null
@@ -0,0 +1,224 @@
+From 5566f2fac91ec4e44bf24dc41db616ae02e653ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 27 Feb 2022 20:25:45 +0800
+Subject: ACPI: APEI: explicit init of HEST and GHES in apci_init()
+
+From: Shuai Xue <xueshuai@linux.alibaba.com>
+
+[ Upstream commit dc4e8c07e9e2f69387579c49caca26ba239f7270 ]
+
+From commit e147133a42cb ("ACPI / APEI: Make hest.c manage the estatus
+memory pool") was merged, ghes_init() relies on acpi_hest_init() to manage
+the estatus memory pool. On the other hand, ghes_init() relies on
+sdei_init() to detect the SDEI version and (un)register events. The
+dependencies are as follows:
+
+    ghes_init() => acpi_hest_init() => acpi_bus_init() => acpi_init()
+    ghes_init() => sdei_init()
+
+HEST is not PCI-specific and initcall ordering is implicit and not
+well-defined within a level.
+
+Based on above, remove acpi_hest_init() from acpi_pci_root_init() and
+convert ghes_init() and sdei_init() from initcalls to explicit calls in the
+following order:
+
+    acpi_hest_init()
+    ghes_init()
+        sdei_init()
+
+Signed-off-by: Shuai Xue <xueshuai@linux.alibaba.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/apei/ghes.c    | 19 ++++++++-----------
+ drivers/acpi/bus.c          |  2 ++
+ drivers/acpi/pci_root.c     |  3 ---
+ drivers/firmware/Kconfig    |  1 +
+ drivers/firmware/arm_sdei.c | 13 ++-----------
+ include/acpi/apei.h         |  4 +++-
+ include/linux/arm_sdei.h    |  2 ++
+ 7 files changed, 18 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
+index 0c8330ed1ffd..06b0184fa912 100644
+--- a/drivers/acpi/apei/ghes.c
++++ b/drivers/acpi/apei/ghes.c
+@@ -1457,33 +1457,35 @@ static struct platform_driver ghes_platform_driver = {
+       .remove         = ghes_remove,
+ };
+-static int __init ghes_init(void)
++void __init ghes_init(void)
+ {
+       int rc;
++      sdei_init();
++
+       if (acpi_disabled)
+-              return -ENODEV;
++              return;
+       switch (hest_disable) {
+       case HEST_NOT_FOUND:
+-              return -ENODEV;
++              return;
+       case HEST_DISABLED:
+               pr_info(GHES_PFX "HEST is not enabled!\n");
+-              return -EINVAL;
++              return;
+       default:
+               break;
+       }
+       if (ghes_disable) {
+               pr_info(GHES_PFX "GHES is not enabled!\n");
+-              return -EINVAL;
++              return;
+       }
+       ghes_nmi_init_cxt();
+       rc = platform_driver_register(&ghes_platform_driver);
+       if (rc)
+-              goto err;
++              return;
+       rc = apei_osc_setup();
+       if (rc == 0 && osc_sb_apei_support_acked)
+@@ -1494,9 +1496,4 @@ static int __init ghes_init(void)
+               pr_info(GHES_PFX "APEI firmware first mode is enabled by APEI bit.\n");
+       else
+               pr_info(GHES_PFX "Failed to enable APEI firmware first mode.\n");
+-
+-      return 0;
+-err:
+-      return rc;
+ }
+-device_initcall(ghes_init);
+diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
+index 3500744e6862..fc9bb06d5411 100644
+--- a/drivers/acpi/bus.c
++++ b/drivers/acpi/bus.c
+@@ -1340,6 +1340,8 @@ static int __init acpi_init(void)
+       pci_mmcfg_late_init();
+       acpi_iort_init();
++      acpi_hest_init();
++      ghes_init();
+       acpi_scan_init();
+       acpi_ec_init();
+       acpi_debugfs_init();
+diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
+index d7deedf3548e..223aa010dd8d 100644
+--- a/drivers/acpi/pci_root.c
++++ b/drivers/acpi/pci_root.c
+@@ -22,8 +22,6 @@
+ #include <linux/slab.h>
+ #include <linux/dmi.h>
+ #include <linux/platform_data/x86/apple.h>
+-#include <acpi/apei.h>        /* for acpi_hest_init() */
+-
+ #include "internal.h"
+ #define ACPI_PCI_ROOT_CLASS           "pci_bridge"
+@@ -938,7 +936,6 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
+ void __init acpi_pci_root_init(void)
+ {
+-      acpi_hest_init();
+       if (acpi_pci_disabled)
+               return;
+diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
+index cda7d7162cbb..97ce31e667fc 100644
+--- a/drivers/firmware/Kconfig
++++ b/drivers/firmware/Kconfig
+@@ -40,6 +40,7 @@ config ARM_SCPI_POWER_DOMAIN
+ config ARM_SDE_INTERFACE
+       bool "ARM Software Delegated Exception Interface (SDEI)"
+       depends on ARM64
++      depends on ACPI_APEI_GHES
+       help
+         The Software Delegated Exception Interface (SDEI) is an ARM
+         standard for registering callbacks from the platform firmware
+diff --git a/drivers/firmware/arm_sdei.c b/drivers/firmware/arm_sdei.c
+index a7e762c352f9..1e1a51510e83 100644
+--- a/drivers/firmware/arm_sdei.c
++++ b/drivers/firmware/arm_sdei.c
+@@ -1059,14 +1059,14 @@ static bool __init sdei_present_acpi(void)
+       return true;
+ }
+-static int __init sdei_init(void)
++void __init sdei_init(void)
+ {
+       struct platform_device *pdev;
+       int ret;
+       ret = platform_driver_register(&sdei_driver);
+       if (ret || !sdei_present_acpi())
+-              return ret;
++              return;
+       pdev = platform_device_register_simple(sdei_driver.driver.name,
+                                              0, NULL, 0);
+@@ -1076,17 +1076,8 @@ static int __init sdei_init(void)
+               pr_info("Failed to register ACPI:SDEI platform device %d\n",
+                       ret);
+       }
+-
+-      return ret;
+ }
+-/*
+- * On an ACPI system SDEI needs to be ready before HEST:GHES tries to register
+- * its events. ACPI is initialised from a subsys_initcall(), GHES is initialised
+- * by device_initcall(). We want to be called in the middle.
+- */
+-subsys_initcall_sync(sdei_init);
+-
+ int sdei_event_handler(struct pt_regs *regs,
+                      struct sdei_registered_event *arg)
+ {
+diff --git a/include/acpi/apei.h b/include/acpi/apei.h
+index 680f80960c3d..a6ac2e8b72da 100644
+--- a/include/acpi/apei.h
++++ b/include/acpi/apei.h
+@@ -27,14 +27,16 @@ extern int hest_disable;
+ extern int erst_disable;
+ #ifdef CONFIG_ACPI_APEI_GHES
+ extern bool ghes_disable;
++void __init ghes_init(void);
+ #else
+ #define ghes_disable 1
++static inline void ghes_init(void) { }
+ #endif
+ #ifdef CONFIG_ACPI_APEI
+ void __init acpi_hest_init(void);
+ #else
+-static inline void acpi_hest_init(void) { return; }
++static inline void acpi_hest_init(void) { }
+ #endif
+ typedef int (*apei_hest_func_t)(struct acpi_hest_header *hest_hdr, void *data);
+diff --git a/include/linux/arm_sdei.h b/include/linux/arm_sdei.h
+index 0a241c5c911d..14dc461b0e82 100644
+--- a/include/linux/arm_sdei.h
++++ b/include/linux/arm_sdei.h
+@@ -46,9 +46,11 @@ int sdei_unregister_ghes(struct ghes *ghes);
+ /* For use by arch code when CPU hotplug notifiers are not appropriate. */
+ int sdei_mask_local_cpu(void);
+ int sdei_unmask_local_cpu(void);
++void __init sdei_init(void);
+ #else
+ static inline int sdei_mask_local_cpu(void) { return 0; }
+ static inline int sdei_unmask_local_cpu(void) { return 0; }
++static inline void sdei_init(void) { }
+ #endif /* CONFIG_ARM_SDE_INTERFACE */
+-- 
+2.35.1
+
diff --git a/queue-5.15/acpi-apei-fix-_einj-vs-efi_memory_sp.patch b/queue-5.15/acpi-apei-fix-_einj-vs-efi_memory_sp.patch
new file mode 100644 (file)
index 0000000..330bc92
--- /dev/null
@@ -0,0 +1,41 @@
+From bac5303f2093a3faaeb7b9f321ea39ecc5745377 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jun 2022 16:05:26 -0700
+Subject: ACPI: APEI: Fix _EINJ vs EFI_MEMORY_SP
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+[ Upstream commit b13a3e5fd40b7d1b394c5ecbb5eb301a4c38e7b2 ]
+
+When a platform marks a memory range as "special purpose" it is not
+onlined as System RAM by default. However, it is still suitable for
+error injection. Add IORES_DESC_SOFT_RESERVED to einj_error_inject() as
+a permissible memory type in the sanity checking of the arguments to
+_EINJ.
+
+Fixes: 262b45ae3ab4 ("x86/efi: EFI soft reservation to E820 enumeration")
+Reviewed-by: Tony Luck <tony.luck@intel.com>
+Reported-by: Omar Avelar <omar.avelar@intel.com>
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/apei/einj.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c
+index 2882450c443e..2e0ab898cce3 100644
+--- a/drivers/acpi/apei/einj.c
++++ b/drivers/acpi/apei/einj.c
+@@ -544,6 +544,8 @@ static int einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2,
+           ((region_intersects(base_addr, size, IORESOURCE_SYSTEM_RAM, IORES_DESC_NONE)
+                               != REGION_INTERSECTS) &&
+            (region_intersects(base_addr, size, IORESOURCE_MEM, IORES_DESC_PERSISTENT_MEMORY)
++                              != REGION_INTERSECTS) &&
++           (region_intersects(base_addr, size, IORESOURCE_MEM, IORES_DESC_SOFT_RESERVED)
+                               != REGION_INTERSECTS)))
+               return -EINVAL;
+-- 
+2.35.1
+
diff --git a/queue-5.15/acpi-ec-drop-the-ec_flags_ignore_dsdt_gpe-quirk.patch b/queue-5.15/acpi-ec-drop-the-ec_flags_ignore_dsdt_gpe-quirk.patch
new file mode 100644 (file)
index 0000000..03a4337
--- /dev/null
@@ -0,0 +1,211 @@
+From fe591882e6af9aa86d9c12a3de7e70c24868dbe4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jun 2022 11:25:44 +0200
+Subject: ACPI: EC: Drop the EC_FLAGS_IGNORE_DSDT_GPE quirk
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit f7090e0ef360d674f08a22fab90e4e209fb1f658 ]
+
+It seems that these quirks are no longer necessary since
+commit 69b957c26b32 ("ACPI: EC: Fix possible issues related to EC
+initialization order"), which has fixed this in a generic manner.
+
+There are 3 commits adding DMI entries with this quirk (adding multiple
+DMI entries per commit). 2/3 commits are from before the generic fix.
+
+Which leaves commit 6306f0431914 ("ACPI: EC: Make more Asus laptops
+use ECDT _GPE"), which was committed way after the generic fix.
+But this was just due to slow upstreaming of it. This commit stems
+from Endless from 15 Aug 2017 (committed upstream 20 May 2021):
+https://github.com/endlessm/linux/pull/288
+
+The current code should work fine without this:
+
+ 1. The EC_FLAGS_IGNORE_DSDT_GPE flag is only checked in ec_parse_device(),
+    like this:
+
+       if (boot_ec && boot_ec_is_ecdt && EC_FLAGS_IGNORE_DSDT_GPE) {
+               ec->gpe = boot_ec->gpe;
+       } else {
+               /* parse GPE */
+       }
+
+ 2. ec_parse_device() is only called from acpi_ec_add() and
+    acpi_ec_dsdt_probe()
+
+ 3. acpi_ec_dsdt_probe() starts with:
+
+       if (boot_ec)
+               return;
+
+    so it only calls ec_parse_device() when boot_ec == NULL, meaning that
+    the quirk never triggers for this call. So only the call in
+    acpi_ec_add() matters.
+
+ 4. acpi_ec_add() does the following after the ec_parse_device() call:
+
+       if (boot_ec && ec->command_addr == boot_ec->command_addr &&
+           ec->data_addr == boot_ec->data_addr &&
+           !EC_FLAGS_TRUST_DSDT_GPE) {
+               /*
+                * Trust PNP0C09 namespace location rather than
+                * ECDT ID. But trust ECDT GPE rather than _GPE
+                * because of ASUS quirks, so do not change
+                * boot_ec->gpe to ec->gpe.
+                */
+               boot_ec->handle = ec->handle;
+               acpi_handle_debug(ec->handle, "duplicated.\n");
+               acpi_ec_free(ec);
+               ec = boot_ec;
+       }
+
+The quirk only matters if boot_ec != NULL and EC_FLAGS_TRUST_DSDT_GPE
+is never set at the same time as EC_FLAGS_IGNORE_DSDT_GPE.
+
+That means that if the addresses match we always enter this if block and
+then only the ec->handle part of the data stored in ec by ec_parse_device()
+is used and the rest is thrown away, after which ec is made to point
+to boot_ec, at which point ec->gpe == boot_ec->gpe, so the same result
+as with the quirk set, independent of the value of the quirk.
+
+Also note the comment in this block which indicates that the gpe result
+from ec_parse_device() is deliberately not taken to deal with buggy
+Asus laptops and all DMI quirks setting EC_FLAGS_IGNORE_DSDT_GPE are for
+Asus laptops.
+
+Based on the above I believe that unless on some quirked laptops
+the ECDT and DSDT EC addresses do not match we can drop the quirk.
+
+I've checked dmesg output to ensure the ECDT and DSDT EC addresses match
+for quirked models using https://linux-hardware.org hw-probe reports.
+
+I've been able to confirm that the addresses match for the following
+models this way: GL702VMK, X505BA, X505BP, X550VXK, X580VD.
+Whereas for the following models I could find any dmesg output:
+FX502VD, FX502VE, X542BA, X542BP.
+
+Note the models without dmesg all were submitted in patches with a batch
+of models and other models from the same batch checkout ok.
+
+This, combined with that all the code adding the quirks was written before
+the generic fix makes me believe that it is safe to remove this quirk now.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Reviewed-by: Daniel Drake <drake@endlessos.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/ec.c | 75 ++++++-----------------------------------------
+ 1 file changed, 9 insertions(+), 66 deletions(-)
+
+diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
+index d41fa0f3a1ac..4e583a8cb562 100644
+--- a/drivers/acpi/ec.c
++++ b/drivers/acpi/ec.c
+@@ -183,7 +183,6 @@ static struct workqueue_struct *ec_wq;
+ static struct workqueue_struct *ec_query_wq;
+ static int EC_FLAGS_CORRECT_ECDT; /* Needs ECDT port address correction */
+-static int EC_FLAGS_IGNORE_DSDT_GPE; /* Needs ECDT GPE as correction setting */
+ static int EC_FLAGS_TRUST_DSDT_GPE; /* Needs DSDT GPE as correction setting */
+ static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */
+@@ -1392,24 +1391,16 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
+       if (ec->data_addr == 0 || ec->command_addr == 0)
+               return AE_OK;
+-      if (boot_ec && boot_ec_is_ecdt && EC_FLAGS_IGNORE_DSDT_GPE) {
+-              /*
+-               * Always inherit the GPE number setting from the ECDT
+-               * EC.
+-               */
+-              ec->gpe = boot_ec->gpe;
+-      } else {
+-              /* Get GPE bit assignment (EC events). */
+-              /* TODO: Add support for _GPE returning a package */
+-              status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp);
+-              if (ACPI_SUCCESS(status))
+-                      ec->gpe = tmp;
++      /* Get GPE bit assignment (EC events). */
++      /* TODO: Add support for _GPE returning a package */
++      status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp);
++      if (ACPI_SUCCESS(status))
++              ec->gpe = tmp;
++      /*
++       * Errors are non-fatal, allowing for ACPI Reduced Hardware
++       * platforms which use GpioInt instead of GPE.
++       */
+-              /*
+-               * Errors are non-fatal, allowing for ACPI Reduced Hardware
+-               * platforms which use GpioInt instead of GPE.
+-               */
+-      }
+       /* Use the global lock for all EC transactions? */
+       tmp = 0;
+       acpi_evaluate_integer(handle, "_GLK", NULL, &tmp);
+@@ -1847,60 +1838,12 @@ static int ec_honor_dsdt_gpe(const struct dmi_system_id *id)
+       return 0;
+ }
+-/*
+- * Some DSDTs contain wrong GPE setting.
+- * Asus FX502VD/VE, GL702VMK, X550VXK, X580VD
+- * https://bugzilla.kernel.org/show_bug.cgi?id=195651
+- */
+-static int ec_honor_ecdt_gpe(const struct dmi_system_id *id)
+-{
+-      pr_debug("Detected system needing ignore DSDT GPE setting.\n");
+-      EC_FLAGS_IGNORE_DSDT_GPE = 1;
+-      return 0;
+-}
+-
+ static const struct dmi_system_id ec_dmi_table[] __initconst = {
+       {
+       ec_correct_ecdt, "MSI MS-171F", {
+       DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star"),
+       DMI_MATCH(DMI_PRODUCT_NAME, "MS-171F"),}, NULL},
+       {
+-      ec_honor_ecdt_gpe, "ASUS FX502VD", {
+-      DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+-      DMI_MATCH(DMI_PRODUCT_NAME, "FX502VD"),}, NULL},
+-      {
+-      ec_honor_ecdt_gpe, "ASUS FX502VE", {
+-      DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+-      DMI_MATCH(DMI_PRODUCT_NAME, "FX502VE"),}, NULL},
+-      {
+-      ec_honor_ecdt_gpe, "ASUS GL702VMK", {
+-      DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+-      DMI_MATCH(DMI_PRODUCT_NAME, "GL702VMK"),}, NULL},
+-      {
+-      ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X505BA", {
+-      DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+-      DMI_MATCH(DMI_PRODUCT_NAME, "X505BA"),}, NULL},
+-      {
+-      ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X505BP", {
+-      DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+-      DMI_MATCH(DMI_PRODUCT_NAME, "X505BP"),}, NULL},
+-      {
+-      ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X542BA", {
+-      DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+-      DMI_MATCH(DMI_PRODUCT_NAME, "X542BA"),}, NULL},
+-      {
+-      ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X542BP", {
+-      DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+-      DMI_MATCH(DMI_PRODUCT_NAME, "X542BP"),}, NULL},
+-      {
+-      ec_honor_ecdt_gpe, "ASUS X550VXK", {
+-      DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+-      DMI_MATCH(DMI_PRODUCT_NAME, "X550VXK"),}, NULL},
+-      {
+-      ec_honor_ecdt_gpe, "ASUS X580VD", {
+-      DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+-      DMI_MATCH(DMI_PRODUCT_NAME, "X580VD"),}, NULL},
+-      {
+       /* https://bugzilla.kernel.org/show_bug.cgi?id=209989 */
+       ec_honor_dsdt_gpe, "HP Pavilion Gaming Laptop 15-cx0xxx", {
+       DMI_MATCH(DMI_SYS_VENDOR, "HP"),
+-- 
+2.35.1
+
diff --git a/queue-5.15/acpi-ec-remove-duplicate-thinkpad-x1-carbon-6th-entr.patch b/queue-5.15/acpi-ec-remove-duplicate-thinkpad-x1-carbon-6th-entr.patch
new file mode 100644 (file)
index 0000000..b064929
--- /dev/null
@@ -0,0 +1,42 @@
+From 7de171ddb57f0de6bff27ccc66a44614fcbc1546 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jun 2022 11:25:43 +0200
+Subject: ACPI: EC: Remove duplicate ThinkPad X1 Carbon 6th entry from DMI
+ quirks
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 0dd6db359e5f206cbf1dd1fd40dd211588cd2725 ]
+
+Somehow the "ThinkPad X1 Carbon 6th" entry ended up twice in the
+struct dmi_system_id acpi_ec_no_wakeup[] array. Remove one of
+the entries.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/ec.c | 7 -------
+ 1 file changed, 7 deletions(-)
+
+diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
+index 9b859ff976e8..d41fa0f3a1ac 100644
+--- a/drivers/acpi/ec.c
++++ b/drivers/acpi/ec.c
+@@ -2167,13 +2167,6 @@ static const struct dmi_system_id acpi_ec_no_wakeup[] = {
+                       DMI_MATCH(DMI_PRODUCT_FAMILY, "Thinkpad X1 Carbon 6th"),
+               },
+       },
+-      {
+-              .ident = "ThinkPad X1 Carbon 6th",
+-              .matches = {
+-                      DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+-                      DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Carbon 6th"),
+-              },
+-      },
+       {
+               .ident = "ThinkPad X1 Yoga 3rd",
+               .matches = {
+-- 
+2.35.1
+
diff --git a/queue-5.15/acpi-lpss-fix-missing-check-in-register_device_clock.patch b/queue-5.15/acpi-lpss-fix-missing-check-in-register_device_clock.patch
new file mode 100644 (file)
index 0000000..26c2749
--- /dev/null
@@ -0,0 +1,36 @@
+From 2c69431aabf95b00ae4d66c3e7ffa623efa61b35 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jun 2022 21:21:27 +0800
+Subject: ACPI: LPSS: Fix missing check in register_device_clock()
+
+From: huhai <huhai@kylinos.cn>
+
+[ Upstream commit b4f1f61ed5928b1128e60e38d0dffa16966f06dc ]
+
+register_device_clock() misses a check for platform_device_register_simple().
+Add a check to fix it.
+
+Signed-off-by: huhai <huhai@kylinos.cn>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/acpi_lpss.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
+index 30b1f511c2af..f609f9d62efd 100644
+--- a/drivers/acpi/acpi_lpss.c
++++ b/drivers/acpi/acpi_lpss.c
+@@ -403,6 +403,9 @@ static int register_device_clock(struct acpi_device *adev,
+       if (!lpss_clk_dev)
+               lpt_register_clock_device();
++      if (IS_ERR(lpss_clk_dev))
++              return PTR_ERR(lpss_clk_dev);
++
+       clk_data = platform_get_drvdata(lpss_clk_dev);
+       if (!clk_data)
+               return -ENODEV;
+-- 
+2.35.1
+
diff --git a/queue-5.15/acpi-pm-save-nvs-memory-for-lenovo-g40-45.patch b/queue-5.15/acpi-pm-save-nvs-memory-for-lenovo-g40-45.patch
new file mode 100644 (file)
index 0000000..22e738e
--- /dev/null
@@ -0,0 +1,44 @@
+From 648438ac9d87cb7832ce63c729ed65be0521a556 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jun 2022 15:42:48 +0800
+Subject: ACPI: PM: save NVS memory for Lenovo G40-45
+
+From: Manyi Li <limanyi@uniontech.com>
+
+[ Upstream commit 4b7ef7b05afcde44142225c184bf43a0cd9e2178 ]
+
+[821d6f0359b0614792ab8e2fb93b503e25a65079] is to make machines
+produced from 2012 to now not saving NVS region to accelerate S3.
+
+But, Lenovo G40-45, a platform released in 2015, still needs NVS memory
+saving during S3. A quirk is introduced for this platform.
+
+Signed-off-by: Manyi Li <limanyi@uniontech.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/sleep.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
+index 07515139141e..d7194047d256 100644
+--- a/drivers/acpi/sleep.c
++++ b/drivers/acpi/sleep.c
+@@ -361,6 +361,14 @@ static const struct dmi_system_id acpisleep_dmi_table[] __initconst = {
+               DMI_MATCH(DMI_PRODUCT_NAME, "80E3"),
+               },
+       },
++      {
++      .callback = init_nvs_save_s3,
++      .ident = "Lenovo G40-45",
++      .matches = {
++              DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++              DMI_MATCH(DMI_PRODUCT_NAME, "80E1"),
++              },
++      },
+       /*
+        * ThinkPad X1 Tablet(2016) cannot do suspend-to-idle using
+        * the Low Power S0 Idle firmware interface (see
+-- 
+2.35.1
+
diff --git a/queue-5.15/acpi-processor-idle-annotate-more-functions-to-live-.patch b/queue-5.15/acpi-processor-idle-annotate-more-functions-to-live-.patch
new file mode 100644 (file)
index 0000000..4522610
--- /dev/null
@@ -0,0 +1,63 @@
+From 72f0ea376c4e4d9e6fadf2bd52a4154cecf2fb6c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jun 2022 19:24:58 -0300
+Subject: ACPI: processor/idle: Annotate more functions to live in cpuidle
+ section
+
+From: Guilherme G. Piccoli <gpiccoli@igalia.com>
+
+[ Upstream commit 409dfdcaffb266acfc1f33529a26b1443c9332d4 ]
+
+Commit 6727ad9e206c ("nmi_backtrace: generate one-line reports for idle cpus")
+introduced a new text section called cpuidle; with that, we have a mechanism
+to add idling functions in such section and skip them from nmi_backtrace
+output, since they're useless and potentially flooding for such report.
+
+Happens that inlining might cause some real idle functions to end-up
+outside of such section; this is currently the case of ACPI processor_idle
+driver; the functions acpi_idle_enter_* do inline acpi_idle_do_entry(),
+hence they stay out of the cpuidle section.
+Fix that by marking such functions to also live in the cpuidle section.
+
+Fixes: 6727ad9e206c ("nmi_backtrace: generate one-line reports for idle cpus")
+Signed-off-by: Guilherme G. Piccoli <gpiccoli@igalia.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/processor_idle.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
+index aedcb92491f2..dc880dad2ade 100644
+--- a/drivers/acpi/processor_idle.c
++++ b/drivers/acpi/processor_idle.c
+@@ -604,7 +604,7 @@ static DEFINE_RAW_SPINLOCK(c3_lock);
+  * @cx: Target state context
+  * @index: index of target state
+  */
+-static int acpi_idle_enter_bm(struct cpuidle_driver *drv,
++static int __cpuidle acpi_idle_enter_bm(struct cpuidle_driver *drv,
+                              struct acpi_processor *pr,
+                              struct acpi_processor_cx *cx,
+                              int index)
+@@ -661,7 +661,7 @@ static int acpi_idle_enter_bm(struct cpuidle_driver *drv,
+       return index;
+ }
+-static int acpi_idle_enter(struct cpuidle_device *dev,
++static int __cpuidle acpi_idle_enter(struct cpuidle_device *dev,
+                          struct cpuidle_driver *drv, int index)
+ {
+       struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu);
+@@ -690,7 +690,7 @@ static int acpi_idle_enter(struct cpuidle_device *dev,
+       return index;
+ }
+-static int acpi_idle_enter_s2idle(struct cpuidle_device *dev,
++static int __cpuidle acpi_idle_enter_s2idle(struct cpuidle_device *dev,
+                                 struct cpuidle_driver *drv, int index)
+ {
+       struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu);
+-- 
+2.35.1
+
diff --git a/queue-5.15/acpi-viot-fix-acs-setup.patch b/queue-5.15/acpi-viot-fix-acs-setup.patch
new file mode 100644 (file)
index 0000000..f5c184b
--- /dev/null
@@ -0,0 +1,112 @@
+From 024c37323ddbd9c6bc38d65b56146d6391d7d12c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Jun 2022 11:40:59 +0200
+Subject: ACPI: VIOT: Fix ACS setup
+
+From: Eric Auger <eric.auger@redhat.com>
+
+[ Upstream commit 3dcb861dbc6ab101838a1548b1efddd00ca3c3ec ]
+
+Currently acpi_viot_init() gets called after the pci
+device has been scanned and pci_enable_acs() has been called.
+So pci_request_acs() fails to be taken into account leading
+to wrong single iommu group topologies when dealing with
+multi-function root ports for instance.
+
+We cannot simply move the acpi_viot_init() earlier, similarly
+as the IORT init because the VIOT parsing relies on the pci
+scan. However we can detect VIOT is present earlier and in
+such a case, request ACS. Introduce a new acpi_viot_early_init()
+routine that allows to call pci_request_acs() before the scan.
+
+While at it, guard the call to pci_request_acs() with #ifdef
+CONFIG_PCI.
+
+Fixes: 3cf485540e7b ("ACPI: Add driver for the VIOT table")
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+Reported-by: Jin Liu <jinl@redhat.com>
+Reviewed-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
+Tested-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/bus.c        |  1 +
+ drivers/acpi/viot.c       | 26 ++++++++++++++++++++------
+ include/linux/acpi_viot.h |  2 ++
+ 3 files changed, 23 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
+index fc9bb06d5411..7774b603a796 100644
+--- a/drivers/acpi/bus.c
++++ b/drivers/acpi/bus.c
+@@ -1340,6 +1340,7 @@ static int __init acpi_init(void)
+       pci_mmcfg_late_init();
+       acpi_iort_init();
++      acpi_viot_early_init();
+       acpi_hest_init();
+       ghes_init();
+       acpi_scan_init();
+diff --git a/drivers/acpi/viot.c b/drivers/acpi/viot.c
+index d2256326c73a..647f11cf165d 100644
+--- a/drivers/acpi/viot.c
++++ b/drivers/acpi/viot.c
+@@ -248,6 +248,26 @@ static int __init viot_parse_node(const struct acpi_viot_header *hdr)
+       return ret;
+ }
++/**
++ * acpi_viot_early_init - Test the presence of VIOT and enable ACS
++ *
++ * If the VIOT does exist, ACS must be enabled. This cannot be
++ * done in acpi_viot_init() which is called after the bus scan
++ */
++void __init acpi_viot_early_init(void)
++{
++#ifdef CONFIG_PCI
++      acpi_status status;
++      struct acpi_table_header *hdr;
++
++      status = acpi_get_table(ACPI_SIG_VIOT, 0, &hdr);
++      if (ACPI_FAILURE(status))
++              return;
++      pci_request_acs();
++      acpi_put_table(hdr);
++#endif
++}
++
+ /**
+  * acpi_viot_init - Parse the VIOT table
+  *
+@@ -319,12 +339,6 @@ static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
+                       epid = ((domain_nr - ep->segment_start) << 16) +
+                               dev_id - ep->bdf_start + ep->endpoint_id;
+-                      /*
+-                       * If we found a PCI range managed by the viommu, we're
+-                       * the one that has to request ACS.
+-                       */
+-                      pci_request_acs();
+-
+                       return viot_dev_iommu_init(&pdev->dev, ep->viommu,
+                                                  epid);
+               }
+diff --git a/include/linux/acpi_viot.h b/include/linux/acpi_viot.h
+index 1eb8ee5b0e5f..a5a122431563 100644
+--- a/include/linux/acpi_viot.h
++++ b/include/linux/acpi_viot.h
+@@ -6,9 +6,11 @@
+ #include <linux/acpi.h>
+ #ifdef CONFIG_ACPI_VIOT
++void __init acpi_viot_early_init(void);
+ void __init acpi_viot_init(void);
+ int viot_iommu_configure(struct device *dev);
+ #else
++static inline void acpi_viot_early_init(void) {}
+ static inline void acpi_viot_init(void) {}
+ static inline int viot_iommu_configure(struct device *dev)
+ {
+-- 
+2.35.1
+
diff --git a/queue-5.15/android-binder-stop-saving-a-pointer-to-the-vma.patch b/queue-5.15/android-binder-stop-saving-a-pointer-to-the-vma.patch
new file mode 100644 (file)
index 0000000..6b8c49c
--- /dev/null
@@ -0,0 +1,137 @@
+From 61e768fc08722523b1e3e6ced3a74b905c2fc3f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jun 2022 21:09:09 -0400
+Subject: android: binder: stop saving a pointer to the VMA
+
+From: Liam R. Howlett <Liam.Howlett@oracle.com>
+
+[ Upstream commit a43cfc87caaf46710c8027a8c23b8a55f1078f19 ]
+
+Do not record a pointer to a VMA outside of the mmap_lock for later use.
+This is unsafe and there are a number of failure paths *after* the
+recorded VMA pointer may be freed during setup.  There is no callback to
+the driver to clear the saved pointer from generic mm code.  Furthermore,
+the VMA pointer may become stale if any number of VMA operations end up
+freeing the VMA so saving it was fragile to being with.
+
+Instead, change the binder_alloc struct to record the start address of the
+VMA and use vma_lookup() to get the vma when needed.  Add lockdep
+mmap_lock checks on updates to the vma pointer to ensure the lock is held
+and depend on that lock for synchronization of readers and writers - which
+was already the case anyways, so the smp_wmb()/smp_rmb() was not
+necessary.
+
+[akpm@linux-foundation.org: fix drivers/android/binder_alloc_selftest.c]
+Link: https://lkml.kernel.org/r/20220621140212.vpkio64idahetbyf@revolver
+Fixes: da1b9564e85b ("android: binder: fix the race mmap and alloc_new_buf_locked")
+Reported-by: syzbot+58b51ac2b04e388ab7b0@syzkaller.appspotmail.com
+Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
+Cc: Minchan Kim <minchan@kernel.org>
+Cc: Christian Brauner (Microsoft) <brauner@kernel.org>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: Hridya Valsaraju <hridya@google.com>
+Cc: Joel Fernandes <joel@joelfernandes.org>
+Cc: Martijn Coenen <maco@android.com>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Todd Kjos <tkjos@android.com>
+Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/android/binder_alloc.c          | 30 ++++++++++++-------------
+ drivers/android/binder_alloc.h          |  2 +-
+ drivers/android/binder_alloc_selftest.c |  2 +-
+ 3 files changed, 16 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c
+index 47bc74a8c7b6..b398909fda36 100644
+--- a/drivers/android/binder_alloc.c
++++ b/drivers/android/binder_alloc.c
+@@ -213,7 +213,7 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate,
+       if (mm) {
+               mmap_read_lock(mm);
+-              vma = alloc->vma;
++              vma = vma_lookup(mm, alloc->vma_addr);
+       }
+       if (!vma && need_mm) {
+@@ -313,16 +313,15 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate,
+ static inline void binder_alloc_set_vma(struct binder_alloc *alloc,
+               struct vm_area_struct *vma)
+ {
+-      if (vma)
++      unsigned long vm_start = 0;
++
++      if (vma) {
++              vm_start = vma->vm_start;
+               alloc->vma_vm_mm = vma->vm_mm;
+-      /*
+-       * If we see alloc->vma is not NULL, buffer data structures set up
+-       * completely. Look at smp_rmb side binder_alloc_get_vma.
+-       * We also want to guarantee new alloc->vma_vm_mm is always visible
+-       * if alloc->vma is set.
+-       */
+-      smp_wmb();
+-      alloc->vma = vma;
++      }
++
++      mmap_assert_write_locked(alloc->vma_vm_mm);
++      alloc->vma_addr = vm_start;
+ }
+ static inline struct vm_area_struct *binder_alloc_get_vma(
+@@ -330,11 +329,9 @@ static inline struct vm_area_struct *binder_alloc_get_vma(
+ {
+       struct vm_area_struct *vma = NULL;
+-      if (alloc->vma) {
+-              /* Look at description in binder_alloc_set_vma */
+-              smp_rmb();
+-              vma = alloc->vma;
+-      }
++      if (alloc->vma_addr)
++              vma = vma_lookup(alloc->vma_vm_mm, alloc->vma_addr);
++
+       return vma;
+ }
+@@ -817,7 +814,8 @@ void binder_alloc_deferred_release(struct binder_alloc *alloc)
+       buffers = 0;
+       mutex_lock(&alloc->mutex);
+-      BUG_ON(alloc->vma);
++      BUG_ON(alloc->vma_addr &&
++             vma_lookup(alloc->vma_vm_mm, alloc->vma_addr));
+       while ((n = rb_first(&alloc->allocated_buffers))) {
+               buffer = rb_entry(n, struct binder_buffer, rb_node);
+diff --git a/drivers/android/binder_alloc.h b/drivers/android/binder_alloc.h
+index 7dea57a84c79..1e4fd37af5e0 100644
+--- a/drivers/android/binder_alloc.h
++++ b/drivers/android/binder_alloc.h
+@@ -100,7 +100,7 @@ struct binder_lru_page {
+  */
+ struct binder_alloc {
+       struct mutex mutex;
+-      struct vm_area_struct *vma;
++      unsigned long vma_addr;
+       struct mm_struct *vma_vm_mm;
+       void __user *buffer;
+       struct list_head buffers;
+diff --git a/drivers/android/binder_alloc_selftest.c b/drivers/android/binder_alloc_selftest.c
+index c2b323bc3b3a..43a881073a42 100644
+--- a/drivers/android/binder_alloc_selftest.c
++++ b/drivers/android/binder_alloc_selftest.c
+@@ -287,7 +287,7 @@ void binder_selftest_alloc(struct binder_alloc *alloc)
+       if (!binder_selftest_run)
+               return;
+       mutex_lock(&binder_selftest_lock);
+-      if (!binder_selftest_run || !alloc->vma)
++      if (!binder_selftest_run || !alloc->vma_addr)
+               goto done;
+       pr_info("STARTED\n");
+       binder_selftest_alloc_offset(alloc, end_offset, 0);
+-- 
+2.35.1
+
diff --git a/queue-5.15/arch-make-trace_irqflags_nmi_support-generic.patch b/queue-5.15/arch-make-trace_irqflags_nmi_support-generic.patch
new file mode 100644 (file)
index 0000000..0d542f5
--- /dev/null
@@ -0,0 +1,95 @@
+From bd9d97efe86e8dbb3af33f1160ea887be478bd53 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 May 2022 14:17:32 +0100
+Subject: arch: make TRACE_IRQFLAGS_NMI_SUPPORT generic
+
+From: Mark Rutland <mark.rutland@arm.com>
+
+[ Upstream commit 4510bffb4d0246cdcc1f14c7367c026b807a862d ]
+
+On most architectures, IRQ flag tracing is disabled in NMI context, and
+architectures need to define and select TRACE_IRQFLAGS_NMI_SUPPORT in
+order to enable this.
+
+Commit:
+
+  859d069ee1ddd878 ("lockdep: Prepare for NMI IRQ state tracking")
+
+Permitted IRQ flag tracing in NMI context, allowing lockdep to work in
+NMI context where an architecture had suitable entry logic. At the time,
+most architectures did not have such suitable entry logic, and this broke
+lockdep on such architectures. Thus, this was partially disabled in
+commit:
+
+  ed00495333ccc80f ("locking/lockdep: Fix TRACE_IRQFLAGS vs. NMIs")
+
+... with architectures needing to select TRACE_IRQFLAGS_NMI_SUPPORT to
+enable IRQ flag tracing in NMI context.
+
+Currently TRACE_IRQFLAGS_NMI_SUPPORT is defined under
+arch/x86/Kconfig.debug. Move it to arch/Kconfig so architectures can
+select it without having to provide their own definition.
+
+Since the regular TRACE_IRQFLAGS_SUPPORT is selected by
+arch/x86/Kconfig, the select of TRACE_IRQFLAGS_NMI_SUPPORT is moved
+there too.
+
+There should be no functional change as a result of this patch.
+
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Will Deacon <will@kernel.org>
+Link: https://lore.kernel.org/r/20220511131733.4074499-2-mark.rutland@arm.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/Kconfig           | 3 +++
+ arch/x86/Kconfig       | 1 +
+ arch/x86/Kconfig.debug | 3 ---
+ 3 files changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/arch/Kconfig b/arch/Kconfig
+index 191589f26b1a..5987363b41c2 100644
+--- a/arch/Kconfig
++++ b/arch/Kconfig
+@@ -200,6 +200,9 @@ config HAVE_NMI
+ config TRACE_IRQFLAGS_SUPPORT
+       bool
++config TRACE_IRQFLAGS_NMI_SUPPORT
++      bool
++
+ #
+ # An arch should select this if it provides all these things:
+ #
+diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
+index fe6981a38795..57f5e881791a 100644
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -260,6 +260,7 @@ config X86
+       select SYSCTL_EXCEPTION_TRACE
+       select THREAD_INFO_IN_TASK
+       select TRACE_IRQFLAGS_SUPPORT
++      select TRACE_IRQFLAGS_NMI_SUPPORT
+       select USER_STACKTRACE_SUPPORT
+       select VIRT_TO_BUS
+       select HAVE_ARCH_KCSAN                  if X86_64
+diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
+index d3a6f74a94bd..d4d6db4dde22 100644
+--- a/arch/x86/Kconfig.debug
++++ b/arch/x86/Kconfig.debug
+@@ -1,8 +1,5 @@
+ # SPDX-License-Identifier: GPL-2.0
+-config TRACE_IRQFLAGS_NMI_SUPPORT
+-      def_bool y
+-
+ config EARLY_PRINTK_USB
+       bool
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm-bcm-fix-refcount-leak-in-bcm_kona_smc_init.patch b/queue-5.15/arm-bcm-fix-refcount-leak-in-bcm_kona_smc_init.patch
new file mode 100644 (file)
index 0000000..fda24b2
--- /dev/null
@@ -0,0 +1,36 @@
+From 155d7562857726a5d3a8cf58f20c6c8663471428 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 May 2022 12:13:25 +0400
+Subject: ARM: bcm: Fix refcount leak in bcm_kona_smc_init
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit cb23389a2458c2e4bfd6c86a513cbbe1c4d35e76 ]
+
+of_find_matching_node() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when not need anymore.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: b8eb35fd594a ("ARM: bcm281xx: Add L2 cache enable code")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-bcm/bcm_kona_smc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/mach-bcm/bcm_kona_smc.c b/arch/arm/mach-bcm/bcm_kona_smc.c
+index 43829e49ad93..347bfb7f03e2 100644
+--- a/arch/arm/mach-bcm/bcm_kona_smc.c
++++ b/arch/arm/mach-bcm/bcm_kona_smc.c
+@@ -52,6 +52,7 @@ int __init bcm_kona_smc_init(void)
+               return -ENODEV;
+       prop_val = of_get_address(node, 0, &prop_size, NULL);
++      of_node_put(node);
+       if (!prop_val)
+               return -EINVAL;
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm-dts-ast2500-evb-fix-board-compatible.patch b/queue-5.15/arm-dts-ast2500-evb-fix-board-compatible.patch
new file mode 100644 (file)
index 0000000..75afcd2
--- /dev/null
@@ -0,0 +1,35 @@
+From b73816303c9af62a755b5b97fb267c5c5b897cdc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 29 May 2022 12:49:25 +0200
+Subject: ARM: dts: ast2500-evb: fix board compatible
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 30b276fca5c0644f3cb17bceb1bd6a626c670184 ]
+
+The AST2500 EVB board should have dedicated compatible.
+
+Fixes: 02440622656d ("arm/dst: Add Aspeed ast2500 device tree")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20220529104928.79636-4-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/aspeed-ast2500-evb.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/aspeed-ast2500-evb.dts b/arch/arm/boot/dts/aspeed-ast2500-evb.dts
+index 1d24b394ea4c..a497dd135491 100644
+--- a/arch/arm/boot/dts/aspeed-ast2500-evb.dts
++++ b/arch/arm/boot/dts/aspeed-ast2500-evb.dts
+@@ -5,7 +5,7 @@
+ / {
+       model = "AST2500 EVB";
+-      compatible = "aspeed,ast2500";
++      compatible = "aspeed,ast2500-evb", "aspeed,ast2500";
+       aliases {
+               serial4 = &uart5;
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm-dts-ast2600-evb-a1-fix-board-compatible.patch b/queue-5.15/arm-dts-ast2600-evb-a1-fix-board-compatible.patch
new file mode 100644 (file)
index 0000000..a6be752
--- /dev/null
@@ -0,0 +1,34 @@
+From 485287fe05fe9cce30c772ede3bedb483e0a1650 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 29 May 2022 12:49:27 +0200
+Subject: ARM: dts: ast2600-evb-a1: fix board compatible
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 33c39140cc298e0d4e36083cb9a665a837773a60 ]
+
+The AST2600 EVB A1 board should have dedicated compatible.
+
+Fixes: a72955180372 ("ARM: dts: aspeed: ast2600evb: Add dts file for A1 and A0")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20220529104928.79636-6-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/aspeed-ast2600-evb-a1.dts | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/boot/dts/aspeed-ast2600-evb-a1.dts b/arch/arm/boot/dts/aspeed-ast2600-evb-a1.dts
+index dd7148060c4a..d0a5c2ff0fec 100644
+--- a/arch/arm/boot/dts/aspeed-ast2600-evb-a1.dts
++++ b/arch/arm/boot/dts/aspeed-ast2600-evb-a1.dts
+@@ -5,6 +5,7 @@
+ / {
+       model = "AST2600 A1 EVB";
++      compatible = "aspeed,ast2600-evb-a1", "aspeed,ast2600";
+       /delete-node/regulator-vcc-sdhci0;
+       /delete-node/regulator-vcc-sdhci1;
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm-dts-ast2600-evb-fix-board-compatible.patch b/queue-5.15/arm-dts-ast2600-evb-fix-board-compatible.patch
new file mode 100644 (file)
index 0000000..f182530
--- /dev/null
@@ -0,0 +1,35 @@
+From 3e1327f6a8ccdfce2e63d19b0c8c8bf0f84d850f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 29 May 2022 12:49:26 +0200
+Subject: ARM: dts: ast2600-evb: fix board compatible
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit aa5e06208500a0db41473caebdee5a2e81d5a277 ]
+
+The AST2600 EVB board should have dedicated compatible.
+
+Fixes: 2ca5646b5c2f ("ARM: dts: aspeed: Add AST2600 and EVB")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20220529104928.79636-5-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/aspeed-ast2600-evb.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/aspeed-ast2600-evb.dts b/arch/arm/boot/dts/aspeed-ast2600-evb.dts
+index 788448cdd6b3..b8e55bf167aa 100644
+--- a/arch/arm/boot/dts/aspeed-ast2600-evb.dts
++++ b/arch/arm/boot/dts/aspeed-ast2600-evb.dts
+@@ -8,7 +8,7 @@
+ / {
+       model = "AST2600 EVB";
+-      compatible = "aspeed,ast2600";
++      compatible = "aspeed,ast2600-evb-a1", "aspeed,ast2600";
+       aliases {
+               serial4 = &uart5;
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm-dts-bcm5301x-add-dt-for-meraki-mr26.patch b/queue-5.15/arm-dts-bcm5301x-add-dt-for-meraki-mr26.patch
new file mode 100644 (file)
index 0000000..ad114cf
--- /dev/null
@@ -0,0 +1,260 @@
+From b90f0afd7b682227db42ac35de9b086ba3a193f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Jun 2022 00:00:29 +0200
+Subject: ARM: dts: BCM5301X: Add DT for Meraki MR26
+
+From: Christian Lamparter <chunkeey@gmail.com>
+
+[ Upstream commit 935327a73553001f8d81375c76985d05f604507f ]
+
+Meraki MR26 is an EOL wireless access point featuring a
+PoE ethernet port and two dual-band 3x3 MIMO 802.11n
+radios and 1x1 dual-band WIFI dedicated to scanning.
+
+Thank you Amir for the unit and PSU.
+
+Hardware info:
+SOC   : Broadcom BCM53015A1KFEBG (dual-core Cortex-A9 CPU at 800 MHz)
+RAM   : SK Hynix Inc. H5TQ1G63EFR, 1 GBit DDR3 SDRAM = 128 MiB
+NAND  : Spansion S34ML01G100TF100, 1 GBit SLC NAND Flash = 128 MiB
+ETH   : 1 GBit Ethernet Port - PoE (TPS23754 PoE Interface)
+WIFI0 : Broadcom BCM43431KMLG, BCM43431 802.11 abgn (3x3:3)
+WIFI1 : Broadcom BCM43431KMLG, BCM43431 802.11 abgn (3x3:3)
+WIFI2 : Broadcom BCM43428 "Air Marshal" 802.11 abgn (1x1:1)
+BUTTON: One reset key behind a small hole next to the Ethernet Port
+LEDS  : One amber (fault), one white (indicator) LED, separate RGB-LED
+MISC  : Atmel AT24C64 8KiB EEPROM i2c
+      : Ti INA219 26V, 12-bit, i2c output current/voltage/power monitor
+
+SERIAL:
+      WARNING: The serial port needs a TTL/RS-232 3V3 level converter!
+      The Serial setting is 115200-8-N-1. The board has a populated
+      right angle 1x4 0.1" pinheader.
+      The pinout is: VCC (next to J3, has the pin 1 indicator), RX, TX, GND.
+
+Odd stuff:
+
+- uboot does not support lzma compression, but gzip'd uImage/DTB work.
+- uboot claims to support FIT, but fails to pass the DTB to the kernel.
+  Appending the dtb after the kernel image works.
+- RGB-controller is supported through an external userspace program.
+- The ubi partition contains a "board-config" volume. It stores the
+  MAC Address (0x66 in binary) and Serial No. (0x7c alpha-numerical).
+- SoC's temperature sensor always reports that it is on fire.
+  This causes the system to immediately shutdown! Looking at reported
+  "418 degree Celsius" suggests that this sensor is not working.
+
+WIFI:
+b43 is able to initialize all three WIFIs @ 802.11bg.
+| b43-phy0: Broadcom 43431 WLAN found (core revision 29)
+| bcma-pci-bridge 0000:01:00.0: bus1: Switched to core: 0x812
+| b43-phy0: Found PHY: Analog 9, Type 7 (HT), Revision 1
+| b43-phy0: Found Radio: Manuf 0x17F, ID 0x2059, Revision 0, Version 1
+| b43-phy0 warning: 5 GHz band is unsupported on this PHY
+| b43-phy1: Broadcom 43431 WLAN found (core revision 29)
+| bcma-pci-bridge 0001:01:00.0: bus2: Switched to core: 0x812
+| b43-phy1: Found PHY: Analog 9, Type 7 (HT), Revision 1
+| b43-phy1: Found Radio: Manuf 0x17F, ID 0x2059, Revision 0, Version 1
+| b43-phy1 warning: 5 GHz band is unsupported on this PHY
+| b43-phy2: Broadcom 43228 WLAN found (core revision 30)
+| bcma-pci-bridge 0002:01:00.0: bus3: Switched to core: 0x812
+| b43-phy2: Found PHY: Analog 9, Type 4 (N), Revision 16
+| b43-phy2: Found Radio: Manuf 0x17F, ID 0x2057, Revision 9, Version 1
+| Broadcom 43xx driver loaded [ Features: NL ]
+
+Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/Makefile                 |   1 +
+ arch/arm/boot/dts/bcm53015-meraki-mr26.dts | 166 +++++++++++++++++++++
+ 2 files changed, 167 insertions(+)
+ create mode 100644 arch/arm/boot/dts/bcm53015-meraki-mr26.dts
+
+diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
+index 27ca1ca6e827..7a72fc636a7a 100644
+--- a/arch/arm/boot/dts/Makefile
++++ b/arch/arm/boot/dts/Makefile
+@@ -127,6 +127,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
+       bcm47094-luxul-xwr-3150-v1.dtb \
+       bcm47094-netgear-r8500.dtb \
+       bcm47094-phicomm-k3.dtb \
++      bcm53015-meraki-mr26.dtb \
+       bcm53016-meraki-mr32.dtb \
+       bcm94708.dtb \
+       bcm94709.dtb \
+diff --git a/arch/arm/boot/dts/bcm53015-meraki-mr26.dts b/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
+new file mode 100644
+index 000000000000..14f58033efeb
+--- /dev/null
++++ b/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
+@@ -0,0 +1,166 @@
++// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
++/*
++ * Broadcom BCM470X / BCM5301X ARM platform code.
++ * DTS for Meraki MR26 / Codename: Venom
++ *
++ * Copyright (C) 2022 Christian Lamparter <chunkeey@gmail.com>
++ */
++
++/dts-v1/;
++
++#include "bcm4708.dtsi"
++#include "bcm5301x-nand-cs0-bch8.dtsi"
++#include <dt-bindings/leds/common.h>
++
++/ {
++      compatible = "meraki,mr26", "brcm,bcm53015", "brcm,bcm4708";
++      model = "Meraki MR26";
++
++      memory@0 {
++              reg = <0x00000000 0x08000000>;
++              device_type = "memory";
++      };
++
++      leds {
++              compatible = "gpio-leds";
++
++              led-0 {
++                      function = LED_FUNCTION_FAULT;
++                      color = <LED_COLOR_ID_AMBER>;
++                      gpios = <&chipcommon 13 GPIO_ACTIVE_HIGH>;
++                      panic-indicator;
++              };
++              led-1 {
++                      function = LED_FUNCTION_INDICATOR;
++                      color = <LED_COLOR_ID_WHITE>;
++                      gpios = <&chipcommon 12 GPIO_ACTIVE_HIGH>;
++              };
++      };
++
++      keys {
++              compatible = "gpio-keys";
++              #address-cells = <1>;
++              #size-cells = <0>;
++
++              key-restart {
++                      label = "Reset";
++                      linux,code = <KEY_RESTART>;
++                      gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
++              };
++      };
++};
++
++&uart0 {
++      clock-frequency = <50000000>;
++      /delete-property/ clocks;
++};
++
++&uart1 {
++      status = "disabled";
++};
++
++&gmac0 {
++      status = "okay";
++};
++
++&gmac1 {
++      status = "disabled";
++};
++&gmac2 {
++      status = "disabled";
++};
++&gmac3 {
++      status = "disabled";
++};
++
++&nandcs {
++      nand-ecc-algo = "hw";
++
++      partitions {
++              compatible = "fixed-partitions";
++              #address-cells = <0x1>;
++              #size-cells = <0x1>;
++
++              partition@0 {
++                      label = "u-boot";
++                      reg = <0x0 0x200000>;
++                      read-only;
++              };
++
++              partition@200000 {
++                      label = "u-boot-env";
++                      reg = <0x200000 0x200000>;
++                      /* empty */
++              };
++
++              partition@400000 {
++                      label = "u-boot-backup";
++                      reg = <0x400000 0x200000>;
++                      /* empty */
++              };
++
++              partition@600000 {
++                      label = "u-boot-env-backup";
++                      reg = <0x600000 0x200000>;
++                      /* empty */
++              };
++
++              partition@800000 {
++                      label = "ubi";
++                      reg = <0x800000 0x7780000>;
++              };
++      };
++};
++
++&srab {
++      status = "okay";
++
++      ports {
++              port@0 {
++                      reg = <0>;
++                      label = "poe";
++              };
++
++              port@5 {
++                      reg = <5>;
++                      label = "cpu";
++                      ethernet = <&gmac0>;
++
++                      fixed-link {
++                              speed = <1000>;
++                              duplex-full;
++                      };
++              };
++      };
++};
++
++&i2c0 {
++      status = "okay";
++
++      pinctrl-names = "default";
++      pinctrl-0 = <&pinmux_i2c>;
++
++      clock-frequency = <100000>;
++
++      ina219@40 {
++              compatible = "ti,ina219"; /* PoE power */
++              reg = <0x40>;
++              shunt-resistor = <60000>; /* = 60 mOhms */
++      };
++
++      eeprom@56 {
++              compatible = "atmel,24c64";
++              reg = <0x56>;
++              pagesize = <32>;
++              read-only;
++              #address-cells = <1>;
++              #size-cells = <1>;
++
++              /* it's empty */
++      };
++};
++
++&thermal {
++      status = "disabled";
++      /* does not work, reads 418 degree Celsius */
++};
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm-dts-imx6ul-add-missing-properties-for-sram.patch b/queue-5.15/arm-dts-imx6ul-add-missing-properties-for-sram.patch
new file mode 100644 (file)
index 0000000..4189ffa
--- /dev/null
@@ -0,0 +1,39 @@
+From 7d7be8c1363630a12f6b73583c452d11425aab1d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 14:33:51 +0200
+Subject: ARM: dts: imx6ul: add missing properties for sram
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit 5655699cf5cff9f4c4ee703792156bdd05d1addf ]
+
+All 3 properties are required by sram.yaml. Fixes the dtbs_check
+warning:
+sram@900000: '#address-cells' is a required property
+sram@900000: '#size-cells' is a required property
+sram@900000: 'ranges' is a required property
+
+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/imx6ul.dtsi | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
+index afeec01f6522..1d435a46fc5c 100644
+--- a/arch/arm/boot/dts/imx6ul.dtsi
++++ b/arch/arm/boot/dts/imx6ul.dtsi
+@@ -149,6 +149,9 @@ soc {
+               ocram: sram@900000 {
+                       compatible = "mmio-sram";
+                       reg = <0x00900000 0x20000>;
++                      ranges = <0 0x00900000 0x20000>;
++                      #address-cells = <1>;
++                      #size-cells = <1>;
+               };
+               intc: interrupt-controller@a01000 {
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm-dts-imx6ul-change-operating-points-to-uint32-mat.patch b/queue-5.15/arm-dts-imx6ul-change-operating-points-to-uint32-mat.patch
new file mode 100644 (file)
index 0000000..a38fc1a
--- /dev/null
@@ -0,0 +1,63 @@
+From cfb22ff3779bd669f076ee4f9249efdbd8da45ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 14:33:52 +0200
+Subject: ARM: dts: imx6ul: change operating-points to uint32-matrix
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit edb67843983bbdf61b4c8c3c50618003d38bb4ae ]
+
+operating-points is a uint32-matrix as per opp-v1.yaml. Change it
+accordingly. While at it, change fsl,soc-operating-points as well,
+although there is no bindings file (yet). But they should have the same
+format. Fixes the dt_binding_check warning:
+cpu@0: operating-points:0: [696000, 1275000, 528000, 1175000, 396000,
+1025000, 198000, 950000] is too long
+cpu@0: operating-points:0: Additional items are not allowed (528000,
+1175000, 396000, 1025000, 198000, 950000 were unexpected)
+
+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/imx6ul.dtsi | 22 ++++++++++------------
+ 1 file changed, 10 insertions(+), 12 deletions(-)
+
+diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
+index 1d435a46fc5c..2fcbd9d91521 100644
+--- a/arch/arm/boot/dts/imx6ul.dtsi
++++ b/arch/arm/boot/dts/imx6ul.dtsi
+@@ -64,20 +64,18 @@ cpu0: cpu@0 {
+                       clock-frequency = <696000000>;
+                       clock-latency = <61036>; /* two CLK32 periods */
+                       #cooling-cells = <2>;
+-                      operating-points = <
++                      operating-points =
+                               /* kHz  uV */
+-                              696000  1275000
+-                              528000  1175000
+-                              396000  1025000
+-                              198000  950000
+-                      >;
+-                      fsl,soc-operating-points = <
++                              <696000 1275000>,
++                              <528000 1175000>,
++                              <396000 1025000>,
++                              <198000 950000>;
++                      fsl,soc-operating-points =
+                               /* KHz  uV */
+-                              696000  1275000
+-                              528000  1175000
+-                              396000  1175000
+-                              198000  1175000
+-                      >;
++                              <696000 1275000>,
++                              <528000 1175000>,
++                              <396000 1175000>,
++                              <198000 1175000>;
+                       clocks = <&clks IMX6UL_CLK_ARM>,
+                                <&clks IMX6UL_CLK_PLL2_BUS>,
+                                <&clks IMX6UL_CLK_PLL2_PFD2>,
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm-dts-imx6ul-fix-csi-node-compatible.patch b/queue-5.15/arm-dts-imx6ul-fix-csi-node-compatible.patch
new file mode 100644 (file)
index 0000000..db6f9e2
--- /dev/null
@@ -0,0 +1,40 @@
+From f1c7ab145f9514a60a866de92d0a4d648c6b5312 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 14:33:55 +0200
+Subject: ARM: dts: imx6ul: fix csi node compatible
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit e0aca931a2c7c29c88ebf37f9c3cd045e083483d ]
+
+"fsl,imx6ul-csi" was never listed as compatible to "fsl,imx7-csi", neither
+in yaml bindings, nor previous txt binding. Remove the imx7 part. Fixes
+the dt schema check warning:
+csi@21c4000: compatible: 'oneOf' conditional failed, one must be fixed:
+['fsl,imx6ul-csi', 'fsl,imx7-csi'] is too long
+Additional items are not allowed ('fsl,imx7-csi' was unexpected)
+'fsl,imx8mm-csi' was expected
+
+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/imx6ul.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
+index df8b4ad62418..367657a9a99f 100644
+--- a/arch/arm/boot/dts/imx6ul.dtsi
++++ b/arch/arm/boot/dts/imx6ul.dtsi
+@@ -999,7 +999,7 @@ cpu_speed_grade: speed-grade@10 {
+                       };
+                       csi: csi@21c4000 {
+-                              compatible = "fsl,imx6ul-csi", "fsl,imx7-csi";
++                              compatible = "fsl,imx6ul-csi";
+                               reg = <0x021c4000 0x4000>;
+                               interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6UL_CLK_CSI>;
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm-dts-imx6ul-fix-keypad-compatible.patch b/queue-5.15/arm-dts-imx6ul-fix-keypad-compatible.patch
new file mode 100644 (file)
index 0000000..e5e17ee
--- /dev/null
@@ -0,0 +1,41 @@
+From 3fb70a3ae4ca79bc766a3336d8805113a7705b62 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 14:33:53 +0200
+Subject: ARM: dts: imx6ul: fix keypad compatible
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit 7d15e0c9a515494af2e3199741cdac7002928a0e ]
+
+According to binding, the compatible shall only contain imx6ul and imx21
+compatibles. Fixes the dt_binding_check warning:
+keypad@20b8000: compatible: 'oneOf' conditional failed, one must be fixed:
+['fsl,imx6ul-kpp', 'fsl,imx6q-kpp', 'fsl,imx21-kpp'] is too long
+Additional items are not allowed ('fsl,imx6q-kpp', 'fsl,imx21-kpp' were
+unexpected)
+Additional items are not allowed ('fsl,imx21-kpp' was unexpected)
+'fsl,imx21-kpp' was expected
+
+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/imx6ul.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
+index 2fcbd9d91521..df8b4ad62418 100644
+--- a/arch/arm/boot/dts/imx6ul.dtsi
++++ b/arch/arm/boot/dts/imx6ul.dtsi
+@@ -544,7 +544,7 @@ fec2: ethernet@20b4000 {
+                       };
+                       kpp: keypad@20b8000 {
+-                              compatible = "fsl,imx6ul-kpp", "fsl,imx6q-kpp", "fsl,imx21-kpp";
++                              compatible = "fsl,imx6ul-kpp", "fsl,imx21-kpp";
+                               reg = <0x020b8000 0x4000>;
+                               interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6UL_CLK_KPP>;
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm-dts-imx6ul-fix-lcdif-node-compatible.patch b/queue-5.15/arm-dts-imx6ul-fix-lcdif-node-compatible.patch
new file mode 100644 (file)
index 0000000..dc10184
--- /dev/null
@@ -0,0 +1,42 @@
+From 8e0ad29b7d2a0899475de23c87ef5fe54f0092d2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 14:33:56 +0200
+Subject: ARM: dts: imx6ul: fix lcdif node compatible
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit 1a884d17ca324531634cce82e9f64c0302bdf7de ]
+
+In yaml binding "fsl,imx6ul-lcdif" is listed as compatible to imx6sx-lcdif,
+but not imx28-lcdif. Change the list accordingly. Fixes the
+dt_binding_check warning:
+lcdif@21c8000: compatible: 'oneOf' conditional failed, one must be fixed:
+['fsl,imx6ul-lcdif', 'fsl,imx28-lcdif'] is too long
+Additional items are not allowed ('fsl,imx28-lcdif' was unexpected)
+'fsl,imx6ul-lcdif' is not one of ['fsl,imx23-lcdif', 'fsl,imx28-lcdif',
+'fsl,imx6sx-lcdif']
+'fsl,imx6sx-lcdif' was expected
+
+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/imx6ul.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
+index 367657a9a99f..bc6548058d8c 100644
+--- a/arch/arm/boot/dts/imx6ul.dtsi
++++ b/arch/arm/boot/dts/imx6ul.dtsi
+@@ -1008,7 +1008,7 @@ csi: csi@21c4000 {
+                       };
+                       lcdif: lcdif@21c8000 {
+-                              compatible = "fsl,imx6ul-lcdif", "fsl,imx28-lcdif";
++                              compatible = "fsl,imx6ul-lcdif", "fsl,imx6sx-lcdif";
+                               reg = <0x021c8000 0x4000>;
+                               interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6UL_CLK_LCDIF_PIX>,
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm-dts-imx6ul-fix-qspi-node-compatible.patch b/queue-5.15/arm-dts-imx6ul-fix-qspi-node-compatible.patch
new file mode 100644 (file)
index 0000000..846cd63
--- /dev/null
@@ -0,0 +1,42 @@
+From 89a1ecd5ab3112156a0e52ac130bd73676411a6e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 14:33:57 +0200
+Subject: ARM: dts: imx6ul: fix qspi node compatible
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit 0c6cf86e1ab433b2d421880fdd9c6e954f404948 ]
+
+imx6ul is not compatible to imx6sx, both have different erratas.
+Fixes the dt_binding_check warning:
+spi@21e0000: compatible: 'oneOf' conditional failed, one must be fixed:
+['fsl,imx6ul-qspi', 'fsl,imx6sx-qspi'] is too long
+Additional items are not allowed ('fsl,imx6sx-qspi' was unexpected)
+'fsl,imx6ul-qspi' is not one of ['fsl,ls1043a-qspi']
+'fsl,imx6ul-qspi' is not one of ['fsl,imx8mq-qspi']
+'fsl,ls1021a-qspi' was expected
+'fsl,imx7d-qspi' was expected
+
+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/imx6ul.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
+index bc6548058d8c..eca8bf89ab88 100644
+--- a/arch/arm/boot/dts/imx6ul.dtsi
++++ b/arch/arm/boot/dts/imx6ul.dtsi
+@@ -1029,7 +1029,7 @@ pxp: pxp@21cc000 {
+                       qspi: spi@21e0000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+-                              compatible = "fsl,imx6ul-qspi", "fsl,imx6sx-qspi";
++                              compatible = "fsl,imx6ul-qspi";
+                               reg = <0x021e0000 0x4000>, <0x60000000 0x10000000>;
+                               reg-names = "QuadSPI", "QuadSPI-memory";
+                               interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm-dts-imx7d-colibri-emmc-add-cpu1-supply.patch b/queue-5.15/arm-dts-imx7d-colibri-emmc-add-cpu1-supply.patch
new file mode 100644 (file)
index 0000000..ef193e6
--- /dev/null
@@ -0,0 +1,38 @@
+From 8d5666d0b23026248d06f80899f37ab95c035b5e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 May 2022 15:47:23 +0200
+Subject: ARM: dts: imx7d-colibri-emmc: add cpu1 supply
+
+From: Marcel Ziswiler <marcel.ziswiler@toradex.com>
+
+[ Upstream commit ba28db60d34271e8a3cf4d7158d71607e8b1e57f ]
+
+Each cpu-core is supposed to list its supply separately, add supply for
+cpu1.
+
+Fixes: 2d7401f8632f ("ARM: dts: imx7d: Add cpu1 supply")
+Signed-off-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/imx7d-colibri-emmc.dtsi | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/arm/boot/dts/imx7d-colibri-emmc.dtsi b/arch/arm/boot/dts/imx7d-colibri-emmc.dtsi
+index af39e5370fa1..045e4413d339 100644
+--- a/arch/arm/boot/dts/imx7d-colibri-emmc.dtsi
++++ b/arch/arm/boot/dts/imx7d-colibri-emmc.dtsi
+@@ -13,6 +13,10 @@ memory@80000000 {
+       };
+ };
++&cpu1 {
++      cpu-supply = <&reg_DCDC2>;
++};
++
+ &gpio6 {
+       gpio-line-names = "",
+                         "",
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm-dts-qcom-mdm9615-add-missing-pmic-gpio-reg.patch b/queue-5.15/arm-dts-qcom-mdm9615-add-missing-pmic-gpio-reg.patch
new file mode 100644 (file)
index 0000000..faf0909
--- /dev/null
@@ -0,0 +1,36 @@
+From d5a26fab00157c9cd5bbfbbac09545f83024e776 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 7 May 2022 21:49:12 +0200
+Subject: ARM: dts: qcom: mdm9615: add missing PMIC GPIO reg
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit dc590cdc31f636ea15658f1206c3e380a53fb78e ]
+
+'reg' property is required in SSBI children:
+  qcom-mdm9615-wp8548-mangoh-green.dtb: gpio@150: 'reg' is a required property
+
+Fixes: 2c5e596524e7 ("ARM: dts: Add MDM9615 dtsi")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220507194913.261121-11-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/qcom-mdm9615.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/boot/dts/qcom-mdm9615.dtsi b/arch/arm/boot/dts/qcom-mdm9615.dtsi
+index dda2ceec6591..ad9b52d53ef9 100644
+--- a/arch/arm/boot/dts/qcom-mdm9615.dtsi
++++ b/arch/arm/boot/dts/qcom-mdm9615.dtsi
+@@ -324,6 +324,7 @@ rtc@11d {
+                               pmicgpio: gpio@150 {
+                                       compatible = "qcom,pm8018-gpio", "qcom,ssbi-gpio";
++                                      reg = <0x150>;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                                       gpio-controller;
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm-dts-qcom-msm8974-fix-irq-type-on-blsp2_uart1.patch b/queue-5.15/arm-dts-qcom-msm8974-fix-irq-type-on-blsp2_uart1.patch
new file mode 100644 (file)
index 0000000..11f0366
--- /dev/null
@@ -0,0 +1,37 @@
+From 0035900afdfd20b91cc2f671b21e8abe258a08e7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 22 May 2022 10:36:18 +0200
+Subject: ARM: dts: qcom-msm8974: fix irq type on blsp2_uart1
+
+From: Luca Weiss <luca@z3ntu.xyz>
+
+[ Upstream commit ab1489017aa7a9f02e24bee73cf9ec8079cd3909 ]
+
+IRQ_TYPE_NONE is invalid, so use the correct interrupt type.
+
+Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
+Fixes: b05f82b152c9 ("ARM: dts: qcom: msm8974: Add blsp2_uart7 for bluetooth on sirius")
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220522083618.17894-1-luca@z3ntu.xyz
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/qcom-msm8974.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
+index 2b01bc29ddf2..05d51839d40a 100644
+--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
++++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
+@@ -718,7 +718,7 @@ blsp1_uart2: serial@f991e000 {
+               blsp2_uart7: serial@f995d000 {
+                       compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+                       reg = <0xf995d000 0x1000>;
+-                      interrupts = <GIC_SPI 113 IRQ_TYPE_NONE>;
++                      interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&gcc GCC_BLSP2_UART1_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>;
+                       clock-names = "core", "iface";
+                       status = "disabled";
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm-dts-qcom-pm8841-add-required-thermal-sensor-cell.patch b/queue-5.15/arm-dts-qcom-pm8841-add-required-thermal-sensor-cell.patch
new file mode 100644 (file)
index 0000000..f9d8878
--- /dev/null
@@ -0,0 +1,35 @@
+From 2d11bbc527725bf8ff85163afb8696d84f47e399 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jun 2022 13:27:02 +0200
+Subject: ARM: dts: qcom: pm8841: add required thermal-sensor-cells
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit e2759fa0676c9a32bbddb9aff955b54bb35066ad ]
+
+The PM8841 temperature sensor has to define thermal-sensor-cells.
+
+Fixes: dab8134ca072 ("ARM: dts: qcom: Add PM8841 functions device nodes")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220608112702.80873-2-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/qcom-pm8841.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/boot/dts/qcom-pm8841.dtsi b/arch/arm/boot/dts/qcom-pm8841.dtsi
+index 2fd59c440903..c73e5b149ac5 100644
+--- a/arch/arm/boot/dts/qcom-pm8841.dtsi
++++ b/arch/arm/boot/dts/qcom-pm8841.dtsi
+@@ -25,6 +25,7 @@ temp-alarm@2400 {
+                       compatible = "qcom,spmi-temp-alarm";
+                       reg = <0x2400>;
+                       interrupts = <4 0x24 0 IRQ_TYPE_EDGE_RISING>;
++                      #thermal-sensor-cells = <0>;
+               };
+       };
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm-dts-qcom-replace-gcc-pxo-with-pxo_board-fixed-cl.patch b/queue-5.15/arm-dts-qcom-replace-gcc-pxo-with-pxo_board-fixed-cl.patch
new file mode 100644 (file)
index 0000000..9ecf3de
--- /dev/null
@@ -0,0 +1,39 @@
+From a7cc6ff9c34f6fad88091f7ac340f6dab6b4d2e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 30 Apr 2022 07:51:17 +0200
+Subject: ARM: dts: qcom: replace gcc PXO with pxo_board fixed clock
+
+From: Ansuel Smith <ansuelsmth@gmail.com>
+
+[ Upstream commit eb9e93937756a05787977875830c0dc482cb57e0 ]
+
+Replace gcc PXO phandle to pxo_board fixed clock declared in the dts.
+gcc driver doesn't provide PXO_SRC as it's a fixed-clock. This cause a
+kernel panic if any driver actually try to use it.
+
+Fixes: 40cf5c884a96 ("ARM: dts: qcom: add L2CC and RPM for IPQ8064")
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220430055118.1947-2-ansuelsmth@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/qcom-ipq8064.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi b/arch/arm/boot/dts/qcom-ipq8064.dtsi
+index 4139d3817bd6..85f906442227 100644
+--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
++++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
+@@ -782,7 +782,7 @@ tcsr: syscon@1a400000 {
+               l2cc: clock-controller@2011000 {
+                       compatible = "qcom,kpss-gcc", "syscon";
+                       reg = <0x2011000 0x1000>;
+-                      clocks = <&gcc PLL8_VOTE>, <&gcc PXO_SRC>;
++                      clocks = <&gcc PLL8_VOTE>, <&pxo_board>;
+                       clock-names = "pll8_vote", "pxo";
+                       clock-output-names = "acpu_l2_aux";
+               };
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm-dts-qcom-sdx55-fix-the-irq-trigger-type-for-uart.patch b/queue-5.15/arm-dts-qcom-sdx55-fix-the-irq-trigger-type-for-uart.patch
new file mode 100644 (file)
index 0000000..0cac06e
--- /dev/null
@@ -0,0 +1,35 @@
+From 85c64520527adebf9b1ddf6722748f31efd29986 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 May 2022 13:38:40 +0530
+Subject: ARM: dts: qcom: sdx55: Fix the IRQ trigger type for UART
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit ae500b351ab0006d933d804a2b7507fe1e98cecc ]
+
+The trigger type should be LEVEL_HIGH. So fix it!
+
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220530080842.37024-2-manivannan.sadhasivam@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/qcom-sdx55.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/qcom-sdx55.dtsi b/arch/arm/boot/dts/qcom-sdx55.dtsi
+index b5b784c5c65e..0e76d03087fe 100644
+--- a/arch/arm/boot/dts/qcom-sdx55.dtsi
++++ b/arch/arm/boot/dts/qcom-sdx55.dtsi
+@@ -205,7 +205,7 @@ gcc: clock-controller@100000 {
+               blsp1_uart3: serial@831000 {
+                       compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+                       reg = <0x00831000 0x200>;
+-                      interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_LOW>;
++                      interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&gcc 30>,
+                                <&gcc 9>;
+                       clock-names = "core", "iface";
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm-dts-ux500-fix-codina-accelerometer-mounting-matr.patch b/queue-5.15/arm-dts-ux500-fix-codina-accelerometer-mounting-matr.patch
new file mode 100644 (file)
index 0000000..8ed3eb7
--- /dev/null
@@ -0,0 +1,37 @@
+From 7b40caab2e234d5881e221be79bfcb161981efa5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Jun 2022 22:42:49 +0200
+Subject: ARM: dts: ux500: Fix Codina accelerometer mounting matrix
+
+From: Linus Walleij <linus.walleij@linaro.org>
+
+[ Upstream commit 0b2152e428ab91533a02888ff24e52e788dc4637 ]
+
+This was fixed wrong so fix it again. Now verified by using
+iio-sensor-proxy monitor-sensor test program.
+
+Link: https://lore.kernel.org/r/20220611204249.472250-1-linus.walleij@linaro.org
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/ste-ux500-samsung-codina.dts | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/ste-ux500-samsung-codina.dts b/arch/arm/boot/dts/ste-ux500-samsung-codina.dts
+index 952606e607ed..ce62ba877da1 100644
+--- a/arch/arm/boot/dts/ste-ux500-samsung-codina.dts
++++ b/arch/arm/boot/dts/ste-ux500-samsung-codina.dts
+@@ -544,8 +544,8 @@ lisd3dh@19 {
+                               reg = <0x19>;
+                               vdd-supply = <&ab8500_ldo_aux1_reg>; // 3V
+                               vddio-supply = <&ab8500_ldo_aux2_reg>; // 1.8V
+-                              mount-matrix = "0", "-1", "0",
+-                                             "1", "0", "0",
++                              mount-matrix = "0", "1", "0",
++                                             "-1", "0", "0",
+                                              "0", "0", "1";
+                       };
+               };
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm-dts-ux500-fix-gavini-accelerometer-mounting-matr.patch b/queue-5.15/arm-dts-ux500-fix-gavini-accelerometer-mounting-matr.patch
new file mode 100644 (file)
index 0000000..c93087d
--- /dev/null
@@ -0,0 +1,37 @@
+From 5db819c496baa81fc9c2205dbf4683e14f4d9da0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Jun 2022 22:51:38 +0200
+Subject: ARM: dts: ux500: Fix Gavini accelerometer mounting matrix
+
+From: Linus Walleij <linus.walleij@linaro.org>
+
+[ Upstream commit e24c75f02a81d6ddac0072cbd7a03e799c19d558 ]
+
+This was fixed wrong so fix it. Now verified by using
+iio-sensor-proxy monitor-sensor test program.
+
+Link: https://lore.kernel.org/r/20220611205138.491513-1-linus.walleij@linaro.org
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/ste-ux500-samsung-gavini.dts | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/ste-ux500-samsung-gavini.dts b/arch/arm/boot/dts/ste-ux500-samsung-gavini.dts
+index fabc390ccb0c..6c9e812ef03f 100644
+--- a/arch/arm/boot/dts/ste-ux500-samsung-gavini.dts
++++ b/arch/arm/boot/dts/ste-ux500-samsung-gavini.dts
+@@ -502,8 +502,8 @@ i2c-gate {
+                                       accelerometer@18 {
+                                               compatible = "bosch,bma222e";
+                                               reg = <0x18>;
+-                                              mount-matrix = "0", "1", "0",
+-                                                             "-1", "0", "0",
++                                              mount-matrix = "0", "-1", "0",
++                                                             "1", "0", "0",
+                                                              "0", "0", "1";
+                                               vddio-supply = <&ab8500_ldo_aux2_reg>; // 1.8V
+                                               vdd-supply = <&ab8500_ldo_aux1_reg>; // 3V
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm-findbit-fix-overflowing-offset.patch b/queue-5.15/arm-findbit-fix-overflowing-offset.patch
new file mode 100644 (file)
index 0000000..9e1b352
--- /dev/null
@@ -0,0 +1,76 @@
+From 7fa45637cfd3fb2e9d3db9591237fbb4e4ec0871 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Jul 2022 23:51:48 +0100
+Subject: ARM: findbit: fix overflowing offset
+
+From: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+
+[ Upstream commit ec85bd369fd2bfaed6f45dd678706429d4f75b48 ]
+
+When offset is larger than the size of the bit array, we should not
+attempt to access the array as we can perform an access beyond the
+end of the array. Fix this by changing the pre-condition.
+
+Using "cmp r2, r1; bhs ..." covers us for the size == 0 case, since
+this will always take the branch when r1 is zero, irrespective of
+the value of r2. This means we can fix this bug without adding any
+additional code!
+
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/lib/findbit.S | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/arch/arm/lib/findbit.S b/arch/arm/lib/findbit.S
+index b5e8b9ae4c7d..7fd3600db8ef 100644
+--- a/arch/arm/lib/findbit.S
++++ b/arch/arm/lib/findbit.S
+@@ -40,8 +40,8 @@ ENDPROC(_find_first_zero_bit_le)
+  * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
+  */
+ ENTRY(_find_next_zero_bit_le)
+-              teq     r1, #0
+-              beq     3b
++              cmp     r2, r1
++              bhs     3b
+               ands    ip, r2, #7
+               beq     1b                      @ If new byte, goto old routine
+  ARM(         ldrb    r3, [r0, r2, lsr #3]    )
+@@ -81,8 +81,8 @@ ENDPROC(_find_first_bit_le)
+  * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
+  */
+ ENTRY(_find_next_bit_le)
+-              teq     r1, #0
+-              beq     3b
++              cmp     r2, r1
++              bhs     3b
+               ands    ip, r2, #7
+               beq     1b                      @ If new byte, goto old routine
+  ARM(         ldrb    r3, [r0, r2, lsr #3]    )
+@@ -115,8 +115,8 @@ ENTRY(_find_first_zero_bit_be)
+ ENDPROC(_find_first_zero_bit_be)
+ ENTRY(_find_next_zero_bit_be)
+-              teq     r1, #0
+-              beq     3b
++              cmp     r2, r1
++              bhs     3b
+               ands    ip, r2, #7
+               beq     1b                      @ If new byte, goto old routine
+               eor     r3, r2, #0x18           @ big endian byte ordering
+@@ -149,8 +149,8 @@ ENTRY(_find_first_bit_be)
+ ENDPROC(_find_first_bit_be)
+ ENTRY(_find_next_bit_be)
+-              teq     r1, #0
+-              beq     3b
++              cmp     r2, r1
++              bhs     3b
+               ands    ip, r2, #7
+               beq     1b                      @ If new byte, goto old routine
+               eor     r3, r2, #0x18           @ big endian byte ordering
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm-omap2-display-fix-refcount-leak-bug.patch b/queue-5.15/arm-omap2-display-fix-refcount-leak-bug.patch
new file mode 100644 (file)
index 0000000..6437acc
--- /dev/null
@@ -0,0 +1,36 @@
+From ed26a0a7a150b8e4ce3a6643e1d2cf76517c1b74 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jun 2022 22:58:03 +0800
+Subject: ARM: OMAP2+: display: Fix refcount leak bug
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 50b87a32a79bca6e275918a711fb8cc55e16d739 ]
+
+In omapdss_init_fbdev(), of_find_node_by_name() will return a node
+pointer with refcount incremented. We should use of_node_put() when
+it is not used anymore.
+
+Signed-off-by: Liang He <windhl@126.com>
+Message-Id: <20220617145803.4050918-1-windhl@126.com>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-omap2/display.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
+index 21413a9b7b6c..eb09a25e3b45 100644
+--- a/arch/arm/mach-omap2/display.c
++++ b/arch/arm/mach-omap2/display.c
+@@ -211,6 +211,7 @@ static int __init omapdss_init_fbdev(void)
+       node = of_find_node_by_name(NULL, "omap4_padconf_global");
+       if (node)
+               omap4_dsi_mux_syscon = syscon_node_to_regmap(node);
++      of_node_put(node);
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm-omap2-fix-refcount-leak-in-omap3xxx_prm_late_ini.patch b/queue-5.15/arm-omap2-fix-refcount-leak-in-omap3xxx_prm_late_ini.patch
new file mode 100644 (file)
index 0000000..2b67f13
--- /dev/null
@@ -0,0 +1,37 @@
+From 69f2be4dc8b9b61a485d08f782b3a326f8523a46 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 May 2022 11:37:24 +0400
+Subject: ARM: OMAP2+: Fix refcount leak in omap3xxx_prm_late_init
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 942228fbf5d4901112178b93d41225be7c0dd9de ]
+
+of_find_matching_node() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when not need anymore.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: 1e037794f7f0 ("ARM: OMAP3+: PRM: register interrupt information from DT")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Message-Id: <20220526073724.21169-1-linmq006@gmail.com>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-omap2/prm3xxx.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/mach-omap2/prm3xxx.c b/arch/arm/mach-omap2/prm3xxx.c
+index 1b442b128569..63e73e9b82bc 100644
+--- a/arch/arm/mach-omap2/prm3xxx.c
++++ b/arch/arm/mach-omap2/prm3xxx.c
+@@ -708,6 +708,7 @@ static int omap3xxx_prm_late_init(void)
+       }
+       irq_num = of_irq_get(np, 0);
++      of_node_put(np);
+       if (irq_num == -EPROBE_DEFER)
+               return irq_num;
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm-omap2-fix-refcount-leak-in-omapdss_init_of.patch b/queue-5.15/arm-omap2-fix-refcount-leak-in-omapdss_init_of.patch
new file mode 100644 (file)
index 0000000..6ad788a
--- /dev/null
@@ -0,0 +1,45 @@
+From 3bc8119e799ef928fed5d1083b9c38dd38f8e5b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Jun 2022 08:48:58 +0400
+Subject: ARM: OMAP2+: Fix refcount leak in omapdss_init_of
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 9705db1eff38d6b9114121f9e253746199b759c9 ]
+
+omapdss_find_dss_of_node() calls of_find_compatible_node() to get device
+node. of_find_compatible_node() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when done.
+Add missing of_node_put() in later error path and normal path.
+
+Fixes: e0c827aca0730 ("drm/omap: Populate DSS children in omapdss driver")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Message-Id: <20220601044858.3352-1-linmq006@gmail.com>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-omap2/display.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
+index eb09a25e3b45..8d829f3dafe7 100644
+--- a/arch/arm/mach-omap2/display.c
++++ b/arch/arm/mach-omap2/display.c
+@@ -260,11 +260,13 @@ static int __init omapdss_init_of(void)
+       if (!pdev) {
+               pr_err("Unable to find DSS platform device\n");
++              of_node_put(node);
+               return -ENODEV;
+       }
+       r = of_platform_populate(node, NULL, NULL, &pdev->dev);
+       put_device(&pdev->dev);
++      of_node_put(node);
+       if (r) {
+               pr_err("Unable to populate DSS submodule devices\n");
+               return r;
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm-omap2-pdata-quirks-fix-refcount-leak-bug.patch b/queue-5.15/arm-omap2-pdata-quirks-fix-refcount-leak-bug.patch
new file mode 100644 (file)
index 0000000..0215078
--- /dev/null
@@ -0,0 +1,36 @@
+From 136c997fde24b559af10feec5ba192396fa42d2b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Jun 2022 10:06:03 +0800
+Subject: ARM: OMAP2+: pdata-quirks: Fix refcount leak bug
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 5cdbab96bab314c6f2f5e4e8b8a019181328bf5f ]
+
+In pdata_quirks_init_clocks(), the loop contains
+of_find_node_by_name() but without corresponding of_node_put().
+
+Signed-off-by: Liang He <windhl@126.com>
+Message-Id: <20220618020603.4055792-1-windhl@126.com>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-omap2/pdata-quirks.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
+index 765809b214e7..bf50acd6b8a3 100644
+--- a/arch/arm/mach-omap2/pdata-quirks.c
++++ b/arch/arm/mach-omap2/pdata-quirks.c
+@@ -587,6 +587,8 @@ pdata_quirks_init_clocks(const struct of_device_id *omap_dt_match_table)
+               of_platform_populate(np, omap_dt_match_table,
+                                    omap_auxdata_lookup, NULL);
++
++              of_node_put(np);
+       }
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm-shmobile-rcar-gen2-increase-refcount-for-new-ref.patch b/queue-5.15/arm-shmobile-rcar-gen2-increase-refcount-for-new-ref.patch
new file mode 100644 (file)
index 0000000..5904932
--- /dev/null
@@ -0,0 +1,60 @@
+From bf80dcc19a78c036a13d6758dee9ba47470e6bc4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 20:18:04 +0800
+Subject: ARM: shmobile: rcar-gen2: Increase refcount for new reference
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 75a185fb92e58ccd3670258d8d3b826bd2fa6d29 ]
+
+In rcar_gen2_regulator_quirk(), for_each_matching_node_and_match() will
+automatically increase and decrease the refcount.  However, we should
+call of_node_get() for the new reference created in 'quirk->np'.
+Besides, we also should call of_node_put() before the 'quirk' being
+freed.
+
+Signed-off-by: Liang He <windhl@126.com>
+Link: https://lore.kernel.org/r/20220701121804.234223-1-windhl@126.com
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
+index 09ef73b99dd8..ba44cec5e59a 100644
+--- a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
++++ b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
+@@ -125,6 +125,7 @@ static int regulator_quirk_notify(struct notifier_block *nb,
+       list_for_each_entry_safe(pos, tmp, &quirk_list, list) {
+               list_del(&pos->list);
++              of_node_put(pos->np);
+               kfree(pos);
+       }
+@@ -174,11 +175,12 @@ static int __init rcar_gen2_regulator_quirk(void)
+               memcpy(&quirk->i2c_msg, id->data, sizeof(quirk->i2c_msg));
+               quirk->id = id;
+-              quirk->np = np;
++              quirk->np = of_node_get(np);
+               quirk->i2c_msg.addr = addr;
+               ret = of_irq_parse_one(np, 0, argsa);
+               if (ret) {      /* Skip invalid entry and continue */
++                      of_node_put(np);
+                       kfree(quirk);
+                       continue;
+               }
+@@ -225,6 +227,7 @@ static int __init rcar_gen2_regulator_quirk(void)
+ err_mem:
+       list_for_each_entry_safe(pos, tmp, &quirk_list, list) {
+               list_del(&pos->list);
++              of_node_put(pos->np);
+               kfree(pos);
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm64-cpufeature-allow-different-pmu-versions-in-id_.patch b/queue-5.15/arm64-cpufeature-allow-different-pmu-versions-in-id_.patch
new file mode 100644 (file)
index 0000000..a2de8b9
--- /dev/null
@@ -0,0 +1,61 @@
+From e4d457ba91e84c33e992a8c5c0831ff6b43b028b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jun 2022 12:13:32 +0100
+Subject: arm64: cpufeature: Allow different PMU versions in ID_DFR0_EL1
+
+From: Alexandru Elisei <alexandru.elisei@arm.com>
+
+[ Upstream commit 506506cad3947b942425b119ffa2b06715d5d804 ]
+
+Commit b20d1ba3cf4b ("arm64: cpufeature: allow for version discrepancy in
+PMU implementations") made it possible to run Linux on a machine with PMUs
+with different versions without tainting the kernel. The patch relaxed the
+restriction only for the ID_AA64DFR0_EL1.PMUVer field, and missed doing the
+same for ID_DFR0_EL1.PerfMon , which also reports the PMU version, but for
+the AArch32 state.
+
+For example, with Linux running on two clusters with different PMU
+versions, the kernel is tainted when bringing up secondaries with the
+following message:
+
+[    0.097027] smp: Bringing up secondary CPUs ...
+[..]
+[    0.142805] Detected PIPT I-cache on CPU4
+[    0.142805] CPU features: SANITY CHECK: Unexpected variation in SYS_ID_DFR0_EL1. Boot CPU: 0x00000004011088, CPU4: 0x00000005011088
+[    0.143555] CPU features: Unsupported CPU feature variation detected.
+[    0.143702] GICv3: CPU4: found redistributor 10000 region 0:0x000000002f180000
+[    0.143702] GICv3: CPU4: using allocated LPI pending table @0x00000008800d0000
+[    0.144888] CPU4: Booted secondary processor 0x0000010000 [0x410fd0f0]
+
+The boot CPU implements FEAT_PMUv3p1 (ID_DFR0_EL1.PerfMon, bits 27:24, is
+0b0100), but CPU4, part of the other cluster, implements FEAT_PMUv3p4
+(ID_DFR0_EL1.PerfMon = 0b0101).
+
+Treat the PerfMon field as FTR_NONSTRICT and FTR_EXACT to pass the sanity
+check and to match how PMUVer is treated for the 64bit ID register.
+
+Fixes: b20d1ba3cf4b ("arm64: cpufeature: allow for version discrepancy in PMU implementations")
+Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
+Link: https://lore.kernel.org/r/20220617111332.203061-1-alexandru.elisei@arm.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/kernel/cpufeature.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
+index e71c9cfb46e8..474aa55c2f68 100644
+--- a/arch/arm64/kernel/cpufeature.c
++++ b/arch/arm64/kernel/cpufeature.c
+@@ -536,7 +536,7 @@ static const struct arm64_ftr_bits ftr_id_pfr2[] = {
+ static const struct arm64_ftr_bits ftr_id_dfr0[] = {
+       /* [31:28] TraceFilt */
+-      S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_DFR0_PERFMON_SHIFT, 4, 0xf),
++      S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_EXACT, ID_DFR0_PERFMON_SHIFT, 4, 0),
+       ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_DFR0_MPROFDBG_SHIFT, 4, 0),
+       ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_DFR0_MMAPTRC_SHIFT, 4, 0),
+       ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_DFR0_COPTRC_SHIFT, 4, 0),
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm64-do-not-forget-syscall-when-starting-a-new-thre.patch b/queue-5.15/arm64-do-not-forget-syscall-when-starting-a-new-thre.patch
new file mode 100644 (file)
index 0000000..a5cbdb2
--- /dev/null
@@ -0,0 +1,40 @@
+From b192322838cc0ef6133ee1d1abcc8a160daea935 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jun 2022 17:24:46 +0100
+Subject: arm64: Do not forget syscall when starting a new thread.
+
+From: Francis Laniel <flaniel@linux.microsoft.com>
+
+[ Upstream commit de6921856f99c11d3986c6702d851e1328d4f7f6 ]
+
+Enable tracing of the execve*() system calls with the
+syscalls:sys_exit_execve tracepoint by removing the call to
+forget_syscall() when starting a new thread and preserving the value of
+regs->syscallno across exec.
+
+Signed-off-by: Francis Laniel <flaniel@linux.microsoft.com>
+Link: https://lore.kernel.org/r/20220608162447.666494-2-flaniel@linux.microsoft.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/include/asm/processor.h | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
+index 5e73d7f7d1e7..d9bf3d12a2b8 100644
+--- a/arch/arm64/include/asm/processor.h
++++ b/arch/arm64/include/asm/processor.h
+@@ -204,8 +204,9 @@ void tls_preserve_current_state(void);
+ static inline void start_thread_common(struct pt_regs *regs, unsigned long pc)
+ {
++      s32 previous_syscall = regs->syscallno;
+       memset(regs, 0, sizeof(*regs));
+-      forget_syscall(regs);
++      regs->syscallno = previous_syscall;
+       regs->pc = pc;
+       if (system_uses_irq_prio_masking())
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm64-dts-allwinner-a64-orangepi-win-fix-led-node-na.patch b/queue-5.15/arm64-dts-allwinner-a64-orangepi-win-fix-led-node-na.patch
new file mode 100644 (file)
index 0000000..5a9e4a7
--- /dev/null
@@ -0,0 +1,37 @@
+From 663b413b371bb75b5dc5f2e7969793365ec6b686 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 2 Jul 2022 08:28:15 -0500
+Subject: arm64: dts: allwinner: a64: orangepi-win: Fix LED node name
+
+From: Samuel Holland <samuel@sholland.org>
+
+[ Upstream commit b8eb2df19fbf97aa1e950cf491232c2e3bef8357 ]
+
+"status" does not match any pattern in the gpio-leds binding. Rename the
+node to the preferred pattern. This fixes a `make dtbs_check` error.
+
+Signed-off-by: Samuel Holland <samuel@sholland.org>
+Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Link: https://lore.kernel.org/r/20220702132816.46456-1-samuel@sholland.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts
+index 097a5511523a..09eee653d5ca 100644
+--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts
++++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts
+@@ -40,7 +40,7 @@ hdmi_con_in: endpoint {
+       leds {
+               compatible = "gpio-leds";
+-              status {
++              led-0 {
+                       label = "orangepi:green:status";
+                       gpios = <&pio 7 11 GPIO_ACTIVE_HIGH>; /* PH11 */
+               };
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm64-dts-mt7622-fix-bpi-r64-wps-button.patch b/queue-5.15/arm64-dts-mt7622-fix-bpi-r64-wps-button.patch
new file mode 100644 (file)
index 0000000..3ecc312
--- /dev/null
@@ -0,0 +1,52 @@
+From 2702dda61ec060997456c94ea58910f93b5d3ec2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Jun 2022 13:16:57 +0200
+Subject: arm64: dts: mt7622: fix BPI-R64 WPS button
+
+From: Nick Hainke <vincent@systemli.org>
+
+[ Upstream commit c98e6e683632386a3bd284acda4342e68aec4c41 ]
+
+The bananapi R64 (BPI-R64) experiences wrong WPS button signals.
+In OpenWrt pushing the WPS button while powering on the device will set
+it to recovery mode. Currently, this also happens without any user
+interaction. In particular, the wrong signals appear while booting the
+device or restarting it, e.g. after doing a system upgrade. If the
+device is in recovery mode the user needs to manually power cycle or
+restart it.
+
+The official BPI-R64 sources set the WPS button to GPIO_ACTIVE_LOW in
+the device tree. This setting seems to suppress the unwanted WPS button
+press signals. So this commit changes the button from GPIO_ACTIVE_HIGH to
+GPIO_ACTIVE_LOW.
+
+The official BPI-R64 sources can be found on
+https://github.com/BPI-SINOVOIP/BPI-R64-openwrt
+
+Fixes: 0b6286dd96c0 ("arm64: dts: mt7622: add bananapi BPI-R64 board")
+
+Suggested-by: INAGAKI Hiroshi <musashino.open@gmail.com>
+Signed-off-by: Nick Hainke <vincent@systemli.org>
+Link: https://lore.kernel.org/r/20220630111746.4098-1-vincent@systemli.org
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+index 2f77dc40b9b8..6b99d903b479 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+@@ -49,7 +49,7 @@ factory {
+               wps {
+                       label = "wps";
+                       linux,code = <KEY_WPS_BUTTON>;
+-                      gpios = <&pio 102 GPIO_ACTIVE_HIGH>;
++                      gpios = <&pio 102 GPIO_ACTIVE_LOW>;
+               };
+       };
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm64-dts-mt8192-fix-idle-states-entry-method.patch b/queue-5.15/arm64-dts-mt8192-fix-idle-states-entry-method.patch
new file mode 100644 (file)
index 0000000..ab46bd7
--- /dev/null
@@ -0,0 +1,43 @@
+From f78a3732116bc60800b155a5174c5cd6fbbfa02f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jun 2022 19:31:50 -0400
+Subject: arm64: dts: mt8192: Fix idle-states entry-method
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+
+[ Upstream commit 2e599740f7e423ee89fb027896cb2635dd43784f ]
+
+The entry-method property of the idle-states node should be "psci" as
+described in the idle-states binding, since this is already the value of
+enable-method in the CPU nodes. Fix it to get rid of a dtbs_check
+warning.
+
+Fixes: 9260918d3a4f ("arm64: dts: mt8192: Add cpu-idle-states")
+Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20220617233150.2466344-3-nfraprado@collabora.com
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt8192.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+index a57ac5163acc..d1e63527b387 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+@@ -168,7 +168,7 @@ l3_0: l3-cache {
+               };
+               idle-states {
+-                      entry-method = "arm,psci";
++                      entry-method = "psci";
+                       cpu_sleep_l: cpu-sleep-l {
+                               compatible = "arm,idle-state";
+                               arm,psci-suspend-param = <0x00010001>;
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm64-dts-mt8192-fix-idle-states-nodes-naming-scheme.patch b/queue-5.15/arm64-dts-mt8192-fix-idle-states-nodes-naming-scheme.patch
new file mode 100644 (file)
index 0000000..6429b91
--- /dev/null
@@ -0,0 +1,144 @@
+From 1d36f5a4a01ed230848431189fd408b80a86413c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jun 2022 19:31:49 -0400
+Subject: arm64: dts: mt8192: Fix idle-states nodes naming scheme
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+
+[ Upstream commit 399e23ad51caaf62400a531c9268ad3c453c3d76 ]
+
+Tweak the name of the idle-states subnodes so that they follow the
+binding pattern, getting rid of dtbs_check warnings.
+
+Only the usage of "-" in the name was necessary, but "off" was also
+exchanged for "sleep" since that seems to be a more common wording in
+other dts files.
+
+Fixes: 9260918d3a4f ("arm64: dts: mt8192: Add cpu-idle-states")
+Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20220617233150.2466344-2-nfraprado@collabora.com
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt8192.dtsi | 24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+index cb1e46d2c1ba..a57ac5163acc 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+@@ -39,7 +39,7 @@ cpu0: cpu@0 {
+                       reg = <0x000>;
+                       enable-method = "psci";
+                       clock-frequency = <1701000000>;
+-                      cpu-idle-states = <&cpuoff_l &clusteroff_l>;
++                      cpu-idle-states = <&cpu_sleep_l &cluster_sleep_l>;
+                       next-level-cache = <&l2_0>;
+                       capacity-dmips-mhz = <530>;
+               };
+@@ -50,7 +50,7 @@ cpu1: cpu@100 {
+                       reg = <0x100>;
+                       enable-method = "psci";
+                       clock-frequency = <1701000000>;
+-                      cpu-idle-states = <&cpuoff_l &clusteroff_l>;
++                      cpu-idle-states = <&cpu_sleep_l &cluster_sleep_l>;
+                       next-level-cache = <&l2_0>;
+                       capacity-dmips-mhz = <530>;
+               };
+@@ -61,7 +61,7 @@ cpu2: cpu@200 {
+                       reg = <0x200>;
+                       enable-method = "psci";
+                       clock-frequency = <1701000000>;
+-                      cpu-idle-states = <&cpuoff_l &clusteroff_l>;
++                      cpu-idle-states = <&cpu_sleep_l &cluster_sleep_l>;
+                       next-level-cache = <&l2_0>;
+                       capacity-dmips-mhz = <530>;
+               };
+@@ -72,7 +72,7 @@ cpu3: cpu@300 {
+                       reg = <0x300>;
+                       enable-method = "psci";
+                       clock-frequency = <1701000000>;
+-                      cpu-idle-states = <&cpuoff_l &clusteroff_l>;
++                      cpu-idle-states = <&cpu_sleep_l &cluster_sleep_l>;
+                       next-level-cache = <&l2_0>;
+                       capacity-dmips-mhz = <530>;
+               };
+@@ -83,7 +83,7 @@ cpu4: cpu@400 {
+                       reg = <0x400>;
+                       enable-method = "psci";
+                       clock-frequency = <2171000000>;
+-                      cpu-idle-states = <&cpuoff_b &clusteroff_b>;
++                      cpu-idle-states = <&cpu_sleep_b &cluster_sleep_b>;
+                       next-level-cache = <&l2_1>;
+                       capacity-dmips-mhz = <1024>;
+               };
+@@ -94,7 +94,7 @@ cpu5: cpu@500 {
+                       reg = <0x500>;
+                       enable-method = "psci";
+                       clock-frequency = <2171000000>;
+-                      cpu-idle-states = <&cpuoff_b &clusteroff_b>;
++                      cpu-idle-states = <&cpu_sleep_b &cluster_sleep_b>;
+                       next-level-cache = <&l2_1>;
+                       capacity-dmips-mhz = <1024>;
+               };
+@@ -105,7 +105,7 @@ cpu6: cpu@600 {
+                       reg = <0x600>;
+                       enable-method = "psci";
+                       clock-frequency = <2171000000>;
+-                      cpu-idle-states = <&cpuoff_b &clusteroff_b>;
++                      cpu-idle-states = <&cpu_sleep_b &cluster_sleep_b>;
+                       next-level-cache = <&l2_1>;
+                       capacity-dmips-mhz = <1024>;
+               };
+@@ -116,7 +116,7 @@ cpu7: cpu@700 {
+                       reg = <0x700>;
+                       enable-method = "psci";
+                       clock-frequency = <2171000000>;
+-                      cpu-idle-states = <&cpuoff_b &clusteroff_b>;
++                      cpu-idle-states = <&cpu_sleep_b &cluster_sleep_b>;
+                       next-level-cache = <&l2_1>;
+                       capacity-dmips-mhz = <1024>;
+               };
+@@ -169,7 +169,7 @@ l3_0: l3-cache {
+               idle-states {
+                       entry-method = "arm,psci";
+-                      cpuoff_l: cpuoff_l {
++                      cpu_sleep_l: cpu-sleep-l {
+                               compatible = "arm,idle-state";
+                               arm,psci-suspend-param = <0x00010001>;
+                               local-timer-stop;
+@@ -177,7 +177,7 @@ cpuoff_l: cpuoff_l {
+                               exit-latency-us = <140>;
+                               min-residency-us = <780>;
+                       };
+-                      cpuoff_b: cpuoff_b {
++                      cpu_sleep_b: cpu-sleep-b {
+                               compatible = "arm,idle-state";
+                               arm,psci-suspend-param = <0x00010001>;
+                               local-timer-stop;
+@@ -185,7 +185,7 @@ cpuoff_b: cpuoff_b {
+                               exit-latency-us = <145>;
+                               min-residency-us = <720>;
+                       };
+-                      clusteroff_l: clusteroff_l {
++                      cluster_sleep_l: cluster-sleep-l {
+                               compatible = "arm,idle-state";
+                               arm,psci-suspend-param = <0x01010002>;
+                               local-timer-stop;
+@@ -193,7 +193,7 @@ clusteroff_l: clusteroff_l {
+                               exit-latency-us = <155>;
+                               min-residency-us = <860>;
+                       };
+-                      clusteroff_b: clusteroff_b {
++                      cluster_sleep_b: cluster-sleep-b {
+                               compatible = "arm,idle-state";
+                               arm,psci-suspend-param = <0x01010002>;
+                               local-timer-stop;
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm64-dts-qcom-ipq8074-fix-nand-node-name.patch b/queue-5.15/arm64-dts-qcom-ipq8074-fix-nand-node-name.patch
new file mode 100644 (file)
index 0000000..73c6339
--- /dev/null
@@ -0,0 +1,37 @@
+From de3dbb63d89880f25c22820d2b065d49c079e068 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Jun 2022 14:06:42 +0200
+Subject: arm64: dts: qcom: ipq8074: fix NAND node name
+
+From: Robert Marko <robimarko@gmail.com>
+
+[ Upstream commit b39961659ffc3c3a9e3d0d43b0476547b5f35d49 ]
+
+Per schema it should be nand-controller@79b0000 instead of nand@79b0000.
+Fix it to match nand-controller.yaml requirements.
+
+Signed-off-by: Robert Marko <robimarko@gmail.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220621120642.518575-1-robimarko@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/ipq8074.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+index fea415302408..6b9ac0550490 100644
+--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
++++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+@@ -437,7 +437,7 @@ qpic_bam: dma-controller@7984000 {
+                       status = "disabled";
+               };
+-              qpic_nand: nand@79b0000 {
++              qpic_nand: nand-controller@79b0000 {
+                       compatible = "qcom,ipq8074-nand";
+                       reg = <0x079b0000 0x10000>;
+                       #address-cells = <1>;
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm64-dts-qcom-msm8916-fix-typo-in-pronto-remoteproc.patch b/queue-5.15/arm64-dts-qcom-msm8916-fix-typo-in-pronto-remoteproc.patch
new file mode 100644 (file)
index 0000000..16fa4d6
--- /dev/null
@@ -0,0 +1,42 @@
+From fdade98f7ed20c1ed9919aba4818d7e03e8a9134 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 May 2022 19:47:40 +0530
+Subject: arm64: dts: qcom: msm8916: Fix typo in pronto remoteproc node
+
+From: Sireesh Kodali <sireeshkodali1@gmail.com>
+
+[ Upstream commit 5458d6f2827cd30218570f266b8d238417461f2f ]
+
+The smem-state properties for the pronto node were incorrectly labelled,
+reading `qcom,state*` rather than `qcom,smem-state*`. Fix that, allowing
+the stop state to be used.
+
+Fixes: 88106096cbf8 ("ARM: dts: msm8916: Add and enable wcnss node")
+Signed-off-by: Sireesh Kodali <sireeshkodali1@gmail.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Stephan Gerhold <stephan@gerhold.net>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220526141740.15834-3-sireeshkodali1@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/msm8916.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
+index 8b2724272464..19e201f52b16 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
+@@ -1747,8 +1747,8 @@ pronto: remoteproc@a21b000 {
+                                       <&rpmpd MSM8916_VDDMX>;
+                       power-domain-names = "cx", "mx";
+-                      qcom,state = <&wcnss_smp2p_out 0>;
+-                      qcom,state-names = "stop";
++                      qcom,smem-states = <&wcnss_smp2p_out 0>;
++                      qcom,smem-state-names = "stop";
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&wcnss_pin_a>;
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm64-dts-qcom-qcs404-fix-incorrect-usb2-phys-assign.patch b/queue-5.15/arm64-dts-qcom-qcs404-fix-incorrect-usb2-phys-assign.patch
new file mode 100644 (file)
index 0000000..5566c5d
--- /dev/null
@@ -0,0 +1,63 @@
+From 1ac832e4e57726517bfa7fb64b40857129934cc4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Jul 2022 14:00:38 +0530
+Subject: arm64: dts: qcom: qcs404: Fix incorrect USB2 PHYs assignment
+
+From: Sumit Garg <sumit.garg@linaro.org>
+
+[ Upstream commit 58577966a42fc0b660b5e2c7c9e5a2241363ea83 ]
+
+Currently the DT for QCS404 SoC has setup for 2 USB2 PHYs with one each
+assigned to USB3 controller and USB2 controller. This assignment is
+incorrect which only works by luck: as when each USB HCI comes up it
+configures the *other* controllers PHY which is enough to make them
+happy. If, for any reason, we were to disable one of the controllers then
+both would stop working.
+
+This was a difficult inconsistency to be caught which was found while
+trying to enable USB support in u-boot. So with all the required drivers
+ported to u-boot, I couldn't get the same USB storage device enumerated
+in u-boot which was being enumerated fine by the kernel.
+
+The root cause of the problem came out to be that I wasn't enabling USB2
+PHY: "usb2_phy_prim" in u-boot. Then I realised that via simply disabling
+the same USB2 PHY currently assigned to USB2 host controller in the
+kernel disabled enumeration for USB3 host controller as well.
+
+So fix this inconsistency by correctly assigning USB2 PHYs.
+
+Fixes: 9375e7d719b3 ("arm64: dts: qcom: qcs404: Add USB devices and PHYs")
+Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
+Reviewed-by: Daniel Thompson <daniel.thompson@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220711083038.1518529-1-sumit.garg@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/qcs404.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/qcs404.dtsi b/arch/arm64/boot/dts/qcom/qcs404.dtsi
+index ca5be1647980..18cc8e3bc93a 100644
+--- a/arch/arm64/boot/dts/qcom/qcs404.dtsi
++++ b/arch/arm64/boot/dts/qcom/qcs404.dtsi
+@@ -548,7 +548,7 @@ dwc3@7580000 {
+                               compatible = "snps,dwc3";
+                               reg = <0x07580000 0xcd00>;
+                               interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+-                              phys = <&usb2_phy_sec>, <&usb3_phy>;
++                              phys = <&usb2_phy_prim>, <&usb3_phy>;
+                               phy-names = "usb2-phy", "usb3-phy";
+                               snps,has-lpm-erratum;
+                               snps,hird-threshold = /bits/ 8 <0x10>;
+@@ -577,7 +577,7 @@ dwc3@78c0000 {
+                               compatible = "snps,dwc3";
+                               reg = <0x078c0000 0xcc00>;
+                               interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+-                              phys = <&usb2_phy_prim>;
++                              phys = <&usb2_phy_sec>;
+                               phy-names = "usb2-phy";
+                               snps,has-lpm-erratum;
+                               snps,hird-threshold = /bits/ 8 <0x10>;
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm64-dts-qcom-sc7180-remove-ipa_fw_mem-node-on-trog.patch b/queue-5.15/arm64-dts-qcom-sc7180-remove-ipa_fw_mem-node-on-trog.patch
new file mode 100644 (file)
index 0000000..66bb1a0
--- /dev/null
@@ -0,0 +1,45 @@
+From 6a4cf7fec131c5e621d6796fcfa18473969de4c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 May 2022 12:33:07 -0700
+Subject: arm64: dts: qcom: sc7180: Remove ipa_fw_mem node on trogdor
+
+From: Stephen Boyd <swboyd@chromium.org>
+
+[ Upstream commit e60414644cf3a703e10ed4429c15263095945ffe ]
+
+We don't use this carveout on trogdor boards, and having it defined in
+the sc7180 SoC file causes an overlap message to be printed at boot.
+
+ OF: reserved mem: OVERLAP DETECTED!
+ memory@86000000 (0x0000000086000000--0x000000008ec00000) overlaps with memory@8b700000 (0x000000008b700000--0x000000008b710000)
+
+Delete the node in the trogdor dtsi file to fix the overlap problem and
+remove the error message.
+
+Cc: Alex Elder <elder@linaro.org>
+Cc: Matthias Kaehlcke <mka@chromium.org>
+Fixes: 310b266655a3 ("arm64: dts: qcom: sc7180: define ipa_fw_mem node")
+Signed-off-by: Stephen Boyd <swboyd@chromium.org>
+Reviewed-by: Alex Elder <elder@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220517193307.3034602-1-swboyd@chromium.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
+index 70c88c37de32..a9d36ac6cb90 100644
+--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
+@@ -42,6 +42,7 @@ charger-crit {
+  */
+ /delete-node/ &hyp_mem;
++/delete-node/ &ipa_fw_mem;
+ /delete-node/ &xbl_mem;
+ /delete-node/ &aop_mem;
+ /delete-node/ &sec_apps_mem;
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm64-dts-qcom-sdm630-disable-gpu-by-default.patch b/queue-5.15/arm64-dts-qcom-sdm630-disable-gpu-by-default.patch
new file mode 100644 (file)
index 0000000..7871be1
--- /dev/null
@@ -0,0 +1,41 @@
+From 1fde6092134d3c876b7f392d84786ccdcfea5e31 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 21 May 2022 23:27:00 +0300
+Subject: arm64: dts: qcom: sdm630: disable GPU by default
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 1c047919763b4548381d1ab3320af1df66ab83df ]
+
+The SoC's device tree file disables gpucc and adreno's SMMU by default.
+So let's disable the GPU too. Moreover it looks like SMMU might be not
+usable without additional patches (which means that GPU is unusable
+too). No board uses GPU at this moment.
+
+Fixes: 5cf69dcbec8b ("arm64: dts: qcom: sdm630: Add Adreno 508 GPU configuration")
+Reviewed-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+Reviewed-by: Marijn Suijten <marijn.suijten@somainline.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220521202708.1509308-4-dmitry.baryshkov@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sdm630.dtsi | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm630.dtsi b/arch/arm64/boot/dts/qcom/sdm630.dtsi
+index a8724fd60645..18957e452bb7 100644
+--- a/arch/arm64/boot/dts/qcom/sdm630.dtsi
++++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi
+@@ -1046,6 +1046,8 @@ adreno_gpu: gpu@5000000 {
+                       operating-points-v2 = <&gpu_sdm630_opp_table>;
++                      status = "disabled";
++
+                       gpu_sdm630_opp_table: opp-table {
+                               compatible  = "operating-points-v2";
+                               opp-775000000 {
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm64-dts-qcom-sdm630-fix-gpu-s-interconnect-path.patch b/queue-5.15/arm64-dts-qcom-sdm630-fix-gpu-s-interconnect-path.patch
new file mode 100644 (file)
index 0000000..95e107c
--- /dev/null
@@ -0,0 +1,52 @@
+From 243a218910bd2ab5d044f5ff73dfec1681ffc2a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 21 May 2022 23:27:04 +0300
+Subject: arm64: dts: qcom: sdm630: fix gpu's interconnect path
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 3cd1c4f41d64a40ea6bc4575ae28e37542123d77 ]
+
+ICC path for the GPU incorrectly states <&gnoc 1 &bimc 5>, which is
+a path from SLAVE_GNOC_BIMC to SLAVE_EBI. According to the downstream
+kernel sources, the GPU uses MASTER_OXILI here, which is equivalent to
+<&bimc 1 ...>.
+
+While we are at it, use defined names instead of the numbers for this
+interconnect path.
+
+Fixes: 5cf69dcbec8b ("arm64: dts: qcom: sdm630: Add Adreno 508 GPU configuration")
+Reported-by: Marijn Suijten <marijn.suijten@somainline.org>
+Reviewed-by: Marijn Suijten <marijn.suijten@somainline.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220521202708.1509308-8-dmitry.baryshkov@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sdm630.dtsi | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm630.dtsi b/arch/arm64/boot/dts/qcom/sdm630.dtsi
+index dca66b8c166c..952bb133914f 100644
+--- a/arch/arm64/boot/dts/qcom/sdm630.dtsi
++++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi
+@@ -8,6 +8,7 @@
+ #include <dt-bindings/clock/qcom,gpucc-sdm660.h>
+ #include <dt-bindings/clock/qcom,mmcc-sdm660.h>
+ #include <dt-bindings/clock/qcom,rpmcc.h>
++#include <dt-bindings/interconnect/qcom,sdm660.h>
+ #include <dt-bindings/power/qcom-rpmpd.h>
+ #include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+@@ -1041,7 +1042,7 @@ adreno_gpu: gpu@5000000 {
+                       nvmem-cells = <&gpu_speed_bin>;
+                       nvmem-cell-names = "speed_bin";
+-                      interconnects = <&gnoc 1 &bimc 5>;
++                      interconnects = <&bimc MASTER_OXILI &bimc SLAVE_EBI>;
+                       interconnect-names = "gfx-mem";
+                       operating-points-v2 = <&gpu_sdm630_opp_table>;
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm64-dts-qcom-sdm630-fix-the-qusb2phy-ref-clock.patch b/queue-5.15/arm64-dts-qcom-sdm630-fix-the-qusb2phy-ref-clock.patch
new file mode 100644 (file)
index 0000000..129f1e0
--- /dev/null
@@ -0,0 +1,40 @@
+From 6099dbe08936beec411d0794f01e5eb5edc81039 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 21 May 2022 23:27:01 +0300
+Subject: arm64: dts: qcom: sdm630: fix the qusb2phy ref clock
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 924bbd8dd60e094344711c3526a5b308d71dc008 ]
+
+According to the downstram DT file, the qusb2phy ref clock should be
+GCC_RX0_USB2_CLKREF_CLK, not GCC_RX1_USB2_CLKREF_CLK.
+
+Fixes: c65a4ed2ea8b ("arm64: dts: qcom: sdm630: Add USB configuration")
+Cc: Konrad Dybcio <konrad.dybcio@somainline.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+Reviewed-by: Marijn Suijten <marijn.suijten@somainline.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220521202708.1509308-5-dmitry.baryshkov@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sdm630.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm630.dtsi b/arch/arm64/boot/dts/qcom/sdm630.dtsi
+index 18957e452bb7..dca66b8c166c 100644
+--- a/arch/arm64/boot/dts/qcom/sdm630.dtsi
++++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi
+@@ -1253,7 +1253,7 @@ qusb2phy: phy@c012000 {
+                       #phy-cells = <0>;
+                       clocks = <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>,
+-                              <&gcc GCC_RX1_USB2_CLKREF_CLK>;
++                               <&gcc GCC_RX0_USB2_CLKREF_CLK>;
+                       clock-names = "cfg_ahb", "ref";
+                       resets = <&gcc GCC_QUSB2PHY_PRIM_BCR>;
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm64-dts-qcom-sdm636-sony-xperia-ganges-mermaid-cor.patch b/queue-5.15/arm64-dts-qcom-sdm636-sony-xperia-ganges-mermaid-cor.patch
new file mode 100644 (file)
index 0000000..a8f5be5
--- /dev/null
@@ -0,0 +1,40 @@
+From 8336853741c53ba321cf7ea306688261e646fbf4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 21 May 2022 23:27:05 +0300
+Subject: arm64: dts: qcom: sdm636-sony-xperia-ganges-mermaid: correct sdc2
+ pinconf
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 3a04cec9cba393abfe70fc62e523f381c9baec2e ]
+
+Fix the device tree node in the &sdc2_state_on override. The sdm630 uses
+'clk' rather than 'pinconf-clk'.
+
+Fixes: 4c1d849ec047 ("arm64: dts: qcom: sdm630-xperia: Retire sdm630-sony-xperia-ganges.dtsi")
+Reviewed-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Marijn Suijten <marijn.suijten@somainline.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220521202708.1509308-9-dmitry.baryshkov@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sdm636-sony-xperia-ganges-mermaid.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm636-sony-xperia-ganges-mermaid.dts b/arch/arm64/boot/dts/qcom/sdm636-sony-xperia-ganges-mermaid.dts
+index bba1c2bce213..0afe9eee025e 100644
+--- a/arch/arm64/boot/dts/qcom/sdm636-sony-xperia-ganges-mermaid.dts
++++ b/arch/arm64/boot/dts/qcom/sdm636-sony-xperia-ganges-mermaid.dts
+@@ -18,7 +18,7 @@ / {
+ };
+ &sdc2_state_on {
+-      pinconf-clk {
++      clk {
+               drive-strength = <14>;
+       };
+ };
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm64-dts-qcom-sm6125-append-state-suffix-to-pinctrl.patch b/queue-5.15/arm64-dts-qcom-sm6125-append-state-suffix-to-pinctrl.patch
new file mode 100644 (file)
index 0000000..02c50bb
--- /dev/null
@@ -0,0 +1,86 @@
+From 60ade5b9add84c6563d084f654079d9409b4e504 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 12:03:34 +0200
+Subject: arm64: dts: qcom: sm6125: Append -state suffix to pinctrl nodes
+
+From: Marijn Suijten <marijn.suijten@somainline.org>
+
+[ Upstream commit cbfb5668aece448877fa7826cde81c9d06f4a4ac ]
+
+According to qcom,sm6125-pinctrl.yaml all nodes inside the tlmm must be
+suffixed by -state:
+
+    qcom/sm6125-sony-xperia-seine-pdx201.dtb: pinctrl@500000: 'sdc2-off', 'sdc2-on' do not match any of the regexes: '-state$', 'pinctrl-[0-9]+'
+
+The label names have been updated to match, going from sdc2_state_X to
+sdc2_X_state.
+
+Fixes: cff4bbaf2a2d ("arm64: dts: qcom: Add support for SM6125")
+Fixes: 82e1783890b7 ("arm64: dts: qcom: sm6125: Add support for Sony Xperia 10II")
+Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220508100336.127176-2-marijn.suijten@somainline.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts     | 4 ++--
+ arch/arm64/boot/dts/qcom/sm6125.dtsi                      | 8 ++++----
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts b/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts
+index d4f0a15b763d..47f8e5397ebb 100644
+--- a/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts
++++ b/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts
+@@ -88,7 +88,7 @@ &hsusb_phy1 {
+       status = "okay";
+ };
+-&sdc2_state_off {
++&sdc2_off_state {
+       sd-cd {
+               pins = "gpio98";
+               drive-strength = <2>;
+@@ -96,7 +96,7 @@ sd-cd {
+       };
+ };
+-&sdc2_state_on {
++&sdc2_on_state {
+       sd-cd {
+               pins = "gpio98";
+               drive-strength = <2>;
+diff --git a/arch/arm64/boot/dts/qcom/sm6125.dtsi b/arch/arm64/boot/dts/qcom/sm6125.dtsi
+index cc16c05a2856..f89af5e35112 100644
+--- a/arch/arm64/boot/dts/qcom/sm6125.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm6125.dtsi
+@@ -336,7 +336,7 @@ tlmm: pinctrl@500000 {
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+-                      sdc2_state_off: sdc2-off {
++                      sdc2_off_state: sdc2-off-state {
+                               clk {
+                                       pins = "sdc2_clk";
+                                       drive-strength = <2>;
+@@ -356,7 +356,7 @@ data {
+                               };
+                       };
+-                      sdc2_state_on: sdc2-on {
++                      sdc2_on_state: sdc2-on-state {
+                               clk {
+                                       pins = "sdc2_clk";
+                                       drive-strength = <16>;
+@@ -437,8 +437,8 @@ sdhc_2: sdhci@4784000 {
+                               <&xo_board>;
+                       clock-names = "iface", "core", "xo";
+-                      pinctrl-0 = <&sdc2_state_on>;
+-                      pinctrl-1 = <&sdc2_state_off>;
++                      pinctrl-0 = <&sdc2_on_state>;
++                      pinctrl-1 = <&sdc2_off_state>;
+                       pinctrl-names = "default", "sleep";
+                       bus-width = <4>;
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm64-dts-qcom-sm6125-move-sdc2-pinctrl-from-seine-p.patch b/queue-5.15/arm64-dts-qcom-sm6125-move-sdc2-pinctrl-from-seine-p.patch
new file mode 100644 (file)
index 0000000..cd17542
--- /dev/null
@@ -0,0 +1,140 @@
+From e045e41121ffce9b1da205b8ef8eacc34c6d2475 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 12:03:33 +0200
+Subject: arm64: dts: qcom: sm6125: Move sdc2 pinctrl from seine-pdx201 to
+ sm6125
+
+From: Marijn Suijten <marijn.suijten@somainline.org>
+
+[ Upstream commit 6990640a93ba4e76dd62ca3ea1082a7354db09d7 ]
+
+Both the sdc2-on and sdc2-off pinctrl nodes are used by the
+sdhci@4784000 node in sm6125.dtsi.  Surprisingly sdc2-off is defined in
+sm6125, yet its sdc2-on counterpart is only defined in board-specific DT
+for the Sony Seine PDX201 board/device resulting in an "undefined label
+&sdc2_state_on" error if sm6125.dtsi were included elsewhere.
+This sm6125 base dtsi should not rely on externally defined labels; the
+properties referencing it should then also be written externally.
+Since the sdc2-on pin configuration is board-independent just like
+sdc2-off, move it from seine-pdx201.dts into sm6125.dtsi.
+
+The SDCard-detect pin (gpio98) is however board-specific, and remains as
+an overwrite in seine-pdx201.dts for both the on and off state.
+
+As a drive-by cleanup, reorder bias- and drive-strength properties.
+
+Fixes: cff4bbaf2a2d ("arm64: dts: qcom: Add support for SM6125")
+Fixes: 82e1783890b7 ("arm64: dts: qcom: sm6125: Add support for Sony Xperia 10II")
+Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220508100336.127176-1-marijn.suijten@somainline.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../qcom/sm6125-sony-xperia-seine-pdx201.dts  | 34 +++++--------------
+ arch/arm64/boot/dts/qcom/sm6125.dtsi          | 24 +++++++++++--
+ 2 files changed, 30 insertions(+), 28 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts b/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts
+index 58b6b2742d3f..d4f0a15b763d 100644
+--- a/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts
++++ b/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts
+@@ -91,8 +91,16 @@ &hsusb_phy1 {
+ &sdc2_state_off {
+       sd-cd {
+               pins = "gpio98";
++              drive-strength = <2>;
+               bias-disable;
++      };
++};
++
++&sdc2_state_on {
++      sd-cd {
++              pins = "gpio98";
+               drive-strength = <2>;
++              bias-pull-up;
+       };
+ };
+@@ -102,32 +110,6 @@ &sdhc_1 {
+ &tlmm {
+       gpio-reserved-ranges = <22 2>, <28 6>;
+-
+-      sdc2_state_on: sdc2-on {
+-              clk {
+-                      pins = "sdc2_clk";
+-                      bias-disable;
+-                      drive-strength = <16>;
+-              };
+-
+-              cmd {
+-                      pins = "sdc2_cmd";
+-                      bias-pull-up;
+-                      drive-strength = <10>;
+-              };
+-
+-              data {
+-                      pins = "sdc2_data";
+-                      bias-pull-up;
+-                      drive-strength = <10>;
+-              };
+-
+-              sd-cd {
+-                      pins = "gpio98";
+-                      bias-pull-up;
+-                      drive-strength = <2>;
+-              };
+-      };
+ };
+ &usb3 {
+diff --git a/arch/arm64/boot/dts/qcom/sm6125.dtsi b/arch/arm64/boot/dts/qcom/sm6125.dtsi
+index 9f476e3d0720..cc16c05a2856 100644
+--- a/arch/arm64/boot/dts/qcom/sm6125.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm6125.dtsi
+@@ -339,20 +339,40 @@ tlmm: pinctrl@500000 {
+                       sdc2_state_off: sdc2-off {
+                               clk {
+                                       pins = "sdc2_clk";
+-                                      bias-disable;
+                                       drive-strength = <2>;
++                                      bias-disable;
+                               };
+                               cmd {
+                                       pins = "sdc2_cmd";
++                                      drive-strength = <2>;
+                                       bias-pull-up;
++                              };
++
++                              data {
++                                      pins = "sdc2_data";
+                                       drive-strength = <2>;
++                                      bias-pull-up;
++                              };
++                      };
++
++                      sdc2_state_on: sdc2-on {
++                              clk {
++                                      pins = "sdc2_clk";
++                                      drive-strength = <16>;
++                                      bias-disable;
++                              };
++
++                              cmd {
++                                      pins = "sdc2_cmd";
++                                      drive-strength = <10>;
++                                      bias-pull-up;
+                               };
+                               data {
+                                       pins = "sdc2_data";
++                                      drive-strength = <10>;
+                                       bias-pull-up;
+-                                      drive-strength = <2>;
+                               };
+                       };
+               };
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm64-dts-qcom-sm8250-add-missing-pcie-phy-clock-cel.patch b/queue-5.15/arm64-dts-qcom-sm8250-add-missing-pcie-phy-clock-cel.patch
new file mode 100644 (file)
index 0000000..0d9ffe8
--- /dev/null
@@ -0,0 +1,55 @@
+From 271de320f57cdbcd5806a23a7369f28006ccbdba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Jul 2022 13:40:20 +0200
+Subject: arm64: dts: qcom: sm8250: add missing PCIe PHY clock-cells
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+[ Upstream commit d9fd162ce764c227fcfd4242f6c1639895a9481f ]
+
+Add the missing '#clock-cells' properties to the PCIe QMP PHY nodes.
+
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Fixes: e53bdfc00977 ("arm64: dts: qcom: sm8250: Add PCIe support")
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220705114032.22787-3-johan+linaro@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8250.dtsi | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi
+index 2786e2c8e565..b710bca45648 100644
+--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi
+@@ -1472,6 +1472,8 @@ pcie0_lane: lanes@1c06200 {
+                               clock-names = "pipe0";
+                               #phy-cells = <0>;
++
++                              #clock-cells = <0>;
+                               clock-output-names = "pcie_0_pipe_clk";
+                       };
+               };
+@@ -1578,6 +1580,8 @@ pcie1_lane: lanes@1c0e200 {
+                               clock-names = "pipe0";
+                               #phy-cells = <0>;
++
++                              #clock-cells = <0>;
+                               clock-output-names = "pcie_1_pipe_clk";
+                       };
+               };
+@@ -1684,6 +1688,8 @@ pcie2_lane: lanes@1c16200 {
+                               clock-names = "pipe0";
+                               #phy-cells = <0>;
++
++                              #clock-cells = <0>;
+                               clock-output-names = "pcie_2_pipe_clk";
+                       };
+               };
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm64-dts-renesas-beacon-fix-regulator-node-names.patch b/queue-5.15/arm64-dts-renesas-beacon-fix-regulator-node-names.patch
new file mode 100644 (file)
index 0000000..001e76f
--- /dev/null
@@ -0,0 +1,60 @@
+From 2558e790ee16901fd4dda4c2d246ce16cf6ef6d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 May 2022 12:14:06 +0200
+Subject: arm64: dts: renesas: beacon: Fix regulator node names
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 7512af9f78dedea7e04225f665dad6750df7d095 ]
+
+Currently there are two nodes named "regulator_camera".  This causes the
+former to be overwritten by the latter.
+
+Fix this by renaming them to unique names, using the preferred hyphen
+instead of an underscore.
+
+While at it, update the name of the audio regulator (which was added in
+the same commit) to use a hyphen.
+
+Fixes: a1d8a344f1ca0709 ("arm64: dts: renesas: Introduce r8a774a1-beacon-rzg2m-kit")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/a9ac82bdf108162487289d091c53a9b3de393f13.1652263918.git.geert+renesas@glider.be
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi b/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi
+index 2692cc64bff6..48e0c0494f6a 100644
+--- a/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi
++++ b/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi
+@@ -146,7 +146,7 @@ rgb_panel: endpoint {
+               };
+       };
+-      reg_audio: regulator_audio {
++      reg_audio: regulator-audio {
+               compatible = "regulator-fixed";
+               regulator-name = "audio-1.8V";
+               regulator-min-microvolt = <1800000>;
+@@ -174,7 +174,7 @@ reg_lcd_reset: regulator-lcd-reset {
+               vin-supply = <&reg_lcd>;
+       };
+-      reg_cam0: regulator_camera {
++      reg_cam0: regulator-cam0 {
+               compatible = "regulator-fixed";
+               regulator-name = "reg_cam0";
+               regulator-min-microvolt = <1800000>;
+@@ -183,7 +183,7 @@ reg_cam0: regulator_camera {
+               enable-active-high;
+       };
+-      reg_cam1: regulator_camera {
++      reg_cam1: regulator-cam1 {
+               compatible = "regulator-fixed";
+               regulator-name = "reg_cam1";
+               regulator-min-microvolt = <1800000>;
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm64-dts-renesas-fix-thermal-sensors-on-single-zone.patch b/queue-5.15/arm64-dts-renesas-fix-thermal-sensors-on-single-zone.patch
new file mode 100644 (file)
index 0000000..9c3d1d8
--- /dev/null
@@ -0,0 +1,67 @@
+From 7e815b491973eedb041ae2475c989148bba3c6d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jun 2022 16:04:26 +0200
+Subject: arm64: dts: renesas: Fix thermal-sensors on single-zone sensors
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 62e8a53431145e06e503b71625a34eaa87b72b2c ]
+
+"make dtbs_check":
+
+    arch/arm64/boot/dts/renesas/r8a774c0-cat874.dtb: thermal-zones: cpu-thermal:thermal-sensors: [[74], [0]] is too long
+    arch/arm64/boot/dts/renesas/r8a774c0-ek874.dtb: thermal-zones: cpu-thermal:thermal-sensors: [[79], [0]] is too long
+    arch/arm64/boot/dts/renesas/r8a774c0-ek874-idk-2121wr.dtb: thermal-zones: cpu-thermal:thermal-sensors: [[82], [0]] is too long
+    arch/arm64/boot/dts/renesas/r8a774c0-ek874-mipi-2.1.dtb: thermal-zones: cpu-thermal:thermal-sensors: [[87], [0]] is too long
+    arch/arm64/boot/dts/renesas/r8a77990-ebisu.dtb: thermal-zones: cpu-thermal:thermal-sensors: [[105], [0]] is too long
+           From schema: Documentation/devicetree/bindings/thermal/thermal-zones.yaml
+
+Indeed, the thermal sensors on R-Car E3 and RZ/G2E support only a single
+zone, hence #thermal-sensor-cells = <0>.
+
+Fix this by dropping the bogus zero cell from the thermal sensor
+specifiers.
+
+Fixes: 8fa7d18f9ee2dc20 ("arm64: dts: renesas: r8a77990: Create thermal zone to support IPA")
+Fixes: 8438bfda9d768157 ("arm64: dts: renesas: r8a774c0: Create thermal zone to support IPA")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+Link: https://lore.kernel.org/r/28b812fdd1fc3698311fac984ab8b91d3d655c1c.1655301684.git.geert+renesas@glider.be
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/renesas/r8a774c0.dtsi | 2 +-
+ arch/arm64/boot/dts/renesas/r8a77990.dtsi | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
+index d597772c4c37..9eb08be3b98e 100644
+--- a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
+@@ -1953,7 +1953,7 @@ thermal-zones {
+               cpu-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <0>;
+-                      thermal-sensors = <&thermal 0>;
++                      thermal-sensors = <&thermal>;
+                       sustainable-power = <717>;
+                       cooling-maps {
+diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
+index 0ea300a8147d..9e616b0f04d4 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
+@@ -2102,7 +2102,7 @@ thermal-zones {
+               cpu-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <0>;
+-                      thermal-sensors = <&thermal 0>;
++                      thermal-sensors = <&thermal>;
+                       sustainable-power = <717>;
+                       cooling-maps {
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm64-fix-oops-in-concurrently-setting-insn_emulatio.patch b/queue-5.15/arm64-fix-oops-in-concurrently-setting-insn_emulatio.patch
new file mode 100644 (file)
index 0000000..c8a1d3b
--- /dev/null
@@ -0,0 +1,93 @@
+From 1a7c9ea7f617648ce1444b2c7dad34665133adc7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 2 Jul 2022 05:43:19 +0000
+Subject: arm64: fix oops in concurrently setting insn_emulation sysctls
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: haibinzhang (张海斌) <haibinzhang@tencent.com>
+
+[ Upstream commit af483947d472eccb79e42059276c4deed76f99a6 ]
+
+emulation_proc_handler() changes table->data for proc_dointvec_minmax
+and can generate the following Oops if called concurrently with itself:
+
+ | Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010
+ | Internal error: Oops: 96000006 [#1] SMP
+ | Call trace:
+ | update_insn_emulation_mode+0xc0/0x148
+ | emulation_proc_handler+0x64/0xb8
+ | proc_sys_call_handler+0x9c/0xf8
+ | proc_sys_write+0x18/0x20
+ | __vfs_write+0x20/0x48
+ | vfs_write+0xe4/0x1d0
+ | ksys_write+0x70/0xf8
+ | __arm64_sys_write+0x20/0x28
+ | el0_svc_common.constprop.0+0x7c/0x1c0
+ | el0_svc_handler+0x2c/0xa0
+ | el0_svc+0x8/0x200
+
+To fix this issue, keep the table->data as &insn->current_mode and
+use container_of() to retrieve the insn pointer. Another mutex is
+used to protect against the current_mode update but not for retrieving
+insn_emulation as table->data is no longer changing.
+
+Co-developed-by: hewenliang <hewenliang4@huawei.com>
+Signed-off-by: hewenliang <hewenliang4@huawei.com>
+Signed-off-by: Haibin Zhang <haibinzhang@tencent.com>
+Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
+Link: https://lore.kernel.org/r/20220128090324.2727688-1-hewenliang4@huawei.com
+Link: https://lore.kernel.org/r/9A004C03-250B-46C5-BF39-782D7551B00E@tencent.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/kernel/armv8_deprecated.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm64/kernel/armv8_deprecated.c b/arch/arm64/kernel/armv8_deprecated.c
+index 0e86e8b9cedd..c5da9d1e954a 100644
+--- a/arch/arm64/kernel/armv8_deprecated.c
++++ b/arch/arm64/kernel/armv8_deprecated.c
+@@ -59,6 +59,7 @@ struct insn_emulation {
+ static LIST_HEAD(insn_emulation);
+ static int nr_insn_emulated __initdata;
+ static DEFINE_RAW_SPINLOCK(insn_emulation_lock);
++static DEFINE_MUTEX(insn_emulation_mutex);
+ static void register_emulation_hooks(struct insn_emulation_ops *ops)
+ {
+@@ -207,10 +208,10 @@ static int emulation_proc_handler(struct ctl_table *table, int write,
+                                 loff_t *ppos)
+ {
+       int ret = 0;
+-      struct insn_emulation *insn = (struct insn_emulation *) table->data;
++      struct insn_emulation *insn = container_of(table->data, struct insn_emulation, current_mode);
+       enum insn_emulation_mode prev_mode = insn->current_mode;
+-      table->data = &insn->current_mode;
++      mutex_lock(&insn_emulation_mutex);
+       ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
+       if (ret || !write || prev_mode == insn->current_mode)
+@@ -223,7 +224,7 @@ static int emulation_proc_handler(struct ctl_table *table, int write,
+               update_insn_emulation_mode(insn, INSN_UNDEF);
+       }
+ ret:
+-      table->data = insn;
++      mutex_unlock(&insn_emulation_mutex);
+       return ret;
+ }
+@@ -247,7 +248,7 @@ static void __init register_insn_emulation_sysctl(void)
+               sysctl->maxlen = sizeof(int);
+               sysctl->procname = insn->ops->name;
+-              sysctl->data = insn;
++              sysctl->data = &insn->current_mode;
+               sysctl->extra1 = &insn->min;
+               sysctl->extra2 = &insn->max;
+               sysctl->proc_handler = emulation_proc_handler;
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm64-kasan-revert-arm64-mte-reset-the-page-tag-in-p.patch b/queue-5.15/arm64-kasan-revert-arm64-mte-reset-the-page-tag-in-p.patch
new file mode 100644 (file)
index 0000000..67ff729
--- /dev/null
@@ -0,0 +1,125 @@
+From 5c38cec415fe9b74fcf99bca4e4b3644790fe583 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jun 2022 16:21:41 +0100
+Subject: arm64: kasan: Revert "arm64: mte: reset the page tag in page->flags"
+
+From: Catalin Marinas <catalin.marinas@arm.com>
+
+[ Upstream commit 20794545c14692094a882d2221c251c4573e6adf ]
+
+This reverts commit e5b8d9218951e59df986f627ec93569a0d22149b.
+
+Pages mapped in user-space with PROT_MTE have the allocation tags either
+zeroed or copied/restored to some user values. In order for the kernel
+to access such pages via page_address(), resetting the tag in
+page->flags was necessary. This tag resetting was deferred to
+set_pte_at() -> mte_sync_page_tags() but it can race with another CPU
+reading the flags (via page_to_virt()):
+
+P0 (mte_sync_page_tags):       P1 (memcpy from virt_to_page):
+                                 Rflags!=0xff
+  Wflags=0xff
+  DMB (doesn't help)
+  Wtags=0
+                                 Rtags=0   // fault
+
+Since now the post_alloc_hook() function resets the page->flags tag when
+unpoisoning is skipped for user pages (including the __GFP_ZEROTAGS
+case), revert the arm64 commit calling page_kasan_tag_reset().
+
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Will Deacon <will@kernel.org>
+Cc: Vincenzo Frascino <vincenzo.frascino@arm.com>
+Cc: Andrey Konovalov <andreyknvl@gmail.com>
+Cc: Peter Collingbourne <pcc@google.com>
+Reviewed-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
+Acked-by: Andrey Konovalov <andreyknvl@gmail.com>
+Link: https://lore.kernel.org/r/20220610152141.2148929-5-catalin.marinas@arm.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/kernel/hibernate.c | 5 -----
+ arch/arm64/kernel/mte.c       | 9 ---------
+ arch/arm64/mm/copypage.c      | 9 ---------
+ arch/arm64/mm/mteswap.c       | 9 ---------
+ 4 files changed, 32 deletions(-)
+
+diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c
+index 46a0b4d6e251..db93ce2b0113 100644
+--- a/arch/arm64/kernel/hibernate.c
++++ b/arch/arm64/kernel/hibernate.c
+@@ -326,11 +326,6 @@ static void swsusp_mte_restore_tags(void)
+               unsigned long pfn = xa_state.xa_index;
+               struct page *page = pfn_to_online_page(pfn);
+-              /*
+-               * It is not required to invoke page_kasan_tag_reset(page)
+-               * at this point since the tags stored in page->flags are
+-               * already restored.
+-               */
+               mte_restore_page_tags(page_address(page), tags);
+               mte_free_tag_storage(tags);
+diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c
+index 7c1c82c8115c..10207e3e5ae2 100644
+--- a/arch/arm64/kernel/mte.c
++++ b/arch/arm64/kernel/mte.c
+@@ -44,15 +44,6 @@ static void mte_sync_page_tags(struct page *page, pte_t old_pte,
+       if (!pte_is_tagged)
+               return;
+-      page_kasan_tag_reset(page);
+-      /*
+-       * We need smp_wmb() in between setting the flags and clearing the
+-       * tags because if another thread reads page->flags and builds a
+-       * tagged address out of it, there is an actual dependency to the
+-       * memory access, but on the current thread we do not guarantee that
+-       * the new page->flags are visible before the tags were updated.
+-       */
+-      smp_wmb();
+       mte_clear_page_tags(page_address(page));
+ }
+diff --git a/arch/arm64/mm/copypage.c b/arch/arm64/mm/copypage.c
+index 0dea80bf6de4..24913271e898 100644
+--- a/arch/arm64/mm/copypage.c
++++ b/arch/arm64/mm/copypage.c
+@@ -23,15 +23,6 @@ void copy_highpage(struct page *to, struct page *from)
+       if (system_supports_mte() && test_bit(PG_mte_tagged, &from->flags)) {
+               set_bit(PG_mte_tagged, &to->flags);
+-              page_kasan_tag_reset(to);
+-              /*
+-               * We need smp_wmb() in between setting the flags and clearing the
+-               * tags because if another thread reads page->flags and builds a
+-               * tagged address out of it, there is an actual dependency to the
+-               * memory access, but on the current thread we do not guarantee that
+-               * the new page->flags are visible before the tags were updated.
+-               */
+-              smp_wmb();
+               mte_copy_page_tags(kto, kfrom);
+       }
+ }
+diff --git a/arch/arm64/mm/mteswap.c b/arch/arm64/mm/mteswap.c
+index 7c4ef56265ee..c52c1847079c 100644
+--- a/arch/arm64/mm/mteswap.c
++++ b/arch/arm64/mm/mteswap.c
+@@ -53,15 +53,6 @@ bool mte_restore_tags(swp_entry_t entry, struct page *page)
+       if (!tags)
+               return false;
+-      page_kasan_tag_reset(page);
+-      /*
+-       * We need smp_wmb() in between setting the flags and clearing the
+-       * tags because if another thread reads page->flags and builds a
+-       * tagged address out of it, there is an actual dependency to the
+-       * memory access, but on the current thread we do not guarantee that
+-       * the new page->flags are visible before the tags were updated.
+-       */
+-      smp_wmb();
+       mte_restore_page_tags(page_address(page), tags);
+       return true;
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm64-select-trace_irqflags_nmi_support.patch b/queue-5.15/arm64-select-trace_irqflags_nmi_support.patch
new file mode 100644 (file)
index 0000000..85e6dc3
--- /dev/null
@@ -0,0 +1,158 @@
+From d88c694ad5182290373703feb1123b441cee7686 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 May 2022 14:17:33 +0100
+Subject: arm64: select TRACE_IRQFLAGS_NMI_SUPPORT
+
+From: Mark Rutland <mark.rutland@arm.com>
+
+[ Upstream commit 3381da254fab37ba08c4b7c4f19b4ee28b1a27ec ]
+
+Due to an oversight, on arm64 lockdep IRQ state tracking doesn't work as
+intended in NMI context. This demonstrably results in bogus warnings
+from lockdep, and in theory could mask a variety of issues.
+
+On arm64, we've consistently tracked IRQ flag state for NMIs (and
+saved/restored the state of the interrupted context) since commit:
+
+  f0cd5ac1e4c53cb6 ("arm64: entry: fix NMI {user, kernel}->kernel transitions")
+
+That commit fixed most lockdep issues with NMI by virtue of the
+save/restore of the lockdep state of the interrupted context. However,
+for lockdep IRQ state tracking to consistently take effect in NMI
+context it has been necessary to select TRACE_IRQFLAGS_NMI_SUPPORT since
+commit:
+
+  ed00495333ccc80f ("locking/lockdep: Fix TRACE_IRQFLAGS vs. NMIs")
+
+As arm64 does not select TRACE_IRQFLAGS_NMI_SUPPORT, this means that the
+lockdep state can be stale in NMI context, and some uses of that state
+can consume stale data.
+
+When an NMI is taken arm64 entry code will call arm64_enter_nmi(). This
+will enter NMI context via __nmi_enter() before calling
+lockdep_hardirqs_off() to inform lockdep that IRQs have been masked.
+Where TRACE_IRQFLAGS_NMI_SUPPORT is not selected, lockdep_hardirqs_off()
+will not update lockdep state if called in NMI context. Thus if IRQs
+were enabled in the original context, lockdep will continue to believe
+that IRQs are enabled despite the call to lockdep_hardirqs_off().
+
+However, the lockdep_assert_*() checks do take effect in NMI context,
+and will consume the stale lockdep state. If an NMI is taken from a
+context which had IRQs enabled, and during the handling of the NMI
+something calls lockdep_assert_irqs_disabled(), this will result in a
+spurious warning based upon the stale lockdep state.
+
+This can be seen when using perf with GICv3 pseudo-NMIs. Within the perf
+NMI handler we may attempt a uaccess to record the userspace callchain,
+and is this faults the el1_abort() call in the nested context will call
+exit_to_kernel_mode() when returning, which has a
+lockdep_assert_irqs_disabled() assertion:
+
+| # ./perf record -a -g sh
+| ------------[ cut here ]------------
+| WARNING: CPU: 0 PID: 164 at arch/arm64/kernel/entry-common.c:73 exit_to_kernel_mode+0x118/0x1ac
+| Modules linked in:
+| CPU: 0 PID: 164 Comm: perf Not tainted 5.18.0-rc5 #1
+| Hardware name: linux,dummy-virt (DT)
+| pstate: 004003c5 (nzcv DAIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+| pc : exit_to_kernel_mode+0x118/0x1ac
+| lr : el1_abort+0x80/0xbc
+| sp : ffff8000080039f0
+| pmr_save: 000000f0
+| x29: ffff8000080039f0 x28: ffff6831054e4980 x27: ffff683103adb400
+| x26: 0000000000000000 x25: 0000000000000001 x24: 0000000000000001
+| x23: 00000000804000c5 x22: 00000000000000c0 x21: 0000000000000001
+| x20: ffffbd51e635ec44 x19: ffff800008003a60 x18: 0000000000000000
+| x17: ffffaadf98d23000 x16: ffff800008004000 x15: 0000ffffd14f25c0
+| x14: 0000000000000000 x13: 00000000000018eb x12: 0000000000000040
+| x11: 000000000000001e x10: 000000002b820020 x9 : 0000000100110000
+| x8 : 000000000045cac0 x7 : 0000ffffd14f25c0 x6 : ffffbd51e639b000
+| x5 : 00000000000003e5 x4 : ffffbd51e58543b0 x3 : 0000000000000001
+| x2 : ffffaadf98d23000 x1 : ffff6831054e4980 x0 : 0000000100110000
+| Call trace:
+|  exit_to_kernel_mode+0x118/0x1ac
+|  el1_abort+0x80/0xbc
+|  el1h_64_sync_handler+0xa4/0xd0
+|  el1h_64_sync+0x74/0x78
+|  __arch_copy_from_user+0xa4/0x230
+|  get_perf_callchain+0x134/0x1e4
+|  perf_callchain+0x7c/0xa0
+|  perf_prepare_sample+0x414/0x660
+|  perf_event_output_forward+0x80/0x180
+|  __perf_event_overflow+0x70/0x13c
+|  perf_event_overflow+0x1c/0x30
+|  armv8pmu_handle_irq+0xe8/0x160
+|  armpmu_dispatch_irq+0x2c/0x70
+|  handle_percpu_devid_fasteoi_nmi+0x7c/0xbc
+|  generic_handle_domain_nmi+0x3c/0x60
+|  gic_handle_irq+0x1dc/0x310
+|  call_on_irq_stack+0x2c/0x54
+|  do_interrupt_handler+0x80/0x94
+|  el1_interrupt+0xb0/0xe4
+|  el1h_64_irq_handler+0x18/0x24
+|  el1h_64_irq+0x74/0x78
+|  lockdep_hardirqs_off+0x50/0x120
+|  trace_hardirqs_off+0x38/0x214
+|  _raw_spin_lock_irq+0x98/0xa0
+|  pipe_read+0x1f8/0x404
+|  new_sync_read+0x140/0x150
+|  vfs_read+0x190/0x1dc
+|  ksys_read+0xdc/0xfc
+|  __arm64_sys_read+0x20/0x30
+|  invoke_syscall+0x48/0x114
+|  el0_svc_common.constprop.0+0x158/0x17c
+|  do_el0_svc+0x28/0x90
+|  el0_svc+0x60/0x150
+|  el0t_64_sync_handler+0xa4/0x130
+|  el0t_64_sync+0x19c/0x1a0
+| irq event stamp: 483
+| hardirqs last  enabled at (483): [<ffffbd51e636aa24>] _raw_spin_unlock_irqrestore+0xa4/0xb0
+| hardirqs last disabled at (482): [<ffffbd51e636acd0>] _raw_spin_lock_irqsave+0xb0/0xb4
+| softirqs last  enabled at (468): [<ffffbd51e5216f58>] put_cpu_fpsimd_context+0x28/0x70
+| softirqs last disabled at (466): [<ffffbd51e5216ed4>] get_cpu_fpsimd_context+0x0/0x5c
+| ---[ end trace 0000000000000000 ]---
+
+Note that as lockdep_assert_irqs_disabled() uses WARN_ON_ONCE(), and
+this uses a BRK, the warning is logged with the real PSTATE at the time
+of the warning, which clearly has DAIF.I set, meaning IRQs (and
+pseudo-NMIs) were definitely masked and the warning is spurious.
+
+Fix this by selecting TRACE_IRQFLAGS_NMI_SUPPORT such that the existing
+entry tracking takes effect, as we had originally intended when the
+arm64 entry code was fixed for transitions to/from NMI.
+
+Arguably the lockdep_assert_*() functions should have the same NMI
+checks as the rest of the code to prevent spurious warnings when
+TRACE_IRQFLAGS_NMI_SUPPORT is not selected, but the real fix for any
+architecture is to explicitly handle the transitions to/from NMI in the
+entry code.
+
+Fixes: f0cd5ac1e4c5 ("arm64: entry: fix NMI {user, kernel}->kernel transitions")
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Will Deacon <will@kernel.org>
+Link: https://lore.kernel.org/r/20220511131733.4074499-3-mark.rutland@arm.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
+index 8b6f090e0364..69e7e293f72e 100644
+--- a/arch/arm64/Kconfig
++++ b/arch/arm64/Kconfig
+@@ -220,6 +220,7 @@ config ARM64
+       select THREAD_INFO_IN_TASK
+       select HAVE_ARCH_USERFAULTFD_MINOR if USERFAULTFD
+       select TRACE_IRQFLAGS_SUPPORT
++      select TRACE_IRQFLAGS_NMI_SUPPORT
+       help
+         ARM 64-bit (AArch64) Linux support.
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm64-tegra-fix-sdmmc1-cd-on-p2888.patch b/queue-5.15/arm64-tegra-fix-sdmmc1-cd-on-p2888.patch
new file mode 100644 (file)
index 0000000..f2295e3
--- /dev/null
@@ -0,0 +1,39 @@
+From 7c274492e6ed97c49441ce21bf32b643c83cc905 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jun 2022 14:59:45 +0000
+Subject: arm64: tegra: Fix SDMMC1 CD on P2888
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Tamás Szűcs <tszucs@protonmail.ch>
+
+[ Upstream commit b415bb7c976f1d595ed752001c0938f702645dab ]
+
+Hook SDMMC1 CD up with CVM GPIO02 (SOC_GPIO11) used for card detection on J4
+(uSD socket) on the carrier.
+
+Fixes: ef633bfc21e9 ("arm64: tegra: Enable card detect for SD card on P2888")
+Signed-off-by: Tamás Szűcs <tszucs@protonmail.ch>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi b/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi
+index c4058ee36fec..1a444705517f 100644
+--- a/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi
+@@ -75,7 +75,7 @@ eeprom@50 {
+               /* SDMMC1 (SD/MMC) */
+               mmc@3400000 {
+-                      cd-gpios = <&gpio TEGRA194_MAIN_GPIO(A, 0) GPIO_ACTIVE_LOW>;
++                      cd-gpios = <&gpio TEGRA194_MAIN_GPIO(G, 7) GPIO_ACTIVE_LOW>;
+               };
+               /* SDMMC4 (eMMC) */
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm64-tegra-fixup-sysram-references.patch b/queue-5.15/arm64-tegra-fixup-sysram-references.patch
new file mode 100644 (file)
index 0000000..257ae0c
--- /dev/null
@@ -0,0 +1,90 @@
+From 0e9d4e8e1a618b331002c0b4f2a127d47713c8ca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Nov 2021 13:35:37 +0100
+Subject: arm64: tegra: Fixup SYSRAM references
+
+From: Thierry Reding <treding@nvidia.com>
+
+[ Upstream commit 7fa307524a4d721d4a04523018509882c5414e72 ]
+
+The json-schema bindings for SRAM expect the nodes to be called "sram"
+rather than "sysram" or "shmem". Furthermore, place the brackets around
+the SYSRAM references such that a two-element array is created rather
+than a two-element array nested in a single-element array. This is not
+relevant for device tree itself, but allows the nodes to be properly
+validated against json-schema bindings.
+
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/nvidia/tegra186.dtsi | 2 +-
+ arch/arm64/boot/dts/nvidia/tegra194.dtsi | 2 +-
+ arch/arm64/boot/dts/nvidia/tegra234.dtsi | 8 ++++----
+ 3 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
+index 062e87e89331..8354512d7b1c 100644
+--- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
+@@ -1635,7 +1635,7 @@ bpmp: bpmp {
+               iommus = <&smmu TEGRA186_SID_BPMP>;
+               mboxes = <&hsp_top0 TEGRA_HSP_MBOX_TYPE_DB
+                                   TEGRA_HSP_DB_MASTER_BPMP>;
+-              shmem = <&cpu_bpmp_tx &cpu_bpmp_rx>;
++              shmem = <&cpu_bpmp_tx>, <&cpu_bpmp_rx>;
+               #clock-cells = <1>;
+               #reset-cells = <1>;
+               #power-domain-cells = <1>;
+diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
+index 510d2974470c..a56fb83839a4 100644
+--- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
+@@ -2267,7 +2267,7 @@ bpmp: bpmp {
+               compatible = "nvidia,tegra186-bpmp";
+               mboxes = <&hsp_top0 TEGRA_HSP_MBOX_TYPE_DB
+                                   TEGRA_HSP_DB_MASTER_BPMP>;
+-              shmem = <&cpu_bpmp_tx &cpu_bpmp_rx>;
++              shmem = <&cpu_bpmp_tx>, <&cpu_bpmp_rx>;
+               #clock-cells = <1>;
+               #reset-cells = <1>;
+               #power-domain-cells = <1>;
+diff --git a/arch/arm64/boot/dts/nvidia/tegra234.dtsi b/arch/arm64/boot/dts/nvidia/tegra234.dtsi
+index f0efb3a62804..28961ed31d87 100644
+--- a/arch/arm64/boot/dts/nvidia/tegra234.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra234.dtsi
+@@ -122,20 +122,20 @@ gic: interrupt-controller@f400000 {
+               };
+       };
+-      sysram@40000000 {
++      sram@40000000 {
+               compatible = "nvidia,tegra234-sysram", "mmio-sram";
+               reg = <0x0 0x40000000 0x0 0x50000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0x0 0x0 0x40000000 0x50000>;
+-              cpu_bpmp_tx: shmem@4e000 {
++              cpu_bpmp_tx: sram@4e000 {
+                       reg = <0x4e000 0x1000>;
+                       label = "cpu-bpmp-tx";
+                       pool;
+               };
+-              cpu_bpmp_rx: shmem@4f000 {
++              cpu_bpmp_rx: sram@4f000 {
+                       reg = <0x4f000 0x1000>;
+                       label = "cpu-bpmp-rx";
+                       pool;
+@@ -146,7 +146,7 @@ bpmp: bpmp {
+               compatible = "nvidia,tegra234-bpmp", "nvidia,tegra186-bpmp";
+               mboxes = <&hsp_top0 TEGRA_HSP_MBOX_TYPE_DB
+                                   TEGRA_HSP_DB_MASTER_BPMP>;
+-              shmem = <&cpu_bpmp_tx &cpu_bpmp_rx>;
++              shmem = <&cpu_bpmp_tx>, <&cpu_bpmp_rx>;
+               #clock-cells = <1>;
+               #reset-cells = <1>;
+               #power-domain-cells = <1>;
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm64-tegra-mark-bpmp-channels-as-no-memory-wc.patch b/queue-5.15/arm64-tegra-mark-bpmp-channels-as-no-memory-wc.patch
new file mode 100644 (file)
index 0000000..1a37f26
--- /dev/null
@@ -0,0 +1,78 @@
+From 8c18184b4cd81146f381462563e4277de056c2fa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jun 2022 16:23:00 +0300
+Subject: arm64: tegra: Mark BPMP channels as no-memory-wc
+
+From: Mikko Perttunen <mperttunen@nvidia.com>
+
+[ Upstream commit 61192a9d8a6367ae1b8234876941b037910a2459 ]
+
+The Tegra SYSRAM contains regions access to which is restricted to
+certain hardware blocks on the system, and speculative accesses to
+those will cause issues.
+
+Patch 'misc: sram: Only map reserved areas in Tegra SYSRAM' attempted
+to resolve this by only mapping the regions specified in the device
+tree on the assumption that there are no such restricted areas within
+the 64K-aligned area of memory that contains the memory we wish to map.
+
+Turns out this assumption is wrong, as there are such areas above the
+4K pages described in the device trees. As such, we need to use the
+bigger hammer that is no-memory-wc, which causes the memory to be
+mapped as Device memory to which speculative accesses are disallowed.
+
+As such, the previous patch in the series,
+  'firmware: tegra: bpmp: do only aligned access to IPC memory area',
+is required with this patch to make the BPMP driver only issue aligned
+memory accesses as those are also required with Device memory.
+
+Fixes: fec29bf04994 ("misc: sram: Only map reserved areas in Tegra SYSRAM")
+Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
+Reviewed-by: Yousaf Kaukab <ykaukab@suse.de>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/nvidia/tegra186.dtsi | 1 +
+ arch/arm64/boot/dts/nvidia/tegra194.dtsi | 1 +
+ arch/arm64/boot/dts/nvidia/tegra234.dtsi | 1 +
+ 3 files changed, 3 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
+index 8354512d7b1c..5b0bc9aa1a42 100644
+--- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
+@@ -1583,6 +1583,7 @@ sram@30000000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0x0 0x0 0x30000000 0x50000>;
++              no-memory-wc;
+               cpu_bpmp_tx: sram@4e000 {
+                       reg = <0x4e000 0x1000>;
+diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
+index a56fb83839a4..ca71b71d801a 100644
+--- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
+@@ -2249,6 +2249,7 @@ sram@40000000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0x0 0x0 0x40000000 0x50000>;
++              no-memory-wc;
+               cpu_bpmp_tx: sram@4e000 {
+                       reg = <0x4e000 0x1000>;
+diff --git a/arch/arm64/boot/dts/nvidia/tegra234.dtsi b/arch/arm64/boot/dts/nvidia/tegra234.dtsi
+index 144a7eb699a7..2b4784572220 100644
+--- a/arch/arm64/boot/dts/nvidia/tegra234.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra234.dtsi
+@@ -128,6 +128,7 @@ sram@40000000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0x0 0x0 0x40000000 0x80000>;
++              no-memory-wc;
+               cpu_bpmp_tx: sram@70000 {
+                       reg = <0x70000 0x1000>;
+-- 
+2.35.1
+
diff --git a/queue-5.15/arm64-tegra-update-tegra234-bpmp-channel-addresses.patch b/queue-5.15/arm64-tegra-update-tegra234-bpmp-channel-addresses.patch
new file mode 100644 (file)
index 0000000..b9b670c
--- /dev/null
@@ -0,0 +1,52 @@
+From aae3accb856098e0927b025633ceefc2c1856d44 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Nov 2021 13:35:39 +0100
+Subject: arm64: tegra: Update Tegra234 BPMP channel addresses
+
+From: Mikko Perttunen <mperttunen@nvidia.com>
+
+[ Upstream commit 98094be152d34f8014ca67fbdc210e5261c4b09d ]
+
+On final Tegra234 systems, shared memory for communication with BPMP is
+located at offset 0x70000 in SYSRAM.
+
+Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/nvidia/tegra234.dtsi | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/nvidia/tegra234.dtsi b/arch/arm64/boot/dts/nvidia/tegra234.dtsi
+index 28961ed31d87..144a7eb699a7 100644
+--- a/arch/arm64/boot/dts/nvidia/tegra234.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra234.dtsi
+@@ -124,19 +124,19 @@ gic: interrupt-controller@f400000 {
+       sram@40000000 {
+               compatible = "nvidia,tegra234-sysram", "mmio-sram";
+-              reg = <0x0 0x40000000 0x0 0x50000>;
++              reg = <0x0 0x40000000 0x0 0x80000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+-              ranges = <0x0 0x0 0x40000000 0x50000>;
++              ranges = <0x0 0x0 0x40000000 0x80000>;
+-              cpu_bpmp_tx: sram@4e000 {
+-                      reg = <0x4e000 0x1000>;
++              cpu_bpmp_tx: sram@70000 {
++                      reg = <0x70000 0x1000>;
+                       label = "cpu-bpmp-tx";
+                       pool;
+               };
+-              cpu_bpmp_rx: sram@4f000 {
+-                      reg = <0x4f000 0x1000>;
++              cpu_bpmp_rx: sram@71000 {
++                      reg = <0x71000 0x1000>;
+                       label = "cpu-bpmp-rx";
+                       pool;
+               };
+-- 
+2.35.1
+
diff --git a/queue-5.15/asoc-audio-graph-card-add-of_node_put-in-fail-path.patch b/queue-5.15/asoc-audio-graph-card-add-of_node_put-in-fail-path.patch
new file mode 100644 (file)
index 0000000..3769a69
--- /dev/null
@@ -0,0 +1,40 @@
+From b94cfe87b7c3986c90e0a1a643bd77783a02839a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Jul 2022 22:43:08 +0800
+Subject: ASoC: audio-graph-card: Add of_node_put() in fail path
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 65fb8e2ef3531a6e950060fca6e551c923fb0f0e ]
+
+In asoc_simple_parse_dai(), we should call of_node_put() for the
+reference returned by of_graph_get_port_parent() in fail path.
+
+Fixes: ae30a694da4c ("ASoC: simple-card-utils: add asoc_simple_card_parse_dai()")
+Signed-off-by: Liang He <windhl@126.com>
+Link: https://lore.kernel.org/r/20220721144308.1301587-1-windhl@126.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/generic/audio-graph-card.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c
+index 546f6fd0609e..28cbcdb56857 100644
+--- a/sound/soc/generic/audio-graph-card.c
++++ b/sound/soc/generic/audio-graph-card.c
+@@ -158,8 +158,10 @@ static int asoc_simple_parse_dai(struct device_node *ep,
+        *    if he unbinded CPU or Codec.
+        */
+       ret = snd_soc_get_dai_name(&args, &dlc->dai_name);
+-      if (ret < 0)
++      if (ret < 0) {
++              of_node_put(node);
+               return ret;
++      }
+       dlc->of_node = node;
+-- 
+2.35.1
+
diff --git a/queue-5.15/asoc-codecs-da7210-add-check-for-i2c_add_driver.patch b/queue-5.15/asoc-codecs-da7210-add-check-for-i2c_add_driver.patch
new file mode 100644 (file)
index 0000000..d183073
--- /dev/null
@@ -0,0 +1,41 @@
+From 12d517fa94044a46dfd47692a2f28c1d3f9d4ab0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 31 May 2022 17:47:12 +0800
+Subject: ASoC: codecs: da7210: add check for i2c_add_driver
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit 82fa8f581a954ddeec1602bed9f8b4a09d100e6e ]
+
+As i2c_add_driver could return error if fails, it should be
+better to check the return value.
+However, if the CONFIG_I2C and CONFIG_SPI_MASTER are both true,
+the return value of i2c_add_driver will be covered by
+spi_register_driver.
+Therefore, it is necessary to add check and return error if fails.
+
+Fixes: aa0e25caafb7 ("ASoC: da7210: Add support for spi regmap")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Link: https://lore.kernel.org/r/20220531094712.2376759-1-jiasheng@iscas.ac.cn
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/da7210.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
+index 8af344b2fdbf..d75d15006f64 100644
+--- a/sound/soc/codecs/da7210.c
++++ b/sound/soc/codecs/da7210.c
+@@ -1336,6 +1336,8 @@ static int __init da7210_modinit(void)
+       int ret = 0;
+ #if IS_ENABLED(CONFIG_I2C)
+       ret = i2c_add_driver(&da7210_i2c_driver);
++      if (ret)
++              return ret;
+ #endif
+ #if defined(CONFIG_SPI_MASTER)
+       ret = spi_register_driver(&da7210_spi_driver);
+-- 
+2.35.1
+
diff --git a/queue-5.15/asoc-codecs-msm8916-wcd-digital-move-gains-from-sx_t.patch b/queue-5.15/asoc-codecs-msm8916-wcd-digital-move-gains-from-sx_t.patch
new file mode 100644 (file)
index 0000000..83252b4
--- /dev/null
@@ -0,0 +1,102 @@
+From ce19e85d01e2e5d92ca19b31dbbf77d25f4084af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jun 2022 12:19:00 +0100
+Subject: ASoC: codecs: msm8916-wcd-digital: move gains from SX_TLV to S8_TLV
+
+From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+
+[ Upstream commit 5babb012c847beb6c8c7108fd78f650b7a2c6054 ]
+
+move all the digital gains form using SX_TLV to S8_TLV, these gains are
+actually 8 bit gains with 7th signed bit and ranges from -84dB to +40dB
+
+rest of the Qualcomm wcd codecs uses these properly.
+
+Fixes: ef8a4757a6db ("ASoC: msm8916-wcd-digital: Add sidetone support")
+Fixes: 150db8c5afa1 ("ASoC: codecs: Add msm8916-wcd digital codec")
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20220609111901.318047-2-srinivas.kandagatla@linaro.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/msm8916-wcd-digital.c | 46 +++++++++++++-------------
+ 1 file changed, 23 insertions(+), 23 deletions(-)
+
+diff --git a/sound/soc/codecs/msm8916-wcd-digital.c b/sound/soc/codecs/msm8916-wcd-digital.c
+index 20a07c92b2fc..098a58990f07 100644
+--- a/sound/soc/codecs/msm8916-wcd-digital.c
++++ b/sound/soc/codecs/msm8916-wcd-digital.c
+@@ -328,8 +328,8 @@ static const struct snd_kcontrol_new rx1_mix2_inp1_mux = SOC_DAPM_ENUM(
+ static const struct snd_kcontrol_new rx2_mix2_inp1_mux = SOC_DAPM_ENUM(
+                               "RX2 MIX2 INP1 Mux", rx2_mix2_inp1_chain_enum);
+-/* Digital Gain control -38.4 dB to +38.4 dB in 0.3 dB steps */
+-static const DECLARE_TLV_DB_SCALE(digital_gain, -3840, 30, 0);
++/* Digital Gain control -84 dB to +40 dB in 1 dB steps */
++static const DECLARE_TLV_DB_SCALE(digital_gain, -8400, 100, -8400);
+ /* Cutoff Freq for High Pass Filter at -3dB */
+ static const char * const hpf_cutoff_text[] = {
+@@ -510,15 +510,15 @@ static int wcd_iir_filter_info(struct snd_kcontrol *kcontrol,
+ static const struct snd_kcontrol_new msm8916_wcd_digital_snd_controls[] = {
+       SOC_SINGLE_S8_TLV("RX1 Digital Volume", LPASS_CDC_RX1_VOL_CTL_B2_CTL,
+-                        -128, 127, digital_gain),
++                      -84, 40, digital_gain),
+       SOC_SINGLE_S8_TLV("RX2 Digital Volume", LPASS_CDC_RX2_VOL_CTL_B2_CTL,
+-                        -128, 127, digital_gain),
++                      -84, 40, digital_gain),
+       SOC_SINGLE_S8_TLV("RX3 Digital Volume", LPASS_CDC_RX3_VOL_CTL_B2_CTL,
+-                        -128, 127, digital_gain),
++                      -84, 40, digital_gain),
+       SOC_SINGLE_S8_TLV("TX1 Digital Volume", LPASS_CDC_TX1_VOL_CTL_GAIN,
+-                        -128, 127, digital_gain),
++                      -84, 40, digital_gain),
+       SOC_SINGLE_S8_TLV("TX2 Digital Volume", LPASS_CDC_TX2_VOL_CTL_GAIN,
+-                        -128, 127, digital_gain),
++                      -84, 40, digital_gain),
+       SOC_ENUM("TX1 HPF Cutoff", tx1_hpf_cutoff_enum),
+       SOC_ENUM("TX2 HPF Cutoff", tx2_hpf_cutoff_enum),
+       SOC_SINGLE("TX1 HPF Switch", LPASS_CDC_TX1_MUX_CTL, 3, 1, 0),
+@@ -553,22 +553,22 @@ static const struct snd_kcontrol_new msm8916_wcd_digital_snd_controls[] = {
+       WCD_IIR_FILTER_CTL("IIR2 Band3", IIR2, BAND3),
+       WCD_IIR_FILTER_CTL("IIR2 Band4", IIR2, BAND4),
+       WCD_IIR_FILTER_CTL("IIR2 Band5", IIR2, BAND5),
+-      SOC_SINGLE_SX_TLV("IIR1 INP1 Volume", LPASS_CDC_IIR1_GAIN_B1_CTL,
+-                      0,  -84, 40, digital_gain),
+-      SOC_SINGLE_SX_TLV("IIR1 INP2 Volume", LPASS_CDC_IIR1_GAIN_B2_CTL,
+-                      0,  -84, 40, digital_gain),
+-      SOC_SINGLE_SX_TLV("IIR1 INP3 Volume", LPASS_CDC_IIR1_GAIN_B3_CTL,
+-                      0,  -84, 40, digital_gain),
+-      SOC_SINGLE_SX_TLV("IIR1 INP4 Volume", LPASS_CDC_IIR1_GAIN_B4_CTL,
+-                      0,  -84,        40, digital_gain),
+-      SOC_SINGLE_SX_TLV("IIR2 INP1 Volume", LPASS_CDC_IIR2_GAIN_B1_CTL,
+-                      0,  -84, 40, digital_gain),
+-      SOC_SINGLE_SX_TLV("IIR2 INP2 Volume", LPASS_CDC_IIR2_GAIN_B2_CTL,
+-                      0,  -84, 40, digital_gain),
+-      SOC_SINGLE_SX_TLV("IIR2 INP3 Volume", LPASS_CDC_IIR2_GAIN_B3_CTL,
+-                      0,  -84, 40, digital_gain),
+-      SOC_SINGLE_SX_TLV("IIR2 INP4 Volume", LPASS_CDC_IIR2_GAIN_B4_CTL,
+-                      0,  -84, 40, digital_gain),
++      SOC_SINGLE_S8_TLV("IIR1 INP1 Volume", LPASS_CDC_IIR1_GAIN_B1_CTL,
++                      -84, 40, digital_gain),
++      SOC_SINGLE_S8_TLV("IIR1 INP2 Volume", LPASS_CDC_IIR1_GAIN_B2_CTL,
++                      -84, 40, digital_gain),
++      SOC_SINGLE_S8_TLV("IIR1 INP3 Volume", LPASS_CDC_IIR1_GAIN_B3_CTL,
++                      -84, 40, digital_gain),
++      SOC_SINGLE_S8_TLV("IIR1 INP4 Volume", LPASS_CDC_IIR1_GAIN_B4_CTL,
++                      -84, 40, digital_gain),
++      SOC_SINGLE_S8_TLV("IIR2 INP1 Volume", LPASS_CDC_IIR2_GAIN_B1_CTL,
++                      -84, 40, digital_gain),
++      SOC_SINGLE_S8_TLV("IIR2 INP2 Volume", LPASS_CDC_IIR2_GAIN_B2_CTL,
++                      -84, 40, digital_gain),
++      SOC_SINGLE_S8_TLV("IIR2 INP3 Volume", LPASS_CDC_IIR2_GAIN_B3_CTL,
++                      -84, 40, digital_gain),
++      SOC_SINGLE_S8_TLV("IIR2 INP4 Volume", LPASS_CDC_IIR2_GAIN_B4_CTL,
++                      -84, 40, digital_gain),
+ };
+-- 
+2.35.1
+
diff --git a/queue-5.15/asoc-codecs-wcd9335-move-gains-from-sx_tlv-to-s8_tlv.patch b/queue-5.15/asoc-codecs-wcd9335-move-gains-from-sx_tlv-to-s8_tlv.patch
new file mode 100644 (file)
index 0000000..bfb8b8b
--- /dev/null
@@ -0,0 +1,118 @@
+From 544dbcbc2fd49f471fc0f5d22da4caac4920c5b2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jun 2022 12:19:01 +0100
+Subject: ASoC: codecs: wcd9335: move gains from SX_TLV to S8_TLV
+
+From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+
+[ Upstream commit 2fbe0953732e06b471cdedbf6f615b84235580d8 ]
+
+move all the digital gains form using SX_TLV to S8_TLV, these gains are
+actually 8 bit gains with 7th signed bit and ranges from -84dB to +40dB
+
+rest of the Qualcomm wcd codecs uses these properly.
+
+Fixes: 8c4f021d806a ("ASoC: wcd9335: add basic controls")
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20220609111901.318047-3-srinivas.kandagatla@linaro.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/wcd9335.c | 81 +++++++++++++++++---------------------
+ 1 file changed, 36 insertions(+), 45 deletions(-)
+
+diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c
+index bc5d68c53e5a..3a13afbfb74b 100644
+--- a/sound/soc/codecs/wcd9335.c
++++ b/sound/soc/codecs/wcd9335.c
+@@ -2252,51 +2252,42 @@ static int wcd9335_rx_hph_mode_put(struct snd_kcontrol *kc,
+ static const struct snd_kcontrol_new wcd9335_snd_controls[] = {
+       /* -84dB min - 40dB max */
+-      SOC_SINGLE_SX_TLV("RX0 Digital Volume", WCD9335_CDC_RX0_RX_VOL_CTL,
+-              0, -84, 40, digital_gain),
+-      SOC_SINGLE_SX_TLV("RX1 Digital Volume", WCD9335_CDC_RX1_RX_VOL_CTL,
+-              0, -84, 40, digital_gain),
+-      SOC_SINGLE_SX_TLV("RX2 Digital Volume", WCD9335_CDC_RX2_RX_VOL_CTL,
+-              0, -84, 40, digital_gain),
+-      SOC_SINGLE_SX_TLV("RX3 Digital Volume", WCD9335_CDC_RX3_RX_VOL_CTL,
+-              0, -84, 40, digital_gain),
+-      SOC_SINGLE_SX_TLV("RX4 Digital Volume", WCD9335_CDC_RX4_RX_VOL_CTL,
+-              0, -84, 40, digital_gain),
+-      SOC_SINGLE_SX_TLV("RX5 Digital Volume", WCD9335_CDC_RX5_RX_VOL_CTL,
+-              0, -84, 40, digital_gain),
+-      SOC_SINGLE_SX_TLV("RX6 Digital Volume", WCD9335_CDC_RX6_RX_VOL_CTL,
+-              0, -84, 40, digital_gain),
+-      SOC_SINGLE_SX_TLV("RX7 Digital Volume", WCD9335_CDC_RX7_RX_VOL_CTL,
+-              0, -84, 40, digital_gain),
+-      SOC_SINGLE_SX_TLV("RX8 Digital Volume", WCD9335_CDC_RX8_RX_VOL_CTL,
+-              0, -84, 40, digital_gain),
+-      SOC_SINGLE_SX_TLV("RX0 Mix Digital Volume",
+-                        WCD9335_CDC_RX0_RX_VOL_MIX_CTL,
+-                        0, -84, 40, digital_gain),
+-      SOC_SINGLE_SX_TLV("RX1 Mix Digital Volume",
+-                        WCD9335_CDC_RX1_RX_VOL_MIX_CTL,
+-                        0, -84, 40, digital_gain),
+-      SOC_SINGLE_SX_TLV("RX2 Mix Digital Volume",
+-                        WCD9335_CDC_RX2_RX_VOL_MIX_CTL,
+-                        0, -84, 40, digital_gain),
+-      SOC_SINGLE_SX_TLV("RX3 Mix Digital Volume",
+-                        WCD9335_CDC_RX3_RX_VOL_MIX_CTL,
+-                        0, -84, 40, digital_gain),
+-      SOC_SINGLE_SX_TLV("RX4 Mix Digital Volume",
+-                        WCD9335_CDC_RX4_RX_VOL_MIX_CTL,
+-                        0, -84, 40, digital_gain),
+-      SOC_SINGLE_SX_TLV("RX5 Mix Digital Volume",
+-                        WCD9335_CDC_RX5_RX_VOL_MIX_CTL,
+-                        0, -84, 40, digital_gain),
+-      SOC_SINGLE_SX_TLV("RX6 Mix Digital Volume",
+-                        WCD9335_CDC_RX6_RX_VOL_MIX_CTL,
+-                        0, -84, 40, digital_gain),
+-      SOC_SINGLE_SX_TLV("RX7 Mix Digital Volume",
+-                        WCD9335_CDC_RX7_RX_VOL_MIX_CTL,
+-                        0, -84, 40, digital_gain),
+-      SOC_SINGLE_SX_TLV("RX8 Mix Digital Volume",
+-                        WCD9335_CDC_RX8_RX_VOL_MIX_CTL,
+-                        0, -84, 40, digital_gain),
++      SOC_SINGLE_S8_TLV("RX0 Digital Volume", WCD9335_CDC_RX0_RX_VOL_CTL,
++                      -84, 40, digital_gain),
++      SOC_SINGLE_S8_TLV("RX1 Digital Volume", WCD9335_CDC_RX1_RX_VOL_CTL,
++                      -84, 40, digital_gain),
++      SOC_SINGLE_S8_TLV("RX2 Digital Volume", WCD9335_CDC_RX2_RX_VOL_CTL,
++                      -84, 40, digital_gain),
++      SOC_SINGLE_S8_TLV("RX3 Digital Volume", WCD9335_CDC_RX3_RX_VOL_CTL,
++                      -84, 40, digital_gain),
++      SOC_SINGLE_S8_TLV("RX4 Digital Volume", WCD9335_CDC_RX4_RX_VOL_CTL,
++                      -84, 40, digital_gain),
++      SOC_SINGLE_S8_TLV("RX5 Digital Volume", WCD9335_CDC_RX5_RX_VOL_CTL,
++                      -84, 40, digital_gain),
++      SOC_SINGLE_S8_TLV("RX6 Digital Volume", WCD9335_CDC_RX6_RX_VOL_CTL,
++                      -84, 40, digital_gain),
++      SOC_SINGLE_S8_TLV("RX7 Digital Volume", WCD9335_CDC_RX7_RX_VOL_CTL,
++                      -84, 40, digital_gain),
++      SOC_SINGLE_S8_TLV("RX8 Digital Volume", WCD9335_CDC_RX8_RX_VOL_CTL,
++                      -84, 40, digital_gain),
++      SOC_SINGLE_S8_TLV("RX0 Mix Digital Volume", WCD9335_CDC_RX0_RX_VOL_MIX_CTL,
++                      -84, 40, digital_gain),
++      SOC_SINGLE_S8_TLV("RX1 Mix Digital Volume", WCD9335_CDC_RX1_RX_VOL_MIX_CTL,
++                      -84, 40, digital_gain),
++      SOC_SINGLE_S8_TLV("RX2 Mix Digital Volume", WCD9335_CDC_RX2_RX_VOL_MIX_CTL,
++                      -84, 40, digital_gain),
++      SOC_SINGLE_S8_TLV("RX3 Mix Digital Volume", WCD9335_CDC_RX3_RX_VOL_MIX_CTL,
++                      -84, 40, digital_gain),
++      SOC_SINGLE_S8_TLV("RX4 Mix Digital Volume", WCD9335_CDC_RX4_RX_VOL_MIX_CTL,
++                      -84, 40, digital_gain),
++      SOC_SINGLE_S8_TLV("RX5 Mix Digital Volume", WCD9335_CDC_RX5_RX_VOL_MIX_CTL,
++                      -84, 40, digital_gain),
++      SOC_SINGLE_S8_TLV("RX6 Mix Digital Volume", WCD9335_CDC_RX6_RX_VOL_MIX_CTL,
++                      -84, 40, digital_gain),
++      SOC_SINGLE_S8_TLV("RX7 Mix Digital Volume", WCD9335_CDC_RX7_RX_VOL_MIX_CTL,
++                      -84, 40, digital_gain),
++      SOC_SINGLE_S8_TLV("RX8 Mix Digital Volume", WCD9335_CDC_RX8_RX_VOL_MIX_CTL,
++                      -84, 40, digital_gain),
+       SOC_ENUM("RX INT0_1 HPF cut off", cf_int0_1_enum),
+       SOC_ENUM("RX INT0_2 HPF cut off", cf_int0_2_enum),
+       SOC_ENUM("RX INT1_1 HPF cut off", cf_int1_1_enum),
+-- 
+2.35.1
+
diff --git a/queue-5.15/asoc-cros_ec_codec-fix-refcount-leak-in-cros_ec_code.patch b/queue-5.15/asoc-cros_ec_codec-fix-refcount-leak-in-cros_ec_code.patch
new file mode 100644 (file)
index 0000000..bc6305e
--- /dev/null
@@ -0,0 +1,40 @@
+From 4d30db48d63624d8ef777676cf427360321cde90 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jun 2022 17:10:43 +0400
+Subject: ASoC: cros_ec_codec: Fix refcount leak in
+ cros_ec_codec_platform_probe
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 0a034d93ee929a9ea89f3fa5f1d8492435b9ee6e ]
+
+of_parse_phandle() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when not need anymore.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: b6bc07d4360d ("ASoC: cros_ec_codec: support WoV")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Reviewed-by: Tzung-Bi Shih <tzungbi@kernel.org>
+Reviewed-by: Guenter Roeck <groeck@chromium.org>
+Link: https://lore.kernel.org/r/20220603131043.38907-1-linmq006@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/cros_ec_codec.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/sound/soc/codecs/cros_ec_codec.c b/sound/soc/codecs/cros_ec_codec.c
+index a201d652aca2..8823edc35113 100644
+--- a/sound/soc/codecs/cros_ec_codec.c
++++ b/sound/soc/codecs/cros_ec_codec.c
+@@ -994,6 +994,7 @@ static int cros_ec_codec_platform_probe(struct platform_device *pdev)
+                       dev_dbg(dev, "ap_shm_phys_addr=%#llx len=%#x\n",
+                               priv->ap_shm_phys_addr, priv->ap_shm_len);
+               }
++              of_node_put(node);
+       }
+ #endif
+-- 
+2.35.1
+
diff --git a/queue-5.15/asoc-fsl-asoc-card-force-cast-the-asrc_format-type.patch b/queue-5.15/asoc-fsl-asoc-card-force-cast-the-asrc_format-type.patch
new file mode 100644 (file)
index 0000000..8d67a4b
--- /dev/null
@@ -0,0 +1,49 @@
+From 27129e91ecd077d7066687718aae1efe758470b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Jul 2022 18:29:51 +0800
+Subject: ASoC: fsl-asoc-card: force cast the asrc_format type
+
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+
+[ Upstream commit 6c7b077dad62178c33f9a3ae17f90d6b0bf6e2e5 ]
+
+Fix sparse warning:
+sound/soc/fsl/fsl-asoc-card.c:833:45: sparse: warning: incorrect type in argument 3 (different base types)
+sound/soc/fsl/fsl-asoc-card.c:833:45: sparse:    expected unsigned int [usertype] *out_value
+sound/soc/fsl/fsl-asoc-card.c:833:45: sparse:    got restricted snd_pcm_format_t *
+
+Fixes: 859e364302c5 ("ASoC: fsl-asoc-card: Support new property fsl, asrc-format")
+Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
+Link: https://lore.kernel.org/r/1658399393-28777-4-git-send-email-shengjiu.wang@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/fsl-asoc-card.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
+index 95286c839b57..c72a156737e6 100644
+--- a/sound/soc/fsl/fsl-asoc-card.c
++++ b/sound/soc/fsl/fsl-asoc-card.c
+@@ -540,6 +540,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
+       struct device *codec_dev = NULL;
+       const char *codec_dai_name;
+       const char *codec_dev_name;
++      u32 asrc_fmt = 0;
+       u32 width;
+       int ret;
+@@ -817,8 +818,8 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
+                       goto asrc_fail;
+               }
+-              ret = of_property_read_u32(asrc_np, "fsl,asrc-format",
+-                                         &priv->asrc_format);
++              ret = of_property_read_u32(asrc_np, "fsl,asrc-format", &asrc_fmt);
++              priv->asrc_format = (__force snd_pcm_format_t)asrc_fmt;
+               if (ret) {
+                       /* Fallback to old binding; translate to asrc_format */
+                       ret = of_property_read_u32(asrc_np, "fsl,asrc-width",
+-- 
+2.35.1
+
diff --git a/queue-5.15/asoc-fsl_asrc-force-cast-the-asrc_format-type.patch b/queue-5.15/asoc-fsl_asrc-force-cast-the-asrc_format-type.patch
new file mode 100644 (file)
index 0000000..0a73e7e
--- /dev/null
@@ -0,0 +1,58 @@
+From fe8d2f88b38673d444a94eec75699fce7ad5792a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Jul 2022 18:29:50 +0800
+Subject: ASoC: fsl_asrc: force cast the asrc_format type
+
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+
+[ Upstream commit c49932726de24405d45516b3f8ad2735714fdf05 ]
+
+Fix sparse warning:
+sound/soc/fsl/fsl_asrc.c:1177:60: sparse: warning: incorrect type in argument 3 (different base types)
+sound/soc/fsl/fsl_asrc.c:1177:60: sparse:    expected unsigned int [usertype] *out_value
+sound/soc/fsl/fsl_asrc.c:1177:60: sparse:    got restricted snd_pcm_format_t *
+sound/soc/fsl/fsl_asrc.c:1200:47: sparse: warning: restricted snd_pcm_format_t degrades to integer
+
+Fixes: 4520af41fd21 ("ASoC: fsl_asrc: Support new property fsl,asrc-format")
+Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
+Link: https://lore.kernel.org/r/1658399393-28777-3-git-send-email-shengjiu.wang@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/fsl_asrc.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
+index d7d1536a4f37..44dcbf49456c 100644
+--- a/sound/soc/fsl/fsl_asrc.c
++++ b/sound/soc/fsl/fsl_asrc.c
+@@ -1066,6 +1066,7 @@ static int fsl_asrc_probe(struct platform_device *pdev)
+       struct resource *res;
+       void __iomem *regs;
+       int irq, ret, i;
++      u32 asrc_fmt = 0;
+       u32 map_idx;
+       char tmp[16];
+       u32 width;
+@@ -1174,7 +1175,8 @@ static int fsl_asrc_probe(struct platform_device *pdev)
+               return ret;
+       }
+-      ret = of_property_read_u32(np, "fsl,asrc-format", &asrc->asrc_format);
++      ret = of_property_read_u32(np, "fsl,asrc-format", &asrc_fmt);
++      asrc->asrc_format = (__force snd_pcm_format_t)asrc_fmt;
+       if (ret) {
+               ret = of_property_read_u32(np, "fsl,asrc-width", &width);
+               if (ret) {
+@@ -1197,7 +1199,7 @@ static int fsl_asrc_probe(struct platform_device *pdev)
+               }
+       }
+-      if (!(FSL_ASRC_FORMATS & (1ULL << asrc->asrc_format))) {
++      if (!(FSL_ASRC_FORMATS & pcm_format_to_bits(asrc->asrc_format))) {
+               dev_warn(&pdev->dev, "unsupported width, use default S24_LE\n");
+               asrc->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/asoc-fsl_easrc-use-snd_pcm_format_t-type-for-sample_.patch b/queue-5.15/asoc-fsl_easrc-use-snd_pcm_format_t-type-for-sample_.patch
new file mode 100644 (file)
index 0000000..71607e5
--- /dev/null
@@ -0,0 +1,107 @@
+From fa7aceb870aa20f004b7a83c96605f20940909dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Jul 2022 18:29:52 +0800
+Subject: ASoC: fsl_easrc: use snd_pcm_format_t type for sample_format
+
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+
+[ Upstream commit de27216cf2d645c2fd14e513707bdcd54e5b1de4 ]
+
+Fix sparse warning:
+sound/soc/fsl/fsl_easrc.c:562:33: sparse: warning: restricted snd_pcm_format_t degrades to integer
+sound/soc/fsl/fsl_easrc.c:563:34: sparse: warning: restricted snd_pcm_format_t degrades to integer
+sound/soc/fsl/fsl_easrc.c:565:38: sparse: warning: restricted snd_pcm_format_t degrades to integer
+sound/soc/fsl/fsl_easrc.c:566:39: sparse: warning: restricted snd_pcm_format_t degrades to integer
+sound/soc/fsl/fsl_easrc.c:608:33: sparse: warning: restricted snd_pcm_format_t degrades to integer
+sound/soc/fsl/fsl_easrc.c:609:34: sparse: warning: restricted snd_pcm_format_t degrades to integer
+sound/soc/fsl/fsl_easrc.c:615:40: sparse: warning: restricted snd_pcm_format_t degrades to integer
+sound/soc/fsl/fsl_easrc.c:616:41: sparse: warning: restricted snd_pcm_format_t degrades to integer
+
+sound/soc/fsl/fsl_easrc.c:1465:51: sparse: warning: incorrect type in assignment (different base types)
+sound/soc/fsl/fsl_easrc.c:1465:51: sparse:    expected unsigned int sample_format
+sound/soc/fsl/fsl_easrc.c:1465:51: sparse:    got restricted snd_pcm_format_t [usertype] format
+sound/soc/fsl/fsl_easrc.c:1467:52: sparse: warning: incorrect type in assignment (different base types)
+sound/soc/fsl/fsl_easrc.c:1467:52: sparse:    expected unsigned int sample_format
+sound/soc/fsl/fsl_easrc.c:1467:52: sparse:    got restricted snd_pcm_format_t [usertype] asrc_format
+sound/soc/fsl/fsl_easrc.c:1470:52: sparse: warning: incorrect type in assignment (different base types)
+sound/soc/fsl/fsl_easrc.c:1470:52: sparse:    expected unsigned int sample_format
+sound/soc/fsl/fsl_easrc.c:1470:52: sparse:    got restricted snd_pcm_format_t [usertype] format
+sound/soc/fsl/fsl_easrc.c:1472:51: sparse: warning: incorrect type in assignment (different base types)
+sound/soc/fsl/fsl_easrc.c:1472:51: sparse:    expected unsigned int sample_format
+sound/soc/fsl/fsl_easrc.c:1472:51: sparse:    got restricted snd_pcm_format_t [usertype] asrc_format
+sound/soc/fsl/fsl_easrc.c:1484:41: sparse: warning: incorrect type in argument 2 (different base types)
+sound/soc/fsl/fsl_easrc.c:1484:41: sparse:    expected restricted snd_pcm_format_t [usertype] *in_raw_format
+sound/soc/fsl/fsl_easrc.c:1484:41: sparse:    got unsigned int *
+sound/soc/fsl/fsl_easrc.c:1485:41: sparse: warning: incorrect type in argument 3 (different base types)
+sound/soc/fsl/fsl_easrc.c:1485:41: sparse:    expected restricted snd_pcm_format_t [usertype] *out_raw_format
+sound/soc/fsl/fsl_easrc.c:1485:41: sparse:    got unsigned int *
+sound/soc/fsl/fsl_easrc.c:1937:60: sparse: warning: incorrect type in argument 3 (different base types)
+sound/soc/fsl/fsl_easrc.c:1937:60: sparse:    expected unsigned int [usertype] *out_value
+sound/soc/fsl/fsl_easrc.c:1937:60: sparse:    got restricted snd_pcm_format_t *
+sound/soc/fsl/fsl_easrc.c:1943:49: sparse: warning: restricted snd_pcm_format_t degrades to integer
+
+Fixes: 955ac624058f ("ASoC: fsl_easrc: Add EASRC ASoC CPU DAI drivers")
+Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
+Link: https://lore.kernel.org/r/1658399393-28777-5-git-send-email-shengjiu.wang@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/fsl_easrc.c | 9 ++++++---
+ sound/soc/fsl/fsl_easrc.h | 2 +-
+ 2 files changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c
+index be14f84796cb..cf0e10d17dbe 100644
+--- a/sound/soc/fsl/fsl_easrc.c
++++ b/sound/soc/fsl/fsl_easrc.c
+@@ -476,7 +476,8 @@ static int fsl_easrc_prefilter_config(struct fsl_asrc *easrc,
+       struct fsl_asrc_pair *ctx;
+       struct device *dev;
+       u32 inrate, outrate, offset = 0;
+-      u32 in_s_rate, out_s_rate, in_s_fmt, out_s_fmt;
++      u32 in_s_rate, out_s_rate;
++      snd_pcm_format_t in_s_fmt, out_s_fmt;
+       int ret, i;
+       if (!easrc)
+@@ -1873,6 +1874,7 @@ static int fsl_easrc_probe(struct platform_device *pdev)
+       struct resource *res;
+       struct device_node *np;
+       void __iomem *regs;
++      u32 asrc_fmt = 0;
+       int ret, irq;
+       easrc = devm_kzalloc(dev, sizeof(*easrc), GFP_KERNEL);
+@@ -1933,13 +1935,14 @@ static int fsl_easrc_probe(struct platform_device *pdev)
+               return ret;
+       }
+-      ret = of_property_read_u32(np, "fsl,asrc-format", &easrc->asrc_format);
++      ret = of_property_read_u32(np, "fsl,asrc-format", &asrc_fmt);
++      easrc->asrc_format = (__force snd_pcm_format_t)asrc_fmt;
+       if (ret) {
+               dev_err(dev, "failed to asrc format\n");
+               return ret;
+       }
+-      if (!(FSL_EASRC_FORMATS & (1ULL << easrc->asrc_format))) {
++      if (!(FSL_EASRC_FORMATS & (pcm_format_to_bits(easrc->asrc_format)))) {
+               dev_warn(dev, "unsupported format, switching to S24_LE\n");
+               easrc->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
+       }
+diff --git a/sound/soc/fsl/fsl_easrc.h b/sound/soc/fsl/fsl_easrc.h
+index 30620d56252c..5b8469757c12 100644
+--- a/sound/soc/fsl/fsl_easrc.h
++++ b/sound/soc/fsl/fsl_easrc.h
+@@ -569,7 +569,7 @@ struct fsl_easrc_io_params {
+       unsigned int access_len;
+       unsigned int fifo_wtmk;
+       unsigned int sample_rate;
+-      unsigned int sample_format;
++      snd_pcm_format_t sample_format;
+       unsigned int norm_rate;
+ };
+-- 
+2.35.1
+
diff --git a/queue-5.15/asoc-imx-audmux-silence-a-clang-warning.patch b/queue-5.15/asoc-imx-audmux-silence-a-clang-warning.patch
new file mode 100644 (file)
index 0000000..bc692d3
--- /dev/null
@@ -0,0 +1,40 @@
+From 3d5b83cbe16aa6cd1ccc307110d4bf6bb9f7fa23 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 May 2022 22:05:43 -0300
+Subject: ASoC: imx-audmux: Silence a clang warning
+
+From: Fabio Estevam <festevam@gmail.com>
+
+[ Upstream commit 2f4a8171da06609bb6a063630ed546ee3d93dad7 ]
+
+Change the of_device_get_match_data() cast to (uintptr_t)
+to silence the following clang warning:
+
+sound/soc/fsl/imx-audmux.c:301:16: warning: cast to smaller integer type 'enum imx_audmux_type' from 'const void *' [-Wvoid-pointer-to-enum-cast]
+
+Reported-by: kernel test robot <lkp@intel.com>
+Fixes: 6a8b8b582db1 ("ASoC: imx-audmux: Remove unused .id_table")
+Signed-off-by: Fabio Estevam <festevam@gmail.com>
+Link: https://lore.kernel.org/r/20220526010543.1164793-1-festevam@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/imx-audmux.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c
+index dfa05d40b276..a8e5e0f57faf 100644
+--- a/sound/soc/fsl/imx-audmux.c
++++ b/sound/soc/fsl/imx-audmux.c
+@@ -298,7 +298,7 @@ static int imx_audmux_probe(struct platform_device *pdev)
+               audmux_clk = NULL;
+       }
+-      audmux_type = (enum imx_audmux_type)of_device_get_match_data(&pdev->dev);
++      audmux_type = (uintptr_t)of_device_get_match_data(&pdev->dev);
+       switch (audmux_type) {
+       case IMX31_AUDMUX:
+-- 
+2.35.1
+
diff --git a/queue-5.15/asoc-imx-card-fix-dsd-pdm-mclk-frequency.patch b/queue-5.15/asoc-imx-card-fix-dsd-pdm-mclk-frequency.patch
new file mode 100644 (file)
index 0000000..e530a02
--- /dev/null
@@ -0,0 +1,59 @@
+From c112e5530870c41b25d02d940fcdad4da7b64e20 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Jul 2022 17:42:55 +0800
+Subject: ASoC: imx-card: Fix DSD/PDM mclk frequency
+
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+
+[ Upstream commit c0fabd12a8570cb932f13d9388f3d887ad44369b ]
+
+The DSD/PDM rate not only DSD64/128/256/512, which are the
+multiple rate of 44.1kHz,  but also support the multiple
+rate of 8kHz, so can't force all mclk frequency to be
+22579200Hz, need to assign the frequency according to
+rate.
+
+Fixes: aa736700f42f ("ASoC: imx-card: Add imx-card machine driver")
+Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
+Link: https://lore.kernel.org/r/1657100575-8261-1-git-send-email-shengjiu.wang@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/imx-card.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/sound/soc/fsl/imx-card.c b/sound/soc/fsl/imx-card.c
+index 55bc1bb0dbbd..b28b30c69a3f 100644
+--- a/sound/soc/fsl/imx-card.c
++++ b/sound/soc/fsl/imx-card.c
+@@ -17,6 +17,9 @@
+ #include "fsl_sai.h"
++#define IMX_CARD_MCLK_22P5792MHZ  22579200
++#define IMX_CARD_MCLK_24P576MHZ   24576000
++
+ enum codec_type {
+       CODEC_DUMMY = 0,
+       CODEC_AK5558 = 1,
+@@ -353,9 +356,14 @@ static int imx_aif_hw_params(struct snd_pcm_substream *substream,
+               mclk_freq = akcodec_get_mclk_rate(substream, params, slots, slot_width);
+       else
+               mclk_freq = params_rate(params) * slots * slot_width;
+-      /* Use the maximum freq from DSD512 (512*44100 = 22579200) */
+-      if (format_is_dsd(params))
+-              mclk_freq = 22579200;
++
++      if (format_is_dsd(params)) {
++              /* Use the maximum freq from DSD512 (512*44100 = 22579200) */
++              if (!(params_rate(params) % 11025))
++                      mclk_freq = IMX_CARD_MCLK_22P5792MHZ;
++              else
++                      mclk_freq = IMX_CARD_MCLK_24P576MHZ;
++      }
+       ret = snd_soc_dai_set_sysclk(cpu_dai, link_data->cpu_sysclk_id, mclk_freq,
+                                    SND_SOC_CLOCK_OUT);
+-- 
+2.35.1
+
diff --git a/queue-5.15/asoc-imx-card-use-snd_pcm_format_t-type-for-asrc_for.patch b/queue-5.15/asoc-imx-card-use-snd_pcm_format_t-type-for-asrc_for.patch
new file mode 100644 (file)
index 0000000..cefec41
--- /dev/null
@@ -0,0 +1,69 @@
+From 9b9abf3cbfc77a3ad1c46fb139824faa18b3cd8b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Jul 2022 18:29:53 +0800
+Subject: ASoC: imx-card: use snd_pcm_format_t type for asrc_format
+
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+
+[ Upstream commit 409a8652e909e323c715f3088e6c3133e37c8881 ]
+
+Fix sparse warning:
+sound/soc/fsl/imx-card.c:653:59: sparse: warning: incorrect type in assignment (different base types)
+sound/soc/fsl/imx-card.c:653:59: sparse:    expected unsigned int [usertype] asrc_format
+sound/soc/fsl/imx-card.c:653:59: sparse:    got restricted snd_pcm_format_t [usertype]
+sound/soc/fsl/imx-card.c:655:59: sparse: warning: incorrect type in assignment (different base types)
+sound/soc/fsl/imx-card.c:655:59: sparse:    expected unsigned int [usertype] asrc_format
+sound/soc/fsl/imx-card.c:655:59: sparse:    got restricted snd_pcm_format_t [usertype]
+
+Fixes: aa736700f42f ("ASoC: imx-card: Add imx-card machine driver")
+Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
+Link: https://lore.kernel.org/r/1658399393-28777-6-git-send-email-shengjiu.wang@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/imx-card.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/sound/soc/fsl/imx-card.c b/sound/soc/fsl/imx-card.c
+index b28b30c69a3f..593d69b96523 100644
+--- a/sound/soc/fsl/imx-card.c
++++ b/sound/soc/fsl/imx-card.c
+@@ -118,7 +118,7 @@ struct imx_card_data {
+       struct snd_soc_card card;
+       int num_dapm_routes;
+       u32 asrc_rate;
+-      u32 asrc_format;
++      snd_pcm_format_t asrc_format;
+ };
+ static struct imx_akcodec_fs_mul ak4458_fs_mul[] = {
+@@ -474,7 +474,7 @@ static int be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+       mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+       snd_mask_none(mask);
+-      snd_mask_set(mask, data->asrc_format);
++      snd_mask_set(mask, (__force unsigned int)data->asrc_format);
+       return 0;
+ }
+@@ -493,6 +493,7 @@ static int imx_card_parse_of(struct imx_card_data *data)
+       struct dai_link_data *link_data;
+       struct of_phandle_args args;
+       int ret, num_links;
++      u32 asrc_fmt = 0;
+       u32 width;
+       ret = snd_soc_of_parse_card_name(card, "model");
+@@ -639,7 +640,8 @@ static int imx_card_parse_of(struct imx_card_data *data)
+                               goto err;
+                       }
+-                      ret = of_property_read_u32(args.np, "fsl,asrc-format", &data->asrc_format);
++                      ret = of_property_read_u32(args.np, "fsl,asrc-format", &asrc_fmt);
++                      data->asrc_format = (__force snd_pcm_format_t)asrc_fmt;
+                       if (ret) {
+                               /* Fallback to old binding; translate to asrc_format */
+                               ret = of_property_read_u32(args.np, "fsl,asrc-width", &width);
+-- 
+2.35.1
+
diff --git a/queue-5.15/asoc-mchp-spdifrx-disable-end-of-block-interrupt-on-.patch b/queue-5.15/asoc-mchp-spdifrx-disable-end-of-block-interrupt-on-.patch
new file mode 100644 (file)
index 0000000..f9ce6ba
--- /dev/null
@@ -0,0 +1,59 @@
+From 25984a673c6e3e32a2da3369866826c4481a0378 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Jul 2022 12:08:13 +0300
+Subject: ASoC: mchp-spdifrx: disable end of block interrupt on failures
+
+From: Claudiu Beznea <claudiu.beznea@microchip.com>
+
+[ Upstream commit 768ac4f12ca0fda935f58eb8c5120e9d795bc6e3 ]
+
+Disable end of block interrupt in case of wait for completion timeout
+or errors to undo previously enable operation (done in
+mchp_spdifrx_isr_blockend_en()). Otherwise we can end up with an
+unbalanced reference counter for this interrupt.
+
+Fixes: ef265c55c1ac ("ASoC: mchp-spdifrx: add driver for SPDIF RX")
+Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Link: https://lore.kernel.org/r/20220727090814.2446111-2-claudiu.beznea@microchip.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/atmel/mchp-spdifrx.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/sound/soc/atmel/mchp-spdifrx.c b/sound/soc/atmel/mchp-spdifrx.c
+index bcd4f3e4fb0f..2a62d9a2fa0d 100644
+--- a/sound/soc/atmel/mchp-spdifrx.c
++++ b/sound/soc/atmel/mchp-spdifrx.c
+@@ -288,15 +288,17 @@ static void mchp_spdifrx_isr_blockend_en(struct mchp_spdifrx_dev *dev)
+       spin_unlock_irqrestore(&dev->blockend_lock, flags);
+ }
+-/* called from atomic context only */
++/* called from atomic/non-atomic context */
+ static void mchp_spdifrx_isr_blockend_dis(struct mchp_spdifrx_dev *dev)
+ {
+-      spin_lock(&dev->blockend_lock);
++      unsigned long flags;
++
++      spin_lock_irqsave(&dev->blockend_lock, flags);
+       dev->blockend_refcount--;
+       /* don't enable BLOCKEND interrupt if it's already enabled */
+       if (dev->blockend_refcount == 0)
+               regmap_write(dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_BLOCKEND);
+-      spin_unlock(&dev->blockend_lock);
++      spin_unlock_irqrestore(&dev->blockend_lock, flags);
+ }
+ static irqreturn_t mchp_spdif_interrupt(int irq, void *dev_id)
+@@ -575,6 +577,7 @@ static int mchp_spdifrx_subcode_ch_get(struct mchp_spdifrx_dev *dev,
+       if (ret <= 0) {
+               dev_dbg(dev->dev, "user data for channel %d timeout\n",
+                       channel);
++              mchp_spdifrx_isr_blockend_dis(dev);
+               return ret;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/asoc-mediatek-mt8173-fix-refcount-leak-in-mt8173_rt5.patch b/queue-5.15/asoc-mediatek-mt8173-fix-refcount-leak-in-mt8173_rt5.patch
new file mode 100644 (file)
index 0000000..ad63dea
--- /dev/null
@@ -0,0 +1,67 @@
+From c92c2d8a65b5b5e19d0f49c8b3a6dedf4465663a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jun 2022 07:41:42 +0400
+Subject: ASoC: mediatek: mt8173: Fix refcount leak in
+ mt8173_rt5650_rt5676_dev_probe
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit ae4f11c1ed2d67192fdf3d89db719ee439827c11 ]
+
+of_parse_phandle() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when not need anymore.
+Fix missing of_node_put() in error paths.
+
+Fixes: 94319ba10eca ("ASoC: mediatek: Use platform_of_node for machine drivers")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Link: https://lore.kernel.org/r/20220602034144.60159-1-linmq006@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
+index c8e4e85e1057..94a9bbf144d1 100644
+--- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
++++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
+@@ -256,14 +256,16 @@ static int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev)
+       if (!mt8173_rt5650_rt5676_dais[DAI_LINK_CODEC_I2S].codecs[0].of_node) {
+               dev_err(&pdev->dev,
+                       "Property 'audio-codec' missing or invalid\n");
+-              return -EINVAL;
++              ret = -EINVAL;
++              goto put_node;
+       }
+       mt8173_rt5650_rt5676_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node =
+               of_parse_phandle(pdev->dev.of_node, "mediatek,audio-codec", 1);
+       if (!mt8173_rt5650_rt5676_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node) {
+               dev_err(&pdev->dev,
+                       "Property 'audio-codec' missing or invalid\n");
+-              return -EINVAL;
++              ret = -EINVAL;
++              goto put_node;
+       }
+       mt8173_rt5650_rt5676_codec_conf[0].dlc.of_node =
+               mt8173_rt5650_rt5676_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node;
+@@ -276,7 +278,8 @@ static int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev)
+       if (!mt8173_rt5650_rt5676_dais[DAI_LINK_HDMI_I2S].codecs->of_node) {
+               dev_err(&pdev->dev,
+                       "Property 'audio-codec' missing or invalid\n");
+-              return -EINVAL;
++              ret = -EINVAL;
++              goto put_node;
+       }
+       card->dev = &pdev->dev;
+@@ -286,6 +289,7 @@ static int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev)
+               dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
+                       __func__, ret);
++put_node:
+       of_node_put(platform_node);
+       return ret;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/asoc-mediatek-mt8173-rt5650-fix-refcount-leak-in-mt8.patch b/queue-5.15/asoc-mediatek-mt8173-rt5650-fix-refcount-leak-in-mt8.patch
new file mode 100644 (file)
index 0000000..34b2e15
--- /dev/null
@@ -0,0 +1,67 @@
+From 35009e6e4f1b493a84a29da5fb8e50763ad47fea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jun 2022 16:42:41 +0400
+Subject: ASoC: mediatek: mt8173-rt5650: Fix refcount leak in
+ mt8173_rt5650_dev_probe
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit efe2178d1a32492f99e7f1f2568eea5c88a85729 ]
+
+of_parse_phandle() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when not need anymore.
+Fix refcount leak in some error paths.
+
+Fixes: 0f83f9296d5c ("ASoC: mediatek: Add machine driver for ALC5650 codec")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Link: https://lore.kernel.org/r/20220603124243.31358-1-linmq006@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/mediatek/mt8173/mt8173-rt5650.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650.c b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
+index e168d31f4445..1de9dab218c6 100644
+--- a/sound/soc/mediatek/mt8173/mt8173-rt5650.c
++++ b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
+@@ -280,7 +280,8 @@ static int mt8173_rt5650_dev_probe(struct platform_device *pdev)
+       if (!mt8173_rt5650_dais[DAI_LINK_CODEC_I2S].codecs[0].of_node) {
+               dev_err(&pdev->dev,
+                       "Property 'audio-codec' missing or invalid\n");
+-              return -EINVAL;
++              ret = -EINVAL;
++              goto put_platform_node;
+       }
+       mt8173_rt5650_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node =
+               mt8173_rt5650_dais[DAI_LINK_CODEC_I2S].codecs[0].of_node;
+@@ -293,7 +294,7 @@ static int mt8173_rt5650_dev_probe(struct platform_device *pdev)
+                       dev_err(&pdev->dev,
+                               "%s codec_capture_dai name fail %d\n",
+                               __func__, ret);
+-                      return ret;
++                      goto put_platform_node;
+               }
+               mt8173_rt5650_dais[DAI_LINK_CODEC_I2S].codecs[1].dai_name =
+                       codec_capture_dai;
+@@ -315,7 +316,8 @@ static int mt8173_rt5650_dev_probe(struct platform_device *pdev)
+       if (!mt8173_rt5650_dais[DAI_LINK_HDMI_I2S].codecs->of_node) {
+               dev_err(&pdev->dev,
+                       "Property 'audio-codec' missing or invalid\n");
+-              return -EINVAL;
++              ret = -EINVAL;
++              goto put_platform_node;
+       }
+       card->dev = &pdev->dev;
+@@ -324,6 +326,7 @@ static int mt8173_rt5650_dev_probe(struct platform_device *pdev)
+               dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
+                       __func__, ret);
++put_platform_node:
+       of_node_put(platform_node);
+       return ret;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/asoc-mt6359-fix-refcount-leak-bug.patch b/queue-5.15/asoc-mt6359-fix-refcount-leak-bug.patch
new file mode 100644 (file)
index 0000000..2ed07f7
--- /dev/null
@@ -0,0 +1,51 @@
+From be34abeaad18970041670d4f0d9c3227e38305a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 18:20:13 +0800
+Subject: ASoC: mt6359: Fix refcount leak bug
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit a8d5df69e2ec702d979f7d04ed519caf8691a032 ]
+
+In mt6359_parse_dt() and mt6359_accdet_parse_dt(), we should call
+of_node_put() for the reference returned by of_get_child_by_name()
+which has increased the refcount.
+
+Fixes: 683530285316 ("ASoC: mt6359: fix failed to parse DT properties")
+Fixes: eef07b9e0925 ("ASoC: mediatek: mt6359: add MT6359 accdet jack driver")
+Signed-off-by: Liang He <windhl@126.com>
+Link: https://lore.kernel.org/r/20220713102013.367336-1-windhl@126.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/mt6359-accdet.c | 1 +
+ sound/soc/codecs/mt6359.c        | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/sound/soc/codecs/mt6359-accdet.c b/sound/soc/codecs/mt6359-accdet.c
+index 6d3d170144a0..c190628e2905 100644
+--- a/sound/soc/codecs/mt6359-accdet.c
++++ b/sound/soc/codecs/mt6359-accdet.c
+@@ -675,6 +675,7 @@ static int mt6359_accdet_parse_dt(struct mt6359_accdet *priv)
+                              sizeof(struct three_key_threshold));
+       }
++      of_node_put(node);
+       dev_warn(priv->dev, "accdet caps=%x\n", priv->caps);
+       return 0;
+diff --git a/sound/soc/codecs/mt6359.c b/sound/soc/codecs/mt6359.c
+index 2d6a4a29b850..cf1febe54bcd 100644
+--- a/sound/soc/codecs/mt6359.c
++++ b/sound/soc/codecs/mt6359.c
+@@ -2780,6 +2780,7 @@ static int mt6359_parse_dt(struct mt6359_priv *priv)
+       ret = of_property_read_u32(np, "mediatek,mic-type-2",
+                                  &priv->mux_select[MUX_MIC_TYPE_2]);
++      of_node_put(np);
+       if (ret) {
+               dev_info(priv->dev,
+                        "%s() failed to read mic-type-2, use default (%d)\n",
+-- 
+2.35.1
+
diff --git a/queue-5.15/asoc-mt6797-mt6351-fix-refcount-leak-in-mt6797_mt635.patch b/queue-5.15/asoc-mt6797-mt6351-fix-refcount-leak-in-mt6797_mt635.patch
new file mode 100644 (file)
index 0000000..296a19c
--- /dev/null
@@ -0,0 +1,49 @@
+From 4cdccee6c406b9660fb08e00e2c3f04fb0027fef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jun 2022 12:34:15 +0400
+Subject: ASoC: mt6797-mt6351: Fix refcount leak in mt6797_mt6351_dev_probe
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 7472eb8d7dd12b6b9b1a4f4527719cc9c7f5965f ]
+
+of_parse_phandle() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when not need anymore.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: f0ab0bf250da ("ASoC: add mt6797-mt6351 driver and config option")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Link: https://lore.kernel.org/r/20220603083417.9011-1-linmq006@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/mediatek/mt6797/mt6797-mt6351.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/mediatek/mt6797/mt6797-mt6351.c b/sound/soc/mediatek/mt6797/mt6797-mt6351.c
+index 496f32bcfb5e..d2f6213a6bfc 100644
+--- a/sound/soc/mediatek/mt6797/mt6797-mt6351.c
++++ b/sound/soc/mediatek/mt6797/mt6797-mt6351.c
+@@ -217,7 +217,8 @@ static int mt6797_mt6351_dev_probe(struct platform_device *pdev)
+       if (!codec_node) {
+               dev_err(&pdev->dev,
+                       "Property 'audio-codec' missing or invalid\n");
+-              return -EINVAL;
++              ret = -EINVAL;
++              goto put_platform_node;
+       }
+       for_each_card_prelinks(card, i, dai_link) {
+               if (dai_link->codecs->name)
+@@ -230,6 +231,9 @@ static int mt6797_mt6351_dev_probe(struct platform_device *pdev)
+               dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
+                       __func__, ret);
++      of_node_put(codec_node);
++put_platform_node:
++      of_node_put(platform_node);
+       return ret;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/asoc-qcom-fix-missing-of_node_put-in-asoc_qcom_lpass.patch b/queue-5.15/asoc-qcom-fix-missing-of_node_put-in-asoc_qcom_lpass.patch
new file mode 100644 (file)
index 0000000..0659e6f
--- /dev/null
@@ -0,0 +1,38 @@
+From 5d2745eca0b6c96c5d30e9ad7f4c544324985abc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 2 Jul 2022 10:01:09 +0800
+Subject: ASoC: qcom: Fix missing of_node_put() in
+ asoc_qcom_lpass_cpu_platform_probe()
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit f507c0c67dac57d2bcd5dcae4b6139b0305d8957 ]
+
+We should call of_node_put() for the reference 'dsp_of_node' returned by
+of_parse_phandle() which will increase the refcount.
+
+Fixes: 9bae4880acee ("ASoC: qcom: move ipq806x specific bits out of lpass driver.")
+Co-authored-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Liang He <windhl@126.com>
+Link: https://lore.kernel.org/r/20220702020109.263980-1-windhl@126.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/qcom/lpass-cpu.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c
+index 3bd9eb3cc688..5e89d280e355 100644
+--- a/sound/soc/qcom/lpass-cpu.c
++++ b/sound/soc/qcom/lpass-cpu.c
+@@ -880,6 +880,7 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)
+       dsp_of_node = of_parse_phandle(pdev->dev.of_node, "qcom,adsp", 0);
+       if (dsp_of_node) {
+               dev_err(dev, "DSP exists and holds audio resources\n");
++              of_node_put(dsp_of_node);
+               return -EBUSY;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/asoc-qcom-q6dsp-fix-an-off-by-one-in-q6adm_alloc_cop.patch b/queue-5.15/asoc-qcom-q6dsp-fix-an-off-by-one-in-q6adm_alloc_cop.patch
new file mode 100644 (file)
index 0000000..840c0ca
--- /dev/null
@@ -0,0 +1,37 @@
+From dfa4c1e4fe9345e02b7a994a3dc06f68912b7f87 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Jul 2022 11:02:22 +0200
+Subject: ASoC: qcom: q6dsp: Fix an off-by-one in q6adm_alloc_copp()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 673f58f62ca6fc98979d1cf3fe89c3ff33f29b2e ]
+
+find_first_zero_bit() returns MAX_COPPS_PER_PORT at max here.
+So 'idx' should be tested with ">=" or the test can't match.
+
+Fixes: 7b20b2be51e1 ("ASoC: qdsp6: q6adm: Add q6adm driver")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://lore.kernel.org/r/0fca3271649736053eb9649d87e1ca01b056be40.1658394124.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/qcom/qdsp6/q6adm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/qcom/qdsp6/q6adm.c b/sound/soc/qcom/qdsp6/q6adm.c
+index 3d831b635524..4ae97afe9062 100644
+--- a/sound/soc/qcom/qdsp6/q6adm.c
++++ b/sound/soc/qcom/qdsp6/q6adm.c
+@@ -217,7 +217,7 @@ static struct q6copp *q6adm_alloc_copp(struct q6adm *adm, int port_idx)
+       idx = find_first_zero_bit(&adm->copp_bitmap[port_idx],
+                                 MAX_COPPS_PER_PORT);
+-      if (idx > MAX_COPPS_PER_PORT)
++      if (idx >= MAX_COPPS_PER_PORT)
+               return ERR_PTR(-EBUSY);
+       c = kzalloc(sizeof(*c), GFP_ATOMIC);
+-- 
+2.35.1
+
diff --git a/queue-5.15/asoc-samsung-change-gpiod_speaker_power-and-rx1950_a.patch b/queue-5.15/asoc-samsung-change-gpiod_speaker_power-and-rx1950_a.patch
new file mode 100644 (file)
index 0000000..f48e52c
--- /dev/null
@@ -0,0 +1,52 @@
+From 78505697906712862e5e75a3aa864309451037c4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Jun 2022 14:53:45 -0400
+Subject: ASoC: samsung: change gpiod_speaker_power and rx1950_audio from
+ global to static variables
+
+From: Tom Rix <trix@redhat.com>
+
+[ Upstream commit d2294461b90e0c5b3bbfaaf2c8baff4fd3e2bb13 ]
+
+sparse reports
+sound/soc/samsung/rx1950_uda1380.c:131:18: warning: symbol 'gpiod_speaker_power' was not declared. Should it be static?
+sound/soc/samsung/rx1950_uda1380.c:231:24: warning: symbol 'rx1950_audio' was not declared. Should it be static?
+
+Both gpiod_speaker_power and rx1950_audio are only used in rx1950_uda1380.c,
+so their storage class specifiers should be static.
+
+Fixes: 83d74e354200 ("ASoC: samsung: rx1950: turn into platform driver")
+Signed-off-by: Tom Rix <trix@redhat.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20220629185345.910406-1-trix@redhat.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/samsung/rx1950_uda1380.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/samsung/rx1950_uda1380.c b/sound/soc/samsung/rx1950_uda1380.c
+index 6ea1c8cc9167..2820097b00b9 100644
+--- a/sound/soc/samsung/rx1950_uda1380.c
++++ b/sound/soc/samsung/rx1950_uda1380.c
+@@ -128,7 +128,7 @@ static int rx1950_startup(struct snd_pcm_substream *substream)
+                                       &hw_rates);
+ }
+-struct gpio_desc *gpiod_speaker_power;
++static struct gpio_desc *gpiod_speaker_power;
+ static int rx1950_spk_power(struct snd_soc_dapm_widget *w,
+                               struct snd_kcontrol *kcontrol, int event)
+@@ -227,7 +227,7 @@ static int rx1950_probe(struct platform_device *pdev)
+       return devm_snd_soc_register_card(dev, &rx1950_asoc);
+ }
+-struct platform_driver rx1950_audio = {
++static struct platform_driver rx1950_audio = {
+       .driver = {
+               .name = "rx1950-audio",
+               .pm = &snd_soc_pm_ops,
+-- 
+2.35.1
+
diff --git a/queue-5.15/asoc-samsung-fix-error-handling-in-aries_audio_probe.patch b/queue-5.15/asoc-samsung-fix-error-handling-in-aries_audio_probe.patch
new file mode 100644 (file)
index 0000000..9698708
--- /dev/null
@@ -0,0 +1,44 @@
+From 33852ddadab8e2d5a237bcee35b67fb474b0e565 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jun 2022 17:06:39 +0400
+Subject: ASoC: samsung: Fix error handling in aries_audio_probe
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 3e2649c5e8643bea0867bb1dd970fedadb0eb7f3 ]
+
+of_get_child_by_name() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when not need anymore.
+This function is missing of_node_put(cpu) in the error path.
+Fix this by goto out label. of_node_put() will check NULL pointer.
+
+Fixes: 7a3a7671fa6c ("ASoC: samsung: Add driver for Aries boards")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20220603130640.37624-1-linmq006@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/samsung/aries_wm8994.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/samsung/aries_wm8994.c b/sound/soc/samsung/aries_wm8994.c
+index 83acbe57b248..a0825da9fff9 100644
+--- a/sound/soc/samsung/aries_wm8994.c
++++ b/sound/soc/samsung/aries_wm8994.c
+@@ -628,8 +628,10 @@ static int aries_audio_probe(struct platform_device *pdev)
+               return -EINVAL;
+       codec = of_get_child_by_name(dev->of_node, "codec");
+-      if (!codec)
+-              return -EINVAL;
++      if (!codec) {
++              ret = -EINVAL;
++              goto out;
++      }
+       for_each_card_prelinks(card, i, dai_link) {
+               dai_link->codecs->of_node = of_parse_phandle(codec,
+-- 
+2.35.1
+
diff --git a/queue-5.15/asoc-samsung-h1940_uda1380-include-proepr-gpio-consu.patch b/queue-5.15/asoc-samsung-h1940_uda1380-include-proepr-gpio-consu.patch
new file mode 100644 (file)
index 0000000..c266f79
--- /dev/null
@@ -0,0 +1,37 @@
+From 75334fe11176b6386111300b7a029da0f0c8887d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 27 Jun 2022 16:19:00 +0200
+Subject: ASoC: samsung: h1940_uda1380: include proepr GPIO consumer header
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit bd10b0dafdcf0ec1677cad70101e1f97b9e28f2e ]
+
+h1940_uda1380 uses gpiod*/GPIOD* so it should include GPIO consumer
+header.
+
+Fixes: 9666e27f90b9 ("ASoC: samsung: h1940: turn into platform driver")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20220627141900.470469-1-krzysztof.kozlowski@linaro.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/samsung/h1940_uda1380.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/samsung/h1940_uda1380.c b/sound/soc/samsung/h1940_uda1380.c
+index c994e67d1eaf..ca086243fcfd 100644
+--- a/sound/soc/samsung/h1940_uda1380.c
++++ b/sound/soc/samsung/h1940_uda1380.c
+@@ -8,7 +8,7 @@
+ // Based on version from Arnaud Patard <arnaud.patard@rtp-net.org>
+ #include <linux/types.h>
+-#include <linux/gpio.h>
++#include <linux/gpio/consumer.h>
+ #include <linux/module.h>
+ #include <sound/soc.h>
+-- 
+2.35.1
+
diff --git a/queue-5.15/ath10k-do-not-enforce-interrupt-trigger-type.patch b/queue-5.15/ath10k-do-not-enforce-interrupt-trigger-type.patch
new file mode 100644 (file)
index 0000000..8958d6f
--- /dev/null
@@ -0,0 +1,58 @@
+From a3f4272b41f6d7263192344257f34ad828d98640 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 May 2022 10:27:26 +0300
+Subject: ath10k: do not enforce interrupt trigger type
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 1ee6c5abebd3cacf2ac4378d0ed4f57fd4850421 ]
+
+Interrupt line can be configured on different hardware in different way,
+even inverted.  Therefore driver should not enforce specific trigger
+type - edge rising - but instead rely on Devicetree to configure it.
+
+All Qualcomm DTSI with WCN3990 define the interrupt type as level high,
+so the mismatch between DTSI and driver causes rebind issues:
+
+  $ echo 18800000.wifi > /sys/bus/platform/drivers/ath10k_snoc/unbind
+  $ echo 18800000.wifi > /sys/bus/platform/drivers/ath10k_snoc/bind
+  [   44.763114] irq: type mismatch, failed to map hwirq-446 for interrupt-controller@17a00000!
+  [   44.763130] ath10k_snoc 18800000.wifi: error -ENXIO: IRQ index 0 not found
+  [   44.763140] ath10k_snoc 18800000.wifi: failed to initialize resource: -6
+
+Tested-on: WCN3990 hw1.0 SNOC WLAN.HL.3.2.0.c8-00009-QCAHLSWSC8180XMTPLZ-1
+Tested-on: WCN3990 hw1.0 SNOC WLAN.HL.2.0-01387-QCAHLSWMTPLZ-1
+
+Fixes: c963a683e701 ("ath10k: add resource init and deinit for WCN3990")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Tested-by: Steev Klimaszewski <steev@kali.org>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20220513151516.357549-1-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath10k/snoc.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath10k/snoc.c b/drivers/net/wireless/ath/ath10k/snoc.c
+index f79dd9a71690..73fe77e7824b 100644
+--- a/drivers/net/wireless/ath/ath10k/snoc.c
++++ b/drivers/net/wireless/ath/ath10k/snoc.c
+@@ -1249,13 +1249,12 @@ static void ath10k_snoc_init_napi(struct ath10k *ar)
+ static int ath10k_snoc_request_irq(struct ath10k *ar)
+ {
+       struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
+-      int irqflags = IRQF_TRIGGER_RISING;
+       int ret, id;
+       for (id = 0; id < CE_COUNT_MAX; id++) {
+               ret = request_irq(ar_snoc->ce_irqs[id].irq_line,
+-                                ath10k_snoc_per_engine_handler,
+-                                irqflags, ce_name[id], ar);
++                                ath10k_snoc_per_engine_handler, 0,
++                                ce_name[id], ar);
+               if (ret) {
+                       ath10k_err(ar,
+                                  "failed to register IRQ handler for CE %d: %d\n",
+-- 
+2.35.1
+
diff --git a/queue-5.15/ath11k-fix-incorrect-debug_mask-mappings.patch b/queue-5.15/ath11k-fix-incorrect-debug_mask-mappings.patch
new file mode 100644 (file)
index 0000000..7b7f10b
--- /dev/null
@@ -0,0 +1,45 @@
+From e2765bbcb20d2f829bca85ced608692f6749f9f4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jun 2022 17:26:21 +0530
+Subject: ath11k: Fix incorrect debug_mask mappings
+
+From: Manikanta Pubbisetty <quic_mpubbise@quicinc.com>
+
+[ Upstream commit 9331f7d3c54a263bede5055e106e40b28d0bd937 ]
+
+Currently a couple of debug_mask entries are mapped to the same value,
+this could enable unintended driver logging. If enabling DP_TX logs was
+the intention, then this could also enable PCI logs flooding the dmesg
+buffer or vice versa. Fix this by correctly assigning the debug masks.
+
+Found during code review.
+
+Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1
+
+Fixes: aa2092a9bab3f ("ath11k: add raw mode and software crypto support")
+Signed-off-by: Manikanta Pubbisetty <quic_mpubbise@quicinc.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20220602115621.15339-1-quic_mpubbise@quicinc.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/debug.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath11k/debug.h b/drivers/net/wireless/ath/ath11k/debug.h
+index 659a275e2eb3..694ebba17fad 100644
+--- a/drivers/net/wireless/ath/ath11k/debug.h
++++ b/drivers/net/wireless/ath/ath11k/debug.h
+@@ -23,8 +23,8 @@ enum ath11k_debug_mask {
+       ATH11K_DBG_TESTMODE     = 0x00000400,
+       ATH11k_DBG_HAL          = 0x00000800,
+       ATH11K_DBG_PCI          = 0x00001000,
+-      ATH11K_DBG_DP_TX        = 0x00001000,
+-      ATH11K_DBG_DP_RX        = 0x00002000,
++      ATH11K_DBG_DP_TX        = 0x00002000,
++      ATH11K_DBG_DP_RX        = 0x00004000,
+       ATH11K_DBG_ANY          = 0xffffffff,
+ };
+-- 
+2.35.1
+
diff --git a/queue-5.15/ath11k-fix-netdev-open-race.patch b/queue-5.15/ath11k-fix-netdev-open-race.patch
new file mode 100644 (file)
index 0000000..acbb041
--- /dev/null
@@ -0,0 +1,109 @@
+From c106474541c85d6286b2468490bc2669ec0dea20 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 22 May 2022 15:33:16 +0300
+Subject: ath11k: fix netdev open race
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+[ Upstream commit d4ba1ff87b17e81686ada8f429300876f55f95ad ]
+
+Make sure to allocate resources needed before registering the device.
+
+This specifically avoids having a racing open() trigger a BUG_ON() in
+mod_timer() when ath11k_mac_op_start() is called before the
+mon_reap_timer as been set up.
+
+I did not see this issue with next-20220310, but I hit it on every probe
+with next-20220511. Perhaps some timing changed in between.
+
+Here's the backtrace:
+
+[   51.346947] kernel BUG at kernel/time/timer.c:990!
+[   51.346958] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP
+...
+[   51.578225] Call trace:
+[   51.583293]  __mod_timer+0x298/0x390
+[   51.589518]  mod_timer+0x14/0x20
+[   51.595368]  ath11k_mac_op_start+0x41c/0x4a0 [ath11k]
+[   51.603165]  drv_start+0x38/0x60 [mac80211]
+[   51.610110]  ieee80211_do_open+0x29c/0x7d0 [mac80211]
+[   51.617945]  ieee80211_open+0x60/0xb0 [mac80211]
+[   51.625311]  __dev_open+0x100/0x1c0
+[   51.631420]  __dev_change_flags+0x194/0x210
+[   51.638214]  dev_change_flags+0x24/0x70
+[   51.644646]  do_setlink+0x228/0xdb0
+[   51.650723]  __rtnl_newlink+0x460/0x830
+[   51.657162]  rtnl_newlink+0x4c/0x80
+[   51.663229]  rtnetlink_rcv_msg+0x124/0x390
+[   51.669917]  netlink_rcv_skb+0x58/0x130
+[   51.676314]  rtnetlink_rcv+0x18/0x30
+[   51.682460]  netlink_unicast+0x250/0x310
+[   51.688960]  netlink_sendmsg+0x19c/0x3e0
+[   51.695458]  ____sys_sendmsg+0x220/0x290
+[   51.701938]  ___sys_sendmsg+0x7c/0xc0
+[   51.708148]  __sys_sendmsg+0x68/0xd0
+[   51.714254]  __arm64_sys_sendmsg+0x28/0x40
+[   51.720900]  invoke_syscall+0x48/0x120
+
+Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3
+
+Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
+Fixes: 840c36fa727a ("ath11k: dp: stop rx pktlog before suspend")
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20220517103436.15867-1-johan+linaro@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/core.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c
+index 48b4151e13a3..48a449fbd2bc 100644
+--- a/drivers/net/wireless/ath/ath11k/core.c
++++ b/drivers/net/wireless/ath/ath11k/core.c
+@@ -699,23 +699,23 @@ static int ath11k_core_pdev_create(struct ath11k_base *ab)
+               return ret;
+       }
+-      ret = ath11k_mac_register(ab);
++      ret = ath11k_dp_pdev_alloc(ab);
+       if (ret) {
+-              ath11k_err(ab, "failed register the radio with mac80211: %d\n", ret);
++              ath11k_err(ab, "failed to attach DP pdev: %d\n", ret);
+               goto err_pdev_debug;
+       }
+-      ret = ath11k_dp_pdev_alloc(ab);
++      ret = ath11k_mac_register(ab);
+       if (ret) {
+-              ath11k_err(ab, "failed to attach DP pdev: %d\n", ret);
+-              goto err_mac_unregister;
++              ath11k_err(ab, "failed register the radio with mac80211: %d\n", ret);
++              goto err_dp_pdev_free;
+       }
+       ret = ath11k_thermal_register(ab);
+       if (ret) {
+               ath11k_err(ab, "could not register thermal device: %d\n",
+                          ret);
+-              goto err_dp_pdev_free;
++              goto err_mac_unregister;
+       }
+       ret = ath11k_spectral_init(ab);
+@@ -728,10 +728,10 @@ static int ath11k_core_pdev_create(struct ath11k_base *ab)
+ err_thermal_unregister:
+       ath11k_thermal_unregister(ab);
+-err_dp_pdev_free:
+-      ath11k_dp_pdev_free(ab);
+ err_mac_unregister:
+       ath11k_mac_unregister(ab);
++err_dp_pdev_free:
++      ath11k_dp_pdev_free(ab);
+ err_pdev_debug:
+       ath11k_debugfs_pdev_destroy(ab);
+-- 
+2.35.1
+
diff --git a/queue-5.15/ath9k-fix-use-after-free-in-ath9k_hif_usb_rx_cb.patch b/queue-5.15/ath9k-fix-use-after-free-in-ath9k_hif_usb_rx_cb.patch
new file mode 100644 (file)
index 0000000..478a586
--- /dev/null
@@ -0,0 +1,94 @@
+From b02f640a626d02f4aa7fb3445b79c0c2d2175194 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 21:43:59 +0300
+Subject: ath9k: fix use-after-free in ath9k_hif_usb_rx_cb
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pavel Skripkin <paskripkin@gmail.com>
+
+[ Upstream commit 0ac4827f78c7ffe8eef074bc010e7e34bc22f533 ]
+
+Syzbot reported use-after-free Read in ath9k_hif_usb_rx_cb() [0]. The
+problem was in incorrect htc_handle->drv_priv initialization.
+
+Probable call trace which can trigger use-after-free:
+
+ath9k_htc_probe_device()
+  /* htc_handle->drv_priv = priv; */
+  ath9k_htc_wait_for_target()      <--- Failed
+  ieee80211_free_hw()             <--- priv pointer is freed
+
+<IRQ>
+...
+ath9k_hif_usb_rx_cb()
+  ath9k_hif_usb_rx_stream()
+   RX_STAT_INC()               <--- htc_handle->drv_priv access
+
+In order to not add fancy protection for drv_priv we can move
+htc_handle->drv_priv initialization at the end of the
+ath9k_htc_probe_device() and add helper macro to make
+all *_STAT_* macros NULL safe, since syzbot has reported related NULL
+deref in that macros [1]
+
+Link: https://syzkaller.appspot.com/bug?id=6ead44e37afb6866ac0c7dd121b4ce07cb665f60 [0]
+Link: https://syzkaller.appspot.com/bug?id=b8101ffcec107c0567a0cd8acbbacec91e9ee8de [1]
+Fixes: fb9987d0f748 ("ath9k_htc: Support for AR9271 chipset.")
+Reported-and-tested-by: syzbot+03110230a11411024147@syzkaller.appspotmail.com
+Reported-and-tested-by: syzbot+c6dde1f690b60e0b9fbe@syzkaller.appspotmail.com
+Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
+Acked-by: Toke Høiland-Jørgensen <toke@toke.dk>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/d57bbedc857950659bfacac0ab48790c1eda00c8.1655145743.git.paskripkin@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath9k/htc.h          | 10 +++++-----
+ drivers/net/wireless/ath/ath9k/htc_drv_init.c |  3 ++-
+ 2 files changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
+index 6b45e63fae4b..e3d546ef71dd 100644
+--- a/drivers/net/wireless/ath/ath9k/htc.h
++++ b/drivers/net/wireless/ath/ath9k/htc.h
+@@ -327,11 +327,11 @@ static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb)
+ }
+ #ifdef CONFIG_ATH9K_HTC_DEBUGFS
+-
+-#define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++)
+-#define TX_STAT_ADD(c, a) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c += a)
+-#define RX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.skbrx_stats.c++)
+-#define RX_STAT_ADD(c, a) (hif_dev->htc_handle->drv_priv->debug.skbrx_stats.c += a)
++#define __STAT_SAFE(expr) (hif_dev->htc_handle->drv_priv ? (expr) : 0)
++#define TX_STAT_INC(c) __STAT_SAFE(hif_dev->htc_handle->drv_priv->debug.tx_stats.c++)
++#define TX_STAT_ADD(c, a) __STAT_SAFE(hif_dev->htc_handle->drv_priv->debug.tx_stats.c += a)
++#define RX_STAT_INC(c) __STAT_SAFE(hif_dev->htc_handle->drv_priv->debug.skbrx_stats.c++)
++#define RX_STAT_ADD(c, a) __STAT_SAFE(hif_dev->htc_handle->drv_priv->debug.skbrx_stats.c += a)
+ #define CAB_STAT_INC   priv->debug.tx_stats.cab_queued++
+ #define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++)
+diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+index ff61ae34ecdf..07ac88fb1c57 100644
+--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
++++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+@@ -944,7 +944,6 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
+       priv->hw = hw;
+       priv->htc = htc_handle;
+       priv->dev = dev;
+-      htc_handle->drv_priv = priv;
+       SET_IEEE80211_DEV(hw, priv->dev);
+       ret = ath9k_htc_wait_for_target(priv);
+@@ -965,6 +964,8 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
+       if (ret)
+               goto err_init;
++      htc_handle->drv_priv = priv;
++
+       return 0;
+ err_init:
+-- 
+2.35.1
+
diff --git a/queue-5.15/binder-fix-redefinition-of-seq_file-attributes.patch b/queue-5.15/binder-fix-redefinition-of-seq_file-attributes.patch
new file mode 100644 (file)
index 0000000..e8715dd
--- /dev/null
@@ -0,0 +1,346 @@
+From e810d6c2b5b1735d338c6d9b0c5177b4be13e1d5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 18:20:41 +0000
+Subject: binder: fix redefinition of seq_file attributes
+
+From: Carlos Llamas <cmllamas@google.com>
+
+[ Upstream commit b7e241bbff24f9e106bf616408fd58bcedc44bae ]
+
+The patchset in [1] exported some definitions to binder_internal.h in
+order to make the debugfs entries such as 'stats' and 'transaction_log'
+available in a binderfs instance. However, the DEFINE_SHOW_ATTRIBUTE
+macro expands into a static function/variable pair, which in turn get
+redefined each time a source file includes this internal header.
+
+This problem was made evident after a report from the kernel test robot
+<lkp@intel.com> where several W=1 build warnings are seen in downstream
+kernels. See the following example:
+
+  include/../drivers/android/binder_internal.h:111:23: warning: 'binder_stats_fops' defined but not used [-Wunused-const-variable=]
+     111 | DEFINE_SHOW_ATTRIBUTE(binder_stats);
+         |                       ^~~~~~~~~~~~
+  include/linux/seq_file.h:174:37: note: in definition of macro 'DEFINE_SHOW_ATTRIBUTE'
+     174 | static const struct file_operations __name ## _fops = {                 \
+         |                                     ^~~~~~
+
+This patch fixes the above issues by moving back the definitions into
+binder.c and instead creates an array of the debugfs entries which is
+more convenient to share with binderfs and iterate through.
+
+  [1] https://lore.kernel.org/all/20190903161655.107408-1-hridya@google.com/
+
+Fixes: 0e13e452dafc ("binder: Add stats, state and transactions files")
+Fixes: 03e2e07e3814 ("binder: Make transaction_log available in binderfs")
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Carlos Llamas <cmllamas@google.com>
+Link: https://lore.kernel.org/r/20220701182041.2134313-1-cmllamas@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/android/binder.c          | 114 +++++++++++++++++++++---------
+ drivers/android/binder_internal.h |  46 +++---------
+ drivers/android/binderfs.c        |  47 +++---------
+ 3 files changed, 100 insertions(+), 107 deletions(-)
+
+diff --git a/drivers/android/binder.c b/drivers/android/binder.c
+index 99ae919255f4..56a2387656a0 100644
+--- a/drivers/android/binder.c
++++ b/drivers/android/binder.c
+@@ -170,8 +170,32 @@ static inline void binder_stats_created(enum binder_stat_types type)
+       atomic_inc(&binder_stats.obj_created[type]);
+ }
+-struct binder_transaction_log binder_transaction_log;
+-struct binder_transaction_log binder_transaction_log_failed;
++struct binder_transaction_log_entry {
++      int debug_id;
++      int debug_id_done;
++      int call_type;
++      int from_proc;
++      int from_thread;
++      int target_handle;
++      int to_proc;
++      int to_thread;
++      int to_node;
++      int data_size;
++      int offsets_size;
++      int return_error_line;
++      uint32_t return_error;
++      uint32_t return_error_param;
++      char context_name[BINDERFS_MAX_NAME + 1];
++};
++
++struct binder_transaction_log {
++      atomic_t cur;
++      bool full;
++      struct binder_transaction_log_entry entry[32];
++};
++
++static struct binder_transaction_log binder_transaction_log;
++static struct binder_transaction_log binder_transaction_log_failed;
+ static struct binder_transaction_log_entry *binder_transaction_log_add(
+       struct binder_transaction_log *log)
+@@ -5801,8 +5825,7 @@ static void print_binder_proc_stats(struct seq_file *m,
+       print_binder_stats(m, "  ", &proc->stats);
+ }
+-
+-int binder_state_show(struct seq_file *m, void *unused)
++static int state_show(struct seq_file *m, void *unused)
+ {
+       struct binder_proc *proc;
+       struct binder_node *node;
+@@ -5841,7 +5864,7 @@ int binder_state_show(struct seq_file *m, void *unused)
+       return 0;
+ }
+-int binder_stats_show(struct seq_file *m, void *unused)
++static int stats_show(struct seq_file *m, void *unused)
+ {
+       struct binder_proc *proc;
+@@ -5857,7 +5880,7 @@ int binder_stats_show(struct seq_file *m, void *unused)
+       return 0;
+ }
+-int binder_transactions_show(struct seq_file *m, void *unused)
++static int transactions_show(struct seq_file *m, void *unused)
+ {
+       struct binder_proc *proc;
+@@ -5913,7 +5936,7 @@ static void print_binder_transaction_log_entry(struct seq_file *m,
+                       "\n" : " (incomplete)\n");
+ }
+-int binder_transaction_log_show(struct seq_file *m, void *unused)
++static int transaction_log_show(struct seq_file *m, void *unused)
+ {
+       struct binder_transaction_log *log = m->private;
+       unsigned int log_cur = atomic_read(&log->cur);
+@@ -5945,6 +5968,45 @@ const struct file_operations binder_fops = {
+       .release = binder_release,
+ };
++DEFINE_SHOW_ATTRIBUTE(state);
++DEFINE_SHOW_ATTRIBUTE(stats);
++DEFINE_SHOW_ATTRIBUTE(transactions);
++DEFINE_SHOW_ATTRIBUTE(transaction_log);
++
++const struct binder_debugfs_entry binder_debugfs_entries[] = {
++      {
++              .name = "state",
++              .mode = 0444,
++              .fops = &state_fops,
++              .data = NULL,
++      },
++      {
++              .name = "stats",
++              .mode = 0444,
++              .fops = &stats_fops,
++              .data = NULL,
++      },
++      {
++              .name = "transactions",
++              .mode = 0444,
++              .fops = &transactions_fops,
++              .data = NULL,
++      },
++      {
++              .name = "transaction_log",
++              .mode = 0444,
++              .fops = &transaction_log_fops,
++              .data = &binder_transaction_log,
++      },
++      {
++              .name = "failed_transaction_log",
++              .mode = 0444,
++              .fops = &transaction_log_fops,
++              .data = &binder_transaction_log_failed,
++      },
++      {} /* terminator */
++};
++
+ static int __init init_binder_device(const char *name)
+ {
+       int ret;
+@@ -5990,36 +6052,18 @@ static int __init binder_init(void)
+       atomic_set(&binder_transaction_log_failed.cur, ~0U);
+       binder_debugfs_dir_entry_root = debugfs_create_dir("binder", NULL);
+-      if (binder_debugfs_dir_entry_root)
++      if (binder_debugfs_dir_entry_root) {
++              const struct binder_debugfs_entry *db_entry;
++
++              binder_for_each_debugfs_entry(db_entry)
++                      debugfs_create_file(db_entry->name,
++                                          db_entry->mode,
++                                          binder_debugfs_dir_entry_root,
++                                          db_entry->data,
++                                          db_entry->fops);
++
+               binder_debugfs_dir_entry_proc = debugfs_create_dir("proc",
+                                                binder_debugfs_dir_entry_root);
+-
+-      if (binder_debugfs_dir_entry_root) {
+-              debugfs_create_file("state",
+-                                  0444,
+-                                  binder_debugfs_dir_entry_root,
+-                                  NULL,
+-                                  &binder_state_fops);
+-              debugfs_create_file("stats",
+-                                  0444,
+-                                  binder_debugfs_dir_entry_root,
+-                                  NULL,
+-                                  &binder_stats_fops);
+-              debugfs_create_file("transactions",
+-                                  0444,
+-                                  binder_debugfs_dir_entry_root,
+-                                  NULL,
+-                                  &binder_transactions_fops);
+-              debugfs_create_file("transaction_log",
+-                                  0444,
+-                                  binder_debugfs_dir_entry_root,
+-                                  &binder_transaction_log,
+-                                  &binder_transaction_log_fops);
+-              debugfs_create_file("failed_transaction_log",
+-                                  0444,
+-                                  binder_debugfs_dir_entry_root,
+-                                  &binder_transaction_log_failed,
+-                                  &binder_transaction_log_fops);
+       }
+       if (!IS_ENABLED(CONFIG_ANDROID_BINDERFS) &&
+diff --git a/drivers/android/binder_internal.h b/drivers/android/binder_internal.h
+index d6b6b8cb7346..1ade9799c8d5 100644
+--- a/drivers/android/binder_internal.h
++++ b/drivers/android/binder_internal.h
+@@ -107,41 +107,19 @@ static inline int __init init_binderfs(void)
+ }
+ #endif
+-int binder_stats_show(struct seq_file *m, void *unused);
+-DEFINE_SHOW_ATTRIBUTE(binder_stats);
+-
+-int binder_state_show(struct seq_file *m, void *unused);
+-DEFINE_SHOW_ATTRIBUTE(binder_state);
+-
+-int binder_transactions_show(struct seq_file *m, void *unused);
+-DEFINE_SHOW_ATTRIBUTE(binder_transactions);
+-
+-int binder_transaction_log_show(struct seq_file *m, void *unused);
+-DEFINE_SHOW_ATTRIBUTE(binder_transaction_log);
+-
+-struct binder_transaction_log_entry {
+-      int debug_id;
+-      int debug_id_done;
+-      int call_type;
+-      int from_proc;
+-      int from_thread;
+-      int target_handle;
+-      int to_proc;
+-      int to_thread;
+-      int to_node;
+-      int data_size;
+-      int offsets_size;
+-      int return_error_line;
+-      uint32_t return_error;
+-      uint32_t return_error_param;
+-      char context_name[BINDERFS_MAX_NAME + 1];
++struct binder_debugfs_entry {
++      const char *name;
++      umode_t mode;
++      const struct file_operations *fops;
++      void *data;
+ };
+-struct binder_transaction_log {
+-      atomic_t cur;
+-      bool full;
+-      struct binder_transaction_log_entry entry[32];
+-};
++extern const struct binder_debugfs_entry binder_debugfs_entries[];
++
++#define binder_for_each_debugfs_entry(entry)  \
++      for ((entry) = binder_debugfs_entries;  \
++           (entry)->name;                     \
++           (entry)++)
+ enum binder_stat_types {
+       BINDER_STAT_PROC,
+@@ -575,6 +553,4 @@ struct binder_object {
+       };
+ };
+-extern struct binder_transaction_log binder_transaction_log;
+-extern struct binder_transaction_log binder_transaction_log_failed;
+ #endif /* _LINUX_BINDER_INTERNAL_H */
+diff --git a/drivers/android/binderfs.c b/drivers/android/binderfs.c
+index e3605cdd4335..6d717ed76766 100644
+--- a/drivers/android/binderfs.c
++++ b/drivers/android/binderfs.c
+@@ -621,6 +621,7 @@ static int init_binder_features(struct super_block *sb)
+ static int init_binder_logs(struct super_block *sb)
+ {
+       struct dentry *binder_logs_root_dir, *dentry, *proc_log_dir;
++      const struct binder_debugfs_entry *db_entry;
+       struct binderfs_info *info;
+       int ret = 0;
+@@ -631,43 +632,15 @@ static int init_binder_logs(struct super_block *sb)
+               goto out;
+       }
+-      dentry = binderfs_create_file(binder_logs_root_dir, "stats",
+-                                    &binder_stats_fops, NULL);
+-      if (IS_ERR(dentry)) {
+-              ret = PTR_ERR(dentry);
+-              goto out;
+-      }
+-
+-      dentry = binderfs_create_file(binder_logs_root_dir, "state",
+-                                    &binder_state_fops, NULL);
+-      if (IS_ERR(dentry)) {
+-              ret = PTR_ERR(dentry);
+-              goto out;
+-      }
+-
+-      dentry = binderfs_create_file(binder_logs_root_dir, "transactions",
+-                                    &binder_transactions_fops, NULL);
+-      if (IS_ERR(dentry)) {
+-              ret = PTR_ERR(dentry);
+-              goto out;
+-      }
+-
+-      dentry = binderfs_create_file(binder_logs_root_dir,
+-                                    "transaction_log",
+-                                    &binder_transaction_log_fops,
+-                                    &binder_transaction_log);
+-      if (IS_ERR(dentry)) {
+-              ret = PTR_ERR(dentry);
+-              goto out;
+-      }
+-
+-      dentry = binderfs_create_file(binder_logs_root_dir,
+-                                    "failed_transaction_log",
+-                                    &binder_transaction_log_fops,
+-                                    &binder_transaction_log_failed);
+-      if (IS_ERR(dentry)) {
+-              ret = PTR_ERR(dentry);
+-              goto out;
++      binder_for_each_debugfs_entry(db_entry) {
++              dentry = binderfs_create_file(binder_logs_root_dir,
++                                            db_entry->name,
++                                            db_entry->fops,
++                                            db_entry->data);
++              if (IS_ERR(dentry)) {
++                      ret = PTR_ERR(dentry);
++                      goto out;
++              }
+       }
+       proc_log_dir = binderfs_create_dir(binder_logs_root_dir, "proc");
+-- 
+2.35.1
+
diff --git a/queue-5.15/blk-mq-don-t-create-hctx-debugfs-dir-until-q-debugfs.patch b/queue-5.15/blk-mq-don-t-create-hctx-debugfs-dir-until-q-debugfs.patch
new file mode 100644 (file)
index 0000000..4ef0090
--- /dev/null
@@ -0,0 +1,44 @@
+From b5145a2ad0acedf3d02677fc71d75616646a9059 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Jul 2022 17:08:08 +0800
+Subject: blk-mq: don't create hctx debugfs dir until q->debugfs_dir is created
+
+From: Ming Lei <ming.lei@redhat.com>
+
+[ Upstream commit f3ec5d11554778c24ac8915e847223ed71d104fc ]
+
+blk_mq_debugfs_register_hctx() can be called by blk_mq_update_nr_hw_queues
+when gendisk isn't added yet, such as nvme tcp.
+
+Fixes the warning of 'debugfs: Directory 'hctx0' with parent '/' already present!'
+which can be observed reliably when running blktests nvme/005.
+
+Fixes: 6cfc0081b046 ("blk-mq: no need to check return value of debugfs_create functions")
+Reported-by: Yi Zhang <yi.zhang@redhat.com>
+Signed-off-by: Ming Lei <ming.lei@redhat.com>
+Tested-by: Yi Zhang <yi.zhang@redhat.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Link: https://lore.kernel.org/r/20220711090808.259682-1-ming.lei@redhat.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-mq-debugfs.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/block/blk-mq-debugfs.c b/block/blk-mq-debugfs.c
+index 3b38d15723de..7023257a133d 100644
+--- a/block/blk-mq-debugfs.c
++++ b/block/blk-mq-debugfs.c
+@@ -879,6 +879,9 @@ void blk_mq_debugfs_register_hctx(struct request_queue *q,
+       char name[20];
+       int i;
++      if (!q->debugfs_dir)
++              return;
++
+       snprintf(name, sizeof(name), "hctx%u", hctx->queue_num);
+       hctx->debugfs_dir = debugfs_create_dir(name, q->debugfs_dir);
+-- 
+2.35.1
+
diff --git a/queue-5.15/blktrace-trace-remapped-requests-correctly.patch b/queue-5.15/blktrace-trace-remapped-requests-correctly.patch
new file mode 100644 (file)
index 0000000..405b1f3
--- /dev/null
@@ -0,0 +1,43 @@
+From dae42e6e08e76ff444895acc3fa34ab255061bc0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 11:06:36 -0700
+Subject: blktrace: Trace remapped requests correctly
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit 22c80aac882f712897b88b7ea8f5a74ea19019df ]
+
+Trace the remapped operation and its flags instead of only the data
+direction of remapped operations. This issue was detected by analyzing
+the warnings reported by sparse related to the new blk_opf_t type.
+
+Reviewed-by: Jun'ichi Nomura <junichi.nomura@nec.com>
+Cc: Mike Snitzer <snitzer@kernel.org>
+Cc: Mike Christie <michael.christie@oracle.com>
+Cc: Li Zefan <lizf@cn.fujitsu.com>
+Cc: Chaitanya Kulkarni <kch@nvidia.com>
+Fixes: 1b9a9ab78b0a ("blktrace: use op accessors")
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Link: https://lore.kernel.org/r/20220714180729.1065367-11-bvanassche@acm.org
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/blktrace.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
+index c42ff77eb6cc..eaa98e2b468f 100644
+--- a/kernel/trace/blktrace.c
++++ b/kernel/trace/blktrace.c
+@@ -1058,7 +1058,7 @@ static void blk_add_trace_rq_remap(void *ignore, struct request *rq, dev_t dev,
+       r.sector_from = cpu_to_be64(from);
+       __blk_add_trace(bt, blk_rq_pos(rq), blk_rq_bytes(rq),
+-                      rq_data_dir(rq), 0, BLK_TA_REMAP, 0,
++                      req_op(rq), rq->cmd_flags, BLK_TA_REMAP, 0,
+                       sizeof(r), &r, blk_trace_request_get_cgid(rq));
+       rcu_read_unlock();
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/block-bio-remove-duplicate-append-pages-code.patch b/queue-5.15/block-bio-remove-duplicate-append-pages-code.patch
new file mode 100644 (file)
index 0000000..971736d
--- /dev/null
@@ -0,0 +1,176 @@
+From 30122c839e01298ee1fa00e2121dabc57c462926 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jun 2022 12:58:21 -0700
+Subject: block/bio: remove duplicate append pages code
+
+From: Keith Busch <kbusch@kernel.org>
+
+[ Upstream commit c58c0074c54c2e2bb3bb0d5a4d8896bb660cc8bc ]
+
+The getting pages setup for zone append and normal IO are identical. Use
+common code for each.
+
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Link: https://lore.kernel.org/r/20220610195830.3574005-3-kbusch@fb.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/bio.c | 102 ++++++++++++++++++++++------------------------------
+ 1 file changed, 42 insertions(+), 60 deletions(-)
+
+diff --git a/block/bio.c b/block/bio.c
+index b117765d58c0..0dd7aa1797f6 100644
+--- a/block/bio.c
++++ b/block/bio.c
+@@ -1071,6 +1071,37 @@ static void bio_put_pages(struct page **pages, size_t size, size_t off)
+               put_page(pages[i]);
+ }
++static int bio_iov_add_page(struct bio *bio, struct page *page,
++              unsigned int len, unsigned int offset)
++{
++      bool same_page = false;
++
++      if (!__bio_try_merge_page(bio, page, len, offset, &same_page)) {
++              if (WARN_ON_ONCE(bio_full(bio, len)))
++                      return -EINVAL;
++              __bio_add_page(bio, page, len, offset);
++              return 0;
++      }
++
++      if (same_page)
++              put_page(page);
++      return 0;
++}
++
++static int bio_iov_add_zone_append_page(struct bio *bio, struct page *page,
++              unsigned int len, unsigned int offset)
++{
++      struct request_queue *q = bdev_get_queue(bio->bi_bdev);
++      bool same_page = false;
++
++      if (bio_add_hw_page(q, bio, page, len, offset,
++                      queue_max_zone_append_sectors(q), &same_page) != len)
++              return -EINVAL;
++      if (same_page)
++              put_page(page);
++      return 0;
++}
++
+ #define PAGE_PTRS_PER_BVEC     (sizeof(struct bio_vec) / sizeof(struct page *))
+ /**
+@@ -1089,7 +1120,6 @@ static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
+       unsigned short entries_left = bio->bi_max_vecs - bio->bi_vcnt;
+       struct bio_vec *bv = bio->bi_io_vec + bio->bi_vcnt;
+       struct page **pages = (struct page **)bv;
+-      bool same_page = false;
+       ssize_t size, left;
+       unsigned len, i;
+       size_t offset;
+@@ -1098,7 +1128,7 @@ static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
+        * Move page array up in the allocated memory for the bio vecs as far as
+        * possible so that we can start filling biovecs from the beginning
+        * without overwriting the temporary page array.
+-      */
++       */
+       BUILD_BUG_ON(PAGE_PTRS_PER_BVEC < 2);
+       pages += entries_left * (PAGE_PTRS_PER_BVEC - 1);
+@@ -1108,18 +1138,18 @@ static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
+       for (left = size, i = 0; left > 0; left -= len, i++) {
+               struct page *page = pages[i];
++              int ret;
+               len = min_t(size_t, PAGE_SIZE - offset, left);
++              if (bio_op(bio) == REQ_OP_ZONE_APPEND)
++                      ret = bio_iov_add_zone_append_page(bio, page, len,
++                                      offset);
++              else
++                      ret = bio_iov_add_page(bio, page, len, offset);
+-              if (__bio_try_merge_page(bio, page, len, offset, &same_page)) {
+-                      if (same_page)
+-                              put_page(page);
+-              } else {
+-                      if (WARN_ON_ONCE(bio_full(bio, len))) {
+-                              bio_put_pages(pages + i, left, offset);
+-                              return -EINVAL;
+-                      }
+-                      __bio_add_page(bio, page, len, offset);
++              if (ret) {
++                      bio_put_pages(pages + i, left, offset);
++                      return ret;
+               }
+               offset = 0;
+       }
+@@ -1128,51 +1158,6 @@ static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
+       return 0;
+ }
+-static int __bio_iov_append_get_pages(struct bio *bio, struct iov_iter *iter)
+-{
+-      unsigned short nr_pages = bio->bi_max_vecs - bio->bi_vcnt;
+-      unsigned short entries_left = bio->bi_max_vecs - bio->bi_vcnt;
+-      struct request_queue *q = bdev_get_queue(bio->bi_bdev);
+-      unsigned int max_append_sectors = queue_max_zone_append_sectors(q);
+-      struct bio_vec *bv = bio->bi_io_vec + bio->bi_vcnt;
+-      struct page **pages = (struct page **)bv;
+-      ssize_t size, left;
+-      unsigned len, i;
+-      size_t offset;
+-      int ret = 0;
+-
+-      /*
+-       * Move page array up in the allocated memory for the bio vecs as far as
+-       * possible so that we can start filling biovecs from the beginning
+-       * without overwriting the temporary page array.
+-       */
+-      BUILD_BUG_ON(PAGE_PTRS_PER_BVEC < 2);
+-      pages += entries_left * (PAGE_PTRS_PER_BVEC - 1);
+-
+-      size = iov_iter_get_pages(iter, pages, LONG_MAX, nr_pages, &offset);
+-      if (unlikely(size <= 0))
+-              return size ? size : -EFAULT;
+-
+-      for (left = size, i = 0; left > 0; left -= len, i++) {
+-              struct page *page = pages[i];
+-              bool same_page = false;
+-
+-              len = min_t(size_t, PAGE_SIZE - offset, left);
+-              if (bio_add_hw_page(q, bio, page, len, offset,
+-                              max_append_sectors, &same_page) != len) {
+-                      bio_put_pages(pages + i, left, offset);
+-                      ret = -EINVAL;
+-                      break;
+-              }
+-              if (same_page)
+-                      put_page(page);
+-              offset = 0;
+-      }
+-
+-      iov_iter_advance(iter, size - left);
+-      return ret;
+-}
+-
+ /**
+  * bio_iov_iter_get_pages - add user or kernel pages to a bio
+  * @bio: bio to add pages to
+@@ -1207,10 +1192,7 @@ int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
+       }
+       do {
+-              if (bio_op(bio) == REQ_OP_ZONE_APPEND)
+-                      ret = __bio_iov_append_get_pages(bio, iter);
+-              else
+-                      ret = __bio_iov_iter_get_pages(bio, iter);
++              ret = __bio_iov_iter_get_pages(bio, iter);
+       } while (!ret && iov_iter_count(iter) && !bio_full(bio, 0));
+       /* don't account direct I/O as memory stall */
+-- 
+2.35.1
+
diff --git a/queue-5.15/block-ensure-iov_iter-advances-for-added-pages.patch b/queue-5.15/block-ensure-iov_iter-advances-for-added-pages.patch
new file mode 100644 (file)
index 0000000..ea92f73
--- /dev/null
@@ -0,0 +1,64 @@
+From 409de64326b9d855a4a36f2ecb4054d9c174d603 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Jul 2022 08:32:54 -0700
+Subject: block: ensure iov_iter advances for added pages
+
+From: Keith Busch <kbusch@kernel.org>
+
+[ Upstream commit 325347d965e7ccf5424a05398807a6d801846612 ]
+
+There are cases where a bio may not accept additional pages, and the iov
+needs to advance to the last data length that was accepted. The zone
+append used to handle this correctly, but was inadvertently broken when
+the setup was made common with the normal r/w case.
+
+Fixes: 576ed9135489c ("block: use bio_add_page in bio_iov_iter_get_pages")
+Fixes: c58c0074c54c2 ("block/bio: remove duplicate append pages code")
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Link: https://lore.kernel.org/r/20220712153256.2202024-1-kbusch@fb.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/bio.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/block/bio.c b/block/bio.c
+index 0dd7aa1797f6..ba9120d4fe49 100644
+--- a/block/bio.c
++++ b/block/bio.c
+@@ -1123,6 +1123,7 @@ static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
+       ssize_t size, left;
+       unsigned len, i;
+       size_t offset;
++      int ret = 0;
+       /*
+        * Move page array up in the allocated memory for the bio vecs as far as
+@@ -1138,7 +1139,6 @@ static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
+       for (left = size, i = 0; left > 0; left -= len, i++) {
+               struct page *page = pages[i];
+-              int ret;
+               len = min_t(size_t, PAGE_SIZE - offset, left);
+               if (bio_op(bio) == REQ_OP_ZONE_APPEND)
+@@ -1149,13 +1149,13 @@ static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
+               if (ret) {
+                       bio_put_pages(pages + i, left, offset);
+-                      return ret;
++                      break;
+               }
+               offset = 0;
+       }
+-      iov_iter_advance(iter, size);
+-      return 0;
++      iov_iter_advance(iter, size - left);
++      return ret;
+ }
+ /**
+-- 
+2.35.1
+
diff --git a/queue-5.15/block-fix-infinite-loop-for-invalid-zone-append.patch b/queue-5.15/block-fix-infinite-loop-for-invalid-zone-append.patch
new file mode 100644 (file)
index 0000000..2945fbe
--- /dev/null
@@ -0,0 +1,45 @@
+From 8bdfac4e6eacf1e94322b0a8cc65598f5a4c6949 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jun 2022 12:58:20 -0700
+Subject: block: fix infinite loop for invalid zone append
+
+From: Keith Busch <kbusch@kernel.org>
+
+[ Upstream commit b82d9fa257cb3725c49d94d2aeafc4677c34448a ]
+
+Returning 0 early from __bio_iov_append_get_pages() for the
+max_append_sectors warning just creates an infinite loop since 0 means
+success, and the bio will never fill from the unadvancing iov_iter. We
+could turn the return into an error value, but it will already be turned
+into an error value later on, so just remove the warning. Clearly no one
+ever hit it anyway.
+
+Fixes: 0512a75b98f84 ("block: Introduce REQ_OP_ZONE_APPEND")
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Reviewed-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Link: https://lore.kernel.org/r/20220610195830.3574005-2-kbusch@fb.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/bio.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/block/bio.c b/block/bio.c
+index b8a8bfba714f..b117765d58c0 100644
+--- a/block/bio.c
++++ b/block/bio.c
+@@ -1141,9 +1141,6 @@ static int __bio_iov_append_get_pages(struct bio *bio, struct iov_iter *iter)
+       size_t offset;
+       int ret = 0;
+-      if (WARN_ON_ONCE(!max_append_sectors))
+-              return 0;
+-
+       /*
+        * Move page array up in the allocated memory for the bio vecs as far as
+        * possible so that we can start filling biovecs from the beginning
+-- 
+2.35.1
+
diff --git a/queue-5.15/block-rnbd-srv-set-keep_id-to-true-after-mutex_trylo.patch b/queue-5.15/block-rnbd-srv-set-keep_id-to-true-after-mutex_trylo.patch
new file mode 100644 (file)
index 0000000..b34455a
--- /dev/null
@@ -0,0 +1,46 @@
+From 9628c466b9827ac284d631effc4013b1d0e8e039 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Jul 2022 16:31:21 +0200
+Subject: block/rnbd-srv: Set keep_id to true after mutex_trylock
+
+From: Md Haris Iqbal <haris.iqbal@ionos.com>
+
+[ Upstream commit 4bc14f3101364877dd59085f39e068a2a7ec9f2d ]
+
+After setting keep_id if the mutex trylock fails, the keep_id stays set
+for the rest of the sess_dev lifetime.
+
+Therefore, set keep_id to true after mutex_trylock succeeds, so that a
+failure of trylock does'nt touch keep_id.
+
+Fixes: b168e1d85cf3 ("block/rnbd-srv: Prevent a deadlock generated by accessing sysfs in parallel")
+Cc: gi-oh.kim@ionos.com
+Signed-off-by: Md Haris Iqbal <haris.iqbal@ionos.com>
+Signed-off-by: Jack Wang <jinpu.wang@ionos.com>
+Link: https://lore.kernel.org/r/20220707143122.460362-2-haris.iqbal@ionos.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/rnbd/rnbd-srv.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/block/rnbd/rnbd-srv.c b/drivers/block/rnbd/rnbd-srv.c
+index 1ba1a93a6fe7..1896cde8135e 100644
+--- a/drivers/block/rnbd/rnbd-srv.c
++++ b/drivers/block/rnbd/rnbd-srv.c
+@@ -333,10 +333,11 @@ void rnbd_srv_sess_dev_force_close(struct rnbd_srv_sess_dev *sess_dev,
+ {
+       struct rnbd_srv_session *sess = sess_dev->sess;
+-      sess_dev->keep_id = true;
+       /* It is already started to close by client's close message. */
+       if (!mutex_trylock(&sess->lock))
+               return;
++
++      sess_dev->keep_id = true;
+       /* first remove sysfs itself to avoid deadlock */
+       sysfs_remove_file_self(&sess_dev->kobj, &attr->attr);
+       rnbd_srv_destroy_dev_session_sysfs(sess_dev);
+-- 
+2.35.1
+
diff --git a/queue-5.15/bluetooth-hci_intel-add-check-for-platform_driver_re.patch b/queue-5.15/bluetooth-hci_intel-add-check-for-platform_driver_re.patch
new file mode 100644 (file)
index 0000000..0b9e65a
--- /dev/null
@@ -0,0 +1,41 @@
+From e998993a67dcc3096b0615b8a81bbf7c28055b3e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jun 2022 09:24:36 +0800
+Subject: Bluetooth: hci_intel: Add check for platform_driver_register
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit ab2d2a982ff721f4b029282d9a40602ea46a745e ]
+
+As platform_driver_register() could fail, it should be better
+to deal with the return value in order to maintain the code
+consisitency.
+
+Fixes: 1ab1f239bf17 ("Bluetooth: hci_intel: Add support for platform driver")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/hci_intel.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/bluetooth/hci_intel.c b/drivers/bluetooth/hci_intel.c
+index 7249b91d9b91..78afb9a348e7 100644
+--- a/drivers/bluetooth/hci_intel.c
++++ b/drivers/bluetooth/hci_intel.c
+@@ -1217,7 +1217,11 @@ static struct platform_driver intel_driver = {
+ int __init intel_init(void)
+ {
+-      platform_driver_register(&intel_driver);
++      int err;
++
++      err = platform_driver_register(&intel_driver);
++      if (err)
++              return err;
+       return hci_uart_register_proto(&intel_proto);
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/bpf-fix-subprog-names-in-stack-traces.patch b/queue-5.15/bpf-fix-subprog-names-in-stack-traces.patch
new file mode 100644 (file)
index 0000000..ef0b65e
--- /dev/null
@@ -0,0 +1,50 @@
+From b8aea84230cc1c8ae44b39a6033aff5b46b5a28a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 14:16:37 -0700
+Subject: bpf: Fix subprog names in stack traces.
+
+From: Alexei Starovoitov <ast@kernel.org>
+
+[ Upstream commit 9c7c48d6a1e2eb5192ad5294c1c4dbd42a88e88b ]
+
+The commit 7337224fc150 ("bpf: Improve the info.func_info and info.func_info_rec_size behavior")
+accidently made bpf_prog_ksym_set_name() conservative for bpf subprograms.
+Fixed it so instead of "bpf_prog_tag_F" the stack traces print "bpf_prog_tag_full_subprog_name".
+
+Fixes: 7337224fc150 ("bpf: Improve the info.func_info and info.func_info_rec_size behavior")
+Reported-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Acked-by: Martin KaFai Lau <kafai@fb.com>
+Acked-by: Yonghong Song <yhs@fb.com>
+Link: https://lore.kernel.org/bpf/20220714211637.17150-1-alexei.starovoitov@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/verifier.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 346d36c905a9..c8b534a498b3 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -12445,6 +12445,7 @@ static int jit_subprogs(struct bpf_verifier_env *env)
+               /* Below members will be freed only at prog->aux */
+               func[i]->aux->btf = prog->aux->btf;
+               func[i]->aux->func_info = prog->aux->func_info;
++              func[i]->aux->func_info_cnt = prog->aux->func_info_cnt;
+               func[i]->aux->poke_tab = prog->aux->poke_tab;
+               func[i]->aux->size_poke_tab = prog->aux->size_poke_tab;
+@@ -12457,9 +12458,6 @@ static int jit_subprogs(struct bpf_verifier_env *env)
+                               poke->aux = func[i]->aux;
+               }
+-              /* Use bpf_prog_F_tag to indicate functions in stack traces.
+-               * Long term would need debug info to populate names
+-               */
+               func[i]->aux->name[0] = 'F';
+               func[i]->aux->stack_depth = env->subprog_info[i].stack_depth;
+               func[i]->jit_requested = 1;
+-- 
+2.35.1
+
diff --git a/queue-5.15/bus-hisi_lpc-fix-missing-platform_device_put-in-hisi.patch b/queue-5.15/bus-hisi_lpc-fix-missing-platform_device_put-in-hisi.patch
new file mode 100644 (file)
index 0000000..70c97c9
--- /dev/null
@@ -0,0 +1,75 @@
+From 767a5b49d67dc344dca0965fa5a7850bbf466645 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 17:43:52 +0800
+Subject: bus: hisi_lpc: fix missing platform_device_put() in
+ hisi_lpc_acpi_probe()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 54872fea6a5ac967ec2272aea525d1438ac6735a ]
+
+In error case in hisi_lpc_acpi_probe() after calling platform_device_add(),
+hisi_lpc_acpi_remove() can't release the failed 'pdev', so it will be leak,
+call platform_device_put() to fix this problem.
+I'v constructed this error case and tested this patch on D05 board.
+
+Fixes: 99c0228d6ff1 ("HISI LPC: Re-Add ACPI child enumeration support")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Acked-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bus/hisi_lpc.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/bus/hisi_lpc.c b/drivers/bus/hisi_lpc.c
+index 378f5d62a991..e7eaa8784fee 100644
+--- a/drivers/bus/hisi_lpc.c
++++ b/drivers/bus/hisi_lpc.c
+@@ -503,13 +503,13 @@ static int hisi_lpc_acpi_probe(struct device *hostdev)
+ {
+       struct acpi_device *adev = ACPI_COMPANION(hostdev);
+       struct acpi_device *child;
++      struct platform_device *pdev;
+       int ret;
+       /* Only consider the children of the host */
+       list_for_each_entry(child, &adev->children, node) {
+               const char *hid = acpi_device_hid(child);
+               const struct hisi_lpc_acpi_cell *cell;
+-              struct platform_device *pdev;
+               const struct resource *res;
+               bool found = false;
+               int num_res;
+@@ -571,22 +571,24 @@ static int hisi_lpc_acpi_probe(struct device *hostdev)
+               ret = platform_device_add_resources(pdev, res, num_res);
+               if (ret)
+-                      goto fail;
++                      goto fail_put_device;
+               ret = platform_device_add_data(pdev, cell->pdata,
+                                              cell->pdata_size);
+               if (ret)
+-                      goto fail;
++                      goto fail_put_device;
+               ret = platform_device_add(pdev);
+               if (ret)
+-                      goto fail;
++                      goto fail_put_device;
+               acpi_device_set_enumerated(child);
+       }
+       return 0;
++fail_put_device:
++      platform_device_put(pdev);
+ fail:
+       hisi_lpc_acpi_remove(hostdev);
+       return ret;
+-- 
+2.35.1
+
diff --git a/queue-5.15/can-error-specify-the-values-of-data-5.7-of-can-erro.patch b/queue-5.15/can-error-specify-the-values-of-data-5.7-of-can-erro.patch
new file mode 100644 (file)
index 0000000..7904369
--- /dev/null
@@ -0,0 +1,49 @@
+From 241ce6db544e287f9df054a66875a96668d6ec64 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 23:35:48 +0900
+Subject: can: error: specify the values of data[5..7] of CAN error frames
+
+From: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+
+[ Upstream commit e70a3263a7eed768d5f947b8f2aff8d2a79c9d97 ]
+
+Currently, data[5..7] of struct can_frame, when used as a CAN error
+frame, are defined as being "controller specific". Device specific
+behaviours are problematic because it prevents someone from writing
+code which is portable between devices.
+
+As a matter of fact, data[5] is never used, data[6] is always used to
+report TX error counter and data[7] is always used to report RX error
+counter. can-utils also relies on this.
+
+This patch updates the comment in the uapi header to specify that
+data[5] is reserved (and thus should not be used) and that data[6..7]
+are used for error counters.
+
+Fixes: 0d66548a10cb ("[CAN]: Add PF_CAN core module")
+Link: https://lore.kernel.org/all/20220719143550.3681-11-mailhol.vincent@wanadoo.fr
+Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/uapi/linux/can/error.h | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/include/uapi/linux/can/error.h b/include/uapi/linux/can/error.h
+index 34633283de64..a1000cb63063 100644
+--- a/include/uapi/linux/can/error.h
++++ b/include/uapi/linux/can/error.h
+@@ -120,6 +120,9 @@
+ #define CAN_ERR_TRX_CANL_SHORT_TO_GND  0x70 /* 0111 0000 */
+ #define CAN_ERR_TRX_CANL_SHORT_TO_CANH 0x80 /* 1000 0000 */
+-/* controller specific additional information / data[5..7] */
++/* data[5] is reserved (do not use) */
++
++/* TX error counter / data[6] */
++/* RX error counter / data[7] */
+ #endif /* _UAPI_CAN_ERROR_H */
+-- 
+2.35.1
+
diff --git a/queue-5.15/can-hi311x-do-not-report-txerr-and-rxerr-during-bus-.patch b/queue-5.15/can-hi311x-do-not-report-txerr-and-rxerr-during-bus-.patch
new file mode 100644 (file)
index 0000000..70b1225
--- /dev/null
@@ -0,0 +1,47 @@
+From efccec26a92048d8f7c41eb37c17d45e900825df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 23:35:43 +0900
+Subject: can: hi311x: do not report txerr and rxerr during bus-off
+
+From: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+
+[ Upstream commit a22bd630cfff496b270211745536e50e98eb3a45 ]
+
+During bus off, the error count is greater than 255 and can not fit in
+a u8.
+
+Fixes: 57e83fb9b746 ("can: hi311x: Add Holt HI-311x CAN driver")
+Link: https://lore.kernel.org/all/20220719143550.3681-6-mailhol.vincent@wanadoo.fr
+Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/spi/hi311x.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/can/spi/hi311x.c b/drivers/net/can/spi/hi311x.c
+index 89d9c986a229..b08b98e6ad1c 100644
+--- a/drivers/net/can/spi/hi311x.c
++++ b/drivers/net/can/spi/hi311x.c
+@@ -670,8 +670,6 @@ static irqreturn_t hi3110_can_ist(int irq, void *dev_id)
+                       txerr = hi3110_read(spi, HI3110_READ_TEC);
+                       rxerr = hi3110_read(spi, HI3110_READ_REC);
+-                      cf->data[6] = txerr;
+-                      cf->data[7] = rxerr;
+                       tx_state = txerr >= rxerr ? new_state : 0;
+                       rx_state = txerr <= rxerr ? new_state : 0;
+                       can_change_state(net, cf, tx_state, rx_state);
+@@ -684,6 +682,9 @@ static irqreturn_t hi3110_can_ist(int irq, void *dev_id)
+                                       hi3110_hw_sleep(spi);
+                                       break;
+                               }
++                      } else {
++                              cf->data[6] = txerr;
++                              cf->data[7] = rxerr;
+                       }
+               }
+-- 
+2.35.1
+
diff --git a/queue-5.15/can-kvaser_usb_hydra-do-not-report-txerr-and-rxerr-d.patch b/queue-5.15/can-kvaser_usb_hydra-do-not-report-txerr-and-rxerr-d.patch
new file mode 100644 (file)
index 0000000..dd42b3e
--- /dev/null
@@ -0,0 +1,55 @@
+From 774453fe97d09ff0a6441aacbf9fe6c98e724727 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 23:35:45 +0900
+Subject: can: kvaser_usb_hydra: do not report txerr and rxerr during bus-off
+
+From: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+
+[ Upstream commit 936e90595376e64b6247c72d3ea8b8b164b7ac96 ]
+
+During bus off, the error count is greater than 255 and can not fit in
+a u8.
+
+Fixes: aec5fb2268b7 ("can: kvaser_usb: Add support for Kvaser USB hydra family")
+Link: https://lore.kernel.org/all/20220719143550.3681-8-mailhol.vincent@wanadoo.fr
+CC: Jimmy Assarsson <extja@kvaser.com>
+Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
+index fce3f069cdbc..93d7ee6d17b6 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
+@@ -916,8 +916,10 @@ static void kvaser_usb_hydra_update_state(struct kvaser_usb_net_priv *priv,
+           new_state < CAN_STATE_BUS_OFF)
+               priv->can.can_stats.restarts++;
+-      cf->data[6] = bec->txerr;
+-      cf->data[7] = bec->rxerr;
++      if (new_state != CAN_STATE_BUS_OFF) {
++              cf->data[6] = bec->txerr;
++              cf->data[7] = bec->rxerr;
++      }
+       stats = &netdev->stats;
+       stats->rx_packets++;
+@@ -1071,8 +1073,10 @@ kvaser_usb_hydra_error_frame(struct kvaser_usb_net_priv *priv,
+       shhwtstamps->hwtstamp = hwtstamp;
+       cf->can_id |= CAN_ERR_BUSERROR;
+-      cf->data[6] = bec.txerr;
+-      cf->data[7] = bec.rxerr;
++      if (new_state != CAN_STATE_BUS_OFF) {
++              cf->data[6] = bec.txerr;
++              cf->data[7] = bec.rxerr;
++      }
+       stats->rx_packets++;
+       stats->rx_bytes += cf->len;
+-- 
+2.35.1
+
diff --git a/queue-5.15/can-kvaser_usb_leaf-do-not-report-txerr-and-rxerr-du.patch b/queue-5.15/can-kvaser_usb_leaf-do-not-report-txerr-and-rxerr-du.patch
new file mode 100644 (file)
index 0000000..4c5ab5c
--- /dev/null
@@ -0,0 +1,42 @@
+From f04e57fbaa7675f4fe342c236f7bf5c4faac77d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 23:35:46 +0900
+Subject: can: kvaser_usb_leaf: do not report txerr and rxerr during bus-off
+
+From: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+
+[ Upstream commit a57732084e06791d37ea1ea447cca46220737abd ]
+
+During bus off, the error count is greater than 255 and can not fit in
+a u8.
+
+Fixes: 7259124eac7d1 ("can: kvaser_usb: Split driver into kvaser_usb_core.c and kvaser_usb_leaf.c")
+Link: https://lore.kernel.org/all/20220719143550.3681-9-mailhol.vincent@wanadoo.fr
+CC: Jimmy Assarsson <extja@kvaser.com>
+Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+index b9c2231e4b43..05d54c4f929f 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+@@ -857,8 +857,10 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev,
+               break;
+       }
+-      cf->data[6] = es->txerr;
+-      cf->data[7] = es->rxerr;
++      if (new_state != CAN_STATE_BUS_OFF) {
++              cf->data[6] = es->txerr;
++              cf->data[7] = es->rxerr;
++      }
+       stats->rx_packets++;
+       stats->rx_bytes += cf->len;
+-- 
+2.35.1
+
diff --git a/queue-5.15/can-netlink-allow-configuring-of-fixed-bit-rates-wit.patch b/queue-5.15/can-netlink-allow-configuring-of-fixed-bit-rates-wit.patch
new file mode 100644 (file)
index 0000000..6cdcd73
--- /dev/null
@@ -0,0 +1,56 @@
+From 434995ebdb8341e5b273ff5195b718e80d563200 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Jun 2022 16:20:58 +0200
+Subject: can: netlink: allow configuring of fixed bit rates without need for
+ do_set_bittiming callback
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+[ Upstream commit 7e193a42c37cf40eba8ac5af2d5e8eeb8b9506f9 ]
+
+Usually CAN devices support configurable bit rates. The limits are
+defined by struct can_priv::bittiming_const. Another way is to
+implement the struct can_priv::do_set_bittiming callback.
+
+If the bit rate is configured via netlink, the can_changelink()
+function checks that either can_priv::bittiming_const or struct
+can_priv::do_set_bittiming is implemented.
+
+In commit 431af779256c ("can: dev: add CAN interface API for fixed
+bitrates") an API for configuring bit rates on CAN interfaces that
+only support fixed bit rates was added. The supported bit rates are
+defined by struct can_priv::bitrate_const.
+
+However the above mentioned commit forgot to add the struct
+can_priv::bitrate_const to the check in can_changelink().
+
+In order to avoid to implement a no-op can_priv::do_set_bittiming
+callback on devices with fixed bit rates, extend the check in
+can_changelink() accordingly.
+
+Link: https://lore.kernel.org/all/20220611144248.3924903-1-mkl@pengutronix.de
+Fixes: 431af779256c ("can: dev: add CAN interface API for fixed bitrates")
+Reported-by: Max Staudt <max@enpas.org>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/dev/netlink.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/can/dev/netlink.c b/drivers/net/can/dev/netlink.c
+index 80425636049d..cdde7fecefcf 100644
+--- a/drivers/net/can/dev/netlink.c
++++ b/drivers/net/can/dev/netlink.c
+@@ -76,7 +76,8 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[],
+                * directly via do_set_bitrate(). Bail out if neither
+                * is given.
+                */
+-              if (!priv->bittiming_const && !priv->do_set_bittiming)
++              if (!priv->bittiming_const && !priv->do_set_bittiming &&
++                  !priv->bitrate_const)
+                       return -EOPNOTSUPP;
+               memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt));
+-- 
+2.35.1
+
diff --git a/queue-5.15/can-netlink-allow-configuring-of-fixed-data-bit-rate.patch b/queue-5.15/can-netlink-allow-configuring-of-fixed-data-bit-rate.patch
new file mode 100644 (file)
index 0000000..60f6381
--- /dev/null
@@ -0,0 +1,60 @@
+From 6cf01d6e8395085a70b057e3cd15d9047400c53d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Jun 2022 16:20:58 +0200
+Subject: can: netlink: allow configuring of fixed data bit rates without need
+ for do_set_data_bittiming callback
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+[ Upstream commit ec30c109391c5eac9b1d689a61e4bfed88148947 ]
+
+This patch is similar to 7e193a42c37c ("can: netlink: allow
+configuring of fixed bit rates without need for do_set_bittiming
+callback") but for data bit rates instead of bit rates.
+
+Usually CAN devices support configurable data bit rates. The limits
+are defined by struct can_priv::data_bittiming_const. Another way is
+to implement the struct can_priv::do_set_data_bittiming callback.
+
+If the bit rate is configured via netlink, the can_changelink()
+function checks that either can_priv::data_bittiming_const or struct
+can_priv::do_set_data_bittiming is implemented.
+
+In commit 431af779256c ("can: dev: add CAN interface API for fixed
+bitrates") an API for configuring bit rates on CAN interfaces that
+only support fixed bit rates was added. The supported bit rates are
+defined by struct can_priv::bitrate_const.
+
+However the above mentioned commit forgot to add the struct
+can_priv::data_bitrate_const to the check in can_changelink().
+
+In order to avoid to implement a no-op can_priv::do_set_data_bittiming
+callback on devices with fixed data bit rates, extend the check in
+can_changelink() accordingly.
+
+Link: https://lore.kernel.org/all/20220613143633.4151884-1-mkl@pengutronix.de
+Fixes: 431af779256c ("can: dev: add CAN interface API for fixed bitrates")
+Acked-by: Max Staudt <max@enpas.org>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/dev/netlink.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/can/dev/netlink.c b/drivers/net/can/dev/netlink.c
+index cdde7fecefcf..29e2beae3357 100644
+--- a/drivers/net/can/dev/netlink.c
++++ b/drivers/net/can/dev/netlink.c
+@@ -170,7 +170,8 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[],
+                * directly via do_set_bitrate(). Bail out if neither
+                * is given.
+                */
+-              if (!priv->data_bittiming_const && !priv->do_set_data_bittiming)
++              if (!priv->data_bittiming_const && !priv->do_set_data_bittiming &&
++                  !priv->data_bitrate_const)
+                       return -EOPNOTSUPP;
+               memcpy(&dbt, nla_data(data[IFLA_CAN_DATA_BITTIMING]),
+-- 
+2.35.1
+
diff --git a/queue-5.15/can-pch_can-do-not-report-txerr-and-rxerr-during-bus.patch b/queue-5.15/can-pch_can-do-not-report-txerr-and-rxerr-during-bus.patch
new file mode 100644 (file)
index 0000000..245983f
--- /dev/null
@@ -0,0 +1,48 @@
+From 0725adaf5dc3ee557669ca33d677428795981411 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 23:35:39 +0900
+Subject: can: pch_can: do not report txerr and rxerr during bus-off
+
+From: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+
+[ Upstream commit 3a5c7e4611ddcf0ef37a3a17296b964d986161a6 ]
+
+During bus off, the error count is greater than 255 and can not fit in
+a u8.
+
+Fixes: 0c78ab76a05c ("pch_can: Add setting TEC/REC statistics processing")
+Link: https://lore.kernel.org/all/20220719143550.3681-2-mailhol.vincent@wanadoo.fr
+Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/pch_can.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c
+index 964c8a09226a..f20e75eb1ce0 100644
+--- a/drivers/net/can/pch_can.c
++++ b/drivers/net/can/pch_can.c
+@@ -496,6 +496,9 @@ static void pch_can_error(struct net_device *ndev, u32 status)
+               cf->can_id |= CAN_ERR_BUSOFF;
+               priv->can.can_stats.bus_off++;
+               can_bus_off(ndev);
++      } else {
++              cf->data[6] = errc & PCH_TEC;
++              cf->data[7] = (errc & PCH_REC) >> 8;
+       }
+       errc = ioread32(&priv->regs->errc);
+@@ -556,9 +559,6 @@ static void pch_can_error(struct net_device *ndev, u32 status)
+               break;
+       }
+-      cf->data[6] = errc & PCH_TEC;
+-      cf->data[7] = (errc & PCH_REC) >> 8;
+-
+       priv->can.state = state;
+       netif_receive_skb(skb);
+-- 
+2.35.1
+
diff --git a/queue-5.15/can-pch_can-pch_can_error-initialize-errc-before-usi.patch b/queue-5.15/can-pch_can-pch_can_error-initialize-errc-before-usi.patch
new file mode 100644 (file)
index 0000000..ae87c7b
--- /dev/null
@@ -0,0 +1,58 @@
+From f907e7ea2dd21fb0325625c989cfcb477fd07092 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Jul 2022 01:00:32 +0900
+Subject: can: pch_can: pch_can_error(): initialize errc before using it
+
+From: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+
+[ Upstream commit 9950f11211331180269867aef848c7cf56861742 ]
+
+After commit 3a5c7e4611dd, the variable errc is accessed before being
+initialized, c.f. below W=2 warning:
+
+| In function 'pch_can_error',
+|     inlined from 'pch_can_poll' at drivers/net/can/pch_can.c:739:4:
+| drivers/net/can/pch_can.c:501:29: warning: 'errc' may be used uninitialized [-Wmaybe-uninitialized]
+|   501 |                 cf->data[6] = errc & PCH_TEC;
+|       |                             ^
+| drivers/net/can/pch_can.c: In function 'pch_can_poll':
+| drivers/net/can/pch_can.c:484:13: note: 'errc' was declared here
+|   484 |         u32 errc, lec;
+|       |             ^~~~
+
+Moving errc initialization up solves this issue.
+
+Fixes: 3a5c7e4611dd ("can: pch_can: do not report txerr and rxerr during bus-off")
+Reported-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Reviewed-by: Nathan Chancellor <nathan@kernel.org>
+Link: https://lore.kernel.org/all/20220721160032.9348-1-mailhol.vincent@wanadoo.fr
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/pch_can.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c
+index f20e75eb1ce0..cd8d536c6fb2 100644
+--- a/drivers/net/can/pch_can.c
++++ b/drivers/net/can/pch_can.c
+@@ -489,6 +489,7 @@ static void pch_can_error(struct net_device *ndev, u32 status)
+       if (!skb)
+               return;
++      errc = ioread32(&priv->regs->errc);
+       if (status & PCH_BUS_OFF) {
+               pch_can_set_tx_all(priv, 0);
+               pch_can_set_rx_all(priv, 0);
+@@ -501,7 +502,6 @@ static void pch_can_error(struct net_device *ndev, u32 status)
+               cf->data[7] = (errc & PCH_REC) >> 8;
+       }
+-      errc = ioread32(&priv->regs->errc);
+       /* Warning interrupt. */
+       if (status & PCH_EWARN) {
+               state = CAN_STATE_ERROR_WARNING;
+-- 
+2.35.1
+
diff --git a/queue-5.15/can-rcar_can-do-not-report-txerr-and-rxerr-during-bu.patch b/queue-5.15/can-rcar_can-do-not-report-txerr-and-rxerr-during-bu.patch
new file mode 100644 (file)
index 0000000..7315f03
--- /dev/null
@@ -0,0 +1,51 @@
+From 397e4ced033ea7d5aab68d656adb55f38bbdd9d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 23:35:40 +0900
+Subject: can: rcar_can: do not report txerr and rxerr during bus-off
+
+From: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+
+[ Upstream commit a37b7245e831a641df360ca41db6a71c023d3746 ]
+
+During bus off, the error count is greater than 255 and can not fit in
+a u8.
+
+Fixes: fd1159318e55 ("can: add Renesas R-Car CAN driver")
+Link: https://lore.kernel.org/all/20220719143550.3681-3-mailhol.vincent@wanadoo.fr
+Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/rcar/rcar_can.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/can/rcar/rcar_can.c b/drivers/net/can/rcar/rcar_can.c
+index 8999ec9455ec..945b319de841 100644
+--- a/drivers/net/can/rcar/rcar_can.c
++++ b/drivers/net/can/rcar/rcar_can.c
+@@ -235,11 +235,8 @@ static void rcar_can_error(struct net_device *ndev)
+       if (eifr & (RCAR_CAN_EIFR_EWIF | RCAR_CAN_EIFR_EPIF)) {
+               txerr = readb(&priv->regs->tecr);
+               rxerr = readb(&priv->regs->recr);
+-              if (skb) {
++              if (skb)
+                       cf->can_id |= CAN_ERR_CRTL;
+-                      cf->data[6] = txerr;
+-                      cf->data[7] = rxerr;
+-              }
+       }
+       if (eifr & RCAR_CAN_EIFR_BEIF) {
+               int rx_errors = 0, tx_errors = 0;
+@@ -339,6 +336,9 @@ static void rcar_can_error(struct net_device *ndev)
+               can_bus_off(ndev);
+               if (skb)
+                       cf->can_id |= CAN_ERR_BUSOFF;
++      } else if (skb) {
++              cf->data[6] = txerr;
++              cf->data[7] = rxerr;
+       }
+       if (eifr & RCAR_CAN_EIFR_ORIF) {
+               netdev_dbg(priv->ndev, "Receive overrun error interrupt\n");
+-- 
+2.35.1
+
diff --git a/queue-5.15/can-sja1000-do-not-report-txerr-and-rxerr-during-bus.patch b/queue-5.15/can-sja1000-do-not-report-txerr-and-rxerr-during-bus.patch
new file mode 100644 (file)
index 0000000..107f119
--- /dev/null
@@ -0,0 +1,49 @@
+From 172d2f462b589a291ff28943e53cdbf3b41aa13c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 23:35:41 +0900
+Subject: can: sja1000: do not report txerr and rxerr during bus-off
+
+From: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+
+[ Upstream commit 164d7cb2d5a30f1b3a5ab4fab1a27731fb1494a8 ]
+
+During bus off, the error count is greater than 255 and can not fit in
+a u8.
+
+Fixes: 215db1856e83 ("can: sja1000: Consolidate and unify state change handling")
+Link: https://lore.kernel.org/all/20220719143550.3681-4-mailhol.vincent@wanadoo.fr
+Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/sja1000/sja1000.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
+index 3fad54646746..aae2677e24f9 100644
+--- a/drivers/net/can/sja1000/sja1000.c
++++ b/drivers/net/can/sja1000/sja1000.c
+@@ -404,9 +404,6 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
+       txerr = priv->read_reg(priv, SJA1000_TXERR);
+       rxerr = priv->read_reg(priv, SJA1000_RXERR);
+-      cf->data[6] = txerr;
+-      cf->data[7] = rxerr;
+-
+       if (isrc & IRQ_DOI) {
+               /* data overrun interrupt */
+               netdev_dbg(dev, "data overrun interrupt\n");
+@@ -428,6 +425,10 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
+               else
+                       state = CAN_STATE_ERROR_ACTIVE;
+       }
++      if (state != CAN_STATE_BUS_OFF) {
++              cf->data[6] = txerr;
++              cf->data[7] = rxerr;
++      }
+       if (isrc & IRQ_BEI) {
+               /* bus error interrupt */
+               priv->can.can_stats.bus_error++;
+-- 
+2.35.1
+
diff --git a/queue-5.15/can-sun4i_can-do-not-report-txerr-and-rxerr-during-b.patch b/queue-5.15/can-sun4i_can-do-not-report-txerr-and-rxerr-during-b.patch
new file mode 100644 (file)
index 0000000..cd66c56
--- /dev/null
@@ -0,0 +1,52 @@
+From 691cc152e6f50588fc7e5aa7e7046835847ebc6c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 23:35:44 +0900
+Subject: can: sun4i_can: do not report txerr and rxerr during bus-off
+
+From: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+
+[ Upstream commit 0ac15a8f661b941519379831d09bfb12271b23ee ]
+
+During bus off, the error count is greater than 255 and can not fit in
+a u8.
+
+Fixes: 0738eff14d81 ("can: Allwinner A10/A20 CAN Controller support - Kernel module")
+Link: https://lore.kernel.org/all/20220719143550.3681-7-mailhol.vincent@wanadoo.fr
+CC: Chen-Yu Tsai <wens@csie.org>
+Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/sun4i_can.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c
+index 54aa7c25c4de..ad8f50807aca 100644
+--- a/drivers/net/can/sun4i_can.c
++++ b/drivers/net/can/sun4i_can.c
+@@ -525,11 +525,6 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
+       rxerr = (errc >> 16) & 0xFF;
+       txerr = errc & 0xFF;
+-      if (skb) {
+-              cf->data[6] = txerr;
+-              cf->data[7] = rxerr;
+-      }
+-
+       if (isrc & SUN4I_INT_DATA_OR) {
+               /* data overrun interrupt */
+               netdev_dbg(dev, "data overrun interrupt\n");
+@@ -560,6 +555,10 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
+               else
+                       state = CAN_STATE_ERROR_ACTIVE;
+       }
++      if (skb && state != CAN_STATE_BUS_OFF) {
++              cf->data[6] = txerr;
++              cf->data[7] = rxerr;
++      }
+       if (isrc & SUN4I_INT_BUS_ERR) {
+               /* bus error interrupt */
+               netdev_dbg(dev, "bus error interrupt\n");
+-- 
+2.35.1
+
diff --git a/queue-5.15/can-usb_8dev-do-not-report-txerr-and-rxerr-during-bu.patch b/queue-5.15/can-usb_8dev-do-not-report-txerr-and-rxerr-during-bu.patch
new file mode 100644 (file)
index 0000000..02c8d5d
--- /dev/null
@@ -0,0 +1,42 @@
+From fb08ea02b2f7fc90633627ac54563b1f41b4d694 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 23:35:47 +0900
+Subject: can: usb_8dev: do not report txerr and rxerr during bus-off
+
+From: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+
+[ Upstream commit aebe8a2433cd090ccdc222861f44bddb75eb01de ]
+
+During bus off, the error count is greater than 255 and can not fit in
+a u8.
+
+Fixes: 0024d8ad1639 ("can: usb_8dev: Add support for USB2CAN interface from 8 devices")
+Link: https://lore.kernel.org/all/20220719143550.3681-10-mailhol.vincent@wanadoo.fr
+Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/usb_8dev.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/can/usb/usb_8dev.c b/drivers/net/can/usb/usb_8dev.c
+index d4c8f934a1ce..a5dee2ee2465 100644
+--- a/drivers/net/can/usb/usb_8dev.c
++++ b/drivers/net/can/usb/usb_8dev.c
+@@ -442,9 +442,10 @@ static void usb_8dev_rx_err_msg(struct usb_8dev_priv *priv,
+       if (rx_errors)
+               stats->rx_errors++;
+-
+-      cf->data[6] = txerr;
+-      cf->data[7] = rxerr;
++      if (priv->can.state != CAN_STATE_BUS_OFF) {
++              cf->data[6] = txerr;
++              cf->data[7] = rxerr;
++      }
+       priv->bec.txerr = txerr;
+       priv->bec.rxerr = rxerr;
+-- 
+2.35.1
+
diff --git a/queue-5.15/clk-mediatek-reset-fix-written-reset-bit-offset.patch b/queue-5.15/clk-mediatek-reset-fix-written-reset-bit-offset.patch
new file mode 100644 (file)
index 0000000..058e6b2
--- /dev/null
@@ -0,0 +1,56 @@
+From 364a84dad611cbc7622ddacce9a02b599ef5cff5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 May 2022 17:33:29 +0800
+Subject: clk: mediatek: reset: Fix written reset bit offset
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rex-BC Chen <rex-bc.chen@mediatek.com>
+
+[ Upstream commit edabcf71d100fd433a0fc2d0c97057c446c33b2a ]
+
+Original assert/deassert bit is BIT(0), but it's more resonable to modify
+them to BIT(id % 32) which is based on id.
+
+This patch will not influence any previous driver because the reset is
+only used for thermal. The id (MT8183_INFRACFG_AO_THERM_SW_RST) is 0.
+
+Fixes: 64ebb57a3df6 ("clk: reset: Modify reset-controller driver")
+Signed-off-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
+Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Tested-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Link: https://lore.kernel.org/r/20220523093346.28493-3-rex-bc.chen@mediatek.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/mediatek/reset.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/mediatek/reset.c b/drivers/clk/mediatek/reset.c
+index e562dc3c10a4..d311da574499 100644
+--- a/drivers/clk/mediatek/reset.c
++++ b/drivers/clk/mediatek/reset.c
+@@ -25,7 +25,7 @@ static int mtk_reset_assert_set_clr(struct reset_controller_dev *rcdev,
+       struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);
+       unsigned int reg = data->regofs + ((id / 32) << 4);
+-      return regmap_write(data->regmap, reg, 1);
++      return regmap_write(data->regmap, reg, BIT(id % 32));
+ }
+ static int mtk_reset_deassert_set_clr(struct reset_controller_dev *rcdev,
+@@ -34,7 +34,7 @@ static int mtk_reset_deassert_set_clr(struct reset_controller_dev *rcdev,
+       struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);
+       unsigned int reg = data->regofs + ((id / 32) << 4) + 0x4;
+-      return regmap_write(data->regmap, reg, 1);
++      return regmap_write(data->regmap, reg, BIT(id % 32));
+ }
+ static int mtk_reset_assert(struct reset_controller_dev *rcdev,
+-- 
+2.35.1
+
diff --git a/queue-5.15/clk-qcom-camcc-sdm845-fix-topology-around-titan_top-.patch b/queue-5.15/clk-qcom-camcc-sdm845-fix-topology-around-titan_top-.patch
new file mode 100644 (file)
index 0000000..d931280
--- /dev/null
@@ -0,0 +1,55 @@
+From a048ce240188f79c3636d32ddc6011ecf129fa9c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 May 2022 00:41:32 +0300
+Subject: clk: qcom: camcc-sdm845: Fix topology around titan_top power domain
+
+From: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
+
+[ Upstream commit 103dd2338bbff567bce7acd00fc5a09c806b38ec ]
+
+On SDM845 two found VFE GDSC power domains shall not be operated, if
+titan top is turned off, thus the former power domains will be set as
+subdomains by a GDSC registration routine.
+
+Fixes: 78412c262004 ("clk: qcom: Add camera clock controller driver for SDM845")
+Signed-off-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
+Reviewed-by: Robert Foss <robert.foss@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220519214133.1728979-2-vladimir.zapolskiy@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/camcc-sdm845.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/clk/qcom/camcc-sdm845.c b/drivers/clk/qcom/camcc-sdm845.c
+index 1b2cefef7431..a8a2cfa83290 100644
+--- a/drivers/clk/qcom/camcc-sdm845.c
++++ b/drivers/clk/qcom/camcc-sdm845.c
+@@ -1521,6 +1521,8 @@ static struct clk_branch cam_cc_sys_tmr_clk = {
+       },
+ };
++static struct gdsc titan_top_gdsc;
++
+ static struct gdsc bps_gdsc = {
+       .gdscr = 0x6004,
+       .pd = {
+@@ -1554,6 +1556,7 @@ static struct gdsc ife_0_gdsc = {
+               .name = "ife_0_gdsc",
+       },
+       .flags = POLL_CFG_GDSCR,
++      .parent = &titan_top_gdsc.pd,
+       .pwrsts = PWRSTS_OFF_ON,
+ };
+@@ -1563,6 +1566,7 @@ static struct gdsc ife_1_gdsc = {
+               .name = "ife_1_gdsc",
+       },
+       .flags = POLL_CFG_GDSCR,
++      .parent = &titan_top_gdsc.pd,
+       .pwrsts = PWRSTS_OFF_ON,
+ };
+-- 
+2.35.1
+
diff --git a/queue-5.15/clk-qcom-camcc-sm8250-fix-halt-on-boot-by-reducing-d.patch b/queue-5.15/clk-qcom-camcc-sm8250-fix-halt-on-boot-by-reducing-d.patch
new file mode 100644 (file)
index 0000000..9fe13c6
--- /dev/null
@@ -0,0 +1,55 @@
+From 875c213485f35191571680cb81472b48f6857ecf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 May 2022 13:35:54 +0300
+Subject: clk: qcom: camcc-sm8250: Fix halt on boot by reducing driver's init
+ level
+
+From: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
+
+[ Upstream commit c4f40351901a10cd662ac2c081396d8fb04f584d ]
+
+Access to I/O of SM8250 camera clock controller IP depends on enabled
+GCC_CAMERA_AHB_CLK clock supplied by global clock controller, the latter
+one is inited on subsys level, so, to satisfy the dependency, it would
+make sense to deprive the init level of camcc-sm8250 driver.
+
+If both drivers are compiled as built-in, there is a change that a board
+won't boot up due to a race, which happens on the same init level.
+
+Fixes: 5d66ca79b58c ("clk: qcom: Add camera clock controller driver for SM8250")
+Signed-off-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
+Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220518103554.949511-1-vladimir.zapolskiy@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/camcc-sm8250.c | 12 +-----------
+ 1 file changed, 1 insertion(+), 11 deletions(-)
+
+diff --git a/drivers/clk/qcom/camcc-sm8250.c b/drivers/clk/qcom/camcc-sm8250.c
+index 439eaafdcc86..ae4e9774f36e 100644
+--- a/drivers/clk/qcom/camcc-sm8250.c
++++ b/drivers/clk/qcom/camcc-sm8250.c
+@@ -2440,17 +2440,7 @@ static struct platform_driver cam_cc_sm8250_driver = {
+       },
+ };
+-static int __init cam_cc_sm8250_init(void)
+-{
+-      return platform_driver_register(&cam_cc_sm8250_driver);
+-}
+-subsys_initcall(cam_cc_sm8250_init);
+-
+-static void __exit cam_cc_sm8250_exit(void)
+-{
+-      platform_driver_unregister(&cam_cc_sm8250_driver);
+-}
+-module_exit(cam_cc_sm8250_exit);
++module_platform_driver(cam_cc_sm8250_driver);
+ MODULE_DESCRIPTION("QTI CAMCC SM8250 Driver");
+ MODULE_LICENSE("GPL v2");
+-- 
+2.35.1
+
diff --git a/queue-5.15/clk-qcom-camcc-sm8250-fix-topology-around-titan_top-.patch b/queue-5.15/clk-qcom-camcc-sm8250-fix-topology-around-titan_top-.patch
new file mode 100644 (file)
index 0000000..4adcea6
--- /dev/null
@@ -0,0 +1,55 @@
+From fc6c999304d250938f05fe9fd821d4e74f26c60b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 May 2022 00:41:33 +0300
+Subject: clk: qcom: camcc-sm8250: Fix topology around titan_top power domain
+
+From: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
+
+[ Upstream commit f8acf01a6a4f84baf05181e24bd48def4ba23f5b ]
+
+On SM8250 two found VFE GDSC power domains shall not be operated, if
+titan top is turned off, thus the former power domains will be set as
+subdomains by a GDSC registration routine.
+
+Fixes: 5d66ca79b58c ("clk: qcom: Add camera clock controller driver for SM8250")
+Signed-off-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
+Reviewed-by: Robert Foss <robert.foss@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220519214133.1728979-3-vladimir.zapolskiy@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/camcc-sm8250.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/clk/qcom/camcc-sm8250.c b/drivers/clk/qcom/camcc-sm8250.c
+index ae4e9774f36e..9b32c56a5bc5 100644
+--- a/drivers/clk/qcom/camcc-sm8250.c
++++ b/drivers/clk/qcom/camcc-sm8250.c
+@@ -2205,6 +2205,8 @@ static struct clk_branch cam_cc_sleep_clk = {
+       },
+ };
++static struct gdsc titan_top_gdsc;
++
+ static struct gdsc bps_gdsc = {
+       .gdscr = 0x7004,
+       .pd = {
+@@ -2238,6 +2240,7 @@ static struct gdsc ife_0_gdsc = {
+               .name = "ife_0_gdsc",
+       },
+       .flags = POLL_CFG_GDSCR,
++      .parent = &titan_top_gdsc.pd,
+       .pwrsts = PWRSTS_OFF_ON,
+ };
+@@ -2247,6 +2250,7 @@ static struct gdsc ife_1_gdsc = {
+               .name = "ife_1_gdsc",
+       },
+       .flags = POLL_CFG_GDSCR,
++      .parent = &titan_top_gdsc.pd,
+       .pwrsts = PWRSTS_OFF_ON,
+ };
+-- 
+2.35.1
+
diff --git a/queue-5.15/clk-qcom-clk-krait-unlock-spin-after-mux-completion.patch b/queue-5.15/clk-qcom-clk-krait-unlock-spin-after-mux-completion.patch
new file mode 100644 (file)
index 0000000..5059da0
--- /dev/null
@@ -0,0 +1,47 @@
+From 933173b852351f561187cea0e668c8ad71e9566d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 30 Apr 2022 07:44:57 +0200
+Subject: clk: qcom: clk-krait: unlock spin after mux completion
+
+From: Ansuel Smith <ansuelsmth@gmail.com>
+
+[ Upstream commit df83d2c9e72910416f650ade1e07cc314ff02731 ]
+
+Unlock spinlock after the mux switch is completed to prevent any corner
+case of mux request while the switch still needs to be done.
+
+Fixes: 4d7dc77babfe ("clk: qcom: Add support for Krait clocks")
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220430054458.31321-3-ansuelsmth@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/clk-krait.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/clk/qcom/clk-krait.c b/drivers/clk/qcom/clk-krait.c
+index 59f1af415b58..90046428693c 100644
+--- a/drivers/clk/qcom/clk-krait.c
++++ b/drivers/clk/qcom/clk-krait.c
+@@ -32,11 +32,16 @@ static void __krait_mux_set_sel(struct krait_mux_clk *mux, int sel)
+               regval |= (sel & mux->mask) << (mux->shift + LPL_SHIFT);
+       }
+       krait_set_l2_indirect_reg(mux->offset, regval);
+-      spin_unlock_irqrestore(&krait_clock_reg_lock, flags);
+       /* Wait for switch to complete. */
+       mb();
+       udelay(1);
++
++      /*
++       * Unlock now to make sure the mux register is not
++       * modified while switching to the new parent.
++       */
++      spin_unlock_irqrestore(&krait_clock_reg_lock, flags);
+ }
+ static int krait_mux_set_parent(struct clk_hw *hw, u8 index)
+-- 
+2.35.1
+
diff --git a/queue-5.15/clk-qcom-clk-rcg2-fail-duty-cycle-configuration-if-m.patch b/queue-5.15/clk-qcom-clk-rcg2-fail-duty-cycle-configuration-if-m.patch
new file mode 100644 (file)
index 0000000..62292cf
--- /dev/null
@@ -0,0 +1,53 @@
+From f3c78a6aa182cbc02e89be79289fe9a1bab5b455 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jun 2022 19:59:52 +0500
+Subject: clk: qcom: clk-rcg2: Fail Duty-Cycle configuration if MND divider is
+ not enabled.
+
+From: Nikita Travkin <nikita@trvn.ru>
+
+[ Upstream commit bdafb609c3bb848d710ad9cd4debd2ee9d6a4049 ]
+
+In cases when MND is not enabled (e.g. when only Half Integer Divider is
+used), setting D registers makes no effect.
+
+Fail instead of making ineffective write.
+
+Fixes: 7f891faf596e ("clk: qcom: clk-rcg2: Add support for duty-cycle for RCG")
+Signed-off-by: Nikita Travkin <nikita@trvn.ru>
+Reviewed-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220612145955.385787-2-nikita@trvn.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/clk-rcg2.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
+index f675fd969c4d..ebdbc842b98a 100644
+--- a/drivers/clk/qcom/clk-rcg2.c
++++ b/drivers/clk/qcom/clk-rcg2.c
+@@ -405,7 +405,7 @@ static int clk_rcg2_get_duty_cycle(struct clk_hw *hw, struct clk_duty *duty)
+ static int clk_rcg2_set_duty_cycle(struct clk_hw *hw, struct clk_duty *duty)
+ {
+       struct clk_rcg2 *rcg = to_clk_rcg2(hw);
+-      u32 notn_m, n, m, d, not2d, mask, duty_per;
++      u32 notn_m, n, m, d, not2d, mask, duty_per, cfg;
+       int ret;
+       /* Duty-cycle cannot be modified for non-MND RCGs */
+@@ -416,6 +416,11 @@ static int clk_rcg2_set_duty_cycle(struct clk_hw *hw, struct clk_duty *duty)
+       regmap_read(rcg->clkr.regmap, RCG_N_OFFSET(rcg), &notn_m);
+       regmap_read(rcg->clkr.regmap, RCG_M_OFFSET(rcg), &m);
++      regmap_read(rcg->clkr.regmap, RCG_CFG_OFFSET(rcg), &cfg);
++
++      /* Duty-cycle cannot be modified if MND divider is in bypass mode. */
++      if (!(cfg & CFG_MODE_MASK))
++              return -EINVAL;
+       n = (~(notn_m) + m) & mask;
+-- 
+2.35.1
+
diff --git a/queue-5.15/clk-qcom-clk-rcg2-make-sure-to-not-write-d-0-to-the-.patch b/queue-5.15/clk-qcom-clk-rcg2-make-sure-to-not-write-d-0-to-the-.patch
new file mode 100644 (file)
index 0000000..0dd20cd
--- /dev/null
@@ -0,0 +1,57 @@
+From e0db49c6a8ef957f52c0101d51e7e5a89a041dd5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jun 2022 19:59:53 +0500
+Subject: clk: qcom: clk-rcg2: Make sure to not write d=0 to the NMD register
+
+From: Nikita Travkin <nikita@trvn.ru>
+
+[ Upstream commit d0696770cef35a1fd16ea2167e2198c18aa6fbfe ]
+
+Sometimes calculation of d value may result in 0 because of the
+rounding after integer division. This causes the following error:
+
+[  113.969689] camss_gp1_clk_src: rcg didn't update its configuration.
+[  113.969754] WARNING: CPU: 3 PID: 35 at drivers/clk/qcom/clk-rcg2.c:122 update_config+0xc8/0xdc
+
+Make sure that D value is never zero.
+
+Fixes: 7f891faf596e ("clk: qcom: clk-rcg2: Add support for duty-cycle for RCG")
+Signed-off-by: Nikita Travkin <nikita@trvn.ru>
+Reviewed-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220612145955.385787-3-nikita@trvn.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/clk-rcg2.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
+index ebdbc842b98a..c3823cc32edc 100644
+--- a/drivers/clk/qcom/clk-rcg2.c
++++ b/drivers/clk/qcom/clk-rcg2.c
+@@ -13,6 +13,7 @@
+ #include <linux/rational.h>
+ #include <linux/regmap.h>
+ #include <linux/math64.h>
++#include <linux/minmax.h>
+ #include <linux/slab.h>
+ #include <asm/div64.h>
+@@ -429,9 +430,11 @@ static int clk_rcg2_set_duty_cycle(struct clk_hw *hw, struct clk_duty *duty)
+       /* Calculate 2d value */
+       d = DIV_ROUND_CLOSEST(n * duty_per * 2, 100);
+-       /* Check bit widths of 2d. If D is too big reduce duty cycle. */
+-      if (d > mask)
+-              d = mask;
++      /*
++       * Check bit widths of 2d. If D is too big reduce duty cycle.
++       * Also make sure it is never zero.
++       */
++      d = clamp_val(d, 1, mask);
+       if ((d / 2) > (n - m))
+               d = (n - m) * 2;
+-- 
+2.35.1
+
diff --git a/queue-5.15/clk-qcom-gcc-msm8939-add-missing-system_mm_noc_bfdcd.patch b/queue-5.15/clk-qcom-gcc-msm8939-add-missing-system_mm_noc_bfdcd.patch
new file mode 100644 (file)
index 0000000..65274de
--- /dev/null
@@ -0,0 +1,42 @@
+From 25ec9601405fbfe3295fac6c84390639b2ac75d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 May 2022 17:38:32 +0100
+Subject: clk: qcom: gcc-msm8939: Add missing SYSTEM_MM_NOC_BFDCD_CLK_SRC
+
+From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+
+[ Upstream commit 07e7fcf1714c5f9930ad27613fea940aedba68da ]
+
+When adding in the indexes for this clock-controller we missed
+SYSTEM_MM_NOC_BFDCD_CLK_SRC.
+
+Add it in now.
+
+Fixes: 4c71d6abc4fc ("clk: qcom: Add DT bindings for MSM8939 GCC")
+Cc: Rob Herring <robh+dt@kernel.org>
+Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
+Cc: devicetree@vger.kernel.org
+Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220504163835.40130-2-bryan.odonoghue@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/dt-bindings/clock/qcom,gcc-msm8939.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/include/dt-bindings/clock/qcom,gcc-msm8939.h b/include/dt-bindings/clock/qcom,gcc-msm8939.h
+index 0634467c4ce5..2d545ed0d35a 100644
+--- a/include/dt-bindings/clock/qcom,gcc-msm8939.h
++++ b/include/dt-bindings/clock/qcom,gcc-msm8939.h
+@@ -192,6 +192,7 @@
+ #define GCC_VENUS0_CORE0_VCODEC0_CLK          183
+ #define GCC_VENUS0_CORE1_VCODEC0_CLK          184
+ #define GCC_OXILI_TIMER_CLK                   185
++#define SYSTEM_MM_NOC_BFDCD_CLK_SRC           186
+ /* Indexes for GDSCs */
+ #define BIMC_GDSC                             0
+-- 
+2.35.1
+
diff --git a/queue-5.15/clk-qcom-gcc-msm8939-add-missing-system_mm_noc_bfdcd.patch-18441 b/queue-5.15/clk-qcom-gcc-msm8939-add-missing-system_mm_noc_bfdcd.patch-18441
new file mode 100644 (file)
index 0000000..99b07ce
--- /dev/null
@@ -0,0 +1,61 @@
+From 595e5482f050da62da5353d3c753ed4b3257fdb7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 May 2022 17:38:34 +0100
+Subject: clk: qcom: gcc-msm8939: Add missing system_mm_noc_bfdcd_clk_src
+
+From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+
+[ Upstream commit dd363e2f7196278e7a30f509a0e8a841cb763b14 ]
+
+The msm8939 has an additional higher operating point for the multi-media
+peripherals. The higher throughput MM componets operate off of the
+system-mm noc not the system noc.
+
+system_mm_noc_bfdcd_clk_src is the source clock for the higher frequency
+capable system noc mm.
+
+Maximum frequency for the MM SNOC is 400 MHz.
+
+Fixes: 1664014e4679 ("clk: qcom: gcc-msm8939: Add MSM8939 Generic Clock Controller")
+Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220504163835.40130-4-bryan.odonoghue@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-msm8939.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/drivers/clk/qcom/gcc-msm8939.c b/drivers/clk/qcom/gcc-msm8939.c
+index 31568658d23d..12bab9067ea8 100644
+--- a/drivers/clk/qcom/gcc-msm8939.c
++++ b/drivers/clk/qcom/gcc-msm8939.c
+@@ -644,6 +644,18 @@ static struct clk_rcg2 bimc_ddr_clk_src = {
+       },
+ };
++static struct clk_rcg2 system_mm_noc_bfdcd_clk_src = {
++      .cmd_rcgr = 0x2600c,
++      .hid_width = 5,
++      .parent_map = gcc_xo_gpll0_gpll6a_map,
++      .clkr.hw.init = &(struct clk_init_data){
++              .name = "system_mm_noc_bfdcd_clk_src",
++              .parent_data = gcc_xo_gpll0_gpll6a_parent_data,
++              .num_parents = 3,
++              .ops = &clk_rcg2_ops,
++      },
++};
++
+ static const struct freq_tbl ftbl_gcc_camss_ahb_clk[] = {
+       F(40000000, P_GPLL0, 10, 1, 2),
+       F(80000000, P_GPLL0, 10, 0, 0),
+@@ -3623,6 +3635,7 @@ static struct clk_regmap *gcc_msm8939_clocks[] = {
+       [GPLL2_VOTE] = &gpll2_vote,
+       [PCNOC_BFDCD_CLK_SRC] = &pcnoc_bfdcd_clk_src.clkr,
+       [SYSTEM_NOC_BFDCD_CLK_SRC] = &system_noc_bfdcd_clk_src.clkr,
++      [SYSTEM_MM_NOC_BFDCD_CLK_SRC] = &system_mm_noc_bfdcd_clk_src.clkr,
+       [CAMSS_AHB_CLK_SRC] = &camss_ahb_clk_src.clkr,
+       [APSS_AHB_CLK_SRC] = &apss_ahb_clk_src.clkr,
+       [CSI0_CLK_SRC] = &csi0_clk_src.clkr,
+-- 
+2.35.1
+
diff --git a/queue-5.15/clk-qcom-gcc-msm8939-fix-bimc_ddr_clk_src-rcgr-base-.patch b/queue-5.15/clk-qcom-gcc-msm8939-fix-bimc_ddr_clk_src-rcgr-base-.patch
new file mode 100644 (file)
index 0000000..8745fd1
--- /dev/null
@@ -0,0 +1,37 @@
+From 89c67910b66956c701fd768fcdf730bf0c82927c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 May 2022 17:38:33 +0100
+Subject: clk: qcom: gcc-msm8939: Fix bimc_ddr_clk_src rcgr base address
+
+From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+
+[ Upstream commit 63d42708320d6d2ca9ed505123d50ff4a542c36f ]
+
+Reviewing qcom docs for the 8939 we can see the command rcgr is pointing to
+the wrong address. bimc_ddr_clk_src_rcgr is @ 0x01832024 not 0x01832004.
+
+Fixes: 1664014e4679 ("clk: qcom: gcc-msm8939: Add MSM8939 Generic Clock Controller")
+Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220504163835.40130-3-bryan.odonoghue@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-msm8939.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/qcom/gcc-msm8939.c b/drivers/clk/qcom/gcc-msm8939.c
+index 39ebb443ae3d..31568658d23d 100644
+--- a/drivers/clk/qcom/gcc-msm8939.c
++++ b/drivers/clk/qcom/gcc-msm8939.c
+@@ -632,7 +632,7 @@ static struct clk_rcg2 system_noc_bfdcd_clk_src = {
+ };
+ static struct clk_rcg2 bimc_ddr_clk_src = {
+-      .cmd_rcgr = 0x32004,
++      .cmd_rcgr = 0x32024,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_bimc_map,
+       .clkr.hw.init = &(struct clk_init_data){
+-- 
+2.35.1
+
diff --git a/queue-5.15/clk-qcom-gcc-msm8939-fix-weird-field-spacing-in-ftbl.patch b/queue-5.15/clk-qcom-gcc-msm8939-fix-weird-field-spacing-in-ftbl.patch
new file mode 100644 (file)
index 0000000..aefe8d7
--- /dev/null
@@ -0,0 +1,39 @@
+From 72c12eb4d7531c89b7f3ce9e257fbf6eebbbdb47 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Jul 2022 13:59:17 +0100
+Subject: clk: qcom: gcc-msm8939: Fix weird field spacing in
+ ftbl_gcc_camss_cci_clk
+
+From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+
+[ Upstream commit 2bc308ebc453ba22f3f120f777b9ac48f973ee80 ]
+
+Adding a new item to this frequency table I see the existing indentation is
+incorrect.
+
+Fixes: 1664014e4679 ("clk: qcom: gcc-msm8939: Add MSM8939 Generic Clock Controller")
+Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220712125922.3461675-2-bryan.odonoghue@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-msm8939.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/qcom/gcc-msm8939.c b/drivers/clk/qcom/gcc-msm8939.c
+index c7377ec0f423..de0022e5450d 100644
+--- a/drivers/clk/qcom/gcc-msm8939.c
++++ b/drivers/clk/qcom/gcc-msm8939.c
+@@ -1014,7 +1014,7 @@ static struct clk_rcg2 blsp1_uart2_apps_clk_src = {
+ };
+ static const struct freq_tbl ftbl_gcc_camss_cci_clk[] = {
+-      F(19200000,     P_XO, 1, 0,     0),
++      F(19200000, P_XO, 1, 0, 0),
+       { }
+ };
+-- 
+2.35.1
+
diff --git a/queue-5.15/clk-qcom-gcc-msm8939-point-mm-peripherals-to-system_.patch b/queue-5.15/clk-qcom-gcc-msm8939-point-mm-peripherals-to-system_.patch
new file mode 100644 (file)
index 0000000..3cbb2c3
--- /dev/null
@@ -0,0 +1,107 @@
+From cdfe8bc3d82e95056171f78cba9f6dac0591e1b9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 May 2022 17:38:35 +0100
+Subject: clk: qcom: gcc-msm8939: Point MM peripherals to system_mm_noc clock
+
+From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+
+[ Upstream commit 05eed0990927aa9634682fec58660e30f7b7ae30 ]
+
+Qcom docs indciate the following peripherals operating from System NOC
+MM not from System NOC clocks.
+
+- MDP
+- VFE
+- JPEGe
+- Venus
+
+Switch over the relevant parent pointers.
+
+Fixes: 1664014e4679 ("clk: qcom: gcc-msm8939: Add MSM8939 Generic Clock Controller")
+Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220504163835.40130-5-bryan.odonoghue@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-msm8939.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/clk/qcom/gcc-msm8939.c b/drivers/clk/qcom/gcc-msm8939.c
+index 12bab9067ea8..c7377ec0f423 100644
+--- a/drivers/clk/qcom/gcc-msm8939.c
++++ b/drivers/clk/qcom/gcc-msm8939.c
+@@ -2453,7 +2453,7 @@ static struct clk_branch gcc_camss_jpeg_axi_clk = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_jpeg_axi_clk",
+                       .parent_data = &(const struct clk_parent_data){
+-                              .hw = &system_noc_bfdcd_clk_src.clkr.hw,
++                              .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+@@ -2657,7 +2657,7 @@ static struct clk_branch gcc_camss_vfe_axi_clk = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_vfe_axi_clk",
+                       .parent_data = &(const struct clk_parent_data){
+-                              .hw = &system_noc_bfdcd_clk_src.clkr.hw,
++                              .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+@@ -2813,7 +2813,7 @@ static struct clk_branch gcc_mdss_axi_clk = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mdss_axi_clk",
+                       .parent_data = &(const struct clk_parent_data){
+-                              .hw = &system_noc_bfdcd_clk_src.clkr.hw,
++                              .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+@@ -3205,7 +3205,7 @@ static struct clk_branch gcc_mdp_tbu_clk = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mdp_tbu_clk",
+                       .parent_data = &(const struct clk_parent_data){
+-                              .hw = &system_noc_bfdcd_clk_src.clkr.hw,
++                              .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+@@ -3223,7 +3223,7 @@ static struct clk_branch gcc_venus_tbu_clk = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_venus_tbu_clk",
+                       .parent_data = &(const struct clk_parent_data){
+-                              .hw = &system_noc_bfdcd_clk_src.clkr.hw,
++                              .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+@@ -3241,7 +3241,7 @@ static struct clk_branch gcc_vfe_tbu_clk = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_vfe_tbu_clk",
+                       .parent_data = &(const struct clk_parent_data){
+-                              .hw = &system_noc_bfdcd_clk_src.clkr.hw,
++                              .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+@@ -3259,7 +3259,7 @@ static struct clk_branch gcc_jpeg_tbu_clk = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_jpeg_tbu_clk",
+                       .parent_data = &(const struct clk_parent_data){
+-                              .hw = &system_noc_bfdcd_clk_src.clkr.hw,
++                              .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+@@ -3496,7 +3496,7 @@ static struct clk_branch gcc_venus0_axi_clk = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_venus0_axi_clk",
+                       .parent_data = &(const struct clk_parent_data){
+-                              .hw = &system_noc_bfdcd_clk_src.clkr.hw,
++                              .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+-- 
+2.35.1
+
diff --git a/queue-5.15/clk-qcom-ipq8074-fix-nss-core-pll-s.patch b/queue-5.15/clk-qcom-ipq8074-fix-nss-core-pll-s.patch
new file mode 100644 (file)
index 0000000..91af55d
--- /dev/null
@@ -0,0 +1,92 @@
+From 41779a6055668b8752be8f97bbd1b03f7aaf6769 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 15 May 2022 23:00:38 +0200
+Subject: clk: qcom: ipq8074: fix NSS core PLL-s
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Robert Marko <robimarko@gmail.com>
+
+[ Upstream commit ca41ec1b30434636c56c5600b24a8d964d359d9c ]
+
+Like in IPQ6018 the NSS related Alpha PLL-s require initial configuration
+to work.
+
+So, obtain the regmap that is required for the Alpha PLL configuration
+and thus utilize the qcom_cc_really_probe() as we already have the regmap.
+Then utilize the Alpha PLL configs from the downstream QCA 5.4 based
+kernel to configure them.
+
+This fixes the UBI32 and NSS crypto PLL-s failing to get enabled by the
+kernel.
+
+Fixes: b8e7e519625f ("clk: qcom: ipq8074: add remaining PLL’s")
+Signed-off-by: Robert Marko <robimarko@gmail.com>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220515210048.483898-1-robimarko@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-ipq8074.c | 39 +++++++++++++++++++++++++++++++++-
+ 1 file changed, 38 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c
+index 541016db3c4b..1a5141da7e23 100644
+--- a/drivers/clk/qcom/gcc-ipq8074.c
++++ b/drivers/clk/qcom/gcc-ipq8074.c
+@@ -4371,6 +4371,33 @@ static struct clk_branch gcc_pcie0_axi_s_bridge_clk = {
+       },
+ };
++static const struct alpha_pll_config ubi32_pll_config = {
++      .l = 0x4e,
++      .config_ctl_val = 0x200d4aa8,
++      .config_ctl_hi_val = 0x3c2,
++      .main_output_mask = BIT(0),
++      .aux_output_mask = BIT(1),
++      .pre_div_val = 0x0,
++      .pre_div_mask = BIT(12),
++      .post_div_val = 0x0,
++      .post_div_mask = GENMASK(9, 8),
++};
++
++static const struct alpha_pll_config nss_crypto_pll_config = {
++      .l = 0x3e,
++      .alpha = 0x0,
++      .alpha_hi = 0x80,
++      .config_ctl_val = 0x4001055b,
++      .main_output_mask = BIT(0),
++      .pre_div_val = 0x0,
++      .pre_div_mask = GENMASK(14, 12),
++      .post_div_val = 0x1 << 8,
++      .post_div_mask = GENMASK(11, 8),
++      .vco_mask = GENMASK(21, 20),
++      .vco_val = 0x0,
++      .alpha_en_mask = BIT(24),
++};
++
+ static struct clk_hw *gcc_ipq8074_hws[] = {
+       &gpll0_out_main_div2.hw,
+       &gpll6_out_main_div2.hw,
+@@ -4772,7 +4799,17 @@ static const struct qcom_cc_desc gcc_ipq8074_desc = {
+ static int gcc_ipq8074_probe(struct platform_device *pdev)
+ {
+-      return qcom_cc_probe(pdev, &gcc_ipq8074_desc);
++      struct regmap *regmap;
++
++      regmap = qcom_cc_map(pdev, &gcc_ipq8074_desc);
++      if (IS_ERR(regmap))
++              return PTR_ERR(regmap);
++
++      clk_alpha_pll_configure(&ubi32_pll_main, regmap, &ubi32_pll_config);
++      clk_alpha_pll_configure(&nss_crypto_pll_main, regmap,
++                              &nss_crypto_pll_config);
++
++      return qcom_cc_really_probe(pdev, &gcc_ipq8074_desc, regmap);
+ }
+ static struct platform_driver gcc_ipq8074_driver = {
+-- 
+2.35.1
+
diff --git a/queue-5.15/clk-qcom-ipq8074-fix-nss-port-frequency-tables.patch b/queue-5.15/clk-qcom-ipq8074-fix-nss-port-frequency-tables.patch
new file mode 100644 (file)
index 0000000..6875368
--- /dev/null
@@ -0,0 +1,76 @@
+From 211aba4cc85d184f87e72d01d110b59a0845f012 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 15 May 2022 23:00:40 +0200
+Subject: clk: qcom: ipq8074: fix NSS port frequency tables
+
+From: Robert Marko <robimarko@gmail.com>
+
+[ Upstream commit 0e9e61a2815b5cd34f1b495b2d72e8127ce9b794 ]
+
+NSS port 5 and 6 frequency tables are currently broken and are causing a
+wide ranges of issue like 1G not working at all on port 6 or port 5 being
+clocked with 312 instead of 125 MHz as UNIPHY1 gets selected.
+
+So, update the frequency tables with the ones from the downstream QCA 5.4
+based kernel which has already fixed this.
+
+Fixes: 7117a51ed303 ("clk: qcom: ipq8074: add NSS ethernet port clocks")
+Signed-off-by: Robert Marko <robimarko@gmail.com>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220515210048.483898-3-robimarko@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-ipq8074.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c
+index b4291ba53c78..f1017f2e61bd 100644
+--- a/drivers/clk/qcom/gcc-ipq8074.c
++++ b/drivers/clk/qcom/gcc-ipq8074.c
+@@ -1788,8 +1788,10 @@ static struct clk_regmap_div nss_port4_tx_div_clk_src = {
+ static const struct freq_tbl ftbl_nss_port5_rx_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(25000000, P_UNIPHY1_RX, 12.5, 0, 0),
++      F(25000000, P_UNIPHY0_RX, 5, 0, 0),
+       F(78125000, P_UNIPHY1_RX, 4, 0, 0),
+       F(125000000, P_UNIPHY1_RX, 2.5, 0, 0),
++      F(125000000, P_UNIPHY0_RX, 1, 0, 0),
+       F(156250000, P_UNIPHY1_RX, 2, 0, 0),
+       F(312500000, P_UNIPHY1_RX, 1, 0, 0),
+       { }
+@@ -1828,8 +1830,10 @@ static struct clk_regmap_div nss_port5_rx_div_clk_src = {
+ static const struct freq_tbl ftbl_nss_port5_tx_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(25000000, P_UNIPHY1_TX, 12.5, 0, 0),
++      F(25000000, P_UNIPHY0_TX, 5, 0, 0),
+       F(78125000, P_UNIPHY1_TX, 4, 0, 0),
+       F(125000000, P_UNIPHY1_TX, 2.5, 0, 0),
++      F(125000000, P_UNIPHY0_TX, 1, 0, 0),
+       F(156250000, P_UNIPHY1_TX, 2, 0, 0),
+       F(312500000, P_UNIPHY1_TX, 1, 0, 0),
+       { }
+@@ -1867,8 +1871,10 @@ static struct clk_regmap_div nss_port5_tx_div_clk_src = {
+ static const struct freq_tbl ftbl_nss_port6_rx_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
++      F(25000000, P_UNIPHY2_RX, 5, 0, 0),
+       F(25000000, P_UNIPHY2_RX, 12.5, 0, 0),
+       F(78125000, P_UNIPHY2_RX, 4, 0, 0),
++      F(125000000, P_UNIPHY2_RX, 1, 0, 0),
+       F(125000000, P_UNIPHY2_RX, 2.5, 0, 0),
+       F(156250000, P_UNIPHY2_RX, 2, 0, 0),
+       F(312500000, P_UNIPHY2_RX, 1, 0, 0),
+@@ -1907,8 +1913,10 @@ static struct clk_regmap_div nss_port6_rx_div_clk_src = {
+ static const struct freq_tbl ftbl_nss_port6_tx_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
++      F(25000000, P_UNIPHY2_TX, 5, 0, 0),
+       F(25000000, P_UNIPHY2_TX, 12.5, 0, 0),
+       F(78125000, P_UNIPHY2_TX, 4, 0, 0),
++      F(125000000, P_UNIPHY2_TX, 1, 0, 0),
+       F(125000000, P_UNIPHY2_TX, 2.5, 0, 0),
+       F(156250000, P_UNIPHY2_TX, 2, 0, 0),
+       F(312500000, P_UNIPHY2_TX, 1, 0, 0),
+-- 
+2.35.1
+
diff --git a/queue-5.15/clk-qcom-ipq8074-set-branch_halt_delay-flag-for-ubi-.patch b/queue-5.15/clk-qcom-ipq8074-set-branch_halt_delay-flag-for-ubi-.patch
new file mode 100644 (file)
index 0000000..07e84d9
--- /dev/null
@@ -0,0 +1,113 @@
+From 2c51dcb0bcc6546b73401cd9db8c89eb8c5fa538 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 15 May 2022 23:00:43 +0200
+Subject: clk: qcom: ipq8074: set BRANCH_HALT_DELAY flag for UBI clocks
+
+From: Robert Marko <robimarko@gmail.com>
+
+[ Upstream commit 2bd357e698207e2e65db03007e4be65bf9d6a7b3 ]
+
+Currently, attempting to enable the UBI clocks will cause the stuck at
+off warning to be printed and clk_enable will fail.
+
+[   14.936694] gcc_ubi1_ahb_clk status stuck at 'off'
+
+Downstream 5.4 QCA kernel has fixed this by seting the BRANCH_HALT_DELAY
+flag on UBI clocks, so lets do the same.
+
+Fixes: 5736294aef83 ("clk: qcom: ipq8074: add NSS clocks")
+Signed-off-by: Robert Marko <robimarko@gmail.com>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220515210048.483898-6-robimarko@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-ipq8074.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c
+index f1017f2e61bd..2c2ecfc5e61f 100644
+--- a/drivers/clk/qcom/gcc-ipq8074.c
++++ b/drivers/clk/qcom/gcc-ipq8074.c
+@@ -3354,6 +3354,7 @@ static struct clk_branch gcc_nssnoc_ubi1_ahb_clk = {
+ static struct clk_branch gcc_ubi0_ahb_clk = {
+       .halt_reg = 0x6820c,
++      .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x6820c,
+               .enable_mask = BIT(0),
+@@ -3371,6 +3372,7 @@ static struct clk_branch gcc_ubi0_ahb_clk = {
+ static struct clk_branch gcc_ubi0_axi_clk = {
+       .halt_reg = 0x68200,
++      .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x68200,
+               .enable_mask = BIT(0),
+@@ -3388,6 +3390,7 @@ static struct clk_branch gcc_ubi0_axi_clk = {
+ static struct clk_branch gcc_ubi0_nc_axi_clk = {
+       .halt_reg = 0x68204,
++      .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x68204,
+               .enable_mask = BIT(0),
+@@ -3405,6 +3408,7 @@ static struct clk_branch gcc_ubi0_nc_axi_clk = {
+ static struct clk_branch gcc_ubi0_core_clk = {
+       .halt_reg = 0x68210,
++      .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x68210,
+               .enable_mask = BIT(0),
+@@ -3422,6 +3426,7 @@ static struct clk_branch gcc_ubi0_core_clk = {
+ static struct clk_branch gcc_ubi0_mpt_clk = {
+       .halt_reg = 0x68208,
++      .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x68208,
+               .enable_mask = BIT(0),
+@@ -3439,6 +3444,7 @@ static struct clk_branch gcc_ubi0_mpt_clk = {
+ static struct clk_branch gcc_ubi1_ahb_clk = {
+       .halt_reg = 0x6822c,
++      .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x6822c,
+               .enable_mask = BIT(0),
+@@ -3456,6 +3462,7 @@ static struct clk_branch gcc_ubi1_ahb_clk = {
+ static struct clk_branch gcc_ubi1_axi_clk = {
+       .halt_reg = 0x68220,
++      .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x68220,
+               .enable_mask = BIT(0),
+@@ -3473,6 +3480,7 @@ static struct clk_branch gcc_ubi1_axi_clk = {
+ static struct clk_branch gcc_ubi1_nc_axi_clk = {
+       .halt_reg = 0x68224,
++      .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x68224,
+               .enable_mask = BIT(0),
+@@ -3490,6 +3498,7 @@ static struct clk_branch gcc_ubi1_nc_axi_clk = {
+ static struct clk_branch gcc_ubi1_core_clk = {
+       .halt_reg = 0x68230,
++      .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x68230,
+               .enable_mask = BIT(0),
+@@ -3507,6 +3516,7 @@ static struct clk_branch gcc_ubi1_core_clk = {
+ static struct clk_branch gcc_ubi1_mpt_clk = {
+       .halt_reg = 0x68228,
++      .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x68228,
+               .enable_mask = BIT(0),
+-- 
+2.35.1
+
diff --git a/queue-5.15/clk-qcom-ipq8074-sw-workaround-for-ubi32-pll-lock.patch b/queue-5.15/clk-qcom-ipq8074-sw-workaround-for-ubi32-pll-lock.patch
new file mode 100644 (file)
index 0000000..c52e7a6
--- /dev/null
@@ -0,0 +1,47 @@
+From 68b5b32e2bdd7fa71eb01fa25571e494735a88ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 15 May 2022 23:00:39 +0200
+Subject: clk: qcom: ipq8074: SW workaround for UBI32 PLL lock
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Robert Marko <robimarko@gmail.com>
+
+[ Upstream commit 3401ea2856ef84f39b75f0dc5ebcaeda81cb90ec ]
+
+UBI32 Huayra PLL fails to lock in 5 us in some SoC silicon and thus it
+will cause the wait_for_pll() to timeout and thus return the error
+indicating that the PLL failed to lock.
+
+This is bug in Huayra PLL HW for which SW workaround
+is to set bit 26 of TEST_CTL register.
+
+This is ported from the QCA 5.4 based downstream kernel.
+
+Fixes: b8e7e519625f ("clk: qcom: ipq8074: add remaining PLL’s")
+Signed-off-by: Robert Marko <robimarko@gmail.com>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220515210048.483898-2-robimarko@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-ipq8074.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c
+index 1a5141da7e23..b4291ba53c78 100644
+--- a/drivers/clk/qcom/gcc-ipq8074.c
++++ b/drivers/clk/qcom/gcc-ipq8074.c
+@@ -4805,6 +4805,9 @@ static int gcc_ipq8074_probe(struct platform_device *pdev)
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
++      /* SW Workaround for UBI32 Huayra PLL */
++      regmap_update_bits(regmap, 0x2501c, BIT(26), BIT(26));
++
+       clk_alpha_pll_configure(&ubi32_pll_main, regmap, &ubi32_pll_config);
+       clk_alpha_pll_configure(&nss_crypto_pll_main, regmap,
+                               &nss_crypto_pll_config);
+-- 
+2.35.1
+
diff --git a/queue-5.15/clk-renesas-r9a06g032-fix-uart-clkgrp-bitsel.patch b/queue-5.15/clk-renesas-r9a06g032-fix-uart-clkgrp-bitsel.patch
new file mode 100644 (file)
index 0000000..b3293e3
--- /dev/null
@@ -0,0 +1,54 @@
+From d9990af2ac2ab808c48d322711e457f907a70e3b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 May 2022 14:25:27 -0400
+Subject: clk: renesas: r9a06g032: Fix UART clkgrp bitsel
+
+From: Ralph Siemsen <ralph.siemsen@linaro.org>
+
+[ Upstream commit 2dee50ab9e72a3cae75b65e5934c8dd3e9bf01bc ]
+
+There are two UART clock groups, each having a mux to select its
+upstream clock source. The register/bit definitions for accessing these
+two muxes appear to have been reversed since introduction. Correct them
+so as to match the hardware manual.
+
+Fixes: 4c3d88526eba ("clk: renesas: Renesas R9A06G032 clock driver")
+
+Signed-off-by: Ralph Siemsen <ralph.siemsen@linaro.org>
+Reviewed-by: Phil Edworthy <phil.edworthy@renesas.com>
+Link: https://lore.kernel.org/r/20220518182527.1693156-1-ralph.siemsen@linaro.org
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/renesas/r9a06g032-clocks.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c
+index c99942f0e4d4..abc0891fd96d 100644
+--- a/drivers/clk/renesas/r9a06g032-clocks.c
++++ b/drivers/clk/renesas/r9a06g032-clocks.c
+@@ -286,8 +286,8 @@ static const struct r9a06g032_clkdesc r9a06g032_clocks[] = {
+               .name = "uart_group_012",
+               .type = K_BITSEL,
+               .source = 1 + R9A06G032_DIV_UART,
+-              /* R9A06G032_SYSCTRL_REG_PWRCTRL_PG1_PR2 */
+-              .dual.sel = ((0xec / 4) << 5) | 24,
++              /* R9A06G032_SYSCTRL_REG_PWRCTRL_PG0_0 */
++              .dual.sel = ((0x34 / 4) << 5) | 30,
+               .dual.group = 0,
+       },
+       {
+@@ -295,8 +295,8 @@ static const struct r9a06g032_clkdesc r9a06g032_clocks[] = {
+               .name = "uart_group_34567",
+               .type = K_BITSEL,
+               .source = 1 + R9A06G032_DIV_P2_PG,
+-              /* R9A06G032_SYSCTRL_REG_PWRCTRL_PG0_0 */
+-              .dual.sel = ((0x34 / 4) << 5) | 30,
++              /* R9A06G032_SYSCTRL_REG_PWRCTRL_PG1_PR2 */
++              .dual.sel = ((0xec / 4) << 5) | 24,
+               .dual.group = 1,
+       },
+       D_UGATE(CLK_UART0, "clk_uart0", UART_GROUP_012, 0, 0, 0x1b2, 0x1b3, 0x1b4, 0x1b5),
+-- 
+2.35.1
+
diff --git a/queue-5.15/cpufreq-zynq-fix-refcount-leak-in-zynq_get_revision.patch b/queue-5.15/cpufreq-zynq-fix-refcount-leak-in-zynq_get_revision.patch
new file mode 100644 (file)
index 0000000..7a8645e
--- /dev/null
@@ -0,0 +1,37 @@
+From 4bac1bc9c278509afbd8286eae2b2840ac7bd865 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Jun 2022 12:28:07 +0400
+Subject: cpufreq: zynq: Fix refcount leak in zynq_get_revision
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit d1ff2559cef0f6f8d97fba6337b28adb10689e16 ]
+
+of_find_compatible_node() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when done.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: 00f7dc636366 ("ARM: zynq: Add support for SOC_BUS")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Link: https://lore.kernel.org/r/20220605082807.21526-1-linmq006@gmail.com
+Signed-off-by: Michal Simek <michal.simek@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-zynq/common.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c
+index e1ca6a5732d2..15e8a321a713 100644
+--- a/arch/arm/mach-zynq/common.c
++++ b/arch/arm/mach-zynq/common.c
+@@ -77,6 +77,7 @@ static int __init zynq_get_revision(void)
+       }
+       zynq_devcfg_base = of_iomap(np, 0);
++      of_node_put(np);
+       if (!zynq_devcfg_base) {
+               pr_err("%s: Unable to map I/O memory\n", __func__);
+               return -1;
+-- 
+2.35.1
+
diff --git a/queue-5.15/crypto-arm64-gcm-select-aead-for-ghash_arm64_ce.patch b/queue-5.15/crypto-arm64-gcm-select-aead-for-ghash_arm64_ce.patch
new file mode 100644 (file)
index 0000000..5d0fefd
--- /dev/null
@@ -0,0 +1,39 @@
+From 91295e9b148b5df069d9548422702d2165793e24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jun 2022 07:13:38 -0400
+Subject: crypto: arm64/gcm - Select AEAD for GHASH_ARM64_CE
+
+From: Qian Cai <quic_qiancai@quicinc.com>
+
+[ Upstream commit fac76f2260893dde5aa05bb693b4c13e8ed0454b ]
+
+Otherwise, we could fail to compile.
+
+ld: arch/arm64/crypto/ghash-ce-glue.o: in function 'ghash_ce_mod_exit':
+ghash-ce-glue.c:(.exit.text+0x24): undefined reference to 'crypto_unregister_aead'
+ld: arch/arm64/crypto/ghash-ce-glue.o: in function 'ghash_ce_mod_init':
+ghash-ce-glue.c:(.init.text+0x34): undefined reference to 'crypto_register_aead'
+
+Fixes: 537c1445ab0b ("crypto: arm64/gcm - implement native driver using v8 Crypto Extensions")
+Signed-off-by: Qian Cai <quic_qiancai@quicinc.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/crypto/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/crypto/Kconfig b/arch/arm64/crypto/Kconfig
+index 55f19450091b..1a5406e599ba 100644
+--- a/arch/arm64/crypto/Kconfig
++++ b/arch/arm64/crypto/Kconfig
+@@ -59,6 +59,7 @@ config CRYPTO_GHASH_ARM64_CE
+       select CRYPTO_HASH
+       select CRYPTO_GF128MUL
+       select CRYPTO_LIB_AES
++      select CRYPTO_AEAD
+ config CRYPTO_CRCT10DIF_ARM64_CE
+       tristate "CRCT10DIF digest algorithm using PMULL instructions"
+-- 
+2.35.1
+
diff --git a/queue-5.15/crypto-ccp-during-shutdown-check-sev-data-pointer-be.patch b/queue-5.15/crypto-ccp-during-shutdown-check-sev-data-pointer-be.patch
new file mode 100644 (file)
index 0000000..70e094f
--- /dev/null
@@ -0,0 +1,44 @@
+From 0493be4ec8b61fe9cea8dab7cdae7c69d7fb155e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jun 2022 10:26:18 -0500
+Subject: crypto: ccp - During shutdown, check SEV data pointer before using
+
+From: Tom Lendacky <thomas.lendacky@amd.com>
+
+[ Upstream commit 1b05ece0c931536c0a38a9385e243a7962e933f6 ]
+
+On shutdown, each CCP device instance performs shutdown processing.
+However, __sev_platform_shutdown_locked() uses the controlling psp
+structure to obtain the pointer to the sev_device structure. However,
+during driver initialization, it is possible that an error can be received
+from the firmware that results in the sev_data pointer being cleared from
+the controlling psp structure. The __sev_platform_shutdown_locked()
+function does not check for this situation and will segfault.
+
+While not common, this scenario should be accounted for. Add a check for a
+NULL sev_device structure before attempting to use it.
+
+Fixes: 5441a07a127f ("crypto: ccp - shutdown SEV firmware on kexec")
+Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/ccp/sev-dev.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c
+index 8cf86dae20a4..900727b5edda 100644
+--- a/drivers/crypto/ccp/sev-dev.c
++++ b/drivers/crypto/ccp/sev-dev.c
+@@ -314,7 +314,7 @@ static int __sev_platform_shutdown_locked(int *error)
+       struct sev_device *sev = psp_master->sev_data;
+       int ret;
+-      if (sev->state == SEV_STATE_UNINIT)
++      if (!sev || sev->state == SEV_STATE_UNINIT)
+               return 0;
+       ret = __sev_do_cmd_locked(SEV_CMD_SHUTDOWN, NULL, error);
+-- 
+2.35.1
+
diff --git a/queue-5.15/crypto-hisilicon-hpre-don-t-use-gfp_kernel-to-alloc-.patch b/queue-5.15/crypto-hisilicon-hpre-don-t-use-gfp_kernel-to-alloc-.patch
new file mode 100644 (file)
index 0000000..7fbbd20
--- /dev/null
@@ -0,0 +1,37 @@
+From 777f9ef63010a74e65bf7913f39d6cf4f549339a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 12:23:23 +0800
+Subject: crypto: hisilicon/hpre - don't use GFP_KERNEL to alloc mem during
+ softirq
+
+From: Zhengchao Shao <shaozhengchao@huawei.com>
+
+[ Upstream commit 98dfa9343f37bdd4112966292751e3a93aaf2e56 ]
+
+The hpre encryption driver may be used to encrypt and decrypt packets
+during the rx softirq, it is not allowed to use GFP_KERNEL.
+
+Fixes: c8b4b477079d ("crypto: hisilicon - add HiSilicon HPRE accelerator")
+Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/hisilicon/hpre/hpre_crypto.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/hisilicon/hpre/hpre_crypto.c b/drivers/crypto/hisilicon/hpre/hpre_crypto.c
+index 7ba7641723a0..4062251fd1b6 100644
+--- a/drivers/crypto/hisilicon/hpre/hpre_crypto.c
++++ b/drivers/crypto/hisilicon/hpre/hpre_crypto.c
+@@ -252,7 +252,7 @@ static int hpre_prepare_dma_buf(struct hpre_asym_request *hpre_req,
+       if (unlikely(shift < 0))
+               return -EINVAL;
+-      ptr = dma_alloc_coherent(dev, ctx->key_sz, tmp, GFP_KERNEL);
++      ptr = dma_alloc_coherent(dev, ctx->key_sz, tmp, GFP_ATOMIC);
+       if (unlikely(!ptr))
+               return -ENOMEM;
+-- 
+2.35.1
+
diff --git a/queue-5.15/crypto-hisilicon-kunpeng916-crypto-driver-don-t-slee.patch b/queue-5.15/crypto-hisilicon-kunpeng916-crypto-driver-don-t-slee.patch
new file mode 100644 (file)
index 0000000..f6cd87c
--- /dev/null
@@ -0,0 +1,97 @@
+From 38e55d164483c83e46ebe4e03599aa437037d7ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 09:59:54 +0800
+Subject: crypto: hisilicon - Kunpeng916 crypto driver don't sleep when in
+ softirq
+
+From: Zhengchao Shao <shaozhengchao@huawei.com>
+
+[ Upstream commit 68740ab505431f268dc1ee26a54b871e75f0ddaa ]
+
+When kunpeng916 encryption driver is used to deencrypt and decrypt
+packets during the softirq, it is not allowed to use mutex lock.
+
+Fixes: 915e4e8413da ("crypto: hisilicon - SEC security accelerator driver")
+Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/hisilicon/sec/sec_algs.c | 14 +++++++-------
+ drivers/crypto/hisilicon/sec/sec_drv.h  |  2 +-
+ 2 files changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/crypto/hisilicon/sec/sec_algs.c b/drivers/crypto/hisilicon/sec/sec_algs.c
+index 0a3c8f019b02..490e1542305e 100644
+--- a/drivers/crypto/hisilicon/sec/sec_algs.c
++++ b/drivers/crypto/hisilicon/sec/sec_algs.c
+@@ -449,7 +449,7 @@ static void sec_skcipher_alg_callback(struct sec_bd_info *sec_resp,
+                */
+       }
+-      mutex_lock(&ctx->queue->queuelock);
++      spin_lock_bh(&ctx->queue->queuelock);
+       /* Put the IV in place for chained cases */
+       switch (ctx->cipher_alg) {
+       case SEC_C_AES_CBC_128:
+@@ -509,7 +509,7 @@ static void sec_skcipher_alg_callback(struct sec_bd_info *sec_resp,
+                       list_del(&backlog_req->backlog_head);
+               }
+       }
+-      mutex_unlock(&ctx->queue->queuelock);
++      spin_unlock_bh(&ctx->queue->queuelock);
+       mutex_lock(&sec_req->lock);
+       list_del(&sec_req_el->head);
+@@ -798,7 +798,7 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq,
+        */
+       /* Grab a big lock for a long time to avoid concurrency issues */
+-      mutex_lock(&queue->queuelock);
++      spin_lock_bh(&queue->queuelock);
+       /*
+        * Can go on to queue if we have space in either:
+@@ -814,15 +814,15 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq,
+               ret = -EBUSY;
+               if ((skreq->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) {
+                       list_add_tail(&sec_req->backlog_head, &ctx->backlog);
+-                      mutex_unlock(&queue->queuelock);
++                      spin_unlock_bh(&queue->queuelock);
+                       goto out;
+               }
+-              mutex_unlock(&queue->queuelock);
++              spin_unlock_bh(&queue->queuelock);
+               goto err_free_elements;
+       }
+       ret = sec_send_request(sec_req, queue);
+-      mutex_unlock(&queue->queuelock);
++      spin_unlock_bh(&queue->queuelock);
+       if (ret)
+               goto err_free_elements;
+@@ -881,7 +881,7 @@ static int sec_alg_skcipher_init(struct crypto_skcipher *tfm)
+       if (IS_ERR(ctx->queue))
+               return PTR_ERR(ctx->queue);
+-      mutex_init(&ctx->queue->queuelock);
++      spin_lock_init(&ctx->queue->queuelock);
+       ctx->queue->havesoftqueue = false;
+       return 0;
+diff --git a/drivers/crypto/hisilicon/sec/sec_drv.h b/drivers/crypto/hisilicon/sec/sec_drv.h
+index 179a8250d691..e2a50bf2234b 100644
+--- a/drivers/crypto/hisilicon/sec/sec_drv.h
++++ b/drivers/crypto/hisilicon/sec/sec_drv.h
+@@ -347,7 +347,7 @@ struct sec_queue {
+       DECLARE_BITMAP(unprocessed, SEC_QUEUE_LEN);
+       DECLARE_KFIFO_PTR(softqueue, typeof(struct sec_request_el *));
+       bool havesoftqueue;
+-      struct mutex queuelock;
++      spinlock_t queuelock;
+       void *shadow[SEC_QUEUE_LEN];
+ };
+-- 
+2.35.1
+
diff --git a/queue-5.15/crypto-hisilicon-sec-don-t-sleep-when-in-softirq.patch b/queue-5.15/crypto-hisilicon-sec-don-t-sleep-when-in-softirq.patch
new file mode 100644 (file)
index 0000000..b661414
--- /dev/null
@@ -0,0 +1,180 @@
+From 51f393b4233da1ff657f856aa9b0336772a71bc1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 09:55:11 +0800
+Subject: crypto: hisilicon/sec - don't sleep when in softirq
+
+From: Zhengchao Shao <shaozhengchao@huawei.com>
+
+[ Upstream commit 02884a4f12de11f54d4ca67a07dd1f111d96fdbd ]
+
+When kunpeng920 encryption driver is used to deencrypt and decrypt
+packets during the softirq, it is not allowed to use mutex lock. The
+kernel will report the following error:
+
+BUG: scheduling while atomic: swapper/57/0/0x00000300
+Call trace:
+dump_backtrace+0x0/0x1e4
+show_stack+0x20/0x2c
+dump_stack+0xd8/0x140
+__schedule_bug+0x68/0x80
+__schedule+0x728/0x840
+schedule+0x50/0xe0
+schedule_preempt_disabled+0x18/0x24
+__mutex_lock.constprop.0+0x594/0x5dc
+__mutex_lock_slowpath+0x1c/0x30
+mutex_lock+0x50/0x60
+sec_request_init+0x8c/0x1a0 [hisi_sec2]
+sec_process+0x28/0x1ac [hisi_sec2]
+sec_skcipher_crypto+0xf4/0x1d4 [hisi_sec2]
+sec_skcipher_encrypt+0x1c/0x30 [hisi_sec2]
+crypto_skcipher_encrypt+0x2c/0x40
+crypto_authenc_encrypt+0xc8/0xfc [authenc]
+crypto_aead_encrypt+0x2c/0x40
+echainiv_encrypt+0x144/0x1a0 [echainiv]
+crypto_aead_encrypt+0x2c/0x40
+esp_output_tail+0x348/0x5c0 [esp4]
+esp_output+0x120/0x19c [esp4]
+xfrm_output_one+0x25c/0x4d4
+xfrm_output_resume+0x6c/0x1fc
+xfrm_output+0xac/0x3c0
+xfrm4_output+0x64/0x130
+ip_build_and_send_pkt+0x158/0x20c
+tcp_v4_send_synack+0xdc/0x1f0
+tcp_conn_request+0x7d0/0x994
+tcp_v4_conn_request+0x58/0x6c
+tcp_v6_conn_request+0xf0/0x100
+tcp_rcv_state_process+0x1cc/0xd60
+tcp_v4_do_rcv+0x10c/0x250
+tcp_v4_rcv+0xfc4/0x10a4
+ip_protocol_deliver_rcu+0xf4/0x200
+ip_local_deliver_finish+0x58/0x70
+ip_local_deliver+0x68/0x120
+ip_sublist_rcv_finish+0x70/0x94
+ip_list_rcv_finish.constprop.0+0x17c/0x1d0
+ip_sublist_rcv+0x40/0xb0
+ip_list_rcv+0x140/0x1dc
+__netif_receive_skb_list_core+0x154/0x28c
+__netif_receive_skb_list+0x120/0x1a0
+netif_receive_skb_list_internal+0xe4/0x1f0
+napi_complete_done+0x70/0x1f0
+gro_cell_poll+0x9c/0xb0
+napi_poll+0xcc/0x264
+net_rx_action+0xd4/0x21c
+__do_softirq+0x130/0x358
+irq_exit+0x11c/0x13c
+__handle_domain_irq+0x88/0xf0
+gic_handle_irq+0x78/0x2c0
+el1_irq+0xb8/0x140
+arch_cpu_idle+0x18/0x40
+default_idle_call+0x5c/0x1c0
+cpuidle_idle_call+0x174/0x1b0
+do_idle+0xc8/0x160
+cpu_startup_entry+0x30/0x11c
+secondary_start_kernel+0x158/0x1e4
+softirq: huh, entered softirq 3 NET_RX 0000000093774ee4 with
+preempt_count 00000100, exited with fffffe00?
+
+Fixes: 416d82204df4 ("crypto: hisilicon - add HiSilicon SEC V2 driver")
+Signed-off-by: Zhengchao Shao <shaozhengchao@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        |  2 +-
+ drivers/crypto/hisilicon/sec2/sec_crypto.c | 20 ++++++++++----------
+ 2 files changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/crypto/hisilicon/sec2/sec.h b/drivers/crypto/hisilicon/sec2/sec.h
+index d97cf02b1df7..cff00fd29765 100644
+--- a/drivers/crypto/hisilicon/sec2/sec.h
++++ b/drivers/crypto/hisilicon/sec2/sec.h
+@@ -119,7 +119,7 @@ struct sec_qp_ctx {
+       struct idr req_idr;
+       struct sec_alg_res res[QM_Q_DEPTH];
+       struct sec_ctx *ctx;
+-      struct mutex req_lock;
++      spinlock_t req_lock;
+       struct list_head backlog;
+       struct hisi_acc_sgl_pool *c_in_pool;
+       struct hisi_acc_sgl_pool *c_out_pool;
+diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c
+index 090920ed50c8..36c789ff1bd4 100644
+--- a/drivers/crypto/hisilicon/sec2/sec_crypto.c
++++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c
+@@ -124,11 +124,11 @@ static int sec_alloc_req_id(struct sec_req *req, struct sec_qp_ctx *qp_ctx)
+ {
+       int req_id;
+-      mutex_lock(&qp_ctx->req_lock);
++      spin_lock_bh(&qp_ctx->req_lock);
+       req_id = idr_alloc_cyclic(&qp_ctx->req_idr, NULL,
+                                 0, QM_Q_DEPTH, GFP_ATOMIC);
+-      mutex_unlock(&qp_ctx->req_lock);
++      spin_unlock_bh(&qp_ctx->req_lock);
+       if (unlikely(req_id < 0)) {
+               dev_err(req->ctx->dev, "alloc req id fail!\n");
+               return req_id;
+@@ -153,9 +153,9 @@ static void sec_free_req_id(struct sec_req *req)
+       qp_ctx->req_list[req_id] = NULL;
+       req->qp_ctx = NULL;
+-      mutex_lock(&qp_ctx->req_lock);
++      spin_lock_bh(&qp_ctx->req_lock);
+       idr_remove(&qp_ctx->req_idr, req_id);
+-      mutex_unlock(&qp_ctx->req_lock);
++      spin_unlock_bh(&qp_ctx->req_lock);
+ }
+ static u8 pre_parse_finished_bd(struct bd_status *status, void *resp)
+@@ -270,7 +270,7 @@ static int sec_bd_send(struct sec_ctx *ctx, struct sec_req *req)
+           !(req->flag & CRYPTO_TFM_REQ_MAY_BACKLOG))
+               return -EBUSY;
+-      mutex_lock(&qp_ctx->req_lock);
++      spin_lock_bh(&qp_ctx->req_lock);
+       ret = hisi_qp_send(qp_ctx->qp, &req->sec_sqe);
+       if (ctx->fake_req_limit <=
+@@ -278,10 +278,10 @@ static int sec_bd_send(struct sec_ctx *ctx, struct sec_req *req)
+               list_add_tail(&req->backlog_head, &qp_ctx->backlog);
+               atomic64_inc(&ctx->sec->debug.dfx.send_cnt);
+               atomic64_inc(&ctx->sec->debug.dfx.send_busy_cnt);
+-              mutex_unlock(&qp_ctx->req_lock);
++              spin_unlock_bh(&qp_ctx->req_lock);
+               return -EBUSY;
+       }
+-      mutex_unlock(&qp_ctx->req_lock);
++      spin_unlock_bh(&qp_ctx->req_lock);
+       if (unlikely(ret == -EBUSY))
+               return -ENOBUFS;
+@@ -484,7 +484,7 @@ static int sec_create_qp_ctx(struct hisi_qm *qm, struct sec_ctx *ctx,
+       qp->req_cb = sec_req_cb;
+-      mutex_init(&qp_ctx->req_lock);
++      spin_lock_init(&qp_ctx->req_lock);
+       idr_init(&qp_ctx->req_idr);
+       INIT_LIST_HEAD(&qp_ctx->backlog);
+@@ -1373,7 +1373,7 @@ static struct sec_req *sec_back_req_clear(struct sec_ctx *ctx,
+ {
+       struct sec_req *backlog_req = NULL;
+-      mutex_lock(&qp_ctx->req_lock);
++      spin_lock_bh(&qp_ctx->req_lock);
+       if (ctx->fake_req_limit >=
+           atomic_read(&qp_ctx->qp->qp_status.used) &&
+           !list_empty(&qp_ctx->backlog)) {
+@@ -1381,7 +1381,7 @@ static struct sec_req *sec_back_req_clear(struct sec_ctx *ctx,
+                               typeof(*backlog_req), backlog_head);
+               list_del(&backlog_req->backlog_head);
+       }
+-      mutex_unlock(&qp_ctx->req_lock);
++      spin_unlock_bh(&qp_ctx->req_lock);
+       return backlog_req;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/crypto-hisilicon-sec-fix-auth-key-size-error.patch b/queue-5.15/crypto-hisilicon-sec-fix-auth-key-size-error.patch
new file mode 100644 (file)
index 0000000..30f44d5
--- /dev/null
@@ -0,0 +1,60 @@
+From ae04ada1255d3b837300eec58f47a57cd2a34dfa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Jul 2022 10:18:31 +0800
+Subject: crypto: hisilicon/sec - fix auth key size error
+
+From: Kai Ye <yekai13@huawei.com>
+
+[ Upstream commit 45f5d0176d8426cc1ab0bab84fbd8ef5c57526c6 ]
+
+The authentication algorithm supports a maximum of 128-byte keys.
+The allocated key memory is insufficient.
+
+Fixes: 2f072d75d1ab ("crypto: hisilicon - Add aead support on SEC2")
+Signed-off-by: Kai Ye <yekai13@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 | 6 +++---
+ drivers/crypto/hisilicon/sec2/sec_crypto.h | 1 +
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c
+index 36c789ff1bd4..0d26eda36a52 100644
+--- a/drivers/crypto/hisilicon/sec2/sec_crypto.c
++++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c
+@@ -617,7 +617,7 @@ static int sec_auth_init(struct sec_ctx *ctx)
+ {
+       struct sec_auth_ctx *a_ctx = &ctx->a_ctx;
+-      a_ctx->a_key = dma_alloc_coherent(ctx->dev, SEC_MAX_KEY_SIZE,
++      a_ctx->a_key = dma_alloc_coherent(ctx->dev, SEC_MAX_AKEY_SIZE,
+                                         &a_ctx->a_key_dma, GFP_KERNEL);
+       if (!a_ctx->a_key)
+               return -ENOMEM;
+@@ -629,8 +629,8 @@ static void sec_auth_uninit(struct sec_ctx *ctx)
+ {
+       struct sec_auth_ctx *a_ctx = &ctx->a_ctx;
+-      memzero_explicit(a_ctx->a_key, SEC_MAX_KEY_SIZE);
+-      dma_free_coherent(ctx->dev, SEC_MAX_KEY_SIZE,
++      memzero_explicit(a_ctx->a_key, SEC_MAX_AKEY_SIZE);
++      dma_free_coherent(ctx->dev, SEC_MAX_AKEY_SIZE,
+                         a_ctx->a_key, a_ctx->a_key_dma);
+ }
+diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.h b/drivers/crypto/hisilicon/sec2/sec_crypto.h
+index 9f71c358a6d3..ee2edaf5058d 100644
+--- a/drivers/crypto/hisilicon/sec2/sec_crypto.h
++++ b/drivers/crypto/hisilicon/sec2/sec_crypto.h
+@@ -7,6 +7,7 @@
+ #define SEC_AIV_SIZE          12
+ #define SEC_IV_SIZE           24
+ #define SEC_MAX_KEY_SIZE      64
++#define SEC_MAX_AKEY_SIZE     128
+ #define SEC_COMM_SCENE                0
+ #define SEC_MIN_BLOCK_SZ      1
+-- 
+2.35.1
+
diff --git a/queue-5.15/crypto-inside-secure-add-missing-module_device_table.patch b/queue-5.15/crypto-inside-secure-add-missing-module_device_table.patch
new file mode 100644 (file)
index 0000000..0ed54ed
--- /dev/null
@@ -0,0 +1,41 @@
+From cfc24cf117f15df0118f8911d7f6891dabd8c628 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 09:54:03 +0200
+Subject: crypto: inside-secure - Add missing MODULE_DEVICE_TABLE for of
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+[ Upstream commit fa4d57b85786ec0e16565c75a51c208834b0c24d ]
+
+Without MODULE_DEVICE_TABLE, crypto_safexcel.ko module is not automatically
+loaded on platforms where inside-secure crypto HW is specified in device
+tree (e.g. Armada 3720). So add missing MODULE_DEVICE_TABLE for of.
+
+Fixes: 1b44c5a60c13 ("crypto: inside-secure - add SafeXcel EIP197 crypto engine driver")
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Acked-by: Marek Behún <kabel@kernel.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/inside-secure/safexcel.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c
+index 9ff885d50edf..389a7b51f1f3 100644
+--- a/drivers/crypto/inside-secure/safexcel.c
++++ b/drivers/crypto/inside-secure/safexcel.c
+@@ -1831,6 +1831,8 @@ static const struct of_device_id safexcel_of_match_table[] = {
+       {},
+ };
++MODULE_DEVICE_TABLE(of, safexcel_of_match_table);
++
+ static struct platform_driver  crypto_safexcel = {
+       .probe          = safexcel_probe,
+       .remove         = safexcel_remove,
+-- 
+2.35.1
+
diff --git a/queue-5.15/crypto-sun8i-ss-do-not-allocate-memory-when-handling.patch b/queue-5.15/crypto-sun8i-ss-do-not-allocate-memory-when-handling.patch
new file mode 100644 (file)
index 0000000..cea211b
--- /dev/null
@@ -0,0 +1,103 @@
+From f1926ad02209bd1ca4da33d24ff1d5ebd55c4267 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 May 2022 20:19:19 +0000
+Subject: crypto: sun8i-ss - do not allocate memory when handling hash requests
+
+From: Corentin Labbe <clabbe@baylibre.com>
+
+[ Upstream commit 8eec4563f152981a441693fc97c5459843dc5e6e ]
+
+Instead of allocate memory on each requests, it is easier to
+pre-allocate buffers.
+This made error path easier.
+
+Signed-off-by: Corentin Labbe <clabbe@baylibre.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c | 10 ++++++++++
+ drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c | 15 +++------------
+ drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h      |  4 ++++
+ 3 files changed, 17 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
+index 657530578643..786b6f5cf300 100644
+--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
++++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
+@@ -486,6 +486,16 @@ static int allocate_flows(struct sun8i_ss_dev *ss)
+                               goto error_engine;
+               }
++              /* the padding could be up to two block. */
++              ss->flows[i].pad = devm_kmalloc(ss->dev, SHA256_BLOCK_SIZE * 2,
++                                              GFP_KERNEL | GFP_DMA);
++              if (!ss->flows[i].pad)
++                      goto error_engine;
++              ss->flows[i].result = devm_kmalloc(ss->dev, SHA256_DIGEST_SIZE,
++                                                 GFP_KERNEL | GFP_DMA);
++              if (!ss->flows[i].result)
++                      goto error_engine;
++
+               ss->flows[i].engine = crypto_engine_alloc_init(ss->dev, true);
+               if (!ss->flows[i].engine) {
+                       dev_err(ss->dev, "Cannot allocate engine\n");
+diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
+index ca4f280af35d..f89a580618aa 100644
+--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
++++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
+@@ -342,18 +342,11 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq)
+       if (digestsize == SHA224_DIGEST_SIZE)
+               digestsize = SHA256_DIGEST_SIZE;
+-      /* the padding could be up to two block. */
+-      pad = kzalloc(algt->alg.hash.halg.base.cra_blocksize * 2, GFP_KERNEL | GFP_DMA);
+-      if (!pad)
+-              return -ENOMEM;
++      result = ss->flows[rctx->flow].result;
++      pad = ss->flows[rctx->flow].pad;
++      memset(pad, 0, algt->alg.hash.halg.base.cra_blocksize * 2);
+       bf = (__le32 *)pad;
+-      result = kzalloc(digestsize, GFP_KERNEL | GFP_DMA);
+-      if (!result) {
+-              kfree(pad);
+-              return -ENOMEM;
+-      }
+-
+       for (i = 0; i < MAX_SG; i++) {
+               rctx->t_dst[i].addr = 0;
+               rctx->t_dst[i].len = 0;
+@@ -449,8 +442,6 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq)
+       memcpy(areq->result, result, algt->alg.hash.halg.digestsize);
+ theend:
+-      kfree(pad);
+-      kfree(result);
+       local_bh_disable();
+       crypto_finalize_hash_request(engine, breq, err);
+       local_bh_enable();
+diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h
+index 57ada8653855..eb82ee5345ae 100644
+--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h
++++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h
+@@ -123,6 +123,8 @@ struct sginfo {
+  * @stat_req: number of request done by this flow
+  * @iv:               list of IV to use for each step
+  * @biv:      buffer which contain the backuped IV
++ * @pad:      padding buffer for hash operations
++ * @result:   buffer for storing the result of hash operations
+  */
+ struct sun8i_ss_flow {
+       struct crypto_engine *engine;
+@@ -130,6 +132,8 @@ struct sun8i_ss_flow {
+       int status;
+       u8 *iv[MAX_SG];
+       u8 *biv;
++      void *pad;
++      void *result;
+ #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG
+       unsigned long stat_req;
+ #endif
+-- 
+2.35.1
+
diff --git a/queue-5.15/crypto-sun8i-ss-fix-error-codes-in-allocate_flows.patch b/queue-5.15/crypto-sun8i-ss-fix-error-codes-in-allocate_flows.patch
new file mode 100644 (file)
index 0000000..11dcf79
--- /dev/null
@@ -0,0 +1,68 @@
+From 54e661cbc0c592f79c3f9c31cd8f79246c230525 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 May 2022 20:33:44 +0300
+Subject: crypto: sun8i-ss - fix error codes in allocate_flows()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit d2765e1b9ac4b2d5a5d5bf17f468c9b3566c3770 ]
+
+These failure paths should return -ENOMEM.  Currently they return
+success.
+
+Fixes: 359e893e8af4 ("crypto: sun8i-ss - rework handling of IV")
+Fixes: 8eec4563f152 ("crypto: sun8i-ss - do not allocate memory when handling hash requests")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Acked-by: Corentin Labbe <clabbe.montjoie@gmail.com>
+Tested-by: Corentin Labbe <clabbe.montjoie@gmail.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../crypto/allwinner/sun8i-ss/sun8i-ss-core.c    | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
+index 786b6f5cf300..47b5828e35c3 100644
+--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
++++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
+@@ -476,25 +476,33 @@ static int allocate_flows(struct sun8i_ss_dev *ss)
+               ss->flows[i].biv = devm_kmalloc(ss->dev, AES_BLOCK_SIZE,
+                                               GFP_KERNEL | GFP_DMA);
+-              if (!ss->flows[i].biv)
++              if (!ss->flows[i].biv) {
++                      err = -ENOMEM;
+                       goto error_engine;
++              }
+               for (j = 0; j < MAX_SG; j++) {
+                       ss->flows[i].iv[j] = devm_kmalloc(ss->dev, AES_BLOCK_SIZE,
+                                                         GFP_KERNEL | GFP_DMA);
+-                      if (!ss->flows[i].iv[j])
++                      if (!ss->flows[i].iv[j]) {
++                              err = -ENOMEM;
+                               goto error_engine;
++                      }
+               }
+               /* the padding could be up to two block. */
+               ss->flows[i].pad = devm_kmalloc(ss->dev, SHA256_BLOCK_SIZE * 2,
+                                               GFP_KERNEL | GFP_DMA);
+-              if (!ss->flows[i].pad)
++              if (!ss->flows[i].pad) {
++                      err = -ENOMEM;
+                       goto error_engine;
++              }
+               ss->flows[i].result = devm_kmalloc(ss->dev, SHA256_DIGEST_SIZE,
+                                                  GFP_KERNEL | GFP_DMA);
+-              if (!ss->flows[i].result)
++              if (!ss->flows[i].result) {
++                      err = -ENOMEM;
+                       goto error_engine;
++              }
+               ss->flows[i].engine = crypto_engine_alloc_init(ss->dev, true);
+               if (!ss->flows[i].engine) {
+-- 
+2.35.1
+
diff --git a/queue-5.15/crypto-sun8i-ss-fix-infinite-loop-in-sun8i_ss_setup_.patch b/queue-5.15/crypto-sun8i-ss-fix-infinite-loop-in-sun8i_ss_setup_.patch
new file mode 100644 (file)
index 0000000..bc74264
--- /dev/null
@@ -0,0 +1,38 @@
+From fe746650873244fca5f3c6aa4bb1d08b60cddac9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jun 2022 21:27:15 +0300
+Subject: crypto: sun8i-ss - fix infinite loop in sun8i_ss_setup_ivs()
+
+From: Alexey Khoroshilov <khoroshilov@ispras.ru>
+
+[ Upstream commit d61a7b3decf7f0cf4121a7204303deefd2c7151b ]
+
+There is no i decrement in while (i >= 0) loop.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
+Fixes: 359e893e8af4 ("crypto: sun8i-ss - rework handling of IV")
+Acked-by: Corentin Labbe <clabbe.montjoie@gmail.com>
+Tested-by: Corentin Labbe <clabbe.montjoie@gmail.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
+index 70e2e6e37389..3c46ad8c3a1c 100644
+--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
++++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
+@@ -151,6 +151,7 @@ static int sun8i_ss_setup_ivs(struct skcipher_request *areq)
+       while (i >= 0) {
+               dma_unmap_single(ss->dev, rctx->p_iv[i], ivsize, DMA_TO_DEVICE);
+               memzero_explicit(sf->iv[i], ivsize);
++              i--;
+       }
+       return err;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/dccp-put-dccp_qpolicy_full-and-dccp_qpolicy_push-in-.patch b/queue-5.15/dccp-put-dccp_qpolicy_full-and-dccp_qpolicy_push-in-.patch
new file mode 100644 (file)
index 0000000..93f12f4
--- /dev/null
@@ -0,0 +1,71 @@
+From 4fe89b6abe232d8ed17176717a42f1b7b5a1b83f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Jul 2022 19:00:27 +0800
+Subject: dccp: put dccp_qpolicy_full() and dccp_qpolicy_push() in the same
+ lock
+
+From: Hangyu Hua <hbh25y@gmail.com>
+
+[ Upstream commit a41b17ff9dacd22f5f118ee53d82da0f3e52d5e3 ]
+
+In the case of sk->dccps_qpolicy == DCCPQ_POLICY_PRIO, dccp_qpolicy_full
+will drop a skb when qpolicy is full. And the lock in dccp_sendmsg is
+released before sock_alloc_send_skb and then relocked after
+sock_alloc_send_skb. The following conditions may lead dccp_qpolicy_push
+to add skb to an already full sk_write_queue:
+
+thread1--->lock
+thread1--->dccp_qpolicy_full: queue is full. drop a skb
+thread1--->unlock
+thread2--->lock
+thread2--->dccp_qpolicy_full: queue is not full. no need to drop.
+thread2--->unlock
+thread1--->lock
+thread1--->dccp_qpolicy_push: add a skb. queue is full.
+thread1--->unlock
+thread2--->lock
+thread2--->dccp_qpolicy_push: add a skb!
+thread2--->unlock
+
+Fix this by moving dccp_qpolicy_full.
+
+Fixes: b1308dc015eb ("[DCCP]: Set TX Queue Length Bounds via Sysctl")
+Signed-off-by: Hangyu Hua <hbh25y@gmail.com>
+Link: https://lore.kernel.org/r/20220729110027.40569-1-hbh25y@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/dccp/proto.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/net/dccp/proto.c b/net/dccp/proto.c
+index fc44dadc778b..c4de716f4994 100644
+--- a/net/dccp/proto.c
++++ b/net/dccp/proto.c
+@@ -747,11 +747,6 @@ int dccp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
+       lock_sock(sk);
+-      if (dccp_qpolicy_full(sk)) {
+-              rc = -EAGAIN;
+-              goto out_release;
+-      }
+-
+       timeo = sock_sndtimeo(sk, noblock);
+       /*
+@@ -770,6 +765,11 @@ int dccp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
+       if (skb == NULL)
+               goto out_release;
++      if (dccp_qpolicy_full(sk)) {
++              rc = -EAGAIN;
++              goto out_discard;
++      }
++
+       if (sk->sk_state == DCCP_CLOSED) {
+               rc = -ENOTCONN;
+               goto out_discard;
+-- 
+2.35.1
+
diff --git a/queue-5.15/dm-return-early-from-dm_pr_call-if-dm-device-is-susp.patch b/queue-5.15/dm-return-early-from-dm_pr_call-if-dm-device-is-susp.patch
new file mode 100644 (file)
index 0000000..ad13cea
--- /dev/null
@@ -0,0 +1,38 @@
+From 39c3d16d5650fbc93c3cb4abefb4a72bc4f76bed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Jul 2022 15:31:23 -0400
+Subject: dm: return early from dm_pr_call() if DM device is suspended
+
+From: Mike Snitzer <snitzer@kernel.org>
+
+[ Upstream commit e120a5f1e78fab6223544e425015f393d90d6f0d ]
+
+Otherwise PR ops may be issued while the broader DM device is being
+reconfigured, etc.
+
+Fixes: 9c72bad1f31a ("dm: call PR reserve/unreserve on each underlying device")
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/md/dm.c b/drivers/md/dm.c
+index 36449422e7e0..41d2e1285c07 100644
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -2911,6 +2911,11 @@ static int dm_call_pr(struct block_device *bdev, iterate_devices_callout_fn fn,
+               goto out;
+       ti = dm_table_get_target(table, 0);
++      if (dm_suspended_md(md)) {
++              ret = -EAGAIN;
++              goto out;
++      }
++
+       ret = -EINVAL;
+       if (!ti->type->iterate_devices)
+               goto out;
+-- 
+2.35.1
+
diff --git a/queue-5.15/dm-writecache-count-number-of-blocks-discarded-not-n.patch b/queue-5.15/dm-writecache-count-number-of-blocks-discarded-not-n.patch
new file mode 100644 (file)
index 0000000..d232a1d
--- /dev/null
@@ -0,0 +1,53 @@
+From a6aa6cdc87c2e0c99d68702895ed893c42cf4fb9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Jul 2022 16:31:52 -0400
+Subject: dm writecache: count number of blocks discarded, not number of
+ discard bios
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+[ Upstream commit 2ee73ef60db4d79b9f9b8cd501e8188b5179449f ]
+
+Change dm-writecache, so that it counts the number of blocks discarded
+instead of the number of discard bios. Make it consistent with the
+read and write statistics counters that were changed to count the
+number of blocks instead of bios.
+
+Fixes: e3a35d03407c ("dm writecache: add event counters")
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/admin-guide/device-mapper/writecache.rst | 2 +-
+ drivers/md/dm-writecache.c                             | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/Documentation/admin-guide/device-mapper/writecache.rst b/Documentation/admin-guide/device-mapper/writecache.rst
+index 6c9a2c74df8a..724e028d1858 100644
+--- a/Documentation/admin-guide/device-mapper/writecache.rst
++++ b/Documentation/admin-guide/device-mapper/writecache.rst
+@@ -87,7 +87,7 @@ Status:
+ 11. the number of write blocks that are allocated in the cache
+ 12. the number of write requests that are blocked on the freelist
+ 13. the number of flush requests
+-14. the number of discard requests
++14. the number of discarded blocks
+ Messages:
+       flush
+diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c
+index c90408eb9c3a..c3e59d8af76f 100644
+--- a/drivers/md/dm-writecache.c
++++ b/drivers/md/dm-writecache.c
+@@ -1513,7 +1513,7 @@ static enum wc_map_op writecache_map_flush(struct dm_writecache *wc, struct bio
+ static enum wc_map_op writecache_map_discard(struct dm_writecache *wc, struct bio *bio)
+ {
+-      wc->stats.discards++;
++      wc->stats.discards += bio->bi_iter.bi_size >> wc->block_size_bits;
+       if (writecache_has_error(wc))
+               return WC_MAP_ERROR;
+-- 
+2.35.1
+
diff --git a/queue-5.15/dm-writecache-count-number-of-blocks-read-not-number.patch b/queue-5.15/dm-writecache-count-number-of-blocks-read-not-number.patch
new file mode 100644 (file)
index 0000000..0240e28
--- /dev/null
@@ -0,0 +1,54 @@
+From 148d14cac4e0f804c58a42ce480760bf75462bbf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Jul 2022 16:30:52 -0400
+Subject: dm writecache: count number of blocks read, not number of read bios
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+[ Upstream commit 2c6e755b49d273243431f5f1184654e71221fc78 ]
+
+Change dm-writecache, so that it counts the number of blocks read
+instead of the number of read bios. Bios can be split and requeued
+using the dm_accept_partial_bio function, so counting bios caused
+inaccurate results.
+
+Fixes: e3a35d03407c ("dm writecache: add event counters")
+Reported-by: Yu Kuai <yukuai1@huaweicloud.com>
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/admin-guide/device-mapper/writecache.rst | 4 ++--
+ drivers/md/dm-writecache.c                             | 1 +
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/Documentation/admin-guide/device-mapper/writecache.rst b/Documentation/admin-guide/device-mapper/writecache.rst
+index 10429779a91a..7bead3b52690 100644
+--- a/Documentation/admin-guide/device-mapper/writecache.rst
++++ b/Documentation/admin-guide/device-mapper/writecache.rst
+@@ -78,8 +78,8 @@ Status:
+ 2. the number of blocks
+ 3. the number of free blocks
+ 4. the number of blocks under writeback
+-5. the number of read requests
+-6. the number of read requests that hit the cache
++5. the number of read blocks
++6. the number of read blocks that hit the cache
+ 7. the number of write requests
+ 8. the number of write requests that hit uncommitted block
+ 9. the number of write requests that hit committed block
+diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c
+index e3d0a9bb27b5..9d6b7b706a65 100644
+--- a/drivers/md/dm-writecache.c
++++ b/drivers/md/dm-writecache.c
+@@ -1364,6 +1364,7 @@ static enum wc_map_op writecache_map_read(struct dm_writecache *wc, struct bio *
+               }
+       } else {
+               writecache_map_remap_origin(wc, bio, e);
++              wc->stats.reads += (bio->bi_iter.bi_size - wc->block_size) >> wc->block_size_bits;
+               map_op = WC_MAP_REMAP_ORIGIN;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/dm-writecache-count-number-of-blocks-written-not-num.patch b/queue-5.15/dm-writecache-count-number-of-blocks-written-not-num.patch
new file mode 100644 (file)
index 0000000..9bdf436
--- /dev/null
@@ -0,0 +1,96 @@
+From 7d1c088468105a9c772426211379d4fe9f4b8e7b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Jul 2022 16:31:26 -0400
+Subject: dm writecache: count number of blocks written, not number of write
+ bios
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+[ Upstream commit b2676e1482af89714af6988ce5d31a84692e2530 ]
+
+Change dm-writecache, so that it counts the number of blocks written
+instead of the number of write bios. Bios can be split and requeued
+using the dm_accept_partial_bio function, so counting bios caused
+inaccurate results.
+
+Fixes: e3a35d03407c ("dm writecache: add event counters")
+Reported-by: Yu Kuai <yukuai1@huaweicloud.com>
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../admin-guide/device-mapper/writecache.rst         | 10 +++++-----
+ drivers/md/dm-writecache.c                           | 12 +++++++++---
+ 2 files changed, 14 insertions(+), 8 deletions(-)
+
+diff --git a/Documentation/admin-guide/device-mapper/writecache.rst b/Documentation/admin-guide/device-mapper/writecache.rst
+index 7bead3b52690..6c9a2c74df8a 100644
+--- a/Documentation/admin-guide/device-mapper/writecache.rst
++++ b/Documentation/admin-guide/device-mapper/writecache.rst
+@@ -80,11 +80,11 @@ Status:
+ 4. the number of blocks under writeback
+ 5. the number of read blocks
+ 6. the number of read blocks that hit the cache
+-7. the number of write requests
+-8. the number of write requests that hit uncommitted block
+-9. the number of write requests that hit committed block
+-10. the number of write requests that bypass the cache
+-11. the number of write requests that are allocated in the cache
++7. the number of write blocks
++8. the number of write blocks that hit uncommitted block
++9. the number of write blocks that hit committed block
++10. the number of write blocks that bypass the cache
++11. the number of write blocks that are allocated in the cache
+ 12. the number of write requests that are blocked on the freelist
+ 13. the number of flush requests
+ 14. the number of discard requests
+diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c
+index 9d6b7b706a65..c90408eb9c3a 100644
+--- a/drivers/md/dm-writecache.c
++++ b/drivers/md/dm-writecache.c
+@@ -1412,6 +1412,9 @@ static void writecache_bio_copy_ssd(struct dm_writecache *wc, struct bio *bio,
+       bio->bi_iter.bi_sector = start_cache_sec;
+       dm_accept_partial_bio(bio, bio_size >> SECTOR_SHIFT);
++      wc->stats.writes += bio->bi_iter.bi_size >> wc->block_size_bits;
++      wc->stats.writes_allocate += (bio->bi_iter.bi_size - wc->block_size) >> wc->block_size_bits;
++
+       if (unlikely(wc->uncommitted_blocks >= wc->autocommit_blocks)) {
+               wc->uncommitted_blocks = 0;
+               queue_work(wc->writeback_wq, &wc->flush_work);
+@@ -1427,9 +1430,10 @@ static enum wc_map_op writecache_map_write(struct dm_writecache *wc, struct bio
+       do {
+               bool found_entry = false;
+               bool search_used = false;
+-              wc->stats.writes++;
+-              if (writecache_has_error(wc))
++              if (writecache_has_error(wc)) {
++                      wc->stats.writes += bio->bi_iter.bi_size >> wc->block_size_bits;
+                       return WC_MAP_ERROR;
++              }
+               e = writecache_find_entry(wc, bio->bi_iter.bi_sector, 0);
+               if (e) {
+                       if (!writecache_entry_is_committed(wc, e)) {
+@@ -1453,9 +1457,10 @@ static enum wc_map_op writecache_map_write(struct dm_writecache *wc, struct bio
+               if (unlikely(!e)) {
+                       if (!WC_MODE_PMEM(wc) && !found_entry) {
+ direct_write:
+-                              wc->stats.writes_around++;
+                               e = writecache_find_entry(wc, bio->bi_iter.bi_sector, WFE_RETURN_FOLLOWING);
+                               writecache_map_remap_origin(wc, bio, e);
++                              wc->stats.writes_around += bio->bi_iter.bi_size >> wc->block_size_bits;
++                              wc->stats.writes += bio->bi_iter.bi_size >> wc->block_size_bits;
+                               return WC_MAP_REMAP_ORIGIN;
+                       }
+                       wc->stats.writes_blocked_on_freelist++;
+@@ -1469,6 +1474,7 @@ static enum wc_map_op writecache_map_write(struct dm_writecache *wc, struct bio
+ bio_copy:
+               if (WC_MODE_PMEM(wc)) {
+                       bio_copy_block(wc, bio, memory_data(wc, e));
++                      wc->stats.writes++;
+               } else {
+                       writecache_bio_copy_ssd(wc, bio, e, search_used);
+                       return WC_MAP_REMAP;
+-- 
+2.35.1
+
diff --git a/queue-5.15/dm-writecache-return-void-from-functions.patch b/queue-5.15/dm-writecache-return-void-from-functions.patch
new file mode 100644 (file)
index 0000000..a5b4642
--- /dev/null
@@ -0,0 +1,102 @@
+From bd565f7976c4b3864d91f4181397920929d6d676 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Jul 2022 16:30:27 -0400
+Subject: dm writecache: return void from functions
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+[ Upstream commit 9bc0c92e4b82adb017026dbb2aa816b1ac2bef31 ]
+
+The functions writecache_map_remap_origin and writecache_bio_copy_ssd
+only return a single value, thus they can be made to return void.
+
+This helps simplify the following IO accounting changes.
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm-writecache.c | 26 +++++++++++++-------------
+ 1 file changed, 13 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c
+index 18320444fb0a..e3d0a9bb27b5 100644
+--- a/drivers/md/dm-writecache.c
++++ b/drivers/md/dm-writecache.c
+@@ -1328,8 +1328,8 @@ enum wc_map_op {
+       WC_MAP_ERROR,
+ };
+-static enum wc_map_op writecache_map_remap_origin(struct dm_writecache *wc, struct bio *bio,
+-                                                struct wc_entry *e)
++static void writecache_map_remap_origin(struct dm_writecache *wc, struct bio *bio,
++                                      struct wc_entry *e)
+ {
+       if (e) {
+               sector_t next_boundary =
+@@ -1337,8 +1337,6 @@ static enum wc_map_op writecache_map_remap_origin(struct dm_writecache *wc, stru
+               if (next_boundary < bio->bi_iter.bi_size >> SECTOR_SHIFT)
+                       dm_accept_partial_bio(bio, next_boundary);
+       }
+-
+-      return WC_MAP_REMAP_ORIGIN;
+ }
+ static enum wc_map_op writecache_map_read(struct dm_writecache *wc, struct bio *bio)
+@@ -1365,14 +1363,15 @@ static enum wc_map_op writecache_map_read(struct dm_writecache *wc, struct bio *
+                       map_op = WC_MAP_REMAP;
+               }
+       } else {
+-              map_op = writecache_map_remap_origin(wc, bio, e);
++              writecache_map_remap_origin(wc, bio, e);
++              map_op = WC_MAP_REMAP_ORIGIN;
+       }
+       return map_op;
+ }
+-static enum wc_map_op writecache_bio_copy_ssd(struct dm_writecache *wc, struct bio *bio,
+-                                            struct wc_entry *e, bool search_used)
++static void writecache_bio_copy_ssd(struct dm_writecache *wc, struct bio *bio,
++                                  struct wc_entry *e, bool search_used)
+ {
+       unsigned bio_size = wc->block_size;
+       sector_t start_cache_sec = cache_sector(wc, e);
+@@ -1418,8 +1417,6 @@ static enum wc_map_op writecache_bio_copy_ssd(struct dm_writecache *wc, struct b
+       } else {
+               writecache_schedule_autocommit(wc);
+       }
+-
+-      return WC_MAP_REMAP;
+ }
+ static enum wc_map_op writecache_map_write(struct dm_writecache *wc, struct bio *bio)
+@@ -1457,7 +1454,8 @@ static enum wc_map_op writecache_map_write(struct dm_writecache *wc, struct bio
+ direct_write:
+                               wc->stats.writes_around++;
+                               e = writecache_find_entry(wc, bio->bi_iter.bi_sector, WFE_RETURN_FOLLOWING);
+-                              return writecache_map_remap_origin(wc, bio, e);
++                              writecache_map_remap_origin(wc, bio, e);
++                              return WC_MAP_REMAP_ORIGIN;
+                       }
+                       wc->stats.writes_blocked_on_freelist++;
+                       writecache_wait_on_freelist(wc);
+@@ -1468,10 +1466,12 @@ static enum wc_map_op writecache_map_write(struct dm_writecache *wc, struct bio
+               wc->uncommitted_blocks++;
+               wc->stats.writes_allocate++;
+ bio_copy:
+-              if (WC_MODE_PMEM(wc))
++              if (WC_MODE_PMEM(wc)) {
+                       bio_copy_block(wc, bio, memory_data(wc, e));
+-              else
+-                      return writecache_bio_copy_ssd(wc, bio, e, search_used);
++              } else {
++                      writecache_bio_copy_ssd(wc, bio, e, search_used);
++                      return WC_MAP_REMAP;
++              }
+       } while (bio->bi_iter.bi_size);
+       if (unlikely(bio->bi_opf & REQ_FUA || wc->uncommitted_blocks >= wc->autocommit_blocks))
+-- 
+2.35.1
+
diff --git a/queue-5.15/dmaengine-dw-edma-fix-edma-rd-wr-channels-and-dma-di.patch b/queue-5.15/dmaengine-dw-edma-fix-edma-rd-wr-channels-and-dma-di.patch
new file mode 100644 (file)
index 0000000..0919bdb
--- /dev/null
@@ -0,0 +1,100 @@
+From 1157a881a1269fa34a32fb64dc2500c7f474ad78 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 May 2022 10:21:57 -0500
+Subject: dmaengine: dw-edma: Fix eDMA Rd/Wr-channels and DMA-direction
+ semantics
+
+From: Serge Semin <Sergey.Semin@baikalelectronics.ru>
+
+[ Upstream commit c1e33979171da63cf47e56243ccb8ba82363c7d3 ]
+
+In accordance with [1, 2] the DW eDMA controller has been created to be
+part of the DW PCIe Root Port and DW PCIe End-point controllers and to
+offload the transferring of large blocks of data between application and
+remote PCIe domains leaving the system CPU free for other tasks. In the
+first case (eDMA being part of DW PCIe Root Port) the eDMA controller is
+always accessible via the CPU DBI interface and never over the PCIe wire.
+
+The latter case is more complex. Depending on the DW PCIe End-Point IP-core
+synthesize parameters it's possible to have the eDMA registers accessible
+not only from the application CPU side, but also via mapping the eDMA CSRs
+over a dedicated endpoint BAR. So based on the specifics denoted above the
+eDMA driver is supposed to support two types of the DMA controller setups:
+
+  1) eDMA embedded into the DW PCIe Root Port/End-point and accessible over
+     the local CPU from the application side.
+
+  2) eDMA embedded into the DW PCIe End-point and accessible via the PCIe
+     wire with MWr/MRd TLPs generated by the CPU PCIe host controller.
+
+Since the CPU memory resides different sides in these cases the semantics
+of the MEM_TO_DEV and DEV_TO_MEM operations is flipped with respect to the
+Tx and Rx DMA channels. So MEM_TO_DEV/DEV_TO_MEM corresponds to the Tx/Rx
+channels in setup 1) and to the Rx/Tx channels in case of setup 2).
+
+The DW eDMA driver has supported the case 2) since e63d79d1ffcd
+("dmaengine: Add Synopsys eDMA IP core driver") in the framework of the
+drivers/dma/dw-edma/dw-edma-pcie.c driver.
+
+The case 1) support was added later by bd96f1b2f43a ("dmaengine: dw-edma:
+support local dma device transfer semantics").  Afterwards the driver was
+supposed to cover the both possible eDMA setups, but the latter commit
+turned out to be not fully correct.
+
+The problem was that the commit together with the new functionality support
+also changed the channel direction semantics so the eDMA Read-channel
+(corresponding to the DMA_DEV_TO_MEM direction for case 1) now uses the
+sgl/cyclic base addresses as the Source addresses of the DMA transfers and
+dma_slave_config.dst_addr as the Destination address of the DMA transfers.
+
+Similarly the eDMA Write-channel (corresponding to the DMA_MEM_TO_DEV
+direction for case 1) now uses dma_slave_config.src_addr as a source
+address of the DMA transfers and sgl/cyclic base address as the Destination
+address of the DMA transfers. This contradicts the logic of the
+DMA-interface, which implies that DEV side is supposed to belong to the
+PCIe device memory and MEM - to the CPU/Application memory. Indeed it seems
+irrational to have the SG-list defined in the PCIe bus space, while
+expecting a contiguous buffer allocated in the CPU memory. Moreover the
+passed SG-list and cyclic DMA buffers are supposed to be mapped in a way so
+to be seen by the DW eDMA Application (CPU) interface.
+
+So in order to have the correct DW eDMA interface we need to invert the
+eDMA Rd/Wr-channels and DMA-slave directions semantics by selecting the
+src/dst addresses based on the DMA transfer direction instead of using the
+channel direction capability.
+
+[1] DesignWare Cores PCI Express Controller Databook - DWC PCIe Root Port,
+    v.5.40a, March 2019, p.1092
+[2] DesignWare Cores PCI Express Controller Databook - DWC PCIe Endpoint,
+    v.5.40a, March 2019, p.1189
+
+Co-developed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Fixes: bd96f1b2f43a ("dmaengine: dw-edma: support local dma device transfer semantics")
+Link: https://lore.kernel.org/r/20220524152159.2370739-7-Frank.Li@nxp.com
+Tested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
+Signed-off-by: Frank Li <Frank.Li@nxp.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Acked-By: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/dw-edma/dw-edma-core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c
+index 53289927dd0d..36b3fe1b6b0f 100644
+--- a/drivers/dma/dw-edma/dw-edma-core.c
++++ b/drivers/dma/dw-edma/dw-edma-core.c
+@@ -424,7 +424,7 @@ dw_edma_device_transfer(struct dw_edma_transfer *xfer)
+               chunk->ll_region.sz += burst->sz;
+               desc->alloc_sz += burst->sz;
+-              if (chan->dir == EDMA_DIR_WRITE) {
++              if (dir == DMA_DEV_TO_MEM) {
+                       burst->sar = src_addr;
+                       if (xfer->type == EDMA_XFER_CYCLIC) {
+                               burst->dar = xfer->xfer.cyclic.paddr;
+-- 
+2.35.1
+
diff --git a/queue-5.15/dmaengine-imx-dma-cast-of_device_get_match_data-with.patch b/queue-5.15/dmaengine-imx-dma-cast-of_device_get_match_data-with.patch
new file mode 100644 (file)
index 0000000..4ef182f
--- /dev/null
@@ -0,0 +1,40 @@
+From 6e66b7373d35b1589a24f6a3e016521f3331b353 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Jul 2022 08:13:27 -0300
+Subject: dmaengine: imx-dma: Cast of_device_get_match_data() with (uintptr_t)
+
+From: Fabio Estevam <festevam@denx.de>
+
+[ Upstream commit c3266ee185b59e5aab3e0f982e5b7f95d31555a7 ]
+
+Change the of_device_get_match_data() cast to (uintptr_t)
+to silence the following clang warning:
+
+drivers/dma/imx-dma.c:1048:20: warning: cast to smaller integer type 'enum imx_dma_type' from 'const void *' [-Wvoid-pointer-to-enum-cast]
+
+Reported-by: kernel test robot <lkp@intel.com>
+Fixes: 0ab785c894e6 ("dmaengine: imx-dma: Remove unused .id_table")
+Signed-off-by: Fabio Estevam <festevam@denx.de>
+Link: https://lore.kernel.org/r/20220706111327.940764-1-festevam@gmail.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/imx-dma.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c
+index 2ddc31e64db0..da31e73d24d4 100644
+--- a/drivers/dma/imx-dma.c
++++ b/drivers/dma/imx-dma.c
+@@ -1047,7 +1047,7 @@ static int __init imxdma_probe(struct platform_device *pdev)
+               return -ENOMEM;
+       imxdma->dev = &pdev->dev;
+-      imxdma->devtype = (enum imx_dma_type)of_device_get_match_data(&pdev->dev);
++      imxdma->devtype = (uintptr_t)of_device_get_match_data(&pdev->dev);
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       imxdma->base = devm_ioremap_resource(&pdev->dev, res);
+-- 
+2.35.1
+
diff --git a/queue-5.15/dmaengine-sf-pdma-add-multithread-support-for-a-dma-.patch b/queue-5.15/dmaengine-sf-pdma-add-multithread-support-for-a-dma-.patch
new file mode 100644 (file)
index 0000000..e4ed896
--- /dev/null
@@ -0,0 +1,140 @@
+From 29628e4dd32a2d522364129cd2d2eb19d2bfda14 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 11:29:42 +0300
+Subject: dmaengine: sf-pdma: Add multithread support for a DMA channel
+
+From: Viacheslav Mitrofanov <v.v.mitrofanov@yadro.com>
+
+[ Upstream commit b2cc5c465c2cb8ab697c3fd6583c614e3f6cfbcc ]
+
+When we get a DMA channel and try to use it in multiple threads it
+will cause oops and hanging the system.
+
+% echo 64 > /sys/module/dmatest/parameters/threads_per_chan
+% echo 10000 > /sys/module/dmatest/parameters/iterations
+% echo 1 > /sys/module/dmatest/parameters/run
+[   89.480664] Unable to handle kernel NULL pointer dereference at virtual
+               address 00000000000000a0
+[   89.488725] Oops [#1]
+[   89.494708] CPU: 2 PID: 1008 Comm: dma0chan0-copy0 Not tainted
+               5.17.0-rc5
+[   89.509385] epc : vchan_find_desc+0x32/0x46
+[   89.513553]  ra : sf_pdma_tx_status+0xca/0xd6
+
+This happens because of data race. Each thread rewrite channels's
+descriptor as soon as device_prep_dma_memcpy() is called. It leads to the
+situation when the driver thinks that it uses right descriptor that
+actually is freed or substituted for other one.
+
+With current fixes a descriptor changes its value only when it has
+been used. A new descriptor is acquired from vc->desc_issued queue that
+is already filled with descriptors that are ready to be sent. Threads
+have no direct access to DMA channel descriptor. Now it is just possible
+to queue a descriptor for further processing.
+
+Fixes: 6973886ad58e ("dmaengine: sf-pdma: add platform DMA support for HiFive Unleashed A00")
+Signed-off-by: Viacheslav Mitrofanov <v.v.mitrofanov@yadro.com>
+Link: https://lore.kernel.org/r/20220701082942.12835-1-v.v.mitrofanov@yadro.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/sf-pdma/sf-pdma.c | 44 ++++++++++++++++++++++++-----------
+ 1 file changed, 30 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/dma/sf-pdma/sf-pdma.c b/drivers/dma/sf-pdma/sf-pdma.c
+index f12606aeff87..ab0ad7a2f201 100644
+--- a/drivers/dma/sf-pdma/sf-pdma.c
++++ b/drivers/dma/sf-pdma/sf-pdma.c
+@@ -52,16 +52,6 @@ static inline struct sf_pdma_desc *to_sf_pdma_desc(struct virt_dma_desc *vd)
+ static struct sf_pdma_desc *sf_pdma_alloc_desc(struct sf_pdma_chan *chan)
+ {
+       struct sf_pdma_desc *desc;
+-      unsigned long flags;
+-
+-      spin_lock_irqsave(&chan->lock, flags);
+-
+-      if (chan->desc && !chan->desc->in_use) {
+-              spin_unlock_irqrestore(&chan->lock, flags);
+-              return chan->desc;
+-      }
+-
+-      spin_unlock_irqrestore(&chan->lock, flags);
+       desc = kzalloc(sizeof(*desc), GFP_NOWAIT);
+       if (!desc)
+@@ -111,7 +101,6 @@ sf_pdma_prep_dma_memcpy(struct dma_chan *dchan,    dma_addr_t dest, dma_addr_t src,
+       desc->async_tx = vchan_tx_prep(&chan->vchan, &desc->vdesc, flags);
+       spin_lock_irqsave(&chan->vchan.lock, iflags);
+-      chan->desc = desc;
+       sf_pdma_fill_desc(desc, dest, src, len);
+       spin_unlock_irqrestore(&chan->vchan.lock, iflags);
+@@ -170,11 +159,17 @@ static size_t sf_pdma_desc_residue(struct sf_pdma_chan *chan,
+       unsigned long flags;
+       u64 residue = 0;
+       struct sf_pdma_desc *desc;
+-      struct dma_async_tx_descriptor *tx;
++      struct dma_async_tx_descriptor *tx = NULL;
+       spin_lock_irqsave(&chan->vchan.lock, flags);
+-      tx = &chan->desc->vdesc.tx;
++      list_for_each_entry(vd, &chan->vchan.desc_submitted, node)
++              if (vd->tx.cookie == cookie)
++                      tx = &vd->tx;
++
++      if (!tx)
++              goto out;
++
+       if (cookie == tx->chan->completed_cookie)
+               goto out;
+@@ -241,6 +236,19 @@ static void sf_pdma_enable_request(struct sf_pdma_chan *chan)
+       writel(v, regs->ctrl);
+ }
++static struct sf_pdma_desc *sf_pdma_get_first_pending_desc(struct sf_pdma_chan *chan)
++{
++      struct virt_dma_chan *vchan = &chan->vchan;
++      struct virt_dma_desc *vdesc;
++
++      if (list_empty(&vchan->desc_issued))
++              return NULL;
++
++      vdesc = list_first_entry(&vchan->desc_issued, struct virt_dma_desc, node);
++
++      return container_of(vdesc, struct sf_pdma_desc, vdesc);
++}
++
+ static void sf_pdma_xfer_desc(struct sf_pdma_chan *chan)
+ {
+       struct sf_pdma_desc *desc = chan->desc;
+@@ -268,8 +276,11 @@ static void sf_pdma_issue_pending(struct dma_chan *dchan)
+       spin_lock_irqsave(&chan->vchan.lock, flags);
+-      if (vchan_issue_pending(&chan->vchan) && chan->desc)
++      if (!chan->desc && vchan_issue_pending(&chan->vchan)) {
++              /* vchan_issue_pending has made a check that desc in not NULL */
++              chan->desc = sf_pdma_get_first_pending_desc(chan);
+               sf_pdma_xfer_desc(chan);
++      }
+       spin_unlock_irqrestore(&chan->vchan.lock, flags);
+ }
+@@ -298,6 +309,11 @@ static void sf_pdma_donebh_tasklet(struct tasklet_struct *t)
+       spin_lock_irqsave(&chan->vchan.lock, flags);
+       list_del(&chan->desc->vdesc.node);
+       vchan_cookie_complete(&chan->desc->vdesc);
++
++      chan->desc = sf_pdma_get_first_pending_desc(chan);
++      if (chan->desc)
++              sf_pdma_xfer_desc(chan);
++
+       spin_unlock_irqrestore(&chan->vchan.lock, flags);
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/driver-core-fix-potential-deadlock-in-__driver_attac.patch b/queue-5.15/driver-core-fix-potential-deadlock-in-__driver_attac.patch
new file mode 100644 (file)
index 0000000..4e6df43
--- /dev/null
@@ -0,0 +1,120 @@
+From 77f215edb0c317d51f4d3fcfe3f06397e72a3e47 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jun 2022 15:43:27 +0800
+Subject: driver core: fix potential deadlock in __driver_attach
+
+From: Zhang Wensheng <zhangwensheng5@huawei.com>
+
+[ Upstream commit 70fe758352cafdee72a7b13bf9db065f9613ced8 ]
+
+In __driver_attach function, There are also AA deadlock problem,
+like the commit b232b02bf3c2 ("driver core: fix deadlock in
+__device_attach").
+
+stack like commit b232b02bf3c2 ("driver core: fix deadlock in
+__device_attach").
+list below:
+    In __driver_attach function, The lock holding logic is as follows:
+    ...
+    __driver_attach
+    if (driver_allows_async_probing(drv))
+      device_lock(dev)      // get lock dev
+        async_schedule_dev(__driver_attach_async_helper, dev); // func
+          async_schedule_node
+            async_schedule_node_domain(func)
+              entry = kzalloc(sizeof(struct async_entry), GFP_ATOMIC);
+              /* when fail or work limit, sync to execute func, but
+                 __driver_attach_async_helper will get lock dev as
+                 will, which will lead to A-A deadlock.  */
+              if (!entry || atomic_read(&entry_count) > MAX_WORK) {
+                func;
+              else
+                queue_work_node(node, system_unbound_wq, &entry->work)
+      device_unlock(dev)
+
+    As above show, when it is allowed to do async probes, because of
+    out of memory or work limit, async work is not be allowed, to do
+    sync execute instead. it will lead to A-A deadlock because of
+    __driver_attach_async_helper getting lock dev.
+
+Reproduce:
+and it can be reproduce by make the condition
+(if (!entry || atomic_read(&entry_count) > MAX_WORK)) untenable, like
+below:
+
+[  370.785650] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables
+this message.
+[  370.787154] task:swapper/0       state:D stack:    0 pid:    1 ppid:
+0 flags:0x00004000
+[  370.788865] Call Trace:
+[  370.789374]  <TASK>
+[  370.789841]  __schedule+0x482/0x1050
+[  370.790613]  schedule+0x92/0x1a0
+[  370.791290]  schedule_preempt_disabled+0x2c/0x50
+[  370.792256]  __mutex_lock.isra.0+0x757/0xec0
+[  370.793158]  __mutex_lock_slowpath+0x1f/0x30
+[  370.794079]  mutex_lock+0x50/0x60
+[  370.794795]  __device_driver_lock+0x2f/0x70
+[  370.795677]  ? driver_probe_device+0xd0/0xd0
+[  370.796576]  __driver_attach_async_helper+0x1d/0xd0
+[  370.797318]  ? driver_probe_device+0xd0/0xd0
+[  370.797957]  async_schedule_node_domain+0xa5/0xc0
+[  370.798652]  async_schedule_node+0x19/0x30
+[  370.799243]  __driver_attach+0x246/0x290
+[  370.799828]  ? driver_allows_async_probing+0xa0/0xa0
+[  370.800548]  bus_for_each_dev+0x9d/0x130
+[  370.801132]  driver_attach+0x22/0x30
+[  370.801666]  bus_add_driver+0x290/0x340
+[  370.802246]  driver_register+0x88/0x140
+[  370.802817]  ? virtio_scsi_init+0x116/0x116
+[  370.803425]  scsi_register_driver+0x1a/0x30
+[  370.804057]  init_sd+0x184/0x226
+[  370.804533]  do_one_initcall+0x71/0x3a0
+[  370.805107]  kernel_init_freeable+0x39a/0x43a
+[  370.805759]  ? rest_init+0x150/0x150
+[  370.806283]  kernel_init+0x26/0x230
+[  370.806799]  ret_from_fork+0x1f/0x30
+
+To fix the deadlock, move the async_schedule_dev outside device_lock,
+as we can see, in async_schedule_node_domain, the parameter of
+queue_work_node is system_unbound_wq, so it can accept concurrent
+operations. which will also not change the code logic, and will
+not lead to deadlock.
+
+Fixes: ef0ff68351be ("driver core: Probe devices asynchronously instead of the driver")
+Signed-off-by: Zhang Wensheng <zhangwensheng5@huawei.com>
+Link: https://lore.kernel.org/r/20220622074327.497102-1-zhangwensheng5@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/dd.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/base/dd.c b/drivers/base/dd.c
+index 76ded601d0c1..70e9ee8a10f7 100644
+--- a/drivers/base/dd.c
++++ b/drivers/base/dd.c
+@@ -1094,6 +1094,7 @@ static void __driver_attach_async_helper(void *_dev, async_cookie_t cookie)
+ static int __driver_attach(struct device *dev, void *data)
+ {
+       struct device_driver *drv = data;
++      bool async = false;
+       int ret;
+       /*
+@@ -1132,9 +1133,11 @@ static int __driver_attach(struct device *dev, void *data)
+               if (!dev->driver) {
+                       get_device(dev);
+                       dev->p->async_driver = drv;
+-                      async_schedule_dev(__driver_attach_async_helper, dev);
++                      async = true;
+               }
+               device_unlock(dev);
++              if (async)
++                      async_schedule_dev(__driver_attach_async_helper, dev);
+               return 0;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/drivers-iio-remove-all-strcpy-uses.patch b/queue-5.15/drivers-iio-remove-all-strcpy-uses.patch
new file mode 100644 (file)
index 0000000..78c57bf
--- /dev/null
@@ -0,0 +1,89 @@
+From c1d9c80ce5d54aa2c18ac2a44b2feda24d794f70 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 15 Aug 2021 19:42:04 +0200
+Subject: drivers/iio: Remove all strcpy() uses
+
+From: Len Baker <len.baker@gmx.com>
+
+[ Upstream commit d722f1e06fbc53eb369b39646945c1fa92068e74 ]
+
+strcpy() performs no bounds checking on the destination buffer. This
+could result in linear overflows beyond the end of the buffer, leading
+to all kinds of misbehaviors. So, remove all the uses and add
+devm_kstrdup() or devm_kasprintf() instead.
+
+Also, modify the "for" loop conditions to clarify the access to the
+st->orientation.rotation buffer.
+
+This patch is an effort to clean up the proliferation of str*()
+functions in the kernel and a previous step in the path to remove
+the strcpy function from the kernel entirely [1].
+
+[1] https://github.com/KSPP/linux/issues/88
+
+Signed-off-by: Len Baker <len.baker@gmx.com>
+Link: https://lore.kernel.org/r/20210815174204.126593-1-len.baker@gmx.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/imu/inv_mpu6050/inv_mpu_magn.c | 36 +++++++++++++---------
+ 1 file changed, 21 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_magn.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_magn.c
+index f282e9cc34c5..6aee6c989485 100644
+--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_magn.c
++++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_magn.c
+@@ -261,6 +261,7 @@ int inv_mpu_magn_set_rate(const struct inv_mpu6050_state *st, int fifo_rate)
+  */
+ int inv_mpu_magn_set_orient(struct inv_mpu6050_state *st)
+ {
++      struct device *dev = regmap_get_device(st->map);
+       const char *orient;
+       char *str;
+       int i;
+@@ -279,22 +280,27 @@ int inv_mpu_magn_set_orient(struct inv_mpu6050_state *st)
+               st->magn_orient.rotation[4] = st->orientation.rotation[1];
+               st->magn_orient.rotation[5] = st->orientation.rotation[2];
+               /* z <- -z */
+-              for (i = 0; i < 3; ++i) {
+-                      orient = st->orientation.rotation[6 + i];
+-                      /* use length + 2 for adding minus sign if needed */
+-                      str = devm_kzalloc(regmap_get_device(st->map),
+-                                         strlen(orient) + 2, GFP_KERNEL);
+-                      if (str == NULL)
++              for (i = 6; i < 9; ++i) {
++                      orient = st->orientation.rotation[i];
++
++                      /*
++                       * The value is negated according to one of the following
++                       * rules:
++                       *
++                       * 1) Drop leading minus.
++                       * 2) Leave 0 as is.
++                       * 3) Add leading minus.
++                       */
++                      if (orient[0] == '-')
++                              str = devm_kstrdup(dev, orient + 1, GFP_KERNEL);
++                      else if (!strcmp(orient, "0"))
++                              str = devm_kstrdup(dev, orient, GFP_KERNEL);
++                      else
++                              str = devm_kasprintf(dev, GFP_KERNEL, "-%s", orient);
++                      if (!str)
+                               return -ENOMEM;
+-                      if (strcmp(orient, "0") == 0) {
+-                              strcpy(str, orient);
+-                      } else if (orient[0] == '-') {
+-                              strcpy(str, &orient[1]);
+-                      } else {
+-                              str[0] = '-';
+-                              strcpy(&str[1], orient);
+-                      }
+-                      st->magn_orient.rotation[6 + i] = str;
++
++                      st->magn_orient.rotation[i] = str;
+               }
+               break;
+       default:
+-- 
+2.35.1
+
diff --git a/queue-5.15/drivers-perf-arm_spe-fix-consistency-of-sys_pmscr_el.patch b/queue-5.15/drivers-perf-arm_spe-fix-consistency-of-sys_pmscr_el.patch
new file mode 100644 (file)
index 0000000..7661345
--- /dev/null
@@ -0,0 +1,103 @@
+From 238c1bdf6a6196d49118d764518fe50252f2620f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 11:43:02 +0530
+Subject: drivers/perf: arm_spe: Fix consistency of SYS_PMSCR_EL1.CX
+
+From: Anshuman Khandual <anshuman.khandual@arm.com>
+
+[ Upstream commit 92f2b8bafa3d6e89c750e9d301a8b7ab76aaa8b6 ]
+
+The arm_spe_pmu driver will enable SYS_PMSCR_EL1.CX in order to add CONTEXT
+packets into the traces, if the owner of the perf event runs with required
+capabilities i.e CAP_PERFMON or CAP_SYS_ADMIN via perfmon_capable() helper.
+
+The value of this bit is computed in the arm_spe_event_to_pmscr() function
+but the check for capabilities happens in the pmu event init callback i.e
+arm_spe_pmu_event_init(). This suggests that the value of the CX bit should
+remain consistent for the duration of the perf session.
+
+However, the function arm_spe_event_to_pmscr() may be called later during
+the event start callback i.e arm_spe_pmu_start() when the "current" process
+is not the owner of the perf session, hence the CX bit setting is currently
+not consistent.
+
+One way to fix this, is by caching the required value of the CX bit during
+the initialization of the PMU event, so that it remains consistent for the
+duration of the session. It uses currently unused 'event->hw.flags' element
+to cache perfmon_capable() value, which can be referred during event start
+callback to compute SYS_PMSCR_EL1.CX. This ensures consistent availability
+of context packets in the trace as per event owner capabilities.
+
+Drop BIT(SYS_PMSCR_EL1_CX_SHIFT) check in arm_spe_pmu_event_init(), because
+now CX bit cannot be set in arm_spe_event_to_pmscr() with perfmon_capable()
+disabled.
+
+Cc: Will Deacon <will@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Alexey Budankov <alexey.budankov@linux.intel.com>
+Cc: linux-arm-kernel@lists.infradead.org
+Cc: linux-kernel@vger.kernel.org
+Fixes: d5d9696b0380 ("drivers/perf: Add support for ARMv8.2 Statistical Profiling Extension")
+Reported-by: German Gomez <german.gomez@arm.com>
+Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
+Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Link: https://lore.kernel.org/r/20220714061302.2715102-1-anshuman.khandual@arm.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/perf/arm_spe_pmu.c | 22 ++++++++++++++++++++--
+ 1 file changed, 20 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/perf/arm_spe_pmu.c b/drivers/perf/arm_spe_pmu.c
+index d44bcc29d99c..cd5945e17fdf 100644
+--- a/drivers/perf/arm_spe_pmu.c
++++ b/drivers/perf/arm_spe_pmu.c
+@@ -39,6 +39,24 @@
+ #include <asm/mmu.h>
+ #include <asm/sysreg.h>
++/*
++ * Cache if the event is allowed to trace Context information.
++ * This allows us to perform the check, i.e, perfmon_capable(),
++ * in the context of the event owner, once, during the event_init().
++ */
++#define SPE_PMU_HW_FLAGS_CX                   BIT(0)
++
++static void set_spe_event_has_cx(struct perf_event *event)
++{
++      if (IS_ENABLED(CONFIG_PID_IN_CONTEXTIDR) && perfmon_capable())
++              event->hw.flags |= SPE_PMU_HW_FLAGS_CX;
++}
++
++static bool get_spe_event_has_cx(struct perf_event *event)
++{
++      return !!(event->hw.flags & SPE_PMU_HW_FLAGS_CX);
++}
++
+ #define ARM_SPE_BUF_PAD_BYTE                  0
+ struct arm_spe_pmu_buf {
+@@ -272,7 +290,7 @@ static u64 arm_spe_event_to_pmscr(struct perf_event *event)
+       if (!attr->exclude_kernel)
+               reg |= BIT(SYS_PMSCR_EL1_E1SPE_SHIFT);
+-      if (IS_ENABLED(CONFIG_PID_IN_CONTEXTIDR) && perfmon_capable())
++      if (get_spe_event_has_cx(event))
+               reg |= BIT(SYS_PMSCR_EL1_CX_SHIFT);
+       return reg;
+@@ -709,10 +727,10 @@ static int arm_spe_pmu_event_init(struct perf_event *event)
+           !(spe_pmu->features & SPE_PMU_FEAT_FILT_LAT))
+               return -EOPNOTSUPP;
++      set_spe_event_has_cx(event);
+       reg = arm_spe_event_to_pmscr(event);
+       if (!perfmon_capable() &&
+           (reg & (BIT(SYS_PMSCR_EL1_PA_SHIFT) |
+-                  BIT(SYS_PMSCR_EL1_CX_SHIFT) |
+                   BIT(SYS_PMSCR_EL1_PCT_SHIFT))))
+               return -EACCES;
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-adv7511-override-i2c-address-of-cec-before-acces.patch b/queue-5.15/drm-adv7511-override-i2c-address-of-cec-before-acces.patch
new file mode 100644 (file)
index 0000000..244b777
--- /dev/null
@@ -0,0 +1,63 @@
+From 81bc84ed151776c394adf95462883dd423e50755 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jun 2022 23:31:44 +0200
+Subject: drm: adv7511: override i2c address of cec before accessing it
+
+From: Antonio Borneo <antonio.borneo@foss.st.com>
+
+[ Upstream commit 9cc4853e4781bf0dd0f35355dc92d97c9da02f5d ]
+
+Commit 680532c50bca ("drm: adv7511: Add support for
+i2c_new_secondary_device") allows a device tree node to override
+the default addresses of the secondary i2c devices. This is useful
+for solving address conflicts on the i2c bus.
+
+In adv7511_init_cec_regmap() the new i2c address of cec device is
+read from device tree and immediately accessed, well before it is
+written in the proper register to override the default address.
+This can cause an i2c error during probe and a consequent probe
+failure.
+
+Once the new i2c address is read from the device tree, override
+the default address before any attempt to access the cec.
+
+Tested with adv7533 and stm32mp157f.
+
+Signed-off-by: Antonio Borneo <antonio.borneo@foss.st.com>
+Fixes: 680532c50bca ("drm: adv7511: Add support for i2c_new_secondary_device")
+Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
+Signed-off-by: Robert Foss <robert.foss@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220607213144.427177-1-antonio.borneo@foss.st.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+index 8c2025584f1b..1aadc6e94fde 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
++++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+@@ -1063,6 +1063,10 @@ static int adv7511_init_cec_regmap(struct adv7511 *adv)
+                                               ADV7511_CEC_I2C_ADDR_DEFAULT);
+       if (IS_ERR(adv->i2c_cec))
+               return PTR_ERR(adv->i2c_cec);
++
++      regmap_write(adv->regmap, ADV7511_REG_CEC_I2C_ADDR,
++                   adv->i2c_cec->addr << 1);
++
+       i2c_set_clientdata(adv->i2c_cec, adv);
+       adv->regmap_cec = devm_regmap_init_i2c(adv->i2c_cec,
+@@ -1267,9 +1271,6 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
+       if (ret)
+               goto err_i2c_unregister_packet;
+-      regmap_write(adv7511->regmap, ADV7511_REG_CEC_I2C_ADDR,
+-                   adv7511->i2c_cec->addr << 1);
+-
+       INIT_WORK(&adv7511->hpd_work, adv7511_hpd_work);
+       if (i2c->irq) {
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-amdgpu-remove-one-duplicated-ef-removal.patch b/queue-5.15/drm-amdgpu-remove-one-duplicated-ef-removal.patch
new file mode 100644 (file)
index 0000000..2831ffd
--- /dev/null
@@ -0,0 +1,48 @@
+From f5b079fad35b7245a561fb99edbcfda76ba39853 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Jul 2022 09:22:44 +0800
+Subject: drm/amdgpu: Remove one duplicated ef removal
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: xinhui pan <xinhui.pan@amd.com>
+
+[ Upstream commit e1aadbab445b06e072013a1365fd0cf2aa25e843 ]
+
+That has been done in BO release notify.
+
+Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/2074
+Signed-off-by: xinhui pan <xinhui.pan@amd.com>
+Acked-by: Christian König <christian.koenig@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>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 6 ------
+ 1 file changed, 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+index 21c02f817a84..c904269b3e14 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+@@ -1318,16 +1318,10 @@ void amdgpu_amdkfd_gpuvm_destroy_cb(struct amdgpu_device *adev,
+                                   struct amdgpu_vm *vm)
+ {
+       struct amdkfd_process_info *process_info = vm->process_info;
+-      struct amdgpu_bo *pd = vm->root.bo;
+       if (!process_info)
+               return;
+-      /* Release eviction fence from PD */
+-      amdgpu_bo_reserve(pd, false);
+-      amdgpu_bo_fence(pd, NULL, false);
+-      amdgpu_bo_unreserve(pd);
+-
+       /* Update process info */
+       mutex_lock(&process_info->lock);
+       process_info->n_vms--;
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-bridge-add-a-function-to-abstract-away-panels.patch b/queue-5.15/drm-bridge-add-a-function-to-abstract-away-panels.patch
new file mode 100644 (file)
index 0000000..877b3b3
--- /dev/null
@@ -0,0 +1,124 @@
+From 4da63c57ff0fb3a905252ec28cbef0e653941edb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Sep 2021 15:09:39 +0200
+Subject: drm/bridge: Add a function to abstract away panels
+
+From: Maxime Ripard <maxime@cerno.tech>
+
+[ Upstream commit 87ea95808d53e56b03e620e8f8f3add48899a88d ]
+
+Display drivers so far need to have a lot of boilerplate to first
+retrieve either the panel or bridge that they are connected to using
+drm_of_find_panel_or_bridge(), and then either deal with each with ad-hoc
+functions or create a drm panel bridge through drm_panel_bridge_add.
+
+In order to reduce the boilerplate and hopefully create a path of least
+resistance towards using the DRM panel bridge layer, let's create the
+function devm_drm_of_get_bridge() to reduce that boilerplate.
+
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210910130941.1740182-2-maxime@cerno.tech
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_bridge.c | 41 ++++++++++++++++++++++++++++++++----
+ drivers/gpu/drm/drm_of.c     |  3 +++
+ include/drm/drm_bridge.h     |  2 ++
+ 3 files changed, 42 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
+index a8ed66751c2d..4c68733fa660 100644
+--- a/drivers/gpu/drm/drm_bridge.c
++++ b/drivers/gpu/drm/drm_bridge.c
+@@ -28,6 +28,7 @@
+ #include <drm/drm_atomic_state_helper.h>
+ #include <drm/drm_bridge.h>
+ #include <drm/drm_encoder.h>
++#include <drm/drm_of.h>
+ #include <drm/drm_print.h>
+ #include "drm_crtc_internal.h"
+@@ -51,10 +52,8 @@
+  *
+  * Display drivers are responsible for linking encoders with the first bridge
+  * in the chains. This is done by acquiring the appropriate bridge with
+- * of_drm_find_bridge() or drm_of_find_panel_or_bridge(), or creating it for a
+- * panel with drm_panel_bridge_add_typed() (or the managed version
+- * devm_drm_panel_bridge_add_typed()). Once acquired, the bridge shall be
+- * attached to the encoder with a call to drm_bridge_attach().
++ * devm_drm_of_get_bridge(). Once acquired, the bridge shall be attached to the
++ * encoder with a call to drm_bridge_attach().
+  *
+  * Bridges are responsible for linking themselves with the next bridge in the
+  * chain, if any. This is done the same way as for encoders, with the call to
+@@ -1233,6 +1232,40 @@ struct drm_bridge *of_drm_find_bridge(struct device_node *np)
+       return NULL;
+ }
+ EXPORT_SYMBOL(of_drm_find_bridge);
++
++/**
++ * devm_drm_of_get_bridge - Return next bridge in the chain
++ * @dev: device to tie the bridge lifetime to
++ * @np: device tree node containing encoder output ports
++ * @port: port in the device tree node
++ * @endpoint: endpoint in the device tree node
++ *
++ * Given a DT node's port and endpoint number, finds the connected node
++ * and returns the associated bridge if any, or creates and returns a
++ * drm panel bridge instance if a panel is connected.
++ *
++ * Returns a pointer to the bridge if successful, or an error pointer
++ * otherwise.
++ */
++struct drm_bridge *devm_drm_of_get_bridge(struct device *dev,
++                                        struct device_node *np,
++                                        u32 port, u32 endpoint)
++{
++      struct drm_bridge *bridge;
++      struct drm_panel *panel;
++      int ret;
++
++      ret = drm_of_find_panel_or_bridge(np, port, endpoint,
++                                        &panel, &bridge);
++      if (ret)
++              return ERR_PTR(ret);
++
++      if (panel)
++              bridge = devm_drm_panel_bridge_add(dev, panel);
++
++      return bridge;
++}
++EXPORT_SYMBOL(devm_drm_of_get_bridge);
+ #endif
+ MODULE_AUTHOR("Ajay Kumar <ajaykumar.rs@samsung.com>");
+diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
+index 997b8827fed2..37c34146eea8 100644
+--- a/drivers/gpu/drm/drm_of.c
++++ b/drivers/gpu/drm/drm_of.c
+@@ -231,6 +231,9 @@ EXPORT_SYMBOL_GPL(drm_of_encoder_active_endpoint);
+  * return either the associated struct drm_panel or drm_bridge device. Either
+  * @panel or @bridge must not be NULL.
+  *
++ * This function is deprecated and should not be used in new drivers. Use
++ * devm_drm_of_get_bridge() instead.
++ *
+  * Returns zero if successful, or one of the standard error codes if it fails.
+  */
+ int drm_of_find_panel_or_bridge(const struct device_node *np,
+diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
+index 46bdfa48c413..9cdbd209388e 100644
+--- a/include/drm/drm_bridge.h
++++ b/include/drm/drm_bridge.h
+@@ -911,6 +911,8 @@ struct drm_bridge *devm_drm_panel_bridge_add(struct device *dev,
+ struct drm_bridge *devm_drm_panel_bridge_add_typed(struct device *dev,
+                                                  struct drm_panel *panel,
+                                                  u32 connector_type);
++struct drm_bridge *devm_drm_of_get_bridge(struct device *dev, struct device_node *node,
++                                        u32 port, u32 endpoint);
+ struct drm_connector *drm_panel_bridge_connector(struct drm_bridge *bridge);
+ #endif
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-bridge-adv7511-add-check-for-mipi_dsi_driver_reg.patch b/queue-5.15/drm-bridge-adv7511-add-check-for-mipi_dsi_driver_reg.patch
new file mode 100644 (file)
index 0000000..bf54c66
--- /dev/null
@@ -0,0 +1,57 @@
+From d0edffa999e1bb910321da770dd010966a5c6c9d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jun 2022 18:34:01 +0800
+Subject: drm: bridge: adv7511: Add check for mipi_dsi_driver_register
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit 831463667b5f4f1e5bce9c3b94e9e794d2bc8923 ]
+
+As mipi_dsi_driver_register could return error if fails,
+it should be better to check the return value and return error
+if fails.
+Moreover, if i2c_add_driver fails,  mipi_dsi_driver_register
+should be reverted.
+
+Fixes: 1e4d58cd7f88 ("drm/bridge: adv7533: Create a MIPI DSI device")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220602103401.2980938-1-jiasheng@iscas.ac.cn
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 17 ++++++++++++++---
+ 1 file changed, 14 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+index 1aadc6e94fde..7e3f6633f255 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
++++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+@@ -1379,10 +1379,21 @@ static struct i2c_driver adv7511_driver = {
+ static int __init adv7511_init(void)
+ {
+-      if (IS_ENABLED(CONFIG_DRM_MIPI_DSI))
+-              mipi_dsi_driver_register(&adv7533_dsi_driver);
++      int ret;
++
++      if (IS_ENABLED(CONFIG_DRM_MIPI_DSI)) {
++              ret = mipi_dsi_driver_register(&adv7533_dsi_driver);
++              if (ret)
++                      return ret;
++      }
+-      return i2c_add_driver(&adv7511_driver);
++      ret = i2c_add_driver(&adv7511_driver);
++      if (ret) {
++              if (IS_ENABLED(CONFIG_DRM_MIPI_DSI))
++                      mipi_dsi_driver_unregister(&adv7533_dsi_driver);
++      }
++
++      return ret;
+ }
+ module_init(adv7511_init);
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-bridge-lt9611uxc-cancel-only-driver-s-work.patch b/queue-5.15/drm-bridge-lt9611uxc-cancel-only-driver-s-work.patch
new file mode 100644 (file)
index 0000000..cc75458
--- /dev/null
@@ -0,0 +1,40 @@
+From d472e03530756496fa618b4af6b793c28d0feb0c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Jun 2022 16:38:18 -0700
+Subject: drm/bridge: lt9611uxc: Cancel only driver's work
+
+From: Bjorn Andersson <bjorn.andersson@linaro.org>
+
+[ Upstream commit dfa687bffc8a4a21ed929c7dececf01b8f1f52ee ]
+
+During device remove care needs to be taken that no work is pending
+before it removes the underlying DRM bridge etc, but this can be done on
+the specific work rather than waiting for the flush of the system-wide
+workqueue.
+
+Fixes: bc6fa8676ebb ("drm/bridge/lontium-lt9611uxc: move HPD notification out of IRQ handler")
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
+Signed-off-by: Robert Foss <robert.foss@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220601233818.1877963-1-bjorn.andersson@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
+index 010657ea7af7..c4454d0f6cad 100644
+--- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
++++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
+@@ -997,7 +997,7 @@ static int lt9611uxc_remove(struct i2c_client *client)
+       struct lt9611uxc *lt9611uxc = i2c_get_clientdata(client);
+       disable_irq(client->irq);
+-      flush_scheduled_work();
++      cancel_work_sync(&lt9611uxc->work);
+       lt9611uxc_audio_exit(lt9611uxc);
+       drm_bridge_remove(&lt9611uxc->bridge);
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-bridge-sii8620-fix-possible-off-by-one.patch b/queue-5.15/drm-bridge-sii8620-fix-possible-off-by-one.patch
new file mode 100644 (file)
index 0000000..5f5d201
--- /dev/null
@@ -0,0 +1,52 @@
+From 96dea7ceae20f8f022ef588a302166b059de6164 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 May 2022 14:58:56 +0800
+Subject: drm: bridge: sii8620: fix possible off-by-one
+
+From: Hangyu Hua <hbh25y@gmail.com>
+
+[ Upstream commit 21779cc21c732c5eff8ea1624be6590450baa30f ]
+
+The next call to sii8620_burst_get_tx_buf will result in off-by-one
+When ctx->burst.tx_count + size == ARRAY_SIZE(ctx->burst.tx_buf). The same
+thing happens in sii8620_burst_get_rx_buf.
+
+This patch also change tx_count and tx_buf to rx_count and rx_buf in
+sii8620_burst_get_rx_buf. It is unreasonable to check tx_buf's size and
+use rx_buf.
+
+Fixes: e19e9c692f81 ("drm/bridge/sii8620: add support for burst eMSC transmissions")
+Signed-off-by: Hangyu Hua <hbh25y@gmail.com>
+Reviewed-by: Andrzej Hajda <andrzej.hajda@intel.com>
+Signed-off-by: Robert Foss <robert.foss@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220518065856.18936-1-hbh25y@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/sil-sii8620.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
+index ec7745c31da0..ab0bce4a988c 100644
+--- a/drivers/gpu/drm/bridge/sil-sii8620.c
++++ b/drivers/gpu/drm/bridge/sil-sii8620.c
+@@ -605,7 +605,7 @@ static void *sii8620_burst_get_tx_buf(struct sii8620 *ctx, int len)
+       u8 *buf = &ctx->burst.tx_buf[ctx->burst.tx_count];
+       int size = len + 2;
+-      if (ctx->burst.tx_count + size > ARRAY_SIZE(ctx->burst.tx_buf)) {
++      if (ctx->burst.tx_count + size >= ARRAY_SIZE(ctx->burst.tx_buf)) {
+               dev_err(ctx->dev, "TX-BLK buffer exhausted\n");
+               ctx->error = -EINVAL;
+               return NULL;
+@@ -622,7 +622,7 @@ static u8 *sii8620_burst_get_rx_buf(struct sii8620 *ctx, int len)
+       u8 *buf = &ctx->burst.rx_buf[ctx->burst.rx_count];
+       int size = len + 1;
+-      if (ctx->burst.tx_count + size > ARRAY_SIZE(ctx->burst.tx_buf)) {
++      if (ctx->burst.rx_count + size >= ARRAY_SIZE(ctx->burst.rx_buf)) {
+               dev_err(ctx->dev, "RX-BLK buffer exhausted\n");
+               ctx->error = -EINVAL;
+               return NULL;
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-bridge-tc358767-move-e-dp-bridge-endpoint-parsin.patch b/queue-5.15/drm-bridge-tc358767-move-e-dp-bridge-endpoint-parsin.patch
new file mode 100644 (file)
index 0000000..19d5213
--- /dev/null
@@ -0,0 +1,87 @@
+From 763cb917809db7d1cc591ac0a833bac22a71777e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Mar 2022 10:50:10 +0200
+Subject: drm/bridge: tc358767: Move (e)DP bridge endpoint parsing into
+ dedicated function
+
+From: Marek Vasut <marex@denx.de>
+
+[ Upstream commit 8478095a8c4bcea3c83b0767d6c9127434160761 ]
+
+The TC358767/TC358867/TC9595 are all capable of operating in multiple
+modes, DPI-to-(e)DP, DSI-to-(e)DP, DSI-to-DPI. Only the first mode is
+currently supported. In order to support the rest of the modes without
+making the tc_probe() overly long, split the bridge endpoint parsing
+into dedicated function, where the necessary logic to detect the bridge
+mode based on which endpoints are connected, can be implemented.
+
+Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
+Tested-by: Lucas Stach <l.stach@pengutronix.de> # In both DPI to eDP and DSI to DPI mode.
+Signed-off-by: Marek Vasut <marex@denx.de>
+Cc: Jonas Karlman <jonas@kwiboo.se>
+Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
+Cc: Maxime Ripard <maxime@cerno.tech>
+Cc: Neil Armstrong <narmstrong@baylibre.com>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Signed-off-by: Robert Foss <robert.foss@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220329085015.39159-7-marex@denx.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/tc358767.c | 30 +++++++++++++++++++++---------
+ 1 file changed, 21 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c
+index 23a6f90b694b..a2d051ed6cd8 100644
+--- a/drivers/gpu/drm/bridge/tc358767.c
++++ b/drivers/gpu/drm/bridge/tc358767.c
+@@ -1549,19 +1549,12 @@ static irqreturn_t tc_irq_handler(int irq, void *arg)
+       return IRQ_HANDLED;
+ }
+-static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id)
++static int tc_probe_edp_bridge_endpoint(struct tc_data *tc)
+ {
+-      struct device *dev = &client->dev;
++      struct device *dev = tc->dev;
+       struct drm_panel *panel;
+-      struct tc_data *tc;
+       int ret;
+-      tc = devm_kzalloc(dev, sizeof(*tc), GFP_KERNEL);
+-      if (!tc)
+-              return -ENOMEM;
+-
+-      tc->dev = dev;
+-
+       /* port@2 is the output port */
+       ret = drm_of_find_panel_or_bridge(dev->of_node, 2, 0, &panel, NULL);
+       if (ret && ret != -ENODEV)
+@@ -1580,6 +1573,25 @@ static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id)
+               tc->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
+       }
++      return ret;
++}
++
++static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id)
++{
++      struct device *dev = &client->dev;
++      struct tc_data *tc;
++      int ret;
++
++      tc = devm_kzalloc(dev, sizeof(*tc), GFP_KERNEL);
++      if (!tc)
++              return -ENOMEM;
++
++      tc->dev = dev;
++
++      ret = tc_probe_edp_bridge_endpoint(tc);
++      if (ret)
++              return ret;
++
+       /* Shut down GPIO is optional */
+       tc->sd_gpio = devm_gpiod_get_optional(dev, "shutdown", GPIOD_OUT_HIGH);
+       if (IS_ERR(tc->sd_gpio))
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-dp-export-symbol-kerneldoc-fixes-for-dp-aux-bus.patch b/queue-5.15/drm-dp-export-symbol-kerneldoc-fixes-for-dp-aux-bus.patch
new file mode 100644 (file)
index 0000000..97253e6
--- /dev/null
@@ -0,0 +1,56 @@
+From 95892f9cef21b7f0f30d9efaff115fa799d6bf69 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 May 2022 12:29:41 -0700
+Subject: drm/dp: Export symbol / kerneldoc fixes for DP AUX bus
+
+From: Douglas Anderson <dianders@chromium.org>
+
+[ Upstream commit 39c28cdfb719f0e306b447f0827dfd712f81858b ]
+
+While working on the DP AUX bus code I found a few small things that
+should be fixed. Namely the non-devm version of
+of_dp_aux_populate_ep_devices() was missing an export. There was also
+an extra blank line in a kerneldoc and a kerneldoc that incorrectly
+documented a return value. Fix these.
+
+Fixes: aeb33699fc2c ("drm: Introduce the DP AUX bus")
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220510122726.v3.1.Ia91f4849adfc5eb9da1eb37ba79aa65fb3c95a0f@changeid
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_dp_aux_bus.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/drm_dp_aux_bus.c b/drivers/gpu/drm/drm_dp_aux_bus.c
+index 298ea7a49591..f7c03ad5a15a 100644
+--- a/drivers/gpu/drm/drm_dp_aux_bus.c
++++ b/drivers/gpu/drm/drm_dp_aux_bus.c
+@@ -66,7 +66,6 @@ static int dp_aux_ep_probe(struct device *dev)
+  * @dev: The device to remove.
+  *
+  * Calls through to the endpoint driver remove.
+- *
+  */
+ static void dp_aux_ep_remove(struct device *dev)
+ {
+@@ -120,8 +119,6 @@ ATTRIBUTE_GROUPS(dp_aux_ep_dev);
+ /**
+  * dp_aux_ep_dev_release() - Free memory for the dp_aux_ep device
+  * @dev: The device to free.
+- *
+- * Return: 0 if no error or negative error code.
+  */
+ static void dp_aux_ep_dev_release(struct device *dev)
+ {
+@@ -256,6 +253,7 @@ int of_dp_aux_populate_ep_devices(struct drm_dp_aux *aux)
+       return 0;
+ }
++EXPORT_SYMBOL_GPL(of_dp_aux_populate_ep_devices);
+ static void of_dp_aux_depopulate_ep_devices_void(void *data)
+ {
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-exynos-exynos7_drm_decon-free-resources-when-clk.patch b/queue-5.15/drm-exynos-exynos7_drm_decon-free-resources-when-clk.patch
new file mode 100644 (file)
index 0000000..82cc9c3
--- /dev/null
@@ -0,0 +1,75 @@
+From 5dc0857942cd341b6433ee9d4777865237db9998 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Jul 2022 13:56:11 +0900
+Subject: drm/exynos/exynos7_drm_decon: free resources when clk_set_parent()
+ failed.
+
+From: Jian Zhang <zhangjian210@huawei.com>
+
+[ Upstream commit 48b927770f8ad3f8cf4a024a552abf272af9f592 ]
+
+In exynos7_decon_resume, When it fails, we must use clk_disable_unprepare()
+to free resource that have been used.
+
+Fixes: 6f83d20838c09 ("drm/exynos: use DRM_DEV_ERROR to print out error
+message")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Jian Zhang <zhangjian210@huawei.com>
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/exynos/exynos7_drm_decon.c | 17 +++++++++++++----
+ 1 file changed, 13 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
+index 12571ac45540..12989a47eb66 100644
+--- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c
++++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
+@@ -806,31 +806,40 @@ static int exynos7_decon_resume(struct device *dev)
+       if (ret < 0) {
+               DRM_DEV_ERROR(dev, "Failed to prepare_enable the pclk [%d]\n",
+                             ret);
+-              return ret;
++              goto err_pclk_enable;
+       }
+       ret = clk_prepare_enable(ctx->aclk);
+       if (ret < 0) {
+               DRM_DEV_ERROR(dev, "Failed to prepare_enable the aclk [%d]\n",
+                             ret);
+-              return ret;
++              goto err_aclk_enable;
+       }
+       ret = clk_prepare_enable(ctx->eclk);
+       if  (ret < 0) {
+               DRM_DEV_ERROR(dev, "Failed to prepare_enable the eclk [%d]\n",
+                             ret);
+-              return ret;
++              goto err_eclk_enable;
+       }
+       ret = clk_prepare_enable(ctx->vclk);
+       if  (ret < 0) {
+               DRM_DEV_ERROR(dev, "Failed to prepare_enable the vclk [%d]\n",
+                             ret);
+-              return ret;
++              goto err_vclk_enable;
+       }
+       return 0;
++
++err_vclk_enable:
++      clk_disable_unprepare(ctx->eclk);
++err_eclk_enable:
++      clk_disable_unprepare(ctx->aclk);
++err_aclk_enable:
++      clk_disable_unprepare(ctx->pclk);
++err_pclk_enable:
++      return ret;
+ }
+ #endif
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-mcde-fix-refcount-leak-in-mcde_dsi_bind.patch b/queue-5.15/drm-mcde-fix-refcount-leak-in-mcde_dsi_bind.patch
new file mode 100644 (file)
index 0000000..08f2b9b
--- /dev/null
@@ -0,0 +1,38 @@
+From 327a2c32d0e9efe5aa878624cb2f929735fb8608 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 May 2022 15:54:11 +0400
+Subject: drm/mcde: Fix refcount leak in mcde_dsi_bind
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 3a149169e4a2f9127022fec6ef5d71b4e804b3b9 ]
+
+Every iteration of for_each_available_child_of_node() decrements
+the reference counter of the previous node. There is no decrement
+when break out from the loop and results in refcount leak.
+Add missing of_node_put() to fix this.
+
+Fixes: 5fc537bfd000 ("drm/mcde: Add new driver for ST-Ericsson MCDE")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220525115411.65455-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mcde/mcde_dsi.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/mcde/mcde_dsi.c b/drivers/gpu/drm/mcde/mcde_dsi.c
+index 180ebbccbeda..0b58d7f4ba78 100644
+--- a/drivers/gpu/drm/mcde/mcde_dsi.c
++++ b/drivers/gpu/drm/mcde/mcde_dsi.c
+@@ -1111,6 +1111,7 @@ static int mcde_dsi_bind(struct device *dev, struct device *master,
+                       bridge = of_drm_find_bridge(child);
+                       if (!bridge) {
+                               dev_err(dev, "failed to find bridge\n");
++                              of_node_put(child);
+                               return -EINVAL;
+                       }
+               }
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-mediatek-add-pull-down-mipi-operation-in-mtk_dsi.patch b/queue-5.15/drm-mediatek-add-pull-down-mipi-operation-in-mtk_dsi.patch
new file mode 100644 (file)
index 0000000..c68580a
--- /dev/null
@@ -0,0 +1,49 @@
+From 017447b2090083273f16c4d25c0cf3dd75ddd1ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 May 2022 10:00:07 +0800
+Subject: drm/mediatek: Add pull-down MIPI operation in mtk_dsi_poweroff
+ function
+
+From: Xinlei Lee <xinlei.lee@mediatek.com>
+
+[ Upstream commit fa5d0a0205c34734c5b8daa77e39ac2817f63a10 ]
+
+In the dsi_enable function, mtk_dsi_rxtx_control is to
+pull up the MIPI signal operation. Before dsi_disable,
+MIPI should also be pulled down by writing a register
+instead of disabling dsi.
+
+If disable dsi without pulling the mipi signal low, the value of
+the register will still maintain the setting of the mipi signal being
+pulled high.
+After resume, even if the mipi signal is not pulled high, it will still
+be in the high state.
+
+Fixes: 2e54c14e310f ("drm/mediatek: Add DSI sub driver")
+
+Link: https://patchwork.kernel.org/project/linux-mediatek/patch/1653012007-11854-5-git-send-email-xinlei.lee@mediatek.com/
+Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
+Signed-off-by: Xinlei Lee <xinlei.lee@mediatek.com>
+Reviewed-by: Rex-BC Chen <rex-bc.chen@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_dsi.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
+index c30af7ca5fad..b0cb0ba53589 100644
+--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
++++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
+@@ -682,6 +682,8 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
+       mtk_dsi_reset_engine(dsi);
+       mtk_dsi_lane0_ulp_mode_enter(dsi);
+       mtk_dsi_clk_ulp_mode_enter(dsi);
++      /* set the lane number as 0 to pull down mipi */
++      writel(0, dsi->regs + DSI_TXRX_CTRL);
+       mtk_dsi_disable(dsi);
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-mediatek-dpi-only-enable-dpi-after-the-bridge-is.patch b/queue-5.15/drm-mediatek-dpi-only-enable-dpi-after-the-bridge-is.patch
new file mode 100644 (file)
index 0000000..439d5a7
--- /dev/null
@@ -0,0 +1,48 @@
+From ee23366e43ec42fca678d3eca15f704997177fca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 11:58:44 +0800
+Subject: drm/mediatek: dpi: Only enable dpi after the bridge is enabled
+
+From: Guillaume Ranquet <granquet@baylibre.com>
+
+[ Upstream commit aed61ef6beb911cc043af0f2f291167663995065 ]
+
+Enabling the dpi too early causes glitches on screen.
+
+Move the call to mtk_dpi_enable() at the end of the bridge_enable
+callback to ensure everything is setup properly before enabling dpi.
+
+Fixes: 9e629c17aa8d ("drm/mediatek: Add DPI sub driver")
+Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
+Signed-off-by: Bo-Chen Chen <rex-bc.chen@mediatek.com>
+Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20220701035845.16458-16-rex-bc.chen@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_dpi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
+index 675e2e4072df..41c783349321 100644
+--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
++++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
+@@ -417,7 +417,6 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
+       if (dpi->pinctrl && dpi->pins_dpi)
+               pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi);
+-      mtk_dpi_enable(dpi);
+       return 0;
+ err_pixel:
+@@ -639,6 +638,7 @@ static void mtk_dpi_bridge_enable(struct drm_bridge *bridge)
+       mtk_dpi_power_on(dpi);
+       mtk_dpi_set_display_mode(dpi, &dpi->mode);
++      mtk_dpi_enable(dpi);
+ }
+ static enum drm_mode_status
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-mediatek-dpi-remove-output-format-of-yuv.patch b/queue-5.15/drm-mediatek-dpi-remove-output-format-of-yuv.patch
new file mode 100644 (file)
index 0000000..2969645
--- /dev/null
@@ -0,0 +1,73 @@
+From e042d3f1937b9a69f0c1d0b68b055f1ba278f686 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 11:58:33 +0800
+Subject: drm/mediatek: dpi: Remove output format of YUV
+
+From: Bo-Chen Chen <rex-bc.chen@mediatek.com>
+
+[ Upstream commit c9ed0713b3c35fc45677707ba47f432cad95da56 ]
+
+DPI is not support output format as YUV, but there is the setting of
+configuring output YUV. Therefore, remove them in this patch.
+
+Fixes: 9e629c17aa8d ("drm/mediatek: Add DPI sub driver")
+Signed-off-by: Bo-Chen Chen <rex-bc.chen@mediatek.com>
+Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20220701035845.16458-5-rex-bc.chen@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_dpi.c | 31 ++++++------------------------
+ 1 file changed, 6 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
+index e61cd67b978f..675e2e4072df 100644
+--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
++++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
+@@ -54,13 +54,7 @@ enum mtk_dpi_out_channel_swap {
+ };
+ enum mtk_dpi_out_color_format {
+-      MTK_DPI_COLOR_FORMAT_RGB,
+-      MTK_DPI_COLOR_FORMAT_RGB_FULL,
+-      MTK_DPI_COLOR_FORMAT_YCBCR_444,
+-      MTK_DPI_COLOR_FORMAT_YCBCR_422,
+-      MTK_DPI_COLOR_FORMAT_XV_YCC,
+-      MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL,
+-      MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL
++      MTK_DPI_COLOR_FORMAT_RGB
+ };
+ struct mtk_dpi {
+@@ -364,24 +358,11 @@ static void mtk_dpi_config_disable_edge(struct mtk_dpi *dpi)
+ static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
+                                       enum mtk_dpi_out_color_format format)
+ {
+-      if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_444) ||
+-          (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) {
+-              mtk_dpi_config_yuv422_enable(dpi, false);
+-              mtk_dpi_config_csc_enable(dpi, true);
+-              mtk_dpi_config_swap_input(dpi, false);
+-              mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_BGR);
+-      } else if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_422) ||
+-                 (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) {
+-              mtk_dpi_config_yuv422_enable(dpi, true);
+-              mtk_dpi_config_csc_enable(dpi, true);
+-              mtk_dpi_config_swap_input(dpi, true);
+-              mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
+-      } else {
+-              mtk_dpi_config_yuv422_enable(dpi, false);
+-              mtk_dpi_config_csc_enable(dpi, false);
+-              mtk_dpi_config_swap_input(dpi, false);
+-              mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
+-      }
++      /* only support RGB888 */
++      mtk_dpi_config_yuv422_enable(dpi, false);
++      mtk_dpi_config_csc_enable(dpi, false);
++      mtk_dpi_config_swap_input(dpi, false);
++      mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
+ }
+ static void mtk_dpi_dual_edge(struct mtk_dpi *dpi)
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-mediatek-modify-dsi-funcs-to-atomic-operations.patch b/queue-5.15/drm-mediatek-modify-dsi-funcs-to-atomic-operations.patch
new file mode 100644 (file)
index 0000000..f6e2993
--- /dev/null
@@ -0,0 +1,59 @@
+From 821af1d64db555f45b0f24854d9e4674f37e0bab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 May 2022 10:00:04 +0800
+Subject: drm/mediatek: Modify dsi funcs to atomic operations
+
+From: Xinlei Lee <xinlei.lee@mediatek.com>
+
+[ Upstream commit 7f6335c6a258edf4d5ff1b904bc033188dc7b48b ]
+
+Because .enable & .disable are deprecated.
+Use .atomic_enable & .atomic_disable instead.
+
+Link: https://patchwork.kernel.org/project/linux-mediatek/patch/1653012007-11854-2-git-send-email-xinlei.lee@mediatek.com/
+Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
+Signed-off-by: Xinlei Lee <xinlei.lee@mediatek.com>
+Reviewed-by: Rex-BC Chen <rex-bc.chen@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_dsi.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
+index 5d90d2eb0019..cfa354037bb8 100644
+--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
++++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
+@@ -751,14 +751,16 @@ static void mtk_dsi_bridge_mode_set(struct drm_bridge *bridge,
+       drm_display_mode_to_videomode(adjusted, &dsi->vm);
+ }
+-static void mtk_dsi_bridge_disable(struct drm_bridge *bridge)
++static void mtk_dsi_bridge_atomic_disable(struct drm_bridge *bridge,
++                                        struct drm_bridge_state *old_bridge_state)
+ {
+       struct mtk_dsi *dsi = bridge_to_dsi(bridge);
+       mtk_output_dsi_disable(dsi);
+ }
+-static void mtk_dsi_bridge_enable(struct drm_bridge *bridge)
++static void mtk_dsi_bridge_atomic_enable(struct drm_bridge *bridge,
++                                       struct drm_bridge_state *old_bridge_state)
+ {
+       struct mtk_dsi *dsi = bridge_to_dsi(bridge);
+@@ -767,8 +769,8 @@ static void mtk_dsi_bridge_enable(struct drm_bridge *bridge)
+ static const struct drm_bridge_funcs mtk_dsi_bridge_funcs = {
+       .attach = mtk_dsi_bridge_attach,
+-      .disable = mtk_dsi_bridge_disable,
+-      .enable = mtk_dsi_bridge_enable,
++      .atomic_disable = mtk_dsi_bridge_atomic_disable,
++      .atomic_enable = mtk_dsi_bridge_atomic_enable,
+       .mode_set = mtk_dsi_bridge_mode_set,
+ };
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-mediatek-separate-poweron-poweroff-from-enable-d.patch b/queue-5.15/drm-mediatek-separate-poweron-poweroff-from-enable-d.patch
new file mode 100644 (file)
index 0000000..2f19d53
--- /dev/null
@@ -0,0 +1,130 @@
+From 5785462a535f046e459170d399192e774c88a0a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 May 2022 10:00:05 +0800
+Subject: drm/mediatek: Separate poweron/poweroff from enable/disable and
+ define new funcs
+
+From: Jitao Shi <jitao.shi@mediatek.com>
+
+[ Upstream commit cde7e2e35c2866d22a3a012e72a41052dfcc255d ]
+
+In order to match the changes of "Use the drm_panel_bridge API",
+the poweron/poweroff of dsi is extracted from enable/disable and
+defined as new funcs (atomic_pre_enable/atomic_post_disable).
+
+Since dsi_poweron is moved from dsi_enable to pre_enable function, in
+order to avoid poweron failure, the operation of dsi register fails to
+cause bus hang. Therefore, the protection mechanism is added to the
+dsi_enable function.
+
+Fixes: 2dd8075d2185 ("drm/mediatek: mtk_dsi: Use the drm_panel_bridge API")
+
+Link: https://patchwork.kernel.org/project/linux-mediatek/patch/1653012007-11854-3-git-send-email-xinlei.lee@mediatek.com/
+Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
+Signed-off-by: Xinlei Lee <xinlei.lee@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Rex-BC Chen <rex-bc.chen@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_dsi.c | 53 +++++++++++++++++++-----------
+ 1 file changed, 34 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
+index cfa354037bb8..c30af7ca5fad 100644
+--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
++++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
+@@ -679,16 +679,6 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
+       if (--dsi->refcount != 0)
+               return;
+-      /*
+-       * mtk_dsi_stop() and mtk_dsi_start() is asymmetric, since
+-       * mtk_dsi_stop() should be called after mtk_drm_crtc_atomic_disable(),
+-       * which needs irq for vblank, and mtk_dsi_stop() will disable irq.
+-       * mtk_dsi_start() needs to be called in mtk_output_dsi_enable(),
+-       * after dsi is fully set.
+-       */
+-      mtk_dsi_stop(dsi);
+-
+-      mtk_dsi_switch_to_cmd_mode(dsi, VM_DONE_INT_FLAG, 500);
+       mtk_dsi_reset_engine(dsi);
+       mtk_dsi_lane0_ulp_mode_enter(dsi);
+       mtk_dsi_clk_ulp_mode_enter(dsi);
+@@ -703,17 +693,9 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
+ static void mtk_output_dsi_enable(struct mtk_dsi *dsi)
+ {
+-      int ret;
+-
+       if (dsi->enabled)
+               return;
+-      ret = mtk_dsi_poweron(dsi);
+-      if (ret < 0) {
+-              DRM_ERROR("failed to power on dsi\n");
+-              return;
+-      }
+-
+       mtk_dsi_set_mode(dsi);
+       mtk_dsi_clk_hs_mode(dsi, 1);
+@@ -727,7 +709,16 @@ static void mtk_output_dsi_disable(struct mtk_dsi *dsi)
+       if (!dsi->enabled)
+               return;
+-      mtk_dsi_poweroff(dsi);
++      /*
++       * mtk_dsi_stop() and mtk_dsi_start() is asymmetric, since
++       * mtk_dsi_stop() should be called after mtk_drm_crtc_atomic_disable(),
++       * which needs irq for vblank, and mtk_dsi_stop() will disable irq.
++       * mtk_dsi_start() needs to be called in mtk_output_dsi_enable(),
++       * after dsi is fully set.
++       */
++      mtk_dsi_stop(dsi);
++
++      mtk_dsi_switch_to_cmd_mode(dsi, VM_DONE_INT_FLAG, 500);
+       dsi->enabled = false;
+ }
+@@ -764,13 +755,37 @@ static void mtk_dsi_bridge_atomic_enable(struct drm_bridge *bridge,
+ {
+       struct mtk_dsi *dsi = bridge_to_dsi(bridge);
++      if (dsi->refcount == 0)
++              return;
++
+       mtk_output_dsi_enable(dsi);
+ }
++static void mtk_dsi_bridge_atomic_pre_enable(struct drm_bridge *bridge,
++                                           struct drm_bridge_state *old_bridge_state)
++{
++      struct mtk_dsi *dsi = bridge_to_dsi(bridge);
++      int ret;
++
++      ret = mtk_dsi_poweron(dsi);
++      if (ret < 0)
++              DRM_ERROR("failed to power on dsi\n");
++}
++
++static void mtk_dsi_bridge_atomic_post_disable(struct drm_bridge *bridge,
++                                             struct drm_bridge_state *old_bridge_state)
++{
++      struct mtk_dsi *dsi = bridge_to_dsi(bridge);
++
++      mtk_dsi_poweroff(dsi);
++}
++
+ static const struct drm_bridge_funcs mtk_dsi_bridge_funcs = {
+       .attach = mtk_dsi_bridge_attach,
+       .atomic_disable = mtk_dsi_bridge_atomic_disable,
+       .atomic_enable = mtk_dsi_bridge_atomic_enable,
++      .atomic_pre_enable = mtk_dsi_bridge_atomic_pre_enable,
++      .atomic_post_disable = mtk_dsi_bridge_atomic_post_disable,
+       .mode_set = mtk_dsi_bridge_mode_set,
+ };
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-meson-encoder_hdmi-fix-refcount-leak-in-meson_en.patch b/queue-5.15/drm-meson-encoder_hdmi-fix-refcount-leak-in-meson_en.patch
new file mode 100644 (file)
index 0000000..a066b42
--- /dev/null
@@ -0,0 +1,85 @@
+From d2cf1e149d014158cc4d4c8fc89ef5f023510995 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Jun 2022 07:39:27 +0400
+Subject: drm/meson: encoder_hdmi: Fix refcount leak in meson_encoder_hdmi_init
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit d82a5a4aae9d0203234737caed1bf470aa317568 ]
+
+of_graph_get_remote_node() returns remote device nodepointer with
+refcount incremented, we should use of_node_put() on it when done.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: e67f6037ae1b ("drm/meson: split out encoder from meson_dw_hdmi")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220601033927.47814-3-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/meson/meson_encoder_hdmi.c | 15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.c b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
+index 5e306de6f485..0d532e8e8cca 100644
+--- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c
++++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
+@@ -365,7 +365,8 @@ int meson_encoder_hdmi_init(struct meson_drm *priv)
+       meson_encoder_hdmi->next_bridge = of_drm_find_bridge(remote);
+       if (!meson_encoder_hdmi->next_bridge) {
+               dev_err(priv->dev, "Failed to find HDMI transceiver bridge\n");
+-              return -EPROBE_DEFER;
++              ret = -EPROBE_DEFER;
++              goto err_put_node;
+       }
+       /* HDMI Encoder Bridge */
+@@ -383,7 +384,7 @@ int meson_encoder_hdmi_init(struct meson_drm *priv)
+                                     DRM_MODE_ENCODER_TMDS);
+       if (ret) {
+               dev_err(priv->dev, "Failed to init HDMI encoder: %d\n", ret);
+-              return ret;
++              goto err_put_node;
+       }
+       meson_encoder_hdmi->encoder.possible_crtcs = BIT(0);
+@@ -393,7 +394,7 @@ int meson_encoder_hdmi_init(struct meson_drm *priv)
+                               DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+       if (ret) {
+               dev_err(priv->dev, "Failed to attach bridge: %d\n", ret);
+-              return ret;
++              goto err_put_node;
+       }
+       /* Initialize & attach Bridge Connector */
+@@ -401,7 +402,8 @@ int meson_encoder_hdmi_init(struct meson_drm *priv)
+                                                       &meson_encoder_hdmi->encoder);
+       if (IS_ERR(meson_encoder_hdmi->connector)) {
+               dev_err(priv->dev, "Unable to create HDMI bridge connector\n");
+-              return PTR_ERR(meson_encoder_hdmi->connector);
++              ret = PTR_ERR(meson_encoder_hdmi->connector);
++              goto err_put_node;
+       }
+       drm_connector_attach_encoder(meson_encoder_hdmi->connector,
+                                    &meson_encoder_hdmi->encoder);
+@@ -428,6 +430,7 @@ int meson_encoder_hdmi_init(struct meson_drm *priv)
+       meson_encoder_hdmi->connector->ycbcr_420_allowed = true;
+       pdev = of_find_device_by_node(remote);
++      of_node_put(remote);
+       if (pdev) {
+               struct cec_connector_info conn_info;
+               struct cec_notifier *notifier;
+@@ -444,4 +447,8 @@ int meson_encoder_hdmi_init(struct meson_drm *priv)
+       dev_dbg(priv->dev, "HDMI encoder initialized\n");
+       return 0;
++
++err_put_node:
++      of_node_put(remote);
++      return ret;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-meson-encoder_hdmi-switch-to-bridge-drm_bridge_a.patch b/queue-5.15/drm-meson-encoder_hdmi-switch-to-bridge-drm_bridge_a.patch
new file mode 100644 (file)
index 0000000..b733851
--- /dev/null
@@ -0,0 +1,213 @@
+From c53543b8685b6e5e01bb0a9555e663d237963302 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Oct 2021 14:39:45 +0200
+Subject: drm/meson: encoder_hdmi: switch to bridge
+ DRM_BRIDGE_ATTACH_NO_CONNECTOR
+
+From: Neil Armstrong <narmstrong@baylibre.com>
+
+[ Upstream commit 0af5e0b41110e2da872030395231ab19c45be931 ]
+
+This implements the necessary change to no more use the embedded
+connector in dw-hdmi and use the dedicated bridge connector driver
+by passing DRM_BRIDGE_ATTACH_NO_CONNECTOR to the bridge attach call.
+
+The necessary connector properties are added to handle the same
+functionalities as the embedded dw-hdmi connector, i.e. the HDR
+metadata, the CEC notifier & other flags.
+
+The dw-hdmi output_port is set to 1 in order to look for a connector
+next bridge in order to get DRM_BRIDGE_ATTACH_NO_CONNECTOR working.
+
+Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
+Acked-by: Sam Ravnborg <sam@ravnborg.org>
+Acked-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20211020123947.2585572-5-narmstrong@baylibre.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/meson/Kconfig              |  2 +
+ drivers/gpu/drm/meson/meson_dw_hdmi.c      |  1 +
+ drivers/gpu/drm/meson/meson_encoder_hdmi.c | 81 +++++++++++++++++++++-
+ 3 files changed, 82 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/meson/Kconfig b/drivers/gpu/drm/meson/Kconfig
+index 9f9281dd49f8..a4e1ed96e5e8 100644
+--- a/drivers/gpu/drm/meson/Kconfig
++++ b/drivers/gpu/drm/meson/Kconfig
+@@ -6,9 +6,11 @@ config DRM_MESON
+       select DRM_KMS_HELPER
+       select DRM_KMS_CMA_HELPER
+       select DRM_GEM_CMA_HELPER
++      select DRM_DISPLAY_CONNECTOR
+       select VIDEOMODE_HELPERS
+       select REGMAP_MMIO
+       select MESON_CANVAS
++      select CEC_CORE if CEC_NOTIFIER
+ config DRM_MESON_DW_HDMI
+       tristate "HDMI Synopsys Controller support for Amlogic Meson Display"
+diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c
+index fb540a503efe..5cd2b2ebbbd3 100644
+--- a/drivers/gpu/drm/meson/meson_dw_hdmi.c
++++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c
+@@ -803,6 +803,7 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
+       dw_plat_data->input_bus_encoding = V4L2_YCBCR_ENC_709;
+       dw_plat_data->ycbcr_420_allowed = true;
+       dw_plat_data->disable_cec = true;
++      dw_plat_data->output_port = 1;
+       if (dw_hdmi_is_compatible(meson_dw_hdmi, "amlogic,meson-gxl-dw-hdmi") ||
+           dw_hdmi_is_compatible(meson_dw_hdmi, "amlogic,meson-gxm-dw-hdmi") ||
+diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.c b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
+index db332fa4cd54..5e306de6f485 100644
+--- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c
++++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
+@@ -14,8 +14,11 @@
+ #include <linux/regulator/consumer.h>
+ #include <linux/reset.h>
++#include <media/cec-notifier.h>
++
+ #include <drm/drm_atomic_helper.h>
+ #include <drm/drm_bridge.h>
++#include <drm/drm_bridge_connector.h>
+ #include <drm/drm_device.h>
+ #include <drm/drm_edid.h>
+ #include <drm/drm_probe_helper.h>
+@@ -34,8 +37,10 @@ struct meson_encoder_hdmi {
+       struct drm_encoder encoder;
+       struct drm_bridge bridge;
+       struct drm_bridge *next_bridge;
++      struct drm_connector *connector;
+       struct meson_drm *priv;
+       unsigned long output_bus_fmt;
++      struct cec_notifier *cec_notifier;
+ };
+ #define bridge_to_meson_encoder_hdmi(x) \
+@@ -50,6 +55,14 @@ static int meson_encoder_hdmi_attach(struct drm_bridge *bridge,
+                                &encoder_hdmi->bridge, flags);
+ }
++static void meson_encoder_hdmi_detach(struct drm_bridge *bridge)
++{
++      struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge);
++
++      cec_notifier_conn_unregister(encoder_hdmi->cec_notifier);
++      encoder_hdmi->cec_notifier = NULL;
++}
++
+ static void meson_encoder_hdmi_set_vclk(struct meson_encoder_hdmi *encoder_hdmi,
+                                       const struct drm_display_mode *mode)
+ {
+@@ -298,9 +311,30 @@ static int meson_encoder_hdmi_atomic_check(struct drm_bridge *bridge,
+       return 0;
+ }
++static void meson_encoder_hdmi_hpd_notify(struct drm_bridge *bridge,
++                                        enum drm_connector_status status)
++{
++      struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge);
++      struct edid *edid;
++
++      if (!encoder_hdmi->cec_notifier)
++              return;
++
++      if (status == connector_status_connected) {
++              edid = drm_bridge_get_edid(encoder_hdmi->next_bridge, encoder_hdmi->connector);
++              if (!edid)
++                      return;
++
++              cec_notifier_set_phys_addr_from_edid(encoder_hdmi->cec_notifier, edid);
++      } else
++              cec_notifier_phys_addr_invalidate(encoder_hdmi->cec_notifier);
++}
++
+ static const struct drm_bridge_funcs meson_encoder_hdmi_bridge_funcs = {
+       .attach = meson_encoder_hdmi_attach,
++      .detach = meson_encoder_hdmi_detach,
+       .mode_valid = meson_encoder_hdmi_mode_valid,
++      .hpd_notify = meson_encoder_hdmi_hpd_notify,
+       .atomic_enable = meson_encoder_hdmi_atomic_enable,
+       .atomic_disable = meson_encoder_hdmi_atomic_disable,
+       .atomic_get_input_bus_fmts = meson_encoder_hdmi_get_inp_bus_fmts,
+@@ -313,6 +347,7 @@ static const struct drm_bridge_funcs meson_encoder_hdmi_bridge_funcs = {
+ int meson_encoder_hdmi_init(struct meson_drm *priv)
+ {
+       struct meson_encoder_hdmi *meson_encoder_hdmi;
++      struct platform_device *pdev;
+       struct device_node *remote;
+       int ret;
+@@ -337,6 +372,7 @@ int meson_encoder_hdmi_init(struct meson_drm *priv)
+       meson_encoder_hdmi->bridge.funcs = &meson_encoder_hdmi_bridge_funcs;
+       meson_encoder_hdmi->bridge.of_node = priv->dev->of_node;
+       meson_encoder_hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
++      meson_encoder_hdmi->bridge.interlace_allowed = true;
+       drm_bridge_add(&meson_encoder_hdmi->bridge);
+@@ -353,17 +389,58 @@ int meson_encoder_hdmi_init(struct meson_drm *priv)
+       meson_encoder_hdmi->encoder.possible_crtcs = BIT(0);
+       /* Attach HDMI Encoder Bridge to Encoder */
+-      ret = drm_bridge_attach(&meson_encoder_hdmi->encoder, &meson_encoder_hdmi->bridge, NULL, 0);
++      ret = drm_bridge_attach(&meson_encoder_hdmi->encoder, &meson_encoder_hdmi->bridge, NULL,
++                              DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+       if (ret) {
+               dev_err(priv->dev, "Failed to attach bridge: %d\n", ret);
+               return ret;
+       }
++      /* Initialize & attach Bridge Connector */
++      meson_encoder_hdmi->connector = drm_bridge_connector_init(priv->drm,
++                                                      &meson_encoder_hdmi->encoder);
++      if (IS_ERR(meson_encoder_hdmi->connector)) {
++              dev_err(priv->dev, "Unable to create HDMI bridge connector\n");
++              return PTR_ERR(meson_encoder_hdmi->connector);
++      }
++      drm_connector_attach_encoder(meson_encoder_hdmi->connector,
++                                   &meson_encoder_hdmi->encoder);
++
+       /*
+        * We should have now in place:
+-       * encoder->[hdmi encoder bridge]->[dw-hdmi bridge]->[dw-hdmi connector]
++       * encoder->[hdmi encoder bridge]->[dw-hdmi bridge]->[display connector bridge]->[display connector]
+        */
++      /*
++       * drm_connector_attach_max_bpc_property() requires the
++       * connector to have a state.
++       */
++      drm_atomic_helper_connector_reset(meson_encoder_hdmi->connector);
++
++      if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL) ||
++          meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
++          meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
++              drm_connector_attach_hdr_output_metadata_property(meson_encoder_hdmi->connector);
++
++      drm_connector_attach_max_bpc_property(meson_encoder_hdmi->connector, 8, 8);
++
++      /* Handle this here until handled by drm_bridge_connector_init() */
++      meson_encoder_hdmi->connector->ycbcr_420_allowed = true;
++
++      pdev = of_find_device_by_node(remote);
++      if (pdev) {
++              struct cec_connector_info conn_info;
++              struct cec_notifier *notifier;
++
++              cec_fill_conn_info_from_drm(&conn_info, meson_encoder_hdmi->connector);
++
++              notifier = cec_notifier_conn_register(&pdev->dev, NULL, &conn_info);
++              if (!notifier)
++                      return -ENOMEM;
++
++              meson_encoder_hdmi->cec_notifier = notifier;
++      }
++
+       dev_dbg(priv->dev, "HDMI encoder initialized\n");
+       return 0;
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-mipi-dbi-align-max_chunk-to-2-in-spi_transfer.patch b/queue-5.15/drm-mipi-dbi-align-max_chunk-to-2-in-spi_transfer.patch
new file mode 100644 (file)
index 0000000..3223f83
--- /dev/null
@@ -0,0 +1,51 @@
+From b4a4c8c1ab4720a561052f4e5e6614c3bcc4736b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 May 2022 11:02:19 +0800
+Subject: drm/mipi-dbi: align max_chunk to 2 in spi_transfer
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Yunhao Tian <t123yh.xyz@gmail.com>
+
+[ Upstream commit 435c249008cba04ed6a7975e9411f3b934620204 ]
+
+In __spi_validate, there's a validation that no partial transfers
+are accepted (xfer->len % w_size must be zero). When
+max_chunk is not a multiple of bpw (e.g. max_chunk = 65535,
+bpw = 16), the transfer will be rejected.
+
+This patch aligns max_chunk to 2 bytes (the maximum value of bpw is 16),
+so that no partial transfer will occur.
+
+Fixes: d23d4d4dac01 ("drm/tinydrm: Move tinydrm_spi_transfer()")
+
+Signed-off-by: Yunhao Tian <t123yh.xyz@gmail.com>
+Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220510030219.2486687-1-t123yh.xyz@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_mipi_dbi.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c
+index 71b646c4131f..00d470ff071d 100644
+--- a/drivers/gpu/drm/drm_mipi_dbi.c
++++ b/drivers/gpu/drm/drm_mipi_dbi.c
+@@ -1183,6 +1183,13 @@ int mipi_dbi_spi_transfer(struct spi_device *spi, u32 speed_hz,
+       size_t chunk;
+       int ret;
++      /* In __spi_validate, there's a validation that no partial transfers
++       * are accepted (xfer->len % w_size must be zero).
++       * Here we align max_chunk to multiple of 2 (16bits),
++       * to prevent transfers from being rejected.
++       */
++      max_chunk = ALIGN_DOWN(max_chunk, 2);
++
+       spi_message_init_with_transfers(&m, &tr, 1);
+       while (len) {
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-msm-avoid-dirtyfb-stalls-on-video-mode-displays-.patch b/queue-5.15/drm-msm-avoid-dirtyfb-stalls-on-video-mode-displays-.patch
new file mode 100644 (file)
index 0000000..6a42f62
--- /dev/null
@@ -0,0 +1,445 @@
+From 1c3f8a9c07b21d6f1a9e68120bf36c42372ff704 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Feb 2022 11:11:08 -0800
+Subject: drm/msm: Avoid dirtyfb stalls on video mode displays (v2)
+
+From: Rob Clark <robdclark@chromium.org>
+
+[ Upstream commit 9e4dde28e9cd34ee13a6b7247f0857fb49fd3f19 ]
+
+Someone on IRC once asked an innocent enough sounding question:  Why
+with xf86-video-modesetting is es2gears limited at 120fps.
+
+So I broke out the perfetto tracing mesa MR and took a look.  It turns
+out the problem was drm_atomic_helper_dirtyfb(), which would end up
+waiting for vblank.. es2gears would rapidly push two frames to Xorg,
+which would blit them to screen and in idle hook (I assume) call the
+DIRTYFB ioctl.  Which in turn would do an atomic update to flush the
+dirty rects, which would stall until the next vblank.  And then the
+whole process would repeat.
+
+But this is a bit silly, we only need dirtyfb for command mode DSI
+panels.  So track in plane state whether dirtyfb is required, and
+track in the fb how many attached planes require dirtyfb so that we
+can skip it when not required.  (Note, mdp4 does not actually have
+cmd mode support.)
+
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://lore.kernel.org/r/20220223191118.881321-1-robdclark@gmail.com
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c   | 20 ++++++++++-
+ drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c  |  5 +--
+ drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h  |  3 ++
+ drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c | 19 ++++++++--
+ drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c  |  8 +++++
+ drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h   |  5 +++
+ drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c | 21 +++++++++--
+ drivers/gpu/drm/msm/msm_atomic.c           | 15 --------
+ drivers/gpu/drm/msm/msm_drv.h              |  6 ++--
+ drivers/gpu/drm/msm/msm_fb.c               | 41 ++++++++++++++++++----
+ 10 files changed, 110 insertions(+), 33 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+index 768012243b44..7706a7106122 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+@@ -898,6 +898,20 @@ struct plane_state {
+       u32 pipe_id;
+ };
++static bool dpu_crtc_needs_dirtyfb(struct drm_crtc_state *cstate)
++{
++      struct drm_crtc *crtc = cstate->crtc;
++      struct drm_encoder *encoder;
++
++      drm_for_each_encoder_mask (encoder, crtc->dev, cstate->encoder_mask) {
++              if (dpu_encoder_get_intf_mode(encoder) == INTF_MODE_CMD) {
++                      return true;
++              }
++      }
++
++      return false;
++}
++
+ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
+               struct drm_atomic_state *state)
+ {
+@@ -918,6 +932,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
+       const struct drm_plane_state *pipe_staged[SSPP_MAX];
+       int left_zpos_cnt = 0, right_zpos_cnt = 0;
+       struct drm_rect crtc_rect = { 0 };
++      bool needs_dirtyfb = dpu_crtc_needs_dirtyfb(crtc_state);
+       pstates = kzalloc(sizeof(*pstates) * DPU_STAGE_MAX * 4, GFP_KERNEL);
+@@ -949,6 +964,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
+        /* get plane state for all drm planes associated with crtc state */
+       drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
++              struct dpu_plane_state *dpu_pstate = to_dpu_plane_state(pstate);
+               struct drm_rect dst, clip = crtc_rect;
+               if (IS_ERR_OR_NULL(pstate)) {
+@@ -960,11 +976,13 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
+               if (cnt >= DPU_STAGE_MAX * 4)
+                       continue;
+-              pstates[cnt].dpu_pstate = to_dpu_plane_state(pstate);
++              pstates[cnt].dpu_pstate = dpu_pstate;
+               pstates[cnt].drm_pstate = pstate;
+               pstates[cnt].stage = pstate->normalized_zpos;
+               pstates[cnt].pipe_id = dpu_plane_pipe(plane);
++              dpu_pstate->needs_dirtyfb = needs_dirtyfb;
++
+               if (pipe_staged[pstates[cnt].pipe_id]) {
+                       multirect_plane[multirect_count].r0 =
+                               pipe_staged[pstates[cnt].pipe_id];
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+index c989621209aa..e32fe89c203c 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+@@ -894,7 +894,7 @@ static int dpu_plane_prepare_fb(struct drm_plane *plane,
+       if (pstate->aspace) {
+               ret = msm_framebuffer_prepare(new_state->fb,
+-                              pstate->aspace);
++                              pstate->aspace, pstate->needs_dirtyfb);
+               if (ret) {
+                       DPU_ERROR("failed to prepare framebuffer\n");
+                       return ret;
+@@ -925,7 +925,8 @@ static void dpu_plane_cleanup_fb(struct drm_plane *plane,
+       DPU_DEBUG_PLANE(pdpu, "FB[%u]\n", old_state->fb->base.id);
+-      msm_framebuffer_cleanup(old_state->fb, old_pstate->aspace);
++      msm_framebuffer_cleanup(old_state->fb, old_pstate->aspace,
++                              old_pstate->needs_dirtyfb);
+ }
+ static bool dpu_plane_validate_src(struct drm_rect *src,
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+index 34e03ac05f4a..17ff48564c8a 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+@@ -28,6 +28,7 @@
+  * @cdp_cfg:  CDP configuration
+  * @plane_fetch_bw: calculated BW per plane
+  * @plane_clk: calculated clk per plane
++ * @needs_dirtyfb: whether attached CRTC needs pixel data explicitly flushed
+  */
+ struct dpu_plane_state {
+       struct drm_plane_state base;
+@@ -45,6 +46,8 @@ struct dpu_plane_state {
+       struct dpu_hw_pipe_cdp_cfg cdp_cfg;
+       u64 plane_fetch_bw;
+       u64 plane_clk;
++
++      bool needs_dirtyfb;
+ };
+ /**
+diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c
+index 49bdabea8ed5..3e20f72d75ef 100644
+--- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c
++++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c
+@@ -7,6 +7,7 @@
+ #include <drm/drm_atomic.h>
+ #include <drm/drm_damage_helper.h>
+ #include <drm/drm_fourcc.h>
++#include <drm/drm_gem_atomic_helper.h>
+ #include "mdp4_kms.h"
+@@ -90,6 +91,20 @@ static const struct drm_plane_funcs mdp4_plane_funcs = {
+               .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
+ };
++static int mdp4_plane_prepare_fb(struct drm_plane *plane,
++                               struct drm_plane_state *new_state)
++{
++      struct msm_drm_private *priv = plane->dev->dev_private;
++      struct msm_kms *kms = priv->kms;
++
++      if (!new_state->fb)
++              return 0;
++
++      drm_gem_plane_helper_prepare_fb(plane, new_state);
++
++      return msm_framebuffer_prepare(new_state->fb, kms->aspace, false);
++}
++
+ static void mdp4_plane_cleanup_fb(struct drm_plane *plane,
+                                 struct drm_plane_state *old_state)
+ {
+@@ -102,7 +117,7 @@ static void mdp4_plane_cleanup_fb(struct drm_plane *plane,
+               return;
+       DBG("%s: cleanup: FB[%u]", mdp4_plane->name, fb->base.id);
+-      msm_framebuffer_cleanup(fb, kms->aspace);
++      msm_framebuffer_cleanup(fb, kms->aspace, false);
+ }
+@@ -130,7 +145,7 @@ static void mdp4_plane_atomic_update(struct drm_plane *plane,
+ }
+ static const struct drm_plane_helper_funcs mdp4_plane_helper_funcs = {
+-              .prepare_fb = msm_atomic_prepare_fb,
++              .prepare_fb = mdp4_plane_prepare_fb,
+               .cleanup_fb = mdp4_plane_cleanup_fb,
+               .atomic_check = mdp4_plane_atomic_check,
+               .atomic_update = mdp4_plane_atomic_update,
+diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
+index 0e02e252ff89..31447da0af25 100644
+--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
++++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
+@@ -696,6 +696,8 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc,
+ {
+       struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
+                                                                         crtc);
++      struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc_state);
++      struct mdp5_interface *intf = mdp5_cstate->pipeline.intf;
+       struct mdp5_kms *mdp5_kms = get_kms(crtc);
+       struct drm_plane *plane;
+       struct drm_device *dev = crtc->dev;
+@@ -712,12 +714,18 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc,
+       DBG("%s: check", crtc->name);
+       drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
++              struct mdp5_plane_state *mdp5_pstate =
++                              to_mdp5_plane_state(pstate);
++
+               if (!pstate->visible)
+                       continue;
+               pstates[cnt].plane = plane;
+               pstates[cnt].state = to_mdp5_plane_state(pstate);
++              mdp5_pstate->needs_dirtyfb =
++                      intf->mode == MDP5_INTF_DSI_MODE_COMMAND;
++
+               /*
+                * if any plane on this crtc uses 2 hwpipes, then we need
+                * the crtc to have a right hwmixer.
+diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h
+index ac269a6802df..29bf11f08601 100644
+--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h
++++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h
+@@ -100,6 +100,11 @@ struct mdp5_plane_state {
+       /* assigned by crtc blender */
+       enum mdp_mixer_stage_id stage;
++
++      /* whether attached CRTC needs pixel data explicitly flushed to
++       * display (ex. DSI command mode display)
++       */
++      bool needs_dirtyfb;
+ };
+ #define to_mdp5_plane_state(x) \
+               container_of(x, struct mdp5_plane_state, base)
+diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
+index c0d947bce9e9..9c42776cb9a8 100644
+--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
++++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
+@@ -8,6 +8,7 @@
+ #include <drm/drm_atomic.h>
+ #include <drm/drm_damage_helper.h>
+ #include <drm/drm_fourcc.h>
++#include <drm/drm_gem_atomic_helper.h>
+ #include <drm/drm_print.h>
+ #include "mdp5_kms.h"
+@@ -143,18 +144,34 @@ static const struct drm_plane_funcs mdp5_plane_funcs = {
+               .atomic_print_state = mdp5_plane_atomic_print_state,
+ };
++static int mdp5_plane_prepare_fb(struct drm_plane *plane,
++                               struct drm_plane_state *new_state)
++{
++      struct msm_drm_private *priv = plane->dev->dev_private;
++      struct msm_kms *kms = priv->kms;
++      bool needs_dirtyfb = to_mdp5_plane_state(new_state)->needs_dirtyfb;
++
++      if (!new_state->fb)
++              return 0;
++
++      drm_gem_plane_helper_prepare_fb(plane, new_state);
++
++      return msm_framebuffer_prepare(new_state->fb, kms->aspace, needs_dirtyfb);
++}
++
+ static void mdp5_plane_cleanup_fb(struct drm_plane *plane,
+                                 struct drm_plane_state *old_state)
+ {
+       struct mdp5_kms *mdp5_kms = get_kms(plane);
+       struct msm_kms *kms = &mdp5_kms->base.base;
+       struct drm_framebuffer *fb = old_state->fb;
++      bool needed_dirtyfb = to_mdp5_plane_state(old_state)->needs_dirtyfb;
+       if (!fb)
+               return;
+       DBG("%s: cleanup: FB[%u]", plane->name, fb->base.id);
+-      msm_framebuffer_cleanup(fb, kms->aspace);
++      msm_framebuffer_cleanup(fb, kms->aspace, needed_dirtyfb);
+ }
+ static int mdp5_plane_atomic_check_with_state(struct drm_crtc_state *crtc_state,
+@@ -452,7 +469,7 @@ static void mdp5_plane_atomic_async_update(struct drm_plane *plane,
+ }
+ static const struct drm_plane_helper_funcs mdp5_plane_helper_funcs = {
+-              .prepare_fb = msm_atomic_prepare_fb,
++              .prepare_fb = mdp5_plane_prepare_fb,
+               .cleanup_fb = mdp5_plane_cleanup_fb,
+               .atomic_check = mdp5_plane_atomic_check,
+               .atomic_update = mdp5_plane_atomic_update,
+diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c
+index fab09e7c6efc..458f4e4316dd 100644
+--- a/drivers/gpu/drm/msm/msm_atomic.c
++++ b/drivers/gpu/drm/msm/msm_atomic.c
+@@ -5,7 +5,6 @@
+  */
+ #include <drm/drm_atomic_uapi.h>
+-#include <drm/drm_gem_atomic_helper.h>
+ #include <drm/drm_vblank.h>
+ #include "msm_atomic_trace.h"
+@@ -13,20 +12,6 @@
+ #include "msm_gem.h"
+ #include "msm_kms.h"
+-int msm_atomic_prepare_fb(struct drm_plane *plane,
+-                        struct drm_plane_state *new_state)
+-{
+-      struct msm_drm_private *priv = plane->dev->dev_private;
+-      struct msm_kms *kms = priv->kms;
+-
+-      if (!new_state->fb)
+-              return 0;
+-
+-      drm_gem_plane_helper_prepare_fb(plane, new_state);
+-
+-      return msm_framebuffer_prepare(new_state->fb, kms->aspace);
+-}
+-
+ /*
+  * Helpers to control vblanks while we flush.. basically just to ensure
+  * that vblank accounting is switched on, so we get valid seqn/timestamp
+diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
+index bd5132bb9bde..8488e49817e1 100644
+--- a/drivers/gpu/drm/msm/msm_drv.h
++++ b/drivers/gpu/drm/msm/msm_drv.h
+@@ -247,8 +247,6 @@ struct msm_format {
+ struct msm_pending_timer;
+-int msm_atomic_prepare_fb(struct drm_plane *plane,
+-                        struct drm_plane_state *new_state);
+ int msm_atomic_init_pending_timer(struct msm_pending_timer *timer,
+               struct msm_kms *kms, int crtc_idx);
+ void msm_atomic_destroy_pending_timer(struct msm_pending_timer *timer);
+@@ -308,9 +306,9 @@ int msm_gem_prime_pin(struct drm_gem_object *obj);
+ void msm_gem_prime_unpin(struct drm_gem_object *obj);
+ int msm_framebuffer_prepare(struct drm_framebuffer *fb,
+-              struct msm_gem_address_space *aspace);
++              struct msm_gem_address_space *aspace, bool needs_dirtyfb);
+ void msm_framebuffer_cleanup(struct drm_framebuffer *fb,
+-              struct msm_gem_address_space *aspace);
++              struct msm_gem_address_space *aspace, bool needed_dirtyfb);
+ uint32_t msm_framebuffer_iova(struct drm_framebuffer *fb,
+               struct msm_gem_address_space *aspace, int plane);
+ struct drm_gem_object *msm_framebuffer_bo(struct drm_framebuffer *fb, int plane);
+diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c
+index 4d34df5354e0..96b379a08327 100644
+--- a/drivers/gpu/drm/msm/msm_fb.c
++++ b/drivers/gpu/drm/msm/msm_fb.c
+@@ -18,16 +18,36 @@
+ struct msm_framebuffer {
+       struct drm_framebuffer base;
+       const struct msm_format *format;
++
++      /* Count of # of attached planes which need dirtyfb: */
++      refcount_t dirtyfb;
+ };
+ #define to_msm_framebuffer(x) container_of(x, struct msm_framebuffer, base)
+ static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
+               const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **bos);
++static int msm_framebuffer_dirtyfb(struct drm_framebuffer *fb,
++                                 struct drm_file *file_priv, unsigned int flags,
++                                 unsigned int color, struct drm_clip_rect *clips,
++                                 unsigned int num_clips)
++{
++      struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb);
++
++      /* If this fb is not used on any display requiring pixel data to be
++       * flushed, then skip dirtyfb
++       */
++      if (refcount_read(&msm_fb->dirtyfb) == 0)
++              return 0;
++
++      return drm_atomic_helper_dirtyfb(fb, file_priv, flags, color,
++                                       clips, num_clips);
++}
++
+ static const struct drm_framebuffer_funcs msm_framebuffer_funcs = {
+       .create_handle = drm_gem_fb_create_handle,
+       .destroy = drm_gem_fb_destroy,
+-      .dirty = drm_atomic_helper_dirtyfb,
++      .dirty = msm_framebuffer_dirtyfb,
+ };
+ #ifdef CONFIG_DEBUG_FS
+@@ -48,17 +68,19 @@ void msm_framebuffer_describe(struct drm_framebuffer *fb, struct seq_file *m)
+ }
+ #endif
+-/* prepare/pin all the fb's bo's for scanout.  Note that it is not valid
+- * to prepare an fb more multiple different initiator 'id's.  But that
+- * should be fine, since only the scanout (mdpN) side of things needs
+- * this, the gpu doesn't care about fb's.
++/* prepare/pin all the fb's bo's for scanout.
+  */
+ int msm_framebuffer_prepare(struct drm_framebuffer *fb,
+-              struct msm_gem_address_space *aspace)
++              struct msm_gem_address_space *aspace,
++              bool needs_dirtyfb)
+ {
++      struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb);
+       int ret, i, n = fb->format->num_planes;
+       uint64_t iova;
++      if (needs_dirtyfb)
++              refcount_inc(&msm_fb->dirtyfb);
++
+       for (i = 0; i < n; i++) {
+               ret = msm_gem_get_and_pin_iova(fb->obj[i], aspace, &iova);
+               drm_dbg_state(fb->dev, "FB[%u]: iova[%d]: %08llx (%d)", fb->base.id, i, iova, ret);
+@@ -70,10 +92,15 @@ int msm_framebuffer_prepare(struct drm_framebuffer *fb,
+ }
+ void msm_framebuffer_cleanup(struct drm_framebuffer *fb,
+-              struct msm_gem_address_space *aspace)
++              struct msm_gem_address_space *aspace,
++              bool needed_dirtyfb)
+ {
++      struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb);
+       int i, n = fb->format->num_planes;
++      if (needed_dirtyfb)
++              refcount_dec(&msm_fb->dirtyfb);
++
+       for (i = 0; i < n; i++)
+               msm_gem_unpin_iova(fb->obj[i], aspace);
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-msm-dpu-fix-for-non-visible-planes.patch b/queue-5.15/drm-msm-dpu-fix-for-non-visible-planes.patch
new file mode 100644 (file)
index 0000000..00412a9
--- /dev/null
@@ -0,0 +1,51 @@
+From 8f36ceef934895477ac4c3b1fb425d5a05eb8f7f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Jul 2022 14:20:00 -0700
+Subject: drm/msm/dpu: Fix for non-visible planes
+
+From: Rob Clark <robdclark@chromium.org>
+
+[ Upstream commit cb77085b1f0a86ef9dfba86b5f3ed6c3340c2ea3 ]
+
+Fixes `kms_cursor_crc --run-subtest cursor-offscreen`.. when the cursor
+moves offscreen the plane becomes non-visible, so we need to skip over
+it in crtc atomic test and mixer setup.
+
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Fixes: 25fdd5933e4c ("drm/msm: Add SDM845 DPU support")
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Patchwork: https://patchwork.freedesktop.org/patch/492819/
+Link: https://lore.kernel.org/r/20220707212003.1710163-1-robdclark@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+index 7706a7106122..2186fc947e5b 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+@@ -230,6 +230,9 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
+               if (!state)
+                       continue;
++              if (!state->visible)
++                      continue;
++
+               pstate = to_dpu_plane_state(state);
+               fb = state->fb;
+@@ -976,6 +979,9 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
+               if (cnt >= DPU_STAGE_MAX * 4)
+                       continue;
++              if (!pstate->visible)
++                      continue;
++
+               pstates[cnt].dpu_pstate = dpu_pstate;
+               pstates[cnt].drm_pstate = pstate;
+               pstates[cnt].stage = pstate->normalized_zpos;
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-msm-hdmi-enable-core-vcc-core-vdda-supply-for-89.patch b/queue-5.15/drm-msm-hdmi-enable-core-vcc-core-vdda-supply-for-89.patch
new file mode 100644 (file)
index 0000000..4138317
--- /dev/null
@@ -0,0 +1,40 @@
+From 0b08904020535e37cb28bd382161c24adf9b1f96 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jun 2022 15:23:43 +0300
+Subject: drm/msm/hdmi: enable core-vcc/core-vdda-supply for 8996 platform
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 1f88301794595ff4c28a1f1befe690e8dbac72a2 ]
+
+DB820c makes use of core-vcc-supply and core-vdda-supply, however the
+driver code doesn't support these regulators. Enable them for HDMI on
+8996 platform.
+
+Fixes: 0afbe59edd3f ("drm/msm/hdmi: Add basic HDMI support for msm8996")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Stephen Boyd <swboyd@chromium.org>
+Patchwork: https://patchwork.freedesktop.org/patch/488857/
+Link: https://lore.kernel.org/r/20220609122350.3157529-8-dmitry.baryshkov@linaro.org
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/hdmi/hdmi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
+index 23fb88b53324..0ec4ea447c4e 100644
+--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
++++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
+@@ -417,7 +417,7 @@ static struct hdmi_platform_config hdmi_tx_8994_config = {
+ };
+ static struct hdmi_platform_config hdmi_tx_8996_config = {
+-              HDMI_CFG(pwr_reg, none),
++              HDMI_CFG(pwr_reg, 8x74),
+               HDMI_CFG(hpd_reg, none),
+               HDMI_CFG(pwr_clk, 8x74),
+               HDMI_CFG(hpd_clk, 8x74),
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-msm-mdp5-fix-global-state-lock-backoff.patch b/queue-5.15/drm-msm-mdp5-fix-global-state-lock-backoff.patch
new file mode 100644 (file)
index 0000000..ac50912
--- /dev/null
@@ -0,0 +1,85 @@
+From 434aa9aaedd0ec8a63f0f8e6e5b39efc4600f74d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Jul 2022 09:20:37 -0700
+Subject: drm/msm/mdp5: Fix global state lock backoff
+
+From: Rob Clark <robdclark@chromium.org>
+
+[ Upstream commit 92ef86ab513593c6329d04146e61f9a670e72fc5 ]
+
+We need to grab the lock after the early return for !hwpipe case.
+Otherwise, we could have hit contention yet still returned 0.
+
+Fixes an issue that the new CONFIG_DRM_DEBUG_MODESET_LOCK stuff flagged
+in CI:
+
+   WARNING: CPU: 0 PID: 282 at drivers/gpu/drm/drm_modeset_lock.c:296 drm_modeset_lock+0xf8/0x154
+   Modules linked in:
+   CPU: 0 PID: 282 Comm: kms_cursor_lega Tainted: G        W         5.19.0-rc2-15930-g875cc8bc536a #1
+   Hardware name: Qualcomm Technologies, Inc. DB820c (DT)
+   pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+   pc : drm_modeset_lock+0xf8/0x154
+   lr : drm_atomic_get_private_obj_state+0x84/0x170
+   sp : ffff80000cfab6a0
+   x29: ffff80000cfab6a0 x28: 0000000000000000 x27: ffff000083bc4d00
+   x26: 0000000000000038 x25: 0000000000000000 x24: ffff80000957ca58
+   x23: 0000000000000000 x22: ffff000081ace080 x21: 0000000000000001
+   x20: ffff000081acec18 x19: ffff80000cfabb80 x18: 0000000000000038
+   x17: 0000000000000000 x16: 0000000000000000 x15: fffffffffffea0d0
+   x14: 0000000000000000 x13: 284e4f5f4e524157 x12: 5f534b434f4c5f47
+   x11: ffff80000a386aa8 x10: 0000000000000029 x9 : ffff80000cfab610
+   x8 : 0000000000000029 x7 : 0000000000000014 x6 : 0000000000000000
+   x5 : 0000000000000001 x4 : ffff8000081ad904 x3 : 0000000000000029
+   x2 : ffff0000801db4c0 x1 : ffff80000cfabb80 x0 : ffff000081aceb58
+   Call trace:
+    drm_modeset_lock+0xf8/0x154
+    drm_atomic_get_private_obj_state+0x84/0x170
+    mdp5_get_global_state+0x54/0x6c
+    mdp5_pipe_release+0x2c/0xd4
+    mdp5_plane_atomic_check+0x2ec/0x414
+    drm_atomic_helper_check_planes+0xd8/0x210
+    drm_atomic_helper_check+0x54/0xb0
+    ...
+   ---[ end trace 0000000000000000 ]---
+   drm_modeset_lock attempting to lock a contended lock without backoff:
+      drm_modeset_lock+0x148/0x154
+      mdp5_get_global_state+0x30/0x6c
+      mdp5_pipe_release+0x2c/0xd4
+      mdp5_plane_atomic_check+0x290/0x414
+      drm_atomic_helper_check_planes+0xd8/0x210
+      drm_atomic_helper_check+0x54/0xb0
+      drm_atomic_check_only+0x4b0/0x8f4
+      drm_atomic_commit+0x68/0xe0
+
+Fixes: d59be579fa93 ("drm/msm/mdp5: Return error code in mdp5_pipe_release when deadlock is detected")
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Patchwork: https://patchwork.freedesktop.org/patch/492701/
+Link: https://lore.kernel.org/r/20220707162040.1594855-1-robdclark@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c
+index a4f5cb90f3e8..e4b8a789835a 100644
+--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c
++++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c
+@@ -123,12 +123,13 @@ int mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe)
+ {
+       struct msm_drm_private *priv = s->dev->dev_private;
+       struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms));
+-      struct mdp5_global_state *state = mdp5_get_global_state(s);
++      struct mdp5_global_state *state;
+       struct mdp5_hw_pipe_state *new_state;
+       if (!hwpipe)
+               return 0;
++      state = mdp5_get_global_state(s);
+       if (IS_ERR(state))
+               return PTR_ERR(state);
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-panel-fix-build-error-when-config_drm_panel_sams.patch b/queue-5.15/drm-panel-fix-build-error-when-config_drm_panel_sams.patch
new file mode 100644 (file)
index 0000000..c4eb41a
--- /dev/null
@@ -0,0 +1,48 @@
+From e888a8b4a18b068d9a4cb043f528b98c1e466b19 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 May 2022 10:45:51 +0800
+Subject: drm/panel: Fix build error when CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20=y
+ && CONFIG_DRM_DISPLAY_HELPER=m
+
+From: Gao Chao <gaochao49@huawei.com>
+
+[ Upstream commit a67664860f7833015a683ea295f7c79ac2901332 ]
+
+If CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20=y && CONFIG_DRM_DISPLAY_HELPER=m,
+bulding fails:
+
+drivers/gpu/drm/panel/panel-samsung-atna33xc20.o: In function `atana33xc20_probe':
+panel-samsung-atna33xc20.c:(.text+0x744): undefined reference to
+ `drm_panel_dp_aux_backlight'
+make: *** [vmlinux] Error 1
+
+Let CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20 select DRM_DISPLAY_DP_HELPER and
+CONFIG_DRM_DISPLAY_HELPER to fix this error.
+
+Fixes: 32ce3b320343 ("drm/panel: atna33xc20: Introduce the Samsung ATNA33XC20 panel")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Gao Chao <gaochao49@huawei.com>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220524024551.539-1-gaochao49@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/panel/Kconfig | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
+index af1402d83d51..479ffdb64486 100644
+--- a/drivers/gpu/drm/panel/Kconfig
++++ b/drivers/gpu/drm/panel/Kconfig
+@@ -373,6 +373,8 @@ config DRM_PANEL_SAMSUNG_ATNA33XC20
+       depends on OF
+       depends on BACKLIGHT_CLASS_DEVICE
+       depends on PM
++      select DRM_DISPLAY_DP_HELPER
++      select DRM_DISPLAY_HELPER
+       select DRM_DP_AUX_BUS
+       help
+         DRM panel driver for the Samsung ATNA33XC20 panel. This panel can't
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-radeon-fix-incorrrect-spdx-license-identifiers.patch b/queue-5.15/drm-radeon-fix-incorrrect-spdx-license-identifiers.patch
new file mode 100644 (file)
index 0000000..3ce25f4
--- /dev/null
@@ -0,0 +1,65 @@
+From d64b018828b2d55301137fcc45671c895b71f24d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jun 2022 12:02:08 -0400
+Subject: drm/radeon: fix incorrrect SPDX-License-Identifiers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit 1f43b8903f3aae4a26a603c36f6d5dd25d6edb51 ]
+
+radeon is MIT.  This were incorrectly changed in
+commit b24413180f56 ("License cleanup: add SPDX GPL-2.0 license identifier to files with no license")
+and
+commit d198b34f3855 (".gitignore: add SPDX License Identifier")
+and:
+commit ec8f24b7faaf ("treewide: Add SPDX license identifier - Makefile/Kconfig")
+
+Fixes: d198b34f3855 (".gitignore: add SPDX License Identifier")
+Fixes: ec8f24b7faaf ("treewide: Add SPDX license identifier - Makefile/Kconfig")
+Fixes: b24413180f56 ("License cleanup: add SPDX GPL-2.0 license identifier to files with no license")
+Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/2053
+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/radeon/.gitignore | 2 +-
+ drivers/gpu/drm/radeon/Kconfig    | 2 +-
+ drivers/gpu/drm/radeon/Makefile   | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/radeon/.gitignore b/drivers/gpu/drm/radeon/.gitignore
+index 9c1a94153983..d8777383a64a 100644
+--- a/drivers/gpu/drm/radeon/.gitignore
++++ b/drivers/gpu/drm/radeon/.gitignore
+@@ -1,4 +1,4 @@
+-# SPDX-License-Identifier: GPL-2.0-only
++# SPDX-License-Identifier: MIT
+ mkregtable
+ *_reg_safe.h
+diff --git a/drivers/gpu/drm/radeon/Kconfig b/drivers/gpu/drm/radeon/Kconfig
+index 6f60f4840cc5..52819e7f1fca 100644
+--- a/drivers/gpu/drm/radeon/Kconfig
++++ b/drivers/gpu/drm/radeon/Kconfig
+@@ -1,4 +1,4 @@
+-# SPDX-License-Identifier: GPL-2.0-only
++# SPDX-License-Identifier: MIT
+ config DRM_RADEON_USERPTR
+       bool "Always enable userptr support"
+       depends on DRM_RADEON
+diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
+index 11c97edde54d..3d502f1bbfcb 100644
+--- a/drivers/gpu/drm/radeon/Makefile
++++ b/drivers/gpu/drm/radeon/Makefile
+@@ -1,4 +1,4 @@
+-# SPDX-License-Identifier: GPL-2.0
++# SPDX-License-Identifier: MIT
+ #
+ # Makefile for the drm device driver.  This driver provides support for the
+ # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-radeon-fix-potential-buffer-overflow-in-ni_set_m.patch b/queue-5.15/drm-radeon-fix-potential-buffer-overflow-in-ni_set_m.patch
new file mode 100644 (file)
index 0000000..187a82e
--- /dev/null
@@ -0,0 +1,61 @@
+From 21405493dc7c6e987cd8272e7b3f5b287d10baba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jun 2022 16:50:54 +0300
+Subject: drm/radeon: fix potential buffer overflow in
+ ni_set_mc_special_registers()
+
+From: Alexey Kodanev <aleksei.kodanev@bell-sw.com>
+
+[ Upstream commit 136f614931a2bb73616b292cf542da3a18daefd5 ]
+
+The last case label can write two buffers 'mc_reg_address[j]' and
+'mc_data[j]' with 'j' offset equal to SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE
+since there are no checks for this value in both case labels after the
+last 'j++'.
+
+Instead of changing '>' to '>=' there, add the bounds check at the start
+of the second 'case' (the first one already has it).
+
+Also, remove redundant last checks for 'j' index bigger than array size.
+The expression is always false. Moreover, before or after the patch
+'table->last' can be equal to SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE and it
+seems it can be a valid value.
+
+Detected using the static analysis tool - Svace.
+Fixes: 69e0b57a91ad ("drm/radeon/kms: add dpm support for cayman (v5)")
+Signed-off-by: Alexey Kodanev <aleksei.kodanev@bell-sw.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/radeon/ni_dpm.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c
+index 769f666335ac..672d2239293e 100644
+--- a/drivers/gpu/drm/radeon/ni_dpm.c
++++ b/drivers/gpu/drm/radeon/ni_dpm.c
+@@ -2741,10 +2741,10 @@ static int ni_set_mc_special_registers(struct radeon_device *rdev,
+                                       table->mc_reg_table_entry[k].mc_data[j] |= 0x100;
+                       }
+                       j++;
+-                      if (j > SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE)
+-                              return -EINVAL;
+                       break;
+               case MC_SEQ_RESERVE_M >> 2:
++                      if (j >= SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE)
++                              return -EINVAL;
+                       temp_reg = RREG32(MC_PMG_CMD_MRS1);
+                       table->mc_reg_address[j].s1 = MC_PMG_CMD_MRS1 >> 2;
+                       table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_MRS1_LP >> 2;
+@@ -2753,8 +2753,6 @@ static int ni_set_mc_special_registers(struct radeon_device *rdev,
+                                       (temp_reg & 0xffff0000) |
+                                       (table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);
+                       j++;
+-                      if (j > SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE)
+-                              return -EINVAL;
+                       break;
+               default:
+                       break;
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-rockchip-fix-an-error-handling-path-rockchip_dp_.patch b/queue-5.15/drm-rockchip-fix-an-error-handling-path-rockchip_dp_.patch
new file mode 100644 (file)
index 0000000..b4b5dce
--- /dev/null
@@ -0,0 +1,45 @@
+From d7501dad3e446580a0e59b7eaf9dacda894f8034 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Jun 2022 19:08:05 +0200
+Subject: drm/rockchip: Fix an error handling path rockchip_dp_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 5074376822fe99fa4ce344b851c5016d00c0444f ]
+
+Should component_add() fail, we should call analogix_dp_remove() in the
+error handling path, as already done in the remove function.
+
+Fixes: 152cce0006ab ("drm/bridge: analogix_dp: Split bind() into probe() and real bind()")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/b719d9061bb97eb85145fbd3c5e63f4549f2e13e.1655572071.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+index ade2327a10e2..512581698a1e 100644
+--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
++++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+@@ -398,7 +398,15 @@ static int rockchip_dp_probe(struct platform_device *pdev)
+       if (IS_ERR(dp->adp))
+               return PTR_ERR(dp->adp);
+-      return component_add(dev, &rockchip_dp_component_ops);
++      ret = component_add(dev, &rockchip_dp_component_ops);
++      if (ret)
++              goto err_dp_remove;
++
++      return 0;
++
++err_dp_remove:
++      analogix_dp_remove(dp->adp);
++      return ret;
+ }
+ static int rockchip_dp_remove(struct platform_device *pdev)
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-rockchip-vop-don-t-crash-for-invalid-duplicate_s.patch b/queue-5.15/drm-rockchip-vop-don-t-crash-for-invalid-duplicate_s.patch
new file mode 100644 (file)
index 0000000..f0abc9c
--- /dev/null
@@ -0,0 +1,42 @@
+From 972ff2497098922927d92531c7bd34914dc002bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jun 2022 17:26:52 -0700
+Subject: drm/rockchip: vop: Don't crash for invalid duplicate_state()
+
+From: Brian Norris <briannorris@chromium.org>
+
+[ Upstream commit 1449110b0dade8b638d2c17ab7c5b0ff696bfccb ]
+
+It's possible for users to try to duplicate the CRTC state even when the
+state doesn't exist. drm_atomic_helper_crtc_duplicate_state() (and other
+users of __drm_atomic_helper_crtc_duplicate_state()) already guard this
+with a WARN_ON() instead of crashing, so let's do that here too.
+
+Fixes: 4e257d9eee23 ("drm/rockchip: get rid of rockchip_drm_crtc_mode_config")
+Signed-off-by: Brian Norris <briannorris@chromium.org>
+Reviewed-by: Sean Paul <seanpaul@chromium.org>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220617172623.1.I62db228170b1559ada60b8d3e1637e1688424926@changeid
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+index 8b4287d40379..d5b74ea06a45 100644
+--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+@@ -1550,6 +1550,9 @@ static struct drm_crtc_state *vop_crtc_duplicate_state(struct drm_crtc *crtc)
+ {
+       struct rockchip_crtc_state *rockchip_state;
++      if (WARN_ON(!crtc->state))
++              return NULL;
++
+       rockchip_state = kzalloc(sizeof(*rockchip_state), GFP_KERNEL);
+       if (!rockchip_state)
+               return NULL;
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-shmem-helper-export-dedicated-wrappers-for-gem-o.patch b/queue-5.15/drm-shmem-helper-export-dedicated-wrappers-for-gem-o.patch
new file mode 100644 (file)
index 0000000..8a0b533
--- /dev/null
@@ -0,0 +1,372 @@
+From 25fa267955f3eb1748933a09f39c42ad91330692 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Nov 2021 10:31:48 +0100
+Subject: drm/shmem-helper: Export dedicated wrappers for GEM object functions
+
+From: Thomas Zimmermann <tzimmermann@suse.de>
+
+[ Upstream commit c7fbcb7149ff9321bbbcc93c9920de534ea8102c ]
+
+Wrap GEM SHMEM functions for struct drm_gem_object_funcs and update
+all callers. This will allow for an update of the public interfaces
+of the GEM SHMEM helper library.
+
+v2:
+       * fix docs for drm_gem_shmem_object_print_info()
+
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Link: https://patchwork.freedesktop.org/patch/msgid/20211108093149.7226-3-tzimmermann@suse.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_gem_shmem_helper.c  |  45 ++++-----
+ drivers/gpu/drm/lima/lima_gem.c         |   8 +-
+ drivers/gpu/drm/panfrost/panfrost_gem.c |  12 +--
+ drivers/gpu/drm/v3d/v3d_bo.c            |  14 +--
+ drivers/gpu/drm/virtio/virtgpu_object.c |  15 ++-
+ include/drm/drm_gem_shmem_helper.h      | 120 ++++++++++++++++++++++++
+ 6 files changed, 161 insertions(+), 53 deletions(-)
+
+diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
+index 15e53674ed54..05a924e29133 100644
+--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
+@@ -25,14 +25,14 @@
+  */
+ static const struct drm_gem_object_funcs drm_gem_shmem_funcs = {
+-      .free = drm_gem_shmem_free_object,
+-      .print_info = drm_gem_shmem_print_info,
+-      .pin = drm_gem_shmem_pin,
+-      .unpin = drm_gem_shmem_unpin,
+-      .get_sg_table = drm_gem_shmem_get_sg_table,
+-      .vmap = drm_gem_shmem_vmap,
+-      .vunmap = drm_gem_shmem_vunmap,
+-      .mmap = drm_gem_shmem_mmap,
++      .free = drm_gem_shmem_object_free,
++      .print_info = drm_gem_shmem_object_print_info,
++      .pin = drm_gem_shmem_object_pin,
++      .unpin = drm_gem_shmem_object_unpin,
++      .get_sg_table = drm_gem_shmem_object_get_sg_table,
++      .vmap = drm_gem_shmem_object_vmap,
++      .vunmap = drm_gem_shmem_object_vunmap,
++      .mmap = drm_gem_shmem_object_mmap,
+ };
+ static struct drm_gem_shmem_object *
+@@ -116,8 +116,7 @@ EXPORT_SYMBOL_GPL(drm_gem_shmem_create);
+  * @obj: GEM object to free
+  *
+  * This function cleans up the GEM object state and frees the memory used to
+- * store the object itself. It should be used to implement
+- * &drm_gem_object_funcs.free.
++ * store the object itself.
+  */
+ void drm_gem_shmem_free_object(struct drm_gem_object *obj)
+ {
+@@ -228,8 +227,7 @@ EXPORT_SYMBOL(drm_gem_shmem_put_pages);
+  * @obj: GEM object
+  *
+  * This function makes sure the backing pages are pinned in memory while the
+- * buffer is exported. It should only be used to implement
+- * &drm_gem_object_funcs.pin.
++ * buffer is exported.
+  *
+  * Returns:
+  * 0 on success or a negative error code on failure.
+@@ -249,7 +247,7 @@ EXPORT_SYMBOL(drm_gem_shmem_pin);
+  * @obj: GEM object
+  *
+  * This function removes the requirement that the backing pages are pinned in
+- * memory. It should only be used to implement &drm_gem_object_funcs.unpin.
++ * memory.
+  */
+ void drm_gem_shmem_unpin(struct drm_gem_object *obj)
+ {
+@@ -321,11 +319,8 @@ static int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem, struct
+  *       store.
+  *
+  * This function makes sure that a contiguous kernel virtual address mapping
+- * exists for the buffer backing the shmem GEM object.
+- *
+- * This function can be used to implement &drm_gem_object_funcs.vmap. But it can
+- * also be called by drivers directly, in which case it will hide the
+- * differences between dma-buf imported and natively allocated objects.
++ * exists for the buffer backing the shmem GEM object. It hides the differences
++ * between dma-buf imported and natively allocated objects.
+  *
+  * Acquired mappings should be cleaned up by calling drm_gem_shmem_vunmap().
+  *
+@@ -377,9 +372,8 @@ static void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem,
+  * drm_gem_shmem_vmap(). The mapping is only removed when the use count drops to
+  * zero.
+  *
+- * This function can be used to implement &drm_gem_object_funcs.vmap. But it can
+- * also be called by drivers directly, in which case it will hide the
+- * differences between dma-buf imported and natively allocated objects.
++ * This function hides the differences between dma-buf imported and natively
++ * allocated objects.
+  */
+ void drm_gem_shmem_vunmap(struct drm_gem_object *obj, struct dma_buf_map *map)
+ {
+@@ -585,8 +579,7 @@ static const struct vm_operations_struct drm_gem_shmem_vm_ops = {
+  * @vma: VMA for the area to be mapped
+  *
+  * This function implements an augmented version of the GEM DRM file mmap
+- * operation for shmem objects. Drivers which employ the shmem helpers should
+- * use this function as their &drm_gem_object_funcs.mmap handler.
++ * operation for shmem objects.
+  *
+  * Returns:
+  * 0 on success or a negative error code on failure.
+@@ -627,8 +620,6 @@ EXPORT_SYMBOL_GPL(drm_gem_shmem_mmap);
+  * @p: DRM printer
+  * @indent: Tab indentation level
+  * @obj: GEM object
+- *
+- * This implements the &drm_gem_object_funcs.info callback.
+  */
+ void drm_gem_shmem_print_info(struct drm_printer *p, unsigned int indent,
+                             const struct drm_gem_object *obj)
+@@ -647,9 +638,7 @@ EXPORT_SYMBOL(drm_gem_shmem_print_info);
+  * @obj: GEM object
+  *
+  * This function exports a scatter/gather table suitable for PRIME usage by
+- * calling the standard DMA mapping API. Drivers should not call this function
+- * directly, instead it should only be used as an implementation for
+- * &drm_gem_object_funcs.get_sg_table.
++ * calling the standard DMA mapping API.
+  *
+  * Drivers who need to acquire an scatter/gather table for objects need to call
+  * drm_gem_shmem_get_pages_sgt() instead.
+diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c
+index de62966243cd..6590e1cae4ee 100644
+--- a/drivers/gpu/drm/lima/lima_gem.c
++++ b/drivers/gpu/drm/lima/lima_gem.c
+@@ -206,12 +206,12 @@ static const struct drm_gem_object_funcs lima_gem_funcs = {
+       .free = lima_gem_free_object,
+       .open = lima_gem_object_open,
+       .close = lima_gem_object_close,
+-      .print_info = drm_gem_shmem_print_info,
++      .print_info = drm_gem_shmem_object_print_info,
+       .pin = lima_gem_pin,
+-      .unpin = drm_gem_shmem_unpin,
+-      .get_sg_table = drm_gem_shmem_get_sg_table,
++      .unpin = drm_gem_shmem_object_unpin,
++      .get_sg_table = drm_gem_shmem_object_get_sg_table,
+       .vmap = lima_gem_vmap,
+-      .vunmap = drm_gem_shmem_vunmap,
++      .vunmap = drm_gem_shmem_object_vunmap,
+       .mmap = lima_gem_mmap,
+ };
+diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c
+index 23377481f4e3..be1cc6579a71 100644
+--- a/drivers/gpu/drm/panfrost/panfrost_gem.c
++++ b/drivers/gpu/drm/panfrost/panfrost_gem.c
+@@ -197,13 +197,13 @@ static const struct drm_gem_object_funcs panfrost_gem_funcs = {
+       .free = panfrost_gem_free_object,
+       .open = panfrost_gem_open,
+       .close = panfrost_gem_close,
+-      .print_info = drm_gem_shmem_print_info,
++      .print_info = drm_gem_shmem_object_print_info,
+       .pin = panfrost_gem_pin,
+-      .unpin = drm_gem_shmem_unpin,
+-      .get_sg_table = drm_gem_shmem_get_sg_table,
+-      .vmap = drm_gem_shmem_vmap,
+-      .vunmap = drm_gem_shmem_vunmap,
+-      .mmap = drm_gem_shmem_mmap,
++      .unpin = drm_gem_shmem_object_unpin,
++      .get_sg_table = drm_gem_shmem_object_get_sg_table,
++      .vmap = drm_gem_shmem_object_vmap,
++      .vunmap = drm_gem_shmem_object_vunmap,
++      .mmap = drm_gem_shmem_object_mmap,
+ };
+ /**
+diff --git a/drivers/gpu/drm/v3d/v3d_bo.c b/drivers/gpu/drm/v3d/v3d_bo.c
+index 6a8731ab9d7d..b50677beb6ac 100644
+--- a/drivers/gpu/drm/v3d/v3d_bo.c
++++ b/drivers/gpu/drm/v3d/v3d_bo.c
+@@ -52,13 +52,13 @@ void v3d_free_object(struct drm_gem_object *obj)
+ static const struct drm_gem_object_funcs v3d_gem_funcs = {
+       .free = v3d_free_object,
+-      .print_info = drm_gem_shmem_print_info,
+-      .pin = drm_gem_shmem_pin,
+-      .unpin = drm_gem_shmem_unpin,
+-      .get_sg_table = drm_gem_shmem_get_sg_table,
+-      .vmap = drm_gem_shmem_vmap,
+-      .vunmap = drm_gem_shmem_vunmap,
+-      .mmap = drm_gem_shmem_mmap,
++      .print_info = drm_gem_shmem_object_print_info,
++      .pin = drm_gem_shmem_object_pin,
++      .unpin = drm_gem_shmem_object_unpin,
++      .get_sg_table = drm_gem_shmem_object_get_sg_table,
++      .vmap = drm_gem_shmem_object_vmap,
++      .vunmap = drm_gem_shmem_object_vunmap,
++      .mmap = drm_gem_shmem_object_mmap,
+ };
+ /* gem_create_object function for allocating a BO struct and doing
+diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c
+index f648b0e24447..698431d233b8 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_object.c
++++ b/drivers/gpu/drm/virtio/virtgpu_object.c
+@@ -116,15 +116,14 @@ static const struct drm_gem_object_funcs virtio_gpu_shmem_funcs = {
+       .free = virtio_gpu_free_object,
+       .open = virtio_gpu_gem_object_open,
+       .close = virtio_gpu_gem_object_close,
+-
+-      .print_info = drm_gem_shmem_print_info,
++      .print_info = drm_gem_shmem_object_print_info,
+       .export = virtgpu_gem_prime_export,
+-      .pin = drm_gem_shmem_pin,
+-      .unpin = drm_gem_shmem_unpin,
+-      .get_sg_table = drm_gem_shmem_get_sg_table,
+-      .vmap = drm_gem_shmem_vmap,
+-      .vunmap = drm_gem_shmem_vunmap,
+-      .mmap = drm_gem_shmem_mmap,
++      .pin = drm_gem_shmem_object_pin,
++      .unpin = drm_gem_shmem_object_unpin,
++      .get_sg_table = drm_gem_shmem_object_get_sg_table,
++      .vmap = drm_gem_shmem_object_vmap,
++      .vunmap = drm_gem_shmem_object_vunmap,
++      .mmap = drm_gem_shmem_object_mmap,
+ };
+ bool virtio_gpu_is_shmem(struct virtio_gpu_object *bo)
+diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h
+index 6b47eb7d9f76..4199877ae588 100644
+--- a/include/drm/drm_gem_shmem_helper.h
++++ b/include/drm/drm_gem_shmem_helper.h
+@@ -137,6 +137,126 @@ void drm_gem_shmem_print_info(struct drm_printer *p, unsigned int indent,
+                             const struct drm_gem_object *obj);
+ struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_object *obj);
++
++/*
++ * GEM object functions
++ */
++
++/**
++ * drm_gem_shmem_object_free - GEM object function for drm_gem_shmem_free_object()
++ * @obj: GEM object to free
++ *
++ * This function wraps drm_gem_shmem_free_object(). Drivers that employ the shmem helpers
++ * should use it as their &drm_gem_object_funcs.free handler.
++ */
++static inline void drm_gem_shmem_object_free(struct drm_gem_object *obj)
++{
++      drm_gem_shmem_free_object(obj);
++}
++
++/**
++ * drm_gem_shmem_object_print_info() - Print &drm_gem_shmem_object info for debugfs
++ * @p: DRM printer
++ * @indent: Tab indentation level
++ * @obj: GEM object
++ *
++ * This function wraps drm_gem_shmem_print_info(). Drivers that employ the shmem helpers should
++ * use this function as their &drm_gem_object_funcs.print_info handler.
++ */
++static inline void drm_gem_shmem_object_print_info(struct drm_printer *p, unsigned int indent,
++                                                 const struct drm_gem_object *obj)
++{
++      drm_gem_shmem_print_info(p, indent, obj);
++}
++
++/**
++ * drm_gem_shmem_object_pin - GEM object function for drm_gem_shmem_pin()
++ * @obj: GEM object
++ *
++ * This function wraps drm_gem_shmem_pin(). Drivers that employ the shmem helpers should
++ * use it as their &drm_gem_object_funcs.pin handler.
++ */
++static inline int drm_gem_shmem_object_pin(struct drm_gem_object *obj)
++{
++      return drm_gem_shmem_pin(obj);
++}
++
++/**
++ * drm_gem_shmem_object_unpin - GEM object function for drm_gem_shmem_unpin()
++ * @obj: GEM object
++ *
++ * This function wraps drm_gem_shmem_unpin(). Drivers that employ the shmem helpers should
++ * use it as their &drm_gem_object_funcs.unpin handler.
++ */
++static inline void drm_gem_shmem_object_unpin(struct drm_gem_object *obj)
++{
++      drm_gem_shmem_unpin(obj);
++}
++
++/**
++ * drm_gem_shmem_object_get_sg_table - GEM object function for drm_gem_shmem_get_sg_table()
++ * @obj: GEM object
++ *
++ * This function wraps drm_gem_shmem_get_sg_table(). Drivers that employ the shmem helpers should
++ * use it as their &drm_gem_object_funcs.get_sg_table handler.
++ *
++ * Returns:
++ * A pointer to the scatter/gather table of pinned pages or NULL on failure.
++ */
++static inline struct sg_table *drm_gem_shmem_object_get_sg_table(struct drm_gem_object *obj)
++{
++      return drm_gem_shmem_get_sg_table(obj);
++}
++
++/*
++ * drm_gem_shmem_object_vmap - GEM object function for drm_gem_shmem_vmap()
++ * @obj: GEM object
++ * @map: Returns the kernel virtual address of the SHMEM GEM object's backing store.
++ *
++ * This function wraps drm_gem_shmem_vmap(). Drivers that employ the shmem helpers should
++ * use it as their &drm_gem_object_funcs.vmap handler.
++ *
++ * Returns:
++ * 0 on success or a negative error code on failure.
++ */
++static inline int drm_gem_shmem_object_vmap(struct drm_gem_object *obj, struct dma_buf_map *map)
++{
++      return drm_gem_shmem_vmap(obj, map);
++}
++
++/*
++ * drm_gem_shmem_object_vunmap - GEM object function for drm_gem_shmem_vunmap()
++ * @obj: GEM object
++ * @map: Kernel virtual address where the SHMEM GEM object was mapped
++ *
++ * This function wraps drm_gem_shmem_vunmap(). Drivers that employ the shmem helpers should
++ * use it as their &drm_gem_object_funcs.vunmap handler.
++ */
++static inline void drm_gem_shmem_object_vunmap(struct drm_gem_object *obj, struct dma_buf_map *map)
++{
++      drm_gem_shmem_vunmap(obj, map);
++}
++
++/**
++ * drm_gem_shmem_object_mmap - GEM object function for drm_gem_shmem_mmap()
++ * @obj: GEM object
++ * @vma: VMA for the area to be mapped
++ *
++ * This function wraps drm_gem_shmem_mmap(). Drivers that employ the shmem helpers should
++ * use it as their &drm_gem_object_funcs.mmap handler.
++ *
++ * Returns:
++ * 0 on success or a negative error code on failure.
++ */
++static inline int drm_gem_shmem_object_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
++{
++      return drm_gem_shmem_mmap(obj, vma);
++}
++
++/*
++ * Driver ops
++ */
++
+ struct drm_gem_object *
+ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
+                                   struct dma_buf_attachment *attach,
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-shmem-helper-pass-gem-shmem-object-in-public-int.patch b/queue-5.15/drm-shmem-helper-pass-gem-shmem-object-in-public-int.patch
new file mode 100644 (file)
index 0000000..15c5edb
--- /dev/null
@@ -0,0 +1,733 @@
+From 45051d5db2c420b245273c3a6a08d75a175b4cd3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Nov 2021 10:31:49 +0100
+Subject: drm/shmem-helper: Pass GEM shmem object in public interfaces
+
+From: Thomas Zimmermann <tzimmermann@suse.de>
+
+[ Upstream commit a193f3b4e050e35c506a34d0870c838d8e0b0449 ]
+
+Change all GEM SHMEM object functions that receive a GEM object
+of type struct drm_gem_object to expect an object of type
+struct drm_gem_shmem_object instead.
+
+This change reduces the number of upcasts from struct drm_gem_object
+by moving them into callers. The C compiler can now verify that the
+GEM SHMEM functions are called with the correct type.
+
+For consistency, the patch also renames drm_gem_shmem_free_object to
+drm_gem_shmem_free. It further updates documentation for a number of
+functions.
+
+v3:
+       * fix docs for drm_gem_shmem_object_free()
+v2:
+       * mention _object_ callbacks in docs (Daniel)
+
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Link: https://patchwork.freedesktop.org/patch/msgid/20211108093149.7226-4-tzimmermann@suse.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_gem_shmem_helper.c        | 83 ++++++++-----------
+ drivers/gpu/drm/lima/lima_gem.c               | 10 +--
+ drivers/gpu/drm/lima/lima_sched.c             |  4 +-
+ drivers/gpu/drm/panfrost/panfrost_drv.c       |  2 +-
+ drivers/gpu/drm/panfrost/panfrost_gem.c       |  8 +-
+ .../gpu/drm/panfrost/panfrost_gem_shrinker.c  |  2 +-
+ drivers/gpu/drm/panfrost/panfrost_mmu.c       |  5 +-
+ drivers/gpu/drm/panfrost/panfrost_perfcnt.c   |  6 +-
+ drivers/gpu/drm/v3d/v3d_bo.c                  |  8 +-
+ drivers/gpu/drm/virtio/virtgpu_object.c       | 12 +--
+ include/drm/drm_gem_shmem_helper.h            | 69 ++++++++-------
+ 11 files changed, 107 insertions(+), 102 deletions(-)
+
+diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
+index 05a924e29133..a30ffc07470c 100644
+--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
+@@ -22,6 +22,11 @@
+  *
+  * This library provides helpers for GEM objects backed by shmem buffers
+  * allocated using anonymous pageable memory.
++ *
++ * Functions that operate on the GEM object receive struct &drm_gem_shmem_object.
++ * For GEM callback helpers in struct &drm_gem_object functions, see likewise
++ * named functions with an _object_ infix (e.g., drm_gem_shmem_object_vmap() wraps
++ * drm_gem_shmem_vmap()). These helpers perform the necessary type conversion.
+  */
+ static const struct drm_gem_object_funcs drm_gem_shmem_funcs = {
+@@ -112,15 +117,15 @@ struct drm_gem_shmem_object *drm_gem_shmem_create(struct drm_device *dev, size_t
+ EXPORT_SYMBOL_GPL(drm_gem_shmem_create);
+ /**
+- * drm_gem_shmem_free_object - Free resources associated with a shmem GEM object
+- * @obj: GEM object to free
++ * drm_gem_shmem_free - Free resources associated with a shmem GEM object
++ * @shmem: shmem GEM object to free
+  *
+  * This function cleans up the GEM object state and frees the memory used to
+  * store the object itself.
+  */
+-void drm_gem_shmem_free_object(struct drm_gem_object *obj)
++void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem)
+ {
+-      struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
++      struct drm_gem_object *obj = &shmem->base;
+       WARN_ON(shmem->vmap_use_count);
+@@ -144,7 +149,7 @@ void drm_gem_shmem_free_object(struct drm_gem_object *obj)
+       mutex_destroy(&shmem->vmap_lock);
+       kfree(shmem);
+ }
+-EXPORT_SYMBOL_GPL(drm_gem_shmem_free_object);
++EXPORT_SYMBOL_GPL(drm_gem_shmem_free);
+ static int drm_gem_shmem_get_pages_locked(struct drm_gem_shmem_object *shmem)
+ {
+@@ -224,7 +229,7 @@ EXPORT_SYMBOL(drm_gem_shmem_put_pages);
+ /**
+  * drm_gem_shmem_pin - Pin backing pages for a shmem GEM object
+- * @obj: GEM object
++ * @shmem: shmem GEM object
+  *
+  * This function makes sure the backing pages are pinned in memory while the
+  * buffer is exported.
+@@ -232,10 +237,8 @@ EXPORT_SYMBOL(drm_gem_shmem_put_pages);
+  * Returns:
+  * 0 on success or a negative error code on failure.
+  */
+-int drm_gem_shmem_pin(struct drm_gem_object *obj)
++int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem)
+ {
+-      struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
+-
+       WARN_ON(shmem->base.import_attach);
+       return drm_gem_shmem_get_pages(shmem);
+@@ -244,15 +247,13 @@ EXPORT_SYMBOL(drm_gem_shmem_pin);
+ /**
+  * drm_gem_shmem_unpin - Unpin backing pages for a shmem GEM object
+- * @obj: GEM object
++ * @shmem: shmem GEM object
+  *
+  * This function removes the requirement that the backing pages are pinned in
+  * memory.
+  */
+-void drm_gem_shmem_unpin(struct drm_gem_object *obj)
++void drm_gem_shmem_unpin(struct drm_gem_shmem_object *shmem)
+ {
+-      struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
+-
+       WARN_ON(shmem->base.import_attach);
+       drm_gem_shmem_put_pages(shmem);
+@@ -327,9 +328,8 @@ static int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem, struct
+  * Returns:
+  * 0 on success or a negative error code on failure.
+  */
+-int drm_gem_shmem_vmap(struct drm_gem_object *obj, struct dma_buf_map *map)
++int drm_gem_shmem_vmap(struct drm_gem_shmem_object *shmem, struct dma_buf_map *map)
+ {
+-      struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
+       int ret;
+       ret = mutex_lock_interruptible(&shmem->vmap_lock);
+@@ -375,10 +375,8 @@ static void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem,
+  * This function hides the differences between dma-buf imported and natively
+  * allocated objects.
+  */
+-void drm_gem_shmem_vunmap(struct drm_gem_object *obj, struct dma_buf_map *map)
++void drm_gem_shmem_vunmap(struct drm_gem_shmem_object *shmem, struct dma_buf_map *map)
+ {
+-      struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
+-
+       mutex_lock(&shmem->vmap_lock);
+       drm_gem_shmem_vunmap_locked(shmem, map);
+       mutex_unlock(&shmem->vmap_lock);
+@@ -413,10 +411,8 @@ drm_gem_shmem_create_with_handle(struct drm_file *file_priv,
+ /* Update madvise status, returns true if not purged, else
+  * false or -errno.
+  */
+-int drm_gem_shmem_madvise(struct drm_gem_object *obj, int madv)
++int drm_gem_shmem_madvise(struct drm_gem_shmem_object *shmem, int madv)
+ {
+-      struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
+-
+       mutex_lock(&shmem->pages_lock);
+       if (shmem->madv >= 0)
+@@ -430,14 +426,14 @@ int drm_gem_shmem_madvise(struct drm_gem_object *obj, int madv)
+ }
+ EXPORT_SYMBOL(drm_gem_shmem_madvise);
+-void drm_gem_shmem_purge_locked(struct drm_gem_object *obj)
++void drm_gem_shmem_purge_locked(struct drm_gem_shmem_object *shmem)
+ {
++      struct drm_gem_object *obj = &shmem->base;
+       struct drm_device *dev = obj->dev;
+-      struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
+       WARN_ON(!drm_gem_shmem_is_purgeable(shmem));
+-      dma_unmap_sgtable(obj->dev->dev, shmem->sgt, DMA_BIDIRECTIONAL, 0);
++      dma_unmap_sgtable(dev->dev, shmem->sgt, DMA_BIDIRECTIONAL, 0);
+       sg_free_table(shmem->sgt);
+       kfree(shmem->sgt);
+       shmem->sgt = NULL;
+@@ -456,18 +452,15 @@ void drm_gem_shmem_purge_locked(struct drm_gem_object *obj)
+        */
+       shmem_truncate_range(file_inode(obj->filp), 0, (loff_t)-1);
+-      invalidate_mapping_pages(file_inode(obj->filp)->i_mapping,
+-                      0, (loff_t)-1);
++      invalidate_mapping_pages(file_inode(obj->filp)->i_mapping, 0, (loff_t)-1);
+ }
+ EXPORT_SYMBOL(drm_gem_shmem_purge_locked);
+-bool drm_gem_shmem_purge(struct drm_gem_object *obj)
++bool drm_gem_shmem_purge(struct drm_gem_shmem_object *shmem)
+ {
+-      struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
+-
+       if (!mutex_trylock(&shmem->pages_lock))
+               return false;
+-      drm_gem_shmem_purge_locked(obj);
++      drm_gem_shmem_purge_locked(shmem);
+       mutex_unlock(&shmem->pages_lock);
+       return true;
+@@ -575,7 +568,7 @@ static const struct vm_operations_struct drm_gem_shmem_vm_ops = {
+ /**
+  * drm_gem_shmem_mmap - Memory-map a shmem GEM object
+- * @obj: gem object
++ * @shmem: shmem GEM object
+  * @vma: VMA for the area to be mapped
+  *
+  * This function implements an augmented version of the GEM DRM file mmap
+@@ -584,9 +577,9 @@ static const struct vm_operations_struct drm_gem_shmem_vm_ops = {
+  * Returns:
+  * 0 on success or a negative error code on failure.
+  */
+-int drm_gem_shmem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
++int drm_gem_shmem_mmap(struct drm_gem_shmem_object *shmem, struct vm_area_struct *vma)
+ {
+-      struct drm_gem_shmem_object *shmem;
++      struct drm_gem_object *obj = &shmem->base;
+       int ret;
+       if (obj->import_attach) {
+@@ -597,8 +590,6 @@ int drm_gem_shmem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
+               return dma_buf_mmap(obj->dma_buf, vma, 0);
+       }
+-      shmem = to_drm_gem_shmem_obj(obj);
+-
+       ret = drm_gem_shmem_get_pages(shmem);
+       if (ret) {
+               drm_gem_vm_close(vma);
+@@ -617,15 +608,13 @@ EXPORT_SYMBOL_GPL(drm_gem_shmem_mmap);
+ /**
+  * drm_gem_shmem_print_info() - Print &drm_gem_shmem_object info for debugfs
++ * @shmem: shmem GEM object
+  * @p: DRM printer
+  * @indent: Tab indentation level
+- * @obj: GEM object
+  */
+-void drm_gem_shmem_print_info(struct drm_printer *p, unsigned int indent,
+-                            const struct drm_gem_object *obj)
++void drm_gem_shmem_print_info(const struct drm_gem_shmem_object *shmem,
++                            struct drm_printer *p, unsigned int indent)
+ {
+-      const struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
+-
+       drm_printf_indent(p, indent, "pages_use_count=%u\n", shmem->pages_use_count);
+       drm_printf_indent(p, indent, "vmap_use_count=%u\n", shmem->vmap_use_count);
+       drm_printf_indent(p, indent, "vaddr=%p\n", shmem->vaddr);
+@@ -635,7 +624,7 @@ EXPORT_SYMBOL(drm_gem_shmem_print_info);
+ /**
+  * drm_gem_shmem_get_sg_table - Provide a scatter/gather table of pinned
+  *                              pages for a shmem GEM object
+- * @obj: GEM object
++ * @shmem: shmem GEM object
+  *
+  * This function exports a scatter/gather table suitable for PRIME usage by
+  * calling the standard DMA mapping API.
+@@ -646,9 +635,9 @@ EXPORT_SYMBOL(drm_gem_shmem_print_info);
+  * Returns:
+  * A pointer to the scatter/gather table of pinned pages or NULL on failure.
+  */
+-struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_object *obj)
++struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_shmem_object *shmem)
+ {
+-      struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
++      struct drm_gem_object *obj = &shmem->base;
+       WARN_ON(shmem->base.import_attach);
+@@ -659,7 +648,7 @@ EXPORT_SYMBOL_GPL(drm_gem_shmem_get_sg_table);
+ /**
+  * drm_gem_shmem_get_pages_sgt - Pin pages, dma map them, and return a
+  *                             scatter/gather table for a shmem GEM object.
+- * @obj: GEM object
++ * @shmem: shmem GEM object
+  *
+  * This function returns a scatter/gather table suitable for driver usage. If
+  * the sg table doesn't exist, the pages are pinned, dma-mapped, and a sg
+@@ -672,10 +661,10 @@ EXPORT_SYMBOL_GPL(drm_gem_shmem_get_sg_table);
+  * Returns:
+  * A pointer to the scatter/gather table of pinned pages or errno on failure.
+  */
+-struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_object *obj)
++struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_shmem_object *shmem)
+ {
++      struct drm_gem_object *obj = &shmem->base;
+       int ret;
+-      struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
+       struct sg_table *sgt;
+       if (shmem->sgt)
+@@ -687,7 +676,7 @@ struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_object *obj)
+       if (ret)
+               return ERR_PTR(ret);
+-      sgt = drm_gem_shmem_get_sg_table(&shmem->base);
++      sgt = drm_gem_shmem_get_sg_table(shmem);
+       if (IS_ERR(sgt)) {
+               ret = PTR_ERR(sgt);
+               goto err_put_pages;
+diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c
+index 6590e1cae4ee..09ea621a4806 100644
+--- a/drivers/gpu/drm/lima/lima_gem.c
++++ b/drivers/gpu/drm/lima/lima_gem.c
+@@ -127,7 +127,7 @@ int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file,
+               if (err)
+                       goto out;
+       } else {
+-              struct sg_table *sgt = drm_gem_shmem_get_pages_sgt(obj);
++              struct sg_table *sgt = drm_gem_shmem_get_pages_sgt(shmem);
+               if (IS_ERR(sgt)) {
+                       err = PTR_ERR(sgt);
+@@ -151,7 +151,7 @@ static void lima_gem_free_object(struct drm_gem_object *obj)
+       if (!list_empty(&bo->va))
+               dev_err(obj->dev->dev, "lima gem free bo still has va\n");
+-      drm_gem_shmem_free_object(obj);
++      drm_gem_shmem_free(&bo->base);
+ }
+ static int lima_gem_object_open(struct drm_gem_object *obj, struct drm_file *file)
+@@ -179,7 +179,7 @@ static int lima_gem_pin(struct drm_gem_object *obj)
+       if (bo->heap_size)
+               return -EINVAL;
+-      return drm_gem_shmem_pin(obj);
++      return drm_gem_shmem_pin(&bo->base);
+ }
+ static int lima_gem_vmap(struct drm_gem_object *obj, struct dma_buf_map *map)
+@@ -189,7 +189,7 @@ static int lima_gem_vmap(struct drm_gem_object *obj, struct dma_buf_map *map)
+       if (bo->heap_size)
+               return -EINVAL;
+-      return drm_gem_shmem_vmap(obj, map);
++      return drm_gem_shmem_vmap(&bo->base, map);
+ }
+ static int lima_gem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
+@@ -199,7 +199,7 @@ static int lima_gem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
+       if (bo->heap_size)
+               return -EINVAL;
+-      return drm_gem_shmem_mmap(obj, vma);
++      return drm_gem_shmem_mmap(&bo->base, vma);
+ }
+ static const struct drm_gem_object_funcs lima_gem_funcs = {
+diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c
+index dba8329937a3..2e817dbdcad7 100644
+--- a/drivers/gpu/drm/lima/lima_sched.c
++++ b/drivers/gpu/drm/lima/lima_sched.c
+@@ -390,7 +390,7 @@ static void lima_sched_build_error_task_list(struct lima_sched_task *task)
+               } else {
+                       buffer_chunk->size = lima_bo_size(bo);
+-                      ret = drm_gem_shmem_vmap(&bo->base.base, &map);
++                      ret = drm_gem_shmem_vmap(&bo->base, &map);
+                       if (ret) {
+                               kvfree(et);
+                               goto out;
+@@ -398,7 +398,7 @@ static void lima_sched_build_error_task_list(struct lima_sched_task *task)
+                       memcpy(buffer_chunk + 1, map.vaddr, buffer_chunk->size);
+-                      drm_gem_shmem_vunmap(&bo->base.base, &map);
++                      drm_gem_shmem_vunmap(&bo->base, &map);
+               }
+               buffer_chunk = (void *)(buffer_chunk + 1) + buffer_chunk->size;
+diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c
+index de533f372764..e48e357ea4f1 100644
+--- a/drivers/gpu/drm/panfrost/panfrost_drv.c
++++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
+@@ -418,7 +418,7 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, void *data,
+               }
+       }
+-      args->retained = drm_gem_shmem_madvise(gem_obj, args->madv);
++      args->retained = drm_gem_shmem_madvise(&bo->base, args->madv);
+       if (args->retained) {
+               if (args->madv == PANFROST_MADV_DONTNEED)
+diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c
+index be1cc6579a71..6d9bdb9180cb 100644
+--- a/drivers/gpu/drm/panfrost/panfrost_gem.c
++++ b/drivers/gpu/drm/panfrost/panfrost_gem.c
+@@ -49,7 +49,7 @@ static void panfrost_gem_free_object(struct drm_gem_object *obj)
+               kvfree(bo->sgts);
+       }
+-      drm_gem_shmem_free_object(obj);
++      drm_gem_shmem_free(&bo->base);
+ }
+ struct panfrost_gem_mapping *
+@@ -187,10 +187,12 @@ void panfrost_gem_close(struct drm_gem_object *obj, struct drm_file *file_priv)
+ static int panfrost_gem_pin(struct drm_gem_object *obj)
+ {
+-      if (to_panfrost_bo(obj)->is_heap)
++      struct panfrost_gem_object *bo = to_panfrost_bo(obj);
++
++      if (bo->is_heap)
+               return -EINVAL;
+-      return drm_gem_shmem_pin(obj);
++      return drm_gem_shmem_pin(&bo->base);
+ }
+ static const struct drm_gem_object_funcs panfrost_gem_funcs = {
+diff --git a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c
+index 1b9f68d8e9aa..b0142341e223 100644
+--- a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c
++++ b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c
+@@ -52,7 +52,7 @@ static bool panfrost_gem_purge(struct drm_gem_object *obj)
+               goto unlock_mappings;
+       panfrost_gem_teardown_mappings_locked(bo);
+-      drm_gem_shmem_purge_locked(obj);
++      drm_gem_shmem_purge_locked(&bo->base);
+       ret = true;
+       mutex_unlock(&shmem->pages_lock);
+diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c
+index c0189cc9a2f1..c3292a6bd1ae 100644
+--- a/drivers/gpu/drm/panfrost/panfrost_mmu.c
++++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c
+@@ -288,7 +288,8 @@ static int mmu_map_sg(struct panfrost_device *pfdev, struct panfrost_mmu *mmu,
+ int panfrost_mmu_map(struct panfrost_gem_mapping *mapping)
+ {
+       struct panfrost_gem_object *bo = mapping->obj;
+-      struct drm_gem_object *obj = &bo->base.base;
++      struct drm_gem_shmem_object *shmem = &bo->base;
++      struct drm_gem_object *obj = &shmem->base;
+       struct panfrost_device *pfdev = to_panfrost_device(obj->dev);
+       struct sg_table *sgt;
+       int prot = IOMMU_READ | IOMMU_WRITE;
+@@ -299,7 +300,7 @@ int panfrost_mmu_map(struct panfrost_gem_mapping *mapping)
+       if (bo->noexec)
+               prot |= IOMMU_NOEXEC;
+-      sgt = drm_gem_shmem_get_pages_sgt(obj);
++      sgt = drm_gem_shmem_get_pages_sgt(shmem);
+       if (WARN_ON(IS_ERR(sgt)))
+               return PTR_ERR(sgt);
+diff --git a/drivers/gpu/drm/panfrost/panfrost_perfcnt.c b/drivers/gpu/drm/panfrost/panfrost_perfcnt.c
+index 5ab03d605f57..9d9c067c1d70 100644
+--- a/drivers/gpu/drm/panfrost/panfrost_perfcnt.c
++++ b/drivers/gpu/drm/panfrost/panfrost_perfcnt.c
+@@ -105,7 +105,7 @@ static int panfrost_perfcnt_enable_locked(struct panfrost_device *pfdev,
+               goto err_close_bo;
+       }
+-      ret = drm_gem_shmem_vmap(&bo->base, &map);
++      ret = drm_gem_shmem_vmap(bo, &map);
+       if (ret)
+               goto err_put_mapping;
+       perfcnt->buf = map.vaddr;
+@@ -164,7 +164,7 @@ static int panfrost_perfcnt_enable_locked(struct panfrost_device *pfdev,
+       return 0;
+ err_vunmap:
+-      drm_gem_shmem_vunmap(&bo->base, &map);
++      drm_gem_shmem_vunmap(bo, &map);
+ err_put_mapping:
+       panfrost_gem_mapping_put(perfcnt->mapping);
+ err_close_bo:
+@@ -194,7 +194,7 @@ static int panfrost_perfcnt_disable_locked(struct panfrost_device *pfdev,
+                 GPU_PERFCNT_CFG_MODE(GPU_PERFCNT_CFG_MODE_OFF));
+       perfcnt->user = NULL;
+-      drm_gem_shmem_vunmap(&perfcnt->mapping->obj->base.base, &map);
++      drm_gem_shmem_vunmap(&perfcnt->mapping->obj->base, &map);
+       perfcnt->buf = NULL;
+       panfrost_gem_close(&perfcnt->mapping->obj->base.base, file_priv);
+       panfrost_mmu_as_put(pfdev, perfcnt->mapping->mmu);
+diff --git a/drivers/gpu/drm/v3d/v3d_bo.c b/drivers/gpu/drm/v3d/v3d_bo.c
+index b50677beb6ac..0d9af62f69ad 100644
+--- a/drivers/gpu/drm/v3d/v3d_bo.c
++++ b/drivers/gpu/drm/v3d/v3d_bo.c
+@@ -47,7 +47,7 @@ void v3d_free_object(struct drm_gem_object *obj)
+       /* GPU execution may have dirtied any pages in the BO. */
+       bo->base.pages_mark_dirty_on_put = true;
+-      drm_gem_shmem_free_object(obj);
++      drm_gem_shmem_free(&bo->base);
+ }
+ static const struct drm_gem_object_funcs v3d_gem_funcs = {
+@@ -95,7 +95,7 @@ v3d_bo_create_finish(struct drm_gem_object *obj)
+       /* So far we pin the BO in the MMU for its lifetime, so use
+        * shmem's helper for getting a lifetime sgt.
+        */
+-      sgt = drm_gem_shmem_get_pages_sgt(&bo->base.base);
++      sgt = drm_gem_shmem_get_pages_sgt(&bo->base);
+       if (IS_ERR(sgt))
+               return PTR_ERR(sgt);
+@@ -141,7 +141,7 @@ struct v3d_bo *v3d_bo_create(struct drm_device *dev, struct drm_file *file_priv,
+       return bo;
+ free_obj:
+-      drm_gem_shmem_free_object(&shmem_obj->base);
++      drm_gem_shmem_free(shmem_obj);
+       return ERR_PTR(ret);
+ }
+@@ -159,7 +159,7 @@ v3d_prime_import_sg_table(struct drm_device *dev,
+       ret = v3d_bo_create_finish(obj);
+       if (ret) {
+-              drm_gem_shmem_free_object(obj);
++              drm_gem_shmem_free(&to_v3d_bo(obj)->base);
+               return ERR_PTR(ret);
+       }
+diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c
+index 698431d233b8..187e10da2f17 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_object.c
++++ b/drivers/gpu/drm/virtio/virtgpu_object.c
+@@ -79,10 +79,10 @@ void virtio_gpu_cleanup_object(struct virtio_gpu_object *bo)
+                       sg_free_table(shmem->pages);
+                       kfree(shmem->pages);
+                       shmem->pages = NULL;
+-                      drm_gem_shmem_unpin(&bo->base.base);
++                      drm_gem_shmem_unpin(&bo->base);
+               }
+-              drm_gem_shmem_free_object(&bo->base.base);
++              drm_gem_shmem_free(&bo->base);
+       } else if (virtio_gpu_is_vram(bo)) {
+               struct virtio_gpu_object_vram *vram = to_virtio_gpu_vram(bo);
+@@ -156,7 +156,7 @@ static int virtio_gpu_object_shmem_init(struct virtio_gpu_device *vgdev,
+       struct scatterlist *sg;
+       int si, ret;
+-      ret = drm_gem_shmem_pin(&bo->base.base);
++      ret = drm_gem_shmem_pin(&bo->base);
+       if (ret < 0)
+               return -EINVAL;
+@@ -166,9 +166,9 @@ static int virtio_gpu_object_shmem_init(struct virtio_gpu_device *vgdev,
+        * dma-ops. This is discouraged for other drivers, but should be fine
+        * since virtio_gpu doesn't support dma-buf import from other devices.
+        */
+-      shmem->pages = drm_gem_shmem_get_sg_table(&bo->base.base);
++      shmem->pages = drm_gem_shmem_get_sg_table(&bo->base);
+       if (!shmem->pages) {
+-              drm_gem_shmem_unpin(&bo->base.base);
++              drm_gem_shmem_unpin(&bo->base);
+               return -EINVAL;
+       }
+@@ -276,6 +276,6 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev,
+ err_put_id:
+       virtio_gpu_resource_id_put(vgdev, bo->hw_res_handle);
+ err_free_gem:
+-      drm_gem_shmem_free_object(&shmem_obj->base);
++      drm_gem_shmem_free(shmem_obj);
+       return ret;
+ }
+diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h
+index 4199877ae588..311d66c9cf4b 100644
+--- a/include/drm/drm_gem_shmem_helper.h
++++ b/include/drm/drm_gem_shmem_helper.h
+@@ -107,16 +107,17 @@ struct drm_gem_shmem_object {
+       container_of(obj, struct drm_gem_shmem_object, base)
+ struct drm_gem_shmem_object *drm_gem_shmem_create(struct drm_device *dev, size_t size);
+-void drm_gem_shmem_free_object(struct drm_gem_object *obj);
++void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem);
+ int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem);
+ void drm_gem_shmem_put_pages(struct drm_gem_shmem_object *shmem);
+-int drm_gem_shmem_pin(struct drm_gem_object *obj);
+-void drm_gem_shmem_unpin(struct drm_gem_object *obj);
+-int drm_gem_shmem_vmap(struct drm_gem_object *obj, struct dma_buf_map *map);
+-void drm_gem_shmem_vunmap(struct drm_gem_object *obj, struct dma_buf_map *map);
++int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem);
++void drm_gem_shmem_unpin(struct drm_gem_shmem_object *shmem);
++int drm_gem_shmem_vmap(struct drm_gem_shmem_object *shmem, struct dma_buf_map *map);
++void drm_gem_shmem_vunmap(struct drm_gem_shmem_object *shmem, struct dma_buf_map *map);
++int drm_gem_shmem_mmap(struct drm_gem_shmem_object *shmem, struct vm_area_struct *vma);
+-int drm_gem_shmem_madvise(struct drm_gem_object *obj, int madv);
++int drm_gem_shmem_madvise(struct drm_gem_shmem_object *shmem, int madv);
+ static inline bool drm_gem_shmem_is_purgeable(struct drm_gem_shmem_object *shmem)
+ {
+@@ -125,33 +126,31 @@ static inline bool drm_gem_shmem_is_purgeable(struct drm_gem_shmem_object *shmem
+               !shmem->base.dma_buf && !shmem->base.import_attach;
+ }
+-void drm_gem_shmem_purge_locked(struct drm_gem_object *obj);
+-bool drm_gem_shmem_purge(struct drm_gem_object *obj);
++void drm_gem_shmem_purge_locked(struct drm_gem_shmem_object *shmem);
++bool drm_gem_shmem_purge(struct drm_gem_shmem_object *shmem);
+-int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
+-                            struct drm_mode_create_dumb *args);
+-
+-int drm_gem_shmem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma);
+-
+-void drm_gem_shmem_print_info(struct drm_printer *p, unsigned int indent,
+-                            const struct drm_gem_object *obj);
++struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_shmem_object *shmem);
++struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_shmem_object *shmem);
+-struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_object *obj);
++void drm_gem_shmem_print_info(const struct drm_gem_shmem_object *shmem,
++                            struct drm_printer *p, unsigned int indent);
+ /*
+  * GEM object functions
+  */
+ /**
+- * drm_gem_shmem_object_free - GEM object function for drm_gem_shmem_free_object()
++ * drm_gem_shmem_object_free - GEM object function for drm_gem_shmem_free()
+  * @obj: GEM object to free
+  *
+- * This function wraps drm_gem_shmem_free_object(). Drivers that employ the shmem helpers
++ * This function wraps drm_gem_shmem_free(). Drivers that employ the shmem helpers
+  * should use it as their &drm_gem_object_funcs.free handler.
+  */
+ static inline void drm_gem_shmem_object_free(struct drm_gem_object *obj)
+ {
+-      drm_gem_shmem_free_object(obj);
++      struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
++
++      drm_gem_shmem_free(shmem);
+ }
+ /**
+@@ -166,7 +165,9 @@ static inline void drm_gem_shmem_object_free(struct drm_gem_object *obj)
+ static inline void drm_gem_shmem_object_print_info(struct drm_printer *p, unsigned int indent,
+                                                  const struct drm_gem_object *obj)
+ {
+-      drm_gem_shmem_print_info(p, indent, obj);
++      const struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
++
++      drm_gem_shmem_print_info(shmem, p, indent);
+ }
+ /**
+@@ -178,7 +179,9 @@ static inline void drm_gem_shmem_object_print_info(struct drm_printer *p, unsign
+  */
+ static inline int drm_gem_shmem_object_pin(struct drm_gem_object *obj)
+ {
+-      return drm_gem_shmem_pin(obj);
++      struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
++
++      return drm_gem_shmem_pin(shmem);
+ }
+ /**
+@@ -190,7 +193,9 @@ static inline int drm_gem_shmem_object_pin(struct drm_gem_object *obj)
+  */
+ static inline void drm_gem_shmem_object_unpin(struct drm_gem_object *obj)
+ {
+-      drm_gem_shmem_unpin(obj);
++      struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
++
++      drm_gem_shmem_unpin(shmem);
+ }
+ /**
+@@ -205,7 +210,9 @@ static inline void drm_gem_shmem_object_unpin(struct drm_gem_object *obj)
+  */
+ static inline struct sg_table *drm_gem_shmem_object_get_sg_table(struct drm_gem_object *obj)
+ {
+-      return drm_gem_shmem_get_sg_table(obj);
++      struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
++
++      return drm_gem_shmem_get_sg_table(shmem);
+ }
+ /*
+@@ -221,7 +228,9 @@ static inline struct sg_table *drm_gem_shmem_object_get_sg_table(struct drm_gem_
+  */
+ static inline int drm_gem_shmem_object_vmap(struct drm_gem_object *obj, struct dma_buf_map *map)
+ {
+-      return drm_gem_shmem_vmap(obj, map);
++      struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
++
++      return drm_gem_shmem_vmap(shmem, map);
+ }
+ /*
+@@ -234,7 +243,9 @@ static inline int drm_gem_shmem_object_vmap(struct drm_gem_object *obj, struct d
+  */
+ static inline void drm_gem_shmem_object_vunmap(struct drm_gem_object *obj, struct dma_buf_map *map)
+ {
+-      drm_gem_shmem_vunmap(obj, map);
++      struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
++
++      drm_gem_shmem_vunmap(shmem, map);
+ }
+ /**
+@@ -250,7 +261,9 @@ static inline void drm_gem_shmem_object_vunmap(struct drm_gem_object *obj, struc
+  */
+ static inline int drm_gem_shmem_object_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
+ {
+-      return drm_gem_shmem_mmap(obj, vma);
++      struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
++
++      return drm_gem_shmem_mmap(shmem, vma);
+ }
+ /*
+@@ -261,8 +274,8 @@ struct drm_gem_object *
+ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
+                                   struct dma_buf_attachment *attach,
+                                   struct sg_table *sgt);
+-
+-struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_object *obj);
++int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
++                            struct drm_mode_create_dumb *args);
+ /**
+  * DRM_GEM_SHMEM_DRIVER_OPS - Default shmem GEM operations
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-shmem-helper-unexport-drm_gem_shmem_create_with_.patch b/queue-5.15/drm-shmem-helper-unexport-drm_gem_shmem_create_with_.patch
new file mode 100644 (file)
index 0000000..4eeb931
--- /dev/null
@@ -0,0 +1,61 @@
+From e6c9fd1eb111a6171468a3b3de0de0f1604de710 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Nov 2021 10:31:47 +0100
+Subject: drm/shmem-helper: Unexport drm_gem_shmem_create_with_handle()
+
+From: Thomas Zimmermann <tzimmermann@suse.de>
+
+[ Upstream commit 5a363c20673308e968b6640deb73d7bf77e8b463 ]
+
+Turn drm_gem_shmem_create_with_handle() into an internal helper
+function. It's not used outside of the compilation unit.
+
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Link: https://patchwork.freedesktop.org/patch/msgid/20211108093149.7226-2-tzimmermann@suse.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_gem_shmem_helper.c | 3 +--
+ include/drm/drm_gem_shmem_helper.h     | 5 -----
+ 2 files changed, 1 insertion(+), 7 deletions(-)
+
+diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
+index 3eb580d76559..15e53674ed54 100644
+--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
+@@ -391,7 +391,7 @@ void drm_gem_shmem_vunmap(struct drm_gem_object *obj, struct dma_buf_map *map)
+ }
+ EXPORT_SYMBOL(drm_gem_shmem_vunmap);
+-struct drm_gem_shmem_object *
++static struct drm_gem_shmem_object *
+ drm_gem_shmem_create_with_handle(struct drm_file *file_priv,
+                                struct drm_device *dev, size_t size,
+                                uint32_t *handle)
+@@ -415,7 +415,6 @@ drm_gem_shmem_create_with_handle(struct drm_file *file_priv,
+       return shmem;
+ }
+-EXPORT_SYMBOL(drm_gem_shmem_create_with_handle);
+ /* Update madvise status, returns true if not purged, else
+  * false or -errno.
+diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h
+index 434328d8a0d9..6b47eb7d9f76 100644
+--- a/include/drm/drm_gem_shmem_helper.h
++++ b/include/drm/drm_gem_shmem_helper.h
+@@ -128,11 +128,6 @@ static inline bool drm_gem_shmem_is_purgeable(struct drm_gem_shmem_object *shmem
+ void drm_gem_shmem_purge_locked(struct drm_gem_object *obj);
+ bool drm_gem_shmem_purge(struct drm_gem_object *obj);
+-struct drm_gem_shmem_object *
+-drm_gem_shmem_create_with_handle(struct drm_file *file_priv,
+-                               struct drm_device *dev, size_t size,
+-                               uint32_t *handle);
+-
+ int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
+                             struct drm_mode_create_dumb *args);
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-st7735r-fix-module-autoloading-for-okaya-rh12812.patch b/queue-5.15/drm-st7735r-fix-module-autoloading-for-okaya-rh12812.patch
new file mode 100644 (file)
index 0000000..414d7e6
--- /dev/null
@@ -0,0 +1,51 @@
+From 29e6d20f69cc1b1fa6e351a1417899023451cee7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 May 2022 11:16:02 +0200
+Subject: drm/st7735r: Fix module autoloading for Okaya RH128128T
+
+From: Javier Martinez Canillas <javierm@redhat.com>
+
+[ Upstream commit 9ad6f181ad9a19a26bda73a7b199df44ccfcdaba ]
+
+The SPI core always reports a "MODALIAS=spi:<foo>", even if the device was
+registered via OF. This means that the st7735r.ko module won't autoload if
+a DT has a node with a compatible "okaya,rh128128t" string.
+
+In that case, kmod expects a "MODALIAS=of:N*T*Cokaya,rh128128t" uevent but
+instead will get a "MODALIAS=spi:rh128128t", which is not present in the
+list of aliases:
+
+  $ modinfo drivers/gpu/drm/tiny/st7735r.ko | grep alias
+  alias:          of:N*T*Cokaya,rh128128tC*
+  alias:          of:N*T*Cokaya,rh128128t
+  alias:          of:N*T*Cjianda,jd-t18003-t01C*
+  alias:          of:N*T*Cjianda,jd-t18003-t01
+  alias:          spi:jd-t18003-t01
+
+To workaround this issue, add in the SPI table an entry for that device.
+
+Fixes: d1d511d516f7 ("drm: tiny: st7735r: Add support for Okaya RH128128T")
+Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Acked-by: David Lechner <david@lechnology.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220520091602.179078-1-javierm@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/tiny/st7735r.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/tiny/st7735r.c b/drivers/gpu/drm/tiny/st7735r.c
+index fc40dd10efa8..713e4b286210 100644
+--- a/drivers/gpu/drm/tiny/st7735r.c
++++ b/drivers/gpu/drm/tiny/st7735r.c
+@@ -174,6 +174,7 @@ MODULE_DEVICE_TABLE(of, st7735r_of_match);
+ static const struct spi_device_id st7735r_id[] = {
+       { "jd-t18003-t01", (uintptr_t)&jd_t18003_t01_cfg },
++      { "rh128128t", (uintptr_t)&rh128128t_cfg },
+       { },
+ };
+ MODULE_DEVICE_TABLE(spi, st7735r_id);
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-vc4-dsi-add-correct-stop-condition-to-vc4_dsi_en.patch b/queue-5.15/drm-vc4-dsi-add-correct-stop-condition-to-vc4_dsi_en.patch
new file mode 100644 (file)
index 0000000..b91be2e
--- /dev/null
@@ -0,0 +1,43 @@
+From 251f7d341a65f3ba6252285f184bd0ba4389ec59 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 16:47:43 +0200
+Subject: drm/vc4: dsi: Add correct stop condition to vc4_dsi_encoder_disable
+ iteration
+
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+
+[ Upstream commit 7bcb9c8d0bc9f3cab8ac2634b056c2e6b63945ca ]
+
+vc4_dsi_encoder_disable is partially an open coded version of
+drm_bridge_chain_disable, but it missed a termination condition
+in the loop for ->disable which meant that no post_disable
+calls were made.
+
+Add in the termination clause.
+
+Fixes: 033bfe7538a1 ("drm/vc4: dsi: Fix bridge chain handling")
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Link: https://lore.kernel.org/r/20220613144800.326124-17-maxime@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_dsi.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
+index 333ea96fcde4..b7b2c76770dc 100644
+--- a/drivers/gpu/drm/vc4/vc4_dsi.c
++++ b/drivers/gpu/drm/vc4/vc4_dsi.c
+@@ -803,6 +803,9 @@ static void vc4_dsi_encoder_disable(struct drm_encoder *encoder)
+       list_for_each_entry_reverse(iter, &dsi->bridge_chain, chain_node) {
+               if (iter->funcs->disable)
+                       iter->funcs->disable(iter);
++
++              if (iter == dsi->bridge)
++                      break;
+       }
+       vc4_dsi_ulps(dsi, true);
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-vc4-dsi-correct-dsi-divider-calculations.patch b/queue-5.15/drm-vc4-dsi-correct-dsi-divider-calculations.patch
new file mode 100644 (file)
index 0000000..1aeefbd
--- /dev/null
@@ -0,0 +1,51 @@
+From f069f7de4797708a607c2d4d71a07ff398ccffa9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 16:47:39 +0200
+Subject: drm/vc4: dsi: Correct DSI divider calculations
+
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+
+[ Upstream commit 3b45eee87da171caa28f61240ddb5c21170cda53 ]
+
+The divider calculations tried to find the divider just faster than the
+clock requested. However if it required a divider of 7 then the for loop
+aborted without handling the "error" case, and could end up with a clock
+lower than requested.
+
+The integer divider from parent PLL to DSI clock is also capable of
+going up to /255, not just /7 that the driver was trying.  This allows
+for slower link frequencies on the DSI bus where the resolution permits.
+
+Correct the loop so that we always have a clock greater than requested,
+and covering the whole range of dividers.
+
+Fixes: 86c1b9eff3f2 ("drm/vc4: Adjust modes in DSI to work around the integer PLL divider.")
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Link: https://lore.kernel.org/r/20220613144800.326124-13-maxime@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_dsi.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
+index e82ee94cafc7..81a6c4e9576d 100644
+--- a/drivers/gpu/drm/vc4/vc4_dsi.c
++++ b/drivers/gpu/drm/vc4/vc4_dsi.c
+@@ -805,11 +805,9 @@ static bool vc4_dsi_encoder_mode_fixup(struct drm_encoder *encoder,
+       /* Find what divider gets us a faster clock than the requested
+        * pixel clock.
+        */
+-      for (divider = 1; divider < 8; divider++) {
+-              if (parent_rate / divider < pll_clock) {
+-                      divider--;
++      for (divider = 1; divider < 255; divider++) {
++              if (parent_rate / (divider + 1) < pll_clock)
+                       break;
+-              }
+       }
+       /* Now that we've picked a PLL divider, calculate back to its
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-vc4-dsi-correct-pixel-order-for-dsi0.patch b/queue-5.15/drm-vc4-dsi-correct-pixel-order-for-dsi0.patch
new file mode 100644 (file)
index 0000000..0223614
--- /dev/null
@@ -0,0 +1,40 @@
+From a3cf4f6c4d416b327c317aa20e3f3a047fde9bc2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 16:47:40 +0200
+Subject: drm/vc4: dsi: Correct pixel order for DSI0
+
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+
+[ Upstream commit edfe84ae0df16be1251b5a8e840d95f1f3827500 ]
+
+For slightly unknown reasons, dsi0 takes a different pixel format
+to dsi1, and that has to be set in the pixel valve.
+
+Amend the setup accordingly.
+
+Fixes: a86773d120d7 ("drm/vc4: Add support for feeding DSI encoders from the pixel valve.")
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Link: https://lore.kernel.org/r/20220613144800.326124-14-maxime@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_crtc.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
+index 88dbb282d15c..5a8c3c6c91af 100644
+--- a/drivers/gpu/drm/vc4/vc4_crtc.c
++++ b/drivers/gpu/drm/vc4/vc4_crtc.c
+@@ -330,7 +330,8 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_atomic_state *s
+       u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1;
+       bool is_dsi = (vc4_encoder->type == VC4_ENCODER_TYPE_DSI0 ||
+                      vc4_encoder->type == VC4_ENCODER_TYPE_DSI1);
+-      u32 format = is_dsi ? PV_CONTROL_FORMAT_DSIV_24 : PV_CONTROL_FORMAT_24;
++      bool is_dsi1 = vc4_encoder->type == VC4_ENCODER_TYPE_DSI1;
++      u32 format = is_dsi1 ? PV_CONTROL_FORMAT_DSIV_24 : PV_CONTROL_FORMAT_24;
+       u8 ppc = pv_data->pixels_per_clock;
+       bool debug_dump_regs = false;
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-vc4-dsi-fix-dsi0-interrupt-support.patch b/queue-5.15/drm-vc4-dsi-fix-dsi0-interrupt-support.patch
new file mode 100644 (file)
index 0000000..7d8b6c0
--- /dev/null
@@ -0,0 +1,201 @@
+From 38b147b6b7df30f448ab9f063649a7a8bcaab5c1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 16:47:42 +0200
+Subject: drm/vc4: dsi: Fix dsi0 interrupt support
+
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+
+[ Upstream commit bc5b815e06f90cccdb6461aba1e49fdc2f3c8cd1 ]
+
+DSI0 seemingly had very little or no testing as a load of
+the register mappings were incorrect/missing, so host
+transfers always timed out due to enabling/checking incorrect
+bits in the interrupt enable and status registers.
+
+Fixes: 4078f5757144 ("drm/vc4: Add DSI driver")
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Link: https://lore.kernel.org/r/20220613144800.326124-16-maxime@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_dsi.c | 111 ++++++++++++++++++++++++++--------
+ 1 file changed, 85 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
+index 97a258c934af..333ea96fcde4 100644
+--- a/drivers/gpu/drm/vc4/vc4_dsi.c
++++ b/drivers/gpu/drm/vc4/vc4_dsi.c
+@@ -181,8 +181,50 @@
+ #define DSI0_TXPKT_PIX_FIFO           0x20 /* AKA PIX_FIFO */
+-#define DSI0_INT_STAT         0x24
+-#define DSI0_INT_EN           0x28
++#define DSI0_INT_STAT                 0x24
++#define DSI0_INT_EN                   0x28
++# define DSI0_INT_FIFO_ERR            BIT(25)
++# define DSI0_INT_CMDC_DONE_MASK      VC4_MASK(24, 23)
++# define DSI0_INT_CMDC_DONE_SHIFT     23
++#  define DSI0_INT_CMDC_DONE_NO_REPEAT                1
++#  define DSI0_INT_CMDC_DONE_REPEAT           3
++# define DSI0_INT_PHY_DIR_RTF         BIT(22)
++# define DSI0_INT_PHY_D1_ULPS         BIT(21)
++# define DSI0_INT_PHY_D1_STOP         BIT(20)
++# define DSI0_INT_PHY_RXLPDT          BIT(19)
++# define DSI0_INT_PHY_RXTRIG          BIT(18)
++# define DSI0_INT_PHY_D0_ULPS         BIT(17)
++# define DSI0_INT_PHY_D0_LPDT         BIT(16)
++# define DSI0_INT_PHY_D0_FTR          BIT(15)
++# define DSI0_INT_PHY_D0_STOP         BIT(14)
++/* Signaled when the clock lane enters the given state. */
++# define DSI0_INT_PHY_CLK_ULPS                BIT(13)
++# define DSI0_INT_PHY_CLK_HS          BIT(12)
++# define DSI0_INT_PHY_CLK_FTR         BIT(11)
++/* Signaled on timeouts */
++# define DSI0_INT_PR_TO                       BIT(10)
++# define DSI0_INT_TA_TO                       BIT(9)
++# define DSI0_INT_LPRX_TO             BIT(8)
++# define DSI0_INT_HSTX_TO             BIT(7)
++/* Contention on a line when trying to drive the line low */
++# define DSI0_INT_ERR_CONT_LP1                BIT(6)
++# define DSI0_INT_ERR_CONT_LP0                BIT(5)
++/* Control error: incorrect line state sequence on data lane 0. */
++# define DSI0_INT_ERR_CONTROL         BIT(4)
++# define DSI0_INT_ERR_SYNC_ESC                BIT(3)
++# define DSI0_INT_RX2_PKT             BIT(2)
++# define DSI0_INT_RX1_PKT             BIT(1)
++# define DSI0_INT_CMD_PKT             BIT(0)
++
++#define DSI0_INTERRUPTS_ALWAYS_ENABLED        (DSI0_INT_ERR_SYNC_ESC | \
++                                       DSI0_INT_ERR_CONTROL |  \
++                                       DSI0_INT_ERR_CONT_LP0 | \
++                                       DSI0_INT_ERR_CONT_LP1 | \
++                                       DSI0_INT_HSTX_TO |      \
++                                       DSI0_INT_LPRX_TO |      \
++                                       DSI0_INT_TA_TO |        \
++                                       DSI0_INT_PR_TO)
++
+ # define DSI1_INT_PHY_D3_ULPS         BIT(30)
+ # define DSI1_INT_PHY_D3_STOP         BIT(29)
+ # define DSI1_INT_PHY_D2_ULPS         BIT(28)
+@@ -892,6 +934,9 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder)
+               DSI_PORT_WRITE(PHY_AFEC0, afec0);
++              /* AFEC reset hold time */
++              mdelay(1);
++
+               DSI_PORT_WRITE(PHY_AFEC1,
+                              VC4_SET_FIELD(6,  DSI0_PHY_AFEC1_IDR_DLANE1) |
+                              VC4_SET_FIELD(6,  DSI0_PHY_AFEC1_IDR_DLANE0) |
+@@ -1058,12 +1103,9 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder)
+               DSI_PORT_WRITE(CTRL, DSI_PORT_READ(CTRL) | DSI1_CTRL_EN);
+       /* Bring AFE out of reset. */
+-      if (dsi->variant->port == 0) {
+-      } else {
+-              DSI_PORT_WRITE(PHY_AFEC0,
+-                             DSI_PORT_READ(PHY_AFEC0) &
+-                             ~DSI1_PHY_AFEC0_RESET);
+-      }
++      DSI_PORT_WRITE(PHY_AFEC0,
++                     DSI_PORT_READ(PHY_AFEC0) &
++                     ~DSI_PORT_BIT(PHY_AFEC0_RESET));
+       vc4_dsi_ulps(dsi, false);
+@@ -1182,13 +1224,28 @@ static ssize_t vc4_dsi_host_transfer(struct mipi_dsi_host *host,
+       /* Enable the appropriate interrupt for the transfer completion. */
+       dsi->xfer_result = 0;
+       reinit_completion(&dsi->xfer_completion);
+-      DSI_PORT_WRITE(INT_STAT, DSI1_INT_TXPKT1_DONE | DSI1_INT_PHY_DIR_RTF);
+-      if (msg->rx_len) {
+-              DSI_PORT_WRITE(INT_EN, (DSI1_INTERRUPTS_ALWAYS_ENABLED |
+-                                      DSI1_INT_PHY_DIR_RTF));
++      if (dsi->variant->port == 0) {
++              DSI_PORT_WRITE(INT_STAT,
++                             DSI0_INT_CMDC_DONE_MASK | DSI1_INT_PHY_DIR_RTF);
++              if (msg->rx_len) {
++                      DSI_PORT_WRITE(INT_EN, (DSI0_INTERRUPTS_ALWAYS_ENABLED |
++                                              DSI0_INT_PHY_DIR_RTF));
++              } else {
++                      DSI_PORT_WRITE(INT_EN,
++                                     (DSI0_INTERRUPTS_ALWAYS_ENABLED |
++                                      VC4_SET_FIELD(DSI0_INT_CMDC_DONE_NO_REPEAT,
++                                                    DSI0_INT_CMDC_DONE)));
++              }
+       } else {
+-              DSI_PORT_WRITE(INT_EN, (DSI1_INTERRUPTS_ALWAYS_ENABLED |
+-                                      DSI1_INT_TXPKT1_DONE));
++              DSI_PORT_WRITE(INT_STAT,
++                             DSI1_INT_TXPKT1_DONE | DSI1_INT_PHY_DIR_RTF);
++              if (msg->rx_len) {
++                      DSI_PORT_WRITE(INT_EN, (DSI1_INTERRUPTS_ALWAYS_ENABLED |
++                                              DSI1_INT_PHY_DIR_RTF));
++              } else {
++                      DSI_PORT_WRITE(INT_EN, (DSI1_INTERRUPTS_ALWAYS_ENABLED |
++                                              DSI1_INT_TXPKT1_DONE));
++              }
+       }
+       /* Send the packet. */
+@@ -1205,7 +1262,7 @@ static ssize_t vc4_dsi_host_transfer(struct mipi_dsi_host *host,
+               ret = dsi->xfer_result;
+       }
+-      DSI_PORT_WRITE(INT_EN, DSI1_INTERRUPTS_ALWAYS_ENABLED);
++      DSI_PORT_WRITE(INT_EN, DSI_PORT_BIT(INTERRUPTS_ALWAYS_ENABLED));
+       if (ret)
+               goto reset_fifo_and_return;
+@@ -1251,7 +1308,7 @@ static ssize_t vc4_dsi_host_transfer(struct mipi_dsi_host *host,
+                      DSI_PORT_BIT(CTRL_RESET_FIFOS));
+       DSI_PORT_WRITE(TXPKT1C, 0);
+-      DSI_PORT_WRITE(INT_EN, DSI1_INTERRUPTS_ALWAYS_ENABLED);
++      DSI_PORT_WRITE(INT_EN, DSI_PORT_BIT(INTERRUPTS_ALWAYS_ENABLED));
+       return ret;
+ }
+@@ -1388,26 +1445,28 @@ static irqreturn_t vc4_dsi_irq_handler(int irq, void *data)
+       DSI_PORT_WRITE(INT_STAT, stat);
+       dsi_handle_error(dsi, &ret, stat,
+-                       DSI1_INT_ERR_SYNC_ESC, "LPDT sync");
++                       DSI_PORT_BIT(INT_ERR_SYNC_ESC), "LPDT sync");
+       dsi_handle_error(dsi, &ret, stat,
+-                       DSI1_INT_ERR_CONTROL, "data lane 0 sequence");
++                       DSI_PORT_BIT(INT_ERR_CONTROL), "data lane 0 sequence");
+       dsi_handle_error(dsi, &ret, stat,
+-                       DSI1_INT_ERR_CONT_LP0, "LP0 contention");
++                       DSI_PORT_BIT(INT_ERR_CONT_LP0), "LP0 contention");
+       dsi_handle_error(dsi, &ret, stat,
+-                       DSI1_INT_ERR_CONT_LP1, "LP1 contention");
++                       DSI_PORT_BIT(INT_ERR_CONT_LP1), "LP1 contention");
+       dsi_handle_error(dsi, &ret, stat,
+-                       DSI1_INT_HSTX_TO, "HSTX timeout");
++                       DSI_PORT_BIT(INT_HSTX_TO), "HSTX timeout");
+       dsi_handle_error(dsi, &ret, stat,
+-                       DSI1_INT_LPRX_TO, "LPRX timeout");
++                       DSI_PORT_BIT(INT_LPRX_TO), "LPRX timeout");
+       dsi_handle_error(dsi, &ret, stat,
+-                       DSI1_INT_TA_TO, "turnaround timeout");
++                       DSI_PORT_BIT(INT_TA_TO), "turnaround timeout");
+       dsi_handle_error(dsi, &ret, stat,
+-                       DSI1_INT_PR_TO, "peripheral reset timeout");
++                       DSI_PORT_BIT(INT_PR_TO), "peripheral reset timeout");
+-      if (stat & (DSI1_INT_TXPKT1_DONE | DSI1_INT_PHY_DIR_RTF)) {
++      if (stat & ((dsi->variant->port ? DSI1_INT_TXPKT1_DONE :
++                                        DSI0_INT_CMDC_DONE_MASK) |
++                  DSI_PORT_BIT(INT_PHY_DIR_RTF))) {
+               complete(&dsi->xfer_completion);
+               ret = IRQ_HANDLED;
+-      } else if (stat & DSI1_INT_HSTX_TO) {
++      } else if (stat & DSI_PORT_BIT(INT_HSTX_TO)) {
+               complete(&dsi->xfer_completion);
+               dsi->xfer_result = -ETIMEDOUT;
+               ret = IRQ_HANDLED;
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-vc4-dsi-register-dsi0-as-the-correct-vc4-encoder.patch b/queue-5.15/drm-vc4-dsi-register-dsi0-as-the-correct-vc4-encoder.patch
new file mode 100644 (file)
index 0000000..86f5cd4
--- /dev/null
@@ -0,0 +1,41 @@
+From c7a03c1408832792b0d6cf678653578585a23e43 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 16:47:41 +0200
+Subject: drm/vc4: dsi: Register dsi0 as the correct vc4 encoder type
+
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+
+[ Upstream commit 4d9273c978d4c1af15d7874c10c732ec83d444d0 ]
+
+vc4_dsi was registering both dsi0 and dsi1 as VC4_ENCODER_TYPE_DSI1
+which seemed to work OK for a single DSI display, but fails
+if there are two DSI displays connected.
+
+Update to register the correct type.
+
+Fixes: 4078f5757144 ("drm/vc4: Add DSI driver")
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Link: https://lore.kernel.org/r/20220613144800.326124-15-maxime@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_dsi.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
+index 81a6c4e9576d..97a258c934af 100644
+--- a/drivers/gpu/drm/vc4/vc4_dsi.c
++++ b/drivers/gpu/drm/vc4/vc4_dsi.c
+@@ -1518,7 +1518,8 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)
+               return -ENOMEM;
+       INIT_LIST_HEAD(&dsi->bridge_chain);
+-      vc4_dsi_encoder->base.type = VC4_ENCODER_TYPE_DSI1;
++      vc4_dsi_encoder->base.type = dsi->variant->port ?
++                      VC4_ENCODER_TYPE_DSI1 : VC4_ENCODER_TYPE_DSI0;
+       vc4_dsi_encoder->dsi = dsi;
+       dsi->encoder = &vc4_dsi_encoder->base.base;
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-vc4-dsi-release-workaround-buffer-and-dma.patch b/queue-5.15/drm-vc4-dsi-release-workaround-buffer-and-dma.patch
new file mode 100644 (file)
index 0000000..7c9c26c
--- /dev/null
@@ -0,0 +1,96 @@
+From 83f2da1e6fbd28254758ae5cdd338ffbd0b8e6bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 16:47:38 +0200
+Subject: drm/vc4: dsi: Release workaround buffer and DMA
+
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+
+[ Upstream commit 89c4bbe2a01ea401c2b0fabc104720809084b77f ]
+
+On Pi0-3 the driver allocates a buffer and requests a DMA channel
+because the ARM can't write to DSI1's registers directly.
+
+However, we never release that buffer or channel. Let's add a
+device-managed action to release each.
+
+Fixes: 4078f5757144 ("drm/vc4: Add DSI driver")
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Link: https://lore.kernel.org/r/20220613144800.326124-12-maxime@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_dsi.c | 29 ++++++++++++++++++++++++++++-
+ 1 file changed, 28 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
+index 98308a17e4ed..e82ee94cafc7 100644
+--- a/drivers/gpu/drm/vc4/vc4_dsi.c
++++ b/drivers/gpu/drm/vc4/vc4_dsi.c
+@@ -1487,13 +1487,29 @@ vc4_dsi_init_phy_clocks(struct vc4_dsi *dsi)
+                                     dsi->clk_onecell);
+ }
++static void vc4_dsi_dma_mem_release(void *ptr)
++{
++      struct vc4_dsi *dsi = ptr;
++      struct device *dev = &dsi->pdev->dev;
++
++      dma_free_coherent(dev, 4, dsi->reg_dma_mem, dsi->reg_dma_paddr);
++      dsi->reg_dma_mem = NULL;
++}
++
++static void vc4_dsi_dma_chan_release(void *ptr)
++{
++      struct vc4_dsi *dsi = ptr;
++
++      dma_release_channel(dsi->reg_dma_chan);
++      dsi->reg_dma_chan = NULL;
++}
++
+ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)
+ {
+       struct platform_device *pdev = to_platform_device(dev);
+       struct drm_device *drm = dev_get_drvdata(master);
+       struct vc4_dsi *dsi = dev_get_drvdata(dev);
+       struct vc4_dsi_encoder *vc4_dsi_encoder;
+-      dma_cap_mask_t dma_mask;
+       int ret;
+       dsi->variant = of_device_get_match_data(dev);
+@@ -1527,6 +1543,8 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)
+        * so set up a channel for talking to it.
+        */
+       if (dsi->variant->broken_axi_workaround) {
++              dma_cap_mask_t dma_mask;
++
+               dsi->reg_dma_mem = dma_alloc_coherent(dev, 4,
+                                                     &dsi->reg_dma_paddr,
+                                                     GFP_KERNEL);
+@@ -1535,8 +1553,13 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)
+                       return -ENOMEM;
+               }
++              ret = devm_add_action_or_reset(dev, vc4_dsi_dma_mem_release, dsi);
++              if (ret)
++                      return ret;
++
+               dma_cap_zero(dma_mask);
+               dma_cap_set(DMA_MEMCPY, dma_mask);
++
+               dsi->reg_dma_chan = dma_request_chan_by_mask(&dma_mask);
+               if (IS_ERR(dsi->reg_dma_chan)) {
+                       ret = PTR_ERR(dsi->reg_dma_chan);
+@@ -1546,6 +1569,10 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)
+                       return ret;
+               }
++              ret = devm_add_action_or_reset(dev, vc4_dsi_dma_chan_release, dsi);
++              if (ret)
++                      return ret;
++
+               /* Get the physical address of the device's registers.  The
+                * struct resource for the regs gives us the bus address
+                * instead.
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-vc4-dsi-switch-to-devm_drm_of_get_bridge.patch b/queue-5.15/drm-vc4-dsi-switch-to-devm_drm_of_get_bridge.patch
new file mode 100644 (file)
index 0000000..3e41f2e
--- /dev/null
@@ -0,0 +1,76 @@
+From 0047eeaafebd7f4d6dd51a1dbbbb4c094b9b7d65 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Sep 2021 15:09:41 +0200
+Subject: drm/vc4: dsi: Switch to devm_drm_of_get_bridge
+
+From: Maxime Ripard <maxime@cerno.tech>
+
+[ Upstream commit a43dd76bacd0d5441a4c84f60d64bdfaedc95bac ]
+
+The new devm_drm_of_get_bridge removes most of the boilerplate we
+have to deal with. Let's switch to it.
+
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Acked-by: Sam Ravnborg <sam@ravnborg.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210910130941.1740182-4-maxime@cerno.tech
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_dsi.c | 28 ++++------------------------
+ 1 file changed, 4 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
+index ca8506316660..64dfefeb03f5 100644
+--- a/drivers/gpu/drm/vc4/vc4_dsi.c
++++ b/drivers/gpu/drm/vc4/vc4_dsi.c
+@@ -1493,7 +1493,6 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)
+       struct drm_device *drm = dev_get_drvdata(master);
+       struct vc4_dsi *dsi = dev_get_drvdata(dev);
+       struct vc4_dsi_encoder *vc4_dsi_encoder;
+-      struct drm_panel *panel;
+       const struct of_device_id *match;
+       dma_cap_mask_t dma_mask;
+       int ret;
+@@ -1605,27 +1604,9 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)
+               return ret;
+       }
+-      ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
+-                                        &panel, &dsi->bridge);
+-      if (ret) {
+-              /* If the bridge or panel pointed by dev->of_node is not
+-               * enabled, just return 0 here so that we don't prevent the DRM
+-               * dev from being registered. Of course that means the DSI
+-               * encoder won't be exposed, but that's not a problem since
+-               * nothing is connected to it.
+-               */
+-              if (ret == -ENODEV)
+-                      return 0;
+-
+-              return ret;
+-      }
+-
+-      if (panel) {
+-              dsi->bridge = devm_drm_panel_bridge_add_typed(dev, panel,
+-                                                            DRM_MODE_CONNECTOR_DSI);
+-              if (IS_ERR(dsi->bridge))
+-                      return PTR_ERR(dsi->bridge);
+-      }
++      dsi->bridge = devm_drm_of_get_bridge(dev, dev->of_node, 0, 0);
++      if (IS_ERR(dsi->bridge))
++              return PTR_ERR(dsi->bridge);
+       /* The esc clock rate is supposed to always be 100Mhz. */
+       ret = clk_set_rate(dsi->escape_clock, 100 * 1000000);
+@@ -1663,8 +1644,7 @@ static void vc4_dsi_unbind(struct device *dev, struct device *master,
+ {
+       struct vc4_dsi *dsi = dev_get_drvdata(dev);
+-      if (dsi->bridge)
+-              pm_runtime_disable(dev);
++      pm_runtime_disable(dev);
+       /*
+        * Restore the bridge_chain so the bridge detach procedure can happen
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-vc4-hdmi-avoid-full-hdmi-audio-fifo-writes.patch b/queue-5.15/drm-vc4-hdmi-avoid-full-hdmi-audio-fifo-writes.patch
new file mode 100644 (file)
index 0000000..67ce97d
--- /dev/null
@@ -0,0 +1,46 @@
+From ab8ffc1f5e3bd711db7d5a9018a74c1203a50412 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 16:47:47 +0200
+Subject: drm/vc4: hdmi: Avoid full hdmi audio fifo writes
+
+From: Dom Cobley <popcornmix@gmail.com>
+
+[ Upstream commit 1c594eeccf92368177c2e22f1d3ee4933dfb8567 ]
+
+We are getting occasional VC4_HD_MAI_CTL_ERRORF in
+HDMI_MAI_CTL which seem to correspond with audio dropouts.
+
+Reduce the threshold where we deassert DREQ to avoid the fifo
+overfilling
+
+Fixes: bb7d78568814 ("drm/vc4: Add HDMI audio support")
+Signed-off-by: Dom Cobley <popcornmix@gmail.com>
+Link: https://lore.kernel.org/r/20220613144800.326124-21-maxime@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
+index e4533fe315bf..879245808e26 100644
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -1383,10 +1383,10 @@ static int vc4_hdmi_audio_prepare(struct device *dev, void *data,
+       /* Set the MAI threshold */
+       HDMI_WRITE(HDMI_MAI_THR,
+-                 VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_PANICHIGH) |
+-                 VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_PANICLOW) |
+-                 VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_DREQHIGH) |
+-                 VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_DREQLOW));
++                 VC4_SET_FIELD(0x08, VC4_HD_MAI_THR_PANICHIGH) |
++                 VC4_SET_FIELD(0x08, VC4_HD_MAI_THR_PANICLOW) |
++                 VC4_SET_FIELD(0x06, VC4_HD_MAI_THR_DREQHIGH) |
++                 VC4_SET_FIELD(0x08, VC4_HD_MAI_THR_DREQLOW));
+       HDMI_WRITE(HDMI_MAI_CONFIG,
+                  VC4_HDMI_MAI_CONFIG_BIT_REVERSE |
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-vc4-hdmi-correct-hdmi-timing-registers-for-inter.patch b/queue-5.15/drm-vc4-hdmi-correct-hdmi-timing-registers-for-inter.patch
new file mode 100644 (file)
index 0000000..6d9b5fb
--- /dev/null
@@ -0,0 +1,46 @@
+From 2bac1bf54b8f7bbcba617aebe8ffe1643ee1d8ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 16:47:59 +0200
+Subject: drm/vc4: hdmi: Correct HDMI timing registers for interlaced modes
+
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+
+[ Upstream commit fb10dc451c0f15e3c19798a2f41d357f3f7576f5 ]
+
+For interlaced modes the timings were not being correctly
+programmed into the HDMI block, so correct them.
+
+Fixes: 8323989140f3 ("drm/vc4: hdmi: Support the BCM2711 HDMI controllers")
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Link: https://lore.kernel.org/r/20220613144800.326124-33-maxime@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
+index ddcead896fe8..10cf623d2830 100644
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -783,13 +783,13 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
+                    VC4_SET_FIELD(mode->crtc_vsync_start - mode->crtc_vdisplay,
+                                  VC5_HDMI_VERTA_VFP) |
+                    VC4_SET_FIELD(mode->crtc_vdisplay, VC5_HDMI_VERTA_VAL));
+-      u32 vertb = (VC4_SET_FIELD(0, VC5_HDMI_VERTB_VSPO) |
+-                   VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end +
+-                                 interlaced,
++      u32 vertb = (VC4_SET_FIELD(mode->htotal >> (2 - pixel_rep),
++                                 VC5_HDMI_VERTB_VSPO) |
++                   VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end,
+                                  VC4_HDMI_VERTB_VBP));
+       u32 vertb_even = (VC4_SET_FIELD(0, VC5_HDMI_VERTB_VSPO) |
+                         VC4_SET_FIELD(mode->crtc_vtotal -
+-                                      mode->crtc_vsync_end,
++                                      mode->crtc_vsync_end - interlaced,
+                                       VC4_HDMI_VERTB_VBP));
+       unsigned char gcp;
+       bool gcp_en;
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-vc4-hdmi-fix-hpd-gpio-detection.patch b/queue-5.15/drm-vc4-hdmi-fix-hpd-gpio-detection.patch
new file mode 100644 (file)
index 0000000..611899a
--- /dev/null
@@ -0,0 +1,50 @@
+From 9fd14bf3d8b0171a6b356a5f94b5ee1a98efcda0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Oct 2021 17:28:55 +0200
+Subject: drm/vc4: hdmi: Fix HPD GPIO detection
+
+From: Maxime Ripard <maxime@cerno.tech>
+
+[ Upstream commit e32e5723256a99c5324824503572f743377dd0fe ]
+
+Prior to commit 6800234ceee0 ("drm/vc4: hdmi: Convert to gpiod"), in the
+detect hook, if we had an HPD GPIO we would only rely on it and return
+whatever state it was in.
+
+However, that commit changed that by mistake to only consider the case
+where we have a GPIO and it returns a logical high, and would fall back
+to the other methods otherwise.
+
+Since we can read the EDIDs when the HPD signal is low on some displays,
+we changed the detection status from disconnected to connected, and we
+would ignore an HPD pulse.
+
+Fixes: 6800234ceee0 ("drm/vc4: hdmi: Convert to gpiod")
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Link: https://lore.kernel.org/r/20211025152903.1088803-3-maxime@cerno.tech
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
+index 1aeb57656112..e4533fe315bf 100644
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -173,9 +173,9 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
+       WARN_ON(pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev));
+-      if (vc4_hdmi->hpd_gpio &&
+-          gpiod_get_value_cansleep(vc4_hdmi->hpd_gpio)) {
+-              connected = true;
++      if (vc4_hdmi->hpd_gpio) {
++              if (gpiod_get_value_cansleep(vc4_hdmi->hpd_gpio))
++                      connected = true;
+       } else if (drm_probe_ddc(vc4_hdmi->ddc)) {
+               connected = true;
+       } else if (HDMI_READ(HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED) {
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-vc4-hdmi-fix-timings-for-interlaced-modes.patch b/queue-5.15/drm-vc4-hdmi-fix-timings-for-interlaced-modes.patch
new file mode 100644 (file)
index 0000000..cabcb56
--- /dev/null
@@ -0,0 +1,98 @@
+From 149b5e0fe7a4ecb32d23d791df5b88257dbae04e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 16:47:57 +0200
+Subject: drm/vc4: hdmi: Fix timings for interlaced modes
+
+From: Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com>
+
+[ Upstream commit 0ee5a40152b15f200ed3a0d51e8aa782ea979c6a ]
+
+Increase the number of post-sync blanking lines on odd fields instead of
+decreasing it on even fields. This makes the total number of lines
+properly match the modelines.
+
+Additionally fix the value of PV_VCONTROL_ODD_DELAY, which did not take
+pixels_per_clock into account, causing some displays to invert the
+fields when driven by bcm2711.
+
+Fixes: 682e62c45406 ("drm/vc4: Fix support for interlaced modes on HDMI.")
+Signed-off-by: Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com>
+Link: https://lore.kernel.org/r/20220613144800.326124-31-maxime@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_crtc.c |  7 ++++---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 12 ++++++------
+ 2 files changed, 10 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
+index 5a8c3c6c91af..3b8576f19321 100644
+--- a/drivers/gpu/drm/vc4/vc4_crtc.c
++++ b/drivers/gpu/drm/vc4/vc4_crtc.c
+@@ -357,7 +357,8 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_atomic_state *s
+                                PV_HORZB_HACTIVE));
+       CRTC_WRITE(PV_VERTA,
+-                 VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end,
++                 VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end +
++                               interlace,
+                                PV_VERTA_VBP) |
+                  VC4_SET_FIELD(mode->crtc_vsync_end - mode->crtc_vsync_start,
+                                PV_VERTA_VSYNC));
+@@ -369,7 +370,7 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_atomic_state *s
+       if (interlace) {
+               CRTC_WRITE(PV_VERTA_EVEN,
+                          VC4_SET_FIELD(mode->crtc_vtotal -
+-                                       mode->crtc_vsync_end - 1,
++                                       mode->crtc_vsync_end,
+                                        PV_VERTA_VBP) |
+                          VC4_SET_FIELD(mode->crtc_vsync_end -
+                                        mode->crtc_vsync_start,
+@@ -389,7 +390,7 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_atomic_state *s
+                          PV_VCONTROL_CONTINUOUS |
+                          (is_dsi ? PV_VCONTROL_DSI : 0) |
+                          PV_VCONTROL_INTERLACE |
+-                         VC4_SET_FIELD(mode->htotal * pixel_rep / 2,
++                         VC4_SET_FIELD(mode->htotal * pixel_rep / (2 * ppc),
+                                        PV_VCONTROL_ODD_DELAY));
+               CRTC_WRITE(PV_VSYNCD_EVEN, 0);
+       } else {
+diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
+index e16fece541da..ddcead896fe8 100644
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -738,12 +738,12 @@ static void vc4_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
+                                  VC4_HDMI_VERTA_VFP) |
+                    VC4_SET_FIELD(mode->crtc_vdisplay, VC4_HDMI_VERTA_VAL));
+       u32 vertb = (VC4_SET_FIELD(0, VC4_HDMI_VERTB_VSPO) |
+-                   VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end,
++                   VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end +
++                                 interlaced,
+                                  VC4_HDMI_VERTB_VBP));
+       u32 vertb_even = (VC4_SET_FIELD(0, VC4_HDMI_VERTB_VSPO) |
+                         VC4_SET_FIELD(mode->crtc_vtotal -
+-                                      mode->crtc_vsync_end -
+-                                      interlaced,
++                                      mode->crtc_vsync_end,
+                                       VC4_HDMI_VERTB_VBP));
+       HDMI_WRITE(HDMI_HORZA,
+@@ -784,12 +784,12 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
+                                  VC5_HDMI_VERTA_VFP) |
+                    VC4_SET_FIELD(mode->crtc_vdisplay, VC5_HDMI_VERTA_VAL));
+       u32 vertb = (VC4_SET_FIELD(0, VC5_HDMI_VERTB_VSPO) |
+-                   VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end,
++                   VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end +
++                                 interlaced,
+                                  VC4_HDMI_VERTB_VBP));
+       u32 vertb_even = (VC4_SET_FIELD(0, VC5_HDMI_VERTB_VSPO) |
+                         VC4_SET_FIELD(mode->crtc_vtotal -
+-                                      mode->crtc_vsync_end -
+-                                      interlaced,
++                                      mode->crtc_vsync_end,
+                                       VC4_HDMI_VERTB_VBP));
+       unsigned char gcp;
+       bool gcp_en;
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-vc4-hdmi-reset-hdmi-misc_control-register.patch b/queue-5.15/drm-vc4-hdmi-reset-hdmi-misc_control-register.patch
new file mode 100644 (file)
index 0000000..7c146df
--- /dev/null
@@ -0,0 +1,84 @@
+From e0256ea1e59928f75033c7e34f31e168c874624d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 16:47:48 +0200
+Subject: drm/vc4: hdmi: Reset HDMI MISC_CONTROL register
+
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+
+[ Upstream commit 35dc00c12a72700a9c4592afee7d136ecb280cbd ]
+
+The HDMI block can repeat pixels for double clocked modes,
+and the firmware is now configuring the block to do this as
+the PV is doing it incorrectly when at 2pixels/clock.
+If the kernel doesn't reset it then we end up with strange
+modes.
+
+Reset MISC_CONTROL.
+
+Fixes: 8323989140f3 ("drm/vc4: hdmi: Support the BCM2711 HDMI controllers")
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Link: https://lore.kernel.org/r/20220613144800.326124-22-maxime@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_hdmi.c      | 8 ++++++++
+ drivers/gpu/drm/vc4/vc4_hdmi_regs.h | 3 +++
+ 2 files changed, 11 insertions(+)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
+index 879245808e26..e16fece541da 100644
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -79,6 +79,9 @@
+ #define VC5_HDMI_VERTB_VSPO_SHIFT             16
+ #define VC5_HDMI_VERTB_VSPO_MASK              VC4_MASK(29, 16)
++#define VC5_HDMI_MISC_CONTROL_PIXEL_REP_SHIFT 0
++#define VC5_HDMI_MISC_CONTROL_PIXEL_REP_MASK  VC4_MASK(3, 0)
++
+ #define VC5_HDMI_SCRAMBLER_CTL_ENABLE         BIT(0)
+ #define VC5_HDMI_DEEP_COLOR_CONFIG_1_INIT_PACK_PHASE_SHIFT    8
+@@ -849,6 +852,11 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
+       reg |= gcp_en ? VC5_HDMI_GCP_CONFIG_GCP_ENABLE : 0;
+       HDMI_WRITE(HDMI_GCP_CONFIG, reg);
++      reg = HDMI_READ(HDMI_MISC_CONTROL);
++      reg &= ~VC5_HDMI_MISC_CONTROL_PIXEL_REP_MASK;
++      reg |= VC4_SET_FIELD(0, VC5_HDMI_MISC_CONTROL_PIXEL_REP);
++      HDMI_WRITE(HDMI_MISC_CONTROL, reg);
++
+       HDMI_WRITE(HDMI_CLOCK_STOP, 0);
+ }
+diff --git a/drivers/gpu/drm/vc4/vc4_hdmi_regs.h b/drivers/gpu/drm/vc4/vc4_hdmi_regs.h
+index 19d2fdc446bc..f126fa425a1d 100644
+--- a/drivers/gpu/drm/vc4/vc4_hdmi_regs.h
++++ b/drivers/gpu/drm/vc4/vc4_hdmi_regs.h
+@@ -123,6 +123,7 @@ enum vc4_hdmi_field {
+       HDMI_VERTB0,
+       HDMI_VERTB1,
+       HDMI_VID_CTL,
++      HDMI_MISC_CONTROL,
+ };
+ struct vc4_hdmi_register {
+@@ -233,6 +234,7 @@ static const struct vc4_hdmi_register __maybe_unused vc5_hdmi_hdmi0_fields[] = {
+       VC4_HDMI_REG(HDMI_VERTB0, 0x0f0),
+       VC4_HDMI_REG(HDMI_VERTA1, 0x0f4),
+       VC4_HDMI_REG(HDMI_VERTB1, 0x0f8),
++      VC4_HDMI_REG(HDMI_MISC_CONTROL, 0x100),
+       VC4_HDMI_REG(HDMI_MAI_CHANNEL_MAP, 0x09c),
+       VC4_HDMI_REG(HDMI_MAI_CONFIG, 0x0a0),
+       VC4_HDMI_REG(HDMI_DEEP_COLOR_CONFIG_1, 0x170),
+@@ -313,6 +315,7 @@ static const struct vc4_hdmi_register __maybe_unused vc5_hdmi_hdmi1_fields[] = {
+       VC4_HDMI_REG(HDMI_VERTB0, 0x0f0),
+       VC4_HDMI_REG(HDMI_VERTA1, 0x0f4),
+       VC4_HDMI_REG(HDMI_VERTB1, 0x0f8),
++      VC4_HDMI_REG(HDMI_MISC_CONTROL, 0x100),
+       VC4_HDMI_REG(HDMI_MAI_CHANNEL_MAP, 0x09c),
+       VC4_HDMI_REG(HDMI_MAI_CONFIG, 0x0a0),
+       VC4_HDMI_REG(HDMI_DEEP_COLOR_CONFIG_1, 0x170),
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-vc4-plane-fix-margin-calculations-for-the-right-.patch b/queue-5.15/drm-vc4-plane-fix-margin-calculations-for-the-right-.patch
new file mode 100644 (file)
index 0000000..d6cfe27
--- /dev/null
@@ -0,0 +1,51 @@
+From ac248e415fc66d3e23cf75069bb46e9f42b01ebb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 16:47:32 +0200
+Subject: drm/vc4: plane: Fix margin calculations for the right/bottom edges
+
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+
+[ Upstream commit b7c3d6821627861f4ea3e1f2b595d0ed9e80aac8 ]
+
+The current plane margin calculation code clips the right and bottom
+edges of the range based using the left and top margins.
+
+This is obviously wrong, so let's fix it.
+
+Fixes: 666e73587f90 ("drm/vc4: Take margin setup into account when updating planes")
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Link: https://lore.kernel.org/r/20220613144800.326124-6-maxime@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_plane.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
+index e9d214d42cc7..8574acefd40e 100644
+--- a/drivers/gpu/drm/vc4/vc4_plane.c
++++ b/drivers/gpu/drm/vc4/vc4_plane.c
+@@ -303,16 +303,16 @@ static int vc4_plane_margins_adj(struct drm_plane_state *pstate)
+                                              adjhdisplay,
+                                              crtc_state->mode.hdisplay);
+       vc4_pstate->crtc_x += left;
+-      if (vc4_pstate->crtc_x > crtc_state->mode.hdisplay - left)
+-              vc4_pstate->crtc_x = crtc_state->mode.hdisplay - left;
++      if (vc4_pstate->crtc_x > crtc_state->mode.hdisplay - right)
++              vc4_pstate->crtc_x = crtc_state->mode.hdisplay - right;
+       adjvdisplay = crtc_state->mode.vdisplay - (top + bottom);
+       vc4_pstate->crtc_y = DIV_ROUND_CLOSEST(vc4_pstate->crtc_y *
+                                              adjvdisplay,
+                                              crtc_state->mode.vdisplay);
+       vc4_pstate->crtc_y += top;
+-      if (vc4_pstate->crtc_y > crtc_state->mode.vdisplay - top)
+-              vc4_pstate->crtc_y = crtc_state->mode.vdisplay - top;
++      if (vc4_pstate->crtc_y > crtc_state->mode.vdisplay - bottom)
++              vc4_pstate->crtc_y = crtc_state->mode.vdisplay - bottom;
+       vc4_pstate->crtc_w = DIV_ROUND_CLOSEST(vc4_pstate->crtc_w *
+                                              adjhdisplay,
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-vc4-plane-remove-subpixel-positioning-check.patch b/queue-5.15/drm-vc4-plane-remove-subpixel-positioning-check.patch
new file mode 100644 (file)
index 0000000..222a8bc
--- /dev/null
@@ -0,0 +1,76 @@
+From 40e07d279b299922ddf63bebec9988fbae533708 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 16:47:31 +0200
+Subject: drm/vc4: plane: Remove subpixel positioning check
+
+From: Dom Cobley <popcornmix@gmail.com>
+
+[ Upstream commit 517db1ab1566dba3093dbdb8de4263ba4aa66416 ]
+
+There is little harm in ignoring fractional coordinates
+(they just get truncated).
+
+Without this:
+modetest -M vc4 -F tiles,gradient -s 32:1920x1080-60 -P89@74:1920x1080*.1.1@XR24
+
+is rejected. We have the same issue in Kodi when trying to
+use zoom options on video.
+
+Note: even if all coordinates are fully integer. e.g.
+src:[0,0,1920,1080] dest:[-10,-10,1940,1100]
+
+it will still get rejected as drm_atomic_helper_check_plane_state
+uses drm_rect_clip_scaled which transforms this to fractional src coords
+
+Fixes: 21af94cf1a4c ("drm/vc4: Add support for scaling of display planes.")
+Signed-off-by: Dom Cobley <popcornmix@gmail.com>
+Link: https://lore.kernel.org/r/20220613144800.326124-5-maxime@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_plane.c | 22 +++++++++-------------
+ 1 file changed, 9 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
+index 19161b6ab27f..e9d214d42cc7 100644
+--- a/drivers/gpu/drm/vc4/vc4_plane.c
++++ b/drivers/gpu/drm/vc4/vc4_plane.c
+@@ -332,7 +332,6 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state)
+       struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
+       struct drm_framebuffer *fb = state->fb;
+       struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0);
+-      u32 subpixel_src_mask = (1 << 16) - 1;
+       int num_planes = fb->format->num_planes;
+       struct drm_crtc_state *crtc_state;
+       u32 h_subsample = fb->format->hsub;
+@@ -354,18 +353,15 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state)
+       for (i = 0; i < num_planes; i++)
+               vc4_state->offsets[i] = bo->paddr + fb->offsets[i];
+-      /* We don't support subpixel source positioning for scaling. */
+-      if ((state->src.x1 & subpixel_src_mask) ||
+-          (state->src.x2 & subpixel_src_mask) ||
+-          (state->src.y1 & subpixel_src_mask) ||
+-          (state->src.y2 & subpixel_src_mask)) {
+-              return -EINVAL;
+-      }
+-
+-      vc4_state->src_x = state->src.x1 >> 16;
+-      vc4_state->src_y = state->src.y1 >> 16;
+-      vc4_state->src_w[0] = (state->src.x2 - state->src.x1) >> 16;
+-      vc4_state->src_h[0] = (state->src.y2 - state->src.y1) >> 16;
++      /*
++       * We don't support subpixel source positioning for scaling,
++       * but fractional coordinates can be generated by clipping
++       * so just round for now
++       */
++      vc4_state->src_x = DIV_ROUND_CLOSEST(state->src.x1, 1 << 16);
++      vc4_state->src_y = DIV_ROUND_CLOSEST(state->src.y1, 1 << 16);
++      vc4_state->src_w[0] = DIV_ROUND_CLOSEST(state->src.x2, 1 << 16) - vc4_state->src_x;
++      vc4_state->src_h[0] = DIV_ROUND_CLOSEST(state->src.y2, 1 << 16) - vc4_state->src_y;
+       vc4_state->crtc_x = state->dst.x1;
+       vc4_state->crtc_y = state->dst.y1;
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-vc4-use-of_device_get_match_data.patch b/queue-5.15/drm-vc4-use-of_device_get_match_data.patch
new file mode 100644 (file)
index 0000000..5443d48
--- /dev/null
@@ -0,0 +1,44 @@
+From 17de1c0427bf83f678355f2aeae6a986f36348ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Feb 2022 02:05:30 +0000
+Subject: drm/vc4: Use of_device_get_match_data()
+
+From: Minghao Chi (CGEL ZTE) <chi.minghao@zte.com.cn>
+
+[ Upstream commit 9cbe89ede58294d23af06ec12c20f2ce6acc1892 ]
+
+Use of_device_get_match_data() to simplify the code.
+
+Reported-by: Zeal Robot <zealci@zte.com.cn>
+Signed-off-by: Minghao Chi (CGEL ZTE) <chi.minghao@zte.com.cn>
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220214020530.1714631-1-chi.minghao@zte.com.cn
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_dsi.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
+index 64dfefeb03f5..98308a17e4ed 100644
+--- a/drivers/gpu/drm/vc4/vc4_dsi.c
++++ b/drivers/gpu/drm/vc4/vc4_dsi.c
+@@ -1493,15 +1493,10 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)
+       struct drm_device *drm = dev_get_drvdata(master);
+       struct vc4_dsi *dsi = dev_get_drvdata(dev);
+       struct vc4_dsi_encoder *vc4_dsi_encoder;
+-      const struct of_device_id *match;
+       dma_cap_mask_t dma_mask;
+       int ret;
+-      match = of_match_device(vc4_dsi_dt_match, dev);
+-      if (!match)
+-              return -ENODEV;
+-
+-      dsi->variant = match->data;
++      dsi->variant = of_device_get_match_data(dev);
+       vc4_dsi_encoder = devm_kzalloc(dev, sizeof(*vc4_dsi_encoder),
+                                      GFP_KERNEL);
+-- 
+2.35.1
+
diff --git a/queue-5.15/drm-virtio-fix-null-vs-is_err-checking-in-virtio_gpu.patch b/queue-5.15/drm-virtio-fix-null-vs-is_err-checking-in-virtio_gpu.patch
new file mode 100644 (file)
index 0000000..a9a63ec
--- /dev/null
@@ -0,0 +1,42 @@
+From 52989be72fdef38bf0f7be53dd7506b035258dd3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jun 2022 14:42:22 +0400
+Subject: drm/virtio: Fix NULL vs IS_ERR checking in
+ virtio_gpu_object_shmem_init
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit c24968734abfed81c8f93dc5f44a7b7a9aecadfa ]
+
+Since drm_prime_pages_to_sg() function return error pointers.
+The drm_gem_shmem_get_sg_table() function returns error pointers too.
+Using IS_ERR() to check the return value to fix this.
+
+Fixes: 2f2aa13724d5 ("drm/virtio: move virtio_gpu_mem_entry initialization to new function")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/20220602104223.54527-1-linmq006@gmail.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/virtio/virtgpu_object.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c
+index 187e10da2f17..9af9f355e0a7 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_object.c
++++ b/drivers/gpu/drm/virtio/virtgpu_object.c
+@@ -167,9 +167,9 @@ static int virtio_gpu_object_shmem_init(struct virtio_gpu_device *vgdev,
+        * since virtio_gpu doesn't support dma-buf import from other devices.
+        */
+       shmem->pages = drm_gem_shmem_get_sg_table(&bo->base);
+-      if (!shmem->pages) {
++      if (IS_ERR(shmem->pages)) {
+               drm_gem_shmem_unpin(&bo->base);
+-              return -EINVAL;
++              return PTR_ERR(shmem->pages);
+       }
+       if (use_dma_api) {
+-- 
+2.35.1
+
diff --git a/queue-5.15/dt-bindings-iio-accel-add-dt-binding-doc-for-adxl355.patch b/queue-5.15/dt-bindings-iio-accel-add-dt-binding-doc-for-adxl355.patch
new file mode 100644 (file)
index 0000000..067de36
--- /dev/null
@@ -0,0 +1,118 @@
+From 09043b48e0763ba7e93f89af6c4873e8c5a726d6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Aug 2021 13:00:26 +0530
+Subject: dt-bindings: iio: accel: Add DT binding doc for ADXL355
+
+From: Puranjay Mohan <puranjay12@gmail.com>
+
+[ Upstream commit bf43a71a0a7f396434f6460b46e33eb00752f78d ]
+
+Add devicetree binding document for ADXL355, a 3-Axis MEMS Accelerometer.
+
+Signed-off-by: Puranjay Mohan <puranjay12@gmail.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Link: https://lore.kernel.org/r/20210811073027.124619-2-puranjay12@gmail.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../bindings/iio/accel/adi,adxl355.yaml       | 88 +++++++++++++++++++
+ 1 file changed, 88 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/iio/accel/adi,adxl355.yaml
+
+diff --git a/Documentation/devicetree/bindings/iio/accel/adi,adxl355.yaml b/Documentation/devicetree/bindings/iio/accel/adi,adxl355.yaml
+new file mode 100644
+index 000000000000..ba54d6998f2e
+--- /dev/null
++++ b/Documentation/devicetree/bindings/iio/accel/adi,adxl355.yaml
+@@ -0,0 +1,88 @@
++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/iio/accel/adi,adxl355.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Analog Devices ADXL355 3-Axis, Low noise MEMS Accelerometer
++
++maintainers:
++  - Puranjay Mohan <puranjay12@gmail.com>
++
++description: |
++  Analog Devices ADXL355 3-Axis, Low noise MEMS Accelerometer that supports
++  both I2C & SPI interfaces
++    https://www.analog.com/en/products/adxl355.html
++
++properties:
++  compatible:
++    enum:
++      - adi,adxl355
++
++  reg:
++    maxItems: 1
++
++  interrupts:
++    minItems: 1
++    maxItems: 3
++    description: |
++      Type for DRDY should be IRQ_TYPE_EDGE_RISING.
++      Three configurable interrupt lines exist.
++
++  interrupt-names:
++    description: Specify which interrupt line is in use.
++    items:
++      enum:
++        - INT1
++        - INT2
++        - DRDY
++    minItems: 1
++    maxItems: 3
++
++  vdd-supply:
++    description: Regulator that provides power to the sensor
++
++  vddio-supply:
++    description: Regulator that provides power to the bus
++
++  spi-max-frequency: true
++
++required:
++  - compatible
++  - reg
++
++additionalProperties: false
++
++examples:
++  - |
++        #include <dt-bindings/gpio/gpio.h>
++        #include <dt-bindings/interrupt-controller/irq.h>
++        i2c {
++                #address-cells = <1>;
++                #size-cells = <0>;
++
++                /* Example for a I2C device node */
++                accelerometer@1d {
++                        compatible = "adi,adxl355";
++                        reg = <0x1d>;
++                        interrupt-parent = <&gpio>;
++                        interrupts = <25 IRQ_TYPE_EDGE_RISING>;
++                        interrupt-names = "DRDY";
++                };
++        };
++  - |
++        #include <dt-bindings/gpio/gpio.h>
++        #include <dt-bindings/interrupt-controller/irq.h>
++        spi {
++                #address-cells = <1>;
++                #size-cells = <0>;
++
++                accelerometer@0 {
++                        compatible = "adi,adxl355";
++                        reg = <0>;
++                        spi-max-frequency = <1000000>;
++                        interrupt-parent = <&gpio>;
++                        interrupts = <25 IRQ_TYPE_EDGE_RISING>;
++                        interrupt-names = "DRDY";
++                };
++        };
+-- 
+2.35.1
+
diff --git a/queue-5.15/eeprom-idt_89hpesx-uninitialized-data-in-idt_dbgfs_c.patch b/queue-5.15/eeprom-idt_89hpesx-uninitialized-data-in-idt_dbgfs_c.patch
new file mode 100644 (file)
index 0000000..d4c7830
--- /dev/null
@@ -0,0 +1,55 @@
+From 62ab2b904ee04c088180bea056d6c785d32f2ec0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Jul 2022 16:46:38 +0300
+Subject: eeprom: idt_89hpesx: uninitialized data in idt_dbgfs_csr_write()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit 71d46f1ff2212ced4852c7e77c5176382a1bdcec ]
+
+The simple_write_to_buffer() function will return positive/success if it
+is able to write a single byte anywhere within the buffer.  However that
+potentially leaves a lot of the buffer uninitialized.
+
+In this code it's better to return 0 if the offset is non-zero.  This
+code is not written to support partial writes.  And then return -EFAULT
+if the buffer is not completely initialized.
+
+Fixes: cfad6425382e ("eeprom: Add IDT 89HPESx EEPROM/CSR driver")
+Reviewed-by: Serge Semin <fancer.lancer@gmail.com>
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Link: https://lore.kernel.org/r/Ysg1Pu/nzSMe3r1q@kili
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/eeprom/idt_89hpesx.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/misc/eeprom/idt_89hpesx.c b/drivers/misc/eeprom/idt_89hpesx.c
+index b0cff4b152da..7f430742ce2b 100644
+--- a/drivers/misc/eeprom/idt_89hpesx.c
++++ b/drivers/misc/eeprom/idt_89hpesx.c
+@@ -909,14 +909,18 @@ static ssize_t idt_dbgfs_csr_write(struct file *filep, const char __user *ubuf,
+       u32 csraddr, csrval;
+       char *buf;
++      if (*offp)
++              return 0;
++
+       /* Copy data from User-space */
+       buf = kmalloc(count + 1, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+-      ret = simple_write_to_buffer(buf, count, offp, ubuf, count);
+-      if (ret < 0)
++      if (copy_from_user(buf, ubuf, count)) {
++              ret = -EFAULT;
+               goto free_buf;
++      }
+       buf[count] = 0;
+       /* Find position of colon in the buffer */
+-- 
+2.35.1
+
diff --git a/queue-5.15/erofs-avoid-consecutive-detection-for-highmem-memory.patch b/queue-5.15/erofs-avoid-consecutive-detection-for-highmem-memory.patch
new file mode 100644 (file)
index 0000000..a4a51a7
--- /dev/null
@@ -0,0 +1,59 @@
+From 7a2e1f730e22388cc34f1500633cfa0f8c1f0175 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Jul 2022 18:10:01 +0800
+Subject: erofs: avoid consecutive detection for Highmem memory
+
+From: Gao Xiang <hsiangkao@linux.alibaba.com>
+
+[ Upstream commit 448b5a1548d87c246c3d0c3df8480d3c6eb6c11a ]
+
+Currently, vmap()s are avoided if physical addresses are
+consecutive for decompressed buffers.
+
+I observed that is very common for 4KiB pclusters since the
+numbers of decompressed pages are almost 2 or 3.
+
+However, such detection doesn't work for Highmem pages on
+32-bit machines, let's fix it now.
+
+Reported-by: Liu Jinbao <liujinbao1@xiaomi.com>
+Fixes: 7fc45dbc938a ("staging: erofs: introduce generic decompression backend")
+Link: https://lore.kernel.org/r/20220708101001.21242-1-hsiangkao@linux.alibaba.com
+Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/erofs/decompressor.c | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/fs/erofs/decompressor.c b/fs/erofs/decompressor.c
+index ad3f31380e6b..8193c14bb111 100644
+--- a/fs/erofs/decompressor.c
++++ b/fs/erofs/decompressor.c
+@@ -93,14 +93,18 @@ static int z_erofs_lz4_prepare_destpages(struct z_erofs_decompress_req *rq,
+               if (page) {
+                       __clear_bit(j, bounced);
+-                      if (kaddr) {
+-                              if (kaddr + PAGE_SIZE == page_address(page))
++                      if (!PageHighMem(page)) {
++                              if (!i) {
++                                      kaddr = page_address(page);
++                                      continue;
++                              }
++                              if (kaddr &&
++                                  kaddr + PAGE_SIZE == page_address(page)) {
+                                       kaddr += PAGE_SIZE;
+-                              else
+-                                      kaddr = NULL;
+-                      } else if (!i) {
+-                              kaddr = page_address(page);
++                                      continue;
++                              }
+                       }
++                      kaddr = NULL;
+                       continue;
+               }
+               kaddr = NULL;
+-- 
+2.35.1
+
diff --git a/queue-5.15/ext2-add-more-validity-checks-for-inode-counts.patch b/queue-5.15/ext2-add-more-validity-checks-for-inode-counts.patch
new file mode 100644 (file)
index 0000000..add3e95
--- /dev/null
@@ -0,0 +1,55 @@
+From 86fa45ada61991b3de8055c278ffe3866622d743 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Jul 2022 13:13:50 +0200
+Subject: ext2: Add more validity checks for inode counts
+
+From: Jan Kara <jack@suse.cz>
+
+[ Upstream commit fa78f336937240d1bc598db817d638086060e7e9 ]
+
+Add checks verifying number of inodes stored in the superblock matches
+the number computed from number of inodes per group. Also verify we have
+at least one block worth of inodes per group. This prevents crashes on
+corrupted filesystems.
+
+Reported-by: syzbot+d273f7d7f58afd93be48@syzkaller.appspotmail.com
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext2/super.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/fs/ext2/super.c b/fs/ext2/super.c
+index 3d21279fe2cb..fd855574ef09 100644
+--- a/fs/ext2/super.c
++++ b/fs/ext2/super.c
+@@ -1058,9 +1058,10 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
+                       sbi->s_frags_per_group);
+               goto failed_mount;
+       }
+-      if (sbi->s_inodes_per_group > sb->s_blocksize * 8) {
++      if (sbi->s_inodes_per_group < sbi->s_inodes_per_block ||
++          sbi->s_inodes_per_group > sb->s_blocksize * 8) {
+               ext2_msg(sb, KERN_ERR,
+-                      "error: #inodes per group too big: %lu",
++                      "error: invalid #inodes per group: %lu",
+                       sbi->s_inodes_per_group);
+               goto failed_mount;
+       }
+@@ -1070,6 +1071,13 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
+       sbi->s_groups_count = ((le32_to_cpu(es->s_blocks_count) -
+                               le32_to_cpu(es->s_first_data_block) - 1)
+                                       / EXT2_BLOCKS_PER_GROUP(sb)) + 1;
++      if ((u64)sbi->s_groups_count * sbi->s_inodes_per_group !=
++          le32_to_cpu(es->s_inodes_count)) {
++              ext2_msg(sb, KERN_ERR, "error: invalid #inodes: %u vs computed %llu",
++                       le32_to_cpu(es->s_inodes_count),
++                       (u64)sbi->s_groups_count * sbi->s_inodes_per_group);
++              goto failed_mount;
++      }
+       db_count = (sbi->s_groups_count + EXT2_DESC_PER_BLOCK(sb) - 1) /
+                  EXT2_DESC_PER_BLOCK(sb);
+       sbi->s_group_desc = kmalloc_array(db_count,
+-- 
+2.35.1
+
diff --git a/queue-5.15/ext4-recover-csum-seed-of-tmp_inode-after-migrating-.patch b/queue-5.15/ext4-recover-csum-seed-of-tmp_inode-after-migrating-.patch
new file mode 100644 (file)
index 0000000..58ba94e
--- /dev/null
@@ -0,0 +1,76 @@
+From bc56f26483e6cd67a7db5c71d3cc85ab3b92d42a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jun 2022 14:25:15 +0800
+Subject: ext4: recover csum seed of tmp_inode after migrating to extents
+
+From: Li Lingfeng <lilingfeng3@huawei.com>
+
+[ Upstream commit 07ea7a617d6b278fb7acedb5cbe1a81ce2de7d0c ]
+
+When migrating to extents, the checksum seed of temporary inode
+need to be replaced by inode's, otherwise the inode checksums
+will be incorrect when swapping the inodes data.
+
+However, the temporary inode can not match it's checksum to
+itself since it has lost it's own checksum seed.
+
+mkfs.ext4 -F /dev/sdc
+mount /dev/sdc /mnt/sdc
+xfs_io -fc "pwrite 4k 4k" -c "fsync" /mnt/sdc/testfile
+chattr -e /mnt/sdc/testfile
+chattr +e /mnt/sdc/testfile
+umount /dev/sdc
+fsck -fn /dev/sdc
+
+========
+...
+Pass 1: Checking inodes, blocks, and sizes
+Inode 13 passes checks, but checksum does not match inode.  Fix? no
+...
+========
+
+The fix is simple, save the checksum seed of temporary inode, and
+recover it after migrating to extents.
+
+Fixes: e81c9302a6c3 ("ext4: set csum seed in tmp inode while migrating to extents")
+Signed-off-by: Li Lingfeng <lilingfeng3@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20220617062515.2113438-1-lilingfeng3@huawei.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/migrate.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c
+index ff8916e1d38e..af5a75a89e6e 100644
+--- a/fs/ext4/migrate.c
++++ b/fs/ext4/migrate.c
+@@ -417,7 +417,7 @@ int ext4_ext_migrate(struct inode *inode)
+       struct inode *tmp_inode = NULL;
+       struct migrate_struct lb;
+       unsigned long max_entries;
+-      __u32 goal;
++      __u32 goal, tmp_csum_seed;
+       uid_t owner[2];
+       /*
+@@ -465,6 +465,7 @@ int ext4_ext_migrate(struct inode *inode)
+        * the migration.
+        */
+       ei = EXT4_I(inode);
++      tmp_csum_seed = EXT4_I(tmp_inode)->i_csum_seed;
+       EXT4_I(tmp_inode)->i_csum_seed = ei->i_csum_seed;
+       i_size_write(tmp_inode, i_size_read(inode));
+       /*
+@@ -575,6 +576,7 @@ int ext4_ext_migrate(struct inode *inode)
+        * the inode is not visible to user space.
+        */
+       tmp_inode->i_blocks = 0;
++      EXT4_I(tmp_inode)->i_csum_seed = tmp_csum_seed;
+       /* Reset the extent details */
+       ext4_ext_tree_init(handle, tmp_inode);
+-- 
+2.35.1
+
diff --git a/queue-5.15/f2fs-allow-compression-for-mmap-files-in-compress_mo.patch b/queue-5.15/f2fs-allow-compression-for-mmap-files-in-compress_mo.patch
new file mode 100644 (file)
index 0000000..8861c28
--- /dev/null
@@ -0,0 +1,56 @@
+From 5ca61b66eae7ba98148c9369ab2b5ddfa4ce1b98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 May 2022 10:29:11 +0900
+Subject: f2fs: allow compression for mmap files in compress_mode=user
+
+From: Sungjong Seo <sj1557.seo@samsung.com>
+
+[ Upstream commit 66d34fcbbe63ebd8584b792e0d741f6648100894 ]
+
+Since commit e3c548323d32 ("f2fs: let's allow compression for mmap files"),
+it has been allowed to compress mmap files. However, in compress_mode=user,
+it is not allowed yet. To keep the same concept in both compress_modes,
+f2fs_ioc_(de)compress_file() should also allow it.
+
+Let's remove checking mmap files in f2fs_ioc_(de)compress_file() so that
+the compression for mmap files is also allowed in compress_mode=user.
+
+Signed-off-by: Sungjong Seo <sj1557.seo@samsung.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/file.c | 10 ----------
+ 1 file changed, 10 deletions(-)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index eacc80ac160f..0669464a942a 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -4011,11 +4011,6 @@ static int f2fs_ioc_decompress_file(struct file *filp, unsigned long arg)
+               goto out;
+       }
+-      if (f2fs_is_mmap_file(inode)) {
+-              ret = -EBUSY;
+-              goto out;
+-      }
+-
+       ret = filemap_write_and_wait_range(inode->i_mapping, 0, LLONG_MAX);
+       if (ret)
+               goto out;
+@@ -4083,11 +4078,6 @@ static int f2fs_ioc_compress_file(struct file *filp, unsigned long arg)
+               goto out;
+       }
+-      if (f2fs_is_mmap_file(inode)) {
+-              ret = -EBUSY;
+-              goto out;
+-      }
+-
+       ret = filemap_write_and_wait_range(inode->i_mapping, 0, LLONG_MAX);
+       if (ret)
+               goto out;
+-- 
+2.35.1
+
diff --git a/queue-5.15/f2fs-do-not-allow-to-decompress-files-have-fi_compre.patch b/queue-5.15/f2fs-do-not-allow-to-decompress-files-have-fi_compre.patch
new file mode 100644 (file)
index 0000000..c97832d
--- /dev/null
@@ -0,0 +1,75 @@
+From 8a1f6208c4360f1d1da28ca27a56ad949d498ade Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Aug 2022 17:53:58 +0900
+Subject: f2fs: do not allow to decompress files have FI_COMPRESS_RELEASED
+
+From: Jaewook Kim <jw5454.kim@samsung.com>
+
+[ Upstream commit 90be48bd9d29ece3965e5e8b21499b6db166e57b ]
+
+If a file has FI_COMPRESS_RELEASED, all writes for it should not be
+allowed. However, as of now, in case of compress_mode=user, writes
+triggered by IOCTLs like F2FS_IOC_DE/COMPRESS_FILE are allowed unexpectly,
+which could crash that file.
+To fix it, let's do not allow F2FS_IOC_DE/COMPRESS_IOCTL if a file already
+has FI_COMPRESS_RELEASED flag.
+
+This is the reproduction process:
+1.  $ touch ./file
+2.  $ chattr +c ./file
+3.  $ dd if=/dev/random of=./file bs=4096 count=30 conv=notrunc
+4.  $ dd if=/dev/zero of=./file bs=4096 count=34 seek=30 conv=notrunc
+5.  $ sync
+6.  $ do_compress ./file      ; call F2FS_IOC_COMPRESS_FILE
+7.  $ get_compr_blocks ./file ; call F2FS_IOC_GET_COMPRESS_BLOCKS
+8.  $ release ./file          ; call F2FS_IOC_RELEASE_COMPRESS_BLOCKS
+9.  $ do_compress ./file      ; call F2FS_IOC_COMPRESS_FILE again
+10. $ get_compr_blocks ./file ; call F2FS_IOC_GET_COMPRESS_BLOCKS again
+
+This reproduction process is tested in 128kb cluster size.
+You can find compr_blocks has a negative value.
+
+Fixes: 5fdb322ff2c2b ("f2fs: add F2FS_IOC_DECOMPRESS_FILE and F2FS_IOC_COMPRESS_FILE")
+
+Signed-off-by: Junbeom Yeom <junbeom.yeom@samsung.com>
+Signed-off-by: Sungjong Seo <sj1557.seo@samsung.com>
+Signed-off-by: Youngjin Gil <youngjin.gil@samsung.com>
+Signed-off-by: Jaewook Kim <jw5454.kim@samsung.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/file.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 0669464a942a..758048a885d2 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -4011,6 +4011,11 @@ static int f2fs_ioc_decompress_file(struct file *filp, unsigned long arg)
+               goto out;
+       }
++      if (is_inode_flag_set(inode, FI_COMPRESS_RELEASED)) {
++              ret = -EINVAL;
++              goto out;
++      }
++
+       ret = filemap_write_and_wait_range(inode->i_mapping, 0, LLONG_MAX);
+       if (ret)
+               goto out;
+@@ -4078,6 +4083,11 @@ static int f2fs_ioc_compress_file(struct file *filp, unsigned long arg)
+               goto out;
+       }
++      if (is_inode_flag_set(inode, FI_COMPRESS_RELEASED)) {
++              ret = -EINVAL;
++              goto out;
++      }
++
+       ret = filemap_write_and_wait_range(inode->i_mapping, 0, LLONG_MAX);
+       if (ret)
+               goto out;
+-- 
+2.35.1
+
diff --git a/queue-5.15/f2fs-fix-to-remove-f2fs_compr_fl-and-tag-f2fs_nocomp.patch b/queue-5.15/f2fs-fix-to-remove-f2fs_compr_fl-and-tag-f2fs_nocomp.patch
new file mode 100644 (file)
index 0000000..c0708ef
--- /dev/null
@@ -0,0 +1,83 @@
+From 9c92a2fd12d5f041c3089103bff6f9e1b13cc251 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Jul 2022 18:16:33 +0800
+Subject: f2fs: fix to remove F2FS_COMPR_FL and tag F2FS_NOCOMP_FL at the same
+ time
+
+From: Chao Liu <liuchao@coolpad.com>
+
+[ Upstream commit 8ee236dcaa690d09ca612622e8bc8d09c302021d ]
+
+If the inode has the compress flag, it will fail to use
+'chattr -c +m' to remove its compress flag and tag no compress flag.
+However, the same command will be successful when executed again,
+as shown below:
+
+  $ touch foo.txt
+  $ chattr +c foo.txt
+  $ chattr -c +m foo.txt
+  chattr: Invalid argument while setting flags on foo.txt
+  $ chattr -c +m foo.txt
+  $ f2fs_io getflags foo.txt
+  get a flag on foo.txt ret=0, flags=nocompression,inline_data
+
+Fix this by removing some checks in f2fs_setflags_common()
+that do not affect the original logic. I go through all the
+possible scenarios, and the results are as follows. Bold is
+the only thing that has changed.
+
++---------------+-----------+-----------+----------+
+|               |            file flags            |
++ command       +-----------+-----------+----------+
+|               | no flag   | compr     | nocompr  |
++---------------+-----------+-----------+----------+
+| chattr +c     | compr     | compr     | -EINVAL  |
+| chattr -c     | no flag   | no flag   | nocompr  |
+| chattr +m     | nocompr   | -EINVAL   | nocompr  |
+| chattr -m     | no flag   | compr     | no flag  |
+| chattr +c +m  | -EINVAL   | -EINVAL   | -EINVAL  |
+| chattr +c -m  | compr     | compr     | compr    |
+| chattr -c +m  | nocompr   | *nocompr* | nocompr  |
+| chattr -c -m  | no flag   | no flag   | no flag  |
++---------------+-----------+-----------+----------+
+
+Link: https://lore.kernel.org/linux-f2fs-devel/20220621064833.1079383-1-chaoliu719@gmail.com/
+Fixes: 4c8ff7095bef ("f2fs: support data compression")
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Chao Liu <liuchao@coolpad.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/file.c | 9 +--------
+ 1 file changed, 1 insertion(+), 8 deletions(-)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index bfcafc20eada..eacc80ac160f 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -1869,10 +1869,7 @@ static int f2fs_setflags_common(struct inode *inode, u32 iflags, u32 mask)
+               if (masked_flags & F2FS_COMPR_FL) {
+                       if (!f2fs_disable_compressed_file(inode))
+                               return -EINVAL;
+-              }
+-              if (iflags & F2FS_NOCOMP_FL)
+-                      return -EINVAL;
+-              if (iflags & F2FS_COMPR_FL) {
++              } else {
+                       if (!f2fs_may_compress(inode))
+                               return -EINVAL;
+                       if (S_ISREG(inode->i_mode) && inode->i_size)
+@@ -1881,10 +1878,6 @@ static int f2fs_setflags_common(struct inode *inode, u32 iflags, u32 mask)
+                       set_compress_context(inode);
+               }
+       }
+-      if ((iflags ^ masked_flags) & F2FS_NOCOMP_FL) {
+-              if (masked_flags & F2FS_COMPR_FL)
+-                      return -EINVAL;
+-      }
+       fi->i_flags = iflags | (fi->i_flags & ~mask);
+       f2fs_bug_on(F2FS_I_SB(inode), (fi->i_flags & F2FS_COMPR_FL) &&
+-- 
+2.35.1
+
diff --git a/queue-5.15/firmware-tegra-fix-error-check-return-value-of-debug.patch b/queue-5.15/firmware-tegra-fix-error-check-return-value-of-debug.patch
new file mode 100644 (file)
index 0000000..749d836
--- /dev/null
@@ -0,0 +1,69 @@
+From 1ba03cab23f59e1ed0bb91626ea558984d772b58 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Apr 2022 01:36:48 +0000
+Subject: firmware: tegra: Fix error check return value of
+ debugfs_create_file()
+
+From: Lv Ruyi <lv.ruyi@zte.com.cn>
+
+[ Upstream commit afcdb8e55c91c6ff0700ab272fd0f74e899ab884 ]
+
+If an error occurs, debugfs_create_file() will return ERR_PTR(-ERROR),
+so use IS_ERR() to check it.
+
+Reported-by: Zeal Robot <zealci@zte.com.cn>
+Signed-off-by: Lv Ruyi <lv.ruyi@zte.com.cn>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/tegra/bpmp-debugfs.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/firmware/tegra/bpmp-debugfs.c b/drivers/firmware/tegra/bpmp-debugfs.c
+index 3e9fa4b54358..1ed881a567d5 100644
+--- a/drivers/firmware/tegra/bpmp-debugfs.c
++++ b/drivers/firmware/tegra/bpmp-debugfs.c
+@@ -465,7 +465,7 @@ static int bpmp_populate_debugfs_inband(struct tegra_bpmp *bpmp,
+                       mode |= attrs & DEBUGFS_S_IWUSR ? 0200 : 0;
+                       dentry = debugfs_create_file(name, mode, parent, bpmp,
+                                                    &bpmp_debug_fops);
+-                      if (!dentry) {
++                      if (IS_ERR(dentry)) {
+                               err = -ENOMEM;
+                               goto out;
+                       }
+@@ -716,7 +716,7 @@ static int bpmp_populate_dir(struct tegra_bpmp *bpmp, struct seqbuf *seqbuf,
+               if (t & DEBUGFS_S_ISDIR) {
+                       dentry = debugfs_create_dir(name, parent);
+-                      if (!dentry)
++                      if (IS_ERR(dentry))
+                               return -ENOMEM;
+                       err = bpmp_populate_dir(bpmp, seqbuf, dentry, depth+1);
+                       if (err < 0)
+@@ -729,7 +729,7 @@ static int bpmp_populate_dir(struct tegra_bpmp *bpmp, struct seqbuf *seqbuf,
+                       dentry = debugfs_create_file(name, mode,
+                                                    parent, bpmp,
+                                                    &debugfs_fops);
+-                      if (!dentry)
++                      if (IS_ERR(dentry))
+                               return -ENOMEM;
+               }
+       }
+@@ -779,11 +779,11 @@ int tegra_bpmp_init_debugfs(struct tegra_bpmp *bpmp)
+               return 0;
+       root = debugfs_create_dir("bpmp", NULL);
+-      if (!root)
++      if (IS_ERR(root))
+               return -ENOMEM;
+       bpmp->debugfs_mirror = debugfs_create_dir("debug", root);
+-      if (!bpmp->debugfs_mirror) {
++      if (IS_ERR(bpmp->debugfs_mirror)) {
+               err = -ENOMEM;
+               goto out;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/fpga-altera-pr-ip-fix-unsigned-comparison-with-less-.patch b/queue-5.15/fpga-altera-pr-ip-fix-unsigned-comparison-with-less-.patch
new file mode 100644 (file)
index 0000000..fdee584
--- /dev/null
@@ -0,0 +1,40 @@
+From 781c4e0335af63e410651b739cc00e05500e7e44 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jun 2022 16:05:19 +0200
+Subject: fpga: altera-pr-ip: fix unsigned comparison with less than zero
+
+From: Marco Pagani <marpagan@redhat.com>
+
+[ Upstream commit 2df84a757d87fd62869fc401119d429735377ec5 ]
+
+Fix the "comparison with less than zero" warning reported by
+cppcheck for the unsigned (size_t) parameter count of the
+alt_pr_fpga_write() function.
+
+Fixes: d201cc17a8a3 ("fpga pr ip: Core driver support for Altera Partial Reconfiguration IP")
+Reviewed-by: Tom Rix <trix@redhat.com>
+Acked-by: Xu Yilun <yilun.xu@intel.com>
+Signed-off-by: Marco Pagani <marpagan@redhat.com>
+Link: https://lore.kernel.org/r/20220609140520.42662-1-marpagan@redhat.com
+Signed-off-by: Xu Yilun <yilun.xu@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/fpga/altera-pr-ip-core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/fpga/altera-pr-ip-core.c b/drivers/fpga/altera-pr-ip-core.c
+index dfdf21ed34c4..c24b6fb2d7c3 100644
+--- a/drivers/fpga/altera-pr-ip-core.c
++++ b/drivers/fpga/altera-pr-ip-core.c
+@@ -108,7 +108,7 @@ static int alt_pr_fpga_write(struct fpga_manager *mgr, const char *buf,
+       u32 *buffer_32 = (u32 *)buf;
+       size_t i = 0;
+-      if (count <= 0)
++      if (!count)
+               return -EINVAL;
+       /* Write out the complete 32-bit chunks */
+-- 
+2.35.1
+
diff --git a/queue-5.15/fs-check-fmode_lseek-to-control-internal-pipe-splici.patch b/queue-5.15/fs-check-fmode_lseek-to-control-internal-pipe-splici.patch
new file mode 100644 (file)
index 0000000..c09119b
--- /dev/null
@@ -0,0 +1,58 @@
+From bfa0849ef5f85ba71e301c32d3cb7093164d571c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Jun 2022 15:06:58 +0200
+Subject: fs: check FMODE_LSEEK to control internal pipe splicing
+
+From: Jason A. Donenfeld <Jason@zx2c4.com>
+
+[ Upstream commit 97ef77c52b789ec1411d360ed99dca1efe4b2c81 ]
+
+The original direct splicing mechanism from Jens required the input to
+be a regular file because it was avoiding the special socket case. It
+also recognized blkdevs as being close enough to a regular file. But it
+forgot about chardevs, which behave the same way and work fine here.
+
+This is an okayish heuristic, but it doesn't totally work. For example,
+a few chardevs should be spliceable here. And a few regular files
+shouldn't. This patch fixes this by instead checking whether FMODE_LSEEK
+is set, which represents decently enough what we need rewinding for when
+splicing to internal pipes.
+
+Fixes: b92ce5589374 ("[PATCH] splice: add direct fd <-> fd splicing support")
+Cc: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/splice.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/fs/splice.c b/fs/splice.c
+index 5dbce4dcc1a7..3abcd7fbc9f2 100644
+--- a/fs/splice.c
++++ b/fs/splice.c
+@@ -814,17 +814,15 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
+ {
+       struct pipe_inode_info *pipe;
+       long ret, bytes;
+-      umode_t i_mode;
+       size_t len;
+       int i, flags, more;
+       /*
+-       * We require the input being a regular file, as we don't want to
+-       * randomly drop data for eg socket -> socket splicing. Use the
+-       * piped splicing for that!
++       * We require the input to be seekable, as we don't want to randomly
++       * drop data for eg socket -> socket splicing. Use the piped splicing
++       * for that!
+        */
+-      i_mode = file_inode(in)->i_mode;
+-      if (unlikely(!S_ISREG(i_mode) && !S_ISBLK(i_mode)))
++      if (unlikely(!(in->f_mode & FMODE_LSEEK)))
+               return -EINVAL;
+       /*
+-- 
+2.35.1
+
diff --git a/queue-5.15/fuse-remove-the-control-interface-for-virtio-fs.patch b/queue-5.15/fuse-remove-the-control-interface-for-virtio-fs.patch
new file mode 100644 (file)
index 0000000..aa31ecc
--- /dev/null
@@ -0,0 +1,50 @@
+From 04d70ab53685b6b46106060fa0234ffc5d07f50e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 16:50:12 +0800
+Subject: fuse: Remove the control interface for virtio-fs
+
+From: Xie Yongji <xieyongji@bytedance.com>
+
+[ Upstream commit c64797809a64c73497082aa05e401a062ec1af34 ]
+
+The commit 15c8e72e88e0 ("fuse: allow skipping control interface and forced
+unmount") tries to remove the control interface for virtio-fs since it does
+not support aborting requests which are being processed. But it doesn't
+work now.
+
+This patch fixes it by skipping creating the control interface if
+fuse_conn->no_control is set.
+
+Fixes: 15c8e72e88e0 ("fuse: allow skipping control interface and forced unmount")
+Signed-off-by: Xie Yongji <xieyongji@bytedance.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/fuse/control.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/fs/fuse/control.c b/fs/fuse/control.c
+index 000d2e5627e9..79f01d09c78c 100644
+--- a/fs/fuse/control.c
++++ b/fs/fuse/control.c
+@@ -275,7 +275,7 @@ int fuse_ctl_add_conn(struct fuse_conn *fc)
+       struct dentry *parent;
+       char name[32];
+-      if (!fuse_control_sb)
++      if (!fuse_control_sb || fc->no_control)
+               return 0;
+       parent = fuse_control_sb->s_root;
+@@ -313,7 +313,7 @@ void fuse_ctl_remove_conn(struct fuse_conn *fc)
+ {
+       int i;
+-      if (!fuse_control_sb)
++      if (!fuse_control_sb || fc->no_control)
+               return;
+       for (i = fc->ctl_ndents - 1; i >= 0; i--) {
+-- 
+2.35.1
+
diff --git a/queue-5.15/genelf-use-have_libcrypto_support-not-the-never-defi.patch b/queue-5.15/genelf-use-have_libcrypto_support-not-the-never-defi.patch
new file mode 100644 (file)
index 0000000..174a4bf
--- /dev/null
@@ -0,0 +1,59 @@
+From 884cd207bc04b02839c87f62c532aec02d1f2ab6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Aug 2022 15:13:22 -0300
+Subject: genelf: Use HAVE_LIBCRYPTO_SUPPORT, not the never defined
+ HAVE_LIBCRYPTO
+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 91cea6be90e436c55cde8770a15e4dac9d3032d0 ]
+
+When genelf was introduced it tested for HAVE_LIBCRYPTO not
+HAVE_LIBCRYPTO_SUPPORT, which is the define the feature test for openssl
+defines, fix it.
+
+This also adds disables the deprecation warning, someone has to fix this
+to build with openssl 3.0 before the warning becomes a hard error.
+
+Fixes: 9b07e27f88b9cd78 ("perf inject: Add jitdump mmap injection support")
+Reported-by: 谭梓煊 <tanzixuan.me@gmail.com>
+Cc: Alexei Starovoitov <ast@kernel.org>
+Cc: Andrii Nakryiko <andrii@kernel.org>
+Cc: Daniel Borkmann <daniel@iogearbox.net>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: John Fastabend <john.fastabend@gmail.com>
+Cc: KP Singh <kpsingh@kernel.org>
+Cc: Martin KaFai Lau <kafai@fb.com>
+Cc: Nick Terrell <terrelln@fb.com>
+Cc: Song Liu <songliubraving@fb.com>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lore.kernel.org/lkml/YulpPqXSOG0Q4J1o@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/genelf.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/tools/perf/util/genelf.c b/tools/perf/util/genelf.c
+index aed49806a09b..953338b9e887 100644
+--- a/tools/perf/util/genelf.c
++++ b/tools/perf/util/genelf.c
+@@ -30,7 +30,11 @@
+ #define BUILD_ID_URANDOM /* different uuid for each run */
+-#ifdef HAVE_LIBCRYPTO
++// FIXME, remove this and fix the deprecation warnings before its removed and
++// We'll break for good here...
++#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
++
++#ifdef HAVE_LIBCRYPTO_SUPPORT
+ #define BUILD_ID_MD5
+ #undef BUILD_ID_SHA   /* does not seem to work well when linked with Java */
+-- 
+2.35.1
+
diff --git a/queue-5.15/genirq-don-t-return-error-on-missing-optional-irq_re.patch b/queue-5.15/genirq-don-t-return-error-on-missing-optional-irq_re.patch
new file mode 100644 (file)
index 0000000..afa85d9
--- /dev/null
@@ -0,0 +1,42 @@
+From 882fd6957ac45df205b3ea9ae082b7907dcde54b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 May 2022 18:05:44 +0200
+Subject: genirq: Don't return error on missing optional
+ irq_request_resources()
+
+From: Antonio Borneo <antonio.borneo@foss.st.com>
+
+[ Upstream commit 95001b756467ecc9f5973eb5e74e97699d9bbdf1 ]
+
+Function irq_chip::irq_request_resources() is reported as optional
+in the declaration of struct irq_chip.
+If the parent irq_chip does not implement it, we should ignore it
+and return.
+
+Don't return error if the functions is missing.
+
+Signed-off-by: Antonio Borneo <antonio.borneo@foss.st.com>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20220512160544.13561-1-antonio.borneo@foss.st.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/irq/chip.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
+index a98bcfc4be7b..f3920374f71c 100644
+--- a/kernel/irq/chip.c
++++ b/kernel/irq/chip.c
+@@ -1516,7 +1516,8 @@ int irq_chip_request_resources_parent(struct irq_data *data)
+       if (data->chip->irq_request_resources)
+               return data->chip->irq_request_resources(data);
+-      return -ENOSYS;
++      /* no error on missing optional irq_chip::irq_request_resources */
++      return 0;
+ }
+ EXPORT_SYMBOL_GPL(irq_chip_request_resources_parent);
+-- 
+2.35.1
+
diff --git a/queue-5.15/genirq-generic_irq_ipi-depends-on-smp.patch b/queue-5.15/genirq-generic_irq_ipi-depends-on-smp.patch
new file mode 100644 (file)
index 0000000..6d9880c
--- /dev/null
@@ -0,0 +1,51 @@
+From b2a3bfc5897b5cfab8de7381fb7fc74148ed55f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 15:00:50 -0500
+Subject: genirq: GENERIC_IRQ_IPI depends on SMP
+
+From: Samuel Holland <samuel@sholland.org>
+
+[ Upstream commit 0f5209fee90b4544c58b4278d944425292789967 ]
+
+The generic IPI code depends on the IRQ affinity mask being allocated
+and initialized. This will not be the case if SMP is disabled. Fix up
+the remaining driver that selected GENERIC_IRQ_IPI in a non-SMP config.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Samuel Holland <samuel@sholland.org>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20220701200056.46555-3-samuel@sholland.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/irqchip/Kconfig | 2 +-
+ kernel/irq/Kconfig      | 1 +
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
+index 8f9c52873338..ae1b9f59abc5 100644
+--- a/drivers/irqchip/Kconfig
++++ b/drivers/irqchip/Kconfig
+@@ -171,7 +171,7 @@ config MADERA_IRQ
+ config IRQ_MIPS_CPU
+       bool
+       select GENERIC_IRQ_CHIP
+-      select GENERIC_IRQ_IPI if SYS_SUPPORTS_MULTITHREADING
++      select GENERIC_IRQ_IPI if SMP && SYS_SUPPORTS_MULTITHREADING
+       select IRQ_DOMAIN
+       select GENERIC_IRQ_EFFECTIVE_AFF_MASK
+diff --git a/kernel/irq/Kconfig b/kernel/irq/Kconfig
+index fbc54c2a7f23..00d58588ea95 100644
+--- a/kernel/irq/Kconfig
++++ b/kernel/irq/Kconfig
+@@ -82,6 +82,7 @@ config IRQ_FASTEOI_HIERARCHY_HANDLERS
+ # Generic IRQ IPI support
+ config GENERIC_IRQ_IPI
+       bool
++      depends on SMP
+       select IRQ_DOMAIN_HIERARCHY
+ # Generic MSI interrupt support
+-- 
+2.35.1
+
diff --git a/queue-5.15/gpio-gpiolib-of-fix-refcount-bugs-in-of_mm_gpiochip_.patch b/queue-5.15/gpio-gpiolib-of-fix-refcount-bugs-in-of_mm_gpiochip_.patch
new file mode 100644 (file)
index 0000000..d22e153
--- /dev/null
@@ -0,0 +1,53 @@
+From 86beae45687f5a62465db0b700cf856cb820e248 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Jul 2022 20:52:38 +0800
+Subject: gpio: gpiolib-of: Fix refcount bugs in of_mm_gpiochip_add_data()
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 5d07a692f9562f9c06e62cce369e9dd108173a0f ]
+
+We should use of_node_get() when a new reference of device_node
+is created. It is noted that the old reference stored in
+'mm_gc->gc.of_node' should also be decreased.
+
+This patch is based on the fact that there is a call site in function
+'qe_add_gpiochips()' of src file 'drivers\soc\fsl\qe\gpio.c'. In this
+function, of_mm_gpiochip_add_data() is contained in an iteration of
+for_each_compatible_node() which will automatically increase and
+decrease the refcount. So we need additional of_node_get() for the
+reference escape in of_mm_gpiochip_add_data().
+
+Fixes: a19e3da5bc5f ("of/gpio: Kill of_gpio_chip and add members directly to gpio_chip")
+Signed-off-by: Liang He <windhl@126.com>
+Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpiolib-of.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
+index 66e434f59f60..7a96eb626a08 100644
+--- a/drivers/gpio/gpiolib-of.c
++++ b/drivers/gpio/gpiolib-of.c
+@@ -863,7 +863,8 @@ int of_mm_gpiochip_add_data(struct device_node *np,
+       if (mm_gc->save_regs)
+               mm_gc->save_regs(mm_gc);
+-      mm_gc->gc.of_node = np;
++      of_node_put(mm_gc->gc.of_node);
++      mm_gc->gc.of_node = of_node_get(np);
+       ret = gpiochip_add_data(gc, data);
+       if (ret)
+@@ -871,6 +872,7 @@ int of_mm_gpiochip_add_data(struct device_node *np,
+       return 0;
+ err2:
++      of_node_put(np);
+       iounmap(mm_gc->regs);
+ err1:
+       kfree(gc->label);
+-- 
+2.35.1
+
diff --git a/queue-5.15/hid-alps-declare-u1_unicorn_legacy-support.patch b/queue-5.15/hid-alps-declare-u1_unicorn_legacy-support.patch
new file mode 100644 (file)
index 0000000..b9ff2d4
--- /dev/null
@@ -0,0 +1,36 @@
+From e3a6ecffd0b1debdb9b66cf927d1f3be877d1725 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 17:53:24 +0300
+Subject: HID: alps: Declare U1_UNICORN_LEGACY support
+
+From: Artem Borisov <dedsa2002@gmail.com>
+
+[ Upstream commit 1117d182c5d72abd7eb8b7d5e7b8c3373181c3ab ]
+
+U1_UNICORN_LEGACY id was added to the driver, but was not declared
+in the device id table, making it impossible to use.
+
+Fixes: 640e403 ("HID: alps: Add AUI1657 device ID")
+Signed-off-by: Artem Borisov <dedsa2002@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-alps.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/hid/hid-alps.c b/drivers/hid/hid-alps.c
+index 2b986d0dbde4..db146d0f7937 100644
+--- a/drivers/hid/hid-alps.c
++++ b/drivers/hid/hid-alps.c
+@@ -830,6 +830,8 @@ static const struct hid_device_id alps_id[] = {
+               USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1_DUAL) },
+       { HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY,
+               USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1) },
++      { HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY,
++              USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1_UNICORN_LEGACY) },
+       { HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY,
+               USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_T4_BTNLESS) },
+       { }
+-- 
+2.35.1
+
diff --git a/queue-5.15/hid-amd_sfh-add-null-check-for-hid-device.patch b/queue-5.15/hid-amd_sfh-add-null-check-for-hid-device.patch
new file mode 100644 (file)
index 0000000..79093a9
--- /dev/null
@@ -0,0 +1,47 @@
+From dafee4f32f35b2e4281a7467db991c181d84372f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Jul 2022 23:48:26 +0530
+Subject: HID: amd_sfh: Add NULL check for hid device
+
+From: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
+
+[ Upstream commit 06aa2a43c307cf4096f422dcb575e5d2913e528f ]
+
+On removal of hid device during SFH set report may cause NULL pointer
+exception. Hence add NULL check for hid device before accessing.
+
+Fixes: 4b2c53d93a4b ("SFH:Transport Driver to add support of AMD Sensor Fusion Hub (SFH)")
+Signed-off-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/amd-sfh-hid/amd_sfh_hid.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_hid.c b/drivers/hid/amd-sfh-hid/amd_sfh_hid.c
+index a4bda2ac713e..3b0615c6aecf 100644
+--- a/drivers/hid/amd-sfh-hid/amd_sfh_hid.c
++++ b/drivers/hid/amd-sfh-hid/amd_sfh_hid.c
+@@ -98,11 +98,15 @@ static int amdtp_wait_for_response(struct hid_device *hid)
+ void amdtp_hid_wakeup(struct hid_device *hid)
+ {
+-      struct amdtp_hid_data *hid_data = hid->driver_data;
+-      struct amdtp_cl_data *cli_data = hid_data->cli_data;
++      struct amdtp_hid_data *hid_data;
++      struct amdtp_cl_data *cli_data;
+-      cli_data->request_done[cli_data->cur_hid_dev] = true;
+-      wake_up_interruptible(&hid_data->hid_wait);
++      if (hid) {
++              hid_data = hid->driver_data;
++              cli_data = hid_data->cli_data;
++              cli_data->request_done[cli_data->cur_hid_dev] = true;
++              wake_up_interruptible(&hid_data->hid_wait);
++      }
+ }
+ static struct hid_ll_driver amdtp_hid_ll_driver = {
+-- 
+2.35.1
+
diff --git a/queue-5.15/hid-amd_sfh-don-t-show-client-init-failed-as-error-w.patch b/queue-5.15/hid-amd_sfh-don-t-show-client-init-failed-as-error-w.patch
new file mode 100644 (file)
index 0000000..d6d1394
--- /dev/null
@@ -0,0 +1,45 @@
+From 0a5dcf474bb3874380b293fcc2e67abad4ab4cf0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 May 2022 13:18:48 -0500
+Subject: HID: amd_sfh: Don't show client init failed as error when discovery
+ fails
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+[ Upstream commit e51d8d3ea3d773334d2c047c8d1623dba66f592a ]
+
+When sensor discovery fails, this means that the system doesn't have
+any sensors connected and a user should only be notified at most one time.
+A message is already displayed at WARN level of "failed to discover,
+sensors not enabled".  It's pointless to show that the client init failed
+at ERR level for the same condition.
+
+Check the return code and don't display this message in those conditions.
+
+Fixes: b5d7f43e97da ("HID: amd_sfh: Add support for sensor discovery")
+Reported-by: David Chang <David.Chang@amd.com>
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Acked-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/amd-sfh-hid/amd_sfh_pcie.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
+index ae8f1f2536e9..13a4db42cd7a 100644
+--- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
++++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
+@@ -323,7 +323,8 @@ static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
+       rc = amd_sfh_hid_client_init(privdata);
+       if (rc) {
+               amd_sfh_clear_intr(privdata);
+-              dev_err(&pdev->dev, "amd_sfh_hid_client_init failed\n");
++              if (rc != -EOPNOTSUPP)
++                      dev_err(&pdev->dev, "amd_sfh_hid_client_init failed\n");
+               return rc;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/hid-amd_sfh-handle-condition-of-no-sensors.patch b/queue-5.15/hid-amd_sfh-handle-condition-of-no-sensors.patch
new file mode 100644 (file)
index 0000000..44c97d0
--- /dev/null
@@ -0,0 +1,36 @@
+From 1c4e1d33d1281b59cbf8ab68b5aa81c7d2afeaf4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Jul 2022 11:40:33 +0530
+Subject: HID: amd_sfh: Handle condition of "no sensors"
+
+From: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
+
+[ Upstream commit 5d4d0f15657535f6a122ab26d47230b5c2b944af ]
+
+Add a check for num_hid_devices to handle special case the situation
+of "no sensors".
+
+Fixes: 4b2c53d93a4b ("SFH:Transport Driver to add support of AMD Sensor Fusion Hub (SFH)")
+Signed-off-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/amd-sfh-hid/amd_sfh_client.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_client.c b/drivers/hid/amd-sfh-hid/amd_sfh_client.c
+index 6284db50ec9b..ab149b80f86c 100644
+--- a/drivers/hid/amd-sfh-hid/amd_sfh_client.c
++++ b/drivers/hid/amd-sfh-hid/amd_sfh_client.c
+@@ -154,6 +154,8 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata)
+       dev = &privdata->pdev->dev;
+       cl_data->num_hid_devices = amd_mp2_get_sensor_num(privdata, &cl_data->sensor_idx[0]);
++      if (cl_data->num_hid_devices == 0)
++              return -ENODEV;
+       INIT_DELAYED_WORK(&cl_data->work, amd_sfh_work);
+       INIT_DELAYED_WORK(&cl_data->work_buffer, amd_sfh_work_buffer);
+-- 
+2.35.1
+
diff --git a/queue-5.15/hid-cp2112-prevent-a-buffer-overflow-in-cp2112_xfer.patch b/queue-5.15/hid-cp2112-prevent-a-buffer-overflow-in-cp2112_xfer.patch
new file mode 100644 (file)
index 0000000..1c2a6ff
--- /dev/null
@@ -0,0 +1,47 @@
+From 0734b51a07237d8dc71756af54555f6e18eb3fed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jun 2022 05:26:09 -0700
+Subject: HID: cp2112: prevent a buffer overflow in cp2112_xfer()
+
+From: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
+
+[ Upstream commit 381583845d19cb4bd21c8193449385f3fefa9caf ]
+
+Smatch warnings:
+drivers/hid/hid-cp2112.c:793 cp2112_xfer() error: __memcpy()
+'data->block[1]' too small (33 vs 255)
+drivers/hid/hid-cp2112.c:793 cp2112_xfer() error: __memcpy() 'buf' too
+small (64 vs 255)
+
+The 'read_length' variable is provided by 'data->block[0]' which comes
+from user and it(read_length) can take a value between 0-255. Add an
+upper bound to 'read_length' variable to prevent a buffer overflow in
+memcpy().
+
+Fixes: 542134c0375b ("HID: cp2112: Fix I2C_BLOCK_DATA transactions")
+Signed-off-by: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-cp2112.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/hid/hid-cp2112.c b/drivers/hid/hid-cp2112.c
+index 477baa30889c..172f20e88c6c 100644
+--- a/drivers/hid/hid-cp2112.c
++++ b/drivers/hid/hid-cp2112.c
+@@ -788,6 +788,11 @@ static int cp2112_xfer(struct i2c_adapter *adap, u16 addr,
+               data->word = le16_to_cpup((__le16 *)buf);
+               break;
+       case I2C_SMBUS_I2C_BLOCK_DATA:
++              if (read_length > I2C_SMBUS_BLOCK_MAX) {
++                      ret = -EINVAL;
++                      goto power_normal;
++              }
++
+               memcpy(data->block + 1, buf, read_length);
+               break;
+       case I2C_SMBUS_BLOCK_DATA:
+-- 
+2.35.1
+
diff --git a/queue-5.15/hid-mcp2221-prevent-a-buffer-overflow-in-mcp_smbus_w.patch b/queue-5.15/hid-mcp2221-prevent-a-buffer-overflow-in-mcp_smbus_w.patch
new file mode 100644 (file)
index 0000000..1d56ca6
--- /dev/null
@@ -0,0 +1,44 @@
+From d899694d0a97c19a503683f07a82374df336d91a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jun 2022 09:28:24 -0700
+Subject: HID: mcp2221: prevent a buffer overflow in mcp_smbus_write()
+
+From: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
+
+[ Upstream commit 62ac2473553a00229e67bdf3cb023b62cf7f5a9a ]
+
+Smatch Warning:
+drivers/hid/hid-mcp2221.c:388 mcp_smbus_write() error: __memcpy()
+'&mcp->txbuf[5]' too small (59 vs 255)
+drivers/hid/hid-mcp2221.c:388 mcp_smbus_write() error: __memcpy() 'buf'
+too small (34 vs 255)
+
+The 'len' variable can take a value between 0-255 as it can come from
+data->block[0] and it is user data. So add an bound check to prevent a
+buffer overflow in memcpy().
+
+Fixes: 67a95c21463d ("HID: mcp2221: add usb to i2c-smbus host bridge")
+Signed-off-by: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-mcp2221.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/hid/hid-mcp2221.c b/drivers/hid/hid-mcp2221.c
+index 4211b9839209..de52e9f7bb8c 100644
+--- a/drivers/hid/hid-mcp2221.c
++++ b/drivers/hid/hid-mcp2221.c
+@@ -385,6 +385,9 @@ static int mcp_smbus_write(struct mcp2221 *mcp, u16 addr,
+               data_len = 7;
+               break;
+       default:
++              if (len > I2C_SMBUS_BLOCK_MAX)
++                      return -EINVAL;
++
+               memcpy(&mcp->txbuf[5], buf, len);
+               data_len = len + 5;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/hinic-use-the-bitmap-api-when-applicable.patch b/queue-5.15/hinic-use-the-bitmap-api-when-applicable.patch
new file mode 100644 (file)
index 0000000..edd4021
--- /dev/null
@@ -0,0 +1,56 @@
+From 65eb6029c8976056150dc6931fb1e3acd97a1809 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 26 Jun 2022 18:27:45 +0200
+Subject: hinic: Use the bitmap API when applicable
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 7c2c57263af41cfd8b5022274e6801542831bb69 ]
+
+'vlan_bitmap' is a bitmap and is used as such. So allocate it with
+devm_bitmap_zalloc() and its explicit bit size (i.e. VLAN_N_VID).
+
+This avoids the need of the VLAN_BITMAP_SIZE macro which:
+   - needlessly has a 'nic_dev' parameter
+   - should be "long" (and not byte) aligned, so that the bitmap semantic
+     is respected
+
+This is in fact not an issue because VLAN_N_VID is 4096 at the time
+being, but devm_bitmap_zalloc() is less verbose and easier to understand.
+
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://lore.kernel.org/r/6ff7b7d21414240794a77dc2456914412718a145.1656260842.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/huawei/hinic/hinic_main.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_main.c b/drivers/net/ethernet/huawei/hinic/hinic_main.c
+index f8aa80ec201b..bece6a12368d 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_main.c
++++ b/drivers/net/ethernet/huawei/hinic/hinic_main.c
+@@ -62,8 +62,6 @@ MODULE_PARM_DESC(rx_weight, "Number Rx packets for NAPI budget (default=64)");
+ #define HINIC_LRO_RX_TIMER_DEFAULT    16
+-#define VLAN_BITMAP_SIZE(nic_dev)       (ALIGN(VLAN_N_VID, 8) / 8)
+-
+ #define work_to_rx_mode_work(work)      \
+               container_of(work, struct hinic_rx_mode_work, work)
+@@ -1241,9 +1239,8 @@ static int nic_dev_init(struct pci_dev *pdev)
+       u64_stats_init(&tx_stats->syncp);
+       u64_stats_init(&rx_stats->syncp);
+-      nic_dev->vlan_bitmap = devm_kzalloc(&pdev->dev,
+-                                          VLAN_BITMAP_SIZE(nic_dev),
+-                                          GFP_KERNEL);
++      nic_dev->vlan_bitmap = devm_bitmap_zalloc(&pdev->dev, VLAN_N_VID,
++                                                GFP_KERNEL);
+       if (!nic_dev->vlan_bitmap) {
+               err = -ENOMEM;
+               goto err_vlan_bitmap;
+-- 
+2.35.1
+
diff --git a/queue-5.15/hwmon-dell-smm-add-dell-xps-13-7390-to-fan-control-w.patch b/queue-5.15/hwmon-dell-smm-add-dell-xps-13-7390-to-fan-control-w.patch
new file mode 100644 (file)
index 0000000..95b160c
--- /dev/null
@@ -0,0 +1,51 @@
+From f8d7840f81eb134f657f6bfc92e4520c9ae52853 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jun 2022 06:18:06 +0200
+Subject: hwmon: (dell-smm) Add Dell XPS 13 7390 to fan control whitelist
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Armin Wolf <W_Armin@gmx.de>
+
+[ Upstream commit 385e5f57053ff293282fea84c1c27186d53f66e1 ]
+
+A user reported that the program dell-bios-fan-control
+worked on his Dell XPS 13 7390 to switch off automatic
+fan control.
+Since it uses the same mechanism as the dell_smm_hwmon
+module, add this model to the fan control whitelist.
+
+Compile-tested only.
+
+Signed-off-by: Armin Wolf <W_Armin@gmx.de>
+Acked-by: Pali Rohár <pali@kernel.org>
+Link: https://lore.kernel.org/r/20220612041806.11367-1-W_Armin@gmx.de
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/dell-smm-hwmon.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/hwmon/dell-smm-hwmon.c b/drivers/hwmon/dell-smm-hwmon.c
+index 9cb1c3588038..597cbb4391bd 100644
+--- a/drivers/hwmon/dell-smm-hwmon.c
++++ b/drivers/hwmon/dell-smm-hwmon.c
+@@ -1198,6 +1198,14 @@ static const struct dmi_system_id i8k_whitelist_fan_control[] __initconst = {
+               },
+               .driver_data = (void *)&i8k_fan_control_data[I8K_FAN_34A3_35A3],
+       },
++      {
++              .ident = "Dell XPS 13 7390",
++              .matches = {
++                      DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++                      DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "XPS 13 7390"),
++              },
++              .driver_data = (void *)&i8k_fan_control_data[I8K_FAN_34A3_35A3],
++      },
+       { }
+ };
+-- 
+2.35.1
+
diff --git a/queue-5.15/hwmon-drivetemp-add-module-alias.patch b/queue-5.15/hwmon-drivetemp-add-module-alias.patch
new file mode 100644 (file)
index 0000000..0930fdd
--- /dev/null
@@ -0,0 +1,33 @@
+From c2b1b1670dc44c727aadc7f52e59a18203ec851f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Jul 2022 23:46:24 +0200
+Subject: hwmon: (drivetemp) Add module alias
+
+From: Linus Walleij <linus.walleij@linaro.org>
+
+[ Upstream commit 5918036cfa8ded7aa8094db70295011ce2275447 ]
+
+Adding a MODULE_ALIAS() to drivetemp will make the driver easier
+for modprobe to autoprobe.
+
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Link: https://lore.kernel.org/r/20220712214624.1845158-1-linus.walleij@linaro.org
+Fixes: 5b46903d8bf3 ("hwmon: Driver for disk and solid state drives with temperature sensors")
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/drivetemp.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/hwmon/drivetemp.c b/drivers/hwmon/drivetemp.c
+index 1eb37106a220..5bac2b0fc7bb 100644
+--- a/drivers/hwmon/drivetemp.c
++++ b/drivers/hwmon/drivetemp.c
+@@ -621,3 +621,4 @@ module_exit(drivetemp_exit);
+ MODULE_AUTHOR("Guenter Roeck <linus@roeck-us.net>");
+ MODULE_DESCRIPTION("Hard drive temperature monitor");
+ MODULE_LICENSE("GPL");
++MODULE_ALIAS("platform:drivetemp");
+-- 
+2.35.1
+
diff --git a/queue-5.15/hwmon-sht15-fix-wrong-assumptions-in-device-remove-c.patch b/queue-5.15/hwmon-sht15-fix-wrong-assumptions-in-device-remove-c.patch
new file mode 100644 (file)
index 0000000..6e3c149
--- /dev/null
@@ -0,0 +1,78 @@
+From d309b46f1a42bb81f3c0c9500b668b57813be662 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Jul 2022 21:43:44 +0200
+Subject: hwmon: (sht15) Fix wrong assumptions in device remove callback
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 7d4edccc9bbfe1dcdff641343f7b0c6763fbe774 ]
+
+Taking a lock at the beginning of .remove() doesn't prevent new readers.
+With the existing approach it can happen, that a read occurs just when
+the lock was taken blocking the reader until the lock is released at the
+end of the remove callback which then accessed *data that is already
+freed then.
+
+To actually fix this problem the hwmon core needs some adaption. Until
+this is implemented take the optimistic approach of assuming that all
+readers are gone after hwmon_device_unregister() and
+sysfs_remove_group() as most other drivers do. (And once the core
+implements that, taking the lock would deadlock.)
+
+So drop the lock, move the reset to after device unregistration to keep
+the device in a workable state until it's deregistered. Also add a error
+message in case the reset fails and return 0 anyhow. (Returning an error
+code, doesn't stop the platform device unregistration and only results
+in a little helpful error message before the devm cleanup handlers are
+called.)
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Link: https://lore.kernel.org/r/20220725194344.150098-1-u.kleine-koenig@pengutronix.de
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/sht15.c | 17 ++++++-----------
+ 1 file changed, 6 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c
+index 7f4a63959730..ae4d14257a11 100644
+--- a/drivers/hwmon/sht15.c
++++ b/drivers/hwmon/sht15.c
+@@ -1020,25 +1020,20 @@ static int sht15_probe(struct platform_device *pdev)
+ static int sht15_remove(struct platform_device *pdev)
+ {
+       struct sht15_data *data = platform_get_drvdata(pdev);
++      int ret;
+-      /*
+-       * Make sure any reads from the device are done and
+-       * prevent new ones beginning
+-       */
+-      mutex_lock(&data->read_lock);
+-      if (sht15_soft_reset(data)) {
+-              mutex_unlock(&data->read_lock);
+-              return -EFAULT;
+-      }
+       hwmon_device_unregister(data->hwmon_dev);
+       sysfs_remove_group(&pdev->dev.kobj, &sht15_attr_group);
++
++      ret = sht15_soft_reset(data);
++      if (ret)
++              dev_err(&pdev->dev, "Failed to reset device (%pe)\n", ERR_PTR(ret));
++
+       if (!IS_ERR(data->reg)) {
+               regulator_unregister_notifier(data->reg, &data->nb);
+               regulator_disable(data->reg);
+       }
+-      mutex_unlock(&data->read_lock);
+-
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/i2c-cadence-support-pec-for-smbus-block-read.patch b/queue-5.15/i2c-cadence-support-pec-for-smbus-block-read.patch
new file mode 100644 (file)
index 0000000..76a2128
--- /dev/null
@@ -0,0 +1,77 @@
+From 83b30dcb07f51d78636a3459d346676efd15b443 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 Jul 2022 16:52:44 +0200
+Subject: i2c: cadence: Support PEC for SMBus block read
+
+From: Lars-Peter Clausen <lars@metafoo.de>
+
+[ Upstream commit 9fdf6d97f03035ad5298e2d1635036c74c2090ed ]
+
+SMBus packet error checking (PEC) is implemented by appending one
+additional byte of checksum data at the end of the message. This provides
+additional protection and allows to detect data corruption on the I2C bus.
+
+SMBus block reads support variable length reads. The first byte in the read
+message is the number of available data bytes.
+
+The combination of PEC and block read is currently not supported by the
+Cadence I2C driver.
+ * When PEC is enabled the maximum transfer length for block reads
+   increases from 33 to 34 bytes.
+ * The I2C core smbus emulation layer relies on the driver updating the
+   `i2c_msg` `len` field with the number of received bytes. The updated
+   length is used when checking the PEC.
+
+Add support to the Cadence I2C driver for handling SMBus block reads with
+PEC. To determine the maximum transfer length uses the initial `len` value
+of the `i2c_msg`. When PEC is enabled this will be 2, when it is disabled
+it will be 1.
+
+Once a read transfer is done also increment the `len` field by the amount
+of received data bytes.
+
+This change has been tested with a UCM90320 PMBus power monitor, which
+requires block reads to access certain data fields, but also has PEC
+enabled by default.
+
+Fixes: df8eb5691c48 ("i2c: Add driver for Cadence I2C controller")
+Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
+Tested-by: Shubhrajyoti Datta <Shubhrajyoti.datta@amd.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-cadence.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c
+index 630cfa4ddd46..33f5588a50c0 100644
+--- a/drivers/i2c/busses/i2c-cadence.c
++++ b/drivers/i2c/busses/i2c-cadence.c
+@@ -573,8 +573,13 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id)
+       ctrl_reg = cdns_i2c_readreg(CDNS_I2C_CR_OFFSET);
+       ctrl_reg |= CDNS_I2C_CR_RW | CDNS_I2C_CR_CLR_FIFO;
++      /*
++       * Receive up to I2C_SMBUS_BLOCK_MAX data bytes, plus one message length
++       * byte, plus one checksum byte if PEC is enabled. p_msg->len will be 2 if
++       * PEC is enabled, otherwise 1.
++       */
+       if (id->p_msg->flags & I2C_M_RECV_LEN)
+-              id->recv_count = I2C_SMBUS_BLOCK_MAX + 1;
++              id->recv_count = I2C_SMBUS_BLOCK_MAX + id->p_msg->len;
+       id->curr_recv_count = id->recv_count;
+@@ -789,6 +794,9 @@ static int cdns_i2c_process_msg(struct cdns_i2c *id, struct i2c_msg *msg,
+       if (id->err_status & CDNS_I2C_IXR_ARB_LOST)
+               return -EAGAIN;
++      if (msg->flags & I2C_M_RECV_LEN)
++              msg->len += min_t(unsigned int, msg->buf[0], I2C_SMBUS_BLOCK_MAX);
++
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/i2c-fix-a-potential-use-after-free.patch b/queue-5.15/i2c-fix-a-potential-use-after-free.patch
new file mode 100644 (file)
index 0000000..fee9290
--- /dev/null
@@ -0,0 +1,40 @@
+From 54658411b5f0f5ec897964481b447a08c8a19709 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 Dec 2019 09:34:32 +0000
+Subject: i2c: Fix a potential use after free
+
+From: Xu Wang <vulab@iscas.ac.cn>
+
+[ Upstream commit e4c72c06c367758a14f227c847f9d623f1994ecf ]
+
+Free the adap structure only after we are done using it.
+This patch just moves the put_device() down a bit to avoid the
+use after free.
+
+Fixes: 611e12ea0f12 ("i2c: core: manage i2c bus device refcount in i2c_[get|put]_adapter")
+Signed-off-by: Xu Wang <vulab@iscas.ac.cn>
+[wsa: added comment to the code, added Fixes tag]
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/i2c-core-base.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
+index cfbef70e8ba7..8fb065caf30b 100644
+--- a/drivers/i2c/i2c-core-base.c
++++ b/drivers/i2c/i2c-core-base.c
+@@ -2464,8 +2464,9 @@ void i2c_put_adapter(struct i2c_adapter *adap)
+       if (!adap)
+               return;
+-      put_device(&adap->dev);
+       module_put(adap->owner);
++      /* Should be last, otherwise we risk use-after-free with 'adap' */
++      put_device(&adap->dev);
+ }
+ EXPORT_SYMBOL(i2c_put_adapter);
+-- 
+2.35.1
+
diff --git a/queue-5.15/i2c-mux-gpmux-add-of_node_put-when-breaking-out-of-l.patch b/queue-5.15/i2c-mux-gpmux-add-of_node_put-when-breaking-out-of-l.patch
new file mode 100644 (file)
index 0000000..19daad9
--- /dev/null
@@ -0,0 +1,37 @@
+From a0ba45763bfe5d8545b5f7ce4c89da4e778a03c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Jul 2022 09:24:01 +0800
+Subject: i2c: mux-gpmux: Add of_node_put() when breaking out of loop
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 6435319c34704994e19b0767f6a4e6f37439867b ]
+
+In i2c_mux_probe(), we should call of_node_put() when breaking out
+of for_each_child_of_node() which will automatically increase and
+decrease the refcount.
+
+Fixes: ac8498f0ce53 ("i2c: i2c-mux-gpmux: new driver")
+Signed-off-by: Liang He <windhl@126.com>
+Acked-by: Peter Rosin <peda@axentia.se>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/muxes/i2c-mux-gpmux.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/i2c/muxes/i2c-mux-gpmux.c b/drivers/i2c/muxes/i2c-mux-gpmux.c
+index d3acd8d66c32..33024acaac02 100644
+--- a/drivers/i2c/muxes/i2c-mux-gpmux.c
++++ b/drivers/i2c/muxes/i2c-mux-gpmux.c
+@@ -134,6 +134,7 @@ static int i2c_mux_probe(struct platform_device *pdev)
+       return 0;
+ err_children:
++      of_node_put(child);
+       i2c_mux_del_adapters(muxc);
+ err_parent:
+       i2c_put_adapter(parent);
+-- 
+2.35.1
+
diff --git a/queue-5.15/i2c-mxs-silence-a-clang-warning.patch b/queue-5.15/i2c-mxs-silence-a-clang-warning.patch
new file mode 100644 (file)
index 0000000..e57aef1
--- /dev/null
@@ -0,0 +1,39 @@
+From 08b79c2a7acede53d86c37ee6958c685f2e41c49 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 May 2022 22:09:14 -0300
+Subject: i2c: mxs: Silence a clang warning
+
+From: Fabio Estevam <festevam@gmail.com>
+
+[ Upstream commit 3d43273d7d1e1a5374d531e901d3c537b4c97bbf ]
+
+Change the of_device_get_match_data() cast to (uintptr_t)
+to silence the following clang warning:
+
+drivers/i2c/busses/i2c-mxs.c:802:18: warning: cast to smaller integer type 'enum mxs_i2c_devtype' from 'const void *' [-Wvoid-pointer-to-enum-cast]
+
+Reported-by: kernel test robot <lkp@intel.com>
+Fixes: c32abd8b5691 ("i2c: mxs: Remove unneeded platform_device_id")
+Signed-off-by: Fabio Estevam <festevam@gmail.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-mxs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c
+index 864a3f1bd4e1..68f67d084c63 100644
+--- a/drivers/i2c/busses/i2c-mxs.c
++++ b/drivers/i2c/busses/i2c-mxs.c
+@@ -799,7 +799,7 @@ static int mxs_i2c_probe(struct platform_device *pdev)
+       if (!i2c)
+               return -ENOMEM;
+-      i2c->dev_type = (enum mxs_i2c_devtype)of_device_get_match_data(&pdev->dev);
++      i2c->dev_type = (uintptr_t)of_device_get_match_data(&pdev->dev);
+       i2c->regs = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(i2c->regs))
+-- 
+2.35.1
+
diff --git a/queue-5.15/i2c-npcm-correct-slave-role-behavior.patch b/queue-5.15/i2c-npcm-correct-slave-role-behavior.patch
new file mode 100644 (file)
index 0000000..817d3f0
--- /dev/null
@@ -0,0 +1,55 @@
+From f79afc987a33c5452a4d7a509f4078e8619d2133 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 May 2022 11:23:39 +0800
+Subject: i2c: npcm: Correct slave role behavior
+
+From: Tali Perry <tali.perry1@gmail.com>
+
+[ Upstream commit d7aa1b149b8fc04d802879cf4662010aa4a42deb ]
+
+Correct the slave transaction logic to be compatible with the generic
+slave backend driver.
+
+Fixes: 56a1485b102e ("i2c: npcm7xx: Add Nuvoton NPCM I2C controller driver")
+Signed-off-by: Tali Perry <tali.perry1@gmail.com>
+Signed-off-by: Tyrone Ting <kfting@nuvoton.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-npcm7xx.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/i2c/busses/i2c-npcm7xx.c b/drivers/i2c/busses/i2c-npcm7xx.c
+index ab31e7fb4cc9..31e3d2c9d6bc 100644
+--- a/drivers/i2c/busses/i2c-npcm7xx.c
++++ b/drivers/i2c/busses/i2c-npcm7xx.c
+@@ -912,11 +912,15 @@ static int npcm_i2c_slave_get_wr_buf(struct npcm_i2c *bus)
+       for (i = 0; i < I2C_HW_FIFO_SIZE; i++) {
+               if (bus->slv_wr_size >= I2C_HW_FIFO_SIZE)
+                       break;
+-              i2c_slave_event(bus->slave, I2C_SLAVE_READ_REQUESTED, &value);
++              if (bus->state == I2C_SLAVE_MATCH) {
++                      i2c_slave_event(bus->slave, I2C_SLAVE_READ_REQUESTED, &value);
++                      bus->state = I2C_OPER_STARTED;
++              } else {
++                      i2c_slave_event(bus->slave, I2C_SLAVE_READ_PROCESSED, &value);
++              }
+               ind = (bus->slv_wr_ind + bus->slv_wr_size) % I2C_HW_FIFO_SIZE;
+               bus->slv_wr_buf[ind] = value;
+               bus->slv_wr_size++;
+-              i2c_slave_event(bus->slave, I2C_SLAVE_READ_PROCESSED, &value);
+       }
+       return I2C_HW_FIFO_SIZE - ret;
+ }
+@@ -964,7 +968,6 @@ static void npcm_i2c_slave_xmit(struct npcm_i2c *bus, u16 nwrite,
+       if (nwrite == 0)
+               return;
+-      bus->state = I2C_OPER_STARTED;
+       bus->operation = I2C_WRITE_OPER;
+       /* get the next buffer */
+-- 
+2.35.1
+
diff --git a/queue-5.15/i2c-npcm-remove-own-slave-addresses-2-10.patch b/queue-5.15/i2c-npcm-remove-own-slave-addresses-2-10.patch
new file mode 100644 (file)
index 0000000..4f2984a
--- /dev/null
@@ -0,0 +1,133 @@
+From 004bbcd8ba37fffdf181f2b3c53e6309951d4516 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 May 2022 11:23:38 +0800
+Subject: i2c: npcm: Remove own slave addresses 2:10
+
+From: Tali Perry <tali.perry1@gmail.com>
+
+[ Upstream commit 47d506d1a28fd10a9fb1f33df5622d88fae72095 ]
+
+NPCM can support up to 10 own slave addresses. In practice, only one
+address is actually being used. In order to access addresses 2 and above,
+need to switch register banks. The switch needs spinlock.
+To avoid using spinlock for this useless feature removed support of SA >=
+2. Also fix returned slave event enum.
+
+Remove some comment since the bank selection is not required. The bank
+selection is not required since the supported slave addresses are reduced.
+
+Fixes: 56a1485b102e ("i2c: npcm7xx: Add Nuvoton NPCM I2C controller driver")
+Signed-off-by: Tali Perry <tali.perry1@gmail.com>
+Signed-off-by: Tyrone Ting <kfting@nuvoton.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-npcm7xx.c | 41 +++++++++++++-------------------
+ 1 file changed, 16 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/i2c/busses/i2c-npcm7xx.c b/drivers/i2c/busses/i2c-npcm7xx.c
+index d9ac62c1ac25..ab31e7fb4cc9 100644
+--- a/drivers/i2c/busses/i2c-npcm7xx.c
++++ b/drivers/i2c/busses/i2c-npcm7xx.c
+@@ -123,11 +123,11 @@ enum i2c_addr {
+  * Since the addr regs are sprinkled all over the address space,
+  * use this array to get the address or each register.
+  */
+-#define I2C_NUM_OWN_ADDR 10
++#define I2C_NUM_OWN_ADDR 2
++#define I2C_NUM_OWN_ADDR_SUPPORTED 2
++
+ static const int npcm_i2caddr[I2C_NUM_OWN_ADDR] = {
+-      NPCM_I2CADDR1, NPCM_I2CADDR2, NPCM_I2CADDR3, NPCM_I2CADDR4,
+-      NPCM_I2CADDR5, NPCM_I2CADDR6, NPCM_I2CADDR7, NPCM_I2CADDR8,
+-      NPCM_I2CADDR9, NPCM_I2CADDR10,
++      NPCM_I2CADDR1, NPCM_I2CADDR2,
+ };
+ #endif
+@@ -391,14 +391,10 @@ static void npcm_i2c_disable(struct npcm_i2c *bus)
+ #if IS_ENABLED(CONFIG_I2C_SLAVE)
+       int i;
+-      /* select bank 0 for I2C addresses */
+-      npcm_i2c_select_bank(bus, I2C_BANK_0);
+-
+       /* Slave addresses removal */
+-      for (i = I2C_SLAVE_ADDR1; i < I2C_NUM_OWN_ADDR; i++)
++      for (i = I2C_SLAVE_ADDR1; i < I2C_NUM_OWN_ADDR_SUPPORTED; i++)
+               iowrite8(0, bus->reg + npcm_i2caddr[i]);
+-      npcm_i2c_select_bank(bus, I2C_BANK_1);
+ #endif
+       /* Disable module */
+       i2cctl2 = ioread8(bus->reg + NPCM_I2CCTL2);
+@@ -603,8 +599,7 @@ static int npcm_i2c_slave_enable(struct npcm_i2c *bus, enum i2c_addr addr_type,
+                       i2cctl1 &= ~NPCM_I2CCTL1_GCMEN;
+               iowrite8(i2cctl1, bus->reg + NPCM_I2CCTL1);
+               return 0;
+-      }
+-      if (addr_type == I2C_ARP_ADDR) {
++      } else if (addr_type == I2C_ARP_ADDR) {
+               i2cctl3 = ioread8(bus->reg + NPCM_I2CCTL3);
+               if (enable)
+                       i2cctl3 |= I2CCTL3_ARPMEN;
+@@ -613,16 +608,16 @@ static int npcm_i2c_slave_enable(struct npcm_i2c *bus, enum i2c_addr addr_type,
+               iowrite8(i2cctl3, bus->reg + NPCM_I2CCTL3);
+               return 0;
+       }
++      if (addr_type > I2C_SLAVE_ADDR2 && addr_type <= I2C_SLAVE_ADDR10)
++              dev_err(bus->dev, "try to enable more than 2 SA not supported\n");
++
+       if (addr_type >= I2C_ARP_ADDR)
+               return -EFAULT;
+-      /* select bank 0 for address 3 to 10 */
+-      if (addr_type > I2C_SLAVE_ADDR2)
+-              npcm_i2c_select_bank(bus, I2C_BANK_0);
++
+       /* Set and enable the address */
+       iowrite8(sa_reg, bus->reg + npcm_i2caddr[addr_type]);
+       npcm_i2c_slave_int_enable(bus, enable);
+-      if (addr_type > I2C_SLAVE_ADDR2)
+-              npcm_i2c_select_bank(bus, I2C_BANK_1);
++
+       return 0;
+ }
+ #endif
+@@ -843,15 +838,11 @@ static u8 npcm_i2c_get_slave_addr(struct npcm_i2c *bus, enum i2c_addr addr_type)
+ {
+       u8 slave_add;
+-      /* select bank 0 for address 3 to 10 */
+-      if (addr_type > I2C_SLAVE_ADDR2)
+-              npcm_i2c_select_bank(bus, I2C_BANK_0);
++      if (addr_type > I2C_SLAVE_ADDR2 && addr_type <= I2C_SLAVE_ADDR10)
++              dev_err(bus->dev, "get slave: try to use more than 2 SA not supported\n");
+       slave_add = ioread8(bus->reg + npcm_i2caddr[(int)addr_type]);
+-      if (addr_type > I2C_SLAVE_ADDR2)
+-              npcm_i2c_select_bank(bus, I2C_BANK_1);
+-
+       return slave_add;
+ }
+@@ -861,12 +852,12 @@ static int npcm_i2c_remove_slave_addr(struct npcm_i2c *bus, u8 slave_add)
+       /* Set the enable bit */
+       slave_add |= 0x80;
+-      npcm_i2c_select_bank(bus, I2C_BANK_0);
+-      for (i = I2C_SLAVE_ADDR1; i < I2C_NUM_OWN_ADDR; i++) {
++
++      for (i = I2C_SLAVE_ADDR1; i < I2C_NUM_OWN_ADDR_SUPPORTED; i++) {
+               if (ioread8(bus->reg + npcm_i2caddr[i]) == slave_add)
+                       iowrite8(0, bus->reg + npcm_i2caddr[i]);
+       }
+-      npcm_i2c_select_bank(bus, I2C_BANK_1);
++
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/iavf-fix-max_rate-limiting.patch b/queue-5.15/iavf-fix-max_rate-limiting.patch
new file mode 100644 (file)
index 0000000..6fabcf5
--- /dev/null
@@ -0,0 +1,104 @@
+From 31267999966ea96756dfb06605aeffca6014a2ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 18:41:23 -0400
+Subject: iavf: Fix max_rate limiting
+
+From: Przemyslaw Patynowski <przemyslawx.patynowski@intel.com>
+
+[ Upstream commit ec60d54cb9a3d43a02c5612a03093c18233e6601 ]
+
+Fix max_rate option in TC, check for proper quanta boundaries.
+Check for minimum value provided and if it fits expected 50Mbps
+quanta.
+
+Without this patch, iavf could send settings for max_rate limiting
+that would be accepted from by PF even the max_rate option is less
+than expected 50Mbps quanta. It results in no rate limiting
+on traffic as rate limiting will be floored to 0.
+
+Example:
+tc qdisc add dev $vf root mqprio num_tc 3 map 0 2 1 queues \
+2@0 2@2 2@4 hw 1 mode channel shaper bw_rlimit \
+max_rate 50Mbps 500Mbps 500Mbps
+
+Should limit TC0 to circa 50 Mbps
+
+tc qdisc add dev $vf root mqprio num_tc 3 map 0 2 1 queues \
+2@0 2@2 2@4 hw 1 mode channel shaper bw_rlimit \
+max_rate 0Mbps 100Kbit 500Mbps
+
+Should return error
+
+Fixes: d5b33d024496 ("i40evf: add ndo_setup_tc callback to i40evf")
+Signed-off-by: Przemyslaw Patynowski <przemyslawx.patynowski@intel.com>
+Signed-off-by: Jun Zhang <xuejun.zhang@intel.com>
+Tested-by: Bharathi Sreenivas <bharathi.sreenivas@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/iavf/iavf.h      |  1 +
+ drivers/net/ethernet/intel/iavf/iavf_main.c | 25 +++++++++++++++++++--
+ 2 files changed, 24 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h
+index 9a122aea6979..ab84fc83352f 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf.h
++++ b/drivers/net/ethernet/intel/iavf/iavf.h
+@@ -89,6 +89,7 @@ struct iavf_vsi {
+ #define IAVF_HKEY_ARRAY_SIZE ((IAVF_VFQF_HKEY_MAX_INDEX + 1) * 4)
+ #define IAVF_HLUT_ARRAY_SIZE ((IAVF_VFQF_HLUT_MAX_INDEX + 1) * 4)
+ #define IAVF_MBPS_DIVISOR     125000 /* divisor to convert to Mbps */
++#define IAVF_MBPS_QUANTA      50
+ #define IAVF_VIRTCHNL_VF_RESOURCE_SIZE (sizeof(struct virtchnl_vf_resource) + \
+                                       (IAVF_MAX_VF_VSI * \
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index ca74824d40b8..067f0b265e7d 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -2732,6 +2732,7 @@ static int iavf_validate_ch_config(struct iavf_adapter *adapter,
+                                  struct tc_mqprio_qopt_offload *mqprio_qopt)
+ {
+       u64 total_max_rate = 0;
++      u32 tx_rate_rem = 0;
+       int i, num_qps = 0;
+       u64 tx_rate = 0;
+       int ret = 0;
+@@ -2746,12 +2747,32 @@ static int iavf_validate_ch_config(struct iavf_adapter *adapter,
+                       return -EINVAL;
+               if (mqprio_qopt->min_rate[i]) {
+                       dev_err(&adapter->pdev->dev,
+-                              "Invalid min tx rate (greater than 0) specified\n");
++                              "Invalid min tx rate (greater than 0) specified for TC%d\n",
++                              i);
+                       return -EINVAL;
+               }
+-              /*convert to Mbps */
++
++              /* convert to Mbps */
+               tx_rate = div_u64(mqprio_qopt->max_rate[i],
+                                 IAVF_MBPS_DIVISOR);
++
++              if (mqprio_qopt->max_rate[i] &&
++                  tx_rate < IAVF_MBPS_QUANTA) {
++                      dev_err(&adapter->pdev->dev,
++                              "Invalid max tx rate for TC%d, minimum %dMbps\n",
++                              i, IAVF_MBPS_QUANTA);
++                      return -EINVAL;
++              }
++
++              (void)div_u64_rem(tx_rate, IAVF_MBPS_QUANTA, &tx_rate_rem);
++
++              if (tx_rate_rem != 0) {
++                      dev_err(&adapter->pdev->dev,
++                              "Invalid max tx rate for TC%d, not divisible by %d\n",
++                              i, IAVF_MBPS_QUANTA);
++                      return -EINVAL;
++              }
++
+               total_max_rate += tx_rate;
+               num_qps += mqprio_qopt->qopt.count[i];
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/iavf-fix-tc-qdisc-show-listing-too-many-queues.patch b/queue-5.15/iavf-fix-tc-qdisc-show-listing-too-many-queues.patch
new file mode 100644 (file)
index 0000000..23e6cd2
--- /dev/null
@@ -0,0 +1,123 @@
+From daecf929199e77a8522dda80a949fc2c427256a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jun 2022 15:36:29 +0200
+Subject: iavf: Fix 'tc qdisc show' listing too many queues
+
+From: Przemyslaw Patynowski <przemyslawx.patynowski@intel.com>
+
+[ Upstream commit 93cb804edab1b9a5bb7bb7b6824012dbb20abf22 ]
+
+Fix tc qdisc show dev <ethX> root displaying too many fq_codel qdiscs.
+tc_modify_qdisc, which is caller of ndo_setup_tc, expects driver to call
+netif_set_real_num_tx_queues, which prepares qdiscs.
+Without this patch, fq_codel qdiscs would not be adjusted to number of
+queues on VF.
+e.g.:
+tc qdisc show dev <ethX>
+qdisc mq 0: root
+qdisc fq_codel 0: parent :4 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64
+qdisc fq_codel 0: parent :3 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64
+qdisc fq_codel 0: parent :2 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64
+qdisc fq_codel 0: parent :1 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64
+tc qdisc add dev <ethX> root mqprio num_tc 2 map 1 0 0 0 0 0 0 0 queues 1@0 1@1 hw 1 mode channel shaper bw_rlimit max_rate 5000Mbit 150Mbit
+tc qdisc show dev <ethX>
+qdisc mqprio 8003: root tc 2 map 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+             queues:(0:0) (1:1)
+             mode:channel
+             shaper:bw_rlimit   max_rate:5Gbit 150Mbit
+qdisc fq_codel 0: parent 8003:4 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64
+qdisc fq_codel 0: parent 8003:3 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64
+qdisc fq_codel 0: parent 8003:2 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64
+qdisc fq_codel 0: parent 8003:1 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64
+
+While after fix:
+tc qdisc add dev <ethX> root mqprio num_tc 2 map 1 0 0 0 0 0 0 0 queues 1@0 1@1 hw 1 mode channel shaper bw_rlimit max_rate 5000Mbit 150Mbit
+tc qdisc show dev <ethX> #should show 2, shows 4
+qdisc mqprio 8004: root tc 2 map 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+             queues:(0:0) (1:1)
+             mode:channel
+             shaper:bw_rlimit   max_rate:5Gbit 150Mbit
+qdisc fq_codel 0: parent 8004:2 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64
+qdisc fq_codel 0: parent 8004:1 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64
+
+Fixes: d5b33d024496 ("i40evf: add ndo_setup_tc callback to i40evf")
+Signed-off-by: Przemyslaw Patynowski <przemyslawx.patynowski@intel.com>
+Co-developed-by: Grzegorz Szczurek <grzegorzx.szczurek@intel.com>
+Signed-off-by: Grzegorz Szczurek <grzegorzx.szczurek@intel.com>
+Co-developed-by: Kiran Patil <kiran.patil@intel.com>
+Signed-off-by: Kiran Patil <kiran.patil@intel.com>
+Signed-off-by: Jedrzej Jagielski <jedrzej.jagielski@intel.com>
+Tested-by: Bharathi Sreenivas <bharathi.sreenivas@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/iavf/iavf.h      |  5 +++++
+ drivers/net/ethernet/intel/iavf/iavf_main.c | 21 +++++++++++++++++++++
+ 2 files changed, 26 insertions(+)
+
+diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h
+index ab84fc83352f..99d2b090a1e6 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf.h
++++ b/drivers/net/ethernet/intel/iavf/iavf.h
+@@ -378,6 +378,11 @@ struct iavf_adapter {
+       /* lock to protect access to the cloud filter list */
+       spinlock_t cloud_filter_list_lock;
+       u16 num_cloud_filters;
++      /* snapshot of "num_active_queues" before setup_tc for qdisc add
++       * is invoked. This information is useful during qdisc del flow,
++       * to restore correct number of queues
++       */
++      int orig_num_active_queues;
+ #define IAVF_MAX_FDIR_FILTERS 128     /* max allowed Flow Director filters */
+       u16 fdir_active_fltr;
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index 067f0b265e7d..e2349131a428 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -2839,6 +2839,7 @@ static int __iavf_setup_tc(struct net_device *netdev, void *type_data)
+                       netif_tx_disable(netdev);
+                       iavf_del_all_cloud_filters(adapter);
+                       adapter->aq_required = IAVF_FLAG_AQ_DISABLE_CHANNELS;
++                      total_qps = adapter->orig_num_active_queues;
+                       goto exit;
+               } else {
+                       return -EINVAL;
+@@ -2882,7 +2883,21 @@ static int __iavf_setup_tc(struct net_device *netdev, void *type_data)
+                               adapter->ch_config.ch_info[i].offset = 0;
+                       }
+               }
++
++              /* Take snapshot of original config such as "num_active_queues"
++               * It is used later when delete ADQ flow is exercised, so that
++               * once delete ADQ flow completes, VF shall go back to its
++               * original queue configuration
++               */
++
++              adapter->orig_num_active_queues = adapter->num_active_queues;
++
++              /* Store queue info based on TC so that VF gets configured
++               * with correct number of queues when VF completes ADQ config
++               * flow
++               */
+               adapter->ch_config.total_qps = total_qps;
++
+               netif_tx_stop_all_queues(netdev);
+               netif_tx_disable(netdev);
+               adapter->aq_required |= IAVF_FLAG_AQ_ENABLE_CHANNELS;
+@@ -2899,6 +2914,12 @@ static int __iavf_setup_tc(struct net_device *netdev, void *type_data)
+               }
+       }
+ exit:
++      if (test_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section))
++              return 0;
++
++      netif_set_real_num_rx_queues(netdev, total_qps);
++      netif_set_real_num_tx_queues(netdev, total_qps);
++
+       return ret;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/ieee80211-add-eht-1k-aggregation-definitions.patch b/queue-5.15/ieee80211-add-eht-1k-aggregation-definitions.patch
new file mode 100644 (file)
index 0000000..49b0868
--- /dev/null
@@ -0,0 +1,117 @@
+From 2343970e4f78295487a069925be1dcab5aa19c24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Feb 2022 17:29:52 +0100
+Subject: ieee80211: add EHT 1K aggregation definitions
+
+From: Mordechay Goodstein <mordechay.goodstein@intel.com>
+
+[ Upstream commit 2a2c86f15e17c5013b9897b67d895e64a25ae3cb ]
+
+We add the fields for parsing extended ADDBA request/respond,
+and new max 1K aggregation for limit ADDBA request/respond.
+
+Adjust drivers to use the proper macro, IEEE80211_MAX_AMPDU_BUF ->
+IEEE80211_MAX_AMPDU_BUF_HE.
+
+Signed-off-by: Mordechay Goodstein <mordechay.goodstein@intel.com>
+Link: https://lore.kernel.org/r/20220214173004.b8b447ce95b7.I0ee2554c94e89abc7a752b0f7cc7fd79c273efea@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/mac.c            | 2 +-
+ drivers/net/wireless/intel/iwlwifi/mvm/ops.c     | 4 ++--
+ drivers/net/wireless/mediatek/mt76/mt7915/init.c | 4 ++--
+ include/linux/ieee80211.h                        | 6 +++++-
+ net/mac80211/agg-rx.c                            | 2 +-
+ 5 files changed, 11 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
+index f85fd341557e..c7ee373a9d2c 100644
+--- a/drivers/net/wireless/ath/ath11k/mac.c
++++ b/drivers/net/wireless/ath/ath11k/mac.c
+@@ -6566,7 +6566,7 @@ static int __ath11k_mac_register(struct ath11k *ar)
+       ar->hw->queues = ATH11K_HW_MAX_QUEUES;
+       ar->hw->wiphy->tx_queue_len = ATH11K_QUEUE_LEN;
+       ar->hw->offchannel_tx_hw_queue = ATH11K_HW_MAX_QUEUES - 1;
+-      ar->hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF;
++      ar->hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_HE;
+       ar->hw->vif_data_size = sizeof(struct ath11k_vif);
+       ar->hw->sta_data_size = sizeof(struct ath11k_sta);
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+index c77d98c88811..eeb81808db08 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+@@ -761,12 +761,12 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
+       if (!hw)
+               return NULL;
+-      hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF;
++      hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_HE;
+       if (cfg->max_tx_agg_size)
+               hw->max_tx_aggregation_subframes = cfg->max_tx_agg_size;
+       else
+-              hw->max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF;
++              hw->max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_HE;
+       op_mode = hw->priv;
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+index b171027e0cfa..1ae42ef147c8 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+@@ -217,8 +217,8 @@ mt7915_init_wiphy(struct ieee80211_hw *hw)
+       struct wiphy *wiphy = hw->wiphy;
+       hw->queues = 4;
+-      hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF;
+-      hw->max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF;
++      hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_HE;
++      hw->max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_HE;
+       hw->netdev_features = NETIF_F_RXCSUM;
+       hw->radiotap_timestamp.units_pos =
+diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
+index 694264503119..00ed7c17698d 100644
+--- a/include/linux/ieee80211.h
++++ b/include/linux/ieee80211.h
+@@ -1023,6 +1023,8 @@ struct ieee80211_tpc_report_ie {
+ #define IEEE80211_ADDBA_EXT_FRAG_LEVEL_MASK   GENMASK(2, 1)
+ #define IEEE80211_ADDBA_EXT_FRAG_LEVEL_SHIFT  1
+ #define IEEE80211_ADDBA_EXT_NO_FRAG           BIT(0)
++#define IEEE80211_ADDBA_EXT_BUF_SIZE_MASK     GENMASK(7, 5)
++#define IEEE80211_ADDBA_EXT_BUF_SIZE_SHIFT    10
+ struct ieee80211_addba_ext_ie {
+       u8 data;
+@@ -1697,10 +1699,12 @@ struct ieee80211_ht_operation {
+  * A-MPDU buffer sizes
+  * According to HT size varies from 8 to 64 frames
+  * HE adds the ability to have up to 256 frames.
++ * EHT adds the ability to have up to 1K frames.
+  */
+ #define IEEE80211_MIN_AMPDU_BUF               0x8
+ #define IEEE80211_MAX_AMPDU_BUF_HT    0x40
+-#define IEEE80211_MAX_AMPDU_BUF               0x100
++#define IEEE80211_MAX_AMPDU_BUF_HE    0x100
++#define IEEE80211_MAX_AMPDU_BUF_EHT   0x400
+ /* Spatial Multiplexing Power Save Modes (for capability) */
+diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
+index ef729b1e39ea..e43176794149 100644
+--- a/net/mac80211/agg-rx.c
++++ b/net/mac80211/agg-rx.c
+@@ -310,7 +310,7 @@ void ___ieee80211_start_rx_ba_session(struct sta_info *sta,
+       }
+       if (sta->sta.he_cap.has_he)
+-              max_buf_size = IEEE80211_MAX_AMPDU_BUF;
++              max_buf_size = IEEE80211_MAX_AMPDU_BUF_HE;
+       else
+               max_buf_size = IEEE80211_MAX_AMPDU_BUF_HT;
+-- 
+2.35.1
+
diff --git a/queue-5.15/iio-accel-bma400-fix-the-scale-min-and-max-macro-val.patch b/queue-5.15/iio-accel-bma400-fix-the-scale-min-and-max-macro-val.patch
new file mode 100644 (file)
index 0000000..e2683f6
--- /dev/null
@@ -0,0 +1,59 @@
+From ac6c7852228ba2d0054ce9603ce12c10398f083c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 May 2022 19:00:12 +0530
+Subject: iio: accel: bma400: Fix the scale min and max macro values
+
+From: Jagath Jog J <jagathjog1996@gmail.com>
+
+[ Upstream commit 747c7cf1592e226d40543231b26502b332d0ea2f ]
+
+Changing the scale macro values to match the bma400 sensitivity
+for 1 LSB of all the available ranges.
+
+Fixes: 465c811f1f20 ("iio: accel: Add driver for the BMA400")
+Signed-off-by: Jagath Jog J <jagathjog1996@gmail.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20220505133021.22362-2-jagathjog1996@gmail.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/accel/bma400.h | 23 +++++++++++++++++++++--
+ 1 file changed, 21 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/accel/bma400.h b/drivers/iio/accel/bma400.h
+index 5ad10db9819f..416090c6b1e8 100644
+--- a/drivers/iio/accel/bma400.h
++++ b/drivers/iio/accel/bma400.h
+@@ -83,8 +83,27 @@
+ #define BMA400_ACC_ODR_MIN_WHOLE_HZ 25
+ #define BMA400_ACC_ODR_MIN_HZ       12
+-#define BMA400_SCALE_MIN            38357
+-#define BMA400_SCALE_MAX            306864
++/*
++ * BMA400_SCALE_MIN macro value represents m/s^2 for 1 LSB before
++ * converting to micro values for +-2g range.
++ *
++ * For +-2g - 1 LSB = 0.976562 milli g = 0.009576 m/s^2
++ * For +-4g - 1 LSB = 1.953125 milli g = 0.019153 m/s^2
++ * For +-16g - 1 LSB = 7.8125 milli g = 0.076614 m/s^2
++ *
++ * The raw value which is used to select the different ranges is determined
++ * by the first bit set position from the scale value, so BMA400_SCALE_MIN
++ * should be odd.
++ *
++ * Scale values for +-2g, +-4g, +-8g and +-16g are populated into bma400_scales
++ * array by left shifting BMA400_SCALE_MIN.
++ * e.g.:
++ * To select +-2g = 9577 << 0 = raw value to write is 0.
++ * To select +-8g = 9577 << 2 = raw value to write is 2.
++ * To select +-16g = 9577 << 3 = raw value to write is 3.
++ */
++#define BMA400_SCALE_MIN            9577
++#define BMA400_SCALE_MAX            76617
+ #define BMA400_NUM_REGULATORS       2
+ #define BMA400_VDD_REGULATOR        0
+-- 
+2.35.1
+
diff --git a/queue-5.15/iio-accel-bma400-reordering-of-header-files.patch b/queue-5.15/iio-accel-bma400-reordering-of-header-files.patch
new file mode 100644 (file)
index 0000000..2e019a4
--- /dev/null
@@ -0,0 +1,45 @@
+From 67d0a3eb3ff2486e2fb6d532e5c1f690f1ed9f5e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 May 2022 19:00:13 +0530
+Subject: iio: accel: bma400: Reordering of header files
+
+From: Jagath Jog J <jagathjog1996@gmail.com>
+
+[ Upstream commit 1bd2dc6ea863690aee5c45ebf09c9194c7a42c0d ]
+
+Reordering of header files and removing the iio/sysfs.h since
+custom attributes are not being used in the driver.
+
+Signed-off-by: Jagath Jog J <jagathjog1996@gmail.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20220505133021.22362-3-jagathjog1996@gmail.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/accel/bma400_core.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/accel/bma400_core.c b/drivers/iio/accel/bma400_core.c
+index 21520e022a21..7e6598534650 100644
+--- a/drivers/iio/accel/bma400_core.c
++++ b/drivers/iio/accel/bma400_core.c
+@@ -13,14 +13,14 @@
+ #include <linux/bitops.h>
+ #include <linux/device.h>
+-#include <linux/iio/iio.h>
+-#include <linux/iio/sysfs.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/mutex.h>
+ #include <linux/regmap.h>
+ #include <linux/regulator/consumer.h>
++#include <linux/iio/iio.h>
++
+ #include "bma400.h"
+ /*
+-- 
+2.35.1
+
diff --git a/queue-5.15/iio-cros-register-fifo-callback-after-sensor-is-regi.patch b/queue-5.15/iio-cros-register-fifo-callback-after-sensor-is-regi.patch
new file mode 100644 (file)
index 0000000..0e83763
--- /dev/null
@@ -0,0 +1,264 @@
+From d6e8d3632d55339720818247fb77bbd76f4ca814 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Jul 2022 07:47:16 -0700
+Subject: iio: cros: Register FIFO callback after sensor is registered
+
+From: Gwendal Grignou <gwendal@chromium.org>
+
+[ Upstream commit 0b4ae3f6d1210c11f9baf159009c7227eacf90f2 ]
+
+Instead of registering callback to process sensor events right at
+initialization time, wait for the sensor to be register in the iio
+subsystem.
+
+Events can come at probe time (in case the kernel rebooted abruptly
+without switching the sensor off for  instance), and be sent to IIO core
+before the sensor is fully registered.
+
+Fixes: aa984f1ba4a4 ("iio: cros_ec: Register to cros_ec_sensorhub when EC supports FIFO")
+Reported-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Gwendal Grignou <gwendal@chromium.org>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Link: https://lore.kernel.org/r/20220711144716.642617-1-gwendal@chromium.org
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/accel/cros_ec_accel_legacy.c      |  4 +-
+ .../cros_ec_sensors/cros_ec_lid_angle.c       |  4 +-
+ .../common/cros_ec_sensors/cros_ec_sensors.c  |  6 +-
+ .../cros_ec_sensors/cros_ec_sensors_core.c    | 58 ++++++++++++++-----
+ drivers/iio/light/cros_ec_light_prox.c        |  6 +-
+ drivers/iio/pressure/cros_ec_baro.c           |  6 +-
+ .../linux/iio/common/cros_ec_sensors_core.h   |  7 ++-
+ 7 files changed, 60 insertions(+), 31 deletions(-)
+
+diff --git a/drivers/iio/accel/cros_ec_accel_legacy.c b/drivers/iio/accel/cros_ec_accel_legacy.c
+index b6f3471b62dc..3b77fded2dc0 100644
+--- a/drivers/iio/accel/cros_ec_accel_legacy.c
++++ b/drivers/iio/accel/cros_ec_accel_legacy.c
+@@ -215,7 +215,7 @@ static int cros_ec_accel_legacy_probe(struct platform_device *pdev)
+               return -ENOMEM;
+       ret = cros_ec_sensors_core_init(pdev, indio_dev, true,
+-                                      cros_ec_sensors_capture, NULL);
++                                      cros_ec_sensors_capture);
+       if (ret)
+               return ret;
+@@ -235,7 +235,7 @@ static int cros_ec_accel_legacy_probe(struct platform_device *pdev)
+               state->sign[CROS_EC_SENSOR_Z] = -1;
+       }
+-      return devm_iio_device_register(dev, indio_dev);
++      return cros_ec_sensors_core_register(dev, indio_dev, NULL);
+ }
+ static struct platform_driver cros_ec_accel_platform_driver = {
+diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c b/drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c
+index af801e203623..02d3cf36acb0 100644
+--- a/drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c
++++ b/drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c
+@@ -97,7 +97,7 @@ static int cros_ec_lid_angle_probe(struct platform_device *pdev)
+       if (!indio_dev)
+               return -ENOMEM;
+-      ret = cros_ec_sensors_core_init(pdev, indio_dev, false, NULL, NULL);
++      ret = cros_ec_sensors_core_init(pdev, indio_dev, false, NULL);
+       if (ret)
+               return ret;
+@@ -113,7 +113,7 @@ static int cros_ec_lid_angle_probe(struct platform_device *pdev)
+       if (ret)
+               return ret;
+-      return devm_iio_device_register(dev, indio_dev);
++      return cros_ec_sensors_core_register(dev, indio_dev, NULL);
+ }
+ static const struct platform_device_id cros_ec_lid_angle_ids[] = {
+diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c
+index 376a5b30010a..5cce34fdff02 100644
+--- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c
++++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c
+@@ -235,8 +235,7 @@ static int cros_ec_sensors_probe(struct platform_device *pdev)
+               return -ENOMEM;
+       ret = cros_ec_sensors_core_init(pdev, indio_dev, true,
+-                                      cros_ec_sensors_capture,
+-                                      cros_ec_sensors_push_data);
++                                      cros_ec_sensors_capture);
+       if (ret)
+               return ret;
+@@ -297,7 +296,8 @@ static int cros_ec_sensors_probe(struct platform_device *pdev)
+       else
+               state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd;
+-      return devm_iio_device_register(dev, indio_dev);
++      return cros_ec_sensors_core_register(dev, indio_dev,
++                      cros_ec_sensors_push_data);
+ }
+ static const struct platform_device_id cros_ec_sensors_ids[] = {
+diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
+index 28bde13003b7..b0c1dc8cc4c5 100644
+--- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
++++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
+@@ -234,21 +234,18 @@ static void cros_ec_sensors_core_clean(void *arg)
+ /**
+  * cros_ec_sensors_core_init() - basic initialization of the core structure
+- * @pdev:             platform device created for the sensors
++ * @pdev:             platform device created for the sensor
+  * @indio_dev:                iio device structure of the device
+  * @physical_device:  true if the device refers to a physical device
+  * @trigger_capture:    function pointer to call buffer is triggered,
+  *    for backward compatibility.
+- * @push_data:          function to call when cros_ec_sensorhub receives
+- *    a sample for that sensor.
+  *
+  * Return: 0 on success, -errno on failure.
+  */
+ int cros_ec_sensors_core_init(struct platform_device *pdev,
+                             struct iio_dev *indio_dev,
+                             bool physical_device,
+-                            cros_ec_sensors_capture_t trigger_capture,
+-                            cros_ec_sensorhub_push_data_cb_t push_data)
++                            cros_ec_sensors_capture_t trigger_capture)
+ {
+       struct device *dev = &pdev->dev;
+       struct cros_ec_sensors_core_state *state = iio_priv(indio_dev);
+@@ -339,17 +336,6 @@ int cros_ec_sensors_core_init(struct platform_device *pdev,
+                       if (ret)
+                               return ret;
+-                      ret = cros_ec_sensorhub_register_push_data(
+-                                      sensor_hub, sensor_platform->sensor_num,
+-                                      indio_dev, push_data);
+-                      if (ret)
+-                              return ret;
+-
+-                      ret = devm_add_action_or_reset(
+-                                      dev, cros_ec_sensors_core_clean, pdev);
+-                      if (ret)
+-                              return ret;
+-
+                       /* Timestamp coming from FIFO are in ns since boot. */
+                       ret = iio_device_set_clock(indio_dev, CLOCK_BOOTTIME);
+                       if (ret)
+@@ -371,6 +357,46 @@ int cros_ec_sensors_core_init(struct platform_device *pdev,
+ }
+ EXPORT_SYMBOL_GPL(cros_ec_sensors_core_init);
++/**
++ * cros_ec_sensors_core_register() - Register callback to FIFO and IIO when
++ * sensor is ready.
++ * It must be called at the end of the sensor probe routine.
++ * @dev:              device created for the sensor
++ * @indio_dev:                iio device structure of the device
++ * @push_data:          function to call when cros_ec_sensorhub receives
++ *    a sample for that sensor.
++ *
++ * Return: 0 on success, -errno on failure.
++ */
++int cros_ec_sensors_core_register(struct device *dev,
++                                struct iio_dev *indio_dev,
++                                cros_ec_sensorhub_push_data_cb_t push_data)
++{
++      struct cros_ec_sensor_platform *sensor_platform = dev_get_platdata(dev);
++      struct cros_ec_sensorhub *sensor_hub = dev_get_drvdata(dev->parent);
++      struct platform_device *pdev = to_platform_device(dev);
++      struct cros_ec_dev *ec = sensor_hub->ec;
++      int ret;
++
++      ret = devm_iio_device_register(dev, indio_dev);
++      if (ret)
++              return ret;
++
++      if (!push_data ||
++          !cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO))
++              return 0;
++
++      ret = cros_ec_sensorhub_register_push_data(
++                      sensor_hub, sensor_platform->sensor_num,
++                      indio_dev, push_data);
++      if (ret)
++              return ret;
++
++      return devm_add_action_or_reset(
++                      dev, cros_ec_sensors_core_clean, pdev);
++}
++EXPORT_SYMBOL_GPL(cros_ec_sensors_core_register);
++
+ /**
+  * cros_ec_motion_send_host_cmd() - send motion sense host command
+  * @state:            pointer to state information for device
+diff --git a/drivers/iio/light/cros_ec_light_prox.c b/drivers/iio/light/cros_ec_light_prox.c
+index de472f23d1cb..16b893bae388 100644
+--- a/drivers/iio/light/cros_ec_light_prox.c
++++ b/drivers/iio/light/cros_ec_light_prox.c
+@@ -181,8 +181,7 @@ static int cros_ec_light_prox_probe(struct platform_device *pdev)
+               return -ENOMEM;
+       ret = cros_ec_sensors_core_init(pdev, indio_dev, true,
+-                                      cros_ec_sensors_capture,
+-                                      cros_ec_sensors_push_data);
++                                      cros_ec_sensors_capture);
+       if (ret)
+               return ret;
+@@ -240,7 +239,8 @@ static int cros_ec_light_prox_probe(struct platform_device *pdev)
+       state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd;
+-      return devm_iio_device_register(dev, indio_dev);
++      return cros_ec_sensors_core_register(dev, indio_dev,
++                                           cros_ec_sensors_push_data);
+ }
+ static const struct platform_device_id cros_ec_light_prox_ids[] = {
+diff --git a/drivers/iio/pressure/cros_ec_baro.c b/drivers/iio/pressure/cros_ec_baro.c
+index 2f882e109423..0511edbf868d 100644
+--- a/drivers/iio/pressure/cros_ec_baro.c
++++ b/drivers/iio/pressure/cros_ec_baro.c
+@@ -138,8 +138,7 @@ static int cros_ec_baro_probe(struct platform_device *pdev)
+               return -ENOMEM;
+       ret = cros_ec_sensors_core_init(pdev, indio_dev, true,
+-                                      cros_ec_sensors_capture,
+-                                      cros_ec_sensors_push_data);
++                                      cros_ec_sensors_capture);
+       if (ret)
+               return ret;
+@@ -186,7 +185,8 @@ static int cros_ec_baro_probe(struct platform_device *pdev)
+       state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd;
+-      return devm_iio_device_register(dev, indio_dev);
++      return cros_ec_sensors_core_register(dev, indio_dev,
++                                           cros_ec_sensors_push_data);
+ }
+ static const struct platform_device_id cros_ec_baro_ids[] = {
+diff --git a/include/linux/iio/common/cros_ec_sensors_core.h b/include/linux/iio/common/cros_ec_sensors_core.h
+index c582e1a14232..7b5dbd749995 100644
+--- a/include/linux/iio/common/cros_ec_sensors_core.h
++++ b/include/linux/iio/common/cros_ec_sensors_core.h
+@@ -95,8 +95,11 @@ int cros_ec_sensors_read_cmd(struct iio_dev *indio_dev, unsigned long scan_mask,
+ struct platform_device;
+ int cros_ec_sensors_core_init(struct platform_device *pdev,
+                             struct iio_dev *indio_dev, bool physical_device,
+-                            cros_ec_sensors_capture_t trigger_capture,
+-                            cros_ec_sensorhub_push_data_cb_t push_data);
++                            cros_ec_sensors_capture_t trigger_capture);
++
++int cros_ec_sensors_core_register(struct device *dev,
++                                struct iio_dev *indio_dev,
++                                cros_ec_sensorhub_push_data_cb_t push_data);
+ irqreturn_t cros_ec_sensors_capture(int irq, void *p);
+ int cros_ec_sensors_push_data(struct iio_dev *indio_dev,
+-- 
+2.35.1
+
diff --git a/queue-5.15/inet-add-read_once-sk-sk_bound_dev_if-in-inet_match.patch b/queue-5.15/inet-add-read_once-sk-sk_bound_dev_if-in-inet_match.patch
new file mode 100644 (file)
index 0000000..64d2bfe
--- /dev/null
@@ -0,0 +1,160 @@
+From bfb4f7b8e835d191778ea60d167122944b163884 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 May 2022 09:56:01 -0700
+Subject: inet: add READ_ONCE(sk->sk_bound_dev_if) in INET_MATCH()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 4915d50e300e96929d2462041d6f6c6f061167fd ]
+
+INET_MATCH() runs without holding a lock on the socket.
+
+We probably need to annotate most reads.
+
+This patch makes INET_MATCH() an inline function
+to ease our changes.
+
+v2:
+
+We remove the 32bit version of it, as modern compilers
+should generate the same code really, no need to
+try to be smarter.
+
+Also make 'struct net *net' the first argument.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/inet_hashtables.h | 35 ++++++++++++++++-------------------
+ include/net/sock.h            |  3 ---
+ net/ipv4/inet_hashtables.c    | 15 +++++----------
+ net/ipv4/udp.c                |  3 +--
+ 4 files changed, 22 insertions(+), 34 deletions(-)
+
+diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
+index 749bb1e46087..825ad1d06d05 100644
+--- a/include/net/inet_hashtables.h
++++ b/include/net/inet_hashtables.h
+@@ -295,7 +295,6 @@ static inline struct sock *inet_lookup_listener(struct net *net,
+       ((__force __portpair)(((__u32)(__dport) << 16) | (__force __u32)(__be16)(__sport)))
+ #endif
+-#if (BITS_PER_LONG == 64)
+ #ifdef __BIG_ENDIAN
+ #define INET_ADDR_COOKIE(__name, __saddr, __daddr) \
+       const __addrpair __name = (__force __addrpair) ( \
+@@ -307,24 +306,22 @@ static inline struct sock *inet_lookup_listener(struct net *net,
+                                  (((__force __u64)(__be32)(__daddr)) << 32) | \
+                                  ((__force __u64)(__be32)(__saddr)))
+ #endif /* __BIG_ENDIAN */
+-#define INET_MATCH(__sk, __net, __cookie, __saddr, __daddr, __ports, __dif, __sdif) \
+-      (((__sk)->sk_portpair == (__ports))                     &&      \
+-       ((__sk)->sk_addrpair == (__cookie))                    &&      \
+-       (((__sk)->sk_bound_dev_if == (__dif))                  ||      \
+-        ((__sk)->sk_bound_dev_if == (__sdif)))                &&      \
+-       net_eq(sock_net(__sk), (__net)))
+-#else /* 32-bit arch */
+-#define INET_ADDR_COOKIE(__name, __saddr, __daddr) \
+-      const int __name __deprecated __attribute__((unused))
+-
+-#define INET_MATCH(__sk, __net, __cookie, __saddr, __daddr, __ports, __dif, __sdif) \
+-      (((__sk)->sk_portpair == (__ports))             &&              \
+-       ((__sk)->sk_daddr      == (__saddr))           &&              \
+-       ((__sk)->sk_rcv_saddr  == (__daddr))           &&              \
+-       (((__sk)->sk_bound_dev_if == (__dif))          ||              \
+-        ((__sk)->sk_bound_dev_if == (__sdif)))        &&              \
+-       net_eq(sock_net(__sk), (__net)))
+-#endif /* 64-bit arch */
++
++static inline bool INET_MATCH(struct net *net, const struct sock *sk,
++                            const __addrpair cookie, const __portpair ports,
++                            int dif, int sdif)
++{
++      int bound_dev_if;
++
++      if (!net_eq(sock_net(sk), net) ||
++          sk->sk_portpair != ports ||
++          sk->sk_addrpair != cookie)
++              return false;
++
++      /* Paired with WRITE_ONCE() from sock_bindtoindex_locked() */
++      bound_dev_if = READ_ONCE(sk->sk_bound_dev_if);
++      return bound_dev_if == dif || bound_dev_if == sdif;
++}
+ /* Sockets in TCP_CLOSE state are _always_ taken out of the hash, so we need
+  * not check it for lookups anymore, thanks Alexey. -DaveM
+diff --git a/include/net/sock.h b/include/net/sock.h
+index e0a88bb0a58c..49a6315d521f 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -161,9 +161,6 @@ typedef __u64 __bitwise __addrpair;
+  *    for struct sock and struct inet_timewait_sock.
+  */
+ struct sock_common {
+-      /* skc_daddr and skc_rcv_saddr must be grouped on a 8 bytes aligned
+-       * address on 64bit arches : cf INET_MATCH()
+-       */
+       union {
+               __addrpair      skc_addrpair;
+               struct {
+diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
+index 342f3df77835..7c502c4a160b 100644
+--- a/net/ipv4/inet_hashtables.c
++++ b/net/ipv4/inet_hashtables.c
+@@ -410,13 +410,11 @@ struct sock *__inet_lookup_established(struct net *net,
+       sk_nulls_for_each_rcu(sk, node, &head->chain) {
+               if (sk->sk_hash != hash)
+                       continue;
+-              if (likely(INET_MATCH(sk, net, acookie,
+-                                    saddr, daddr, ports, dif, sdif))) {
++              if (likely(INET_MATCH(net, sk, acookie, ports, dif, sdif))) {
+                       if (unlikely(!refcount_inc_not_zero(&sk->sk_refcnt)))
+                               goto out;
+-                      if (unlikely(!INET_MATCH(sk, net, acookie,
+-                                               saddr, daddr, ports,
+-                                               dif, sdif))) {
++                      if (unlikely(!INET_MATCH(net, sk, acookie,
++                                               ports, dif, sdif))) {
+                               sock_gen_put(sk);
+                               goto begin;
+                       }
+@@ -465,8 +463,7 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row,
+               if (sk2->sk_hash != hash)
+                       continue;
+-              if (likely(INET_MATCH(sk2, net, acookie,
+-                                       saddr, daddr, ports, dif, sdif))) {
++              if (likely(INET_MATCH(net, sk2, acookie, ports, dif, sdif))) {
+                       if (sk2->sk_state == TCP_TIME_WAIT) {
+                               tw = inet_twsk(sk2);
+                               if (twsk_unique(sk, sk2, twp))
+@@ -532,9 +529,7 @@ static bool inet_ehash_lookup_by_sk(struct sock *sk,
+               if (esk->sk_hash != sk->sk_hash)
+                       continue;
+               if (sk->sk_family == AF_INET) {
+-                      if (unlikely(INET_MATCH(esk, net, acookie,
+-                                              sk->sk_daddr,
+-                                              sk->sk_rcv_saddr,
++                      if (unlikely(INET_MATCH(net, esk, acookie,
+                                               ports, dif, sdif))) {
+                               return true;
+                       }
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index 4ad4daa16cce..efef7ba44e1d 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -2554,8 +2554,7 @@ static struct sock *__udp4_lib_demux_lookup(struct net *net,
+       struct sock *sk;
+       udp_portaddr_for_each_entry_rcu(sk, &hslot2->head) {
+-              if (INET_MATCH(sk, net, acookie, rmt_addr,
+-                             loc_addr, ports, dif, sdif))
++              if (INET_MATCH(net, sk, acookie, ports, dif, sdif))
+                       return sk;
+               /* Only check first socket in chain */
+               break;
+-- 
+2.35.1
+
diff --git a/queue-5.15/intel_th-fix-a-resource-leak-in-an-error-handling-pa.patch b/queue-5.15/intel_th-fix-a-resource-leak-in-an-error-handling-pa.patch
new file mode 100644 (file)
index 0000000..233ae05
--- /dev/null
@@ -0,0 +1,55 @@
+From d2999bc696d393c442cbfa4091c96b0b8bb0ea9e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Jul 2022 11:26:32 +0300
+Subject: intel_th: Fix a resource leak in an error handling path
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 086c28ab7c5699256aced0049aae9c42f1410313 ]
+
+If an error occurs after calling 'pci_alloc_irq_vectors()',
+'pci_free_irq_vectors()' must be called as already done in the remove
+function.
+
+Fixes: 7b7036d47c35 ("intel_th: pci: Use MSI interrupt signalling")
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Link: https://lore.kernel.org/r/20220705082637.59979-2-alexander.shishkin@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwtracing/intel_th/pci.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/hwtracing/intel_th/pci.c b/drivers/hwtracing/intel_th/pci.c
+index 7da4f298ed01..fcd0aca75007 100644
+--- a/drivers/hwtracing/intel_th/pci.c
++++ b/drivers/hwtracing/intel_th/pci.c
+@@ -100,8 +100,10 @@ static int intel_th_pci_probe(struct pci_dev *pdev,
+               }
+       th = intel_th_alloc(&pdev->dev, drvdata, resource, r);
+-      if (IS_ERR(th))
+-              return PTR_ERR(th);
++      if (IS_ERR(th)) {
++              err = PTR_ERR(th);
++              goto err_free_irq;
++      }
+       th->activate   = intel_th_pci_activate;
+       th->deactivate = intel_th_pci_deactivate;
+@@ -109,6 +111,10 @@ static int intel_th_pci_probe(struct pci_dev *pdev,
+       pci_set_master(pdev);
+       return 0;
++
++err_free_irq:
++      pci_free_irq_vectors(pdev);
++      return err;
+ }
+ static void intel_th_pci_remove(struct pci_dev *pdev)
+-- 
+2.35.1
+
diff --git a/queue-5.15/intel_th-msu-fix-vmalloced-buffers.patch b/queue-5.15/intel_th-msu-fix-vmalloced-buffers.patch
new file mode 100644 (file)
index 0000000..7ff3fbe
--- /dev/null
@@ -0,0 +1,74 @@
+From bc41f195230c27799b04d7e88de08e02ba5a81b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Jul 2022 11:26:34 +0300
+Subject: intel_th: msu: Fix vmalloced buffers
+
+From: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+
+[ Upstream commit ac12ad3ccf6d386e64a9d6a890595a2509d24edd ]
+
+After commit f5ff79fddf0e ("dma-mapping: remove CONFIG_DMA_REMAP") there's
+a chance of DMA buffer getting allocated via vmalloc(), which messes up
+the mmapping code:
+
+> RIP: msc_mmap_fault [intel_th_msu]
+> Call Trace:
+>  <TASK>
+>  __do_fault
+>  do_fault
+...
+
+Fix this by accounting for vmalloc possibility.
+
+Fixes: ba39bd830605 ("intel_th: msu: Switch over to scatterlist")
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Link: https://lore.kernel.org/r/20220705082637.59979-4-alexander.shishkin@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwtracing/intel_th/msu.c | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/hwtracing/intel_th/msu.c b/drivers/hwtracing/intel_th/msu.c
+index 432ade0842f6..d95d916b4682 100644
+--- a/drivers/hwtracing/intel_th/msu.c
++++ b/drivers/hwtracing/intel_th/msu.c
+@@ -1069,6 +1069,16 @@ msc_buffer_set_uc(struct msc *msc) {}
+ static inline void msc_buffer_set_wb(struct msc *msc) {}
+ #endif /* CONFIG_X86 */
++static struct page *msc_sg_page(struct scatterlist *sg)
++{
++      void *addr = sg_virt(sg);
++
++      if (is_vmalloc_addr(addr))
++              return vmalloc_to_page(addr);
++
++      return sg_page(sg);
++}
++
+ /**
+  * msc_buffer_win_alloc() - alloc a window for a multiblock mode
+  * @msc:      MSC device
+@@ -1139,7 +1149,7 @@ static void __msc_buffer_win_free(struct msc *msc, struct msc_window *win)
+       int i;
+       for_each_sg(win->sgt->sgl, sg, win->nr_segs, i) {
+-              struct page *page = sg_page(sg);
++              struct page *page = msc_sg_page(sg);
+               page->mapping = NULL;
+               dma_free_coherent(msc_dev(win->msc)->parent->parent, PAGE_SIZE,
+@@ -1403,7 +1413,7 @@ static struct page *msc_buffer_get_page(struct msc *msc, unsigned long pgoff)
+       pgoff -= win->pgoff;
+       for_each_sg(win->sgt->sgl, sg, win->nr_segs, blk) {
+-              struct page *page = sg_page(sg);
++              struct page *page = msc_sg_page(sg);
+               size_t pgsz = PFN_DOWN(sg->length);
+               if (pgoff < pgsz)
+-- 
+2.35.1
+
diff --git a/queue-5.15/intel_th-msu-sink-potential-dereference-of-null-poin.patch b/queue-5.15/intel_th-msu-sink-potential-dereference-of-null-poin.patch
new file mode 100644 (file)
index 0000000..5aba07b
--- /dev/null
@@ -0,0 +1,41 @@
+From aa5bab0713915ece154ad5869cee0446aaef5fdd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Jul 2022 11:26:33 +0300
+Subject: intel_th: msu-sink: Potential dereference of null pointer
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit 82f76a4a720791d889de775b5f7541d601efc8bd ]
+
+The return value of dma_alloc_coherent() needs to be checked.
+To avoid use of null pointer in sg_set_buf() in case of the failure of
+alloc.
+
+Fixes: f220df66f676 ("intel_th: msu-sink: An example msu buffer "sink"")
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Link: https://lore.kernel.org/r/20220705082637.59979-3-alexander.shishkin@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwtracing/intel_th/msu-sink.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/hwtracing/intel_th/msu-sink.c b/drivers/hwtracing/intel_th/msu-sink.c
+index 2c7f5116be12..891b28ea25fe 100644
+--- a/drivers/hwtracing/intel_th/msu-sink.c
++++ b/drivers/hwtracing/intel_th/msu-sink.c
+@@ -71,6 +71,9 @@ static int msu_sink_alloc_window(void *data, struct sg_table **sgt, size_t size)
+               block = dma_alloc_coherent(priv->dev->parent->parent,
+                                          PAGE_SIZE, &sg_dma_address(sg_ptr),
+                                          GFP_KERNEL);
++              if (!block)
++                      return -ENOMEM;
++
+               sg_set_buf(sg_ptr, block, PAGE_SIZE);
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/interconnect-imx-fix-max_node_id.patch b/queue-5.15/interconnect-imx-fix-max_node_id.patch
new file mode 100644 (file)
index 0000000..82074fb
--- /dev/null
@@ -0,0 +1,51 @@
+From 178e8ff2cee9a7dcc8a73606f16cd7d853800f7b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 3 Jul 2022 17:11:26 +0800
+Subject: interconnect: imx: fix max_node_id
+
+From: Peng Fan <peng.fan@nxp.com>
+
+[ Upstream commit bd734481e172b4827af09c9ab06c51d2ab7201e6 ]
+
+max_node_id not equal to the ARRAY_SIZE of node array, need increase 1,
+otherwise xlate will fail for the last entry. And rename max_node_id
+to num_nodes to reflect the reality.
+
+Fixes: f0d8048525d7d ("interconnect: Add imx core driver")
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Link: https://lore.kernel.org/r/20220703091132.1412063-5-peng.fan@oss.nxp.com
+Signed-off-by: Georgi Djakov <djakov@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/interconnect/imx/imx.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/interconnect/imx/imx.c b/drivers/interconnect/imx/imx.c
+index c770951a909c..aabd9edf2ef7 100644
+--- a/drivers/interconnect/imx/imx.c
++++ b/drivers/interconnect/imx/imx.c
+@@ -226,16 +226,16 @@ int imx_icc_register(struct platform_device *pdev,
+       struct device *dev = &pdev->dev;
+       struct icc_onecell_data *data;
+       struct icc_provider *provider;
+-      int max_node_id;
++      int num_nodes;
+       int ret;
+       /* icc_onecell_data is indexed by node_id, unlike nodes param */
+-      max_node_id = get_max_node_id(nodes, nodes_count);
+-      data = devm_kzalloc(dev, struct_size(data, nodes, max_node_id),
++      num_nodes = get_max_node_id(nodes, nodes_count) + 1;
++      data = devm_kzalloc(dev, struct_size(data, nodes, num_nodes),
+                           GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+-      data->num_nodes = max_node_id;
++      data->num_nodes = num_nodes;
+       provider = devm_kzalloc(dev, sizeof(*provider), GFP_KERNEL);
+       if (!provider)
+-- 
+2.35.1
+
diff --git a/queue-5.15/iommu-arm-smmu-qcom_iommu-add-of_node_put-when-break.patch b/queue-5.15/iommu-arm-smmu-qcom_iommu-add-of_node_put-when-break.patch
new file mode 100644 (file)
index 0000000..3420701
--- /dev/null
@@ -0,0 +1,45 @@
+From 52578d30973f6d9ecbdc5d7645917f1d04888993 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 20:49:55 +0800
+Subject: iommu/arm-smmu: qcom_iommu: Add of_node_put() when breaking out of
+ loop
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit a91eb6803c1c715738682fece095145cbd68fe0b ]
+
+In qcom_iommu_has_secure_context(), we should call of_node_put()
+for the reference 'child' when breaking out of for_each_child_of_node()
+which will automatically increase and decrease the refcount.
+
+Fixes: d051f28c8807 ("iommu/qcom: Initialize secure page table")
+Signed-off-by: Liang He <windhl@126.com>
+Link: https://lore.kernel.org/r/20220719124955.1242171-1-windhl@126.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/arm/arm-smmu/qcom_iommu.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+index b91874cb6cf3..a47cb654b704 100644
+--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
++++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+@@ -748,9 +748,12 @@ static bool qcom_iommu_has_secure_context(struct qcom_iommu_dev *qcom_iommu)
+ {
+       struct device_node *child;
+-      for_each_child_of_node(qcom_iommu->dev->of_node, child)
+-              if (of_device_is_compatible(child, "qcom,msm-iommu-v1-sec"))
++      for_each_child_of_node(qcom_iommu->dev->of_node, child) {
++              if (of_device_is_compatible(child, "qcom,msm-iommu-v1-sec")) {
++                      of_node_put(child);
+                       return true;
++              }
++      }
+       return false;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/iommu-exynos-handle-failed-iommu-device-registration.patch b/queue-5.15/iommu-exynos-handle-failed-iommu-device-registration.patch
new file mode 100644 (file)
index 0000000..1364713
--- /dev/null
@@ -0,0 +1,51 @@
+From 81793e6c8000636d1eb634fb0b3eb355a04e0c2e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 19:55:46 +0300
+Subject: iommu/exynos: Handle failed IOMMU device registration properly
+
+From: Sam Protsenko <semen.protsenko@linaro.org>
+
+[ Upstream commit fce398d2d02c0a9a2bedf7c7201b123e153e8963 ]
+
+If iommu_device_register() fails in exynos_sysmmu_probe(), the previous
+calls have to be cleaned up. In this case, the iommu_device_sysfs_add()
+should be cleaned up, by calling its remove counterpart call.
+
+Fixes: d2c302b6e8b1 ("iommu/exynos: Make use of iommu_device_register interface")
+Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Acked-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Link: https://lore.kernel.org/r/20220714165550.8884-3-semen.protsenko@linaro.org
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/exynos-iommu.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
+index 939ffa768986..f96acc3525e8 100644
+--- a/drivers/iommu/exynos-iommu.c
++++ b/drivers/iommu/exynos-iommu.c
+@@ -630,7 +630,7 @@ static int exynos_sysmmu_probe(struct platform_device *pdev)
+       ret = iommu_device_register(&data->iommu, &exynos_iommu_ops, dev);
+       if (ret)
+-              return ret;
++              goto err_iommu_register;
+       platform_set_drvdata(pdev, data);
+@@ -657,6 +657,10 @@ static int exynos_sysmmu_probe(struct platform_device *pdev)
+       pm_runtime_enable(dev);
+       return 0;
++
++err_iommu_register:
++      iommu_device_sysfs_remove(&data->iommu);
++      return ret;
+ }
+ static int __maybe_unused exynos_sysmmu_suspend(struct device *dev)
+-- 
+2.35.1
+
diff --git a/queue-5.15/ipv6-add-read_once-sk-sk_bound_dev_if-in-inet6_match.patch b/queue-5.15/ipv6-add-read_once-sk-sk_bound_dev_if-in-inet6_match.patch
new file mode 100644 (file)
index 0000000..3f0776b
--- /dev/null
@@ -0,0 +1,125 @@
+From e89a21387e9965c832fd2bcd9b049f085bb217eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 May 2022 11:55:49 -0700
+Subject: ipv6: add READ_ONCE(sk->sk_bound_dev_if) in INET6_MATCH()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 5d368f03280d3678433a7f119efe15dfbbb87bc8 ]
+
+INET6_MATCH() runs without holding a lock on the socket.
+
+We probably need to annotate most reads.
+
+This patch makes INET6_MATCH() an inline function
+to ease our changes.
+
+v2: inline function only defined if IS_ENABLED(CONFIG_IPV6)
+    Change the name to inet6_match(), this is no longer a macro.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/inet6_hashtables.h | 28 +++++++++++++++++++---------
+ net/ipv4/inet_hashtables.c     |  2 +-
+ net/ipv6/inet6_hashtables.c    |  6 +++---
+ net/ipv6/udp.c                 |  2 +-
+ 4 files changed, 24 insertions(+), 14 deletions(-)
+
+diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h
+index 81b965953036..f259e1ae14ba 100644
+--- a/include/net/inet6_hashtables.h
++++ b/include/net/inet6_hashtables.h
+@@ -103,15 +103,25 @@ struct sock *inet6_lookup(struct net *net, struct inet_hashinfo *hashinfo,
+                         const int dif);
+ int inet6_hash(struct sock *sk);
+-#endif /* IS_ENABLED(CONFIG_IPV6) */
+-#define INET6_MATCH(__sk, __net, __saddr, __daddr, __ports, __dif, __sdif) \
+-      (((__sk)->sk_portpair == (__ports))                     &&      \
+-       ((__sk)->sk_family == AF_INET6)                        &&      \
+-       ipv6_addr_equal(&(__sk)->sk_v6_daddr, (__saddr))               &&      \
+-       ipv6_addr_equal(&(__sk)->sk_v6_rcv_saddr, (__daddr))   &&      \
+-       (((__sk)->sk_bound_dev_if == (__dif))  ||                      \
+-        ((__sk)->sk_bound_dev_if == (__sdif)))                &&      \
+-       net_eq(sock_net(__sk), (__net)))
++static inline bool inet6_match(struct net *net, const struct sock *sk,
++                             const struct in6_addr *saddr,
++                             const struct in6_addr *daddr,
++                             const __portpair ports,
++                             const int dif, const int sdif)
++{
++      int bound_dev_if;
++
++      if (!net_eq(sock_net(sk), net) ||
++          sk->sk_family != AF_INET6 ||
++          sk->sk_portpair != ports ||
++          !ipv6_addr_equal(&sk->sk_v6_daddr, saddr) ||
++          !ipv6_addr_equal(&sk->sk_v6_rcv_saddr, daddr))
++              return false;
++
++      bound_dev_if = READ_ONCE(sk->sk_bound_dev_if);
++      return bound_dev_if == dif || bound_dev_if == sdif;
++}
++#endif /* IS_ENABLED(CONFIG_IPV6) */
+ #endif /* _INET6_HASHTABLES_H */
+diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
+index 7c502c4a160b..26c4dd4ec459 100644
+--- a/net/ipv4/inet_hashtables.c
++++ b/net/ipv4/inet_hashtables.c
+@@ -536,7 +536,7 @@ static bool inet_ehash_lookup_by_sk(struct sock *sk,
+               }
+ #if IS_ENABLED(CONFIG_IPV6)
+               else if (sk->sk_family == AF_INET6) {
+-                      if (unlikely(INET6_MATCH(esk, net,
++                      if (unlikely(inet6_match(net, esk,
+                                                &sk->sk_v6_daddr,
+                                                &sk->sk_v6_rcv_saddr,
+                                                ports, dif, sdif))) {
+diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
+index 40203255ed88..b4a5e01e1201 100644
+--- a/net/ipv6/inet6_hashtables.c
++++ b/net/ipv6/inet6_hashtables.c
+@@ -71,12 +71,12 @@ struct sock *__inet6_lookup_established(struct net *net,
+       sk_nulls_for_each_rcu(sk, node, &head->chain) {
+               if (sk->sk_hash != hash)
+                       continue;
+-              if (!INET6_MATCH(sk, net, saddr, daddr, ports, dif, sdif))
++              if (!inet6_match(net, sk, saddr, daddr, ports, dif, sdif))
+                       continue;
+               if (unlikely(!refcount_inc_not_zero(&sk->sk_refcnt)))
+                       goto out;
+-              if (unlikely(!INET6_MATCH(sk, net, saddr, daddr, ports, dif, sdif))) {
++              if (unlikely(!inet6_match(net, sk, saddr, daddr, ports, dif, sdif))) {
+                       sock_gen_put(sk);
+                       goto begin;
+               }
+@@ -269,7 +269,7 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,
+               if (sk2->sk_hash != hash)
+                       continue;
+-              if (likely(INET6_MATCH(sk2, net, saddr, daddr, ports,
++              if (likely(inet6_match(net, sk2, saddr, daddr, ports,
+                                      dif, sdif))) {
+                       if (sk2->sk_state == TCP_TIME_WAIT) {
+                               tw = inet_twsk(sk2);
+diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
+index 932c6f2a5494..4a9afdbd5f29 100644
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -1035,7 +1035,7 @@ static struct sock *__udp6_lib_demux_lookup(struct net *net,
+       udp_portaddr_for_each_entry_rcu(sk, &hslot2->head) {
+               if (sk->sk_state == TCP_ESTABLISHED &&
+-                  INET6_MATCH(sk, net, rmt_addr, loc_addr, ports, dif, sdif))
++                  inet6_match(net, sk, rmt_addr, loc_addr, ports, dif, sdif))
+                       return sk;
+               /* Only check first socket in chain */
+               break;
+-- 
+2.35.1
+
diff --git a/queue-5.15/irqchip-mips-gic-check-the-return-value-of-ioremap-i.patch b/queue-5.15/irqchip-mips-gic-check-the-return-value-of-ioremap-i.patch
new file mode 100644 (file)
index 0000000..73968e2
--- /dev/null
@@ -0,0 +1,40 @@
+From d9603e8b9904d10fffac0385eb11816a1fb74cdf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Jul 2022 18:01:28 +0800
+Subject: irqchip/mips-gic: Check the return value of ioremap() in
+ gic_of_init()
+
+From: William Dean <williamsukatube@163.com>
+
+[ Upstream commit 71349cc85e5930dce78ed87084dee098eba24b59 ]
+
+The function ioremap() in gic_of_init() can fail, so
+its return value should be checked.
+
+Reported-by: Hacash Robot <hacashRobot@santino.com>
+Signed-off-by: William Dean <williamsukatube@163.com>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20220723100128.2964304-1-williamsukatube@163.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/irqchip/irq-mips-gic.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
+index f03f47ffea1e..d815285f1efe 100644
+--- a/drivers/irqchip/irq-mips-gic.c
++++ b/drivers/irqchip/irq-mips-gic.c
+@@ -767,6 +767,10 @@ static int __init gic_of_init(struct device_node *node,
+       }
+       mips_gic_base = ioremap(gic_base, gic_len);
++      if (!mips_gic_base) {
++              pr_err("Failed to ioremap gic_base\n");
++              return -ENOMEM;
++      }
+       gicconfig = read_gic_config();
+       gic_shared_intrs = gicconfig & GIC_CONFIG_NUMINTERRUPTS;
+-- 
+2.35.1
+
diff --git a/queue-5.15/irqchip-mips-gic-only-register-ipi-domain-when-smp-i.patch b/queue-5.15/irqchip-mips-gic-only-register-ipi-domain-when-smp-i.patch
new file mode 100644 (file)
index 0000000..e106fbd
--- /dev/null
@@ -0,0 +1,181 @@
+From ac9c10a586652204fb8d7875c0c4f08603ffe3ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 15:00:49 -0500
+Subject: irqchip/mips-gic: Only register IPI domain when SMP is enabled
+
+From: Samuel Holland <samuel@sholland.org>
+
+[ Upstream commit 8190cc572981f2f13b6ffc26c7cfa7899e5d3ccc ]
+
+The MIPS GIC irqchip driver may be selected in a uniprocessor
+configuration, but it unconditionally registers an IPI domain.
+
+Limit the part of the driver dealing with IPIs to only be compiled when
+GENERIC_IRQ_IPI is enabled, which corresponds to an SMP configuration.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Samuel Holland <samuel@sholland.org>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20220701200056.46555-2-samuel@sholland.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/irqchip/Kconfig        |  3 +-
+ drivers/irqchip/irq-mips-gic.c | 80 +++++++++++++++++++++++-----------
+ 2 files changed, 56 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
+index aca7b595c4c7..8f9c52873338 100644
+--- a/drivers/irqchip/Kconfig
++++ b/drivers/irqchip/Kconfig
+@@ -304,7 +304,8 @@ config KEYSTONE_IRQ
+ config MIPS_GIC
+       bool
+-      select GENERIC_IRQ_IPI
++      select GENERIC_IRQ_IPI if SMP
++      select IRQ_DOMAIN_HIERARCHY
+       select MIPS_CM
+ config INGENIC_IRQ
+diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
+index 54c7092cc61d..f03f47ffea1e 100644
+--- a/drivers/irqchip/irq-mips-gic.c
++++ b/drivers/irqchip/irq-mips-gic.c
+@@ -51,13 +51,15 @@ static DEFINE_PER_CPU_READ_MOSTLY(unsigned long[GIC_MAX_LONGS], pcpu_masks);
+ static DEFINE_SPINLOCK(gic_lock);
+ static struct irq_domain *gic_irq_domain;
+-static struct irq_domain *gic_ipi_domain;
+ static int gic_shared_intrs;
+ static unsigned int gic_cpu_pin;
+ static unsigned int timer_cpu_pin;
+ static struct irq_chip gic_level_irq_controller, gic_edge_irq_controller;
++
++#ifdef CONFIG_GENERIC_IRQ_IPI
+ static DECLARE_BITMAP(ipi_resrv, GIC_MAX_INTRS);
+ static DECLARE_BITMAP(ipi_available, GIC_MAX_INTRS);
++#endif /* CONFIG_GENERIC_IRQ_IPI */
+ static struct gic_all_vpes_chip_data {
+       u32     map;
+@@ -460,9 +462,11 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq,
+       u32 map;
+       if (hwirq >= GIC_SHARED_HWIRQ_BASE) {
++#ifdef CONFIG_GENERIC_IRQ_IPI
+               /* verify that shared irqs don't conflict with an IPI irq */
+               if (test_bit(GIC_HWIRQ_TO_SHARED(hwirq), ipi_resrv))
+                       return -EBUSY;
++#endif /* CONFIG_GENERIC_IRQ_IPI */
+               err = irq_domain_set_hwirq_and_chip(d, virq, hwirq,
+                                                   &gic_level_irq_controller,
+@@ -551,6 +555,8 @@ static const struct irq_domain_ops gic_irq_domain_ops = {
+       .map = gic_irq_domain_map,
+ };
++#ifdef CONFIG_GENERIC_IRQ_IPI
++
+ static int gic_ipi_domain_xlate(struct irq_domain *d, struct device_node *ctrlr,
+                               const u32 *intspec, unsigned int intsize,
+                               irq_hw_number_t *out_hwirq,
+@@ -654,6 +660,48 @@ static const struct irq_domain_ops gic_ipi_domain_ops = {
+       .match = gic_ipi_domain_match,
+ };
++static int gic_register_ipi_domain(struct device_node *node)
++{
++      struct irq_domain *gic_ipi_domain;
++      unsigned int v[2], num_ipis;
++
++      gic_ipi_domain = irq_domain_add_hierarchy(gic_irq_domain,
++                                                IRQ_DOMAIN_FLAG_IPI_PER_CPU,
++                                                GIC_NUM_LOCAL_INTRS + gic_shared_intrs,
++                                                node, &gic_ipi_domain_ops, NULL);
++      if (!gic_ipi_domain) {
++              pr_err("Failed to add IPI domain");
++              return -ENXIO;
++      }
++
++      irq_domain_update_bus_token(gic_ipi_domain, DOMAIN_BUS_IPI);
++
++      if (node &&
++          !of_property_read_u32_array(node, "mti,reserved-ipi-vectors", v, 2)) {
++              bitmap_set(ipi_resrv, v[0], v[1]);
++      } else {
++              /*
++               * Reserve 2 interrupts per possible CPU/VP for use as IPIs,
++               * meeting the requirements of arch/mips SMP.
++               */
++              num_ipis = 2 * num_possible_cpus();
++              bitmap_set(ipi_resrv, gic_shared_intrs - num_ipis, num_ipis);
++      }
++
++      bitmap_copy(ipi_available, ipi_resrv, GIC_MAX_INTRS);
++
++      return 0;
++}
++
++#else /* !CONFIG_GENERIC_IRQ_IPI */
++
++static inline int gic_register_ipi_domain(struct device_node *node)
++{
++      return 0;
++}
++
++#endif /* !CONFIG_GENERIC_IRQ_IPI */
++
+ static int gic_cpu_startup(unsigned int cpu)
+ {
+       /* Enable or disable EIC */
+@@ -672,11 +720,12 @@ static int gic_cpu_startup(unsigned int cpu)
+ static int __init gic_of_init(struct device_node *node,
+                             struct device_node *parent)
+ {
+-      unsigned int cpu_vec, i, gicconfig, v[2], num_ipis;
++      unsigned int cpu_vec, i, gicconfig;
+       unsigned long reserved;
+       phys_addr_t gic_base;
+       struct resource res;
+       size_t gic_len;
++      int ret;
+       /* Find the first available CPU vector. */
+       i = 0;
+@@ -765,30 +814,9 @@ static int __init gic_of_init(struct device_node *node,
+               return -ENXIO;
+       }
+-      gic_ipi_domain = irq_domain_add_hierarchy(gic_irq_domain,
+-                                                IRQ_DOMAIN_FLAG_IPI_PER_CPU,
+-                                                GIC_NUM_LOCAL_INTRS + gic_shared_intrs,
+-                                                node, &gic_ipi_domain_ops, NULL);
+-      if (!gic_ipi_domain) {
+-              pr_err("Failed to add IPI domain");
+-              return -ENXIO;
+-      }
+-
+-      irq_domain_update_bus_token(gic_ipi_domain, DOMAIN_BUS_IPI);
+-
+-      if (node &&
+-          !of_property_read_u32_array(node, "mti,reserved-ipi-vectors", v, 2)) {
+-              bitmap_set(ipi_resrv, v[0], v[1]);
+-      } else {
+-              /*
+-               * Reserve 2 interrupts per possible CPU/VP for use as IPIs,
+-               * meeting the requirements of arch/mips SMP.
+-               */
+-              num_ipis = 2 * num_possible_cpus();
+-              bitmap_set(ipi_resrv, gic_shared_intrs - num_ipis, num_ipis);
+-      }
+-
+-      bitmap_copy(ipi_available, ipi_resrv, GIC_MAX_INTRS);
++      ret = gic_register_ipi_domain(node);
++      if (ret)
++              return ret;
+       board_bind_eic_interrupt = &gic_bind_eic_interrupt;
+-- 
+2.35.1
+
diff --git a/queue-5.15/irqdomain-report-irq-number-for-nomap-domains.patch b/queue-5.15/irqdomain-report-irq-number-for-nomap-domains.patch
new file mode 100644 (file)
index 0000000..e350079
--- /dev/null
@@ -0,0 +1,44 @@
+From aeb4c5da71511e26ab3457582c3a5b5872e19e33 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 06:36:40 +0000
+Subject: irqdomain: Report irq number for NOMAP domains
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Xu Qiang <xuqiang36@huawei.com>
+
+[ Upstream commit 6f194c99f466147148cc08452718b46664112548 ]
+
+When using a NOMAP domain, __irq_resolve_mapping() doesn't store
+the Linux IRQ number at the address optionally provided by the caller.
+While this isn't a huge deal (the returned value is guaranteed
+to the hwirq that was passed as a parameter), let's honour the letter
+of the API by writing the expected value.
+
+Fixes: d22558dd0a6c (“irqdomain: Introduce irq_resolve_mapping()”)
+Signed-off-by: Xu Qiang <xuqiang36@huawei.com>
+[maz: commit message]
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20220719063641.56541-2-xuqiang36@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/irq/irqdomain.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
+index 4d8fc65cf38f..035e3038c4de 100644
+--- a/kernel/irq/irqdomain.c
++++ b/kernel/irq/irqdomain.c
+@@ -910,6 +910,8 @@ struct irq_desc *__irq_resolve_mapping(struct irq_domain *domain,
+                       data = irq_domain_get_irq_data(domain, hwirq);
+                       if (data && data->hwirq == hwirq)
+                               desc = irq_data_to_desc(data);
++                      if (irq && desc)
++                              *irq = hwirq;
+               }
+               return desc;
+-- 
+2.35.1
+
diff --git a/queue-5.15/jbd2-fix-assertion-jh-b_frozen_data-null-failure-whe.patch b/queue-5.15/jbd2-fix-assertion-jh-b_frozen_data-null-failure-whe.patch
new file mode 100644 (file)
index 0000000..5509734
--- /dev/null
@@ -0,0 +1,110 @@
+From 89544b06924aeb49a55a3db7d4eecfc64df8a89b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 20:51:52 +0800
+Subject: jbd2: fix assertion 'jh->b_frozen_data == NULL' failure when journal
+ aborted
+
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+
+[ Upstream commit 4a734f0869f970b8a9b65062ea40b09a5da9dba8 ]
+
+Following process will fail assertion 'jh->b_frozen_data == NULL' in
+jbd2_journal_dirty_metadata():
+
+                   jbd2_journal_commit_transaction
+unlink(dir/a)
+ jh->b_transaction = trans1
+ jh->b_jlist = BJ_Metadata
+                    journal->j_running_transaction = NULL
+                    trans1->t_state = T_COMMIT
+unlink(dir/b)
+ handle->h_trans = trans2
+ do_get_write_access
+  jh->b_modified = 0
+  jh->b_frozen_data = frozen_buffer
+  jh->b_next_transaction = trans2
+ jbd2_journal_dirty_metadata
+  is_handle_aborted
+   is_journal_aborted // return false
+
+           --> jbd2 abort <--
+
+                     while (commit_transaction->t_buffers)
+                      if (is_journal_aborted)
+                       jbd2_journal_refile_buffer
+                        __jbd2_journal_refile_buffer
+                         WRITE_ONCE(jh->b_transaction,
+                                               jh->b_next_transaction)
+                         WRITE_ONCE(jh->b_next_transaction, NULL)
+                         __jbd2_journal_file_buffer(jh, BJ_Reserved)
+        J_ASSERT_JH(jh, jh->b_frozen_data == NULL) // assertion failure !
+
+The reproducer (See detail in [Link]) reports:
+ ------------[ cut here ]------------
+ kernel BUG at fs/jbd2/transaction.c:1629!
+ invalid opcode: 0000 [#1] PREEMPT SMP
+ CPU: 2 PID: 584 Comm: unlink Tainted: G        W
+ 5.19.0-rc6-00115-g4a57a8400075-dirty #697
+ RIP: 0010:jbd2_journal_dirty_metadata+0x3c5/0x470
+ RSP: 0018:ffffc90000be7ce0 EFLAGS: 00010202
+ Call Trace:
+  <TASK>
+  __ext4_handle_dirty_metadata+0xa0/0x290
+  ext4_handle_dirty_dirblock+0x10c/0x1d0
+  ext4_delete_entry+0x104/0x200
+  __ext4_unlink+0x22b/0x360
+  ext4_unlink+0x275/0x390
+  vfs_unlink+0x20b/0x4c0
+  do_unlinkat+0x42f/0x4c0
+  __x64_sys_unlink+0x37/0x50
+  do_syscall_64+0x35/0x80
+
+After journal aborting, __jbd2_journal_refile_buffer() is executed with
+holding @jh->b_state_lock, we can fix it by moving 'is_handle_aborted()'
+into the area protected by @jh->b_state_lock.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=216251
+Fixes: 470decc613ab20 ("[PATCH] jbd2: initial copy of files from jbd")
+Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Link: https://lore.kernel.org/r/20220715125152.4022726-1-chengzhihao1@huawei.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/jbd2/transaction.c | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
+index 6a3caedd2285..53cb236b53db 100644
+--- a/fs/jbd2/transaction.c
++++ b/fs/jbd2/transaction.c
+@@ -1477,8 +1477,6 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
+       struct journal_head *jh;
+       int ret = 0;
+-      if (is_handle_aborted(handle))
+-              return -EROFS;
+       if (!buffer_jbd(bh))
+               return -EUCLEAN;
+@@ -1525,6 +1523,18 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
+       journal = transaction->t_journal;
+       spin_lock(&jh->b_state_lock);
++      if (is_handle_aborted(handle)) {
++              /*
++               * Check journal aborting with @jh->b_state_lock locked,
++               * since 'jh->b_transaction' could be replaced with
++               * 'jh->b_next_transaction' during old transaction
++               * committing if journal aborted, which may fail
++               * assertion on 'jh->b_frozen_data == NULL'.
++               */
++              ret = -EROFS;
++              goto out_unlock_bh;
++      }
++
+       if (jh->b_modified == 0) {
+               /*
+                * This buffer's got modified and becoming part
+-- 
+2.35.1
+
diff --git a/queue-5.15/jbd2-fix-outstanding-credits-assert-in-jbd2_journal_.patch b/queue-5.15/jbd2-fix-outstanding-credits-assert-in-jbd2_journal_.patch
new file mode 100644 (file)
index 0000000..c8126cf
--- /dev/null
@@ -0,0 +1,75 @@
+From 18a6e57ce5e966ddd45864aae1a303c9a260346e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Jun 2022 21:04:26 +0800
+Subject: jbd2: fix outstanding credits assert in
+ jbd2_journal_commit_transaction()
+
+From: Zhang Yi <yi.zhang@huawei.com>
+
+[ Upstream commit a89573ce4ad32f19f43ec669771726817e185be0 ]
+
+We catch an assert problem in jbd2_journal_commit_transaction() when
+doing fsstress and request falut injection tests. The problem is
+happened in a race condition between jbd2_journal_commit_transaction()
+and ext4_end_io_end(). Firstly, ext4_writepages() writeback dirty pages
+and start reserved handle, and then the journal was aborted due to some
+previous metadata IO error, jbd2_journal_abort() start to commit current
+running transaction, the committing procedure could be raced by
+ext4_end_io_end() and lead to subtract j_reserved_credits twice from
+commit_transaction->t_outstanding_credits, finally the
+t_outstanding_credits is mistakenly smaller than t_nr_buffers and
+trigger assert.
+
+kjournald2           kworker
+
+jbd2_journal_commit_transaction()
+ write_unlock(&journal->j_state_lock);
+ atomic_sub(j_reserved_credits, t_outstanding_credits); //sub once
+
+                    jbd2_journal_start_reserved()
+                     start_this_handle()  //detect aborted journal
+                     jbd2_journal_free_reserved()  //get running transaction
+                       read_lock(&journal->j_state_lock)
+                       __jbd2_journal_unreserve_handle()
+                      atomic_sub(j_reserved_credits, t_outstanding_credits);
+                       //sub again
+                       read_unlock(&journal->j_state_lock);
+
+ journal->j_running_transaction = NULL;
+ J_ASSERT(t_nr_buffers <= t_outstanding_credits) //bomb!!!
+
+Fix this issue by using journal->j_state_lock to protect the subtraction
+in jbd2_journal_commit_transaction().
+
+Fixes: 96f1e0974575 ("jbd2: avoid long hold times of j_state_lock while committing a transaction")
+Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20220611130426.2013258-1-yi.zhang@huawei.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/jbd2/commit.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
+index 34b1406c06fd..69538061c551 100644
+--- a/fs/jbd2/commit.c
++++ b/fs/jbd2/commit.c
+@@ -564,13 +564,13 @@ void jbd2_journal_commit_transaction(journal_t *journal)
+        */
+       jbd2_journal_switch_revoke_table(journal);
++      write_lock(&journal->j_state_lock);
+       /*
+        * Reserved credits cannot be claimed anymore, free them
+        */
+       atomic_sub(atomic_read(&journal->j_reserved_credits),
+                  &commit_transaction->t_outstanding_credits);
+-      write_lock(&journal->j_state_lock);
+       trace_jbd2_commit_flushing(journal, commit_transaction);
+       stats.run.rs_flushing = jiffies;
+       stats.run.rs_locked = jbd2_time_diff(stats.run.rs_locked,
+-- 
+2.35.1
+
diff --git a/queue-5.15/kasan-test-silence-gcc-12-warnings.patch b/queue-5.15/kasan-test-silence-gcc-12-warnings.patch
new file mode 100644 (file)
index 0000000..8cf3010
--- /dev/null
@@ -0,0 +1,107 @@
+From 0ed08f0e7300469899f301a169525ba97ce05f87 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jun 2022 14:40:24 -0700
+Subject: kasan: test: Silence GCC 12 warnings
+
+From: Kees Cook <keescook@chromium.org>
+
+[ Upstream commit aaf50b1969d7933a51ea421b11432a7fb90974e3 ]
+
+GCC 12 continues to get smarter about array accesses. The KASAN tests
+are expecting to explicitly test out-of-bounds conditions at run-time,
+so hide the variable from GCC, to avoid warnings like:
+
+../lib/test_kasan.c: In function 'ksize_uaf':
+../lib/test_kasan.c:790:61: warning: array subscript 120 is outside array bounds of 'void[120]' [-Warray-bounds]
+  790 |         KUNIT_EXPECT_KASAN_FAIL(test, ((volatile char *)ptr)[size]);
+      |                                       ~~~~~~~~~~~~~~~~~~~~~~^~~~~~
+../lib/test_kasan.c:97:9: note: in definition of macro 'KUNIT_EXPECT_KASAN_FAIL'
+   97 |         expression; \
+      |         ^~~~~~~~~~
+
+Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
+Cc: Alexander Potapenko <glider@google.com>
+Cc: Andrey Konovalov <andreyknvl@gmail.com>
+Cc: Dmitry Vyukov <dvyukov@google.com>
+Cc: Vincenzo Frascino <vincenzo.frascino@arm.com>
+Cc: kasan-dev@googlegroups.com
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Link: https://lore.kernel.org/r/20220608214024.1068451-1-keescook@chromium.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/test_kasan.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/lib/test_kasan.c b/lib/test_kasan.c
+index 8835e0784578..89f444cabd4a 100644
+--- a/lib/test_kasan.c
++++ b/lib/test_kasan.c
+@@ -125,6 +125,7 @@ static void kmalloc_oob_right(struct kunit *test)
+       ptr = kmalloc(size, GFP_KERNEL);
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
++      OPTIMIZER_HIDE_VAR(ptr);
+       /*
+        * An unaligned access past the requested kmalloc size.
+        * Only generic KASAN can precisely detect these.
+@@ -153,6 +154,7 @@ static void kmalloc_oob_left(struct kunit *test)
+       ptr = kmalloc(size, GFP_KERNEL);
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
++      OPTIMIZER_HIDE_VAR(ptr);
+       KUNIT_EXPECT_KASAN_FAIL(test, *ptr = *(ptr - 1));
+       kfree(ptr);
+ }
+@@ -165,6 +167,7 @@ static void kmalloc_node_oob_right(struct kunit *test)
+       ptr = kmalloc_node(size, GFP_KERNEL, 0);
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
++      OPTIMIZER_HIDE_VAR(ptr);
+       KUNIT_EXPECT_KASAN_FAIL(test, ptr[0] = ptr[size]);
+       kfree(ptr);
+ }
+@@ -185,6 +188,7 @@ static void kmalloc_pagealloc_oob_right(struct kunit *test)
+       ptr = kmalloc(size, GFP_KERNEL);
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
++      OPTIMIZER_HIDE_VAR(ptr);
+       KUNIT_EXPECT_KASAN_FAIL(test, ptr[size + OOB_TAG_OFF] = 0);
+       kfree(ptr);
+@@ -265,6 +269,7 @@ static void kmalloc_large_oob_right(struct kunit *test)
+       ptr = kmalloc(size, GFP_KERNEL);
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
++      OPTIMIZER_HIDE_VAR(ptr);
+       KUNIT_EXPECT_KASAN_FAIL(test, ptr[size] = 0);
+       kfree(ptr);
+ }
+@@ -404,6 +409,8 @@ static void kmalloc_oob_16(struct kunit *test)
+       ptr2 = kmalloc(sizeof(*ptr2), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr2);
++      OPTIMIZER_HIDE_VAR(ptr1);
++      OPTIMIZER_HIDE_VAR(ptr2);
+       KUNIT_EXPECT_KASAN_FAIL(test, *ptr1 = *ptr2);
+       kfree(ptr1);
+       kfree(ptr2);
+@@ -712,6 +719,8 @@ static void ksize_unpoisons_memory(struct kunit *test)
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
+       real_size = ksize(ptr);
++      OPTIMIZER_HIDE_VAR(ptr);
++
+       /* This access shouldn't trigger a KASAN report. */
+       ptr[size] = 'x';
+@@ -734,6 +743,7 @@ static void ksize_uaf(struct kunit *test)
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
+       kfree(ptr);
++      OPTIMIZER_HIDE_VAR(ptr);
+       KUNIT_EXPECT_KASAN_FAIL(test, ksize(ptr));
+       KUNIT_EXPECT_KASAN_FAIL(test, ((volatile char *)ptr)[0]);
+       KUNIT_EXPECT_KASAN_FAIL(test, ((volatile char *)ptr)[size]);
+-- 
+2.35.1
+
diff --git a/queue-5.15/kfifo-fix-kfifo_to_user-return-type.patch b/queue-5.15/kfifo-fix-kfifo_to_user-return-type.patch
new file mode 100644 (file)
index 0000000..223d4e9
--- /dev/null
@@ -0,0 +1,44 @@
+From e44b628278908751a4b2eaa189c72ca80dc4a5d1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jun 2022 08:30:04 +0300
+Subject: kfifo: fix kfifo_to_user() return type
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit 045ed31e23aea840648c290dbde04797064960db ]
+
+The kfifo_to_user() macro is supposed to return zero for success or
+negative error codes.  Unfortunately, there is a signedness bug so it
+returns unsigned int.  This only affects callers which try to save the
+result in ssize_t and as far as I can see the only place which does that
+is line6_hwdep_read().
+
+TL;DR: s/_uint/_int/.
+
+Link: https://lkml.kernel.org/r/YrVL3OJVLlNhIMFs@kili
+Fixes: 144ecf310eb5 ("kfifo: fix kfifo_alloc() to return a signed int value")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Cc: Stefani Seibold <stefani@seibold.net>
+Cc: Randy Dunlap <randy.dunlap@oracle.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/kfifo.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h
+index 86249476b57f..0b35a41440ff 100644
+--- a/include/linux/kfifo.h
++++ b/include/linux/kfifo.h
+@@ -688,7 +688,7 @@ __kfifo_uint_must_check_helper( \
+  * writer, you don't need extra locking to use these macro.
+  */
+ #define       kfifo_to_user(fifo, to, len, copied) \
+-__kfifo_uint_must_check_helper( \
++__kfifo_int_must_check_helper( \
+ ({ \
+       typeof((fifo) + 1) __tmp = (fifo); \
+       void __user *__to = (to); \
+-- 
+2.35.1
+
diff --git a/queue-5.15/kprobes-forbid-probing-on-trampoline-and-bpf-code-ar.patch b/queue-5.15/kprobes-forbid-probing-on-trampoline-and-bpf-code-ar.patch
new file mode 100644 (file)
index 0000000..cd1fffc
--- /dev/null
@@ -0,0 +1,52 @@
+From 802ee1b8ac6f858bb1bb605622e1d15b67ace33f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Aug 2022 11:37:19 +0800
+Subject: kprobes: Forbid probing on trampoline and BPF code areas
+
+From: Chen Zhongjin <chenzhongjin@huawei.com>
+
+[ Upstream commit 28f6c37a2910f565b4f5960df52b2eccae28c891 ]
+
+kernel_text_address() treats ftrace_trampoline, kprobe_insn_slot
+and bpf_text_address as valid kprobe addresses - which is not ideal.
+
+These text areas are removable and changeable without any notification
+to kprobes, and probing on them can trigger unexpected behavior:
+
+  https://lkml.org/lkml/2022/7/26/1148
+
+Considering that jump_label and static_call text are already
+forbiden to probe, kernel_text_address() should be replaced with
+core_kernel_text() and is_module_text_address() to check other text
+areas which are unsafe to kprobe.
+
+[ mingo: Rewrote the changelog. ]
+
+Fixes: 5b485629ba0d ("kprobes, extable: Identify kprobes trampolines as kernel text area")
+Fixes: 74451e66d516 ("bpf: make jited programs visible in traces")
+Signed-off-by: Chen Zhongjin <chenzhongjin@huawei.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Link: https://lore.kernel.org/r/20220801033719.228248-1-chenzhongjin@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/kprobes.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/kprobes.c b/kernel/kprobes.c
+index 2ef90d15699f..3a3c0166bd1f 100644
+--- a/kernel/kprobes.c
++++ b/kernel/kprobes.c
+@@ -1559,7 +1559,8 @@ static int check_kprobe_address_safe(struct kprobe *p,
+       preempt_disable();
+       /* Ensure it is not in reserved area nor out of text */
+-      if (!kernel_text_address((unsigned long) p->addr) ||
++      if (!(core_kernel_text((unsigned long) p->addr) ||
++          is_module_text_address((unsigned long) p->addr)) ||
+           within_kprobe_blacklist((unsigned long) p->addr) ||
+           jump_label_text_reserved(p->addr, p->addr) ||
+           static_call_text_reserved(p->addr, p->addr) ||
+-- 
+2.35.1
+
diff --git a/queue-5.15/kvm-arm64-don-t-return-from-void-function.patch b/queue-5.15/kvm-arm64-don-t-return-from-void-function.patch
new file mode 100644 (file)
index 0000000..4522f73
--- /dev/null
@@ -0,0 +1,54 @@
+From 999d3e6b7f98d9010692dd1fbf4b016a9d62a445 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Jul 2022 14:23:10 +0000
+Subject: KVM: arm64: Don't return from void function
+
+From: Quentin Perret <qperret@google.com>
+
+[ Upstream commit 1c3ace2b8b3995d3213c5e2d2aca01a0577a3b0f ]
+
+Although harmless, the return statement in kvm_unexpected_el2_exception
+is rather confusing as the function itself has a void return type. The
+C standard is also pretty clear that "A return statement with an
+expression shall not appear in a function whose return type is void".
+Given that this return statement does not seem to add any actual value,
+let's not pointlessly violate the standard.
+
+Build-tested with GCC 10 and CLANG 13 for good measure, the disassembled
+code is identical with or without the return statement.
+
+Fixes: e9ee186bb735 ("KVM: arm64: Add kvm_extable for vaxorcism code")
+Signed-off-by: Quentin Perret <qperret@google.com>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20220705142310.3847918-1-qperret@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/kvm/hyp/nvhe/switch.c | 2 +-
+ arch/arm64/kvm/hyp/vhe/switch.c  | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
+index a34b01cc8ab9..4db5409f40c4 100644
+--- a/arch/arm64/kvm/hyp/nvhe/switch.c
++++ b/arch/arm64/kvm/hyp/nvhe/switch.c
+@@ -279,5 +279,5 @@ void __noreturn hyp_panic(void)
+ asmlinkage void kvm_unexpected_el2_exception(void)
+ {
+-      return __kvm_unexpected_el2_exception();
++      __kvm_unexpected_el2_exception();
+ }
+diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
+index d88d3c143a73..813e6e2178c1 100644
+--- a/arch/arm64/kvm/hyp/vhe/switch.c
++++ b/arch/arm64/kvm/hyp/vhe/switch.c
+@@ -220,5 +220,5 @@ void __noreturn hyp_panic(void)
+ asmlinkage void kvm_unexpected_el2_exception(void)
+ {
+-      return __kvm_unexpected_el2_exception();
++      __kvm_unexpected_el2_exception();
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/kvm-don-t-set-accessed-dirty-bits-for-zero_page.patch b/queue-5.15/kvm-don-t-set-accessed-dirty-bits-for-zero_page.patch
new file mode 100644 (file)
index 0000000..6d6d302
--- /dev/null
@@ -0,0 +1,64 @@
+From a71976a3eae29082de9cfbc85420c4801d8c4e54 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Apr 2022 01:04:09 +0000
+Subject: KVM: Don't set Accessed/Dirty bits for ZERO_PAGE
+
+From: Sean Christopherson <seanjc@google.com>
+
+[ Upstream commit a1040b0d42acf69bb4f6dbdc54c2dcd78eea1de5 ]
+
+Don't set Accessed/Dirty bits for a struct page with PG_reserved set,
+i.e. don't set A/D bits for the ZERO_PAGE.  The ZERO_PAGE (or pages
+depending on the architecture) should obviously never be written, and
+similarly there's no point in marking it accessed as the page will never
+be swapped out or reclaimed.  The comment in page-flags.h is quite clear
+that PG_reserved pages should be managed only by their owner, and
+strictly following that mandate also simplifies KVM's logic.
+
+Fixes: 7df003c85218 ("KVM: fix overflow of zero page refcount with ksm running")
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Message-Id: <20220429010416.2788472-4-seanjc@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ virt/kvm/kvm_main.c | 16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
+index 0816b8018cde..251b4143f505 100644
+--- a/virt/kvm/kvm_main.c
++++ b/virt/kvm/kvm_main.c
+@@ -2762,16 +2762,28 @@ void kvm_release_pfn_dirty(kvm_pfn_t pfn)
+ }
+ EXPORT_SYMBOL_GPL(kvm_release_pfn_dirty);
++static bool kvm_is_ad_tracked_pfn(kvm_pfn_t pfn)
++{
++      if (!pfn_valid(pfn))
++              return false;
++
++      /*
++       * Per page-flags.h, pages tagged PG_reserved "should in general not be
++       * touched (e.g. set dirty) except by its owner".
++       */
++      return !PageReserved(pfn_to_page(pfn));
++}
++
+ void kvm_set_pfn_dirty(kvm_pfn_t pfn)
+ {
+-      if (!kvm_is_reserved_pfn(pfn) && !kvm_is_zone_device_pfn(pfn))
++      if (kvm_is_ad_tracked_pfn(pfn))
+               SetPageDirty(pfn_to_page(pfn));
+ }
+ EXPORT_SYMBOL_GPL(kvm_set_pfn_dirty);
+ void kvm_set_pfn_accessed(kvm_pfn_t pfn)
+ {
+-      if (!kvm_is_reserved_pfn(pfn) && !kvm_is_zone_device_pfn(pfn))
++      if (kvm_is_ad_tracked_pfn(pfn))
+               mark_page_accessed(pfn_to_page(pfn));
+ }
+ EXPORT_SYMBOL_GPL(kvm_set_pfn_accessed);
+-- 
+2.35.1
+
diff --git a/queue-5.15/kvm-nvmx-set-umip-bit-cr4_fixed1-msr-when-emulating-.patch b/queue-5.15/kvm-nvmx-set-umip-bit-cr4_fixed1-msr-when-emulating-.patch
new file mode 100644 (file)
index 0000000..389fbfe
--- /dev/null
@@ -0,0 +1,44 @@
+From d4674a970c03f691260e769528ae314465982cbe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jun 2022 21:36:00 +0000
+Subject: KVM: nVMX: Set UMIP bit CR4_FIXED1 MSR when emulating UMIP
+
+From: Sean Christopherson <seanjc@google.com>
+
+[ Upstream commit a910b5ab6b250a88fff1866bf708642d83317466 ]
+
+Make UMIP an "allowed-1" bit CR4_FIXED1 MSR when KVM is emulating UMIP.
+KVM emulates UMIP for both L1 and L2, and so should enumerate that L2 is
+allowed to have CR4.UMIP=1.  Not setting the bit doesn't immediately
+break nVMX, as KVM does set/clear the bit in CR4_FIXED1 in response to a
+guest CPUID update, i.e. KVM will correctly (dis)allow nested VM-Entry
+based on whether or not UMIP is exposed to L1.  That said, KVM should
+enumerate the bit as being allowed from time zero, e.g. userspace will
+see the wrong value if the MSR is read before CPUID is written.
+
+Fixes: 0367f205a3b7 ("KVM: vmx: add support for emulating UMIP")
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Message-Id: <20220607213604.3346000-12-seanjc@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kvm/vmx/nested.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
+index 256a2aba830a..9f845556dde8 100644
+--- a/arch/x86/kvm/vmx/nested.c
++++ b/arch/x86/kvm/vmx/nested.c
+@@ -6736,6 +6736,9 @@ void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, u32 ept_caps)
+       rdmsrl(MSR_IA32_VMX_CR0_FIXED1, msrs->cr0_fixed1);
+       rdmsrl(MSR_IA32_VMX_CR4_FIXED1, msrs->cr4_fixed1);
++      if (vmx_umip_emulated())
++              msrs->cr4_fixed1 |= X86_CR4_UMIP;
++
+       msrs->vmcs_enum = nested_vmx_calc_vmcs_enum_msr();
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/kvm-s390-pv-leak-the-topmost-page-table-when-destroy.patch b/queue-5.15/kvm-s390-pv-leak-the-topmost-page-table-when-destroy.patch
new file mode 100644 (file)
index 0000000..b321bd2
--- /dev/null
@@ -0,0 +1,173 @@
+From c95c16c2aecbee4af230bc7e9f9eec55aa333f84 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Jun 2022 15:56:02 +0200
+Subject: KVM: s390: pv: leak the topmost page table when destroy fails
+
+From: Claudio Imbrenda <imbrenda@linux.ibm.com>
+
+[ Upstream commit faa2f72cb3569256480c5540d242c84e99965160 ]
+
+Each secure guest must have a unique ASCE (address space control
+element); we must avoid that new guests use the same page for their
+ASCE, to avoid errors.
+
+Since the ASCE mostly consists of the address of the topmost page table
+(plus some flags), we must not return that memory to the pool unless
+the ASCE is no longer in use.
+
+Only a successful Destroy Secure Configuration UVC will make the ASCE
+reusable again.
+
+If the Destroy Configuration UVC fails, the ASCE cannot be reused for a
+secure guest (either for the ASCE or for other memory areas). To avoid
+a collision, it must not be used again. This is a permanent error and
+the page becomes in practice unusable, so we set it aside and leak it.
+On failure we already leak other memory that belongs to the ultravisor
+(i.e. the variable and base storage for a guest) and not leaking the
+topmost page table was an oversight.
+
+This error (and thus the leakage) should not happen unless the hardware
+is broken or KVM has some unknown serious bug.
+
+Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
+Fixes: 29b40f105ec8d55 ("KVM: s390: protvirt: Add initial vm and cpu lifecycle handling")
+Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
+Link: https://lore.kernel.org/r/20220628135619.32410-2-imbrenda@linux.ibm.com
+Message-Id: <20220628135619.32410-2-imbrenda@linux.ibm.com>
+Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/include/asm/gmap.h |  2 +
+ arch/s390/kvm/pv.c           |  9 ++--
+ arch/s390/mm/gmap.c          | 86 ++++++++++++++++++++++++++++++++++++
+ 3 files changed, 94 insertions(+), 3 deletions(-)
+
+diff --git a/arch/s390/include/asm/gmap.h b/arch/s390/include/asm/gmap.h
+index 40264f60b0da..f4073106e1f3 100644
+--- a/arch/s390/include/asm/gmap.h
++++ b/arch/s390/include/asm/gmap.h
+@@ -148,4 +148,6 @@ void gmap_sync_dirty_log_pmd(struct gmap *gmap, unsigned long dirty_bitmap[4],
+                            unsigned long gaddr, unsigned long vmaddr);
+ int gmap_mark_unmergeable(void);
+ void s390_reset_acc(struct mm_struct *mm);
++void s390_unlist_old_asce(struct gmap *gmap);
++int s390_replace_asce(struct gmap *gmap);
+ #endif /* _ASM_S390_GMAP_H */
+diff --git a/arch/s390/kvm/pv.c b/arch/s390/kvm/pv.c
+index 00d272d134c2..b906658ffc2e 100644
+--- a/arch/s390/kvm/pv.c
++++ b/arch/s390/kvm/pv.c
+@@ -168,10 +168,13 @@ int kvm_s390_pv_deinit_vm(struct kvm *kvm, u16 *rc, u16 *rrc)
+       atomic_set(&kvm->mm->context.is_protected, 0);
+       KVM_UV_EVENT(kvm, 3, "PROTVIRT DESTROY VM: rc %x rrc %x", *rc, *rrc);
+       WARN_ONCE(cc, "protvirt destroy vm failed rc %x rrc %x", *rc, *rrc);
+-      /* Inteded memory leak on "impossible" error */
+-      if (!cc)
++      /* Intended memory leak on "impossible" error */
++      if (!cc) {
+               kvm_s390_pv_dealloc_vm(kvm);
+-      return cc ? -EIO : 0;
++              return 0;
++      }
++      s390_replace_asce(kvm->arch.gmap);
++      return -EIO;
+ }
+ int kvm_s390_pv_init_vm(struct kvm *kvm, u16 *rc, u16 *rrc)
+diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c
+index 4ce3a2f01c91..ff40bf92db43 100644
+--- a/arch/s390/mm/gmap.c
++++ b/arch/s390/mm/gmap.c
+@@ -2726,3 +2726,89 @@ void s390_reset_acc(struct mm_struct *mm)
+       mmput(mm);
+ }
+ EXPORT_SYMBOL_GPL(s390_reset_acc);
++
++/**
++ * s390_unlist_old_asce - Remove the topmost level of page tables from the
++ * list of page tables of the gmap.
++ * @gmap: the gmap whose table is to be removed
++ *
++ * On s390x, KVM keeps a list of all pages containing the page tables of the
++ * gmap (the CRST list). This list is used at tear down time to free all
++ * pages that are now not needed anymore.
++ *
++ * This function removes the topmost page of the tree (the one pointed to by
++ * the ASCE) from the CRST list.
++ *
++ * This means that it will not be freed when the VM is torn down, and needs
++ * to be handled separately by the caller, unless a leak is actually
++ * intended. Notice that this function will only remove the page from the
++ * list, the page will still be used as a top level page table (and ASCE).
++ */
++void s390_unlist_old_asce(struct gmap *gmap)
++{
++      struct page *old;
++
++      old = virt_to_page(gmap->table);
++      spin_lock(&gmap->guest_table_lock);
++      list_del(&old->lru);
++      /*
++       * Sometimes the topmost page might need to be "removed" multiple
++       * times, for example if the VM is rebooted into secure mode several
++       * times concurrently, or if s390_replace_asce fails after calling
++       * s390_remove_old_asce and is attempted again later. In that case
++       * the old asce has been removed from the list, and therefore it
++       * will not be freed when the VM terminates, but the ASCE is still
++       * in use and still pointed to.
++       * A subsequent call to replace_asce will follow the pointer and try
++       * to remove the same page from the list again.
++       * Therefore it's necessary that the page of the ASCE has valid
++       * pointers, so list_del can work (and do nothing) without
++       * dereferencing stale or invalid pointers.
++       */
++      INIT_LIST_HEAD(&old->lru);
++      spin_unlock(&gmap->guest_table_lock);
++}
++EXPORT_SYMBOL_GPL(s390_unlist_old_asce);
++
++/**
++ * s390_replace_asce - Try to replace the current ASCE of a gmap with a copy
++ * @gmap: the gmap whose ASCE needs to be replaced
++ *
++ * If the allocation of the new top level page table fails, the ASCE is not
++ * replaced.
++ * In any case, the old ASCE is always removed from the gmap CRST list.
++ * Therefore the caller has to make sure to save a pointer to it
++ * beforehand, unless a leak is actually intended.
++ */
++int s390_replace_asce(struct gmap *gmap)
++{
++      unsigned long asce;
++      struct page *page;
++      void *table;
++
++      s390_unlist_old_asce(gmap);
++
++      page = alloc_pages(GFP_KERNEL_ACCOUNT, CRST_ALLOC_ORDER);
++      if (!page)
++              return -ENOMEM;
++      table = page_to_virt(page);
++      memcpy(table, gmap->table, 1UL << (CRST_ALLOC_ORDER + PAGE_SHIFT));
++
++      /*
++       * The caller has to deal with the old ASCE, but here we make sure
++       * the new one is properly added to the CRST list, so that
++       * it will be freed when the VM is torn down.
++       */
++      spin_lock(&gmap->guest_table_lock);
++      list_add(&page->lru, &gmap->crst_list);
++      spin_unlock(&gmap->guest_table_lock);
++
++      /* Set new table origin while preserving existing ASCE control bits */
++      asce = (gmap->asce & ~_ASCE_ORIGIN) | __pa(table);
++      WRITE_ONCE(gmap->asce, asce);
++      WRITE_ONCE(gmap->mm->context.gmap_asce, asce);
++      WRITE_ONCE(gmap->table, table);
++
++      return 0;
++}
++EXPORT_SYMBOL_GPL(s390_replace_asce);
+-- 
+2.35.1
+
diff --git a/queue-5.15/kvm-svm-stuff-next_rip-on-emulated-int3-injection-if.patch b/queue-5.15/kvm-svm-stuff-next_rip-on-emulated-int3-injection-if.patch
new file mode 100644 (file)
index 0000000..2049fc9
--- /dev/null
@@ -0,0 +1,54 @@
+From 213aeac7b17f3c430bfc43dfe77add753f24eca3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 May 2022 00:07:28 +0200
+Subject: KVM: SVM: Stuff next_rip on emulated INT3 injection if NRIPS is
+ supported
+
+From: Sean Christopherson <seanjc@google.com>
+
+[ Upstream commit 3741aec4c38fa4123ab08ae552f05366d4fd05d8 ]
+
+If NRIPS is supported in hardware but disabled in KVM, set next_rip to
+the next RIP when advancing RIP as part of emulating INT3 injection.
+There is no flag to tell the CPU that KVM isn't using next_rip, and so
+leaving next_rip is left as is will result in the CPU pushing garbage
+onto the stack when vectoring the injected event.
+
+Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
+Fixes: 66b7138f9136 ("KVM: SVM: Emulate nRIP feature when reinjecting INT3")
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Signed-off-by: Maciej S. Szmigiero <maciej.szmigiero@oracle.com>
+Message-Id: <cd328309a3b88604daa2359ad56f36cb565ce2d4.1651440202.git.maciej.szmigiero@oracle.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kvm/svm/svm.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
+index 05d76832362d..2947e3c965e3 100644
+--- a/arch/x86/kvm/svm/svm.c
++++ b/arch/x86/kvm/svm/svm.c
+@@ -394,6 +394,10 @@ static void svm_queue_exception(struct kvm_vcpu *vcpu)
+                */
+               (void)skip_emulated_instruction(vcpu);
+               rip = kvm_rip_read(vcpu);
++
++              if (boot_cpu_has(X86_FEATURE_NRIPS))
++                      svm->vmcb->control.next_rip = rip;
++
+               svm->int3_rip = rip + svm->vmcb->save.cs.base;
+               svm->int3_injected = rip - old_rip;
+       }
+@@ -3683,7 +3687,7 @@ static void svm_complete_interrupts(struct kvm_vcpu *vcpu)
+       /*
+        * If NextRIP isn't enabled, KVM must manually advance RIP prior to
+        * injecting the soft exception/interrupt.  That advancement needs to
+-       * be unwound if vectoring didn't complete.  Note, the _new_ event may
++       * be unwound if vectoring didn't complete.  Note, the new event may
+        * not be the injected event, e.g. if KVM injected an INTn, the INTn
+        * hit a #NP in the guest, and the #NP encountered a #PF, the #NP will
+        * be the reported vectored event, but RIP still needs to be unwound.
+-- 
+2.35.1
+
diff --git a/queue-5.15/kvm-svm-unwind-speculative-rip-advancement-if-intn-i.patch b/queue-5.15/kvm-svm-unwind-speculative-rip-advancement-if-intn-i.patch
new file mode 100644 (file)
index 0000000..dbee780
--- /dev/null
@@ -0,0 +1,86 @@
+From a8c9181a902361e9730ba000ed8dcf21f81d3b84 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 May 2022 00:07:27 +0200
+Subject: KVM: SVM: Unwind "speculative" RIP advancement if INTn injection
+ "fails"
+
+From: Sean Christopherson <seanjc@google.com>
+
+[ Upstream commit cd9e6da8048c5b40315ee2d929b6230ce1252c3c ]
+
+Unwind the RIP advancement done by svm_queue_exception() when injecting
+an INT3 ultimately "fails" due to the CPU encountering a VM-Exit while
+vectoring the injected event, even if the exception reported by the CPU
+isn't the same event that was injected.  If vectoring INT3 encounters an
+exception, e.g. #NP, and vectoring the #NP encounters an intercepted
+exception, e.g. #PF when KVM is using shadow paging, then the #NP will
+be reported as the event that was in-progress.
+
+Note, this is still imperfect, as it will get a false positive if the
+INT3 is cleanly injected, no VM-Exit occurs before the IRET from the INT3
+handler in the guest, the instruction following the INT3 generates an
+exception (directly or indirectly), _and_ vectoring that exception
+encounters an exception that is intercepted by KVM.  The false positives
+could theoretically be solved by further analyzing the vectoring event,
+e.g. by comparing the error code against the expected error code were an
+exception to occur when vectoring the original injected exception, but
+SVM without NRIPS is a complete disaster, trying to make it 100% correct
+is a waste of time.
+
+Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
+Fixes: 66b7138f9136 ("KVM: SVM: Emulate nRIP feature when reinjecting INT3")
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Signed-off-by: Maciej S. Szmigiero <maciej.szmigiero@oracle.com>
+Message-Id: <450133cf0a026cb9825a2ff55d02cb136a1cb111.1651440202.git.maciej.szmigiero@oracle.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kvm/svm/svm.c | 23 +++++++++++++++--------
+ 1 file changed, 15 insertions(+), 8 deletions(-)
+
+diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
+index b001f7d94d1d..05d76832362d 100644
+--- a/arch/x86/kvm/svm/svm.c
++++ b/arch/x86/kvm/svm/svm.c
+@@ -3680,6 +3680,18 @@ static void svm_complete_interrupts(struct kvm_vcpu *vcpu)
+       vector = exitintinfo & SVM_EXITINTINFO_VEC_MASK;
+       type = exitintinfo & SVM_EXITINTINFO_TYPE_MASK;
++      /*
++       * If NextRIP isn't enabled, KVM must manually advance RIP prior to
++       * injecting the soft exception/interrupt.  That advancement needs to
++       * be unwound if vectoring didn't complete.  Note, the _new_ event may
++       * not be the injected event, e.g. if KVM injected an INTn, the INTn
++       * hit a #NP in the guest, and the #NP encountered a #PF, the #NP will
++       * be the reported vectored event, but RIP still needs to be unwound.
++       */
++      if (int3_injected && type == SVM_EXITINTINFO_TYPE_EXEPT &&
++         kvm_is_linear_rip(vcpu, svm->int3_rip))
++              kvm_rip_write(vcpu, kvm_rip_read(vcpu) - int3_injected);
++
+       switch (type) {
+       case SVM_EXITINTINFO_TYPE_NMI:
+               vcpu->arch.nmi_injected = true;
+@@ -3693,16 +3705,11 @@ static void svm_complete_interrupts(struct kvm_vcpu *vcpu)
+               /*
+                * In case of software exceptions, do not reinject the vector,
+-               * but re-execute the instruction instead. Rewind RIP first
+-               * if we emulated INT3 before.
++               * but re-execute the instruction instead.
+                */
+-              if (kvm_exception_is_soft(vector)) {
+-                      if (vector == BP_VECTOR && int3_injected &&
+-                          kvm_is_linear_rip(vcpu, svm->int3_rip))
+-                              kvm_rip_write(vcpu,
+-                                            kvm_rip_read(vcpu) - int3_injected);
++              if (kvm_exception_is_soft(vector))
+                       break;
+-              }
++
+               if (exitintinfo & SVM_EXITINTINFO_VALID_ERR) {
+                       u32 err = svm->vmcb->control.exit_int_info_err;
+                       kvm_requeue_exception_e(vcpu, vector, err);
+-- 
+2.35.1
+
diff --git a/queue-5.15/lib-smp_processor_id-fix-imbalanced-instrumentation_.patch b/queue-5.15/lib-smp_processor_id-fix-imbalanced-instrumentation_.patch
new file mode 100644 (file)
index 0000000..d3344af
--- /dev/null
@@ -0,0 +1,42 @@
+From c94292f9576f38a4cb5a154df18fc0910cda6cbe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jun 2022 14:46:31 +0900
+Subject: lib/smp_processor_id: fix imbalanced instrumentation_end() call
+
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+
+[ Upstream commit bd27acaac24e4b252ee28dddcabaee80456d0faf ]
+
+Currently instrumentation_end() won't be called if printk_ratelimit()
+returned false.
+
+Link: https://lkml.kernel.org/r/a636d8e0-ad32-5888-acac-671f7f553bb3@I-love.SAKURA.ne.jp
+Fixes: 126f21f0e8d46e2c ("lib/smp_processor_id: Move it into noinstr section")
+Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Alexandre Chartre <alexandre.chartre@oracle.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/smp_processor_id.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/smp_processor_id.c b/lib/smp_processor_id.c
+index 046ac6297c78..a2bb7738c373 100644
+--- a/lib/smp_processor_id.c
++++ b/lib/smp_processor_id.c
+@@ -47,9 +47,9 @@ unsigned int check_preemption_disabled(const char *what1, const char *what2)
+       printk("caller is %pS\n", __builtin_return_address(0));
+       dump_stack();
+-      instrumentation_end();
+ out_enable:
++      instrumentation_end();
+       preempt_enable_no_resched_notrace();
+ out:
+       return this_cpu;
+-- 
+2.35.1
+
diff --git a/queue-5.15/lib-test_hmm-avoid-accessing-uninitialized-pages.patch b/queue-5.15/lib-test_hmm-avoid-accessing-uninitialized-pages.patch
new file mode 100644 (file)
index 0000000..96e5497
--- /dev/null
@@ -0,0 +1,61 @@
+From 32c3ddaadefca4d7dc0fcb4eb28e0076c565b8c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jun 2022 21:08:35 +0800
+Subject: lib/test_hmm: avoid accessing uninitialized pages
+
+From: Miaohe Lin <linmiaohe@huawei.com>
+
+[ Upstream commit ed913b055a74b723976f8e885a3395162a0371e6 ]
+
+If make_device_exclusive_range() fails or returns pages marked for
+exclusive access less than required, remaining fields of pages will left
+uninitialized.  So dmirror_atomic_map() will access those yet
+uninitialized fields of pages.  To fix it, do dmirror_atomic_map() iff all
+pages are marked for exclusive access (we will break if mapped is less
+than required anyway) so we won't access those uninitialized fields of
+pages.
+
+Link: https://lkml.kernel.org/r/20220609130835.35110-1-linmiaohe@huawei.com
+Fixes: b659baea7546 ("mm: selftests for exclusive device memory")
+Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>
+Cc: Jerome Glisse <jglisse@redhat.com>
+Cc: Alistair Popple <apopple@nvidia.com>
+Cc: Jason Gunthorpe <jgg@ziepe.ca>
+Cc: Ralph Campbell <rcampbell@nvidia.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/test_hmm.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/lib/test_hmm.c b/lib/test_hmm.c
+index ac794e354069..a89cb4281c9d 100644
+--- a/lib/test_hmm.c
++++ b/lib/test_hmm.c
+@@ -731,7 +731,7 @@ static int dmirror_exclusive(struct dmirror *dmirror,
+       mmap_read_lock(mm);
+       for (addr = start; addr < end; addr = next) {
+-              unsigned long mapped;
++              unsigned long mapped = 0;
+               int i;
+               if (end < addr + (ARRAY_SIZE(pages) << PAGE_SHIFT))
+@@ -740,7 +740,13 @@ static int dmirror_exclusive(struct dmirror *dmirror,
+                       next = addr + (ARRAY_SIZE(pages) << PAGE_SHIFT);
+               ret = make_device_exclusive_range(mm, addr, next, pages, NULL);
+-              mapped = dmirror_atomic_map(addr, next, pages, dmirror);
++              /*
++               * Do dmirror_atomic_map() iff all pages are marked for
++               * exclusive access to avoid accessing uninitialized
++               * fields of pages.
++               */
++              if (ret == (next - addr) >> PAGE_SHIFT)
++                      mapped = dmirror_atomic_map(addr, next, pages, dmirror);
+               for (i = 0; i < ret; i++) {
+                       if (pages[i]) {
+                               unlock_page(pages[i]);
+-- 
+2.35.1
+
diff --git a/queue-5.15/libbpf-fix-an-snprintf-overflow-check.patch b/queue-5.15/libbpf-fix-an-snprintf-overflow-check.patch
new file mode 100644 (file)
index 0000000..d618451
--- /dev/null
@@ -0,0 +1,39 @@
+From 25f17b62212904b025180c22e4efa97feaf4d424 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 12:51:28 +0300
+Subject: libbpf: fix an snprintf() overflow check
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit b77ffb30cfc5f58e957571d8541c6a7e3da19221 ]
+
+The snprintf() function returns the number of bytes it *would* have
+copied if there were enough space.  So it can return > the
+sizeof(gen->attach_target).
+
+Fixes: 67234743736a ("libbpf: Generate loader program out of BPF ELF file.")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Acked-by: Martin KaFai Lau <kafai@fb.com>
+Link: https://lore.kernel.org/r/YtZ+oAySqIhFl6/J@kili
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/gen_loader.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/lib/bpf/gen_loader.c b/tools/lib/bpf/gen_loader.c
+index 33c19590ee43..4435c09fe132 100644
+--- a/tools/lib/bpf/gen_loader.c
++++ b/tools/lib/bpf/gen_loader.c
+@@ -480,7 +480,7 @@ void bpf_gen__record_attach_target(struct bpf_gen *gen, const char *attach_name,
+       gen->attach_kind = kind;
+       ret = snprintf(gen->attach_target, sizeof(gen->attach_target), "%s%s",
+                      prefix, attach_name);
+-      if (ret == sizeof(gen->attach_target))
++      if (ret >= sizeof(gen->attach_target))
+               gen->error = -ENOSPC;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/libbpf-fix-the-name-of-a-reused-map.patch b/queue-5.15/libbpf-fix-the-name-of-a-reused-map.patch
new file mode 100644 (file)
index 0000000..b4195cd
--- /dev/null
@@ -0,0 +1,74 @@
+From d438a8b8669b3d958cdff27fecf2f4d1ed6b5d7c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Jul 2022 11:15:40 +0800
+Subject: libbpf: Fix the name of a reused map
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Anquan Wu <leiqi96@hotmail.com>
+
+[ Upstream commit bf3f00378524adae16628cbadbd11ba7211863bb ]
+
+BPF map name is limited to BPF_OBJ_NAME_LEN.
+A map name is defined as being longer than BPF_OBJ_NAME_LEN,
+it will be truncated to BPF_OBJ_NAME_LEN when a userspace program
+calls libbpf to create the map. A pinned map also generates a path
+in the /sys. If the previous program wanted to reuse the map,
+it can not get bpf_map by name, because the name of the map is only
+partially the same as the name which get from pinned path.
+
+The syscall information below show that map name "process_pinned_map"
+is truncated to "process_pinned_".
+
+    bpf(BPF_OBJ_GET, {pathname="/sys/fs/bpf/process_pinned_map",
+    bpf_fd=0, file_flags=0}, 144) = -1 ENOENT (No such file or directory)
+
+    bpf(BPF_MAP_CREATE, {map_type=BPF_MAP_TYPE_HASH, key_size=4,
+    value_size=4,max_entries=1024, map_flags=0, inner_map_fd=0,
+    map_name="process_pinned_",map_ifindex=0, btf_fd=3, btf_key_type_id=6,
+    btf_value_type_id=10,btf_vmlinux_value_type_id=0}, 72) = 4
+
+This patch check that if the name of pinned map are the same as the
+actual name for the first (BPF_OBJ_NAME_LEN - 1),
+bpf map still uses the name which is included in bpf object.
+
+Fixes: 26736eb9a483 ("tools: libbpf: allow map reuse")
+Signed-off-by: Anquan Wu <leiqi96@hotmail.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/OSZP286MB1725CEA1C95C5CB8E7CCC53FB8869@OSZP286MB1725.JPNP286.PROD.OUTLOOK.COM
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/libbpf.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
+index 1ba2dd3523f8..050622649797 100644
+--- a/tools/lib/bpf/libbpf.c
++++ b/tools/lib/bpf/libbpf.c
+@@ -3942,7 +3942,7 @@ static int bpf_get_map_info_from_fdinfo(int fd, struct bpf_map_info *info)
+ int bpf_map__reuse_fd(struct bpf_map *map, int fd)
+ {
+       struct bpf_map_info info = {};
+-      __u32 len = sizeof(info);
++      __u32 len = sizeof(info), name_len;
+       int new_fd, err;
+       char *new_name;
+@@ -3952,7 +3952,12 @@ int bpf_map__reuse_fd(struct bpf_map *map, int fd)
+       if (err)
+               return libbpf_err(err);
+-      new_name = strdup(info.name);
++      name_len = strlen(info.name);
++      if (name_len == BPF_OBJ_NAME_LEN - 1 && strncmp(map->name, info.name, name_len) == 0)
++              new_name = strdup(map->name);
++      else
++              new_name = strdup(info.name);
++
+       if (!new_name)
+               return libbpf_err(-errno);
+-- 
+2.35.1
+
diff --git a/queue-5.15/locking-lockdep-fix-lockdep_init_map_-confusion.patch b/queue-5.15/locking-lockdep-fix-lockdep_init_map_-confusion.patch
new file mode 100644 (file)
index 0000000..2c8af76
--- /dev/null
@@ -0,0 +1,101 @@
+From 11f18c023eeabd92895c6118ed26f5dc3b25d6fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jun 2022 15:26:06 +0200
+Subject: locking/lockdep: Fix lockdep_init_map_*() confusion
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+[ Upstream commit eae6d58d67d9739be5f7ae2dbead1d0ef6528243 ]
+
+Commit dfd5e3f5fe27 ("locking/lockdep: Mark local_lock_t") added yet
+another lockdep_init_map_*() variant, but forgot to update all the
+existing users of the most complicated version.
+
+This could lead to a loss of lock_type and hence an incorrect report.
+Given the relative rarity of both local_lock and these annotations,
+this is unlikely to happen in practise, still, best fix things.
+
+Fixes: dfd5e3f5fe27 ("locking/lockdep: Mark local_lock_t")
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/YqyEDtoan20K0CVD@worktop.programming.kicks-ass.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/lockdep.h  | 30 +++++++++++++++++-------------
+ kernel/locking/lockdep.c |  7 ++++---
+ 2 files changed, 21 insertions(+), 16 deletions(-)
+
+diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
+index 9fe165beb0f9..aa0ecfc6cdb4 100644
+--- a/include/linux/lockdep.h
++++ b/include/linux/lockdep.h
+@@ -192,7 +192,7 @@ static inline void
+ lockdep_init_map_waits(struct lockdep_map *lock, const char *name,
+                      struct lock_class_key *key, int subclass, u8 inner, u8 outer)
+ {
+-      lockdep_init_map_type(lock, name, key, subclass, inner, LD_WAIT_INV, LD_LOCK_NORMAL);
++      lockdep_init_map_type(lock, name, key, subclass, inner, outer, LD_LOCK_NORMAL);
+ }
+ static inline void
+@@ -215,24 +215,28 @@ static inline void lockdep_init_map(struct lockdep_map *lock, const char *name,
+  * or they are too narrow (they suffer from a false class-split):
+  */
+ #define lockdep_set_class(lock, key)                          \
+-      lockdep_init_map_waits(&(lock)->dep_map, #key, key, 0,  \
+-                             (lock)->dep_map.wait_type_inner, \
+-                             (lock)->dep_map.wait_type_outer)
++      lockdep_init_map_type(&(lock)->dep_map, #key, key, 0,   \
++                            (lock)->dep_map.wait_type_inner,  \
++                            (lock)->dep_map.wait_type_outer,  \
++                            (lock)->dep_map.lock_type)
+ #define lockdep_set_class_and_name(lock, key, name)           \
+-      lockdep_init_map_waits(&(lock)->dep_map, name, key, 0,  \
+-                             (lock)->dep_map.wait_type_inner, \
+-                             (lock)->dep_map.wait_type_outer)
++      lockdep_init_map_type(&(lock)->dep_map, name, key, 0,   \
++                            (lock)->dep_map.wait_type_inner,  \
++                            (lock)->dep_map.wait_type_outer,  \
++                            (lock)->dep_map.lock_type)
+ #define lockdep_set_class_and_subclass(lock, key, sub)                \
+-      lockdep_init_map_waits(&(lock)->dep_map, #key, key, sub,\
+-                             (lock)->dep_map.wait_type_inner, \
+-                             (lock)->dep_map.wait_type_outer)
++      lockdep_init_map_type(&(lock)->dep_map, #key, key, sub, \
++                            (lock)->dep_map.wait_type_inner,  \
++                            (lock)->dep_map.wait_type_outer,  \
++                            (lock)->dep_map.lock_type)
+ #define lockdep_set_subclass(lock, sub)                                       \
+-      lockdep_init_map_waits(&(lock)->dep_map, #lock, (lock)->dep_map.key, sub,\
+-                             (lock)->dep_map.wait_type_inner,         \
+-                             (lock)->dep_map.wait_type_outer)
++      lockdep_init_map_type(&(lock)->dep_map, #lock, (lock)->dep_map.key, sub,\
++                            (lock)->dep_map.wait_type_inner,          \
++                            (lock)->dep_map.wait_type_outer,          \
++                            (lock)->dep_map.lock_type)
+ #define lockdep_set_novalidate_class(lock) \
+       lockdep_set_class_and_name(lock, &__lockdep_no_validate__, #lock)
+diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
+index a30702b847ba..120bbdacd58b 100644
+--- a/kernel/locking/lockdep.c
++++ b/kernel/locking/lockdep.c
+@@ -5202,9 +5202,10 @@ __lock_set_class(struct lockdep_map *lock, const char *name,
+               return 0;
+       }
+-      lockdep_init_map_waits(lock, name, key, 0,
+-                             lock->wait_type_inner,
+-                             lock->wait_type_outer);
++      lockdep_init_map_type(lock, name, key, 0,
++                            lock->wait_type_inner,
++                            lock->wait_type_outer,
++                            lock->lock_type);
+       class = register_lock_class(lock, subclass, 0);
+       hlock->class_idx = class - lock_classes;
+-- 
+2.35.1
+
diff --git a/queue-5.15/media-atmel-atmel-sama7g5-isc-fix-warning-in-configs.patch b/queue-5.15/media-atmel-atmel-sama7g5-isc-fix-warning-in-configs.patch
new file mode 100644 (file)
index 0000000..6de1397
--- /dev/null
@@ -0,0 +1,59 @@
+From 6340a5e67b5b523b08cd2ef80bb043caecff2e70 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 May 2022 12:12:16 +0100
+Subject: media: atmel: atmel-sama7g5-isc: fix warning in configs without OF
+
+From: Eugen Hristev <eugen.hristev@microchip.com>
+
+[ Upstream commit b2bae4b8e637dd751d27918a6b27bd5abcd08859 ]
+
+All warnings (new ones prefixed by >>):
+
+>> drivers/media/platform/atmel/atmel-sama7g5-isc.c:610:34: warning: unused variable 'microchip_xisc_of_match' [-Wunused-const-variable]
+   static const struct of_device_id microchip_xisc_of_match[] = {
+                                    ^
+   13 warnings generated.
+
+vim +/microchip_xisc_of_match +610 drivers/media/platform/atmel/atmel-sama7g5-isc.c
+
+   609
+ > 610  static const struct of_device_id microchip_xisc_of_match[] = {
+   611          { .compatible = "microchip,sama7g5-isc" },
+   612          { }
+   613  };
+   614  MODULE_DEVICE_TABLE(of, microchip_xisc_of_match);
+   615
+
+Fixed warning by guarding the atmel_isc_of_match by CONFIG_OF.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Fixes: c9aa973884a1 ("media: atmel: atmel-isc: add microchip-xisc driver")
+Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/atmel/atmel-sama7g5-isc.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/media/platform/atmel/atmel-sama7g5-isc.c b/drivers/media/platform/atmel/atmel-sama7g5-isc.c
+index 6a5d3f7ce75e..a4defc30cf41 100644
+--- a/drivers/media/platform/atmel/atmel-sama7g5-isc.c
++++ b/drivers/media/platform/atmel/atmel-sama7g5-isc.c
+@@ -587,11 +587,13 @@ static const struct dev_pm_ops microchip_xisc_dev_pm_ops = {
+       SET_RUNTIME_PM_OPS(xisc_runtime_suspend, xisc_runtime_resume, NULL)
+ };
++#if IS_ENABLED(CONFIG_OF)
+ static const struct of_device_id microchip_xisc_of_match[] = {
+       { .compatible = "microchip,sama7g5-isc" },
+       { }
+ };
+ MODULE_DEVICE_TABLE(of, microchip_xisc_of_match);
++#endif
+ static struct platform_driver microchip_xisc_driver = {
+       .probe  = microchip_xisc_probe,
+-- 
+2.35.1
+
diff --git a/queue-5.15/media-cedrus-h265-fix-flag-name.patch b/queue-5.15/media-cedrus-h265-fix-flag-name.patch
new file mode 100644 (file)
index 0000000..6e9f12f
--- /dev/null
@@ -0,0 +1,70 @@
+From 68142537f79a61d1e22b47013823fcb7e4d36a13 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jun 2022 18:55:11 +0100
+Subject: media: cedrus: h265: Fix flag name
+
+From: Jernej Skrabec <jernej.skrabec@gmail.com>
+
+[ Upstream commit 104a70e1d0bcef28db13c4192b8729086089651c ]
+
+Bit 21 in register 0x24 (slice header info 1) actually represents
+negated version of low delay flag. This can be seen in vendor Cedar
+library source code. While this flag is not part of the standard, it can
+be found in reference HEVC implementation.
+
+Fix macro name and change it to flag.
+
+Fixes: 86caab29da78 ("media: cedrus: Add HEVC/H.265 decoding support")
+Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/media/sunxi/cedrus/cedrus_h265.c | 4 +++-
+ drivers/staging/media/sunxi/cedrus/cedrus_regs.h | 3 +--
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+index 754942ecf064..f2cec43fd1f0 100644
+--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
++++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+@@ -495,7 +495,6 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
+       reg = VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_TC_OFFSET_DIV2(slice_params->slice_tc_offset_div2) |
+             VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_BETA_OFFSET_DIV2(slice_params->slice_beta_offset_div2) |
+-            VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_POC_BIGEST_IN_RPS_ST(decode_params->num_poc_st_curr_after == 0) |
+             VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_CR_QP_OFFSET(slice_params->slice_cr_qp_offset) |
+             VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_CB_QP_OFFSET(slice_params->slice_cb_qp_offset) |
+             VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_QP_DELTA(slice_params->slice_qp_delta);
+@@ -508,6 +507,9 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
+                               V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED,
+                               slice_params->flags);
++      if (decode_params->num_poc_st_curr_after == 0)
++              reg |= VE_DEC_H265_DEC_SLICE_HDR_INFO1_FLAG_SLICE_NOT_LOW_DELAY;
++
+       cedrus_write(dev, VE_DEC_H265_DEC_SLICE_HDR_INFO1, reg);
+       chroma_log2_weight_denom = pred_weight_table->luma_log2_weight_denom +
+diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
+index 92ace87c1c7d..5f34e3670289 100644
+--- a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
++++ b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
+@@ -377,13 +377,12 @@
+ #define VE_DEC_H265_DEC_SLICE_HDR_INFO1_FLAG_SLICE_DEBLOCKING_FILTER_DISABLED BIT(23)
+ #define VE_DEC_H265_DEC_SLICE_HDR_INFO1_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED BIT(22)
++#define VE_DEC_H265_DEC_SLICE_HDR_INFO1_FLAG_SLICE_NOT_LOW_DELAY BIT(21)
+ #define VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_TC_OFFSET_DIV2(v) \
+       SHIFT_AND_MASK_BITS(v, 31, 28)
+ #define VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_BETA_OFFSET_DIV2(v) \
+       SHIFT_AND_MASK_BITS(v, 27, 24)
+-#define VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_POC_BIGEST_IN_RPS_ST(v) \
+-      ((v) ? BIT(21) : 0)
+ #define VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_CR_QP_OFFSET(v) \
+       SHIFT_AND_MASK_BITS(v, 20, 16)
+ #define VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_CB_QP_OFFSET(v) \
+-- 
+2.35.1
+
diff --git a/queue-5.15/media-cedrus-hevc-add-check-for-invalid-timestamp.patch b/queue-5.15/media-cedrus-hevc-add-check-for-invalid-timestamp.patch
new file mode 100644 (file)
index 0000000..7acd152
--- /dev/null
@@ -0,0 +1,45 @@
+From dd375652f9d24f223fc965f96d4c4338564bcbd1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 18:56:49 +0200
+Subject: media: cedrus: hevc: Add check for invalid timestamp
+
+From: Jernej Skrabec <jernej.skrabec@gmail.com>
+
+[ Upstream commit 143201a6435bf65f0115435e9dc6d95c66b908e9 ]
+
+Not all DPB entries will be used most of the time. Unused entries will
+thus have invalid timestamps. They will produce negative buffer index
+which is not specifically handled. This works just by chance in current
+code. It will even produce bogus pointer, but since it's not used, it
+won't do any harm.
+
+Let's fix that brittle design by skipping writing DPB entry altogether
+if timestamp is invalid.
+
+Fixes: 86caab29da78 ("media: cedrus: Add HEVC/H.265 decoding support")
+Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Reviewed-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/media/sunxi/cedrus/cedrus_h265.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+index f2cec43fd1f0..830cae03fc6e 100644
+--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
++++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+@@ -147,6 +147,9 @@ static void cedrus_h265_frame_info_write_dpb(struct cedrus_ctx *ctx,
+                       dpb[i].pic_order_cnt[1]
+               };
++              if (buffer_index < 0)
++                      continue;
++
+               cedrus_h265_frame_info_write_single(ctx, i, dpb[i].field_pic,
+                                                   pic_order_cnt,
+                                                   buffer_index);
+-- 
+2.35.1
+
diff --git a/queue-5.15/media-driver-nxp-imx-jpeg-fix-a-unexpected-return-va.patch b/queue-5.15/media-driver-nxp-imx-jpeg-fix-a-unexpected-return-va.patch
new file mode 100644 (file)
index 0000000..6b555bd
--- /dev/null
@@ -0,0 +1,44 @@
+From 40e2d2597934d1933f59812d0316c7a02724f8c1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jun 2022 09:34:23 +0100
+Subject: media: driver/nxp/imx-jpeg: fix a unexpected return value problem
+
+From: Jian Zhang <zhangjian210@huawei.com>
+
+[ Upstream commit 5b304046a81eda221b5d06a9c62f7b5e45530fa5 ]
+
+In function mxc_jpeg_probe(), when devm_clk_get() fail, the return value
+will be unexpected, and it should be the devm_clk_get's error code.
+
+Fixes: 4c2e5156d9fa6 ("media: imx-jpeg: Add pm-runtime support for imx-jpeg")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Jian Zhang <zhangjian210@huawei.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/imx-jpeg/mxc-jpeg.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
+index aeb3704cfff0..984fcdfa0f09 100644
+--- a/drivers/media/platform/imx-jpeg/mxc-jpeg.c
++++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
+@@ -2108,12 +2108,14 @@ static int mxc_jpeg_probe(struct platform_device *pdev)
+       jpeg->clk_ipg = devm_clk_get(dev, "ipg");
+       if (IS_ERR(jpeg->clk_ipg)) {
+               dev_err(dev, "failed to get clock: ipg\n");
++              ret = PTR_ERR(jpeg->clk_ipg);
+               goto err_clk;
+       }
+       jpeg->clk_per = devm_clk_get(dev, "per");
+       if (IS_ERR(jpeg->clk_per)) {
+               dev_err(dev, "failed to get clock: per\n");
++              ret = PTR_ERR(jpeg->clk_per);
+               goto err_clk;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/media-hantro-postproc-fix-motion-vector-space-size.patch b/queue-5.15/media-hantro-postproc-fix-motion-vector-space-size.patch
new file mode 100644 (file)
index 0000000..2a89940
--- /dev/null
@@ -0,0 +1,51 @@
+From 560b5cde74aa9b07a33fcb536553fb9383ae1bc1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Nov 2021 14:38:31 +0000
+Subject: media: hantro: postproc: Fix motion vector space size
+
+From: Ezequiel Garcia <ezequiel@collabora.com>
+
+[ Upstream commit 9393761aec4c56b7f2f19d21f806d316731401c1 ]
+
+When the post-processor hardware block is enabled, the driver
+allocates an internal queue of buffers for the decoder enginer,
+and uses the vb2 queue for the post-processor engine.
+
+For instance, on a G1 core, the decoder engine produces NV12 buffers
+and the post-processor engine can produce YUY2 buffers. The decoder
+engine expects motion vectors to be appended to the NV12 buffers,
+but this is only required for CODECs that need motion vectors,
+such as H.264.
+
+Fix the post-processor logic accordingly.
+
+Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/media/hantro/hantro_postproc.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/staging/media/hantro/hantro_postproc.c b/drivers/staging/media/hantro/hantro_postproc.c
+index ed8916c950a4..07842152003f 100644
+--- a/drivers/staging/media/hantro/hantro_postproc.c
++++ b/drivers/staging/media/hantro/hantro_postproc.c
+@@ -132,9 +132,10 @@ int hantro_postproc_alloc(struct hantro_ctx *ctx)
+       unsigned int num_buffers = cap_queue->num_buffers;
+       unsigned int i, buf_size;
+-      buf_size = ctx->dst_fmt.plane_fmt[0].sizeimage +
+-                 hantro_h264_mv_size(ctx->dst_fmt.width,
+-                                     ctx->dst_fmt.height);
++      buf_size = ctx->dst_fmt.plane_fmt[0].sizeimage;
++      if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_H264_SLICE)
++              buf_size += hantro_h264_mv_size(ctx->dst_fmt.width,
++                                              ctx->dst_fmt.height);
+       for (i = 0; i < num_buffers; ++i) {
+               struct hantro_aux_buf *priv = &ctx->postproc.dec_q[i];
+-- 
+2.35.1
+
diff --git a/queue-5.15/media-hantro-simplify-postprocessor.patch b/queue-5.15/media-hantro-simplify-postprocessor.patch
new file mode 100644 (file)
index 0000000..3047262
--- /dev/null
@@ -0,0 +1,106 @@
+From 2ba834c79bfc194a808a34ec01861909542d79bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Nov 2021 14:38:33 +0000
+Subject: media: hantro: Simplify postprocessor
+
+From: Ezequiel Garcia <ezequiel@collabora.com>
+
+[ Upstream commit 53a3e71095c572333ceea30762565dbedec951ca ]
+
+Add a 'postprocessed' boolean property to struct hantro_fmt
+to signal that a format is produced by the post-processor.
+This will allow to introduce the G2 post-processor in a simple way.
+
+Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/media/hantro/hantro.h          | 2 ++
+ drivers/staging/media/hantro/hantro_postproc.c | 8 +-------
+ drivers/staging/media/hantro/imx8m_vpu_hw.c    | 1 +
+ drivers/staging/media/hantro/rockchip_vpu_hw.c | 1 +
+ drivers/staging/media/hantro/sama5d4_vdec_hw.c | 1 +
+ 5 files changed, 6 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/staging/media/hantro/hantro.h b/drivers/staging/media/hantro/hantro.h
+index c2e2dca38628..88792c863edc 100644
+--- a/drivers/staging/media/hantro/hantro.h
++++ b/drivers/staging/media/hantro/hantro.h
+@@ -262,6 +262,7 @@ struct hantro_ctx {
+  * @max_depth:        Maximum depth, for bitstream formats
+  * @enc_fmt:  Format identifier for encoder registers.
+  * @frmsize:  Supported range of frame sizes (only for bitstream formats).
++ * @postprocessed: Indicates if this format needs the post-processor.
+  */
+ struct hantro_fmt {
+       char *name;
+@@ -271,6 +272,7 @@ struct hantro_fmt {
+       int max_depth;
+       enum hantro_enc_fmt enc_fmt;
+       struct v4l2_frmsize_stepwise frmsize;
++      bool postprocessed;
+ };
+ struct hantro_reg {
+diff --git a/drivers/staging/media/hantro/hantro_postproc.c b/drivers/staging/media/hantro/hantro_postproc.c
+index 07842152003f..46434c97317b 100644
+--- a/drivers/staging/media/hantro/hantro_postproc.c
++++ b/drivers/staging/media/hantro/hantro_postproc.c
+@@ -53,15 +53,9 @@ const struct hantro_postproc_regs hantro_g1_postproc_regs = {
+ bool hantro_needs_postproc(const struct hantro_ctx *ctx,
+                          const struct hantro_fmt *fmt)
+ {
+-      struct hantro_dev *vpu = ctx->dev;
+-
+       if (ctx->is_encoder)
+               return false;
+-
+-      if (!vpu->variant->postproc_fmts)
+-              return false;
+-
+-      return fmt->fourcc != V4L2_PIX_FMT_NV12;
++      return fmt->postprocessed;
+ }
+ void hantro_postproc_enable(struct hantro_ctx *ctx)
+diff --git a/drivers/staging/media/hantro/imx8m_vpu_hw.c b/drivers/staging/media/hantro/imx8m_vpu_hw.c
+index ea919bfb9891..b692b74b0914 100644
+--- a/drivers/staging/media/hantro/imx8m_vpu_hw.c
++++ b/drivers/staging/media/hantro/imx8m_vpu_hw.c
+@@ -82,6 +82,7 @@ static const struct hantro_fmt imx8m_vpu_postproc_fmts[] = {
+       {
+               .fourcc = V4L2_PIX_FMT_YUYV,
+               .codec_mode = HANTRO_MODE_NONE,
++              .postprocessed = true,
+       },
+ };
+diff --git a/drivers/staging/media/hantro/rockchip_vpu_hw.c b/drivers/staging/media/hantro/rockchip_vpu_hw.c
+index 0c22039162a0..543dc4a5486c 100644
+--- a/drivers/staging/media/hantro/rockchip_vpu_hw.c
++++ b/drivers/staging/media/hantro/rockchip_vpu_hw.c
+@@ -62,6 +62,7 @@ static const struct hantro_fmt rockchip_vpu1_postproc_fmts[] = {
+       {
+               .fourcc = V4L2_PIX_FMT_YUYV,
+               .codec_mode = HANTRO_MODE_NONE,
++              .postprocessed = true,
+       },
+ };
+diff --git a/drivers/staging/media/hantro/sama5d4_vdec_hw.c b/drivers/staging/media/hantro/sama5d4_vdec_hw.c
+index 9c3b8cd0b239..99432008b241 100644
+--- a/drivers/staging/media/hantro/sama5d4_vdec_hw.c
++++ b/drivers/staging/media/hantro/sama5d4_vdec_hw.c
+@@ -15,6 +15,7 @@ static const struct hantro_fmt sama5d4_vdec_postproc_fmts[] = {
+       {
+               .fourcc = V4L2_PIX_FMT_YUYV,
+               .codec_mode = HANTRO_MODE_NONE,
++              .postprocessed = true,
+       },
+ };
+-- 
+2.35.1
+
diff --git a/queue-5.15/media-hdpvr-fix-error-value-returns-in-hdpvr_read.patch b/queue-5.15/media-hdpvr-fix-error-value-returns-in-hdpvr_read.patch
new file mode 100644 (file)
index 0000000..1d47272
--- /dev/null
@@ -0,0 +1,44 @@
+From b90bb78bc6c0043c2aa2ccf840b7ef19be1a3b9f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jun 2022 18:50:02 +0100
+Subject: media: hdpvr: fix error value returns in hdpvr_read
+
+From: Niels Dossche <dossche.niels@gmail.com>
+
+[ Upstream commit 359c27c6ddbde404f44a9c0d3ec88ccd1e2042f2 ]
+
+Error return values are supposed to be negative in hdpvr_read. Most
+error returns are currently handled via an unsigned integer "ret". When
+setting a negative error value to "ret", the value actually becomes a
+large positive value, because "ret" is unsigned. Later on, the "ret"
+value is returned. But as ssize_t is a 64-bit signed number, the error
+return value stays a large positive integer instead of a negative
+integer. This can cause an error value to be interpreted as the read
+size, which can cause a buffer overread for applications relying on the
+returned size.
+
+Fixes: 9aba42efe85b ("V4L/DVB (11096): V4L2 Driver for the Hauppauge HD PVR usb capture device")
+Signed-off-by: Niels Dossche <dossche.niels@gmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/hdpvr/hdpvr-video.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/usb/hdpvr/hdpvr-video.c b/drivers/media/usb/hdpvr/hdpvr-video.c
+index 60e57e0f1927..fd7d2a9d0449 100644
+--- a/drivers/media/usb/hdpvr/hdpvr-video.c
++++ b/drivers/media/usb/hdpvr/hdpvr-video.c
+@@ -409,7 +409,7 @@ static ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count,
+       struct hdpvr_device *dev = video_drvdata(file);
+       struct hdpvr_buffer *buf = NULL;
+       struct urb *urb;
+-      unsigned int ret = 0;
++      int ret = 0;
+       int rem, cnt;
+       if (*pos)
+-- 
+2.35.1
+
diff --git a/queue-5.15/media-hevc-embedded-indexes-in-rps.patch b/queue-5.15/media-hevc-embedded-indexes-in-rps.patch
new file mode 100644 (file)
index 0000000..ebdad97
--- /dev/null
@@ -0,0 +1,111 @@
+From 8a54a086c2f31ae7e44c7723fce301d8867ba132 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jan 2022 16:54:55 +0100
+Subject: media: hevc: Embedded indexes in RPS
+
+From: Benjamin Gaignard <benjamin.gaignard@collabora.com>
+
+[ Upstream commit d95a63daca85f4bca3b70e622c75586b5bf0ea5c ]
+
+Reference Picture Set lists provide indices of short and long term
+reference in DBP array.
+Fix Hantro to not do a look up in DBP entries.
+Make documentation more clear about it.
+
+[hverkuil: fix typo in commit log]
+
+Signed-off-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
+Reviewed-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../media/v4l/ext-ctrls-codec.rst             |  6 ++---
+ .../staging/media/hantro/hantro_g2_hevc_dec.c | 25 +++++--------------
+ 2 files changed, 9 insertions(+), 22 deletions(-)
+
+diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
+index 976d34445a24..f1421cf1a1b3 100644
+--- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
++++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
+@@ -3326,15 +3326,15 @@ enum v4l2_mpeg_video_hevc_size_of_length_field -
+     * - __u8
+       - ``poc_st_curr_before[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
+       - PocStCurrBefore as described in section 8.3.2 "Decoding process for reference
+-        picture set.
++        picture set": provides the index of the short term before references in DPB array.
+     * - __u8
+       - ``poc_st_curr_after[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
+       - PocStCurrAfter as described in section 8.3.2 "Decoding process for reference
+-        picture set.
++        picture set": provides the index of the short term after references in DPB array.
+     * - __u8
+       - ``poc_lt_curr[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
+       - PocLtCurr as described in section 8.3.2 "Decoding process for reference
+-        picture set.
++        picture set": provides the index of the long term references in DPB array.
+     * - __u64
+       - ``flags``
+       - See :ref:`Decode Parameters Flags <hevc_decode_params_flags>`
+diff --git a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
+index e63b777d4266..87086f5c5495 100644
+--- a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
++++ b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
+@@ -264,24 +264,11 @@ static void set_params(struct hantro_ctx *ctx)
+       hantro_reg_write(vpu, &g2_apf_threshold, 8);
+ }
+-static int find_ref_pic_index(const struct v4l2_hevc_dpb_entry *dpb, int pic_order_cnt)
+-{
+-      int i;
+-
+-      for (i = 0; i < V4L2_HEVC_DPB_ENTRIES_NUM_MAX; i++) {
+-              if (dpb[i].pic_order_cnt[0] == pic_order_cnt)
+-                      return i;
+-      }
+-
+-      return 0x0;
+-}
+-
+ static void set_ref_pic_list(struct hantro_ctx *ctx)
+ {
+       const struct hantro_hevc_dec_ctrls *ctrls = &ctx->hevc_dec.ctrls;
+       struct hantro_dev *vpu = ctx->dev;
+       const struct v4l2_ctrl_hevc_decode_params *decode_params = ctrls->decode_params;
+-      const struct v4l2_hevc_dpb_entry *dpb = decode_params->dpb;
+       u32 list0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX] = {};
+       u32 list1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX] = {};
+       static const struct hantro_reg ref_pic_regs0[] = {
+@@ -325,11 +312,11 @@ static void set_ref_pic_list(struct hantro_ctx *ctx)
+       /* List 0 contains: short term before, short term after and long term */
+       j = 0;
+       for (i = 0; i < decode_params->num_poc_st_curr_before && j < ARRAY_SIZE(list0); i++)
+-              list0[j++] = find_ref_pic_index(dpb, decode_params->poc_st_curr_before[i]);
++              list0[j++] = decode_params->poc_st_curr_before[i];
+       for (i = 0; i < decode_params->num_poc_st_curr_after && j < ARRAY_SIZE(list0); i++)
+-              list0[j++] = find_ref_pic_index(dpb, decode_params->poc_st_curr_after[i]);
++              list0[j++] = decode_params->poc_st_curr_after[i];
+       for (i = 0; i < decode_params->num_poc_lt_curr && j < ARRAY_SIZE(list0); i++)
+-              list0[j++] = find_ref_pic_index(dpb, decode_params->poc_lt_curr[i]);
++              list0[j++] = decode_params->poc_lt_curr[i];
+       /* Fill the list, copying over and over */
+       i = 0;
+@@ -338,11 +325,11 @@ static void set_ref_pic_list(struct hantro_ctx *ctx)
+       j = 0;
+       for (i = 0; i < decode_params->num_poc_st_curr_after && j < ARRAY_SIZE(list1); i++)
+-              list1[j++] = find_ref_pic_index(dpb, decode_params->poc_st_curr_after[i]);
++              list1[j++] = decode_params->poc_st_curr_after[i];
+       for (i = 0; i < decode_params->num_poc_st_curr_before && j < ARRAY_SIZE(list1); i++)
+-              list1[j++] = find_ref_pic_index(dpb, decode_params->poc_st_curr_before[i]);
++              list1[j++] = decode_params->poc_st_curr_before[i];
+       for (i = 0; i < decode_params->num_poc_lt_curr && j < ARRAY_SIZE(list1); i++)
+-              list1[j++] = find_ref_pic_index(dpb, decode_params->poc_lt_curr[i]);
++              list1[j++] = decode_params->poc_lt_curr[i];
+       i = 0;
+       while (j < ARRAY_SIZE(list1))
+-- 
+2.35.1
+
diff --git a/queue-5.15/media-imx-jpeg-add-pm-runtime-support-for-imx-jpeg.patch b/queue-5.15/media-imx-jpeg-add-pm-runtime-support-for-imx-jpeg.patch
new file mode 100644 (file)
index 0000000..6e3b411
--- /dev/null
@@ -0,0 +1,188 @@
+From d5c825706bd7fea69b2b20bfd30663192f661611 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Oct 2021 17:30:38 +0100
+Subject: media: imx-jpeg: Add pm-runtime support for imx-jpeg
+
+From: Mirela Rabulea <mirela.rabulea@oss.nxp.com>
+
+[ Upstream commit 4c2e5156d9fa63a3f41c2bf56b694ad42df825d7 ]
+
+Save some power by disabling/enabling the jpeg clocks with
+every stream stop/start.
+Do not use DL_FLAG_RPM_ACTIVE in mxc_jpeg_attach_pm_domains,
+to ensure power domains are off after probe.
+
+Signed-off-by: Mirela Rabulea <mirela.rabulea@oss.nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/imx-jpeg/mxc-jpeg.c | 73 +++++++++++++++++++++-
+ drivers/media/platform/imx-jpeg/mxc-jpeg.h |  2 +
+ 2 files changed, 72 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
+index 5289a822bcb1..bc66c09b807a 100644
+--- a/drivers/media/platform/imx-jpeg/mxc-jpeg.c
++++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
+@@ -49,6 +49,7 @@
+ #include <linux/slab.h>
+ #include <linux/irqreturn.h>
+ #include <linux/interrupt.h>
++#include <linux/pm_runtime.h>
+ #include <linux/pm_domain.h>
+ #include <linux/string.h>
+@@ -1074,10 +1075,17 @@ static int mxc_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
+ {
+       struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(q);
+       struct mxc_jpeg_q_data *q_data = mxc_jpeg_get_q_data(ctx, q->type);
++      int ret;
+       dev_dbg(ctx->mxc_jpeg->dev, "Start streaming ctx=%p", ctx);
+       q_data->sequence = 0;
++      ret = pm_runtime_resume_and_get(ctx->mxc_jpeg->dev);
++      if (ret < 0) {
++              dev_err(ctx->mxc_jpeg->dev, "Failed to power up jpeg\n");
++              return ret;
++      }
++
+       return 0;
+ }
+@@ -1095,9 +1103,10 @@ static void mxc_jpeg_stop_streaming(struct vb2_queue *q)
+               else
+                       vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+               if (!vbuf)
+-                      return;
++                      break;
+               v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
+       }
++      pm_runtime_put_sync(&ctx->mxc_jpeg->pdev->dev);
+ }
+ static int mxc_jpeg_valid_comp_id(struct device *dev,
+@@ -1957,8 +1966,7 @@ static int mxc_jpeg_attach_pm_domains(struct mxc_jpeg_dev *jpeg)
+               jpeg->pd_link[i] = device_link_add(dev, jpeg->pd_dev[i],
+                                                  DL_FLAG_STATELESS |
+-                                                 DL_FLAG_PM_RUNTIME |
+-                                                 DL_FLAG_RPM_ACTIVE);
++                                                 DL_FLAG_PM_RUNTIME);
+               if (!jpeg->pd_link[i]) {
+                       ret = -EINVAL;
+                       goto fail;
+@@ -2023,6 +2031,19 @@ static int mxc_jpeg_probe(struct platform_device *pdev)
+       jpeg->dev = dev;
+       jpeg->mode = mode;
++      /* Get clocks */
++      jpeg->clk_ipg = devm_clk_get(dev, "ipg");
++      if (IS_ERR(jpeg->clk_ipg)) {
++              dev_err(dev, "failed to get clock: ipg\n");
++              goto err_clk;
++      }
++
++      jpeg->clk_per = devm_clk_get(dev, "per");
++      if (IS_ERR(jpeg->clk_per)) {
++              dev_err(dev, "failed to get clock: per\n");
++              goto err_clk;
++      }
++
+       ret = mxc_jpeg_attach_pm_domains(jpeg);
+       if (ret < 0) {
+               dev_err(dev, "failed to attach power domains %d\n", ret);
+@@ -2091,6 +2112,7 @@ static int mxc_jpeg_probe(struct platform_device *pdev)
+                         jpeg->dec_vdev->minor);
+       platform_set_drvdata(pdev, jpeg);
++      pm_runtime_enable(dev);
+       return 0;
+@@ -2107,9 +2129,52 @@ static int mxc_jpeg_probe(struct platform_device *pdev)
+       mxc_jpeg_detach_pm_domains(jpeg);
+ err_irq:
++err_clk:
++      return ret;
++}
++
++#ifdef CONFIG_PM
++static int mxc_jpeg_runtime_resume(struct device *dev)
++{
++      struct mxc_jpeg_dev *jpeg = dev_get_drvdata(dev);
++      int ret;
++
++      ret = clk_prepare_enable(jpeg->clk_ipg);
++      if (ret < 0) {
++              dev_err(dev, "failed to enable clock: ipg\n");
++              goto err_ipg;
++      }
++
++      ret = clk_prepare_enable(jpeg->clk_per);
++      if (ret < 0) {
++              dev_err(dev, "failed to enable clock: per\n");
++              goto err_per;
++      }
++
++      return 0;
++
++err_per:
++      clk_disable_unprepare(jpeg->clk_ipg);
++err_ipg:
+       return ret;
+ }
++static int mxc_jpeg_runtime_suspend(struct device *dev)
++{
++      struct mxc_jpeg_dev *jpeg = dev_get_drvdata(dev);
++
++      clk_disable_unprepare(jpeg->clk_ipg);
++      clk_disable_unprepare(jpeg->clk_per);
++
++      return 0;
++}
++#endif
++
++static const struct dev_pm_ops        mxc_jpeg_pm_ops = {
++      SET_RUNTIME_PM_OPS(mxc_jpeg_runtime_suspend,
++                         mxc_jpeg_runtime_resume, NULL)
++};
++
+ static int mxc_jpeg_remove(struct platform_device *pdev)
+ {
+       unsigned int slot;
+@@ -2118,6 +2183,7 @@ static int mxc_jpeg_remove(struct platform_device *pdev)
+       for (slot = 0; slot < MXC_MAX_SLOTS; slot++)
+               mxc_jpeg_free_slot_data(jpeg, slot);
++      pm_runtime_disable(&pdev->dev);
+       video_unregister_device(jpeg->dec_vdev);
+       v4l2_m2m_release(jpeg->m2m_dev);
+       v4l2_device_unregister(&jpeg->v4l2_dev);
+@@ -2134,6 +2200,7 @@ static struct platform_driver mxc_jpeg_driver = {
+       .driver = {
+               .name = "mxc-jpeg",
+               .of_match_table = mxc_jpeg_match,
++              .pm = &mxc_jpeg_pm_ops,
+       },
+ };
+ module_platform_driver(mxc_jpeg_driver);
+diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg.h b/drivers/media/platform/imx-jpeg/mxc-jpeg.h
+index 4c210852e876..9fb2a5aaa941 100644
+--- a/drivers/media/platform/imx-jpeg/mxc-jpeg.h
++++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.h
+@@ -109,6 +109,8 @@ struct mxc_jpeg_dev {
+       spinlock_t                      hw_lock; /* hardware access lock */
+       unsigned int                    mode;
+       struct mutex                    lock; /* v4l2 ioctls serialization */
++      struct clk                      *clk_ipg;
++      struct clk                      *clk_per;
+       struct platform_device          *pdev;
+       struct device                   *dev;
+       void __iomem                    *base_reg;
+-- 
+2.35.1
+
diff --git a/queue-5.15/media-imx-jpeg-align-upwards-buffer-size.patch b/queue-5.15/media-imx-jpeg-align-upwards-buffer-size.patch
new file mode 100644 (file)
index 0000000..b23a8a8
--- /dev/null
@@ -0,0 +1,188 @@
+From fdb865bea637f0a8e8eee745f1a2005ad40927a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 May 2022 08:49:19 +0100
+Subject: media: imx-jpeg: Align upwards buffer size
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit 9e7aa76cdb02923ee23a0ddd48f38bdc3512f92b ]
+
+The hardware can support any image size WxH,
+with arbitrary W (image width) and H (image height) dimensions.
+
+Align upwards buffer size for both encoder and decoder.
+and leave the picture resolution unchanged.
+
+For decoder, the risk of memory out of bounds can be avoided.
+For both encoder and decoder, the driver will lift the limitation of
+resolution alignment.
+
+For example, the decoder can support jpeg whose resolution is 227x149
+the encoder can support nv12 1080P, won't change it to 1920x1072.
+
+Fixes: 2db16c6ed72ce ("media: imx-jpeg: Add V4L2 driver for i.MX8 JPEG Encoder/Decoder")
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/imx-jpeg/mxc-jpeg.c | 88 +++++++++-------------
+ 1 file changed, 37 insertions(+), 51 deletions(-)
+
+diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
+index 52732fbb2664..e043023836e3 100644
+--- a/drivers/media/platform/imx-jpeg/mxc-jpeg.c
++++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
+@@ -875,8 +875,8 @@ static void mxc_jpeg_config_enc_desc(struct vb2_buffer *out_buf,
+       jpeg->slot_data[slot].cfg_stream_size =
+                       mxc_jpeg_setup_cfg_stream(cfg_stream_vaddr,
+                                                 q_data->fmt->fourcc,
+-                                                q_data->w_adjusted,
+-                                                q_data->h_adjusted);
++                                                q_data->w,
++                                                q_data->h);
+       /* chain the config descriptor with the encoding descriptor */
+       cfg_desc->next_descpt_ptr = desc_handle | MXC_NXT_DESCPT_EN;
+@@ -956,7 +956,7 @@ static bool mxc_jpeg_source_change(struct mxc_jpeg_ctx *ctx,
+                                     &q_data_cap->h_adjusted,
+                                     q_data_cap->h_adjusted, /* adjust up */
+                                     MXC_JPEG_MAX_HEIGHT,
+-                                    q_data_cap->fmt->v_align,
++                                    0,
+                                     0);
+               /* setup bytesperline/sizeimage for capture queue */
+@@ -1145,16 +1145,28 @@ static int mxc_jpeg_queue_setup(struct vb2_queue *q,
+ {
+       struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(q);
+       struct mxc_jpeg_q_data *q_data = NULL;
++      struct mxc_jpeg_q_data tmp_q;
+       int i;
+       q_data = mxc_jpeg_get_q_data(ctx, q->type);
+       if (!q_data)
+               return -EINVAL;
++      tmp_q.fmt = q_data->fmt;
++      tmp_q.w = q_data->w_adjusted;
++      tmp_q.h = q_data->h_adjusted;
++      for (i = 0; i < MXC_JPEG_MAX_PLANES; i++) {
++              tmp_q.bytesperline[i] = q_data->bytesperline[i];
++              tmp_q.sizeimage[i] = q_data->sizeimage[i];
++      }
++      mxc_jpeg_sizeimage(&tmp_q);
++      for (i = 0; i < MXC_JPEG_MAX_PLANES; i++)
++              tmp_q.sizeimage[i] = max(tmp_q.sizeimage[i], q_data->sizeimage[i]);
++
+       /* Handle CREATE_BUFS situation - *nplanes != 0 */
+       if (*nplanes) {
+               for (i = 0; i < *nplanes; i++) {
+-                      if (sizes[i] < q_data->sizeimage[i])
++                      if (sizes[i] < tmp_q.sizeimage[i])
+                               return -EINVAL;
+               }
+               return 0;
+@@ -1163,7 +1175,7 @@ static int mxc_jpeg_queue_setup(struct vb2_queue *q,
+       /* Handle REQBUFS situation */
+       *nplanes = q_data->fmt->colplanes;
+       for (i = 0; i < *nplanes; i++)
+-              sizes[i] = q_data->sizeimage[i];
++              sizes[i] = tmp_q.sizeimage[i];
+       return 0;
+ }
+@@ -1363,11 +1375,6 @@ static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx, struct vb2_buffer *vb)
+       }
+       q_data_out->w = header.frame.width;
+       q_data_out->h = header.frame.height;
+-      if (header.frame.width % 8 != 0 || header.frame.height % 8 != 0) {
+-              dev_err(dev, "JPEG width or height not multiple of 8: %dx%d\n",
+-                      header.frame.width, header.frame.height);
+-              return -EINVAL;
+-      }
+       if (header.frame.width > MXC_JPEG_MAX_WIDTH ||
+           header.frame.height > MXC_JPEG_MAX_HEIGHT) {
+               dev_err(dev, "JPEG width or height should be <= 8192: %dx%d\n",
+@@ -1679,22 +1686,17 @@ static int mxc_jpeg_try_fmt(struct v4l2_format *f, const struct mxc_jpeg_fmt *fm
+       pix_mp->num_planes = fmt->colplanes;
+       pix_mp->pixelformat = fmt->fourcc;
+-      /*
+-       * use MXC_JPEG_H_ALIGN instead of fmt->v_align, for vertical
+-       * alignment, to loosen up the alignment to multiple of 8,
+-       * otherwise NV12-1080p fails as 1080 is not a multiple of 16
+-       */
++      pix_mp->width = w;
++      pix_mp->height = h;
+       v4l_bound_align_image(&w,
+-                            MXC_JPEG_MIN_WIDTH,
+-                            w, /* adjust downwards*/
++                            w, /* adjust upwards*/
++                            MXC_JPEG_MAX_WIDTH,
+                             fmt->h_align,
+                             &h,
+-                            MXC_JPEG_MIN_HEIGHT,
+-                            h, /* adjust downwards*/
+-                            MXC_JPEG_H_ALIGN,
++                            h, /* adjust upwards*/
++                            MXC_JPEG_MAX_HEIGHT,
++                            0,
+                             0);
+-      pix_mp->width = w; /* negotiate the width */
+-      pix_mp->height = h; /* negotiate the height */
+       /* get user input into the tmp_q */
+       tmp_q.w = w;
+@@ -1820,35 +1822,19 @@ static int mxc_jpeg_s_fmt(struct mxc_jpeg_ctx *ctx,
+       q_data->w_adjusted = q_data->w;
+       q_data->h_adjusted = q_data->h;
+-      if (jpeg->mode == MXC_JPEG_DECODE) {
+-              /*
+-               * align up the resolution for CAST IP,
+-               * but leave the buffer resolution unchanged
+-               */
+-              v4l_bound_align_image(&q_data->w_adjusted,
+-                                    q_data->w_adjusted,  /* adjust upwards */
+-                                    MXC_JPEG_MAX_WIDTH,
+-                                    q_data->fmt->h_align,
+-                                    &q_data->h_adjusted,
+-                                    q_data->h_adjusted, /* adjust upwards */
+-                                    MXC_JPEG_MAX_HEIGHT,
+-                                    q_data->fmt->v_align,
+-                                    0);
+-      } else {
+-              /*
+-               * align down the resolution for CAST IP,
+-               * but leave the buffer resolution unchanged
+-               */
+-              v4l_bound_align_image(&q_data->w_adjusted,
+-                                    MXC_JPEG_MIN_WIDTH,
+-                                    q_data->w_adjusted, /* adjust downwards*/
+-                                    q_data->fmt->h_align,
+-                                    &q_data->h_adjusted,
+-                                    MXC_JPEG_MIN_HEIGHT,
+-                                    q_data->h_adjusted, /* adjust downwards*/
+-                                    q_data->fmt->v_align,
+-                                    0);
+-      }
++      /*
++       * align up the resolution for CAST IP,
++       * but leave the buffer resolution unchanged
++       */
++      v4l_bound_align_image(&q_data->w_adjusted,
++                            q_data->w_adjusted,  /* adjust upwards */
++                            MXC_JPEG_MAX_WIDTH,
++                            q_data->fmt->h_align,
++                            &q_data->h_adjusted,
++                            q_data->h_adjusted, /* adjust upwards */
++                            MXC_JPEG_MAX_HEIGHT,
++                            q_data->fmt->v_align,
++                            0);
+       for (i = 0; i < pix_mp->num_planes; i++) {
+               q_data->bytesperline[i] = pix_mp->plane_fmt[i].bytesperline;
+-- 
+2.35.1
+
diff --git a/queue-5.15/media-imx-jpeg-correct-some-definition-according-spe.patch b/queue-5.15/media-imx-jpeg-correct-some-definition-according-spe.patch
new file mode 100644 (file)
index 0000000..2209d16
--- /dev/null
@@ -0,0 +1,46 @@
+From 44a3f085468fe7ab69a896f7d419d4da90783cae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 May 2022 08:47:31 +0100
+Subject: media: imx-jpeg: Correct some definition according specification
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit 5a601f89e846c1b6005ab274d039e5036fc22015 ]
+
+the register CAST_NOMFRSIZE_LO should be equal to CAST_STATUS16
+the register CAST_NOMFRSIZE_HI should be equal to CAST_STATUS17
+the register CAST_OFBSIZE_LO should be equal to CAST_STATUS18
+the register CAST_OFBSIZE_HI should be equal to CAST_STATUS19
+
+Fixes: 2db16c6ed72ce ("media: imx-jpeg: Add V4L2 driver for i.MX8 JPEG Encoder/Decoder")
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Reviewed-by: Mirela Rabulea <mirela.rabulea@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/imx-jpeg/mxc-jpeg-hw.h | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg-hw.h b/drivers/media/platform/imx-jpeg/mxc-jpeg-hw.h
+index ae70d3a0dc24..12f132a83a23 100644
+--- a/drivers/media/platform/imx-jpeg/mxc-jpeg-hw.h
++++ b/drivers/media/platform/imx-jpeg/mxc-jpeg-hw.h
+@@ -53,10 +53,10 @@
+ #define CAST_REC_REGS_SEL             CAST_STATUS4
+ #define CAST_LUMTH                    CAST_STATUS5
+ #define CAST_CHRTH                    CAST_STATUS6
+-#define CAST_NOMFRSIZE_LO             CAST_STATUS7
+-#define CAST_NOMFRSIZE_HI             CAST_STATUS8
+-#define CAST_OFBSIZE_LO                       CAST_STATUS9
+-#define CAST_OFBSIZE_HI                       CAST_STATUS10
++#define CAST_NOMFRSIZE_LO             CAST_STATUS16
++#define CAST_NOMFRSIZE_HI             CAST_STATUS17
++#define CAST_OFBSIZE_LO                       CAST_STATUS18
++#define CAST_OFBSIZE_HI                       CAST_STATUS19
+ #define MXC_MAX_SLOTS 1 /* TODO use all 4 slots*/
+ /* JPEG-Decoder Wrapper Slot Registers 0..3 */
+-- 
+2.35.1
+
diff --git a/queue-5.15/media-imx-jpeg-disable-slot-interrupt-when-frame-don.patch b/queue-5.15/media-imx-jpeg-disable-slot-interrupt-when-frame-don.patch
new file mode 100644 (file)
index 0000000..897a525
--- /dev/null
@@ -0,0 +1,88 @@
+From b19cc6d79e91aea87d80952e9e3be027da3358f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jun 2022 03:00:57 +0100
+Subject: media: imx-jpeg: Disable slot interrupt when frame done
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit 22a2bc88c139dc9757bdb1d0a3665ac27edc79a5 ]
+
+The interrupt STMBUF_HALF may be triggered after frame done.
+It may led to system hang if driver try to access the register after
+power off.
+
+Disable the slot interrupt when frame done.
+
+Fixes: 2db16c6ed72ce ("media: imx-jpeg: Add V4L2 driver for i.MX8 JPEG Encoder/Decoder")
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Reviewed-by: Mirela Rabulea <mirela.rabulea@nxp.com>
+Tested-by: Mirela Rabulea <mirela.rabulea@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/imx-jpeg/mxc-jpeg-hw.c |  5 +++++
+ drivers/media/platform/imx-jpeg/mxc-jpeg-hw.h |  1 +
+ drivers/media/platform/imx-jpeg/mxc-jpeg.c    | 10 ++--------
+ 3 files changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg-hw.c b/drivers/media/platform/imx-jpeg/mxc-jpeg-hw.c
+index 29c604b1b179..718b7b08f93e 100644
+--- a/drivers/media/platform/imx-jpeg/mxc-jpeg-hw.c
++++ b/drivers/media/platform/imx-jpeg/mxc-jpeg-hw.c
+@@ -79,6 +79,11 @@ void mxc_jpeg_enable_irq(void __iomem *reg, int slot)
+       writel(0xFFFFFFFF, reg + MXC_SLOT_OFFSET(slot, SLOT_IRQ_EN));
+ }
++void mxc_jpeg_disable_irq(void __iomem *reg, int slot)
++{
++      writel(0x0, reg + MXC_SLOT_OFFSET(slot, SLOT_IRQ_EN));
++}
++
+ void mxc_jpeg_sw_reset(void __iomem *reg)
+ {
+       /*
+diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg-hw.h b/drivers/media/platform/imx-jpeg/mxc-jpeg-hw.h
+index 12f132a83a23..bf4e1973a066 100644
+--- a/drivers/media/platform/imx-jpeg/mxc-jpeg-hw.h
++++ b/drivers/media/platform/imx-jpeg/mxc-jpeg-hw.h
+@@ -125,6 +125,7 @@ u32 mxc_jpeg_get_offset(void __iomem *reg, int slot);
+ void mxc_jpeg_enable_slot(void __iomem *reg, int slot);
+ void mxc_jpeg_set_l_endian(void __iomem *reg, int le);
+ void mxc_jpeg_enable_irq(void __iomem *reg, int slot);
++void mxc_jpeg_disable_irq(void __iomem *reg, int slot);
+ int mxc_jpeg_set_input(void __iomem *reg, u32 in_buf, u32 bufsize);
+ int mxc_jpeg_set_output(void __iomem *reg, u16 out_pitch, u32 out_buf,
+                       u16 w, u16 h);
+diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
+index da80167cb57d..aeb3704cfff0 100644
+--- a/drivers/media/platform/imx-jpeg/mxc-jpeg.c
++++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
+@@ -579,15 +579,8 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv)
+       dev_dbg(dev, "Irq %d on slot %d.\n", irq, slot);
+       ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
+-      if (!ctx) {
+-              dev_err(dev,
+-                      "Instance released before the end of transaction.\n");
+-              /* soft reset only resets internal state, not registers */
+-              mxc_jpeg_sw_reset(reg);
+-              /* clear all interrupts */
+-              writel(0xFFFFFFFF, reg + MXC_SLOT_OFFSET(slot, SLOT_STATUS));
++      if (WARN_ON(!ctx))
+               goto job_unlock;
+-      }
+       if (slot != ctx->slot) {
+               /* TODO investigate when adding multi-instance support */
+@@ -659,6 +652,7 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv)
+       buf_state = VB2_BUF_STATE_DONE;
+ buffers_done:
++      mxc_jpeg_disable_irq(reg, ctx->slot);
+       jpeg->slot_data[slot].used = false; /* unused, but don't free */
+       mxc_jpeg_check_and_set_last_buffer(ctx, src_buf, dst_buf);
+       v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+-- 
+2.35.1
+
diff --git a/queue-5.15/media-imx-jpeg-handle-source-change-in-a-function.patch b/queue-5.15/media-imx-jpeg-handle-source-change-in-a-function.patch
new file mode 100644 (file)
index 0000000..83fb4d1
--- /dev/null
@@ -0,0 +1,184 @@
+From 0f6e6f6b31455fd2d15d40239e1781610a0e0480 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Mar 2022 10:05:57 +0100
+Subject: media: imx-jpeg: Handle source change in a function
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit 831f87424dd3973612782983ef7352789795b4df ]
+
+Refine code to support dynamic resolution change
+
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Reviewed-by: Mirela Rabulea <mirela.rabulea@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/imx-jpeg/mxc-jpeg.c | 114 ++++++++++++---------
+ 1 file changed, 65 insertions(+), 49 deletions(-)
+
+diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
+index 718de999987e..6289fec6e2a0 100644
+--- a/drivers/media/platform/imx-jpeg/mxc-jpeg.c
++++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
+@@ -301,6 +301,9 @@ struct mxc_jpeg_src_buf {
+       /* mxc-jpeg specific */
+       bool                    dht_needed;
+       bool                    jpeg_parse_error;
++      const struct mxc_jpeg_fmt       *fmt;
++      int                     w;
++      int                     h;
+ };
+ static inline struct mxc_jpeg_src_buf *vb2_to_mxc_buf(struct vb2_buffer *vb)
+@@ -313,6 +316,9 @@ static unsigned int debug;
+ module_param(debug, int, 0644);
+ MODULE_PARM_DESC(debug, "Debug level (0-3)");
++static void mxc_jpeg_bytesperline(struct mxc_jpeg_q_data *q, u32 precision);
++static void mxc_jpeg_sizeimage(struct mxc_jpeg_q_data *q);
++
+ static void _bswap16(u16 *a)
+ {
+       *a = ((*a & 0x00FF) << 8) | ((*a & 0xFF00) >> 8);
+@@ -908,6 +914,59 @@ static void mxc_jpeg_config_enc_desc(struct vb2_buffer *out_buf,
+       mxc_jpeg_set_desc(cfg_desc_handle, reg, slot);
+ }
++static bool mxc_jpeg_source_change(struct mxc_jpeg_ctx *ctx,
++                                 struct mxc_jpeg_src_buf *jpeg_src_buf)
++{
++      struct device *dev = ctx->mxc_jpeg->dev;
++      struct mxc_jpeg_q_data *q_data_cap;
++      bool src_chg = false;
++
++      if (!jpeg_src_buf->fmt)
++              return src_chg;
++
++      q_data_cap = mxc_jpeg_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
++      if (q_data_cap->w != jpeg_src_buf->w || q_data_cap->h != jpeg_src_buf->h) {
++              dev_dbg(dev, "Detected jpeg res=(%dx%d)->(%dx%d), pixfmt=%c%c%c%c\n",
++                      q_data_cap->w, q_data_cap->h,
++                      jpeg_src_buf->w, jpeg_src_buf->h,
++                      (jpeg_src_buf->fmt->fourcc & 0xff),
++                      (jpeg_src_buf->fmt->fourcc >>  8) & 0xff,
++                      (jpeg_src_buf->fmt->fourcc >> 16) & 0xff,
++                      (jpeg_src_buf->fmt->fourcc >> 24) & 0xff);
++
++              /*
++               * set-up the capture queue with the pixelformat and resolution
++               * detected from the jpeg output stream
++               */
++              q_data_cap->w = jpeg_src_buf->w;
++              q_data_cap->h = jpeg_src_buf->h;
++              q_data_cap->fmt = jpeg_src_buf->fmt;
++              q_data_cap->w_adjusted = q_data_cap->w;
++              q_data_cap->h_adjusted = q_data_cap->h;
++
++              /*
++               * align up the resolution for CAST IP,
++               * but leave the buffer resolution unchanged
++               */
++              v4l_bound_align_image(&q_data_cap->w_adjusted,
++                                    q_data_cap->w_adjusted,  /* adjust up */
++                                    MXC_JPEG_MAX_WIDTH,
++                                    q_data_cap->fmt->h_align,
++                                    &q_data_cap->h_adjusted,
++                                    q_data_cap->h_adjusted, /* adjust up */
++                                    MXC_JPEG_MAX_HEIGHT,
++                                    q_data_cap->fmt->v_align,
++                                    0);
++
++              /* setup bytesperline/sizeimage for capture queue */
++              mxc_jpeg_bytesperline(q_data_cap, jpeg_src_buf->fmt->precision);
++              mxc_jpeg_sizeimage(q_data_cap);
++              notify_src_chg(ctx);
++              src_chg = true;
++      }
++      return src_chg;
++}
++
+ static void mxc_jpeg_device_run(void *priv)
+ {
+       struct mxc_jpeg_ctx *ctx = priv;
+@@ -1200,8 +1259,7 @@ static u32 mxc_jpeg_get_image_format(struct device *dev,
+       return fourcc;
+ }
+-static void mxc_jpeg_bytesperline(struct mxc_jpeg_q_data *q,
+-                                u32 precision)
++static void mxc_jpeg_bytesperline(struct mxc_jpeg_q_data *q, u32 precision)
+ {
+       /* Bytes distance between the leftmost pixels in two adjacent lines */
+       if (q->fmt->fourcc == V4L2_PIX_FMT_JPEG) {
+@@ -1252,9 +1310,7 @@ static void mxc_jpeg_sizeimage(struct mxc_jpeg_q_data *q)
+ static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx, struct vb2_buffer *vb)
+ {
+       struct device *dev = ctx->mxc_jpeg->dev;
+-      struct mxc_jpeg_q_data *q_data_out, *q_data_cap;
+-      enum v4l2_buf_type cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+-      bool src_chg = false;
++      struct mxc_jpeg_q_data *q_data_out;
+       u32 fourcc;
+       struct v4l2_jpeg_header header;
+       struct mxc_jpeg_sof *psof = NULL;
+@@ -1322,51 +1378,11 @@ static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx, struct vb2_buffer *vb)
+       if (fourcc == 0)
+               return -EINVAL;
+-      /*
+-       * set-up the capture queue with the pixelformat and resolution
+-       * detected from the jpeg output stream
+-       */
+-      q_data_cap = mxc_jpeg_get_q_data(ctx, cap_type);
+-      if (q_data_cap->w != header.frame.width ||
+-          q_data_cap->h != header.frame.height)
+-              src_chg = true;
+-      q_data_cap->w = header.frame.width;
+-      q_data_cap->h = header.frame.height;
+-      q_data_cap->fmt = mxc_jpeg_find_format(ctx, fourcc);
+-      q_data_cap->w_adjusted = q_data_cap->w;
+-      q_data_cap->h_adjusted = q_data_cap->h;
+-      /*
+-       * align up the resolution for CAST IP,
+-       * but leave the buffer resolution unchanged
+-       */
+-      v4l_bound_align_image(&q_data_cap->w_adjusted,
+-                            q_data_cap->w_adjusted,  /* adjust up */
+-                            MXC_JPEG_MAX_WIDTH,
+-                            q_data_cap->fmt->h_align,
+-                            &q_data_cap->h_adjusted,
+-                            q_data_cap->h_adjusted, /* adjust up */
+-                            MXC_JPEG_MAX_HEIGHT,
+-                            q_data_cap->fmt->v_align,
+-                            0);
+-      dev_dbg(dev, "Detected jpeg res=(%dx%d)->(%dx%d), pixfmt=%c%c%c%c\n",
+-              q_data_cap->w, q_data_cap->h,
+-              q_data_cap->w_adjusted, q_data_cap->h_adjusted,
+-              (fourcc & 0xff),
+-              (fourcc >>  8) & 0xff,
+-              (fourcc >> 16) & 0xff,
+-              (fourcc >> 24) & 0xff);
+-
+-      /* setup bytesperline/sizeimage for capture queue */
+-      mxc_jpeg_bytesperline(q_data_cap, q_data_cap->fmt->precision);
+-      mxc_jpeg_sizeimage(q_data_cap);
++      jpeg_src_buf->fmt = mxc_jpeg_find_format(ctx, fourcc);
++      jpeg_src_buf->w = header.frame.width;
++      jpeg_src_buf->h = header.frame.height;
+-      /*
+-       * if the CAPTURE format was updated with new values, regardless of
+-       * whether they match the values set by the client or not, signal
+-       * a source change event
+-       */
+-      if (src_chg)
+-              notify_src_chg(ctx);
++      mxc_jpeg_source_change(ctx, jpeg_src_buf);
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/media-imx-jpeg-identify-and-handle-precision-correct.patch b/queue-5.15/media-imx-jpeg-identify-and-handle-precision-correct.patch
new file mode 100644 (file)
index 0000000..d43453e
--- /dev/null
@@ -0,0 +1,181 @@
+From a89ed300e4919c8cd7e93784e2c56b36d00a900c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Mar 2022 10:05:55 +0100
+Subject: media: imx-jpeg: Identify and handle precision correctly
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit bec0a3a67389ede106d0661a007edf832878d8b2 ]
+
+The decoder will save the precision that was detected from jpeg header
+and use it later, when choosing the pixel format and also calculate
+bytesperline according to precision.
+
+The 12bit jpeg is not supported yet,
+but driver shouldn't led to serious problem if user enqueue a 12 bit jpeg.
+And the 12bit jpeg is supported by hardware, driver may support it later.
+
+[hverkuil: document the new precision field]
+
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Reviewed-by: Mirela Rabulea <mirela.rabulea@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/imx-jpeg/mxc-jpeg.c | 37 +++++++++++++++-------
+ drivers/media/platform/imx-jpeg/mxc-jpeg.h |  2 ++
+ 2 files changed, 27 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
+index 5064a994a42e..718de999987e 100644
+--- a/drivers/media/platform/imx-jpeg/mxc-jpeg.c
++++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
+@@ -82,6 +82,7 @@ static const struct mxc_jpeg_fmt mxc_formats[] = {
+               .h_align        = 3,
+               .v_align        = 3,
+               .flags          = MXC_JPEG_FMT_TYPE_RAW,
++              .precision      = 8,
+       },
+       {
+               .name           = "ARGB", /* ARGBARGB packed format */
+@@ -93,6 +94,7 @@ static const struct mxc_jpeg_fmt mxc_formats[] = {
+               .h_align        = 3,
+               .v_align        = 3,
+               .flags          = MXC_JPEG_FMT_TYPE_RAW,
++              .precision      = 8,
+       },
+       {
+               .name           = "YUV420", /* 1st plane = Y, 2nd plane = UV */
+@@ -104,6 +106,7 @@ static const struct mxc_jpeg_fmt mxc_formats[] = {
+               .h_align        = 4,
+               .v_align        = 4,
+               .flags          = MXC_JPEG_FMT_TYPE_RAW,
++              .precision      = 8,
+       },
+       {
+               .name           = "YUV422", /* YUYV */
+@@ -115,6 +118,7 @@ static const struct mxc_jpeg_fmt mxc_formats[] = {
+               .h_align        = 4,
+               .v_align        = 3,
+               .flags          = MXC_JPEG_FMT_TYPE_RAW,
++              .precision      = 8,
+       },
+       {
+               .name           = "YUV444", /* YUVYUV */
+@@ -126,6 +130,7 @@ static const struct mxc_jpeg_fmt mxc_formats[] = {
+               .h_align        = 3,
+               .v_align        = 3,
+               .flags          = MXC_JPEG_FMT_TYPE_RAW,
++              .precision      = 8,
+       },
+       {
+               .name           = "Gray", /* Gray (Y8/Y12) or Single Comp */
+@@ -137,6 +142,7 @@ static const struct mxc_jpeg_fmt mxc_formats[] = {
+               .h_align        = 3,
+               .v_align        = 3,
+               .flags          = MXC_JPEG_FMT_TYPE_RAW,
++              .precision      = 8,
+       },
+ };
+@@ -1166,14 +1172,17 @@ static u32 mxc_jpeg_get_image_format(struct device *dev,
+       for (i = 0; i < MXC_JPEG_NUM_FORMATS; i++)
+               if (mxc_formats[i].subsampling == header->frame.subsampling &&
+-                  mxc_formats[i].nc == header->frame.num_components) {
++                  mxc_formats[i].nc == header->frame.num_components &&
++                  mxc_formats[i].precision == header->frame.precision) {
+                       fourcc = mxc_formats[i].fourcc;
+                       break;
+               }
+       if (fourcc == 0) {
+-              dev_err(dev, "Could not identify image format nc=%d, subsampling=%d\n",
++              dev_err(dev,
++                      "Could not identify image format nc=%d, subsampling=%d, precision=%d\n",
+                       header->frame.num_components,
+-                      header->frame.subsampling);
++                      header->frame.subsampling,
++                      header->frame.precision);
+               return fourcc;
+       }
+       /*
+@@ -1199,18 +1208,22 @@ static void mxc_jpeg_bytesperline(struct mxc_jpeg_q_data *q,
+               /* bytesperline unused for compressed formats */
+               q->bytesperline[0] = 0;
+               q->bytesperline[1] = 0;
+-      } else if (q->fmt->fourcc == V4L2_PIX_FMT_NV12M) {
++      } else if (q->fmt->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_420) {
+               /* When the image format is planar the bytesperline value
+                * applies to the first plane and is divided by the same factor
+                * as the width field for the other planes
+                */
+-              q->bytesperline[0] = q->w * (precision / 8) *
+-                                   (q->fmt->depth / 8);
++              q->bytesperline[0] = q->w * DIV_ROUND_UP(precision, 8);
+               q->bytesperline[1] = q->bytesperline[0];
++      } else if (q->fmt->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_422) {
++              q->bytesperline[0] = q->w * DIV_ROUND_UP(precision, 8) * 2;
++              q->bytesperline[1] = 0;
++      } else if (q->fmt->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_444) {
++              q->bytesperline[0] = q->w * DIV_ROUND_UP(precision, 8) * q->fmt->nc;
++              q->bytesperline[1] = 0;
+       } else {
+-              /* single plane formats */
+-              q->bytesperline[0] = q->w * (precision / 8) *
+-                                   (q->fmt->depth / 8);
++              /* grayscale */
++              q->bytesperline[0] = q->w * DIV_ROUND_UP(precision, 8);
+               q->bytesperline[1] = 0;
+       }
+ }
+@@ -1344,7 +1357,7 @@ static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx, struct vb2_buffer *vb)
+               (fourcc >> 24) & 0xff);
+       /* setup bytesperline/sizeimage for capture queue */
+-      mxc_jpeg_bytesperline(q_data_cap, header.frame.precision);
++      mxc_jpeg_bytesperline(q_data_cap, q_data_cap->fmt->precision);
+       mxc_jpeg_sizeimage(q_data_cap);
+       /*
+@@ -1500,7 +1513,7 @@ static void mxc_jpeg_set_default_params(struct mxc_jpeg_ctx *ctx)
+               q[i]->h = MXC_JPEG_DEFAULT_HEIGHT;
+               q[i]->w_adjusted = MXC_JPEG_DEFAULT_WIDTH;
+               q[i]->h_adjusted = MXC_JPEG_DEFAULT_HEIGHT;
+-              mxc_jpeg_bytesperline(q[i], 8);
++              mxc_jpeg_bytesperline(q[i], q[i]->fmt->precision);
+               mxc_jpeg_sizeimage(q[i]);
+       }
+ }
+@@ -1642,7 +1655,7 @@ static int mxc_jpeg_try_fmt(struct v4l2_format *f, const struct mxc_jpeg_fmt *fm
+       }
+       /* calculate bytesperline & sizeimage into the tmp_q */
+-      mxc_jpeg_bytesperline(&tmp_q, 8);
++      mxc_jpeg_bytesperline(&tmp_q, fmt->precision);
+       mxc_jpeg_sizeimage(&tmp_q);
+       /* adjust user format according to our calculations */
+diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg.h b/drivers/media/platform/imx-jpeg/mxc-jpeg.h
+index f53f004ba851..2b4b30d01e51 100644
+--- a/drivers/media/platform/imx-jpeg/mxc-jpeg.h
++++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.h
+@@ -49,6 +49,7 @@ enum mxc_jpeg_mode {
+  * @h_align:  horizontal alignment order (align to 2^h_align)
+  * @v_align:  vertical alignment order (align to 2^v_align)
+  * @flags:    flags describing format applicability
++ * @precision:  jpeg sample precision
+  */
+ struct mxc_jpeg_fmt {
+       const char                              *name;
+@@ -60,6 +61,7 @@ struct mxc_jpeg_fmt {
+       int                                     h_align;
+       int                                     v_align;
+       u32                                     flags;
++      u8                                      precision;
+ };
+ struct mxc_jpeg_desc {
+-- 
+2.35.1
+
diff --git a/queue-5.15/media-imx-jpeg-implement-drain-using-v4l2-mem2mem-he.patch b/queue-5.15/media-imx-jpeg-implement-drain-using-v4l2-mem2mem-he.patch
new file mode 100644 (file)
index 0000000..d825dee
--- /dev/null
@@ -0,0 +1,309 @@
+From c50098b2c14ee5a60df22dbb803e0ee838dc0eaf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 May 2022 08:50:02 +0100
+Subject: media: imx-jpeg: Implement drain using v4l2-mem2mem helpers
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit 4911c5acf9351c4caf692895c7cf6a4fa46c26b0 ]
+
+v4l2 m2m has supplied some helper function to handle drain,
+so the driver can use the helper function directly.
+
+Fixes: d8ebe298d008c ("media: imx-jpeg: Set V4L2_BUF_FLAG_LAST at eos")
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/imx-jpeg/mxc-jpeg.c | 155 ++++++++++-----------
+ drivers/media/platform/imx-jpeg/mxc-jpeg.h |   2 -
+ 2 files changed, 73 insertions(+), 84 deletions(-)
+
+diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
+index e043023836e3..da80167cb57d 100644
+--- a/drivers/media/platform/imx-jpeg/mxc-jpeg.c
++++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
+@@ -545,6 +545,18 @@ static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg,
+       jpeg->slot_data[slot].used = false;
+ }
++static void mxc_jpeg_check_and_set_last_buffer(struct mxc_jpeg_ctx *ctx,
++                                             struct vb2_v4l2_buffer *src_buf,
++                                             struct vb2_v4l2_buffer *dst_buf)
++{
++      if (v4l2_m2m_is_last_draining_src_buf(ctx->fh.m2m_ctx, src_buf)) {
++              dst_buf->flags |= V4L2_BUF_FLAG_LAST;
++              v4l2_m2m_mark_stopped(ctx->fh.m2m_ctx);
++              notify_eos(ctx);
++              ctx->header_parsed = false;
++      }
++}
++
+ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv)
+ {
+       struct mxc_jpeg_dev *jpeg = priv;
+@@ -619,6 +631,7 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv)
+               dev_dbg(dev, "Decoder DHT cfg finished. Start decoding...\n");
+               goto job_unlock;
+       }
++
+       if (jpeg->mode == MXC_JPEG_ENCODE) {
+               payload = readl(reg + MXC_SLOT_OFFSET(slot, SLOT_BUF_PTR));
+               vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload);
+@@ -647,6 +660,7 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv)
+ buffers_done:
+       jpeg->slot_data[slot].used = false; /* unused, but don't free */
++      mxc_jpeg_check_and_set_last_buffer(ctx, src_buf, dst_buf);
+       v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+       v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+       v4l2_m2m_buf_done(src_buf, buf_state);
+@@ -1013,6 +1027,7 @@ static void mxc_jpeg_device_run(void *priv)
+               jpeg_src_buf->jpeg_parse_error = true;
+       }
+       if (jpeg_src_buf->jpeg_parse_error) {
++              mxc_jpeg_check_and_set_last_buffer(ctx, src_buf, dst_buf);
+               v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+               v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+               v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
+@@ -1068,45 +1083,33 @@ static void mxc_jpeg_device_run(void *priv)
+       spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags);
+ }
+-static void mxc_jpeg_set_last_buffer_dequeued(struct mxc_jpeg_ctx *ctx)
+-{
+-      struct vb2_queue *q;
+-
+-      ctx->stopped = 1;
+-      q = v4l2_m2m_get_dst_vq(ctx->fh.m2m_ctx);
+-      if (!list_empty(&q->done_list))
+-              return;
+-
+-      q->last_buffer_dequeued = true;
+-      wake_up(&q->done_wq);
+-      ctx->stopped = 0;
+-      ctx->header_parsed = false;
+-}
+-
+ static int mxc_jpeg_decoder_cmd(struct file *file, void *priv,
+                               struct v4l2_decoder_cmd *cmd)
+ {
+       struct v4l2_fh *fh = file->private_data;
+       struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(fh);
+-      struct device *dev = ctx->mxc_jpeg->dev;
+       int ret;
+       ret = v4l2_m2m_ioctl_try_decoder_cmd(file, fh, cmd);
+       if (ret < 0)
+               return ret;
+-      if (cmd->cmd == V4L2_DEC_CMD_STOP) {
+-              dev_dbg(dev, "Received V4L2_DEC_CMD_STOP");
+-              if (v4l2_m2m_num_src_bufs_ready(fh->m2m_ctx) == 0) {
+-                      /* No more src bufs, notify app EOS */
+-                      notify_eos(ctx);
+-                      mxc_jpeg_set_last_buffer_dequeued(ctx);
+-              } else {
+-                      /* will send EOS later*/
+-                      ctx->stopping = 1;
+-              }
++      if (!vb2_is_streaming(v4l2_m2m_get_src_vq(fh->m2m_ctx)))
++              return 0;
++
++      ret = v4l2_m2m_ioctl_decoder_cmd(file, priv, cmd);
++      if (ret < 0)
++              return ret;
++
++      if (cmd->cmd == V4L2_DEC_CMD_STOP &&
++          v4l2_m2m_has_stopped(fh->m2m_ctx)) {
++              notify_eos(ctx);
++              ctx->header_parsed = false;
+       }
++      if (cmd->cmd == V4L2_DEC_CMD_START &&
++          v4l2_m2m_has_stopped(fh->m2m_ctx))
++              vb2_clear_last_buffer_dequeued(&fh->m2m_ctx->cap_q_ctx.q);
+       return 0;
+ }
+@@ -1115,24 +1118,27 @@ static int mxc_jpeg_encoder_cmd(struct file *file, void *priv,
+ {
+       struct v4l2_fh *fh = file->private_data;
+       struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(fh);
+-      struct device *dev = ctx->mxc_jpeg->dev;
+       int ret;
+       ret = v4l2_m2m_ioctl_try_encoder_cmd(file, fh, cmd);
+       if (ret < 0)
+               return ret;
+-      if (cmd->cmd == V4L2_ENC_CMD_STOP) {
+-              dev_dbg(dev, "Received V4L2_ENC_CMD_STOP");
+-              if (v4l2_m2m_num_src_bufs_ready(fh->m2m_ctx) == 0) {
+-                      /* No more src bufs, notify app EOS */
+-                      notify_eos(ctx);
+-                      mxc_jpeg_set_last_buffer_dequeued(ctx);
+-              } else {
+-                      /* will send EOS later*/
+-                      ctx->stopping = 1;
+-              }
+-      }
++      if (!vb2_is_streaming(v4l2_m2m_get_src_vq(fh->m2m_ctx)) ||
++          !vb2_is_streaming(v4l2_m2m_get_dst_vq(fh->m2m_ctx)))
++              return 0;
++
++      ret = v4l2_m2m_ioctl_encoder_cmd(file, fh, cmd);
++      if (ret < 0)
++              return 0;
++
++      if (cmd->cmd == V4L2_ENC_CMD_STOP &&
++          v4l2_m2m_has_stopped(fh->m2m_ctx))
++              notify_eos(ctx);
++
++      if (cmd->cmd == V4L2_ENC_CMD_START &&
++          v4l2_m2m_has_stopped(fh->m2m_ctx))
++              vb2_clear_last_buffer_dequeued(&fh->m2m_ctx->cap_q_ctx.q);
+       return 0;
+ }
+@@ -1186,6 +1192,8 @@ static int mxc_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
+       struct mxc_jpeg_q_data *q_data = mxc_jpeg_get_q_data(ctx, q->type);
+       int ret;
++      v4l2_m2m_update_start_streaming_state(ctx->fh.m2m_ctx, q);
++
+       if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE && V4L2_TYPE_IS_CAPTURE(q->type))
+               ctx->source_change = 0;
+       dev_dbg(ctx->mxc_jpeg->dev, "Start streaming ctx=%p", ctx);
+@@ -1217,11 +1225,15 @@ static void mxc_jpeg_stop_streaming(struct vb2_queue *q)
+                       break;
+               v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
+       }
+-      pm_runtime_put_sync(&ctx->mxc_jpeg->pdev->dev);
+-      if (V4L2_TYPE_IS_OUTPUT(q->type)) {
+-              ctx->stopping = 0;
+-              ctx->stopped = 0;
++
++      v4l2_m2m_update_stop_streaming_state(ctx->fh.m2m_ctx, q);
++      if (V4L2_TYPE_IS_OUTPUT(q->type) &&
++          v4l2_m2m_has_stopped(ctx->fh.m2m_ctx)) {
++              notify_eos(ctx);
++              ctx->header_parsed = false;
+       }
++
++      pm_runtime_put_sync(&ctx->mxc_jpeg->pdev->dev);
+ }
+ static int mxc_jpeg_valid_comp_id(struct device *dev,
+@@ -1420,6 +1432,20 @@ static void mxc_jpeg_buf_queue(struct vb2_buffer *vb)
+       struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+       struct mxc_jpeg_src_buf *jpeg_src_buf;
++      if (V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type) &&
++          vb2_is_streaming(vb->vb2_queue) &&
++          v4l2_m2m_dst_buf_is_last(ctx->fh.m2m_ctx)) {
++              struct mxc_jpeg_q_data *q_data;
++
++              q_data = mxc_jpeg_get_q_data(ctx, vb->vb2_queue->type);
++              vbuf->field = V4L2_FIELD_NONE;
++              vbuf->sequence = q_data->sequence++;
++              v4l2_m2m_last_buffer_done(ctx->fh.m2m_ctx, vbuf);
++              notify_eos(ctx);
++              ctx->header_parsed = false;
++              return;
++      }
++
+       if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+               goto end;
+@@ -1469,24 +1495,11 @@ static int mxc_jpeg_buf_prepare(struct vb2_buffer *vb)
+               }
+               vb2_set_plane_payload(vb, i, sizeimage);
+       }
+-      return 0;
+-}
+-
+-static void mxc_jpeg_buf_finish(struct vb2_buffer *vb)
+-{
+-      struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+-      struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+-      struct vb2_queue *q = vb->vb2_queue;
+-
+-      if (V4L2_TYPE_IS_OUTPUT(vb->type))
+-              return;
+-      if (!ctx->stopped)
+-              return;
+-      if (list_empty(&q->done_list)) {
+-              vbuf->flags |= V4L2_BUF_FLAG_LAST;
+-              ctx->stopped = 0;
+-              ctx->header_parsed = false;
++      if (V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type)) {
++              vb2_set_plane_payload(vb, 0, 0);
++              vb2_set_plane_payload(vb, 1, 0);
+       }
++      return 0;
+ }
+ static const struct vb2_ops mxc_jpeg_qops = {
+@@ -1495,7 +1508,6 @@ static const struct vb2_ops mxc_jpeg_qops = {
+       .wait_finish            = vb2_ops_wait_finish,
+       .buf_out_validate       = mxc_jpeg_buf_out_validate,
+       .buf_prepare            = mxc_jpeg_buf_prepare,
+-      .buf_finish             = mxc_jpeg_buf_finish,
+       .start_streaming        = mxc_jpeg_start_streaming,
+       .stop_streaming         = mxc_jpeg_stop_streaming,
+       .buf_queue              = mxc_jpeg_buf_queue,
+@@ -1916,27 +1928,6 @@ static int mxc_jpeg_subscribe_event(struct v4l2_fh *fh,
+       }
+ }
+-static int mxc_jpeg_dqbuf(struct file *file, void *priv,
+-                        struct v4l2_buffer *buf)
+-{
+-      struct v4l2_fh *fh = file->private_data;
+-      struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
+-      struct device *dev = ctx->mxc_jpeg->dev;
+-      int num_src_ready = v4l2_m2m_num_src_bufs_ready(fh->m2m_ctx);
+-      int ret;
+-
+-      dev_dbg(dev, "DQBUF type=%d, index=%d", buf->type, buf->index);
+-      if (ctx->stopping == 1 && num_src_ready == 0) {
+-              /* No more src bufs, notify app EOS */
+-              notify_eos(ctx);
+-              ctx->stopping = 0;
+-              mxc_jpeg_set_last_buffer_dequeued(ctx);
+-      }
+-
+-      ret = v4l2_m2m_dqbuf(file, fh->m2m_ctx, buf);
+-      return ret;
+-}
+-
+ static const struct v4l2_ioctl_ops mxc_jpeg_ioctl_ops = {
+       .vidioc_querycap                = mxc_jpeg_querycap,
+       .vidioc_enum_fmt_vid_cap        = mxc_jpeg_enum_fmt_vid_cap,
+@@ -1960,7 +1951,7 @@ static const struct v4l2_ioctl_ops mxc_jpeg_ioctl_ops = {
+       .vidioc_encoder_cmd             = mxc_jpeg_encoder_cmd,
+       .vidioc_qbuf                    = v4l2_m2m_ioctl_qbuf,
+-      .vidioc_dqbuf                   = mxc_jpeg_dqbuf,
++      .vidioc_dqbuf                   = v4l2_m2m_ioctl_dqbuf,
+       .vidioc_create_bufs             = v4l2_m2m_ioctl_create_bufs,
+       .vidioc_prepare_buf             = v4l2_m2m_ioctl_prepare_buf,
+diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg.h b/drivers/media/platform/imx-jpeg/mxc-jpeg.h
+index 6913ae087e44..542993eb8d5b 100644
+--- a/drivers/media/platform/imx-jpeg/mxc-jpeg.h
++++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.h
+@@ -92,8 +92,6 @@ struct mxc_jpeg_ctx {
+       struct mxc_jpeg_q_data          cap_q;
+       struct v4l2_fh                  fh;
+       enum mxc_jpeg_enc_state         enc_state;
+-      unsigned int                    stopping;
+-      unsigned int                    stopped;
+       unsigned int                    slot;
+       unsigned int                    source_change;
+       bool                            header_parsed;
+-- 
+2.35.1
+
diff --git a/queue-5.15/media-imx-jpeg-leave-a-blank-space-before-the-config.patch b/queue-5.15/media-imx-jpeg-leave-a-blank-space-before-the-config.patch
new file mode 100644 (file)
index 0000000..6631602
--- /dev/null
@@ -0,0 +1,59 @@
+From 2d868182ce68088b86b58dc1fbe6f23b29e86435 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 May 2022 08:48:37 +0100
+Subject: media: imx-jpeg: Leave a blank space before the configuration data
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit 6285cdea19daf764bf00f662a59fc83ef67345cf ]
+
+There is a hardware bug that it will load
+the first 128 bytes of configuration data twice,
+it will led to some configure error.
+so shift the configuration data 128 bytes,
+and make the first 128 bytes all zero,
+then hardware will load the 128 zero twice,
+and ignore them as garbage.
+then the configuration data can be loaded correctly
+
+Fixes: 2db16c6ed72ce ("media: imx-jpeg: Add V4L2 driver for i.MX8 JPEG Encoder/Decoder")
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Reviewed-by: Mirela Rabulea <mirela.rabulea@nxp.com>
+Reviewed-by: Tommaso Merciai <tommaso.merciai@amarulasolutions.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/imx-jpeg/mxc-jpeg.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
+index 37905547466b..5289a822bcb1 100644
+--- a/drivers/media/platform/imx-jpeg/mxc-jpeg.c
++++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
+@@ -493,6 +493,7 @@ static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg,
+                                    GFP_ATOMIC);
+       if (!cfg_stm)
+               goto err;
++      memset(cfg_stm, 0, MXC_JPEG_MAX_CFG_STREAM);
+       jpeg->slot_data[slot].cfg_stream_vaddr = cfg_stm;
+ skip_alloc:
+@@ -728,7 +729,13 @@ static unsigned int mxc_jpeg_setup_cfg_stream(void *cfg_stream_vaddr,
+                                             u32 fourcc,
+                                             u16 w, u16 h)
+ {
+-      unsigned int offset = 0;
++      /*
++       * There is a hardware issue that first 128 bytes of configuration data
++       * can't be loaded correctly.
++       * To avoid this issue, we need to write the configuration from
++       * an offset which should be no less than 0x80 (128 bytes).
++       */
++      unsigned int offset = 0x80;
+       u8 *cfg = (u8 *)cfg_stream_vaddr;
+       struct mxc_jpeg_sof *sof;
+       struct mxc_jpeg_sos *sos;
+-- 
+2.35.1
+
diff --git a/queue-5.15/media-imx-jpeg-refactor-function-mxc_jpeg_parse.patch b/queue-5.15/media-imx-jpeg-refactor-function-mxc_jpeg_parse.patch
new file mode 100644 (file)
index 0000000..2f32d34
--- /dev/null
@@ -0,0 +1,68 @@
+From efb9acdb83026829c430edf9526ee37a38b48c58 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Mar 2022 10:05:54 +0100
+Subject: media: imx-jpeg: Refactor function mxc_jpeg_parse
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit 8dd504a3a0a5f73b4c137ce3afc35936a4ecd871 ]
+
+Refine code to support dynamic resolution change
+
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Reviewed-by: Mirela Rabulea <mirela.rabulea@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/imx-jpeg/mxc-jpeg.c | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
+index 2d0c1307180f..5064a994a42e 100644
+--- a/drivers/media/platform/imx-jpeg/mxc-jpeg.c
++++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
+@@ -1236,8 +1236,7 @@ static void mxc_jpeg_sizeimage(struct mxc_jpeg_q_data *q)
+       }
+ }
+-static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx,
+-                        u8 *src_addr, u32 size, bool *dht_needed)
++static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx, struct vb2_buffer *vb)
+ {
+       struct device *dev = ctx->mxc_jpeg->dev;
+       struct mxc_jpeg_q_data *q_data_out, *q_data_cap;
+@@ -1247,6 +1246,9 @@ static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx,
+       struct v4l2_jpeg_header header;
+       struct mxc_jpeg_sof *psof = NULL;
+       struct mxc_jpeg_sos *psos = NULL;
++      struct mxc_jpeg_src_buf *jpeg_src_buf = vb2_to_mxc_buf(vb);
++      u8 *src_addr = (u8 *)vb2_plane_vaddr(vb, 0);
++      u32 size = vb2_get_plane_payload(vb, 0);
+       int ret;
+       memset(&header, 0, sizeof(header));
+@@ -1257,7 +1259,7 @@ static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx,
+       }
+       /* if DHT marker present, no need to inject default one */
+-      *dht_needed = (header.num_dht == 0);
++      jpeg_src_buf->dht_needed = (header.num_dht == 0);
+       q_data_out = mxc_jpeg_get_q_data(ctx,
+                                        V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+@@ -1372,10 +1374,7 @@ static void mxc_jpeg_buf_queue(struct vb2_buffer *vb)
+       jpeg_src_buf = vb2_to_mxc_buf(vb);
+       jpeg_src_buf->jpeg_parse_error = false;
+-      ret = mxc_jpeg_parse(ctx,
+-                           (u8 *)vb2_plane_vaddr(vb, 0),
+-                           vb2_get_plane_payload(vb, 0),
+-                           &jpeg_src_buf->dht_needed);
++      ret = mxc_jpeg_parse(ctx, vb);
+       if (ret)
+               jpeg_src_buf->jpeg_parse_error = true;
+-- 
+2.35.1
+
diff --git a/queue-5.15/media-imx-jpeg-set-v4l2_buf_flag_last-at-eos.patch b/queue-5.15/media-imx-jpeg-set-v4l2_buf_flag_last-at-eos.patch
new file mode 100644 (file)
index 0000000..c0473c1
--- /dev/null
@@ -0,0 +1,135 @@
+From 0938af0ed3533aeb1f1baeafcf6951d140589c8e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Feb 2022 16:41:16 +0800
+Subject: media: imx-jpeg: Set V4L2_BUF_FLAG_LAST at eos
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit d8ebe298d008ccbae3011cbeb139707f01a730c8 ]
+
+The V4L2_EVENT_EOS event is a deprecated behavior,
+the V4L2_BUF_FLAG_LAST buffer flag should be used instead.
+
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Reviewed-by: Mirela Rabulea <mirela.rabulea@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/imx-jpeg/mxc-jpeg.c | 41 ++++++++++++++++++++--
+ drivers/media/platform/imx-jpeg/mxc-jpeg.h |  1 +
+ 2 files changed, 40 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
+index 1ec60f54d5a1..2d0c1307180f 100644
+--- a/drivers/media/platform/imx-jpeg/mxc-jpeg.c
++++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
+@@ -988,6 +988,20 @@ static void mxc_jpeg_device_run(void *priv)
+       spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags);
+ }
++static void mxc_jpeg_set_last_buffer_dequeued(struct mxc_jpeg_ctx *ctx)
++{
++      struct vb2_queue *q;
++
++      ctx->stopped = 1;
++      q = v4l2_m2m_get_dst_vq(ctx->fh.m2m_ctx);
++      if (!list_empty(&q->done_list))
++              return;
++
++      q->last_buffer_dequeued = true;
++      wake_up(&q->done_wq);
++      ctx->stopped = 0;
++}
++
+ static int mxc_jpeg_decoder_cmd(struct file *file, void *priv,
+                               struct v4l2_decoder_cmd *cmd)
+ {
+@@ -1005,6 +1019,7 @@ static int mxc_jpeg_decoder_cmd(struct file *file, void *priv,
+               if (v4l2_m2m_num_src_bufs_ready(fh->m2m_ctx) == 0) {
+                       /* No more src bufs, notify app EOS */
+                       notify_eos(ctx);
++                      mxc_jpeg_set_last_buffer_dequeued(ctx);
+               } else {
+                       /* will send EOS later*/
+                       ctx->stopping = 1;
+@@ -1031,6 +1046,7 @@ static int mxc_jpeg_encoder_cmd(struct file *file, void *priv,
+               if (v4l2_m2m_num_src_bufs_ready(fh->m2m_ctx) == 0) {
+                       /* No more src bufs, notify app EOS */
+                       notify_eos(ctx);
++                      mxc_jpeg_set_last_buffer_dequeued(ctx);
+               } else {
+                       /* will send EOS later*/
+                       ctx->stopping = 1;
+@@ -1107,6 +1123,10 @@ static void mxc_jpeg_stop_streaming(struct vb2_queue *q)
+               v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
+       }
+       pm_runtime_put_sync(&ctx->mxc_jpeg->pdev->dev);
++      if (V4L2_TYPE_IS_OUTPUT(q->type)) {
++              ctx->stopping = 0;
++              ctx->stopped = 0;
++      }
+ }
+ static int mxc_jpeg_valid_comp_id(struct device *dev,
+@@ -1398,12 +1418,29 @@ static int mxc_jpeg_buf_prepare(struct vb2_buffer *vb)
+       return 0;
+ }
++static void mxc_jpeg_buf_finish(struct vb2_buffer *vb)
++{
++      struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
++      struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
++      struct vb2_queue *q = vb->vb2_queue;
++
++      if (V4L2_TYPE_IS_OUTPUT(vb->type))
++              return;
++      if (!ctx->stopped)
++              return;
++      if (list_empty(&q->done_list)) {
++              vbuf->flags |= V4L2_BUF_FLAG_LAST;
++              ctx->stopped = 0;
++      }
++}
++
+ static const struct vb2_ops mxc_jpeg_qops = {
+       .queue_setup            = mxc_jpeg_queue_setup,
+       .wait_prepare           = vb2_ops_wait_prepare,
+       .wait_finish            = vb2_ops_wait_finish,
+       .buf_out_validate       = mxc_jpeg_buf_out_validate,
+       .buf_prepare            = mxc_jpeg_buf_prepare,
++      .buf_finish             = mxc_jpeg_buf_finish,
+       .start_streaming        = mxc_jpeg_start_streaming,
+       .stop_streaming         = mxc_jpeg_stop_streaming,
+       .buf_queue              = mxc_jpeg_buf_queue,
+@@ -1839,14 +1876,14 @@ static int mxc_jpeg_dqbuf(struct file *file, void *priv,
+       int ret;
+       dev_dbg(dev, "DQBUF type=%d, index=%d", buf->type, buf->index);
+-      if (ctx->stopping == 1  && num_src_ready == 0) {
++      if (ctx->stopping == 1 && num_src_ready == 0) {
+               /* No more src bufs, notify app EOS */
+               notify_eos(ctx);
+               ctx->stopping = 0;
++              mxc_jpeg_set_last_buffer_dequeued(ctx);
+       }
+       ret = v4l2_m2m_dqbuf(file, fh->m2m_ctx, buf);
+-
+       return ret;
+ }
+diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg.h b/drivers/media/platform/imx-jpeg/mxc-jpeg.h
+index 9fb2a5aaa941..f53f004ba851 100644
+--- a/drivers/media/platform/imx-jpeg/mxc-jpeg.h
++++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.h
+@@ -91,6 +91,7 @@ struct mxc_jpeg_ctx {
+       struct v4l2_fh                  fh;
+       enum mxc_jpeg_enc_state         enc_state;
+       unsigned int                    stopping;
++      unsigned int                    stopped;
+       unsigned int                    slot;
+ };
+-- 
+2.35.1
+
diff --git a/queue-5.15/media-imx-jpeg-support-dynamic-resolution-change.patch b/queue-5.15/media-imx-jpeg-support-dynamic-resolution-change.patch
new file mode 100644 (file)
index 0000000..4bbcfe4
--- /dev/null
@@ -0,0 +1,211 @@
+From f4989178b182e1e4914575f83fc5c39e10c2d26b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Mar 2022 10:05:58 +0100
+Subject: media: imx-jpeg: Support dynamic resolution change
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit b4e1fb8643daabba850e97df532191acffc23e6a ]
+
+To support dynamic resolution change,
+driver should meet the following conditions:
+1. the previous pictures are all decoded before source change event.
+2. prevent decoding new resolution pictures with incorrect capture
+   buffer, until user handle source change event and setup capture.
+3. report correct fmt and resolution during source change.
+
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Reviewed-by: Mirela Rabulea <mirela.rabulea@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/imx-jpeg/mxc-jpeg.c | 69 +++++++++++++++++-----
+ drivers/media/platform/imx-jpeg/mxc-jpeg.h |  2 +
+ 2 files changed, 55 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
+index 6289fec6e2a0..52732fbb2664 100644
+--- a/drivers/media/platform/imx-jpeg/mxc-jpeg.c
++++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
+@@ -919,13 +919,14 @@ static bool mxc_jpeg_source_change(struct mxc_jpeg_ctx *ctx,
+ {
+       struct device *dev = ctx->mxc_jpeg->dev;
+       struct mxc_jpeg_q_data *q_data_cap;
+-      bool src_chg = false;
+       if (!jpeg_src_buf->fmt)
+-              return src_chg;
++              return false;
+       q_data_cap = mxc_jpeg_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+-      if (q_data_cap->w != jpeg_src_buf->w || q_data_cap->h != jpeg_src_buf->h) {
++      if (q_data_cap->fmt != jpeg_src_buf->fmt ||
++          q_data_cap->w != jpeg_src_buf->w ||
++          q_data_cap->h != jpeg_src_buf->h) {
+               dev_dbg(dev, "Detected jpeg res=(%dx%d)->(%dx%d), pixfmt=%c%c%c%c\n",
+                       q_data_cap->w, q_data_cap->h,
+                       jpeg_src_buf->w, jpeg_src_buf->h,
+@@ -962,9 +963,16 @@ static bool mxc_jpeg_source_change(struct mxc_jpeg_ctx *ctx,
+               mxc_jpeg_bytesperline(q_data_cap, jpeg_src_buf->fmt->precision);
+               mxc_jpeg_sizeimage(q_data_cap);
+               notify_src_chg(ctx);
+-              src_chg = true;
++              ctx->source_change = 1;
+       }
+-      return src_chg;
++      return ctx->source_change ? true : false;
++}
++
++static int mxc_jpeg_job_ready(void *priv)
++{
++      struct mxc_jpeg_ctx *ctx = priv;
++
++      return ctx->source_change ? 0 : 1;
+ }
+ static void mxc_jpeg_device_run(void *priv)
+@@ -1014,6 +1022,13 @@ static void mxc_jpeg_device_run(void *priv)
+               return;
+       }
++      if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE) {
++              if (ctx->source_change || mxc_jpeg_source_change(ctx, jpeg_src_buf)) {
++                      spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags);
++                      v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
++                      return;
++              }
++      }
+       /*
+        * TODO: this reset should be removed, once we figure out
+@@ -1065,6 +1080,7 @@ static void mxc_jpeg_set_last_buffer_dequeued(struct mxc_jpeg_ctx *ctx)
+       q->last_buffer_dequeued = true;
+       wake_up(&q->done_wq);
+       ctx->stopped = 0;
++      ctx->header_parsed = false;
+ }
+ static int mxc_jpeg_decoder_cmd(struct file *file, void *priv,
+@@ -1158,6 +1174,8 @@ static int mxc_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
+       struct mxc_jpeg_q_data *q_data = mxc_jpeg_get_q_data(ctx, q->type);
+       int ret;
++      if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE && V4L2_TYPE_IS_CAPTURE(q->type))
++              ctx->source_change = 0;
+       dev_dbg(ctx->mxc_jpeg->dev, "Start streaming ctx=%p", ctx);
+       q_data->sequence = 0;
+@@ -1336,16 +1354,15 @@ static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx, struct vb2_buffer *vb)
+               dev_warn(dev, "Invalid user resolution 0x0");
+               dev_warn(dev, "Keeping resolution from JPEG: %dx%d",
+                        header.frame.width, header.frame.height);
+-              q_data_out->w = header.frame.width;
+-              q_data_out->h = header.frame.height;
+       } else if (header.frame.width != q_data_out->w ||
+                  header.frame.height != q_data_out->h) {
+               dev_err(dev,
+                       "Resolution mismatch: %dx%d (JPEG) versus %dx%d(user)",
+                       header.frame.width, header.frame.height,
+                       q_data_out->w, q_data_out->h);
+-              return -EINVAL;
+       }
++      q_data_out->w = header.frame.width;
++      q_data_out->h = header.frame.height;
+       if (header.frame.width % 8 != 0 || header.frame.height % 8 != 0) {
+               dev_err(dev, "JPEG width or height not multiple of 8: %dx%d\n",
+                       header.frame.width, header.frame.height);
+@@ -1381,8 +1398,10 @@ static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx, struct vb2_buffer *vb)
+       jpeg_src_buf->fmt = mxc_jpeg_find_format(ctx, fourcc);
+       jpeg_src_buf->w = header.frame.width;
+       jpeg_src_buf->h = header.frame.height;
++      ctx->header_parsed = true;
+-      mxc_jpeg_source_change(ctx, jpeg_src_buf);
++      if (!v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx))
++              mxc_jpeg_source_change(ctx, jpeg_src_buf);
+       return 0;
+ }
+@@ -1459,6 +1478,7 @@ static void mxc_jpeg_buf_finish(struct vb2_buffer *vb)
+       if (list_empty(&q->done_list)) {
+               vbuf->flags |= V4L2_BUF_FLAG_LAST;
+               ctx->stopped = 0;
++              ctx->header_parsed = false;
+       }
+ }
+@@ -1604,26 +1624,42 @@ static int mxc_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
+                                    struct v4l2_fmtdesc *f)
+ {
+       struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
++      struct mxc_jpeg_q_data *q_data = mxc_jpeg_get_q_data(ctx, f->type);
+-      if (ctx->mxc_jpeg->mode == MXC_JPEG_ENCODE)
++      if (ctx->mxc_jpeg->mode == MXC_JPEG_ENCODE) {
+               return enum_fmt(mxc_formats, MXC_JPEG_NUM_FORMATS, f,
+                       MXC_JPEG_FMT_TYPE_ENC);
+-      else
++      } else if (!ctx->header_parsed) {
+               return enum_fmt(mxc_formats, MXC_JPEG_NUM_FORMATS, f,
+                       MXC_JPEG_FMT_TYPE_RAW);
++      } else {
++              /* For the decoder CAPTURE queue, only enumerate the raw formats
++               * supported for the format currently active on OUTPUT
++               * (more precisely what was propagated on capture queue
++               * after jpeg parse on the output buffer)
++               */
++              if (f->index)
++                      return -EINVAL;
++              f->pixelformat = q_data->fmt->fourcc;
++              strscpy(f->description, q_data->fmt->name, sizeof(f->description));
++              return 0;
++      }
+ }
+ static int mxc_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
+                                    struct v4l2_fmtdesc *f)
+ {
+       struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
++      u32 type = ctx->mxc_jpeg->mode == MXC_JPEG_DECODE ?  MXC_JPEG_FMT_TYPE_ENC :
++                                                           MXC_JPEG_FMT_TYPE_RAW;
++      int ret;
++      ret = enum_fmt(mxc_formats, MXC_JPEG_NUM_FORMATS, f, type);
++      if (ret)
++              return ret;
+       if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE)
+-              return enum_fmt(mxc_formats, MXC_JPEG_NUM_FORMATS, f,
+-                              MXC_JPEG_FMT_TYPE_ENC);
+-      else
+-              return enum_fmt(mxc_formats, MXC_JPEG_NUM_FORMATS, f,
+-                              MXC_JPEG_FMT_TYPE_RAW);
++              f->flags = V4L2_FMT_FLAG_DYN_RESOLUTION;
++      return 0;
+ }
+ static int mxc_jpeg_try_fmt(struct v4l2_format *f, const struct mxc_jpeg_fmt *fmt,
+@@ -1981,6 +2017,7 @@ static const struct v4l2_file_operations mxc_jpeg_fops = {
+ };
+ static const struct v4l2_m2m_ops mxc_jpeg_m2m_ops = {
++      .job_ready      = mxc_jpeg_job_ready,
+       .device_run     = mxc_jpeg_device_run,
+ };
+diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg.h b/drivers/media/platform/imx-jpeg/mxc-jpeg.h
+index 2b4b30d01e51..6913ae087e44 100644
+--- a/drivers/media/platform/imx-jpeg/mxc-jpeg.h
++++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.h
+@@ -95,6 +95,8 @@ struct mxc_jpeg_ctx {
+       unsigned int                    stopping;
+       unsigned int                    stopped;
+       unsigned int                    slot;
++      unsigned int                    source_change;
++      bool                            header_parsed;
+ };
+ struct mxc_jpeg_slot_data {
+-- 
+2.35.1
+
diff --git a/queue-5.15/media-imx-jpeg-use-nv12m-to-represent-non-contiguous.patch b/queue-5.15/media-imx-jpeg-use-nv12m-to-represent-non-contiguous.patch
new file mode 100644 (file)
index 0000000..30a19fc
--- /dev/null
@@ -0,0 +1,87 @@
+From f535a4130e184c8c9b0a7994bef9007a8e0727e6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Dec 2021 04:02:41 +0100
+Subject: media: imx-jpeg: use NV12M to represent non contiguous NV12
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit 784a1883cff07e7510a81ad3041d6ec443d51944 ]
+
+V4L2_PIX_FMT_NV12 requires num_planes equals to 1,
+V4L2_PIX_FMT_NV12M requires num_planes equals to 2.
+and mxc-jpeg supports 2 planes for nv12,
+so we should use 4L2_PIX_FMT_NV12M instead of V4L2_PIX_FMT_NV12,
+otherwise it will confuses gstreamer and prevent encoding and decoding.
+
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Signed-off-by: Shijie Qin <shijie.qin@nxp.com>
+Signed-off-by: Zhou Peng <eagle.zhou@nxp.com>
+Reviewed-by: Mirela Rabulea <mirela.rabulea@oss.nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/imx-jpeg/mxc-jpeg.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
+index bc66c09b807a..1ec60f54d5a1 100644
+--- a/drivers/media/platform/imx-jpeg/mxc-jpeg.c
++++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
+@@ -96,7 +96,7 @@ static const struct mxc_jpeg_fmt mxc_formats[] = {
+       },
+       {
+               .name           = "YUV420", /* 1st plane = Y, 2nd plane = UV */
+-              .fourcc         = V4L2_PIX_FMT_NV12,
++              .fourcc         = V4L2_PIX_FMT_NV12M,
+               .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
+               .nc             = 3,
+               .depth          = 12, /* 6 bytes (4Y + UV) for 4 pixels */
+@@ -390,7 +390,7 @@ static enum mxc_jpeg_image_format mxc_jpeg_fourcc_to_imgfmt(u32 fourcc)
+               return MXC_JPEG_GRAY;
+       case V4L2_PIX_FMT_YUYV:
+               return MXC_JPEG_YUV422;
+-      case V4L2_PIX_FMT_NV12:
++      case V4L2_PIX_FMT_NV12M:
+               return MXC_JPEG_YUV420;
+       case V4L2_PIX_FMT_YUV24:
+               return MXC_JPEG_YUV444;
+@@ -660,7 +660,7 @@ static int mxc_jpeg_fixup_sof(struct mxc_jpeg_sof *sof,
+       _bswap16(&sof->width);
+       switch (fourcc) {
+-      case V4L2_PIX_FMT_NV12:
++      case V4L2_PIX_FMT_NV12M:
+               sof->components_no = 3;
+               sof->comp[0].v = 0x2;
+               sof->comp[0].h = 0x2;
+@@ -696,7 +696,7 @@ static int mxc_jpeg_fixup_sos(struct mxc_jpeg_sos *sos,
+       u8 *sof_u8 = (u8 *)sos;
+       switch (fourcc) {
+-      case V4L2_PIX_FMT_NV12:
++      case V4L2_PIX_FMT_NV12M:
+               sos->components_no = 3;
+               break;
+       case V4L2_PIX_FMT_YUYV:
+@@ -1179,7 +1179,7 @@ static void mxc_jpeg_bytesperline(struct mxc_jpeg_q_data *q,
+               /* bytesperline unused for compressed formats */
+               q->bytesperline[0] = 0;
+               q->bytesperline[1] = 0;
+-      } else if (q->fmt->fourcc == V4L2_PIX_FMT_NV12) {
++      } else if (q->fmt->fourcc == V4L2_PIX_FMT_NV12M) {
+               /* When the image format is planar the bytesperline value
+                * applies to the first plane and is divided by the same factor
+                * as the width field for the other planes
+@@ -1211,7 +1211,7 @@ static void mxc_jpeg_sizeimage(struct mxc_jpeg_q_data *q)
+       } else {
+               q->sizeimage[0] = q->bytesperline[0] * q->h;
+               q->sizeimage[1] = 0;
+-              if (q->fmt->fourcc == V4L2_PIX_FMT_NV12)
++              if (q->fmt->fourcc == V4L2_PIX_FMT_NV12M)
+                       q->sizeimage[1] = q->sizeimage[0] / 2;
+       }
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/media-platform-mtk-mdp-fix-mdp_ipi_comm-structure-al.patch b/queue-5.15/media-platform-mtk-mdp-fix-mdp_ipi_comm-structure-al.patch
new file mode 100644 (file)
index 0000000..5ce94a3
--- /dev/null
@@ -0,0 +1,57 @@
+From 722887cd02f46bbe6b90ce750bda5ff0288f58cf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jun 2022 14:55:46 +0100
+Subject: media: platform: mtk-mdp: Fix mdp_ipi_comm structure alignment
+
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+[ Upstream commit ab14c99c035da7156a3b66fa171171295bc4b89a ]
+
+The mdp_ipi_comm structure defines a command that is either
+PROCESS (start processing) or DEINIT (destroy instance); we
+are using this one to send PROCESS or DEINIT commands from Linux
+to an MDP instance through a VPU write but, while the first wants
+us to stay 4-bytes aligned, the VPU instead requires an 8-bytes
+data alignment.
+
+Keeping in mind that these commands are executed immediately
+after sending them (hence not chained with others before the
+VPU/MDP "actually" start executing), it is fine to simply add
+a padding of 4 bytes to this structure: this keeps the same
+performance as before, as we're still stack-allocating it,
+while avoiding hackery inside of mtk-vpu to ensure alignment
+bringing a definitely bigger performance impact.
+
+Fixes: c8eb2d7e8202 ("[media] media: Add Mediatek MDP Driver")
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Houlong Wei <houlong.wei@mediatek.com>
+Reviewed-by: Irui Wang <irui.wang@mediatek.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/mtk-mdp/mtk_mdp_ipi.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_ipi.h b/drivers/media/platform/mtk-mdp/mtk_mdp_ipi.h
+index 2cb8cecb3077..b810c96695c8 100644
+--- a/drivers/media/platform/mtk-mdp/mtk_mdp_ipi.h
++++ b/drivers/media/platform/mtk-mdp/mtk_mdp_ipi.h
+@@ -40,12 +40,14 @@ struct mdp_ipi_init {
+  * @ipi_id        : IPI_MDP
+  * @ap_inst       : AP mtk_mdp_vpu address
+  * @vpu_inst_addr : VPU MDP instance address
++ * @padding       : Alignment padding
+  */
+ struct mdp_ipi_comm {
+       uint32_t msg_id;
+       uint32_t ipi_id;
+       uint64_t ap_inst;
+       uint32_t vpu_inst_addr;
++      uint32_t padding;
+ };
+ /**
+-- 
+2.35.1
+
diff --git a/queue-5.15/media-staging-media-hantro-fix-typos.patch b/queue-5.15/media-staging-media-hantro-fix-typos.patch
new file mode 100644 (file)
index 0000000..04361ed
--- /dev/null
@@ -0,0 +1,50 @@
+From 4b4e9d76be16e991dd98ee6d61bbec38b8b3ec16 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 26 Mar 2022 19:36:03 +0100
+Subject: media: staging: media: hantro: Fix typos
+
+From: Sebastian Fricke <sebastian.fricke@collabora.com>
+
+[ Upstream commit d8f6f1c56d5469e22eeb7cc1f3580b29e2f0fef5 ]
+
+Fix typos in comments within the Hantro driver.
+
+Signed-off-by: Sebastian Fricke <sebastian.fricke@collabora.com>
+Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/media/hantro/hantro_g2_hevc_dec.c | 2 +-
+ drivers/staging/media/hantro/hantro_hevc.c        | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
+index 87086f5c5495..bcdfa359de7f 100644
+--- a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
++++ b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
+@@ -413,7 +413,7 @@ static int set_ref(struct hantro_ctx *ctx)
+       set_ref_pic_list(ctx);
+-      /* We will only keep the references picture that are still used */
++      /* We will only keep the reference pictures that are still used */
+       ctx->hevc_dec.ref_bufs_used = 0;
+       /* Set up addresses of DPB buffers */
+diff --git a/drivers/staging/media/hantro/hantro_hevc.c b/drivers/staging/media/hantro/hantro_hevc.c
+index 5347f5a41c2a..7ce98a2b1655 100644
+--- a/drivers/staging/media/hantro/hantro_hevc.c
++++ b/drivers/staging/media/hantro/hantro_hevc.c
+@@ -98,7 +98,7 @@ dma_addr_t hantro_hevc_get_ref_buf(struct hantro_ctx *ctx,
+       struct hantro_hevc_dec_hw_ctx *hevc_dec = &ctx->hevc_dec;
+       int i;
+-      /* Find the reference buffer in already know ones */
++      /* Find the reference buffer in already known ones */
+       for (i = 0;  i < NUM_REF_PICTURES; i++) {
+               if (hevc_dec->ref_bufs_poc[i] == poc) {
+                       hevc_dec->ref_bufs_used |= 1 << i;
+-- 
+2.35.1
+
diff --git a/queue-5.15/media-tw686x-fix-memory-leak-in-tw686x_video_init.patch b/queue-5.15/media-tw686x-fix-memory-leak-in-tw686x_video_init.patch
new file mode 100644 (file)
index 0000000..6ebe859
--- /dev/null
@@ -0,0 +1,41 @@
+From 50293469993bbf81fdf1dc76b841e4c6dc7b7fea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Jun 2022 06:30:30 +0100
+Subject: media: tw686x: Fix memory leak in tw686x_video_init
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit e0b212ec9d8177d6f7c404315293f6a085d6ee42 ]
+
+video_device_alloc() allocates memory for vdev,
+when video_register_device() fails, it doesn't release the memory and
+leads to memory leak, call video_device_release() to fix this.
+
+Fixes: 704a84ccdbf1 ("[media] media: Support Intersil/Techwell TW686x-based video capture cards")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/pci/tw686x/tw686x-video.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/pci/tw686x/tw686x-video.c b/drivers/media/pci/tw686x/tw686x-video.c
+index b227e9e78ebd..37a20fe24241 100644
+--- a/drivers/media/pci/tw686x/tw686x-video.c
++++ b/drivers/media/pci/tw686x/tw686x-video.c
+@@ -1282,8 +1282,10 @@ int tw686x_video_init(struct tw686x_dev *dev)
+               video_set_drvdata(vdev, vc);
+               err = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
+-              if (err < 0)
++              if (err < 0) {
++                      video_device_release(vdev);
+                       goto error;
++              }
+               vc->num = vdev->num;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/media-tw686x-register-the-irq-at-the-end-of-probe.patch b/queue-5.15/media-tw686x-register-the-irq-at-the-end-of-probe.patch
new file mode 100644 (file)
index 0000000..bc4f218
--- /dev/null
@@ -0,0 +1,82 @@
+From b0b76990e7be5937713b8f9c453b350e14d01c60 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 21 May 2022 07:24:01 +0100
+Subject: media: tw686x: Register the irq at the end of probe
+
+From: Zheyu Ma <zheyuma97@gmail.com>
+
+[ Upstream commit fb730334e0f759d00f72168fbc555e5a95e35210 ]
+
+We got the following warning when booting the kernel:
+
+[    3.243674] INFO: trying to register non-static key.
+[    3.243922] The code is fine but needs lockdep annotation, or maybe
+[    3.244230] you didn't initialize this object before use?
+[    3.245642] Call Trace:
+[    3.247836]  lock_acquire+0xff/0x2d0
+[    3.248727]  tw686x_audio_irq+0x1a5/0xcc0 [tw686x]
+[    3.249211]  tw686x_irq+0x1f9/0x480 [tw686x]
+
+The lock 'vc->qlock' will be initialized in tw686x_video_init(), but the
+driver registers the irq before calling the tw686x_video_init(), and we
+got the warning.
+
+Fix this by registering the irq at the end of probe
+
+Fixes: 704a84ccdbf1 ("[media] media: Support Intersil/Techwell TW686x-based video capture cards")
+Signed-off-by: Zheyu Ma <zheyuma97@gmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/pci/tw686x/tw686x-core.c | 18 ++++++++----------
+ 1 file changed, 8 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/media/pci/tw686x/tw686x-core.c b/drivers/media/pci/tw686x/tw686x-core.c
+index 6676e069b515..384d38754a4b 100644
+--- a/drivers/media/pci/tw686x/tw686x-core.c
++++ b/drivers/media/pci/tw686x/tw686x-core.c
+@@ -315,13 +315,6 @@ static int tw686x_probe(struct pci_dev *pci_dev,
+       spin_lock_init(&dev->lock);
+-      err = request_irq(pci_dev->irq, tw686x_irq, IRQF_SHARED,
+-                        dev->name, dev);
+-      if (err < 0) {
+-              dev_err(&pci_dev->dev, "unable to request interrupt\n");
+-              goto iounmap;
+-      }
+-
+       timer_setup(&dev->dma_delay_timer, tw686x_dma_delay, 0);
+       /*
+@@ -333,18 +326,23 @@ static int tw686x_probe(struct pci_dev *pci_dev,
+       err = tw686x_video_init(dev);
+       if (err) {
+               dev_err(&pci_dev->dev, "can't register video\n");
+-              goto free_irq;
++              goto iounmap;
+       }
+       err = tw686x_audio_init(dev);
+       if (err)
+               dev_warn(&pci_dev->dev, "can't register audio\n");
++      err = request_irq(pci_dev->irq, tw686x_irq, IRQF_SHARED,
++                        dev->name, dev);
++      if (err < 0) {
++              dev_err(&pci_dev->dev, "unable to request interrupt\n");
++              goto iounmap;
++      }
++
+       pci_set_drvdata(pci_dev, dev);
+       return 0;
+-free_irq:
+-      free_irq(pci_dev->irq, dev);
+ iounmap:
+       pci_iounmap(pci_dev, dev->mmio);
+ free_region:
+-- 
+2.35.1
+
diff --git a/queue-5.15/media-v4l2-mem2mem-prevent-pollerr-when-last_buffer_.patch b/queue-5.15/media-v4l2-mem2mem-prevent-pollerr-when-last_buffer_.patch
new file mode 100644 (file)
index 0000000..6a7c5c8
--- /dev/null
@@ -0,0 +1,44 @@
+From 86870f689b45260c80a617f1248833bd77954e7f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jun 2022 04:19:20 +0100
+Subject: media: v4l2-mem2mem: prevent pollerr when last_buffer_dequeued is set
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit d4de27a9b1eadd33a2e40de87a646d1bf5fef756 ]
+
+If the last buffer was dequeued from the capture queue,
+signal userspace. DQBUF(CAPTURE) will return -EPIPE.
+
+But if output queue is empty and capture queue is empty,
+v4l2_m2m_poll_for_data will return EPOLLERR,
+This is very easy to happen in drain.
+
+When last_buffer_dequeued is set, we shouldn't return EPOLLERR,
+but return EPOLLIN | EPOLLRDNORM.
+
+Fixes: 1698a7f151126 ("media: v4l2-mem2mem: simplify poll logic")
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/v4l2-core/v4l2-mem2mem.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
+index 3de683b5e06d..8aeed39c415f 100644
+--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
++++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
+@@ -924,7 +924,7 @@ static __poll_t v4l2_m2m_poll_for_data(struct file *file,
+       if ((!src_q->streaming || src_q->error ||
+            list_empty(&src_q->queued_list)) &&
+           (!dst_q->streaming || dst_q->error ||
+-           list_empty(&dst_q->queued_list)))
++           (list_empty(&dst_q->queued_list) && !dst_q->last_buffer_dequeued)))
+               return EPOLLERR;
+       spin_lock_irqsave(&src_q->done_lock, flags);
+-- 
+2.35.1
+
diff --git a/queue-5.15/mediatek-mt76-eeprom-fix-missing-of_node_put-in-mt76.patch b/queue-5.15/mediatek-mt76-eeprom-fix-missing-of_node_put-in-mt76.patch
new file mode 100644 (file)
index 0000000..d93397a
--- /dev/null
@@ -0,0 +1,43 @@
+From 7c5a769c8aca5517b1022cbe9576c9d688a1a90a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Jul 2022 16:34:21 +0800
+Subject: mediatek: mt76: eeprom: fix missing of_node_put() in
+ mt76_find_power_limits_node()
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 3bd53ea02d77917c2314ec7be9e2d05be22f87d3 ]
+
+We should use of_node_put() for the reference 'np' returned by
+of_get_child_by_name() which will increase the refcount.
+
+Fixes: 22b980badc0f ("mt76: add functions for parsing rate power limits from DT")
+Signed-off-by: Liang He <windhl@126.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/eeprom.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c
+index 3b47e85e95e7..db0cd56c8dc7 100644
+--- a/drivers/net/wireless/mediatek/mt76/eeprom.c
++++ b/drivers/net/wireless/mediatek/mt76/eeprom.c
+@@ -146,10 +146,13 @@ mt76_find_power_limits_node(struct mt76_dev *dev)
+               }
+               if (mt76_string_prop_find(country, dev->alpha2) ||
+-                  mt76_string_prop_find(regd, region_name))
++                  mt76_string_prop_find(regd, region_name)) {
++                      of_node_put(np);
+                       return cur;
++              }
+       }
++      of_node_put(np);
+       return fallback;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/mediatek-mt76-mac80211-fix-missing-of_node_put-in-mt.patch b/queue-5.15/mediatek-mt76-mac80211-fix-missing-of_node_put-in-mt.patch
new file mode 100644 (file)
index 0000000..c00ba22
--- /dev/null
@@ -0,0 +1,36 @@
+From 00df5597f4fa986616f730f3f1e805f96701b4d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Jul 2022 16:34:20 +0800
+Subject: mediatek: mt76: mac80211: Fix missing of_node_put() in
+ mt76_led_init()
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 0a14c1d0113f121151edf34333cdf212dd209190 ]
+
+We should use of_node_put() for the reference 'np' returned by
+of_get_child_by_name() which will increase the refcount.
+
+Fixes: 17f1de56df05 ("mt76: add common code shared between multiple chipsets")
+Signed-off-by: Liang He <windhl@126.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mac80211.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c
+index 029599d68ca7..028519a739fd 100644
+--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
++++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
+@@ -123,6 +123,7 @@ static int mt76_led_init(struct mt76_dev *dev)
+               if (!of_property_read_u32(np, "led-sources", &led_pin))
+                       dev->led_pin = led_pin;
+               dev->led_al = of_property_read_bool(np, "led-active-low");
++              of_node_put(np);
+       }
+       return led_classdev_register(dev->dev, &dev->led_cdev);
+-- 
+2.35.1
+
diff --git a/queue-5.15/memremap-remove-support-for-external-pgmap-refcounts.patch b/queue-5.15/memremap-remove-support-for-external-pgmap-refcounts.patch
new file mode 100644 (file)
index 0000000..aae4e17
--- /dev/null
@@ -0,0 +1,263 @@
+From 2c771afdafddfd79d3758b5fe7b93a15b8f43294 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Oct 2021 17:10:17 +0200
+Subject: memremap: remove support for external pgmap refcounts
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit b80892ca022e9eb484771a66eb68e12364695a2a ]
+
+No driver is left using the external pgmap refcount, so remove the
+code to support it.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Acked-by: Bjorn Helgaas <bhelgaas@google.com>
+Link: https://lore.kernel.org/r/20211028151017.50234-1-hch@lst.de
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/p2pdma.c              |  2 +-
+ include/linux/memremap.h          | 18 ++--------
+ mm/memremap.c                     | 59 +++++++------------------------
+ tools/testing/nvdimm/test/iomap.c | 43 +++++++---------------
+ 4 files changed, 28 insertions(+), 94 deletions(-)
+
+diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
+index 50cdde3e9a8b..316fd2f44df4 100644
+--- a/drivers/pci/p2pdma.c
++++ b/drivers/pci/p2pdma.c
+@@ -219,7 +219,7 @@ int pci_p2pdma_add_resource(struct pci_dev *pdev, int bar, size_t size,
+       error = gen_pool_add_owner(p2pdma->pool, (unsigned long)addr,
+                       pci_bus_address(pdev, bar) + offset,
+                       range_len(&pgmap->range), dev_to_node(&pdev->dev),
+-                      pgmap->ref);
++                      &pgmap->ref);
+       if (error)
+               goto pages_free;
+diff --git a/include/linux/memremap.h b/include/linux/memremap.h
+index c0e9d35889e8..a8bc588fe7aa 100644
+--- a/include/linux/memremap.h
++++ b/include/linux/memremap.h
+@@ -72,16 +72,6 @@ struct dev_pagemap_ops {
+        */
+       void (*page_free)(struct page *page);
+-      /*
+-       * Transition the refcount in struct dev_pagemap to the dead state.
+-       */
+-      void (*kill)(struct dev_pagemap *pgmap);
+-
+-      /*
+-       * Wait for refcount in struct dev_pagemap to be idle and reap it.
+-       */
+-      void (*cleanup)(struct dev_pagemap *pgmap);
+-
+       /*
+        * Used for private (un-addressable) device memory only.  Must migrate
+        * the page back to a CPU accessible page.
+@@ -95,8 +85,7 @@ struct dev_pagemap_ops {
+  * struct dev_pagemap - metadata for ZONE_DEVICE mappings
+  * @altmap: pre-allocated/reserved memory for vmemmap allocations
+  * @ref: reference count that pins the devm_memremap_pages() mapping
+- * @internal_ref: internal reference if @ref is not provided by the caller
+- * @done: completion for @internal_ref
++ * @done: completion for @ref
+  * @type: memory type: see MEMORY_* in memory_hotplug.h
+  * @flags: PGMAP_* flags to specify defailed behavior
+  * @ops: method table
+@@ -109,8 +98,7 @@ struct dev_pagemap_ops {
+  */
+ struct dev_pagemap {
+       struct vmem_altmap altmap;
+-      struct percpu_ref *ref;
+-      struct percpu_ref internal_ref;
++      struct percpu_ref ref;
+       struct completion done;
+       enum memory_type type;
+       unsigned int flags;
+@@ -191,7 +179,7 @@ static inline unsigned long memremap_compat_align(void)
+ static inline void put_dev_pagemap(struct dev_pagemap *pgmap)
+ {
+       if (pgmap)
+-              percpu_ref_put(pgmap->ref);
++              percpu_ref_put(&pgmap->ref);
+ }
+ #endif /* _LINUX_MEMREMAP_H_ */
+diff --git a/mm/memremap.c b/mm/memremap.c
+index e77487375c8e..a638a27d89f5 100644
+--- a/mm/memremap.c
++++ b/mm/memremap.c
+@@ -112,30 +112,6 @@ static unsigned long pfn_next(unsigned long pfn)
+ #define for_each_device_pfn(pfn, map, i) \
+       for (pfn = pfn_first(map, i); pfn < pfn_end(map, i); pfn = pfn_next(pfn))
+-static void dev_pagemap_kill(struct dev_pagemap *pgmap)
+-{
+-      if (pgmap->ops && pgmap->ops->kill)
+-              pgmap->ops->kill(pgmap);
+-      else
+-              percpu_ref_kill(pgmap->ref);
+-}
+-
+-static void dev_pagemap_cleanup(struct dev_pagemap *pgmap)
+-{
+-      if (pgmap->ops && pgmap->ops->cleanup) {
+-              pgmap->ops->cleanup(pgmap);
+-      } else {
+-              wait_for_completion(&pgmap->done);
+-              percpu_ref_exit(pgmap->ref);
+-      }
+-      /*
+-       * Undo the pgmap ref assignment for the internal case as the
+-       * caller may re-enable the same pgmap.
+-       */
+-      if (pgmap->ref == &pgmap->internal_ref)
+-              pgmap->ref = NULL;
+-}
+-
+ static void pageunmap_range(struct dev_pagemap *pgmap, int range_id)
+ {
+       struct range *range = &pgmap->ranges[range_id];
+@@ -167,11 +143,12 @@ void memunmap_pages(struct dev_pagemap *pgmap)
+       unsigned long pfn;
+       int i;
+-      dev_pagemap_kill(pgmap);
++      percpu_ref_kill(&pgmap->ref);
+       for (i = 0; i < pgmap->nr_range; i++)
+               for_each_device_pfn(pfn, pgmap, i)
+                       put_page(pfn_to_page(pfn));
+-      dev_pagemap_cleanup(pgmap);
++      wait_for_completion(&pgmap->done);
++      percpu_ref_exit(&pgmap->ref);
+       for (i = 0; i < pgmap->nr_range; i++)
+               pageunmap_range(pgmap, i);
+@@ -188,8 +165,7 @@ static void devm_memremap_pages_release(void *data)
+ static void dev_pagemap_percpu_release(struct percpu_ref *ref)
+ {
+-      struct dev_pagemap *pgmap =
+-              container_of(ref, struct dev_pagemap, internal_ref);
++      struct dev_pagemap *pgmap = container_of(ref, struct dev_pagemap, ref);
+       complete(&pgmap->done);
+ }
+@@ -295,8 +271,8 @@ static int pagemap_range(struct dev_pagemap *pgmap, struct mhp_params *params,
+       memmap_init_zone_device(&NODE_DATA(nid)->node_zones[ZONE_DEVICE],
+                               PHYS_PFN(range->start),
+                               PHYS_PFN(range_len(range)), pgmap);
+-      percpu_ref_get_many(pgmap->ref, pfn_end(pgmap, range_id)
+-                      - pfn_first(pgmap, range_id));
++      percpu_ref_get_many(&pgmap->ref,
++              pfn_end(pgmap, range_id) - pfn_first(pgmap, range_id));
+       return 0;
+ err_add_memory:
+@@ -362,22 +338,11 @@ void *memremap_pages(struct dev_pagemap *pgmap, int nid)
+               break;
+       }
+-      if (!pgmap->ref) {
+-              if (pgmap->ops && (pgmap->ops->kill || pgmap->ops->cleanup))
+-                      return ERR_PTR(-EINVAL);
+-
+-              init_completion(&pgmap->done);
+-              error = percpu_ref_init(&pgmap->internal_ref,
+-                              dev_pagemap_percpu_release, 0, GFP_KERNEL);
+-              if (error)
+-                      return ERR_PTR(error);
+-              pgmap->ref = &pgmap->internal_ref;
+-      } else {
+-              if (!pgmap->ops || !pgmap->ops->kill || !pgmap->ops->cleanup) {
+-                      WARN(1, "Missing reference count teardown definition\n");
+-                      return ERR_PTR(-EINVAL);
+-              }
+-      }
++      init_completion(&pgmap->done);
++      error = percpu_ref_init(&pgmap->ref, dev_pagemap_percpu_release, 0,
++                              GFP_KERNEL);
++      if (error)
++              return ERR_PTR(error);
+       devmap_managed_enable_get(pgmap);
+@@ -486,7 +451,7 @@ struct dev_pagemap *get_dev_pagemap(unsigned long pfn,
+       /* fall back to slow path lookup */
+       rcu_read_lock();
+       pgmap = xa_load(&pgmap_array, PHYS_PFN(phys));
+-      if (pgmap && !percpu_ref_tryget_live(pgmap->ref))
++      if (pgmap && !percpu_ref_tryget_live(&pgmap->ref))
+               pgmap = NULL;
+       rcu_read_unlock();
+diff --git a/tools/testing/nvdimm/test/iomap.c b/tools/testing/nvdimm/test/iomap.c
+index ed563bdd88f3..b752ce47ead3 100644
+--- a/tools/testing/nvdimm/test/iomap.c
++++ b/tools/testing/nvdimm/test/iomap.c
+@@ -100,25 +100,17 @@ static void nfit_test_kill(void *_pgmap)
+ {
+       struct dev_pagemap *pgmap = _pgmap;
+-      WARN_ON(!pgmap || !pgmap->ref);
+-
+-      if (pgmap->ops && pgmap->ops->kill)
+-              pgmap->ops->kill(pgmap);
+-      else
+-              percpu_ref_kill(pgmap->ref);
+-
+-      if (pgmap->ops && pgmap->ops->cleanup) {
+-              pgmap->ops->cleanup(pgmap);
+-      } else {
+-              wait_for_completion(&pgmap->done);
+-              percpu_ref_exit(pgmap->ref);
+-      }
++      WARN_ON(!pgmap);
++
++      percpu_ref_kill(&pgmap->ref);
++
++      wait_for_completion(&pgmap->done);
++      percpu_ref_exit(&pgmap->ref);
+ }
+ static void dev_pagemap_percpu_release(struct percpu_ref *ref)
+ {
+-      struct dev_pagemap *pgmap =
+-              container_of(ref, struct dev_pagemap, internal_ref);
++      struct dev_pagemap *pgmap = container_of(ref, struct dev_pagemap, ref);
+       complete(&pgmap->done);
+ }
+@@ -132,22 +124,11 @@ void *__wrap_devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap)
+       if (!nfit_res)
+               return devm_memremap_pages(dev, pgmap);
+-      if (!pgmap->ref) {
+-              if (pgmap->ops && (pgmap->ops->kill || pgmap->ops->cleanup))
+-                      return ERR_PTR(-EINVAL);
+-
+-              init_completion(&pgmap->done);
+-              error = percpu_ref_init(&pgmap->internal_ref,
+-                              dev_pagemap_percpu_release, 0, GFP_KERNEL);
+-              if (error)
+-                      return ERR_PTR(error);
+-              pgmap->ref = &pgmap->internal_ref;
+-      } else {
+-              if (!pgmap->ops || !pgmap->ops->kill || !pgmap->ops->cleanup) {
+-                      WARN(1, "Missing reference count teardown definition\n");
+-                      return ERR_PTR(-EINVAL);
+-              }
+-      }
++      init_completion(&pgmap->done);
++      error = percpu_ref_init(&pgmap->ref, dev_pagemap_percpu_release, 0,
++                              GFP_KERNEL);
++      if (error)
++              return ERR_PTR(error);
+       error = devm_add_action_or_reset(dev, nfit_test_kill, pgmap);
+       if (error)
+-- 
+2.35.1
+
diff --git a/queue-5.15/memstick-ms_block-fix-a-memory-leak.patch b/queue-5.15/memstick-ms_block-fix-a-memory-leak.patch
new file mode 100644 (file)
index 0000000..babda3c
--- /dev/null
@@ -0,0 +1,39 @@
+From 79e268c2b8a4798c57f9c2efae15f07ea38161f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 25 Jun 2022 14:55:56 +0200
+Subject: memstick/ms_block: Fix a memory leak
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 54eb7a55be6779c4d0c25eaf5056498a28595049 ]
+
+'erased_blocks_bitmap' is never freed. As it is allocated at the same time
+as 'used_blocks_bitmap', it is likely that it should be freed also at the
+same time.
+
+Add the corresponding bitmap_free() in msb_data_clear().
+
+Fixes: 0ab30494bc4f ("memstick: add support for legacy memorysticks")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://lore.kernel.org/r/b3b78926569445962ea5c3b6e9102418a9effb88.1656155715.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/memstick/core/ms_block.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/memstick/core/ms_block.c b/drivers/memstick/core/ms_block.c
+index 7275217e485e..f854822f84d6 100644
+--- a/drivers/memstick/core/ms_block.c
++++ b/drivers/memstick/core/ms_block.c
+@@ -1963,6 +1963,7 @@ static void msb_data_clear(struct msb_data *msb)
+ {
+       kfree(msb->boot_page);
+       bitmap_free(msb->used_blocks_bitmap);
++      bitmap_free(msb->erased_blocks_bitmap);
+       kfree(msb->lba_to_pba_table);
+       kfree(msb->cache);
+       msb->card = NULL;
+-- 
+2.35.1
+
diff --git a/queue-5.15/memstick-ms_block-fix-some-incorrect-memory-allocati.patch b/queue-5.15/memstick-ms_block-fix-some-incorrect-memory-allocati.patch
new file mode 100644 (file)
index 0000000..beb190b
--- /dev/null
@@ -0,0 +1,65 @@
+From 48c70dbf92d0b24656afcbd387a7697eb29f92ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 25 Jun 2022 14:55:25 +0200
+Subject: memstick/ms_block: Fix some incorrect memory allocation
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 2e531bc3e0d86362fcd8a577b3278d9ef3cc2ba0 ]
+
+Some functions of the bitmap API take advantage of the fact that a bitmap
+is an array of long.
+
+So, to make sure this assertion is correct, allocate bitmaps with
+bitmap_zalloc() instead of kzalloc()+hand-computed number of bytes.
+
+While at it, also use bitmap_free() instead of kfree() to keep the
+semantic.
+
+Fixes: 0ab30494bc4f ("memstick: add support for legacy memorysticks")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://lore.kernel.org/r/dbf633c48c24ae6d95f852557e8d8b3bbdef65fe.1656155715.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/memstick/core/ms_block.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/memstick/core/ms_block.c b/drivers/memstick/core/ms_block.c
+index 487e4cc2951e..7275217e485e 100644
+--- a/drivers/memstick/core/ms_block.c
++++ b/drivers/memstick/core/ms_block.c
+@@ -1341,17 +1341,17 @@ static int msb_ftl_initialize(struct msb_data *msb)
+       msb->zone_count = msb->block_count / MS_BLOCKS_IN_ZONE;
+       msb->logical_block_count = msb->zone_count * 496 - 2;
+-      msb->used_blocks_bitmap = kzalloc(msb->block_count / 8, GFP_KERNEL);
+-      msb->erased_blocks_bitmap = kzalloc(msb->block_count / 8, GFP_KERNEL);
++      msb->used_blocks_bitmap = bitmap_zalloc(msb->block_count, GFP_KERNEL);
++      msb->erased_blocks_bitmap = bitmap_zalloc(msb->block_count, GFP_KERNEL);
+       msb->lba_to_pba_table =
+               kmalloc_array(msb->logical_block_count, sizeof(u16),
+                             GFP_KERNEL);
+       if (!msb->used_blocks_bitmap || !msb->lba_to_pba_table ||
+                                               !msb->erased_blocks_bitmap) {
+-              kfree(msb->used_blocks_bitmap);
++              bitmap_free(msb->used_blocks_bitmap);
++              bitmap_free(msb->erased_blocks_bitmap);
+               kfree(msb->lba_to_pba_table);
+-              kfree(msb->erased_blocks_bitmap);
+               return -ENOMEM;
+       }
+@@ -1962,7 +1962,7 @@ static int msb_bd_open(struct block_device *bdev, fmode_t mode)
+ static void msb_data_clear(struct msb_data *msb)
+ {
+       kfree(msb->boot_page);
+-      kfree(msb->used_blocks_bitmap);
++      bitmap_free(msb->used_blocks_bitmap);
+       kfree(msb->lba_to_pba_table);
+       kfree(msb->cache);
+       msb->card = NULL;
+-- 
+2.35.1
+
diff --git a/queue-5.15/meson-mx-socinfo-fix-refcount-leak-in-meson_mx_socin.patch b/queue-5.15/meson-mx-socinfo-fix-refcount-leak-in-meson_mx_socin.patch
new file mode 100644 (file)
index 0000000..edfaecd
--- /dev/null
@@ -0,0 +1,38 @@
+From 3e702374107134e6bed8912f66fecfde47600cda Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 May 2022 10:57:29 +0400
+Subject: meson-mx-socinfo: Fix refcount leak in meson_mx_socinfo_init
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit a2106f38077e78afcb4bf98fdda3e162118cfb3d ]
+
+of_find_matching_node() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when not need anymore.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: 5e68c0fc8df8 ("soc: amlogic: Add Meson6/Meson8/Meson8b/Meson8m2 SoC Information driver")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
+Link: https://lore.kernel.org/r/20220524065729.33689-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/amlogic/meson-mx-socinfo.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/soc/amlogic/meson-mx-socinfo.c b/drivers/soc/amlogic/meson-mx-socinfo.c
+index 78f0f1aeca57..92125dd65f33 100644
+--- a/drivers/soc/amlogic/meson-mx-socinfo.c
++++ b/drivers/soc/amlogic/meson-mx-socinfo.c
+@@ -126,6 +126,7 @@ static int __init meson_mx_socinfo_init(void)
+       np = of_find_matching_node(NULL, meson_mx_socinfo_analog_top_ids);
+       if (np) {
+               analog_top_regmap = syscon_node_to_regmap(np);
++              of_node_put(np);
+               if (IS_ERR(analog_top_regmap))
+                       return PTR_ERR(analog_top_regmap);
+-- 
+2.35.1
+
diff --git a/queue-5.15/mfd-max77620-fix-refcount-leak-in-max77620_initialis.patch b/queue-5.15/mfd-max77620-fix-refcount-leak-in-max77620_initialis.patch
new file mode 100644 (file)
index 0000000..3e277ba
--- /dev/null
@@ -0,0 +1,42 @@
+From 69bd8542658d7df062c3d675f4788a02c3eab7f4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Jun 2022 08:32:22 +0400
+Subject: mfd: max77620: Fix refcount leak in max77620_initialise_fps
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 1520669c8255bd637c6b248b2be910e2688d38dd ]
+
+of_get_child_by_name() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when not need anymore.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: 327156c59360 ("mfd: max77620: Add core driver for MAX77620/MAX20024")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+Link: https://lore.kernel.org/r/20220601043222.64441-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/max77620.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/mfd/max77620.c b/drivers/mfd/max77620.c
+index fec2096474ad..a6661e07035b 100644
+--- a/drivers/mfd/max77620.c
++++ b/drivers/mfd/max77620.c
+@@ -419,9 +419,11 @@ static int max77620_initialise_fps(struct max77620_chip *chip)
+               ret = max77620_config_fps(chip, fps_child);
+               if (ret < 0) {
+                       of_node_put(fps_child);
++                      of_node_put(fps_np);
+                       return ret;
+               }
+       }
++      of_node_put(fps_np);
+       config = chip->enable_global_lpm ? MAX77620_ONOFFCNFG2_SLP_LPM_MSK : 0;
+       ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG2,
+-- 
+2.35.1
+
diff --git a/queue-5.15/mfd-t7l66xb-drop-platform-disable-callback.patch b/queue-5.15/mfd-t7l66xb-drop-platform-disable-callback.patch
new file mode 100644 (file)
index 0000000..93276b5
--- /dev/null
@@ -0,0 +1,70 @@
+From 04d501ed662d810d5231df2cd6a9ba8c0f7687c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 May 2022 21:24:28 +0200
+Subject: mfd: t7l66xb: Drop platform disable callback
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 128ac294e1b437cb8a7f2ff8ede1cde9082bddbe ]
+
+None of the in-tree instantiations of struct t7l66xb_platform_data
+provides a disable callback. So better don't dereference this function
+pointer unconditionally. As there is no user, drop it completely instead
+of calling it conditional.
+
+This is a preparation for making platform remove callbacks return void.
+
+Fixes: 1f192015ca5b ("mfd: driver for the T7L66XB TMIO SoC")
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+Link: https://lore.kernel.org/r/20220530192430.2108217-3-u.kleine-koenig@pengutronix.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/t7l66xb.c       | 6 +-----
+ include/linux/mfd/t7l66xb.h | 1 -
+ 2 files changed, 1 insertion(+), 6 deletions(-)
+
+diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c
+index 5369c67e3280..663ffd4b8570 100644
+--- a/drivers/mfd/t7l66xb.c
++++ b/drivers/mfd/t7l66xb.c
+@@ -397,11 +397,8 @@ static int t7l66xb_probe(struct platform_device *dev)
+ static int t7l66xb_remove(struct platform_device *dev)
+ {
+-      struct t7l66xb_platform_data *pdata = dev_get_platdata(&dev->dev);
+       struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
+-      int ret;
+-      ret = pdata->disable(dev);
+       clk_disable_unprepare(t7l66xb->clk48m);
+       clk_put(t7l66xb->clk48m);
+       clk_disable_unprepare(t7l66xb->clk32k);
+@@ -412,8 +409,7 @@ static int t7l66xb_remove(struct platform_device *dev)
+       mfd_remove_devices(&dev->dev);
+       kfree(t7l66xb);
+-      return ret;
+-
++      return 0;
+ }
+ static struct platform_driver t7l66xb_platform_driver = {
+diff --git a/include/linux/mfd/t7l66xb.h b/include/linux/mfd/t7l66xb.h
+index 69632c1b07bd..ae3e7a5c5219 100644
+--- a/include/linux/mfd/t7l66xb.h
++++ b/include/linux/mfd/t7l66xb.h
+@@ -12,7 +12,6 @@
+ struct t7l66xb_platform_data {
+       int (*enable)(struct platform_device *dev);
+-      int (*disable)(struct platform_device *dev);
+       int (*suspend)(struct platform_device *dev);
+       int (*resume)(struct platform_device *dev);
+-- 
+2.35.1
+
diff --git a/queue-5.15/mips-fixed-__debug_virt_addr_valid.patch b/queue-5.15/mips-fixed-__debug_virt_addr_valid.patch
new file mode 100644 (file)
index 0000000..01df9da
--- /dev/null
@@ -0,0 +1,72 @@
+From 04b5d690b7b2264998c591e51a748e1adc4df869 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 15:25:12 -0700
+Subject: MIPS: Fixed __debug_virt_addr_valid()
+
+From: Florian Fainelli <f.fainelli@gmail.com>
+
+[ Upstream commit 8a2b456665d1e797123669581524cbb095fb003b ]
+
+It is permissible for kernel code to call virt_to_phys() against virtual
+addresses that are in KSEG0 or KSEG1 and we need to be dealing with both
+types. Rewrite the test condition to ensure that the kernel virtual
+addresses are above PAGE_OFFSET which they must be, and below KSEG2
+where the non-linear mapping starts.
+
+For EVA, there is not much that we can do given the linear address range
+that is offered, so just return any virtual address as being valid.
+
+Finally, when HIGHMEM is not enabled, all virtual addresses are assumed
+to be valid as well.
+
+Fixes: dfad83cb7193 ("MIPS: Add support for CONFIG_DEBUG_VIRTUAL")
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Reviewed-by: Serge Semin <fancer.lancer@gmail.com>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/mm/physaddr.c | 14 ++++----------
+ 1 file changed, 4 insertions(+), 10 deletions(-)
+
+diff --git a/arch/mips/mm/physaddr.c b/arch/mips/mm/physaddr.c
+index a1ced5e44951..f9b8c85e9843 100644
+--- a/arch/mips/mm/physaddr.c
++++ b/arch/mips/mm/physaddr.c
+@@ -5,6 +5,7 @@
+ #include <linux/mmdebug.h>
+ #include <linux/mm.h>
++#include <asm/addrspace.h>
+ #include <asm/sections.h>
+ #include <asm/io.h>
+ #include <asm/page.h>
+@@ -12,15 +13,6 @@
+ static inline bool __debug_virt_addr_valid(unsigned long x)
+ {
+-      /* high_memory does not get immediately defined, and there
+-       * are early callers of __pa() against PAGE_OFFSET
+-       */
+-      if (!high_memory && x >= PAGE_OFFSET)
+-              return true;
+-
+-      if (high_memory && x >= PAGE_OFFSET && x < (unsigned long)high_memory)
+-              return true;
+-
+       /*
+        * MAX_DMA_ADDRESS is a virtual address that may not correspond to an
+        * actual physical address. Enough code relies on
+@@ -30,7 +22,9 @@ static inline bool __debug_virt_addr_valid(unsigned long x)
+       if (x == MAX_DMA_ADDRESS)
+               return true;
+-      return false;
++      return x >= PAGE_OFFSET && (KSEGX(x) < KSEG2 ||
++             IS_ENABLED(CONFIG_EVA) ||
++             !IS_ENABLED(CONFIG_HIGHMEM));
+ }
+ phys_addr_t __virt_to_phys(volatile const void *x)
+-- 
+2.35.1
+
diff --git a/queue-5.15/mips-vdso-utilize-__pa-for-gic_pfn.patch b/queue-5.15/mips-vdso-utilize-__pa-for-gic_pfn.patch
new file mode 100644 (file)
index 0000000..bb1632c
--- /dev/null
@@ -0,0 +1,43 @@
+From 9323fc5248cb167cd851598ae8d67b070575f04a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Jul 2022 13:27:58 -0700
+Subject: MIPS: vdso: Utilize __pa() for gic_pfn
+
+From: Florian Fainelli <f.fainelli@gmail.com>
+
+[ Upstream commit 8baa65126e19af5ee9f3c07e7bb53da41c39e4b1 ]
+
+The GIC user offset is mapped into every process' virtual address and is
+therefore part of the hot-path of arch_setup_additional_pages(). Utilize
+__pa() such that we are more optimal even when CONFIG_DEBUG_VIRTUAL is
+enabled, and while at it utilize PFN_DOWN() instead of open-coding the
+right shift by PAGE_SHIFT.
+
+Reported-by: Greg Ungerer <gerg@kernel.org>
+Suggested-by: Serge Semin <fancer.lancer@gmail.com>
+Fixes: dfad83cb7193 ("MIPS: Add support for CONFIG_DEBUG_VIRTUAL")
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Acked-by: Greg Ungerer <gerg@kernel.org>
+Tested-by: Greg Ungerer <gerg@kernel.org>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/kernel/vdso.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c
+index 3d0cf471f2fe..b2cc2c2dd4bf 100644
+--- a/arch/mips/kernel/vdso.c
++++ b/arch/mips/kernel/vdso.c
+@@ -159,7 +159,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+       /* Map GIC user page. */
+       if (gic_size) {
+               gic_base = (unsigned long)mips_gic_base + MIPS_GIC_USER_OFS;
+-              gic_pfn = virt_to_phys((void *)gic_base) >> PAGE_SHIFT;
++              gic_pfn = PFN_DOWN(__pa(gic_base));
+               ret = io_remap_pfn_range(vma, base, gic_pfn, gic_size,
+                                        pgprot_noncached(vma->vm_page_prot));
+-- 
+2.35.1
+
diff --git a/queue-5.15/misc-rtsx-fix-an-error-handling-path-in-rtsx_pci_pro.patch b/queue-5.15/misc-rtsx-fix-an-error-handling-path-in-rtsx_pci_pro.patch
new file mode 100644 (file)
index 0000000..6b8984d
--- /dev/null
@@ -0,0 +1,51 @@
+From 37ebf289910aedd1c26ee6efb91e899010c596d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jun 2022 07:33:44 +0200
+Subject: misc: rtsx: Fix an error handling path in rtsx_pci_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 44fd1917314e9d4f53dd95dd65df1c152f503d3a ]
+
+If an error occurs after a successful idr_alloc() call, the corresponding
+resource must be released with idr_remove() as already done in the .remove
+function.
+
+Update the error handling path to add the missing idr_remove() call.
+
+Fixes: ada8a8a13b13 ("mfd: Add realtek pcie card reader driver")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://lore.kernel.org/r/e8dc41716cbf52fb37a12e70d8972848e69df6d6.1655271216.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/cardreader/rtsx_pcr.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/misc/cardreader/rtsx_pcr.c b/drivers/misc/cardreader/rtsx_pcr.c
+index 5121edb0d9ef..62fdbbd55e74 100644
+--- a/drivers/misc/cardreader/rtsx_pcr.c
++++ b/drivers/misc/cardreader/rtsx_pcr.c
+@@ -1581,7 +1581,7 @@ static int rtsx_pci_probe(struct pci_dev *pcidev,
+       pcr->remap_addr = ioremap(base, len);
+       if (!pcr->remap_addr) {
+               ret = -ENOMEM;
+-              goto free_handle;
++              goto free_idr;
+       }
+       pcr->rtsx_resv_buf = dma_alloc_coherent(&(pcidev->dev),
+@@ -1651,6 +1651,10 @@ static int rtsx_pci_probe(struct pci_dev *pcidev,
+                       pcr->rtsx_resv_buf, pcr->rtsx_resv_buf_addr);
+ unmap:
+       iounmap(pcr->remap_addr);
++free_idr:
++      spin_lock(&rtsx_pci_lock);
++      idr_remove(&rtsx_pci_idr, pcr->id);
++      spin_unlock(&rtsx_pci_lock);
+ free_handle:
+       kfree(handle);
+ free_pcr:
+-- 
+2.35.1
+
diff --git a/queue-5.15/mm-mempolicy-fix-get_nodes-out-of-bound-access.patch b/queue-5.15/mm-mempolicy-fix-get_nodes-out-of-bound-access.patch
new file mode 100644 (file)
index 0000000..2bb48fd
--- /dev/null
@@ -0,0 +1,39 @@
+From 9db8c708ea2c01db413b7d894da7e9f94ea8c19f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Jun 2022 17:32:11 +0800
+Subject: mm/mempolicy: fix get_nodes out of bound access
+
+From: Tianyu Li <tianyu.li@arm.com>
+
+[ Upstream commit 000eca5d044d1ee23b4ca311793cf3fc528da6c6 ]
+
+When user specified more nodes than supported, get_nodes will access nmask
+array out of bounds.
+
+Link: https://lkml.kernel.org/r/20220601093211.2970565-1-tianyu.li@arm.com
+Fixes: e130242dc351 ("mm: simplify compat numa syscalls")
+Signed-off-by: Tianyu Li <tianyu.li@arm.com>
+Cc: Arnd Bergmann <arnd@arndb.de>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/mempolicy.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/mm/mempolicy.c b/mm/mempolicy.c
+index 9db0158155e1..4472be6f123d 100644
+--- a/mm/mempolicy.c
++++ b/mm/mempolicy.c
+@@ -1389,7 +1389,7 @@ static int get_nodes(nodemask_t *nodes, const unsigned long __user *nmask,
+               unsigned long bits = min_t(unsigned long, maxnode, BITS_PER_LONG);
+               unsigned long t;
+-              if (get_bitmap(&t, &nmask[maxnode / BITS_PER_LONG], bits))
++              if (get_bitmap(&t, &nmask[(maxnode - 1) / BITS_PER_LONG], bits))
+                       return -EFAULT;
+               if (maxnode - bits >= MAX_NUMNODES) {
+-- 
+2.35.1
+
diff --git a/queue-5.15/mm-memremap-fix-memunmap_pages-race-with-get_dev_pag.patch b/queue-5.15/mm-memremap-fix-memunmap_pages-race-with-get_dev_pag.patch
new file mode 100644 (file)
index 0000000..55a0954
--- /dev/null
@@ -0,0 +1,61 @@
+From c5e1ab50a164fc7614b4bfe2685c61674c847f83 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jun 2022 20:13:05 +0800
+Subject: mm/memremap: fix memunmap_pages() race with get_dev_pagemap()
+
+From: Miaohe Lin <linmiaohe@huawei.com>
+
+[ Upstream commit 1e57ffb6e3fd9583268c6462c4e3853575b21701 ]
+
+Think about the below scene:
+
+ CPU1                  CPU2
+ memunmap_pages
+   percpu_ref_exit
+     __percpu_ref_exit
+       free_percpu(percpu_count);
+         /* percpu_count is freed here! */
+                        get_dev_pagemap
+                          xa_load(&pgmap_array, PHYS_PFN(phys))
+                            /* pgmap still in the pgmap_array */
+                          percpu_ref_tryget_live(&pgmap->ref)
+                            if __ref_is_percpu
+                              /* __PERCPU_REF_ATOMIC_DEAD not set yet */
+                              this_cpu_inc(*percpu_count)
+                                /* access freed percpu_count here! */
+      ref->percpu_count_ptr = __PERCPU_REF_ATOMIC_DEAD;
+        /* too late... */
+   pageunmap_range
+
+To fix the issue, do percpu_ref_exit() after pgmap_array is emptied. So
+we won't do percpu_ref_tryget_live() against a being freed percpu_ref.
+
+Link: https://lkml.kernel.org/r/20220609121305.2508-1-linmiaohe@huawei.com
+Fixes: b7b3c01b1915 ("mm/memremap_pages: support multiple ranges per invocation")
+Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>
+Cc: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/memremap.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/mm/memremap.c b/mm/memremap.c
+index a638a27d89f5..8d743cbc2964 100644
+--- a/mm/memremap.c
++++ b/mm/memremap.c
+@@ -148,10 +148,10 @@ void memunmap_pages(struct dev_pagemap *pgmap)
+               for_each_device_pfn(pfn, pgmap, i)
+                       put_page(pfn_to_page(pfn));
+       wait_for_completion(&pgmap->done);
+-      percpu_ref_exit(&pgmap->ref);
+       for (i = 0; i < pgmap->nr_range; i++)
+               pageunmap_range(pgmap, i);
++      percpu_ref_exit(&pgmap->ref);
+       WARN_ONCE(pgmap->altmap.alloc, "failed to free all reserved pages\n");
+       devmap_managed_enable_put(pgmap);
+-- 
+2.35.1
+
diff --git a/queue-5.15/mm-mmap.c-fix-missing-call-to-vm_unacct_memory-in-mm.patch b/queue-5.15/mm-mmap.c-fix-missing-call-to-vm_unacct_memory-in-mm.patch
new file mode 100644 (file)
index 0000000..db82899
--- /dev/null
@@ -0,0 +1,40 @@
+From 63f3af71d68dbeb4569f207926428a62bfb306a4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Jun 2022 16:20:27 +0800
+Subject: mm/mmap.c: fix missing call to vm_unacct_memory in mmap_region
+
+From: Miaohe Lin <linmiaohe@huawei.com>
+
+[ Upstream commit 7f82f922319ede486540e8746769865b9508d2c2 ]
+
+Since the beginning, charged is set to 0 to avoid calling vm_unacct_memory
+twice because vm_unacct_memory will be called by above unmap_region.  But
+since commit 4f74d2c8e827 ("vm: remove 'nr_accounted' calculations from
+the unmap_vmas() interfaces"), unmap_region doesn't call vm_unacct_memory
+anymore.  So charged shouldn't be set to 0 now otherwise the calling to
+paired vm_unacct_memory will be missed and leads to imbalanced account.
+
+Link: https://lkml.kernel.org/r/20220618082027.43391-1-linmiaohe@huawei.com
+Fixes: 4f74d2c8e827 ("vm: remove 'nr_accounted' calculations from the unmap_vmas() interfaces")
+Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/mmap.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/mm/mmap.c b/mm/mmap.c
+index 6bb553ed5c55..031fca1a7c65 100644
+--- a/mm/mmap.c
++++ b/mm/mmap.c
+@@ -1878,7 +1878,6 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
+       /* Undo any partial mapping done by a device driver. */
+       unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
+-      charged = 0;
+       if (vm_flags & VM_SHARED)
+               mapping_unmap_writable(file->f_mapping);
+ free_vma:
+-- 
+2.35.1
+
diff --git a/queue-5.15/mmc-block-add-single-read-for-4k-sector-cards.patch b/queue-5.15/mmc-block-add-single-read-for-4k-sector-cards.patch
new file mode 100644 (file)
index 0000000..6ead406
--- /dev/null
@@ -0,0 +1,129 @@
+From 7dd8511d6d188190deee1211704fc4ee5a0e47bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 12:43:09 +0000
+Subject: mmc: block: Add single read for 4k sector cards
+
+From: Christian Loehle <CLoehle@hyperstone.com>
+
+[ Upstream commit b3fa3e6dccc465969721b8bd2824213bd235efeb ]
+
+Cards with 4k native sector size may only be read 4k-aligned,
+accommodate for this in the single read recovery and use it.
+
+Fixes: 81196976ed946 (mmc: block: Add blk-mq support)
+Signed-off-by: Christian Loehle <cloehle@hyperstone.com>
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Reviewed-by: Avri Altman <avri.altman@wdc.com>
+Link: https://lore.kernel.org/r/cf4f316274c5474586d0d99b17db4a4c@hyperstone.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/core/block.c | 28 ++++++++++++++--------------
+ 1 file changed, 14 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
+index a196116444a3..3222a9d0c245 100644
+--- a/drivers/mmc/core/block.c
++++ b/drivers/mmc/core/block.c
+@@ -175,7 +175,7 @@ static inline int mmc_blk_part_switch(struct mmc_card *card,
+                                     unsigned int part_type);
+ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
+                              struct mmc_card *card,
+-                             int disable_multi,
++                             int recovery_mode,
+                              struct mmc_queue *mq);
+ static void mmc_blk_hsq_req_done(struct mmc_request *mrq);
+@@ -1285,7 +1285,7 @@ static void mmc_blk_eval_resp_error(struct mmc_blk_request *brq)
+ }
+ static void mmc_blk_data_prep(struct mmc_queue *mq, struct mmc_queue_req *mqrq,
+-                            int disable_multi, bool *do_rel_wr_p,
++                            int recovery_mode, bool *do_rel_wr_p,
+                             bool *do_data_tag_p)
+ {
+       struct mmc_blk_data *md = mq->blkdata;
+@@ -1351,12 +1351,12 @@ static void mmc_blk_data_prep(struct mmc_queue *mq, struct mmc_queue_req *mqrq,
+                       brq->data.blocks--;
+               /*
+-               * After a read error, we redo the request one sector
++               * After a read error, we redo the request one (native) sector
+                * at a time in order to accurately determine which
+                * sectors can be read successfully.
+                */
+-              if (disable_multi)
+-                      brq->data.blocks = 1;
++              if (recovery_mode)
++                      brq->data.blocks = queue_physical_block_size(mq->queue) >> 9;
+               /*
+                * Some controllers have HW issues while operating
+@@ -1573,7 +1573,7 @@ static int mmc_blk_cqe_issue_rw_rq(struct mmc_queue *mq, struct request *req)
+ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
+                              struct mmc_card *card,
+-                             int disable_multi,
++                             int recovery_mode,
+                              struct mmc_queue *mq)
+ {
+       u32 readcmd, writecmd;
+@@ -1582,7 +1582,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
+       struct mmc_blk_data *md = mq->blkdata;
+       bool do_rel_wr, do_data_tag;
+-      mmc_blk_data_prep(mq, mqrq, disable_multi, &do_rel_wr, &do_data_tag);
++      mmc_blk_data_prep(mq, mqrq, recovery_mode, &do_rel_wr, &do_data_tag);
+       brq->mrq.cmd = &brq->cmd;
+@@ -1673,7 +1673,7 @@ static int mmc_blk_fix_state(struct mmc_card *card, struct request *req)
+ #define MMC_READ_SINGLE_RETRIES       2
+-/* Single sector read during recovery */
++/* Single (native) sector read during recovery */
+ static void mmc_blk_read_single(struct mmc_queue *mq, struct request *req)
+ {
+       struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
+@@ -1681,6 +1681,7 @@ static void mmc_blk_read_single(struct mmc_queue *mq, struct request *req)
+       struct mmc_card *card = mq->card;
+       struct mmc_host *host = card->host;
+       blk_status_t error = BLK_STS_OK;
++      size_t bytes_per_read = queue_physical_block_size(mq->queue);
+       do {
+               u32 status;
+@@ -1715,13 +1716,13 @@ static void mmc_blk_read_single(struct mmc_queue *mq, struct request *req)
+               else
+                       error = BLK_STS_OK;
+-      } while (blk_update_request(req, error, 512));
++      } while (blk_update_request(req, error, bytes_per_read));
+       return;
+ error_exit:
+       mrq->data->bytes_xfered = 0;
+-      blk_update_request(req, BLK_STS_IOERR, 512);
++      blk_update_request(req, BLK_STS_IOERR, bytes_per_read);
+       /* Let it try the remaining request again */
+       if (mqrq->retries > MMC_MAX_RETRIES - 1)
+               mqrq->retries = MMC_MAX_RETRIES - 1;
+@@ -1862,10 +1863,9 @@ static void mmc_blk_mq_rw_recovery(struct mmc_queue *mq, struct request *req)
+               return;
+       }
+-      /* FIXME: Missing single sector read for large sector size */
+-      if (!mmc_large_sector(card) && rq_data_dir(req) == READ &&
+-          brq->data.blocks > 1) {
+-              /* Read one sector at a time */
++      if (rq_data_dir(req) == READ && brq->data.blocks >
++                      queue_physical_block_size(mq->queue) >> 9) {
++              /* Read one (native) sector at a time */
+               mmc_blk_read_single(mq, req);
+               return;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/mmc-cavium-octeon-add-of_node_put-when-breaking-out-.patch b/queue-5.15/mmc-cavium-octeon-add-of_node_put-when-breaking-out-.patch
new file mode 100644 (file)
index 0000000..494f480
--- /dev/null
@@ -0,0 +1,38 @@
+From b0eb51f0ca208f84e6d874dc4406e11a3b90f76f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 17:52:15 +0800
+Subject: mmc: cavium-octeon: Add of_node_put() when breaking out of loop
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 19bbb49acf8d7a03cb83e05624363741a4c3ec6f ]
+
+In octeon_mmc_probe(), we should call of_node_put() when breaking
+out of for_each_child_of_node() which has increased and decreased
+the refcount during each iteration.
+
+Fixes: 01d95843335c ("mmc: cavium: Add MMC support for Octeon SOCs.")
+Signed-off-by: Liang He <windhl@126.com>
+Acked-by: Robert Richter <rric@kernel.org>
+Link: https://lore.kernel.org/r/20220719095216.1241601-1-windhl@126.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/cavium-octeon.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/mmc/host/cavium-octeon.c b/drivers/mmc/host/cavium-octeon.c
+index 2c4b2df52adb..12dca91a8ef6 100644
+--- a/drivers/mmc/host/cavium-octeon.c
++++ b/drivers/mmc/host/cavium-octeon.c
+@@ -277,6 +277,7 @@ static int octeon_mmc_probe(struct platform_device *pdev)
+               if (ret) {
+                       dev_err(&pdev->dev, "Error populating slots\n");
+                       octeon_mmc_set_shared_power(host, 0);
++                      of_node_put(cn);
+                       goto error;
+               }
+               i++;
+-- 
+2.35.1
+
diff --git a/queue-5.15/mmc-cavium-thunderx-add-of_node_put-when-breaking-ou.patch b/queue-5.15/mmc-cavium-thunderx-add-of_node_put-when-breaking-ou.patch
new file mode 100644 (file)
index 0000000..d49d8b5
--- /dev/null
@@ -0,0 +1,42 @@
+From 764645c0b37a59ef0141ac3df7527ab5842ee85a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 17:52:16 +0800
+Subject: mmc: cavium-thunderx: Add of_node_put() when breaking out of loop
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 7ee480795e41db314f2c445c65ed854a5d6e8e32 ]
+
+In thunder_mmc_probe(), we should call of_node_put() when breaking
+out of for_each_child_of_node() which has increased and decreased
+the refcount during each iteration.
+
+Fixes: 166bac38c3c5 ("mmc: cavium: Add MMC PCI driver for ThunderX SOCs")
+Signed-off-by: Liang He <windhl@126.com>
+Acked-by: Robert Richter <rric@kernel.org>
+Link: https://lore.kernel.org/r/20220719095216.1241601-2-windhl@126.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/cavium-thunderx.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/cavium-thunderx.c b/drivers/mmc/host/cavium-thunderx.c
+index 76013bbbcff3..202b1d6da678 100644
+--- a/drivers/mmc/host/cavium-thunderx.c
++++ b/drivers/mmc/host/cavium-thunderx.c
+@@ -142,8 +142,10 @@ static int thunder_mmc_probe(struct pci_dev *pdev,
+                               continue;
+                       ret = cvm_mmc_of_slot_probe(&host->slot_pdev[i]->dev, host);
+-                      if (ret)
++                      if (ret) {
++                              of_node_put(child_node);
+                               goto error;
++                      }
+               }
+               i++;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/mmc-mxcmmc-silence-a-clang-warning.patch b/queue-5.15/mmc-mxcmmc-silence-a-clang-warning.patch
new file mode 100644 (file)
index 0000000..155a99c
--- /dev/null
@@ -0,0 +1,40 @@
+From 2fa9680349284cc7e7113af021c60b16a32e4c53 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 May 2022 22:00:22 -0300
+Subject: mmc: mxcmmc: Silence a clang warning
+
+From: Fabio Estevam <festevam@gmail.com>
+
+[ Upstream commit 7dc65e3c0ef4b746a583b7c58f99873fddf5ccfa ]
+
+Change the of_device_get_match_data() cast to (uintptr_t)
+to silence the following clang warning:
+
+drivers/mmc/host/mxcmmc.c:1028:18: warning: cast to smaller integer type 'enum mxcmci_type' from 'const void *' [-Wvoid-pointer-to-enum-cast]
+
+Reported-by: kernel test robot <lkp@intel.com>
+Fixes: 8223e885e74b ("mmc: mxc: Convert the driver to DT-only")
+Signed-off-by: Fabio Estevam <festevam@gmail.com>
+Link: https://lore.kernel.org/r/20220526010022.1163483-1-festevam@gmail.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/mxcmmc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
+index 2fe6fcdbb1b3..9bf95ba217fa 100644
+--- a/drivers/mmc/host/mxcmmc.c
++++ b/drivers/mmc/host/mxcmmc.c
+@@ -1025,7 +1025,7 @@ static int mxcmci_probe(struct platform_device *pdev)
+       mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
+       mmc->max_seg_size = mmc->max_req_size;
+-      host->devtype = (enum mxcmci_type)of_device_get_match_data(&pdev->dev);
++      host->devtype = (uintptr_t)of_device_get_match_data(&pdev->dev);
+       /* adjust max_segs after devtype detection */
+       if (!is_mpc512x_mmc(host))
+-- 
+2.35.1
+
diff --git a/queue-5.15/mmc-renesas_sdhi-get-the-reset-handle-early-in-the-p.patch b/queue-5.15/mmc-renesas_sdhi-get-the-reset-handle-early-in-the-p.patch
new file mode 100644 (file)
index 0000000..d47817d
--- /dev/null
@@ -0,0 +1,57 @@
+From 074fbdf8b2201efaf415a68bf665763532fa6e05 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jun 2022 19:14:37 +0100
+Subject: mmc: renesas_sdhi: Get the reset handle early in the probe
+
+From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+
+[ Upstream commit 0dac1e498f8130fdacfdd5289e3a7ac87ec1b9ad ]
+
+In case of devm_reset_control_get_optional_exclusive() failure we returned
+directly instead of jumping to the error path to roll back initialization.
+
+This patch moves devm_reset_control_get_optional_exclusive() early in the
+probe so that we have the reset handle prior to initialization of the
+hardware.
+
+Fixes: b4d86f37eacb7 ("mmc: renesas_sdhi: do hard reset if possible")
+Reported-by: Pavel Machek <pavel@denx.de>
+Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Link: https://lore.kernel.org/r/20220624181438.4355-2-prabhakar.mahadev-lad.rj@bp.renesas.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/renesas_sdhi_core.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
+index ae689bf54686..791e180a0617 100644
+--- a/drivers/mmc/host/renesas_sdhi_core.c
++++ b/drivers/mmc/host/renesas_sdhi_core.c
+@@ -925,6 +925,10 @@ int renesas_sdhi_probe(struct platform_device *pdev,
+       if (IS_ERR(priv->clk_cd))
+               priv->clk_cd = NULL;
++      priv->rstc = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL);
++      if (IS_ERR(priv->rstc))
++              return PTR_ERR(priv->rstc);
++
+       priv->pinctrl = devm_pinctrl_get(&pdev->dev);
+       if (!IS_ERR(priv->pinctrl)) {
+               priv->pins_default = pinctrl_lookup_state(priv->pinctrl,
+@@ -1013,10 +1017,6 @@ int renesas_sdhi_probe(struct platform_device *pdev,
+       if (ret)
+               goto efree;
+-      priv->rstc = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL);
+-      if (IS_ERR(priv->rstc))
+-              return PTR_ERR(priv->rstc);
+-
+       ver = sd_ctrl_read16(host, CTL_VERSION);
+       /* GEN2_SDR104 is first known SDHI to use 32bit block count */
+       if (ver < SDHI_VER_GEN2_SDR104 && mmc_data->max_blk_count > U16_MAX)
+-- 
+2.35.1
+
diff --git a/queue-5.15/mmc-renesas_sdhi-get-the-reset-handle-early-in-the-p.patch-12121 b/queue-5.15/mmc-renesas_sdhi-get-the-reset-handle-early-in-the-p.patch-12121
new file mode 100644 (file)
index 0000000..707c218
--- /dev/null
@@ -0,0 +1,46 @@
+From 6c8b682c62db9b2841ef8cf013679a090e660ac6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jun 2022 19:14:37 +0100
+Subject: mmc: renesas_sdhi: Get the reset handle early in the probe
+
+From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+
+[ Upstream commit 0dac1e498f8130fdacfdd5289e3a7ac87ec1b9ad ]
+
+In case of devm_reset_control_get_optional_exclusive() failure we returned
+directly instead of jumping to the error path to roll back initialization.
+
+This patch moves devm_reset_control_get_optional_exclusive() early in the
+probe so that we have the reset handle prior to initialization of the
+hardware.
+
+Fixes: b4d86f37eacb7 ("mmc: renesas_sdhi: do hard reset if possible")
+Reported-by: Pavel Machek <pavel@denx.de>
+Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Link: https://lore.kernel.org/r/20220624181438.4355-2-prabhakar.mahadev-lad.rj@bp.renesas.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/renesas_sdhi_core.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
+index 791e180a0617..c692709fcdd7 100644
+--- a/drivers/mmc/host/renesas_sdhi_core.c
++++ b/drivers/mmc/host/renesas_sdhi_core.c
+@@ -929,6 +929,10 @@ int renesas_sdhi_probe(struct platform_device *pdev,
+       if (IS_ERR(priv->rstc))
+               return PTR_ERR(priv->rstc);
++      priv->rstc = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL);
++      if (IS_ERR(priv->rstc))
++              return PTR_ERR(priv->rstc);
++
+       priv->pinctrl = devm_pinctrl_get(&pdev->dev);
+       if (!IS_ERR(priv->pinctrl)) {
+               priv->pins_default = pinctrl_lookup_state(priv->pinctrl,
+-- 
+2.35.1
+
diff --git a/queue-5.15/mmc-sdhci-of-at91-fix-set_uhs_signaling-rewriting-of.patch b/queue-5.15/mmc-sdhci-of-at91-fix-set_uhs_signaling-rewriting-of.patch
new file mode 100644 (file)
index 0000000..c2646fd
--- /dev/null
@@ -0,0 +1,48 @@
+From 5415d0f308628e7aef121a9ed471bec2636aaad1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Jun 2022 12:09:26 +0300
+Subject: mmc: sdhci-of-at91: fix set_uhs_signaling rewriting of MC1R
+
+From: Eugen Hristev <eugen.hristev@microchip.com>
+
+[ Upstream commit 5987e6ded29d52e42fc7b06aa575c60a25eee38e ]
+
+In set_uhs_signaling, the DDR bit is being set by fully writing the MC1R
+register.
+This can lead to accidental erase of certain bits in this register.
+Avoid this by doing a read-modify-write operation.
+
+Fixes: d0918764c17b ("mmc: sdhci-of-at91: fix MMC_DDR_52 timing selection")
+Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
+Tested-by: Karl Olsen <karl@micro-technic.com>
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Link: https://lore.kernel.org/r/20220630090926.15061-1-eugen.hristev@microchip.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/sdhci-of-at91.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mmc/host/sdhci-of-at91.c b/drivers/mmc/host/sdhci-of-at91.c
+index d1a1c548c515..0452c312b65e 100644
+--- a/drivers/mmc/host/sdhci-of-at91.c
++++ b/drivers/mmc/host/sdhci-of-at91.c
+@@ -100,8 +100,13 @@ static void sdhci_at91_set_clock(struct sdhci_host *host, unsigned int clock)
+ static void sdhci_at91_set_uhs_signaling(struct sdhci_host *host,
+                                        unsigned int timing)
+ {
+-      if (timing == MMC_TIMING_MMC_DDR52)
+-              sdhci_writeb(host, SDMMC_MC1R_DDR, SDMMC_MC1R);
++      u8 mc1r;
++
++      if (timing == MMC_TIMING_MMC_DDR52) {
++              mc1r = sdhci_readb(host, SDMMC_MC1R);
++              mc1r |= SDMMC_MC1R_DDR;
++              sdhci_writeb(host, mc1r, SDMMC_MC1R);
++      }
+       sdhci_set_uhs_signaling(host, timing);
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/mmc-sdhci-of-esdhc-fix-refcount-leak-in-esdhc_signal.patch b/queue-5.15/mmc-sdhci-of-esdhc-fix-refcount-leak-in-esdhc_signal.patch
new file mode 100644 (file)
index 0000000..03e0b75
--- /dev/null
@@ -0,0 +1,38 @@
+From b987de22046742cd0d6ed399a5f702bd1ed784fe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 May 2022 18:42:54 +0400
+Subject: mmc: sdhci-of-esdhc: Fix refcount leak in esdhc_signal_voltage_switch
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit b5899a3e2f783a27b268e38d37f9b24c71bddf45 ]
+
+of_find_matching_node() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when not need anymore.
+Add missing of_node_put() to avoid refcount leak.
+of_node_put() checks null pointer.
+
+Fixes: ea35645a3c66 ("mmc: sdhci-of-esdhc: add support for signal voltage switch")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Link: https://lore.kernel.org/r/20220523144255.10310-1-linmq006@gmail.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/sdhci-of-esdhc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
+index 0f3658b36513..04a37fd137ee 100644
+--- a/drivers/mmc/host/sdhci-of-esdhc.c
++++ b/drivers/mmc/host/sdhci-of-esdhc.c
+@@ -904,6 +904,7 @@ static int esdhc_signal_voltage_switch(struct mmc_host *mmc,
+               scfg_node = of_find_matching_node(NULL, scfg_device_ids);
+               if (scfg_node)
+                       scfg_base = of_iomap(scfg_node, 0);
++              of_node_put(scfg_node);
+               if (scfg_base) {
+                       sdhciovselcr = SDHCIOVSELCR_TGLEN |
+                                      SDHCIOVSELCR_VSELVAL;
+-- 
+2.35.1
+
diff --git a/queue-5.15/mt76-mt7615-do-not-update-pm-stats-in-case-of-error.patch b/queue-5.15/mt76-mt7615-do-not-update-pm-stats-in-case-of-error.patch
new file mode 100644 (file)
index 0000000..d582508
--- /dev/null
@@ -0,0 +1,42 @@
+From 43509a6152e3cc41fb0e0672111a5aadd0fff12d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 14:03:28 +0200
+Subject: mt76: mt7615: do not update pm stats in case of error
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit 79717c4eeeae9dec894794fbe8af72f08f03ebdd ]
+
+Do not update pm stats if mt7615_mcu_fw_pmctrl returns an error.
+
+Fixes: abe912ae3cd42 ("mt76: mt7663: add awake and doze time accounting")
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7615/mcu.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
+index 4fed3afad67c..bde65af72fed 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
+@@ -385,10 +385,11 @@ static int mt7615_mcu_fw_pmctrl(struct mt7615_dev *dev)
+       }
+       mt7622_trigger_hif_int(dev, false);
+-
+-      pm->stats.last_doze_event = jiffies;
+-      pm->stats.awake_time += pm->stats.last_doze_event -
+-                              pm->stats.last_wake_event;
++      if (!err) {
++              pm->stats.last_doze_event = jiffies;
++              pm->stats.awake_time += pm->stats.last_doze_event -
++                                      pm->stats.last_wake_event;
++      }
+ out:
+       mutex_unlock(&pm->mutex);
+-- 
+2.35.1
+
diff --git a/queue-5.15/mt76-mt76x02u-fix-possible-memory-leak-in-__mt76x02u.patch b/queue-5.15/mt76-mt76x02u-fix-possible-memory-leak-in-__mt76x02u.patch
new file mode 100644 (file)
index 0000000..94f61ec
--- /dev/null
@@ -0,0 +1,37 @@
+From fc736a26f9136ec8fa23eda5fe1a223927addadf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 May 2022 18:37:07 +0200
+Subject: mt76: mt76x02u: fix possible memory leak in __mt76x02u_mcu_send_msg
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit cffd93411575afd987788e2ec3cb8eaff70f0215 ]
+
+Free the skb if mt76u_bulk_msg fails in __mt76x02u_mcu_send_msg routine.
+
+Fixes: 4c89ff2c74e39 ("mt76: split __mt76u_mcu_send_msg and mt76u_mcu_send_msg routines")
+Co-developed-by: Gergo Koteles <soyer@irl.hu>
+Signed-off-by: Gergo Koteles <soyer@irl.hu>
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c
+index 2953df7d8388..c6c16fe8ee85 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c
+@@ -108,7 +108,7 @@ __mt76x02u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb,
+       ret = mt76u_bulk_msg(dev, skb->data, skb->len, NULL, 500,
+                            MT_EP_OUT_INBAND_CMD);
+       if (ret)
+-              return ret;
++              goto out;
+       if (wait_resp)
+               ret = mt76x02u_mcu_wait_resp(dev, seq);
+-- 
+2.35.1
+
diff --git a/queue-5.15/mt76-mt7921-enlarge-maximum-vht-mpdu-length-to-11454.patch b/queue-5.15/mt76-mt7921-enlarge-maximum-vht-mpdu-length-to-11454.patch
new file mode 100644 (file)
index 0000000..8ae2693
--- /dev/null
@@ -0,0 +1,37 @@
+From 45ff55b505e62717da371225fbf2ddd2efb93cce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Jun 2022 18:56:44 +0800
+Subject: mt76: mt7921: enlarge maximum VHT MPDU length to 11454
+
+From: Deren Wu <deren.wu@mediatek.com>
+
+[ Upstream commit 31f3248a75932b111bc90c66b1f6c7d89eedca8e ]
+
+Enlarge maximum MPDU length to 11454 that both mt7921/mt7922 can support.
+After this fixing, we can get better performance.
+
+Fixes: 5c14a5f944b9 ("mt76: mt7921: introduce mt7921e support")
+Tested-by: Ming Yen Hsieh <mingyen.hsieh@mediatek.com>
+Signed-off-by: Deren Wu <deren.wu@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7921/init.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
+index a8998e6bfb6f..c059cb419efd 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
+@@ -219,7 +219,7 @@ int mt7921_register_device(struct mt7921_dev *dev)
+                       IEEE80211_HT_CAP_LDPC_CODING |
+                       IEEE80211_HT_CAP_MAX_AMSDU;
+       dev->mphy.sband_5g.sband.vht_cap.cap |=
+-                      IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 |
++                      IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |
+                       IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK |
+                       IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
+                       IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |
+-- 
+2.35.1
+
diff --git a/queue-5.15/mt76-mt7921-fix-aggregation-subframes-setting-to-he-.patch b/queue-5.15/mt76-mt7921-fix-aggregation-subframes-setting-to-he-.patch
new file mode 100644 (file)
index 0000000..e4e59bc
--- /dev/null
@@ -0,0 +1,40 @@
+From c95351a4c9b5f01f12b0556bd470595d74e025ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jun 2022 23:57:43 +0800
+Subject: mt76: mt7921: fix aggregation subframes setting to HE max
+
+From: Deren Wu <deren.wu@mediatek.com>
+
+[ Upstream commit d5a50e6bd1972c481f82befa846dce0b9866f025 ]
+
+mt7921/mt7922 support HE max aggregation subframes 256 for both tx/rx.
+Get better throughput then before.
+
+Fixes: 94bb18b03d43 ("mt76: mt7921: fix max aggregation subframes setting")
+Tested-by: Ming Yen Hsieh <mingyen.hsieh@mediatek.com>
+Reviewed-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Deren Wu <deren.wu@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7921/init.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
+index 78a00028137b..a8998e6bfb6f 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
+@@ -49,8 +49,8 @@ mt7921_init_wiphy(struct ieee80211_hw *hw)
+       struct wiphy *wiphy = hw->wiphy;
+       hw->queues = 4;
+-      hw->max_rx_aggregation_subframes = 64;
+-      hw->max_tx_aggregation_subframes = 128;
++      hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_HE;
++      hw->max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_HE;
+       hw->netdev_features = NETIF_F_RXCSUM;
+       hw->radiotap_timestamp.units_pos =
+-- 
+2.35.1
+
diff --git a/queue-5.15/mtd-dataflash-add-spi-id-table.patch b/queue-5.15/mtd-dataflash-add-spi-id-table.patch
new file mode 100644 (file)
index 0000000..2211da7
--- /dev/null
@@ -0,0 +1,53 @@
+From 0794a29b76a01b69e0f9e093ed2ff80f3e322fb8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jun 2022 16:23:13 +0100
+Subject: mtd: dataflash: Add SPI ID table
+
+From: Mark Brown <broonie@kernel.org>
+
+[ Upstream commit ac4f83482afbfd927d0fe118151b747cf175e724 ]
+
+Currently autoloading for SPI devices does not use the DT ID table, it uses
+SPI modalises. Supporting OF modalises is going to be difficult if not
+impractical, an attempt was made but has been reverted, so ensure that
+module autoloading works for this driver by adding an id_table listing the
+SPI IDs for everything.
+
+Fixes: 96c8395e2166 ("spi: Revert modalias changes")
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20220620152313.708768-1-broonie@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/devices/mtd_dataflash.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c
+index 2b317ed6c103..9c714c982c6e 100644
+--- a/drivers/mtd/devices/mtd_dataflash.c
++++ b/drivers/mtd/devices/mtd_dataflash.c
+@@ -112,6 +112,13 @@ static const struct of_device_id dataflash_dt_ids[] = {
+ MODULE_DEVICE_TABLE(of, dataflash_dt_ids);
+ #endif
++static const struct spi_device_id dataflash_spi_ids[] = {
++      { .name = "at45", },
++      { .name = "dataflash", },
++      { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(spi, dataflash_spi_ids);
++
+ /* ......................................................................... */
+ /*
+@@ -938,6 +945,7 @@ static struct spi_driver dataflash_driver = {
+       .probe          = dataflash_probe,
+       .remove         = dataflash_remove,
++      .id_table       = dataflash_spi_ids,
+       /* FIXME:  investigate suspend and resume... */
+ };
+-- 
+2.35.1
+
diff --git a/queue-5.15/mtd-maps-fix-refcount-leak-in-ap_flash_init.patch b/queue-5.15/mtd-maps-fix-refcount-leak-in-ap_flash_init.patch
new file mode 100644 (file)
index 0000000..60b19b4
--- /dev/null
@@ -0,0 +1,38 @@
+From 3f44764fc028d184804a9e833cabe38292c238c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 May 2022 18:32:55 +0400
+Subject: mtd: maps: Fix refcount leak in ap_flash_init
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 77087a04c8fd554134bddcb8a9ff87b21f357926 ]
+
+of_find_matching_node() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when not need anymore.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: b0afd44bc192 ("mtd: physmap_of: add a hook for Versatile write protection")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20220523143255.4376-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/maps/physmap-versatile.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/mtd/maps/physmap-versatile.c b/drivers/mtd/maps/physmap-versatile.c
+index 297a50957356..a1b8b7b25f88 100644
+--- a/drivers/mtd/maps/physmap-versatile.c
++++ b/drivers/mtd/maps/physmap-versatile.c
+@@ -93,6 +93,7 @@ static int ap_flash_init(struct platform_device *pdev)
+               return -ENODEV;
+       }
+       ebi_base = of_iomap(ebi, 0);
++      of_node_put(ebi);
+       if (!ebi_base)
+               return -ENODEV;
+-- 
+2.35.1
+
diff --git a/queue-5.15/mtd-maps-fix-refcount-leak-in-of_flash_probe_versati.patch b/queue-5.15/mtd-maps-fix-refcount-leak-in-of_flash_probe_versati.patch
new file mode 100644 (file)
index 0000000..37e97cc
--- /dev/null
@@ -0,0 +1,38 @@
+From 093c3b74d4da10ddb36152f95ee88df23f2c34b9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 May 2022 18:02:05 +0400
+Subject: mtd: maps: Fix refcount leak in of_flash_probe_versatile
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 33ec82a6d2b119938f26e5c8040ed5d92378eb54 ]
+
+of_find_matching_node_and_match() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when not need anymore.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: b0afd44bc192 ("mtd: physmap_of: add a hook for Versatile write protection")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20220523140205.48625-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/maps/physmap-versatile.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/mtd/maps/physmap-versatile.c b/drivers/mtd/maps/physmap-versatile.c
+index ad7cd9cfaee0..297a50957356 100644
+--- a/drivers/mtd/maps/physmap-versatile.c
++++ b/drivers/mtd/maps/physmap-versatile.c
+@@ -207,6 +207,7 @@ int of_flash_probe_versatile(struct platform_device *pdev,
+               versatile_flashprot = (enum versatile_flashprot)devid->data;
+               rmap = syscon_node_to_regmap(sysnp);
++              of_node_put(sysnp);
+               if (IS_ERR(rmap))
+                       return PTR_ERR(rmap);
+-- 
+2.35.1
+
diff --git a/queue-5.15/mtd-parsers-ofpart-fix-refcount-leak-in-bcm4908_part.patch b/queue-5.15/mtd-parsers-ofpart-fix-refcount-leak-in-bcm4908_part.patch
new file mode 100644 (file)
index 0000000..45e2dca
--- /dev/null
@@ -0,0 +1,46 @@
+From d7599862c023eac65fe8dd50cb5fe5a9074bfdfd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Jun 2022 11:07:23 +0400
+Subject: mtd: parsers: ofpart: Fix refcount leak in
+ bcm4908_partitions_fw_offset
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit e607879b0da18c451de5e91daf239cc2f2f8ff2d ]
+
+of_find_node_by_path() returns a node pointer with refcount incremented,
+we should use of_node_put() on it when not need anymore.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: bb17230c61a6 ("mtd: parsers: ofpart: support BCM4908 fixed partitions")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20220605070726.5979-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/parsers/ofpart_bcm4908.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/mtd/parsers/ofpart_bcm4908.c b/drivers/mtd/parsers/ofpart_bcm4908.c
+index 0eddef4c198e..bb072a0940e4 100644
+--- a/drivers/mtd/parsers/ofpart_bcm4908.c
++++ b/drivers/mtd/parsers/ofpart_bcm4908.c
+@@ -35,12 +35,15 @@ static long long bcm4908_partitions_fw_offset(void)
+               err = kstrtoul(s + len + 1, 0, &offset);
+               if (err) {
+                       pr_err("failed to parse %s\n", s + len + 1);
++                      of_node_put(root);
+                       return err;
+               }
++              of_node_put(root);
+               return offset << 10;
+       }
++      of_node_put(root);
+       return -ENOENT;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/mtd-partitions-fix-refcount-leak-in-parse_redboot_of.patch b/queue-5.15/mtd-partitions-fix-refcount-leak-in-parse_redboot_of.patch
new file mode 100644 (file)
index 0000000..379c746
--- /dev/null
@@ -0,0 +1,38 @@
+From 1decf5e92c9ebf96151dfdc36d5a9fadb5410b94 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 May 2022 15:06:49 +0400
+Subject: mtd: partitions: Fix refcount leak in parse_redboot_of
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 9f7e62815cf3cbbcb1b8cb21649fb4dfdb3aa016 ]
+
+of_get_child_by_name() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when not need anymore.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: 237960880960 ("mtd: partitions: redboot: seek fis-index-block in the right node")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20220526110652.64849-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/parsers/redboot.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/mtd/parsers/redboot.c b/drivers/mtd/parsers/redboot.c
+index feb44a573d44..a16b42a88581 100644
+--- a/drivers/mtd/parsers/redboot.c
++++ b/drivers/mtd/parsers/redboot.c
+@@ -58,6 +58,7 @@ static void parse_redboot_of(struct mtd_info *master)
+               return;
+       ret = of_property_read_u32(npart, "fis-index-block", &dirblock);
++      of_node_put(npart);
+       if (ret)
+               return;
+-- 
+2.35.1
+
diff --git a/queue-5.15/mtd-rawnand-meson-fix-a-potential-double-free-issue.patch b/queue-5.15/mtd-rawnand-meson-fix-a-potential-double-free-issue.patch
new file mode 100644 (file)
index 0000000..980c873
--- /dev/null
@@ -0,0 +1,46 @@
+From ea71d00a9302f79f475492619b8d7e92a05e0759 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 May 2022 18:41:40 +0200
+Subject: mtd: rawnand: meson: Fix a potential double free issue
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit ec0da06337751b18f6dee06b6526e0f0d6e80369 ]
+
+When meson_nfc_nand_chip_cleanup() is called, it will call:
+       meson_nfc_free_buffer(&meson_chip->nand);
+       nand_cleanup(&meson_chip->nand);
+
+nand_cleanup() in turn will call nand_detach() which calls the
+.detach_chip() which is here meson_nand_detach_chip().
+
+meson_nand_detach_chip() already calls meson_nfc_free_buffer(), so we
+could double free some memory.
+
+Fix it by removing the unneeded explicit call to meson_nfc_free_buffer().
+
+Fixes: 8fae856c5350 ("mtd: rawnand: meson: add support for Amlogic NAND flash controller")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Acked-by: Liang Yang <liang.yang@amlogic.com>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/ec15c358b8063f7c50ff4cd628cf0d2e14e43f49.1653064877.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/nand/raw/meson_nand.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
+index ac3be92872d0..032180183339 100644
+--- a/drivers/mtd/nand/raw/meson_nand.c
++++ b/drivers/mtd/nand/raw/meson_nand.c
+@@ -1307,7 +1307,6 @@ static int meson_nfc_nand_chip_cleanup(struct meson_nfc *nfc)
+               if (ret)
+                       return ret;
+-              meson_nfc_free_buffer(&meson_chip->nand);
+               nand_cleanup(&meson_chip->nand);
+               list_del(&meson_chip->node);
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/mtd-sm_ftl-fix-deadlock-caused-by-cancel_work_sync-i.patch b/queue-5.15/mtd-sm_ftl-fix-deadlock-caused-by-cancel_work_sync-i.patch
new file mode 100644 (file)
index 0000000..5df5bbc
--- /dev/null
@@ -0,0 +1,53 @@
+From 65c7ec94e0e74dea944ace3f7180da06da80e97a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 May 2022 12:48:41 +0800
+Subject: mtd: sm_ftl: Fix deadlock caused by cancel_work_sync in sm_release
+
+From: Duoming Zhou <duoming@zju.edu.cn>
+
+[ Upstream commit a61528d997619a518ee8c51cf0ef0513021afaff ]
+
+There is a deadlock between sm_release and sm_cache_flush_work
+which is a work item. The cancel_work_sync in sm_release will
+not return until sm_cache_flush_work is finished. If we hold
+mutex_lock and use cancel_work_sync to wait the work item to
+finish, the work item also requires mutex_lock. As a result,
+the sm_release will be blocked forever. The race condition is
+shown below:
+
+    (Thread 1)             |   (Thread 2)
+sm_release                 |
+  mutex_lock(&ftl->mutex)  | sm_cache_flush_work
+                           |   mutex_lock(&ftl->mutex)
+  cancel_work_sync         |   ...
+
+This patch moves del_timer_sync and cancel_work_sync out of
+mutex_lock in order to mitigate deadlock.
+
+Fixes: 7d17c02a01a1 ("mtd: Add new SmartMedia/xD FTL")
+Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20220524044841.10517-1-duoming@zju.edu.cn
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/sm_ftl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/sm_ftl.c b/drivers/mtd/sm_ftl.c
+index 0cff2cda1b5a..7f955fade838 100644
+--- a/drivers/mtd/sm_ftl.c
++++ b/drivers/mtd/sm_ftl.c
+@@ -1111,9 +1111,9 @@ static void sm_release(struct mtd_blktrans_dev *dev)
+ {
+       struct sm_ftl *ftl = dev->priv;
+-      mutex_lock(&ftl->mutex);
+       del_timer_sync(&ftl->timer);
+       cancel_work_sync(&ftl->flush_work);
++      mutex_lock(&ftl->mutex);
+       sm_cache_flush(ftl);
+       mutex_unlock(&ftl->mutex);
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/mtd-spi-nor-fix-spi_nor_spimem_setup_op-call-in-spi_.patch b/queue-5.15/mtd-spi-nor-fix-spi_nor_spimem_setup_op-call-in-spi_.patch
new file mode 100644 (file)
index 0000000..b550f06
--- /dev/null
@@ -0,0 +1,65 @@
+From 8ebccfb95c1f2855fad9e758cc1a74f250bcd843 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Jun 2022 15:30:13 +0200
+Subject: mtd: spi-nor: fix spi_nor_spimem_setup_op() call in
+ spi_nor_erase_{sector,chip}()
+
+From: Patrice Chotard <patrice.chotard@foss.st.com>
+
+[ Upstream commit f8cd9f632f4415b1e8838bdca8ab42cfb37a6584 ]
+
+For erase operations, reg_proto must be used as indicated in
+struct spi_nor description in spi-nor.h.
+
+This issue was found when DT property spi-tx-bus-width is set to 4.
+In this case the spi_mem_op->addr.buswidth is set to 4 for erase command
+which is not correct.
+
+Tested on stm32mp157c-ev1 board with mx66l51235f spi-nor.
+
+Fixes: 0e30f47232ab ("mtd: spi-nor: add support for DTR protocol")
+Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com>
+[ta: use nor->reg_proto in spi_nor_controller_ops_erase()]
+Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
+Tested-by: Alexander Sverdlin <alexander.sverdlin@nokia.com>
+Reviewed-by: Pratyush Yadav <p.yadav@ti.com>
+Link: https://lore.kernel.org/r/20220629133013.3382393-1-patrice.chotard@foss.st.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/spi-nor/core.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
+index d97cdbc2b9de..eb5d7b3d1860 100644
+--- a/drivers/mtd/spi-nor/core.c
++++ b/drivers/mtd/spi-nor/core.c
+@@ -177,7 +177,7 @@ static int spi_nor_controller_ops_write_reg(struct spi_nor *nor, u8 opcode,
+ static int spi_nor_controller_ops_erase(struct spi_nor *nor, loff_t offs)
+ {
+-      if (spi_nor_protocol_is_dtr(nor->write_proto))
++      if (spi_nor_protocol_is_dtr(nor->reg_proto))
+               return -EOPNOTSUPP;
+       return nor->controller_ops->erase(nor, offs);
+@@ -1195,7 +1195,7 @@ static int spi_nor_erase_chip(struct spi_nor *nor)
+                                  SPI_MEM_OP_NO_DUMMY,
+                                  SPI_MEM_OP_NO_DATA);
+-              spi_nor_spimem_setup_op(nor, &op, nor->write_proto);
++              spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
+               ret = spi_mem_exec_op(nor->spimem, &op);
+       } else {
+@@ -1340,7 +1340,7 @@ int spi_nor_erase_sector(struct spi_nor *nor, u32 addr)
+                                  SPI_MEM_OP_NO_DUMMY,
+                                  SPI_MEM_OP_NO_DATA);
+-              spi_nor_spimem_setup_op(nor, &op, nor->write_proto);
++              spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
+               return spi_mem_exec_op(nor->spimem, &op);
+       } else if (nor->controller_ops->erase) {
+-- 
+2.35.1
+
diff --git a/queue-5.15/mtd-st_spi_fsm-add-a-clk_disable_unprepare-in-.probe.patch b/queue-5.15/mtd-st_spi_fsm-add-a-clk_disable_unprepare-in-.probe.patch
new file mode 100644 (file)
index 0000000..06a0ef0
--- /dev/null
@@ -0,0 +1,49 @@
+From 42992d08df8ebbc7fa5d11ec65097bd10476370b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jun 2022 17:24:55 +0200
+Subject: mtd: st_spi_fsm: Add a clk_disable_unprepare() in .probe()'s error
+ path
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 28607b426c3d050714f250d0faeb99d2e9106e90 ]
+
+For all but one error path clk_disable_unprepare() is already there. Add
+it to the one location where it's missing.
+
+Fixes: 481815a6193b ("mtd: st_spi_fsm: Handle clk_prepare_enable/clk_disable_unprepare.")
+Fixes: 69d5af8d016c ("mtd: st_spi_fsm: Obtain and use EMI clock")
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20220607152458.232847-2-u.kleine-koenig@pengutronix.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/devices/st_spi_fsm.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
+index 983999c020d6..48bda2dd1bb5 100644
+--- a/drivers/mtd/devices/st_spi_fsm.c
++++ b/drivers/mtd/devices/st_spi_fsm.c
+@@ -2115,10 +2115,12 @@ static int stfsm_probe(struct platform_device *pdev)
+               (long long)fsm->mtd.size, (long long)(fsm->mtd.size >> 20),
+               fsm->mtd.erasesize, (fsm->mtd.erasesize >> 10));
+-      return mtd_device_register(&fsm->mtd, NULL, 0);
+-
++      ret = mtd_device_register(&fsm->mtd, NULL, 0);
++      if (ret) {
+ err_clk_unprepare:
+-      clk_disable_unprepare(fsm->clk);
++              clk_disable_unprepare(fsm->clk);
++      }
++
+       return ret;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/mwifiex-fix-sleep-in-atomic-context-bugs-caused-by-d.patch b/queue-5.15/mwifiex-fix-sleep-in-atomic-context-bugs-caused-by-d.patch
new file mode 100644 (file)
index 0000000..4781824
--- /dev/null
@@ -0,0 +1,173 @@
+From d97977c1d2638e188b7a9f79f99e45d6c94220b2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jun 2022 11:26:26 +0800
+Subject: mwifiex: fix sleep in atomic context bugs caused by dev_coredumpv
+
+From: Duoming Zhou <duoming@zju.edu.cn>
+
+[ Upstream commit a52ed4866d2b90dd5e4ae9dabd453f3ed8fa3cbc ]
+
+There are sleep in atomic context bugs when uploading device dump
+data in mwifiex. The root cause is that dev_coredumpv could not
+be used in atomic contexts, because it calls dev_set_name which
+include operations that may sleep. The call tree shows execution
+paths that could lead to bugs:
+
+   (Interrupt context)
+fw_dump_timer_fn
+  mwifiex_upload_device_dump
+    dev_coredumpv(..., GFP_KERNEL)
+      dev_coredumpm()
+        kzalloc(sizeof(*devcd), gfp); //may sleep
+        dev_set_name
+          kobject_set_name_vargs
+            kvasprintf_const(GFP_KERNEL, ...); //may sleep
+            kstrdup(s, GFP_KERNEL); //may sleep
+
+The corresponding fail log is shown below:
+
+[  135.275938] usb 1-1: == mwifiex dump information to /sys/class/devcoredump start
+[  135.281029] BUG: sleeping function called from invalid context at include/linux/sched/mm.h:265
+...
+[  135.293613] Call Trace:
+[  135.293613]  <IRQ>
+[  135.293613]  dump_stack_lvl+0x57/0x7d
+[  135.293613]  __might_resched.cold+0x138/0x173
+[  135.293613]  ? dev_coredumpm+0xca/0x2e0
+[  135.293613]  kmem_cache_alloc_trace+0x189/0x1f0
+[  135.293613]  ? devcd_match_failing+0x30/0x30
+[  135.293613]  dev_coredumpm+0xca/0x2e0
+[  135.293613]  ? devcd_freev+0x10/0x10
+[  135.293613]  dev_coredumpv+0x1c/0x20
+[  135.293613]  ? devcd_match_failing+0x30/0x30
+[  135.293613]  mwifiex_upload_device_dump+0x65/0xb0
+[  135.293613]  ? mwifiex_dnld_fw+0x1b0/0x1b0
+[  135.293613]  call_timer_fn+0x122/0x3d0
+[  135.293613]  ? msleep_interruptible+0xb0/0xb0
+[  135.293613]  ? lock_downgrade+0x3c0/0x3c0
+[  135.293613]  ? __next_timer_interrupt+0x13c/0x160
+[  135.293613]  ? lockdep_hardirqs_on_prepare+0xe/0x220
+[  135.293613]  ? mwifiex_dnld_fw+0x1b0/0x1b0
+[  135.293613]  __run_timers.part.0+0x3f8/0x540
+[  135.293613]  ? call_timer_fn+0x3d0/0x3d0
+[  135.293613]  ? arch_restore_msi_irqs+0x10/0x10
+[  135.293613]  ? lapic_next_event+0x31/0x40
+[  135.293613]  run_timer_softirq+0x4f/0xb0
+[  135.293613]  __do_softirq+0x1c2/0x651
+...
+[  135.293613] RIP: 0010:default_idle+0xb/0x10
+[  135.293613] RSP: 0018:ffff888006317e68 EFLAGS: 00000246
+[  135.293613] RAX: ffffffff82ad8d10 RBX: ffff888006301cc0 RCX: ffffffff82ac90e1
+[  135.293613] RDX: ffffed100d9ff1b4 RSI: ffffffff831ad140 RDI: ffffffff82ad8f20
+[  135.293613] RBP: 0000000000000003 R08: 0000000000000000 R09: ffff88806cff8d9b
+[  135.293613] R10: ffffed100d9ff1b3 R11: 0000000000000001 R12: ffffffff84593410
+[  135.293613] R13: 0000000000000000 R14: 0000000000000000 R15: 1ffff11000c62fd2
+...
+[  135.389205] usb 1-1: == mwifiex dump information to /sys/class/devcoredump end
+
+This patch uses delayed work to replace timer and moves the operations
+that may sleep into a delayed work in order to mitigate bugs, it was
+tested on Marvell 88W8801 chip whose port is usb and the firmware is
+usb8801_uapsta.bin. The following is the result after using delayed
+work to replace timer.
+
+[  134.936453] usb 1-1: == mwifiex dump information to /sys/class/devcoredump start
+[  135.043344] usb 1-1: == mwifiex dump information to /sys/class/devcoredump end
+
+As we can see, there is no bug now.
+
+Fixes: f5ecd02a8b20 ("mwifiex: device dump support for usb interface")
+Reviewed-by: Brian Norris <briannorris@chromium.org>
+Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
+Link: https://lore.kernel.org/r/b63b77fc84ed3e8a6bef02378e17c7c71a0bc3be.1654569290.git.duoming@zju.edu.cn
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/marvell/mwifiex/init.c      | 9 +++++----
+ drivers/net/wireless/marvell/mwifiex/main.h      | 3 ++-
+ drivers/net/wireless/marvell/mwifiex/sta_event.c | 6 +++---
+ 3 files changed, 10 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/init.c b/drivers/net/wireless/marvell/mwifiex/init.c
+index f006a3d72b40..e5bb240eb3ed 100644
+--- a/drivers/net/wireless/marvell/mwifiex/init.c
++++ b/drivers/net/wireless/marvell/mwifiex/init.c
+@@ -63,9 +63,10 @@ static void wakeup_timer_fn(struct timer_list *t)
+               adapter->if_ops.card_reset(adapter);
+ }
+-static void fw_dump_timer_fn(struct timer_list *t)
++static void fw_dump_work(struct work_struct *work)
+ {
+-      struct mwifiex_adapter *adapter = from_timer(adapter, t, devdump_timer);
++      struct mwifiex_adapter *adapter =
++              container_of(work, struct mwifiex_adapter, devdump_work.work);
+       mwifiex_upload_device_dump(adapter);
+ }
+@@ -321,7 +322,7 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
+       adapter->active_scan_triggered = false;
+       timer_setup(&adapter->wakeup_timer, wakeup_timer_fn, 0);
+       adapter->devdump_len = 0;
+-      timer_setup(&adapter->devdump_timer, fw_dump_timer_fn, 0);
++      INIT_DELAYED_WORK(&adapter->devdump_work, fw_dump_work);
+ }
+ /*
+@@ -400,7 +401,7 @@ static void
+ mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
+ {
+       del_timer(&adapter->wakeup_timer);
+-      del_timer_sync(&adapter->devdump_timer);
++      cancel_delayed_work_sync(&adapter->devdump_work);
+       mwifiex_cancel_all_pending_cmd(adapter);
+       wake_up_interruptible(&adapter->cmd_wait_q.wait);
+       wake_up_interruptible(&adapter->hs_activate_wait_q);
+diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h
+index f4e3dce10d65..3357cb7a5230 100644
+--- a/drivers/net/wireless/marvell/mwifiex/main.h
++++ b/drivers/net/wireless/marvell/mwifiex/main.h
+@@ -49,6 +49,7 @@
+ #include <linux/pm_runtime.h>
+ #include <linux/slab.h>
+ #include <linux/of_irq.h>
++#include <linux/workqueue.h>
+ #include "decl.h"
+ #include "ioctl.h"
+@@ -1053,7 +1054,7 @@ struct mwifiex_adapter {
+       /* Device dump data/length */
+       void *devdump_data;
+       int devdump_len;
+-      struct timer_list devdump_timer;
++      struct delayed_work devdump_work;
+       bool ignore_btcoex_events;
+ };
+diff --git a/drivers/net/wireless/marvell/mwifiex/sta_event.c b/drivers/net/wireless/marvell/mwifiex/sta_event.c
+index 7d42c5d2dbf6..4d93386494c5 100644
+--- a/drivers/net/wireless/marvell/mwifiex/sta_event.c
++++ b/drivers/net/wireless/marvell/mwifiex/sta_event.c
+@@ -623,8 +623,8 @@ mwifiex_fw_dump_info_event(struct mwifiex_private *priv,
+                * transmission event get lost, in this cornel case,
+                * user would still get partial of the dump.
+                */
+-              mod_timer(&adapter->devdump_timer,
+-                        jiffies + msecs_to_jiffies(MWIFIEX_TIMER_10S));
++              schedule_delayed_work(&adapter->devdump_work,
++                                    msecs_to_jiffies(MWIFIEX_TIMER_10S));
+       }
+       /* Overflow check */
+@@ -643,7 +643,7 @@ mwifiex_fw_dump_info_event(struct mwifiex_private *priv,
+       return;
+ upload_dump:
+-      del_timer_sync(&adapter->devdump_timer);
++      cancel_delayed_work_sync(&adapter->devdump_work);
+       mwifiex_upload_device_dump(adapter);
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/mwifiex-ignore-btcoex-events-from-the-88w8897-firmwa.patch b/queue-5.15/mwifiex-ignore-btcoex-events-from-the-88w8897-firmwa.patch
new file mode 100644 (file)
index 0000000..95e6874
--- /dev/null
@@ -0,0 +1,81 @@
+From faa6559f2515e4cd98898dead43b3f226637b1b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Nov 2021 21:58:27 +0100
+Subject: mwifiex: Ignore BTCOEX events from the 88W8897 firmware
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonas Dreßler <verdre@v0yd.nl>
+
+[ Upstream commit 84d94e16efa268e4f2887d858cd67ee37b870f25 ]
+
+The firmware of the 88W8897 PCIe+USB card sends those events very
+unreliably, sometimes bluetooth together with 2.4ghz-wifi is used and no
+COEX event comes in, and sometimes bluetooth is disabled but the
+coexistance mode doesn't get disabled.
+
+This means we sometimes end up capping the rx/tx window size while
+bluetooth is not enabled anymore, artifically limiting wifi speeds even
+though bluetooth is not being used.
+
+Since we can't fix the firmware, let's just ignore those events on the
+88W8897 device. From some Wireshark capture sessions it seems that the
+Windows driver also doesn't change the rx/tx window sizes when bluetooth
+gets enabled or disabled, so this is fairly consistent with the Windows
+driver.
+
+Signed-off-by: Jonas Dreßler <verdre@v0yd.nl>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/20211103205827.14559-1-verdre@v0yd.nl
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/marvell/mwifiex/main.h      | 2 ++
+ drivers/net/wireless/marvell/mwifiex/pcie.c      | 3 +++
+ drivers/net/wireless/marvell/mwifiex/sta_event.c | 3 +++
+ 3 files changed, 8 insertions(+)
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h
+index 5923c5c14c8d..f4e3dce10d65 100644
+--- a/drivers/net/wireless/marvell/mwifiex/main.h
++++ b/drivers/net/wireless/marvell/mwifiex/main.h
+@@ -1054,6 +1054,8 @@ struct mwifiex_adapter {
+       void *devdump_data;
+       int devdump_len;
+       struct timer_list devdump_timer;
++
++      bool ignore_btcoex_events;
+ };
+ void mwifiex_process_tx_queue(struct mwifiex_adapter *adapter);
+diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
+index c3f5583ea70d..d5fb29400bad 100644
+--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
++++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
+@@ -3152,6 +3152,9 @@ static int mwifiex_init_pcie(struct mwifiex_adapter *adapter)
+       if (ret)
+               goto err_alloc_buffers;
++      if (pdev->device == PCIE_DEVICE_ID_MARVELL_88W8897)
++              adapter->ignore_btcoex_events = true;
++
+       return 0;
+ err_alloc_buffers:
+diff --git a/drivers/net/wireless/marvell/mwifiex/sta_event.c b/drivers/net/wireless/marvell/mwifiex/sta_event.c
+index 2b2e6e0166e1..7d42c5d2dbf6 100644
+--- a/drivers/net/wireless/marvell/mwifiex/sta_event.c
++++ b/drivers/net/wireless/marvell/mwifiex/sta_event.c
+@@ -1062,6 +1062,9 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
+               break;
+       case EVENT_BT_COEX_WLAN_PARA_CHANGE:
+               dev_dbg(adapter->dev, "EVENT: BT coex wlan param update\n");
++              if (adapter->ignore_btcoex_events)
++                      break;
++
+               mwifiex_bt_coex_wlan_param_update_event(priv,
+                                                       adapter->event_skb);
+               break;
+-- 
+2.35.1
+
diff --git a/queue-5.15/net-9p-fix-refcount-leak-in-p9_read_work-error-handl.patch b/queue-5.15/net-9p-fix-refcount-leak-in-p9_read_work-error-handl.patch
new file mode 100644 (file)
index 0000000..af168ef
--- /dev/null
@@ -0,0 +1,37 @@
+From 1d8bb28491ef86f72f2742fd0539df5323e8ac9f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 09:55:11 +0900
+Subject: net: 9p: fix refcount leak in p9_read_work() error handling
+
+From: Hangyu Hua <hbh25y@gmail.com>
+
+[ Upstream commit 4ac7573e1f9333073fa8d303acc941c9b7ab7f61 ]
+
+p9_req_put need to be called when m->rreq->rc.sdata is NULL to avoid
+temporary refcount leak.
+
+Link: https://lkml.kernel.org/r/20220712104438.30800-1-hbh25y@gmail.com
+Fixes: 728356dedeff ("9p: Add refcount to p9_req_t")
+Signed-off-by: Hangyu Hua <hbh25y@gmail.com>
+[Dominique: commit wording adjustments, p9_req_put argument fixes for rebase]
+Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/9p/trans_fd.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
+index c55c8a608bc7..6fe3719c1fc6 100644
+--- a/net/9p/trans_fd.c
++++ b/net/9p/trans_fd.c
+@@ -345,6 +345,7 @@ static void p9_read_work(struct work_struct *work)
+                       p9_debug(P9_DEBUG_ERROR,
+                                "No recv fcall for tag %d (req %p), disconnecting!\n",
+                                m->rc.tag, m->rreq);
++                      p9_req_put(m->client, m->rreq);
+                       m->rreq = NULL;
+                       err = -EIO;
+                       goto error;
+-- 
+2.35.1
+
diff --git a/queue-5.15/net-allow-unbound-socket-for-packets-in-vrf-when-tcp.patch b/queue-5.15/net-allow-unbound-socket-for-packets-in-vrf-when-tcp.patch
new file mode 100644 (file)
index 0000000..ed04c08
--- /dev/null
@@ -0,0 +1,126 @@
+From 09c467dc9d44be12345d464bb054e85f96a1a699 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Jul 2022 19:14:42 +0100
+Subject: net: allow unbound socket for packets in VRF when tcp_l3mdev_accept
+ set
+
+From: Mike Manning <mvrmanning@gmail.com>
+
+[ Upstream commit 944fd1aeacb627fa617f85f8e5a34f7ae8ea4d8e ]
+
+The commit 3c82a21f4320 ("net: allow binding socket in a VRF when
+there's an unbound socket") changed the inet socket lookup to avoid
+packets in a VRF from matching an unbound socket. This is to ensure the
+necessary isolation between the default and other VRFs for routing and
+forwarding. VRF-unaware processes running in the default VRF cannot
+access another VRF and have to be run with 'ip vrf exec <vrf>'. This is
+to be expected with tcp_l3mdev_accept disabled, but could be reallowed
+when this sysctl option is enabled. So instead of directly checking dif
+and sdif in inet[6]_match, here call inet_sk_bound_dev_eq(). This
+allows a match on unbound socket for non-zero sdif i.e. for packets in
+a VRF, if tcp_l3mdev_accept is enabled.
+
+Fixes: 3c82a21f4320 ("net: allow binding socket in a VRF when there's an unbound socket")
+Signed-off-by: Mike Manning <mvrmanning@gmail.com>
+Link: https://lore.kernel.org/netdev/a54c149aed38fded2d3b5fdb1a6c89e36a083b74.camel@lasnet.de/
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/inet6_hashtables.h |  7 +++----
+ include/net/inet_hashtables.h  | 19 +++----------------
+ include/net/inet_sock.h        | 11 +++++++++++
+ 3 files changed, 17 insertions(+), 20 deletions(-)
+
+diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h
+index f259e1ae14ba..56f1286583d3 100644
+--- a/include/net/inet6_hashtables.h
++++ b/include/net/inet6_hashtables.h
+@@ -110,8 +110,6 @@ static inline bool inet6_match(struct net *net, const struct sock *sk,
+                              const __portpair ports,
+                              const int dif, const int sdif)
+ {
+-      int bound_dev_if;
+-
+       if (!net_eq(sock_net(sk), net) ||
+           sk->sk_family != AF_INET6 ||
+           sk->sk_portpair != ports ||
+@@ -119,8 +117,9 @@ static inline bool inet6_match(struct net *net, const struct sock *sk,
+           !ipv6_addr_equal(&sk->sk_v6_rcv_saddr, daddr))
+               return false;
+-      bound_dev_if = READ_ONCE(sk->sk_bound_dev_if);
+-      return bound_dev_if == dif || bound_dev_if == sdif;
++      /* READ_ONCE() paired with WRITE_ONCE() in sock_bindtoindex_locked() */
++      return inet_sk_bound_dev_eq(net, READ_ONCE(sk->sk_bound_dev_if), dif,
++                                  sdif);
+ }
+ #endif /* IS_ENABLED(CONFIG_IPV6) */
+diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
+index 825ad1d06d05..53c22b64e972 100644
+--- a/include/net/inet_hashtables.h
++++ b/include/net/inet_hashtables.h
+@@ -203,17 +203,6 @@ static inline void inet_ehash_locks_free(struct inet_hashinfo *hashinfo)
+       hashinfo->ehash_locks = NULL;
+ }
+-static inline bool inet_sk_bound_dev_eq(struct net *net, int bound_dev_if,
+-                                      int dif, int sdif)
+-{
+-#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV)
+-      return inet_bound_dev_eq(!!READ_ONCE(net->ipv4.sysctl_tcp_l3mdev_accept),
+-                               bound_dev_if, dif, sdif);
+-#else
+-      return inet_bound_dev_eq(true, bound_dev_if, dif, sdif);
+-#endif
+-}
+-
+ struct inet_bind_bucket *
+ inet_bind_bucket_create(struct kmem_cache *cachep, struct net *net,
+                       struct inet_bind_hashbucket *head,
+@@ -311,16 +300,14 @@ static inline bool INET_MATCH(struct net *net, const struct sock *sk,
+                             const __addrpair cookie, const __portpair ports,
+                             int dif, int sdif)
+ {
+-      int bound_dev_if;
+-
+       if (!net_eq(sock_net(sk), net) ||
+           sk->sk_portpair != ports ||
+           sk->sk_addrpair != cookie)
+               return false;
+-      /* Paired with WRITE_ONCE() from sock_bindtoindex_locked() */
+-      bound_dev_if = READ_ONCE(sk->sk_bound_dev_if);
+-      return bound_dev_if == dif || bound_dev_if == sdif;
++      /* READ_ONCE() paired with WRITE_ONCE() in sock_bindtoindex_locked() */
++      return inet_sk_bound_dev_eq(net, READ_ONCE(sk->sk_bound_dev_if), dif,
++                                  sdif);
+ }
+ /* Sockets in TCP_CLOSE state are _always_ taken out of the hash, so we need
+diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
+index c307a547d2cb..2c2b41ea7f81 100644
+--- a/include/net/inet_sock.h
++++ b/include/net/inet_sock.h
+@@ -149,6 +149,17 @@ static inline bool inet_bound_dev_eq(bool l3mdev_accept, int bound_dev_if,
+       return bound_dev_if == dif || bound_dev_if == sdif;
+ }
++static inline bool inet_sk_bound_dev_eq(struct net *net, int bound_dev_if,
++                                      int dif, int sdif)
++{
++#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV)
++      return inet_bound_dev_eq(!!READ_ONCE(net->ipv4.sysctl_tcp_l3mdev_accept),
++                               bound_dev_if, dif, sdif);
++#else
++      return inet_bound_dev_eq(true, bound_dev_if, dif, sdif);
++#endif
++}
++
+ struct inet_cork {
+       unsigned int            flags;
+       __be32                  addr;
+-- 
+2.35.1
+
diff --git a/queue-5.15/net-fix-sk_wmem_schedule-and-sk_rmem_schedule-errors.patch b/queue-5.15/net-fix-sk_wmem_schedule-and-sk_rmem_schedule-errors.patch
new file mode 100644 (file)
index 0000000..da47dc9
--- /dev/null
@@ -0,0 +1,58 @@
+From f1fb6cde54bb03d22e9788c73a3b3220d95c975f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jun 2022 23:34:10 -0700
+Subject: net: fix sk_wmem_schedule() and sk_rmem_schedule() errors
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 7c80b038d23e1f4c7fcc311f43f83b8c60e7fb80 ]
+
+If sk->sk_forward_alloc is 150000, and we need to schedule 150001 bytes,
+we want to allocate 1 byte more (rounded up to one page),
+instead of 150001 :/
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Shakeel Butt <shakeelb@google.com>
+Acked-by: Soheil Hassas Yeganeh <soheil@google.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/sock.h | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/include/net/sock.h b/include/net/sock.h
+index 819c53965ef3..e0a88bb0a58c 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -1507,19 +1507,23 @@ static inline bool sk_has_account(struct sock *sk)
+ static inline bool sk_wmem_schedule(struct sock *sk, int size)
+ {
++      int delta;
++
+       if (!sk_has_account(sk))
+               return true;
+-      return size <= sk->sk_forward_alloc ||
+-              __sk_mem_schedule(sk, size, SK_MEM_SEND);
++      delta = size - sk->sk_forward_alloc;
++      return delta <= 0 || __sk_mem_schedule(sk, delta, SK_MEM_SEND);
+ }
+ static inline bool
+ sk_rmem_schedule(struct sock *sk, struct sk_buff *skb, int size)
+ {
++      int delta;
++
+       if (!sk_has_account(sk))
+               return true;
+-      return size <= sk->sk_forward_alloc ||
+-              __sk_mem_schedule(sk, size, SK_MEM_RECV) ||
++      delta = size - sk->sk_forward_alloc;
++      return delta <= 0 || __sk_mem_schedule(sk, delta, SK_MEM_RECV) ||
+               skb_pfmemalloc(skb);
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/net-hinic-avoid-kernel-hung-in-hinic_get_stats64.patch b/queue-5.15/net-hinic-avoid-kernel-hung-in-hinic_get_stats64.patch
new file mode 100644 (file)
index 0000000..c17761b
--- /dev/null
@@ -0,0 +1,98 @@
+From 3d9980e85a02fc5bace6bf59a0122be14e80fe22 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Jul 2022 19:22:23 +0800
+Subject: net: hinic: avoid kernel hung in hinic_get_stats64()
+
+From: Qiao Ma <mqaio@linux.alibaba.com>
+
+[ Upstream commit 98f9fcdee35add80505b6c73f72de5f750d5c03c ]
+
+When using hinic device as a bond slave device, and reading device stats
+of master bond device, the kernel may hung.
+
+The kernel panic calltrace as follows:
+Kernel panic - not syncing: softlockup: hung tasks
+Call trace:
+  native_queued_spin_lock_slowpath+0x1ec/0x31c
+  dev_get_stats+0x60/0xcc
+  dev_seq_printf_stats+0x40/0x120
+  dev_seq_show+0x1c/0x40
+  seq_read_iter+0x3c8/0x4dc
+  seq_read+0xe0/0x130
+  proc_reg_read+0xa8/0xe0
+  vfs_read+0xb0/0x1d4
+  ksys_read+0x70/0xfc
+  __arm64_sys_read+0x20/0x30
+  el0_svc_common+0x88/0x234
+  do_el0_svc+0x2c/0x90
+  el0_svc+0x1c/0x30
+  el0_sync_handler+0xa8/0xb0
+  el0_sync+0x148/0x180
+
+And the calltrace of task that actually caused kernel hungs as follows:
+  __switch_to+124
+  __schedule+548
+  schedule+72
+  schedule_timeout+348
+  __down_common+188
+  __down+24
+  down+104
+  hinic_get_stats64+44 [hinic]
+  dev_get_stats+92
+  bond_get_stats+172 [bonding]
+  dev_get_stats+92
+  dev_seq_printf_stats+60
+  dev_seq_show+24
+  seq_read_iter+964
+  seq_read+220
+  proc_reg_read+164
+  vfs_read+172
+  ksys_read+108
+  __arm64_sys_read+28
+  el0_svc_common+132
+  do_el0_svc+40
+  el0_svc+24
+  el0_sync_handler+164
+  el0_sync+324
+
+When getting device stats from bond, kernel will call bond_get_stats().
+It first holds the spinlock bond->stats_lock, and then call
+hinic_get_stats64() to collect hinic device's stats.
+However, hinic_get_stats64() calls `down(&nic_dev->mgmt_lock)` to
+protect its critical section, which may schedule current task out.
+And if system is under high pressure, the task cannot be woken up
+immediately, which eventually triggers kernel hung panic.
+
+Since previous patch has replaced hinic_dev.tx_stats/rx_stats with local
+variable in hinic_get_stats64(), there is nothing need to be protected
+by lock, so just removing down()/up() is ok.
+
+Fixes: edd384f682cc ("net-next/hinic: Add ethtool and stats")
+Signed-off-by: Qiao Ma <mqaio@linux.alibaba.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/huawei/hinic/hinic_main.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_main.c b/drivers/net/ethernet/huawei/hinic/hinic_main.c
+index 909758367e7c..8c6ec7c25809 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_main.c
++++ b/drivers/net/ethernet/huawei/hinic/hinic_main.c
+@@ -842,13 +842,9 @@ static void hinic_get_stats64(struct net_device *netdev,
+       struct hinic_rxq_stats nic_rx_stats = {};
+       struct hinic_txq_stats nic_tx_stats = {};
+-      down(&nic_dev->mgmt_lock);
+-
+       if (nic_dev->flags & HINIC_INTF_UP)
+               gather_nic_stats(nic_dev, &nic_rx_stats, &nic_tx_stats);
+-      up(&nic_dev->mgmt_lock);
+-
+       stats->rx_bytes   = nic_rx_stats.bytes;
+       stats->rx_packets = nic_rx_stats.pkts;
+       stats->rx_errors  = nic_rx_stats.errors;
+-- 
+2.35.1
+
diff --git a/queue-5.15/net-hinic-fix-bug-that-ethtool-get-wrong-stats.patch b/queue-5.15/net-hinic-fix-bug-that-ethtool-get-wrong-stats.patch
new file mode 100644 (file)
index 0000000..dabb20c
--- /dev/null
@@ -0,0 +1,271 @@
+From 5663273a8c4b4a4ab23487566e2dd935ed032532 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Jul 2022 19:22:22 +0800
+Subject: net: hinic: fix bug that ethtool get wrong stats
+
+From: Qiao Ma <mqaio@linux.alibaba.com>
+
+[ Upstream commit 67dffd3db98570af8ff54c934f7d14664c0d182a ]
+
+Function hinic_get_stats64() will do two operations:
+1. reads stats from every hinic_rxq/txq and accumulates them
+2. calls hinic_rxq/txq_clean_stats() to clean every rxq/txq's stats
+
+For hinic_get_stats64(), it could get right data, because it sums all
+data to nic_dev->rx_stats/tx_stats.
+But it is wrong for get_drv_queue_stats(), this function will read
+hinic_rxq's stats, which have been cleared to zero by hinic_get_stats64().
+
+I have observed hinic's cleanup operation by using such command:
+> watch -n 1 "cat ethtool -S eth4 | tail -40"
+
+Result before:
+     ...
+     rxq7_pkts: 1
+     rxq7_bytes: 90
+     rxq7_errors: 0
+     rxq7_csum_errors: 0
+     rxq7_other_errors: 0
+     ...
+     rxq9_pkts: 11
+     rxq9_bytes: 726
+     rxq9_errors: 0
+     rxq9_csum_errors: 0
+     rxq9_other_errors: 0
+     ...
+     rxq11_pkts: 0
+     rxq11_bytes: 0
+     rxq11_errors: 0
+     rxq11_csum_errors: 0
+     rxq11_other_errors: 0
+
+Result after a few seconds:
+     ...
+     rxq7_pkts: 0
+     rxq7_bytes: 0
+     rxq7_errors: 0
+     rxq7_csum_errors: 0
+     rxq7_other_errors: 0
+     ...
+     rxq9_pkts: 2
+     rxq9_bytes: 132
+     rxq9_errors: 0
+     rxq9_csum_errors: 0
+     rxq9_other_errors: 0
+     ...
+     rxq11_pkts: 1
+     rxq11_bytes: 170
+     rxq11_errors: 0
+     rxq11_csum_errors: 0
+     rxq11_other_errors: 0
+
+To solve this problem, we just keep every queue's total stats in their own
+queue (aka hinic_{rxq|txq}), and simply sum all per-queue stats every time
+calling hinic_get_stats64().
+With that solution, there is no need to clean per-queue stats now,
+and there is no need to maintain global hinic_dev.{tx|rx}_stats, too.
+
+Fixes: edd384f682cc ("net-next/hinic: Add ethtool and stats")
+Signed-off-by: Qiao Ma <mqaio@linux.alibaba.com>
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/huawei/hinic/hinic_dev.h |  3 -
+ .../net/ethernet/huawei/hinic/hinic_main.c    | 57 ++++++-------------
+ drivers/net/ethernet/huawei/hinic/hinic_rx.c  |  2 -
+ drivers/net/ethernet/huawei/hinic/hinic_tx.c  |  2 -
+ 4 files changed, 16 insertions(+), 48 deletions(-)
+
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_dev.h b/drivers/net/ethernet/huawei/hinic/hinic_dev.h
+index fb3e89141a0d..a4fbf44f944c 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_dev.h
++++ b/drivers/net/ethernet/huawei/hinic/hinic_dev.h
+@@ -95,9 +95,6 @@ struct hinic_dev {
+       u16                             sq_depth;
+       u16                             rq_depth;
+-      struct hinic_txq_stats          tx_stats;
+-      struct hinic_rxq_stats          rx_stats;
+-
+       u8                              rss_tmpl_idx;
+       u8                              rss_hash_engine;
+       u16                             num_rss;
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_main.c b/drivers/net/ethernet/huawei/hinic/hinic_main.c
+index bece6a12368d..909758367e7c 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_main.c
++++ b/drivers/net/ethernet/huawei/hinic/hinic_main.c
+@@ -80,56 +80,44 @@ static int set_features(struct hinic_dev *nic_dev,
+                       netdev_features_t pre_features,
+                       netdev_features_t features, bool force_change);
+-static void update_rx_stats(struct hinic_dev *nic_dev, struct hinic_rxq *rxq)
++static void gather_rx_stats(struct hinic_rxq_stats *nic_rx_stats, struct hinic_rxq *rxq)
+ {
+-      struct hinic_rxq_stats *nic_rx_stats = &nic_dev->rx_stats;
+       struct hinic_rxq_stats rx_stats;
+-      u64_stats_init(&rx_stats.syncp);
+-
+       hinic_rxq_get_stats(rxq, &rx_stats);
+-      u64_stats_update_begin(&nic_rx_stats->syncp);
+       nic_rx_stats->bytes += rx_stats.bytes;
+       nic_rx_stats->pkts  += rx_stats.pkts;
+       nic_rx_stats->errors += rx_stats.errors;
+       nic_rx_stats->csum_errors += rx_stats.csum_errors;
+       nic_rx_stats->other_errors += rx_stats.other_errors;
+-      u64_stats_update_end(&nic_rx_stats->syncp);
+-
+-      hinic_rxq_clean_stats(rxq);
+ }
+-static void update_tx_stats(struct hinic_dev *nic_dev, struct hinic_txq *txq)
++static void gather_tx_stats(struct hinic_txq_stats *nic_tx_stats, struct hinic_txq *txq)
+ {
+-      struct hinic_txq_stats *nic_tx_stats = &nic_dev->tx_stats;
+       struct hinic_txq_stats tx_stats;
+-      u64_stats_init(&tx_stats.syncp);
+-
+       hinic_txq_get_stats(txq, &tx_stats);
+-      u64_stats_update_begin(&nic_tx_stats->syncp);
+       nic_tx_stats->bytes += tx_stats.bytes;
+       nic_tx_stats->pkts += tx_stats.pkts;
+       nic_tx_stats->tx_busy += tx_stats.tx_busy;
+       nic_tx_stats->tx_wake += tx_stats.tx_wake;
+       nic_tx_stats->tx_dropped += tx_stats.tx_dropped;
+       nic_tx_stats->big_frags_pkts += tx_stats.big_frags_pkts;
+-      u64_stats_update_end(&nic_tx_stats->syncp);
+-
+-      hinic_txq_clean_stats(txq);
+ }
+-static void update_nic_stats(struct hinic_dev *nic_dev)
++static void gather_nic_stats(struct hinic_dev *nic_dev,
++                           struct hinic_rxq_stats *nic_rx_stats,
++                           struct hinic_txq_stats *nic_tx_stats)
+ {
+       int i, num_qps = hinic_hwdev_num_qps(nic_dev->hwdev);
+       for (i = 0; i < num_qps; i++)
+-              update_rx_stats(nic_dev, &nic_dev->rxqs[i]);
++              gather_rx_stats(nic_rx_stats, &nic_dev->rxqs[i]);
+       for (i = 0; i < num_qps; i++)
+-              update_tx_stats(nic_dev, &nic_dev->txqs[i]);
++              gather_tx_stats(nic_tx_stats, &nic_dev->txqs[i]);
+ }
+ /**
+@@ -558,8 +546,6 @@ int hinic_close(struct net_device *netdev)
+       netif_carrier_off(netdev);
+       netif_tx_disable(netdev);
+-      update_nic_stats(nic_dev);
+-
+       up(&nic_dev->mgmt_lock);
+       if (!HINIC_IS_VF(nic_dev->hwdev->hwif))
+@@ -853,26 +839,23 @@ static void hinic_get_stats64(struct net_device *netdev,
+                             struct rtnl_link_stats64 *stats)
+ {
+       struct hinic_dev *nic_dev = netdev_priv(netdev);
+-      struct hinic_rxq_stats *nic_rx_stats;
+-      struct hinic_txq_stats *nic_tx_stats;
+-
+-      nic_rx_stats = &nic_dev->rx_stats;
+-      nic_tx_stats = &nic_dev->tx_stats;
++      struct hinic_rxq_stats nic_rx_stats = {};
++      struct hinic_txq_stats nic_tx_stats = {};
+       down(&nic_dev->mgmt_lock);
+       if (nic_dev->flags & HINIC_INTF_UP)
+-              update_nic_stats(nic_dev);
++              gather_nic_stats(nic_dev, &nic_rx_stats, &nic_tx_stats);
+       up(&nic_dev->mgmt_lock);
+-      stats->rx_bytes   = nic_rx_stats->bytes;
+-      stats->rx_packets = nic_rx_stats->pkts;
+-      stats->rx_errors  = nic_rx_stats->errors;
++      stats->rx_bytes   = nic_rx_stats.bytes;
++      stats->rx_packets = nic_rx_stats.pkts;
++      stats->rx_errors  = nic_rx_stats.errors;
+-      stats->tx_bytes   = nic_tx_stats->bytes;
+-      stats->tx_packets = nic_tx_stats->pkts;
+-      stats->tx_errors  = nic_tx_stats->tx_dropped;
++      stats->tx_bytes   = nic_tx_stats.bytes;
++      stats->tx_packets = nic_tx_stats.pkts;
++      stats->tx_errors  = nic_tx_stats.tx_dropped;
+ }
+ static int hinic_set_features(struct net_device *netdev,
+@@ -1171,8 +1154,6 @@ static void hinic_free_intr_coalesce(struct hinic_dev *nic_dev)
+ static int nic_dev_init(struct pci_dev *pdev)
+ {
+       struct hinic_rx_mode_work *rx_mode_work;
+-      struct hinic_txq_stats *tx_stats;
+-      struct hinic_rxq_stats *rx_stats;
+       struct hinic_dev *nic_dev;
+       struct net_device *netdev;
+       struct hinic_hwdev *hwdev;
+@@ -1233,12 +1214,6 @@ static int nic_dev_init(struct pci_dev *pdev)
+       sema_init(&nic_dev->mgmt_lock, 1);
+-      tx_stats = &nic_dev->tx_stats;
+-      rx_stats = &nic_dev->rx_stats;
+-
+-      u64_stats_init(&tx_stats->syncp);
+-      u64_stats_init(&rx_stats->syncp);
+-
+       nic_dev->vlan_bitmap = devm_bitmap_zalloc(&pdev->dev, VLAN_N_VID,
+                                                 GFP_KERNEL);
+       if (!nic_dev->vlan_bitmap) {
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_rx.c b/drivers/net/ethernet/huawei/hinic/hinic_rx.c
+index fed3b6bc0d76..a102d486c435 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_rx.c
++++ b/drivers/net/ethernet/huawei/hinic/hinic_rx.c
+@@ -73,7 +73,6 @@ void hinic_rxq_get_stats(struct hinic_rxq *rxq, struct hinic_rxq_stats *stats)
+       struct hinic_rxq_stats *rxq_stats = &rxq->rxq_stats;
+       unsigned int start;
+-      u64_stats_update_begin(&stats->syncp);
+       do {
+               start = u64_stats_fetch_begin(&rxq_stats->syncp);
+               stats->pkts = rxq_stats->pkts;
+@@ -83,7 +82,6 @@ void hinic_rxq_get_stats(struct hinic_rxq *rxq, struct hinic_rxq_stats *stats)
+               stats->csum_errors = rxq_stats->csum_errors;
+               stats->other_errors = rxq_stats->other_errors;
+       } while (u64_stats_fetch_retry(&rxq_stats->syncp, start));
+-      u64_stats_update_end(&stats->syncp);
+ }
+ /**
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_tx.c b/drivers/net/ethernet/huawei/hinic/hinic_tx.c
+index a984a7a6dd2e..d1ea358a1fc0 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_tx.c
++++ b/drivers/net/ethernet/huawei/hinic/hinic_tx.c
+@@ -97,7 +97,6 @@ void hinic_txq_get_stats(struct hinic_txq *txq, struct hinic_txq_stats *stats)
+       struct hinic_txq_stats *txq_stats = &txq->txq_stats;
+       unsigned int start;
+-      u64_stats_update_begin(&stats->syncp);
+       do {
+               start = u64_stats_fetch_begin(&txq_stats->syncp);
+               stats->pkts    = txq_stats->pkts;
+@@ -107,7 +106,6 @@ void hinic_txq_get_stats(struct hinic_txq *txq, struct hinic_txq_stats *stats)
+               stats->tx_dropped = txq_stats->tx_dropped;
+               stats->big_frags_pkts = txq_stats->big_frags_pkts;
+       } while (u64_stats_fetch_retry(&txq_stats->syncp, start));
+-      u64_stats_update_end(&stats->syncp);
+ }
+ /**
+-- 
+2.35.1
+
diff --git a/queue-5.15/net-ionic-fix-error-check-for-vlan-flags-in-ionic_se.patch b/queue-5.15/net-ionic-fix-error-check-for-vlan-flags-in-ionic_se.patch
new file mode 100644 (file)
index 0000000..aa210b3
--- /dev/null
@@ -0,0 +1,42 @@
+From 37588ddc271479799289f7fb292d0febefa5f560 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Jul 2022 18:17:55 +0800
+Subject: net: ionic: fix error check for vlan flags in
+ ionic_set_nic_features()
+
+From: Jian Shen <shenjian15@huawei.com>
+
+[ Upstream commit a86e86db5e6d72c82724a63ca1c5293409a21518 ]
+
+The prototype of input features of ionic_set_nic_features() is
+netdev_features_t, but the vlan_flags is using the private
+definition of ionic drivers. It should use the variable
+ctx.cmd.lif_setattr.features, rather than features to check
+the vlan flags. So fixes it.
+
+Fixes: beead698b173 ("ionic: Add the basic NDO callbacks for netdev support")
+Signed-off-by: Jian Shen <shenjian15@huawei.com>
+Signed-off-by: Guangbin Huang <huangguangbin2@huawei.com>
+Acked-by: Shannon Nelson <snelson@pensando.io>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/pensando/ionic/ionic_lif.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+index 6ac507ddf09a..781313dbd04f 100644
+--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
++++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+@@ -1565,7 +1565,7 @@ static int ionic_set_nic_features(struct ionic_lif *lif,
+       if ((old_hw_features ^ lif->hw_features) & IONIC_ETH_HW_RX_HASH)
+               ionic_lif_rss_config(lif, lif->rss_types, NULL, NULL);
+-      if ((vlan_flags & features) &&
++      if ((vlan_flags & le64_to_cpu(ctx.cmd.lif_setattr.features)) &&
+           !(vlan_flags & le64_to_cpu(ctx.comp.lif_setattr.features)))
+               dev_info_once(lif->ionic->dev, "NIC is not supporting vlan offload, likely in SmartNIC mode\n");
+-- 
+2.35.1
+
diff --git a/queue-5.15/net-mlx5-adjust-log_max_qp-to-be-18-at-most.patch b/queue-5.15/net-mlx5-adjust-log_max_qp-to-be-18-at-most.patch
new file mode 100644 (file)
index 0000000..97cc69a
--- /dev/null
@@ -0,0 +1,41 @@
+From 59d962517a0a8a59251406cb0ff7d4d000428ced Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Jul 2022 11:28:21 +0300
+Subject: net/mlx5: Adjust log_max_qp to be 18 at most
+
+From: Maher Sanalla <msanalla@nvidia.com>
+
+[ Upstream commit a6e9085d791f8306084fd5bc44dd3fdd4e1ac27b ]
+
+The cited commit limited log_max_qp to be 17 due to FW capabilities.
+Recently, it turned out that there are old FW versions that supported
+more than 17, so the cited commit caused a degradation.
+
+Thus, set the maximum log_max_qp back to 18 as it was before the
+cited commit.
+
+Fixes: 7f839965b2d7 ("net/mlx5: Update log_max_qp value to be 17 at most")
+Signed-off-by: Maher Sanalla <msanalla@nvidia.com>
+Reviewed-by: Maor Gottlieb <maorg@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+index 4ed740994279..5a6606c843ed 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+@@ -516,7 +516,7 @@ static int handle_hca_cap(struct mlx5_core_dev *dev, void *set_ctx)
+       /* Check log_max_qp from HCA caps to set in current profile */
+       if (prof->log_max_qp == LOG_MAX_SUPPORTED_QPS) {
+-              prof->log_max_qp = min_t(u8, 17, MLX5_CAP_GEN_MAX(dev, log_max_qp));
++              prof->log_max_qp = min_t(u8, 18, MLX5_CAP_GEN_MAX(dev, log_max_qp));
+       } else if (MLX5_CAP_GEN_MAX(dev, log_max_qp) < prof->log_max_qp) {
+               mlx5_core_warn(dev, "log_max_qp value in current profile is %d, changing it to HCA capability limit (%d)\n",
+                              prof->log_max_qp,
+-- 
+2.35.1
+
diff --git a/queue-5.15/net-mlx5e-fix-the-value-of-mlx5e_max_rq_num_mtts.patch b/queue-5.15/net-mlx5e-fix-the-value-of-mlx5e_max_rq_num_mtts.patch
new file mode 100644 (file)
index 0000000..ccda12a
--- /dev/null
@@ -0,0 +1,40 @@
+From d0bd2605b4bdc338a34cdf66d1feed9e188f963a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 May 2022 16:48:47 +0300
+Subject: net/mlx5e: Fix the value of MLX5E_MAX_RQ_NUM_MTTS
+
+From: Maxim Mikityanskiy <maximmi@nvidia.com>
+
+[ Upstream commit 562696c3c62c7c23dd896e9447252ce9268cb812 ]
+
+MLX5E_MAX_RQ_NUM_MTTS should be the maximum value, so that
+MLX5_MTT_OCTW(MLX5E_MAX_RQ_NUM_MTTS) fits into u16. The current value of
+1 << 17 results in MLX5_MTT_OCTW(1 << 17) = 1 << 16, which doesn't fit
+into u16. This commit replaces it with the maximum value that still
+fits u16.
+
+Fixes: 73281b78a37a ("net/mlx5e: Derive Striding RQ size from MTU")
+Signed-off-by: Maxim Mikityanskiy <maximmi@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
+index 7204bc86e474..c22a38e5337b 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
+@@ -103,7 +103,7 @@ struct page_pool;
+ #define MLX5E_REQUIRED_WQE_MTTS               (MLX5_ALIGN_MTTS(MLX5_MPWRQ_PAGES_PER_WQE + 1))
+ #define MLX5E_REQUIRED_MTTS(wqes)     (wqes * MLX5E_REQUIRED_WQE_MTTS)
+ #define MLX5E_MAX_RQ_NUM_MTTS \
+-      ((1 << 16) * 2) /* So that MLX5_MTT_OCTW(num_mtts) fits into u16 */
++      (ALIGN_DOWN(U16_MAX, 4) * 2) /* So that MLX5_MTT_OCTW(num_mtts) fits into u16 */
+ #define MLX5E_ORDER2_MAX_PACKET_MTU (order_base_2(10 * 1024))
+ #define MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE_MPW  \
+               (ilog2(MLX5E_MAX_RQ_NUM_MTTS / MLX5E_REQUIRED_WQE_MTTS))
+-- 
+2.35.1
+
diff --git a/queue-5.15/net-mlx5e-remove-warn_on-when-trying-to-offload-an-u.patch b/queue-5.15/net-mlx5e-remove-warn_on-when-trying-to-offload-an-u.patch
new file mode 100644 (file)
index 0000000..682eab6
--- /dev/null
@@ -0,0 +1,43 @@
+From 00e1eb48638cbb5a5a752d73b6250c5e65c82fd0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 13:57:03 +0300
+Subject: net/mlx5e: Remove WARN_ON when trying to offload an unsupported TLS
+ cipher/version
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit 115d9f95ea7ab780ef315dc356bebba2e07cb731 ]
+
+The driver reports whether TX/RX TLS device offloads are supported, but
+not which ciphers/versions, these should be handled by returning
+-EOPNOTSUPP when .tls_dev_add() is called.
+
+Remove the WARN_ON kernel trace when the driver gets a request to
+offload a cipher/version that is not supported as it is expected.
+
+Fixes: d2ead1f360e8 ("net/mlx5e: Add kTLS TX HW offload support")
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Maxim Mikityanskiy <maximmi@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c
+index d93aadbf10da..90ea78239d40 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c
+@@ -16,7 +16,7 @@ static int mlx5e_ktls_add(struct net_device *netdev, struct sock *sk,
+       struct mlx5_core_dev *mdev = priv->mdev;
+       int err;
+-      if (WARN_ON(!mlx5e_ktls_type_check(mdev, crypto_info)))
++      if (!mlx5e_ktls_type_check(mdev, crypto_info))
+               return -EOPNOTSUPP;
+       if (direction == TLS_OFFLOAD_CTX_DIR_TX)
+-- 
+2.35.1
+
diff --git a/queue-5.15/net-rose-fix-netdev-reference-changes.patch b/queue-5.15/net-rose-fix-netdev-reference-changes.patch
new file mode 100644 (file)
index 0000000..e42af5f
--- /dev/null
@@ -0,0 +1,110 @@
+From b6c32b5da7bf873fbe2457726776868ca9d46cab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Jul 2022 09:12:32 +0000
+Subject: net: rose: fix netdev reference changes
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 931027820e4dafabc78aff82af59f8c1c4bd3128 ]
+
+Bernard reported that trying to unload rose module would lead
+to infamous messages:
+
+unregistered_netdevice: waiting for rose0 to become free. Usage count = xx
+
+This patch solves the issue, by making sure each socket referring to
+a netdevice holds a reference count on it, and properly releases it
+in rose_release().
+
+rose_dev_first() is also fixed to take a device reference
+before leaving the rcu_read_locked section.
+
+Following patch will add ref_tracker annotations to ease
+future bug hunting.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: Bernard Pidoux <f6bvp@free.fr>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Tested-by: Bernard Pidoux <f6bvp@free.fr>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rose/af_rose.c    | 11 +++++++++--
+ net/rose/rose_route.c |  2 ++
+ 2 files changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
+index cf7d974e0f61..29a208ed8fb8 100644
+--- a/net/rose/af_rose.c
++++ b/net/rose/af_rose.c
+@@ -191,6 +191,7 @@ static void rose_kill_by_device(struct net_device *dev)
+                       rose_disconnect(s, ENETUNREACH, ROSE_OUT_OF_ORDER, 0);
+                       if (rose->neighbour)
+                               rose->neighbour->use--;
++                      dev_put(rose->device);
+                       rose->device = NULL;
+               }
+       }
+@@ -591,6 +592,8 @@ static struct sock *rose_make_new(struct sock *osk)
+       rose->idle      = orose->idle;
+       rose->defer     = orose->defer;
+       rose->device    = orose->device;
++      if (rose->device)
++              dev_hold(rose->device);
+       rose->qbitincl  = orose->qbitincl;
+       return sk;
+@@ -644,6 +647,7 @@ static int rose_release(struct socket *sock)
+               break;
+       }
++      dev_put(rose->device);
+       sock->sk = NULL;
+       release_sock(sk);
+       sock_put(sk);
+@@ -720,7 +724,6 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
+       struct rose_sock *rose = rose_sk(sk);
+       struct sockaddr_rose *addr = (struct sockaddr_rose *)uaddr;
+       unsigned char cause, diagnostic;
+-      struct net_device *dev;
+       ax25_uid_assoc *user;
+       int n, err = 0;
+@@ -777,9 +780,12 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
+       }
+       if (sock_flag(sk, SOCK_ZAPPED)) {       /* Must bind first - autobinding in this may or may not work */
++              struct net_device *dev;
++
+               sock_reset_flag(sk, SOCK_ZAPPED);
+-              if ((dev = rose_dev_first()) == NULL) {
++              dev = rose_dev_first();
++              if (!dev) {
+                       err = -ENETUNREACH;
+                       goto out_release;
+               }
+@@ -787,6 +793,7 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
+               user = ax25_findbyuid(current_euid());
+               if (!user) {
+                       err = -EINVAL;
++                      dev_put(dev);
+                       goto out_release;
+               }
+diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
+index 764a726debb1..66aa05db5390 100644
+--- a/net/rose/rose_route.c
++++ b/net/rose/rose_route.c
+@@ -615,6 +615,8 @@ struct net_device *rose_dev_first(void)
+                       if (first == NULL || strncmp(dev->name, first->name, 3) < 0)
+                               first = dev;
+       }
++      if (first)
++              dev_hold(first);
+       rcu_read_unlock();
+       return first;
+-- 
+2.35.1
+
diff --git a/queue-5.15/net-usb-make-usb_rtl8153_ecm-non-user-configurable.patch b/queue-5.15/net-usb-make-usb_rtl8153_ecm-non-user-configurable.patch
new file mode 100644 (file)
index 0000000..0697018
--- /dev/null
@@ -0,0 +1,103 @@
+From 401a2bc7302fbb6456d094f86a4322ca842634c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 30 Jul 2022 16:01:13 -0700
+Subject: net: usb: make USB_RTL8153_ECM non user configurable
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Maciej Żenczykowski <maze@google.com>
+
+[ Upstream commit f56530dcdb0684406661ac9f1accf48319d07600 ]
+
+This refixes:
+
+    commit 7da17624e7948d5d9660b910f8079d26d26ce453
+    nt: usb: USB_RTL8153_ECM should not default to y
+
+    In general, device drivers should not be enabled by default.
+
+which basically broke the commit it claimed to fix, ie:
+
+    commit 657bc1d10bfc23ac06d5d687ce45826c760744f9
+    r8153_ecm: avoid to be prior to r8152 driver
+
+    Avoid r8153_ecm is compiled as built-in, if r8152 driver is compiled
+    as modules. Otherwise, the r8153_ecm would be used, even though the
+    device is supported by r8152 driver.
+
+this commit amounted to:
+
+drivers/net/usb/Kconfig:
+
++config USB_RTL8153_ECM
++       tristate "RTL8153 ECM support"
++       depends on USB_NET_CDCETHER && (USB_RTL8152 || USB_RTL8152=n)
++       default y
++       help
++         This option supports ECM mode for RTL8153 ethernet adapter, when
++         CONFIG_USB_RTL8152 is not set, or the RTL8153 device is not
++         supported by r8152 driver.
+
+drivers/net/usb/Makefile:
+
+-obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o r8153_ecm.o
++obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o
++obj-$(CONFIG_USB_RTL8153_ECM)  += r8153_ecm.o
+
+And as can be seen it pulls a piece of the cdc_ether driver out into
+a separate config option to be able to make this piece modular in case
+cdc_ether is builtin, while r8152 is modular.
+
+While in general, device drivers should indeed not be enabled by default:
+this isn't a device driver per say, but rather this is support code for
+the CDCETHER (ECM) driver, and should thus be enabled if it is enabled.
+
+See also email thread at:
+  https://www.spinics.net/lists/netdev/msg767649.html
+
+In:
+  https://www.spinics.net/lists/netdev/msg768284.html
+
+Jakub wrote:
+  And when we say "removed" we can just hide it from what's prompted
+  to the user (whatever such internal options are called)? I believe
+  this way we don't bring back Marek's complaint.
+
+Side note: these incorrect defaults will result in Android 13
+on 5.15 GKI kernels lacking USB_RTL8153_ECM support while having
+USB_NET_CDCETHER (luckily we also have USB_RTL8150 and USB_RTL8152,
+so it's probably only an issue for very new RTL815x hardware with
+no native 5.15 driver).
+
+Fixes: 7da17624e7948d5d ("nt: usb: USB_RTL8153_ECM should not default to y")
+Cc: Geert Uytterhoeven <geert+renesas@glider.be>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: Hayes Wang <hayeswang@realtek.com>
+Cc: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Maciej Żenczykowski <maze@google.com>
+Link: https://lore.kernel.org/r/20220730230113.4138858-1-zenczykowski@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/Kconfig | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
+index b554054a7560..8939e5fbd50a 100644
+--- a/drivers/net/usb/Kconfig
++++ b/drivers/net/usb/Kconfig
+@@ -636,8 +636,9 @@ config USB_NET_AQC111
+         * Aquantia AQtion USB to 5GbE
+ config USB_RTL8153_ECM
+-      tristate "RTL8153 ECM support"
++      tristate
+       depends on USB_NET_CDCETHER && (USB_RTL8152 || USB_RTL8152=n)
++      default y
+       help
+         This option supports ECM mode for RTL8153 ethernet adapter, when
+         CONFIG_USB_RTL8152 is not set, or the RTL8153 device is not
+-- 
+2.35.1
+
diff --git a/queue-5.15/netdevsim-avoid-allocation-warnings-triggered-from-u.patch b/queue-5.15/netdevsim-avoid-allocation-warnings-triggered-from-u.patch
new file mode 100644 (file)
index 0000000..39988ec
--- /dev/null
@@ -0,0 +1,54 @@
+From bc6f53c41363f7173db0eeacdb22c53904226bad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Jul 2022 14:36:05 -0700
+Subject: netdevsim: Avoid allocation warnings triggered from user space
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit d0b80a9edb1a029ff913e81b47540e57ad034329 ]
+
+We need to suppress warnings from sily map sizes. Also switch
+from GFP_USER to GFP_KERNEL_ACCOUNT, I'm pretty sure I misunderstood
+the flags when writing this code.
+
+Fixes: 395cacb5f1a0 ("netdevsim: bpf: support fake map offload")
+Reported-by: syzbot+ad24705d3fd6463b18c6@syzkaller.appspotmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20220726213605.154204-1-kuba@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/netdevsim/bpf.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/netdevsim/bpf.c b/drivers/net/netdevsim/bpf.c
+index a43820212932..50854265864d 100644
+--- a/drivers/net/netdevsim/bpf.c
++++ b/drivers/net/netdevsim/bpf.c
+@@ -351,10 +351,12 @@ nsim_map_alloc_elem(struct bpf_offloaded_map *offmap, unsigned int idx)
+ {
+       struct nsim_bpf_bound_map *nmap = offmap->dev_priv;
+-      nmap->entry[idx].key = kmalloc(offmap->map.key_size, GFP_USER);
++      nmap->entry[idx].key = kmalloc(offmap->map.key_size,
++                                     GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
+       if (!nmap->entry[idx].key)
+               return -ENOMEM;
+-      nmap->entry[idx].value = kmalloc(offmap->map.value_size, GFP_USER);
++      nmap->entry[idx].value = kmalloc(offmap->map.value_size,
++                                       GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
+       if (!nmap->entry[idx].value) {
+               kfree(nmap->entry[idx].key);
+               nmap->entry[idx].key = NULL;
+@@ -496,7 +498,7 @@ nsim_bpf_map_alloc(struct netdevsim *ns, struct bpf_offloaded_map *offmap)
+       if (offmap->map.map_flags)
+               return -EINVAL;
+-      nmap = kzalloc(sizeof(*nmap), GFP_USER);
++      nmap = kzalloc(sizeof(*nmap), GFP_KERNEL_ACCOUNT);
+       if (!nmap)
+               return -ENOMEM;
+-- 
+2.35.1
+
diff --git a/queue-5.15/netdevsim-fib-fix-reference-count-leak-on-route-dele.patch b/queue-5.15/netdevsim-fib-fix-reference-count-leak-on-route-dele.patch
new file mode 100644 (file)
index 0000000..4ba6231
--- /dev/null
@@ -0,0 +1,117 @@
+From b8b4e38ee969efeba002d1fa3c15547c6968482c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Jul 2022 14:45:33 +0300
+Subject: netdevsim: fib: Fix reference count leak on route deletion failure
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 180a6a3ee60a7cb69ed1232388460644f6a21f00 ]
+
+As part of FIB offload simulation, netdevsim stores IPv4 and IPv6 routes
+and holds a reference on FIB info structures that in turn hold a
+reference on the associated nexthop device(s).
+
+In the unlikely case where we are unable to allocate memory to process a
+route deletion request, netdevsim will not release the reference from
+the associated FIB info structure, thereby preventing the associated
+nexthop device(s) from ever being removed [1].
+
+Fix this by scheduling a work item that will flush netdevsim's FIB table
+upon route deletion failure. This will cause netdevsim to release its
+reference from all the FIB info structures in its table.
+
+Reported by Lucas Leong of Trend Micro Zero Day Initiative.
+
+Fixes: 0ae3eb7b4611 ("netdevsim: fib: Perform the route programming in a non-atomic context")
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Amit Cohen <amcohen@nvidia.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/netdevsim/fib.c | 27 ++++++++++++++++++++++++++-
+ 1 file changed, 26 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/netdevsim/fib.c b/drivers/net/netdevsim/fib.c
+index 378ee779061c..14787d17f703 100644
+--- a/drivers/net/netdevsim/fib.c
++++ b/drivers/net/netdevsim/fib.c
+@@ -53,6 +53,7 @@ struct nsim_fib_data {
+       struct rhashtable nexthop_ht;
+       struct devlink *devlink;
+       struct work_struct fib_event_work;
++      struct work_struct fib_flush_work;
+       struct list_head fib_event_queue;
+       spinlock_t fib_event_queue_lock; /* Protects fib event queue list */
+       struct mutex nh_lock; /* Protects NH HT */
+@@ -977,7 +978,7 @@ static int nsim_fib_event_schedule_work(struct nsim_fib_data *data,
+       fib_event = kzalloc(sizeof(*fib_event), GFP_ATOMIC);
+       if (!fib_event)
+-              return NOTIFY_BAD;
++              goto err_fib_event_alloc;
+       fib_event->data = data;
+       fib_event->event = event;
+@@ -1005,6 +1006,9 @@ static int nsim_fib_event_schedule_work(struct nsim_fib_data *data,
+ err_fib_prepare_event:
+       kfree(fib_event);
++err_fib_event_alloc:
++      if (event == FIB_EVENT_ENTRY_DEL)
++              schedule_work(&data->fib_flush_work);
+       return NOTIFY_BAD;
+ }
+@@ -1482,6 +1486,24 @@ static void nsim_fib_event_work(struct work_struct *work)
+       mutex_unlock(&data->fib_lock);
+ }
++static void nsim_fib_flush_work(struct work_struct *work)
++{
++      struct nsim_fib_data *data = container_of(work, struct nsim_fib_data,
++                                                fib_flush_work);
++      struct nsim_fib_rt *fib_rt, *fib_rt_tmp;
++
++      /* Process pending work. */
++      flush_work(&data->fib_event_work);
++
++      mutex_lock(&data->fib_lock);
++      list_for_each_entry_safe(fib_rt, fib_rt_tmp, &data->fib_rt_list, list) {
++              rhashtable_remove_fast(&data->fib_rt_ht, &fib_rt->ht_node,
++                                     nsim_fib_rt_ht_params);
++              nsim_fib_rt_free(fib_rt, data);
++      }
++      mutex_unlock(&data->fib_lock);
++}
++
+ static int
+ nsim_fib_debugfs_init(struct nsim_fib_data *data, struct nsim_dev *nsim_dev)
+ {
+@@ -1540,6 +1562,7 @@ struct nsim_fib_data *nsim_fib_create(struct devlink *devlink,
+               goto err_rhashtable_nexthop_destroy;
+       INIT_WORK(&data->fib_event_work, nsim_fib_event_work);
++      INIT_WORK(&data->fib_flush_work, nsim_fib_flush_work);
+       INIT_LIST_HEAD(&data->fib_event_queue);
+       spin_lock_init(&data->fib_event_queue_lock);
+@@ -1586,6 +1609,7 @@ struct nsim_fib_data *nsim_fib_create(struct devlink *devlink,
+ err_nexthop_nb_unregister:
+       unregister_nexthop_notifier(devlink_net(devlink), &data->nexthop_nb);
+ err_rhashtable_fib_destroy:
++      cancel_work_sync(&data->fib_flush_work);
+       flush_work(&data->fib_event_work);
+       rhashtable_free_and_destroy(&data->fib_rt_ht, nsim_fib_rt_free,
+                                   data);
+@@ -1615,6 +1639,7 @@ void nsim_fib_destroy(struct devlink *devlink, struct nsim_fib_data *data)
+                                           NSIM_RESOURCE_IPV4_FIB);
+       unregister_fib_notifier(devlink_net(devlink), &data->fib_nb);
+       unregister_nexthop_notifier(devlink_net(devlink), &data->nexthop_nb);
++      cancel_work_sync(&data->fib_flush_work);
+       flush_work(&data->fib_event_work);
+       rhashtable_free_and_destroy(&data->fib_rt_ht, nsim_fib_rt_free,
+                                   data);
+-- 
+2.35.1
+
diff --git a/queue-5.15/netfilter-nf_tables-add-rescheduling-points-during-l.patch b/queue-5.15/netfilter-nf_tables-add-rescheduling-points-during-l.patch
new file mode 100644 (file)
index 0000000..c3794ea
--- /dev/null
@@ -0,0 +1,53 @@
+From cb18ae0ad6de7e17090c7c780933c075c6898f9d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Jul 2022 12:44:35 +0200
+Subject: netfilter: nf_tables: add rescheduling points during loop detection
+ walks
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit 81ea010667417ef3f218dfd99b69769fe66c2b67 ]
+
+Add explicit rescheduling points during ruleset walk.
+
+Switching to a faster algorithm is possible but this is a much
+smaller change, suitable for nf tree.
+
+Link: https://bugzilla.netfilter.org/show_bug.cgi?id=1460
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 13d14fcc2371..3d52a08bd560 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -3248,6 +3248,8 @@ int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain)
+                       if (err < 0)
+                               return err;
+               }
++
++              cond_resched();
+       }
+       return 0;
+@@ -9225,9 +9227,13 @@ static int nf_tables_check_loops(const struct nft_ctx *ctx,
+                               break;
+                       }
+               }
++
++              cond_resched();
+       }
+       list_for_each_entry(set, &ctx->table->sets, list) {
++              cond_resched();
++
+               if (!nft_is_active_next(ctx->net, set))
+                       continue;
+               if (!(set->flags & NFT_SET_MAP) ||
+-- 
+2.35.1
+
diff --git a/queue-5.15/netfilter-xtables-bring-spdx-identifier-back.patch b/queue-5.15/netfilter-xtables-bring-spdx-identifier-back.patch
new file mode 100644 (file)
index 0000000..cb8f4ac
--- /dev/null
@@ -0,0 +1,67 @@
+From f5ff38b6ee0f5544afcf4553c39899bf253d4125 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jun 2022 17:23:45 +0200
+Subject: netfilter: xtables: Bring SPDX identifier back
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+[ Upstream commit 20646f5b1e798bcc20044ae90ac3702f177bf254 ]
+
+Commit e2be04c7f995 ("License cleanup: add SPDX license identifier to
+uapi header files with a license") added the correct SPDX identifier to
+include/uapi/linux/netfilter/xt_IDLETIMER.h.
+
+A subsequent commit removed it for no reason and reintroduced the UAPI
+license incorrectness as the file is now missing the UAPI exception
+again.
+
+Add it back and remove the GPLv2 boilerplate while at it.
+
+Fixes: 68983a354a65 ("netfilter: xtables: Add snapshot of hardidletimer target")
+Cc: Manoj Basapathi <manojbm@codeaurora.org>
+Cc: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
+Cc: Pablo Neira Ayuso <pablo@netfilter.org>
+Cc: netfilter-devel@vger.kernel.org
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/uapi/linux/netfilter/xt_IDLETIMER.h | 17 +----------------
+ 1 file changed, 1 insertion(+), 16 deletions(-)
+
+diff --git a/include/uapi/linux/netfilter/xt_IDLETIMER.h b/include/uapi/linux/netfilter/xt_IDLETIMER.h
+index 49ddcdc61c09..7bfb31a66fc9 100644
+--- a/include/uapi/linux/netfilter/xt_IDLETIMER.h
++++ b/include/uapi/linux/netfilter/xt_IDLETIMER.h
+@@ -1,6 +1,5 @@
++/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
+ /*
+- * linux/include/linux/netfilter/xt_IDLETIMER.h
+- *
+  * Header file for Xtables timer target module.
+  *
+  * Copyright (C) 2004, 2010 Nokia Corporation
+@@ -10,20 +9,6 @@
+  * by Luciano Coelho <luciano.coelho@nokia.com>
+  *
+  * Contact: Luciano Coelho <luciano.coelho@nokia.com>
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU General Public License
+- * version 2 as published by the Free Software Foundation.
+- *
+- * This program is distributed in the hope that it will be useful, but
+- * WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+- * General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+- * 02110-1301 USA
+  */
+ #ifndef _XT_IDLETIMER_H
+-- 
+2.35.1
+
diff --git a/queue-5.15/nohz-full-sched-rt-fix-missed-tick-reenabling-bug-in.patch b/queue-5.15/nohz-full-sched-rt-fix-missed-tick-reenabling-bug-in.patch
new file mode 100644 (file)
index 0000000..0ef117a
--- /dev/null
@@ -0,0 +1,118 @@
+From c38285c0dae12a62c12b0f3cf1b0af0e55aa14a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Jun 2022 11:22:59 +0200
+Subject: nohz/full, sched/rt: Fix missed tick-reenabling bug in
+ dequeue_task_rt()
+
+From: Nicolas Saenz Julienne <nsaenzju@redhat.com>
+
+[ Upstream commit 5c66d1b9b30f737fcef85a0b75bfe0590e16b62a ]
+
+dequeue_task_rt() only decrements 'rt_rq->rt_nr_running' after having
+called sched_update_tick_dependency() preventing it from re-enabling the
+tick on systems that no longer have pending SCHED_RT tasks but have
+multiple runnable SCHED_OTHER tasks:
+
+  dequeue_task_rt()
+    dequeue_rt_entity()
+      dequeue_rt_stack()
+        dequeue_top_rt_rq()
+         sub_nr_running()      // decrements rq->nr_running
+           sched_update_tick_dependency()
+             sched_can_stop_tick()     // checks rq->rt.rt_nr_running,
+             ...
+        __dequeue_rt_entity()
+          dec_rt_tasks()       // decrements rq->rt.rt_nr_running
+         ...
+
+Every other scheduler class performs the operation in the opposite
+order, and sched_update_tick_dependency() expects the values to be
+updated as such. So avoid the misbehaviour by inverting the order in
+which the above operations are performed in the RT scheduler.
+
+Fixes: 76d92ac305f2 ("sched: Migrate sched to use new tick dependency mask model")
+Signed-off-by: Nicolas Saenz Julienne <nsaenzju@redhat.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Valentin Schneider <vschneid@redhat.com>
+Reviewed-by: Phil Auld <pauld@redhat.com>
+Link: https://lore.kernel.org/r/20220628092259.330171-1-nsaenzju@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/rt.c | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
+index 8007d087a57f..f75dcd3537b8 100644
+--- a/kernel/sched/rt.c
++++ b/kernel/sched/rt.c
+@@ -444,7 +444,7 @@ static inline void rt_queue_push_tasks(struct rq *rq)
+ #endif /* CONFIG_SMP */
+ static void enqueue_top_rt_rq(struct rt_rq *rt_rq);
+-static void dequeue_top_rt_rq(struct rt_rq *rt_rq);
++static void dequeue_top_rt_rq(struct rt_rq *rt_rq, unsigned int count);
+ static inline int on_rt_rq(struct sched_rt_entity *rt_se)
+ {
+@@ -565,7 +565,7 @@ static void sched_rt_rq_dequeue(struct rt_rq *rt_rq)
+       rt_se = rt_rq->tg->rt_se[cpu];
+       if (!rt_se) {
+-              dequeue_top_rt_rq(rt_rq);
++              dequeue_top_rt_rq(rt_rq, rt_rq->rt_nr_running);
+               /* Kick cpufreq (see the comment in kernel/sched/sched.h). */
+               cpufreq_update_util(rq_of_rt_rq(rt_rq), 0);
+       }
+@@ -651,7 +651,7 @@ static inline void sched_rt_rq_enqueue(struct rt_rq *rt_rq)
+ static inline void sched_rt_rq_dequeue(struct rt_rq *rt_rq)
+ {
+-      dequeue_top_rt_rq(rt_rq);
++      dequeue_top_rt_rq(rt_rq, rt_rq->rt_nr_running);
+ }
+ static inline int rt_rq_throttled(struct rt_rq *rt_rq)
+@@ -1051,7 +1051,7 @@ static void update_curr_rt(struct rq *rq)
+ }
+ static void
+-dequeue_top_rt_rq(struct rt_rq *rt_rq)
++dequeue_top_rt_rq(struct rt_rq *rt_rq, unsigned int count)
+ {
+       struct rq *rq = rq_of_rt_rq(rt_rq);
+@@ -1062,7 +1062,7 @@ dequeue_top_rt_rq(struct rt_rq *rt_rq)
+       BUG_ON(!rq->nr_running);
+-      sub_nr_running(rq, rt_rq->rt_nr_running);
++      sub_nr_running(rq, count);
+       rt_rq->rt_queued = 0;
+ }
+@@ -1342,18 +1342,21 @@ static void __dequeue_rt_entity(struct sched_rt_entity *rt_se, unsigned int flag
+ static void dequeue_rt_stack(struct sched_rt_entity *rt_se, unsigned int flags)
+ {
+       struct sched_rt_entity *back = NULL;
++      unsigned int rt_nr_running;
+       for_each_sched_rt_entity(rt_se) {
+               rt_se->back = back;
+               back = rt_se;
+       }
+-      dequeue_top_rt_rq(rt_rq_of_se(back));
++      rt_nr_running = rt_rq_of_se(back)->rt_nr_running;
+       for (rt_se = back; rt_se; rt_se = rt_se->back) {
+               if (on_rt_rq(rt_se))
+                       __dequeue_rt_entity(rt_se, flags);
+       }
++
++      dequeue_top_rt_rq(rt_rq_of_se(back), rt_nr_running);
+ }
+ static void enqueue_rt_entity(struct sched_rt_entity *rt_se, unsigned int flags)
+-- 
+2.35.1
+
diff --git a/queue-5.15/null_blk-fix-ida-error-handling-in-null_add_dev.patch b/queue-5.15/null_blk-fix-ida-error-handling-in-null_add_dev.patch
new file mode 100644 (file)
index 0000000..2186a48
--- /dev/null
@@ -0,0 +1,62 @@
+From 5dd8058e733f5fb8d6c71fa279c09b9e6070fb9f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 11:12:14 +0300
+Subject: null_blk: fix ida error handling in null_add_dev()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit ee452a8d984f94fa8e894f003a52e776e4572881 ]
+
+There needs to be some error checking if ida_simple_get() fails.
+Also call ida_free() if there are errors later.
+
+Fixes: 94bc02e30fb8 ("nullb: use ida to manage index")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Link: https://lore.kernel.org/r/YtEhXsr6vJeoiYhd@kili
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/null_blk/main.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c
+index 187d779c8ca0..4c8b4101516c 100644
+--- a/drivers/block/null_blk/main.c
++++ b/drivers/block/null_blk/main.c
+@@ -1884,8 +1884,13 @@ static int null_add_dev(struct nullb_device *dev)
+       blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, nullb->q);
+       mutex_lock(&lock);
+-      nullb->index = ida_simple_get(&nullb_indexes, 0, 0, GFP_KERNEL);
+-      dev->index = nullb->index;
++      rv = ida_simple_get(&nullb_indexes, 0, 0, GFP_KERNEL);
++      if (rv < 0) {
++              mutex_unlock(&lock);
++              goto out_cleanup_zone;
++      }
++      nullb->index = rv;
++      dev->index = rv;
+       mutex_unlock(&lock);
+       blk_queue_logical_block_size(nullb->q, dev->blocksize);
+@@ -1905,13 +1910,16 @@ static int null_add_dev(struct nullb_device *dev)
+       rv = null_gendisk_register(nullb);
+       if (rv)
+-              goto out_cleanup_zone;
++              goto out_ida_free;
+       mutex_lock(&lock);
+       list_add_tail(&nullb->list, &nullb_list);
+       mutex_unlock(&lock);
+       return 0;
++
++out_ida_free:
++      ida_free(&nullb_indexes, nullb->index);
+ out_cleanup_zone:
+       null_free_zoned_dev(dev);
+ out_cleanup_disk:
+-- 
+2.35.1
+
diff --git a/queue-5.15/nvme-catch-enodev-from-nvme_revalidate_zones-again.patch b/queue-5.15/nvme-catch-enodev-from-nvme_revalidate_zones-again.patch
new file mode 100644 (file)
index 0000000..a099b51
--- /dev/null
@@ -0,0 +1,73 @@
+From 5fe1c4e5574efde918a46218a22893bfc2f9ff48 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Jul 2022 07:56:35 +0200
+Subject: nvme: catch -ENODEV from nvme_revalidate_zones again
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit e06b425bc835ead08b9fd935bf5e47eef473e7a0 ]
+
+nvme_revalidate_zones can also return -ENODEV if e.g. zone sizes aren't
+constant or not a power of two.  In that case we should jump to marking
+the gendisk hidden and only support pass through.
+
+Fixes: 602e57c9799c ("nvme: also mark passthrough-only namespaces ready in nvme_update_ns_info")
+Reported-by: Joel Granados <j.granados@samsung.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Joel Granados <j.granados@samsung.com>
+Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/core.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index ddaad05ff043..ed2740585c5d 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -1914,8 +1914,10 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
+       if (ns->head->ids.csi == NVME_CSI_ZNS) {
+               ret = nvme_update_zone_info(ns, lbaf);
+-              if (ret)
+-                      goto out_unfreeze;
++              if (ret) {
++                      blk_mq_unfreeze_queue(ns->disk->queue);
++                      goto out;
++              }
+       }
+       set_disk_ro(ns->disk, (id->nsattr & NVME_NS_ATTR_RO) ||
+@@ -1926,7 +1928,7 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
+       if (blk_queue_is_zoned(ns->queue)) {
+               ret = nvme_revalidate_zones(ns);
+               if (ret && !nvme_first_scan(ns->disk))
+-                      return ret;
++                      goto out;
+       }
+       if (nvme_ns_head_multipath(ns->head)) {
+@@ -1941,9 +1943,9 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
+               disk_update_readahead(ns->head->disk);
+               blk_mq_unfreeze_queue(ns->head->disk->queue);
+       }
+-      return 0;
+-out_unfreeze:
++      ret = 0;
++out:
+       /*
+        * If probing fails due an unsupported feature, hide the block device,
+        * but still allow other access.
+@@ -1953,7 +1955,6 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
+               set_bit(NVME_NS_READY, &ns->flags);
+               ret = 0;
+       }
+-      blk_mq_unfreeze_queue(ns->disk->queue);
+       return ret;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/nvme-define-compat_ioctl-again-to-unbreak-32-bit-use.patch b/queue-5.15/nvme-define-compat_ioctl-again-to-unbreak-32-bit-use.patch
new file mode 100644 (file)
index 0000000..1e936c6
--- /dev/null
@@ -0,0 +1,66 @@
+From 4e75f48c67a19fba8858f8e0aeebb5e884a6b3da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Jul 2022 23:57:35 -0400
+Subject: nvme: define compat_ioctl again to unbreak 32-bit userspace.
+
+From: Nick Bowler <nbowler@draconx.ca>
+
+[ Upstream commit a25d4261582cf00dad884c194d21084836663d3d ]
+
+Commit 89b3d6e60550 ("nvme: simplify the compat ioctl handling") removed
+the initialization of compat_ioctl from the nvme block_device_operations
+structures.
+
+Presumably the expectation was that 32-bit ioctls would be directed
+through the regular handler but this is not the case: failing to assign
+.compat_ioctl actually means that the compat case is disabled entirely,
+and any attempt to submit nvme ioctls from 32-bit userspace fails
+outright with -ENOTTY.
+
+For example:
+
+  % smartctl -x /dev/nvme0n1
+  [...]
+  Read NVMe Identify Controller failed: NVME_IOCTL_ADMIN_CMD: Inappropriate ioctl for device
+
+The blkdev_compat_ptr_ioctl helper can be used to direct compat calls
+through the main ioctl handler and makes things work again.
+
+Fixes: 89b3d6e60550 ("nvme: simplify the compat ioctl handling")
+Signed-off-by: Nick Bowler <nbowler@draconx.ca>
+Reviewed-by: Guixin Liu <kanie@linux.alibaba.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/core.c      | 1 +
+ drivers/nvme/host/multipath.c | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index 0c9cdbaf5cd6..ace55ebb1bff 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -2102,6 +2102,7 @@ static int nvme_report_zones(struct gendisk *disk, sector_t sector,
+ static const struct block_device_operations nvme_bdev_ops = {
+       .owner          = THIS_MODULE,
+       .ioctl          = nvme_ioctl,
++      .compat_ioctl   = blkdev_compat_ptr_ioctl,
+       .open           = nvme_open,
+       .release        = nvme_release,
+       .getgeo         = nvme_getgeo,
+diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
+index 064acad505d3..04fa276701d1 100644
+--- a/drivers/nvme/host/multipath.c
++++ b/drivers/nvme/host/multipath.c
+@@ -388,6 +388,7 @@ const struct block_device_operations nvme_ns_head_ops = {
+       .open           = nvme_ns_head_open,
+       .release        = nvme_ns_head_release,
+       .ioctl          = nvme_ns_head_ioctl,
++      .compat_ioctl   = blkdev_compat_ptr_ioctl,
+       .getgeo         = nvme_getgeo,
+       .report_zones   = nvme_ns_head_report_zones,
+       .pr_ops         = &nvme_pr_ops,
+-- 
+2.35.1
+
diff --git a/queue-5.15/nvme-disable-namespace-access-for-unsupported-metada.patch b/queue-5.15/nvme-disable-namespace-access-for-unsupported-metada.patch
new file mode 100644 (file)
index 0000000..01386c0
--- /dev/null
@@ -0,0 +1,61 @@
+From 1c72a7529042258a03b5138357ae9d013b6e8d25 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 Nov 2021 08:14:54 -0800
+Subject: nvme: disable namespace access for unsupported metadata
+
+From: Keith Busch <kbusch@kernel.org>
+
+[ Upstream commit d39ad2a45c0e38def3e0c95f5b90d9af4274c939 ]
+
+The only fabrics target that supports metadata handling through the
+separate integrity buffer is RDMA. It is currently usable only if the
+size is 8B per block and formatted for protection information. If an
+rdma target were to export a namespace with a different format (ex:
+4k+64B), the driver will not be able to submit valid read/write commands
+for that namespace.
+
+Suppress setting the metadata feature in the namespace so that the
+gendisk capacity will be set to 0. This will prevent read/write access
+through the block stack, but will continue to allow ioctl passthrough
+commands.
+
+Cc: Max Gurtovoy <mgurtovoy@nvidia.com>
+Cc: Sagi Grimberg <sagi@grimberg.me>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/core.c | 17 ++++++++++++++---
+ 1 file changed, 14 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index ace55ebb1bff..d9aea6c22f52 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -1744,9 +1744,20 @@ static int nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id)
+                */
+               if (WARN_ON_ONCE(!(id->flbas & NVME_NS_FLBAS_META_EXT)))
+                       return -EINVAL;
+-              if (ctrl->max_integrity_segments)
+-                      ns->features |=
+-                              (NVME_NS_METADATA_SUPPORTED | NVME_NS_EXT_LBAS);
++
++              ns->features |= NVME_NS_EXT_LBAS;
++
++              /*
++               * The current fabrics transport drivers support namespace
++               * metadata formats only if nvme_ns_has_pi() returns true.
++               * Suppress support for all other formats so the namespace will
++               * have a 0 capacity and not be usable through the block stack.
++               *
++               * Note, this check will need to be modified if any drivers
++               * gain the ability to use other metadata formats.
++               */
++              if (ctrl->max_integrity_segments && nvme_ns_has_pi(ns))
++                      ns->features |= NVME_NS_METADATA_SUPPORTED;
+       } else {
+               /*
+                * For PCIe controllers, we can't easily remap the separate
+-- 
+2.35.1
+
diff --git a/queue-5.15/nvme-don-t-return-an-error-from-nvme_configure_metad.patch b/queue-5.15/nvme-don-t-return-an-error-from-nvme_configure_metad.patch
new file mode 100644 (file)
index 0000000..ec2b2fb
--- /dev/null
@@ -0,0 +1,77 @@
+From e74ed08688c22affb6b3adbced2906aa0343270b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Feb 2022 15:07:15 +0100
+Subject: nvme: don't return an error from nvme_configure_metadata
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit 363f6368603743072e5f318c668c632bccb097a3 ]
+
+When a fabrics controller claims to support an invalidate metadata
+configuration we already warn and disable metadata support.  No need to
+also return an error during revalidation.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
+Reviewed-by: Daniel Wagner <dwagner@suse.de>
+Tested-by: Kanchan Joshi <joshi.k@samsung.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/core.c | 13 +++++--------
+ 1 file changed, 5 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index d9aea6c22f52..ddaad05ff043 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -1719,7 +1719,7 @@ static int nvme_setup_streams_ns(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
+       return 0;
+ }
+-static int nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id)
++static void nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id)
+ {
+       struct nvme_ctrl *ctrl = ns->ctrl;
+@@ -1735,7 +1735,8 @@ static int nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id)
+       ns->features &= ~(NVME_NS_METADATA_SUPPORTED | NVME_NS_EXT_LBAS);
+       if (!ns->ms || !(ctrl->ops->flags & NVME_F_METADATA_SUPPORTED))
+-              return 0;
++              return;
++
+       if (ctrl->ops->flags & NVME_F_FABRICS) {
+               /*
+                * The NVMe over Fabrics specification only supports metadata as
+@@ -1743,7 +1744,7 @@ static int nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id)
+                * remap the separate metadata buffer from the block layer.
+                */
+               if (WARN_ON_ONCE(!(id->flbas & NVME_NS_FLBAS_META_EXT)))
+-                      return -EINVAL;
++                      return;
+               ns->features |= NVME_NS_EXT_LBAS;
+@@ -1770,8 +1771,6 @@ static int nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id)
+               else
+                       ns->features |= NVME_NS_METADATA_SUPPORTED;
+       }
+-
+-      return 0;
+ }
+ static void nvme_set_queue_limits(struct nvme_ctrl *ctrl,
+@@ -1909,9 +1908,7 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
+       ns->lba_shift = id->lbaf[lbaf].ds;
+       nvme_set_queue_limits(ns->ctrl, ns->queue);
+-      ret = nvme_configure_metadata(ns, id);
+-      if (ret)
+-              goto out_unfreeze;
++      nvme_configure_metadata(ns, id);
+       nvme_set_chunk_sectors(ns, id);
+       nvme_update_disk_info(ns->disk, ns, id);
+-- 
+2.35.1
+
diff --git a/queue-5.15/nvme-use-command_id-instead-of-req-tag-in-trace_nvme.patch b/queue-5.15/nvme-use-command_id-instead-of-req-tag-in-trace_nvme.patch
new file mode 100644 (file)
index 0000000..8c90fb8
--- /dev/null
@@ -0,0 +1,40 @@
+From faef130f301c0e36604c1068ff986231fb500ca1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 23:27:21 +0200
+Subject: nvme: use command_id instead of req->tag in trace_nvme_complete_rq()
+
+From: Bean Huo <beanhuo@micron.com>
+
+[ Upstream commit 679c54f2de672b7d79d02f8c4ad483ff6dd8ce2e ]
+
+Use command_id instead of req->tag in trace_nvme_complete_rq(),
+because of commit e7006de6c238 ("nvme: code command_id with a genctr
+for use authentication after release"), cmd->common.command_id is set to
+((genctl & 0xf)< 12 | req->tag), no longer req->tag, which makes cid in
+trace_nvme_complete_rq and trace_nvme_setup_cmd are not the same.
+
+Fixes: e7006de6c238 ("nvme: code command_id with a genctr for use authentication after release")
+Signed-off-by: Bean Huo <beanhuo@micron.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/trace.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/nvme/host/trace.h b/drivers/nvme/host/trace.h
+index 35bac7a25422..aa8b0f86b2be 100644
+--- a/drivers/nvme/host/trace.h
++++ b/drivers/nvme/host/trace.h
+@@ -98,7 +98,7 @@ TRACE_EVENT(nvme_complete_rq,
+           TP_fast_assign(
+               __entry->ctrl_id = nvme_req(req)->ctrl->instance;
+               __entry->qid = nvme_req_qid(req);
+-              __entry->cid = req->tag;
++              __entry->cid = nvme_req(req)->cmd->common.command_id;
+               __entry->result = le64_to_cpu(nvme_req(req)->result.u64);
+               __entry->retries = nvme_req(req)->retries;
+               __entry->flags = nvme_req(req)->flags;
+-- 
+2.35.1
+
diff --git a/queue-5.15/of-check-previous-kernel-s-ima-kexec-buffer-against-.patch b/queue-5.15/of-check-previous-kernel-s-ima-kexec-buffer-against-.patch
new file mode 100644 (file)
index 0000000..42d0557
--- /dev/null
@@ -0,0 +1,94 @@
+From 38b333a0a57f38db14e95efda489d8bca83c82aa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 31 May 2022 09:44:46 +0530
+Subject: of: check previous kernel's ima-kexec-buffer against memory bounds
+
+From: Vaibhav Jain <vaibhav@linux.ibm.com>
+
+[ Upstream commit cbf9c4b9617b6767886a913705ca14b7600c77db ]
+
+Presently ima_get_kexec_buffer() doesn't check if the previous kernel's
+ima-kexec-buffer lies outside the addressable memory range. This can result
+in a kernel panic if the new kernel is booted with 'mem=X' arg and the
+ima-kexec-buffer was allocated beyond that range by the previous kernel.
+The panic is usually of the form below:
+
+$ sudo kexec --initrd initrd vmlinux --append='mem=16G'
+
+<snip>
+ BUG: Unable to handle kernel data access on read at 0xc000c01fff7f0000
+ Faulting instruction address: 0xc000000000837974
+ Oops: Kernel access of bad area, sig: 11 [#1]
+<snip>
+ NIP [c000000000837974] ima_restore_measurement_list+0x94/0x6c0
+ LR [c00000000083b55c] ima_load_kexec_buffer+0xac/0x160
+ Call Trace:
+ [c00000000371fa80] [c00000000083b55c] ima_load_kexec_buffer+0xac/0x160
+ [c00000000371fb00] [c0000000020512c4] ima_init+0x80/0x108
+ [c00000000371fb70] [c0000000020514dc] init_ima+0x4c/0x120
+ [c00000000371fbf0] [c000000000012240] do_one_initcall+0x60/0x2c0
+ [c00000000371fcc0] [c000000002004ad0] kernel_init_freeable+0x344/0x3ec
+ [c00000000371fda0] [c0000000000128a4] kernel_init+0x34/0x1b0
+ [c00000000371fe10] [c00000000000ce64] ret_from_kernel_thread+0x5c/0x64
+ Instruction dump:
+ f92100b8 f92100c0 90e10090 910100a0 4182050c 282a0017 3bc00000 40810330
+ 7c0802a6 fb610198 7c9b2378 f80101d0 <a1240000> 2c090001 40820614 e9240010
+ ---[ end trace 0000000000000000 ]---
+
+Fix this issue by checking returned PFN range of previous kernel's
+ima-kexec-buffer with page_is_ram() to ensure correct memory bounds.
+
+Fixes: 467d27824920 ("powerpc: ima: get the kexec buffer passed by the previous kernel")
+Cc: Frank Rowand <frowand.list@gmail.com>
+Cc: Prakhar Srivastava <prsriva@linux.microsoft.com>
+Cc: Lakshmi Ramasubramanian <nramas@linux.microsoft.com>
+Cc: Thiago Jung Bauermann <bauerman@linux.ibm.com>
+Cc: Rob Herring <robh@kernel.org>
+Cc: Ritesh Harjani <ritesh.list@gmail.com>
+Cc: Robin Murphy <robin.murphy@arm.com>
+Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com>
+Signed-off-by: Rob Herring <robh@kernel.org>
+Link: https://lore.kernel.org/r/20220531041446.3334259-1-vaibhav@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/kexec.c | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+diff --git a/drivers/of/kexec.c b/drivers/of/kexec.c
+index 72c790a3c910..8f9dba11873c 100644
+--- a/drivers/of/kexec.c
++++ b/drivers/of/kexec.c
+@@ -125,6 +125,7 @@ int ima_get_kexec_buffer(void **addr, size_t *size)
+ {
+       int ret, len;
+       unsigned long tmp_addr;
++      unsigned long start_pfn, end_pfn;
+       size_t tmp_size;
+       const void *prop;
+@@ -139,6 +140,22 @@ int ima_get_kexec_buffer(void **addr, size_t *size)
+       if (ret)
+               return ret;
++      /* Do some sanity on the returned size for the ima-kexec buffer */
++      if (!tmp_size)
++              return -ENOENT;
++
++      /*
++       * Calculate the PFNs for the buffer and ensure
++       * they are with in addressable memory.
++       */
++      start_pfn = PHYS_PFN(tmp_addr);
++      end_pfn = PHYS_PFN(tmp_addr + tmp_size - 1);
++      if (!page_is_ram(start_pfn) || !page_is_ram(end_pfn)) {
++              pr_warn("IMA buffer at 0x%lx, size = 0x%zx beyond memory\n",
++                      tmp_addr, tmp_size);
++              return -EINVAL;
++      }
++
+       *addr = __va(tmp_addr);
+       *size = tmp_size;
+-- 
+2.35.1
+
diff --git a/queue-5.15/of-device-fix-missing-of_node_put-in-of_dma_set_rest.patch b/queue-5.15/of-device-fix-missing-of_node_put-in-of_dma_set_rest.patch
new file mode 100644 (file)
index 0000000..72b694d
--- /dev/null
@@ -0,0 +1,42 @@
+From 3d9393b852f6d45991f4c511758a2df7f5cc3560 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 2 Jul 2022 09:44:49 +0800
+Subject: of: device: Fix missing of_node_put() in of_dma_set_restricted_buffer
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit d17e37c41b7ed38459957a5d2968ba61516fd5c2 ]
+
+We should use of_node_put() for the reference 'node' returned by
+of_parse_phandle() which will increase the refcount.
+
+Fixes: fec9b625095f ("of: Add plumbing for restricted DMA pool")
+Co-authored-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Liang He <windhl@126.com>
+Signed-off-by: Rob Herring <robh@kernel.org>
+Link: https://lore.kernel.org/r/20220702014449.263772-1-windhl@126.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/device.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/of/device.c b/drivers/of/device.c
+index b0800c260f64..45335fe523f7 100644
+--- a/drivers/of/device.c
++++ b/drivers/of/device.c
+@@ -81,8 +81,11 @@ of_dma_set_restricted_buffer(struct device *dev, struct device_node *np)
+                * restricted-dma-pool region is allowed.
+                */
+               if (of_device_is_compatible(node, "restricted-dma-pool") &&
+-                  of_device_is_available(node))
++                  of_device_is_available(node)) {
++                      of_node_put(node);
+                       break;
++              }
++              of_node_put(node);
+       }
+       /*
+-- 
+2.35.1
+
diff --git a/queue-5.15/of-fdt-declared-return-type-does-not-match-actual-re.patch b/queue-5.15/of-fdt-declared-return-type-does-not-match-actual-re.patch
new file mode 100644 (file)
index 0000000..f66e63e
--- /dev/null
@@ -0,0 +1,46 @@
+From ec678084e4f1b345cfbfdab1953c844b4607086f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Aug 2022 12:05:06 +0000
+Subject: of/fdt: declared return type does not match actual return type
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Xu Qiang <xuqiang36@huawei.com>
+
+[ Upstream commit 7913145afa51bbed9eaf8e5b4ee55fa9884a71e5 ]
+
+The commit 649cab56de8e (“of: properly check for error returned
+by fdt_get_name()”) changed the return value type from bool to int,
+but forgot to change the return value simultaneously.
+
+populate_node was only called in unflatten_dt_nodes, and returns
+with values greater than or equal to 0 were discarded without further
+processing. Considering that return 0 usually indicates success,
+return 0 instead of return true.
+
+Fixes: 649cab56de8e (“of: properly check for error returned by fdt_get_name()”)
+Signed-off-by: Xu Qiang <xuqiang36@huawei.com>
+Signed-off-by: Rob Herring <robh@kernel.org>
+Link: https://lore.kernel.org/r/20220801120506.11461-2-xuqiang36@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/fdt.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
+index 59a7a9ee58ef..d245628b15dd 100644
+--- a/drivers/of/fdt.c
++++ b/drivers/of/fdt.c
+@@ -245,7 +245,7 @@ static int populate_node(const void *blob,
+       }
+       *pnp = np;
+-      return true;
++      return 0;
+ }
+ static void reverse_nodes(struct device_node *parent)
+-- 
+2.35.1
+
diff --git a/queue-5.15/opp-fix-error-check-in-dev_pm_opp_attach_genpd.patch b/queue-5.15/opp-fix-error-check-in-dev_pm_opp_attach_genpd.patch
new file mode 100644 (file)
index 0000000..3704083
--- /dev/null
@@ -0,0 +1,39 @@
+From b065d08ccac57831e6992f8bef720a64f1cbd0d6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 May 2022 20:31:51 +0800
+Subject: opp: Fix error check in dev_pm_opp_attach_genpd()
+
+From: Tang Bin <tangbin@cmss.chinamobile.com>
+
+[ Upstream commit 4ea9496cbc959eb5c78f3e379199aca9ef4e386b ]
+
+dev_pm_domain_attach_by_name() may return NULL in some cases,
+so IS_ERR() doesn't meet the requirements. Thus fix it.
+
+Fixes: 6319aee10e53 ("opp: Attach genpds to devices from within OPP core")
+Signed-off-by: Tang Bin <tangbin@cmss.chinamobile.com>
+[ Viresh: Replace ENODATA with ENODEV ]
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/opp/core.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/opp/core.c b/drivers/opp/core.c
+index 04b4691a8aac..b2da497dd378 100644
+--- a/drivers/opp/core.c
++++ b/drivers/opp/core.c
+@@ -2388,8 +2388,8 @@ struct opp_table *dev_pm_opp_attach_genpd(struct device *dev,
+               }
+               virt_dev = dev_pm_domain_attach_by_name(dev, *name);
+-              if (IS_ERR(virt_dev)) {
+-                      ret = PTR_ERR(virt_dev);
++              if (IS_ERR_OR_NULL(virt_dev)) {
++                      ret = PTR_ERR(virt_dev) ? : -ENODEV;
+                       dev_err(dev, "Couldn't attach to pm_domain: %d\n", ret);
+                       goto err;
+               }
+-- 
+2.35.1
+
diff --git a/queue-5.15/pci-dwc-add-unroll-iatu-space-support-to-dw_pcie_dis.patch b/queue-5.15/pci-dwc-add-unroll-iatu-space-support-to-dw_pcie_dis.patch
new file mode 100644 (file)
index 0000000..080690b
--- /dev/null
@@ -0,0 +1,71 @@
+From 4a0269732721575856d3d07f1063cade3218ed13 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jun 2022 17:34:12 +0300
+Subject: PCI: dwc: Add unroll iATU space support to dw_pcie_disable_atu()
+
+From: Serge Semin <Sergey.Semin@baikalelectronics.ru>
+
+[ Upstream commit d1cf738f2b65a5640234e1da90a68d3523fbed83 ]
+
+dw_pcie_disable_atu() was introduced by f8aed6ec624f ("PCI: dwc:
+designware: Add EP mode support") and supported only the viewport version
+of the iATU CSRs.
+
+DW PCIe IP cores v4.80a and newer also support unrolled iATU/eDMA space.
+Callers of dw_pcie_disable_atu(), including pci_epc_ops.clear_bar(),
+pci_epc_ops.unmap_addr(), and dw_pcie_setup_rc(), don't work correctly when
+it is enabled.
+
+Add dw_pcie_disable_atu() support for controllers with unrolled iATU CSRs
+enabled.
+
+[bhelgaas: commit log]
+Fixes: f8aed6ec624f ("PCI: dwc: designware: Add EP mode support")
+Link: https://lore.kernel.org/r/20220624143428.8334-3-Sergey.Semin@baikalelectronics.ru
+Tested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pcie-designware.c | 16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
+index 3254f60d1713..ff74ddf2cc35 100644
+--- a/drivers/pci/controller/dwc/pcie-designware.c
++++ b/drivers/pci/controller/dwc/pcie-designware.c
+@@ -491,7 +491,7 @@ int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
+ void dw_pcie_disable_atu(struct dw_pcie *pci, int index,
+                        enum dw_pcie_region_type type)
+ {
+-      int region;
++      u32 region;
+       switch (type) {
+       case DW_PCIE_REGION_INBOUND:
+@@ -504,8 +504,18 @@ void dw_pcie_disable_atu(struct dw_pcie *pci, int index,
+               return;
+       }
+-      dw_pcie_writel_dbi(pci, PCIE_ATU_VIEWPORT, region | index);
+-      dw_pcie_writel_dbi(pci, PCIE_ATU_CR2, ~(u32)PCIE_ATU_ENABLE);
++      if (pci->iatu_unroll_enabled) {
++              if (region == PCIE_ATU_REGION_INBOUND) {
++                      dw_pcie_writel_ib_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL2,
++                                               ~(u32)PCIE_ATU_ENABLE);
++              } else {
++                      dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL2,
++                                               ~(u32)PCIE_ATU_ENABLE);
++              }
++      } else {
++              dw_pcie_writel_dbi(pci, PCIE_ATU_VIEWPORT, region | index);
++              dw_pcie_writel_dbi(pci, PCIE_ATU_CR2, ~(u32)PCIE_ATU_ENABLE);
++      }
+ }
+ int dw_pcie_wait_for_link(struct dw_pcie *pci)
+-- 
+2.35.1
+
diff --git a/queue-5.15/pci-dwc-always-enable-cdm-check-if-snps-enable-cdm-c.patch b/queue-5.15/pci-dwc-always-enable-cdm-check-if-snps-enable-cdm-c.patch
new file mode 100644 (file)
index 0000000..07d3914
--- /dev/null
@@ -0,0 +1,62 @@
+From 629aef19038743d4ebc30ebf119c53e75d3ca63e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jun 2022 17:34:16 +0300
+Subject: PCI: dwc: Always enable CDM check if "snps,enable-cdm-check" exists
+
+From: Serge Semin <Sergey.Semin@baikalelectronics.ru>
+
+[ Upstream commit ec7b952f453ce7eabe7e1bea584626934d44f668 ]
+
+If the "snps,enable-cdm-check" property exists, we should enable the CDM
+check.  But previously dw_pcie_setup() could exit before doing so if the
+"num-lanes" property was absent or invalid.
+
+Move the CDM enable earlier so we do it regardless of whether "num-lanes"
+is present.
+
+[bhelgaas: commit log]
+Fixes: 07f123def73e ("PCI: dwc: Add support to enable CDM register check")
+Link: https://lore.kernel.org/r/20220624143428.8334-7-Sergey.Semin@baikalelectronics.ru
+Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Vidya Sagar <vidyas@nvidia.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pcie-designware.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
+index e863cc2f1e1d..e408ebf5bd73 100644
+--- a/drivers/pci/controller/dwc/pcie-designware.c
++++ b/drivers/pci/controller/dwc/pcie-designware.c
+@@ -739,6 +739,13 @@ void dw_pcie_setup(struct dw_pcie *pci)
+       val |= PORT_LINK_DLL_LINK_EN;
+       dw_pcie_writel_dbi(pci, PCIE_PORT_LINK_CONTROL, val);
++      if (of_property_read_bool(np, "snps,enable-cdm-check")) {
++              val = dw_pcie_readl_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS);
++              val |= PCIE_PL_CHK_REG_CHK_REG_CONTINUOUS |
++                     PCIE_PL_CHK_REG_CHK_REG_START;
++              dw_pcie_writel_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS, val);
++      }
++
+       of_property_read_u32(np, "num-lanes", &pci->num_lanes);
+       if (!pci->num_lanes) {
+               dev_dbg(pci->dev, "Using h/w default number of lanes\n");
+@@ -785,11 +792,4 @@ void dw_pcie_setup(struct dw_pcie *pci)
+               break;
+       }
+       dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, val);
+-
+-      if (of_property_read_bool(np, "snps,enable-cdm-check")) {
+-              val = dw_pcie_readl_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS);
+-              val |= PCIE_PL_CHK_REG_CHK_REG_CONTINUOUS |
+-                     PCIE_PL_CHK_REG_CHK_REG_START;
+-              dw_pcie_writel_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS, val);
+-      }
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/pci-dwc-deallocate-epc-memory-on-dw_pcie_ep_init-err.patch b/queue-5.15/pci-dwc-deallocate-epc-memory-on-dw_pcie_ep_init-err.patch
new file mode 100644 (file)
index 0000000..567f740
--- /dev/null
@@ -0,0 +1,66 @@
+From 2aa01e5699b0f5b5cd213ab24abf3f636d685c8c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jun 2022 17:34:15 +0300
+Subject: PCI: dwc: Deallocate EPC memory on dw_pcie_ep_init() errors
+
+From: Serge Semin <Sergey.Semin@baikalelectronics.ru>
+
+[ Upstream commit 8161e9626b50892eaedbd8070ecb1586ecedb109 ]
+
+If dw_pcie_ep_init() fails to perform any action after the EPC memory is
+initialized and the MSI memory region is allocated, the latter parts won't
+be undone thus causing a memory leak.  Add a cleanup-on-error path to fix
+these leaks.
+
+[bhelgaas: commit log]
+Fixes: 2fd0c9d966cc ("PCI: designware-ep: Pre-allocate memory for MSI in dw_pcie_ep_init")
+Link: https://lore.kernel.org/r/20220624143428.8334-6-Sergey.Semin@baikalelectronics.ru
+Tested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../pci/controller/dwc/pcie-designware-ep.c    | 18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
+index 998b698f4085..2af4ed90e12b 100644
+--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
++++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
+@@ -777,8 +777,9 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
+       ep->msi_mem = pci_epc_mem_alloc_addr(epc, &ep->msi_mem_phys,
+                                            epc->mem->window.page_size);
+       if (!ep->msi_mem) {
++              ret = -ENOMEM;
+               dev_err(dev, "Failed to reserve memory for MSI/MSI-X\n");
+-              return -ENOMEM;
++              goto err_exit_epc_mem;
+       }
+       if (ep->ops->get_features) {
+@@ -787,6 +788,19 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
+                       return 0;
+       }
+-      return dw_pcie_ep_init_complete(ep);
++      ret = dw_pcie_ep_init_complete(ep);
++      if (ret)
++              goto err_free_epc_mem;
++
++      return 0;
++
++err_free_epc_mem:
++      pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem,
++                            epc->mem->window.page_size);
++
++err_exit_epc_mem:
++      pci_epc_mem_exit(epc);
++
++      return ret;
+ }
+ EXPORT_SYMBOL_GPL(dw_pcie_ep_init);
+-- 
+2.35.1
+
diff --git a/queue-5.15/pci-dwc-disable-outbound-windows-only-for-controller.patch b/queue-5.15/pci-dwc-disable-outbound-windows-only-for-controller.patch
new file mode 100644 (file)
index 0000000..4496c69
--- /dev/null
@@ -0,0 +1,70 @@
+From ae6115816395ec77599037c9751f2ac9bd29c42f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jun 2022 17:34:13 +0300
+Subject: PCI: dwc: Disable outbound windows only for controllers using iATU
+
+From: Serge Semin <Sergey.Semin@baikalelectronics.ru>
+
+[ Upstream commit d60a2e281e9de2b2f67343b2e39417ca0f4fd54e ]
+
+Some DWC-based controllers (e.g., pcie-al.c and pci-keystone.c, identified
+by the fact that they override the default dw_child_pcie_ops) use their own
+address translation approach instead of the DWC internal ATU (iATU).  For
+those controllers, skip disabling the iATU outbound windows.
+
+[bhelgaas: commit log, update multiple window comment]
+Fixes: 458ad06c4cdd ("PCI: dwc: Ensure all outbound ATU windows are reset")
+Link: https://lore.kernel.org/r/20220624143428.8334-4-Sergey.Semin@baikalelectronics.ru
+Tested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pcie-designware-host.c | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
+index 3200e906bcda..7cd4593ad12f 100644
+--- a/drivers/pci/controller/dwc/pcie-designware-host.c
++++ b/drivers/pci/controller/dwc/pcie-designware-host.c
+@@ -536,7 +536,6 @@ static struct pci_ops dw_pcie_ops = {
+ void dw_pcie_setup_rc(struct pcie_port *pp)
+ {
+-      int i;
+       u32 val, ctrl, num_ctrls;
+       struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+@@ -588,19 +587,22 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
+               PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
+       dw_pcie_writel_dbi(pci, PCI_COMMAND, val);
+-      /* Ensure all outbound windows are disabled so there are multiple matches */
+-      for (i = 0; i < pci->num_ob_windows; i++)
+-              dw_pcie_disable_atu(pci, i, DW_PCIE_REGION_OUTBOUND);
+-
+       /*
+        * If the platform provides its own child bus config accesses, it means
+        * the platform uses its own address translation component rather than
+        * ATU, so we should not program the ATU here.
+        */
+       if (pp->bridge->child_ops == &dw_child_pcie_ops) {
+-              int atu_idx = 0;
++              int i, atu_idx = 0;
+               struct resource_entry *entry;
++              /*
++               * Disable all outbound windows to make sure a transaction
++               * can't match multiple windows.
++               */
++              for (i = 0; i < pci->num_ob_windows; i++)
++                      dw_pcie_disable_atu(pci, i, DW_PCIE_REGION_OUTBOUND);
++
+               /* Get last memory resource entry */
+               resource_list_for_each_entry(entry, &pp->bridge->windows) {
+                       if (resource_type(entry->res) != IORESOURCE_MEM)
+-- 
+2.35.1
+
diff --git a/queue-5.15/pci-dwc-set-increase_region_size-flag-based-on-limit.patch b/queue-5.15/pci-dwc-set-increase_region_size-flag-based-on-limit.patch
new file mode 100644 (file)
index 0000000..5037a28
--- /dev/null
@@ -0,0 +1,99 @@
+From 42486b9759db6e93880f8be174e023960c7c3ebf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jun 2022 17:34:14 +0300
+Subject: PCI: dwc: Set INCREASE_REGION_SIZE flag based on limit address
+
+From: Serge Semin <Sergey.Semin@baikalelectronics.ru>
+
+[ Upstream commit 777e7c3ab73036105e6fc4a67ed950179dbffbab ]
+
+We program the 64-bit ATU limit address (in PCIE_ATU_LIMIT/
+PCIE_ATU_UPPER_LIMIT or PCIE_ATU_UNR_LOWER_LIMIT/PCIE_ATU_UNR_UPPER_LIMIT),
+but in addition, the PCIE_ATU_INCREASE_REGION_SIZE bit must be set if the
+upper 32 bits of the limit address differ from the upper 32 bits of the
+base address (see [1,2]).
+
+5b4cf0f65324 ("PCI: dwc: Add upper limit address for outbound iATU") set
+PCIE_ATU_INCREASE_REGION_SIZE, but only when the *size* was greater than
+4GB.  It did not set it when a smaller region crossed a 4GB boundary, e.g.,
+[mem 0x0_f0000000-0x1_0fffffff].
+
+Set PCIE_ATU_INCREASE_REGION_SIZE whenever PCIE_ATU_UPPER_LIMIT is
+greater than PCIE_ATU_UPPER_BASE.
+
+[1] DesignWare Cores PCI Express Controller Databook - DWC PCIe Root Port,
+    v5.40a, March 2019, fig.3-36, p.175
+[2] DesignWare Cores PCI Express Controller Databook - DWC PCIe Root Port,
+    v5.40a, March 2019, fig.3-37, p.176
+
+[bhelgaas: commit log]
+Fixes: 5b4cf0f65324 ("PCI: dwc: Add upper limit address for outbound iATU")
+Link: https://lore.kernel.org/r/20220624143428.8334-5-Sergey.Semin@baikalelectronics.ru
+Tested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pcie-designware.c | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
+index ff74ddf2cc35..e863cc2f1e1d 100644
+--- a/drivers/pci/controller/dwc/pcie-designware.c
++++ b/drivers/pci/controller/dwc/pcie-designware.c
+@@ -287,8 +287,8 @@ static void dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, u8 func_no,
+       dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_UPPER_TARGET,
+                                upper_32_bits(pci_addr));
+       val = type | PCIE_ATU_FUNC_NUM(func_no);
+-      val = upper_32_bits(size - 1) ?
+-              val | PCIE_ATU_INCREASE_REGION_SIZE : val;
++      if (upper_32_bits(limit_addr) > upper_32_bits(cpu_addr))
++              val |= PCIE_ATU_INCREASE_REGION_SIZE;
+       if (pci->version == 0x490A)
+               val = dw_pcie_enable_ecrc(val);
+       dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL1, val);
+@@ -315,6 +315,7 @@ static void __dw_pcie_prog_outbound_atu(struct dw_pcie *pci, u8 func_no,
+                                       u64 pci_addr, u64 size)
+ {
+       u32 retries, val;
++      u64 limit_addr;
+       if (pci->ops && pci->ops->cpu_addr_fixup)
+               cpu_addr = pci->ops->cpu_addr_fixup(pci, cpu_addr);
+@@ -325,6 +326,8 @@ static void __dw_pcie_prog_outbound_atu(struct dw_pcie *pci, u8 func_no,
+               return;
+       }
++      limit_addr = cpu_addr + size - 1;
++
+       dw_pcie_writel_dbi(pci, PCIE_ATU_VIEWPORT,
+                          PCIE_ATU_REGION_OUTBOUND | index);
+       dw_pcie_writel_dbi(pci, PCIE_ATU_LOWER_BASE,
+@@ -332,17 +335,18 @@ static void __dw_pcie_prog_outbound_atu(struct dw_pcie *pci, u8 func_no,
+       dw_pcie_writel_dbi(pci, PCIE_ATU_UPPER_BASE,
+                          upper_32_bits(cpu_addr));
+       dw_pcie_writel_dbi(pci, PCIE_ATU_LIMIT,
+-                         lower_32_bits(cpu_addr + size - 1));
++                         lower_32_bits(limit_addr));
+       if (pci->version >= 0x460A)
+               dw_pcie_writel_dbi(pci, PCIE_ATU_UPPER_LIMIT,
+-                                 upper_32_bits(cpu_addr + size - 1));
++                                 upper_32_bits(limit_addr));
+       dw_pcie_writel_dbi(pci, PCIE_ATU_LOWER_TARGET,
+                          lower_32_bits(pci_addr));
+       dw_pcie_writel_dbi(pci, PCIE_ATU_UPPER_TARGET,
+                          upper_32_bits(pci_addr));
+       val = type | PCIE_ATU_FUNC_NUM(func_no);
+-      val = ((upper_32_bits(size - 1)) && (pci->version >= 0x460A)) ?
+-              val | PCIE_ATU_INCREASE_REGION_SIZE : val;
++      if (upper_32_bits(limit_addr) > upper_32_bits(cpu_addr) &&
++          pci->version >= 0x460A)
++              val |= PCIE_ATU_INCREASE_REGION_SIZE;
+       if (pci->version == 0x490A)
+               val = dw_pcie_enable_ecrc(val);
+       dw_pcie_writel_dbi(pci, PCIE_ATU_CR1, val);
+-- 
+2.35.1
+
diff --git a/queue-5.15/pci-dwc-stop-link-on-host_init-errors-and-de-initial.patch b/queue-5.15/pci-dwc-stop-link-on-host_init-errors-and-de-initial.patch
new file mode 100644 (file)
index 0000000..ae6bc1a
--- /dev/null
@@ -0,0 +1,68 @@
+From 783d8a88b29e88e81c4756c17a3f2f1222241f3b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jun 2022 17:34:11 +0300
+Subject: PCI: dwc: Stop link on host_init errors and de-initialization
+
+From: Serge Semin <Sergey.Semin@baikalelectronics.ru>
+
+[ Upstream commit 113fa857b74c947137d845e7e635afcf6a59c43a ]
+
+It's logically correct to undo everything that was done when an error is
+discovered or in the corresponding cleanup counterpart. Otherwise the host
+controller will be left in an undetermined state. Since the link is set up
+in the host_init method, deactivate it there in the cleanup-on-error block
+and stop the link in the antagonistic routine - dw_pcie_host_deinit(). Link
+deactivation is platform-specific and should be implemented in
+dw_pcie_ops.stop_link().
+
+Fixes: 886a9c134755 ("PCI: dwc: Move link handling into common code")
+Link: https://lore.kernel.org/r/20220624143428.8334-2-Sergey.Semin@baikalelectronics.ru
+Tested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../pci/controller/dwc/pcie-designware-host.c    | 16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
+index bc0807fe3fc3..3200e906bcda 100644
+--- a/drivers/pci/controller/dwc/pcie-designware-host.c
++++ b/drivers/pci/controller/dwc/pcie-designware-host.c
+@@ -414,8 +414,14 @@ int dw_pcie_host_init(struct pcie_port *pp)
+       bridge->sysdata = pp;
+       ret = pci_host_probe(bridge);
+-      if (!ret)
+-              return 0;
++      if (ret)
++              goto err_stop_link;
++
++      return 0;
++
++err_stop_link:
++      if (pci->ops && pci->ops->stop_link)
++              pci->ops->stop_link(pci);
+ err_free_msi:
+       if (pp->has_msi_ctrl)
+@@ -426,8 +432,14 @@ EXPORT_SYMBOL_GPL(dw_pcie_host_init);
+ void dw_pcie_host_deinit(struct pcie_port *pp)
+ {
++      struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
++
+       pci_stop_root_bus(pp->bridge->bus);
+       pci_remove_root_bus(pp->bridge->bus);
++
++      if (pci->ops && pci->ops->stop_link)
++              pci->ops->stop_link(pci);
++
+       if (pp->has_msi_ctrl)
+               dw_pcie_free_msi(pp);
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/pci-endpoint-don-t-stop-controller-when-unbinding-en.patch b/queue-5.15/pci-endpoint-don-t-stop-controller-when-unbinding-en.patch
new file mode 100644 (file)
index 0000000..e632866
--- /dev/null
@@ -0,0 +1,41 @@
+From bc44b3631b0577a7e5791b8b01cb6ee9d9f63475 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jun 2022 13:09:24 +0900
+Subject: PCI: endpoint: Don't stop controller when unbinding endpoint function
+
+From: Shunsuke Mie <mie@igel.co.jp>
+
+[ Upstream commit 1bc2b7bfba6e2f64edf5e246f3af2967261f6c3d ]
+
+Unbinding an endpoint function from the endpoint controller shouldn't stop
+the controller.  This is especially a problem for multi-function endpoints
+where other endpoints may still be active.
+
+Don't stop the controller when unbinding one of its endpoints.  Normally
+the controller is stopped via configfs.
+
+Fixes: 349e7a85b25f ("PCI: endpoint: functions: Add an EP function to test PCI")
+Link: https://lore.kernel.org/r/20220622040924.113279-1-mie@igel.co.jp
+Signed-off-by: Shunsuke Mie <mie@igel.co.jp>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Acked-by: Kishon Vijay Abraham I <kishon@ti.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/endpoint/functions/pci-epf-test.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
+index 5b833f00e980..a5ed779b0a51 100644
+--- a/drivers/pci/endpoint/functions/pci-epf-test.c
++++ b/drivers/pci/endpoint/functions/pci-epf-test.c
+@@ -627,7 +627,6 @@ static void pci_epf_test_unbind(struct pci_epf *epf)
+       cancel_delayed_work(&epf_test->cmd_handler);
+       pci_epf_test_clean_dma_chan(epf_test);
+-      pci_epc_stop(epc);
+       for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
+               epf_bar = &epf->bar[bar];
+-- 
+2.35.1
+
diff --git a/queue-5.15/pci-mediatek-gen3-fix-refcount-leak-in-mtk_pcie_init.patch b/queue-5.15/pci-mediatek-gen3-fix-refcount-leak-in-mtk_pcie_init.patch
new file mode 100644 (file)
index 0000000..8c8e69f
--- /dev/null
@@ -0,0 +1,59 @@
+From 2a5e60cd35dd3b4ad3e446219986ca1f3f69aac4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Jun 2022 08:12:58 +0400
+Subject: PCI: mediatek-gen3: Fix refcount leak in mtk_pcie_init_irq_domains()
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit bf038503d5fe90189743124233fe7aeb0984e961 ]
+
+of_get_child_by_name() returns a node pointer with refcount incremented, so
+we should use of_node_put() on it when we don't need it anymore.
+
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: 814cceebba9b ("PCI: mediatek-gen3: Add INTx support")
+Link: https://lore.kernel.org/r/20220601041259.56185-1-linmq006@gmail.com
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Miles Chen <miles.chen@mediatek.com>
+Acked-by: Jianjun Wang <jianjun.wang@mediatek.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/pcie-mediatek-gen3.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c
+index 21207df680cc..36c8702439e9 100644
+--- a/drivers/pci/controller/pcie-mediatek-gen3.c
++++ b/drivers/pci/controller/pcie-mediatek-gen3.c
+@@ -600,7 +600,8 @@ static int mtk_pcie_init_irq_domains(struct mtk_pcie_port *port)
+                                                 &intx_domain_ops, port);
+       if (!port->intx_domain) {
+               dev_err(dev, "failed to create INTx IRQ domain\n");
+-              return -ENODEV;
++              ret = -ENODEV;
++              goto out_put_node;
+       }
+       /* Setup MSI */
+@@ -623,6 +624,7 @@ static int mtk_pcie_init_irq_domains(struct mtk_pcie_port *port)
+               goto err_msi_domain;
+       }
++      of_node_put(intc_node);
+       return 0;
+ err_msi_domain:
+@@ -630,6 +632,8 @@ static int mtk_pcie_init_irq_domains(struct mtk_pcie_port *port)
+ err_msi_bottom_domain:
+       irq_domain_remove(port->intx_domain);
++out_put_node:
++      of_node_put(intc_node);
+       return ret;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/pci-microchip-fix-refcount-leak-in-mc_pcie_init_irq_.patch b/queue-5.15/pci-microchip-fix-refcount-leak-in-mc_pcie_init_irq_.patch
new file mode 100644 (file)
index 0000000..8b95827
--- /dev/null
@@ -0,0 +1,49 @@
+From a08e083d45deac0886f0362029f93d0074fe082e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Jun 2022 09:51:23 +0400
+Subject: PCI: microchip: Fix refcount leak in mc_pcie_init_irq_domains()
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit f030304fdeb87ec8f1b518c73703214aec6cc24a ]
+
+of_get_next_child() returns a node pointer with refcount incremented, so we
+should use of_node_put() on it when we don't need it anymore.
+
+mc_pcie_init_irq_domains() only calls of_node_put() in the normal path,
+missing it in some error paths.  Add missing of_node_put() to avoid
+refcount leak.
+
+Fixes: 6f15a9c9f941 ("PCI: microchip: Add Microchip PolarFire PCIe controller driver")
+Link: https://lore.kernel.org/r/20220605055123.59127-1-linmq006@gmail.com
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/pcie-microchip-host.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/pci/controller/pcie-microchip-host.c b/drivers/pci/controller/pcie-microchip-host.c
+index fa209ad067bf..6e8a6540b377 100644
+--- a/drivers/pci/controller/pcie-microchip-host.c
++++ b/drivers/pci/controller/pcie-microchip-host.c
+@@ -894,6 +894,7 @@ static int mc_pcie_init_irq_domains(struct mc_port *port)
+                                                  &event_domain_ops, port);
+       if (!port->event_domain) {
+               dev_err(dev, "failed to get event domain\n");
++              of_node_put(pcie_intc_node);
+               return -ENOMEM;
+       }
+@@ -903,6 +904,7 @@ static int mc_pcie_init_irq_domains(struct mc_port *port)
+                                                 &intx_domain_ops, port);
+       if (!port->intx_domain) {
+               dev_err(dev, "failed to get an INTx IRQ domain\n");
++              of_node_put(pcie_intc_node);
+               return -ENOMEM;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/pci-portdrv-don-t-disable-aer-reporting-in-get_port_.patch b/queue-5.15/pci-portdrv-don-t-disable-aer-reporting-in-get_port_.patch
new file mode 100644 (file)
index 0000000..5292d6a
--- /dev/null
@@ -0,0 +1,106 @@
+From f71ad8da440de68b7e1b6fa0587b2c086f5bd59f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jan 2022 08:18:19 +0100
+Subject: PCI/portdrv: Don't disable AER reporting in
+ get_port_device_capability()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Stefan Roese <sr@denx.de>
+
+[ Upstream commit 8795e182b02dc87e343c79e73af6b8b7f9c5e635 ]
+
+AER reporting is currently disabled in the DevCtl registers of all non Root
+Port PCIe devices on systems using pcie_ports_native || host->native_aer,
+disabling AER completely in such systems. This is because 2bd50dd800b5
+("PCI: PCIe: Disable PCIe port services during port initialization"), added
+a call to pci_disable_pcie_error_reporting() *after* the AER setup was
+completed for the PCIe device tree.
+
+Here a longer analysis about the current status of AER enabling /
+disabling upon bootup provided by Bjorn:
+
+  pcie_portdrv_probe
+    pcie_port_device_register
+      get_port_device_capability
+        pci_disable_pcie_error_reporting
+          clear CERE NFERE FERE URRE               # <-- disable for RP USP DSP
+      pcie_device_init
+        device_register                            # new AER service device
+          aer_probe
+            aer_enable_rootport                    # RP only
+              set_downstream_devices_error_reporting
+                set_device_error_reporting         # self (RP)
+                  if (RP || USP || DSP)
+                    pci_enable_pcie_error_reporting
+                      set CERE NFERE FERE URRE     # <-- enable for RP
+                pci_walk_bus
+                  set_device_error_reporting
+                    if (RP || USP || DSP)
+                      pci_enable_pcie_error_reporting
+                        set CERE NFERE FERE URRE   # <-- enable for USP DSP
+
+In a typical Root Port -> Endpoint hierarchy, the above:
+  - Disables Error Reporting for the Root Port,
+  - Enables Error Reporting for the Root Port,
+  - Does NOT enable Error Reporting for the Endpoint because it is not a
+    Root Port or Switch Port.
+
+In a deeper Root Port -> Upstream Switch Port -> Downstream Switch
+Port -> Endpoint hierarchy:
+  - Disables Error Reporting for the Root Port,
+  - Enables Error Reporting for the Root Port,
+  - Enables Error Reporting for both Switch Ports,
+  - Does NOT enable Error Reporting for the Endpoint because it is not a
+    Root Port or Switch Port,
+  - Disables Error Reporting for the Switch Ports when pcie_portdrv_probe()
+    claims them.  AER does not re-enable it because these are not Root
+    Ports.
+
+Remove this call to pci_disable_pcie_error_reporting() from
+get_port_device_capability(), leaving the already enabled AER configuration
+intact. With this change, AER is enabled in the Root Port and the PCIe
+switch upstream and downstream ports. Only the PCIe Endpoints don't have
+AER enabled yet. A follow-up patch will take care of this Endpoint
+enabling.
+
+Fixes: 2bd50dd800b5 ("PCI: PCIe: Disable PCIe port services during port initialization")
+Link: https://lore.kernel.org/r/20220125071820.2247260-3-sr@denx.de
+Signed-off-by: Stefan Roese <sr@denx.de>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Pali Rohár <pali@kernel.org>
+Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
+Cc: Bharat Kumar Gogada <bharat.kumar.gogada@xilinx.com>
+Cc: Michal Simek <michal.simek@xilinx.com>
+Cc: Yao Hongbo <yaohongbo@linux.alibaba.com>
+Cc: Naveen Naidu <naveennaidu479@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pcie/portdrv_core.c | 9 +--------
+ 1 file changed, 1 insertion(+), 8 deletions(-)
+
+diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
+index 604feeb84ee4..1ac7fec47d6f 100644
+--- a/drivers/pci/pcie/portdrv_core.c
++++ b/drivers/pci/pcie/portdrv_core.c
+@@ -222,15 +222,8 @@ static int get_port_device_capability(struct pci_dev *dev)
+ #ifdef CONFIG_PCIEAER
+       if (dev->aer_cap && pci_aer_available() &&
+-          (pcie_ports_native || host->native_aer)) {
++          (pcie_ports_native || host->native_aer))
+               services |= PCIE_PORT_SERVICE_AER;
+-
+-              /*
+-               * Disable AER on this port in case it's been enabled by the
+-               * BIOS (the AER service driver will enable it when necessary).
+-               */
+-              pci_disable_pcie_error_reporting(dev);
+-      }
+ #endif
+       /* Root Ports and Root Complex Event Collectors may generate PMEs */
+-- 
+2.35.1
+
diff --git a/queue-5.15/pci-qcom-set-up-rev-2.1.0-parf_phy-before-enabling-c.patch b/queue-5.15/pci-qcom-set-up-rev-2.1.0-parf_phy-before-enabling-c.patch
new file mode 100644 (file)
index 0000000..6774b9f
--- /dev/null
@@ -0,0 +1,68 @@
+From 8d6bce39cb72e9466e73dc27d926c3bf6e341e38 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 9 Jul 2022 00:27:43 +0200
+Subject: PCI: qcom: Set up rev 2.1.0 PARF_PHY before enabling clocks
+
+From: Christian Marangi <ansuelsmth@gmail.com>
+
+[ Upstream commit 38f897ae3d44900f627cad708a15db498ce2ca31 ]
+
+We currently enable clocks BEFORE we write to PARF_PHY_CTRL reg to enable
+clocks and resets. This causes the driver to never set to a ready state
+with the error 'Phy link never came up'.
+
+This is caused by the PHY clock getting enabled before setting the required
+bits in the PARF regs.
+
+A workaround for this was set but with this new discovery we can drop
+the workaround and use a proper solution to the problem by just enabling
+the clock only AFTER the PARF_PHY_CTRL bit is set.
+
+This correctly sets up the PCIe link and makes it usable even when a
+bootloader leaves the PCIe link in an undefined state.
+
+Fixes: 82a823833f4e ("PCI: qcom: Add Qualcomm PCIe controller driver")
+Link: https://lore.kernel.org/r/20220708222743.27019-1-ansuelsmth@gmail.com
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pcie-qcom.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
+index b139a2e4af12..45210c6380b1 100644
+--- a/drivers/pci/controller/dwc/pcie-qcom.c
++++ b/drivers/pci/controller/dwc/pcie-qcom.c
+@@ -325,8 +325,6 @@ static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie)
+       reset_control_assert(res->ext_reset);
+       reset_control_assert(res->phy_reset);
+-      writel(1, pcie->parf + PCIE20_PARF_PHY_CTRL);
+-
+       ret = regulator_bulk_enable(ARRAY_SIZE(res->supplies), res->supplies);
+       if (ret < 0) {
+               dev_err(dev, "cannot enable regulators\n");
+@@ -369,15 +367,15 @@ static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie)
+               goto err_deassert_axi;
+       }
+-      ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
+-      if (ret)
+-              goto err_clks;
+-
+       /* enable PCIe clocks and resets */
+       val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
+       val &= ~BIT(0);
+       writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
++      ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
++      if (ret)
++              goto err_clks;
++
+       if (of_device_is_compatible(node, "qcom,pcie-ipq8064") ||
+           of_device_is_compatible(node, "qcom,pcie-ipq8064-v2")) {
+               writel(PCS_DEEMPH_TX_DEEMPH_GEN1(24) |
+-- 
+2.35.1
+
diff --git a/queue-5.15/pci-tegra194-fix-link-up-retry-sequence.patch b/queue-5.15/pci-tegra194-fix-link-up-retry-sequence.patch
new file mode 100644 (file)
index 0000000..2434cf4
--- /dev/null
@@ -0,0 +1,37 @@
+From 5a7fa6be057ca776b1293cd7ccf1913b646f1ab8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Jul 2022 19:50:50 +0530
+Subject: PCI: tegra194: Fix link up retry sequence
+
+From: Vidya Sagar <vidyas@nvidia.com>
+
+[ Upstream commit e05fd6ae77c3e2cc0dba283005d24b6d56d2b1fa ]
+
+Add the missing DLF capability offset while clearing DL_FEATURE_EXCHANGE_EN
+bit during link up retry.
+
+Link: https://lore.kernel.org/r/20220721142052.25971-15-vidyas@nvidia.com
+Fixes: 56e15a238d92 ("PCI: tegra: Add Tegra194 PCIe support")
+Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pcie-tegra194.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
+index ba9f29d6bca1..bdd84765e646 100644
+--- a/drivers/pci/controller/dwc/pcie-tegra194.c
++++ b/drivers/pci/controller/dwc/pcie-tegra194.c
+@@ -978,7 +978,7 @@ static int tegra_pcie_dw_start_link(struct dw_pcie *pci)
+               offset = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_DLF);
+               val = dw_pcie_readl_dbi(pci, offset + PCI_DLF_CAP);
+               val &= ~PCI_DLF_EXCHANGE_ENABLE;
+-              dw_pcie_writel_dbi(pci, offset, val);
++              dw_pcie_writel_dbi(pci, offset + PCI_DLF_CAP, val);
+               tegra_pcie_dw_host_init(pp);
+               dw_pcie_setup_rc(pp);
+-- 
+2.35.1
+
diff --git a/queue-5.15/pci-tegra194-fix-pm-error-handling-in-tegra_pcie_con.patch b/queue-5.15/pci-tegra194-fix-pm-error-handling-in-tegra_pcie_con.patch
new file mode 100644 (file)
index 0000000..1bce4a0
--- /dev/null
@@ -0,0 +1,40 @@
+From daafff0a7dc0dafcb99bd34792f5cb6d151cdc53 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jun 2022 07:19:08 +0400
+Subject: PCI: tegra194: Fix PM error handling in tegra_pcie_config_ep()
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit e8fbd344a5ea62663554b8546b6bf9f88b93785a ]
+
+pm_runtime_enable() will increase power disable depth.  If
+dw_pcie_ep_init() fails, we should use pm_runtime_disable() to balance it
+with pm_runtime_enable().
+
+Add missing pm_runtime_disable() for tegra_pcie_config_ep().
+
+Fixes: c57247f940e8 ("PCI: tegra: Add support for PCIe endpoint mode in Tegra194")
+Link: https://lore.kernel.org/r/20220602031910.55859-1-linmq006@gmail.com
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Vidya Sagar <vidyas@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pcie-tegra194.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
+index 904976913081..98da2578e4db 100644
+--- a/drivers/pci/controller/dwc/pcie-tegra194.c
++++ b/drivers/pci/controller/dwc/pcie-tegra194.c
+@@ -1951,6 +1951,7 @@ static int tegra_pcie_config_ep(struct tegra_pcie_dw *pcie,
+       if (ret) {
+               dev_err(dev, "Failed to initialize DWC Endpoint subsystem: %d\n",
+                       ret);
++              pm_runtime_disable(dev);
+               return ret;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/pci-tegra194-fix-root-port-interrupt-handling.patch b/queue-5.15/pci-tegra194-fix-root-port-interrupt-handling.patch
new file mode 100644 (file)
index 0000000..f7157ee
--- /dev/null
@@ -0,0 +1,115 @@
+From d4036902501248c242eaa32ddf6fbcbad53a607e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Jul 2022 19:50:46 +0530
+Subject: PCI: tegra194: Fix Root Port interrupt handling
+
+From: Vidya Sagar <vidyas@nvidia.com>
+
+[ Upstream commit 6646e99bcec627e866bc84365af37942c72b4b76 ]
+
+As part of Root Port interrupt handling, level-0 register is read first and
+based on the bits set in that, corresponding level-1 registers are read for
+further interrupt processing. Since both these values are currently read
+into the same 'val' variable, checking level-0 bits the second time around
+is happening on the 'val' variable value of level-1 register contents
+instead of freshly reading the level-0 value again.
+
+Fix by using different variables to store level-0 and level-1 registers
+contents.
+
+Link: https://lore.kernel.org/r/20220721142052.25971-11-vidyas@nvidia.com
+Fixes: 56e15a238d92 ("PCI: tegra: Add Tegra194 PCIe support")
+Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pcie-tegra194.c | 46 +++++++++++-----------
+ 1 file changed, 22 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
+index 98da2578e4db..ba9f29d6bca1 100644
+--- a/drivers/pci/controller/dwc/pcie-tegra194.c
++++ b/drivers/pci/controller/dwc/pcie-tegra194.c
+@@ -352,15 +352,14 @@ static irqreturn_t tegra_pcie_rp_irq_handler(int irq, void *arg)
+       struct tegra_pcie_dw *pcie = arg;
+       struct dw_pcie *pci = &pcie->pci;
+       struct pcie_port *pp = &pci->pp;
+-      u32 val, tmp;
++      u32 val, status_l0, status_l1;
+       u16 val_w;
+-      val = appl_readl(pcie, APPL_INTR_STATUS_L0);
+-      if (val & APPL_INTR_STATUS_L0_LINK_STATE_INT) {
+-              val = appl_readl(pcie, APPL_INTR_STATUS_L1_0_0);
+-              if (val & APPL_INTR_STATUS_L1_0_0_LINK_REQ_RST_NOT_CHGED) {
+-                      appl_writel(pcie, val, APPL_INTR_STATUS_L1_0_0);
+-
++      status_l0 = appl_readl(pcie, APPL_INTR_STATUS_L0);
++      if (status_l0 & APPL_INTR_STATUS_L0_LINK_STATE_INT) {
++              status_l1 = appl_readl(pcie, APPL_INTR_STATUS_L1_0_0);
++              appl_writel(pcie, status_l1, APPL_INTR_STATUS_L1_0_0);
++              if (status_l1 & APPL_INTR_STATUS_L1_0_0_LINK_REQ_RST_NOT_CHGED) {
+                       /* SBR & Surprise Link Down WAR */
+                       val = appl_readl(pcie, APPL_CAR_RESET_OVRD);
+                       val &= ~APPL_CAR_RESET_OVRD_CYA_OVERRIDE_CORE_RST_N;
+@@ -376,15 +375,15 @@ static irqreturn_t tegra_pcie_rp_irq_handler(int irq, void *arg)
+               }
+       }
+-      if (val & APPL_INTR_STATUS_L0_INT_INT) {
+-              val = appl_readl(pcie, APPL_INTR_STATUS_L1_8_0);
+-              if (val & APPL_INTR_STATUS_L1_8_0_AUTO_BW_INT_STS) {
++      if (status_l0 & APPL_INTR_STATUS_L0_INT_INT) {
++              status_l1 = appl_readl(pcie, APPL_INTR_STATUS_L1_8_0);
++              if (status_l1 & APPL_INTR_STATUS_L1_8_0_AUTO_BW_INT_STS) {
+                       appl_writel(pcie,
+                                   APPL_INTR_STATUS_L1_8_0_AUTO_BW_INT_STS,
+                                   APPL_INTR_STATUS_L1_8_0);
+                       apply_bad_link_workaround(pp);
+               }
+-              if (val & APPL_INTR_STATUS_L1_8_0_BW_MGT_INT_STS) {
++              if (status_l1 & APPL_INTR_STATUS_L1_8_0_BW_MGT_INT_STS) {
+                       appl_writel(pcie,
+                                   APPL_INTR_STATUS_L1_8_0_BW_MGT_INT_STS,
+                                   APPL_INTR_STATUS_L1_8_0);
+@@ -396,25 +395,24 @@ static irqreturn_t tegra_pcie_rp_irq_handler(int irq, void *arg)
+               }
+       }
+-      val = appl_readl(pcie, APPL_INTR_STATUS_L0);
+-      if (val & APPL_INTR_STATUS_L0_CDM_REG_CHK_INT) {
+-              val = appl_readl(pcie, APPL_INTR_STATUS_L1_18);
+-              tmp = dw_pcie_readl_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS);
+-              if (val & APPL_INTR_STATUS_L1_18_CDM_REG_CHK_CMPLT) {
++      if (status_l0 & APPL_INTR_STATUS_L0_CDM_REG_CHK_INT) {
++              status_l1 = appl_readl(pcie, APPL_INTR_STATUS_L1_18);
++              val = dw_pcie_readl_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS);
++              if (status_l1 & APPL_INTR_STATUS_L1_18_CDM_REG_CHK_CMPLT) {
+                       dev_info(pci->dev, "CDM check complete\n");
+-                      tmp |= PCIE_PL_CHK_REG_CHK_REG_COMPLETE;
++                      val |= PCIE_PL_CHK_REG_CHK_REG_COMPLETE;
+               }
+-              if (val & APPL_INTR_STATUS_L1_18_CDM_REG_CHK_CMP_ERR) {
++              if (status_l1 & APPL_INTR_STATUS_L1_18_CDM_REG_CHK_CMP_ERR) {
+                       dev_err(pci->dev, "CDM comparison mismatch\n");
+-                      tmp |= PCIE_PL_CHK_REG_CHK_REG_COMPARISON_ERROR;
++                      val |= PCIE_PL_CHK_REG_CHK_REG_COMPARISON_ERROR;
+               }
+-              if (val & APPL_INTR_STATUS_L1_18_CDM_REG_CHK_LOGIC_ERR) {
++              if (status_l1 & APPL_INTR_STATUS_L1_18_CDM_REG_CHK_LOGIC_ERR) {
+                       dev_err(pci->dev, "CDM Logic error\n");
+-                      tmp |= PCIE_PL_CHK_REG_CHK_REG_LOGIC_ERROR;
++                      val |= PCIE_PL_CHK_REG_CHK_REG_LOGIC_ERROR;
+               }
+-              dw_pcie_writel_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS, tmp);
+-              tmp = dw_pcie_readl_dbi(pci, PCIE_PL_CHK_REG_ERR_ADDR);
+-              dev_err(pci->dev, "CDM Error Address Offset = 0x%08X\n", tmp);
++              dw_pcie_writel_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS, val);
++              val = dw_pcie_readl_dbi(pci, PCIE_PL_CHK_REG_ERR_ADDR);
++              dev_err(pci->dev, "CDM Error Address Offset = 0x%08X\n", val);
+       }
+       return IRQ_HANDLED;
+-- 
+2.35.1
+
diff --git a/queue-5.15/perf-symbol-fail-to-read-phdr-workaround.patch b/queue-5.15/perf-symbol-fail-to-read-phdr-workaround.patch
new file mode 100644 (file)
index 0000000..4b847df
--- /dev/null
@@ -0,0 +1,107 @@
+From c2a45f1b38d4c1ed4b2ac9cc5ca54a0ee1c525d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 31 Jul 2022 09:49:23 -0700
+Subject: perf symbol: Fail to read phdr workaround
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 6d518ac7be6223811ab947897273b1bbef846180 ]
+
+The perf jvmti agent doesn't create program headers, in this case
+fallback on section headers as happened previously.
+
+Committer notes:
+
+To test this, from a public post by Ian:
+
+1) download a Java workload dacapo-9.12-MR1-bach.jar from
+https://sourceforge.net/projects/dacapobench/
+
+2) build perf such as "make -C tools/perf O=/tmp/perf NO_LIBBFD=1" it
+should detect Java and create /tmp/perf/libperf-jvmti.so
+
+3) run perf with the jvmti agent:
+
+  perf record -k 1 java -agentpath:/tmp/perf/libperf-jvmti.so -jar dacapo-9.12-MR1-bach.jar -n 10 fop
+
+4) run perf inject:
+
+  perf inject -i perf.data -o perf-injected.data -j
+
+5) run perf report
+
+  perf report -i perf-injected.data | grep org.apache.fop
+
+With this patch reverted I see lots of symbols like:
+
+     0.00%  java             jitted-388040-4656.so  [.] org.apache.fop.fo.FObj.bind(org.apache.fop.fo.PropertyList)
+
+With the patch (2d86612aacb7805f ("perf symbol: Correct address for bss
+symbols")) I see lots of:
+
+  dso__load_sym_internal: failed to find program header for symbol:
+  Lorg/apache/fop/fo/FObj;bind(Lorg/apache/fop/fo/PropertyList;)V
+  st_value: 0x40
+
+Fixes: 2d86612aacb7805f ("perf symbol: Correct address for bss symbols")
+Reviewed-by: Leo Yan <leo.yan@linaro.org>
+Signed-off-by: Ian Rogers <irogers@google.com>
+Tested-by: Leo Yan <leo.yan@linaro.org>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Leo Yan <leo.yan@linaro.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lore.kernel.org/lkml/20220731164923.691193-1-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/symbol-elf.c | 27 ++++++++++++++++++++-------
+ 1 file changed, 20 insertions(+), 7 deletions(-)
+
+diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
+index ef6ced5c5746..cb7b24493782 100644
+--- a/tools/perf/util/symbol-elf.c
++++ b/tools/perf/util/symbol-elf.c
+@@ -1294,16 +1294,29 @@ dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss,
+                       if (elf_read_program_header(syms_ss->elf,
+                                                   (u64)sym.st_value, &phdr)) {
+-                              pr_warning("%s: failed to find program header for "
++                              pr_debug4("%s: failed to find program header for "
+                                          "symbol: %s st_value: %#" PRIx64 "\n",
+                                          __func__, elf_name, (u64)sym.st_value);
+-                              continue;
++                              pr_debug4("%s: adjusting symbol: st_value: %#" PRIx64 " "
++                                      "sh_addr: %#" PRIx64 " sh_offset: %#" PRIx64 "\n",
++                                      __func__, (u64)sym.st_value, (u64)shdr.sh_addr,
++                                      (u64)shdr.sh_offset);
++                              /*
++                               * Fail to find program header, let's rollback
++                               * to use shdr.sh_addr and shdr.sh_offset to
++                               * calibrate symbol's file address, though this
++                               * is not necessary for normal C ELF file, we
++                               * still need to handle java JIT symbols in this
++                               * case.
++                               */
++                              sym.st_value -= shdr.sh_addr - shdr.sh_offset;
++                      } else {
++                              pr_debug4("%s: adjusting symbol: st_value: %#" PRIx64 " "
++                                      "p_vaddr: %#" PRIx64 " p_offset: %#" PRIx64 "\n",
++                                      __func__, (u64)sym.st_value, (u64)phdr.p_vaddr,
++                                      (u64)phdr.p_offset);
++                              sym.st_value -= phdr.p_vaddr - phdr.p_offset;
+                       }
+-                      pr_debug4("%s: adjusting symbol: st_value: %#" PRIx64 " "
+-                                "p_vaddr: %#" PRIx64 " p_offset: %#" PRIx64 "\n",
+-                                __func__, (u64)sym.st_value, (u64)phdr.p_vaddr,
+-                                (u64)phdr.p_offset);
+-                      sym.st_value -= phdr.p_vaddr - phdr.p_offset;
+               }
+               demangled = demangle_sym(dso, kmodule, elf_name);
+-- 
+2.35.1
+
diff --git a/queue-5.15/perf-tools-fix-dso_id-inode-generation-comparison.patch b/queue-5.15/perf-tools-fix-dso_id-inode-generation-comparison.patch
new file mode 100644 (file)
index 0000000..7f8c986
--- /dev/null
@@ -0,0 +1,57 @@
+From 42ea0ae4c3a86772446d2b89e71f0e4f91e160f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Jul 2022 12:31:44 +0300
+Subject: perf tools: Fix dso_id inode generation comparison
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+[ Upstream commit 68566a7cf56bf3148797c218ed45a9de078ef47c ]
+
+Synthesized MMAP events have zero ino_generation, so do not compare
+them to DSOs with a real ino_generation otherwise we end up with a DSO
+without a build id.
+
+Fixes: 0e3149f86b99ddab ("perf dso: Move dso_id from 'struct map' to 'struct dso'")
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: kvm@vger.kernel.org
+Cc: Namhyung Kim <namhyung@kernel.org>
+Link: https://lore.kernel.org/r/20220711093218.10967-2-adrian.hunter@intel.com
+[ Added clarification to the comment from Ian + more detailed explanation from Adrian ]
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/dsos.c | 15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/tools/perf/util/dsos.c b/tools/perf/util/dsos.c
+index 183a81d5b2f9..2db91121bdaf 100644
+--- a/tools/perf/util/dsos.c
++++ b/tools/perf/util/dsos.c
+@@ -20,8 +20,19 @@ static int __dso_id__cmp(struct dso_id *a, struct dso_id *b)
+       if (a->ino > b->ino) return -1;
+       if (a->ino < b->ino) return 1;
+-      if (a->ino_generation > b->ino_generation) return -1;
+-      if (a->ino_generation < b->ino_generation) return 1;
++      /*
++       * Synthesized MMAP events have zero ino_generation, avoid comparing
++       * them with MMAP events with actual ino_generation.
++       *
++       * I found it harmful because the mismatch resulted in a new
++       * dso that did not have a build ID whereas the original dso did have a
++       * build ID. The build ID was essential because the object was not found
++       * otherwise. - Adrian
++       */
++      if (a->ino_generation && b->ino_generation) {
++              if (a->ino_generation > b->ino_generation) return -1;
++              if (a->ino_generation < b->ino_generation) return 1;
++      }
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/phy-samsung-exynosautov9-ufs-correct-tsrv-register-c.patch b/queue-5.15/phy-samsung-exynosautov9-ufs-correct-tsrv-register-c.patch
new file mode 100644 (file)
index 0000000..1ec71c7
--- /dev/null
@@ -0,0 +1,63 @@
+From ce29142adadc39bfaae147435134fe4b1312878e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jun 2022 14:05:36 +0900
+Subject: phy: samsung: exynosautov9-ufs: correct TSRV register configurations
+
+From: Chanho Park <chanho61.park@samsung.com>
+
+[ Upstream commit f7fdc4db071f7ee7d408ea3f083222a060c76623 ]
+
+For exynos auto v9's UFS MPHY, We should use 0x50 offset of TSRV register
+configurations. So, it must be
+
+s/PHY_TRSV_REG_CFG/PHY_TRSV_REG_CFG_AUTOV9/g
+
+Fixes: d64519249e1d ("phy: samsung-ufs: support exynosauto ufs phy driver")
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20220603050536.61957-1-chanho61.park@samsung.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/samsung/phy-exynosautov9-ufs.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/phy/samsung/phy-exynosautov9-ufs.c b/drivers/phy/samsung/phy-exynosautov9-ufs.c
+index 36398a15c2db..d043dfdb598a 100644
+--- a/drivers/phy/samsung/phy-exynosautov9-ufs.c
++++ b/drivers/phy/samsung/phy-exynosautov9-ufs.c
+@@ -31,22 +31,22 @@ static const struct samsung_ufs_phy_cfg exynosautov9_pre_init_cfg[] = {
+       PHY_COMN_REG_CFG(0x023, 0xc0, PWR_MODE_ANY),
+       PHY_COMN_REG_CFG(0x023, 0x00, PWR_MODE_ANY),
+-      PHY_TRSV_REG_CFG(0x042, 0x5d, PWR_MODE_ANY),
+-      PHY_TRSV_REG_CFG(0x043, 0x80, PWR_MODE_ANY),
++      PHY_TRSV_REG_CFG_AUTOV9(0x042, 0x5d, PWR_MODE_ANY),
++      PHY_TRSV_REG_CFG_AUTOV9(0x043, 0x80, PWR_MODE_ANY),
+       END_UFS_PHY_CFG,
+ };
+ /* Calibration for HS mode series A/B */
+ static const struct samsung_ufs_phy_cfg exynosautov9_pre_pwr_hs_cfg[] = {
+-      PHY_TRSV_REG_CFG(0x032, 0xbc, PWR_MODE_HS_ANY),
+-      PHY_TRSV_REG_CFG(0x03c, 0x7f, PWR_MODE_HS_ANY),
+-      PHY_TRSV_REG_CFG(0x048, 0xc0, PWR_MODE_HS_ANY),
++      PHY_TRSV_REG_CFG_AUTOV9(0x032, 0xbc, PWR_MODE_HS_ANY),
++      PHY_TRSV_REG_CFG_AUTOV9(0x03c, 0x7f, PWR_MODE_HS_ANY),
++      PHY_TRSV_REG_CFG_AUTOV9(0x048, 0xc0, PWR_MODE_HS_ANY),
+-      PHY_TRSV_REG_CFG(0x04a, 0x00, PWR_MODE_HS_G3_SER_B),
+-      PHY_TRSV_REG_CFG(0x04b, 0x10, PWR_MODE_HS_G1_SER_B |
+-                                    PWR_MODE_HS_G3_SER_B),
+-      PHY_TRSV_REG_CFG(0x04d, 0x63, PWR_MODE_HS_G3_SER_B),
++      PHY_TRSV_REG_CFG_AUTOV9(0x04a, 0x00, PWR_MODE_HS_G3_SER_B),
++      PHY_TRSV_REG_CFG_AUTOV9(0x04b, 0x10, PWR_MODE_HS_G1_SER_B |
++                              PWR_MODE_HS_G3_SER_B),
++      PHY_TRSV_REG_CFG_AUTOV9(0x04d, 0x63, PWR_MODE_HS_G3_SER_B),
+       END_UFS_PHY_CFG,
+ };
+-- 
+2.35.1
+
diff --git a/queue-5.15/phy-stm32-fix-error-return-in-stm32_usbphyc_phy_init.patch b/queue-5.15/phy-stm32-fix-error-return-in-stm32_usbphyc_phy_init.patch
new file mode 100644 (file)
index 0000000..954affd
--- /dev/null
@@ -0,0 +1,41 @@
+From 8dba61a1b378eb43d64a620f8d17e942bc6a49e9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 15:39:53 +0200
+Subject: phy: stm32: fix error return in stm32_usbphyc_phy_init
+
+From: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
+
+[ Upstream commit 32b378a9179ae4db61cfc5d502717214e6cd1e1c ]
+
+Error code is overridden, in case the PLL doesn't lock. So, the USB
+initialization can continue. This leads to a platform freeze.
+This can be avoided by returning proper error code to avoid USB probe
+freezing the platform. It also displays proper errors in log.
+
+Fixes: 5b1af71280ab ("phy: stm32: rework PLL Lock detection")
+Signed-off-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
+Link: https://lore.kernel.org/r/20220713133953.595134-1-fabrice.gasnier@foss.st.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/st/phy-stm32-usbphyc.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/phy/st/phy-stm32-usbphyc.c b/drivers/phy/st/phy-stm32-usbphyc.c
+index da05642d3bd4..cd0747ab6267 100644
+--- a/drivers/phy/st/phy-stm32-usbphyc.c
++++ b/drivers/phy/st/phy-stm32-usbphyc.c
+@@ -279,7 +279,9 @@ static int stm32_usbphyc_phy_init(struct phy *phy)
+       return 0;
+ pll_disable:
+-      return stm32_usbphyc_pll_disable(usbphyc);
++      stm32_usbphyc_pll_disable(usbphyc);
++
++      return ret;
+ }
+ static int stm32_usbphyc_phy_exit(struct phy *phy)
+-- 
+2.35.1
+
diff --git a/queue-5.15/platform-chrome-cros_ec-always-expose-last-resume-re.patch b/queue-5.15/platform-chrome-cros_ec-always-expose-last-resume-re.patch
new file mode 100644 (file)
index 0000000..581dd87
--- /dev/null
@@ -0,0 +1,64 @@
+From c684564d8f4a3c812e4f63b83934bdf93926fb8e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jun 2022 00:57:26 -0700
+Subject: platform/chrome: cros_ec: Always expose last resume result
+
+From: Stephen Boyd <swboyd@chromium.org>
+
+[ Upstream commit 74bb746407bf0d7c7d126c7731dbcd66d467619b ]
+
+The last resume result exposing logic in cros_ec_sleep_event()
+incorrectly requires S0ix support, which doesn't work on ARM based
+systems where S0ix doesn't exist. That's because cros_ec_sleep_event()
+only reports the last resume result when the EC indicates the last sleep
+event was an S0ix resume. On ARM systems, the last sleep event is always
+S3 resume, but the EC can still detect sleep hang events in case some
+other part of the AP is blocking sleep.
+
+Always expose the last resume result if the EC supports it so that this
+works on all devices regardless of S0ix support. This fixes sleep hang
+detection on ARM based chromebooks like Trogdor.
+
+Cc: Rajat Jain <rajatja@chromium.org>
+Cc: Matthias Kaehlcke <mka@chromium.org>
+Cc: Hsin-Yi Wang <hsinyi@chromium.org>
+Cc: Tzung-Bi Shih <tzungbi@kernel.org>
+Reviewed-by: Guenter Roeck <groeck@chromium.org>
+Reviewed-by: Evan Green <evgreen@chromium.org>
+Fixes: 7235560ac77a ("platform/chrome: Add support for v1 of host sleep event")
+Signed-off-by: Stephen Boyd <swboyd@chromium.org>
+Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
+Link: https://lore.kernel.org/r/20220614075726.2729987-1-swboyd@chromium.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/chrome/cros_ec.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/platform/chrome/cros_ec.c b/drivers/platform/chrome/cros_ec.c
+index ff2a24b0c611..4f0390b10cd3 100644
+--- a/drivers/platform/chrome/cros_ec.c
++++ b/drivers/platform/chrome/cros_ec.c
+@@ -135,16 +135,16 @@ static int cros_ec_sleep_event(struct cros_ec_device *ec_dev, u8 sleep_event)
+       buf.msg.command = EC_CMD_HOST_SLEEP_EVENT;
+       ret = cros_ec_cmd_xfer_status(ec_dev, &buf.msg);
+-
+-      /* For now, report failure to transition to S0ix with a warning. */
++      /* Report failure to transition to system wide suspend with a warning. */
+       if (ret >= 0 && ec_dev->host_sleep_v1 &&
+-          (sleep_event == HOST_SLEEP_EVENT_S0IX_RESUME)) {
++          (sleep_event == HOST_SLEEP_EVENT_S0IX_RESUME ||
++           sleep_event == HOST_SLEEP_EVENT_S3_RESUME)) {
+               ec_dev->last_resume_result =
+                       buf.u.resp1.resume_response.sleep_transitions;
+               WARN_ONCE(buf.u.resp1.resume_response.sleep_transitions &
+                         EC_HOST_RESUME_SLEEP_TIMEOUT,
+-                        "EC detected sleep transition timeout. Total slp_s0 transitions: %d",
++                        "EC detected sleep transition timeout. Total sleep transitions: %d",
+                         buf.u.resp1.resume_response.sleep_transitions &
+                         EC_HOST_RESUME_SLEEP_TRANSITIONS_MASK);
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/platform-olpc-fix-uninitialized-data-in-debugfs-writ.patch b/queue-5.15/platform-olpc-fix-uninitialized-data-in-debugfs-writ.patch
new file mode 100644 (file)
index 0000000..728101b
--- /dev/null
@@ -0,0 +1,50 @@
+From ddc3dad071b30e9bd69cb741be9e8c379783a133 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Jul 2022 21:23:38 +0300
+Subject: platform/olpc: Fix uninitialized data in debugfs write
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit 40ec787e1adf302c11668d4cc69838f4d584187d ]
+
+The call to:
+
+       size = simple_write_to_buffer(cmdbuf, sizeof(cmdbuf), ppos, buf, size);
+
+will succeed if at least one byte is written to the "cmdbuf" buffer.
+The "*ppos" value controls which byte is written.  Another problem is
+that this code does not check for errors so it's possible for the entire
+buffer to be uninitialized.
+
+Inintialize the struct to zero to prevent reading uninitialized stack
+data.
+
+Debugfs is normally only writable by root so the impact of this bug is
+very minimal.
+
+Fixes: 6cca83d498bd ("Platform: OLPC: move debugfs support from x86 EC driver")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Link: https://lore.kernel.org/r/YthIKn+TfZSZMEcM@kili
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/olpc/olpc-ec.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/platform/olpc/olpc-ec.c b/drivers/platform/olpc/olpc-ec.c
+index 4ff5c3a12991..921520475ff6 100644
+--- a/drivers/platform/olpc/olpc-ec.c
++++ b/drivers/platform/olpc/olpc-ec.c
+@@ -264,7 +264,7 @@ static ssize_t ec_dbgfs_cmd_write(struct file *file, const char __user *buf,
+       int i, m;
+       unsigned char ec_cmd[EC_MAX_CMD_ARGS];
+       unsigned int ec_cmd_int[EC_MAX_CMD_ARGS];
+-      char cmdbuf[64];
++      char cmdbuf[64] = "";
+       int ec_cmd_bytes;
+       mutex_lock(&ec_dbgfs_lock);
+-- 
+2.35.1
+
diff --git a/queue-5.15/pm-domains-ensure-genpd_debugfs_dir-exists-before-re.patch b/queue-5.15/pm-domains-ensure-genpd_debugfs_dir-exists-before-re.patch
new file mode 100644 (file)
index 0000000..e73fa5e
--- /dev/null
@@ -0,0 +1,57 @@
+From 1d81b847c1b8e48278f9f74b2158793b2702f286 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Jul 2022 01:16:49 +0800
+Subject: PM: domains: Ensure genpd_debugfs_dir exists before remove
+
+From: Hsin-Yi Wang <hsinyi@chromium.org>
+
+[ Upstream commit 37101d3c719386040ded735a5ec06974f1d94d1f ]
+
+Both genpd_debug_add() and genpd_debug_remove() may be called
+indirectly by other drivers while genpd_debugfs_dir is not yet
+set. For example, drivers can call pm_genpd_init() in probe or
+pm_genpd_init() in probe fail/cleanup path:
+
+pm_genpd_init()
+ --> genpd_debug_add()
+
+pm_genpd_remove()
+ --> genpd_remove()
+   --> genpd_debug_remove()
+
+At this time, genpd_debug_init() may not yet be called.
+
+genpd_debug_add() checks that if genpd_debugfs_dir is NULL, it
+will return directly. Make sure this is also checked
+in pm_genpd_remove(), otherwise components under debugfs root
+which has the same name as other components under pm_genpd may
+be accidentally removed, since NULL represents debugfs root.
+
+Fixes: 718072ceb211 ("PM: domains: create debugfs nodes when adding power domains")
+Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/power/domain.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
+index 0f2e42f36851..7f3d21e6fdfb 100644
+--- a/drivers/base/power/domain.c
++++ b/drivers/base/power/domain.c
+@@ -219,6 +219,9 @@ static void genpd_debug_remove(struct generic_pm_domain *genpd)
+ {
+       struct dentry *d;
++      if (!genpd_debugfs_dir)
++              return;
++
+       d = debugfs_lookup(genpd->name, genpd_debugfs_dir);
+       debugfs_remove(d);
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/pm-hibernate-defer-device-probing-when-resuming-from.patch b/queue-5.15/pm-hibernate-defer-device-probing-when-resuming-from.patch
new file mode 100644 (file)
index 0000000..5bb460a
--- /dev/null
@@ -0,0 +1,106 @@
+From f5147658b6dca15107e2f067a4a8351a6a2889ab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 14:49:58 +0900
+Subject: PM: hibernate: defer device probing when resuming from hibernation
+
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+
+[ Upstream commit 8386c414e27caba8501119948e9551e52b527f59 ]
+
+syzbot is reporting hung task at misc_open() [1], for there is a race
+window of AB-BA deadlock which involves probe_count variable. Currently
+wait_for_device_probe() from snapshot_open() from misc_open() can sleep
+forever with misc_mtx held if probe_count cannot become 0.
+
+When a device is probed by hub_event() work function, probe_count is
+incremented before the probe function starts, and probe_count is
+decremented after the probe function completed.
+
+There are three cases that can prevent probe_count from dropping to 0.
+
+  (a) A device being probed stopped responding (i.e. broken/malicious
+      hardware).
+
+  (b) A process emulating a USB device using /dev/raw-gadget interface
+      stopped responding for some reason.
+
+  (c) New device probe requests keeps coming in before existing device
+      probe requests complete.
+
+The phenomenon syzbot is reporting is (b). A process which is holding
+system_transition_mutex and misc_mtx is waiting for probe_count to become
+0 inside wait_for_device_probe(), but the probe function which is called
+ from hub_event() work function is waiting for the processes which are
+blocked at mutex_lock(&misc_mtx) to respond via /dev/raw-gadget interface.
+
+This patch mitigates (b) by deferring wait_for_device_probe() from
+snapshot_open() to snapshot_write() and snapshot_ioctl(). Please note that
+the possibility of (b) remains as long as any thread which is emulating a
+USB device via /dev/raw-gadget interface can be blocked by uninterruptible
+blocking operations (e.g. mutex_lock()).
+
+Please also note that (a) and (c) are not addressed. Regarding (c), we
+should change the code to wait for only one device which contains the
+image for resuming from hibernation. I don't know how to address (a), for
+use of timeout for wait_for_device_probe() might result in loss of user
+data in the image. Maybe we should require the userland to wait for the
+image device before opening /dev/snapshot interface.
+
+Link: https://syzkaller.appspot.com/bug?extid=358c9ab4c93da7b7238c [1]
+Reported-by: syzbot <syzbot+358c9ab4c93da7b7238c@syzkaller.appspotmail.com>
+Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Tested-by: syzbot <syzbot+358c9ab4c93da7b7238c@syzkaller.appspotmail.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/power/user.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/power/user.c b/kernel/power/user.c
+index 740723bb3885..13cca2e2c2bc 100644
+--- a/kernel/power/user.c
++++ b/kernel/power/user.c
+@@ -26,6 +26,7 @@
+ #include "power.h"
++static bool need_wait;
+ static struct snapshot_data {
+       struct snapshot_handle handle;
+@@ -78,7 +79,7 @@ static int snapshot_open(struct inode *inode, struct file *filp)
+                * Resuming.  We may need to wait for the image device to
+                * appear.
+                */
+-              wait_for_device_probe();
++              need_wait = true;
+               data->swap = -1;
+               data->mode = O_WRONLY;
+@@ -168,6 +169,11 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf,
+       ssize_t res;
+       loff_t pg_offp = *offp & ~PAGE_MASK;
++      if (need_wait) {
++              wait_for_device_probe();
++              need_wait = false;
++      }
++
+       lock_system_sleep();
+       data = filp->private_data;
+@@ -244,6 +250,11 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
+       loff_t size;
+       sector_t offset;
++      if (need_wait) {
++              wait_for_device_probe();
++              need_wait = false;
++      }
++
+       if (_IOC_TYPE(cmd) != SNAPSHOT_IOC_MAGIC)
+               return -ENOTTY;
+       if (_IOC_NR(cmd) > SNAPSHOT_IOC_MAXNR)
+-- 
+2.35.1
+
diff --git a/queue-5.15/powerpc-32-call-mmu_mark_initmem_nx-regardless-of-da.patch b/queue-5.15/powerpc-32-call-mmu_mark_initmem_nx-regardless-of-da.patch
new file mode 100644 (file)
index 0000000..8a0785d
--- /dev/null
@@ -0,0 +1,78 @@
+From 23e2bcbf4c971607aa1e8ad83b74adccde587cfb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jun 2022 12:34:08 +0200
+Subject: powerpc/32: Call mmu_mark_initmem_nx() regardless of data block
+ mapping.
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+[ Upstream commit 980bbf7ca72012d317617fcdbfabe8708e4cef29 ]
+
+mark_initmem_nx() calls either mmu_mark_initmem_nx() or
+set_memory_attr() based on return from v_block_mapped()
+of _sinittext.
+
+But we can now handle text and data independently, so that
+text may be mapped by block even when data is mapped by pages.
+
+On the 8xx for instance, at startup 32Mbytes of memory are
+pinned in TLB. So the pinned entries need to go away for sinittext.
+
+In next patch a BAT will be set to also covers sinittext on book3s/32.
+So it will also be needed to call mmu_mark_initmem_nx() even when
+data above sinittext is not mapped with BATs.
+
+As this is highly dependent on the platform, call mmu_mark_initmem_nx()
+regardless of data block mapping. Then the platform will know what to
+do.
+
+Modify 8xx mmu_mark_initmem_nx() so that inittext mapping is modified
+only when pagealloc debug and kfence are not active, otherwise inittext
+is mapped with standard pages. And don't do anything on kernel text
+which is already mapped with PAGE_KERNEL_TEXT.
+
+Fixes: da1adea07576 ("powerpc/8xx: Allow STRICT_KERNEL_RwX with pinned TLB")
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/db3fc14f3bfa6215b0786ef58a6e2bc1e1f964d7.1655202804.git.christophe.leroy@csgroup.eu
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/mm/nohash/8xx.c | 4 ++--
+ arch/powerpc/mm/pgtable_32.c | 6 +++---
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/arch/powerpc/mm/nohash/8xx.c b/arch/powerpc/mm/nohash/8xx.c
+index 0df9fe29dd56..5348e1f9eb94 100644
+--- a/arch/powerpc/mm/nohash/8xx.c
++++ b/arch/powerpc/mm/nohash/8xx.c
+@@ -183,8 +183,8 @@ void mmu_mark_initmem_nx(void)
+       unsigned long boundary = strict_kernel_rwx_enabled() ? sinittext : etext8;
+       unsigned long einittext8 = ALIGN(__pa(_einittext), SZ_8M);
+-      mmu_mapin_ram_chunk(0, boundary, PAGE_KERNEL_TEXT, false);
+-      mmu_mapin_ram_chunk(boundary, einittext8, PAGE_KERNEL, false);
++      if (!debug_pagealloc_enabled_or_kfence())
++              mmu_mapin_ram_chunk(boundary, einittext8, PAGE_KERNEL, false);
+       mmu_pin_tlb(block_mapped_ram, false);
+ }
+diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
+index f28859771440..502e3d3d1dbf 100644
+--- a/arch/powerpc/mm/pgtable_32.c
++++ b/arch/powerpc/mm/pgtable_32.c
+@@ -138,9 +138,9 @@ void mark_initmem_nx(void)
+       unsigned long numpages = PFN_UP((unsigned long)_einittext) -
+                                PFN_DOWN((unsigned long)_sinittext);
+-      if (v_block_mapped((unsigned long)_sinittext)) {
+-              mmu_mark_initmem_nx();
+-      } else {
++      mmu_mark_initmem_nx();
++
++      if (!v_block_mapped((unsigned long)_sinittext)) {
+               set_memory_nx((unsigned long)_sinittext, numpages);
+               set_memory_rw((unsigned long)_sinittext, numpages);
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/powerpc-32-do-not-allow-selection-of-e5500-or-e6500-.patch b/queue-5.15/powerpc-32-do-not-allow-selection-of-e5500-or-e6500-.patch
new file mode 100644 (file)
index 0000000..ddad3f3
--- /dev/null
@@ -0,0 +1,48 @@
+From d38551ea6ed5f48051bb6dee7f044c88268d6545 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Jul 2022 16:19:29 +0200
+Subject: powerpc/32: Do not allow selection of e5500 or e6500 CPUs on PPC32
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+[ Upstream commit 9be013b2a9ecb29b5168e4b9db0e48ed53acf37c ]
+
+Commit 0e00a8c9fd92 ("powerpc: Allow CPU selection also on PPC32")
+enlarged the CPU selection logic to PPC32 by removing depend to
+PPC64, and failed to restrict that depend to E5500_CPU and E6500_CPU.
+Fortunately that got unnoticed because -mcpu=8540 will override the
+-mcpu=e500mc64 or -mpcu=e6500 as they are ealier, but that's
+fragile and may no be right in the future.
+
+Add back the depend PPC64 on E5500_CPU and E6500_CPU.
+
+Fixes: 0e00a8c9fd92 ("powerpc: Allow CPU selection also on PPC32")
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/8abab4888da69ff78b73a56f64d9678a7bf684e9.1657549153.git.christophe.leroy@csgroup.eu
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/Kconfig.cputype | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
+index 87a95cbff2f3..81f8c9634832 100644
+--- a/arch/powerpc/platforms/Kconfig.cputype
++++ b/arch/powerpc/platforms/Kconfig.cputype
+@@ -170,11 +170,11 @@ config POWER9_CPU
+ config E5500_CPU
+       bool "Freescale e5500"
+-      depends on E500
++      depends on PPC64 && E500
+ config E6500_CPU
+       bool "Freescale e6500"
+-      depends on E500
++      depends on PPC64 && E500
+ config 860_CPU
+       bool "8xx family"
+-- 
+2.35.1
+
diff --git a/queue-5.15/powerpc-64s-disable-stack-variable-initialisation-fo.patch b/queue-5.15/powerpc-64s-disable-stack-variable-initialisation-fo.patch
new file mode 100644 (file)
index 0000000..11bda48
--- /dev/null
@@ -0,0 +1,55 @@
+From bfb4d071c465ee7ed89164b00f4c93e57c466849 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 23:44:18 +1000
+Subject: powerpc/64s: Disable stack variable initialisation for prom_init
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+[ Upstream commit be640317a1d0b9cf42fedb2debc2887a7cfa38de ]
+
+With GCC 12 allmodconfig prom_init fails to build:
+
+  Error: External symbol 'memset' referenced from prom_init.c
+  make[2]: *** [arch/powerpc/kernel/Makefile:204: arch/powerpc/kernel/prom_init_check] Error 1
+
+The allmodconfig build enables KASAN, so all calls to memset in
+prom_init should be converted to __memset by the #ifdefs in
+asm/string.h, because prom_init must use the non-KASAN instrumented
+versions.
+
+The build failure happens because there's a call to memset that hasn't
+been caught by the pre-processor and converted to __memset. Typically
+that's because it's a memset generated by the compiler itself, and that
+is the case here.
+
+With GCC 12, allmodconfig enables CONFIG_INIT_STACK_ALL_PATTERN, which
+causes the compiler to emit memset calls to initialise on-stack
+variables with a pattern.
+
+Because prom_init is non-user-facing boot-time only code, as a
+workaround just disable stack variable initialisation to unbreak the
+build.
+
+Reported-by: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20220718134418.354114-1-mpe@ellerman.id.au
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/Makefile | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
+index b1b23b4d56ba..ed91d5b9ffc6 100644
+--- a/arch/powerpc/kernel/Makefile
++++ b/arch/powerpc/kernel/Makefile
+@@ -20,6 +20,7 @@ CFLAGS_prom.o += $(DISABLE_LATENT_ENTROPY_PLUGIN)
+ CFLAGS_prom_init.o += -fno-stack-protector
+ CFLAGS_prom_init.o += -DDISABLE_BRANCH_PROFILING
+ CFLAGS_prom_init.o += -ffreestanding
++CFLAGS_prom_init.o += $(call cc-option, -ftrivial-auto-var-init=uninitialized)
+ ifdef CONFIG_FUNCTION_TRACER
+ # Do not trace early boot code
+-- 
+2.35.1
+
diff --git a/queue-5.15/powerpc-cell-axon_msi-fix-refcount-leak-in-setup_msi.patch b/queue-5.15/powerpc-cell-axon_msi-fix-refcount-leak-in-setup_msi.patch
new file mode 100644 (file)
index 0000000..03c93fa
--- /dev/null
@@ -0,0 +1,37 @@
+From 422cba82198e647ac45e3607cf2479b2704e124d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Jun 2022 10:51:29 +0400
+Subject: powerpc/cell/axon_msi: Fix refcount leak in setup_msi_msg_address
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit df5d4b616ee76abc97e5bd348e22659c2b095b1c ]
+
+of_get_next_parent() returns a node pointer with refcount incremented,
+we should use of_node_put() on it when not need anymore.
+Add missing of_node_put() in the error path to avoid refcount leak.
+
+Fixes: ce21b3c9648a ("[CELL] add support for MSI on Axon-based Cell systems")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20220605065129.63906-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/cell/axon_msi.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
+index 82335e364c44..f630693c8de7 100644
+--- a/arch/powerpc/platforms/cell/axon_msi.c
++++ b/arch/powerpc/platforms/cell/axon_msi.c
+@@ -226,6 +226,7 @@ static int setup_msi_msg_address(struct pci_dev *dev, struct msi_msg *msg)
+       if (!prop) {
+               dev_dbg(&dev->dev,
+                       "axon_msi: no msi-address-(32|64) properties found\n");
++              of_node_put(dn);
+               return -ENOENT;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/powerpc-iommu-fix-iommu_table_in_use-for-a-small-def.patch b/queue-5.15/powerpc-iommu-fix-iommu_table_in_use-for-a-small-def.patch
new file mode 100644 (file)
index 0000000..fd33869
--- /dev/null
@@ -0,0 +1,55 @@
+From c171e178994cae9648f78df7f4ea7523d7b63077 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 18:11:19 +1000
+Subject: powerpc/iommu: Fix iommu_table_in_use for a small default DMA window
+ case
+
+From: Alexey Kardashevskiy <aik@ozlabs.ru>
+
+[ Upstream commit d80f6de9d601c30b53c17f00cb7cfe3169f2ddad ]
+
+The existing iommu_table_in_use() helper checks if the kernel is using
+any of TCEs. There are some reserved TCEs:
+1) the very first one if DMA window starts from 0 to avoid having a zero
+but still valid DMA handle;
+2) it_reserved_start..it_reserved_end to exclude MMIO32 window in case
+the default window spans across that - this is the default for the first
+DMA window on PowerNV.
+
+When 1) is the case and 2) is not the helper does not skip 1) and returns
+wrong status.
+
+This only seems occurring when passing through a PCI device to a nested
+guest (not something we support really well) so it has not been seen
+before.
+
+This fixes the bug by adding a special case for no MMIO32 reservation.
+
+Fixes: 3c33066a2190 ("powerpc/kernel/iommu: Add new iommu_table_in_use() helper")
+Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20220714081119.3714605-1-aik@ozlabs.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/iommu.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
+index 07093b7cdcb9..a67fd54ccc57 100644
+--- a/arch/powerpc/kernel/iommu.c
++++ b/arch/powerpc/kernel/iommu.c
+@@ -776,6 +776,11 @@ bool iommu_table_in_use(struct iommu_table *tbl)
+       /* ignore reserved bit0 */
+       if (tbl->it_offset == 0)
+               start = 1;
++
++      /* Simple case with no reserved MMIO32 region */
++      if (!tbl->it_reserved_start && !tbl->it_reserved_end)
++              return find_next_bit(tbl->it_map, tbl->it_size, start) != tbl->it_size;
++
+       end = tbl->it_reserved_start - tbl->it_offset;
+       if (find_next_bit(tbl->it_map, end, start) != end)
+               return true;
+-- 
+2.35.1
+
diff --git a/queue-5.15/powerpc-pci-fix-phb-numbering-when-using-opal-phbid.patch b/queue-5.15/powerpc-pci-fix-phb-numbering-when-using-opal-phbid.patch
new file mode 100644 (file)
index 0000000..0d11e91
--- /dev/null
@@ -0,0 +1,61 @@
+From d5913bb567925e43068c313c2f8d46c1518134e5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Aug 2022 20:38:32 +1000
+Subject: powerpc/pci: Fix PHB numbering when using opal-phbid
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+[ Upstream commit f4b39e88b42d13366b831270306326b5c20971ca ]
+
+The recent change to the PHB numbering logic has a logic error in the
+handling of "ibm,opal-phbid".
+
+When an "ibm,opal-phbid" property is present, &prop is written to and
+ret is set to zero.
+
+The following call to of_alias_get_id() is skipped because ret == 0.
+
+But then the if (ret >= 0) is true, and the body of that if statement
+sets prop = ret which throws away the value that was just read from
+"ibm,opal-phbid".
+
+Fix the logic by only doing the ret >= 0 check in the of_alias_get_id()
+case.
+
+Fixes: 0fe1e96fef0a ("powerpc/pci: Prefer PCI domain assignment via DT 'linux,pci-domain' and alias")
+Reviewed-by: Pali Rohár <pali@kernel.org>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20220802105723.1055178-1-mpe@ellerman.id.au
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/pci-common.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
+index 08eea633c380..fc5187c6559a 100644
+--- a/arch/powerpc/kernel/pci-common.c
++++ b/arch/powerpc/kernel/pci-common.c
+@@ -90,11 +90,13 @@ static int get_phb_number(struct device_node *dn)
+       }
+       if (ret)
+               ret = of_property_read_u64(dn, "ibm,opal-phbid", &prop);
+-      if (ret)
++
++      if (ret) {
+               ret = of_alias_get_id(dn, "pci");
+-      if (ret >= 0) {
+-              prop = ret;
+-              ret = 0;
++              if (ret >= 0) {
++                      prop = ret;
++                      ret = 0;
++              }
+       }
+       if (ret) {
+               u32 prop_32;
+-- 
+2.35.1
+
diff --git a/queue-5.15/powerpc-pci-prefer-pci-domain-assignment-via-dt-linu.patch b/queue-5.15/powerpc-pci-prefer-pci-domain-assignment-via-dt-linu.patch
new file mode 100644 (file)
index 0000000..db02c20
--- /dev/null
@@ -0,0 +1,88 @@
+From 404f15aa012e2415615ee5644783787de0013921 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Jul 2022 12:21:48 +0200
+Subject: powerpc/pci: Prefer PCI domain assignment via DT 'linux,pci-domain'
+ and alias
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+[ Upstream commit 0fe1e96fef0a5c53b4c0d1500d356f3906000f81 ]
+
+Other Linux architectures use DT property 'linux,pci-domain' for
+specifying fixed PCI domain of PCI controller specified in Device-Tree.
+
+And lot of Freescale powerpc boards have defined numbered pci alias in
+Device-Tree for every PCIe controller which number specify preferred PCI
+domain.
+
+So prefer usage of DT property 'linux,pci-domain' (via function
+of_get_pci_domain_nr()) and DT pci alias (via function
+of_alias_get_id()) on powerpc architecture for assigning PCI domain to
+PCI controller.
+
+Fixes: 63a72284b159 ("powerpc/pci: Assign fixed PHB number based on device-tree properties")
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20220706102148.5060-2-pali@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/pci-common.c | 27 +++++++++++++++++++--------
+ 1 file changed, 19 insertions(+), 8 deletions(-)
+
+diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
+index c3573430919d..08eea633c380 100644
+--- a/arch/powerpc/kernel/pci-common.c
++++ b/arch/powerpc/kernel/pci-common.c
+@@ -74,16 +74,30 @@ void set_pci_dma_ops(const struct dma_map_ops *dma_ops)
+ static int get_phb_number(struct device_node *dn)
+ {
+       int ret, phb_id = -1;
+-      u32 prop_32;
+       u64 prop;
+       /*
+        * Try fixed PHB numbering first, by checking archs and reading
+-       * the respective device-tree properties. Firstly, try powernv by
+-       * reading "ibm,opal-phbid", only present in OPAL environment.
++       * the respective device-tree properties. Firstly, try reading
++       * standard "linux,pci-domain", then try reading "ibm,opal-phbid"
++       * (only present in powernv OPAL environment), then try device-tree
++       * alias and as the last try to use lower bits of "reg" property.
+        */
+-      ret = of_property_read_u64(dn, "ibm,opal-phbid", &prop);
++      ret = of_get_pci_domain_nr(dn);
++      if (ret >= 0) {
++              prop = ret;
++              ret = 0;
++      }
++      if (ret)
++              ret = of_property_read_u64(dn, "ibm,opal-phbid", &prop);
++      if (ret)
++              ret = of_alias_get_id(dn, "pci");
++      if (ret >= 0) {
++              prop = ret;
++              ret = 0;
++      }
+       if (ret) {
++              u32 prop_32;
+               ret = of_property_read_u32_index(dn, "reg", 1, &prop_32);
+               prop = prop_32;
+       }
+@@ -95,10 +109,7 @@ static int get_phb_number(struct device_node *dn)
+       if ((phb_id >= 0) && !test_and_set_bit(phb_id, phb_bitmap))
+               return phb_id;
+-      /*
+-       * If not pseries nor powernv, or if fixed PHB numbering tried to add
+-       * the same PHB number twice, then fallback to dynamic PHB numbering.
+-       */
++      /* If everything fails then fallback to dynamic PHB numbering. */
+       phb_id = find_first_zero_bit(phb_bitmap, MAX_PHBS);
+       BUG_ON(phb_id >= MAX_PHBS);
+       set_bit(phb_id, phb_bitmap);
+-- 
+2.35.1
+
diff --git a/queue-5.15/powerpc-perf-optimize-clearing-the-pending-pmi-and-r.patch b/queue-5.15/powerpc-perf-optimize-clearing-the-pending-pmi-and-r.patch
new file mode 100644 (file)
index 0000000..a4ce9bb
--- /dev/null
@@ -0,0 +1,157 @@
+From fcd54533295dc5ae2e9c01e3d70022695cfbda56 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 22 May 2022 19:52:56 +0530
+Subject: powerpc/perf: Optimize clearing the pending PMI and remove WARN_ON
+ for PMI check in power_pmu_disable
+
+From: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
+
+[ Upstream commit 890005a7d98f7452cfe86dcfb2aeeb7df01132ce ]
+
+commit 2c9ac51b850d ("powerpc/perf: Fix PMU callbacks to clear
+pending PMI before resetting an overflown PMC") added a new
+function "pmi_irq_pending" in hw_irq.h. This function is to check
+if there is a PMI marked as pending in Paca (PACA_IRQ_PMI).This is
+used in power_pmu_disable in a WARN_ON. The intention here is to
+provide a warning if there is PMI pending, but no counter is found
+overflown.
+
+During some of the perf runs, below warning is hit:
+
+WARNING: CPU: 36 PID: 0 at arch/powerpc/perf/core-book3s.c:1332 power_pmu_disable+0x25c/0x2c0
+ Modules linked in:
+ -----
+
+ NIP [c000000000141c3c] power_pmu_disable+0x25c/0x2c0
+ LR [c000000000141c8c] power_pmu_disable+0x2ac/0x2c0
+ Call Trace:
+ [c000000baffcfb90] [c000000000141c8c] power_pmu_disable+0x2ac/0x2c0 (unreliable)
+ [c000000baffcfc10] [c0000000003e2f8c] perf_pmu_disable+0x4c/0x60
+ [c000000baffcfc30] [c0000000003e3344] group_sched_out.part.124+0x44/0x100
+ [c000000baffcfc80] [c0000000003e353c] __perf_event_disable+0x13c/0x240
+ [c000000baffcfcd0] [c0000000003dd334] event_function+0xc4/0x140
+ [c000000baffcfd20] [c0000000003d855c] remote_function+0x7c/0xa0
+ [c000000baffcfd50] [c00000000026c394] flush_smp_call_function_queue+0xd4/0x300
+ [c000000baffcfde0] [c000000000065b24] smp_ipi_demux_relaxed+0xa4/0x100
+ [c000000baffcfe20] [c0000000000cb2b0] xive_muxed_ipi_action+0x20/0x40
+ [c000000baffcfe40] [c000000000207c3c] __handle_irq_event_percpu+0x8c/0x250
+ [c000000baffcfee0] [c000000000207e2c] handle_irq_event_percpu+0x2c/0xa0
+ [c000000baffcff10] [c000000000210a04] handle_percpu_irq+0x84/0xc0
+ [c000000baffcff40] [c000000000205f14] generic_handle_irq+0x54/0x80
+ [c000000baffcff60] [c000000000015740] __do_irq+0x90/0x1d0
+ [c000000baffcff90] [c000000000016990] __do_IRQ+0xc0/0x140
+ [c0000009732f3940] [c000000bafceaca8] 0xc000000bafceaca8
+ [c0000009732f39d0] [c000000000016b78] do_IRQ+0x168/0x1c0
+ [c0000009732f3a00] [c0000000000090c8] hardware_interrupt_common_virt+0x218/0x220
+
+This means that there is no PMC overflown among the active events
+in the PMU, but there is a PMU pending in Paca. The function
+"any_pmc_overflown" checks the PMCs on active events in
+cpuhw->n_events. Code snippet:
+
+<<>>
+if (any_pmc_overflown(cpuhw))
+       clear_pmi_irq_pending();
+ else
+       WARN_ON(pmi_irq_pending());
+<<>>
+
+Here the PMC overflown is not from active event. Example: When we do
+perf record, default cycles and instructions will be running on PMC6
+and PMC5 respectively. It could happen that overflowed event is currently
+not active and pending PMI is for the inactive event. Debug logs from
+trace_printk:
+
+<<>>
+any_pmc_overflown: idx is 5: pmc value is 0xd9a
+power_pmu_disable: PMC1: 0x0, PMC2: 0x0, PMC3: 0x0, PMC4: 0x0, PMC5: 0xd9a, PMC6: 0x80002011
+<<>>
+
+Here active PMC (from idx) is PMC5 , but overflown PMC is PMC6(0x80002011).
+When we handle PMI interrupt for such cases, if the PMC overflown is
+from inactive event, it will be ignored. Reference commit:
+commit bc09c219b2e6 ("powerpc/perf: Fix finding overflowed PMC in interrupt")
+
+Patch addresses two changes:
+1) Fix 1 : Removal of warning ( WARN_ON(pmi_irq_pending()); )
+   We were printing warning if no PMC is found overflown among active PMU
+   events, but PMI pending in PACA. But this could happen in cases where
+   PMC overflown is not in active PMC. An inactive event could have caused
+   the overflow. Hence the warning is not needed. To know pending PMI is
+   from an inactive event, we need to loop through all PMC's which will
+   cause more SPR reads via mfspr and increase in context switch. Also in
+   existing function: perf_event_interrupt, already we ignore PMI's
+   overflown when it is from an inactive PMC.
+
+2) Fix 2: optimization in clearing pending PMI.
+   Currently we check for any active PMC overflown before clearing PMI
+   pending in Paca. This is causing additional SPR read also. From point 1,
+   we know that if PMI pending in Paca from inactive cases, that is going
+   to be ignored during replay. Hence if there is pending PMI in Paca, just
+   clear it irrespective of PMC overflown or not.
+
+In summary, remove the any_pmc_overflown check entirely in
+power_pmu_disable. ie If there is a pending PMI in Paca, clear it, since
+we are in pmu_disable. There could be cases where PMI is pending because
+of inactive PMC ( which later when replayed also will get ignored ), so
+WARN_ON could give false warning. Hence removing it.
+
+Fixes: 2c9ac51b850d ("powerpc/perf: Fix PMU callbacks to clear pending PMI before resetting an overflown PMC")
+Signed-off-by: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20220522142256.24699-1-atrajeev@linux.vnet.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/perf/core-book3s.c | 35 ++++++++++++++-------------------
+ 1 file changed, 15 insertions(+), 20 deletions(-)
+
+diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
+index e78de7050947..1078784b74c9 100644
+--- a/arch/powerpc/perf/core-book3s.c
++++ b/arch/powerpc/perf/core-book3s.c
+@@ -1320,27 +1320,22 @@ static void power_pmu_disable(struct pmu *pmu)
+                * a PMI happens during interrupt replay and perf counter
+                * values are cleared by PMU callbacks before replay.
+                *
+-               * If any PMC corresponding to the active PMU events are
+-               * overflown, disable the interrupt by clearing the paca
+-               * bit for PMI since we are disabling the PMU now.
+-               * Otherwise provide a warning if there is PMI pending, but
+-               * no counter is found overflown.
++               * Disable the interrupt by clearing the paca bit for PMI
++               * since we are disabling the PMU now. Otherwise provide a
++               * warning if there is PMI pending, but no counter is found
++               * overflown.
++               *
++               * Since power_pmu_disable runs under local_irq_save, it
++               * could happen that code hits a PMC overflow without PMI
++               * pending in paca. Hence only clear PMI pending if it was
++               * set.
++               *
++               * If a PMI is pending, then MSR[EE] must be disabled (because
++               * the masked PMI handler disabling EE). So it is safe to
++               * call clear_pmi_irq_pending().
+                */
+-              if (any_pmc_overflown(cpuhw)) {
+-                      /*
+-                       * Since power_pmu_disable runs under local_irq_save, it
+-                       * could happen that code hits a PMC overflow without PMI
+-                       * pending in paca. Hence only clear PMI pending if it was
+-                       * set.
+-                       *
+-                       * If a PMI is pending, then MSR[EE] must be disabled (because
+-                       * the masked PMI handler disabling EE). So it is safe to
+-                       * call clear_pmi_irq_pending().
+-                       */
+-                      if (pmi_irq_pending())
+-                              clear_pmi_irq_pending();
+-              } else
+-                      WARN_ON(pmi_irq_pending());
++              if (pmi_irq_pending())
++                      clear_pmi_irq_pending();
+               val = mmcra = cpuhw->mmcr.mmcra;
+-- 
+2.35.1
+
diff --git a/queue-5.15/powerpc-spufs-fix-refcount-leak-in-spufs_init_isolat.patch b/queue-5.15/powerpc-spufs-fix-refcount-leak-in-spufs_init_isolat.patch
new file mode 100644 (file)
index 0000000..9b85fe7
--- /dev/null
@@ -0,0 +1,38 @@
+From dc8a9e133c19ea9a9260199e1e04b872f644d636 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jun 2022 16:15:42 +0400
+Subject: powerpc/spufs: Fix refcount leak in spufs_init_isolated_loader
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 6ac059dacffa8ab2f7798f20e4bd3333890c541c ]
+
+of_find_node_by_path() returns remote device nodepointer with
+refcount incremented, we should use of_node_put() on it when done.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: 0afacde3df4c ("[POWERPC] spufs: allow isolated mode apps by starting the SPE loader")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Acked-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20220603121543.22884-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/cell/spufs/inode.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
+index bed05b644c2c..ed37a93bf858 100644
+--- a/arch/powerpc/platforms/cell/spufs/inode.c
++++ b/arch/powerpc/platforms/cell/spufs/inode.c
+@@ -659,6 +659,7 @@ spufs_init_isolated_loader(void)
+               return;
+       loader = of_get_property(dn, "loader", &size);
++      of_node_put(dn);
+       if (!loader)
+               return;
+-- 
+2.35.1
+
diff --git a/queue-5.15/powerpc-xive-fix-refcount-leak-in-xive_get_max_prio.patch b/queue-5.15/powerpc-xive-fix-refcount-leak-in-xive_get_max_prio.patch
new file mode 100644 (file)
index 0000000..8f54705
--- /dev/null
@@ -0,0 +1,37 @@
+From abd06508dd9a970416c14d883f9a0aacf01446f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Jun 2022 09:32:23 +0400
+Subject: powerpc/xive: Fix refcount leak in xive_get_max_prio
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 255b650cbec6849443ce2e0cdd187fd5e61c218c ]
+
+of_find_node_by_path() returns a node pointer with
+refcount incremented, we should use of_node_put() on it when done.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: eac1e731b59e ("powerpc/xive: guest exploitation of the XIVE interrupt controller")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20220605053225.56125-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/sysdev/xive/spapr.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/powerpc/sysdev/xive/spapr.c b/arch/powerpc/sysdev/xive/spapr.c
+index 583b2c6df390..2bf78a30238b 100644
+--- a/arch/powerpc/sysdev/xive/spapr.c
++++ b/arch/powerpc/sysdev/xive/spapr.c
+@@ -716,6 +716,7 @@ static bool xive_get_max_prio(u8 *max_prio)
+       }
+       reg = of_get_property(rootdn, "ibm,plat-res-int-priorities", &len);
++      of_node_put(rootdn);
+       if (!reg) {
+               pr_err("Failed to read 'ibm,plat-res-int-priorities' property\n");
+               return false;
+-- 
+2.35.1
+
diff --git a/queue-5.15/proc-fix-a-dentry-lock-race-between-release_task-and.patch b/queue-5.15/proc-fix-a-dentry-lock-race-between-release_task-and.patch
new file mode 100644 (file)
index 0000000..d8226f0
--- /dev/null
@@ -0,0 +1,168 @@
+From f7fe51d7d10b733d8d7db46c9955989032a96da0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 21:00:29 +0800
+Subject: proc: fix a dentry lock race between release_task and lookup
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+
+[ Upstream commit d919a1e79bac890421537cf02ae773007bf55e6b ]
+
+Commit 7bc3e6e55acf06 ("proc: Use a list of inodes to flush from proc")
+moved proc_flush_task() behind __exit_signal().  Then, process systemd can
+take long period high cpu usage during releasing task in following
+concurrent processes:
+
+  systemd                                 ps
+kernel_waitid                 stat(/proc/tgid)
+  do_wait                       filename_lookup
+    wait_consider_task            lookup_fast
+      release_task
+        __exit_signal
+          __unhash_process
+            detach_pid
+              __change_pid // remove task->pid_links
+                                     d_revalidate -> pid_revalidate  // 0
+                                     d_invalidate(/proc/tgid)
+                                       shrink_dcache_parent(/proc/tgid)
+                                         d_walk(/proc/tgid)
+                                           spin_lock_nested(/proc/tgid/fd)
+                                           // iterating opened fd
+        proc_flush_pid                                    |
+           d_invalidate (/proc/tgid/fd)                   |
+              shrink_dcache_parent(/proc/tgid/fd)         |
+                shrink_dentry_list(subdirs)               ↓
+                  shrink_lock_dentry(/proc/tgid/fd) --> race on dentry lock
+
+Function d_invalidate() will remove dentry from hash firstly, but why does
+proc_flush_pid() process dentry '/proc/tgid/fd' before dentry
+'/proc/tgid'?  That's because proc_pid_make_inode() adds proc inode in
+reverse order by invoking hlist_add_head_rcu().  But proc should not add
+any inodes under '/proc/tgid' except '/proc/tgid/task/pid', fix it by
+adding inode into 'pid->inodes' only if the inode is /proc/tgid or
+/proc/tgid/task/pid.
+
+Performance regression:
+Create 200 tasks, each task open one file for 50,000 times. Kill all
+tasks when opened files exceed 10,000,000 (cat /proc/sys/fs/file-nr).
+
+Before fix:
+$ time killall -wq aa
+  real    4m40.946s   # During this period, we can see 'ps' and 'systemd'
+                       taking high cpu usage.
+
+After fix:
+$ time killall -wq aa
+  real    1m20.732s   # During this period, we can see 'systemd' taking
+                       high cpu usage.
+
+Link: https://lkml.kernel.org/r/20220713130029.4133533-1-chengzhihao1@huawei.com
+Fixes: 7bc3e6e55acf06 ("proc: Use a list of inodes to flush from proc")
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=216054
+Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
+Suggested-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Brian Foster <bfoster@redhat.com>
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Cc: Alexey Dobriyan <adobriyan@gmail.com>
+Cc: Eric Biederman <ebiederm@xmission.com>
+Cc: Matthew Wilcox <willy@infradead.org>
+Cc: Baoquan He <bhe@redhat.com>
+Cc: Kalesh Singh <kaleshsingh@google.com>
+Cc: Yu Kuai <yukuai3@huawei.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/proc/base.c | 46 ++++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 38 insertions(+), 8 deletions(-)
+
+diff --git a/fs/proc/base.c b/fs/proc/base.c
+index 1f394095eb88..300d53ee7040 100644
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -1886,7 +1886,7 @@ void proc_pid_evict_inode(struct proc_inode *ei)
+       put_pid(pid);
+ }
+-struct inode *proc_pid_make_inode(struct super_block * sb,
++struct inode *proc_pid_make_inode(struct super_block *sb,
+                                 struct task_struct *task, umode_t mode)
+ {
+       struct inode * inode;
+@@ -1915,11 +1915,6 @@ struct inode *proc_pid_make_inode(struct super_block * sb,
+       /* Let the pid remember us for quick removal */
+       ei->pid = pid;
+-      if (S_ISDIR(mode)) {
+-              spin_lock(&pid->lock);
+-              hlist_add_head_rcu(&ei->sibling_inodes, &pid->inodes);
+-              spin_unlock(&pid->lock);
+-      }
+       task_dump_owner(task, 0, &inode->i_uid, &inode->i_gid);
+       security_task_to_inode(task, inode);
+@@ -1932,6 +1927,39 @@ struct inode *proc_pid_make_inode(struct super_block * sb,
+       return NULL;
+ }
++/*
++ * Generating an inode and adding it into @pid->inodes, so that task will
++ * invalidate inode's dentry before being released.
++ *
++ * This helper is used for creating dir-type entries under '/proc' and
++ * '/proc/<tgid>/task'. Other entries(eg. fd, stat) under '/proc/<tgid>'
++ * can be released by invalidating '/proc/<tgid>' dentry.
++ * In theory, dentries under '/proc/<tgid>/task' can also be released by
++ * invalidating '/proc/<tgid>' dentry, we reserve it to handle single
++ * thread exiting situation: Any one of threads should invalidate its
++ * '/proc/<tgid>/task/<pid>' dentry before released.
++ */
++static struct inode *proc_pid_make_base_inode(struct super_block *sb,
++                              struct task_struct *task, umode_t mode)
++{
++      struct inode *inode;
++      struct proc_inode *ei;
++      struct pid *pid;
++
++      inode = proc_pid_make_inode(sb, task, mode);
++      if (!inode)
++              return NULL;
++
++      /* Let proc_flush_pid find this directory inode */
++      ei = PROC_I(inode);
++      pid = ei->pid;
++      spin_lock(&pid->lock);
++      hlist_add_head_rcu(&ei->sibling_inodes, &pid->inodes);
++      spin_unlock(&pid->lock);
++
++      return inode;
++}
++
+ int pid_getattr(struct user_namespace *mnt_userns, const struct path *path,
+               struct kstat *stat, u32 request_mask, unsigned int query_flags)
+ {
+@@ -3349,7 +3377,8 @@ static struct dentry *proc_pid_instantiate(struct dentry * dentry,
+ {
+       struct inode *inode;
+-      inode = proc_pid_make_inode(dentry->d_sb, task, S_IFDIR | S_IRUGO | S_IXUGO);
++      inode = proc_pid_make_base_inode(dentry->d_sb, task,
++                                       S_IFDIR | S_IRUGO | S_IXUGO);
+       if (!inode)
+               return ERR_PTR(-ENOENT);
+@@ -3648,7 +3677,8 @@ static struct dentry *proc_task_instantiate(struct dentry *dentry,
+       struct task_struct *task, const void *ptr)
+ {
+       struct inode *inode;
+-      inode = proc_pid_make_inode(dentry->d_sb, task, S_IFDIR | S_IRUGO | S_IXUGO);
++      inode = proc_pid_make_base_inode(dentry->d_sb, task,
++                                       S_IFDIR | S_IRUGO | S_IXUGO);
+       if (!inode)
+               return ERR_PTR(-ENOENT);
+-- 
+2.35.1
+
diff --git a/queue-5.15/profiling-fix-shift-too-large-makes-kernel-panic.patch b/queue-5.15/profiling-fix-shift-too-large-makes-kernel-panic.patch
new file mode 100644 (file)
index 0000000..37b5e59
--- /dev/null
@@ -0,0 +1,91 @@
+From 83739a1aa5ed9f6102f23f2edfbb1f1d769cf773 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 31 May 2022 09:28:54 +0800
+Subject: profiling: fix shift too large makes kernel panic
+
+From: Chen Zhongjin <chenzhongjin@huawei.com>
+
+[ Upstream commit 0fe6ee8f123a4dfb529a5aff07536bb481f34043 ]
+
+2d186afd04d6 ("profiling: fix shift-out-of-bounds bugs") limits shift
+value by [0, BITS_PER_LONG -1], which means [0, 63].
+
+However, syzbot found that the max shift value should be the bit number of
+(_etext - _stext).  If shift is outside of this, the "buffer_bytes" will
+be zero and will cause kzalloc(0).  Then the kernel panics due to
+dereferencing the returned pointer 16.
+
+This can be easily reproduced by passing a large number like 60 to enable
+profiling and then run readprofile.
+
+LOGS:
+ BUG: kernel NULL pointer dereference, address: 0000000000000010
+ #PF: supervisor write access in kernel mode
+ #PF: error_code(0x0002) - not-present page
+ PGD 6148067 P4D 6148067 PUD 6142067 PMD 0
+ PREEMPT SMP
+ CPU: 4 PID: 184 Comm: readprofile Not tainted 5.18.0+ #162
+ Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.15.0-0-g2dd4b9b3f840-prebuilt.qemu.org 04/01/2014
+ RIP: 0010:read_profile+0x104/0x220
+ RSP: 0018:ffffc900006fbe80 EFLAGS: 00000202
+ RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000
+ RDX: ffff888006150000 RSI: 0000000000000001 RDI: ffffffff82aba4a0
+ RBP: 000000000188bb60 R08: 0000000000000010 R09: ffff888006151000
+ R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff82aba4a0
+ R13: 0000000000000000 R14: ffffc900006fbf08 R15: 0000000000020c30
+ FS:  000000000188a8c0(0000) GS:ffff88803ed00000(0000) knlGS:0000000000000000
+ CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 0000000000000010 CR3: 0000000006144000 CR4: 00000000000006e0
+ Call Trace:
+  <TASK>
+  proc_reg_read+0x56/0x70
+  vfs_read+0x9a/0x1b0
+  ksys_read+0xa1/0xe0
+  ? fpregs_assert_state_consistent+0x1e/0x40
+  do_syscall_64+0x3a/0x80
+  entry_SYSCALL_64_after_hwframe+0x46/0xb0
+ RIP: 0033:0x4d4b4e
+ RSP: 002b:00007ffebb668d58 EFLAGS: 00000246 ORIG_RAX: 0000000000000000
+ RAX: ffffffffffffffda RBX: 000000000188a8a0 RCX: 00000000004d4b4e
+ RDX: 0000000000000400 RSI: 000000000188bb60 RDI: 0000000000000003
+ RBP: 0000000000000003 R08: 000000000000006e R09: 0000000000000000
+ R10: 0000000000000041 R11: 0000000000000246 R12: 000000000188bb60
+ R13: 0000000000000400 R14: 0000000000000000 R15: 000000000188bb60
+  </TASK>
+ Modules linked in:
+ CR2: 0000000000000010
+Killed
+ ---[ end trace 0000000000000000 ]---
+
+Check prof_len in profile_init() to prevent it be zero.
+
+Link: https://lkml.kernel.org/r/20220531012854.229439-1-chenzhongjin@huawei.com
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Chen Zhongjin <chenzhongjin@huawei.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/profile.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/kernel/profile.c b/kernel/profile.c
+index eb9c7f0f5ac5..0db1122855c0 100644
+--- a/kernel/profile.c
++++ b/kernel/profile.c
+@@ -109,6 +109,13 @@ int __ref profile_init(void)
+       /* only text is profiled */
+       prof_len = (_etext - _stext) >> prof_shift;
++
++      if (!prof_len) {
++              pr_warn("profiling shift: %u too large\n", prof_shift);
++              prof_on = 0;
++              return -EINVAL;
++      }
++
+       buffer_bytes = prof_len*sizeof(atomic_t);
+       if (!alloc_cpumask_var(&prof_cpu_mask, GFP_KERNEL))
+-- 
+2.35.1
+
diff --git a/queue-5.15/pwm-lpc18xx-fix-period-handling.patch b/queue-5.15/pwm-lpc18xx-fix-period-handling.patch
new file mode 100644 (file)
index 0000000..7d03a51
--- /dev/null
@@ -0,0 +1,145 @@
+From 265b09714e84e02cc9f208537a89f1c1b287a15f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Jul 2022 18:15:19 +0200
+Subject: pwm: lpc18xx: Fix period handling
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 8933d30c5f468d6cc1e4bf9bb535149da35f202e ]
+
+The calculation:
+
+       val = (u64)NSEC_PER_SEC * LPC18XX_PWM_TIMER_MAX;
+       do_div(val, lpc18xx_pwm->clk_rate);
+       lpc18xx_pwm->max_period_ns = val;
+
+is bogus because with NSEC_PER_SEC = 1000000000,
+LPC18XX_PWM_TIMER_MAX = 0xffffffff and clk_rate < NSEC_PER_SEC this
+overflows the (on lpc18xx (i.e. ARM32) 32 bit wide) unsigned int
+.max_period_ns. This results (dependant of the actual clk rate) in an
+arbitrary limitation of the maximal period.  E.g. for clkrate =
+333333333 (Hz) we get max_period_ns = 9 instead of 12884901897.
+
+So make .max_period_ns an u64 and pass period and duty as u64 to not
+discard relevant digits. And also make use of mul_u64_u64_div_u64()
+which prevents all overflows assuming clk_rate < NSEC_PER_SEC.
+
+Fixes: 841e6f90bb78 ("pwm: NXP LPC18xx PWM/SCT driver")
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pwm/pwm-lpc18xx-sct.c | 55 +++++++++++++++++++++++++----------
+ 1 file changed, 39 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/pwm/pwm-lpc18xx-sct.c b/drivers/pwm/pwm-lpc18xx-sct.c
+index b909096dba2f..43b5509dde51 100644
+--- a/drivers/pwm/pwm-lpc18xx-sct.c
++++ b/drivers/pwm/pwm-lpc18xx-sct.c
+@@ -98,7 +98,7 @@ struct lpc18xx_pwm_chip {
+       unsigned long clk_rate;
+       unsigned int period_ns;
+       unsigned int min_period_ns;
+-      unsigned int max_period_ns;
++      u64 max_period_ns;
+       unsigned int period_event;
+       unsigned long event_map;
+       struct mutex res_lock;
+@@ -145,40 +145,48 @@ static void lpc18xx_pwm_set_conflict_res(struct lpc18xx_pwm_chip *lpc18xx_pwm,
+       mutex_unlock(&lpc18xx_pwm->res_lock);
+ }
+-static void lpc18xx_pwm_config_period(struct pwm_chip *chip, int period_ns)
++static void lpc18xx_pwm_config_period(struct pwm_chip *chip, u64 period_ns)
+ {
+       struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip);
+-      u64 val;
++      u32 val;
+-      val = (u64)period_ns * lpc18xx_pwm->clk_rate;
+-      do_div(val, NSEC_PER_SEC);
++      /*
++       * With clk_rate < NSEC_PER_SEC this cannot overflow.
++       * With period_ns < max_period_ns this also fits into an u32.
++       * As period_ns >= min_period_ns = DIV_ROUND_UP(NSEC_PER_SEC, lpc18xx_pwm->clk_rate);
++       * we have val >= 1.
++       */
++      val = mul_u64_u64_div_u64(period_ns, lpc18xx_pwm->clk_rate, NSEC_PER_SEC);
+       lpc18xx_pwm_writel(lpc18xx_pwm,
+                          LPC18XX_PWM_MATCH(lpc18xx_pwm->period_event),
+-                         (u32)val - 1);
++                         val - 1);
+       lpc18xx_pwm_writel(lpc18xx_pwm,
+                          LPC18XX_PWM_MATCHREL(lpc18xx_pwm->period_event),
+-                         (u32)val - 1);
++                         val - 1);
+ }
+ static void lpc18xx_pwm_config_duty(struct pwm_chip *chip,
+-                                  struct pwm_device *pwm, int duty_ns)
++                                  struct pwm_device *pwm, u64 duty_ns)
+ {
+       struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip);
+       struct lpc18xx_pwm_data *lpc18xx_data = &lpc18xx_pwm->channeldata[pwm->hwpwm];
+-      u64 val;
++      u32 val;
+-      val = (u64)duty_ns * lpc18xx_pwm->clk_rate;
+-      do_div(val, NSEC_PER_SEC);
++      /*
++       * With clk_rate < NSEC_PER_SEC this cannot overflow.
++       * With duty_ns <= period_ns < max_period_ns this also fits into an u32.
++       */
++      val = mul_u64_u64_div_u64(duty_ns, lpc18xx_pwm->clk_rate, NSEC_PER_SEC);
+       lpc18xx_pwm_writel(lpc18xx_pwm,
+                          LPC18XX_PWM_MATCH(lpc18xx_data->duty_event),
+-                         (u32)val);
++                         val);
+       lpc18xx_pwm_writel(lpc18xx_pwm,
+                          LPC18XX_PWM_MATCHREL(lpc18xx_data->duty_event),
+-                         (u32)val);
++                         val);
+ }
+ static int lpc18xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+@@ -360,12 +368,27 @@ static int lpc18xx_pwm_probe(struct platform_device *pdev)
+               goto disable_pwmclk;
+       }
++      /*
++       * If clkrate is too fast, the calculations in .apply() might overflow.
++       */
++      if (lpc18xx_pwm->clk_rate > NSEC_PER_SEC) {
++              ret = dev_err_probe(&pdev->dev, -EINVAL, "pwm clock to fast\n");
++              goto disable_pwmclk;
++      }
++
++      /*
++       * If clkrate is too fast, the calculations in .apply() might overflow.
++       */
++      if (lpc18xx_pwm->clk_rate > NSEC_PER_SEC) {
++              ret = dev_err_probe(&pdev->dev, -EINVAL, "pwm clock to fast\n");
++              goto disable_pwmclk;
++      }
++
+       mutex_init(&lpc18xx_pwm->res_lock);
+       mutex_init(&lpc18xx_pwm->period_lock);
+-      val = (u64)NSEC_PER_SEC * LPC18XX_PWM_TIMER_MAX;
+-      do_div(val, lpc18xx_pwm->clk_rate);
+-      lpc18xx_pwm->max_period_ns = val;
++      lpc18xx_pwm->max_period_ns =
++              mul_u64_u64_div_u64(NSEC_PER_SEC, LPC18XX_PWM_TIMER_MAX, lpc18xx_pwm->clk_rate);
+       lpc18xx_pwm->min_period_ns = DIV_ROUND_UP(NSEC_PER_SEC,
+                                                 lpc18xx_pwm->clk_rate);
+-- 
+2.35.1
+
diff --git a/queue-5.15/pwm-lpc18xx-sct-reduce-number-of-devm-memory-allocat.patch b/queue-5.15/pwm-lpc18xx-sct-reduce-number-of-devm-memory-allocat.patch
new file mode 100644 (file)
index 0000000..97344a1
--- /dev/null
@@ -0,0 +1,72 @@
+From 2672850dda80bee413a1135ab5f7e2d80b78d92c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Nov 2021 09:49:49 +0100
+Subject: pwm: lpc18xx-sct: Reduce number of devm memory allocations
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 20d9de9c4d6642bb40c935233697723b56573cbc ]
+
+Each devm allocations has an overhead of 24 bytes to store the related
+struct devres_node additionally to the fragmentation of the allocator.
+So allocating 16 struct lpc18xx_pwm_data (which only hold a single int)
+adds quite some overhead. Instead put the per-channel data into the
+driver data struct and allocate it in one go.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pwm/pwm-lpc18xx-sct.c | 12 +++++-------
+ 1 file changed, 5 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/pwm/pwm-lpc18xx-sct.c b/drivers/pwm/pwm-lpc18xx-sct.c
+index 8cc8ae16553c..6cf02554066c 100644
+--- a/drivers/pwm/pwm-lpc18xx-sct.c
++++ b/drivers/pwm/pwm-lpc18xx-sct.c
+@@ -76,6 +76,8 @@
+ #define LPC18XX_PWM_EVENT_PERIOD      0
+ #define LPC18XX_PWM_EVENT_MAX         16
++#define LPC18XX_NUM_PWMS              16
++
+ /* SCT conflict resolution */
+ enum lpc18xx_pwm_res_action {
+       LPC18XX_PWM_RES_NONE,
+@@ -101,6 +103,7 @@ struct lpc18xx_pwm_chip {
+       unsigned long event_map;
+       struct mutex res_lock;
+       struct mutex period_lock;
++      struct lpc18xx_pwm_data channeldata[LPC18XX_NUM_PWMS];
+ };
+ static inline struct lpc18xx_pwm_chip *
+@@ -370,7 +373,7 @@ static int lpc18xx_pwm_probe(struct platform_device *pdev)
+       lpc18xx_pwm->chip.dev = &pdev->dev;
+       lpc18xx_pwm->chip.ops = &lpc18xx_pwm_ops;
+-      lpc18xx_pwm->chip.npwm = 16;
++      lpc18xx_pwm->chip.npwm = LPC18XX_NUM_PWMS;
+       /* SCT counter must be in unify (32 bit) mode */
+       lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_CONFIG,
+@@ -400,12 +403,7 @@ static int lpc18xx_pwm_probe(struct platform_device *pdev)
+               pwm = &lpc18xx_pwm->chip.pwms[i];
+-              data = devm_kzalloc(lpc18xx_pwm->dev, sizeof(*data),
+-                                  GFP_KERNEL);
+-              if (!data) {
+-                      ret = -ENOMEM;
+-                      goto disable_pwmclk;
+-              }
++              data = &lpc18xx_pwm->channeldata[i];
+               pwm_set_chip_data(pwm, data);
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/pwm-lpc18xx-sct-simplify-driver-by-not-using-pwm_-gs.patch b/queue-5.15/pwm-lpc18xx-sct-simplify-driver-by-not-using-pwm_-gs.patch
new file mode 100644 (file)
index 0000000..376d355
--- /dev/null
@@ -0,0 +1,124 @@
+From 27c42359ee7f549039bfec63eb2451682cbc5b9d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Nov 2021 09:49:50 +0100
+Subject: pwm: lpc18xx-sct: Simplify driver by not using pwm_[gs]et_chip_data()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 9136a39e6cf69e49803ac6123a4ac4431bc915a2 ]
+
+The per-channel data is available directly in the driver data struct. So
+use it without making use of pwm_[gs]et_chip_data().
+
+The relevant change introduced by this patch to lpc18xx_pwm_disable() at
+the assembler level (for an arm lpc18xx_defconfig build) is:
+
+       push    {r3, r4, r5, lr}
+       mov     r4, r0
+       mov     r0, r1
+       mov     r5, r1
+       bl      0 <pwm_get_chip_data>
+       ldr     r3, [r0, #0]
+
+changes to
+
+       ldr     r3, [r1, #8]
+       push    {r4, lr}
+       add.w   r3, r0, r3, lsl #2
+       ldr     r3, [r3, #92]   ; 0x5c
+
+So this reduces stack usage, has an improved runtime behavior because of
+better pipeline usage, doesn't branch to an external function and the
+generated code is a bit smaller occupying less memory.
+
+The codesize of lpc18xx_pwm_probe() is reduced by 32 bytes.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pwm/pwm-lpc18xx-sct.c | 23 ++++++-----------------
+ 1 file changed, 6 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/pwm/pwm-lpc18xx-sct.c b/drivers/pwm/pwm-lpc18xx-sct.c
+index 6cf02554066c..b909096dba2f 100644
+--- a/drivers/pwm/pwm-lpc18xx-sct.c
++++ b/drivers/pwm/pwm-lpc18xx-sct.c
+@@ -166,7 +166,7 @@ static void lpc18xx_pwm_config_duty(struct pwm_chip *chip,
+                                   struct pwm_device *pwm, int duty_ns)
+ {
+       struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip);
+-      struct lpc18xx_pwm_data *lpc18xx_data = pwm_get_chip_data(pwm);
++      struct lpc18xx_pwm_data *lpc18xx_data = &lpc18xx_pwm->channeldata[pwm->hwpwm];
+       u64 val;
+       val = (u64)duty_ns * lpc18xx_pwm->clk_rate;
+@@ -236,7 +236,7 @@ static int lpc18xx_pwm_set_polarity(struct pwm_chip *chip,
+ static int lpc18xx_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+ {
+       struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip);
+-      struct lpc18xx_pwm_data *lpc18xx_data = pwm_get_chip_data(pwm);
++      struct lpc18xx_pwm_data *lpc18xx_data = &lpc18xx_pwm->channeldata[pwm->hwpwm];
+       enum lpc18xx_pwm_res_action res_action;
+       unsigned int set_event, clear_event;
+@@ -271,7 +271,7 @@ static int lpc18xx_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+ static void lpc18xx_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+ {
+       struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip);
+-      struct lpc18xx_pwm_data *lpc18xx_data = pwm_get_chip_data(pwm);
++      struct lpc18xx_pwm_data *lpc18xx_data = &lpc18xx_pwm->channeldata[pwm->hwpwm];
+       lpc18xx_pwm_writel(lpc18xx_pwm,
+                          LPC18XX_PWM_EVCTRL(lpc18xx_data->duty_event), 0);
+@@ -282,7 +282,7 @@ static void lpc18xx_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+ static int lpc18xx_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
+ {
+       struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip);
+-      struct lpc18xx_pwm_data *lpc18xx_data = pwm_get_chip_data(pwm);
++      struct lpc18xx_pwm_data *lpc18xx_data = &lpc18xx_pwm->channeldata[pwm->hwpwm];
+       unsigned long event;
+       event = find_first_zero_bit(&lpc18xx_pwm->event_map,
+@@ -303,7 +303,7 @@ static int lpc18xx_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
+ static void lpc18xx_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
+ {
+       struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip);
+-      struct lpc18xx_pwm_data *lpc18xx_data = pwm_get_chip_data(pwm);
++      struct lpc18xx_pwm_data *lpc18xx_data = &lpc18xx_pwm->channeldata[pwm->hwpwm];
+       clear_bit(lpc18xx_data->duty_event, &lpc18xx_pwm->event_map);
+ }
+@@ -327,8 +327,7 @@ MODULE_DEVICE_TABLE(of, lpc18xx_pwm_of_match);
+ static int lpc18xx_pwm_probe(struct platform_device *pdev)
+ {
+       struct lpc18xx_pwm_chip *lpc18xx_pwm;
+-      struct pwm_device *pwm;
+-      int ret, i;
++      int ret;
+       u64 val;
+       lpc18xx_pwm = devm_kzalloc(&pdev->dev, sizeof(*lpc18xx_pwm),
+@@ -398,16 +397,6 @@ static int lpc18xx_pwm_probe(struct platform_device *pdev)
+       lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_LIMIT,
+                          BIT(lpc18xx_pwm->period_event));
+-      for (i = 0; i < lpc18xx_pwm->chip.npwm; i++) {
+-              struct lpc18xx_pwm_data *data;
+-
+-              pwm = &lpc18xx_pwm->chip.pwms[i];
+-
+-              data = &lpc18xx_pwm->channeldata[i];
+-
+-              pwm_set_chip_data(pwm, data);
+-      }
+-
+       val = lpc18xx_pwm_readl(lpc18xx_pwm, LPC18XX_PWM_CTRL);
+       val &= ~LPC18XX_PWM_BIDIR;
+       val &= ~LPC18XX_PWM_CTRL_HALT;
+-- 
+2.35.1
+
diff --git a/queue-5.15/pwm-sifive-ensure-the-clk-is-enabled-exactly-once-pe.patch b/queue-5.15/pwm-sifive-ensure-the-clk-is-enabled-exactly-once-pe.patch
new file mode 100644 (file)
index 0000000..4ca9e1b
--- /dev/null
@@ -0,0 +1,116 @@
+From eacd4b004dbb0d77c23970860ac85c0cb054f99c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Jul 2022 12:31:28 +0200
+Subject: pwm: sifive: Ensure the clk is enabled exactly once per running PWM
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit ace41d7564e655c39f709a78c035188a460c7cbd ]
+
+.apply() assumes the clk to be for a given PWM iff the PWM is enabled.
+So make sure this is the case when .probe() completes. And in .remove()
+disable the according number of times.
+
+This fixes a clk enable/disable imbalance, if some PWMs are already running
+at probe time.
+
+Fixes: 9e37a53eb051 (pwm: sifive: Add a driver for SiFive SoC PWM)
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Tested-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pwm/pwm-sifive.c | 46 ++++++++++++++++++++++++++++++++--------
+ 1 file changed, 37 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c
+index a55f7345dc87..3936fda53366 100644
+--- a/drivers/pwm/pwm-sifive.c
++++ b/drivers/pwm/pwm-sifive.c
+@@ -229,6 +229,8 @@ static int pwm_sifive_probe(struct platform_device *pdev)
+       struct pwm_sifive_ddata *ddata;
+       struct pwm_chip *chip;
+       int ret;
++      u32 val;
++      unsigned int enabled_pwms = 0, enabled_clks = 1;
+       ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
+       if (!ddata)
+@@ -255,6 +257,33 @@ static int pwm_sifive_probe(struct platform_device *pdev)
+               return ret;
+       }
++      val = readl(ddata->regs + PWM_SIFIVE_PWMCFG);
++      if (val & PWM_SIFIVE_PWMCFG_EN_ALWAYS) {
++              unsigned int i;
++
++              for (i = 0; i < chip->npwm; ++i) {
++                      val = readl(ddata->regs + PWM_SIFIVE_PWMCMP(i));
++                      if (val > 0)
++                              ++enabled_pwms;
++              }
++      }
++
++      /* The clk should be on once for each running PWM. */
++      if (enabled_pwms) {
++              while (enabled_clks < enabled_pwms) {
++                      /* This is not expected to fail as the clk is already on */
++                      ret = clk_enable(ddata->clk);
++                      if (unlikely(ret)) {
++                              dev_err_probe(dev, ret, "Failed to enable clk\n");
++                              goto disable_clk;
++                      }
++                      ++enabled_clks;
++              }
++      } else {
++              clk_disable(ddata->clk);
++              enabled_clks = 0;
++      }
++
+       /* Watch for changes to underlying clock frequency */
+       ddata->notifier.notifier_call = pwm_sifive_clock_notifier;
+       ret = clk_notifier_register(ddata->clk, &ddata->notifier);
+@@ -277,7 +306,11 @@ static int pwm_sifive_probe(struct platform_device *pdev)
+ unregister_clk:
+       clk_notifier_unregister(ddata->clk, &ddata->notifier);
+ disable_clk:
+-      clk_disable_unprepare(ddata->clk);
++      while (enabled_clks) {
++              clk_disable(ddata->clk);
++              --enabled_clks;
++      }
++      clk_unprepare(ddata->clk);
+       return ret;
+ }
+@@ -285,21 +318,16 @@ static int pwm_sifive_probe(struct platform_device *pdev)
+ static int pwm_sifive_remove(struct platform_device *dev)
+ {
+       struct pwm_sifive_ddata *ddata = platform_get_drvdata(dev);
+-      bool is_enabled = false;
+       struct pwm_device *pwm;
+       int ch;
+       for (ch = 0; ch < ddata->chip.npwm; ch++) {
+               pwm = &ddata->chip.pwms[ch];
+-              if (pwm->state.enabled) {
+-                      is_enabled = true;
+-                      break;
+-              }
++              if (pwm->state.enabled)
++                      clk_disable(ddata->clk);
+       }
+-      if (is_enabled)
+-              clk_disable(ddata->clk);
+-      clk_disable_unprepare(ddata->clk);
++      clk_unprepare(ddata->clk);
+       pwmchip_remove(&ddata->chip);
+       clk_notifier_unregister(ddata->clk, &ddata->notifier);
+-- 
+2.35.1
+
diff --git a/queue-5.15/pwm-sifive-shut-down-hardware-only-after-pwmchip_rem.patch b/queue-5.15/pwm-sifive-shut-down-hardware-only-after-pwmchip_rem.patch
new file mode 100644 (file)
index 0000000..18a5ac5
--- /dev/null
@@ -0,0 +1,50 @@
+From 13e9baa352fdfd1f2af1e2b3d2c97ae92e6f60ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Jul 2022 12:31:29 +0200
+Subject: pwm: sifive: Shut down hardware only after pwmchip_remove() completed
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 2375e964d541bb09158cd2dff67b5d74e8de61cd ]
+
+The PWMs are expected to be functional until pwmchip_remove() is called.
+So disable the clks only afterwards.
+
+Fixes: 9e37a53eb051 ("pwm: sifive: Add a driver for SiFive SoC PWM")
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Tested-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pwm/pwm-sifive.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c
+index 3936fda53366..58347fcd4812 100644
+--- a/drivers/pwm/pwm-sifive.c
++++ b/drivers/pwm/pwm-sifive.c
+@@ -321,6 +321,9 @@ static int pwm_sifive_remove(struct platform_device *dev)
+       struct pwm_device *pwm;
+       int ch;
++      pwmchip_remove(&ddata->chip);
++      clk_notifier_unregister(ddata->clk, &ddata->notifier);
++
+       for (ch = 0; ch < ddata->chip.npwm; ch++) {
+               pwm = &ddata->chip.pwms[ch];
+               if (pwm->state.enabled)
+@@ -328,8 +331,6 @@ static int pwm_sifive_remove(struct platform_device *dev)
+       }
+       clk_unprepare(ddata->clk);
+-      pwmchip_remove(&ddata->chip);
+-      clk_notifier_unregister(ddata->clk, &ddata->notifier);
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/pwm-sifive-simplify-offset-calculation-for-pwmcmp-re.patch b/queue-5.15/pwm-sifive-simplify-offset-calculation-for-pwmcmp-re.patch
new file mode 100644 (file)
index 0000000..2d462c0
--- /dev/null
@@ -0,0 +1,74 @@
+From d9169ae9b4518ade6aea27bd4f6b39ae3863c9e3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Jul 2022 12:31:23 +0200
+Subject: pwm: sifive: Simplify offset calculation for PWMCMP registers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 20550a61880fc55e68a0d290ad195b74729c0e7b ]
+
+Instead of explicitly using PWM_SIFIVE_PWMCMP0 + pwm->hwpwm *
+PWM_SIFIVE_SIZE_PWMCMP for each access to one of the PWMCMP registers,
+introduce a macro that takes the hwpwm id as parameter.
+
+For the register definition using a plain 4 instead of the cpp constant
+PWM_SIFIVE_SIZE_PWMCMP is easier to read, so define the offset macro
+without the constant. The latter can then be dropped as there are no
+users left.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Tested-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pwm/pwm-sifive.c | 10 +++-------
+ 1 file changed, 3 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c
+index 253c4a17d255..a55f7345dc87 100644
+--- a/drivers/pwm/pwm-sifive.c
++++ b/drivers/pwm/pwm-sifive.c
+@@ -23,7 +23,7 @@
+ #define PWM_SIFIVE_PWMCFG             0x0
+ #define PWM_SIFIVE_PWMCOUNT           0x8
+ #define PWM_SIFIVE_PWMS                       0x10
+-#define PWM_SIFIVE_PWMCMP0            0x20
++#define PWM_SIFIVE_PWMCMP(i)          (0x20 + 4 * (i))
+ /* PWMCFG fields */
+ #define PWM_SIFIVE_PWMCFG_SCALE               GENMASK(3, 0)
+@@ -36,8 +36,6 @@
+ #define PWM_SIFIVE_PWMCFG_GANG                BIT(24)
+ #define PWM_SIFIVE_PWMCFG_IP          BIT(28)
+-/* PWM_SIFIVE_SIZE_PWMCMP is used to calculate offset for pwmcmpX registers */
+-#define PWM_SIFIVE_SIZE_PWMCMP                4
+ #define PWM_SIFIVE_CMPWIDTH           16
+ #define PWM_SIFIVE_DEFAULT_PERIOD     10000000
+@@ -112,8 +110,7 @@ static void pwm_sifive_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+       struct pwm_sifive_ddata *ddata = pwm_sifive_chip_to_ddata(chip);
+       u32 duty, val;
+-      duty = readl(ddata->regs + PWM_SIFIVE_PWMCMP0 +
+-                   pwm->hwpwm * PWM_SIFIVE_SIZE_PWMCMP);
++      duty = readl(ddata->regs + PWM_SIFIVE_PWMCMP(pwm->hwpwm));
+       state->enabled = duty > 0;
+@@ -194,8 +191,7 @@ static int pwm_sifive_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+               pwm_sifive_update_clock(ddata, clk_get_rate(ddata->clk));
+       }
+-      writel(frac, ddata->regs + PWM_SIFIVE_PWMCMP0 +
+-             pwm->hwpwm * PWM_SIFIVE_SIZE_PWMCMP);
++      writel(frac, ddata->regs + PWM_SIFIVE_PWMCMP(pwm->hwpwm));
+       if (state->enabled != enabled)
+               pwm_sifive_enable(chip, state->enabled);
+-- 
+2.35.1
+
diff --git a/queue-5.15/rcutorture-don-t-cpuhp_remove_state-if-cpuhp_setup_s.patch b/queue-5.15/rcutorture-don-t-cpuhp_remove_state-if-cpuhp_setup_s.patch
new file mode 100644 (file)
index 0000000..19b9c6f
--- /dev/null
@@ -0,0 +1,49 @@
+From 08cb7d785b5d6520ac098c90d4405f29654928d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Aug 2021 08:57:26 -0700
+Subject: rcutorture: Don't cpuhp_remove_state() if cpuhp_setup_state() failed
+
+From: Paul E. McKenney <paulmck@kernel.org>
+
+[ Upstream commit fd13fe16db0d82612b260640f4e26f6d9d1e11fd ]
+
+Currently, in CONFIG_RCU_BOOST kernels, if the rcu_torture_init()
+function's call to cpuhp_setup_state() fails, rcu_torture_cleanup()
+gamely passes nonsense to cpuhp_remove_state().  This results in
+strange and misleading splats.  This commit therefore ensures that if
+the rcu_torture_init() function's call to cpuhp_setup_state() fails,
+rcu_torture_cleanup() avoids invoking cpuhp_remove_state().
+
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/rcu/rcutorture.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
+index c1b36c52e896..3262330d1679 100644
+--- a/kernel/rcu/rcutorture.c
++++ b/kernel/rcu/rcutorture.c
+@@ -2848,7 +2848,7 @@ rcu_torture_cleanup(void)
+                rcutorture_seq_diff(gp_seq, start_gp_seq));
+       torture_stop_kthread(rcu_torture_stats, stats_task);
+       torture_stop_kthread(rcu_torture_fqs, fqs_task);
+-      if (rcu_torture_can_boost())
++      if (rcu_torture_can_boost() && rcutor_hp >= 0)
+               cpuhp_remove_state(rcutor_hp);
+       /*
+@@ -3161,9 +3161,9 @@ rcu_torture_init(void)
+               firsterr = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "RCU_TORTURE",
+                                            rcutorture_booster_init,
+                                            rcutorture_booster_cleanup);
++              rcutor_hp = firsterr;
+               if (torture_init_error(firsterr))
+                       goto unwind;
+-              rcutor_hp = firsterr;
+               // Testing RCU priority boosting requires rcutorture do
+               // some serious abuse.  Counter this by running ksoftirqd
+-- 
+2.35.1
+
diff --git a/queue-5.15/rcutorture-fix-ksoftirqd-boosting-timing-and-iterati.patch b/queue-5.15/rcutorture-fix-ksoftirqd-boosting-timing-and-iterati.patch
new file mode 100644 (file)
index 0000000..2dd75d7
--- /dev/null
@@ -0,0 +1,116 @@
+From 11f4b165b781e360d508e24d99466ad8e31d2803 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jun 2022 15:03:57 +0200
+Subject: rcutorture: Fix ksoftirqd boosting timing and iteration
+
+From: Frederic Weisbecker <frederic@kernel.org>
+
+[ Upstream commit 3002153a91a9732a6d1d0bb95138593c7da15743 ]
+
+The RCU priority boosting can fail in two situations:
+
+1) If (nr_cpus= > maxcpus=), which means if the total number of CPUs
+is higher than those brought online at boot, then torture_onoff() may
+later bring up CPUs that weren't online on boot. Now since rcutorture
+initialization only boosts the ksoftirqds of the CPUs that have been
+set online on boot, the CPUs later set online by torture_onoff won't
+benefit from the boost, making RCU priority boosting fail.
+
+2) The ksoftirqd kthreads are boosted after the creation of
+rcu_torture_boost() kthreads, which opens a window large enough for these
+rcu_torture_boost() kthreads to wait (despite running at FIFO priority)
+for ksoftirqds that are still running at SCHED_NORMAL priority.
+
+The issues can trigger for example with:
+
+       ./kvm.sh --configs TREE01 --kconfig "CONFIG_RCU_BOOST=y"
+
+       [   34.968561] rcu-torture: !!!
+       [   34.968627] ------------[ cut here ]------------
+       [   35.014054] WARNING: CPU: 4 PID: 114 at kernel/rcu/rcutorture.c:1979 rcu_torture_stats_print+0x5ad/0x610
+       [   35.052043] Modules linked in:
+       [   35.069138] CPU: 4 PID: 114 Comm: rcu_torture_sta Not tainted 5.18.0-rc1 #1
+       [   35.096424] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.14.0-0-g155821a-rebuilt.opensuse.org 04/01/2014
+       [   35.154570] RIP: 0010:rcu_torture_stats_print+0x5ad/0x610
+       [   35.198527] Code: 63 1b 02 00 74 02 0f 0b 48 83 3d 35 63 1b 02 00 74 02 0f 0b 48 83 3d 21 63 1b 02 00 74 02 0f 0b 48 83 3d 0d 63 1b 02 00 74 02 <0f> 0b 83 eb 01 0f 8e ba fc ff ff 0f 0b e9 b3 fc ff f82
+       [   37.251049] RSP: 0000:ffffa92a0050bdf8 EFLAGS: 00010202
+       [   37.277320] rcu: De-offloading 8
+       [   37.290367] RAX: 0000000000000000 RBX: 0000000000000001 RCX: 0000000000000001
+       [   37.290387] RDX: 0000000000000000 RSI: 00000000ffffbfff RDI: 00000000ffffffff
+       [   37.290398] RBP: 000000000000007b R08: 0000000000000000 R09: c0000000ffffbfff
+       [   37.290407] R10: 000000000000002a R11: ffffa92a0050bc18 R12: ffffa92a0050be20
+       [   37.290417] R13: ffffa92a0050be78 R14: 0000000000000000 R15: 000000000001bea0
+       [   37.290427] FS:  0000000000000000(0000) GS:ffff96045eb00000(0000) knlGS:0000000000000000
+       [   37.290448] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+       [   37.290460] CR2: 0000000000000000 CR3: 000000001dc0c000 CR4: 00000000000006e0
+       [   37.290470] Call Trace:
+       [   37.295049]  <TASK>
+       [   37.295065]  ? preempt_count_add+0x63/0x90
+       [   37.295095]  ? _raw_spin_lock_irqsave+0x12/0x40
+       [   37.295125]  ? rcu_torture_stats_print+0x610/0x610
+       [   37.295143]  rcu_torture_stats+0x29/0x70
+       [   37.295160]  kthread+0xe3/0x110
+       [   37.295176]  ? kthread_complete_and_exit+0x20/0x20
+       [   37.295193]  ret_from_fork+0x22/0x30
+       [   37.295218]  </TASK>
+
+Fix this with boosting the ksoftirqds kthreads from the boosting
+hotplug callback itself and before the boosting kthreads are created.
+
+Fixes: ea6d962e80b6 ("rcutorture: Judge RCU priority boosting on grace periods, not callbacks")
+Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/rcu/rcutorture.c | 28 +++++++++++++---------------
+ 1 file changed, 13 insertions(+), 15 deletions(-)
+
+diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
+index 3262330d1679..d820ef615475 100644
+--- a/kernel/rcu/rcutorture.c
++++ b/kernel/rcu/rcutorture.c
+@@ -1991,6 +1991,19 @@ static int rcutorture_booster_init(unsigned int cpu)
+       if (boost_tasks[cpu] != NULL)
+               return 0;  /* Already created, nothing more to do. */
++      // Testing RCU priority boosting requires rcutorture do
++      // some serious abuse.  Counter this by running ksoftirqd
++      // at higher priority.
++      if (IS_BUILTIN(CONFIG_RCU_TORTURE_TEST)) {
++              struct sched_param sp;
++              struct task_struct *t;
++
++              t = per_cpu(ksoftirqd, cpu);
++              WARN_ON_ONCE(!t);
++              sp.sched_priority = 2;
++              sched_setscheduler_nocheck(t, SCHED_FIFO, &sp);
++      }
++
+       /* Don't allow time recalculation while creating a new task. */
+       mutex_lock(&boost_mutex);
+       rcu_torture_disable_rt_throttle();
+@@ -3164,21 +3177,6 @@ rcu_torture_init(void)
+               rcutor_hp = firsterr;
+               if (torture_init_error(firsterr))
+                       goto unwind;
+-
+-              // Testing RCU priority boosting requires rcutorture do
+-              // some serious abuse.  Counter this by running ksoftirqd
+-              // at higher priority.
+-              if (IS_BUILTIN(CONFIG_RCU_TORTURE_TEST)) {
+-                      for_each_online_cpu(cpu) {
+-                              struct sched_param sp;
+-                              struct task_struct *t;
+-
+-                              t = per_cpu(ksoftirqd, cpu);
+-                              WARN_ON_ONCE(!t);
+-                              sp.sched_priority = 2;
+-                              sched_setscheduler_nocheck(t, SCHED_FIFO, &sp);
+-                      }
+-              }
+       }
+       shutdown_jiffies = jiffies + shutdown_secs * HZ;
+       firsterr = torture_shutdown_init(shutdown_secs, rcu_torture_cleanup);
+-- 
+2.35.1
+
diff --git a/queue-5.15/rcutorture-warn-on-individual-rcu_torture_init-error.patch b/queue-5.15/rcutorture-warn-on-individual-rcu_torture_init-error.patch
new file mode 100644 (file)
index 0000000..e3a8096
--- /dev/null
@@ -0,0 +1,155 @@
+From 86e2c909d084976b6ee3e58480d9929364b16bb9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Aug 2021 13:28:24 -0700
+Subject: rcutorture: Warn on individual rcu_torture_init() error conditions
+
+From: Paul E. McKenney <paulmck@kernel.org>
+
+[ Upstream commit efeff6b39b9de4480572c7b0c5eb77204795cb57 ]
+
+When running rcutorture as a module, any rcu_torture_init() issues will be
+reflected in the error code from modprobe or insmod, as the case may be.
+However, these error codes are not available when running rcutorture
+built-in, for example, when using the kvm.sh script.  This commit
+therefore adds WARN_ON_ONCE() to allow distinguishing rcu_torture_init()
+errors when running rcutorture built-in.
+
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/torture.h |  8 ++++++++
+ kernel/rcu/rcutorture.c | 30 +++++++++++++++---------------
+ 2 files changed, 23 insertions(+), 15 deletions(-)
+
+diff --git a/include/linux/torture.h b/include/linux/torture.h
+index 0910c5803f35..24f58e50a94b 100644
+--- a/include/linux/torture.h
++++ b/include/linux/torture.h
+@@ -47,6 +47,14 @@ do {                                                                                \
+ } while (0)
+ void verbose_torout_sleep(void);
++#define torture_init_error(firsterr)                                          \
++({                                                                            \
++      int ___firsterr = (firsterr);                                           \
++                                                                              \
++      WARN_ONCE(!IS_MODULE(CONFIG_RCU_TORTURE_TEST) && ___firsterr < 0, "Torture-test initialization failed with error code %d\n", ___firsterr); \
++      ___firsterr < 0;                                                                \
++})
++
+ /* Definitions for online/offline exerciser. */
+ #ifdef CONFIG_HOTPLUG_CPU
+ int torture_num_online_cpus(void);
+diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
+index f922937eb39a..c1b36c52e896 100644
+--- a/kernel/rcu/rcutorture.c
++++ b/kernel/rcu/rcutorture.c
+@@ -3066,7 +3066,7 @@ rcu_torture_init(void)
+       rcu_torture_write_types();
+       firsterr = torture_create_kthread(rcu_torture_writer, NULL,
+                                         writer_task);
+-      if (firsterr)
++      if (torture_init_error(firsterr))
+               goto unwind;
+       if (nfakewriters > 0) {
+               fakewriter_tasks = kcalloc(nfakewriters,
+@@ -3081,7 +3081,7 @@ rcu_torture_init(void)
+       for (i = 0; i < nfakewriters; i++) {
+               firsterr = torture_create_kthread(rcu_torture_fakewriter,
+                                                 NULL, fakewriter_tasks[i]);
+-              if (firsterr)
++              if (torture_init_error(firsterr))
+                       goto unwind;
+       }
+       reader_tasks = kcalloc(nrealreaders, sizeof(reader_tasks[0]),
+@@ -3097,7 +3097,7 @@ rcu_torture_init(void)
+               rcu_torture_reader_mbchk[i].rtc_chkrdr = -1;
+               firsterr = torture_create_kthread(rcu_torture_reader, (void *)i,
+                                                 reader_tasks[i]);
+-              if (firsterr)
++              if (torture_init_error(firsterr))
+                       goto unwind;
+       }
+       nrealnocbers = nocbs_nthreads;
+@@ -3117,18 +3117,18 @@ rcu_torture_init(void)
+       }
+       for (i = 0; i < nrealnocbers; i++) {
+               firsterr = torture_create_kthread(rcu_nocb_toggle, NULL, nocb_tasks[i]);
+-              if (firsterr)
++              if (torture_init_error(firsterr))
+                       goto unwind;
+       }
+       if (stat_interval > 0) {
+               firsterr = torture_create_kthread(rcu_torture_stats, NULL,
+                                                 stats_task);
+-              if (firsterr)
++              if (torture_init_error(firsterr))
+                       goto unwind;
+       }
+       if (test_no_idle_hz && shuffle_interval > 0) {
+               firsterr = torture_shuffle_init(shuffle_interval * HZ);
+-              if (firsterr)
++              if (torture_init_error(firsterr))
+                       goto unwind;
+       }
+       if (stutter < 0)
+@@ -3138,7 +3138,7 @@ rcu_torture_init(void)
+               t = cur_ops->stall_dur ? cur_ops->stall_dur() : stutter * HZ;
+               firsterr = torture_stutter_init(stutter * HZ, t);
+-              if (firsterr)
++              if (torture_init_error(firsterr))
+                       goto unwind;
+       }
+       if (fqs_duration < 0)
+@@ -3147,7 +3147,7 @@ rcu_torture_init(void)
+               /* Create the fqs thread */
+               firsterr = torture_create_kthread(rcu_torture_fqs, NULL,
+                                                 fqs_task);
+-              if (firsterr)
++              if (torture_init_error(firsterr))
+                       goto unwind;
+       }
+       if (test_boost_interval < 1)
+@@ -3161,7 +3161,7 @@ rcu_torture_init(void)
+               firsterr = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "RCU_TORTURE",
+                                            rcutorture_booster_init,
+                                            rcutorture_booster_cleanup);
+-              if (firsterr < 0)
++              if (torture_init_error(firsterr))
+                       goto unwind;
+               rcutor_hp = firsterr;
+@@ -3182,23 +3182,23 @@ rcu_torture_init(void)
+       }
+       shutdown_jiffies = jiffies + shutdown_secs * HZ;
+       firsterr = torture_shutdown_init(shutdown_secs, rcu_torture_cleanup);
+-      if (firsterr)
++      if (torture_init_error(firsterr))
+               goto unwind;
+       firsterr = torture_onoff_init(onoff_holdoff * HZ, onoff_interval,
+                                     rcutorture_sync);
+-      if (firsterr)
++      if (torture_init_error(firsterr))
+               goto unwind;
+       firsterr = rcu_torture_stall_init();
+-      if (firsterr)
++      if (torture_init_error(firsterr))
+               goto unwind;
+       firsterr = rcu_torture_fwd_prog_init();
+-      if (firsterr)
++      if (torture_init_error(firsterr))
+               goto unwind;
+       firsterr = rcu_torture_barrier_init();
+-      if (firsterr)
++      if (torture_init_error(firsterr))
+               goto unwind;
+       firsterr = rcu_torture_read_exit_init();
+-      if (firsterr)
++      if (torture_init_error(firsterr))
+               goto unwind;
+       if (object_debug)
+               rcu_test_debug_objects();
+-- 
+2.35.1
+
diff --git a/queue-5.15/rdma-hfi1-fix-potential-memory-leak-in-setup_base_ct.patch b/queue-5.15/rdma-hfi1-fix-potential-memory-leak-in-setup_base_ct.patch
new file mode 100644 (file)
index 0000000..880ed01
--- /dev/null
@@ -0,0 +1,45 @@
+From eb54c68b57939f27569d76aac57063ffced61c98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Jul 2022 15:07:18 +0800
+Subject: RDMA/hfi1: fix potential memory leak in setup_base_ctxt()
+
+From: Jianglei Nie <niejianglei2021@163.com>
+
+[ Upstream commit aa2a1df3a2c85f855af7d54466ac10bd48645d63 ]
+
+setup_base_ctxt() allocates a memory chunk for uctxt->groups with
+hfi1_alloc_ctxt_rcv_groups(). When init_user_ctxt() fails, uctxt->groups
+is not released, which will lead to a memory leak.
+
+We should release the uctxt->groups with hfi1_free_ctxt_rcv_groups()
+when init_user_ctxt() fails.
+
+Fixes: e87473bc1b6c ("IB/hfi1: Only set fd pointer when base context is completely initialized")
+Link: https://lore.kernel.org/r/20220711070718.2318320-1-niejianglei2021@163.com
+Signed-off-by: Jianglei Nie <niejianglei2021@163.com>
+Acked-by: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hfi1/file_ops.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/hfi1/file_ops.c b/drivers/infiniband/hw/hfi1/file_ops.c
+index 3ebdd42fec36..686d170a5947 100644
+--- a/drivers/infiniband/hw/hfi1/file_ops.c
++++ b/drivers/infiniband/hw/hfi1/file_ops.c
+@@ -1179,8 +1179,10 @@ static int setup_base_ctxt(struct hfi1_filedata *fd,
+               goto done;
+       ret = init_user_ctxt(fd, uctxt);
+-      if (ret)
++      if (ret) {
++              hfi1_free_ctxt_rcv_groups(uctxt);
+               goto done;
++      }
+       user_init(uctxt);
+-- 
+2.35.1
+
diff --git a/queue-5.15/rdma-hns-fix-incorrect-clearing-of-interrupt-status-.patch b/queue-5.15/rdma-hns-fix-incorrect-clearing-of-interrupt-status-.patch
new file mode 100644 (file)
index 0000000..fcad74a
--- /dev/null
@@ -0,0 +1,41 @@
+From 6409f34f319988e76bb4efef4f6e5b23eec12293 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 21:43:51 +0800
+Subject: RDMA/hns: Fix incorrect clearing of interrupt status register
+
+From: Haoyue Xu <xuhaoyue1@hisilicon.com>
+
+[ Upstream commit ecb4db5c3590aa956b4b2c352081a5b632d1f9f9 ]
+
+The driver will clear all the interrupts in the same area
+when the driver handles the interrupt of type AEQ overflow.
+It should only set the interrupt status bit of type AEQ overflow.
+
+Fixes: a5073d6054f7 ("RDMA/hns: Add eq support of hip08")
+Link: https://lore.kernel.org/r/20220714134353.16700-4-liangwenpeng@huawei.com
+Signed-off-by: Haoyue Xu <xuhaoyue1@hisilicon.com>
+Signed-off-by: Wenpeng Liang <liangwenpeng@huawei.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+index bf01210c56c2..1dbad159f379 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -5854,8 +5854,8 @@ static irqreturn_t hns_roce_v2_msix_interrupt_abn(int irq, void *dev_id)
+               dev_err(dev, "AEQ overflow!\n");
+-              int_st |= 1 << HNS_ROCE_V2_VF_INT_ST_AEQ_OVERFLOW_S;
+-              roce_write(hr_dev, ROCEE_VF_ABN_INT_ST_REG, int_st);
++              roce_write(hr_dev, ROCEE_VF_ABN_INT_ST_REG,
++                         1 << HNS_ROCE_V2_VF_INT_ST_AEQ_OVERFLOW_S);
+               /* Set reset level for reset_event() */
+               if (ops->set_default_reset_request)
+-- 
+2.35.1
+
diff --git a/queue-5.15/rdma-irdma-fix-a-window-for-use-after-free.patch b/queue-5.15/rdma-irdma-fix-a-window-for-use-after-free.patch
new file mode 100644 (file)
index 0000000..6c1462f
--- /dev/null
@@ -0,0 +1,45 @@
+From 1e385f09f570629fdf50da851d0f8f37da8c7aa1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Jul 2022 18:08:13 -0500
+Subject: RDMA/irdma: Fix a window for use-after-free
+
+From: Mustafa Ismail <mustafa.ismail@intel.com>
+
+[ Upstream commit 8ecef7890b3aea78c8bbb501a4b5b8134367b821 ]
+
+During a destroy CQ an interrupt may cause processing of a CQE after CQ
+resources are freed by irdma_cq_free_rsrc(). Fix this by moving the call
+to irdma_cq_free_rsrc() after the irdma_sc_cleanup_ceqes(), which is
+called under the cq_lock.
+
+Fixes: b48c24c2d710 ("RDMA/irdma: Implement device supported verb APIs")
+Link: https://lore.kernel.org/r/20220705230815.265-6-shiraz.saleem@intel.com
+Signed-off-by: Bartosz Sobczak <bartosz.sobczak@intel.com>
+Signed-off-by: Mustafa Ismail <mustafa.ismail@intel.com>
+Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/verbs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
+index 0eef46428691..cac4fb228b9b 100644
+--- a/drivers/infiniband/hw/irdma/verbs.c
++++ b/drivers/infiniband/hw/irdma/verbs.c
+@@ -1759,11 +1759,11 @@ static int irdma_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
+       spin_unlock_irqrestore(&iwcq->lock, flags);
+       irdma_cq_wq_destroy(iwdev->rf, cq);
+-      irdma_cq_free_rsrc(iwdev->rf, iwcq);
+       spin_lock_irqsave(&iwceq->ce_lock, flags);
+       irdma_sc_cleanup_ceqes(cq, ceq);
+       spin_unlock_irqrestore(&iwceq->ce_lock, flags);
++      irdma_cq_free_rsrc(iwdev->rf, iwcq);
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/rdma-irdma-fix-setting-of-qp-context-err_rq_idx_vali.patch b/queue-5.15/rdma-irdma-fix-setting-of-qp-context-err_rq_idx_vali.patch
new file mode 100644 (file)
index 0000000..c9f2ee6
--- /dev/null
@@ -0,0 +1,73 @@
+From 9eaa1aed3f6c3bf7eca8245af56038135336ddc4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Jul 2022 18:08:15 -0500
+Subject: RDMA/irdma: Fix setting of QP context err_rq_idx_valid field
+
+From: Mustafa Ismail <mustafa.ismail@intel.com>
+
+[ Upstream commit 3a844596ed71b7c12ac602f6f6b7b0f17e4d6a90 ]
+
+Setting err_rq_idx_valid field in QP context when the AE source of the
+AEQE is not associated with an RQ causes the firmware flush to fail.
+
+Set err_rq_idx_valid field in QP context only if it is associated with an
+RQ. Additionally, cleanup the redundant setting of this field in
+irdma_process_aeq.
+
+Fixes: 44d9e52977a1 ("RDMA/irdma: Implement device initialization definitions")
+Link: https://lore.kernel.org/r/20220705230815.265-8-shiraz.saleem@intel.com
+Signed-off-by: Mustafa Ismail <mustafa.ismail@intel.com>
+Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/hw.c | 15 ++++-----------
+ 1 file changed, 4 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/infiniband/hw/irdma/hw.c b/drivers/infiniband/hw/irdma/hw.c
+index 4f763e552eae..3d5d3f8d5ded 100644
+--- a/drivers/infiniband/hw/irdma/hw.c
++++ b/drivers/infiniband/hw/irdma/hw.c
+@@ -257,10 +257,6 @@ static void irdma_process_aeq(struct irdma_pci_f *rf)
+                               iwqp->last_aeq = info->ae_id;
+                       spin_unlock_irqrestore(&iwqp->lock, flags);
+                       ctx_info = &iwqp->ctx_info;
+-                      if (rdma_protocol_roce(&iwqp->iwdev->ibdev, 1))
+-                              ctx_info->roce_info->err_rq_idx_valid = true;
+-                      else
+-                              ctx_info->iwarp_info->err_rq_idx_valid = true;
+               } else {
+                       if (info->ae_id != IRDMA_AE_CQ_OPERATION_ERROR)
+                               continue;
+@@ -370,16 +366,12 @@ static void irdma_process_aeq(struct irdma_pci_f *rf)
+               case IRDMA_AE_LCE_FUNCTION_CATASTROPHIC:
+               case IRDMA_AE_LCE_CQ_CATASTROPHIC:
+               case IRDMA_AE_UDA_XMIT_DGRAM_TOO_LONG:
+-                      if (rdma_protocol_roce(&iwdev->ibdev, 1))
+-                              ctx_info->roce_info->err_rq_idx_valid = false;
+-                      else
+-                              ctx_info->iwarp_info->err_rq_idx_valid = false;
+-                      fallthrough;
+               default:
+                       ibdev_err(&iwdev->ibdev, "abnormal ae_id = 0x%x bool qp=%d qp_id = %d\n",
+                                 info->ae_id, info->qp, info->qp_cq_id);
+                       if (rdma_protocol_roce(&iwdev->ibdev, 1)) {
+-                              if (!info->sq && ctx_info->roce_info->err_rq_idx_valid) {
++                              ctx_info->roce_info->err_rq_idx_valid = info->rq;
++                              if (info->rq) {
+                                       ctx_info->roce_info->err_rq_idx = info->wqe_idx;
+                                       irdma_sc_qp_setctx_roce(&iwqp->sc_qp, iwqp->host_ctx.va,
+                                                               ctx_info);
+@@ -388,7 +380,8 @@ static void irdma_process_aeq(struct irdma_pci_f *rf)
+                               irdma_cm_disconn(iwqp);
+                               break;
+                       }
+-                      if (!info->sq && ctx_info->iwarp_info->err_rq_idx_valid) {
++                      ctx_info->iwarp_info->err_rq_idx_valid = info->rq;
++                      if (info->rq) {
+                               ctx_info->iwarp_info->err_rq_idx = info->wqe_idx;
+                               ctx_info->tcp_info_valid = false;
+                               ctx_info->iwarp_info_valid = true;
+-- 
+2.35.1
+
diff --git a/queue-5.15/rdma-irdma-fix-vlan-connection-with-wildcard-address.patch b/queue-5.15/rdma-irdma-fix-vlan-connection-with-wildcard-address.patch
new file mode 100644 (file)
index 0000000..444dedd
--- /dev/null
@@ -0,0 +1,51 @@
+From 40fd75c8cd9a9fd48d553947874522c69e973bad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Jul 2022 18:08:14 -0500
+Subject: RDMA/irdma: Fix VLAN connection with wildcard address
+
+From: Mustafa Ismail <mustafa.ismail@intel.com>
+
+[ Upstream commit 82ab2b52654c43ba24a3f6603fec40874cc5a7e5 ]
+
+When an application listens on a wildcard address, and there are VLAN and
+non-VLAN IP addresses, iWARP connection establishemnt can fail if the listen
+node VLAN ID does not match.
+
+Fix this by checking the vlan_id only if not a wildcard listen node.
+
+Fixes: 146b9756f14c ("RDMA/irdma: Add connection manager")
+Link: https://lore.kernel.org/r/20220705230815.265-7-shiraz.saleem@intel.com
+Signed-off-by: Mustafa Ismail <mustafa.ismail@intel.com>
+Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/cm.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/infiniband/hw/irdma/cm.c b/drivers/infiniband/hw/irdma/cm.c
+index 60d4e9c151ff..b08c67bb264c 100644
+--- a/drivers/infiniband/hw/irdma/cm.c
++++ b/drivers/infiniband/hw/irdma/cm.c
+@@ -1477,12 +1477,13 @@ irdma_find_listener(struct irdma_cm_core *cm_core, u32 *dst_addr, u16 dst_port,
+       list_for_each_entry (listen_node, &cm_core->listen_list, list) {
+               memcpy(listen_addr, listen_node->loc_addr, sizeof(listen_addr));
+               listen_port = listen_node->loc_port;
++              if (listen_port != dst_port ||
++                  !(listener_state & listen_node->listener_state))
++                      continue;
+               /* compare node pair, return node handle if a match */
+-              if ((!memcmp(listen_addr, dst_addr, sizeof(listen_addr)) ||
+-                   !memcmp(listen_addr, ip_zero, sizeof(listen_addr))) &&
+-                  listen_port == dst_port &&
+-                  vlan_id == listen_node->vlan_id &&
+-                  (listener_state & listen_node->listener_state)) {
++              if (!memcmp(listen_addr, ip_zero, sizeof(listen_addr)) ||
++                  (!memcmp(listen_addr, dst_addr, sizeof(listen_addr)) &&
++                   vlan_id == listen_node->vlan_id)) {
+                       refcount_inc(&listen_node->refcnt);
+                       spin_unlock_irqrestore(&cm_core->listen_list_lock,
+                                              flags);
+-- 
+2.35.1
+
diff --git a/queue-5.15/rdma-mlx5-add-missing-check-for-return-value-in-get-.patch b/queue-5.15/rdma-mlx5-add-missing-check-for-return-value-in-get-.patch
new file mode 100644 (file)
index 0000000..e659857
--- /dev/null
@@ -0,0 +1,46 @@
+From 75fdd96e79f06c48c71db98572e6c055007160c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 31 Jul 2022 11:29:08 +0300
+Subject: RDMA/mlx5: Add missing check for return value in get namespace flow
+
+From: Maor Gottlieb <maorg@nvidia.com>
+
+[ Upstream commit c9776457bd5eaad4ce4ecb17af8d8f3cc6957c0b ]
+
+Add missing check for return value when calling to
+mlx5_ib_ft_type_to_namespace, even though it can't really fail in this
+specific call.
+
+Fixes: 52438be44112 ("RDMA/mlx5: Allow inserting a steering rule to the FDB")
+Link: https://lore.kernel.org/r/7b9ceda217d9368a51dc47a46b769bad4af9ac92.1659256069.git.leonro@nvidia.com
+Reviewed-by: Itay Aveksis <itayav@nvidia.com>
+Signed-off-by: Maor Gottlieb <maorg@nvidia.com>
+Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/mlx5/fs.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/infiniband/hw/mlx5/fs.c b/drivers/infiniband/hw/mlx5/fs.c
+index 5fbc0a8454b9..8a7e182af530 100644
+--- a/drivers/infiniband/hw/mlx5/fs.c
++++ b/drivers/infiniband/hw/mlx5/fs.c
+@@ -2078,12 +2078,10 @@ static int mlx5_ib_matcher_ns(struct uverbs_attr_bundle *attrs,
+               if (err)
+                       return err;
+-              if (flags) {
+-                      mlx5_ib_ft_type_to_namespace(
++              if (flags)
++                      return mlx5_ib_ft_type_to_namespace(
+                               MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_TX,
+                               &obj->ns_type);
+-                      return 0;
+-              }
+       }
+       obj->ns_type = MLX5_FLOW_NAMESPACE_BYPASS;
+-- 
+2.35.1
+
diff --git a/queue-5.15/rdma-qedr-fix-potential-memory-leak-in-__qedr_alloc_.patch b/queue-5.15/rdma-qedr-fix-potential-memory-leak-in-__qedr_alloc_.patch
new file mode 100644 (file)
index 0000000..80ddcb3
--- /dev/null
@@ -0,0 +1,67 @@
+From be386198380e988ef4daccb1fa4f56ff5820faf0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 14:15:05 +0800
+Subject: RDMA/qedr: Fix potential memory leak in __qedr_alloc_mr()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jianglei Nie <niejianglei2021@163.com>
+
+[ Upstream commit b3236a64ddd125a455ef5b5316c1b9051b732974 ]
+
+__qedr_alloc_mr() allocates a memory chunk for "mr->info.pbl_table" with
+init_mr_info(). When rdma_alloc_tid() and rdma_register_tid() fail, "mr"
+is released while "mr->info.pbl_table" is not released, which will lead
+to a memory leak.
+
+We should release the "mr->info.pbl_table" with qedr_free_pbl() when error
+occurs to fix the memory leak.
+
+Fixes: e0290cce6ac0 ("qedr: Add support for memory registeration verbs")
+Link: https://lore.kernel.org/r/20220714061505.2342759-1-niejianglei2021@163.com
+Signed-off-by: Jianglei Nie <niejianglei2021@163.com>
+Acked-by: Michal Kalderon <michal.kalderon@marvell.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/qedr/verbs.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/infiniband/hw/qedr/verbs.c b/drivers/infiniband/hw/qedr/verbs.c
+index 49dfedbc5665..bb0c2b93a34d 100644
+--- a/drivers/infiniband/hw/qedr/verbs.c
++++ b/drivers/infiniband/hw/qedr/verbs.c
+@@ -3093,7 +3093,7 @@ static struct qedr_mr *__qedr_alloc_mr(struct ib_pd *ibpd,
+               else
+                       DP_ERR(dev, "roce alloc tid returned error %d\n", rc);
+-              goto err0;
++              goto err1;
+       }
+       /* Index only, 18 bit long, lkey = itid << 8 | key */
+@@ -3117,7 +3117,7 @@ static struct qedr_mr *__qedr_alloc_mr(struct ib_pd *ibpd,
+       rc = dev->ops->rdma_register_tid(dev->rdma_ctx, &mr->hw_mr);
+       if (rc) {
+               DP_ERR(dev, "roce register tid returned an error %d\n", rc);
+-              goto err1;
++              goto err2;
+       }
+       mr->ibmr.lkey = mr->hw_mr.itid << 8 | mr->hw_mr.key;
+@@ -3126,8 +3126,10 @@ static struct qedr_mr *__qedr_alloc_mr(struct ib_pd *ibpd,
+       DP_DEBUG(dev, QEDR_MSG_MR, "alloc frmr: %x\n", mr->ibmr.lkey);
+       return mr;
+-err1:
++err2:
+       dev->ops->rdma_free_tid(dev->rdma_ctx, mr->hw_mr.itid);
++err1:
++      qedr_free_pbl(dev, &mr->info.pbl_info, mr->info.pbl_table);
+ err0:
+       kfree(mr);
+       return ERR_PTR(rc);
+-- 
+2.35.1
+
diff --git a/queue-5.15/rdma-rtrs-clt-rename-rtrs_clt_sess-to-rtrs_clt_path.patch b/queue-5.15/rdma-rtrs-clt-rename-rtrs_clt_sess-to-rtrs_clt_path.patch
new file mode 100644 (file)
index 0000000..2330d5b
--- /dev/null
@@ -0,0 +1,2826 @@
+From 0d1c889cfb944a95ec2516ff5d527a7514fc50b8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Jan 2022 19:07:06 +0100
+Subject: RDMA/rtrs-clt: Rename rtrs_clt_sess to rtrs_clt_path
+
+From: Vaishali Thakkar <vaishali.thakkar@ionos.com>
+
+[ Upstream commit caa84d95c78f35168847e2ab861a3a7f87033d36 ]
+
+rtrs_clt_sess is used for paths and not sessions on the client side. This
+creates confusion so let's rename it to rtrs_clt_path. Also, rename
+related variables and functions.
+
+Coccinelle is used to do the transformations for most of the occurrences
+and remaining ones were handled manually.
+
+Link: https://lore.kernel.org/r/20220105180708.7774-4-jinpu.wang@ionos.com
+Signed-off-by: Vaishali Thakkar <vaishali.thakkar@ionos.com>
+Signed-off-by: Jack Wang <jinpu.wang@ionos.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/rtrs/rtrs-clt-stats.c |   8 +-
+ drivers/infiniband/ulp/rtrs/rtrs-clt-sysfs.c | 123 +--
+ drivers/infiniband/ulp/rtrs/rtrs-clt.c       | 997 ++++++++++---------
+ drivers/infiniband/ulp/rtrs/rtrs-clt.h       |  20 +-
+ drivers/infiniband/ulp/rtrs/rtrs-pri.h       |   2 +-
+ drivers/infiniband/ulp/rtrs/rtrs.h           |   4 +-
+ 6 files changed, 586 insertions(+), 568 deletions(-)
+
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt-stats.c b/drivers/infiniband/ulp/rtrs/rtrs-clt-stats.c
+index 40b4d6dd4924..e7b57bdfe3ea 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-clt-stats.c
++++ b/drivers/infiniband/ulp/rtrs/rtrs-clt-stats.c
+@@ -13,8 +13,8 @@
+ void rtrs_clt_update_wc_stats(struct rtrs_clt_con *con)
+ {
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
+-      struct rtrs_clt_stats *stats = sess->stats;
++      struct rtrs_clt_path *clt_path = to_clt_path(con->c.path);
++      struct rtrs_clt_stats *stats = clt_path->stats;
+       struct rtrs_clt_stats_pcpu *s;
+       int cpu;
+@@ -174,8 +174,8 @@ static inline void rtrs_clt_update_rdma_stats(struct rtrs_clt_stats *stats,
+ void rtrs_clt_update_all_stats(struct rtrs_clt_io_req *req, int dir)
+ {
+       struct rtrs_clt_con *con = req->con;
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
+-      struct rtrs_clt_stats *stats = sess->stats;
++      struct rtrs_clt_path *clt_path = to_clt_path(con->c.path);
++      struct rtrs_clt_stats *stats = clt_path->stats;
+       unsigned int len;
+       len = req->usr_len + req->data_len;
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt-sysfs.c b/drivers/infiniband/ulp/rtrs/rtrs-clt-sysfs.c
+index 4ee592ccf979..dbf9a778c3bd 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-clt-sysfs.c
++++ b/drivers/infiniband/ulp/rtrs/rtrs-clt-sysfs.c
+@@ -16,21 +16,21 @@
+ #define MIN_MAX_RECONN_ATT -1
+ #define MAX_MAX_RECONN_ATT 9999
+-static void rtrs_clt_sess_release(struct kobject *kobj)
++static void rtrs_clt_path_release(struct kobject *kobj)
+ {
+-      struct rtrs_clt_sess *sess;
++      struct rtrs_clt_path *clt_path;
+-      sess = container_of(kobj, struct rtrs_clt_sess, kobj);
++      clt_path = container_of(kobj, struct rtrs_clt_path, kobj);
+-      free_sess(sess);
++      free_path(clt_path);
+ }
+ static struct kobj_type ktype_sess = {
+       .sysfs_ops = &kobj_sysfs_ops,
+-      .release = rtrs_clt_sess_release
++      .release = rtrs_clt_path_release
+ };
+-static void rtrs_clt_sess_stats_release(struct kobject *kobj)
++static void rtrs_clt_path_stats_release(struct kobject *kobj)
+ {
+       struct rtrs_clt_stats *stats;
+@@ -43,7 +43,7 @@ static void rtrs_clt_sess_stats_release(struct kobject *kobj)
+ static struct kobj_type ktype_stats = {
+       .sysfs_ops = &kobj_sysfs_ops,
+-      .release = rtrs_clt_sess_stats_release,
++      .release = rtrs_clt_path_stats_release,
+ };
+ static ssize_t max_reconnect_attempts_show(struct device *dev,
+@@ -197,10 +197,10 @@ static DEVICE_ATTR_RW(add_path);
+ static ssize_t rtrs_clt_state_show(struct kobject *kobj,
+                                   struct kobj_attribute *attr, char *page)
+ {
+-      struct rtrs_clt_sess *sess;
++      struct rtrs_clt_path *clt_path;
+-      sess = container_of(kobj, struct rtrs_clt_sess, kobj);
+-      if (sess->state == RTRS_CLT_CONNECTED)
++      clt_path = container_of(kobj, struct rtrs_clt_path, kobj);
++      if (clt_path->state == RTRS_CLT_CONNECTED)
+               return sysfs_emit(page, "connected\n");
+       return sysfs_emit(page, "disconnected\n");
+@@ -219,16 +219,16 @@ static ssize_t rtrs_clt_reconnect_store(struct kobject *kobj,
+                                        struct kobj_attribute *attr,
+                                        const char *buf, size_t count)
+ {
+-      struct rtrs_clt_sess *sess;
++      struct rtrs_clt_path *clt_path;
+       int ret;
+-      sess = container_of(kobj, struct rtrs_clt_sess, kobj);
++      clt_path = container_of(kobj, struct rtrs_clt_path, kobj);
+       if (!sysfs_streq(buf, "1")) {
+-              rtrs_err(sess->clt, "%s: unknown value: '%s'\n",
++              rtrs_err(clt_path->clt, "%s: unknown value: '%s'\n",
+                         attr->attr.name, buf);
+               return -EINVAL;
+       }
+-      ret = rtrs_clt_reconnect_from_sysfs(sess);
++      ret = rtrs_clt_reconnect_from_sysfs(clt_path);
+       if (ret)
+               return ret;
+@@ -249,15 +249,15 @@ static ssize_t rtrs_clt_disconnect_store(struct kobject *kobj,
+                                         struct kobj_attribute *attr,
+                                         const char *buf, size_t count)
+ {
+-      struct rtrs_clt_sess *sess;
++      struct rtrs_clt_path *clt_path;
+-      sess = container_of(kobj, struct rtrs_clt_sess, kobj);
++      clt_path = container_of(kobj, struct rtrs_clt_path, kobj);
+       if (!sysfs_streq(buf, "1")) {
+-              rtrs_err(sess->clt, "%s: unknown value: '%s'\n",
++              rtrs_err(clt_path->clt, "%s: unknown value: '%s'\n",
+                         attr->attr.name, buf);
+               return -EINVAL;
+       }
+-      rtrs_clt_close_conns(sess, true);
++      rtrs_clt_close_conns(clt_path, true);
+       return count;
+ }
+@@ -276,16 +276,16 @@ static ssize_t rtrs_clt_remove_path_store(struct kobject *kobj,
+                                          struct kobj_attribute *attr,
+                                          const char *buf, size_t count)
+ {
+-      struct rtrs_clt_sess *sess;
++      struct rtrs_clt_path *clt_path;
+       int ret;
+-      sess = container_of(kobj, struct rtrs_clt_sess, kobj);
++      clt_path = container_of(kobj, struct rtrs_clt_path, kobj);
+       if (!sysfs_streq(buf, "1")) {
+-              rtrs_err(sess->clt, "%s: unknown value: '%s'\n",
++              rtrs_err(clt_path->clt, "%s: unknown value: '%s'\n",
+                         attr->attr.name, buf);
+               return -EINVAL;
+       }
+-      ret = rtrs_clt_remove_path_from_sysfs(sess, &attr->attr);
++      ret = rtrs_clt_remove_path_from_sysfs(clt_path, &attr->attr);
+       if (ret)
+               return ret;
+@@ -328,11 +328,11 @@ static ssize_t rtrs_clt_hca_port_show(struct kobject *kobj,
+                                      struct kobj_attribute *attr,
+                                      char *page)
+ {
+-      struct rtrs_clt_sess *sess;
++      struct rtrs_clt_path *clt_path;
+-      sess = container_of(kobj, typeof(*sess), kobj);
++      clt_path = container_of(kobj, typeof(*clt_path), kobj);
+-      return sysfs_emit(page, "%u\n", sess->hca_port);
++      return sysfs_emit(page, "%u\n", clt_path->hca_port);
+ }
+ static struct kobj_attribute rtrs_clt_hca_port_attr =
+@@ -342,11 +342,11 @@ static ssize_t rtrs_clt_hca_name_show(struct kobject *kobj,
+                                      struct kobj_attribute *attr,
+                                      char *page)
+ {
+-      struct rtrs_clt_sess *sess;
++      struct rtrs_clt_path *clt_path;
+-      sess = container_of(kobj, struct rtrs_clt_sess, kobj);
++      clt_path = container_of(kobj, struct rtrs_clt_path, kobj);
+-      return sysfs_emit(page, "%s\n", sess->hca_name);
++      return sysfs_emit(page, "%s\n", clt_path->hca_name);
+ }
+ static struct kobj_attribute rtrs_clt_hca_name_attr =
+@@ -356,12 +356,12 @@ static ssize_t rtrs_clt_cur_latency_show(struct kobject *kobj,
+                                   struct kobj_attribute *attr,
+                                   char *page)
+ {
+-      struct rtrs_clt_sess *sess;
++      struct rtrs_clt_path *clt_path;
+-      sess = container_of(kobj, struct rtrs_clt_sess, kobj);
++      clt_path = container_of(kobj, struct rtrs_clt_path, kobj);
+       return sysfs_emit(page, "%lld ns\n",
+-                        ktime_to_ns(sess->s.hb_cur_latency));
++                        ktime_to_ns(clt_path->s.hb_cur_latency));
+ }
+ static struct kobj_attribute rtrs_clt_cur_latency_attr =
+@@ -371,11 +371,11 @@ static ssize_t rtrs_clt_src_addr_show(struct kobject *kobj,
+                                      struct kobj_attribute *attr,
+                                      char *page)
+ {
+-      struct rtrs_clt_sess *sess;
++      struct rtrs_clt_path *clt_path;
+       int len;
+-      sess = container_of(kobj, struct rtrs_clt_sess, kobj);
+-      len = sockaddr_to_str((struct sockaddr *)&sess->s.src_addr, page,
++      clt_path = container_of(kobj, struct rtrs_clt_path, kobj);
++      len = sockaddr_to_str((struct sockaddr *)&clt_path->s.src_addr, page,
+                             PAGE_SIZE);
+       len += sysfs_emit_at(page, len, "\n");
+       return len;
+@@ -388,11 +388,11 @@ static ssize_t rtrs_clt_dst_addr_show(struct kobject *kobj,
+                                      struct kobj_attribute *attr,
+                                      char *page)
+ {
+-      struct rtrs_clt_sess *sess;
++      struct rtrs_clt_path *clt_path;
+       int len;
+-      sess = container_of(kobj, struct rtrs_clt_sess, kobj);
+-      len = sockaddr_to_str((struct sockaddr *)&sess->s.dst_addr, page,
++      clt_path = container_of(kobj, struct rtrs_clt_path, kobj);
++      len = sockaddr_to_str((struct sockaddr *)&clt_path->s.dst_addr, page,
+                             PAGE_SIZE);
+       len += sysfs_emit_at(page, len, "\n");
+       return len;
+@@ -401,7 +401,7 @@ static ssize_t rtrs_clt_dst_addr_show(struct kobject *kobj,
+ static struct kobj_attribute rtrs_clt_dst_addr_attr =
+       __ATTR(dst_addr, 0444, rtrs_clt_dst_addr_show, NULL);
+-static struct attribute *rtrs_clt_sess_attrs[] = {
++static struct attribute *rtrs_clt_path_attrs[] = {
+       &rtrs_clt_hca_name_attr.attr,
+       &rtrs_clt_hca_port_attr.attr,
+       &rtrs_clt_src_addr_attr.attr,
+@@ -414,42 +414,43 @@ static struct attribute *rtrs_clt_sess_attrs[] = {
+       NULL,
+ };
+-static const struct attribute_group rtrs_clt_sess_attr_group = {
+-      .attrs = rtrs_clt_sess_attrs,
++static const struct attribute_group rtrs_clt_path_attr_group = {
++      .attrs = rtrs_clt_path_attrs,
+ };
+-int rtrs_clt_create_sess_files(struct rtrs_clt_sess *sess)
++int rtrs_clt_create_path_files(struct rtrs_clt_path *clt_path)
+ {
+-      struct rtrs_clt *clt = sess->clt;
++      struct rtrs_clt *clt = clt_path->clt;
+       char str[NAME_MAX];
+       int err;
+       struct rtrs_addr path = {
+-              .src = &sess->s.src_addr,
+-              .dst = &sess->s.dst_addr,
++              .src = &clt_path->s.src_addr,
++              .dst = &clt_path->s.dst_addr,
+       };
+       rtrs_addr_to_str(&path, str, sizeof(str));
+-      err = kobject_init_and_add(&sess->kobj, &ktype_sess, clt->kobj_paths,
++      err = kobject_init_and_add(&clt_path->kobj, &ktype_sess,
++                                 clt->kobj_paths,
+                                  "%s", str);
+       if (err) {
+               pr_err("kobject_init_and_add: %d\n", err);
+-              kobject_put(&sess->kobj);
++              kobject_put(&clt_path->kobj);
+               return err;
+       }
+-      err = sysfs_create_group(&sess->kobj, &rtrs_clt_sess_attr_group);
++      err = sysfs_create_group(&clt_path->kobj, &rtrs_clt_path_attr_group);
+       if (err) {
+               pr_err("sysfs_create_group(): %d\n", err);
+               goto put_kobj;
+       }
+-      err = kobject_init_and_add(&sess->stats->kobj_stats, &ktype_stats,
+-                                 &sess->kobj, "stats");
++      err = kobject_init_and_add(&clt_path->stats->kobj_stats, &ktype_stats,
++                                 &clt_path->kobj, "stats");
+       if (err) {
+               pr_err("kobject_init_and_add: %d\n", err);
+-              kobject_put(&sess->stats->kobj_stats);
++              kobject_put(&clt_path->stats->kobj_stats);
+               goto remove_group;
+       }
+-      err = sysfs_create_group(&sess->stats->kobj_stats,
++      err = sysfs_create_group(&clt_path->stats->kobj_stats,
+                                &rtrs_clt_stats_attr_group);
+       if (err) {
+               pr_err("failed to create stats sysfs group, err: %d\n", err);
+@@ -459,25 +460,25 @@ int rtrs_clt_create_sess_files(struct rtrs_clt_sess *sess)
+       return 0;
+ put_kobj_stats:
+-      kobject_del(&sess->stats->kobj_stats);
+-      kobject_put(&sess->stats->kobj_stats);
++      kobject_del(&clt_path->stats->kobj_stats);
++      kobject_put(&clt_path->stats->kobj_stats);
+ remove_group:
+-      sysfs_remove_group(&sess->kobj, &rtrs_clt_sess_attr_group);
++      sysfs_remove_group(&clt_path->kobj, &rtrs_clt_path_attr_group);
+ put_kobj:
+-      kobject_del(&sess->kobj);
+-      kobject_put(&sess->kobj);
++      kobject_del(&clt_path->kobj);
++      kobject_put(&clt_path->kobj);
+       return err;
+ }
+-void rtrs_clt_destroy_sess_files(struct rtrs_clt_sess *sess,
++void rtrs_clt_destroy_path_files(struct rtrs_clt_path *clt_path,
+                                 const struct attribute *sysfs_self)
+ {
+-      kobject_del(&sess->stats->kobj_stats);
+-      kobject_put(&sess->stats->kobj_stats);
++      kobject_del(&clt_path->stats->kobj_stats);
++      kobject_put(&clt_path->stats->kobj_stats);
+       if (sysfs_self)
+-              sysfs_remove_file_self(&sess->kobj, sysfs_self);
+-      kobject_del(&sess->kobj);
++              sysfs_remove_file_self(&clt_path->kobj, sysfs_self);
++      kobject_del(&clt_path->kobj);
+ }
+ static struct attribute *rtrs_clt_attrs[] = {
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
+index 5e73127f2adc..a46ef2821e36 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c
++++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
+@@ -48,12 +48,12 @@ static struct class *rtrs_clt_dev_class;
+ static inline bool rtrs_clt_is_connected(const struct rtrs_clt *clt)
+ {
+-      struct rtrs_clt_sess *sess;
++      struct rtrs_clt_path *clt_path;
+       bool connected = false;
+       rcu_read_lock();
+-      list_for_each_entry_rcu(sess, &clt->paths_list, s.entry)
+-              connected |= READ_ONCE(sess->state) == RTRS_CLT_CONNECTED;
++      list_for_each_entry_rcu(clt_path, &clt->paths_list, s.entry)
++              connected |= READ_ONCE(clt_path->state) == RTRS_CLT_CONNECTED;
+       rcu_read_unlock();
+       return connected;
+@@ -163,29 +163,29 @@ EXPORT_SYMBOL(rtrs_clt_put_permit);
+ /**
+  * rtrs_permit_to_clt_con() - returns RDMA connection pointer by the permit
+- * @sess: client session pointer
++ * @clt_path: client path pointer
+  * @permit: permit for the allocation of the RDMA buffer
+  * Note:
+  *     IO connection starts from 1.
+  *     0 connection is for user messages.
+  */
+ static
+-struct rtrs_clt_con *rtrs_permit_to_clt_con(struct rtrs_clt_sess *sess,
++struct rtrs_clt_con *rtrs_permit_to_clt_con(struct rtrs_clt_path *clt_path,
+                                           struct rtrs_permit *permit)
+ {
+       int id = 0;
+       if (permit->con_type == RTRS_IO_CON)
+-              id = (permit->cpu_id % (sess->s.irq_con_num - 1)) + 1;
++              id = (permit->cpu_id % (clt_path->s.irq_con_num - 1)) + 1;
+-      return to_clt_con(sess->s.con[id]);
++      return to_clt_con(clt_path->s.con[id]);
+ }
+ /**
+  * rtrs_clt_change_state() - change the session state through session state
+  * machine.
+  *
+- * @sess: client session to change the state of.
++ * @clt_path: client path to change the state of.
+  * @new_state: state to change to.
+  *
+  * returns true if sess's state is changed to new state, otherwise return false.
+@@ -193,15 +193,15 @@ struct rtrs_clt_con *rtrs_permit_to_clt_con(struct rtrs_clt_sess *sess,
+  * Locks:
+  * state_wq lock must be hold.
+  */
+-static bool rtrs_clt_change_state(struct rtrs_clt_sess *sess,
++static bool rtrs_clt_change_state(struct rtrs_clt_path *clt_path,
+                                    enum rtrs_clt_state new_state)
+ {
+       enum rtrs_clt_state old_state;
+       bool changed = false;
+-      lockdep_assert_held(&sess->state_wq.lock);
++      lockdep_assert_held(&clt_path->state_wq.lock);
+-      old_state = sess->state;
++      old_state = clt_path->state;
+       switch (new_state) {
+       case RTRS_CLT_CONNECTING:
+               switch (old_state) {
+@@ -275,42 +275,42 @@ static bool rtrs_clt_change_state(struct rtrs_clt_sess *sess,
+               break;
+       }
+       if (changed) {
+-              sess->state = new_state;
+-              wake_up_locked(&sess->state_wq);
++              clt_path->state = new_state;
++              wake_up_locked(&clt_path->state_wq);
+       }
+       return changed;
+ }
+-static bool rtrs_clt_change_state_from_to(struct rtrs_clt_sess *sess,
++static bool rtrs_clt_change_state_from_to(struct rtrs_clt_path *clt_path,
+                                          enum rtrs_clt_state old_state,
+                                          enum rtrs_clt_state new_state)
+ {
+       bool changed = false;
+-      spin_lock_irq(&sess->state_wq.lock);
+-      if (sess->state == old_state)
+-              changed = rtrs_clt_change_state(sess, new_state);
+-      spin_unlock_irq(&sess->state_wq.lock);
++      spin_lock_irq(&clt_path->state_wq.lock);
++      if (clt_path->state == old_state)
++              changed = rtrs_clt_change_state(clt_path, new_state);
++      spin_unlock_irq(&clt_path->state_wq.lock);
+       return changed;
+ }
+ static void rtrs_rdma_error_recovery(struct rtrs_clt_con *con)
+ {
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
++      struct rtrs_clt_path *clt_path = to_clt_path(con->c.path);
+-      if (rtrs_clt_change_state_from_to(sess,
++      if (rtrs_clt_change_state_from_to(clt_path,
+                                          RTRS_CLT_CONNECTED,
+                                          RTRS_CLT_RECONNECTING)) {
+-              struct rtrs_clt *clt = sess->clt;
++              struct rtrs_clt *clt = clt_path->clt;
+               unsigned int delay_ms;
+               /*
+                * Normal scenario, reconnect if we were successfully connected
+                */
+               delay_ms = clt->reconnect_delay_sec * 1000;
+-              queue_delayed_work(rtrs_wq, &sess->reconnect_dwork,
++              queue_delayed_work(rtrs_wq, &clt_path->reconnect_dwork,
+                                  msecs_to_jiffies(delay_ms +
+                                                   prandom_u32() % RTRS_RECONNECT_SEED));
+       } else {
+@@ -319,7 +319,7 @@ static void rtrs_rdma_error_recovery(struct rtrs_clt_con *con)
+                * so notify waiter with error state, waiter is responsible
+                * for cleaning the rest and reconnect if needed.
+                */
+-              rtrs_clt_change_state_from_to(sess,
++              rtrs_clt_change_state_from_to(clt_path,
+                                              RTRS_CLT_CONNECTING,
+                                              RTRS_CLT_CONNECTING_ERR);
+       }
+@@ -380,14 +380,14 @@ static void complete_rdma_req(struct rtrs_clt_io_req *req, int errno,
+                             bool notify, bool can_wait)
+ {
+       struct rtrs_clt_con *con = req->con;
+-      struct rtrs_clt_sess *sess;
++      struct rtrs_clt_path *clt_path;
+       int err;
+       if (WARN_ON(!req->in_use))
+               return;
+       if (WARN_ON(!req->con))
+               return;
+-      sess = to_clt_sess(con->c.path);
++      clt_path = to_clt_path(con->c.path);
+       if (req->sg_cnt) {
+               if (req->dir == DMA_FROM_DEVICE && req->need_inv) {
+@@ -433,21 +433,21 @@ static void complete_rdma_req(struct rtrs_clt_io_req *req, int errno,
+                       if (!refcount_dec_and_test(&req->ref))
+                               return;
+               }
+-              ib_dma_unmap_sg(sess->s.dev->ib_dev, req->sglist,
++              ib_dma_unmap_sg(clt_path->s.dev->ib_dev, req->sglist,
+                               req->sg_cnt, req->dir);
+       }
+       if (!refcount_dec_and_test(&req->ref))
+               return;
+       if (req->mp_policy == MP_POLICY_MIN_INFLIGHT)
+-              atomic_dec(&sess->stats->inflight);
++              atomic_dec(&clt_path->stats->inflight);
+       req->in_use = false;
+       req->con = NULL;
+       if (errno) {
+               rtrs_err_rl(con->c.path, "IO request failed: error=%d path=%s [%s:%u] notify=%d\n",
+-                          errno, kobject_name(&sess->kobj), sess->hca_name,
+-                          sess->hca_port, notify);
++                          errno, kobject_name(&clt_path->kobj), clt_path->hca_name,
++                          clt_path->hca_port, notify);
+       }
+       if (notify)
+@@ -459,7 +459,7 @@ static int rtrs_post_send_rdma(struct rtrs_clt_con *con,
+                               struct rtrs_rbuf *rbuf, u32 off,
+                               u32 imm, struct ib_send_wr *wr)
+ {
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
++      struct rtrs_clt_path *clt_path = to_clt_path(con->c.path);
+       enum ib_send_flags flags;
+       struct ib_sge sge;
+@@ -472,16 +472,17 @@ static int rtrs_post_send_rdma(struct rtrs_clt_con *con,
+       /* user data and user message in the first list element */
+       sge.addr   = req->iu->dma_addr;
+       sge.length = req->sg_size;
+-      sge.lkey   = sess->s.dev->ib_pd->local_dma_lkey;
++      sge.lkey   = clt_path->s.dev->ib_pd->local_dma_lkey;
+       /*
+        * From time to time we have to post signalled sends,
+        * or send queue will fill up and only QP reset can help.
+        */
+-      flags = atomic_inc_return(&con->c.wr_cnt) % sess->s.signal_interval ?
++      flags = atomic_inc_return(&con->c.wr_cnt) % clt_path->s.signal_interval ?
+                       0 : IB_SEND_SIGNALED;
+-      ib_dma_sync_single_for_device(sess->s.dev->ib_dev, req->iu->dma_addr,
++      ib_dma_sync_single_for_device(clt_path->s.dev->ib_dev,
++                                    req->iu->dma_addr,
+                                     req->sg_size, DMA_TO_DEVICE);
+       return rtrs_iu_post_rdma_write_imm(&con->c, req->iu, &sge, 1,
+@@ -489,15 +490,15 @@ static int rtrs_post_send_rdma(struct rtrs_clt_con *con,
+                                           imm, flags, wr, NULL);
+ }
+-static void process_io_rsp(struct rtrs_clt_sess *sess, u32 msg_id,
++static void process_io_rsp(struct rtrs_clt_path *clt_path, u32 msg_id,
+                          s16 errno, bool w_inval)
+ {
+       struct rtrs_clt_io_req *req;
+-      if (WARN_ON(msg_id >= sess->queue_depth))
++      if (WARN_ON(msg_id >= clt_path->queue_depth))
+               return;
+-      req = &sess->reqs[msg_id];
++      req = &clt_path->reqs[msg_id];
+       /* Drop need_inv if server responded with send with invalidation */
+       req->need_inv &= !w_inval;
+       complete_rdma_req(req, errno, true, false);
+@@ -507,9 +508,9 @@ static void rtrs_clt_recv_done(struct rtrs_clt_con *con, struct ib_wc *wc)
+ {
+       struct rtrs_iu *iu;
+       int err;
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
++      struct rtrs_clt_path *clt_path = to_clt_path(con->c.path);
+-      WARN_ON((sess->flags & RTRS_MSG_NEW_RKEY_F) == 0);
++      WARN_ON((clt_path->flags & RTRS_MSG_NEW_RKEY_F) == 0);
+       iu = container_of(wc->wr_cqe, struct rtrs_iu,
+                         cqe);
+       err = rtrs_iu_post_recv(&con->c, iu);
+@@ -521,7 +522,7 @@ static void rtrs_clt_recv_done(struct rtrs_clt_con *con, struct ib_wc *wc)
+ static void rtrs_clt_rkey_rsp_done(struct rtrs_clt_con *con, struct ib_wc *wc)
+ {
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
++      struct rtrs_clt_path *clt_path = to_clt_path(con->c.path);
+       struct rtrs_msg_rkey_rsp *msg;
+       u32 imm_type, imm_payload;
+       bool w_inval = false;
+@@ -529,7 +530,7 @@ static void rtrs_clt_rkey_rsp_done(struct rtrs_clt_con *con, struct ib_wc *wc)
+       u32 buf_id;
+       int err;
+-      WARN_ON((sess->flags & RTRS_MSG_NEW_RKEY_F) == 0);
++      WARN_ON((clt_path->flags & RTRS_MSG_NEW_RKEY_F) == 0);
+       iu = container_of(wc->wr_cqe, struct rtrs_iu, cqe);
+@@ -538,16 +539,17 @@ static void rtrs_clt_rkey_rsp_done(struct rtrs_clt_con *con, struct ib_wc *wc)
+                         wc->byte_len);
+               goto out;
+       }
+-      ib_dma_sync_single_for_cpu(sess->s.dev->ib_dev, iu->dma_addr,
++      ib_dma_sync_single_for_cpu(clt_path->s.dev->ib_dev, iu->dma_addr,
+                                  iu->size, DMA_FROM_DEVICE);
+       msg = iu->buf;
+       if (le16_to_cpu(msg->type) != RTRS_MSG_RKEY_RSP) {
+-              rtrs_err(sess->clt, "rkey response is malformed: type %d\n",
++              rtrs_err(clt_path->clt,
++                        "rkey response is malformed: type %d\n",
+                         le16_to_cpu(msg->type));
+               goto out;
+       }
+       buf_id = le16_to_cpu(msg->buf_id);
+-      if (WARN_ON(buf_id >= sess->queue_depth))
++      if (WARN_ON(buf_id >= clt_path->queue_depth))
+               goto out;
+       rtrs_from_imm(be32_to_cpu(wc->ex.imm_data), &imm_type, &imm_payload);
+@@ -560,10 +562,10 @@ static void rtrs_clt_rkey_rsp_done(struct rtrs_clt_con *con, struct ib_wc *wc)
+               if (WARN_ON(buf_id != msg_id))
+                       goto out;
+-              sess->rbufs[buf_id].rkey = le32_to_cpu(msg->rkey);
+-              process_io_rsp(sess, msg_id, err, w_inval);
++              clt_path->rbufs[buf_id].rkey = le32_to_cpu(msg->rkey);
++              process_io_rsp(clt_path, msg_id, err, w_inval);
+       }
+-      ib_dma_sync_single_for_device(sess->s.dev->ib_dev, iu->dma_addr,
++      ib_dma_sync_single_for_device(clt_path->s.dev->ib_dev, iu->dma_addr,
+                                     iu->size, DMA_FROM_DEVICE);
+       return rtrs_clt_recv_done(con, wc);
+ out:
+@@ -600,14 +602,14 @@ static int rtrs_post_recv_empty_x2(struct rtrs_con *con, struct ib_cqe *cqe)
+ static void rtrs_clt_rdma_done(struct ib_cq *cq, struct ib_wc *wc)
+ {
+       struct rtrs_clt_con *con = to_clt_con(wc->qp->qp_context);
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
++      struct rtrs_clt_path *clt_path = to_clt_path(con->c.path);
+       u32 imm_type, imm_payload;
+       bool w_inval = false;
+       int err;
+       if (wc->status != IB_WC_SUCCESS) {
+               if (wc->status != IB_WC_WR_FLUSH_ERR) {
+-                      rtrs_err(sess->clt, "RDMA failed: %s\n",
++                      rtrs_err(clt_path->clt, "RDMA failed: %s\n",
+                                 ib_wc_status_msg(wc->status));
+                       rtrs_rdma_error_recovery(con);
+               }
+@@ -632,18 +634,18 @@ static void rtrs_clt_rdma_done(struct ib_cq *cq, struct ib_wc *wc)
+                       w_inval = (imm_type == RTRS_IO_RSP_W_INV_IMM);
+                       rtrs_from_io_rsp_imm(imm_payload, &msg_id, &err);
+-                      process_io_rsp(sess, msg_id, err, w_inval);
++                      process_io_rsp(clt_path, msg_id, err, w_inval);
+               } else if (imm_type == RTRS_HB_MSG_IMM) {
+                       WARN_ON(con->c.cid);
+-                      rtrs_send_hb_ack(&sess->s);
+-                      if (sess->flags & RTRS_MSG_NEW_RKEY_F)
++                      rtrs_send_hb_ack(&clt_path->s);
++                      if (clt_path->flags & RTRS_MSG_NEW_RKEY_F)
+                               return  rtrs_clt_recv_done(con, wc);
+               } else if (imm_type == RTRS_HB_ACK_IMM) {
+                       WARN_ON(con->c.cid);
+-                      sess->s.hb_missed_cnt = 0;
+-                      sess->s.hb_cur_latency =
+-                              ktime_sub(ktime_get(), sess->s.hb_last_sent);
+-                      if (sess->flags & RTRS_MSG_NEW_RKEY_F)
++                      clt_path->s.hb_missed_cnt = 0;
++                      clt_path->s.hb_cur_latency =
++                              ktime_sub(ktime_get(), clt_path->s.hb_last_sent);
++                      if (clt_path->flags & RTRS_MSG_NEW_RKEY_F)
+                               return  rtrs_clt_recv_done(con, wc);
+               } else {
+                       rtrs_wrn(con->c.path, "Unknown IMM type %u\n",
+@@ -670,7 +672,7 @@ static void rtrs_clt_rdma_done(struct ib_cq *cq, struct ib_wc *wc)
+               WARN_ON(!(wc->wc_flags & IB_WC_WITH_INVALIDATE ||
+                         wc->wc_flags & IB_WC_WITH_IMM));
+               WARN_ON(wc->wr_cqe->done != rtrs_clt_rdma_done);
+-              if (sess->flags & RTRS_MSG_NEW_RKEY_F) {
++              if (clt_path->flags & RTRS_MSG_NEW_RKEY_F) {
+                       if (wc->wc_flags & IB_WC_WITH_INVALIDATE)
+                               return  rtrs_clt_recv_done(con, wc);
+@@ -685,7 +687,7 @@ static void rtrs_clt_rdma_done(struct ib_cq *cq, struct ib_wc *wc)
+               break;
+       default:
+-              rtrs_wrn(sess->clt, "Unexpected WC type: %d\n", wc->opcode);
++              rtrs_wrn(clt_path->clt, "Unexpected WC type: %d\n", wc->opcode);
+               return;
+       }
+ }
+@@ -693,10 +695,10 @@ static void rtrs_clt_rdma_done(struct ib_cq *cq, struct ib_wc *wc)
+ static int post_recv_io(struct rtrs_clt_con *con, size_t q_size)
+ {
+       int err, i;
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
++      struct rtrs_clt_path *clt_path = to_clt_path(con->c.path);
+       for (i = 0; i < q_size; i++) {
+-              if (sess->flags & RTRS_MSG_NEW_RKEY_F) {
++              if (clt_path->flags & RTRS_MSG_NEW_RKEY_F) {
+                       struct rtrs_iu *iu = &con->rsp_ius[i];
+                       err = rtrs_iu_post_recv(&con->c, iu);
+@@ -710,16 +712,16 @@ static int post_recv_io(struct rtrs_clt_con *con, size_t q_size)
+       return 0;
+ }
+-static int post_recv_sess(struct rtrs_clt_sess *sess)
++static int post_recv_path(struct rtrs_clt_path *clt_path)
+ {
+       size_t q_size = 0;
+       int err, cid;
+-      for (cid = 0; cid < sess->s.con_num; cid++) {
++      for (cid = 0; cid < clt_path->s.con_num; cid++) {
+               if (cid == 0)
+                       q_size = SERVICE_CON_QUEUE_DEPTH;
+               else
+-                      q_size = sess->queue_depth;
++                      q_size = clt_path->queue_depth;
+               /*
+                * x2 for RDMA read responses + FR key invalidations,
+@@ -727,9 +729,10 @@ static int post_recv_sess(struct rtrs_clt_sess *sess)
+                */
+               q_size *= 2;
+-              err = post_recv_io(to_clt_con(sess->s.con[cid]), q_size);
++              err = post_recv_io(to_clt_con(clt_path->s.con[cid]), q_size);
+               if (err) {
+-                      rtrs_err(sess->clt, "post_recv_io(), err: %d\n", err);
++                      rtrs_err(clt_path->clt, "post_recv_io(), err: %d\n",
++                               err);
+                       return err;
+               }
+       }
+@@ -741,7 +744,7 @@ struct path_it {
+       int i;
+       struct list_head skip_list;
+       struct rtrs_clt *clt;
+-      struct rtrs_clt_sess *(*next_path)(struct path_it *it);
++      struct rtrs_clt_path *(*next_path)(struct path_it *it);
+ };
+ /**
+@@ -773,10 +776,10 @@ struct path_it {
+  * Locks:
+  *    rcu_read_lock() must be hold.
+  */
+-static struct rtrs_clt_sess *get_next_path_rr(struct path_it *it)
++static struct rtrs_clt_path *get_next_path_rr(struct path_it *it)
+ {
+-      struct rtrs_clt_sess __rcu **ppcpu_path;
+-      struct rtrs_clt_sess *path;
++      struct rtrs_clt_path __rcu **ppcpu_path;
++      struct rtrs_clt_path *path;
+       struct rtrs_clt *clt;
+       clt = it->clt;
+@@ -811,26 +814,26 @@ static struct rtrs_clt_sess *get_next_path_rr(struct path_it *it)
+  * Locks:
+  *    rcu_read_lock() must be hold.
+  */
+-static struct rtrs_clt_sess *get_next_path_min_inflight(struct path_it *it)
++static struct rtrs_clt_path *get_next_path_min_inflight(struct path_it *it)
+ {
+-      struct rtrs_clt_sess *min_path = NULL;
++      struct rtrs_clt_path *min_path = NULL;
+       struct rtrs_clt *clt = it->clt;
+-      struct rtrs_clt_sess *sess;
++      struct rtrs_clt_path *clt_path;
+       int min_inflight = INT_MAX;
+       int inflight;
+-      list_for_each_entry_rcu(sess, &clt->paths_list, s.entry) {
+-              if (READ_ONCE(sess->state) != RTRS_CLT_CONNECTED)
++      list_for_each_entry_rcu(clt_path, &clt->paths_list, s.entry) {
++              if (READ_ONCE(clt_path->state) != RTRS_CLT_CONNECTED)
+                       continue;
+-              if (!list_empty(raw_cpu_ptr(sess->mp_skip_entry)))
++              if (!list_empty(raw_cpu_ptr(clt_path->mp_skip_entry)))
+                       continue;
+-              inflight = atomic_read(&sess->stats->inflight);
++              inflight = atomic_read(&clt_path->stats->inflight);
+               if (inflight < min_inflight) {
+                       min_inflight = inflight;
+-                      min_path = sess;
++                      min_path = clt_path;
+               }
+       }
+@@ -862,26 +865,26 @@ static struct rtrs_clt_sess *get_next_path_min_inflight(struct path_it *it)
+  * Therefore the caller MUST check the returned
+  * path is NULL and trigger the IO error.
+  */
+-static struct rtrs_clt_sess *get_next_path_min_latency(struct path_it *it)
++static struct rtrs_clt_path *get_next_path_min_latency(struct path_it *it)
+ {
+-      struct rtrs_clt_sess *min_path = NULL;
++      struct rtrs_clt_path *min_path = NULL;
+       struct rtrs_clt *clt = it->clt;
+-      struct rtrs_clt_sess *sess;
++      struct rtrs_clt_path *clt_path;
+       ktime_t min_latency = KTIME_MAX;
+       ktime_t latency;
+-      list_for_each_entry_rcu(sess, &clt->paths_list, s.entry) {
+-              if (READ_ONCE(sess->state) != RTRS_CLT_CONNECTED)
++      list_for_each_entry_rcu(clt_path, &clt->paths_list, s.entry) {
++              if (READ_ONCE(clt_path->state) != RTRS_CLT_CONNECTED)
+                       continue;
+-              if (!list_empty(raw_cpu_ptr(sess->mp_skip_entry)))
++              if (!list_empty(raw_cpu_ptr(clt_path->mp_skip_entry)))
+                       continue;
+-              latency = sess->s.hb_cur_latency;
++              latency = clt_path->s.hb_cur_latency;
+               if (latency < min_latency) {
+                       min_latency = latency;
+-                      min_path = sess;
++                      min_path = clt_path;
+               }
+       }
+@@ -928,7 +931,7 @@ static inline void path_it_deinit(struct path_it *it)
+  * the corresponding buffer of rtrs_iu (req->iu->buf), which later on will
+  * also hold the control message of rtrs.
+  * @req: an io request holding information about IO.
+- * @sess: client session
++ * @clt_path: client path
+  * @conf: conformation callback function to notify upper layer.
+  * @permit: permit for allocation of RDMA remote buffer
+  * @priv: private pointer
+@@ -940,7 +943,7 @@ static inline void path_it_deinit(struct path_it *it)
+  * @dir: direction of the IO.
+  */
+ static void rtrs_clt_init_req(struct rtrs_clt_io_req *req,
+-                            struct rtrs_clt_sess *sess,
++                            struct rtrs_clt_path *clt_path,
+                             void (*conf)(void *priv, int errno),
+                             struct rtrs_permit *permit, void *priv,
+                             const struct kvec *vec, size_t usr_len,
+@@ -958,13 +961,13 @@ static void rtrs_clt_init_req(struct rtrs_clt_io_req *req,
+       req->sg_cnt = sg_cnt;
+       req->priv = priv;
+       req->dir = dir;
+-      req->con = rtrs_permit_to_clt_con(sess, permit);
++      req->con = rtrs_permit_to_clt_con(clt_path, permit);
+       req->conf = conf;
+       req->need_inv = false;
+       req->need_inv_comp = false;
+       req->inv_errno = 0;
+       refcount_set(&req->ref, 1);
+-      req->mp_policy = sess->clt->mp_policy;
++      req->mp_policy = clt_path->clt->mp_policy;
+       iov_iter_kvec(&iter, READ, vec, 1, usr_len);
+       len = _copy_from_iter(req->iu->buf, usr_len, &iter);
+@@ -974,7 +977,7 @@ static void rtrs_clt_init_req(struct rtrs_clt_io_req *req,
+ }
+ static struct rtrs_clt_io_req *
+-rtrs_clt_get_req(struct rtrs_clt_sess *sess,
++rtrs_clt_get_req(struct rtrs_clt_path *clt_path,
+                void (*conf)(void *priv, int errno),
+                struct rtrs_permit *permit, void *priv,
+                const struct kvec *vec, size_t usr_len,
+@@ -983,14 +986,14 @@ rtrs_clt_get_req(struct rtrs_clt_sess *sess,
+ {
+       struct rtrs_clt_io_req *req;
+-      req = &sess->reqs[permit->mem_id];
+-      rtrs_clt_init_req(req, sess, conf, permit, priv, vec, usr_len,
++      req = &clt_path->reqs[permit->mem_id];
++      rtrs_clt_init_req(req, clt_path, conf, permit, priv, vec, usr_len,
+                          sg, sg_cnt, data_len, dir);
+       return req;
+ }
+ static struct rtrs_clt_io_req *
+-rtrs_clt_get_copy_req(struct rtrs_clt_sess *alive_sess,
++rtrs_clt_get_copy_req(struct rtrs_clt_path *alive_path,
+                      struct rtrs_clt_io_req *fail_req)
+ {
+       struct rtrs_clt_io_req *req;
+@@ -999,8 +1002,8 @@ rtrs_clt_get_copy_req(struct rtrs_clt_sess *alive_sess,
+               .iov_len  = fail_req->usr_len
+       };
+-      req = &alive_sess->reqs[fail_req->permit->mem_id];
+-      rtrs_clt_init_req(req, alive_sess, fail_req->conf, fail_req->permit,
++      req = &alive_path->reqs[fail_req->permit->mem_id];
++      rtrs_clt_init_req(req, alive_path, fail_req->conf, fail_req->permit,
+                          fail_req->priv, &vec, fail_req->usr_len,
+                          fail_req->sglist, fail_req->sg_cnt,
+                          fail_req->data_len, fail_req->dir);
+@@ -1013,7 +1016,7 @@ static int rtrs_post_rdma_write_sg(struct rtrs_clt_con *con,
+                                  u32 size, u32 imm, struct ib_send_wr *wr,
+                                  struct ib_send_wr *tail)
+ {
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
++      struct rtrs_clt_path *clt_path = to_clt_path(con->c.path);
+       struct ib_sge *sge = req->sge;
+       enum ib_send_flags flags;
+       struct scatterlist *sg;
+@@ -1033,22 +1036,23 @@ static int rtrs_post_rdma_write_sg(struct rtrs_clt_con *con,
+               for_each_sg(req->sglist, sg, req->sg_cnt, i) {
+                       sge[i].addr   = sg_dma_address(sg);
+                       sge[i].length = sg_dma_len(sg);
+-                      sge[i].lkey   = sess->s.dev->ib_pd->local_dma_lkey;
++                      sge[i].lkey   = clt_path->s.dev->ib_pd->local_dma_lkey;
+               }
+               num_sge = 1 + req->sg_cnt;
+       }
+       sge[i].addr   = req->iu->dma_addr;
+       sge[i].length = size;
+-      sge[i].lkey   = sess->s.dev->ib_pd->local_dma_lkey;
++      sge[i].lkey   = clt_path->s.dev->ib_pd->local_dma_lkey;
+       /*
+        * From time to time we have to post signalled sends,
+        * or send queue will fill up and only QP reset can help.
+        */
+-      flags = atomic_inc_return(&con->c.wr_cnt) % sess->s.signal_interval ?
++      flags = atomic_inc_return(&con->c.wr_cnt) % clt_path->s.signal_interval ?
+                       0 : IB_SEND_SIGNALED;
+-      ib_dma_sync_single_for_device(sess->s.dev->ib_dev, req->iu->dma_addr,
++      ib_dma_sync_single_for_device(clt_path->s.dev->ib_dev,
++                                    req->iu->dma_addr,
+                                     size, DMA_TO_DEVICE);
+       return rtrs_iu_post_rdma_write_imm(&con->c, req->iu, sge, num_sge,
+@@ -1075,7 +1079,7 @@ static int rtrs_clt_write_req(struct rtrs_clt_io_req *req)
+ {
+       struct rtrs_clt_con *con = req->con;
+       struct rtrs_path *s = con->c.path;
+-      struct rtrs_clt_sess *sess = to_clt_sess(s);
++      struct rtrs_clt_path *clt_path = to_clt_path(s);
+       struct rtrs_msg_rdma_write *msg;
+       struct rtrs_rbuf *rbuf;
+@@ -1088,13 +1092,13 @@ static int rtrs_clt_write_req(struct rtrs_clt_io_req *req)
+       const size_t tsize = sizeof(*msg) + req->data_len + req->usr_len;
+-      if (tsize > sess->chunk_size) {
++      if (tsize > clt_path->chunk_size) {
+               rtrs_wrn(s, "Write request failed, size too big %zu > %d\n",
+-                        tsize, sess->chunk_size);
++                        tsize, clt_path->chunk_size);
+               return -EMSGSIZE;
+       }
+       if (req->sg_cnt) {
+-              count = ib_dma_map_sg(sess->s.dev->ib_dev, req->sglist,
++              count = ib_dma_map_sg(clt_path->s.dev->ib_dev, req->sglist,
+                                     req->sg_cnt, req->dir);
+               if (!count) {
+                       rtrs_wrn(s, "Write request failed, map failed\n");
+@@ -1111,7 +1115,7 @@ static int rtrs_clt_write_req(struct rtrs_clt_io_req *req)
+       imm = rtrs_to_io_req_imm(imm);
+       buf_id = req->permit->mem_id;
+       req->sg_size = tsize;
+-      rbuf = &sess->rbufs[buf_id];
++      rbuf = &clt_path->rbufs[buf_id];
+       if (count) {
+               ret = rtrs_map_sg_fr(req, count);
+@@ -1119,7 +1123,7 @@ static int rtrs_clt_write_req(struct rtrs_clt_io_req *req)
+                       rtrs_err_rl(s,
+                                   "Write request failed, failed to map fast reg. data, err: %d\n",
+                                   ret);
+-                      ib_dma_unmap_sg(sess->s.dev->ib_dev, req->sglist,
++                      ib_dma_unmap_sg(clt_path->s.dev->ib_dev, req->sglist,
+                                       req->sg_cnt, req->dir);
+                       return ret;
+               }
+@@ -1153,12 +1157,12 @@ static int rtrs_clt_write_req(struct rtrs_clt_io_req *req)
+       if (ret) {
+               rtrs_err_rl(s,
+                           "Write request failed: error=%d path=%s [%s:%u]\n",
+-                          ret, kobject_name(&sess->kobj), sess->hca_name,
+-                          sess->hca_port);
++                          ret, kobject_name(&clt_path->kobj), clt_path->hca_name,
++                          clt_path->hca_port);
+               if (req->mp_policy == MP_POLICY_MIN_INFLIGHT)
+-                      atomic_dec(&sess->stats->inflight);
++                      atomic_dec(&clt_path->stats->inflight);
+               if (req->sg_cnt)
+-                      ib_dma_unmap_sg(sess->s.dev->ib_dev, req->sglist,
++                      ib_dma_unmap_sg(clt_path->s.dev->ib_dev, req->sglist,
+                                       req->sg_cnt, req->dir);
+       }
+@@ -1169,9 +1173,9 @@ static int rtrs_clt_read_req(struct rtrs_clt_io_req *req)
+ {
+       struct rtrs_clt_con *con = req->con;
+       struct rtrs_path *s = con->c.path;
+-      struct rtrs_clt_sess *sess = to_clt_sess(s);
++      struct rtrs_clt_path *clt_path = to_clt_path(s);
+       struct rtrs_msg_rdma_read *msg;
+-      struct rtrs_ib_dev *dev = sess->s.dev;
++      struct rtrs_ib_dev *dev = clt_path->s.dev;
+       struct ib_reg_wr rwr;
+       struct ib_send_wr *wr = NULL;
+@@ -1181,10 +1185,10 @@ static int rtrs_clt_read_req(struct rtrs_clt_io_req *req)
+       const size_t tsize = sizeof(*msg) + req->data_len + req->usr_len;
+-      if (tsize > sess->chunk_size) {
++      if (tsize > clt_path->chunk_size) {
+               rtrs_wrn(s,
+                         "Read request failed, message size is %zu, bigger than CHUNK_SIZE %d\n",
+-                        tsize, sess->chunk_size);
++                        tsize, clt_path->chunk_size);
+               return -EMSGSIZE;
+       }
+@@ -1254,15 +1258,15 @@ static int rtrs_clt_read_req(struct rtrs_clt_io_req *req)
+        */
+       rtrs_clt_update_all_stats(req, READ);
+-      ret = rtrs_post_send_rdma(req->con, req, &sess->rbufs[buf_id],
++      ret = rtrs_post_send_rdma(req->con, req, &clt_path->rbufs[buf_id],
+                                  req->data_len, imm, wr);
+       if (ret) {
+               rtrs_err_rl(s,
+                           "Read request failed: error=%d path=%s [%s:%u]\n",
+-                          ret, kobject_name(&sess->kobj), sess->hca_name,
+-                          sess->hca_port);
++                          ret, kobject_name(&clt_path->kobj), clt_path->hca_name,
++                          clt_path->hca_port);
+               if (req->mp_policy == MP_POLICY_MIN_INFLIGHT)
+-                      atomic_dec(&sess->stats->inflight);
++                      atomic_dec(&clt_path->stats->inflight);
+               req->need_inv = false;
+               if (req->sg_cnt)
+                       ib_dma_unmap_sg(dev->ib_dev, req->sglist,
+@@ -1280,18 +1284,18 @@ static int rtrs_clt_read_req(struct rtrs_clt_io_req *req)
+ static int rtrs_clt_failover_req(struct rtrs_clt *clt,
+                                struct rtrs_clt_io_req *fail_req)
+ {
+-      struct rtrs_clt_sess *alive_sess;
++      struct rtrs_clt_path *alive_path;
+       struct rtrs_clt_io_req *req;
+       int err = -ECONNABORTED;
+       struct path_it it;
+       rcu_read_lock();
+       for (path_it_init(&it, clt);
+-           (alive_sess = it.next_path(&it)) && it.i < it.clt->paths_num;
++           (alive_path = it.next_path(&it)) && it.i < it.clt->paths_num;
+            it.i++) {
+-              if (READ_ONCE(alive_sess->state) != RTRS_CLT_CONNECTED)
++              if (READ_ONCE(alive_path->state) != RTRS_CLT_CONNECTED)
+                       continue;
+-              req = rtrs_clt_get_copy_req(alive_sess, fail_req);
++              req = rtrs_clt_get_copy_req(alive_path, fail_req);
+               if (req->dir == DMA_TO_DEVICE)
+                       err = rtrs_clt_write_req(req);
+               else
+@@ -1301,7 +1305,7 @@ static int rtrs_clt_failover_req(struct rtrs_clt *clt,
+                       continue;
+               }
+               /* Success path */
+-              rtrs_clt_inc_failover_cnt(alive_sess->stats);
++              rtrs_clt_inc_failover_cnt(alive_path->stats);
+               break;
+       }
+       path_it_deinit(&it);
+@@ -1310,16 +1314,16 @@ static int rtrs_clt_failover_req(struct rtrs_clt *clt,
+       return err;
+ }
+-static void fail_all_outstanding_reqs(struct rtrs_clt_sess *sess)
++static void fail_all_outstanding_reqs(struct rtrs_clt_path *clt_path)
+ {
+-      struct rtrs_clt *clt = sess->clt;
++      struct rtrs_clt *clt = clt_path->clt;
+       struct rtrs_clt_io_req *req;
+       int i, err;
+-      if (!sess->reqs)
++      if (!clt_path->reqs)
+               return;
+-      for (i = 0; i < sess->queue_depth; ++i) {
+-              req = &sess->reqs[i];
++      for (i = 0; i < clt_path->queue_depth; ++i) {
++              req = &clt_path->reqs[i];
+               if (!req->in_use)
+                       continue;
+@@ -1337,38 +1341,39 @@ static void fail_all_outstanding_reqs(struct rtrs_clt_sess *sess)
+       }
+ }
+-static void free_sess_reqs(struct rtrs_clt_sess *sess)
++static void free_path_reqs(struct rtrs_clt_path *clt_path)
+ {
+       struct rtrs_clt_io_req *req;
+       int i;
+-      if (!sess->reqs)
++      if (!clt_path->reqs)
+               return;
+-      for (i = 0; i < sess->queue_depth; ++i) {
+-              req = &sess->reqs[i];
++      for (i = 0; i < clt_path->queue_depth; ++i) {
++              req = &clt_path->reqs[i];
+               if (req->mr)
+                       ib_dereg_mr(req->mr);
+               kfree(req->sge);
+-              rtrs_iu_free(req->iu, sess->s.dev->ib_dev, 1);
++              rtrs_iu_free(req->iu, clt_path->s.dev->ib_dev, 1);
+       }
+-      kfree(sess->reqs);
+-      sess->reqs = NULL;
++      kfree(clt_path->reqs);
++      clt_path->reqs = NULL;
+ }
+-static int alloc_sess_reqs(struct rtrs_clt_sess *sess)
++static int alloc_path_reqs(struct rtrs_clt_path *clt_path)
+ {
+       struct rtrs_clt_io_req *req;
+       int i, err = -ENOMEM;
+-      sess->reqs = kcalloc(sess->queue_depth, sizeof(*sess->reqs),
+-                           GFP_KERNEL);
+-      if (!sess->reqs)
++      clt_path->reqs = kcalloc(clt_path->queue_depth,
++                               sizeof(*clt_path->reqs),
++                               GFP_KERNEL);
++      if (!clt_path->reqs)
+               return -ENOMEM;
+-      for (i = 0; i < sess->queue_depth; ++i) {
+-              req = &sess->reqs[i];
+-              req->iu = rtrs_iu_alloc(1, sess->max_hdr_size, GFP_KERNEL,
+-                                       sess->s.dev->ib_dev,
++      for (i = 0; i < clt_path->queue_depth; ++i) {
++              req = &clt_path->reqs[i];
++              req->iu = rtrs_iu_alloc(1, clt_path->max_hdr_size, GFP_KERNEL,
++                                       clt_path->s.dev->ib_dev,
+                                        DMA_TO_DEVICE,
+                                        rtrs_clt_rdma_done);
+               if (!req->iu)
+@@ -1378,13 +1383,14 @@ static int alloc_sess_reqs(struct rtrs_clt_sess *sess)
+               if (!req->sge)
+                       goto out;
+-              req->mr = ib_alloc_mr(sess->s.dev->ib_pd, IB_MR_TYPE_MEM_REG,
+-                                    sess->max_pages_per_mr);
++              req->mr = ib_alloc_mr(clt_path->s.dev->ib_pd,
++                                    IB_MR_TYPE_MEM_REG,
++                                    clt_path->max_pages_per_mr);
+               if (IS_ERR(req->mr)) {
+                       err = PTR_ERR(req->mr);
+                       req->mr = NULL;
+-                      pr_err("Failed to alloc sess->max_pages_per_mr %d\n",
+-                             sess->max_pages_per_mr);
++                      pr_err("Failed to alloc clt_path->max_pages_per_mr %d\n",
++                             clt_path->max_pages_per_mr);
+                       goto out;
+               }
+@@ -1394,7 +1400,7 @@ static int alloc_sess_reqs(struct rtrs_clt_sess *sess)
+       return 0;
+ out:
+-      free_sess_reqs(sess);
++      free_path_reqs(clt_path);
+       return err;
+ }
+@@ -1447,13 +1453,13 @@ static void free_permits(struct rtrs_clt *clt)
+       clt->permits = NULL;
+ }
+-static void query_fast_reg_mode(struct rtrs_clt_sess *sess)
++static void query_fast_reg_mode(struct rtrs_clt_path *clt_path)
+ {
+       struct ib_device *ib_dev;
+       u64 max_pages_per_mr;
+       int mr_page_shift;
+-      ib_dev = sess->s.dev->ib_dev;
++      ib_dev = clt_path->s.dev->ib_dev;
+       /*
+        * Use the smallest page size supported by the HCA, down to a
+@@ -1463,24 +1469,24 @@ static void query_fast_reg_mode(struct rtrs_clt_sess *sess)
+       mr_page_shift      = max(12, ffs(ib_dev->attrs.page_size_cap) - 1);
+       max_pages_per_mr   = ib_dev->attrs.max_mr_size;
+       do_div(max_pages_per_mr, (1ull << mr_page_shift));
+-      sess->max_pages_per_mr =
+-              min3(sess->max_pages_per_mr, (u32)max_pages_per_mr,
++      clt_path->max_pages_per_mr =
++              min3(clt_path->max_pages_per_mr, (u32)max_pages_per_mr,
+                    ib_dev->attrs.max_fast_reg_page_list_len);
+-      sess->clt->max_segments =
+-              min(sess->max_pages_per_mr, sess->clt->max_segments);
++      clt_path->clt->max_segments =
++              min(clt_path->max_pages_per_mr, clt_path->clt->max_segments);
+ }
+-static bool rtrs_clt_change_state_get_old(struct rtrs_clt_sess *sess,
++static bool rtrs_clt_change_state_get_old(struct rtrs_clt_path *clt_path,
+                                          enum rtrs_clt_state new_state,
+                                          enum rtrs_clt_state *old_state)
+ {
+       bool changed;
+-      spin_lock_irq(&sess->state_wq.lock);
++      spin_lock_irq(&clt_path->state_wq.lock);
+       if (old_state)
+-              *old_state = sess->state;
+-      changed = rtrs_clt_change_state(sess, new_state);
+-      spin_unlock_irq(&sess->state_wq.lock);
++              *old_state = clt_path->state;
++      changed = rtrs_clt_change_state(clt_path, new_state);
++      spin_unlock_irq(&clt_path->state_wq.lock);
+       return changed;
+ }
+@@ -1492,9 +1498,9 @@ static void rtrs_clt_hb_err_handler(struct rtrs_con *c)
+       rtrs_rdma_error_recovery(con);
+ }
+-static void rtrs_clt_init_hb(struct rtrs_clt_sess *sess)
++static void rtrs_clt_init_hb(struct rtrs_clt_path *clt_path)
+ {
+-      rtrs_init_hb(&sess->s, &io_comp_cqe,
++      rtrs_init_hb(&clt_path->s, &io_comp_cqe,
+                     RTRS_HB_INTERVAL_MS,
+                     RTRS_HB_MISSED_MAX,
+                     rtrs_clt_hb_err_handler,
+@@ -1504,17 +1510,17 @@ static void rtrs_clt_init_hb(struct rtrs_clt_sess *sess)
+ static void rtrs_clt_reconnect_work(struct work_struct *work);
+ static void rtrs_clt_close_work(struct work_struct *work);
+-static struct rtrs_clt_sess *alloc_sess(struct rtrs_clt *clt,
++static struct rtrs_clt_path *alloc_path(struct rtrs_clt *clt,
+                                       const struct rtrs_addr *path,
+                                       size_t con_num, u32 nr_poll_queues)
+ {
+-      struct rtrs_clt_sess *sess;
++      struct rtrs_clt_path *clt_path;
+       int err = -ENOMEM;
+       int cpu;
+       size_t total_con;
+-      sess = kzalloc(sizeof(*sess), GFP_KERNEL);
+-      if (!sess)
++      clt_path = kzalloc(sizeof(*clt_path), GFP_KERNEL);
++      if (!clt_path)
+               goto err;
+       /*
+@@ -1522,20 +1528,21 @@ static struct rtrs_clt_sess *alloc_sess(struct rtrs_clt *clt,
+        * +1: Extra connection for user messages
+        */
+       total_con = con_num + nr_poll_queues + 1;
+-      sess->s.con = kcalloc(total_con, sizeof(*sess->s.con), GFP_KERNEL);
+-      if (!sess->s.con)
+-              goto err_free_sess;
++      clt_path->s.con = kcalloc(total_con, sizeof(*clt_path->s.con),
++                                GFP_KERNEL);
++      if (!clt_path->s.con)
++              goto err_free_path;
+-      sess->s.con_num = total_con;
+-      sess->s.irq_con_num = con_num + 1;
++      clt_path->s.con_num = total_con;
++      clt_path->s.irq_con_num = con_num + 1;
+-      sess->stats = kzalloc(sizeof(*sess->stats), GFP_KERNEL);
+-      if (!sess->stats)
++      clt_path->stats = kzalloc(sizeof(*clt_path->stats), GFP_KERNEL);
++      if (!clt_path->stats)
+               goto err_free_con;
+-      mutex_init(&sess->init_mutex);
+-      uuid_gen(&sess->s.uuid);
+-      memcpy(&sess->s.dst_addr, path->dst,
++      mutex_init(&clt_path->init_mutex);
++      uuid_gen(&clt_path->s.uuid);
++      memcpy(&clt_path->s.dst_addr, path->dst,
+              rdma_addr_size((struct sockaddr *)path->dst));
+       /*
+@@ -1544,53 +1551,54 @@ static struct rtrs_clt_sess *alloc_sess(struct rtrs_clt *clt,
+        * the sess->src_addr will contain only zeros, which is then fine.
+        */
+       if (path->src)
+-              memcpy(&sess->s.src_addr, path->src,
++              memcpy(&clt_path->s.src_addr, path->src,
+                      rdma_addr_size((struct sockaddr *)path->src));
+-      strscpy(sess->s.sessname, clt->sessname, sizeof(sess->s.sessname));
+-      sess->clt = clt;
+-      sess->max_pages_per_mr = RTRS_MAX_SEGMENTS;
+-      init_waitqueue_head(&sess->state_wq);
+-      sess->state = RTRS_CLT_CONNECTING;
+-      atomic_set(&sess->connected_cnt, 0);
+-      INIT_WORK(&sess->close_work, rtrs_clt_close_work);
+-      INIT_DELAYED_WORK(&sess->reconnect_dwork, rtrs_clt_reconnect_work);
+-      rtrs_clt_init_hb(sess);
+-
+-      sess->mp_skip_entry = alloc_percpu(typeof(*sess->mp_skip_entry));
+-      if (!sess->mp_skip_entry)
++      strscpy(clt_path->s.sessname, clt->sessname,
++              sizeof(clt_path->s.sessname));
++      clt_path->clt = clt;
++      clt_path->max_pages_per_mr = RTRS_MAX_SEGMENTS;
++      init_waitqueue_head(&clt_path->state_wq);
++      clt_path->state = RTRS_CLT_CONNECTING;
++      atomic_set(&clt_path->connected_cnt, 0);
++      INIT_WORK(&clt_path->close_work, rtrs_clt_close_work);
++      INIT_DELAYED_WORK(&clt_path->reconnect_dwork, rtrs_clt_reconnect_work);
++      rtrs_clt_init_hb(clt_path);
++
++      clt_path->mp_skip_entry = alloc_percpu(typeof(*clt_path->mp_skip_entry));
++      if (!clt_path->mp_skip_entry)
+               goto err_free_stats;
+       for_each_possible_cpu(cpu)
+-              INIT_LIST_HEAD(per_cpu_ptr(sess->mp_skip_entry, cpu));
++              INIT_LIST_HEAD(per_cpu_ptr(clt_path->mp_skip_entry, cpu));
+-      err = rtrs_clt_init_stats(sess->stats);
++      err = rtrs_clt_init_stats(clt_path->stats);
+       if (err)
+               goto err_free_percpu;
+-      return sess;
++      return clt_path;
+ err_free_percpu:
+-      free_percpu(sess->mp_skip_entry);
++      free_percpu(clt_path->mp_skip_entry);
+ err_free_stats:
+-      kfree(sess->stats);
++      kfree(clt_path->stats);
+ err_free_con:
+-      kfree(sess->s.con);
+-err_free_sess:
+-      kfree(sess);
++      kfree(clt_path->s.con);
++err_free_path:
++      kfree(clt_path);
+ err:
+       return ERR_PTR(err);
+ }
+-void free_sess(struct rtrs_clt_sess *sess)
++void free_path(struct rtrs_clt_path *clt_path)
+ {
+-      free_percpu(sess->mp_skip_entry);
+-      mutex_destroy(&sess->init_mutex);
+-      kfree(sess->s.con);
+-      kfree(sess->rbufs);
+-      kfree(sess);
++      free_percpu(clt_path->mp_skip_entry);
++      mutex_destroy(&clt_path->init_mutex);
++      kfree(clt_path->s.con);
++      kfree(clt_path->rbufs);
++      kfree(clt_path);
+ }
+-static int create_con(struct rtrs_clt_sess *sess, unsigned int cid)
++static int create_con(struct rtrs_clt_path *clt_path, unsigned int cid)
+ {
+       struct rtrs_clt_con *con;
+@@ -1601,28 +1609,28 @@ static int create_con(struct rtrs_clt_sess *sess, unsigned int cid)
+       /* Map first two connections to the first CPU */
+       con->cpu  = (cid ? cid - 1 : 0) % nr_cpu_ids;
+       con->c.cid = cid;
+-      con->c.path = &sess->s;
++      con->c.path = &clt_path->s;
+       /* Align with srv, init as 1 */
+       atomic_set(&con->c.wr_cnt, 1);
+       mutex_init(&con->con_mutex);
+-      sess->s.con[cid] = &con->c;
++      clt_path->s.con[cid] = &con->c;
+       return 0;
+ }
+ static void destroy_con(struct rtrs_clt_con *con)
+ {
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
++      struct rtrs_clt_path *clt_path = to_clt_path(con->c.path);
+-      sess->s.con[con->c.cid] = NULL;
++      clt_path->s.con[con->c.cid] = NULL;
+       mutex_destroy(&con->con_mutex);
+       kfree(con);
+ }
+ static int create_con_cq_qp(struct rtrs_clt_con *con)
+ {
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
++      struct rtrs_clt_path *clt_path = to_clt_path(con->c.path);
+       u32 max_send_wr, max_recv_wr, cq_num, max_send_sge, wr_limit;
+       int err, cq_vector;
+       struct rtrs_msg_rkey_rsp *rsp;
+@@ -1631,7 +1639,7 @@ static int create_con_cq_qp(struct rtrs_clt_con *con)
+       if (con->c.cid == 0) {
+               max_send_sge = 1;
+               /* We must be the first here */
+-              if (WARN_ON(sess->s.dev))
++              if (WARN_ON(clt_path->s.dev))
+                       return -EINVAL;
+               /*
+@@ -1639,16 +1647,16 @@ static int create_con_cq_qp(struct rtrs_clt_con *con)
+                * Be careful not to close user connection before ib dev
+                * is gracefully put.
+                */
+-              sess->s.dev = rtrs_ib_dev_find_or_add(con->c.cm_id->device,
++              clt_path->s.dev = rtrs_ib_dev_find_or_add(con->c.cm_id->device,
+                                                      &dev_pd);
+-              if (!sess->s.dev) {
+-                      rtrs_wrn(sess->clt,
++              if (!clt_path->s.dev) {
++                      rtrs_wrn(clt_path->clt,
+                                 "rtrs_ib_dev_find_get_or_add(): no memory\n");
+                       return -ENOMEM;
+               }
+-              sess->s.dev_ref = 1;
+-              query_fast_reg_mode(sess);
+-              wr_limit = sess->s.dev->ib_dev->attrs.max_qp_wr;
++              clt_path->s.dev_ref = 1;
++              query_fast_reg_mode(clt_path);
++              wr_limit = clt_path->s.dev->ib_dev->attrs.max_qp_wr;
+               /*
+                * Two (request + registration) completion for send
+                * Two for recv if always_invalidate is set on server
+@@ -1665,27 +1673,28 @@ static int create_con_cq_qp(struct rtrs_clt_con *con)
+                * This is always true if user connection (cid == 0) is
+                * established first.
+                */
+-              if (WARN_ON(!sess->s.dev))
++              if (WARN_ON(!clt_path->s.dev))
+                       return -EINVAL;
+-              if (WARN_ON(!sess->queue_depth))
++              if (WARN_ON(!clt_path->queue_depth))
+                       return -EINVAL;
+-              wr_limit = sess->s.dev->ib_dev->attrs.max_qp_wr;
++              wr_limit = clt_path->s.dev->ib_dev->attrs.max_qp_wr;
+               /* Shared between connections */
+-              sess->s.dev_ref++;
++              clt_path->s.dev_ref++;
+               max_send_wr = min_t(int, wr_limit,
+                             /* QD * (REQ + RSP + FR REGS or INVS) + drain */
+-                            sess->queue_depth * 3 + 1);
++                            clt_path->queue_depth * 3 + 1);
+               max_recv_wr = min_t(int, wr_limit,
+-                            sess->queue_depth * 3 + 1);
++                            clt_path->queue_depth * 3 + 1);
+               max_send_sge = 2;
+       }
+       atomic_set(&con->c.sq_wr_avail, max_send_wr);
+       cq_num = max_send_wr + max_recv_wr;
+       /* alloc iu to recv new rkey reply when server reports flags set */
+-      if (sess->flags & RTRS_MSG_NEW_RKEY_F || con->c.cid == 0) {
++      if (clt_path->flags & RTRS_MSG_NEW_RKEY_F || con->c.cid == 0) {
+               con->rsp_ius = rtrs_iu_alloc(cq_num, sizeof(*rsp),
+-                                            GFP_KERNEL, sess->s.dev->ib_dev,
++                                            GFP_KERNEL,
++                                            clt_path->s.dev->ib_dev,
+                                             DMA_FROM_DEVICE,
+                                             rtrs_clt_rdma_done);
+               if (!con->rsp_ius)
+@@ -1693,13 +1702,13 @@ static int create_con_cq_qp(struct rtrs_clt_con *con)
+               con->queue_num = cq_num;
+       }
+       cq_num = max_send_wr + max_recv_wr;
+-      cq_vector = con->cpu % sess->s.dev->ib_dev->num_comp_vectors;
+-      if (con->c.cid >= sess->s.irq_con_num)
+-              err = rtrs_cq_qp_create(&sess->s, &con->c, max_send_sge,
++      cq_vector = con->cpu % clt_path->s.dev->ib_dev->num_comp_vectors;
++      if (con->c.cid >= clt_path->s.irq_con_num)
++              err = rtrs_cq_qp_create(&clt_path->s, &con->c, max_send_sge,
+                                       cq_vector, cq_num, max_send_wr,
+                                       max_recv_wr, IB_POLL_DIRECT);
+       else
+-              err = rtrs_cq_qp_create(&sess->s, &con->c, max_send_sge,
++              err = rtrs_cq_qp_create(&clt_path->s, &con->c, max_send_sge,
+                                       cq_vector, cq_num, max_send_wr,
+                                       max_recv_wr, IB_POLL_SOFTIRQ);
+       /*
+@@ -1711,7 +1720,7 @@ static int create_con_cq_qp(struct rtrs_clt_con *con)
+ static void destroy_con_cq_qp(struct rtrs_clt_con *con)
+ {
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
++      struct rtrs_clt_path *clt_path = to_clt_path(con->c.path);
+       /*
+        * Be careful here: destroy_con_cq_qp() can be called even
+@@ -1720,13 +1729,14 @@ static void destroy_con_cq_qp(struct rtrs_clt_con *con)
+       lockdep_assert_held(&con->con_mutex);
+       rtrs_cq_qp_destroy(&con->c);
+       if (con->rsp_ius) {
+-              rtrs_iu_free(con->rsp_ius, sess->s.dev->ib_dev, con->queue_num);
++              rtrs_iu_free(con->rsp_ius, clt_path->s.dev->ib_dev,
++                           con->queue_num);
+               con->rsp_ius = NULL;
+               con->queue_num = 0;
+       }
+-      if (sess->s.dev_ref && !--sess->s.dev_ref) {
+-              rtrs_ib_dev_put(sess->s.dev);
+-              sess->s.dev = NULL;
++      if (clt_path->s.dev_ref && !--clt_path->s.dev_ref) {
++              rtrs_ib_dev_put(clt_path->s.dev);
++              clt_path->s.dev = NULL;
+       }
+ }
+@@ -1764,8 +1774,8 @@ static int rtrs_rdma_addr_resolved(struct rtrs_clt_con *con)
+ static int rtrs_rdma_route_resolved(struct rtrs_clt_con *con)
+ {
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
+-      struct rtrs_clt *clt = sess->clt;
++      struct rtrs_clt_path *clt_path = to_clt_path(con->c.path);
++      struct rtrs_clt *clt = clt_path->clt;
+       struct rtrs_msg_conn_req msg;
+       struct rdma_conn_param param;
+@@ -1782,11 +1792,11 @@ static int rtrs_rdma_route_resolved(struct rtrs_clt_con *con)
+               .magic = cpu_to_le16(RTRS_MAGIC),
+               .version = cpu_to_le16(RTRS_PROTO_VER),
+               .cid = cpu_to_le16(con->c.cid),
+-              .cid_num = cpu_to_le16(sess->s.con_num),
+-              .recon_cnt = cpu_to_le16(sess->s.recon_cnt),
++              .cid_num = cpu_to_le16(clt_path->s.con_num),
++              .recon_cnt = cpu_to_le16(clt_path->s.recon_cnt),
+       };
+-      msg.first_conn = sess->for_new_clt ? FIRST_CONN : 0;
+-      uuid_copy(&msg.sess_uuid, &sess->s.uuid);
++      msg.first_conn = clt_path->for_new_clt ? FIRST_CONN : 0;
++      uuid_copy(&msg.sess_uuid, &clt_path->s.uuid);
+       uuid_copy(&msg.paths_uuid, &clt->paths_uuid);
+       err = rdma_connect_locked(con->c.cm_id, &param);
+@@ -1799,8 +1809,8 @@ static int rtrs_rdma_route_resolved(struct rtrs_clt_con *con)
+ static int rtrs_rdma_conn_established(struct rtrs_clt_con *con,
+                                      struct rdma_cm_event *ev)
+ {
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
+-      struct rtrs_clt *clt = sess->clt;
++      struct rtrs_clt_path *clt_path = to_clt_path(con->c.path);
++      struct rtrs_clt *clt = clt_path->clt;
+       const struct rtrs_msg_conn_rsp *msg;
+       u16 version, queue_depth;
+       int errno;
+@@ -1831,31 +1841,32 @@ static int rtrs_rdma_conn_established(struct rtrs_clt_con *con,
+       if (con->c.cid == 0) {
+               queue_depth = le16_to_cpu(msg->queue_depth);
+-              if (sess->queue_depth > 0 && queue_depth != sess->queue_depth) {
++              if (clt_path->queue_depth > 0 && queue_depth != clt_path->queue_depth) {
+                       rtrs_err(clt, "Error: queue depth changed\n");
+                       /*
+                        * Stop any more reconnection attempts
+                        */
+-                      sess->reconnect_attempts = -1;
++                      clt_path->reconnect_attempts = -1;
+                       rtrs_err(clt,
+                               "Disabling auto-reconnect. Trigger a manual reconnect after issue is resolved\n");
+                       return -ECONNRESET;
+               }
+-              if (!sess->rbufs) {
+-                      sess->rbufs = kcalloc(queue_depth, sizeof(*sess->rbufs),
+-                                            GFP_KERNEL);
+-                      if (!sess->rbufs)
++              if (!clt_path->rbufs) {
++                      clt_path->rbufs = kcalloc(queue_depth,
++                                                sizeof(*clt_path->rbufs),
++                                                GFP_KERNEL);
++                      if (!clt_path->rbufs)
+                               return -ENOMEM;
+               }
+-              sess->queue_depth = queue_depth;
+-              sess->s.signal_interval = min_not_zero(queue_depth,
++              clt_path->queue_depth = queue_depth;
++              clt_path->s.signal_interval = min_not_zero(queue_depth,
+                                               (unsigned short) SERVICE_CON_QUEUE_DEPTH);
+-              sess->max_hdr_size = le32_to_cpu(msg->max_hdr_size);
+-              sess->max_io_size = le32_to_cpu(msg->max_io_size);
+-              sess->flags = le32_to_cpu(msg->flags);
+-              sess->chunk_size = sess->max_io_size + sess->max_hdr_size;
++              clt_path->max_hdr_size = le32_to_cpu(msg->max_hdr_size);
++              clt_path->max_io_size = le32_to_cpu(msg->max_io_size);
++              clt_path->flags = le32_to_cpu(msg->flags);
++              clt_path->chunk_size = clt_path->max_io_size + clt_path->max_hdr_size;
+               /*
+                * Global IO size is always a minimum.
+@@ -1866,20 +1877,20 @@ static int rtrs_rdma_conn_established(struct rtrs_clt_con *con,
+                * connections in parallel, use lock.
+                */
+               mutex_lock(&clt->paths_mutex);
+-              clt->queue_depth = sess->queue_depth;
+-              clt->max_io_size = min_not_zero(sess->max_io_size,
++              clt->queue_depth = clt_path->queue_depth;
++              clt->max_io_size = min_not_zero(clt_path->max_io_size,
+                                               clt->max_io_size);
+               mutex_unlock(&clt->paths_mutex);
+               /*
+                * Cache the hca_port and hca_name for sysfs
+                */
+-              sess->hca_port = con->c.cm_id->port_num;
+-              scnprintf(sess->hca_name, sizeof(sess->hca_name),
+-                        sess->s.dev->ib_dev->name);
+-              sess->s.src_addr = con->c.cm_id->route.addr.src_addr;
++              clt_path->hca_port = con->c.cm_id->port_num;
++              scnprintf(clt_path->hca_name, sizeof(clt_path->hca_name),
++                        clt_path->s.dev->ib_dev->name);
++              clt_path->s.src_addr = con->c.cm_id->route.addr.src_addr;
+               /* set for_new_clt, to allow future reconnect on any path */
+-              sess->for_new_clt = 1;
++              clt_path->for_new_clt = 1;
+       }
+       return 0;
+@@ -1887,9 +1898,9 @@ static int rtrs_rdma_conn_established(struct rtrs_clt_con *con,
+ static inline void flag_success_on_conn(struct rtrs_clt_con *con)
+ {
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
++      struct rtrs_clt_path *clt_path = to_clt_path(con->c.path);
+-      atomic_inc(&sess->connected_cnt);
++      atomic_inc(&clt_path->connected_cnt);
+       con->cm_err = 1;
+ }
+@@ -1924,23 +1935,23 @@ static int rtrs_rdma_conn_rejected(struct rtrs_clt_con *con,
+       return -ECONNRESET;
+ }
+-void rtrs_clt_close_conns(struct rtrs_clt_sess *sess, bool wait)
++void rtrs_clt_close_conns(struct rtrs_clt_path *clt_path, bool wait)
+ {
+-      if (rtrs_clt_change_state_get_old(sess, RTRS_CLT_CLOSING, NULL))
+-              queue_work(rtrs_wq, &sess->close_work);
++      if (rtrs_clt_change_state_get_old(clt_path, RTRS_CLT_CLOSING, NULL))
++              queue_work(rtrs_wq, &clt_path->close_work);
+       if (wait)
+-              flush_work(&sess->close_work);
++              flush_work(&clt_path->close_work);
+ }
+ static inline void flag_error_on_conn(struct rtrs_clt_con *con, int cm_err)
+ {
+       if (con->cm_err == 1) {
+-              struct rtrs_clt_sess *sess;
++              struct rtrs_clt_path *clt_path;
+-              sess = to_clt_sess(con->c.path);
+-              if (atomic_dec_and_test(&sess->connected_cnt))
++              clt_path = to_clt_path(con->c.path);
++              if (atomic_dec_and_test(&clt_path->connected_cnt))
+-                      wake_up(&sess->state_wq);
++                      wake_up(&clt_path->state_wq);
+       }
+       con->cm_err = cm_err;
+ }
+@@ -1950,7 +1961,7 @@ static int rtrs_clt_rdma_cm_handler(struct rdma_cm_id *cm_id,
+ {
+       struct rtrs_clt_con *con = cm_id->context;
+       struct rtrs_path *s = con->c.path;
+-      struct rtrs_clt_sess *sess = to_clt_sess(s);
++      struct rtrs_clt_path *clt_path = to_clt_path(s);
+       int cm_err = 0;
+       switch (ev->event) {
+@@ -1968,7 +1979,7 @@ static int rtrs_clt_rdma_cm_handler(struct rdma_cm_id *cm_id,
+                        * i.e. wake up without state change, but we set cm_err.
+                        */
+                       flag_success_on_conn(con);
+-                      wake_up(&sess->state_wq);
++                      wake_up(&clt_path->state_wq);
+                       return 0;
+               }
+               break;
+@@ -1997,7 +2008,7 @@ static int rtrs_clt_rdma_cm_handler(struct rdma_cm_id *cm_id,
+               /*
+                * Device removal is a special case.  Queue close and return 0.
+                */
+-              rtrs_clt_close_conns(sess, false);
++              rtrs_clt_close_conns(clt_path, false);
+               return 0;
+       default:
+               rtrs_err(s, "Unexpected RDMA CM error (CM event: %s, err: %d)\n",
+@@ -2021,12 +2032,12 @@ static int rtrs_clt_rdma_cm_handler(struct rdma_cm_id *cm_id,
+ static int create_cm(struct rtrs_clt_con *con)
+ {
+       struct rtrs_path *s = con->c.path;
+-      struct rtrs_clt_sess *sess = to_clt_sess(s);
++      struct rtrs_clt_path *clt_path = to_clt_path(s);
+       struct rdma_cm_id *cm_id;
+       int err;
+       cm_id = rdma_create_id(&init_net, rtrs_clt_rdma_cm_handler, con,
+-                             sess->s.dst_addr.ss_family == AF_IB ?
++                             clt_path->s.dst_addr.ss_family == AF_IB ?
+                              RDMA_PS_IB : RDMA_PS_TCP, IB_QPT_RC);
+       if (IS_ERR(cm_id)) {
+               err = PTR_ERR(cm_id);
+@@ -2042,8 +2053,8 @@ static int create_cm(struct rtrs_clt_con *con)
+               rtrs_err(s, "Set address reuse failed, err: %d\n", err);
+               goto destroy_cm;
+       }
+-      err = rdma_resolve_addr(cm_id, (struct sockaddr *)&sess->s.src_addr,
+-                              (struct sockaddr *)&sess->s.dst_addr,
++      err = rdma_resolve_addr(cm_id, (struct sockaddr *)&clt_path->s.src_addr,
++                              (struct sockaddr *)&clt_path->s.dst_addr,
+                               RTRS_CONNECT_TIMEOUT_MS);
+       if (err) {
+               rtrs_err(s, "Failed to resolve address, err: %d\n", err);
+@@ -2055,8 +2066,8 @@ static int create_cm(struct rtrs_clt_con *con)
+        * or session state was really changed to error by device removal.
+        */
+       err = wait_event_interruptible_timeout(
+-                      sess->state_wq,
+-                      con->cm_err || sess->state != RTRS_CLT_CONNECTING,
++                      clt_path->state_wq,
++                      con->cm_err || clt_path->state != RTRS_CLT_CONNECTING,
+                       msecs_to_jiffies(RTRS_CONNECT_TIMEOUT_MS));
+       if (err == 0 || err == -ERESTARTSYS) {
+               if (err == 0)
+@@ -2068,7 +2079,7 @@ static int create_cm(struct rtrs_clt_con *con)
+               err = con->cm_err;
+               goto errr;
+       }
+-      if (READ_ONCE(sess->state) != RTRS_CLT_CONNECTING) {
++      if (READ_ONCE(clt_path->state) != RTRS_CLT_CONNECTING) {
+               /* Device removal */
+               err = -ECONNABORTED;
+               goto errr;
+@@ -2087,9 +2098,9 @@ static int create_cm(struct rtrs_clt_con *con)
+       return err;
+ }
+-static void rtrs_clt_sess_up(struct rtrs_clt_sess *sess)
++static void rtrs_clt_path_up(struct rtrs_clt_path *clt_path)
+ {
+-      struct rtrs_clt *clt = sess->clt;
++      struct rtrs_clt *clt = clt_path->clt;
+       int up;
+       /*
+@@ -2113,19 +2124,19 @@ static void rtrs_clt_sess_up(struct rtrs_clt_sess *sess)
+       mutex_unlock(&clt->paths_ev_mutex);
+       /* Mark session as established */
+-      sess->established = true;
+-      sess->reconnect_attempts = 0;
+-      sess->stats->reconnects.successful_cnt++;
++      clt_path->established = true;
++      clt_path->reconnect_attempts = 0;
++      clt_path->stats->reconnects.successful_cnt++;
+ }
+-static void rtrs_clt_sess_down(struct rtrs_clt_sess *sess)
++static void rtrs_clt_path_down(struct rtrs_clt_path *clt_path)
+ {
+-      struct rtrs_clt *clt = sess->clt;
++      struct rtrs_clt *clt = clt_path->clt;
+-      if (!sess->established)
++      if (!clt_path->established)
+               return;
+-      sess->established = false;
++      clt_path->established = false;
+       mutex_lock(&clt->paths_ev_mutex);
+       WARN_ON(!clt->paths_up);
+       if (--clt->paths_up == 0)
+@@ -2133,19 +2144,19 @@ static void rtrs_clt_sess_down(struct rtrs_clt_sess *sess)
+       mutex_unlock(&clt->paths_ev_mutex);
+ }
+-static void rtrs_clt_stop_and_destroy_conns(struct rtrs_clt_sess *sess)
++static void rtrs_clt_stop_and_destroy_conns(struct rtrs_clt_path *clt_path)
+ {
+       struct rtrs_clt_con *con;
+       unsigned int cid;
+-      WARN_ON(READ_ONCE(sess->state) == RTRS_CLT_CONNECTED);
++      WARN_ON(READ_ONCE(clt_path->state) == RTRS_CLT_CONNECTED);
+       /*
+        * Possible race with rtrs_clt_open(), when DEVICE_REMOVAL comes
+        * exactly in between.  Start destroying after it finishes.
+        */
+-      mutex_lock(&sess->init_mutex);
+-      mutex_unlock(&sess->init_mutex);
++      mutex_lock(&clt_path->init_mutex);
++      mutex_unlock(&clt_path->init_mutex);
+       /*
+        * All IO paths must observe !CONNECTED state before we
+@@ -2153,7 +2164,7 @@ static void rtrs_clt_stop_and_destroy_conns(struct rtrs_clt_sess *sess)
+        */
+       synchronize_rcu();
+-      rtrs_stop_hb(&sess->s);
++      rtrs_stop_hb(&clt_path->s);
+       /*
+        * The order it utterly crucial: firstly disconnect and complete all
+@@ -2162,15 +2173,15 @@ static void rtrs_clt_stop_and_destroy_conns(struct rtrs_clt_sess *sess)
+        * eventually notify upper layer about session disconnection.
+        */
+-      for (cid = 0; cid < sess->s.con_num; cid++) {
+-              if (!sess->s.con[cid])
++      for (cid = 0; cid < clt_path->s.con_num; cid++) {
++              if (!clt_path->s.con[cid])
+                       break;
+-              con = to_clt_con(sess->s.con[cid]);
++              con = to_clt_con(clt_path->s.con[cid]);
+               stop_cm(con);
+       }
+-      fail_all_outstanding_reqs(sess);
+-      free_sess_reqs(sess);
+-      rtrs_clt_sess_down(sess);
++      fail_all_outstanding_reqs(clt_path);
++      free_path_reqs(clt_path);
++      rtrs_clt_path_down(clt_path);
+       /*
+        * Wait for graceful shutdown, namely when peer side invokes
+@@ -2180,13 +2191,14 @@ static void rtrs_clt_stop_and_destroy_conns(struct rtrs_clt_sess *sess)
+        * since CM does not fire anything.  That is fine, we are not in
+        * hurry.
+        */
+-      wait_event_timeout(sess->state_wq, !atomic_read(&sess->connected_cnt),
++      wait_event_timeout(clt_path->state_wq,
++                         !atomic_read(&clt_path->connected_cnt),
+                          msecs_to_jiffies(RTRS_CONNECT_TIMEOUT_MS));
+-      for (cid = 0; cid < sess->s.con_num; cid++) {
+-              if (!sess->s.con[cid])
++      for (cid = 0; cid < clt_path->s.con_num; cid++) {
++              if (!clt_path->s.con[cid])
+                       break;
+-              con = to_clt_con(sess->s.con[cid]);
++              con = to_clt_con(clt_path->s.con[cid]);
+               mutex_lock(&con->con_mutex);
+               destroy_con_cq_qp(con);
+               mutex_unlock(&con->con_mutex);
+@@ -2195,26 +2207,26 @@ static void rtrs_clt_stop_and_destroy_conns(struct rtrs_clt_sess *sess)
+       }
+ }
+-static inline bool xchg_sessions(struct rtrs_clt_sess __rcu **rcu_ppcpu_path,
+-                               struct rtrs_clt_sess *sess,
+-                               struct rtrs_clt_sess *next)
++static inline bool xchg_paths(struct rtrs_clt_path __rcu **rcu_ppcpu_path,
++                            struct rtrs_clt_path *clt_path,
++                            struct rtrs_clt_path *next)
+ {
+-      struct rtrs_clt_sess **ppcpu_path;
++      struct rtrs_clt_path **ppcpu_path;
+       /* Call cmpxchg() without sparse warnings */
+       ppcpu_path = (typeof(ppcpu_path))rcu_ppcpu_path;
+-      return sess == cmpxchg(ppcpu_path, sess, next);
++      return clt_path == cmpxchg(ppcpu_path, clt_path, next);
+ }
+-static void rtrs_clt_remove_path_from_arr(struct rtrs_clt_sess *sess)
++static void rtrs_clt_remove_path_from_arr(struct rtrs_clt_path *clt_path)
+ {
+-      struct rtrs_clt *clt = sess->clt;
+-      struct rtrs_clt_sess *next;
++      struct rtrs_clt *clt = clt_path->clt;
++      struct rtrs_clt_path *next;
+       bool wait_for_grace = false;
+       int cpu;
+       mutex_lock(&clt->paths_mutex);
+-      list_del_rcu(&sess->s.entry);
++      list_del_rcu(&clt_path->s.entry);
+       /* Make sure everybody observes path removal. */
+       synchronize_rcu();
+@@ -2255,7 +2267,7 @@ static void rtrs_clt_remove_path_from_arr(struct rtrs_clt_sess *sess)
+        * removed.  If @sess is the last element, then @next is NULL.
+        */
+       rcu_read_lock();
+-      next = list_next_or_null_rr_rcu(&clt->paths_list, &sess->s.entry,
++      next = list_next_or_null_rr_rcu(&clt->paths_list, &clt_path->s.entry,
+                                       typeof(*next), s.entry);
+       rcu_read_unlock();
+@@ -2264,11 +2276,11 @@ static void rtrs_clt_remove_path_from_arr(struct rtrs_clt_sess *sess)
+        * removed, so change the pointer manually.
+        */
+       for_each_possible_cpu(cpu) {
+-              struct rtrs_clt_sess __rcu **ppcpu_path;
++              struct rtrs_clt_path __rcu **ppcpu_path;
+               ppcpu_path = per_cpu_ptr(clt->pcpu_path, cpu);
+               if (rcu_dereference_protected(*ppcpu_path,
+-                      lockdep_is_held(&clt->paths_mutex)) != sess)
++                      lockdep_is_held(&clt->paths_mutex)) != clt_path)
+                       /*
+                        * synchronize_rcu() was called just after deleting
+                        * entry from the list, thus IO code path cannot
+@@ -2281,7 +2293,7 @@ static void rtrs_clt_remove_path_from_arr(struct rtrs_clt_sess *sess)
+                * We race with IO code path, which also changes pointer,
+                * thus we have to be careful not to overwrite it.
+                */
+-              if (xchg_sessions(ppcpu_path, sess, next))
++              if (xchg_paths(ppcpu_path, clt_path, next))
+                       /*
+                        * @ppcpu_path was successfully replaced with @next,
+                        * that means that someone could also pick up the
+@@ -2296,29 +2308,29 @@ static void rtrs_clt_remove_path_from_arr(struct rtrs_clt_sess *sess)
+       mutex_unlock(&clt->paths_mutex);
+ }
+-static void rtrs_clt_add_path_to_arr(struct rtrs_clt_sess *sess)
++static void rtrs_clt_add_path_to_arr(struct rtrs_clt_path *clt_path)
+ {
+-      struct rtrs_clt *clt = sess->clt;
++      struct rtrs_clt *clt = clt_path->clt;
+       mutex_lock(&clt->paths_mutex);
+       clt->paths_num++;
+-      list_add_tail_rcu(&sess->s.entry, &clt->paths_list);
++      list_add_tail_rcu(&clt_path->s.entry, &clt->paths_list);
+       mutex_unlock(&clt->paths_mutex);
+ }
+ static void rtrs_clt_close_work(struct work_struct *work)
+ {
+-      struct rtrs_clt_sess *sess;
++      struct rtrs_clt_path *clt_path;
+-      sess = container_of(work, struct rtrs_clt_sess, close_work);
++      clt_path = container_of(work, struct rtrs_clt_path, close_work);
+-      cancel_delayed_work_sync(&sess->reconnect_dwork);
+-      rtrs_clt_stop_and_destroy_conns(sess);
+-      rtrs_clt_change_state_get_old(sess, RTRS_CLT_CLOSED, NULL);
++      cancel_delayed_work_sync(&clt_path->reconnect_dwork);
++      rtrs_clt_stop_and_destroy_conns(clt_path);
++      rtrs_clt_change_state_get_old(clt_path, RTRS_CLT_CLOSED, NULL);
+ }
+-static int init_conns(struct rtrs_clt_sess *sess)
++static int init_conns(struct rtrs_clt_path *clt_path)
+ {
+       unsigned int cid;
+       int err;
+@@ -2328,31 +2340,31 @@ static int init_conns(struct rtrs_clt_sess *sess)
+        * to avoid clashes with previous sessions not yet closed
+        * sessions on a server side.
+        */
+-      sess->s.recon_cnt++;
++      clt_path->s.recon_cnt++;
+       /* Establish all RDMA connections  */
+-      for (cid = 0; cid < sess->s.con_num; cid++) {
+-              err = create_con(sess, cid);
++      for (cid = 0; cid < clt_path->s.con_num; cid++) {
++              err = create_con(clt_path, cid);
+               if (err)
+                       goto destroy;
+-              err = create_cm(to_clt_con(sess->s.con[cid]));
++              err = create_cm(to_clt_con(clt_path->s.con[cid]));
+               if (err) {
+-                      destroy_con(to_clt_con(sess->s.con[cid]));
++                      destroy_con(to_clt_con(clt_path->s.con[cid]));
+                       goto destroy;
+               }
+       }
+-      err = alloc_sess_reqs(sess);
++      err = alloc_path_reqs(clt_path);
+       if (err)
+               goto destroy;
+-      rtrs_start_hb(&sess->s);
++      rtrs_start_hb(&clt_path->s);
+       return 0;
+ destroy:
+       while (cid--) {
+-              struct rtrs_clt_con *con = to_clt_con(sess->s.con[cid]);
++              struct rtrs_clt_con *con = to_clt_con(clt_path->s.con[cid]);
+               stop_cm(con);
+@@ -2367,7 +2379,7 @@ static int init_conns(struct rtrs_clt_sess *sess)
+        * doing rdma_resolve_addr(), switch to CONNECTION_ERR state
+        * manually to keep reconnecting.
+        */
+-      rtrs_clt_change_state_get_old(sess, RTRS_CLT_CONNECTING_ERR, NULL);
++      rtrs_clt_change_state_get_old(clt_path, RTRS_CLT_CONNECTING_ERR, NULL);
+       return err;
+ }
+@@ -2375,31 +2387,32 @@ static int init_conns(struct rtrs_clt_sess *sess)
+ static void rtrs_clt_info_req_done(struct ib_cq *cq, struct ib_wc *wc)
+ {
+       struct rtrs_clt_con *con = to_clt_con(wc->qp->qp_context);
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
++      struct rtrs_clt_path *clt_path = to_clt_path(con->c.path);
+       struct rtrs_iu *iu;
+       iu = container_of(wc->wr_cqe, struct rtrs_iu, cqe);
+-      rtrs_iu_free(iu, sess->s.dev->ib_dev, 1);
++      rtrs_iu_free(iu, clt_path->s.dev->ib_dev, 1);
+       if (wc->status != IB_WC_SUCCESS) {
+-              rtrs_err(sess->clt, "Sess info request send failed: %s\n",
++              rtrs_err(clt_path->clt, "Path info request send failed: %s\n",
+                         ib_wc_status_msg(wc->status));
+-              rtrs_clt_change_state_get_old(sess, RTRS_CLT_CONNECTING_ERR, NULL);
++              rtrs_clt_change_state_get_old(clt_path, RTRS_CLT_CONNECTING_ERR, NULL);
+               return;
+       }
+       rtrs_clt_update_wc_stats(con);
+ }
+-static int process_info_rsp(struct rtrs_clt_sess *sess,
++static int process_info_rsp(struct rtrs_clt_path *clt_path,
+                           const struct rtrs_msg_info_rsp *msg)
+ {
+       unsigned int sg_cnt, total_len;
+       int i, sgi;
+       sg_cnt = le16_to_cpu(msg->sg_cnt);
+-      if (!sg_cnt || (sess->queue_depth % sg_cnt)) {
+-              rtrs_err(sess->clt, "Incorrect sg_cnt %d, is not multiple\n",
++      if (!sg_cnt || (clt_path->queue_depth % sg_cnt)) {
++              rtrs_err(clt_path->clt,
++                        "Incorrect sg_cnt %d, is not multiple\n",
+                         sg_cnt);
+               return -EINVAL;
+       }
+@@ -2408,15 +2421,15 @@ static int process_info_rsp(struct rtrs_clt_sess *sess,
+        * Check if IB immediate data size is enough to hold the mem_id and
+        * the offset inside the memory chunk.
+        */
+-      if ((ilog2(sg_cnt - 1) + 1) + (ilog2(sess->chunk_size - 1) + 1) >
++      if ((ilog2(sg_cnt - 1) + 1) + (ilog2(clt_path->chunk_size - 1) + 1) >
+           MAX_IMM_PAYL_BITS) {
+-              rtrs_err(sess->clt,
++              rtrs_err(clt_path->clt,
+                         "RDMA immediate size (%db) not enough to encode %d buffers of size %dB\n",
+-                        MAX_IMM_PAYL_BITS, sg_cnt, sess->chunk_size);
++                        MAX_IMM_PAYL_BITS, sg_cnt, clt_path->chunk_size);
+               return -EINVAL;
+       }
+       total_len = 0;
+-      for (sgi = 0, i = 0; sgi < sg_cnt && i < sess->queue_depth; sgi++) {
++      for (sgi = 0, i = 0; sgi < sg_cnt && i < clt_path->queue_depth; sgi++) {
+               const struct rtrs_sg_desc *desc = &msg->desc[sgi];
+               u32 len, rkey;
+               u64 addr;
+@@ -2427,26 +2440,28 @@ static int process_info_rsp(struct rtrs_clt_sess *sess,
+               total_len += len;
+-              if (!len || (len % sess->chunk_size)) {
+-                      rtrs_err(sess->clt, "Incorrect [%d].len %d\n", sgi,
++              if (!len || (len % clt_path->chunk_size)) {
++                      rtrs_err(clt_path->clt, "Incorrect [%d].len %d\n",
++                                sgi,
+                                 len);
+                       return -EINVAL;
+               }
+-              for ( ; len && i < sess->queue_depth; i++) {
+-                      sess->rbufs[i].addr = addr;
+-                      sess->rbufs[i].rkey = rkey;
++              for ( ; len && i < clt_path->queue_depth; i++) {
++                      clt_path->rbufs[i].addr = addr;
++                      clt_path->rbufs[i].rkey = rkey;
+-                      len  -= sess->chunk_size;
+-                      addr += sess->chunk_size;
++                      len  -= clt_path->chunk_size;
++                      addr += clt_path->chunk_size;
+               }
+       }
+       /* Sanity check */
+-      if (sgi != sg_cnt || i != sess->queue_depth) {
+-              rtrs_err(sess->clt, "Incorrect sg vector, not fully mapped\n");
++      if (sgi != sg_cnt || i != clt_path->queue_depth) {
++              rtrs_err(clt_path->clt,
++                       "Incorrect sg vector, not fully mapped\n");
+               return -EINVAL;
+       }
+-      if (total_len != sess->chunk_size * sess->queue_depth) {
+-              rtrs_err(sess->clt, "Incorrect total_len %d\n", total_len);
++      if (total_len != clt_path->chunk_size * clt_path->queue_depth) {
++              rtrs_err(clt_path->clt, "Incorrect total_len %d\n", total_len);
+               return -EINVAL;
+       }
+@@ -2456,7 +2471,7 @@ static int process_info_rsp(struct rtrs_clt_sess *sess,
+ static void rtrs_clt_info_rsp_done(struct ib_cq *cq, struct ib_wc *wc)
+ {
+       struct rtrs_clt_con *con = to_clt_con(wc->qp->qp_context);
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
++      struct rtrs_clt_path *clt_path = to_clt_path(con->c.path);
+       struct rtrs_msg_info_rsp *msg;
+       enum rtrs_clt_state state;
+       struct rtrs_iu *iu;
+@@ -2468,37 +2483,37 @@ static void rtrs_clt_info_rsp_done(struct ib_cq *cq, struct ib_wc *wc)
+       WARN_ON(con->c.cid);
+       iu = container_of(wc->wr_cqe, struct rtrs_iu, cqe);
+       if (wc->status != IB_WC_SUCCESS) {
+-              rtrs_err(sess->clt, "Sess info response recv failed: %s\n",
++              rtrs_err(clt_path->clt, "Path info response recv failed: %s\n",
+                         ib_wc_status_msg(wc->status));
+               goto out;
+       }
+       WARN_ON(wc->opcode != IB_WC_RECV);
+       if (wc->byte_len < sizeof(*msg)) {
+-              rtrs_err(sess->clt, "Sess info response is malformed: size %d\n",
++              rtrs_err(clt_path->clt, "Path info response is malformed: size %d\n",
+                         wc->byte_len);
+               goto out;
+       }
+-      ib_dma_sync_single_for_cpu(sess->s.dev->ib_dev, iu->dma_addr,
++      ib_dma_sync_single_for_cpu(clt_path->s.dev->ib_dev, iu->dma_addr,
+                                  iu->size, DMA_FROM_DEVICE);
+       msg = iu->buf;
+       if (le16_to_cpu(msg->type) != RTRS_MSG_INFO_RSP) {
+-              rtrs_err(sess->clt, "Sess info response is malformed: type %d\n",
++              rtrs_err(clt_path->clt, "Path info response is malformed: type %d\n",
+                         le16_to_cpu(msg->type));
+               goto out;
+       }
+       rx_sz  = sizeof(*msg);
+       rx_sz += sizeof(msg->desc[0]) * le16_to_cpu(msg->sg_cnt);
+       if (wc->byte_len < rx_sz) {
+-              rtrs_err(sess->clt, "Sess info response is malformed: size %d\n",
++              rtrs_err(clt_path->clt, "Path info response is malformed: size %d\n",
+                         wc->byte_len);
+               goto out;
+       }
+-      err = process_info_rsp(sess, msg);
++      err = process_info_rsp(clt_path, msg);
+       if (err)
+               goto out;
+-      err = post_recv_sess(sess);
++      err = post_recv_path(clt_path);
+       if (err)
+               goto out;
+@@ -2506,25 +2521,25 @@ static void rtrs_clt_info_rsp_done(struct ib_cq *cq, struct ib_wc *wc)
+ out:
+       rtrs_clt_update_wc_stats(con);
+-      rtrs_iu_free(iu, sess->s.dev->ib_dev, 1);
+-      rtrs_clt_change_state_get_old(sess, state, NULL);
++      rtrs_iu_free(iu, clt_path->s.dev->ib_dev, 1);
++      rtrs_clt_change_state_get_old(clt_path, state, NULL);
+ }
+-static int rtrs_send_sess_info(struct rtrs_clt_sess *sess)
++static int rtrs_send_path_info(struct rtrs_clt_path *clt_path)
+ {
+-      struct rtrs_clt_con *usr_con = to_clt_con(sess->s.con[0]);
++      struct rtrs_clt_con *usr_con = to_clt_con(clt_path->s.con[0]);
+       struct rtrs_msg_info_req *msg;
+       struct rtrs_iu *tx_iu, *rx_iu;
+       size_t rx_sz;
+       int err;
+       rx_sz  = sizeof(struct rtrs_msg_info_rsp);
+-      rx_sz += sizeof(struct rtrs_sg_desc) * sess->queue_depth;
++      rx_sz += sizeof(struct rtrs_sg_desc) * clt_path->queue_depth;
+       tx_iu = rtrs_iu_alloc(1, sizeof(struct rtrs_msg_info_req), GFP_KERNEL,
+-                             sess->s.dev->ib_dev, DMA_TO_DEVICE,
++                             clt_path->s.dev->ib_dev, DMA_TO_DEVICE,
+                              rtrs_clt_info_req_done);
+-      rx_iu = rtrs_iu_alloc(1, rx_sz, GFP_KERNEL, sess->s.dev->ib_dev,
++      rx_iu = rtrs_iu_alloc(1, rx_sz, GFP_KERNEL, clt_path->s.dev->ib_dev,
+                              DMA_FROM_DEVICE, rtrs_clt_info_rsp_done);
+       if (!tx_iu || !rx_iu) {
+               err = -ENOMEM;
+@@ -2533,33 +2548,34 @@ static int rtrs_send_sess_info(struct rtrs_clt_sess *sess)
+       /* Prepare for getting info response */
+       err = rtrs_iu_post_recv(&usr_con->c, rx_iu);
+       if (err) {
+-              rtrs_err(sess->clt, "rtrs_iu_post_recv(), err: %d\n", err);
++              rtrs_err(clt_path->clt, "rtrs_iu_post_recv(), err: %d\n", err);
+               goto out;
+       }
+       rx_iu = NULL;
+       msg = tx_iu->buf;
+       msg->type = cpu_to_le16(RTRS_MSG_INFO_REQ);
+-      memcpy(msg->sessname, sess->s.sessname, sizeof(msg->sessname));
++      memcpy(msg->pathname, clt_path->s.sessname, sizeof(msg->pathname));
+-      ib_dma_sync_single_for_device(sess->s.dev->ib_dev, tx_iu->dma_addr,
++      ib_dma_sync_single_for_device(clt_path->s.dev->ib_dev,
++                                    tx_iu->dma_addr,
+                                     tx_iu->size, DMA_TO_DEVICE);
+       /* Send info request */
+       err = rtrs_iu_post_send(&usr_con->c, tx_iu, sizeof(*msg), NULL);
+       if (err) {
+-              rtrs_err(sess->clt, "rtrs_iu_post_send(), err: %d\n", err);
++              rtrs_err(clt_path->clt, "rtrs_iu_post_send(), err: %d\n", err);
+               goto out;
+       }
+       tx_iu = NULL;
+       /* Wait for state change */
+-      wait_event_interruptible_timeout(sess->state_wq,
+-                                       sess->state != RTRS_CLT_CONNECTING,
++      wait_event_interruptible_timeout(clt_path->state_wq,
++                                       clt_path->state != RTRS_CLT_CONNECTING,
+                                        msecs_to_jiffies(
+                                                RTRS_CONNECT_TIMEOUT_MS));
+-      if (READ_ONCE(sess->state) != RTRS_CLT_CONNECTED) {
+-              if (READ_ONCE(sess->state) == RTRS_CLT_CONNECTING_ERR)
++      if (READ_ONCE(clt_path->state) != RTRS_CLT_CONNECTED) {
++              if (READ_ONCE(clt_path->state) == RTRS_CLT_CONNECTING_ERR)
+                       err = -ECONNRESET;
+               else
+                       err = -ETIMEDOUT;
+@@ -2567,82 +2583,82 @@ static int rtrs_send_sess_info(struct rtrs_clt_sess *sess)
+ out:
+       if (tx_iu)
+-              rtrs_iu_free(tx_iu, sess->s.dev->ib_dev, 1);
++              rtrs_iu_free(tx_iu, clt_path->s.dev->ib_dev, 1);
+       if (rx_iu)
+-              rtrs_iu_free(rx_iu, sess->s.dev->ib_dev, 1);
++              rtrs_iu_free(rx_iu, clt_path->s.dev->ib_dev, 1);
+       if (err)
+               /* If we've never taken async path because of malloc problems */
+-              rtrs_clt_change_state_get_old(sess, RTRS_CLT_CONNECTING_ERR, NULL);
++              rtrs_clt_change_state_get_old(clt_path,
++                                            RTRS_CLT_CONNECTING_ERR, NULL);
+       return err;
+ }
+ /**
+- * init_sess() - establishes all session connections and does handshake
+- * @sess: client session.
++ * init_path() - establishes all path connections and does handshake
++ * @clt_path: client path.
+  * In case of error full close or reconnect procedure should be taken,
+  * because reconnect or close async works can be started.
+  */
+-static int init_sess(struct rtrs_clt_sess *sess)
++static int init_path(struct rtrs_clt_path *clt_path)
+ {
+       int err;
+       char str[NAME_MAX];
+       struct rtrs_addr path = {
+-              .src = &sess->s.src_addr,
+-              .dst = &sess->s.dst_addr,
++              .src = &clt_path->s.src_addr,
++              .dst = &clt_path->s.dst_addr,
+       };
+       rtrs_addr_to_str(&path, str, sizeof(str));
+-      mutex_lock(&sess->init_mutex);
+-      err = init_conns(sess);
++      mutex_lock(&clt_path->init_mutex);
++      err = init_conns(clt_path);
+       if (err) {
+-              rtrs_err(sess->clt,
++              rtrs_err(clt_path->clt,
+                        "init_conns() failed: err=%d path=%s [%s:%u]\n", err,
+-                       str, sess->hca_name, sess->hca_port);
++                       str, clt_path->hca_name, clt_path->hca_port);
+               goto out;
+       }
+-      err = rtrs_send_sess_info(sess);
++      err = rtrs_send_path_info(clt_path);
+       if (err) {
+-              rtrs_err(
+-                      sess->clt,
+-                      "rtrs_send_sess_info() failed: err=%d path=%s [%s:%u]\n",
+-                      err, str, sess->hca_name, sess->hca_port);
++              rtrs_err(clt_path->clt,
++                       "rtrs_send_path_info() failed: err=%d path=%s [%s:%u]\n",
++                       err, str, clt_path->hca_name, clt_path->hca_port);
+               goto out;
+       }
+-      rtrs_clt_sess_up(sess);
++      rtrs_clt_path_up(clt_path);
+ out:
+-      mutex_unlock(&sess->init_mutex);
++      mutex_unlock(&clt_path->init_mutex);
+       return err;
+ }
+ static void rtrs_clt_reconnect_work(struct work_struct *work)
+ {
+-      struct rtrs_clt_sess *sess;
++      struct rtrs_clt_path *clt_path;
+       struct rtrs_clt *clt;
+       unsigned int delay_ms;
+       int err;
+-      sess = container_of(to_delayed_work(work), struct rtrs_clt_sess,
+-                          reconnect_dwork);
+-      clt = sess->clt;
++      clt_path = container_of(to_delayed_work(work), struct rtrs_clt_path,
++                              reconnect_dwork);
++      clt = clt_path->clt;
+-      if (READ_ONCE(sess->state) != RTRS_CLT_RECONNECTING)
++      if (READ_ONCE(clt_path->state) != RTRS_CLT_RECONNECTING)
+               return;
+-      if (sess->reconnect_attempts >= clt->max_reconnect_attempts) {
+-              /* Close a session completely if max attempts is reached */
+-              rtrs_clt_close_conns(sess, false);
++      if (clt_path->reconnect_attempts >= clt->max_reconnect_attempts) {
++              /* Close a path completely if max attempts is reached */
++              rtrs_clt_close_conns(clt_path, false);
+               return;
+       }
+-      sess->reconnect_attempts++;
++      clt_path->reconnect_attempts++;
+       /* Stop everything */
+-      rtrs_clt_stop_and_destroy_conns(sess);
++      rtrs_clt_stop_and_destroy_conns(clt_path);
+       msleep(RTRS_RECONNECT_BACKOFF);
+-      if (rtrs_clt_change_state_get_old(sess, RTRS_CLT_CONNECTING, NULL)) {
+-              err = init_sess(sess);
++      if (rtrs_clt_change_state_get_old(clt_path, RTRS_CLT_CONNECTING, NULL)) {
++              err = init_path(clt_path);
+               if (err)
+                       goto reconnect_again;
+       }
+@@ -2650,10 +2666,10 @@ static void rtrs_clt_reconnect_work(struct work_struct *work)
+       return;
+ reconnect_again:
+-      if (rtrs_clt_change_state_get_old(sess, RTRS_CLT_RECONNECTING, NULL)) {
+-              sess->stats->reconnects.fail_cnt++;
++      if (rtrs_clt_change_state_get_old(clt_path, RTRS_CLT_RECONNECTING, NULL)) {
++              clt_path->stats->reconnects.fail_cnt++;
+               delay_ms = clt->reconnect_delay_sec * 1000;
+-              queue_delayed_work(rtrs_wq, &sess->reconnect_dwork,
++              queue_delayed_work(rtrs_wq, &clt_path->reconnect_dwork,
+                                  msecs_to_jiffies(delay_ms +
+                                                   prandom_u32() %
+                                                   RTRS_RECONNECT_SEED));
+@@ -2762,7 +2778,7 @@ static void free_clt(struct rtrs_clt *clt)
+ }
+ /**
+- * rtrs_clt_open() - Open a session to an RTRS server
++ * rtrs_clt_open() - Open a path to an RTRS server
+  * @ops: holds the link event callback and the private pointer.
+  * @sessname: name of the session
+  * @paths: Paths to be established defined by their src and dst addresses
+@@ -2780,23 +2796,23 @@ static void free_clt(struct rtrs_clt *clt)
+  * Return a valid pointer on success otherwise PTR_ERR.
+  */
+ struct rtrs_clt *rtrs_clt_open(struct rtrs_clt_ops *ops,
+-                               const char *sessname,
++                               const char *pathname,
+                                const struct rtrs_addr *paths,
+                                size_t paths_num, u16 port,
+                                size_t pdu_sz, u8 reconnect_delay_sec,
+                                s16 max_reconnect_attempts, u32 nr_poll_queues)
+ {
+-      struct rtrs_clt_sess *sess, *tmp;
++      struct rtrs_clt_path *clt_path, *tmp;
+       struct rtrs_clt *clt;
+       int err, i;
+-      if (strchr(sessname, '/') || strchr(sessname, '.')) {
+-              pr_err("sessname cannot contain / and .\n");
++      if (strchr(pathname, '/') || strchr(pathname, '.')) {
++              pr_err("pathname cannot contain / and .\n");
+               err = -EINVAL;
+               goto out;
+       }
+-      clt = alloc_clt(sessname, paths_num, port, pdu_sz, ops->priv,
++      clt = alloc_clt(pathname, paths_num, port, pdu_sz, ops->priv,
+                       ops->link_ev,
+                       reconnect_delay_sec,
+                       max_reconnect_attempts);
+@@ -2805,49 +2821,49 @@ struct rtrs_clt *rtrs_clt_open(struct rtrs_clt_ops *ops,
+               goto out;
+       }
+       for (i = 0; i < paths_num; i++) {
+-              struct rtrs_clt_sess *sess;
++              struct rtrs_clt_path *clt_path;
+-              sess = alloc_sess(clt, &paths[i], nr_cpu_ids,
++              clt_path = alloc_path(clt, &paths[i], nr_cpu_ids,
+                                 nr_poll_queues);
+-              if (IS_ERR(sess)) {
+-                      err = PTR_ERR(sess);
+-                      goto close_all_sess;
++              if (IS_ERR(clt_path)) {
++                      err = PTR_ERR(clt_path);
++                      goto close_all_path;
+               }
+               if (!i)
+-                      sess->for_new_clt = 1;
+-              list_add_tail_rcu(&sess->s.entry, &clt->paths_list);
++                      clt_path->for_new_clt = 1;
++              list_add_tail_rcu(&clt_path->s.entry, &clt->paths_list);
+-              err = init_sess(sess);
++              err = init_path(clt_path);
+               if (err) {
+-                      list_del_rcu(&sess->s.entry);
+-                      rtrs_clt_close_conns(sess, true);
+-                      free_percpu(sess->stats->pcpu_stats);
+-                      kfree(sess->stats);
+-                      free_sess(sess);
+-                      goto close_all_sess;
++                      list_del_rcu(&clt_path->s.entry);
++                      rtrs_clt_close_conns(clt_path, true);
++                      free_percpu(clt_path->stats->pcpu_stats);
++                      kfree(clt_path->stats);
++                      free_path(clt_path);
++                      goto close_all_path;
+               }
+-              err = rtrs_clt_create_sess_files(sess);
++              err = rtrs_clt_create_path_files(clt_path);
+               if (err) {
+-                      list_del_rcu(&sess->s.entry);
+-                      rtrs_clt_close_conns(sess, true);
+-                      free_percpu(sess->stats->pcpu_stats);
+-                      kfree(sess->stats);
+-                      free_sess(sess);
+-                      goto close_all_sess;
++                      list_del_rcu(&clt_path->s.entry);
++                      rtrs_clt_close_conns(clt_path, true);
++                      free_percpu(clt_path->stats->pcpu_stats);
++                      kfree(clt_path->stats);
++                      free_path(clt_path);
++                      goto close_all_path;
+               }
+       }
+       err = alloc_permits(clt);
+       if (err)
+-              goto close_all_sess;
++              goto close_all_path;
+       return clt;
+-close_all_sess:
+-      list_for_each_entry_safe(sess, tmp, &clt->paths_list, s.entry) {
+-              rtrs_clt_destroy_sess_files(sess, NULL);
+-              rtrs_clt_close_conns(sess, true);
+-              kobject_put(&sess->kobj);
++close_all_path:
++      list_for_each_entry_safe(clt_path, tmp, &clt->paths_list, s.entry) {
++              rtrs_clt_destroy_path_files(clt_path, NULL);
++              rtrs_clt_close_conns(clt_path, true);
++              kobject_put(&clt_path->kobj);
+       }
+       rtrs_clt_destroy_sysfs_root(clt);
+       free_clt(clt);
+@@ -2858,38 +2874,39 @@ struct rtrs_clt *rtrs_clt_open(struct rtrs_clt_ops *ops,
+ EXPORT_SYMBOL(rtrs_clt_open);
+ /**
+- * rtrs_clt_close() - Close a session
++ * rtrs_clt_close() - Close a path
+  * @clt: Session handle. Session is freed upon return.
+  */
+ void rtrs_clt_close(struct rtrs_clt *clt)
+ {
+-      struct rtrs_clt_sess *sess, *tmp;
++      struct rtrs_clt_path *clt_path, *tmp;
+       /* Firstly forbid sysfs access */
+       rtrs_clt_destroy_sysfs_root(clt);
+       /* Now it is safe to iterate over all paths without locks */
+-      list_for_each_entry_safe(sess, tmp, &clt->paths_list, s.entry) {
+-              rtrs_clt_close_conns(sess, true);
+-              rtrs_clt_destroy_sess_files(sess, NULL);
+-              kobject_put(&sess->kobj);
++      list_for_each_entry_safe(clt_path, tmp, &clt->paths_list, s.entry) {
++              rtrs_clt_close_conns(clt_path, true);
++              rtrs_clt_destroy_path_files(clt_path, NULL);
++              kobject_put(&clt_path->kobj);
+       }
+       free_permits(clt);
+       free_clt(clt);
+ }
+ EXPORT_SYMBOL(rtrs_clt_close);
+-int rtrs_clt_reconnect_from_sysfs(struct rtrs_clt_sess *sess)
++int rtrs_clt_reconnect_from_sysfs(struct rtrs_clt_path *clt_path)
+ {
+       enum rtrs_clt_state old_state;
+       int err = -EBUSY;
+       bool changed;
+-      changed = rtrs_clt_change_state_get_old(sess, RTRS_CLT_RECONNECTING,
++      changed = rtrs_clt_change_state_get_old(clt_path,
++                                               RTRS_CLT_RECONNECTING,
+                                                &old_state);
+       if (changed) {
+-              sess->reconnect_attempts = 0;
+-              queue_delayed_work(rtrs_wq, &sess->reconnect_dwork, 0);
++              clt_path->reconnect_attempts = 0;
++              queue_delayed_work(rtrs_wq, &clt_path->reconnect_dwork, 0);
+       }
+       if (changed || old_state == RTRS_CLT_RECONNECTING) {
+               /*
+@@ -2897,15 +2914,15 @@ int rtrs_clt_reconnect_from_sysfs(struct rtrs_clt_sess *sess)
+                * execution, so do the flush if we have queued something
+                * right now or work is pending.
+                */
+-              flush_delayed_work(&sess->reconnect_dwork);
+-              err = (READ_ONCE(sess->state) ==
++              flush_delayed_work(&clt_path->reconnect_dwork);
++              err = (READ_ONCE(clt_path->state) ==
+                      RTRS_CLT_CONNECTED ? 0 : -ENOTCONN);
+       }
+       return err;
+ }
+-int rtrs_clt_remove_path_from_sysfs(struct rtrs_clt_sess *sess,
++int rtrs_clt_remove_path_from_sysfs(struct rtrs_clt_path *clt_path,
+                                    const struct attribute *sysfs_self)
+ {
+       enum rtrs_clt_state old_state;
+@@ -2921,16 +2938,16 @@ int rtrs_clt_remove_path_from_sysfs(struct rtrs_clt_sess *sess,
+        *    removing the path.
+        */
+       do {
+-              rtrs_clt_close_conns(sess, true);
+-              changed = rtrs_clt_change_state_get_old(sess,
++              rtrs_clt_close_conns(clt_path, true);
++              changed = rtrs_clt_change_state_get_old(clt_path,
+                                                       RTRS_CLT_DEAD,
+                                                       &old_state);
+       } while (!changed && old_state != RTRS_CLT_DEAD);
+       if (changed) {
+-              rtrs_clt_remove_path_from_arr(sess);
+-              rtrs_clt_destroy_sess_files(sess, sysfs_self);
+-              kobject_put(&sess->kobj);
++              rtrs_clt_remove_path_from_arr(clt_path);
++              rtrs_clt_destroy_path_files(clt_path, sysfs_self);
++              kobject_put(&clt_path->kobj);
+       }
+       return 0;
+@@ -2976,7 +2993,7 @@ int rtrs_clt_request(int dir, struct rtrs_clt_req_ops *ops,
+                     struct scatterlist *sg, unsigned int sg_cnt)
+ {
+       struct rtrs_clt_io_req *req;
+-      struct rtrs_clt_sess *sess;
++      struct rtrs_clt_path *clt_path;
+       enum dma_data_direction dma_dir;
+       int err = -ECONNABORTED, i;
+@@ -2998,19 +3015,19 @@ int rtrs_clt_request(int dir, struct rtrs_clt_req_ops *ops,
+       rcu_read_lock();
+       for (path_it_init(&it, clt);
+-           (sess = it.next_path(&it)) && it.i < it.clt->paths_num; it.i++) {
+-              if (READ_ONCE(sess->state) != RTRS_CLT_CONNECTED)
++           (clt_path = it.next_path(&it)) && it.i < it.clt->paths_num; it.i++) {
++              if (READ_ONCE(clt_path->state) != RTRS_CLT_CONNECTED)
+                       continue;
+-              if (usr_len + hdr_len > sess->max_hdr_size) {
+-                      rtrs_wrn_rl(sess->clt,
++              if (usr_len + hdr_len > clt_path->max_hdr_size) {
++                      rtrs_wrn_rl(clt_path->clt,
+                                    "%s request failed, user message size is %zu and header length %zu, but max size is %u\n",
+                                    dir == READ ? "Read" : "Write",
+-                                   usr_len, hdr_len, sess->max_hdr_size);
++                                   usr_len, hdr_len, clt_path->max_hdr_size);
+                       err = -EMSGSIZE;
+                       break;
+               }
+-              req = rtrs_clt_get_req(sess, ops->conf_fn, permit, ops->priv,
++              req = rtrs_clt_get_req(clt_path, ops->conf_fn, permit, ops->priv,
+                                      vec, usr_len, sg, sg_cnt, data_len,
+                                      dma_dir);
+               if (dir == READ)
+@@ -3036,16 +3053,16 @@ int rtrs_clt_rdma_cq_direct(struct rtrs_clt *clt, unsigned int index)
+       /* If no path, return -1 for block layer not to try again */
+       int cnt = -1;
+       struct rtrs_con *con;
+-      struct rtrs_clt_sess *sess;
++      struct rtrs_clt_path *clt_path;
+       struct path_it it;
+       rcu_read_lock();
+       for (path_it_init(&it, clt);
+-           (sess = it.next_path(&it)) && it.i < it.clt->paths_num; it.i++) {
+-              if (READ_ONCE(sess->state) != RTRS_CLT_CONNECTED)
++           (clt_path = it.next_path(&it)) && it.i < it.clt->paths_num; it.i++) {
++              if (READ_ONCE(clt_path->state) != RTRS_CLT_CONNECTED)
+                       continue;
+-              con = sess->s.con[index + 1];
++              con = clt_path->s.con[index + 1];
+               cnt = ib_process_cq_direct(con->cq, -1);
+               if (cnt)
+                       break;
+@@ -3083,12 +3100,12 @@ EXPORT_SYMBOL(rtrs_clt_query);
+ int rtrs_clt_create_path_from_sysfs(struct rtrs_clt *clt,
+                                    struct rtrs_addr *addr)
+ {
+-      struct rtrs_clt_sess *sess;
++      struct rtrs_clt_path *clt_path;
+       int err;
+-      sess = alloc_sess(clt, addr, nr_cpu_ids, 0);
+-      if (IS_ERR(sess))
+-              return PTR_ERR(sess);
++      clt_path = alloc_path(clt, addr, nr_cpu_ids, 0);
++      if (IS_ERR(clt_path))
++              return PTR_ERR(clt_path);
+       mutex_lock(&clt->paths_mutex);
+       if (clt->paths_num == 0) {
+@@ -3097,7 +3114,7 @@ int rtrs_clt_create_path_from_sysfs(struct rtrs_clt *clt,
+                * the addition of the first path is like a new session for
+                * the storage server
+                */
+-              sess->for_new_clt = 1;
++              clt_path->for_new_clt = 1;
+       }
+       mutex_unlock(&clt->paths_mutex);
+@@ -3107,24 +3124,24 @@ int rtrs_clt_create_path_from_sysfs(struct rtrs_clt *clt,
+        * IO will never grab it.  Also it is very important to add
+        * path before init, since init fires LINK_CONNECTED event.
+        */
+-      rtrs_clt_add_path_to_arr(sess);
++      rtrs_clt_add_path_to_arr(clt_path);
+-      err = init_sess(sess);
++      err = init_path(clt_path);
+       if (err)
+-              goto close_sess;
++              goto close_path;
+-      err = rtrs_clt_create_sess_files(sess);
++      err = rtrs_clt_create_path_files(clt_path);
+       if (err)
+-              goto close_sess;
++              goto close_path;
+       return 0;
+-close_sess:
+-      rtrs_clt_remove_path_from_arr(sess);
+-      rtrs_clt_close_conns(sess, true);
+-      free_percpu(sess->stats->pcpu_stats);
+-      kfree(sess->stats);
+-      free_sess(sess);
++close_path:
++      rtrs_clt_remove_path_from_arr(clt_path);
++      rtrs_clt_close_conns(clt_path, true);
++      free_percpu(clt_path->stats->pcpu_stats);
++      kfree(clt_path->stats);
++      free_path(clt_path);
+       return err;
+ }
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.h b/drivers/infiniband/ulp/rtrs/rtrs-clt.h
+index d616f325bc40..7f2a64995fb6 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-clt.h
++++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.h
+@@ -124,7 +124,7 @@ struct rtrs_rbuf {
+       u32 rkey;
+ };
+-struct rtrs_clt_sess {
++struct rtrs_clt_path {
+       struct rtrs_path        s;
+       struct rtrs_clt *clt;
+       wait_queue_head_t       state_wq;
+@@ -156,7 +156,7 @@ struct rtrs_clt_sess {
+ struct rtrs_clt {
+       struct list_head        paths_list; /* rcu protected list */
+       size_t                  paths_num;
+-      struct rtrs_clt_sess
++      struct rtrs_clt_path
+       __rcu * __percpu        *pcpu_path;
+       uuid_t                  paths_uuid;
+       int                     paths_up;
+@@ -186,9 +186,9 @@ static inline struct rtrs_clt_con *to_clt_con(struct rtrs_con *c)
+       return container_of(c, struct rtrs_clt_con, c);
+ }
+-static inline struct rtrs_clt_sess *to_clt_sess(struct rtrs_path *s)
++static inline struct rtrs_clt_path *to_clt_path(struct rtrs_path *s)
+ {
+-      return container_of(s, struct rtrs_clt_sess, s);
++      return container_of(s, struct rtrs_clt_path, s);
+ }
+ static inline int permit_size(struct rtrs_clt *clt)
+@@ -201,16 +201,16 @@ static inline struct rtrs_permit *get_permit(struct rtrs_clt *clt, int idx)
+       return (struct rtrs_permit *)(clt->permits + permit_size(clt) * idx);
+ }
+-int rtrs_clt_reconnect_from_sysfs(struct rtrs_clt_sess *sess);
+-void rtrs_clt_close_conns(struct rtrs_clt_sess *sess, bool wait);
++int rtrs_clt_reconnect_from_sysfs(struct rtrs_clt_path *path);
++void rtrs_clt_close_conns(struct rtrs_clt_path *clt_path, bool wait);
+ int rtrs_clt_create_path_from_sysfs(struct rtrs_clt *clt,
+                                    struct rtrs_addr *addr);
+-int rtrs_clt_remove_path_from_sysfs(struct rtrs_clt_sess *sess,
++int rtrs_clt_remove_path_from_sysfs(struct rtrs_clt_path *path,
+                                    const struct attribute *sysfs_self);
+ void rtrs_clt_set_max_reconnect_attempts(struct rtrs_clt *clt, int value);
+ int rtrs_clt_get_max_reconnect_attempts(const struct rtrs_clt *clt);
+-void free_sess(struct rtrs_clt_sess *sess);
++void free_path(struct rtrs_clt_path *clt_path);
+ /* rtrs-clt-stats.c */
+@@ -243,8 +243,8 @@ ssize_t rtrs_clt_reset_all_help(struct rtrs_clt_stats *stats,
+ int rtrs_clt_create_sysfs_root_files(struct rtrs_clt *clt);
+ void rtrs_clt_destroy_sysfs_root(struct rtrs_clt *clt);
+-int rtrs_clt_create_sess_files(struct rtrs_clt_sess *sess);
+-void rtrs_clt_destroy_sess_files(struct rtrs_clt_sess *sess,
++int rtrs_clt_create_path_files(struct rtrs_clt_path *clt_path);
++void rtrs_clt_destroy_path_files(struct rtrs_clt_path *clt_path,
+                                 const struct attribute *sysfs_self);
+ #endif /* RTRS_CLT_H */
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-pri.h b/drivers/infiniband/ulp/rtrs/rtrs-pri.h
+index 412cf5ce3e7c..b69fa1fe9a70 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-pri.h
++++ b/drivers/infiniband/ulp/rtrs/rtrs-pri.h
+@@ -230,7 +230,7 @@ struct rtrs_msg_conn_rsp {
+ /**
+  * struct rtrs_msg_info_req
+  * @type:             @RTRS_MSG_INFO_REQ
+- * @sessname:         Session name chosen by client
++ * @pathname:         Path name chosen by client
+  */
+ struct rtrs_msg_info_req {
+       __le16          type;
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs.h b/drivers/infiniband/ulp/rtrs/rtrs.h
+index 9da9202fbee5..c529b6d63c9a 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs.h
++++ b/drivers/infiniband/ulp/rtrs/rtrs.h
+@@ -53,13 +53,13 @@ struct rtrs_clt_ops {
+ };
+ struct rtrs_clt *rtrs_clt_open(struct rtrs_clt_ops *ops,
+-                               const char *sessname,
++                               const char *pathname,
+                                const struct rtrs_addr *paths,
+                                size_t path_cnt, u16 port,
+                                size_t pdu_sz, u8 reconnect_delay_sec,
+                                s16 max_reconnect_attempts, u32 nr_poll_queues);
+-void rtrs_clt_close(struct rtrs_clt *sess);
++void rtrs_clt_close(struct rtrs_clt *clt_path);
+ enum wait_type {
+       RTRS_PERMIT_NOWAIT = 0,
+-- 
+2.35.1
+
diff --git a/queue-5.15/rdma-rtrs-clt-replace-list_next_or_null_rr_rcu-with-.patch b/queue-5.15/rdma-rtrs-clt-replace-list_next_or_null_rr_rcu-with-.patch
new file mode 100644 (file)
index 0000000..eec56c0
--- /dev/null
@@ -0,0 +1,99 @@
+From 5ca86b91672175889aa935dbd760a70caa37bd6e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Jul 2022 12:31:12 +0200
+Subject: RDMA/rtrs-clt: Replace list_next_or_null_rr_rcu with an inline
+ function
+
+From: Md Haris Iqbal <haris.iqbal@ionos.com>
+
+[ Upstream commit c14adff285ad1bb8eefc5d8fc202ceb1f7e3a2f1 ]
+
+removes list_next_or_null_rr_rcu macro to fix below warnings.
+That macro is used only twice.
+CHECK:MACRO_ARG_REUSE: Macro argument reuse 'head' - possible side-effects?
+CHECK:MACRO_ARG_REUSE: Macro argument reuse 'ptr' - possible side-effects?
+CHECK:MACRO_ARG_REUSE: Macro argument reuse 'memb' - possible side-effects?
+
+Replaces that macro with an inline function.
+
+Fixes: 6a98d71daea1 ("RDMA/rtrs: client: main functionality")
+Cc: jinpu.wang@ionos.com
+Link: https://lore.kernel.org/r/20220712103113.617754-5-haris.iqbal@ionos.com
+Signed-off-by: Md Haris Iqbal <haris.iqbal@ionos.com>
+Suggested-by: Jason Gunthorpe <jgg@ziepe.ca>
+Signed-off-by: Jack Wang <jinpu.wang@ionos.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/rtrs/rtrs-clt.c | 35 ++++++++++++--------------
+ 1 file changed, 16 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
+index a46ef2821e36..9edbb309b96c 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c
++++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
+@@ -747,25 +747,25 @@ struct path_it {
+       struct rtrs_clt_path *(*next_path)(struct path_it *it);
+ };
+-/**
+- * list_next_or_null_rr_rcu - get next list element in round-robin fashion.
++/*
++ * rtrs_clt_get_next_path_or_null - get clt path from the list or return NULL
+  * @head:     the head for the list.
+- * @ptr:        the list head to take the next element from.
+- * @type:       the type of the struct this is embedded in.
+- * @memb:       the name of the list_head within the struct.
++ * @clt_path: The element to take the next clt_path from.
+  *
+- * Next element returned in round-robin fashion, i.e. head will be skipped,
++ * Next clt path returned in round-robin fashion, i.e. head will be skipped,
+  * but if list is observed as empty, NULL will be returned.
+  *
+- * This primitive may safely run concurrently with the _rcu list-mutation
++ * This function may safely run concurrently with the _rcu list-mutation
+  * primitives such as list_add_rcu() as long as it's guarded by rcu_read_lock().
+  */
+-#define list_next_or_null_rr_rcu(head, ptr, type, memb) \
+-({ \
+-      list_next_or_null_rcu(head, ptr, type, memb) ?: \
+-              list_next_or_null_rcu(head, READ_ONCE((ptr)->next), \
+-                                    type, memb); \
+-})
++static inline struct rtrs_clt_path *
++rtrs_clt_get_next_path_or_null(struct list_head *head, struct rtrs_clt_path *clt_path)
++{
++      return list_next_or_null_rcu(head, &clt_path->s.entry, typeof(*clt_path), s.entry) ?:
++                                   list_next_or_null_rcu(head,
++                                                         READ_ONCE((&clt_path->s.entry)->next),
++                                                         typeof(*clt_path), s.entry);
++}
+ /**
+  * get_next_path_rr() - Returns path in round-robin fashion.
+@@ -796,10 +796,8 @@ static struct rtrs_clt_path *get_next_path_rr(struct path_it *it)
+               path = list_first_or_null_rcu(&clt->paths_list,
+                                             typeof(*path), s.entry);
+       else
+-              path = list_next_or_null_rr_rcu(&clt->paths_list,
+-                                              &path->s.entry,
+-                                              typeof(*path),
+-                                              s.entry);
++              path = rtrs_clt_get_next_path_or_null(&clt->paths_list, path);
++
+       rcu_assign_pointer(*ppcpu_path, path);
+       return path;
+@@ -2267,8 +2265,7 @@ static void rtrs_clt_remove_path_from_arr(struct rtrs_clt_path *clt_path)
+        * removed.  If @sess is the last element, then @next is NULL.
+        */
+       rcu_read_lock();
+-      next = list_next_or_null_rr_rcu(&clt->paths_list, &clt_path->s.entry,
+-                                      typeof(*next), s.entry);
++      next = rtrs_clt_get_next_path_or_null(&clt->paths_list, clt_path);
+       rcu_read_unlock();
+       /*
+-- 
+2.35.1
+
diff --git a/queue-5.15/rdma-rtrs-do-not-allow-sessname-to-contain-special-s.patch b/queue-5.15/rdma-rtrs-do-not-allow-sessname-to-contain-special-s.patch
new file mode 100644 (file)
index 0000000..06b64ca
--- /dev/null
@@ -0,0 +1,60 @@
+From 0c481679ced8bff23978430c2acf0d7e26003fa4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Sep 2021 14:53:32 +0200
+Subject: RDMA/rtrs: Do not allow sessname to contain special symbols / and .
+
+From: Md Haris Iqbal <haris.iqbal@ionos.com>
+
+[ Upstream commit dea7bb3ad3e08f96815330f88a62c24d7a9dacae ]
+
+Allowing these characters in sessname can lead to unexpected results,
+particularly because / is used as a separator between files in a path, and
+. points to the current directory.
+
+Link: https://lore.kernel.org/r/20210922125333.351454-7-haris.iqbal@ionos.com
+Signed-off-by: Md Haris Iqbal <haris.iqbal@ionos.com>
+Reviewed-by: Gioh Kim <gi-oh.kim@ionos.com>
+Reviewed-by: Aleksei Marov <aleksei.marov@ionos.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/rtrs/rtrs-clt.c | 6 ++++++
+ drivers/infiniband/ulp/rtrs/rtrs-srv.c | 5 +++++
+ 2 files changed, 11 insertions(+)
+
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
+index a23438bacf12..be96701cf281 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c
++++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
+@@ -2790,6 +2790,12 @@ struct rtrs_clt *rtrs_clt_open(struct rtrs_clt_ops *ops,
+       struct rtrs_clt *clt;
+       int err, i;
++      if (strchr(sessname, '/') || strchr(sessname, '.')) {
++              pr_err("sessname cannot contain / and .\n");
++              err = -EINVAL;
++              goto out;
++      }
++
+       clt = alloc_clt(sessname, paths_num, port, pdu_sz, ops->priv,
+                       ops->link_ev,
+                       reconnect_delay_sec,
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.c b/drivers/infiniband/ulp/rtrs/rtrs-srv.c
+index 078a1cbac90c..7df71f8cf149 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c
++++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c
+@@ -803,6 +803,11 @@ static int process_info_req(struct rtrs_srv_con *con,
+               return err;
+       }
++      if (strchr(msg->sessname, '/') || strchr(msg->sessname, '.')) {
++              rtrs_err(s, "sessname cannot contain / and .\n");
++              return -EINVAL;
++      }
++
+       if (exist_sessname(sess->srv->ctx,
+                          msg->sessname, &sess->srv->paths_uuid)) {
+               rtrs_err(s, "sessname is duplicated: %s\n", msg->sessname);
+-- 
+2.35.1
+
diff --git a/queue-5.15/rdma-rtrs-fix-warning-when-use-poll-mode-on-client-s.patch b/queue-5.15/rdma-rtrs-fix-warning-when-use-poll-mode-on-client-s.patch
new file mode 100644 (file)
index 0000000..6bbb41a
--- /dev/null
@@ -0,0 +1,95 @@
+From af772a272c4c813c245506b3afab49a043160021 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Sep 2021 14:53:29 +0200
+Subject: RDMA/rtrs: Fix warning when use poll mode on client side.
+
+From: Jack Wang <jinpu.wang@ionos.com>
+
+[ Upstream commit 4b6afe9bc955bee44c0527005c3fb0edac91ac30 ]
+
+When testing with poll mode, it will fail and lead to warning below on
+client side:
+
+$ echo "sessname=bla path=gid:fe80::2:c903:4e:d0b3@gid:fe80::2:c903:8:ca17 device_path=/dev/nullb2 nr_poll_queues=-1" | \
+  sudo tee /sys/devices/virtual/rnbd-client/ctl/map_device
+
+rnbd_client L597: Mapping device /dev/nullb2 on session bla, (access_mode: rw, nr_poll_queues: 8)
+WARNING: CPU: 3 PID: 9886 at drivers/infiniband/core/cq.c:447 ib_cq_pool_get+0x26f/0x2a0 [ib_core]
+
+The problem is in case of poll queue, we need to still call
+ib_alloc_cq/ib_free_cq, we can't use cq_poll api for poll queue.
+
+As both client and server use shared function from rtrs, set irq_con_num
+to con_num on server side, which is number of total connection of the
+session, this way we can differ if the rtrs_con requires pollqueue.
+
+Following up patches will replace the duplicate code with helpers.
+
+Link: https://lore.kernel.org/r/20210922125333.351454-4-haris.iqbal@ionos.com
+Signed-off-by: Jack Wang <jinpu.wang@ionos.com>
+Reviewed-by: Gioh Kim <gi-oh.kim@ionos.com>
+Signed-off-by: Md Haris Iqbal <haris.iqbal@cloud.ionos.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/rtrs/rtrs-srv.c |  1 +
+ drivers/infiniband/ulp/rtrs/rtrs.c     | 17 ++++++++++++++---
+ 2 files changed, 15 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.c b/drivers/infiniband/ulp/rtrs/rtrs-srv.c
+index 716ef7b23558..078a1cbac90c 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c
++++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c
+@@ -1766,6 +1766,7 @@ static struct rtrs_srv_sess *__alloc_sess(struct rtrs_srv *srv,
+       strscpy(sess->s.sessname, str, sizeof(sess->s.sessname));
+       sess->s.con_num = con_num;
++      sess->s.irq_con_num = con_num;
+       sess->s.recon_cnt = recon_cnt;
+       uuid_copy(&sess->s.uuid, uuid);
+       spin_lock_init(&sess->state_lock);
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs.c b/drivers/infiniband/ulp/rtrs/rtrs.c
+index ca542e477d38..9bc323490ce3 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs.c
++++ b/drivers/infiniband/ulp/rtrs/rtrs.c
+@@ -228,7 +228,12 @@ static int create_cq(struct rtrs_con *con, int cq_vector, int nr_cqe,
+       struct rdma_cm_id *cm_id = con->cm_id;
+       struct ib_cq *cq;
+-      cq = ib_cq_pool_get(cm_id->device, nr_cqe, cq_vector, poll_ctx);
++      if (con->cid >= con->sess->irq_con_num)
++              cq = ib_alloc_cq(cm_id->device, con, nr_cqe, cq_vector,
++                               poll_ctx);
++      else
++              cq = ib_cq_pool_get(cm_id->device, nr_cqe, cq_vector, poll_ctx);
++
+       if (IS_ERR(cq)) {
+               rtrs_err(con->sess, "Creating completion queue failed, errno: %ld\n",
+                         PTR_ERR(cq));
+@@ -283,7 +288,10 @@ int rtrs_cq_qp_create(struct rtrs_sess *sess, struct rtrs_con *con,
+       err = create_qp(con, sess->dev->ib_pd, max_send_wr, max_recv_wr,
+                       max_send_sge);
+       if (err) {
+-              ib_cq_pool_put(con->cq, con->nr_cqe);
++              if (con->cid >= con->sess->irq_con_num)
++                      ib_free_cq(con->cq);
++              else
++                      ib_cq_pool_put(con->cq, con->nr_cqe);
+               con->cq = NULL;
+               return err;
+       }
+@@ -300,7 +308,10 @@ void rtrs_cq_qp_destroy(struct rtrs_con *con)
+               con->qp = NULL;
+       }
+       if (con->cq) {
+-              ib_cq_pool_put(con->cq, con->nr_cqe);
++              if (con->cid >= con->sess->irq_con_num)
++                      ib_free_cq(con->cq);
++              else
++                      ib_cq_pool_put(con->cq, con->nr_cqe);
+               con->cq = NULL;
+       }
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/rdma-rtrs-introduce-destroy_cq-helper.patch b/queue-5.15/rdma-rtrs-introduce-destroy_cq-helper.patch
new file mode 100644 (file)
index 0000000..d29e9f4
--- /dev/null
@@ -0,0 +1,74 @@
+From 42a58e566d38b92f2352c4d7e60d35f7e2a6f945 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Sep 2021 14:53:31 +0200
+Subject: RDMA/rtrs: Introduce destroy_cq helper
+
+From: Md Haris Iqbal <haris.iqbal@ionos.com>
+
+[ Upstream commit 6f5649afd3984e35c4b862a05c4511c6d18b27af ]
+
+The same code snip used twice, to avoid duplicate, replace it with a
+destroy_cq helper.
+
+Link: https://lore.kernel.org/r/20210922125333.351454-6-haris.iqbal@ionos.com
+Signed-off-by: Jack Wang <jinpu.wang@ionos.com>
+Signed-off-by: Md Haris Iqbal <haris.iqbal@ionos.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/rtrs/rtrs.c | 25 +++++++++++++------------
+ 1 file changed, 13 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs.c b/drivers/infiniband/ulp/rtrs/rtrs.c
+index ac83cd97f838..37952c8e768c 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs.c
++++ b/drivers/infiniband/ulp/rtrs/rtrs.c
+@@ -279,6 +279,17 @@ static int create_qp(struct rtrs_con *con, struct ib_pd *pd,
+       return ret;
+ }
++static void destroy_cq(struct rtrs_con *con)
++{
++      if (con->cq) {
++              if (is_pollqueue(con))
++                      ib_free_cq(con->cq);
++              else
++                      ib_cq_pool_put(con->cq, con->nr_cqe);
++      }
++      con->cq = NULL;
++}
++
+ int rtrs_cq_qp_create(struct rtrs_sess *sess, struct rtrs_con *con,
+                      u32 max_send_sge, int cq_vector, int nr_cqe,
+                      u32 max_send_wr, u32 max_recv_wr,
+@@ -293,11 +304,7 @@ int rtrs_cq_qp_create(struct rtrs_sess *sess, struct rtrs_con *con,
+       err = create_qp(con, sess->dev->ib_pd, max_send_wr, max_recv_wr,
+                       max_send_sge);
+       if (err) {
+-              if (is_pollqueue(con))
+-                      ib_free_cq(con->cq);
+-              else
+-                      ib_cq_pool_put(con->cq, con->nr_cqe);
+-              con->cq = NULL;
++              destroy_cq(con);
+               return err;
+       }
+       con->sess = sess;
+@@ -312,13 +319,7 @@ void rtrs_cq_qp_destroy(struct rtrs_con *con)
+               rdma_destroy_qp(con->cm_id);
+               con->qp = NULL;
+       }
+-      if (con->cq) {
+-              if (is_pollqueue(con))
+-                      ib_free_cq(con->cq);
+-              else
+-                      ib_cq_pool_put(con->cq, con->nr_cqe);
+-              con->cq = NULL;
+-      }
++      destroy_cq(con);
+ }
+ EXPORT_SYMBOL_GPL(rtrs_cq_qp_destroy);
+-- 
+2.35.1
+
diff --git a/queue-5.15/rdma-rtrs-rename-rtrs_sess-to-rtrs_path.patch b/queue-5.15/rdma-rtrs-rename-rtrs_sess-to-rtrs_path.patch
new file mode 100644 (file)
index 0000000..5c9df0b
--- /dev/null
@@ -0,0 +1,918 @@
+From bb5c106dcef6e77351d969e42b22fb64ff3d4d79 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Jan 2022 19:07:04 +0100
+Subject: RDMA/rtrs: Rename rtrs_sess to rtrs_path
+
+From: Vaishali Thakkar <vaishali.thakkar@ionos.com>
+
+[ Upstream commit d9372794717f44b6e746d8fbab66763b6d753e71 ]
+
+rtrs_sess is in fact a path. This makes it confusing and difficult to get
+into the code. So let's rename the structure and related use cases of it.
+
+Coccinelle was used to do the transformation for most of the occurrences
+and remaining ones were handled manually.
+
+Link: https://lore.kernel.org/r/20220105180708.7774-2-jinpu.wang@ionos.com
+Signed-off-by: Vaishali Thakkar <vaishali.thakkar@ionos.com>
+Signed-off-by: Jack Wang <jinpu.wang@ionos.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/rtrs/rtrs-clt-stats.c |  4 +-
+ drivers/infiniband/ulp/rtrs/rtrs-clt.c       | 66 ++++++-------
+ drivers/infiniband/ulp/rtrs/rtrs-clt.h       |  4 +-
+ drivers/infiniband/ulp/rtrs/rtrs-pri.h       | 14 +--
+ drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c |  6 +-
+ drivers/infiniband/ulp/rtrs/rtrs-srv.c       | 46 ++++-----
+ drivers/infiniband/ulp/rtrs/rtrs-srv.h       |  2 +-
+ drivers/infiniband/ulp/rtrs/rtrs.c           | 98 ++++++++++----------
+ 8 files changed, 120 insertions(+), 120 deletions(-)
+
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt-stats.c b/drivers/infiniband/ulp/rtrs/rtrs-clt-stats.c
+index 5e780bdd763d..40b4d6dd4924 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-clt-stats.c
++++ b/drivers/infiniband/ulp/rtrs/rtrs-clt-stats.c
+@@ -13,7 +13,7 @@
+ void rtrs_clt_update_wc_stats(struct rtrs_clt_con *con)
+ {
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.sess);
++      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
+       struct rtrs_clt_stats *stats = sess->stats;
+       struct rtrs_clt_stats_pcpu *s;
+       int cpu;
+@@ -174,7 +174,7 @@ static inline void rtrs_clt_update_rdma_stats(struct rtrs_clt_stats *stats,
+ void rtrs_clt_update_all_stats(struct rtrs_clt_io_req *req, int dir)
+ {
+       struct rtrs_clt_con *con = req->con;
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.sess);
++      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
+       struct rtrs_clt_stats *stats = sess->stats;
+       unsigned int len;
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
+index be96701cf281..5e73127f2adc 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c
++++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
+@@ -298,7 +298,7 @@ static bool rtrs_clt_change_state_from_to(struct rtrs_clt_sess *sess,
+ static void rtrs_rdma_error_recovery(struct rtrs_clt_con *con)
+ {
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.sess);
++      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
+       if (rtrs_clt_change_state_from_to(sess,
+                                          RTRS_CLT_CONNECTED,
+@@ -330,7 +330,7 @@ static void rtrs_clt_fast_reg_done(struct ib_cq *cq, struct ib_wc *wc)
+       struct rtrs_clt_con *con = to_clt_con(wc->qp->qp_context);
+       if (wc->status != IB_WC_SUCCESS) {
+-              rtrs_err(con->c.sess, "Failed IB_WR_REG_MR: %s\n",
++              rtrs_err(con->c.path, "Failed IB_WR_REG_MR: %s\n",
+                         ib_wc_status_msg(wc->status));
+               rtrs_rdma_error_recovery(con);
+       }
+@@ -350,7 +350,7 @@ static void rtrs_clt_inv_rkey_done(struct ib_cq *cq, struct ib_wc *wc)
+       struct rtrs_clt_con *con = to_clt_con(wc->qp->qp_context);
+       if (wc->status != IB_WC_SUCCESS) {
+-              rtrs_err(con->c.sess, "Failed IB_WR_LOCAL_INV: %s\n",
++              rtrs_err(con->c.path, "Failed IB_WR_LOCAL_INV: %s\n",
+                         ib_wc_status_msg(wc->status));
+               rtrs_rdma_error_recovery(con);
+       }
+@@ -387,7 +387,7 @@ static void complete_rdma_req(struct rtrs_clt_io_req *req, int errno,
+               return;
+       if (WARN_ON(!req->con))
+               return;
+-      sess = to_clt_sess(con->c.sess);
++      sess = to_clt_sess(con->c.path);
+       if (req->sg_cnt) {
+               if (req->dir == DMA_FROM_DEVICE && req->need_inv) {
+@@ -417,7 +417,7 @@ static void complete_rdma_req(struct rtrs_clt_io_req *req, int errno,
+                       refcount_inc(&req->ref);
+                       err = rtrs_inv_rkey(req);
+                       if (err) {
+-                              rtrs_err(con->c.sess, "Send INV WR key=%#x: %d\n",
++                              rtrs_err(con->c.path, "Send INV WR key=%#x: %d\n",
+                                         req->mr->rkey, err);
+                       } else if (can_wait) {
+                               wait_for_completion(&req->inv_comp);
+@@ -445,7 +445,7 @@ static void complete_rdma_req(struct rtrs_clt_io_req *req, int errno,
+       req->con = NULL;
+       if (errno) {
+-              rtrs_err_rl(con->c.sess, "IO request failed: error=%d path=%s [%s:%u] notify=%d\n",
++              rtrs_err_rl(con->c.path, "IO request failed: error=%d path=%s [%s:%u] notify=%d\n",
+                           errno, kobject_name(&sess->kobj), sess->hca_name,
+                           sess->hca_port, notify);
+       }
+@@ -459,12 +459,12 @@ static int rtrs_post_send_rdma(struct rtrs_clt_con *con,
+                               struct rtrs_rbuf *rbuf, u32 off,
+                               u32 imm, struct ib_send_wr *wr)
+ {
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.sess);
++      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
+       enum ib_send_flags flags;
+       struct ib_sge sge;
+       if (!req->sg_size) {
+-              rtrs_wrn(con->c.sess,
++              rtrs_wrn(con->c.path,
+                        "Doing RDMA Write failed, no data supplied\n");
+               return -EINVAL;
+       }
+@@ -507,21 +507,21 @@ static void rtrs_clt_recv_done(struct rtrs_clt_con *con, struct ib_wc *wc)
+ {
+       struct rtrs_iu *iu;
+       int err;
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.sess);
++      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
+       WARN_ON((sess->flags & RTRS_MSG_NEW_RKEY_F) == 0);
+       iu = container_of(wc->wr_cqe, struct rtrs_iu,
+                         cqe);
+       err = rtrs_iu_post_recv(&con->c, iu);
+       if (err) {
+-              rtrs_err(con->c.sess, "post iu failed %d\n", err);
++              rtrs_err(con->c.path, "post iu failed %d\n", err);
+               rtrs_rdma_error_recovery(con);
+       }
+ }
+ static void rtrs_clt_rkey_rsp_done(struct rtrs_clt_con *con, struct ib_wc *wc)
+ {
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.sess);
++      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
+       struct rtrs_msg_rkey_rsp *msg;
+       u32 imm_type, imm_payload;
+       bool w_inval = false;
+@@ -534,7 +534,7 @@ static void rtrs_clt_rkey_rsp_done(struct rtrs_clt_con *con, struct ib_wc *wc)
+       iu = container_of(wc->wr_cqe, struct rtrs_iu, cqe);
+       if (wc->byte_len < sizeof(*msg)) {
+-              rtrs_err(con->c.sess, "rkey response is malformed: size %d\n",
++              rtrs_err(con->c.path, "rkey response is malformed: size %d\n",
+                         wc->byte_len);
+               goto out;
+       }
+@@ -600,7 +600,7 @@ static int rtrs_post_recv_empty_x2(struct rtrs_con *con, struct ib_cqe *cqe)
+ static void rtrs_clt_rdma_done(struct ib_cq *cq, struct ib_wc *wc)
+ {
+       struct rtrs_clt_con *con = to_clt_con(wc->qp->qp_context);
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.sess);
++      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
+       u32 imm_type, imm_payload;
+       bool w_inval = false;
+       int err;
+@@ -646,7 +646,7 @@ static void rtrs_clt_rdma_done(struct ib_cq *cq, struct ib_wc *wc)
+                       if (sess->flags & RTRS_MSG_NEW_RKEY_F)
+                               return  rtrs_clt_recv_done(con, wc);
+               } else {
+-                      rtrs_wrn(con->c.sess, "Unknown IMM type %u\n",
++                      rtrs_wrn(con->c.path, "Unknown IMM type %u\n",
+                                 imm_type);
+               }
+               if (w_inval)
+@@ -658,7 +658,7 @@ static void rtrs_clt_rdma_done(struct ib_cq *cq, struct ib_wc *wc)
+               else
+                       err = rtrs_post_recv_empty(&con->c, &io_comp_cqe);
+               if (err) {
+-                      rtrs_err(con->c.sess, "rtrs_post_recv_empty(): %d\n",
++                      rtrs_err(con->c.path, "rtrs_post_recv_empty(): %d\n",
+                                 err);
+                       rtrs_rdma_error_recovery(con);
+               }
+@@ -693,7 +693,7 @@ static void rtrs_clt_rdma_done(struct ib_cq *cq, struct ib_wc *wc)
+ static int post_recv_io(struct rtrs_clt_con *con, size_t q_size)
+ {
+       int err, i;
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.sess);
++      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
+       for (i = 0; i < q_size; i++) {
+               if (sess->flags & RTRS_MSG_NEW_RKEY_F) {
+@@ -1013,7 +1013,7 @@ static int rtrs_post_rdma_write_sg(struct rtrs_clt_con *con,
+                                  u32 size, u32 imm, struct ib_send_wr *wr,
+                                  struct ib_send_wr *tail)
+ {
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.sess);
++      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
+       struct ib_sge *sge = req->sge;
+       enum ib_send_flags flags;
+       struct scatterlist *sg;
+@@ -1074,7 +1074,7 @@ static int rtrs_map_sg_fr(struct rtrs_clt_io_req *req, size_t count)
+ static int rtrs_clt_write_req(struct rtrs_clt_io_req *req)
+ {
+       struct rtrs_clt_con *con = req->con;
+-      struct rtrs_sess *s = con->c.sess;
++      struct rtrs_path *s = con->c.path;
+       struct rtrs_clt_sess *sess = to_clt_sess(s);
+       struct rtrs_msg_rdma_write *msg;
+@@ -1168,7 +1168,7 @@ static int rtrs_clt_write_req(struct rtrs_clt_io_req *req)
+ static int rtrs_clt_read_req(struct rtrs_clt_io_req *req)
+ {
+       struct rtrs_clt_con *con = req->con;
+-      struct rtrs_sess *s = con->c.sess;
++      struct rtrs_path *s = con->c.path;
+       struct rtrs_clt_sess *sess = to_clt_sess(s);
+       struct rtrs_msg_rdma_read *msg;
+       struct rtrs_ib_dev *dev = sess->s.dev;
+@@ -1601,7 +1601,7 @@ static int create_con(struct rtrs_clt_sess *sess, unsigned int cid)
+       /* Map first two connections to the first CPU */
+       con->cpu  = (cid ? cid - 1 : 0) % nr_cpu_ids;
+       con->c.cid = cid;
+-      con->c.sess = &sess->s;
++      con->c.path = &sess->s;
+       /* Align with srv, init as 1 */
+       atomic_set(&con->c.wr_cnt, 1);
+       mutex_init(&con->con_mutex);
+@@ -1613,7 +1613,7 @@ static int create_con(struct rtrs_clt_sess *sess, unsigned int cid)
+ static void destroy_con(struct rtrs_clt_con *con)
+ {
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.sess);
++      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
+       sess->s.con[con->c.cid] = NULL;
+       mutex_destroy(&con->con_mutex);
+@@ -1622,7 +1622,7 @@ static void destroy_con(struct rtrs_clt_con *con)
+ static int create_con_cq_qp(struct rtrs_clt_con *con)
+ {
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.sess);
++      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
+       u32 max_send_wr, max_recv_wr, cq_num, max_send_sge, wr_limit;
+       int err, cq_vector;
+       struct rtrs_msg_rkey_rsp *rsp;
+@@ -1711,7 +1711,7 @@ static int create_con_cq_qp(struct rtrs_clt_con *con)
+ static void destroy_con_cq_qp(struct rtrs_clt_con *con)
+ {
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.sess);
++      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
+       /*
+        * Be careful here: destroy_con_cq_qp() can be called even
+@@ -1745,7 +1745,7 @@ static void destroy_cm(struct rtrs_clt_con *con)
+ static int rtrs_rdma_addr_resolved(struct rtrs_clt_con *con)
+ {
+-      struct rtrs_sess *s = con->c.sess;
++      struct rtrs_path *s = con->c.path;
+       int err;
+       mutex_lock(&con->con_mutex);
+@@ -1764,7 +1764,7 @@ static int rtrs_rdma_addr_resolved(struct rtrs_clt_con *con)
+ static int rtrs_rdma_route_resolved(struct rtrs_clt_con *con)
+ {
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.sess);
++      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
+       struct rtrs_clt *clt = sess->clt;
+       struct rtrs_msg_conn_req msg;
+       struct rdma_conn_param param;
+@@ -1799,7 +1799,7 @@ static int rtrs_rdma_route_resolved(struct rtrs_clt_con *con)
+ static int rtrs_rdma_conn_established(struct rtrs_clt_con *con,
+                                      struct rdma_cm_event *ev)
+ {
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.sess);
++      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
+       struct rtrs_clt *clt = sess->clt;
+       const struct rtrs_msg_conn_rsp *msg;
+       u16 version, queue_depth;
+@@ -1887,7 +1887,7 @@ static int rtrs_rdma_conn_established(struct rtrs_clt_con *con,
+ static inline void flag_success_on_conn(struct rtrs_clt_con *con)
+ {
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.sess);
++      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
+       atomic_inc(&sess->connected_cnt);
+       con->cm_err = 1;
+@@ -1896,7 +1896,7 @@ static inline void flag_success_on_conn(struct rtrs_clt_con *con)
+ static int rtrs_rdma_conn_rejected(struct rtrs_clt_con *con,
+                                   struct rdma_cm_event *ev)
+ {
+-      struct rtrs_sess *s = con->c.sess;
++      struct rtrs_path *s = con->c.path;
+       const struct rtrs_msg_conn_rsp *msg;
+       const char *rej_msg;
+       int status, errno;
+@@ -1937,7 +1937,7 @@ static inline void flag_error_on_conn(struct rtrs_clt_con *con, int cm_err)
+       if (con->cm_err == 1) {
+               struct rtrs_clt_sess *sess;
+-              sess = to_clt_sess(con->c.sess);
++              sess = to_clt_sess(con->c.path);
+               if (atomic_dec_and_test(&sess->connected_cnt))
+                       wake_up(&sess->state_wq);
+@@ -1949,7 +1949,7 @@ static int rtrs_clt_rdma_cm_handler(struct rdma_cm_id *cm_id,
+                                    struct rdma_cm_event *ev)
+ {
+       struct rtrs_clt_con *con = cm_id->context;
+-      struct rtrs_sess *s = con->c.sess;
++      struct rtrs_path *s = con->c.path;
+       struct rtrs_clt_sess *sess = to_clt_sess(s);
+       int cm_err = 0;
+@@ -2020,7 +2020,7 @@ static int rtrs_clt_rdma_cm_handler(struct rdma_cm_id *cm_id,
+ static int create_cm(struct rtrs_clt_con *con)
+ {
+-      struct rtrs_sess *s = con->c.sess;
++      struct rtrs_path *s = con->c.path;
+       struct rtrs_clt_sess *sess = to_clt_sess(s);
+       struct rdma_cm_id *cm_id;
+       int err;
+@@ -2375,7 +2375,7 @@ static int init_conns(struct rtrs_clt_sess *sess)
+ static void rtrs_clt_info_req_done(struct ib_cq *cq, struct ib_wc *wc)
+ {
+       struct rtrs_clt_con *con = to_clt_con(wc->qp->qp_context);
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.sess);
++      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
+       struct rtrs_iu *iu;
+       iu = container_of(wc->wr_cqe, struct rtrs_iu, cqe);
+@@ -2456,7 +2456,7 @@ static int process_info_rsp(struct rtrs_clt_sess *sess,
+ static void rtrs_clt_info_rsp_done(struct ib_cq *cq, struct ib_wc *wc)
+ {
+       struct rtrs_clt_con *con = to_clt_con(wc->qp->qp_context);
+-      struct rtrs_clt_sess *sess = to_clt_sess(con->c.sess);
++      struct rtrs_clt_sess *sess = to_clt_sess(con->c.path);
+       struct rtrs_msg_info_rsp *msg;
+       enum rtrs_clt_state state;
+       struct rtrs_iu *iu;
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.h b/drivers/infiniband/ulp/rtrs/rtrs-clt.h
+index 9dc819885ec7..d616f325bc40 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-clt.h
++++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.h
+@@ -125,7 +125,7 @@ struct rtrs_rbuf {
+ };
+ struct rtrs_clt_sess {
+-      struct rtrs_sess        s;
++      struct rtrs_path        s;
+       struct rtrs_clt *clt;
+       wait_queue_head_t       state_wq;
+       enum rtrs_clt_state     state;
+@@ -186,7 +186,7 @@ static inline struct rtrs_clt_con *to_clt_con(struct rtrs_con *c)
+       return container_of(c, struct rtrs_clt_con, c);
+ }
+-static inline struct rtrs_clt_sess *to_clt_sess(struct rtrs_sess *s)
++static inline struct rtrs_clt_sess *to_clt_sess(struct rtrs_path *s)
+ {
+       return container_of(s, struct rtrs_clt_sess, s);
+ }
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-pri.h b/drivers/infiniband/ulp/rtrs/rtrs-pri.h
+index e39267bccce8..fad06c707b9b 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-pri.h
++++ b/drivers/infiniband/ulp/rtrs/rtrs-pri.h
+@@ -91,7 +91,7 @@ struct rtrs_ib_dev {
+ };
+ struct rtrs_con {
+-      struct rtrs_sess        *sess;
++      struct rtrs_path        *path;
+       struct ib_qp            *qp;
+       struct ib_cq            *cq;
+       struct rdma_cm_id       *cm_id;
+@@ -101,7 +101,7 @@ struct rtrs_con {
+       atomic_t                sq_wr_avail;
+ };
+-struct rtrs_sess {
++struct rtrs_path {
+       struct list_head        entry;
+       struct sockaddr_storage dst_addr;
+       struct sockaddr_storage src_addr;
+@@ -314,19 +314,19 @@ int rtrs_iu_post_rdma_write_imm(struct rtrs_con *con, struct rtrs_iu *iu,
+ int rtrs_post_recv_empty(struct rtrs_con *con, struct ib_cqe *cqe);
+-int rtrs_cq_qp_create(struct rtrs_sess *sess, struct rtrs_con *con,
++int rtrs_cq_qp_create(struct rtrs_path *path, struct rtrs_con *con,
+                     u32 max_send_sge, int cq_vector, int nr_cqe,
+                     u32 max_send_wr, u32 max_recv_wr,
+                     enum ib_poll_context poll_ctx);
+ void rtrs_cq_qp_destroy(struct rtrs_con *con);
+-void rtrs_init_hb(struct rtrs_sess *sess, struct ib_cqe *cqe,
++void rtrs_init_hb(struct rtrs_path *path, struct ib_cqe *cqe,
+                 unsigned int interval_ms, unsigned int missed_max,
+                 void (*err_handler)(struct rtrs_con *con),
+                 struct workqueue_struct *wq);
+-void rtrs_start_hb(struct rtrs_sess *sess);
+-void rtrs_stop_hb(struct rtrs_sess *sess);
+-void rtrs_send_hb_ack(struct rtrs_sess *sess);
++void rtrs_start_hb(struct rtrs_path *path);
++void rtrs_stop_hb(struct rtrs_path *path);
++void rtrs_send_hb_ack(struct rtrs_path *path);
+ void rtrs_rdma_dev_pd_init(enum ib_pd_flags pd_flags,
+                          struct rtrs_rdma_dev_pd *pool);
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c b/drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c
+index 20efd44297fb..aedddc416003 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c
++++ b/drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c
+@@ -37,7 +37,7 @@ static ssize_t rtrs_srv_disconnect_store(struct kobject *kobj,
+                                         const char *buf, size_t count)
+ {
+       struct rtrs_srv_sess *sess;
+-      struct rtrs_sess *s;
++      struct rtrs_path *s;
+       char str[MAXHOSTNAMELEN];
+       sess = container_of(kobj, struct rtrs_srv_sess, kobj);
+@@ -230,7 +230,7 @@ static struct kobj_type ktype_stats = {
+ static int rtrs_srv_create_stats_files(struct rtrs_srv_sess *sess)
+ {
+       int err;
+-      struct rtrs_sess *s = &sess->s;
++      struct rtrs_path *s = &sess->s;
+       err = kobject_init_and_add(&sess->stats->kobj_stats, &ktype_stats,
+                                  &sess->kobj, "stats");
+@@ -258,7 +258,7 @@ static int rtrs_srv_create_stats_files(struct rtrs_srv_sess *sess)
+ int rtrs_srv_create_sess_files(struct rtrs_srv_sess *sess)
+ {
+       struct rtrs_srv *srv = sess->srv;
+-      struct rtrs_sess *s = &sess->s;
++      struct rtrs_path *s = &sess->s;
+       char str[NAME_MAX];
+       int err;
+       struct rtrs_addr path = {
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.c b/drivers/infiniband/ulp/rtrs/rtrs-srv.c
+index 7df71f8cf149..de4f214233b6 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c
++++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c
+@@ -62,7 +62,7 @@ static inline struct rtrs_srv_con *to_srv_con(struct rtrs_con *c)
+       return container_of(c, struct rtrs_srv_con, c);
+ }
+-static inline struct rtrs_srv_sess *to_srv_sess(struct rtrs_sess *s)
++static inline struct rtrs_srv_sess *to_srv_sess(struct rtrs_path *s)
+ {
+       return container_of(s, struct rtrs_srv_sess, s);
+ }
+@@ -180,7 +180,7 @@ static inline void rtrs_srv_put_ops_ids(struct rtrs_srv_sess *sess)
+ static void rtrs_srv_reg_mr_done(struct ib_cq *cq, struct ib_wc *wc)
+ {
+       struct rtrs_srv_con *con = to_srv_con(wc->qp->qp_context);
+-      struct rtrs_sess *s = con->c.sess;
++      struct rtrs_path *s = con->c.path;
+       struct rtrs_srv_sess *sess = to_srv_sess(s);
+       if (wc->status != IB_WC_SUCCESS) {
+@@ -197,7 +197,7 @@ static struct ib_cqe local_reg_cqe = {
+ static int rdma_write_sg(struct rtrs_srv_op *id)
+ {
+-      struct rtrs_sess *s = id->con->c.sess;
++      struct rtrs_path *s = id->con->c.path;
+       struct rtrs_srv_sess *sess = to_srv_sess(s);
+       dma_addr_t dma_addr = sess->dma_addr[id->msg_id];
+       struct rtrs_srv_mr *srv_mr;
+@@ -341,7 +341,7 @@ static int rdma_write_sg(struct rtrs_srv_op *id)
+ static int send_io_resp_imm(struct rtrs_srv_con *con, struct rtrs_srv_op *id,
+                           int errno)
+ {
+-      struct rtrs_sess *s = con->c.sess;
++      struct rtrs_path *s = con->c.path;
+       struct rtrs_srv_sess *sess = to_srv_sess(s);
+       struct ib_send_wr inv_wr, *wr = NULL;
+       struct ib_rdma_wr imm_wr;
+@@ -482,14 +482,14 @@ bool rtrs_srv_resp_rdma(struct rtrs_srv_op *id, int status)
+ {
+       struct rtrs_srv_sess *sess;
+       struct rtrs_srv_con *con;
+-      struct rtrs_sess *s;
++      struct rtrs_path *s;
+       int err;
+       if (WARN_ON(!id))
+               return true;
+       con = id->con;
+-      s = con->c.sess;
++      s = con->c.path;
+       sess = to_srv_sess(s);
+       id->status = status;
+@@ -564,7 +564,7 @@ static void unmap_cont_bufs(struct rtrs_srv_sess *sess)
+ static int map_cont_bufs(struct rtrs_srv_sess *sess)
+ {
+       struct rtrs_srv *srv = sess->srv;
+-      struct rtrs_sess *ss = &sess->s;
++      struct rtrs_path *ss = &sess->s;
+       int i, mri, err, mrs_num;
+       unsigned int chunk_bits;
+       int chunks_per_mr = 1;
+@@ -677,7 +677,7 @@ static int map_cont_bufs(struct rtrs_srv_sess *sess)
+ static void rtrs_srv_hb_err_handler(struct rtrs_con *c)
+ {
+-      close_sess(to_srv_sess(c->sess));
++      close_sess(to_srv_sess(c->path));
+ }
+ static void rtrs_srv_init_hb(struct rtrs_srv_sess *sess)
+@@ -702,7 +702,7 @@ static void rtrs_srv_stop_hb(struct rtrs_srv_sess *sess)
+ static void rtrs_srv_info_rsp_done(struct ib_cq *cq, struct ib_wc *wc)
+ {
+       struct rtrs_srv_con *con = to_srv_con(wc->qp->qp_context);
+-      struct rtrs_sess *s = con->c.sess;
++      struct rtrs_path *s = con->c.path;
+       struct rtrs_srv_sess *sess = to_srv_sess(s);
+       struct rtrs_iu *iu;
+@@ -788,7 +788,7 @@ static int rtrs_rdma_do_reject(struct rdma_cm_id *cm_id, int errno);
+ static int process_info_req(struct rtrs_srv_con *con,
+                           struct rtrs_msg_info_req *msg)
+ {
+-      struct rtrs_sess *s = con->c.sess;
++      struct rtrs_path *s = con->c.path;
+       struct rtrs_srv_sess *sess = to_srv_sess(s);
+       struct ib_send_wr *reg_wr = NULL;
+       struct rtrs_msg_info_rsp *rsp;
+@@ -889,7 +889,7 @@ static int process_info_req(struct rtrs_srv_con *con,
+ static void rtrs_srv_info_req_done(struct ib_cq *cq, struct ib_wc *wc)
+ {
+       struct rtrs_srv_con *con = to_srv_con(wc->qp->qp_context);
+-      struct rtrs_sess *s = con->c.sess;
++      struct rtrs_path *s = con->c.path;
+       struct rtrs_srv_sess *sess = to_srv_sess(s);
+       struct rtrs_msg_info_req *msg;
+       struct rtrs_iu *iu;
+@@ -932,7 +932,7 @@ static void rtrs_srv_info_req_done(struct ib_cq *cq, struct ib_wc *wc)
+ static int post_recv_info_req(struct rtrs_srv_con *con)
+ {
+-      struct rtrs_sess *s = con->c.sess;
++      struct rtrs_path *s = con->c.path;
+       struct rtrs_srv_sess *sess = to_srv_sess(s);
+       struct rtrs_iu *rx_iu;
+       int err;
+@@ -969,7 +969,7 @@ static int post_recv_io(struct rtrs_srv_con *con, size_t q_size)
+ static int post_recv_sess(struct rtrs_srv_sess *sess)
+ {
+       struct rtrs_srv *srv = sess->srv;
+-      struct rtrs_sess *s = &sess->s;
++      struct rtrs_path *s = &sess->s;
+       size_t q_size;
+       int err, cid;
+@@ -993,7 +993,7 @@ static void process_read(struct rtrs_srv_con *con,
+                        struct rtrs_msg_rdma_read *msg,
+                        u32 buf_id, u32 off)
+ {
+-      struct rtrs_sess *s = con->c.sess;
++      struct rtrs_path *s = con->c.path;
+       struct rtrs_srv_sess *sess = to_srv_sess(s);
+       struct rtrs_srv *srv = sess->srv;
+       struct rtrs_srv_ctx *ctx = srv->ctx;
+@@ -1051,7 +1051,7 @@ static void process_write(struct rtrs_srv_con *con,
+                         struct rtrs_msg_rdma_write *req,
+                         u32 buf_id, u32 off)
+ {
+-      struct rtrs_sess *s = con->c.sess;
++      struct rtrs_path *s = con->c.path;
+       struct rtrs_srv_sess *sess = to_srv_sess(s);
+       struct rtrs_srv *srv = sess->srv;
+       struct rtrs_srv_ctx *ctx = srv->ctx;
+@@ -1102,7 +1102,7 @@ static void process_write(struct rtrs_srv_con *con,
+ static void process_io_req(struct rtrs_srv_con *con, void *msg,
+                          u32 id, u32 off)
+ {
+-      struct rtrs_sess *s = con->c.sess;
++      struct rtrs_path *s = con->c.path;
+       struct rtrs_srv_sess *sess = to_srv_sess(s);
+       struct rtrs_msg_rdma_hdr *hdr;
+       unsigned int type;
+@@ -1137,7 +1137,7 @@ static void rtrs_srv_inv_rkey_done(struct ib_cq *cq, struct ib_wc *wc)
+       struct rtrs_srv_mr *mr =
+               container_of(wc->wr_cqe, typeof(*mr), inv_cqe);
+       struct rtrs_srv_con *con = to_srv_con(wc->qp->qp_context);
+-      struct rtrs_sess *s = con->c.sess;
++      struct rtrs_path *s = con->c.path;
+       struct rtrs_srv_sess *sess = to_srv_sess(s);
+       struct rtrs_srv *srv = sess->srv;
+       u32 msg_id, off;
+@@ -1194,7 +1194,7 @@ static void rtrs_rdma_process_wr_wait_list(struct rtrs_srv_con *con)
+ static void rtrs_srv_rdma_done(struct ib_cq *cq, struct ib_wc *wc)
+ {
+       struct rtrs_srv_con *con = to_srv_con(wc->qp->qp_context);
+-      struct rtrs_sess *s = con->c.sess;
++      struct rtrs_path *s = con->c.path;
+       struct rtrs_srv_sess *sess = to_srv_sess(s);
+       struct rtrs_srv *srv = sess->srv;
+       u32 imm_type, imm_payload;
+@@ -1633,7 +1633,7 @@ static int create_con(struct rtrs_srv_sess *sess,
+                     unsigned int cid)
+ {
+       struct rtrs_srv *srv = sess->srv;
+-      struct rtrs_sess *s = &sess->s;
++      struct rtrs_path *s = &sess->s;
+       struct rtrs_srv_con *con;
+       u32 cq_num, max_send_wr, max_recv_wr, wr_limit;
+@@ -1648,7 +1648,7 @@ static int create_con(struct rtrs_srv_sess *sess,
+       spin_lock_init(&con->rsp_wr_wait_lock);
+       INIT_LIST_HEAD(&con->rsp_wr_wait_list);
+       con->c.cm_id = cm_id;
+-      con->c.sess = &sess->s;
++      con->c.path = &sess->s;
+       con->c.cid = cid;
+       atomic_set(&con->c.wr_cnt, 1);
+       wr_limit = sess->s.dev->ib_dev->attrs.max_qp_wr;
+@@ -1859,7 +1859,7 @@ static int rtrs_rdma_connect(struct rdma_cm_id *cm_id,
+       mutex_lock(&srv->paths_mutex);
+       sess = __find_sess(srv, &msg->sess_uuid);
+       if (sess) {
+-              struct rtrs_sess *s = &sess->s;
++              struct rtrs_path *s = &sess->s;
+               /* Session already holds a reference */
+               put_srv(srv);
+@@ -1938,12 +1938,12 @@ static int rtrs_srv_rdma_cm_handler(struct rdma_cm_id *cm_id,
+                                    struct rdma_cm_event *ev)
+ {
+       struct rtrs_srv_sess *sess = NULL;
+-      struct rtrs_sess *s = NULL;
++      struct rtrs_path *s = NULL;
+       if (ev->event != RDMA_CM_EVENT_CONNECT_REQUEST) {
+               struct rtrs_con *c = cm_id->context;
+-              s = c->sess;
++              s = c->path;
+               sess = to_srv_sess(s);
+       }
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.h b/drivers/infiniband/ulp/rtrs/rtrs-srv.h
+index 9d8d2a91a235..f0fbd8bf8871 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-srv.h
++++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.h
+@@ -72,7 +72,7 @@ struct rtrs_srv_mr {
+ };
+ struct rtrs_srv_sess {
+-      struct rtrs_sess        s;
++      struct rtrs_path        s;
+       struct rtrs_srv *srv;
+       struct work_struct      close_work;
+       enum rtrs_srv_state     state;
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs.c b/drivers/infiniband/ulp/rtrs/rtrs.c
+index 37952c8e768c..4da889103a5f 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs.c
++++ b/drivers/infiniband/ulp/rtrs/rtrs.c
+@@ -69,16 +69,16 @@ EXPORT_SYMBOL_GPL(rtrs_iu_free);
+ int rtrs_iu_post_recv(struct rtrs_con *con, struct rtrs_iu *iu)
+ {
+-      struct rtrs_sess *sess = con->sess;
++      struct rtrs_path *path = con->path;
+       struct ib_recv_wr wr;
+       struct ib_sge list;
+       list.addr   = iu->dma_addr;
+       list.length = iu->size;
+-      list.lkey   = sess->dev->ib_pd->local_dma_lkey;
++      list.lkey   = path->dev->ib_pd->local_dma_lkey;
+       if (list.length == 0) {
+-              rtrs_wrn(con->sess,
++              rtrs_wrn(con->path,
+                         "Posting receive work request failed, sg list is empty\n");
+               return -EINVAL;
+       }
+@@ -126,7 +126,7 @@ static int rtrs_post_send(struct ib_qp *qp, struct ib_send_wr *head,
+ int rtrs_iu_post_send(struct rtrs_con *con, struct rtrs_iu *iu, size_t size,
+                      struct ib_send_wr *head)
+ {
+-      struct rtrs_sess *sess = con->sess;
++      struct rtrs_path *path = con->path;
+       struct ib_send_wr wr;
+       struct ib_sge list;
+@@ -135,7 +135,7 @@ int rtrs_iu_post_send(struct rtrs_con *con, struct rtrs_iu *iu, size_t size,
+       list.addr   = iu->dma_addr;
+       list.length = size;
+-      list.lkey   = sess->dev->ib_pd->local_dma_lkey;
++      list.lkey   = path->dev->ib_pd->local_dma_lkey;
+       wr = (struct ib_send_wr) {
+               .wr_cqe     = &iu->cqe,
+@@ -188,11 +188,11 @@ static int rtrs_post_rdma_write_imm_empty(struct rtrs_con *con,
+                                         struct ib_send_wr *head)
+ {
+       struct ib_rdma_wr wr;
+-      struct rtrs_sess *sess = con->sess;
++      struct rtrs_path *path = con->path;
+       enum ib_send_flags sflags;
+       atomic_dec_if_positive(&con->sq_wr_avail);
+-      sflags = (atomic_inc_return(&con->wr_cnt) % sess->signal_interval) ?
++      sflags = (atomic_inc_return(&con->wr_cnt) % path->signal_interval) ?
+               0 : IB_SEND_SIGNALED;
+       wr = (struct ib_rdma_wr) {
+@@ -211,12 +211,12 @@ static void qp_event_handler(struct ib_event *ev, void *ctx)
+       switch (ev->event) {
+       case IB_EVENT_COMM_EST:
+-              rtrs_info(con->sess, "QP event %s (%d) received\n",
++              rtrs_info(con->path, "QP event %s (%d) received\n",
+                          ib_event_msg(ev->event), ev->event);
+               rdma_notify(con->cm_id, IB_EVENT_COMM_EST);
+               break;
+       default:
+-              rtrs_info(con->sess, "Unhandled QP event %s (%d) received\n",
++              rtrs_info(con->path, "Unhandled QP event %s (%d) received\n",
+                          ib_event_msg(ev->event), ev->event);
+               break;
+       }
+@@ -224,7 +224,7 @@ static void qp_event_handler(struct ib_event *ev, void *ctx)
+ static bool is_pollqueue(struct rtrs_con *con)
+ {
+-      return con->cid >= con->sess->irq_con_num;
++      return con->cid >= con->path->irq_con_num;
+ }
+ static int create_cq(struct rtrs_con *con, int cq_vector, int nr_cqe,
+@@ -240,7 +240,7 @@ static int create_cq(struct rtrs_con *con, int cq_vector, int nr_cqe,
+               cq = ib_cq_pool_get(cm_id->device, nr_cqe, cq_vector, poll_ctx);
+       if (IS_ERR(cq)) {
+-              rtrs_err(con->sess, "Creating completion queue failed, errno: %ld\n",
++              rtrs_err(con->path, "Creating completion queue failed, errno: %ld\n",
+                         PTR_ERR(cq));
+               return PTR_ERR(cq);
+       }
+@@ -271,7 +271,7 @@ static int create_qp(struct rtrs_con *con, struct ib_pd *pd,
+       ret = rdma_create_qp(cm_id, pd, &init_attr);
+       if (ret) {
+-              rtrs_err(con->sess, "Creating QP failed, err: %d\n", ret);
++              rtrs_err(con->path, "Creating QP failed, err: %d\n", ret);
+               return ret;
+       }
+       con->qp = cm_id->qp;
+@@ -290,7 +290,7 @@ static void destroy_cq(struct rtrs_con *con)
+       con->cq = NULL;
+ }
+-int rtrs_cq_qp_create(struct rtrs_sess *sess, struct rtrs_con *con,
++int rtrs_cq_qp_create(struct rtrs_path *path, struct rtrs_con *con,
+                      u32 max_send_sge, int cq_vector, int nr_cqe,
+                      u32 max_send_wr, u32 max_recv_wr,
+                      enum ib_poll_context poll_ctx)
+@@ -301,13 +301,13 @@ int rtrs_cq_qp_create(struct rtrs_sess *sess, struct rtrs_con *con,
+       if (err)
+               return err;
+-      err = create_qp(con, sess->dev->ib_pd, max_send_wr, max_recv_wr,
++      err = create_qp(con, path->dev->ib_pd, max_send_wr, max_recv_wr,
+                       max_send_sge);
+       if (err) {
+               destroy_cq(con);
+               return err;
+       }
+-      con->sess = sess;
++      con->path = path;
+       return 0;
+ }
+@@ -323,24 +323,24 @@ void rtrs_cq_qp_destroy(struct rtrs_con *con)
+ }
+ EXPORT_SYMBOL_GPL(rtrs_cq_qp_destroy);
+-static void schedule_hb(struct rtrs_sess *sess)
++static void schedule_hb(struct rtrs_path *path)
+ {
+-      queue_delayed_work(sess->hb_wq, &sess->hb_dwork,
+-                         msecs_to_jiffies(sess->hb_interval_ms));
++      queue_delayed_work(path->hb_wq, &path->hb_dwork,
++                         msecs_to_jiffies(path->hb_interval_ms));
+ }
+-void rtrs_send_hb_ack(struct rtrs_sess *sess)
++void rtrs_send_hb_ack(struct rtrs_path *path)
+ {
+-      struct rtrs_con *usr_con = sess->con[0];
++      struct rtrs_con *usr_con = path->con[0];
+       u32 imm;
+       int err;
+       imm = rtrs_to_imm(RTRS_HB_ACK_IMM, 0);
+-      err = rtrs_post_rdma_write_imm_empty(usr_con, sess->hb_cqe, imm,
++      err = rtrs_post_rdma_write_imm_empty(usr_con, path->hb_cqe, imm,
+                                            NULL);
+       if (err) {
+-              rtrs_err(sess, "send HB ACK failed, errno: %d\n", err);
+-              sess->hb_err_handler(usr_con);
++              rtrs_err(path, "send HB ACK failed, errno: %d\n", err);
++              path->hb_err_handler(usr_con);
+               return;
+       }
+ }
+@@ -349,63 +349,63 @@ EXPORT_SYMBOL_GPL(rtrs_send_hb_ack);
+ static void hb_work(struct work_struct *work)
+ {
+       struct rtrs_con *usr_con;
+-      struct rtrs_sess *sess;
++      struct rtrs_path *path;
+       u32 imm;
+       int err;
+-      sess = container_of(to_delayed_work(work), typeof(*sess), hb_dwork);
+-      usr_con = sess->con[0];
++      path = container_of(to_delayed_work(work), typeof(*path), hb_dwork);
++      usr_con = path->con[0];
+-      if (sess->hb_missed_cnt > sess->hb_missed_max) {
+-              rtrs_err(sess, "HB missed max reached.\n");
+-              sess->hb_err_handler(usr_con);
++      if (path->hb_missed_cnt > path->hb_missed_max) {
++              rtrs_err(path, "HB missed max reached.\n");
++              path->hb_err_handler(usr_con);
+               return;
+       }
+-      if (sess->hb_missed_cnt++) {
++      if (path->hb_missed_cnt++) {
+               /* Reschedule work without sending hb */
+-              schedule_hb(sess);
++              schedule_hb(path);
+               return;
+       }
+-      sess->hb_last_sent = ktime_get();
++      path->hb_last_sent = ktime_get();
+       imm = rtrs_to_imm(RTRS_HB_MSG_IMM, 0);
+-      err = rtrs_post_rdma_write_imm_empty(usr_con, sess->hb_cqe, imm,
++      err = rtrs_post_rdma_write_imm_empty(usr_con, path->hb_cqe, imm,
+                                            NULL);
+       if (err) {
+-              rtrs_err(sess, "HB send failed, errno: %d\n", err);
+-              sess->hb_err_handler(usr_con);
++              rtrs_err(path, "HB send failed, errno: %d\n", err);
++              path->hb_err_handler(usr_con);
+               return;
+       }
+-      schedule_hb(sess);
++      schedule_hb(path);
+ }
+-void rtrs_init_hb(struct rtrs_sess *sess, struct ib_cqe *cqe,
++void rtrs_init_hb(struct rtrs_path *path, struct ib_cqe *cqe,
+                 unsigned int interval_ms, unsigned int missed_max,
+                 void (*err_handler)(struct rtrs_con *con),
+                 struct workqueue_struct *wq)
+ {
+-      sess->hb_cqe = cqe;
+-      sess->hb_interval_ms = interval_ms;
+-      sess->hb_err_handler = err_handler;
+-      sess->hb_wq = wq;
+-      sess->hb_missed_max = missed_max;
+-      sess->hb_missed_cnt = 0;
+-      INIT_DELAYED_WORK(&sess->hb_dwork, hb_work);
++      path->hb_cqe = cqe;
++      path->hb_interval_ms = interval_ms;
++      path->hb_err_handler = err_handler;
++      path->hb_wq = wq;
++      path->hb_missed_max = missed_max;
++      path->hb_missed_cnt = 0;
++      INIT_DELAYED_WORK(&path->hb_dwork, hb_work);
+ }
+ EXPORT_SYMBOL_GPL(rtrs_init_hb);
+-void rtrs_start_hb(struct rtrs_sess *sess)
++void rtrs_start_hb(struct rtrs_path *path)
+ {
+-      schedule_hb(sess);
++      schedule_hb(path);
+ }
+ EXPORT_SYMBOL_GPL(rtrs_start_hb);
+-void rtrs_stop_hb(struct rtrs_sess *sess)
++void rtrs_stop_hb(struct rtrs_path *path)
+ {
+-      cancel_delayed_work_sync(&sess->hb_dwork);
+-      sess->hb_missed_cnt = 0;
++      cancel_delayed_work_sync(&path->hb_dwork);
++      path->hb_missed_cnt = 0;
+ }
+ EXPORT_SYMBOL_GPL(rtrs_stop_hb);
+-- 
+2.35.1
+
diff --git a/queue-5.15/rdma-rtrs-replace-duplicate-check-with-is_pollqueue-.patch b/queue-5.15/rdma-rtrs-replace-duplicate-check-with-is_pollqueue-.patch
new file mode 100644 (file)
index 0000000..f3287a9
--- /dev/null
@@ -0,0 +1,66 @@
+From 2c1541b1fdad91d2cb6538d7e372525087d2f1d2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Sep 2021 14:53:30 +0200
+Subject: RDMA/rtrs: Replace duplicate check with is_pollqueue helper
+
+From: Jack Wang <jinpu.wang@ionos.com>
+
+[ Upstream commit 36332ded46b6292296bc7170fada6e238a0802cc ]
+
+if (con->cid >= con->sess->irq_con_num) check can be replaced with a
+is_pollqueue helper.
+
+Link: https://lore.kernel.org/r/20210922125333.351454-5-haris.iqbal@ionos.com
+Signed-off-by: Jack Wang <jinpu.wang@ionos.com>
+Signed-off-by: Md Haris Iqbal <haris.iqbal@ionos.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/rtrs/rtrs.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs.c b/drivers/infiniband/ulp/rtrs/rtrs.c
+index 9bc323490ce3..ac83cd97f838 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs.c
++++ b/drivers/infiniband/ulp/rtrs/rtrs.c
+@@ -222,13 +222,18 @@ static void qp_event_handler(struct ib_event *ev, void *ctx)
+       }
+ }
++static bool is_pollqueue(struct rtrs_con *con)
++{
++      return con->cid >= con->sess->irq_con_num;
++}
++
+ static int create_cq(struct rtrs_con *con, int cq_vector, int nr_cqe,
+                    enum ib_poll_context poll_ctx)
+ {
+       struct rdma_cm_id *cm_id = con->cm_id;
+       struct ib_cq *cq;
+-      if (con->cid >= con->sess->irq_con_num)
++      if (is_pollqueue(con))
+               cq = ib_alloc_cq(cm_id->device, con, nr_cqe, cq_vector,
+                                poll_ctx);
+       else
+@@ -288,7 +293,7 @@ int rtrs_cq_qp_create(struct rtrs_sess *sess, struct rtrs_con *con,
+       err = create_qp(con, sess->dev->ib_pd, max_send_wr, max_recv_wr,
+                       max_send_sge);
+       if (err) {
+-              if (con->cid >= con->sess->irq_con_num)
++              if (is_pollqueue(con))
+                       ib_free_cq(con->cq);
+               else
+                       ib_cq_pool_put(con->cq, con->nr_cqe);
+@@ -308,7 +313,7 @@ void rtrs_cq_qp_destroy(struct rtrs_con *con)
+               con->qp = NULL;
+       }
+       if (con->cq) {
+-              if (con->cid >= con->sess->irq_con_num)
++              if (is_pollqueue(con))
+                       ib_free_cq(con->cq);
+               else
+                       ib_cq_pool_put(con->cq, con->nr_cqe);
+-- 
+2.35.1
+
diff --git a/queue-5.15/rdma-rtrs-srv-fix-modinfo-output-for-stringify.patch b/queue-5.15/rdma-rtrs-srv-fix-modinfo-output-for-stringify.patch
new file mode 100644 (file)
index 0000000..899863b
--- /dev/null
@@ -0,0 +1,65 @@
+From 15385530ae97fe610f230b9ec6d06fce5c4d4372 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Jul 2022 12:31:09 +0200
+Subject: RDMA/rtrs-srv: Fix modinfo output for stringify
+
+From: Jack Wang <jinpu.wang@ionos.com>
+
+[ Upstream commit ed6e53820ee4f68ed927de17e5675ff2a07a47e2 ]
+
+stringify works with define, not enum.
+
+Fixes: 91fddedd439c ("RDMA/rtrs: private headers with rtrs protocol structs and helpers")
+Cc: jinpu.wang@ionos.com
+Link: https://lore.kernel.org/r/20220712103113.617754-2-haris.iqbal@ionos.com
+Signed-off-by: Jack Wang <jinpu.wang@ionos.com>
+Signed-off-by: Md Haris Iqbal <haris.iqbal@ionos.com>
+Reviewed-by: Aleksei Marov <aleksei.marov@ionos.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/rtrs/rtrs-pri.h | 21 +++++++++++----------
+ 1 file changed, 11 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-pri.h b/drivers/infiniband/ulp/rtrs/rtrs-pri.h
+index d12ddfa50747..e39267bccce8 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-pri.h
++++ b/drivers/infiniband/ulp/rtrs/rtrs-pri.h
+@@ -23,6 +23,17 @@
+ #define RTRS_PROTO_VER_STRING __stringify(RTRS_PROTO_VER_MAJOR) "." \
+                              __stringify(RTRS_PROTO_VER_MINOR)
++/*
++ * Max IB immediate data size is 2^28 (MAX_IMM_PAYL_BITS)
++ * and the minimum chunk size is 4096 (2^12).
++ * So the maximum sess_queue_depth is 65536 (2^16) in theory.
++ * But mempool_create, create_qp and ib_post_send fail with
++ * "cannot allocate memory" error if sess_queue_depth is too big.
++ * Therefore the pratical max value of sess_queue_depth is
++ * somewhere between 1 and 65534 and it depends on the system.
++ */
++#define MAX_SESS_QUEUE_DEPTH 65535
++
+ enum rtrs_imm_const {
+       MAX_IMM_TYPE_BITS = 4,
+       MAX_IMM_TYPE_MASK = ((1 << MAX_IMM_TYPE_BITS) - 1),
+@@ -46,16 +57,6 @@ enum {
+       MAX_PATHS_NUM = 128,
+-      /*
+-       * Max IB immediate data size is 2^28 (MAX_IMM_PAYL_BITS)
+-       * and the minimum chunk size is 4096 (2^12).
+-       * So the maximum sess_queue_depth is 65536 (2^16) in theory.
+-       * But mempool_create, create_qp and ib_post_send fail with
+-       * "cannot allocate memory" error if sess_queue_depth is too big.
+-       * Therefore the pratical max value of sess_queue_depth is
+-       * somewhere between 1 and 65534 and it depends on the system.
+-       */
+-      MAX_SESS_QUEUE_DEPTH = 65535,
+       MIN_CHUNK_SIZE = 8192,
+       RTRS_HB_INTERVAL_MS = 5000,
+-- 
+2.35.1
+
diff --git a/queue-5.15/rdma-rtrs-srv-rename-rtrs_srv_sess-to-rtrs_srv_path.patch b/queue-5.15/rdma-rtrs-srv-rename-rtrs_srv_sess-to-rtrs_srv_path.patch
new file mode 100644 (file)
index 0000000..672412d
--- /dev/null
@@ -0,0 +1,1939 @@
+From 5fc374f49cc30c70329bceabc775a6a49949d1b6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Jan 2022 19:07:05 +0100
+Subject: RDMA/rtrs-srv: Rename rtrs_srv_sess to rtrs_srv_path
+
+From: Vaishali Thakkar <vaishali.thakkar@ionos.com>
+
+[ Upstream commit ae4c81644e9105d9f7f713bb0d444737bb6a0cf1 ]
+
+rtrs_srv_sess is used for paths and not sessions on the server side. This
+creates confusion so let's rename it to rtrs_srv_path. Also, rename
+related variables and functions.
+
+Coccinelle is used to do the transformations for most of the occurrences
+and remaining ones were handled manually.
+
+Link: https://lore.kernel.org/r/20220105180708.7774-3-jinpu.wang@ionos.com
+Signed-off-by: Vaishali Thakkar <vaishali.thakkar@ionos.com>
+Signed-off-by: Jack Wang <jinpu.wang@ionos.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/rnbd/rnbd-srv.c                |  12 +-
+ drivers/infiniband/ulp/rtrs/rtrs-pri.h       |   2 +-
+ drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c | 119 ++--
+ drivers/infiniband/ulp/rtrs/rtrs-srv.c       | 627 ++++++++++---------
+ drivers/infiniband/ulp/rtrs/rtrs-srv.h       |  10 +-
+ drivers/infiniband/ulp/rtrs/rtrs.h           |   3 +-
+ 6 files changed, 392 insertions(+), 381 deletions(-)
+
+diff --git a/drivers/block/rnbd/rnbd-srv.c b/drivers/block/rnbd/rnbd-srv.c
+index aafecfe97055..1ba1a93a6fe7 100644
+--- a/drivers/block/rnbd/rnbd-srv.c
++++ b/drivers/block/rnbd/rnbd-srv.c
+@@ -266,12 +266,12 @@ static void destroy_sess(struct rnbd_srv_session *srv_sess)
+ static int create_sess(struct rtrs_srv *rtrs)
+ {
+       struct rnbd_srv_session *srv_sess;
+-      char sessname[NAME_MAX];
++      char pathname[NAME_MAX];
+       int err;
+-      err = rtrs_srv_get_sess_name(rtrs, sessname, sizeof(sessname));
++      err = rtrs_srv_get_path_name(rtrs, pathname, sizeof(pathname));
+       if (err) {
+-              pr_err("rtrs_srv_get_sess_name(%s): %d\n", sessname, err);
++              pr_err("rtrs_srv_get_path_name(%s): %d\n", pathname, err);
+               return err;
+       }
+@@ -284,8 +284,8 @@ static int create_sess(struct rtrs_srv *rtrs)
+                         offsetof(struct rnbd_dev_blk_io, bio),
+                         BIOSET_NEED_BVECS);
+       if (err) {
+-              pr_err("Allocating srv_session for session %s failed\n",
+-                     sessname);
++              pr_err("Allocating srv_session for path %s failed\n",
++                     pathname);
+               kfree(srv_sess);
+               return err;
+       }
+@@ -298,7 +298,7 @@ static int create_sess(struct rtrs_srv *rtrs)
+       mutex_unlock(&sess_lock);
+       srv_sess->rtrs = rtrs;
+-      strscpy(srv_sess->sessname, sessname, sizeof(srv_sess->sessname));
++      strscpy(srv_sess->sessname, pathname, sizeof(srv_sess->sessname));
+       rtrs_srv_set_sess_priv(rtrs, srv_sess);
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-pri.h b/drivers/infiniband/ulp/rtrs/rtrs-pri.h
+index fad06c707b9b..412cf5ce3e7c 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-pri.h
++++ b/drivers/infiniband/ulp/rtrs/rtrs-pri.h
+@@ -234,7 +234,7 @@ struct rtrs_msg_conn_rsp {
+  */
+ struct rtrs_msg_info_req {
+       __le16          type;
+-      u8              sessname[NAME_MAX];
++      u8              pathname[NAME_MAX];
+       u8              reserved[15];
+ };
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c b/drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c
+index aedddc416003..309080184aac 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c
++++ b/drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c
+@@ -15,10 +15,10 @@
+ static void rtrs_srv_release(struct kobject *kobj)
+ {
+-      struct rtrs_srv_sess *sess;
++      struct rtrs_srv_path *srv_path;
+-      sess = container_of(kobj, struct rtrs_srv_sess, kobj);
+-      kfree(sess);
++      srv_path = container_of(kobj, struct rtrs_srv_path, kobj);
++      kfree(srv_path);
+ }
+ static struct kobj_type ktype = {
+@@ -36,24 +36,25 @@ static ssize_t rtrs_srv_disconnect_store(struct kobject *kobj,
+                                         struct kobj_attribute *attr,
+                                         const char *buf, size_t count)
+ {
+-      struct rtrs_srv_sess *sess;
++      struct rtrs_srv_path *srv_path;
+       struct rtrs_path *s;
+       char str[MAXHOSTNAMELEN];
+-      sess = container_of(kobj, struct rtrs_srv_sess, kobj);
+-      s = &sess->s;
++      srv_path = container_of(kobj, struct rtrs_srv_path, kobj);
++      s = &srv_path->s;
+       if (!sysfs_streq(buf, "1")) {
+               rtrs_err(s, "%s: invalid value: '%s'\n",
+                         attr->attr.name, buf);
+               return -EINVAL;
+       }
+-      sockaddr_to_str((struct sockaddr *)&sess->s.dst_addr, str, sizeof(str));
++      sockaddr_to_str((struct sockaddr *)&srv_path->s.dst_addr, str,
++                      sizeof(str));
+       rtrs_info(s, "disconnect for path %s requested\n", str);
+       /* first remove sysfs itself to avoid deadlock */
+-      sysfs_remove_file_self(&sess->kobj, &attr->attr);
+-      close_sess(sess);
++      sysfs_remove_file_self(&srv_path->kobj, &attr->attr);
++      close_path(srv_path);
+       return count;
+ }
+@@ -66,11 +67,11 @@ static ssize_t rtrs_srv_hca_port_show(struct kobject *kobj,
+                                      struct kobj_attribute *attr,
+                                      char *page)
+ {
+-      struct rtrs_srv_sess *sess;
++      struct rtrs_srv_path *srv_path;
+       struct rtrs_con *usr_con;
+-      sess = container_of(kobj, typeof(*sess), kobj);
+-      usr_con = sess->s.con[0];
++      srv_path = container_of(kobj, typeof(*srv_path), kobj);
++      usr_con = srv_path->s.con[0];
+       return sysfs_emit(page, "%u\n", usr_con->cm_id->port_num);
+ }
+@@ -82,11 +83,11 @@ static ssize_t rtrs_srv_hca_name_show(struct kobject *kobj,
+                                      struct kobj_attribute *attr,
+                                      char *page)
+ {
+-      struct rtrs_srv_sess *sess;
++      struct rtrs_srv_path *srv_path;
+-      sess = container_of(kobj, struct rtrs_srv_sess, kobj);
++      srv_path = container_of(kobj, struct rtrs_srv_path, kobj);
+-      return sysfs_emit(page, "%s\n", sess->s.dev->ib_dev->name);
++      return sysfs_emit(page, "%s\n", srv_path->s.dev->ib_dev->name);
+ }
+ static struct kobj_attribute rtrs_srv_hca_name_attr =
+@@ -96,11 +97,11 @@ static ssize_t rtrs_srv_src_addr_show(struct kobject *kobj,
+                                      struct kobj_attribute *attr,
+                                      char *page)
+ {
+-      struct rtrs_srv_sess *sess;
++      struct rtrs_srv_path *srv_path;
+       int cnt;
+-      sess = container_of(kobj, struct rtrs_srv_sess, kobj);
+-      cnt = sockaddr_to_str((struct sockaddr *)&sess->s.dst_addr,
++      srv_path = container_of(kobj, struct rtrs_srv_path, kobj);
++      cnt = sockaddr_to_str((struct sockaddr *)&srv_path->s.dst_addr,
+                             page, PAGE_SIZE);
+       return cnt + scnprintf(page + cnt, PAGE_SIZE - cnt, "\n");
+ }
+@@ -112,11 +113,11 @@ static ssize_t rtrs_srv_dst_addr_show(struct kobject *kobj,
+                                      struct kobj_attribute *attr,
+                                      char *page)
+ {
+-      struct rtrs_srv_sess *sess;
++      struct rtrs_srv_path *srv_path;
+       int len;
+-      sess = container_of(kobj, struct rtrs_srv_sess, kobj);
+-      len = sockaddr_to_str((struct sockaddr *)&sess->s.src_addr, page,
++      srv_path = container_of(kobj, struct rtrs_srv_path, kobj);
++      len = sockaddr_to_str((struct sockaddr *)&srv_path->s.src_addr, page,
+                             PAGE_SIZE);
+       len += sysfs_emit_at(page, len, "\n");
+       return len;
+@@ -125,7 +126,7 @@ static ssize_t rtrs_srv_dst_addr_show(struct kobject *kobj,
+ static struct kobj_attribute rtrs_srv_dst_addr_attr =
+       __ATTR(dst_addr, 0444, rtrs_srv_dst_addr_show, NULL);
+-static struct attribute *rtrs_srv_sess_attrs[] = {
++static struct attribute *rtrs_srv_path_attrs[] = {
+       &rtrs_srv_hca_name_attr.attr,
+       &rtrs_srv_hca_port_attr.attr,
+       &rtrs_srv_src_addr_attr.attr,
+@@ -134,8 +135,8 @@ static struct attribute *rtrs_srv_sess_attrs[] = {
+       NULL,
+ };
+-static const struct attribute_group rtrs_srv_sess_attr_group = {
+-      .attrs = rtrs_srv_sess_attrs,
++static const struct attribute_group rtrs_srv_path_attr_group = {
++      .attrs = rtrs_srv_path_attrs,
+ };
+ STAT_ATTR(struct rtrs_srv_stats, rdma,
+@@ -151,9 +152,9 @@ static const struct attribute_group rtrs_srv_stats_attr_group = {
+       .attrs = rtrs_srv_stats_attrs,
+ };
+-static int rtrs_srv_create_once_sysfs_root_folders(struct rtrs_srv_sess *sess)
++static int rtrs_srv_create_once_sysfs_root_folders(struct rtrs_srv_path *srv_path)
+ {
+-      struct rtrs_srv *srv = sess->srv;
++      struct rtrs_srv *srv = srv_path->srv;
+       int err = 0;
+       mutex_lock(&srv->paths_mutex);
+@@ -164,7 +165,7 @@ static int rtrs_srv_create_once_sysfs_root_folders(struct rtrs_srv_sess *sess)
+               goto unlock;
+       }
+       srv->dev.class = rtrs_dev_class;
+-      err = dev_set_name(&srv->dev, "%s", sess->s.sessname);
++      err = dev_set_name(&srv->dev, "%s", srv_path->s.sessname);
+       if (err)
+               goto unlock;
+@@ -196,9 +197,9 @@ static int rtrs_srv_create_once_sysfs_root_folders(struct rtrs_srv_sess *sess)
+ }
+ static void
+-rtrs_srv_destroy_once_sysfs_root_folders(struct rtrs_srv_sess *sess)
++rtrs_srv_destroy_once_sysfs_root_folders(struct rtrs_srv_path *srv_path)
+ {
+-      struct rtrs_srv *srv = sess->srv;
++      struct rtrs_srv *srv = srv_path->srv;
+       mutex_lock(&srv->paths_mutex);
+       if (!--srv->dev_ref) {
+@@ -213,7 +214,7 @@ rtrs_srv_destroy_once_sysfs_root_folders(struct rtrs_srv_sess *sess)
+       }
+ }
+-static void rtrs_srv_sess_stats_release(struct kobject *kobj)
++static void rtrs_srv_path_stats_release(struct kobject *kobj)
+ {
+       struct rtrs_srv_stats *stats;
+@@ -224,22 +225,22 @@ static void rtrs_srv_sess_stats_release(struct kobject *kobj)
+ static struct kobj_type ktype_stats = {
+       .sysfs_ops = &kobj_sysfs_ops,
+-      .release = rtrs_srv_sess_stats_release,
++      .release = rtrs_srv_path_stats_release,
+ };
+-static int rtrs_srv_create_stats_files(struct rtrs_srv_sess *sess)
++static int rtrs_srv_create_stats_files(struct rtrs_srv_path *srv_path)
+ {
+       int err;
+-      struct rtrs_path *s = &sess->s;
++      struct rtrs_path *s = &srv_path->s;
+-      err = kobject_init_and_add(&sess->stats->kobj_stats, &ktype_stats,
+-                                 &sess->kobj, "stats");
++      err = kobject_init_and_add(&srv_path->stats->kobj_stats, &ktype_stats,
++                                 &srv_path->kobj, "stats");
+       if (err) {
+               rtrs_err(s, "kobject_init_and_add(): %d\n", err);
+-              kobject_put(&sess->stats->kobj_stats);
++              kobject_put(&srv_path->stats->kobj_stats);
+               return err;
+       }
+-      err = sysfs_create_group(&sess->stats->kobj_stats,
++      err = sysfs_create_group(&srv_path->stats->kobj_stats,
+                                &rtrs_srv_stats_attr_group);
+       if (err) {
+               rtrs_err(s, "sysfs_create_group(): %d\n", err);
+@@ -249,64 +250,64 @@ static int rtrs_srv_create_stats_files(struct rtrs_srv_sess *sess)
+       return 0;
+ err:
+-      kobject_del(&sess->stats->kobj_stats);
+-      kobject_put(&sess->stats->kobj_stats);
++      kobject_del(&srv_path->stats->kobj_stats);
++      kobject_put(&srv_path->stats->kobj_stats);
+       return err;
+ }
+-int rtrs_srv_create_sess_files(struct rtrs_srv_sess *sess)
++int rtrs_srv_create_path_files(struct rtrs_srv_path *srv_path)
+ {
+-      struct rtrs_srv *srv = sess->srv;
+-      struct rtrs_path *s = &sess->s;
++      struct rtrs_srv *srv = srv_path->srv;
++      struct rtrs_path *s = &srv_path->s;
+       char str[NAME_MAX];
+       int err;
+       struct rtrs_addr path = {
+-              .src = &sess->s.dst_addr,
+-              .dst = &sess->s.src_addr,
++              .src = &srv_path->s.dst_addr,
++              .dst = &srv_path->s.src_addr,
+       };
+       rtrs_addr_to_str(&path, str, sizeof(str));
+-      err = rtrs_srv_create_once_sysfs_root_folders(sess);
++      err = rtrs_srv_create_once_sysfs_root_folders(srv_path);
+       if (err)
+               return err;
+-      err = kobject_init_and_add(&sess->kobj, &ktype, srv->kobj_paths,
++      err = kobject_init_and_add(&srv_path->kobj, &ktype, srv->kobj_paths,
+                                  "%s", str);
+       if (err) {
+               rtrs_err(s, "kobject_init_and_add(): %d\n", err);
+               goto destroy_root;
+       }
+-      err = sysfs_create_group(&sess->kobj, &rtrs_srv_sess_attr_group);
++      err = sysfs_create_group(&srv_path->kobj, &rtrs_srv_path_attr_group);
+       if (err) {
+               rtrs_err(s, "sysfs_create_group(): %d\n", err);
+               goto put_kobj;
+       }
+-      err = rtrs_srv_create_stats_files(sess);
++      err = rtrs_srv_create_stats_files(srv_path);
+       if (err)
+               goto remove_group;
+       return 0;
+ remove_group:
+-      sysfs_remove_group(&sess->kobj, &rtrs_srv_sess_attr_group);
++      sysfs_remove_group(&srv_path->kobj, &rtrs_srv_path_attr_group);
+ put_kobj:
+-      kobject_del(&sess->kobj);
++      kobject_del(&srv_path->kobj);
+ destroy_root:
+-      kobject_put(&sess->kobj);
+-      rtrs_srv_destroy_once_sysfs_root_folders(sess);
++      kobject_put(&srv_path->kobj);
++      rtrs_srv_destroy_once_sysfs_root_folders(srv_path);
+       return err;
+ }
+-void rtrs_srv_destroy_sess_files(struct rtrs_srv_sess *sess)
++void rtrs_srv_destroy_path_files(struct rtrs_srv_path *srv_path)
+ {
+-      if (sess->kobj.state_in_sysfs) {
+-              kobject_del(&sess->stats->kobj_stats);
+-              kobject_put(&sess->stats->kobj_stats);
+-              sysfs_remove_group(&sess->kobj, &rtrs_srv_sess_attr_group);
+-              kobject_put(&sess->kobj);
++      if (srv_path->kobj.state_in_sysfs) {
++              kobject_del(&srv_path->stats->kobj_stats);
++              kobject_put(&srv_path->stats->kobj_stats);
++              sysfs_remove_group(&srv_path->kobj, &rtrs_srv_path_attr_group);
++              kobject_put(&srv_path->kobj);
+-              rtrs_srv_destroy_once_sysfs_root_folders(sess);
++              rtrs_srv_destroy_once_sysfs_root_folders(srv_path);
+       }
+ }
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.c b/drivers/infiniband/ulp/rtrs/rtrs-srv.c
+index de4f214233b6..1ca31b919e98 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c
++++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c
+@@ -62,19 +62,19 @@ static inline struct rtrs_srv_con *to_srv_con(struct rtrs_con *c)
+       return container_of(c, struct rtrs_srv_con, c);
+ }
+-static inline struct rtrs_srv_sess *to_srv_sess(struct rtrs_path *s)
++static inline struct rtrs_srv_path *to_srv_path(struct rtrs_path *s)
+ {
+-      return container_of(s, struct rtrs_srv_sess, s);
++      return container_of(s, struct rtrs_srv_path, s);
+ }
+-static bool rtrs_srv_change_state(struct rtrs_srv_sess *sess,
++static bool rtrs_srv_change_state(struct rtrs_srv_path *srv_path,
+                                 enum rtrs_srv_state new_state)
+ {
+       enum rtrs_srv_state old_state;
+       bool changed = false;
+-      spin_lock_irq(&sess->state_lock);
+-      old_state = sess->state;
++      spin_lock_irq(&srv_path->state_lock);
++      old_state = srv_path->state;
+       switch (new_state) {
+       case RTRS_SRV_CONNECTED:
+               if (old_state == RTRS_SRV_CONNECTING)
+@@ -93,8 +93,8 @@ static bool rtrs_srv_change_state(struct rtrs_srv_sess *sess,
+               break;
+       }
+       if (changed)
+-              sess->state = new_state;
+-      spin_unlock_irq(&sess->state_lock);
++              srv_path->state = new_state;
++      spin_unlock_irq(&srv_path->state_lock);
+       return changed;
+ }
+@@ -106,16 +106,16 @@ static void free_id(struct rtrs_srv_op *id)
+       kfree(id);
+ }
+-static void rtrs_srv_free_ops_ids(struct rtrs_srv_sess *sess)
++static void rtrs_srv_free_ops_ids(struct rtrs_srv_path *srv_path)
+ {
+-      struct rtrs_srv *srv = sess->srv;
++      struct rtrs_srv *srv = srv_path->srv;
+       int i;
+-      if (sess->ops_ids) {
++      if (srv_path->ops_ids) {
+               for (i = 0; i < srv->queue_depth; i++)
+-                      free_id(sess->ops_ids[i]);
+-              kfree(sess->ops_ids);
+-              sess->ops_ids = NULL;
++                      free_id(srv_path->ops_ids[i]);
++              kfree(srv_path->ops_ids);
++              srv_path->ops_ids = NULL;
+       }
+ }
+@@ -127,21 +127,24 @@ static struct ib_cqe io_comp_cqe = {
+ static inline void rtrs_srv_inflight_ref_release(struct percpu_ref *ref)
+ {
+-      struct rtrs_srv_sess *sess = container_of(ref, struct rtrs_srv_sess, ids_inflight_ref);
++      struct rtrs_srv_path *srv_path = container_of(ref,
++                                                    struct rtrs_srv_path,
++                                                    ids_inflight_ref);
+-      percpu_ref_exit(&sess->ids_inflight_ref);
+-      complete(&sess->complete_done);
++      percpu_ref_exit(&srv_path->ids_inflight_ref);
++      complete(&srv_path->complete_done);
+ }
+-static int rtrs_srv_alloc_ops_ids(struct rtrs_srv_sess *sess)
++static int rtrs_srv_alloc_ops_ids(struct rtrs_srv_path *srv_path)
+ {
+-      struct rtrs_srv *srv = sess->srv;
++      struct rtrs_srv *srv = srv_path->srv;
+       struct rtrs_srv_op *id;
+       int i, ret;
+-      sess->ops_ids = kcalloc(srv->queue_depth, sizeof(*sess->ops_ids),
+-                              GFP_KERNEL);
+-      if (!sess->ops_ids)
++      srv_path->ops_ids = kcalloc(srv->queue_depth,
++                                  sizeof(*srv_path->ops_ids),
++                                  GFP_KERNEL);
++      if (!srv_path->ops_ids)
+               goto err;
+       for (i = 0; i < srv->queue_depth; ++i) {
+@@ -149,44 +152,44 @@ static int rtrs_srv_alloc_ops_ids(struct rtrs_srv_sess *sess)
+               if (!id)
+                       goto err;
+-              sess->ops_ids[i] = id;
++              srv_path->ops_ids[i] = id;
+       }
+-      ret = percpu_ref_init(&sess->ids_inflight_ref,
++      ret = percpu_ref_init(&srv_path->ids_inflight_ref,
+                             rtrs_srv_inflight_ref_release, 0, GFP_KERNEL);
+       if (ret) {
+               pr_err("Percpu reference init failed\n");
+               goto err;
+       }
+-      init_completion(&sess->complete_done);
++      init_completion(&srv_path->complete_done);
+       return 0;
+ err:
+-      rtrs_srv_free_ops_ids(sess);
++      rtrs_srv_free_ops_ids(srv_path);
+       return -ENOMEM;
+ }
+-static inline void rtrs_srv_get_ops_ids(struct rtrs_srv_sess *sess)
++static inline void rtrs_srv_get_ops_ids(struct rtrs_srv_path *srv_path)
+ {
+-      percpu_ref_get(&sess->ids_inflight_ref);
++      percpu_ref_get(&srv_path->ids_inflight_ref);
+ }
+-static inline void rtrs_srv_put_ops_ids(struct rtrs_srv_sess *sess)
++static inline void rtrs_srv_put_ops_ids(struct rtrs_srv_path *srv_path)
+ {
+-      percpu_ref_put(&sess->ids_inflight_ref);
++      percpu_ref_put(&srv_path->ids_inflight_ref);
+ }
+ static void rtrs_srv_reg_mr_done(struct ib_cq *cq, struct ib_wc *wc)
+ {
+       struct rtrs_srv_con *con = to_srv_con(wc->qp->qp_context);
+       struct rtrs_path *s = con->c.path;
+-      struct rtrs_srv_sess *sess = to_srv_sess(s);
++      struct rtrs_srv_path *srv_path = to_srv_path(s);
+       if (wc->status != IB_WC_SUCCESS) {
+               rtrs_err(s, "REG MR failed: %s\n",
+                         ib_wc_status_msg(wc->status));
+-              close_sess(sess);
++              close_path(srv_path);
+               return;
+       }
+ }
+@@ -198,8 +201,8 @@ static struct ib_cqe local_reg_cqe = {
+ static int rdma_write_sg(struct rtrs_srv_op *id)
+ {
+       struct rtrs_path *s = id->con->c.path;
+-      struct rtrs_srv_sess *sess = to_srv_sess(s);
+-      dma_addr_t dma_addr = sess->dma_addr[id->msg_id];
++      struct rtrs_srv_path *srv_path = to_srv_path(s);
++      dma_addr_t dma_addr = srv_path->dma_addr[id->msg_id];
+       struct rtrs_srv_mr *srv_mr;
+       struct ib_send_wr inv_wr;
+       struct ib_rdma_wr imm_wr;
+@@ -233,7 +236,7 @@ static int rdma_write_sg(struct rtrs_srv_op *id)
+               return -EINVAL;
+       }
+-      plist->lkey = sess->s.dev->ib_pd->local_dma_lkey;
++      plist->lkey = srv_path->s.dev->ib_pd->local_dma_lkey;
+       offset += plist->length;
+       wr->wr.sg_list  = plist;
+@@ -284,7 +287,7 @@ static int rdma_write_sg(struct rtrs_srv_op *id)
+       if (always_invalidate) {
+               struct rtrs_msg_rkey_rsp *msg;
+-              srv_mr = &sess->mrs[id->msg_id];
++              srv_mr = &srv_path->mrs[id->msg_id];
+               rwr.wr.opcode = IB_WR_REG_MR;
+               rwr.wr.wr_cqe = &local_reg_cqe;
+               rwr.wr.num_sge = 0;
+@@ -300,11 +303,11 @@ static int rdma_write_sg(struct rtrs_srv_op *id)
+               list.addr   = srv_mr->iu->dma_addr;
+               list.length = sizeof(*msg);
+-              list.lkey   = sess->s.dev->ib_pd->local_dma_lkey;
++              list.lkey   = srv_path->s.dev->ib_pd->local_dma_lkey;
+               imm_wr.wr.sg_list = &list;
+               imm_wr.wr.num_sge = 1;
+               imm_wr.wr.opcode = IB_WR_SEND_WITH_IMM;
+-              ib_dma_sync_single_for_device(sess->s.dev->ib_dev,
++              ib_dma_sync_single_for_device(srv_path->s.dev->ib_dev,
+                                             srv_mr->iu->dma_addr,
+                                             srv_mr->iu->size, DMA_TO_DEVICE);
+       } else {
+@@ -317,7 +320,7 @@ static int rdma_write_sg(struct rtrs_srv_op *id)
+                                                            0, need_inval));
+       imm_wr.wr.wr_cqe   = &io_comp_cqe;
+-      ib_dma_sync_single_for_device(sess->s.dev->ib_dev, dma_addr,
++      ib_dma_sync_single_for_device(srv_path->s.dev->ib_dev, dma_addr,
+                                     offset, DMA_BIDIRECTIONAL);
+       err = ib_post_send(id->con->c.qp, &id->tx_wr.wr, NULL);
+@@ -342,7 +345,7 @@ static int send_io_resp_imm(struct rtrs_srv_con *con, struct rtrs_srv_op *id,
+                           int errno)
+ {
+       struct rtrs_path *s = con->c.path;
+-      struct rtrs_srv_sess *sess = to_srv_sess(s);
++      struct rtrs_srv_path *srv_path = to_srv_path(s);
+       struct ib_send_wr inv_wr, *wr = NULL;
+       struct ib_rdma_wr imm_wr;
+       struct ib_reg_wr rwr;
+@@ -402,7 +405,7 @@ static int send_io_resp_imm(struct rtrs_srv_con *con, struct rtrs_srv_op *id,
+               struct ib_sge list;
+               struct rtrs_msg_rkey_rsp *msg;
+-              srv_mr = &sess->mrs[id->msg_id];
++              srv_mr = &srv_path->mrs[id->msg_id];
+               rwr.wr.next = &imm_wr.wr;
+               rwr.wr.opcode = IB_WR_REG_MR;
+               rwr.wr.wr_cqe = &local_reg_cqe;
+@@ -419,11 +422,11 @@ static int send_io_resp_imm(struct rtrs_srv_con *con, struct rtrs_srv_op *id,
+               list.addr   = srv_mr->iu->dma_addr;
+               list.length = sizeof(*msg);
+-              list.lkey   = sess->s.dev->ib_pd->local_dma_lkey;
++              list.lkey   = srv_path->s.dev->ib_pd->local_dma_lkey;
+               imm_wr.wr.sg_list = &list;
+               imm_wr.wr.num_sge = 1;
+               imm_wr.wr.opcode = IB_WR_SEND_WITH_IMM;
+-              ib_dma_sync_single_for_device(sess->s.dev->ib_dev,
++              ib_dma_sync_single_for_device(srv_path->s.dev->ib_dev,
+                                             srv_mr->iu->dma_addr,
+                                             srv_mr->iu->size, DMA_TO_DEVICE);
+       } else {
+@@ -444,11 +447,11 @@ static int send_io_resp_imm(struct rtrs_srv_con *con, struct rtrs_srv_op *id,
+       return err;
+ }
+-void close_sess(struct rtrs_srv_sess *sess)
++void close_path(struct rtrs_srv_path *srv_path)
+ {
+-      if (rtrs_srv_change_state(sess, RTRS_SRV_CLOSING))
+-              queue_work(rtrs_wq, &sess->close_work);
+-      WARN_ON(sess->state != RTRS_SRV_CLOSING);
++      if (rtrs_srv_change_state(srv_path, RTRS_SRV_CLOSING))
++              queue_work(rtrs_wq, &srv_path->close_work);
++      WARN_ON(srv_path->state != RTRS_SRV_CLOSING);
+ }
+ static inline const char *rtrs_srv_state_str(enum rtrs_srv_state state)
+@@ -480,7 +483,7 @@ static inline const char *rtrs_srv_state_str(enum rtrs_srv_state state)
+  */
+ bool rtrs_srv_resp_rdma(struct rtrs_srv_op *id, int status)
+ {
+-      struct rtrs_srv_sess *sess;
++      struct rtrs_srv_path *srv_path;
+       struct rtrs_srv_con *con;
+       struct rtrs_path *s;
+       int err;
+@@ -490,25 +493,25 @@ bool rtrs_srv_resp_rdma(struct rtrs_srv_op *id, int status)
+       con = id->con;
+       s = con->c.path;
+-      sess = to_srv_sess(s);
++      srv_path = to_srv_path(s);
+       id->status = status;
+-      if (sess->state != RTRS_SRV_CONNECTED) {
++      if (srv_path->state != RTRS_SRV_CONNECTED) {
+               rtrs_err_rl(s,
+-                          "Sending I/O response failed,  session %s is disconnected, sess state %s\n",
+-                          kobject_name(&sess->kobj),
+-                          rtrs_srv_state_str(sess->state));
++                          "Sending I/O response failed,  server path %s is disconnected, path state %s\n",
++                          kobject_name(&srv_path->kobj),
++                          rtrs_srv_state_str(srv_path->state));
+               goto out;
+       }
+       if (always_invalidate) {
+-              struct rtrs_srv_mr *mr = &sess->mrs[id->msg_id];
++              struct rtrs_srv_mr *mr = &srv_path->mrs[id->msg_id];
+               ib_update_fast_reg_key(mr->mr, ib_inc_rkey(mr->mr->rkey));
+       }
+       if (atomic_sub_return(1, &con->c.sq_wr_avail) < 0) {
+-              rtrs_err(s, "IB send queue full: sess=%s cid=%d\n",
+-                       kobject_name(&sess->kobj),
++              rtrs_err(s, "IB send queue full: srv_path=%s cid=%d\n",
++                       kobject_name(&srv_path->kobj),
+                        con->c.cid);
+               atomic_add(1, &con->c.sq_wr_avail);
+               spin_lock(&con->rsp_wr_wait_lock);
+@@ -523,12 +526,12 @@ bool rtrs_srv_resp_rdma(struct rtrs_srv_op *id, int status)
+               err = rdma_write_sg(id);
+       if (err) {
+-              rtrs_err_rl(s, "IO response failed: %d: sess=%s\n", err,
+-                          kobject_name(&sess->kobj));
+-              close_sess(sess);
++              rtrs_err_rl(s, "IO response failed: %d: srv_path=%s\n", err,
++                          kobject_name(&srv_path->kobj));
++              close_path(srv_path);
+       }
+ out:
+-      rtrs_srv_put_ops_ids(sess);
++      rtrs_srv_put_ops_ids(srv_path);
+       return true;
+ }
+ EXPORT_SYMBOL(rtrs_srv_resp_rdma);
+@@ -544,27 +547,27 @@ void rtrs_srv_set_sess_priv(struct rtrs_srv *srv, void *priv)
+ }
+ EXPORT_SYMBOL(rtrs_srv_set_sess_priv);
+-static void unmap_cont_bufs(struct rtrs_srv_sess *sess)
++static void unmap_cont_bufs(struct rtrs_srv_path *srv_path)
+ {
+       int i;
+-      for (i = 0; i < sess->mrs_num; i++) {
++      for (i = 0; i < srv_path->mrs_num; i++) {
+               struct rtrs_srv_mr *srv_mr;
+-              srv_mr = &sess->mrs[i];
+-              rtrs_iu_free(srv_mr->iu, sess->s.dev->ib_dev, 1);
++              srv_mr = &srv_path->mrs[i];
++              rtrs_iu_free(srv_mr->iu, srv_path->s.dev->ib_dev, 1);
+               ib_dereg_mr(srv_mr->mr);
+-              ib_dma_unmap_sg(sess->s.dev->ib_dev, srv_mr->sgt.sgl,
++              ib_dma_unmap_sg(srv_path->s.dev->ib_dev, srv_mr->sgt.sgl,
+                               srv_mr->sgt.nents, DMA_BIDIRECTIONAL);
+               sg_free_table(&srv_mr->sgt);
+       }
+-      kfree(sess->mrs);
++      kfree(srv_path->mrs);
+ }
+-static int map_cont_bufs(struct rtrs_srv_sess *sess)
++static int map_cont_bufs(struct rtrs_srv_path *srv_path)
+ {
+-      struct rtrs_srv *srv = sess->srv;
+-      struct rtrs_path *ss = &sess->s;
++      struct rtrs_srv *srv = srv_path->srv;
++      struct rtrs_path *ss = &srv_path->s;
+       int i, mri, err, mrs_num;
+       unsigned int chunk_bits;
+       int chunks_per_mr = 1;
+@@ -581,19 +584,19 @@ static int map_cont_bufs(struct rtrs_srv_sess *sess)
+               mrs_num = srv->queue_depth;
+       } else {
+               chunks_per_mr =
+-                      sess->s.dev->ib_dev->attrs.max_fast_reg_page_list_len;
++                      srv_path->s.dev->ib_dev->attrs.max_fast_reg_page_list_len;
+               mrs_num = DIV_ROUND_UP(srv->queue_depth, chunks_per_mr);
+               chunks_per_mr = DIV_ROUND_UP(srv->queue_depth, mrs_num);
+       }
+-      sess->mrs = kcalloc(mrs_num, sizeof(*sess->mrs), GFP_KERNEL);
+-      if (!sess->mrs)
++      srv_path->mrs = kcalloc(mrs_num, sizeof(*srv_path->mrs), GFP_KERNEL);
++      if (!srv_path->mrs)
+               return -ENOMEM;
+-      sess->mrs_num = mrs_num;
++      srv_path->mrs_num = mrs_num;
+       for (mri = 0; mri < mrs_num; mri++) {
+-              struct rtrs_srv_mr *srv_mr = &sess->mrs[mri];
++              struct rtrs_srv_mr *srv_mr = &srv_path->mrs[mri];
+               struct sg_table *sgt = &srv_mr->sgt;
+               struct scatterlist *s;
+               struct ib_mr *mr;
+@@ -612,13 +615,13 @@ static int map_cont_bufs(struct rtrs_srv_sess *sess)
+                       sg_set_page(s, srv->chunks[chunks + i],
+                                   max_chunk_size, 0);
+-              nr = ib_dma_map_sg(sess->s.dev->ib_dev, sgt->sgl,
++              nr = ib_dma_map_sg(srv_path->s.dev->ib_dev, sgt->sgl,
+                                  sgt->nents, DMA_BIDIRECTIONAL);
+               if (nr < sgt->nents) {
+                       err = nr < 0 ? nr : -EINVAL;
+                       goto free_sg;
+               }
+-              mr = ib_alloc_mr(sess->s.dev->ib_pd, IB_MR_TYPE_MEM_REG,
++              mr = ib_alloc_mr(srv_path->s.dev->ib_pd, IB_MR_TYPE_MEM_REG,
+                                sgt->nents);
+               if (IS_ERR(mr)) {
+                       err = PTR_ERR(mr);
+@@ -634,7 +637,7 @@ static int map_cont_bufs(struct rtrs_srv_sess *sess)
+               if (always_invalidate) {
+                       srv_mr->iu = rtrs_iu_alloc(1,
+                                       sizeof(struct rtrs_msg_rkey_rsp),
+-                                      GFP_KERNEL, sess->s.dev->ib_dev,
++                                      GFP_KERNEL, srv_path->s.dev->ib_dev,
+                                       DMA_TO_DEVICE, rtrs_srv_rdma_done);
+                       if (!srv_mr->iu) {
+                               err = -ENOMEM;
+@@ -644,7 +647,7 @@ static int map_cont_bufs(struct rtrs_srv_sess *sess)
+               }
+               /* Eventually dma addr for each chunk can be cached */
+               for_each_sg(sgt->sgl, s, sgt->orig_nents, i)
+-                      sess->dma_addr[chunks + i] = sg_dma_address(s);
++                      srv_path->dma_addr[chunks + i] = sg_dma_address(s);
+               ib_update_fast_reg_key(mr, ib_inc_rkey(mr->rkey));
+               srv_mr->mr = mr;
+@@ -652,75 +655,75 @@ static int map_cont_bufs(struct rtrs_srv_sess *sess)
+               continue;
+ err:
+               while (mri--) {
+-                      srv_mr = &sess->mrs[mri];
++                      srv_mr = &srv_path->mrs[mri];
+                       sgt = &srv_mr->sgt;
+                       mr = srv_mr->mr;
+-                      rtrs_iu_free(srv_mr->iu, sess->s.dev->ib_dev, 1);
++                      rtrs_iu_free(srv_mr->iu, srv_path->s.dev->ib_dev, 1);
+ dereg_mr:
+                       ib_dereg_mr(mr);
+ unmap_sg:
+-                      ib_dma_unmap_sg(sess->s.dev->ib_dev, sgt->sgl,
++                      ib_dma_unmap_sg(srv_path->s.dev->ib_dev, sgt->sgl,
+                                       sgt->nents, DMA_BIDIRECTIONAL);
+ free_sg:
+                       sg_free_table(sgt);
+               }
+-              kfree(sess->mrs);
++              kfree(srv_path->mrs);
+               return err;
+       }
+       chunk_bits = ilog2(srv->queue_depth - 1) + 1;
+-      sess->mem_bits = (MAX_IMM_PAYL_BITS - chunk_bits);
++      srv_path->mem_bits = (MAX_IMM_PAYL_BITS - chunk_bits);
+       return 0;
+ }
+ static void rtrs_srv_hb_err_handler(struct rtrs_con *c)
+ {
+-      close_sess(to_srv_sess(c->path));
++      close_path(to_srv_path(c->path));
+ }
+-static void rtrs_srv_init_hb(struct rtrs_srv_sess *sess)
++static void rtrs_srv_init_hb(struct rtrs_srv_path *srv_path)
+ {
+-      rtrs_init_hb(&sess->s, &io_comp_cqe,
++      rtrs_init_hb(&srv_path->s, &io_comp_cqe,
+                     RTRS_HB_INTERVAL_MS,
+                     RTRS_HB_MISSED_MAX,
+                     rtrs_srv_hb_err_handler,
+                     rtrs_wq);
+ }
+-static void rtrs_srv_start_hb(struct rtrs_srv_sess *sess)
++static void rtrs_srv_start_hb(struct rtrs_srv_path *srv_path)
+ {
+-      rtrs_start_hb(&sess->s);
++      rtrs_start_hb(&srv_path->s);
+ }
+-static void rtrs_srv_stop_hb(struct rtrs_srv_sess *sess)
++static void rtrs_srv_stop_hb(struct rtrs_srv_path *srv_path)
+ {
+-      rtrs_stop_hb(&sess->s);
++      rtrs_stop_hb(&srv_path->s);
+ }
+ static void rtrs_srv_info_rsp_done(struct ib_cq *cq, struct ib_wc *wc)
+ {
+       struct rtrs_srv_con *con = to_srv_con(wc->qp->qp_context);
+       struct rtrs_path *s = con->c.path;
+-      struct rtrs_srv_sess *sess = to_srv_sess(s);
++      struct rtrs_srv_path *srv_path = to_srv_path(s);
+       struct rtrs_iu *iu;
+       iu = container_of(wc->wr_cqe, struct rtrs_iu, cqe);
+-      rtrs_iu_free(iu, sess->s.dev->ib_dev, 1);
++      rtrs_iu_free(iu, srv_path->s.dev->ib_dev, 1);
+       if (wc->status != IB_WC_SUCCESS) {
+               rtrs_err(s, "Sess info response send failed: %s\n",
+                         ib_wc_status_msg(wc->status));
+-              close_sess(sess);
++              close_path(srv_path);
+               return;
+       }
+       WARN_ON(wc->opcode != IB_WC_SEND);
+ }
+-static void rtrs_srv_sess_up(struct rtrs_srv_sess *sess)
++static void rtrs_srv_path_up(struct rtrs_srv_path *srv_path)
+ {
+-      struct rtrs_srv *srv = sess->srv;
++      struct rtrs_srv *srv = srv_path->srv;
+       struct rtrs_srv_ctx *ctx = srv->ctx;
+       int up;
+@@ -731,18 +734,18 @@ static void rtrs_srv_sess_up(struct rtrs_srv_sess *sess)
+       mutex_unlock(&srv->paths_ev_mutex);
+       /* Mark session as established */
+-      sess->established = true;
++      srv_path->established = true;
+ }
+-static void rtrs_srv_sess_down(struct rtrs_srv_sess *sess)
++static void rtrs_srv_path_down(struct rtrs_srv_path *srv_path)
+ {
+-      struct rtrs_srv *srv = sess->srv;
++      struct rtrs_srv *srv = srv_path->srv;
+       struct rtrs_srv_ctx *ctx = srv->ctx;
+-      if (!sess->established)
++      if (!srv_path->established)
+               return;
+-      sess->established = false;
++      srv_path->established = false;
+       mutex_lock(&srv->paths_ev_mutex);
+       WARN_ON(!srv->paths_up);
+       if (--srv->paths_up == 0)
+@@ -750,11 +753,11 @@ static void rtrs_srv_sess_down(struct rtrs_srv_sess *sess)
+       mutex_unlock(&srv->paths_ev_mutex);
+ }
+-static bool exist_sessname(struct rtrs_srv_ctx *ctx,
+-                         const char *sessname, const uuid_t *path_uuid)
++static bool exist_pathname(struct rtrs_srv_ctx *ctx,
++                         const char *pathname, const uuid_t *path_uuid)
+ {
+       struct rtrs_srv *srv;
+-      struct rtrs_srv_sess *sess;
++      struct rtrs_srv_path *srv_path;
+       bool found = false;
+       mutex_lock(&ctx->srv_mutex);
+@@ -767,9 +770,9 @@ static bool exist_sessname(struct rtrs_srv_ctx *ctx,
+                       continue;
+               }
+-              list_for_each_entry(sess, &srv->paths_list, s.entry) {
+-                      if (strlen(sess->s.sessname) == strlen(sessname) &&
+-                          !strcmp(sess->s.sessname, sessname)) {
++              list_for_each_entry(srv_path, &srv->paths_list, s.entry) {
++                      if (strlen(srv_path->s.sessname) == strlen(pathname) &&
++                          !strcmp(srv_path->s.sessname, pathname)) {
+                               found = true;
+                               break;
+                       }
+@@ -782,14 +785,14 @@ static bool exist_sessname(struct rtrs_srv_ctx *ctx,
+       return found;
+ }
+-static int post_recv_sess(struct rtrs_srv_sess *sess);
++static int post_recv_path(struct rtrs_srv_path *srv_path);
+ static int rtrs_rdma_do_reject(struct rdma_cm_id *cm_id, int errno);
+ static int process_info_req(struct rtrs_srv_con *con,
+                           struct rtrs_msg_info_req *msg)
+ {
+       struct rtrs_path *s = con->c.path;
+-      struct rtrs_srv_sess *sess = to_srv_sess(s);
++      struct rtrs_srv_path *srv_path = to_srv_path(s);
+       struct ib_send_wr *reg_wr = NULL;
+       struct rtrs_msg_info_rsp *rsp;
+       struct rtrs_iu *tx_iu;
+@@ -797,31 +800,32 @@ static int process_info_req(struct rtrs_srv_con *con,
+       int mri, err;
+       size_t tx_sz;
+-      err = post_recv_sess(sess);
++      err = post_recv_path(srv_path);
+       if (err) {
+-              rtrs_err(s, "post_recv_sess(), err: %d\n", err);
++              rtrs_err(s, "post_recv_path(), err: %d\n", err);
+               return err;
+       }
+-      if (strchr(msg->sessname, '/') || strchr(msg->sessname, '.')) {
+-              rtrs_err(s, "sessname cannot contain / and .\n");
++      if (strchr(msg->pathname, '/') || strchr(msg->pathname, '.')) {
++              rtrs_err(s, "pathname cannot contain / and .\n");
+               return -EINVAL;
+       }
+-      if (exist_sessname(sess->srv->ctx,
+-                         msg->sessname, &sess->srv->paths_uuid)) {
+-              rtrs_err(s, "sessname is duplicated: %s\n", msg->sessname);
++      if (exist_pathname(srv_path->srv->ctx,
++                         msg->pathname, &srv_path->srv->paths_uuid)) {
++              rtrs_err(s, "pathname is duplicated: %s\n", msg->pathname);
+               return -EPERM;
+       }
+-      strscpy(sess->s.sessname, msg->sessname, sizeof(sess->s.sessname));
++      strscpy(srv_path->s.sessname, msg->pathname,
++              sizeof(srv_path->s.sessname));
+-      rwr = kcalloc(sess->mrs_num, sizeof(*rwr), GFP_KERNEL);
++      rwr = kcalloc(srv_path->mrs_num, sizeof(*rwr), GFP_KERNEL);
+       if (!rwr)
+               return -ENOMEM;
+       tx_sz  = sizeof(*rsp);
+-      tx_sz += sizeof(rsp->desc[0]) * sess->mrs_num;
+-      tx_iu = rtrs_iu_alloc(1, tx_sz, GFP_KERNEL, sess->s.dev->ib_dev,
++      tx_sz += sizeof(rsp->desc[0]) * srv_path->mrs_num;
++      tx_iu = rtrs_iu_alloc(1, tx_sz, GFP_KERNEL, srv_path->s.dev->ib_dev,
+                              DMA_TO_DEVICE, rtrs_srv_info_rsp_done);
+       if (!tx_iu) {
+               err = -ENOMEM;
+@@ -830,10 +834,10 @@ static int process_info_req(struct rtrs_srv_con *con,
+       rsp = tx_iu->buf;
+       rsp->type = cpu_to_le16(RTRS_MSG_INFO_RSP);
+-      rsp->sg_cnt = cpu_to_le16(sess->mrs_num);
++      rsp->sg_cnt = cpu_to_le16(srv_path->mrs_num);
+-      for (mri = 0; mri < sess->mrs_num; mri++) {
+-              struct ib_mr *mr = sess->mrs[mri].mr;
++      for (mri = 0; mri < srv_path->mrs_num; mri++) {
++              struct ib_mr *mr = srv_path->mrs[mri].mr;
+               rsp->desc[mri].addr = cpu_to_le64(mr->iova);
+               rsp->desc[mri].key  = cpu_to_le32(mr->rkey);
+@@ -854,13 +858,13 @@ static int process_info_req(struct rtrs_srv_con *con,
+               reg_wr = &rwr[mri].wr;
+       }
+-      err = rtrs_srv_create_sess_files(sess);
++      err = rtrs_srv_create_path_files(srv_path);
+       if (err)
+               goto iu_free;
+-      kobject_get(&sess->kobj);
+-      get_device(&sess->srv->dev);
+-      rtrs_srv_change_state(sess, RTRS_SRV_CONNECTED);
+-      rtrs_srv_start_hb(sess);
++      kobject_get(&srv_path->kobj);
++      get_device(&srv_path->srv->dev);
++      rtrs_srv_change_state(srv_path, RTRS_SRV_CONNECTED);
++      rtrs_srv_start_hb(srv_path);
+       /*
+        * We do not account number of established connections at the current
+@@ -868,9 +872,10 @@ static int process_info_req(struct rtrs_srv_con *con,
+        * all connections are successfully established.  Thus, simply notify
+        * listener with a proper event if we are the first path.
+        */
+-      rtrs_srv_sess_up(sess);
++      rtrs_srv_path_up(srv_path);
+-      ib_dma_sync_single_for_device(sess->s.dev->ib_dev, tx_iu->dma_addr,
++      ib_dma_sync_single_for_device(srv_path->s.dev->ib_dev,
++                                    tx_iu->dma_addr,
+                                     tx_iu->size, DMA_TO_DEVICE);
+       /* Send info response */
+@@ -878,7 +883,7 @@ static int process_info_req(struct rtrs_srv_con *con,
+       if (err) {
+               rtrs_err(s, "rtrs_iu_post_send(), err: %d\n", err);
+ iu_free:
+-              rtrs_iu_free(tx_iu, sess->s.dev->ib_dev, 1);
++              rtrs_iu_free(tx_iu, srv_path->s.dev->ib_dev, 1);
+       }
+ rwr_free:
+       kfree(rwr);
+@@ -890,7 +895,7 @@ static void rtrs_srv_info_req_done(struct ib_cq *cq, struct ib_wc *wc)
+ {
+       struct rtrs_srv_con *con = to_srv_con(wc->qp->qp_context);
+       struct rtrs_path *s = con->c.path;
+-      struct rtrs_srv_sess *sess = to_srv_sess(s);
++      struct rtrs_srv_path *srv_path = to_srv_path(s);
+       struct rtrs_msg_info_req *msg;
+       struct rtrs_iu *iu;
+       int err;
+@@ -910,7 +915,7 @@ static void rtrs_srv_info_req_done(struct ib_cq *cq, struct ib_wc *wc)
+                         wc->byte_len);
+               goto close;
+       }
+-      ib_dma_sync_single_for_cpu(sess->s.dev->ib_dev, iu->dma_addr,
++      ib_dma_sync_single_for_cpu(srv_path->s.dev->ib_dev, iu->dma_addr,
+                                  iu->size, DMA_FROM_DEVICE);
+       msg = iu->buf;
+       if (le16_to_cpu(msg->type) != RTRS_MSG_INFO_REQ) {
+@@ -923,22 +928,22 @@ static void rtrs_srv_info_req_done(struct ib_cq *cq, struct ib_wc *wc)
+               goto close;
+ out:
+-      rtrs_iu_free(iu, sess->s.dev->ib_dev, 1);
++      rtrs_iu_free(iu, srv_path->s.dev->ib_dev, 1);
+       return;
+ close:
+-      close_sess(sess);
++      close_path(srv_path);
+       goto out;
+ }
+ static int post_recv_info_req(struct rtrs_srv_con *con)
+ {
+       struct rtrs_path *s = con->c.path;
+-      struct rtrs_srv_sess *sess = to_srv_sess(s);
++      struct rtrs_srv_path *srv_path = to_srv_path(s);
+       struct rtrs_iu *rx_iu;
+       int err;
+       rx_iu = rtrs_iu_alloc(1, sizeof(struct rtrs_msg_info_req),
+-                             GFP_KERNEL, sess->s.dev->ib_dev,
++                             GFP_KERNEL, srv_path->s.dev->ib_dev,
+                              DMA_FROM_DEVICE, rtrs_srv_info_req_done);
+       if (!rx_iu)
+               return -ENOMEM;
+@@ -946,7 +951,7 @@ static int post_recv_info_req(struct rtrs_srv_con *con)
+       err = rtrs_iu_post_recv(&con->c, rx_iu);
+       if (err) {
+               rtrs_err(s, "rtrs_iu_post_recv(), err: %d\n", err);
+-              rtrs_iu_free(rx_iu, sess->s.dev->ib_dev, 1);
++              rtrs_iu_free(rx_iu, srv_path->s.dev->ib_dev, 1);
+               return err;
+       }
+@@ -966,20 +971,20 @@ static int post_recv_io(struct rtrs_srv_con *con, size_t q_size)
+       return 0;
+ }
+-static int post_recv_sess(struct rtrs_srv_sess *sess)
++static int post_recv_path(struct rtrs_srv_path *srv_path)
+ {
+-      struct rtrs_srv *srv = sess->srv;
+-      struct rtrs_path *s = &sess->s;
++      struct rtrs_srv *srv = srv_path->srv;
++      struct rtrs_path *s = &srv_path->s;
+       size_t q_size;
+       int err, cid;
+-      for (cid = 0; cid < sess->s.con_num; cid++) {
++      for (cid = 0; cid < srv_path->s.con_num; cid++) {
+               if (cid == 0)
+                       q_size = SERVICE_CON_QUEUE_DEPTH;
+               else
+                       q_size = srv->queue_depth;
+-              err = post_recv_io(to_srv_con(sess->s.con[cid]), q_size);
++              err = post_recv_io(to_srv_con(srv_path->s.con[cid]), q_size);
+               if (err) {
+                       rtrs_err(s, "post_recv_io(), err: %d\n", err);
+                       return err;
+@@ -994,8 +999,8 @@ static void process_read(struct rtrs_srv_con *con,
+                        u32 buf_id, u32 off)
+ {
+       struct rtrs_path *s = con->c.path;
+-      struct rtrs_srv_sess *sess = to_srv_sess(s);
+-      struct rtrs_srv *srv = sess->srv;
++      struct rtrs_srv_path *srv_path = to_srv_path(s);
++      struct rtrs_srv *srv = srv_path->srv;
+       struct rtrs_srv_ctx *ctx = srv->ctx;
+       struct rtrs_srv_op *id;
+@@ -1003,10 +1008,10 @@ static void process_read(struct rtrs_srv_con *con,
+       void *data;
+       int ret;
+-      if (sess->state != RTRS_SRV_CONNECTED) {
++      if (srv_path->state != RTRS_SRV_CONNECTED) {
+               rtrs_err_rl(s,
+                            "Processing read request failed,  session is disconnected, sess state %s\n",
+-                           rtrs_srv_state_str(sess->state));
++                           rtrs_srv_state_str(srv_path->state));
+               return;
+       }
+       if (msg->sg_cnt != 1 && msg->sg_cnt != 0) {
+@@ -1014,9 +1019,9 @@ static void process_read(struct rtrs_srv_con *con,
+                           "Processing read request failed, invalid message\n");
+               return;
+       }
+-      rtrs_srv_get_ops_ids(sess);
+-      rtrs_srv_update_rdma_stats(sess->stats, off, READ);
+-      id = sess->ops_ids[buf_id];
++      rtrs_srv_get_ops_ids(srv_path);
++      rtrs_srv_update_rdma_stats(srv_path->stats, off, READ);
++      id = srv_path->ops_ids[buf_id];
+       id->con         = con;
+       id->dir         = READ;
+       id->msg_id      = buf_id;
+@@ -1042,9 +1047,9 @@ static void process_read(struct rtrs_srv_con *con,
+               rtrs_err_rl(s,
+                            "Sending err msg for failed RDMA-Write-Req failed, msg_id %d, err: %d\n",
+                            buf_id, ret);
+-              close_sess(sess);
++              close_path(srv_path);
+       }
+-      rtrs_srv_put_ops_ids(sess);
++      rtrs_srv_put_ops_ids(srv_path);
+ }
+ static void process_write(struct rtrs_srv_con *con,
+@@ -1052,8 +1057,8 @@ static void process_write(struct rtrs_srv_con *con,
+                         u32 buf_id, u32 off)
+ {
+       struct rtrs_path *s = con->c.path;
+-      struct rtrs_srv_sess *sess = to_srv_sess(s);
+-      struct rtrs_srv *srv = sess->srv;
++      struct rtrs_srv_path *srv_path = to_srv_path(s);
++      struct rtrs_srv *srv = srv_path->srv;
+       struct rtrs_srv_ctx *ctx = srv->ctx;
+       struct rtrs_srv_op *id;
+@@ -1061,15 +1066,15 @@ static void process_write(struct rtrs_srv_con *con,
+       void *data;
+       int ret;
+-      if (sess->state != RTRS_SRV_CONNECTED) {
++      if (srv_path->state != RTRS_SRV_CONNECTED) {
+               rtrs_err_rl(s,
+                            "Processing write request failed,  session is disconnected, sess state %s\n",
+-                           rtrs_srv_state_str(sess->state));
++                           rtrs_srv_state_str(srv_path->state));
+               return;
+       }
+-      rtrs_srv_get_ops_ids(sess);
+-      rtrs_srv_update_rdma_stats(sess->stats, off, WRITE);
+-      id = sess->ops_ids[buf_id];
++      rtrs_srv_get_ops_ids(srv_path);
++      rtrs_srv_update_rdma_stats(srv_path->stats, off, WRITE);
++      id = srv_path->ops_ids[buf_id];
+       id->con    = con;
+       id->dir    = WRITE;
+       id->msg_id = buf_id;
+@@ -1094,20 +1099,21 @@ static void process_write(struct rtrs_srv_con *con,
+               rtrs_err_rl(s,
+                            "Processing write request failed, sending I/O response failed, msg_id %d, err: %d\n",
+                            buf_id, ret);
+-              close_sess(sess);
++              close_path(srv_path);
+       }
+-      rtrs_srv_put_ops_ids(sess);
++      rtrs_srv_put_ops_ids(srv_path);
+ }
+ static void process_io_req(struct rtrs_srv_con *con, void *msg,
+                          u32 id, u32 off)
+ {
+       struct rtrs_path *s = con->c.path;
+-      struct rtrs_srv_sess *sess = to_srv_sess(s);
++      struct rtrs_srv_path *srv_path = to_srv_path(s);
+       struct rtrs_msg_rdma_hdr *hdr;
+       unsigned int type;
+-      ib_dma_sync_single_for_cpu(sess->s.dev->ib_dev, sess->dma_addr[id],
++      ib_dma_sync_single_for_cpu(srv_path->s.dev->ib_dev,
++                                 srv_path->dma_addr[id],
+                                  max_chunk_size, DMA_BIDIRECTIONAL);
+       hdr = msg;
+       type = le16_to_cpu(hdr->type);
+@@ -1129,7 +1135,7 @@ static void process_io_req(struct rtrs_srv_con *con, void *msg,
+       return;
+ err:
+-      close_sess(sess);
++      close_path(srv_path);
+ }
+ static void rtrs_srv_inv_rkey_done(struct ib_cq *cq, struct ib_wc *wc)
+@@ -1138,15 +1144,15 @@ static void rtrs_srv_inv_rkey_done(struct ib_cq *cq, struct ib_wc *wc)
+               container_of(wc->wr_cqe, typeof(*mr), inv_cqe);
+       struct rtrs_srv_con *con = to_srv_con(wc->qp->qp_context);
+       struct rtrs_path *s = con->c.path;
+-      struct rtrs_srv_sess *sess = to_srv_sess(s);
+-      struct rtrs_srv *srv = sess->srv;
++      struct rtrs_srv_path *srv_path = to_srv_path(s);
++      struct rtrs_srv *srv = srv_path->srv;
+       u32 msg_id, off;
+       void *data;
+       if (wc->status != IB_WC_SUCCESS) {
+               rtrs_err(s, "Failed IB_WR_LOCAL_INV: %s\n",
+                         ib_wc_status_msg(wc->status));
+-              close_sess(sess);
++              close_path(srv_path);
+       }
+       msg_id = mr->msg_id;
+       off = mr->msg_off;
+@@ -1195,8 +1201,8 @@ static void rtrs_srv_rdma_done(struct ib_cq *cq, struct ib_wc *wc)
+ {
+       struct rtrs_srv_con *con = to_srv_con(wc->qp->qp_context);
+       struct rtrs_path *s = con->c.path;
+-      struct rtrs_srv_sess *sess = to_srv_sess(s);
+-      struct rtrs_srv *srv = sess->srv;
++      struct rtrs_srv_path *srv_path = to_srv_path(s);
++      struct rtrs_srv *srv = srv_path->srv;
+       u32 imm_type, imm_payload;
+       int err;
+@@ -1206,7 +1212,7 @@ static void rtrs_srv_rdma_done(struct ib_cq *cq, struct ib_wc *wc)
+                                 "%s (wr_cqe: %p, type: %d, vendor_err: 0x%x, len: %u)\n",
+                                 ib_wc_status_msg(wc->status), wc->wr_cqe,
+                                 wc->opcode, wc->vendor_err, wc->byte_len);
+-                      close_sess(sess);
++                      close_path(srv_path);
+               }
+               return;
+       }
+@@ -1222,7 +1228,7 @@ static void rtrs_srv_rdma_done(struct ib_cq *cq, struct ib_wc *wc)
+               err = rtrs_post_recv_empty(&con->c, &io_comp_cqe);
+               if (err) {
+                       rtrs_err(s, "rtrs_post_recv(), err: %d\n", err);
+-                      close_sess(sess);
++                      close_path(srv_path);
+                       break;
+               }
+               rtrs_from_imm(be32_to_cpu(wc->ex.imm_data),
+@@ -1231,16 +1237,16 @@ static void rtrs_srv_rdma_done(struct ib_cq *cq, struct ib_wc *wc)
+                       u32 msg_id, off;
+                       void *data;
+-                      msg_id = imm_payload >> sess->mem_bits;
+-                      off = imm_payload & ((1 << sess->mem_bits) - 1);
++                      msg_id = imm_payload >> srv_path->mem_bits;
++                      off = imm_payload & ((1 << srv_path->mem_bits) - 1);
+                       if (msg_id >= srv->queue_depth || off >= max_chunk_size) {
+                               rtrs_err(s, "Wrong msg_id %u, off %u\n",
+                                         msg_id, off);
+-                              close_sess(sess);
++                              close_path(srv_path);
+                               return;
+                       }
+                       if (always_invalidate) {
+-                              struct rtrs_srv_mr *mr = &sess->mrs[msg_id];
++                              struct rtrs_srv_mr *mr = &srv_path->mrs[msg_id];
+                               mr->msg_off = off;
+                               mr->msg_id = msg_id;
+@@ -1248,7 +1254,7 @@ static void rtrs_srv_rdma_done(struct ib_cq *cq, struct ib_wc *wc)
+                               if (err) {
+                                       rtrs_err(s, "rtrs_post_recv(), err: %d\n",
+                                                 err);
+-                                      close_sess(sess);
++                                      close_path(srv_path);
+                                       break;
+                               }
+                       } else {
+@@ -1257,10 +1263,10 @@ static void rtrs_srv_rdma_done(struct ib_cq *cq, struct ib_wc *wc)
+                       }
+               } else if (imm_type == RTRS_HB_MSG_IMM) {
+                       WARN_ON(con->c.cid);
+-                      rtrs_send_hb_ack(&sess->s);
++                      rtrs_send_hb_ack(&srv_path->s);
+               } else if (imm_type == RTRS_HB_ACK_IMM) {
+                       WARN_ON(con->c.cid);
+-                      sess->s.hb_missed_cnt = 0;
++                      srv_path->s.hb_missed_cnt = 0;
+               } else {
+                       rtrs_wrn(s, "Unknown IMM type %u\n", imm_type);
+               }
+@@ -1284,22 +1290,23 @@ static void rtrs_srv_rdma_done(struct ib_cq *cq, struct ib_wc *wc)
+ }
+ /**
+- * rtrs_srv_get_sess_name() - Get rtrs_srv peer hostname.
++ * rtrs_srv_get_path_name() - Get rtrs_srv peer hostname.
+  * @srv:      Session
+- * @sessname: Sessname buffer
++ * @pathname: Pathname buffer
+  * @len:      Length of sessname buffer
+  */
+-int rtrs_srv_get_sess_name(struct rtrs_srv *srv, char *sessname, size_t len)
++int rtrs_srv_get_path_name(struct rtrs_srv *srv, char *pathname,
++                         size_t len)
+ {
+-      struct rtrs_srv_sess *sess;
++      struct rtrs_srv_path *srv_path;
+       int err = -ENOTCONN;
+       mutex_lock(&srv->paths_mutex);
+-      list_for_each_entry(sess, &srv->paths_list, s.entry) {
+-              if (sess->state != RTRS_SRV_CONNECTED)
++      list_for_each_entry(srv_path, &srv->paths_list, s.entry) {
++              if (srv_path->state != RTRS_SRV_CONNECTED)
+                       continue;
+-              strscpy(sessname, sess->s.sessname,
+-                     min_t(size_t, sizeof(sess->s.sessname), len));
++              strscpy(pathname, srv_path->s.sessname,
++                      min_t(size_t, sizeof(srv_path->s.sessname), len));
+               err = 0;
+               break;
+       }
+@@ -1307,7 +1314,7 @@ int rtrs_srv_get_sess_name(struct rtrs_srv *srv, char *sessname, size_t len)
+       return err;
+ }
+-EXPORT_SYMBOL(rtrs_srv_get_sess_name);
++EXPORT_SYMBOL(rtrs_srv_get_path_name);
+ /**
+  * rtrs_srv_get_queue_depth() - Get rtrs_srv qdepth.
+@@ -1319,22 +1326,22 @@ int rtrs_srv_get_queue_depth(struct rtrs_srv *srv)
+ }
+ EXPORT_SYMBOL(rtrs_srv_get_queue_depth);
+-static int find_next_bit_ring(struct rtrs_srv_sess *sess)
++static int find_next_bit_ring(struct rtrs_srv_path *srv_path)
+ {
+-      struct ib_device *ib_dev = sess->s.dev->ib_dev;
++      struct ib_device *ib_dev = srv_path->s.dev->ib_dev;
+       int v;
+-      v = cpumask_next(sess->cur_cq_vector, &cq_affinity_mask);
++      v = cpumask_next(srv_path->cur_cq_vector, &cq_affinity_mask);
+       if (v >= nr_cpu_ids || v >= ib_dev->num_comp_vectors)
+               v = cpumask_first(&cq_affinity_mask);
+       return v;
+ }
+-static int rtrs_srv_get_next_cq_vector(struct rtrs_srv_sess *sess)
++static int rtrs_srv_get_next_cq_vector(struct rtrs_srv_path *srv_path)
+ {
+-      sess->cur_cq_vector = find_next_bit_ring(sess);
++      srv_path->cur_cq_vector = find_next_bit_ring(srv_path);
+-      return sess->cur_cq_vector;
++      return srv_path->cur_cq_vector;
+ }
+ static void rtrs_srv_dev_release(struct device *dev)
+@@ -1439,22 +1446,22 @@ static void put_srv(struct rtrs_srv *srv)
+ }
+ static void __add_path_to_srv(struct rtrs_srv *srv,
+-                            struct rtrs_srv_sess *sess)
++                            struct rtrs_srv_path *srv_path)
+ {
+-      list_add_tail(&sess->s.entry, &srv->paths_list);
++      list_add_tail(&srv_path->s.entry, &srv->paths_list);
+       srv->paths_num++;
+       WARN_ON(srv->paths_num >= MAX_PATHS_NUM);
+ }
+-static void del_path_from_srv(struct rtrs_srv_sess *sess)
++static void del_path_from_srv(struct rtrs_srv_path *srv_path)
+ {
+-      struct rtrs_srv *srv = sess->srv;
++      struct rtrs_srv *srv = srv_path->srv;
+       if (WARN_ON(!srv))
+               return;
+       mutex_lock(&srv->paths_mutex);
+-      list_del(&sess->s.entry);
++      list_del(&srv_path->s.entry);
+       WARN_ON(!srv->paths_num);
+       srv->paths_num--;
+       mutex_unlock(&srv->paths_mutex);
+@@ -1487,44 +1494,44 @@ static int sockaddr_cmp(const struct sockaddr *a, const struct sockaddr *b)
+ static bool __is_path_w_addr_exists(struct rtrs_srv *srv,
+                                   struct rdma_addr *addr)
+ {
+-      struct rtrs_srv_sess *sess;
++      struct rtrs_srv_path *srv_path;
+-      list_for_each_entry(sess, &srv->paths_list, s.entry)
+-              if (!sockaddr_cmp((struct sockaddr *)&sess->s.dst_addr,
++      list_for_each_entry(srv_path, &srv->paths_list, s.entry)
++              if (!sockaddr_cmp((struct sockaddr *)&srv_path->s.dst_addr,
+                                 (struct sockaddr *)&addr->dst_addr) &&
+-                  !sockaddr_cmp((struct sockaddr *)&sess->s.src_addr,
++                  !sockaddr_cmp((struct sockaddr *)&srv_path->s.src_addr,
+                                 (struct sockaddr *)&addr->src_addr))
+                       return true;
+       return false;
+ }
+-static void free_sess(struct rtrs_srv_sess *sess)
++static void free_path(struct rtrs_srv_path *srv_path)
+ {
+-      if (sess->kobj.state_in_sysfs) {
+-              kobject_del(&sess->kobj);
+-              kobject_put(&sess->kobj);
++      if (srv_path->kobj.state_in_sysfs) {
++              kobject_del(&srv_path->kobj);
++              kobject_put(&srv_path->kobj);
+       } else {
+-              kfree(sess->stats);
+-              kfree(sess);
++              kfree(srv_path->stats);
++              kfree(srv_path);
+       }
+ }
+ static void rtrs_srv_close_work(struct work_struct *work)
+ {
+-      struct rtrs_srv_sess *sess;
++      struct rtrs_srv_path *srv_path;
+       struct rtrs_srv_con *con;
+       int i;
+-      sess = container_of(work, typeof(*sess), close_work);
++      srv_path = container_of(work, typeof(*srv_path), close_work);
+-      rtrs_srv_destroy_sess_files(sess);
+-      rtrs_srv_stop_hb(sess);
++      rtrs_srv_destroy_path_files(srv_path);
++      rtrs_srv_stop_hb(srv_path);
+-      for (i = 0; i < sess->s.con_num; i++) {
+-              if (!sess->s.con[i])
++      for (i = 0; i < srv_path->s.con_num; i++) {
++              if (!srv_path->s.con[i])
+                       continue;
+-              con = to_srv_con(sess->s.con[i]);
++              con = to_srv_con(srv_path->s.con[i]);
+               rdma_disconnect(con->c.cm_id);
+               ib_drain_qp(con->c.qp);
+       }
+@@ -1533,41 +1540,41 @@ static void rtrs_srv_close_work(struct work_struct *work)
+        * Degrade ref count to the usual model with a single shared
+        * atomic_t counter
+        */
+-      percpu_ref_kill(&sess->ids_inflight_ref);
++      percpu_ref_kill(&srv_path->ids_inflight_ref);
+       /* Wait for all completion */
+-      wait_for_completion(&sess->complete_done);
++      wait_for_completion(&srv_path->complete_done);
+       /* Notify upper layer if we are the last path */
+-      rtrs_srv_sess_down(sess);
++      rtrs_srv_path_down(srv_path);
+-      unmap_cont_bufs(sess);
+-      rtrs_srv_free_ops_ids(sess);
++      unmap_cont_bufs(srv_path);
++      rtrs_srv_free_ops_ids(srv_path);
+-      for (i = 0; i < sess->s.con_num; i++) {
+-              if (!sess->s.con[i])
++      for (i = 0; i < srv_path->s.con_num; i++) {
++              if (!srv_path->s.con[i])
+                       continue;
+-              con = to_srv_con(sess->s.con[i]);
++              con = to_srv_con(srv_path->s.con[i]);
+               rtrs_cq_qp_destroy(&con->c);
+               rdma_destroy_id(con->c.cm_id);
+               kfree(con);
+       }
+-      rtrs_ib_dev_put(sess->s.dev);
++      rtrs_ib_dev_put(srv_path->s.dev);
+-      del_path_from_srv(sess);
+-      put_srv(sess->srv);
+-      sess->srv = NULL;
+-      rtrs_srv_change_state(sess, RTRS_SRV_CLOSED);
++      del_path_from_srv(srv_path);
++      put_srv(srv_path->srv);
++      srv_path->srv = NULL;
++      rtrs_srv_change_state(srv_path, RTRS_SRV_CLOSED);
+-      kfree(sess->dma_addr);
+-      kfree(sess->s.con);
+-      free_sess(sess);
++      kfree(srv_path->dma_addr);
++      kfree(srv_path->s.con);
++      free_path(srv_path);
+ }
+-static int rtrs_rdma_do_accept(struct rtrs_srv_sess *sess,
++static int rtrs_rdma_do_accept(struct rtrs_srv_path *srv_path,
+                              struct rdma_cm_id *cm_id)
+ {
+-      struct rtrs_srv *srv = sess->srv;
++      struct rtrs_srv *srv = srv_path->srv;
+       struct rtrs_msg_conn_rsp msg;
+       struct rdma_conn_param param;
+       int err;
+@@ -1615,25 +1622,25 @@ static int rtrs_rdma_do_reject(struct rdma_cm_id *cm_id, int errno)
+       return errno;
+ }
+-static struct rtrs_srv_sess *
+-__find_sess(struct rtrs_srv *srv, const uuid_t *sess_uuid)
++static struct rtrs_srv_path *
++__find_path(struct rtrs_srv *srv, const uuid_t *sess_uuid)
+ {
+-      struct rtrs_srv_sess *sess;
++      struct rtrs_srv_path *srv_path;
+-      list_for_each_entry(sess, &srv->paths_list, s.entry) {
+-              if (uuid_equal(&sess->s.uuid, sess_uuid))
+-                      return sess;
++      list_for_each_entry(srv_path, &srv->paths_list, s.entry) {
++              if (uuid_equal(&srv_path->s.uuid, sess_uuid))
++                      return srv_path;
+       }
+       return NULL;
+ }
+-static int create_con(struct rtrs_srv_sess *sess,
++static int create_con(struct rtrs_srv_path *srv_path,
+                     struct rdma_cm_id *cm_id,
+                     unsigned int cid)
+ {
+-      struct rtrs_srv *srv = sess->srv;
+-      struct rtrs_path *s = &sess->s;
++      struct rtrs_srv *srv = srv_path->srv;
++      struct rtrs_path *s = &srv_path->s;
+       struct rtrs_srv_con *con;
+       u32 cq_num, max_send_wr, max_recv_wr, wr_limit;
+@@ -1648,10 +1655,10 @@ static int create_con(struct rtrs_srv_sess *sess,
+       spin_lock_init(&con->rsp_wr_wait_lock);
+       INIT_LIST_HEAD(&con->rsp_wr_wait_list);
+       con->c.cm_id = cm_id;
+-      con->c.path = &sess->s;
++      con->c.path = &srv_path->s;
+       con->c.cid = cid;
+       atomic_set(&con->c.wr_cnt, 1);
+-      wr_limit = sess->s.dev->ib_dev->attrs.max_qp_wr;
++      wr_limit = srv_path->s.dev->ib_dev->attrs.max_qp_wr;
+       if (con->c.cid == 0) {
+               /*
+@@ -1684,10 +1691,10 @@ static int create_con(struct rtrs_srv_sess *sess,
+       }
+       cq_num = max_send_wr + max_recv_wr;
+       atomic_set(&con->c.sq_wr_avail, max_send_wr);
+-      cq_vector = rtrs_srv_get_next_cq_vector(sess);
++      cq_vector = rtrs_srv_get_next_cq_vector(srv_path);
+       /* TODO: SOFTIRQ can be faster, but be careful with softirq context */
+-      err = rtrs_cq_qp_create(&sess->s, &con->c, 1, cq_vector, cq_num,
++      err = rtrs_cq_qp_create(&srv_path->s, &con->c, 1, cq_vector, cq_num,
+                                max_send_wr, max_recv_wr,
+                                IB_POLL_WORKQUEUE);
+       if (err) {
+@@ -1699,8 +1706,8 @@ static int create_con(struct rtrs_srv_sess *sess,
+               if (err)
+                       goto free_cqqp;
+       }
+-      WARN_ON(sess->s.con[cid]);
+-      sess->s.con[cid] = &con->c;
++      WARN_ON(srv_path->s.con[cid]);
++      srv_path->s.con[cid] = &con->c;
+       /*
+        * Change context from server to current connection.  The other
+@@ -1719,13 +1726,13 @@ static int create_con(struct rtrs_srv_sess *sess,
+       return err;
+ }
+-static struct rtrs_srv_sess *__alloc_sess(struct rtrs_srv *srv,
++static struct rtrs_srv_path *__alloc_path(struct rtrs_srv *srv,
+                                          struct rdma_cm_id *cm_id,
+                                          unsigned int con_num,
+                                          unsigned int recon_cnt,
+                                          const uuid_t *uuid)
+ {
+-      struct rtrs_srv_sess *sess;
++      struct rtrs_srv_path *srv_path;
+       int err = -ENOMEM;
+       char str[NAME_MAX];
+       struct rtrs_addr path;
+@@ -1739,74 +1746,76 @@ static struct rtrs_srv_sess *__alloc_sess(struct rtrs_srv *srv,
+               pr_err("Path with same addr exists\n");
+               goto err;
+       }
+-      sess = kzalloc(sizeof(*sess), GFP_KERNEL);
+-      if (!sess)
++      srv_path = kzalloc(sizeof(*srv_path), GFP_KERNEL);
++      if (!srv_path)
+               goto err;
+-      sess->stats = kzalloc(sizeof(*sess->stats), GFP_KERNEL);
+-      if (!sess->stats)
++      srv_path->stats = kzalloc(sizeof(*srv_path->stats), GFP_KERNEL);
++      if (!srv_path->stats)
+               goto err_free_sess;
+-      sess->stats->sess = sess;
++      srv_path->stats->srv_path = srv_path;
+-      sess->dma_addr = kcalloc(srv->queue_depth, sizeof(*sess->dma_addr),
+-                               GFP_KERNEL);
+-      if (!sess->dma_addr)
++      srv_path->dma_addr = kcalloc(srv->queue_depth,
++                                   sizeof(*srv_path->dma_addr),
++                                   GFP_KERNEL);
++      if (!srv_path->dma_addr)
+               goto err_free_stats;
+-      sess->s.con = kcalloc(con_num, sizeof(*sess->s.con), GFP_KERNEL);
+-      if (!sess->s.con)
++      srv_path->s.con = kcalloc(con_num, sizeof(*srv_path->s.con),
++                                GFP_KERNEL);
++      if (!srv_path->s.con)
+               goto err_free_dma_addr;
+-      sess->state = RTRS_SRV_CONNECTING;
+-      sess->srv = srv;
+-      sess->cur_cq_vector = -1;
+-      sess->s.dst_addr = cm_id->route.addr.dst_addr;
+-      sess->s.src_addr = cm_id->route.addr.src_addr;
++      srv_path->state = RTRS_SRV_CONNECTING;
++      srv_path->srv = srv;
++      srv_path->cur_cq_vector = -1;
++      srv_path->s.dst_addr = cm_id->route.addr.dst_addr;
++      srv_path->s.src_addr = cm_id->route.addr.src_addr;
+       /* temporary until receiving session-name from client */
+-      path.src = &sess->s.src_addr;
+-      path.dst = &sess->s.dst_addr;
++      path.src = &srv_path->s.src_addr;
++      path.dst = &srv_path->s.dst_addr;
+       rtrs_addr_to_str(&path, str, sizeof(str));
+-      strscpy(sess->s.sessname, str, sizeof(sess->s.sessname));
+-
+-      sess->s.con_num = con_num;
+-      sess->s.irq_con_num = con_num;
+-      sess->s.recon_cnt = recon_cnt;
+-      uuid_copy(&sess->s.uuid, uuid);
+-      spin_lock_init(&sess->state_lock);
+-      INIT_WORK(&sess->close_work, rtrs_srv_close_work);
+-      rtrs_srv_init_hb(sess);
+-
+-      sess->s.dev = rtrs_ib_dev_find_or_add(cm_id->device, &dev_pd);
+-      if (!sess->s.dev) {
++      strscpy(srv_path->s.sessname, str, sizeof(srv_path->s.sessname));
++
++      srv_path->s.con_num = con_num;
++      srv_path->s.irq_con_num = con_num;
++      srv_path->s.recon_cnt = recon_cnt;
++      uuid_copy(&srv_path->s.uuid, uuid);
++      spin_lock_init(&srv_path->state_lock);
++      INIT_WORK(&srv_path->close_work, rtrs_srv_close_work);
++      rtrs_srv_init_hb(srv_path);
++
++      srv_path->s.dev = rtrs_ib_dev_find_or_add(cm_id->device, &dev_pd);
++      if (!srv_path->s.dev) {
+               err = -ENOMEM;
+               goto err_free_con;
+       }
+-      err = map_cont_bufs(sess);
++      err = map_cont_bufs(srv_path);
+       if (err)
+               goto err_put_dev;
+-      err = rtrs_srv_alloc_ops_ids(sess);
++      err = rtrs_srv_alloc_ops_ids(srv_path);
+       if (err)
+               goto err_unmap_bufs;
+-      __add_path_to_srv(srv, sess);
++      __add_path_to_srv(srv, srv_path);
+-      return sess;
++      return srv_path;
+ err_unmap_bufs:
+-      unmap_cont_bufs(sess);
++      unmap_cont_bufs(srv_path);
+ err_put_dev:
+-      rtrs_ib_dev_put(sess->s.dev);
++      rtrs_ib_dev_put(srv_path->s.dev);
+ err_free_con:
+-      kfree(sess->s.con);
++      kfree(srv_path->s.con);
+ err_free_dma_addr:
+-      kfree(sess->dma_addr);
++      kfree(srv_path->dma_addr);
+ err_free_stats:
+-      kfree(sess->stats);
++      kfree(srv_path->stats);
+ err_free_sess:
+-      kfree(sess);
++      kfree(srv_path);
+ err:
+       return ERR_PTR(err);
+ }
+@@ -1816,7 +1825,7 @@ static int rtrs_rdma_connect(struct rdma_cm_id *cm_id,
+                             size_t len)
+ {
+       struct rtrs_srv_ctx *ctx = cm_id->context;
+-      struct rtrs_srv_sess *sess;
++      struct rtrs_srv_path *srv_path;
+       struct rtrs_srv *srv;
+       u16 version, con_num, cid;
+@@ -1857,16 +1866,16 @@ static int rtrs_rdma_connect(struct rdma_cm_id *cm_id,
+               goto reject_w_err;
+       }
+       mutex_lock(&srv->paths_mutex);
+-      sess = __find_sess(srv, &msg->sess_uuid);
+-      if (sess) {
+-              struct rtrs_path *s = &sess->s;
++      srv_path = __find_path(srv, &msg->sess_uuid);
++      if (srv_path) {
++              struct rtrs_path *s = &srv_path->s;
+               /* Session already holds a reference */
+               put_srv(srv);
+-              if (sess->state != RTRS_SRV_CONNECTING) {
++              if (srv_path->state != RTRS_SRV_CONNECTING) {
+                       rtrs_err(s, "Session in wrong state: %s\n",
+-                                rtrs_srv_state_str(sess->state));
++                                rtrs_srv_state_str(srv_path->state));
+                       mutex_unlock(&srv->paths_mutex);
+                       goto reject_w_err;
+               }
+@@ -1886,19 +1895,19 @@ static int rtrs_rdma_connect(struct rdma_cm_id *cm_id,
+                       goto reject_w_err;
+               }
+       } else {
+-              sess = __alloc_sess(srv, cm_id, con_num, recon_cnt,
++              srv_path = __alloc_path(srv, cm_id, con_num, recon_cnt,
+                                   &msg->sess_uuid);
+-              if (IS_ERR(sess)) {
++              if (IS_ERR(srv_path)) {
+                       mutex_unlock(&srv->paths_mutex);
+                       put_srv(srv);
+-                      err = PTR_ERR(sess);
++                      err = PTR_ERR(srv_path);
+                       pr_err("RTRS server session allocation failed: %d\n", err);
+                       goto reject_w_err;
+               }
+       }
+-      err = create_con(sess, cm_id, cid);
++      err = create_con(srv_path, cm_id, cid);
+       if (err) {
+-              rtrs_err((&sess->s), "create_con(), error %d\n", err);
++              rtrs_err((&srv_path->s), "create_con(), error %d\n", err);
+               rtrs_rdma_do_reject(cm_id, err);
+               /*
+                * Since session has other connections we follow normal way
+@@ -1907,9 +1916,9 @@ static int rtrs_rdma_connect(struct rdma_cm_id *cm_id,
+                */
+               goto close_and_return_err;
+       }
+-      err = rtrs_rdma_do_accept(sess, cm_id);
++      err = rtrs_rdma_do_accept(srv_path, cm_id);
+       if (err) {
+-              rtrs_err((&sess->s), "rtrs_rdma_do_accept(), error %d\n", err);
++              rtrs_err((&srv_path->s), "rtrs_rdma_do_accept(), error %d\n", err);
+               rtrs_rdma_do_reject(cm_id, err);
+               /*
+                * Since current connection was successfully added to the
+@@ -1929,7 +1938,7 @@ static int rtrs_rdma_connect(struct rdma_cm_id *cm_id,
+ close_and_return_err:
+       mutex_unlock(&srv->paths_mutex);
+-      close_sess(sess);
++      close_path(srv_path);
+       return err;
+ }
+@@ -1937,14 +1946,14 @@ static int rtrs_rdma_connect(struct rdma_cm_id *cm_id,
+ static int rtrs_srv_rdma_cm_handler(struct rdma_cm_id *cm_id,
+                                    struct rdma_cm_event *ev)
+ {
+-      struct rtrs_srv_sess *sess = NULL;
++      struct rtrs_srv_path *srv_path = NULL;
+       struct rtrs_path *s = NULL;
+       if (ev->event != RDMA_CM_EVENT_CONNECT_REQUEST) {
+               struct rtrs_con *c = cm_id->context;
+               s = c->path;
+-              sess = to_srv_sess(s);
++              srv_path = to_srv_path(s);
+       }
+       switch (ev->event) {
+@@ -1968,7 +1977,7 @@ static int rtrs_srv_rdma_cm_handler(struct rdma_cm_id *cm_id,
+       case RDMA_CM_EVENT_ADDR_CHANGE:
+       case RDMA_CM_EVENT_TIMEWAIT_EXIT:
+       case RDMA_CM_EVENT_DEVICE_REMOVAL:
+-              close_sess(sess);
++              close_path(srv_path);
+               break;
+       default:
+               pr_err("Ignoring unexpected CM event %s, err %d\n",
+@@ -2176,13 +2185,13 @@ struct rtrs_srv_ctx *rtrs_srv_open(struct rtrs_srv_ops *ops, u16 port)
+ }
+ EXPORT_SYMBOL(rtrs_srv_open);
+-static void close_sessions(struct rtrs_srv *srv)
++static void close_paths(struct rtrs_srv *srv)
+ {
+-      struct rtrs_srv_sess *sess;
++      struct rtrs_srv_path *srv_path;
+       mutex_lock(&srv->paths_mutex);
+-      list_for_each_entry(sess, &srv->paths_list, s.entry)
+-              close_sess(sess);
++      list_for_each_entry(srv_path, &srv->paths_list, s.entry)
++              close_path(srv_path);
+       mutex_unlock(&srv->paths_mutex);
+ }
+@@ -2192,7 +2201,7 @@ static void close_ctx(struct rtrs_srv_ctx *ctx)
+       mutex_lock(&ctx->srv_mutex);
+       list_for_each_entry(srv, &ctx->srv_list, ctx_list)
+-              close_sessions(srv);
++              close_paths(srv);
+       mutex_unlock(&ctx->srv_mutex);
+       flush_workqueue(rtrs_wq);
+ }
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.h b/drivers/infiniband/ulp/rtrs/rtrs-srv.h
+index f0fbd8bf8871..ee3578b9aa01 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-srv.h
++++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.h
+@@ -37,7 +37,7 @@ struct rtrs_srv_stats_rdma_stats {
+ struct rtrs_srv_stats {
+       struct kobject                          kobj_stats;
+       struct rtrs_srv_stats_rdma_stats        rdma_stats;
+-      struct rtrs_srv_sess                    *sess;
++      struct rtrs_srv_path                    *srv_path;
+ };
+ struct rtrs_srv_con {
+@@ -71,7 +71,7 @@ struct rtrs_srv_mr {
+       struct rtrs_iu  *iu;            /* send buffer for new rkey msg */
+ };
+-struct rtrs_srv_sess {
++struct rtrs_srv_path {
+       struct rtrs_path        s;
+       struct rtrs_srv *srv;
+       struct work_struct      close_work;
+@@ -125,7 +125,7 @@ struct rtrs_srv_ib_ctx {
+ extern struct class *rtrs_dev_class;
+-void close_sess(struct rtrs_srv_sess *sess);
++void close_path(struct rtrs_srv_path *srv_path);
+ static inline void rtrs_srv_update_rdma_stats(struct rtrs_srv_stats *s,
+                                             size_t size, int d)
+@@ -143,7 +143,7 @@ ssize_t rtrs_srv_reset_all_help(struct rtrs_srv_stats *stats,
+                                char *page, size_t len);
+ /* functions which are implemented in rtrs-srv-sysfs.c */
+-int rtrs_srv_create_sess_files(struct rtrs_srv_sess *sess);
+-void rtrs_srv_destroy_sess_files(struct rtrs_srv_sess *sess);
++int rtrs_srv_create_path_files(struct rtrs_srv_path *srv_path);
++void rtrs_srv_destroy_path_files(struct rtrs_srv_path *srv_path);
+ #endif /* RTRS_SRV_H */
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs.h b/drivers/infiniband/ulp/rtrs/rtrs.h
+index 859c79685daf..9da9202fbee5 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs.h
++++ b/drivers/infiniband/ulp/rtrs/rtrs.h
+@@ -175,7 +175,8 @@ bool rtrs_srv_resp_rdma(struct rtrs_srv_op *id, int errno);
+ void rtrs_srv_set_sess_priv(struct rtrs_srv *sess, void *priv);
+-int rtrs_srv_get_sess_name(struct rtrs_srv *sess, char *sessname, size_t len);
++int rtrs_srv_get_path_name(struct rtrs_srv *sess, char *pathname,
++                         size_t len);
+ int rtrs_srv_get_queue_depth(struct rtrs_srv *sess);
+-- 
+2.35.1
+
diff --git a/queue-5.15/rdma-rxe-add-memory-barriers-to-kernel-queues.patch b/queue-5.15/rdma-rxe-add-memory-barriers-to-kernel-queues.patch
new file mode 100644 (file)
index 0000000..3c9d060
--- /dev/null
@@ -0,0 +1,934 @@
+From df9e930429b2b99ef44bd615cf0b9ef81583a028 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Sep 2021 11:42:03 -0500
+Subject: RDMA/rxe: Add memory barriers to kernel queues
+
+From: Bob Pearson <rpearsonhpe@gmail.com>
+
+[ Upstream commit ae6e843fe08d0ea8e158815809dcc20e3a1afc22 ]
+
+Earlier patches added memory barriers to protect user space to kernel
+space communications. The user space queues were previously shown to have
+occasional memory synchonization errors which were removed by adding
+smp_load_acquire, smp_store_release barriers.  This patch extends that to
+the case where queues are used between kernel space threads.
+
+This patch also extends the queue types to include kernel ULP queues which
+access the other end of the queues in kernel verbs calls like poll_cq and
+post_send/recv.
+
+Link: https://lore.kernel.org/r/20210914164206.19768-2-rpearsonhpe@gmail.com
+Signed-off-by: Bob Pearson <rpearsonhpe@gmail.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/rxe/rxe_comp.c  |  12 +-
+ drivers/infiniband/sw/rxe/rxe_cq.c    |  25 +--
+ drivers/infiniband/sw/rxe/rxe_qp.c    |  12 +-
+ drivers/infiniband/sw/rxe/rxe_queue.c |  30 ++-
+ drivers/infiniband/sw/rxe/rxe_queue.h | 292 +++++++++++---------------
+ drivers/infiniband/sw/rxe/rxe_req.c   |  37 ++--
+ drivers/infiniband/sw/rxe/rxe_resp.c  |  40 +---
+ drivers/infiniband/sw/rxe/rxe_srq.c   |   2 +-
+ drivers/infiniband/sw/rxe/rxe_verbs.c |  53 +----
+ 9 files changed, 189 insertions(+), 314 deletions(-)
+
+diff --git a/drivers/infiniband/sw/rxe/rxe_comp.c b/drivers/infiniband/sw/rxe/rxe_comp.c
+index d2d802c776fd..48a3864ada29 100644
+--- a/drivers/infiniband/sw/rxe/rxe_comp.c
++++ b/drivers/infiniband/sw/rxe/rxe_comp.c
+@@ -142,10 +142,7 @@ static inline enum comp_state get_wqe(struct rxe_qp *qp,
+       /* we come here whether or not we found a response packet to see if
+        * there are any posted WQEs
+        */
+-      if (qp->is_user)
+-              wqe = queue_head(qp->sq.queue, QUEUE_TYPE_FROM_USER);
+-      else
+-              wqe = queue_head(qp->sq.queue, QUEUE_TYPE_KERNEL);
++      wqe = queue_head(qp->sq.queue, QUEUE_TYPE_FROM_CLIENT);
+       *wqe_p = wqe;
+       /* no WQE or requester has not started it yet */
+@@ -432,10 +429,7 @@ static void do_complete(struct rxe_qp *qp, struct rxe_send_wqe *wqe)
+       if (post)
+               make_send_cqe(qp, wqe, &cqe);
+-      if (qp->is_user)
+-              advance_consumer(qp->sq.queue, QUEUE_TYPE_FROM_USER);
+-      else
+-              advance_consumer(qp->sq.queue, QUEUE_TYPE_KERNEL);
++      queue_advance_consumer(qp->sq.queue, QUEUE_TYPE_FROM_CLIENT);
+       if (post)
+               rxe_cq_post(qp->scq, &cqe, 0);
+@@ -539,7 +533,7 @@ static void rxe_drain_resp_pkts(struct rxe_qp *qp, bool notify)
+                       wqe->status = IB_WC_WR_FLUSH_ERR;
+                       do_complete(qp, wqe);
+               } else {
+-                      advance_consumer(q, q->type);
++                      queue_advance_consumer(q, q->type);
+               }
+       }
+ }
+diff --git a/drivers/infiniband/sw/rxe/rxe_cq.c b/drivers/infiniband/sw/rxe/rxe_cq.c
+index aef288f164fd..4eedaa0244b3 100644
+--- a/drivers/infiniband/sw/rxe/rxe_cq.c
++++ b/drivers/infiniband/sw/rxe/rxe_cq.c
+@@ -25,11 +25,7 @@ int rxe_cq_chk_attr(struct rxe_dev *rxe, struct rxe_cq *cq,
+       }
+       if (cq) {
+-              if (cq->is_user)
+-                      count = queue_count(cq->queue, QUEUE_TYPE_TO_USER);
+-              else
+-                      count = queue_count(cq->queue, QUEUE_TYPE_KERNEL);
+-
++              count = queue_count(cq->queue, QUEUE_TYPE_TO_CLIENT);
+               if (cqe < count) {
+                       pr_warn("cqe(%d) < current # elements in queue (%d)",
+                               cqe, count);
+@@ -65,7 +61,7 @@ int rxe_cq_from_init(struct rxe_dev *rxe, struct rxe_cq *cq, int cqe,
+       int err;
+       enum queue_type type;
+-      type = uresp ? QUEUE_TYPE_TO_USER : QUEUE_TYPE_KERNEL;
++      type = QUEUE_TYPE_TO_CLIENT;
+       cq->queue = rxe_queue_init(rxe, &cqe,
+                       sizeof(struct rxe_cqe), type);
+       if (!cq->queue) {
+@@ -117,11 +113,7 @@ int rxe_cq_post(struct rxe_cq *cq, struct rxe_cqe *cqe, int solicited)
+       spin_lock_irqsave(&cq->cq_lock, flags);
+-      if (cq->is_user)
+-              full = queue_full(cq->queue, QUEUE_TYPE_TO_USER);
+-      else
+-              full = queue_full(cq->queue, QUEUE_TYPE_KERNEL);
+-
++      full = queue_full(cq->queue, QUEUE_TYPE_TO_CLIENT);
+       if (unlikely(full)) {
+               spin_unlock_irqrestore(&cq->cq_lock, flags);
+               if (cq->ibcq.event_handler) {
+@@ -134,17 +126,10 @@ int rxe_cq_post(struct rxe_cq *cq, struct rxe_cqe *cqe, int solicited)
+               return -EBUSY;
+       }
+-      if (cq->is_user)
+-              addr = producer_addr(cq->queue, QUEUE_TYPE_TO_USER);
+-      else
+-              addr = producer_addr(cq->queue, QUEUE_TYPE_KERNEL);
+-
++      addr = queue_producer_addr(cq->queue, QUEUE_TYPE_TO_CLIENT);
+       memcpy(addr, cqe, sizeof(*cqe));
+-      if (cq->is_user)
+-              advance_producer(cq->queue, QUEUE_TYPE_TO_USER);
+-      else
+-              advance_producer(cq->queue, QUEUE_TYPE_KERNEL);
++      queue_advance_producer(cq->queue, QUEUE_TYPE_TO_CLIENT);
+       spin_unlock_irqrestore(&cq->cq_lock, flags);
+diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c
+index ed326d82725c..0d6a3d363554 100644
+--- a/drivers/infiniband/sw/rxe/rxe_qp.c
++++ b/drivers/infiniband/sw/rxe/rxe_qp.c
+@@ -231,7 +231,7 @@ static int rxe_qp_init_req(struct rxe_dev *rxe, struct rxe_qp *qp,
+       qp->sq.max_inline = init->cap.max_inline_data = wqe_size;
+       wqe_size += sizeof(struct rxe_send_wqe);
+-      type = uresp ? QUEUE_TYPE_FROM_USER : QUEUE_TYPE_KERNEL;
++      type = QUEUE_TYPE_FROM_CLIENT;
+       qp->sq.queue = rxe_queue_init(rxe, &qp->sq.max_wr,
+                               wqe_size, type);
+       if (!qp->sq.queue)
+@@ -248,12 +248,8 @@ static int rxe_qp_init_req(struct rxe_dev *rxe, struct rxe_qp *qp,
+               return err;
+       }
+-      if (qp->is_user)
+-              qp->req.wqe_index = producer_index(qp->sq.queue,
+-                                              QUEUE_TYPE_FROM_USER);
+-      else
+-              qp->req.wqe_index = producer_index(qp->sq.queue,
+-                                              QUEUE_TYPE_KERNEL);
++      qp->req.wqe_index = queue_get_producer(qp->sq.queue,
++                                             QUEUE_TYPE_FROM_CLIENT);
+       qp->req.state           = QP_STATE_RESET;
+       qp->req.opcode          = -1;
+@@ -293,7 +289,7 @@ static int rxe_qp_init_resp(struct rxe_dev *rxe, struct rxe_qp *qp,
+               pr_debug("qp#%d max_wr = %d, max_sge = %d, wqe_size = %d\n",
+                        qp_num(qp), qp->rq.max_wr, qp->rq.max_sge, wqe_size);
+-              type = uresp ? QUEUE_TYPE_FROM_USER : QUEUE_TYPE_KERNEL;
++              type = QUEUE_TYPE_FROM_CLIENT;
+               qp->rq.queue = rxe_queue_init(rxe, &qp->rq.max_wr,
+                                       wqe_size, type);
+               if (!qp->rq.queue)
+diff --git a/drivers/infiniband/sw/rxe/rxe_queue.c b/drivers/infiniband/sw/rxe/rxe_queue.c
+index 72d95398e604..6e6e023c1b45 100644
+--- a/drivers/infiniband/sw/rxe/rxe_queue.c
++++ b/drivers/infiniband/sw/rxe/rxe_queue.c
+@@ -111,17 +111,33 @@ struct rxe_queue *rxe_queue_init(struct rxe_dev *rxe, int *num_elem,
+ static int resize_finish(struct rxe_queue *q, struct rxe_queue *new_q,
+                        unsigned int num_elem)
+ {
+-      if (!queue_empty(q, q->type) && (num_elem < queue_count(q, q->type)))
++      enum queue_type type = q->type;
++      u32 prod;
++      u32 cons;
++
++      if (!queue_empty(q, q->type) && (num_elem < queue_count(q, type)))
+               return -EINVAL;
+-      while (!queue_empty(q, q->type)) {
+-              memcpy(producer_addr(new_q, new_q->type),
+-                                      consumer_addr(q, q->type),
+-                                      new_q->elem_size);
+-              advance_producer(new_q, new_q->type);
+-              advance_consumer(q, q->type);
++      prod = queue_get_producer(new_q, type);
++      cons = queue_get_consumer(q, type);
++
++      while (!queue_empty(q, type)) {
++              memcpy(queue_addr_from_index(new_q, prod),
++                     queue_addr_from_index(q, cons), new_q->elem_size);
++              prod = queue_next_index(new_q, prod);
++              cons = queue_next_index(q, cons);
+       }
++      new_q->buf->producer_index = prod;
++      q->buf->consumer_index = cons;
++
++      /* update private index copies */
++      if (type == QUEUE_TYPE_TO_CLIENT)
++              new_q->index = new_q->buf->producer_index;
++      else
++              q->index = q->buf->consumer_index;
++
++      /* exchange rxe_queue headers */
+       swap(*q, *new_q);
+       return 0;
+diff --git a/drivers/infiniband/sw/rxe/rxe_queue.h b/drivers/infiniband/sw/rxe/rxe_queue.h
+index 2702b0e55fc3..6227112ef7a2 100644
+--- a/drivers/infiniband/sw/rxe/rxe_queue.h
++++ b/drivers/infiniband/sw/rxe/rxe_queue.h
+@@ -10,34 +10,47 @@
+ /* for definition of shared struct rxe_queue_buf */
+ #include <uapi/rdma/rdma_user_rxe.h>
+-/* implements a simple circular buffer that can optionally be
+- * shared between user space and the kernel and can be resized
+- * the requested element size is rounded up to a power of 2
+- * and the number of elements in the buffer is also rounded
+- * up to a power of 2. Since the queue is empty when the
+- * producer and consumer indices match the maximum capacity
+- * of the queue is one less than the number of element slots
++/* Implements a simple circular buffer that is shared between user
++ * and the driver and can be resized. The requested element size is
++ * rounded up to a power of 2 and the number of elements in the buffer
++ * is also rounded up to a power of 2. Since the queue is empty when
++ * the producer and consumer indices match the maximum capacity of the
++ * queue is one less than the number of element slots.
+  *
+  * Notes:
+- *   - Kernel space indices are always masked off to q->index_mask
+- *   before storing so do not need to be checked on reads.
+- *   - User space indices may be out of range and must be
+- *   masked before use when read.
+- *   - The kernel indices for shared queues must not be written
+- *   by user space so a local copy is used and a shared copy is
+- *   stored when the local copy changes.
++ *   - The driver indices are always masked off to q->index_mask
++ *     before storing so do not need to be checked on reads.
++ *   - The user whether user space or kernel is generally
++ *     not trusted so its parameters are masked to make sure
++ *     they do not access the queue out of bounds on reads.
++ *   - The driver indices for queues must not be written
++ *     by user so a local copy is used and a shared copy is
++ *     stored when the local copy is changed.
+  *   - By passing the type in the parameter list separate from q
+- *   the compiler can eliminate the switch statement when the
+- *   actual queue type is known when the function is called.
+- *   In the performance path this is done. In less critical
+- *   paths just q->type is passed.
++ *     the compiler can eliminate the switch statement when the
++ *     actual queue type is known when the function is called at
++ *     compile time.
++ *   - These queues are lock free. The user and driver must protect
++ *     changes to their end of the queues with locks if more than one
++ *     CPU can be accessing it at the same time.
+  */
+-/* type of queue */
++/**
++ * enum queue_type - type of queue
++ * @QUEUE_TYPE_TO_CLIENT:     Queue is written by rxe driver and
++ *                            read by client. Used by rxe driver only.
++ * @QUEUE_TYPE_FROM_CLIENT:   Queue is written by client and
++ *                            read by rxe driver. Used by rxe driver only.
++ * @QUEUE_TYPE_TO_DRIVER:     Queue is written by client and
++ *                            read by rxe driver. Used by kernel client only.
++ * @QUEUE_TYPE_FROM_DRIVER:   Queue is written by rxe driver and
++ *                            read by client. Used by kernel client only.
++ */
+ enum queue_type {
+-      QUEUE_TYPE_KERNEL,
+-      QUEUE_TYPE_TO_USER,
+-      QUEUE_TYPE_FROM_USER,
++      QUEUE_TYPE_TO_CLIENT,
++      QUEUE_TYPE_FROM_CLIENT,
++      QUEUE_TYPE_TO_DRIVER,
++      QUEUE_TYPE_FROM_DRIVER,
+ };
+ struct rxe_queue {
+@@ -69,238 +82,171 @@ struct rxe_queue *rxe_queue_init(struct rxe_dev *rxe, int *num_elem,
+ int rxe_queue_resize(struct rxe_queue *q, unsigned int *num_elem_p,
+                    unsigned int elem_size, struct ib_udata *udata,
+                    struct mminfo __user *outbuf,
+-                   /* Protect producers while resizing queue */
+-                   spinlock_t *producer_lock,
+-                   /* Protect consumers while resizing queue */
+-                   spinlock_t *consumer_lock);
++                   spinlock_t *producer_lock, spinlock_t *consumer_lock);
+ void rxe_queue_cleanup(struct rxe_queue *queue);
+-static inline int next_index(struct rxe_queue *q, int index)
++static inline u32 queue_next_index(struct rxe_queue *q, int index)
+ {
+-      return (index + 1) & q->buf->index_mask;
++      return (index + 1) & q->index_mask;
+ }
+-static inline int queue_empty(struct rxe_queue *q, enum queue_type type)
++static inline u32 queue_get_producer(const struct rxe_queue *q,
++                                   enum queue_type type)
+ {
+       u32 prod;
+-      u32 cons;
+       switch (type) {
+-      case QUEUE_TYPE_FROM_USER:
+-              /* protect user space index */
++      case QUEUE_TYPE_FROM_CLIENT:
++              /* protect user index */
+               prod = smp_load_acquire(&q->buf->producer_index);
+-              cons = q->index;
+               break;
+-      case QUEUE_TYPE_TO_USER:
++      case QUEUE_TYPE_TO_CLIENT:
+               prod = q->index;
+-              /* protect user space index */
+-              cons = smp_load_acquire(&q->buf->consumer_index);
+               break;
+-      case QUEUE_TYPE_KERNEL:
++      case QUEUE_TYPE_FROM_DRIVER:
++              /* protect driver index */
++              prod = smp_load_acquire(&q->buf->producer_index);
++              break;
++      case QUEUE_TYPE_TO_DRIVER:
+               prod = q->buf->producer_index;
+-              cons = q->buf->consumer_index;
+               break;
+       }
+-      return ((prod - cons) & q->index_mask) == 0;
++      return prod;
+ }
+-static inline int queue_full(struct rxe_queue *q, enum queue_type type)
++static inline u32 queue_get_consumer(const struct rxe_queue *q,
++                                   enum queue_type type)
+ {
+-      u32 prod;
+       u32 cons;
+       switch (type) {
+-      case QUEUE_TYPE_FROM_USER:
+-              /* protect user space index */
+-              prod = smp_load_acquire(&q->buf->producer_index);
++      case QUEUE_TYPE_FROM_CLIENT:
+               cons = q->index;
+               break;
+-      case QUEUE_TYPE_TO_USER:
+-              prod = q->index;
+-              /* protect user space index */
++      case QUEUE_TYPE_TO_CLIENT:
++              /* protect user index */
+               cons = smp_load_acquire(&q->buf->consumer_index);
+               break;
+-      case QUEUE_TYPE_KERNEL:
+-              prod = q->buf->producer_index;
++      case QUEUE_TYPE_FROM_DRIVER:
+               cons = q->buf->consumer_index;
+               break;
++      case QUEUE_TYPE_TO_DRIVER:
++              /* protect driver index */
++              cons = smp_load_acquire(&q->buf->consumer_index);
++              break;
+       }
+-      return ((prod + 1 - cons) & q->index_mask) == 0;
++      return cons;
+ }
+-static inline unsigned int queue_count(const struct rxe_queue *q,
+-                                      enum queue_type type)
++static inline int queue_empty(struct rxe_queue *q, enum queue_type type)
+ {
+-      u32 prod;
+-      u32 cons;
+-
+-      switch (type) {
+-      case QUEUE_TYPE_FROM_USER:
+-              /* protect user space index */
+-              prod = smp_load_acquire(&q->buf->producer_index);
+-              cons = q->index;
+-              break;
+-      case QUEUE_TYPE_TO_USER:
+-              prod = q->index;
+-              /* protect user space index */
+-              cons = smp_load_acquire(&q->buf->consumer_index);
+-              break;
+-      case QUEUE_TYPE_KERNEL:
+-              prod = q->buf->producer_index;
+-              cons = q->buf->consumer_index;
+-              break;
+-      }
++      u32 prod = queue_get_producer(q, type);
++      u32 cons = queue_get_consumer(q, type);
+-      return (prod - cons) & q->index_mask;
++      return ((prod - cons) & q->index_mask) == 0;
+ }
+-static inline void advance_producer(struct rxe_queue *q, enum queue_type type)
++static inline int queue_full(struct rxe_queue *q, enum queue_type type)
+ {
+-      u32 prod;
++      u32 prod = queue_get_producer(q, type);
++      u32 cons = queue_get_consumer(q, type);
+-      switch (type) {
+-      case QUEUE_TYPE_FROM_USER:
+-              pr_warn_once("Normally kernel should not write user space index\n");
+-              /* protect user space index */
+-              prod = smp_load_acquire(&q->buf->producer_index);
+-              prod = (prod + 1) & q->index_mask;
+-              /* same */
+-              smp_store_release(&q->buf->producer_index, prod);
+-              break;
+-      case QUEUE_TYPE_TO_USER:
+-              prod = q->index;
+-              q->index = (prod + 1) & q->index_mask;
+-              q->buf->producer_index = q->index;
+-              break;
+-      case QUEUE_TYPE_KERNEL:
+-              prod = q->buf->producer_index;
+-              q->buf->producer_index = (prod + 1) & q->index_mask;
+-              break;
+-      }
++      return ((prod + 1 - cons) & q->index_mask) == 0;
+ }
+-static inline void advance_consumer(struct rxe_queue *q, enum queue_type type)
++static inline u32 queue_count(const struct rxe_queue *q,
++                                      enum queue_type type)
+ {
+-      u32 cons;
++      u32 prod = queue_get_producer(q, type);
++      u32 cons = queue_get_consumer(q, type);
+-      switch (type) {
+-      case QUEUE_TYPE_FROM_USER:
+-              cons = q->index;
+-              q->index = (cons + 1) & q->index_mask;
+-              q->buf->consumer_index = q->index;
+-              break;
+-      case QUEUE_TYPE_TO_USER:
+-              pr_warn_once("Normally kernel should not write user space index\n");
+-              /* protect user space index */
+-              cons = smp_load_acquire(&q->buf->consumer_index);
+-              cons = (cons + 1) & q->index_mask;
+-              /* same */
+-              smp_store_release(&q->buf->consumer_index, cons);
+-              break;
+-      case QUEUE_TYPE_KERNEL:
+-              cons = q->buf->consumer_index;
+-              q->buf->consumer_index = (cons + 1) & q->index_mask;
+-              break;
+-      }
++      return (prod - cons) & q->index_mask;
+ }
+-static inline void *producer_addr(struct rxe_queue *q, enum queue_type type)
++static inline void queue_advance_producer(struct rxe_queue *q,
++                                        enum queue_type type)
+ {
+       u32 prod;
+       switch (type) {
+-      case QUEUE_TYPE_FROM_USER:
+-              /* protect user space index */
+-              prod = smp_load_acquire(&q->buf->producer_index);
+-              prod &= q->index_mask;
++      case QUEUE_TYPE_FROM_CLIENT:
++              pr_warn("%s: attempt to advance client index\n",
++                      __func__);
+               break;
+-      case QUEUE_TYPE_TO_USER:
++      case QUEUE_TYPE_TO_CLIENT:
+               prod = q->index;
++              prod = (prod + 1) & q->index_mask;
++              q->index = prod;
++              /* protect user index */
++              smp_store_release(&q->buf->producer_index, prod);
++              break;
++      case QUEUE_TYPE_FROM_DRIVER:
++              pr_warn("%s: attempt to advance driver index\n",
++                      __func__);
+               break;
+-      case QUEUE_TYPE_KERNEL:
++      case QUEUE_TYPE_TO_DRIVER:
+               prod = q->buf->producer_index;
++              prod = (prod + 1) & q->index_mask;
++              q->buf->producer_index = prod;
+               break;
+       }
+-
+-      return q->buf->data + (prod << q->log2_elem_size);
+ }
+-static inline void *consumer_addr(struct rxe_queue *q, enum queue_type type)
++static inline void queue_advance_consumer(struct rxe_queue *q,
++                                        enum queue_type type)
+ {
+       u32 cons;
+       switch (type) {
+-      case QUEUE_TYPE_FROM_USER:
++      case QUEUE_TYPE_FROM_CLIENT:
+               cons = q->index;
++              cons = (cons + 1) & q->index_mask;
++              q->index = cons;
++              /* protect user index */
++              smp_store_release(&q->buf->consumer_index, cons);
+               break;
+-      case QUEUE_TYPE_TO_USER:
+-              /* protect user space index */
+-              cons = smp_load_acquire(&q->buf->consumer_index);
+-              cons &= q->index_mask;
++      case QUEUE_TYPE_TO_CLIENT:
++              pr_warn("%s: attempt to advance client index\n",
++                      __func__);
+               break;
+-      case QUEUE_TYPE_KERNEL:
++      case QUEUE_TYPE_FROM_DRIVER:
+               cons = q->buf->consumer_index;
++              cons = (cons + 1) & q->index_mask;
++              q->buf->consumer_index = cons;
++              break;
++      case QUEUE_TYPE_TO_DRIVER:
++              pr_warn("%s: attempt to advance driver index\n",
++                      __func__);
+               break;
+       }
+-
+-      return q->buf->data + (cons << q->log2_elem_size);
+ }
+-static inline unsigned int producer_index(struct rxe_queue *q,
+-                                              enum queue_type type)
++static inline void *queue_producer_addr(struct rxe_queue *q,
++                                      enum queue_type type)
+ {
+-      u32 prod;
++      u32 prod = queue_get_producer(q, type);
+-      switch (type) {
+-      case QUEUE_TYPE_FROM_USER:
+-              /* protect user space index */
+-              prod = smp_load_acquire(&q->buf->producer_index);
+-              prod &= q->index_mask;
+-              break;
+-      case QUEUE_TYPE_TO_USER:
+-              prod = q->index;
+-              break;
+-      case QUEUE_TYPE_KERNEL:
+-              prod = q->buf->producer_index;
+-              break;
+-      }
+-
+-      return prod;
++      return q->buf->data + (prod << q->log2_elem_size);
+ }
+-static inline unsigned int consumer_index(struct rxe_queue *q,
+-                                              enum queue_type type)
++static inline void *queue_consumer_addr(struct rxe_queue *q,
++                                      enum queue_type type)
+ {
+-      u32 cons;
+-
+-      switch (type) {
+-      case QUEUE_TYPE_FROM_USER:
+-              cons = q->index;
+-              break;
+-      case QUEUE_TYPE_TO_USER:
+-              /* protect user space index */
+-              cons = smp_load_acquire(&q->buf->consumer_index);
+-              cons &= q->index_mask;
+-              break;
+-      case QUEUE_TYPE_KERNEL:
+-              cons = q->buf->consumer_index;
+-              break;
+-      }
++      u32 cons = queue_get_consumer(q, type);
+-      return cons;
++      return q->buf->data + (cons << q->log2_elem_size);
+ }
+-static inline void *addr_from_index(struct rxe_queue *q,
+-                              unsigned int index)
++static inline void *queue_addr_from_index(struct rxe_queue *q, u32 index)
+ {
+       return q->buf->data + ((index & q->index_mask)
+-                              << q->buf->log2_elem_size);
++                              << q->log2_elem_size);
+ }
+-static inline unsigned int index_from_addr(const struct rxe_queue *q,
++static inline u32 queue_index_from_addr(const struct rxe_queue *q,
+                               const void *addr)
+ {
+       return (((u8 *)addr - q->buf->data) >> q->log2_elem_size)
+@@ -309,7 +255,7 @@ static inline unsigned int index_from_addr(const struct rxe_queue *q,
+ static inline void *queue_head(struct rxe_queue *q, enum queue_type type)
+ {
+-      return queue_empty(q, type) ? NULL : consumer_addr(q, type);
++      return queue_empty(q, type) ? NULL : queue_consumer_addr(q, type);
+ }
+ #endif /* RXE_QUEUE_H */
+diff --git a/drivers/infiniband/sw/rxe/rxe_req.c b/drivers/infiniband/sw/rxe/rxe_req.c
+index 4ea9319f0d52..8c0e7ecd4141 100644
+--- a/drivers/infiniband/sw/rxe/rxe_req.c
++++ b/drivers/infiniband/sw/rxe/rxe_req.c
+@@ -49,21 +49,16 @@ static void req_retry(struct rxe_qp *qp)
+       unsigned int cons;
+       unsigned int prod;
+-      if (qp->is_user) {
+-              cons = consumer_index(q, QUEUE_TYPE_FROM_USER);
+-              prod = producer_index(q, QUEUE_TYPE_FROM_USER);
+-      } else {
+-              cons = consumer_index(q, QUEUE_TYPE_KERNEL);
+-              prod = producer_index(q, QUEUE_TYPE_KERNEL);
+-      }
++      cons = queue_get_consumer(q, QUEUE_TYPE_FROM_CLIENT);
++      prod = queue_get_producer(q, QUEUE_TYPE_FROM_CLIENT);
+       qp->req.wqe_index       = cons;
+       qp->req.psn             = qp->comp.psn;
+       qp->req.opcode          = -1;
+       for (wqe_index = cons; wqe_index != prod;
+-                      wqe_index = next_index(q, wqe_index)) {
+-              wqe = addr_from_index(qp->sq.queue, wqe_index);
++                      wqe_index = queue_next_index(q, wqe_index)) {
++              wqe = queue_addr_from_index(qp->sq.queue, wqe_index);
+               mask = wr_opcode_mask(wqe->wr.opcode, qp);
+               if (wqe->state == wqe_state_posted)
+@@ -121,15 +116,9 @@ static struct rxe_send_wqe *req_next_wqe(struct rxe_qp *qp)
+       unsigned int cons;
+       unsigned int prod;
+-      if (qp->is_user) {
+-              wqe = queue_head(q, QUEUE_TYPE_FROM_USER);
+-              cons = consumer_index(q, QUEUE_TYPE_FROM_USER);
+-              prod = producer_index(q, QUEUE_TYPE_FROM_USER);
+-      } else {
+-              wqe = queue_head(q, QUEUE_TYPE_KERNEL);
+-              cons = consumer_index(q, QUEUE_TYPE_KERNEL);
+-              prod = producer_index(q, QUEUE_TYPE_KERNEL);
+-      }
++      wqe = queue_head(q, QUEUE_TYPE_FROM_CLIENT);
++      cons = queue_get_consumer(q, QUEUE_TYPE_FROM_CLIENT);
++      prod = queue_get_producer(q, QUEUE_TYPE_FROM_CLIENT);
+       if (unlikely(qp->req.state == QP_STATE_DRAIN)) {
+               /* check to see if we are drained;
+@@ -170,7 +159,7 @@ static struct rxe_send_wqe *req_next_wqe(struct rxe_qp *qp)
+       if (index == prod)
+               return NULL;
+-      wqe = addr_from_index(q, index);
++      wqe = queue_addr_from_index(q, index);
+       if (unlikely((qp->req.state == QP_STATE_DRAIN ||
+                     qp->req.state == QP_STATE_DRAINED) &&
+@@ -560,7 +549,8 @@ static void update_state(struct rxe_qp *qp, struct rxe_send_wqe *wqe,
+       qp->req.opcode = pkt->opcode;
+       if (pkt->mask & RXE_END_MASK)
+-              qp->req.wqe_index = next_index(qp->sq.queue, qp->req.wqe_index);
++              qp->req.wqe_index = queue_next_index(qp->sq.queue,
++                                                   qp->req.wqe_index);
+       qp->need_req_skb = 0;
+@@ -610,7 +600,7 @@ static int rxe_do_local_ops(struct rxe_qp *qp, struct rxe_send_wqe *wqe)
+       wqe->state = wqe_state_done;
+       wqe->status = IB_WC_SUCCESS;
+-      qp->req.wqe_index = next_index(qp->sq.queue, qp->req.wqe_index);
++      qp->req.wqe_index = queue_next_index(qp->sq.queue, qp->req.wqe_index);
+       /* There is no ack coming for local work requests
+        * which can lead to a deadlock. So go ahead and complete
+@@ -643,7 +633,8 @@ int rxe_requester(void *arg)
+               goto exit;
+       if (unlikely(qp->req.state == QP_STATE_RESET)) {
+-              qp->req.wqe_index = consumer_index(q, q->type);
++              qp->req.wqe_index = queue_get_consumer(q,
++                                              QUEUE_TYPE_FROM_CLIENT);
+               qp->req.opcode = -1;
+               qp->req.need_rd_atomic = 0;
+               qp->req.wait_psn = 0;
+@@ -709,7 +700,7 @@ int rxe_requester(void *arg)
+                       wqe->last_psn = qp->req.psn;
+                       qp->req.psn = (qp->req.psn + 1) & BTH_PSN_MASK;
+                       qp->req.opcode = IB_OPCODE_UD_SEND_ONLY;
+-                      qp->req.wqe_index = next_index(qp->sq.queue,
++                      qp->req.wqe_index = queue_next_index(qp->sq.queue,
+                                                      qp->req.wqe_index);
+                       wqe->state = wqe_state_done;
+                       wqe->status = IB_WC_SUCCESS;
+diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c
+index 8ed172ab0beb..e7dec8481061 100644
+--- a/drivers/infiniband/sw/rxe/rxe_resp.c
++++ b/drivers/infiniband/sw/rxe/rxe_resp.c
+@@ -303,10 +303,7 @@ static enum resp_states get_srq_wqe(struct rxe_qp *qp)
+       spin_lock_bh(&srq->rq.consumer_lock);
+-      if (qp->is_user)
+-              wqe = queue_head(q, QUEUE_TYPE_FROM_USER);
+-      else
+-              wqe = queue_head(q, QUEUE_TYPE_KERNEL);
++      wqe = queue_head(q, QUEUE_TYPE_FROM_CLIENT);
+       if (!wqe) {
+               spin_unlock_bh(&srq->rq.consumer_lock);
+               return RESPST_ERR_RNR;
+@@ -322,13 +319,8 @@ static enum resp_states get_srq_wqe(struct rxe_qp *qp)
+       memcpy(&qp->resp.srq_wqe, wqe, size);
+       qp->resp.wqe = &qp->resp.srq_wqe.wqe;
+-      if (qp->is_user) {
+-              advance_consumer(q, QUEUE_TYPE_FROM_USER);
+-              count = queue_count(q, QUEUE_TYPE_FROM_USER);
+-      } else {
+-              advance_consumer(q, QUEUE_TYPE_KERNEL);
+-              count = queue_count(q, QUEUE_TYPE_KERNEL);
+-      }
++      queue_advance_consumer(q, QUEUE_TYPE_FROM_CLIENT);
++      count = queue_count(q, QUEUE_TYPE_FROM_CLIENT);
+       if (srq->limit && srq->ibsrq.event_handler && (count < srq->limit)) {
+               srq->limit = 0;
+@@ -357,12 +349,8 @@ static enum resp_states check_resource(struct rxe_qp *qp,
+                       qp->resp.status = IB_WC_WR_FLUSH_ERR;
+                       return RESPST_COMPLETE;
+               } else if (!srq) {
+-                      if (qp->is_user)
+-                              qp->resp.wqe = queue_head(qp->rq.queue,
+-                                              QUEUE_TYPE_FROM_USER);
+-                      else
+-                              qp->resp.wqe = queue_head(qp->rq.queue,
+-                                              QUEUE_TYPE_KERNEL);
++                      qp->resp.wqe = queue_head(qp->rq.queue,
++                                      QUEUE_TYPE_FROM_CLIENT);
+                       if (qp->resp.wqe) {
+                               qp->resp.status = IB_WC_WR_FLUSH_ERR;
+                               return RESPST_COMPLETE;
+@@ -389,12 +377,8 @@ static enum resp_states check_resource(struct rxe_qp *qp,
+               if (srq)
+                       return get_srq_wqe(qp);
+-              if (qp->is_user)
+-                      qp->resp.wqe = queue_head(qp->rq.queue,
+-                                      QUEUE_TYPE_FROM_USER);
+-              else
+-                      qp->resp.wqe = queue_head(qp->rq.queue,
+-                                      QUEUE_TYPE_KERNEL);
++              qp->resp.wqe = queue_head(qp->rq.queue,
++                              QUEUE_TYPE_FROM_CLIENT);
+               return (qp->resp.wqe) ? RESPST_CHK_LENGTH : RESPST_ERR_RNR;
+       }
+@@ -938,12 +922,8 @@ static enum resp_states do_complete(struct rxe_qp *qp,
+       }
+       /* have copy for srq and reference for !srq */
+-      if (!qp->srq) {
+-              if (qp->is_user)
+-                      advance_consumer(qp->rq.queue, QUEUE_TYPE_FROM_USER);
+-              else
+-                      advance_consumer(qp->rq.queue, QUEUE_TYPE_KERNEL);
+-      }
++      if (!qp->srq)
++              queue_advance_consumer(qp->rq.queue, QUEUE_TYPE_FROM_CLIENT);
+       qp->resp.wqe = NULL;
+@@ -1215,7 +1195,7 @@ static void rxe_drain_req_pkts(struct rxe_qp *qp, bool notify)
+               return;
+       while (!qp->srq && q && queue_head(q, q->type))
+-              advance_consumer(q, q->type);
++              queue_advance_consumer(q, q->type);
+ }
+ int rxe_responder(void *arg)
+diff --git a/drivers/infiniband/sw/rxe/rxe_srq.c b/drivers/infiniband/sw/rxe/rxe_srq.c
+index 610c98d24b5c..a9e7817e2732 100644
+--- a/drivers/infiniband/sw/rxe/rxe_srq.c
++++ b/drivers/infiniband/sw/rxe/rxe_srq.c
+@@ -93,7 +93,7 @@ int rxe_srq_from_init(struct rxe_dev *rxe, struct rxe_srq *srq,
+       spin_lock_init(&srq->rq.producer_lock);
+       spin_lock_init(&srq->rq.consumer_lock);
+-      type = uresp ? QUEUE_TYPE_FROM_USER : QUEUE_TYPE_KERNEL;
++      type = QUEUE_TYPE_FROM_CLIENT;
+       q = rxe_queue_init(rxe, &srq->rq.max_wr,
+                       srq_wqe_size, type);
+       if (!q) {
+diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c
+index 267b5a9c345d..46eaa1c5d4b3 100644
+--- a/drivers/infiniband/sw/rxe/rxe_verbs.c
++++ b/drivers/infiniband/sw/rxe/rxe_verbs.c
+@@ -218,11 +218,7 @@ static int post_one_recv(struct rxe_rq *rq, const struct ib_recv_wr *ibwr)
+       int num_sge = ibwr->num_sge;
+       int full;
+-      if (rq->is_user)
+-              full = queue_full(rq->queue, QUEUE_TYPE_FROM_USER);
+-      else
+-              full = queue_full(rq->queue, QUEUE_TYPE_KERNEL);
+-
++      full = queue_full(rq->queue, QUEUE_TYPE_TO_DRIVER);
+       if (unlikely(full)) {
+               err = -ENOMEM;
+               goto err1;
+@@ -237,11 +233,7 @@ static int post_one_recv(struct rxe_rq *rq, const struct ib_recv_wr *ibwr)
+       for (i = 0; i < num_sge; i++)
+               length += ibwr->sg_list[i].length;
+-      if (rq->is_user)
+-              recv_wqe = producer_addr(rq->queue, QUEUE_TYPE_FROM_USER);
+-      else
+-              recv_wqe = producer_addr(rq->queue, QUEUE_TYPE_KERNEL);
+-
++      recv_wqe = queue_producer_addr(rq->queue, QUEUE_TYPE_TO_DRIVER);
+       recv_wqe->wr_id = ibwr->wr_id;
+       recv_wqe->num_sge = num_sge;
+@@ -254,10 +246,7 @@ static int post_one_recv(struct rxe_rq *rq, const struct ib_recv_wr *ibwr)
+       recv_wqe->dma.cur_sge           = 0;
+       recv_wqe->dma.sge_offset        = 0;
+-      if (rq->is_user)
+-              advance_producer(rq->queue, QUEUE_TYPE_FROM_USER);
+-      else
+-              advance_producer(rq->queue, QUEUE_TYPE_KERNEL);
++      queue_advance_producer(rq->queue, QUEUE_TYPE_TO_DRIVER);
+       return 0;
+@@ -633,27 +622,17 @@ static int post_one_send(struct rxe_qp *qp, const struct ib_send_wr *ibwr,
+       spin_lock_irqsave(&qp->sq.sq_lock, flags);
+-      if (qp->is_user)
+-              full = queue_full(sq->queue, QUEUE_TYPE_FROM_USER);
+-      else
+-              full = queue_full(sq->queue, QUEUE_TYPE_KERNEL);
++      full = queue_full(sq->queue, QUEUE_TYPE_TO_DRIVER);
+       if (unlikely(full)) {
+               spin_unlock_irqrestore(&qp->sq.sq_lock, flags);
+               return -ENOMEM;
+       }
+-      if (qp->is_user)
+-              send_wqe = producer_addr(sq->queue, QUEUE_TYPE_FROM_USER);
+-      else
+-              send_wqe = producer_addr(sq->queue, QUEUE_TYPE_KERNEL);
+-
++      send_wqe = queue_producer_addr(sq->queue, QUEUE_TYPE_TO_DRIVER);
+       init_send_wqe(qp, ibwr, mask, length, send_wqe);
+-      if (qp->is_user)
+-              advance_producer(sq->queue, QUEUE_TYPE_FROM_USER);
+-      else
+-              advance_producer(sq->queue, QUEUE_TYPE_KERNEL);
++      queue_advance_producer(sq->queue, QUEUE_TYPE_TO_DRIVER);
+       spin_unlock_irqrestore(&qp->sq.sq_lock, flags);
+@@ -845,18 +824,12 @@ static int rxe_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc)
+       spin_lock_irqsave(&cq->cq_lock, flags);
+       for (i = 0; i < num_entries; i++) {
+-              if (cq->is_user)
+-                      cqe = queue_head(cq->queue, QUEUE_TYPE_TO_USER);
+-              else
+-                      cqe = queue_head(cq->queue, QUEUE_TYPE_KERNEL);
++              cqe = queue_head(cq->queue, QUEUE_TYPE_FROM_DRIVER);
+               if (!cqe)
+                       break;
+               memcpy(wc++, &cqe->ibwc, sizeof(*wc));
+-              if (cq->is_user)
+-                      advance_consumer(cq->queue, QUEUE_TYPE_TO_USER);
+-              else
+-                      advance_consumer(cq->queue, QUEUE_TYPE_KERNEL);
++              queue_advance_consumer(cq->queue, QUEUE_TYPE_FROM_DRIVER);
+       }
+       spin_unlock_irqrestore(&cq->cq_lock, flags);
+@@ -868,10 +841,7 @@ static int rxe_peek_cq(struct ib_cq *ibcq, int wc_cnt)
+       struct rxe_cq *cq = to_rcq(ibcq);
+       int count;
+-      if (cq->is_user)
+-              count = queue_count(cq->queue, QUEUE_TYPE_TO_USER);
+-      else
+-              count = queue_count(cq->queue, QUEUE_TYPE_KERNEL);
++      count = queue_count(cq->queue, QUEUE_TYPE_FROM_DRIVER);
+       return (count > wc_cnt) ? wc_cnt : count;
+ }
+@@ -887,10 +857,7 @@ static int rxe_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags)
+       if (cq->notify != IB_CQ_NEXT_COMP)
+               cq->notify = flags & IB_CQ_SOLICITED_MASK;
+-      if (cq->is_user)
+-              empty = queue_empty(cq->queue, QUEUE_TYPE_TO_USER);
+-      else
+-              empty = queue_empty(cq->queue, QUEUE_TYPE_KERNEL);
++      empty = queue_empty(cq->queue, QUEUE_TYPE_FROM_DRIVER);
+       if ((flags & IB_CQ_REPORT_MISSED_EVENTS) && !empty)
+               ret = 1;
+-- 
+2.35.1
+
diff --git a/queue-5.15/rdma-rxe-fix-deadlock-in-rxe_do_local_ops.patch b/queue-5.15/rdma-rxe-fix-deadlock-in-rxe_do_local_ops.patch
new file mode 100644 (file)
index 0000000..745f2eb
--- /dev/null
@@ -0,0 +1,54 @@
+From c22a05ca9b7ace68f6fb8aec9ea70ca73359b3b8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 May 2022 17:32:52 -0500
+Subject: RDMA/rxe: Fix deadlock in rxe_do_local_ops()
+
+From: Bob Pearson <rpearsonhpe@gmail.com>
+
+[ Upstream commit 7cb33d1bc1ac8e51fd88928f96674d392f8e07c4 ]
+
+When a local operation (invalidate mr, reg mr, bind mw) is finished there
+will be no ack packet coming from a responder to cause the wqe to be
+completed. This may happen anyway if a subsequent wqe performs
+IO. Currently if the wqe is signalled the completer tasklet is scheduled
+immediately but not otherwise.
+
+This leads to a deadlock if the next wqe has the fence bit set in send
+flags and the operation is not signalled. This patch removes the condition
+that the wqe must be signalled in order to schedule the completer tasklet
+which is the simplest fix for this deadlock and is fairly low cost. This
+is the analog for local operations of always setting the ackreq bit in all
+last or only request packets even if the operation is not signalled.
+
+Link: https://lore.kernel.org/r/20220523223251.15350-1-rpearsonhpe@gmail.com
+Reported-by: Jenny Hack <jhack@hpe.com>
+Fixes: c1a411268a4b ("RDMA/rxe: Move local ops to subroutine")
+Signed-off-by: Bob Pearson <rpearsonhpe@gmail.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/rxe/rxe_req.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/infiniband/sw/rxe/rxe_req.c b/drivers/infiniband/sw/rxe/rxe_req.c
+index 7812e3d6a6c2..4ea9319f0d52 100644
+--- a/drivers/infiniband/sw/rxe/rxe_req.c
++++ b/drivers/infiniband/sw/rxe/rxe_req.c
+@@ -612,9 +612,11 @@ static int rxe_do_local_ops(struct rxe_qp *qp, struct rxe_send_wqe *wqe)
+       wqe->status = IB_WC_SUCCESS;
+       qp->req.wqe_index = next_index(qp->sq.queue, qp->req.wqe_index);
+-      if ((wqe->wr.send_flags & IB_SEND_SIGNALED) ||
+-          qp->sq_sig_type == IB_SIGNAL_ALL_WR)
+-              rxe_run_task(&qp->comp.task, 1);
++      /* There is no ack coming for local work requests
++       * which can lead to a deadlock. So go ahead and complete
++       * it now.
++       */
++      rxe_run_task(&qp->comp.task, 1);
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/rdma-rxe-fix-error-unwind-in-rxe_create_qp.patch b/queue-5.15/rdma-rxe-fix-error-unwind-in-rxe_create_qp.patch
new file mode 100644 (file)
index 0000000..a752c4d
--- /dev/null
@@ -0,0 +1,69 @@
+From f564476e7b4b53fdca7f1e436e85484709e5a882 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 31 Jul 2022 02:36:21 -0400
+Subject: RDMA/rxe: Fix error unwind in rxe_create_qp()
+
+From: Zhu Yanjun <yanjun.zhu@linux.dev>
+
+[ Upstream commit fd5382c5805c4bcb50fd25b7246247d3f7114733 ]
+
+In the function rxe_create_qp(), rxe_qp_from_init() is called to
+initialize qp, internally things like the spin locks are not setup until
+rxe_qp_init_req().
+
+If an error occures before this point then the unwind will call
+rxe_cleanup() and eventually to rxe_qp_do_cleanup()/rxe_cleanup_task()
+which will oops when trying to access the uninitialized spinlock.
+
+Move the spinlock initializations earlier before any failures.
+
+Fixes: 8700e3e7c485 ("Soft RoCE driver")
+Link: https://lore.kernel.org/r/20220731063621.298405-1-yanjun.zhu@linux.dev
+Reported-by: syzbot+833061116fa28df97f3b@syzkaller.appspotmail.com
+Signed-off-by: Zhu Yanjun <yanjun.zhu@linux.dev>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/rxe/rxe_qp.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c
+index 5731bc15991c..661b83d65af3 100644
+--- a/drivers/infiniband/sw/rxe/rxe_qp.c
++++ b/drivers/infiniband/sw/rxe/rxe_qp.c
+@@ -195,6 +195,14 @@ static void rxe_qp_init_misc(struct rxe_dev *rxe, struct rxe_qp *qp,
+       spin_lock_init(&qp->grp_lock);
+       spin_lock_init(&qp->state_lock);
++      spin_lock_init(&qp->req.task.state_lock);
++      spin_lock_init(&qp->resp.task.state_lock);
++      spin_lock_init(&qp->comp.task.state_lock);
++
++      spin_lock_init(&qp->sq.sq_lock);
++      spin_lock_init(&qp->rq.producer_lock);
++      spin_lock_init(&qp->rq.consumer_lock);
++
+       atomic_set(&qp->ssn, 0);
+       atomic_set(&qp->skb_out, 0);
+ }
+@@ -255,7 +263,6 @@ static int rxe_qp_init_req(struct rxe_dev *rxe, struct rxe_qp *qp,
+       qp->req.opcode          = -1;
+       qp->comp.opcode         = -1;
+-      spin_lock_init(&qp->sq.sq_lock);
+       skb_queue_head_init(&qp->req_pkts);
+       rxe_init_task(rxe, &qp->req.task, qp,
+@@ -306,9 +313,6 @@ static int rxe_qp_init_resp(struct rxe_dev *rxe, struct rxe_qp *qp,
+               }
+       }
+-      spin_lock_init(&qp->rq.producer_lock);
+-      spin_lock_init(&qp->rq.consumer_lock);
+-
+       skb_queue_head_init(&qp->resp_pkts);
+       rxe_init_task(rxe, &qp->resp.task, qp,
+-- 
+2.35.1
+
diff --git a/queue-5.15/rdma-rxe-fix-mw-bind-to-allow-any-consumer-key-porti.patch b/queue-5.15/rdma-rxe-fix-mw-bind-to-allow-any-consumer-key-porti.patch
new file mode 100644 (file)
index 0000000..98e8cd6
--- /dev/null
@@ -0,0 +1,52 @@
+From 120db268ec26593ee30d7e2093f0a0ed3f0c7739 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 15:46:20 -0500
+Subject: RDMA/rxe: Fix mw bind to allow any consumer key portion
+
+From: Bob Pearson <rpearsonhpe@gmail.com>
+
+[ Upstream commit 1603f89935ec86d40a7667e1250392626976ccc2 ]
+
+The current implementation of rxe_check_bind_mw() in rxe_mw.c is incorrect
+since it requires the new key portion provided by the mw consumer to be
+different than the previous key portion. This is not required by the
+IBA. Remove the test.
+
+Link: https://lore.kernel.org/linux-rdma/fb4614e7-4cac-0dc7-3ef7-766dfd10e8f2@gmail.com/
+Fixes: 32a577b4c3a9 ("Add support for bind MW work requests")
+Link: https://lore.kernel.org/r/20220714204619.13396-1-rpearsonhpe@gmail.com
+Signed-off-by: Bob Pearson <rpearsonhpe@gmail.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/rxe/rxe_mw.c | 7 -------
+ 1 file changed, 7 deletions(-)
+
+diff --git a/drivers/infiniband/sw/rxe/rxe_mw.c b/drivers/infiniband/sw/rxe/rxe_mw.c
+index a5e2ea7d80f0..933a0b29275b 100644
+--- a/drivers/infiniband/sw/rxe/rxe_mw.c
++++ b/drivers/infiniband/sw/rxe/rxe_mw.c
+@@ -71,8 +71,6 @@ int rxe_dealloc_mw(struct ib_mw *ibmw)
+ static int rxe_check_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe,
+                        struct rxe_mw *mw, struct rxe_mr *mr)
+ {
+-      u32 key = wqe->wr.wr.mw.rkey & 0xff;
+-
+       if (mw->ibmw.type == IB_MW_TYPE_1) {
+               if (unlikely(mw->state != RXE_MW_STATE_VALID)) {
+                       pr_err_once(
+@@ -110,11 +108,6 @@ static int rxe_check_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe,
+               }
+       }
+-      if (unlikely(key == (mw->rkey & 0xff))) {
+-              pr_err_once("attempt to bind MW with same key\n");
+-              return -EINVAL;
+-      }
+-
+       /* remaining checks only apply to a nonzero MR */
+       if (!mr)
+               return 0;
+-- 
+2.35.1
+
diff --git a/queue-5.15/rdma-rxe-for-invalidate-compare-according-to-set-key.patch b/queue-5.15/rdma-rxe-for-invalidate-compare-according-to-set-key.patch
new file mode 100644 (file)
index 0000000..70362a4
--- /dev/null
@@ -0,0 +1,79 @@
+From c01c9bc7b45914080951f264b562ad180322478d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Jul 2022 09:30:06 +0200
+Subject: RDMA/rxe: For invalidate compare according to set keys in mr
+
+From: Md Haris Iqbal <haris.phnx@gmail.com>
+
+[ Upstream commit 174e7b137042f19b5ce88beb4fc0ff4ec6b0c72a ]
+
+The 'rkey' input can be an lkey or rkey, and in rxe the lkey or rkey have
+the same value, including the variant bits.
+
+So, if mr->rkey is set, compare the invalidate key with it, otherwise
+compare with the mr->lkey.
+
+Since we already did a lookup on the non-varient bits to get this far, the
+check's only purpose is to confirm that the wqe has the correct variant
+bits.
+
+Fixes: 001345339f4c ("RDMA/rxe: Separate HW and SW l/rkeys")
+Link: https://lore.kernel.org/r/20220707073006.328737-1-haris.phnx@gmail.com
+Signed-off-by: Md Haris Iqbal <haris.phnx@gmail.com>
+Reviewed-by: Bob Pearson <rpearsonhpe@gmail.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/rxe/rxe_loc.h |  2 +-
+ drivers/infiniband/sw/rxe/rxe_mr.c  | 12 ++++++------
+ 2 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/infiniband/sw/rxe/rxe_loc.h b/drivers/infiniband/sw/rxe/rxe_loc.h
+index 4fd73b51fabf..21bd969718bd 100644
+--- a/drivers/infiniband/sw/rxe/rxe_loc.h
++++ b/drivers/infiniband/sw/rxe/rxe_loc.h
+@@ -85,7 +85,7 @@ struct rxe_mr *lookup_mr(struct rxe_pd *pd, int access, u32 key,
+                        enum rxe_mr_lookup_type type);
+ int mr_check_range(struct rxe_mr *mr, u64 iova, size_t length);
+ int advance_dma_data(struct rxe_dma_info *dma, unsigned int length);
+-int rxe_invalidate_mr(struct rxe_qp *qp, u32 rkey);
++int rxe_invalidate_mr(struct rxe_qp *qp, u32 key);
+ int rxe_reg_fast_mr(struct rxe_qp *qp, struct rxe_send_wqe *wqe);
+ int rxe_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata);
+ void rxe_mr_cleanup(struct rxe_pool_entry *arg);
+diff --git a/drivers/infiniband/sw/rxe/rxe_mr.c b/drivers/infiniband/sw/rxe/rxe_mr.c
+index bedcf15aaea7..7c2e7b291b65 100644
+--- a/drivers/infiniband/sw/rxe/rxe_mr.c
++++ b/drivers/infiniband/sw/rxe/rxe_mr.c
+@@ -522,22 +522,22 @@ struct rxe_mr *lookup_mr(struct rxe_pd *pd, int access, u32 key,
+       return mr;
+ }
+-int rxe_invalidate_mr(struct rxe_qp *qp, u32 rkey)
++int rxe_invalidate_mr(struct rxe_qp *qp, u32 key)
+ {
+       struct rxe_dev *rxe = to_rdev(qp->ibqp.device);
+       struct rxe_mr *mr;
+       int ret;
+-      mr = rxe_pool_get_index(&rxe->mr_pool, rkey >> 8);
++      mr = rxe_pool_get_index(&rxe->mr_pool, key >> 8);
+       if (!mr) {
+-              pr_err("%s: No MR for rkey %#x\n", __func__, rkey);
++              pr_err("%s: No MR for key %#x\n", __func__, key);
+               ret = -EINVAL;
+               goto err;
+       }
+-      if (rkey != mr->rkey) {
+-              pr_err("%s: rkey (%#x) doesn't match mr->rkey (%#x)\n",
+-                      __func__, rkey, mr->rkey);
++      if (mr->rkey ? (key != mr->rkey) : (key != mr->lkey)) {
++              pr_err("%s: wr key (%#x) doesn't match mr key (%#x)\n",
++                      __func__, key, (mr->rkey ? mr->rkey : mr->lkey));
+               ret = -EINVAL;
+               goto err_drop_ref;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/rdma-rxe-remove-the-is_user-members-of-struct-rxe_sq.patch b/queue-5.15/rdma-rxe-remove-the-is_user-members-of-struct-rxe_sq.patch
new file mode 100644 (file)
index 0000000..38bc189
--- /dev/null
@@ -0,0 +1,94 @@
+From badfb3fadc2d09801198db77e6f850dd72e06e90 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Sep 2021 17:48:10 +0800
+Subject: RDMA/rxe: Remove the is_user members of struct rxe_sq/rxe_rq/rxe_srq
+
+From: Xiao Yang <yangx.jy@fujitsu.com>
+
+[ Upstream commit 1cf2ce8272802e677398fab47a73713bc6e1fd5c ]
+
+The is_user members of struct rxe_sq/rxe_rq/rxe_srq are unsed since
+commit ae6e843fe08d ("RDMA/rxe: Add memory barriers to kernel queues").
+In this case, it is fine to remove them directly.
+
+Link: https://lore.kernel.org/r/20210930094813.226888-2-yangx.jy@fujitsu.com
+Signed-off-by: Xiao Yang <yangx.jy@fujitsu.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/rxe/rxe_qp.c    | 2 --
+ drivers/infiniband/sw/rxe/rxe_srq.c   | 1 -
+ drivers/infiniband/sw/rxe/rxe_verbs.c | 3 ---
+ drivers/infiniband/sw/rxe/rxe_verbs.h | 3 ---
+ 4 files changed, 9 deletions(-)
+
+diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c
+index 0d6a3d363554..5731bc15991c 100644
+--- a/drivers/infiniband/sw/rxe/rxe_qp.c
++++ b/drivers/infiniband/sw/rxe/rxe_qp.c
+@@ -309,8 +309,6 @@ static int rxe_qp_init_resp(struct rxe_dev *rxe, struct rxe_qp *qp,
+       spin_lock_init(&qp->rq.producer_lock);
+       spin_lock_init(&qp->rq.consumer_lock);
+-      qp->rq.is_user = qp->is_user;
+-
+       skb_queue_head_init(&qp->resp_pkts);
+       rxe_init_task(rxe, &qp->resp.task, qp,
+diff --git a/drivers/infiniband/sw/rxe/rxe_srq.c b/drivers/infiniband/sw/rxe/rxe_srq.c
+index a9e7817e2732..eb1c4c3b3a78 100644
+--- a/drivers/infiniband/sw/rxe/rxe_srq.c
++++ b/drivers/infiniband/sw/rxe/rxe_srq.c
+@@ -86,7 +86,6 @@ int rxe_srq_from_init(struct rxe_dev *rxe, struct rxe_srq *srq,
+       srq->srq_num            = srq->pelem.index;
+       srq->rq.max_wr          = init->attr.max_wr;
+       srq->rq.max_sge         = init->attr.max_sge;
+-      srq->rq.is_user         = srq->is_user;
+       srq_wqe_size            = rcv_wqe_size(srq->rq.max_sge);
+diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c
+index 46eaa1c5d4b3..e40927cf5772 100644
+--- a/drivers/infiniband/sw/rxe/rxe_verbs.c
++++ b/drivers/infiniband/sw/rxe/rxe_verbs.c
+@@ -270,9 +270,6 @@ static int rxe_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *init,
+               if (udata->outlen < sizeof(*uresp))
+                       return -EINVAL;
+               uresp = udata->outbuf;
+-              srq->is_user = true;
+-      } else {
+-              srq->is_user = false;
+       }
+       err = rxe_srq_chk_attr(rxe, NULL, &init->attr, IB_SRQ_INIT_MASK);
+diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.h b/drivers/infiniband/sw/rxe/rxe_verbs.h
+index d90b1d77de34..c852a9907bad 100644
+--- a/drivers/infiniband/sw/rxe/rxe_verbs.h
++++ b/drivers/infiniband/sw/rxe/rxe_verbs.h
+@@ -77,7 +77,6 @@ enum wqe_state {
+ };
+ struct rxe_sq {
+-      bool                    is_user;
+       int                     max_wr;
+       int                     max_sge;
+       int                     max_inline;
+@@ -86,7 +85,6 @@ struct rxe_sq {
+ };
+ struct rxe_rq {
+-      bool                    is_user;
+       int                     max_wr;
+       int                     max_sge;
+       spinlock_t              producer_lock; /* guard queue producer */
+@@ -100,7 +98,6 @@ struct rxe_srq {
+       struct rxe_pd           *pd;
+       struct rxe_rq           rq;
+       u32                     srq_num;
+-      bool                    is_user;
+       int                     limit;
+       int                     error;
+-- 
+2.35.1
+
diff --git a/queue-5.15/rdma-siw-fix-duplicated-reported-iw_cm_event_connect.patch b/queue-5.15/rdma-siw-fix-duplicated-reported-iw_cm_event_connect.patch
new file mode 100644 (file)
index 0000000..57711de
--- /dev/null
@@ -0,0 +1,73 @@
+From 31caad5f5e3be79dc7c8e7ff953bb5c80c0d58bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 09:30:47 +0800
+Subject: RDMA/siw: Fix duplicated reported IW_CM_EVENT_CONNECT_REPLY event
+
+From: Cheng Xu <chengyou@linux.alibaba.com>
+
+[ Upstream commit 3056fc6c32e613b760422b94c7617ac9a24a4721 ]
+
+If siw_recv_mpa_rr returns -EAGAIN, it means that the MPA reply hasn't
+been received completely, and should not report IW_CM_EVENT_CONNECT_REPLY
+in this case. This may trigger a call trace in iw_cm. A simple way to
+trigger this:
+ server: ib_send_lat
+ client: ib_send_lat -R <server_ip>
+
+The call trace looks like this:
+
+ kernel BUG at drivers/infiniband/core/iwcm.c:894!
+ invalid opcode: 0000 [#1] PREEMPT SMP NOPTI
+ <...>
+ Workqueue: iw_cm_wq cm_work_handler [iw_cm]
+ Call Trace:
+  <TASK>
+  cm_work_handler+0x1dd/0x370 [iw_cm]
+  process_one_work+0x1e2/0x3b0
+  worker_thread+0x49/0x2e0
+  ? rescuer_thread+0x370/0x370
+  kthread+0xe5/0x110
+  ? kthread_complete_and_exit+0x20/0x20
+  ret_from_fork+0x1f/0x30
+  </TASK>
+
+Fixes: 6c52fdc244b5 ("rdma/siw: connection management")
+Link: https://lore.kernel.org/r/dae34b5fd5c2ea2bd9744812c1d2653a34a94c67.1657706960.git.chengyou@linux.alibaba.com
+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/sw/siw/siw_cm.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/infiniband/sw/siw/siw_cm.c b/drivers/infiniband/sw/siw/siw_cm.c
+index 18a64ccbb0e5..69d639cab898 100644
+--- a/drivers/infiniband/sw/siw/siw_cm.c
++++ b/drivers/infiniband/sw/siw/siw_cm.c
+@@ -725,11 +725,11 @@ static int siw_proc_mpareply(struct siw_cep *cep)
+       enum mpa_v2_ctrl mpa_p2p_mode = MPA_V2_RDMA_NO_RTR;
+       rv = siw_recv_mpa_rr(cep);
+-      if (rv != -EAGAIN)
+-              siw_cancel_mpatimer(cep);
+       if (rv)
+               goto out_err;
++      siw_cancel_mpatimer(cep);
++
+       rep = &cep->mpa.hdr;
+       if (__mpa_rr_revision(rep->params.bits) > MPA_REVISION_2) {
+@@ -895,7 +895,8 @@ static int siw_proc_mpareply(struct siw_cep *cep)
+       }
+ out_err:
+-      siw_cm_upcall(cep, IW_CM_EVENT_CONNECT_REPLY, -EINVAL);
++      if (rv != -EAGAIN)
++              siw_cm_upcall(cep, IW_CM_EVENT_CONNECT_REPLY, -EINVAL);
+       return rv;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/rdma-srpt-duplicate-port-name-members.patch b/queue-5.15/rdma-srpt-duplicate-port-name-members.patch
new file mode 100644 (file)
index 0000000..4130d5d
--- /dev/null
@@ -0,0 +1,85 @@
+From 097898b9eea5d1fdb110135e7dceb5e401cad117 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Jul 2022 12:34:13 -0700
+Subject: RDMA/srpt: Duplicate port name members
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit b03b1ae2a3125d4475452e4f19f5d3a6e910ff6e ]
+
+Prepare for decoupling the lifetimes of struct srpt_port and struct
+srpt_port_id by duplicating the port name into struct srpt_port.
+
+Link: https://lore.kernel.org/r/20220727193415.1583860-2-bvanassche@acm.org
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/srpt/ib_srpt.c |  9 ++++++---
+ drivers/infiniband/ulp/srpt/ib_srpt.h | 10 +++++++---
+ 2 files changed, 13 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
+index 3cadf1295417..d36873e6d8fa 100644
+--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
++++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
+@@ -566,14 +566,17 @@ static int srpt_refresh_port(struct srpt_port *sport)
+               return ret;
+       sport->port_guid_id.wwn.priv = sport;
+-      srpt_format_guid(sport->port_guid_id.name,
+-                       sizeof(sport->port_guid_id.name),
++      srpt_format_guid(sport->guid_name, ARRAY_SIZE(sport->guid_name),
+                        &sport->gid.global.interface_id);
++      memcpy(sport->port_guid_id.name, sport->guid_name,
++             ARRAY_SIZE(sport->guid_name));
+       sport->port_gid_id.wwn.priv = sport;
+-      snprintf(sport->port_gid_id.name, sizeof(sport->port_gid_id.name),
++      snprintf(sport->gid_name, ARRAY_SIZE(sport->gid_name),
+                "0x%016llx%016llx",
+                be64_to_cpu(sport->gid.global.subnet_prefix),
+                be64_to_cpu(sport->gid.global.interface_id));
++      memcpy(sport->port_gid_id.name, sport->gid_name,
++             ARRAY_SIZE(sport->gid_name));
+       if (rdma_protocol_iwarp(sport->sdev->device, sport->port))
+               return 0;
+diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.h b/drivers/infiniband/ulp/srpt/ib_srpt.h
+index 76e66f630c17..3844a7058559 100644
+--- a/drivers/infiniband/ulp/srpt/ib_srpt.h
++++ b/drivers/infiniband/ulp/srpt/ib_srpt.h
+@@ -376,7 +376,7 @@ struct srpt_tpg {
+ };
+ /**
+- * struct srpt_port_id - information about an RDMA port name
++ * struct srpt_port_id - LIO RDMA port information
+  * @mutex:    Protects @tpg_list changes.
+  * @tpg_list: TPGs associated with the RDMA port name.
+  * @wwn:      WWN associated with the RDMA port name.
+@@ -402,8 +402,10 @@ struct srpt_port_id {
+  * @lid:       cached value of the port's lid.
+  * @gid:       cached value of the port's gid.
+  * @work:      work structure for refreshing the aforementioned cached values.
+- * @port_guid_id: target port GUID
+- * @port_gid_id: target port GID
++ * @guid_name: port name in GUID format.
++ * @port_guid_id: LIO target port information for the port name in GUID format.
++ * @gid_name:  port name in GID format.
++ * @port_gid_id: LIO target port information for the port name in GID format.
+  * @port_attrib:   Port attributes that can be accessed through configfs.
+  * @refcount:    Number of objects associated with this port.
+  * @freed_channels: Completion that will be signaled once @refcount becomes 0.
+@@ -419,7 +421,9 @@ struct srpt_port {
+       u32                     lid;
+       union ib_gid            gid;
+       struct work_struct      work;
++      char                    guid_name[64];
+       struct srpt_port_id     port_guid_id;
++      char                    gid_name[64];
+       struct srpt_port_id     port_gid_id;
+       struct srpt_port_attrib port_attrib;
+       atomic_t                refcount;
+-- 
+2.35.1
+
diff --git a/queue-5.15/rdma-srpt-fix-a-use-after-free.patch b/queue-5.15/rdma-srpt-fix-a-use-after-free.patch
new file mode 100644 (file)
index 0000000..14cac1a
--- /dev/null
@@ -0,0 +1,306 @@
+From eb09c8b8cc21e8d41ad365b4858d124560f4ba65 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Jul 2022 12:34:15 -0700
+Subject: RDMA/srpt: Fix a use-after-free
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit b5605148e6ce36bb21020d49010b617693933128 ]
+
+Change the LIO port members inside struct srpt_port from regular members
+into pointers. Allocate the LIO port data structures from inside
+srpt_make_tport() and free these from inside srpt_make_tport(). Keep
+struct srpt_device as long as either an RDMA port or a LIO target port is
+associated with it. This patch decouples the lifetime of struct srpt_port
+(controlled by the RDMA core) and struct srpt_port_id (controlled by LIO).
+This patch fixes the following KASAN complaint:
+
+  BUG: KASAN: use-after-free in srpt_enable_tpg+0x31/0x70 [ib_srpt]
+  Read of size 8 at addr ffff888141cc34b8 by task check/5093
+
+  Call Trace:
+   <TASK>
+   show_stack+0x4e/0x53
+   dump_stack_lvl+0x51/0x66
+   print_address_description.constprop.0.cold+0xea/0x41e
+   print_report.cold+0x90/0x205
+   kasan_report+0xb9/0xf0
+   __asan_load8+0x69/0x90
+   srpt_enable_tpg+0x31/0x70 [ib_srpt]
+   target_fabric_tpg_base_enable_store+0xe2/0x140 [target_core_mod]
+   configfs_write_iter+0x18b/0x210
+   new_sync_write+0x1f2/0x2f0
+   vfs_write+0x3e3/0x540
+   ksys_write+0xbb/0x140
+   __x64_sys_write+0x42/0x50
+   do_syscall_64+0x34/0x80
+   entry_SYSCALL_64_after_hwframe+0x46/0xb0
+   </TASK>
+
+Link: https://lore.kernel.org/r/20220727193415.1583860-4-bvanassche@acm.org
+Reported-by: Li Zhijian <lizhijian@fujitsu.com>
+Tested-by: Li Zhijian <lizhijian@fujitsu.com>
+Fixes: a42d985bd5b2 ("ib_srpt: Initial SRP Target merge for v3.3-rc1")
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/srpt/ib_srpt.c | 130 ++++++++++++++++++--------
+ drivers/infiniband/ulp/srpt/ib_srpt.h |  10 +-
+ 2 files changed, 94 insertions(+), 46 deletions(-)
+
+diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
+index b59fc584de18..7b69b0c9e48d 100644
+--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
++++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
+@@ -565,18 +565,12 @@ static int srpt_refresh_port(struct srpt_port *sport)
+       if (ret)
+               return ret;
+-      sport->port_guid_id.wwn.priv = sport;
+       srpt_format_guid(sport->guid_name, ARRAY_SIZE(sport->guid_name),
+                        &sport->gid.global.interface_id);
+-      memcpy(sport->port_guid_id.name, sport->guid_name,
+-             ARRAY_SIZE(sport->guid_name));
+-      sport->port_gid_id.wwn.priv = sport;
+       snprintf(sport->gid_name, ARRAY_SIZE(sport->gid_name),
+                "0x%016llx%016llx",
+                be64_to_cpu(sport->gid.global.subnet_prefix),
+                be64_to_cpu(sport->gid.global.interface_id));
+-      memcpy(sport->port_gid_id.name, sport->gid_name,
+-             ARRAY_SIZE(sport->gid_name));
+       if (rdma_protocol_iwarp(sport->sdev->device, sport->port))
+               return 0;
+@@ -2317,31 +2311,35 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev,
+       tag_num = ch->rq_size;
+       tag_size = 1; /* ib_srpt does not use se_sess->sess_cmd_map */
+-      mutex_lock(&sport->port_guid_id.mutex);
+-      list_for_each_entry(stpg, &sport->port_guid_id.tpg_list, entry) {
+-              if (!IS_ERR_OR_NULL(ch->sess))
+-                      break;
+-              ch->sess = target_setup_session(&stpg->tpg, tag_num,
++      if (sport->guid_id) {
++              mutex_lock(&sport->guid_id->mutex);
++              list_for_each_entry(stpg, &sport->guid_id->tpg_list, entry) {
++                      if (!IS_ERR_OR_NULL(ch->sess))
++                              break;
++                      ch->sess = target_setup_session(&stpg->tpg, tag_num,
+                                               tag_size, TARGET_PROT_NORMAL,
+                                               ch->sess_name, ch, NULL);
++              }
++              mutex_unlock(&sport->guid_id->mutex);
+       }
+-      mutex_unlock(&sport->port_guid_id.mutex);
+-      mutex_lock(&sport->port_gid_id.mutex);
+-      list_for_each_entry(stpg, &sport->port_gid_id.tpg_list, entry) {
+-              if (!IS_ERR_OR_NULL(ch->sess))
+-                      break;
+-              ch->sess = target_setup_session(&stpg->tpg, tag_num,
++      if (sport->gid_id) {
++              mutex_lock(&sport->gid_id->mutex);
++              list_for_each_entry(stpg, &sport->gid_id->tpg_list, entry) {
++                      if (!IS_ERR_OR_NULL(ch->sess))
++                              break;
++                      ch->sess = target_setup_session(&stpg->tpg, tag_num,
+                                       tag_size, TARGET_PROT_NORMAL, i_port_id,
+                                       ch, NULL);
+-              if (!IS_ERR_OR_NULL(ch->sess))
+-                      break;
+-              /* Retry without leading "0x" */
+-              ch->sess = target_setup_session(&stpg->tpg, tag_num,
++                      if (!IS_ERR_OR_NULL(ch->sess))
++                              break;
++                      /* Retry without leading "0x" */
++                      ch->sess = target_setup_session(&stpg->tpg, tag_num,
+                                               tag_size, TARGET_PROT_NORMAL,
+                                               i_port_id + 2, ch, NULL);
++              }
++              mutex_unlock(&sport->gid_id->mutex);
+       }
+-      mutex_unlock(&sport->port_gid_id.mutex);
+       if (IS_ERR_OR_NULL(ch->sess)) {
+               WARN_ON_ONCE(ch->sess == NULL);
+@@ -2986,7 +2984,12 @@ static int srpt_release_sport(struct srpt_port *sport)
+       return 0;
+ }
+-static struct se_wwn *__srpt_lookup_wwn(const char *name)
++struct port_and_port_id {
++      struct srpt_port *sport;
++      struct srpt_port_id **port_id;
++};
++
++static struct port_and_port_id __srpt_lookup_port(const char *name)
+ {
+       struct ib_device *dev;
+       struct srpt_device *sdev;
+@@ -3001,25 +3004,38 @@ static struct se_wwn *__srpt_lookup_wwn(const char *name)
+               for (i = 0; i < dev->phys_port_cnt; i++) {
+                       sport = &sdev->port[i];
+-                      if (strcmp(sport->port_guid_id.name, name) == 0)
+-                              return &sport->port_guid_id.wwn;
+-                      if (strcmp(sport->port_gid_id.name, name) == 0)
+-                              return &sport->port_gid_id.wwn;
++                      if (strcmp(sport->guid_name, name) == 0) {
++                              kref_get(&sdev->refcnt);
++                              return (struct port_and_port_id){
++                                      sport, &sport->guid_id};
++                      }
++                      if (strcmp(sport->gid_name, name) == 0) {
++                              kref_get(&sdev->refcnt);
++                              return (struct port_and_port_id){
++                                      sport, &sport->gid_id};
++                      }
+               }
+       }
+-      return NULL;
++      return (struct port_and_port_id){};
+ }
+-static struct se_wwn *srpt_lookup_wwn(const char *name)
++/**
++ * srpt_lookup_port() - Look up an RDMA port by name
++ * @name: ASCII port name
++ *
++ * Increments the RDMA port reference count if an RDMA port pointer is returned.
++ * The caller must drop that reference count by calling srpt_port_put_ref().
++ */
++static struct port_and_port_id srpt_lookup_port(const char *name)
+ {
+-      struct se_wwn *wwn;
++      struct port_and_port_id papi;
+       spin_lock(&srpt_dev_lock);
+-      wwn = __srpt_lookup_wwn(name);
++      papi = __srpt_lookup_port(name);
+       spin_unlock(&srpt_dev_lock);
+-      return wwn;
++      return papi;
+ }
+ static void srpt_free_srq(struct srpt_device *sdev)
+@@ -3198,10 +3214,6 @@ static int srpt_add_one(struct ib_device *device)
+               sport->port_attrib.srp_sq_size = DEF_SRPT_SQ_SIZE;
+               sport->port_attrib.use_srq = false;
+               INIT_WORK(&sport->work, srpt_refresh_port_work);
+-              mutex_init(&sport->port_guid_id.mutex);
+-              INIT_LIST_HEAD(&sport->port_guid_id.tpg_list);
+-              mutex_init(&sport->port_gid_id.mutex);
+-              INIT_LIST_HEAD(&sport->port_gid_id.tpg_list);
+               ret = srpt_refresh_port(sport);
+               if (ret) {
+@@ -3302,10 +3314,10 @@ static struct srpt_port_id *srpt_wwn_to_sport_id(struct se_wwn *wwn)
+ {
+       struct srpt_port *sport = wwn->priv;
+-      if (wwn == &sport->port_guid_id.wwn)
+-              return &sport->port_guid_id;
+-      if (wwn == &sport->port_gid_id.wwn)
+-              return &sport->port_gid_id;
++      if (sport->guid_id && &sport->guid_id->wwn == wwn)
++              return sport->guid_id;
++      if (sport->gid_id && &sport->gid_id->wwn == wwn)
++              return sport->gid_id;
+       WARN_ON_ONCE(true);
+       return NULL;
+ }
+@@ -3820,7 +3832,31 @@ static struct se_wwn *srpt_make_tport(struct target_fabric_configfs *tf,
+                                     struct config_group *group,
+                                     const char *name)
+ {
+-      return srpt_lookup_wwn(name) ? : ERR_PTR(-EINVAL);
++      struct port_and_port_id papi = srpt_lookup_port(name);
++      struct srpt_port *sport = papi.sport;
++      struct srpt_port_id *port_id;
++
++      if (!papi.port_id)
++              return ERR_PTR(-EINVAL);
++      if (*papi.port_id) {
++              /* Attempt to create a directory that already exists. */
++              WARN_ON_ONCE(true);
++              return &(*papi.port_id)->wwn;
++      }
++      port_id = kzalloc(sizeof(*port_id), GFP_KERNEL);
++      if (!port_id) {
++              srpt_sdev_put(sport->sdev);
++              return ERR_PTR(-ENOMEM);
++      }
++      mutex_init(&port_id->mutex);
++      INIT_LIST_HEAD(&port_id->tpg_list);
++      port_id->wwn.priv = sport;
++      memcpy(port_id->name, port_id == sport->guid_id ? sport->guid_name :
++             sport->gid_name, ARRAY_SIZE(port_id->name));
++
++      *papi.port_id = port_id;
++
++      return &port_id->wwn;
+ }
+ /**
+@@ -3829,6 +3865,18 @@ static struct se_wwn *srpt_make_tport(struct target_fabric_configfs *tf,
+  */
+ static void srpt_drop_tport(struct se_wwn *wwn)
+ {
++      struct srpt_port_id *port_id = container_of(wwn, typeof(*port_id), wwn);
++      struct srpt_port *sport = wwn->priv;
++
++      if (sport->guid_id == port_id)
++              sport->guid_id = NULL;
++      else if (sport->gid_id == port_id)
++              sport->gid_id = NULL;
++      else
++              WARN_ON_ONCE(true);
++
++      srpt_sdev_put(sport->sdev);
++      kfree(port_id);
+ }
+ static ssize_t srpt_wwn_version_show(struct config_item *item, char *buf)
+diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.h b/drivers/infiniband/ulp/srpt/ib_srpt.h
+index 0cb867d580f1..4c46b301eea1 100644
+--- a/drivers/infiniband/ulp/srpt/ib_srpt.h
++++ b/drivers/infiniband/ulp/srpt/ib_srpt.h
+@@ -393,7 +393,7 @@ struct srpt_port_id {
+ };
+ /**
+- * struct srpt_port - information associated by SRPT with a single IB port
++ * struct srpt_port - SRPT RDMA port information
+  * @sdev:      backpointer to the HCA information.
+  * @mad_agent: per-port management datagram processing information.
+  * @enabled:   Whether or not this target port is enabled.
+@@ -403,9 +403,9 @@ struct srpt_port_id {
+  * @gid:       cached value of the port's gid.
+  * @work:      work structure for refreshing the aforementioned cached values.
+  * @guid_name: port name in GUID format.
+- * @port_guid_id: LIO target port information for the port name in GUID format.
++ * @guid_id:   LIO target port information for the port name in GUID format.
+  * @gid_name:  port name in GID format.
+- * @port_gid_id: LIO target port information for the port name in GID format.
++ * @gid_id:    LIO target port information for the port name in GID format.
+  * @port_attrib:   Port attributes that can be accessed through configfs.
+  * @refcount:    Number of objects associated with this port.
+  * @freed_channels: Completion that will be signaled once @refcount becomes 0.
+@@ -422,9 +422,9 @@ struct srpt_port {
+       union ib_gid            gid;
+       struct work_struct      work;
+       char                    guid_name[64];
+-      struct srpt_port_id     port_guid_id;
++      struct srpt_port_id     *guid_id;
+       char                    gid_name[64];
+-      struct srpt_port_id     port_gid_id;
++      struct srpt_port_id     *gid_id;
+       struct srpt_port_attrib port_attrib;
+       atomic_t                refcount;
+       struct completion       *freed_channels;
+-- 
+2.35.1
+
diff --git a/queue-5.15/rdma-srpt-introduce-a-reference-count-in-struct-srpt.patch b/queue-5.15/rdma-srpt-introduce-a-reference-count-in-struct-srpt.patch
new file mode 100644 (file)
index 0000000..4a111d3
--- /dev/null
@@ -0,0 +1,94 @@
+From 8e92727e3c68bc77e9a0409d178a2cd9a7e990ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Jul 2022 12:34:14 -0700
+Subject: RDMA/srpt: Introduce a reference count in struct srpt_device
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit aa7dfbb41b5a60ab90e244d6f586b8cb5c791c3e ]
+
+This will be used to keep struct srpt_device around as long as either the
+RDMA port exists or a LIO target port is associated with the struct
+srpt_device.
+
+Link: https://lore.kernel.org/r/20220727193415.1583860-3-bvanassche@acm.org
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/srpt/ib_srpt.c | 17 +++++++++++++++--
+ drivers/infiniband/ulp/srpt/ib_srpt.h |  2 ++
+ 2 files changed, 17 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
+index d36873e6d8fa..b59fc584de18 100644
+--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
++++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
+@@ -3104,6 +3104,18 @@ static int srpt_use_srq(struct srpt_device *sdev, bool use_srq)
+       return ret;
+ }
++static void srpt_free_sdev(struct kref *refcnt)
++{
++      struct srpt_device *sdev = container_of(refcnt, typeof(*sdev), refcnt);
++
++      kfree(sdev);
++}
++
++static void srpt_sdev_put(struct srpt_device *sdev)
++{
++      kref_put(&sdev->refcnt, srpt_free_sdev);
++}
++
+ /**
+  * srpt_add_one - InfiniBand device addition callback function
+  * @device: Describes a HCA.
+@@ -3122,6 +3134,7 @@ static int srpt_add_one(struct ib_device *device)
+       if (!sdev)
+               return -ENOMEM;
++      kref_init(&sdev->refcnt);
+       sdev->device = device;
+       mutex_init(&sdev->sdev_mutex);
+@@ -3217,7 +3230,7 @@ static int srpt_add_one(struct ib_device *device)
+       srpt_free_srq(sdev);
+       ib_dealloc_pd(sdev->pd);
+ free_dev:
+-      kfree(sdev);
++      srpt_sdev_put(sdev);
+       pr_info("%s(%s) failed.\n", __func__, dev_name(&device->dev));
+       return ret;
+ }
+@@ -3261,7 +3274,7 @@ static void srpt_remove_one(struct ib_device *device, void *client_data)
+       ib_dealloc_pd(sdev->pd);
+-      kfree(sdev);
++      srpt_sdev_put(sdev);
+ }
+ static struct ib_client srpt_client = {
+diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.h b/drivers/infiniband/ulp/srpt/ib_srpt.h
+index 3844a7058559..0cb867d580f1 100644
+--- a/drivers/infiniband/ulp/srpt/ib_srpt.h
++++ b/drivers/infiniband/ulp/srpt/ib_srpt.h
+@@ -434,6 +434,7 @@ struct srpt_port {
+ /**
+  * struct srpt_device - information associated by SRPT with a single HCA
++ * @refcnt:      Reference count for this device.
+  * @device:        Backpointer to the struct ib_device managed by the IB core.
+  * @pd:            IB protection domain.
+  * @lkey:          L_Key (local key) with write access to all local memory.
+@@ -449,6 +450,7 @@ struct srpt_port {
+  * @port:          Information about the ports owned by this HCA.
+  */
+ struct srpt_device {
++      struct kref             refcnt;
+       struct ib_device        *device;
+       struct ib_pd            *pd;
+       u32                     lkey;
+-- 
+2.35.1
+
diff --git a/queue-5.15/regulator-of-fix-refcount-leak-bug-in-of_get_regulat.patch b/queue-5.15/regulator-of-fix-refcount-leak-bug-in-of_get_regulat.patch
new file mode 100644 (file)
index 0000000..508c4ae
--- /dev/null
@@ -0,0 +1,43 @@
+From 8b3e88feca2d6fdcdf9799cf04d1b66f41cf8996 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 19:10:27 +0800
+Subject: regulator: of: Fix refcount leak bug in
+ of_get_regulation_constraints()
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 66efb665cd5ad69b27dca8571bf89fc6b9c628a4 ]
+
+We should call the of_node_put() for the reference returned by
+of_get_child_by_name() which has increased the refcount.
+
+Fixes: 40e20d68bb3f ("regulator: of: Add support for parsing regulator_state for suspend state")
+Signed-off-by: Liang He <windhl@126.com>
+Link: https://lore.kernel.org/r/20220715111027.391032-1-windhl@126.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/of_regulator.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c
+index f54d4f176882..e12b681c72e5 100644
+--- a/drivers/regulator/of_regulator.c
++++ b/drivers/regulator/of_regulator.c
+@@ -264,8 +264,12 @@ static int of_get_regulation_constraints(struct device *dev,
+               }
+               suspend_np = of_get_child_by_name(np, regulator_states[i]);
+-              if (!suspend_np || !suspend_state)
++              if (!suspend_np)
+                       continue;
++              if (!suspend_state) {
++                      of_node_put(suspend_np);
++                      continue;
++              }
+               if (!of_property_read_u32(suspend_np, "regulator-mode",
+                                         &pval)) {
+-- 
+2.35.1
+
diff --git a/queue-5.15/regulator-qcom_smd-fix-pm8916_pldo-range.patch b/queue-5.15/regulator-qcom_smd-fix-pm8916_pldo-range.patch
new file mode 100644 (file)
index 0000000..901d9a9
--- /dev/null
@@ -0,0 +1,55 @@
+From fb2092f7a3769f0540044ace0453739a8b01c731 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jun 2022 11:46:12 +0200
+Subject: regulator: qcom_smd: Fix pm8916_pldo range
+
+From: Stephan Gerhold <stephan.gerhold@kernkonzept.com>
+
+[ Upstream commit e8977917e116d1571dacb8e9864474551c1c12bd ]
+
+The PM8916 device specification [1] documents a programmable range of
+1.75V to 3.337V with 12.5mV steps for the PMOS LDOs in PM8916. This
+range is also used when controlling the regulator directly using the
+qcom_spmi-regulator driver ("ult_pldo" there).
+
+However, for some reason the qcom_smd-regulator driver allows a much
+larger range for the same hardware component. This could be simply a
+typo, since the start of the range is essentially just missing a '1'.
+
+In practice this does not cause any major problems, since the driver
+just sends the actual voltage to the RPM firmware instead of making use
+of the incorrect voltage selector. Still, having the wrong range there
+is confusing and prevents the regulator core from validating requests
+correctly.
+
+[1]: https://developer.qualcomm.com/download/sd410/pm8916pm8916-1-power-management-ic-device-specification.pdf
+
+Fixes: 57d6567680ed ("regulator: qcom-smd: Add PM8916 support")
+Signed-off-by: Stephan Gerhold <stephan.gerhold@kernkonzept.com>
+Link: https://lore.kernel.org/r/20220623094614.1410180-2-stephan.gerhold@kernkonzept.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/qcom_smd-regulator.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/regulator/qcom_smd-regulator.c b/drivers/regulator/qcom_smd-regulator.c
+index eb974b9c0b19..2fe13c765eff 100644
+--- a/drivers/regulator/qcom_smd-regulator.c
++++ b/drivers/regulator/qcom_smd-regulator.c
+@@ -357,10 +357,10 @@ static const struct regulator_desc pm8941_switch = {
+ static const struct regulator_desc pm8916_pldo = {
+       .linear_ranges = (struct linear_range[]) {
+-              REGULATOR_LINEAR_RANGE(750000, 0, 208, 12500),
++              REGULATOR_LINEAR_RANGE(1750000, 0, 127, 12500),
+       },
+       .n_linear_ranges = 1,
+-      .n_voltages = 209,
++      .n_voltages = 128,
+       .ops = &rpm_smps_ldo_ops,
+ };
+-- 
+2.35.1
+
diff --git a/queue-5.15/remoteproc-imx_rproc-fix-refcount-leak-in-imx_rproc_.patch b/queue-5.15/remoteproc-imx_rproc-fix-refcount-leak-in-imx_rproc_.patch
new file mode 100644 (file)
index 0000000..2d84478
--- /dev/null
@@ -0,0 +1,51 @@
+From a1469531b48840df109cde124cdf355f466ce649 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 May 2022 08:55:58 +0400
+Subject: remoteproc: imx_rproc: Fix refcount leak in imx_rproc_addr_init
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 61afafe8b938bc74841cf4b1a73dd08b9d287c5a ]
+
+of_parse_phandle() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when not needed anymore.
+This function has two paths missing of_node_put().
+
+Fixes: 6e962bfe56b9 ("remoteproc: imx_rproc: add missing of_node_put")
+Fixes: a0ff4aa6f010 ("remoteproc: imx_rproc: add a NXP/Freescale imx_rproc driver")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Link: https://lore.kernel.org/r/20220512045558.7142-1-linmq006@gmail.com
+Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/imx_rproc.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
+index 59eae605ad59..e8a170ad43c1 100644
+--- a/drivers/remoteproc/imx_rproc.c
++++ b/drivers/remoteproc/imx_rproc.c
+@@ -586,16 +586,17 @@ static int imx_rproc_addr_init(struct imx_rproc *priv,
+               node = of_parse_phandle(np, "memory-region", a);
+               /* Not map vdevbuffer, vdevring region */
+-              if (!strncmp(node->name, "vdev", strlen("vdev")))
++              if (!strncmp(node->name, "vdev", strlen("vdev"))) {
++                      of_node_put(node);
+                       continue;
++              }
+               err = of_address_to_resource(node, 0, &res);
++              of_node_put(node);
+               if (err) {
+                       dev_err(dev, "unable to resolve memory region\n");
+                       return err;
+               }
+-              of_node_put(node);
+-
+               if (b >= IMX_RPROC_MEM_MAX)
+                       break;
+-- 
+2.35.1
+
diff --git a/queue-5.15/remoteproc-k3-r5-fix-refcount-leak-in-k3_r5_cluster_.patch b/queue-5.15/remoteproc-k3-r5-fix-refcount-leak-in-k3_r5_cluster_.patch
new file mode 100644 (file)
index 0000000..1e5ed52
--- /dev/null
@@ -0,0 +1,48 @@
+From 1f25464e109ad9eb23a24ca2a520d326f0b2e9ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Jun 2022 12:33:34 +0400
+Subject: remoteproc: k3-r5: Fix refcount leak in k3_r5_cluster_of_init
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit fa220c05d282e7479abe08b54e3bdffd06c25e97 ]
+
+Every iteration of for_each_available_child_of_node() decrements
+the reference count of the previous node.
+When breaking early from a for_each_available_child_of_node() loop,
+we need to explicitly call of_node_put() on the child node.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: 6dedbd1d5443 ("remoteproc: k3-r5: Add a remoteproc driver for R5F subsystem")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Acked-by: Suman Anna <s-anna@ti.com>
+Link: https://lore.kernel.org/r/20220605083334.23942-1-linmq006@gmail.com
+Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/ti_k3_r5_remoteproc.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/remoteproc/ti_k3_r5_remoteproc.c b/drivers/remoteproc/ti_k3_r5_remoteproc.c
+index 71615210df3e..54266ea69c84 100644
+--- a/drivers/remoteproc/ti_k3_r5_remoteproc.c
++++ b/drivers/remoteproc/ti_k3_r5_remoteproc.c
+@@ -1430,6 +1430,7 @@ static int k3_r5_cluster_of_init(struct platform_device *pdev)
+               if (!cpdev) {
+                       ret = -ENODEV;
+                       dev_err(dev, "could not get R5 core platform device\n");
++                      of_node_put(child);
+                       goto fail;
+               }
+@@ -1438,6 +1439,7 @@ static int k3_r5_cluster_of_init(struct platform_device *pdev)
+                       dev_err(dev, "k3_r5_core_of_init failed, ret = %d\n",
+                               ret);
+                       put_device(&cpdev->dev);
++                      of_node_put(child);
+                       goto fail;
+               }
+-- 
+2.35.1
+
diff --git a/queue-5.15/remoteproc-qcom-pas-check-if-coredump-is-enabled.patch b/queue-5.15/remoteproc-qcom-pas-check-if-coredump-is-enabled.patch
new file mode 100644 (file)
index 0000000..fb461d8
--- /dev/null
@@ -0,0 +1,41 @@
+From d161eff341e10c32526dedc9d9684e81b8929ce7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Jul 2022 17:38:17 +0530
+Subject: remoteproc: qcom: pas: Check if coredump is enabled
+
+From: Siddharth Gupta <sidgup@codeaurora.org>
+
+[ Upstream commit 7b6ece968fca4ec9e42d34caff7e06dc84c45717 ]
+
+Client drivers need to check if coredump is enabled for the rproc before
+continuing with coredump generation. This change adds a check in the PAS
+driver.
+
+Fixes: 8ed8485c4f05 ("remoteproc: qcom: Add capability to collect minidumps")
+Signed-off-by: Siddharth Gupta <sidgup@codeaurora.org>
+Signed-off-by: Sibi Sankar <quic_sibis@quicinc.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/1657022900-2049-5-git-send-email-quic_sibis@quicinc.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/qcom_q6v5_pas.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
+index 699eaac5b760..78d90d856e40 100644
+--- a/drivers/remoteproc/qcom_q6v5_pas.c
++++ b/drivers/remoteproc/qcom_q6v5_pas.c
+@@ -87,6 +87,9 @@ static void adsp_minidump(struct rproc *rproc)
+ {
+       struct qcom_adsp *adsp = rproc->priv;
++      if (rproc->dump_conf == RPROC_COREDUMP_DISABLED)
++              return;
++
+       qcom_minidump(rproc, adsp->minidump_id);
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/remoteproc-qcom-wcnss-fix-handling-of-irqs.patch b/queue-5.15/remoteproc-qcom-wcnss-fix-handling-of-irqs.patch
new file mode 100644 (file)
index 0000000..b0e24a7
--- /dev/null
@@ -0,0 +1,60 @@
+From c728cab9f90c8153d41c3945e1279db300ee227c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 May 2022 19:47:39 +0530
+Subject: remoteproc: qcom: wcnss: Fix handling of IRQs
+
+From: Sireesh Kodali <sireeshkodali1@gmail.com>
+
+[ Upstream commit bed0adac1ded4cb486ba19a3a7e730fbd9a1c9c6 ]
+
+The wcnss_get_irq function is expected to return a value > 0 in the
+event that an IRQ is succssfully obtained, but it instead returns 0.
+This causes the stop and ready IRQs to never actually be used despite
+being defined in the device-tree. This patch fixes that.
+
+Fixes: aed361adca9f ("remoteproc: qcom: Introduce WCNSS peripheral image loader")
+Signed-off-by: Sireesh Kodali <sireeshkodali1@gmail.com>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220526141740.15834-2-sireeshkodali1@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/qcom_wcnss.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/remoteproc/qcom_wcnss.c b/drivers/remoteproc/qcom_wcnss.c
+index b17742eac9ff..97a0c0dc4c77 100644
+--- a/drivers/remoteproc/qcom_wcnss.c
++++ b/drivers/remoteproc/qcom_wcnss.c
+@@ -468,6 +468,7 @@ static int wcnss_request_irq(struct qcom_wcnss *wcnss,
+                            irq_handler_t thread_fn)
+ {
+       int ret;
++      int irq_number;
+       ret = platform_get_irq_byname(pdev, name);
+       if (ret < 0 && optional) {
+@@ -478,14 +479,19 @@ static int wcnss_request_irq(struct qcom_wcnss *wcnss,
+               return ret;
+       }
++      irq_number = ret;
++
+       ret = devm_request_threaded_irq(&pdev->dev, ret,
+                                       NULL, thread_fn,
+                                       IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+                                       "wcnss", wcnss);
+-      if (ret)
++      if (ret) {
+               dev_err(&pdev->dev, "request %s IRQ failed\n", name);
++              return ret;
++      }
+-      return ret;
++      /* Return the IRQ number if the IRQ was successfully acquired */
++      return irq_number;
+ }
+ static int wcnss_alloc_memory_region(struct qcom_wcnss *wcnss)
+-- 
+2.35.1
+
diff --git a/queue-5.15/remoteproc-sysmon-wait-for-ssctl-service-to-come-up.patch b/queue-5.15/remoteproc-sysmon-wait-for-ssctl-service-to-come-up.patch
new file mode 100644 (file)
index 0000000..4eac38c
--- /dev/null
@@ -0,0 +1,78 @@
+From 424d4f46a63fc30db142e0a6236466e95de9c71b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Jul 2022 17:38:19 +0530
+Subject: remoteproc: sysmon: Wait for SSCTL service to come up
+
+From: Sibi Sankar <quic_sibis@quicinc.com>
+
+[ Upstream commit 47c04e00eff86a81cd357c3feed04c86089bcb85 ]
+
+The SSCTL service comes up after a finite time when the remote Q6 comes
+out of reset. Any graceful shutdowns requested during this period will
+be a NOP and abrupt tearing down of the glink channel might lead to pending
+transactions on the remote Q6 side and will ultimately lead to a fatal
+error. Fix this by waiting for the SSCTL service when a graceful shutdown
+is requested.
+
+Fixes: 1fb82ee806d1 ("remoteproc: qcom: Introduce sysmon")
+Reviewed-by: Matthias Kaehlcke <mka@chromium.org>
+Signed-off-by: Sibi Sankar <quic_sibis@quicinc.com>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/1657022900-2049-7-git-send-email-quic_sibis@quicinc.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/qcom_sysmon.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/remoteproc/qcom_sysmon.c b/drivers/remoteproc/qcom_sysmon.c
+index 9fca81492863..a9f04dd83ab6 100644
+--- a/drivers/remoteproc/qcom_sysmon.c
++++ b/drivers/remoteproc/qcom_sysmon.c
+@@ -41,6 +41,7 @@ struct qcom_sysmon {
+       struct completion comp;
+       struct completion ind_comp;
+       struct completion shutdown_comp;
++      struct completion ssctl_comp;
+       struct mutex lock;
+       bool ssr_ack;
+@@ -445,6 +446,8 @@ static int ssctl_new_server(struct qmi_handle *qmi, struct qmi_service *svc)
+       svc->priv = sysmon;
++      complete(&sysmon->ssctl_comp);
++
+       return 0;
+ }
+@@ -501,6 +504,7 @@ static int sysmon_start(struct rproc_subdev *subdev)
+               .ssr_event = SSCTL_SSR_EVENT_AFTER_POWERUP
+       };
++      reinit_completion(&sysmon->ssctl_comp);
+       mutex_lock(&sysmon->state_lock);
+       sysmon->state = SSCTL_SSR_EVENT_AFTER_POWERUP;
+       blocking_notifier_call_chain(&sysmon_notifiers, 0, (void *)&event);
+@@ -545,6 +549,11 @@ static void sysmon_stop(struct rproc_subdev *subdev, bool crashed)
+       if (crashed)
+               return;
++      if (sysmon->ssctl_instance) {
++              if (!wait_for_completion_timeout(&sysmon->ssctl_comp, HZ / 2))
++                      dev_err(sysmon->dev, "timeout waiting for ssctl service\n");
++      }
++
+       if (sysmon->ssctl_version)
+               sysmon->shutdown_acked = ssctl_request_shutdown(sysmon);
+       else if (sysmon->ept)
+@@ -631,6 +640,7 @@ struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc,
+       init_completion(&sysmon->comp);
+       init_completion(&sysmon->ind_comp);
+       init_completion(&sysmon->shutdown_comp);
++      init_completion(&sysmon->ssctl_comp);
+       mutex_init(&sysmon->lock);
+       mutex_init(&sysmon->state_lock);
+-- 
+2.35.1
+
diff --git a/queue-5.15/rpmsg-char-add-mutex-protection-for-rpmsg_eptdev_ope.patch b/queue-5.15/rpmsg-char-add-mutex-protection-for-rpmsg_eptdev_ope.patch
new file mode 100644 (file)
index 0000000..c877c7b
--- /dev/null
@@ -0,0 +1,58 @@
+From c1f23debd20d027d7dd22f4422c0d4c56722bbfc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 21 May 2022 11:35:05 +0800
+Subject: rpmsg: char: Add mutex protection for rpmsg_eptdev_open()
+
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+
+[ Upstream commit abe13e9a561d6b3e82b21362c0d6dd3ecd8a5b13 ]
+
+There is no mutex protection for rpmsg_eptdev_open(),
+especially for eptdev->ept read and write operation.
+It may cause issues when multiple instances call
+rpmsg_eptdev_open() in parallel,the return state
+may be success or EBUSY.
+
+Fixes: 964e8bedd5a1 ("rpmsg: char: Return an error if device already open")
+Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
+Link: https://lore.kernel.org/r/1653104105-16779-1-git-send-email-shengjiu.wang@nxp.com
+Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rpmsg/rpmsg_char.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/rpmsg/rpmsg_char.c b/drivers/rpmsg/rpmsg_char.c
+index 49dd5a200998..88c985f9e73a 100644
+--- a/drivers/rpmsg/rpmsg_char.c
++++ b/drivers/rpmsg/rpmsg_char.c
+@@ -127,8 +127,11 @@ static int rpmsg_eptdev_open(struct inode *inode, struct file *filp)
+       struct rpmsg_device *rpdev = eptdev->rpdev;
+       struct device *dev = &eptdev->dev;
+-      if (eptdev->ept)
++      mutex_lock(&eptdev->ept_lock);
++      if (eptdev->ept) {
++              mutex_unlock(&eptdev->ept_lock);
+               return -EBUSY;
++      }
+       get_device(dev);
+@@ -136,11 +139,13 @@ static int rpmsg_eptdev_open(struct inode *inode, struct file *filp)
+       if (!ept) {
+               dev_err(dev, "failed to open %s\n", eptdev->chinfo.name);
+               put_device(dev);
++              mutex_unlock(&eptdev->ept_lock);
+               return -EINVAL;
+       }
+       eptdev->ept = ept;
+       filp->private_data = eptdev;
++      mutex_unlock(&eptdev->ept_lock);
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/rpmsg-mtk_rpmsg-fix-circular-locking-dependency.patch b/queue-5.15/rpmsg-mtk_rpmsg-fix-circular-locking-dependency.patch
new file mode 100644 (file)
index 0000000..6e29215
--- /dev/null
@@ -0,0 +1,126 @@
+From e46ab8647ac33deab4a4dda6fadc8b7d76aec034 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 May 2022 11:12:01 +0200
+Subject: rpmsg: mtk_rpmsg: Fix circular locking dependency
+
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+[ Upstream commit 353d9214682e65c55cdffad8c82139a3321c5f13 ]
+
+During execution of the worker that's used to register rpmsg devices
+we are safely locking the channels mutex but, when creating a new
+endpoint for such devices, we are registering a IPI on the SCP, which
+then makes the SCP to trigger an interrupt, lock its own mutex and in
+turn register more subdevices.
+This creates a circular locking dependency situation, as the mtk_rpmsg
+channels_lock will then depend on the SCP IPI lock.
+
+[   15.447736] ======================================================
+[   15.460158] WARNING: possible circular locking dependency detected
+[   15.460161] 5.17.0-next-20220324+ #399 Not tainted
+[   15.460165] ------------------------------------------------------
+[   15.460166] kworker/0:3/155 is trying to acquire lock:
+[   15.460170] ffff5b4d0eaf1308 (&scp->ipi_desc[i].lock){+.+.}-{4:4}, at: scp_ipi_lock+0x34/0x50 [mtk_scp_ipi]
+[   15.504958]
+[]                but task is already holding lock:
+[   15.504960] ffff5b4d0e8f1918 (&mtk_subdev->channels_lock){+.+.}-{4:4}, at: mtk_register_device_work_function+0x50/0x1cc [mtk_rpmsg]
+[   15.504978]
+[]                which lock already depends on the new lock.
+
+[   15.504980]
+[]                the existing dependency chain (in reverse order) is:
+[   15.504982]
+[]               -> #1 (&mtk_subdev->channels_lock){+.+.}-{4:4}:
+[   15.504990]        lock_acquire+0x68/0x84
+[   15.504999]        __mutex_lock+0xa4/0x3e0
+[   15.505007]        mutex_lock_nested+0x40/0x70
+[   15.505012]        mtk_rpmsg_ns_cb+0xe4/0x134 [mtk_rpmsg]
+[   15.641684]        mtk_rpmsg_ipi_handler+0x38/0x64 [mtk_rpmsg]
+[   15.641693]        scp_ipi_handler+0xbc/0x180 [mtk_scp]
+[   15.663905]        mt8192_scp_irq_handler+0x44/0xa4 [mtk_scp]
+[   15.663915]        scp_irq_handler+0x6c/0xa0 [mtk_scp]
+[   15.685779]        irq_thread_fn+0x34/0xa0
+[   15.685785]        irq_thread+0x18c/0x240
+[   15.685789]        kthread+0x104/0x110
+[   15.709579]        ret_from_fork+0x10/0x20
+[   15.709586]
+[]               -> #0 (&scp->ipi_desc[i].lock){+.+.}-{4:4}:
+[   15.731271]        __lock_acquire+0x11e4/0x1910
+[   15.740367]        lock_acquire.part.0+0xd8/0x220
+[   15.749813]        lock_acquire+0x68/0x84
+[   15.757861]        __mutex_lock+0xa4/0x3e0
+[   15.766084]        mutex_lock_nested+0x40/0x70
+[   15.775006]        scp_ipi_lock+0x34/0x50 [mtk_scp_ipi]
+[   15.785503]        scp_ipi_register+0x40/0xa4 [mtk_scp_ipi]
+[   15.796697]        scp_register_ipi+0x1c/0x30 [mtk_scp]
+[   15.807194]        mtk_rpmsg_create_ept+0xa0/0x108 [mtk_rpmsg]
+[   15.818912]        rpmsg_create_ept+0x44/0x60
+[   15.827660]        cros_ec_rpmsg_probe+0x15c/0x1f0
+[   15.837282]        rpmsg_dev_probe+0x128/0x1d0
+[   15.846203]        really_probe.part.0+0xa4/0x2a0
+[   15.855649]        __driver_probe_device+0xa0/0x150
+[   15.865443]        driver_probe_device+0x48/0x150
+[   15.877157]        __device_attach_driver+0xc0/0x12c
+[   15.889359]        bus_for_each_drv+0x80/0xe0
+[   15.900330]        __device_attach+0xe4/0x190
+[   15.911303]        device_initial_probe+0x1c/0x2c
+[   15.922969]        bus_probe_device+0xa8/0xb0
+[   15.933927]        device_add+0x3a8/0x8a0
+[   15.944193]        device_register+0x28/0x40
+[   15.954970]        rpmsg_register_device+0x5c/0xa0
+[   15.966782]        mtk_register_device_work_function+0x148/0x1cc [mtk_rpmsg]
+[   15.983146]        process_one_work+0x294/0x664
+[   15.994458]        worker_thread+0x7c/0x45c
+[   16.005069]        kthread+0x104/0x110
+[   16.014789]        ret_from_fork+0x10/0x20
+[   16.025201]
+[]               other info that might help us debug this:
+
+[   16.047769]  Possible unsafe locking scenario:
+
+[   16.063942]        CPU0                    CPU1
+[   16.075166]        ----                    ----
+[   16.086376]   lock(&mtk_subdev->channels_lock);
+[   16.097592]                                lock(&scp->ipi_desc[i].lock);
+[   16.113188]                                lock(&mtk_subdev->channels_lock);
+[   16.129482]   lock(&scp->ipi_desc[i].lock);
+[   16.140020]
+[]                *** DEADLOCK ***
+
+[   16.158282] 4 locks held by kworker/0:3/155:
+[   16.168978]  #0: ffff5b4d00008748 ((wq_completion)events){+.+.}-{0:0}, at: process_one_work+0x1fc/0x664
+[   16.190017]  #1: ffff80000953bdc8 ((work_completion)(&mtk_subdev->register_work)){+.+.}-{0:0}, at: process_one_work+0x1fc/0x664
+[   16.215269]  #2: ffff5b4d0e8f1918 (&mtk_subdev->channels_lock){+.+.}-{4:4}, at: mtk_register_device_work_function+0x50/0x1cc [mtk_rpmsg]
+[   16.242131]  #3: ffff5b4d05964190 (&dev->mutex){....}-{4:4}, at: __device_attach+0x44/0x190
+
+To solve this, simply unlock the channels_lock mutex before calling
+mtk_rpmsg_register_device() and relock it right after, as safety is
+still ensured by the locking mechanism that happens right after
+through SCP.
+
+Fixes: 7017996951fd ("rpmsg: add rpmsg support for mt8183 SCP.")
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20220525091201.14210-1-angelogioacchino.delregno@collabora.com
+Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rpmsg/mtk_rpmsg.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/rpmsg/mtk_rpmsg.c b/drivers/rpmsg/mtk_rpmsg.c
+index 96a17ec29140..2d8cb596ad69 100644
+--- a/drivers/rpmsg/mtk_rpmsg.c
++++ b/drivers/rpmsg/mtk_rpmsg.c
+@@ -234,7 +234,9 @@ static void mtk_register_device_work_function(struct work_struct *register_work)
+               if (info->registered)
+                       continue;
++              mutex_unlock(&subdev->channels_lock);
+               ret = mtk_rpmsg_register_device(subdev, &info->info);
++              mutex_lock(&subdev->channels_lock);
+               if (ret) {
+                       dev_err(&pdev->dev, "Can't create rpmsg_device\n");
+                       continue;
+-- 
+2.35.1
+
diff --git a/queue-5.15/rpmsg-qcom_smd-fix-refcount-leak-in-qcom_smd_parse_e.patch b/queue-5.15/rpmsg-qcom_smd-fix-refcount-leak-in-qcom_smd_parse_e.patch
new file mode 100644 (file)
index 0000000..50cec68
--- /dev/null
@@ -0,0 +1,36 @@
+From cf3daf41340ee091e48b1e35e6983c076aa58f24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 May 2022 16:07:37 +0400
+Subject: rpmsg: qcom_smd: Fix refcount leak in qcom_smd_parse_edge
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 65382585f067d4256ba087934f30f85c9b6984de ]
+
+of_parse_phandle() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when done.
+
+Fixes: 53e2822e56c7 ("rpmsg: Introduce Qualcomm SMD backend")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220511120737.57374-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rpmsg/qcom_smd.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/rpmsg/qcom_smd.c b/drivers/rpmsg/qcom_smd.c
+index 370688e8646b..c1c07ff39a79 100644
+--- a/drivers/rpmsg/qcom_smd.c
++++ b/drivers/rpmsg/qcom_smd.c
+@@ -1380,6 +1380,7 @@ static int qcom_smd_parse_edge(struct device *dev,
+               }
+               edge->ipc_regmap = syscon_node_to_regmap(syscon_np);
++              of_node_put(syscon_np);
+               if (IS_ERR(edge->ipc_regmap)) {
+                       ret = PTR_ERR(edge->ipc_regmap);
+                       goto put_node;
+-- 
+2.35.1
+
diff --git a/queue-5.15/s390-crash-fix-incorrect-number-of-bytes-to-copy-to-.patch b/queue-5.15/s390-crash-fix-incorrect-number-of-bytes-to-copy-to-.patch
new file mode 100644 (file)
index 0000000..9a973ad
--- /dev/null
@@ -0,0 +1,36 @@
+From 8d682d3c34088e24ed7a267d0b5324502e373826 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 12:59:33 +0200
+Subject: s390/crash: fix incorrect number of bytes to copy to user space
+
+From: Alexander Gordeev <agordeev@linux.ibm.com>
+
+[ Upstream commit f6749da17a34eb08c9665f072ce7c812ff68aad2 ]
+
+The number of bytes in a chunk is correctly calculated, but instead
+the total number of bytes is passed to copy_to_user_real() function.
+
+Reported-by: Matthew Wilcox <willy@infradead.org>
+Fixes: df9694c7975f ("s390/dump: streamline oldmem copy functions")
+Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/kernel/crash_dump.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c
+index 199f136d1644..f17ad2daab07 100644
+--- a/arch/s390/kernel/crash_dump.c
++++ b/arch/s390/kernel/crash_dump.c
+@@ -198,7 +198,7 @@ static int copy_oldmem_user(void __user *dst, unsigned long src, size_t count)
+                       } else {
+                               len = count;
+                       }
+-                      rc = copy_to_user_real(dst, src, count);
++                      rc = copy_to_user_real(dst, src, len);
+                       if (rc)
+                               return rc;
+               }
+-- 
+2.35.1
+
diff --git a/queue-5.15/s390-dump-fix-old-lowcore-virtual-vs-physical-addres.patch b/queue-5.15/s390-dump-fix-old-lowcore-virtual-vs-physical-addres.patch
new file mode 100644 (file)
index 0000000..f88e4ed
--- /dev/null
@@ -0,0 +1,82 @@
+From 06497a5975667fb26f3e870e80e7138e538eaec0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 29 Jan 2022 08:38:56 +0100
+Subject: s390/dump: fix old lowcore virtual vs physical address confusion
+
+From: Alexander Gordeev <agordeev@linux.ibm.com>
+
+[ Upstream commit dc306186a130c6d9feb0aabc1c71b8ed1674a3bf ]
+
+Virtual addresses of vmcore_info and os_info members are
+wrongly passed to copy_oldmem_kernel(), while the function
+expects physical address of the source. Instead, __pa()
+macro should have been applied.
+
+Yet, use of __pa() macro could be somehow confusing, since
+copy_oldmem_kernel() may treat the source as an offset, not
+as a direct physical address (that depens from the oldmem
+availability and location).
+
+Fix the virtual vs physical address confusion and make the
+way the old lowcore is read consistent across all sources.
+
+Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/kernel/asm-offsets.c | 2 ++
+ arch/s390/kernel/crash_dump.c  | 2 +-
+ arch/s390/kernel/os_info.c     | 3 ++-
+ 3 files changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c
+index b57da9338588..9242d7ad71e7 100644
+--- a/arch/s390/kernel/asm-offsets.c
++++ b/arch/s390/kernel/asm-offsets.c
+@@ -128,6 +128,8 @@ int main(void)
+       OFFSET(__LC_BR_R1, lowcore, br_r1_trampoline);
+       /* software defined ABI-relevant lowcore locations 0xe00 - 0xe20 */
+       OFFSET(__LC_DUMP_REIPL, lowcore, ipib);
++      OFFSET(__LC_VMCORE_INFO, lowcore, vmcore_info);
++      OFFSET(__LC_OS_INFO, lowcore, os_info);
+       /* hardware defined lowcore locations 0x1000 - 0x18ff */
+       OFFSET(__LC_MCESAD, lowcore, mcesad);
+       OFFSET(__LC_EXT_PARAMS2, lowcore, ext_params2);
+diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c
+index 785d54c9350c..9c2597be28dc 100644
+--- a/arch/s390/kernel/crash_dump.c
++++ b/arch/s390/kernel/crash_dump.c
+@@ -432,7 +432,7 @@ static void *get_vmcoreinfo_old(unsigned long *size)
+       Elf64_Nhdr note;
+       void *addr;
+-      if (copy_oldmem_kernel(&addr, &S390_lowcore.vmcore_info, sizeof(addr)))
++      if (copy_oldmem_kernel(&addr, (void *)__LC_VMCORE_INFO, sizeof(addr)))
+               return NULL;
+       memset(nt_name, 0, sizeof(nt_name));
+       if (copy_oldmem_kernel(&note, addr, sizeof(note)))
+diff --git a/arch/s390/kernel/os_info.c b/arch/s390/kernel/os_info.c
+index 4bef35b79b93..198f9694e439 100644
+--- a/arch/s390/kernel/os_info.c
++++ b/arch/s390/kernel/os_info.c
+@@ -15,6 +15,7 @@
+ #include <asm/checksum.h>
+ #include <asm/lowcore.h>
+ #include <asm/os_info.h>
++#include <asm/asm-offsets.h>
+ /*
+  * OS info structure has to be page aligned
+@@ -123,7 +124,7 @@ static void os_info_old_init(void)
+               return;
+       if (!oldmem_data.start)
+               goto fail;
+-      if (copy_oldmem_kernel(&addr, &S390_lowcore.os_info, sizeof(addr)))
++      if (copy_oldmem_kernel(&addr, (void *)__LC_OS_INFO, sizeof(addr)))
+               goto fail;
+       if (addr == 0 || addr % PAGE_SIZE)
+               goto fail;
+-- 
+2.35.1
+
diff --git a/queue-5.15/s390-dump-fix-os_info-virtual-vs-physical-address-co.patch b/queue-5.15/s390-dump-fix-os_info-virtual-vs-physical-address-co.patch
new file mode 100644 (file)
index 0000000..bd221dd
--- /dev/null
@@ -0,0 +1,48 @@
+From 5eb772c6f79e540be35ecaae3cc2009c06859370 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Jan 2022 13:47:59 +0100
+Subject: s390/dump: fix os_info virtual vs physical address confusion
+
+From: Alexander Gordeev <agordeev@linux.ibm.com>
+
+[ Upstream commit 9de209c7d584d6e06ad92f120d83d4f27c200497 ]
+
+Due to historical reasons os_info handling functions misuse
+the notion of physical vs virtual addresses difference.
+
+Note: this does not fix a bug currently, since virtual
+and physical addresses are identical.
+
+Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/kernel/os_info.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/s390/kernel/os_info.c b/arch/s390/kernel/os_info.c
+index e548844dde28..6b5b64e67eee 100644
+--- a/arch/s390/kernel/os_info.c
++++ b/arch/s390/kernel/os_info.c
+@@ -46,7 +46,7 @@ void os_info_crashkernel_add(unsigned long base, unsigned long size)
+  */
+ void os_info_entry_add(int nr, void *ptr, u64 size)
+ {
+-      os_info.entry[nr].addr = (u64)(unsigned long)ptr;
++      os_info.entry[nr].addr = __pa(ptr);
+       os_info.entry[nr].size = size;
+       os_info.entry[nr].csum = (__force u32)csum_partial(ptr, size, 0);
+       os_info.csum = os_info_csum(&os_info);
+@@ -63,7 +63,7 @@ void __init os_info_init(void)
+       os_info.version_minor = OS_INFO_VERSION_MINOR;
+       os_info.magic = OS_INFO_MAGIC;
+       os_info.csum = os_info_csum(&os_info);
+-      mem_assign_absolute(S390_lowcore.os_info, (unsigned long) ptr);
++      mem_assign_absolute(S390_lowcore.os_info, __pa(ptr));
+ }
+ #ifdef CONFIG_CRASH_DUMP
+-- 
+2.35.1
+
diff --git a/queue-5.15/s390-maccess-fix-semantics-of-memcpy_real-and-its-ca.patch b/queue-5.15/s390-maccess-fix-semantics-of-memcpy_real-and-its-ca.patch
new file mode 100644 (file)
index 0000000..04a3d60
--- /dev/null
@@ -0,0 +1,286 @@
+From 8451bf340adf4fb6982b5c5d263e87ccd735bfd1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 29 Jan 2022 09:24:50 +0100
+Subject: s390/maccess: fix semantics of memcpy_real() and its callers
+
+From: Alexander Gordeev <agordeev@linux.ibm.com>
+
+[ Upstream commit 303fd988ed644c7daa260410f3ac99266573557d ]
+
+There is a confusion with regard to the source address of
+memcpy_real() and calling functions. While the declared
+type for a source assumes a virtual address, in fact it
+always called with physical address of the source.
+
+This confusion led to bugs in copy_oldmem_kernel() and
+copy_oldmem_user() functions, where __pa() macro applied
+mistakenly to physical addresses. It does not lead to a
+real issue, since virtual and physical addresses are
+currently the same.
+
+Fix both the bugs and memcpy_real() prototype by making
+type of source address consistent to the function name
+and the way it actually used.
+
+Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/include/asm/os_info.h   |  2 +-
+ arch/s390/include/asm/processor.h |  2 +-
+ arch/s390/include/asm/uaccess.h   |  2 +-
+ arch/s390/kernel/crash_dump.c     | 58 +++++++++++++++----------------
+ arch/s390/kernel/os_info.c        |  7 ++--
+ arch/s390/kernel/smp.c            |  2 +-
+ arch/s390/mm/maccess.c            |  4 +--
+ drivers/s390/char/zcore.c         |  3 +-
+ 8 files changed, 38 insertions(+), 42 deletions(-)
+
+diff --git a/arch/s390/include/asm/os_info.h b/arch/s390/include/asm/os_info.h
+index 3c89279d2a4b..147a8d547ef9 100644
+--- a/arch/s390/include/asm/os_info.h
++++ b/arch/s390/include/asm/os_info.h
+@@ -39,7 +39,7 @@ u32 os_info_csum(struct os_info *os_info);
+ #ifdef CONFIG_CRASH_DUMP
+ void *os_info_old_entry(int nr, unsigned long *size);
+-int copy_oldmem_kernel(void *dst, void *src, size_t count);
++int copy_oldmem_kernel(void *dst, unsigned long src, size_t count);
+ #else
+ static inline void *os_info_old_entry(int nr, unsigned long *size)
+ {
+diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h
+index 879b8e3f609c..e9db8efd50f2 100644
+--- a/arch/s390/include/asm/processor.h
++++ b/arch/s390/include/asm/processor.h
+@@ -318,7 +318,7 @@ extern void (*s390_base_pgm_handler_fn)(void);
+ #define ARCH_LOW_ADDRESS_LIMIT        0x7fffffffUL
+-extern int memcpy_real(void *, void *, size_t);
++extern int memcpy_real(void *, unsigned long, size_t);
+ extern void memcpy_absolute(void *, void *, size_t);
+ #define mem_assign_absolute(dest, val) do {                   \
+diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h
+index ce550d06abc3..3379694e9a42 100644
+--- a/arch/s390/include/asm/uaccess.h
++++ b/arch/s390/include/asm/uaccess.h
+@@ -245,7 +245,7 @@ static inline unsigned long __must_check clear_user(void __user *to, unsigned lo
+       return __clear_user(to, n);
+ }
+-int copy_to_user_real(void __user *dest, void *src, unsigned long count);
++int copy_to_user_real(void __user *dest, unsigned long src, unsigned long count);
+ void *s390_kernel_write(void *dst, const void *src, size_t size);
+ #define HAVE_GET_KERNEL_NOFAULT
+diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c
+index 9c2597be28dc..199f136d1644 100644
+--- a/arch/s390/kernel/crash_dump.c
++++ b/arch/s390/kernel/crash_dump.c
+@@ -132,28 +132,27 @@ static inline void *load_real_addr(void *addr)
+ /*
+  * Copy memory of the old, dumped system to a kernel space virtual address
+  */
+-int copy_oldmem_kernel(void *dst, void *src, size_t count)
++int copy_oldmem_kernel(void *dst, unsigned long src, size_t count)
+ {
+-      unsigned long from, len;
++      unsigned long len;
+       void *ra;
+       int rc;
+       while (count) {
+-              from = __pa(src);
+-              if (!oldmem_data.start && from < sclp.hsa_size) {
++              if (!oldmem_data.start && src < sclp.hsa_size) {
+                       /* Copy from zfcp/nvme dump HSA area */
+-                      len = min(count, sclp.hsa_size - from);
+-                      rc = memcpy_hsa_kernel(dst, from, len);
++                      len = min(count, sclp.hsa_size - src);
++                      rc = memcpy_hsa_kernel(dst, src, len);
+                       if (rc)
+                               return rc;
+               } else {
+                       /* Check for swapped kdump oldmem areas */
+-                      if (oldmem_data.start && from - oldmem_data.start < oldmem_data.size) {
+-                              from -= oldmem_data.start;
+-                              len = min(count, oldmem_data.size - from);
+-                      } else if (oldmem_data.start && from < oldmem_data.size) {
+-                              len = min(count, oldmem_data.size - from);
+-                              from += oldmem_data.start;
++                      if (oldmem_data.start && src - oldmem_data.start < oldmem_data.size) {
++                              src -= oldmem_data.start;
++                              len = min(count, oldmem_data.size - src);
++                      } else if (oldmem_data.start && src < oldmem_data.size) {
++                              len = min(count, oldmem_data.size - src);
++                              src += oldmem_data.start;
+                       } else {
+                               len = count;
+                       }
+@@ -163,7 +162,7 @@ int copy_oldmem_kernel(void *dst, void *src, size_t count)
+                       } else {
+                               ra = dst;
+                       }
+-                      if (memcpy_real(ra, (void *) from, len))
++                      if (memcpy_real(ra, src, len))
+                               return -EFAULT;
+               }
+               dst += len;
+@@ -176,31 +175,30 @@ int copy_oldmem_kernel(void *dst, void *src, size_t count)
+ /*
+  * Copy memory of the old, dumped system to a user space virtual address
+  */
+-static int copy_oldmem_user(void __user *dst, void *src, size_t count)
++static int copy_oldmem_user(void __user *dst, unsigned long src, size_t count)
+ {
+-      unsigned long from, len;
++      unsigned long len;
+       int rc;
+       while (count) {
+-              from = __pa(src);
+-              if (!oldmem_data.start && from < sclp.hsa_size) {
++              if (!oldmem_data.start && src < sclp.hsa_size) {
+                       /* Copy from zfcp/nvme dump HSA area */
+-                      len = min(count, sclp.hsa_size - from);
+-                      rc = memcpy_hsa_user(dst, from, len);
++                      len = min(count, sclp.hsa_size - src);
++                      rc = memcpy_hsa_user(dst, src, len);
+                       if (rc)
+                               return rc;
+               } else {
+                       /* Check for swapped kdump oldmem areas */
+-                      if (oldmem_data.start && from - oldmem_data.start < oldmem_data.size) {
+-                              from -= oldmem_data.start;
+-                              len = min(count, oldmem_data.size - from);
+-                      } else if (oldmem_data.start && from < oldmem_data.size) {
+-                              len = min(count, oldmem_data.size - from);
+-                              from += oldmem_data.start;
++                      if (oldmem_data.start && src - oldmem_data.start < oldmem_data.size) {
++                              src -= oldmem_data.start;
++                              len = min(count, oldmem_data.size - src);
++                      } else if (oldmem_data.start && src < oldmem_data.size) {
++                              len = min(count, oldmem_data.size - src);
++                              src += oldmem_data.start;
+                       } else {
+                               len = count;
+                       }
+-                      rc = copy_to_user_real(dst, (void *) from, count);
++                      rc = copy_to_user_real(dst, src, count);
+                       if (rc)
+                               return rc;
+               }
+@@ -217,12 +215,12 @@ static int copy_oldmem_user(void __user *dst, void *src, size_t count)
+ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, size_t csize,
+                        unsigned long offset, int userbuf)
+ {
+-      void *src;
++      unsigned long src;
+       int rc;
+       if (!csize)
+               return 0;
+-      src = (void *) (pfn << PAGE_SHIFT) + offset;
++      src = pfn_to_phys(pfn) + offset;
+       if (userbuf)
+               rc = copy_oldmem_user((void __force __user *) buf, src, csize);
+       else
+@@ -429,10 +427,10 @@ static void *nt_prpsinfo(void *ptr)
+ static void *get_vmcoreinfo_old(unsigned long *size)
+ {
+       char nt_name[11], *vmcoreinfo;
++      unsigned long addr;
+       Elf64_Nhdr note;
+-      void *addr;
+-      if (copy_oldmem_kernel(&addr, (void *)__LC_VMCORE_INFO, sizeof(addr)))
++      if (copy_oldmem_kernel(&addr, __LC_VMCORE_INFO, sizeof(addr)))
+               return NULL;
+       memset(nt_name, 0, sizeof(nt_name));
+       if (copy_oldmem_kernel(&note, addr, sizeof(note)))
+diff --git a/arch/s390/kernel/os_info.c b/arch/s390/kernel/os_info.c
+index 198f9694e439..e548844dde28 100644
+--- a/arch/s390/kernel/os_info.c
++++ b/arch/s390/kernel/os_info.c
+@@ -91,7 +91,7 @@ static void os_info_old_alloc(int nr, int align)
+               goto fail;
+       }
+       buf_align = PTR_ALIGN(buf, align);
+-      if (copy_oldmem_kernel(buf_align, (void *) addr, size)) {
++      if (copy_oldmem_kernel(buf_align, addr, size)) {
+               msg = "copy failed";
+               goto fail_free;
+       }
+@@ -124,15 +124,14 @@ static void os_info_old_init(void)
+               return;
+       if (!oldmem_data.start)
+               goto fail;
+-      if (copy_oldmem_kernel(&addr, (void *)__LC_OS_INFO, sizeof(addr)))
++      if (copy_oldmem_kernel(&addr, __LC_OS_INFO, sizeof(addr)))
+               goto fail;
+       if (addr == 0 || addr % PAGE_SIZE)
+               goto fail;
+       os_info_old = kzalloc(sizeof(*os_info_old), GFP_KERNEL);
+       if (!os_info_old)
+               goto fail;
+-      if (copy_oldmem_kernel(os_info_old, (void *) addr,
+-                             sizeof(*os_info_old)))
++      if (copy_oldmem_kernel(os_info_old, addr, sizeof(*os_info_old)))
+               goto fail_free;
+       if (os_info_old->magic != OS_INFO_MAGIC)
+               goto fail_free;
+diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
+index 1a04e5bdf655..e57eb2260b90 100644
+--- a/arch/s390/kernel/smp.c
++++ b/arch/s390/kernel/smp.c
+@@ -675,7 +675,7 @@ static __init void smp_save_cpu_regs(struct save_area *sa, u16 addr,
+       void *regs = (void *) page;
+       if (is_boot_cpu)
+-              copy_oldmem_kernel(regs, (void *) __LC_FPREGS_SAVE_AREA, 512);
++              copy_oldmem_kernel(regs, __LC_FPREGS_SAVE_AREA, 512);
+       else
+               __pcpu_sigp_relax(addr, SIGP_STORE_STATUS_AT_ADDRESS, page);
+       save_area_add_regs(sa, regs);
+diff --git a/arch/s390/mm/maccess.c b/arch/s390/mm/maccess.c
+index 9663ce3625bc..2ed198b4f7d0 100644
+--- a/arch/s390/mm/maccess.c
++++ b/arch/s390/mm/maccess.c
+@@ -123,7 +123,7 @@ static unsigned long __no_sanitize_address _memcpy_real(unsigned long dest,
+ /*
+  * Copy memory in real mode (kernel to kernel)
+  */
+-int memcpy_real(void *dest, void *src, size_t count)
++int memcpy_real(void *dest, unsigned long src, size_t count)
+ {
+       unsigned long _dest  = (unsigned long)dest;
+       unsigned long _src   = (unsigned long)src;
+@@ -175,7 +175,7 @@ void memcpy_absolute(void *dest, void *src, size_t count)
+ /*
+  * Copy memory from kernel (real) to user (virtual)
+  */
+-int copy_to_user_real(void __user *dest, void *src, unsigned long count)
++int copy_to_user_real(void __user *dest, unsigned long src, unsigned long count)
+ {
+       int offs = 0, size, rc;
+       char *buf;
+diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c
+index 3ba2d934a3e8..516783ba950f 100644
+--- a/drivers/s390/char/zcore.c
++++ b/drivers/s390/char/zcore.c
+@@ -229,8 +229,7 @@ static int __init zcore_reipl_init(void)
+               rc = memcpy_hsa_kernel(zcore_ipl_block, ipib_info.ipib,
+                                      PAGE_SIZE);
+       else
+-              rc = memcpy_real(zcore_ipl_block, (void *) ipib_info.ipib,
+-                               PAGE_SIZE);
++              rc = memcpy_real(zcore_ipl_block, ipib_info.ipib, PAGE_SIZE);
+       if (rc || (__force u32)csum_partial(zcore_ipl_block, zcore_ipl_block->hdr.len, 0) !=
+           ipib_info.checksum) {
+               TRACE("Checksum does not match\n");
+-- 
+2.35.1
+
diff --git a/queue-5.15/s390-maccess-rework-absolute-lowcore-accessors.patch b/queue-5.15/s390-maccess-rework-absolute-lowcore-accessors.patch
new file mode 100644 (file)
index 0000000..7e0f1fb
--- /dev/null
@@ -0,0 +1,175 @@
+From 344aeea7312628af5822f750e72dee7449516839 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Mar 2022 15:03:03 +0100
+Subject: s390/maccess: rework absolute lowcore accessors
+
+From: Alexander Gordeev <agordeev@linux.ibm.com>
+
+[ Upstream commit ed0192bc644f3553d64a5cb461bdd0b1fbae3fdf ]
+
+Macro mem_assign_absolute() is able to access the whole memory, but
+is only used and makes sense when updating the absolute lowcore.
+Instead, introduce get_abs_lowcore() and put_abs_lowcore() macros
+that limit access to absolute lowcore addresses only.
+
+Suggested-by: Heiko Carstens <hca@linux.ibm.com>
+Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/include/asm/processor.h | 17 ++++++++++++-----
+ arch/s390/kernel/ipl.c            |  4 ++--
+ arch/s390/kernel/machine_kexec.c  |  2 +-
+ arch/s390/kernel/os_info.c        |  2 +-
+ arch/s390/kernel/setup.c          | 19 ++++++++++---------
+ arch/s390/kernel/smp.c            | 12 ++++++------
+ 6 files changed, 32 insertions(+), 24 deletions(-)
+
+diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h
+index e9db8efd50f2..d7ca76bb2720 100644
+--- a/arch/s390/include/asm/processor.h
++++ b/arch/s390/include/asm/processor.h
+@@ -321,11 +321,18 @@ extern void (*s390_base_pgm_handler_fn)(void);
+ extern int memcpy_real(void *, unsigned long, size_t);
+ extern void memcpy_absolute(void *, void *, size_t);
+-#define mem_assign_absolute(dest, val) do {                   \
+-      __typeof__(dest) __tmp = (val);                         \
+-                                                              \
+-      BUILD_BUG_ON(sizeof(__tmp) != sizeof(val));             \
+-      memcpy_absolute(&(dest), &__tmp, sizeof(__tmp));        \
++#define put_abs_lowcore(member, x) do {                                       \
++      unsigned long __abs_address = offsetof(struct lowcore, member); \
++      __typeof__(((struct lowcore *)0)->member) __tmp = (x);          \
++                                                                      \
++      memcpy_absolute(__va(__abs_address), &__tmp, sizeof(__tmp));    \
++} while (0)
++
++#define get_abs_lowcore(x, member) do {                                       \
++      unsigned long __abs_address = offsetof(struct lowcore, member); \
++      __typeof__(((struct lowcore *)0)->member) *__ptr = &(x);        \
++                                                                      \
++      memcpy_absolute(__ptr, __va(__abs_address), sizeof(*__ptr));    \
+ } while (0)
+ extern int s390_isolate_bp(void);
+diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
+index 5ad1dde23dc5..ba2988783d66 100644
+--- a/arch/s390/kernel/ipl.c
++++ b/arch/s390/kernel/ipl.c
+@@ -1646,8 +1646,8 @@ static void dump_reipl_run(struct shutdown_trigger *trigger)
+       csum = (__force unsigned int)
+              csum_partial(reipl_block_actual, reipl_block_actual->hdr.len, 0);
+-      mem_assign_absolute(S390_lowcore.ipib, ipib);
+-      mem_assign_absolute(S390_lowcore.ipib_checksum, csum);
++      put_abs_lowcore(ipib, ipib);
++      put_abs_lowcore(ipib_checksum, csum);
+       dump_run(trigger);
+ }
+diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c
+index 0505e55a6297..4b95684fbe46 100644
+--- a/arch/s390/kernel/machine_kexec.c
++++ b/arch/s390/kernel/machine_kexec.c
+@@ -227,7 +227,7 @@ void arch_crash_save_vmcoreinfo(void)
+       vmcoreinfo_append_str("SAMODE31=%lx\n", __samode31);
+       vmcoreinfo_append_str("EAMODE31=%lx\n", __eamode31);
+       vmcoreinfo_append_str("KERNELOFFSET=%lx\n", kaslr_offset());
+-      mem_assign_absolute(S390_lowcore.vmcore_info, paddr_vmcoreinfo_note());
++      put_abs_lowcore(vmcore_info, paddr_vmcoreinfo_note());
+ }
+ void machine_shutdown(void)
+diff --git a/arch/s390/kernel/os_info.c b/arch/s390/kernel/os_info.c
+index 6b5b64e67eee..1acc2e05d70f 100644
+--- a/arch/s390/kernel/os_info.c
++++ b/arch/s390/kernel/os_info.c
+@@ -63,7 +63,7 @@ void __init os_info_init(void)
+       os_info.version_minor = OS_INFO_VERSION_MINOR;
+       os_info.magic = OS_INFO_MAGIC;
+       os_info.csum = os_info_csum(&os_info);
+-      mem_assign_absolute(S390_lowcore.os_info, __pa(ptr));
++      put_abs_lowcore(os_info, __pa(ptr));
+ }
+ #ifdef CONFIG_CRASH_DUMP
+diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
+index 36c1f31dfd66..6b1a8697fae8 100644
+--- a/arch/s390/kernel/setup.c
++++ b/arch/s390/kernel/setup.c
+@@ -479,11 +479,11 @@ static void __init setup_lowcore_dat_off(void)
+       lc->mcck_stack = mcck_stack + STACK_INIT_OFFSET;
+       /* Setup absolute zero lowcore */
+-      mem_assign_absolute(S390_lowcore.restart_stack, lc->restart_stack);
+-      mem_assign_absolute(S390_lowcore.restart_fn, lc->restart_fn);
+-      mem_assign_absolute(S390_lowcore.restart_data, lc->restart_data);
+-      mem_assign_absolute(S390_lowcore.restart_source, lc->restart_source);
+-      mem_assign_absolute(S390_lowcore.restart_psw, lc->restart_psw);
++      put_abs_lowcore(restart_stack, lc->restart_stack);
++      put_abs_lowcore(restart_fn, lc->restart_fn);
++      put_abs_lowcore(restart_data, lc->restart_data);
++      put_abs_lowcore(restart_source, lc->restart_source);
++      put_abs_lowcore(restart_psw, lc->restart_psw);
+       lc->spinlock_lockval = arch_spin_lockval(0);
+       lc->spinlock_index = 0;
+@@ -500,6 +500,7 @@ static void __init setup_lowcore_dat_off(void)
+ static void __init setup_lowcore_dat_on(void)
+ {
+       struct lowcore *lc = lowcore_ptr[0];
++      int cr;
+       __ctl_clear_bit(0, 28);
+       S390_lowcore.external_new_psw.mask |= PSW_MASK_DAT;
+@@ -508,10 +509,10 @@ static void __init setup_lowcore_dat_on(void)
+       S390_lowcore.io_new_psw.mask |= PSW_MASK_DAT;
+       __ctl_store(S390_lowcore.cregs_save_area, 0, 15);
+       __ctl_set_bit(0, 28);
+-      mem_assign_absolute(S390_lowcore.restart_flags, RESTART_FLAG_CTLREGS);
+-      mem_assign_absolute(S390_lowcore.program_new_psw, lc->program_new_psw);
+-      memcpy_absolute(&S390_lowcore.cregs_save_area, lc->cregs_save_area,
+-                      sizeof(S390_lowcore.cregs_save_area));
++      put_abs_lowcore(restart_flags, RESTART_FLAG_CTLREGS);
++      put_abs_lowcore(program_new_psw, lc->program_new_psw);
++      for (cr = 0; cr < ARRAY_SIZE(lc->cregs_save_area); cr++)
++              put_abs_lowcore(cregs_save_area[cr], lc->cregs_save_area[cr]);
+ }
+ static struct resource code_resource = {
+diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
+index 7bbcb5b8d3f6..35af70ed58fc 100644
+--- a/arch/s390/kernel/smp.c
++++ b/arch/s390/kernel/smp.c
+@@ -334,10 +334,10 @@ static void pcpu_delegate(struct pcpu *pcpu,
+               lc->restart_data = (unsigned long)data;
+               lc->restart_source = source_cpu;
+       } else {
+-              mem_assign_absolute(lc->restart_stack, stack);
+-              mem_assign_absolute(lc->restart_fn, (unsigned long)func);
+-              mem_assign_absolute(lc->restart_data, (unsigned long)data);
+-              mem_assign_absolute(lc->restart_source, source_cpu);
++              put_abs_lowcore(restart_stack, stack);
++              put_abs_lowcore(restart_fn, (unsigned long)func);
++              put_abs_lowcore(restart_data, (unsigned long)data);
++              put_abs_lowcore(restart_source, source_cpu);
+       }
+       __bpon();
+       asm volatile(
+@@ -593,9 +593,9 @@ void smp_ctl_set_clear_bit(int cr, int bit, bool set)
+               parms.andval = ~(1UL << bit);
+       }
+       spin_lock(&ctl_lock);
+-      memcpy_absolute(&ctlreg, &S390_lowcore.cregs_save_area[cr], sizeof(ctlreg));
++      get_abs_lowcore(ctlreg, cregs_save_area[cr]);
+       ctlreg = (ctlreg & parms.andval) | parms.orval;
+-      memcpy_absolute(&S390_lowcore.cregs_save_area[cr], &ctlreg, sizeof(ctlreg));
++      put_abs_lowcore(cregs_save_area[cr], ctlreg);
+       spin_unlock(&ctl_lock);
+       on_each_cpu(smp_ctl_bit_callback, &parms, 1);
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/s390-smp-cleanup-control-register-update-routines.patch b/queue-5.15/s390-smp-cleanup-control-register-update-routines.patch
new file mode 100644 (file)
index 0000000..d6d747c
--- /dev/null
@@ -0,0 +1,112 @@
+From f64be17b72d9b8c645358622c1783fd558f4c4d1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Mar 2022 15:03:02 +0100
+Subject: s390/smp: cleanup control register update routines
+
+From: Alexander Gordeev <agordeev@linux.ibm.com>
+
+[ Upstream commit 9097fc793f74ef9c677f8c4aed0c24f6f07f0133 ]
+
+Get rid of duplicate code and redundant data.
+
+Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/include/asm/ctl_reg.h | 16 ++++++++++-----
+ arch/s390/kernel/smp.c          | 36 +++++++++++----------------------
+ 2 files changed, 23 insertions(+), 29 deletions(-)
+
+diff --git a/arch/s390/include/asm/ctl_reg.h b/arch/s390/include/asm/ctl_reg.h
+index 04dc65f8901d..80b93c06a2bb 100644
+--- a/arch/s390/include/asm/ctl_reg.h
++++ b/arch/s390/include/asm/ctl_reg.h
+@@ -72,8 +72,17 @@ static __always_inline void __ctl_clear_bit(unsigned int cr, unsigned int bit)
+       __ctl_load(reg, cr, cr);
+ }
+-void smp_ctl_set_bit(int cr, int bit);
+-void smp_ctl_clear_bit(int cr, int bit);
++void smp_ctl_set_clear_bit(int cr, int bit, bool set);
++
++static inline void ctl_set_bit(int cr, int bit)
++{
++      smp_ctl_set_clear_bit(cr, bit, true);
++}
++
++static inline void ctl_clear_bit(int cr, int bit)
++{
++      smp_ctl_set_clear_bit(cr, bit, false);
++}
+ union ctlreg0 {
+       unsigned long val;
+@@ -128,8 +137,5 @@ union ctlreg15 {
+       };
+ };
+-#define ctl_set_bit(cr, bit) smp_ctl_set_bit(cr, bit)
+-#define ctl_clear_bit(cr, bit) smp_ctl_clear_bit(cr, bit)
+-
+ #endif /* __ASSEMBLY__ */
+ #endif /* __ASM_CTL_REG_H */
+diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
+index 982b72ca677c..7bbcb5b8d3f6 100644
+--- a/arch/s390/kernel/smp.c
++++ b/arch/s390/kernel/smp.c
+@@ -579,39 +579,27 @@ static void smp_ctl_bit_callback(void *info)
+ }
+ static DEFINE_SPINLOCK(ctl_lock);
+-static unsigned long ctlreg;
+-/*
+- * Set a bit in a control register of all cpus
+- */
+-void smp_ctl_set_bit(int cr, int bit)
++void smp_ctl_set_clear_bit(int cr, int bit, bool set)
+ {
+-      struct ec_creg_mask_parms parms = { 1UL << bit, -1UL, cr };
+-
+-      spin_lock(&ctl_lock);
+-      memcpy_absolute(&ctlreg, &S390_lowcore.cregs_save_area[cr], sizeof(ctlreg));
+-      __set_bit(bit, &ctlreg);
+-      memcpy_absolute(&S390_lowcore.cregs_save_area[cr], &ctlreg, sizeof(ctlreg));
+-      spin_unlock(&ctl_lock);
+-      on_each_cpu(smp_ctl_bit_callback, &parms, 1);
+-}
+-EXPORT_SYMBOL(smp_ctl_set_bit);
+-
+-/*
+- * Clear a bit in a control register of all cpus
+- */
+-void smp_ctl_clear_bit(int cr, int bit)
+-{
+-      struct ec_creg_mask_parms parms = { 0, ~(1UL << bit), cr };
++      struct ec_creg_mask_parms parms = { .cr = cr, };
++      u64 ctlreg;
++      if (set) {
++              parms.orval = 1UL << bit;
++              parms.andval = -1UL;
++      } else {
++              parms.orval = 0;
++              parms.andval = ~(1UL << bit);
++      }
+       spin_lock(&ctl_lock);
+       memcpy_absolute(&ctlreg, &S390_lowcore.cregs_save_area[cr], sizeof(ctlreg));
+-      __clear_bit(bit, &ctlreg);
++      ctlreg = (ctlreg & parms.andval) | parms.orval;
+       memcpy_absolute(&S390_lowcore.cregs_save_area[cr], &ctlreg, sizeof(ctlreg));
+       spin_unlock(&ctl_lock);
+       on_each_cpu(smp_ctl_bit_callback, &parms, 1);
+ }
+-EXPORT_SYMBOL(smp_ctl_clear_bit);
++EXPORT_SYMBOL(smp_ctl_set_clear_bit);
+ #ifdef CONFIG_CRASH_DUMP
+-- 
+2.35.1
+
diff --git a/queue-5.15/s390-smp-cleanup-target-cpu-callback-starting.patch b/queue-5.15/s390-smp-cleanup-target-cpu-callback-starting.patch
new file mode 100644 (file)
index 0000000..fcb33ed
--- /dev/null
@@ -0,0 +1,56 @@
+From 1d0d449eeeea2ede7426ab3d7b426b3452db0bf4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Mar 2022 15:03:01 +0100
+Subject: s390/smp: cleanup target CPU callback starting
+
+From: Alexander Gordeev <agordeev@linux.ibm.com>
+
+[ Upstream commit dc2ab23b992c9d5dab93b9bf01b10b10465e537e ]
+
+Macro mem_assign_absolute() is used to initialize a target
+CPU lowcore callback parameters. But despite the macro name
+it writes to the absolute lowcore only if the target CPU is
+offline. In case the CPU is online the macro does implicitly
+write to the normal memory.
+
+That behaviour is correct, but extremely subtle. Sacrifice
+few program bits in favour of clarity and distinguish between
+online vs offline CPUs and normal vs absolute lowcore pointer.
+
+Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/kernel/smp.c | 15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
+index e57eb2260b90..982b72ca677c 100644
+--- a/arch/s390/kernel/smp.c
++++ b/arch/s390/kernel/smp.c
+@@ -328,10 +328,17 @@ static void pcpu_delegate(struct pcpu *pcpu,
+       /* Stop target cpu (if func returns this stops the current cpu). */
+       pcpu_sigp_retry(pcpu, SIGP_STOP, 0);
+       /* Restart func on the target cpu and stop the current cpu. */
+-      mem_assign_absolute(lc->restart_stack, stack);
+-      mem_assign_absolute(lc->restart_fn, (unsigned long) func);
+-      mem_assign_absolute(lc->restart_data, (unsigned long) data);
+-      mem_assign_absolute(lc->restart_source, source_cpu);
++      if (lc) {
++              lc->restart_stack = stack;
++              lc->restart_fn = (unsigned long)func;
++              lc->restart_data = (unsigned long)data;
++              lc->restart_source = source_cpu;
++      } else {
++              mem_assign_absolute(lc->restart_stack, stack);
++              mem_assign_absolute(lc->restart_fn, (unsigned long)func);
++              mem_assign_absolute(lc->restart_data, (unsigned long)data);
++              mem_assign_absolute(lc->restart_source, source_cpu);
++      }
+       __bpon();
+       asm volatile(
+               "0:     sigp    0,%0,%2 # sigp restart to target cpu\n"
+-- 
+2.35.1
+
diff --git a/queue-5.15/s390-smp-enforce-lowcore-protection-on-cpu-restart.patch b/queue-5.15/s390-smp-enforce-lowcore-protection-on-cpu-restart.patch
new file mode 100644 (file)
index 0000000..bc9eac9
--- /dev/null
@@ -0,0 +1,41 @@
+From abdba5e46e2c025b5837093ed9f5692c3569f5d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Jul 2022 07:24:03 +0200
+Subject: s390/smp: enforce lowcore protection on CPU restart
+
+From: Alexander Gordeev <agordeev@linux.ibm.com>
+
+[ Upstream commit 6f5c672d17f583b081e283927f5040f726c54598 ]
+
+As result of commit 915fea04f932 ("s390/smp: enable DAT before
+CPU restart callback is called") the low-address protection bit
+gets mistakenly unset in control register 0 save area of the
+absolute zero memory. That area is used when manual PSW restart
+happened to hit an offline CPU. In this case the low-address
+protection for that CPU will be dropped.
+
+Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
+Fixes: 915fea04f932 ("s390/smp: enable DAT before CPU restart callback is called")
+Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/kernel/setup.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
+index 6b1a8697fae8..c8e7b3db82e2 100644
+--- a/arch/s390/kernel/setup.c
++++ b/arch/s390/kernel/setup.c
+@@ -507,8 +507,8 @@ static void __init setup_lowcore_dat_on(void)
+       S390_lowcore.svc_new_psw.mask |= PSW_MASK_DAT;
+       S390_lowcore.program_new_psw.mask |= PSW_MASK_DAT;
+       S390_lowcore.io_new_psw.mask |= PSW_MASK_DAT;
+-      __ctl_store(S390_lowcore.cregs_save_area, 0, 15);
+       __ctl_set_bit(0, 28);
++      __ctl_store(S390_lowcore.cregs_save_area, 0, 15);
+       put_abs_lowcore(restart_flags, RESTART_FLAG_CTLREGS);
+       put_abs_lowcore(program_new_psw, lc->program_new_psw);
+       for (cr = 0; cr < ARRAY_SIZE(lc->cregs_save_area); cr++)
+-- 
+2.35.1
+
diff --git a/queue-5.15/s390-zcore-fix-race-when-reading-from-hardware-syste.patch b/queue-5.15/s390-zcore-fix-race-when-reading-from-hardware-syste.patch
new file mode 100644 (file)
index 0000000..2816c5d
--- /dev/null
@@ -0,0 +1,84 @@
+From b62d17fc7e9876b4d16ee0451ddc864afe5ed834 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 07:16:33 +0200
+Subject: s390/zcore: fix race when reading from hardware system area
+
+From: Alexander Gordeev <agordeev@linux.ibm.com>
+
+[ Upstream commit 9ffed254d938c9e99eb7761c7f739294c84e0367 ]
+
+Memory buffer used for reading out data from hardware system
+area is not protected against concurrent access.
+
+Reported-by: Matthew Wilcox <willy@infradead.org>
+Fixes: 411ed3225733 ("[S390] zfcpdump support.")
+Acked-by: Heiko Carstens <hca@linux.ibm.com>
+Tested-by: Alexander Egorenkov <egorenar@linux.ibm.com>
+Link: https://lore.kernel.org/r/e68137f0f9a0d2558f37becc20af18e2939934f6.1658206891.git.agordeev@linux.ibm.com
+Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/s390/char/zcore.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c
+index 516783ba950f..92b32ce645b9 100644
+--- a/drivers/s390/char/zcore.c
++++ b/drivers/s390/char/zcore.c
+@@ -50,6 +50,7 @@ static struct dentry *zcore_reipl_file;
+ static struct dentry *zcore_hsa_file;
+ static struct ipl_parameter_block *zcore_ipl_block;
++static DEFINE_MUTEX(hsa_buf_mutex);
+ static char hsa_buf[PAGE_SIZE] __aligned(PAGE_SIZE);
+ /*
+@@ -66,19 +67,24 @@ int memcpy_hsa_user(void __user *dest, unsigned long src, size_t count)
+       if (!hsa_available)
+               return -ENODATA;
++      mutex_lock(&hsa_buf_mutex);
+       while (count) {
+               if (sclp_sdias_copy(hsa_buf, src / PAGE_SIZE + 2, 1)) {
+                       TRACE("sclp_sdias_copy() failed\n");
++                      mutex_unlock(&hsa_buf_mutex);
+                       return -EIO;
+               }
+               offset = src % PAGE_SIZE;
+               bytes = min(PAGE_SIZE - offset, count);
+-              if (copy_to_user(dest, hsa_buf + offset, bytes))
++              if (copy_to_user(dest, hsa_buf + offset, bytes)) {
++                      mutex_unlock(&hsa_buf_mutex);
+                       return -EFAULT;
++              }
+               src += bytes;
+               dest += bytes;
+               count -= bytes;
+       }
++      mutex_unlock(&hsa_buf_mutex);
+       return 0;
+ }
+@@ -96,9 +102,11 @@ int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count)
+       if (!hsa_available)
+               return -ENODATA;
++      mutex_lock(&hsa_buf_mutex);
+       while (count) {
+               if (sclp_sdias_copy(hsa_buf, src / PAGE_SIZE + 2, 1)) {
+                       TRACE("sclp_sdias_copy() failed\n");
++                      mutex_unlock(&hsa_buf_mutex);
+                       return -EIO;
+               }
+               offset = src % PAGE_SIZE;
+@@ -108,6 +116,7 @@ int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count)
+               dest += bytes;
+               count -= bytes;
+       }
++      mutex_unlock(&hsa_buf_mutex);
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/sched-core-always-flush-pending-blk_plug.patch b/queue-5.15/sched-core-always-flush-pending-blk_plug.patch
new file mode 100644 (file)
index 0000000..973b081
--- /dev/null
@@ -0,0 +1,154 @@
+From e624c344400c1f9062ba6af3b70a247cb887ee77 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Jul 2022 17:27:02 +0100
+Subject: sched/core: Always flush pending blk_plug
+
+From: John Keeping <john@metanate.com>
+
+[ Upstream commit 401e4963bf45c800e3e9ea0d3a0289d738005fd4 ]
+
+With CONFIG_PREEMPT_RT, it is possible to hit a deadlock between two
+normal priority tasks (SCHED_OTHER, nice level zero):
+
+       INFO: task kworker/u8:0:8 blocked for more than 491 seconds.
+             Not tainted 5.15.49-rt46 #1
+       "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+       task:kworker/u8:0    state:D stack:    0 pid:    8 ppid:     2 flags:0x00000000
+       Workqueue: writeback wb_workfn (flush-7:0)
+       [<c08a3a10>] (__schedule) from [<c08a3d84>] (schedule+0xdc/0x134)
+       [<c08a3d84>] (schedule) from [<c08a65a0>] (rt_mutex_slowlock_block.constprop.0+0xb8/0x174)
+       [<c08a65a0>] (rt_mutex_slowlock_block.constprop.0) from [<c08a6708>]
+       +(rt_mutex_slowlock.constprop.0+0xac/0x174)
+       [<c08a6708>] (rt_mutex_slowlock.constprop.0) from [<c0374d60>] (fat_write_inode+0x34/0x54)
+       [<c0374d60>] (fat_write_inode) from [<c0297304>] (__writeback_single_inode+0x354/0x3ec)
+       [<c0297304>] (__writeback_single_inode) from [<c0297998>] (writeback_sb_inodes+0x250/0x45c)
+       [<c0297998>] (writeback_sb_inodes) from [<c0297c20>] (__writeback_inodes_wb+0x7c/0xb8)
+       [<c0297c20>] (__writeback_inodes_wb) from [<c0297f24>] (wb_writeback+0x2c8/0x2e4)
+       [<c0297f24>] (wb_writeback) from [<c0298c40>] (wb_workfn+0x1a4/0x3e4)
+       [<c0298c40>] (wb_workfn) from [<c0138ab8>] (process_one_work+0x1fc/0x32c)
+       [<c0138ab8>] (process_one_work) from [<c0139120>] (worker_thread+0x22c/0x2d8)
+       [<c0139120>] (worker_thread) from [<c013e6e0>] (kthread+0x16c/0x178)
+       [<c013e6e0>] (kthread) from [<c01000fc>] (ret_from_fork+0x14/0x38)
+       Exception stack(0xc10e3fb0 to 0xc10e3ff8)
+       3fa0:                                     00000000 00000000 00000000 00000000
+       3fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
+       3fe0: 00000000 00000000 00000000 00000000 00000013 00000000
+
+       INFO: task tar:2083 blocked for more than 491 seconds.
+             Not tainted 5.15.49-rt46 #1
+       "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+       task:tar             state:D stack:    0 pid: 2083 ppid:  2082 flags:0x00000000
+       [<c08a3a10>] (__schedule) from [<c08a3d84>] (schedule+0xdc/0x134)
+       [<c08a3d84>] (schedule) from [<c08a41b0>] (io_schedule+0x14/0x24)
+       [<c08a41b0>] (io_schedule) from [<c08a455c>] (bit_wait_io+0xc/0x30)
+       [<c08a455c>] (bit_wait_io) from [<c08a441c>] (__wait_on_bit_lock+0x54/0xa8)
+       [<c08a441c>] (__wait_on_bit_lock) from [<c08a44f4>] (out_of_line_wait_on_bit_lock+0x84/0xb0)
+       [<c08a44f4>] (out_of_line_wait_on_bit_lock) from [<c0371fb0>] (fat_mirror_bhs+0xa0/0x144)
+       [<c0371fb0>] (fat_mirror_bhs) from [<c0372a68>] (fat_alloc_clusters+0x138/0x2a4)
+       [<c0372a68>] (fat_alloc_clusters) from [<c0370b14>] (fat_alloc_new_dir+0x34/0x250)
+       [<c0370b14>] (fat_alloc_new_dir) from [<c03787c0>] (vfat_mkdir+0x58/0x148)
+       [<c03787c0>] (vfat_mkdir) from [<c0277b60>] (vfs_mkdir+0x68/0x98)
+       [<c0277b60>] (vfs_mkdir) from [<c027b484>] (do_mkdirat+0xb0/0xec)
+       [<c027b484>] (do_mkdirat) from [<c0100060>] (ret_fast_syscall+0x0/0x1c)
+       Exception stack(0xc2e1bfa8 to 0xc2e1bff0)
+       bfa0:                   01ee42f0 01ee4208 01ee42f0 000041ed 00000000 00004000
+       bfc0: 01ee42f0 01ee4208 00000000 00000027 01ee4302 00000004 000dcb00 01ee4190
+       bfe0: 000dc368 bed11924 0006d4b0 b6ebddfc
+
+Here the kworker is waiting on msdos_sb_info::s_lock which is held by
+tar which is in turn waiting for a buffer which is locked waiting to be
+flushed, but this operation is plugged in the kworker.
+
+The lock is a normal struct mutex, so tsk_is_pi_blocked() will always
+return false on !RT and thus the behaviour changes for RT.
+
+It seems that the intent here is to skip blk_flush_plug() in the case
+where a non-preemptible lock (such as a spinlock) has been converted to
+a rtmutex on RT, which is the case covered by the SM_RTLOCK_WAIT
+schedule flag.  But sched_submit_work() is only called from schedule()
+which is never called in this scenario, so the check can simply be
+deleted.
+
+Looking at the history of the -rt patchset, in fact this change was
+present from v5.9.1-rt20 until being dropped in v5.13-rt1 as it was part
+of a larger patch [1] most of which was replaced by commit b4bfa3fcfe3b
+("sched/core: Rework the __schedule() preempt argument").
+
+As described in [1]:
+
+   The schedule process must distinguish between blocking on a regular
+   sleeping lock (rwsem and mutex) and a RT-only sleeping lock (spinlock
+   and rwlock):
+   - rwsem and mutex must flush block requests (blk_schedule_flush_plug())
+     even if blocked on a lock. This can not deadlock because this also
+     happens for non-RT.
+     There should be a warning if the scheduling point is within a RCU read
+     section.
+
+   - spinlock and rwlock must not flush block requests. This will deadlock
+     if the callback attempts to acquire a lock which is already acquired.
+     Similarly to being preempted, there should be no warning if the
+     scheduling point is within a RCU read section.
+
+and with the tsk_is_pi_blocked() in the scheduler path, we hit the first
+issue.
+
+[1] https://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-rt-devel.git/tree/patches/0022-locking-rtmutex-Use-custom-scheduling-function-for-s.patch?h=linux-5.10.y-rt-patches
+
+Signed-off-by: John Keeping <john@metanate.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Link: https://lkml.kernel.org/r/20220708162702.1758865-1-john@metanate.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/sched/rt.h | 8 --------
+ kernel/sched/core.c      | 8 ++++++--
+ 2 files changed, 6 insertions(+), 10 deletions(-)
+
+diff --git a/include/linux/sched/rt.h b/include/linux/sched/rt.h
+index e5af028c08b4..994c25640e15 100644
+--- a/include/linux/sched/rt.h
++++ b/include/linux/sched/rt.h
+@@ -39,20 +39,12 @@ static inline struct task_struct *rt_mutex_get_top_task(struct task_struct *p)
+ }
+ extern void rt_mutex_setprio(struct task_struct *p, struct task_struct *pi_task);
+ extern void rt_mutex_adjust_pi(struct task_struct *p);
+-static inline bool tsk_is_pi_blocked(struct task_struct *tsk)
+-{
+-      return tsk->pi_blocked_on != NULL;
+-}
+ #else
+ static inline struct task_struct *rt_mutex_get_top_task(struct task_struct *task)
+ {
+       return NULL;
+ }
+ # define rt_mutex_adjust_pi(p)                do { } while (0)
+-static inline bool tsk_is_pi_blocked(struct task_struct *tsk)
+-{
+-      return false;
+-}
+ #endif
+ extern void normalize_rt_tasks(void);
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index b89ca5c83143..012c037da58a 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -6379,8 +6379,12 @@ static inline void sched_submit_work(struct task_struct *tsk)
+               preempt_enable_no_resched();
+       }
+-      if (tsk_is_pi_blocked(tsk))
+-              return;
++      /*
++       * spinlock and rwlock must not flush block requests.  This will
++       * deadlock if the callback attempts to acquire a lock which is
++       * already acquired.
++       */
++      SCHED_WARN_ON(current->__state & TASK_RTLOCK_WAIT);
+       /*
+        * If we are going to sleep and we have plugged IO queued,
+-- 
+2.35.1
+
diff --git a/queue-5.15/sched-core-do-not-requeue-task-on-cpu-excluded-from-.patch b/queue-5.15/sched-core-do-not-requeue-task-on-cpu-excluded-from-.patch
new file mode 100644 (file)
index 0000000..f738865
--- /dev/null
@@ -0,0 +1,85 @@
+From 1e365cb22d18f8f84aebf445946640b80b8f7957 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Aug 2022 10:21:19 +0100
+Subject: sched/core: Do not requeue task on CPU excluded from cpus_mask
+
+From: Mel Gorman <mgorman@techsingularity.net>
+
+[ Upstream commit 751d4cbc43879229dbc124afefe240b70fd29a85 ]
+
+The following warning was triggered on a large machine early in boot on
+a distribution kernel but the same problem should also affect mainline.
+
+   WARNING: CPU: 439 PID: 10 at ../kernel/workqueue.c:2231 process_one_work+0x4d/0x440
+   Call Trace:
+    <TASK>
+    rescuer_thread+0x1f6/0x360
+    kthread+0x156/0x180
+    ret_from_fork+0x22/0x30
+    </TASK>
+
+Commit c6e7bd7afaeb ("sched/core: Optimize ttwu() spinning on p->on_cpu")
+optimises ttwu by queueing a task that is descheduling on the wakelist,
+but does not check if the task descheduling is still allowed to run on that CPU.
+
+In this warning, the problematic task is a workqueue rescue thread which
+checks if the rescue is for a per-cpu workqueue and running on the wrong CPU.
+While this is early in boot and it should be possible to create workers,
+the rescue thread may still used if the MAYDAY_INITIAL_TIMEOUT is reached
+or MAYDAY_INTERVAL and on a sufficiently large machine, the rescue
+thread is being used frequently.
+
+Tracing confirmed that the task should have migrated properly using the
+stopper thread to handle the migration. However, a parallel wakeup from udev
+running on another CPU that does not share CPU cache observes p->on_cpu and
+uses task_cpu(p), queues the task on the old CPU and triggers the warning.
+
+Check that the wakee task that is descheduling is still allowed to run
+on its current CPU and if not, wait for the descheduling to complete
+and select an allowed CPU.
+
+Fixes: c6e7bd7afaeb ("sched/core: Optimize ttwu() spinning on p->on_cpu")
+Signed-off-by: Mel Gorman <mgorman@techsingularity.net>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Link: https://lore.kernel.org/r/20220804092119.20137-1-mgorman@techsingularity.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/core.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index 4499b58ac2ca..85be684687b0 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -3714,7 +3714,7 @@ bool cpus_share_cache(int this_cpu, int that_cpu)
+       return per_cpu(sd_llc_id, this_cpu) == per_cpu(sd_llc_id, that_cpu);
+ }
+-static inline bool ttwu_queue_cond(int cpu)
++static inline bool ttwu_queue_cond(struct task_struct *p, int cpu)
+ {
+       /*
+        * Do not complicate things with the async wake_list while the CPU is
+@@ -3723,6 +3723,10 @@ static inline bool ttwu_queue_cond(int cpu)
+       if (!cpu_active(cpu))
+               return false;
++      /* Ensure the task will still be allowed to run on the CPU. */
++      if (!cpumask_test_cpu(cpu, p->cpus_ptr))
++              return false;
++
+       /*
+        * If the CPU does not share cache, then queue the task on the
+        * remote rqs wakelist to avoid accessing remote data.
+@@ -3752,7 +3756,7 @@ static inline bool ttwu_queue_cond(int cpu)
+ static bool ttwu_queue_wakelist(struct task_struct *p, int cpu, int wake_flags)
+ {
+-      if (sched_feat(TTWU_QUEUE) && ttwu_queue_cond(cpu)) {
++      if (sched_feat(TTWU_QUEUE) && ttwu_queue_cond(p, cpu)) {
+               sched_clock_cpu(cpu); /* Sync clocks across CPUs */
+               __ttwu_queue_wakelist(p, cpu, wake_flags);
+               return true;
+-- 
+2.35.1
+
diff --git a/queue-5.15/sched-cpuset-fix-dl_cpu_busy-panic-due-to-empty-cs-c.patch b/queue-5.15/sched-cpuset-fix-dl_cpu_busy-panic-due-to-empty-cs-c.patch
new file mode 100644 (file)
index 0000000..aad3051
--- /dev/null
@@ -0,0 +1,109 @@
+From 23d7babff1ae2f8e92d5750634b0af9e36f76ea4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Aug 2022 21:54:51 -0400
+Subject: sched, cpuset: Fix dl_cpu_busy() panic due to empty cs->cpus_allowed
+
+From: Waiman Long <longman@redhat.com>
+
+[ Upstream commit b6e8d40d43ae4dec00c8fea2593eeea3114b8f44 ]
+
+With cgroup v2, the cpuset's cpus_allowed mask can be empty indicating
+that the cpuset will just use the effective CPUs of its parent. So
+cpuset_can_attach() can call task_can_attach() with an empty mask.
+This can lead to cpumask_any_and() returns nr_cpu_ids causing the call
+to dl_bw_of() to crash due to percpu value access of an out of bound
+CPU value. For example:
+
+       [80468.182258] BUG: unable to handle page fault for address: ffffffff8b6648b0
+         :
+       [80468.191019] RIP: 0010:dl_cpu_busy+0x30/0x2b0
+         :
+       [80468.207946] Call Trace:
+       [80468.208947]  cpuset_can_attach+0xa0/0x140
+       [80468.209953]  cgroup_migrate_execute+0x8c/0x490
+       [80468.210931]  cgroup_update_dfl_csses+0x254/0x270
+       [80468.211898]  cgroup_subtree_control_write+0x322/0x400
+       [80468.212854]  kernfs_fop_write_iter+0x11c/0x1b0
+       [80468.213777]  new_sync_write+0x11f/0x1b0
+       [80468.214689]  vfs_write+0x1eb/0x280
+       [80468.215592]  ksys_write+0x5f/0xe0
+       [80468.216463]  do_syscall_64+0x5c/0x80
+       [80468.224287]  entry_SYSCALL_64_after_hwframe+0x44/0xae
+
+Fix that by using effective_cpus instead. For cgroup v1, effective_cpus
+is the same as cpus_allowed. For v2, effective_cpus is the real cpumask
+to be used by tasks within the cpuset anyway.
+
+Also update task_can_attach()'s 2nd argument name to cs_effective_cpus to
+reflect the change. In addition, a check is added to task_can_attach()
+to guard against the possibility that cpumask_any_and() may return a
+value >= nr_cpu_ids.
+
+Fixes: 7f51412a415d ("sched/deadline: Fix bandwidth check/update when migrating tasks between exclusive cpusets")
+Signed-off-by: Waiman Long <longman@redhat.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Juri Lelli <juri.lelli@redhat.com>
+Link: https://lore.kernel.org/r/20220803015451.2219567-1-longman@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/sched.h  | 2 +-
+ kernel/cgroup/cpuset.c | 2 +-
+ kernel/sched/core.c    | 8 +++++---
+ 3 files changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/include/linux/sched.h b/include/linux/sched.h
+index ad7ff332a0ac..dcba347cbffa 100644
+--- a/include/linux/sched.h
++++ b/include/linux/sched.h
+@@ -1797,7 +1797,7 @@ current_restore_flags(unsigned long orig_flags, unsigned long flags)
+ }
+ extern int cpuset_cpumask_can_shrink(const struct cpumask *cur, const struct cpumask *trial);
+-extern int task_can_attach(struct task_struct *p, const struct cpumask *cs_cpus_allowed);
++extern int task_can_attach(struct task_struct *p, const struct cpumask *cs_effective_cpus);
+ #ifdef CONFIG_SMP
+ extern void do_set_cpus_allowed(struct task_struct *p, const struct cpumask *new_mask);
+ extern int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask);
+diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
+index 31f94c6ea0a5..9c5b659db63f 100644
+--- a/kernel/cgroup/cpuset.c
++++ b/kernel/cgroup/cpuset.c
+@@ -2199,7 +2199,7 @@ static int cpuset_can_attach(struct cgroup_taskset *tset)
+               goto out_unlock;
+       cgroup_taskset_for_each(task, css, tset) {
+-              ret = task_can_attach(task, cs->cpus_allowed);
++              ret = task_can_attach(task, cs->effective_cpus);
+               if (ret)
+                       goto out_unlock;
+               ret = security_task_setscheduler(task);
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index 154506e4d1f5..5c7937b504d2 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -8741,7 +8741,7 @@ int cpuset_cpumask_can_shrink(const struct cpumask *cur,
+ }
+ int task_can_attach(struct task_struct *p,
+-                  const struct cpumask *cs_cpus_allowed)
++                  const struct cpumask *cs_effective_cpus)
+ {
+       int ret = 0;
+@@ -8760,9 +8760,11 @@ int task_can_attach(struct task_struct *p,
+       }
+       if (dl_task(p) && !cpumask_intersects(task_rq(p)->rd->span,
+-                                            cs_cpus_allowed)) {
+-              int cpu = cpumask_any_and(cpu_active_mask, cs_cpus_allowed);
++                                            cs_effective_cpus)) {
++              int cpu = cpumask_any_and(cpu_active_mask, cs_effective_cpus);
++              if (unlikely(cpu >= nr_cpu_ids))
++                      return -EINVAL;
+               ret = dl_cpu_busy(cpu, p);
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/sched-deadline-merge-dl_task_can_attach-and-dl_cpu_b.patch b/queue-5.15/sched-deadline-merge-dl_task_can_attach-and-dl_cpu_b.patch
new file mode 100644 (file)
index 0000000..c5ab2a8
--- /dev/null
@@ -0,0 +1,164 @@
+From dcd4bc4551184540eed06b1f89645a5e3b0ac3ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Mar 2022 19:34:30 +0100
+Subject: sched/deadline: Merge dl_task_can_attach() and dl_cpu_busy()
+
+From: Dietmar Eggemann <dietmar.eggemann@arm.com>
+
+[ Upstream commit 772b6539fdda31462cc08368e78df60b31a58bab ]
+
+Both functions are doing almost the same, that is checking if admission
+control is still respected.
+
+With exclusive cpusets, dl_task_can_attach() checks if the destination
+cpuset (i.e. its root domain) has enough CPU capacity to accommodate the
+task.
+dl_cpu_busy() checks if there is enough CPU capacity in the cpuset in
+case the CPU is hot-plugged out.
+
+dl_task_can_attach() is used to check if a task can be admitted while
+dl_cpu_busy() is used to check if a CPU can be hotplugged out.
+
+Make dl_cpu_busy() able to deal with a task and use it instead of
+dl_task_can_attach() in task_can_attach().
+
+Signed-off-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Acked-by: Juri Lelli <juri.lelli@redhat.com>
+Link: https://lore.kernel.org/r/20220302183433.333029-4-dietmar.eggemann@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/core.c     | 13 +++++++----
+ kernel/sched/deadline.c | 52 +++++++++++------------------------------
+ kernel/sched/sched.h    |  3 +--
+ 3 files changed, 24 insertions(+), 44 deletions(-)
+
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index 012c037da58a..154506e4d1f5 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -8760,8 +8760,11 @@ int task_can_attach(struct task_struct *p,
+       }
+       if (dl_task(p) && !cpumask_intersects(task_rq(p)->rd->span,
+-                                            cs_cpus_allowed))
+-              ret = dl_task_can_attach(p, cs_cpus_allowed);
++                                            cs_cpus_allowed)) {
++              int cpu = cpumask_any_and(cpu_active_mask, cs_cpus_allowed);
++
++              ret = dl_cpu_busy(cpu, p);
++      }
+ out:
+       return ret;
+@@ -9045,8 +9048,10 @@ static void cpuset_cpu_active(void)
+ static int cpuset_cpu_inactive(unsigned int cpu)
+ {
+       if (!cpuhp_tasks_frozen) {
+-              if (dl_cpu_busy(cpu))
+-                      return -EBUSY;
++              int ret = dl_cpu_busy(cpu, NULL);
++
++              if (ret)
++                      return ret;
+               cpuset_update_active_cpus();
+       } else {
+               num_cpus_frozen++;
+diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
+index ee673a205e22..147b757d162b 100644
+--- a/kernel/sched/deadline.c
++++ b/kernel/sched/deadline.c
+@@ -2864,41 +2864,6 @@ bool dl_param_changed(struct task_struct *p, const struct sched_attr *attr)
+ }
+ #ifdef CONFIG_SMP
+-int dl_task_can_attach(struct task_struct *p, const struct cpumask *cs_cpus_allowed)
+-{
+-      unsigned long flags, cap;
+-      unsigned int dest_cpu;
+-      struct dl_bw *dl_b;
+-      bool overflow;
+-      int ret;
+-
+-      dest_cpu = cpumask_any_and(cpu_active_mask, cs_cpus_allowed);
+-
+-      rcu_read_lock_sched();
+-      dl_b = dl_bw_of(dest_cpu);
+-      raw_spin_lock_irqsave(&dl_b->lock, flags);
+-      cap = dl_bw_capacity(dest_cpu);
+-      overflow = __dl_overflow(dl_b, cap, 0, p->dl.dl_bw);
+-      if (overflow) {
+-              ret = -EBUSY;
+-      } else {
+-              /*
+-               * We reserve space for this task in the destination
+-               * root_domain, as we can't fail after this point.
+-               * We will free resources in the source root_domain
+-               * later on (see set_cpus_allowed_dl()).
+-               */
+-              int cpus = dl_bw_cpus(dest_cpu);
+-
+-              __dl_add(dl_b, p->dl.dl_bw, cpus);
+-              ret = 0;
+-      }
+-      raw_spin_unlock_irqrestore(&dl_b->lock, flags);
+-      rcu_read_unlock_sched();
+-
+-      return ret;
+-}
+-
+ int dl_cpuset_cpumask_can_shrink(const struct cpumask *cur,
+                                const struct cpumask *trial)
+ {
+@@ -2920,7 +2885,7 @@ int dl_cpuset_cpumask_can_shrink(const struct cpumask *cur,
+       return ret;
+ }
+-bool dl_cpu_busy(unsigned int cpu)
++int dl_cpu_busy(int cpu, struct task_struct *p)
+ {
+       unsigned long flags, cap;
+       struct dl_bw *dl_b;
+@@ -2930,11 +2895,22 @@ bool dl_cpu_busy(unsigned int cpu)
+       dl_b = dl_bw_of(cpu);
+       raw_spin_lock_irqsave(&dl_b->lock, flags);
+       cap = dl_bw_capacity(cpu);
+-      overflow = __dl_overflow(dl_b, cap, 0, 0);
++      overflow = __dl_overflow(dl_b, cap, 0, p ? p->dl.dl_bw : 0);
++
++      if (!overflow && p) {
++              /*
++               * We reserve space for this task in the destination
++               * root_domain, as we can't fail after this point.
++               * We will free resources in the source root_domain
++               * later on (see set_cpus_allowed_dl()).
++               */
++              __dl_add(dl_b, p->dl.dl_bw, dl_bw_cpus(cpu));
++      }
++
+       raw_spin_unlock_irqrestore(&dl_b->lock, flags);
+       rcu_read_unlock_sched();
+-      return overflow;
++      return overflow ? -EBUSY : 0;
+ }
+ #endif
+diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
+index fe8be2f8a47d..2bbf1f006d63 100644
+--- a/kernel/sched/sched.h
++++ b/kernel/sched/sched.h
+@@ -348,9 +348,8 @@ extern void __setparam_dl(struct task_struct *p, const struct sched_attr *attr);
+ extern void __getparam_dl(struct task_struct *p, struct sched_attr *attr);
+ extern bool __checkparam_dl(const struct sched_attr *attr);
+ extern bool dl_param_changed(struct task_struct *p, const struct sched_attr *attr);
+-extern int  dl_task_can_attach(struct task_struct *p, const struct cpumask *cs_cpus_allowed);
+ extern int  dl_cpuset_cpumask_can_shrink(const struct cpumask *cur, const struct cpumask *trial);
+-extern bool dl_cpu_busy(unsigned int cpu);
++extern int  dl_cpu_busy(int cpu, struct task_struct *p);
+ #ifdef CONFIG_CGROUP_SCHED
+-- 
+2.35.1
+
diff --git a/queue-5.15/sched-fair-introduce-sis_util-to-search-idle-cpu-bas.patch b/queue-5.15/sched-fair-introduce-sis_util-to-search-idle-cpu-bas.patch
new file mode 100644 (file)
index 0000000..4688d3c
--- /dev/null
@@ -0,0 +1,541 @@
+From 21dd3d11af306814a754df5c316bfccf654622f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 00:34:28 +0800
+Subject: sched/fair: Introduce SIS_UTIL to search idle CPU based on sum of
+ util_avg
+
+From: Chen Yu <yu.c.chen@intel.com>
+
+[ Upstream commit 70fb5ccf2ebb09a0c8ebba775041567812d45f86 ]
+
+[Problem Statement]
+select_idle_cpu() might spend too much time searching for an idle CPU,
+when the system is overloaded.
+
+The following histogram is the time spent in select_idle_cpu(),
+when running 224 instances of netperf on a system with 112 CPUs
+per LLC domain:
+
+@usecs:
+[0]                  533 |                                                    |
+[1]                 5495 |                                                    |
+[2, 4)             12008 |                                                    |
+[4, 8)            239252 |                                                    |
+[8, 16)          4041924 |@@@@@@@@@@@@@@                                      |
+[16, 32)        12357398 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@         |
+[32, 64)        14820255 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|
+[64, 128)       13047682 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@       |
+[128, 256)       8235013 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@                        |
+[256, 512)       4507667 |@@@@@@@@@@@@@@@                                     |
+[512, 1K)        2600472 |@@@@@@@@@                                           |
+[1K, 2K)          927912 |@@@                                                 |
+[2K, 4K)          218720 |                                                    |
+[4K, 8K)           98161 |                                                    |
+[8K, 16K)          37722 |                                                    |
+[16K, 32K)          6715 |                                                    |
+[32K, 64K)           477 |                                                    |
+[64K, 128K)            7 |                                                    |
+
+netperf latency usecs:
+=======
+case                   load                Lat_99th        std%
+TCP_RR                 thread-224            257.39    (  0.21)
+
+The time spent in select_idle_cpu() is visible to netperf and might have a negative
+impact.
+
+[Symptom analysis]
+The patch [1] from Mel Gorman has been applied to track the efficiency
+of select_idle_sibling. Copy the indicators here:
+
+SIS Search Efficiency(se_eff%):
+        A ratio expressed as a percentage of runqueues scanned versus
+        idle CPUs found. A 100% efficiency indicates that the target,
+        prev or recent CPU of a task was idle at wakeup. The lower the
+        efficiency, the more runqueues were scanned before an idle CPU
+        was found.
+
+SIS Domain Search Efficiency(dom_eff%):
+        Similar, except only for the slower SIS
+       patch.
+
+SIS Fast Success Rate(fast_rate%):
+        Percentage of SIS that used target, prev or
+       recent CPUs.
+
+SIS Success rate(success_rate%):
+        Percentage of scans that found an idle CPU.
+
+The test is based on Aubrey's schedtests tool, including netperf, hackbench,
+schbench and tbench.
+
+Test on vanilla kernel:
+schedstat_parse.py -f netperf_vanilla.log
+case           load        se_eff%         dom_eff%      fast_rate%    success_rate%
+TCP_RR    28 threads        99.978           18.535          99.995         100.000
+TCP_RR    56 threads        99.397            5.671          99.964         100.000
+TCP_RR    84 threads        21.721            6.818          73.632         100.000
+TCP_RR   112 threads        12.500            5.533          59.000         100.000
+TCP_RR   140 threads         8.524            4.535          49.020         100.000
+TCP_RR   168 threads         6.438            3.945          40.309          99.999
+TCP_RR   196 threads         5.397            3.718          32.320          99.982
+TCP_RR   224 threads         4.874            3.661          25.775          99.767
+UDP_RR    28 threads        99.988           17.704          99.997         100.000
+UDP_RR    56 threads        99.528            5.977          99.970         100.000
+UDP_RR    84 threads        24.219            6.992          76.479         100.000
+UDP_RR   112 threads        13.907            5.706          62.538         100.000
+UDP_RR   140 threads         9.408            4.699          52.519         100.000
+UDP_RR   168 threads         7.095            4.077          44.352         100.000
+UDP_RR   196 threads         5.757            3.775          35.764          99.991
+UDP_RR   224 threads         5.124            3.704          28.748          99.860
+
+schedstat_parse.py -f schbench_vanilla.log
+(each group has 28 tasks)
+case           load        se_eff%         dom_eff%      fast_rate%    success_rate%
+normal    1   mthread       99.152            6.400          99.941         100.000
+normal    2   mthreads      97.844            4.003          99.908         100.000
+normal    3   mthreads      96.395            2.118          99.917          99.998
+normal    4   mthreads      55.288            1.451          98.615          99.804
+normal    5   mthreads       7.004            1.870          45.597          61.036
+normal    6   mthreads       3.354            1.346          20.777          34.230
+normal    7   mthreads       2.183            1.028          11.257          21.055
+normal    8   mthreads       1.653            0.825           7.849          15.549
+
+schedstat_parse.py -f hackbench_vanilla.log
+(each group has 28 tasks)
+case                   load            se_eff%     dom_eff%      fast_rate%    success_rate%
+process-pipe        1 group             99.991        7.692          99.999         100.000
+process-pipe       2 groups             99.934        4.615          99.997         100.000
+process-pipe       3 groups             99.597        3.198          99.987         100.000
+process-pipe       4 groups             98.378        2.464          99.958         100.000
+process-pipe       5 groups             27.474        3.653          89.811          99.800
+process-pipe       6 groups             20.201        4.098          82.763          99.570
+process-pipe       7 groups             16.423        4.156          77.398          99.316
+process-pipe       8 groups             13.165        3.920          72.232          98.828
+process-sockets             1 group             99.977        5.882          99.999         100.000
+process-sockets            2 groups             99.927        5.505          99.996         100.000
+process-sockets            3 groups             99.397        3.250          99.980         100.000
+process-sockets            4 groups             79.680        4.258          98.864          99.998
+process-sockets            5 groups              7.673        2.503          63.659          92.115
+process-sockets            6 groups              4.642        1.584          58.946          88.048
+process-sockets            7 groups              3.493        1.379          49.816          81.164
+process-sockets            8 groups              3.015        1.407          40.845          75.500
+threads-pipe        1 group             99.997        0.000         100.000         100.000
+threads-pipe       2 groups             99.894        2.932          99.997         100.000
+threads-pipe       3 groups             99.611        4.117          99.983         100.000
+threads-pipe       4 groups             97.703        2.624          99.937         100.000
+threads-pipe       5 groups             22.919        3.623          87.150          99.764
+threads-pipe       6 groups             18.016        4.038          80.491          99.557
+threads-pipe       7 groups             14.663        3.991          75.239          99.247
+threads-pipe       8 groups             12.242        3.808          70.651          98.644
+threads-sockets             1 group             99.990        6.667          99.999         100.000
+threads-sockets            2 groups             99.940        5.114          99.997         100.000
+threads-sockets            3 groups             99.469        4.115          99.977         100.000
+threads-sockets            4 groups             87.528        4.038          99.400         100.000
+threads-sockets            5 groups              6.942        2.398          59.244          88.337
+threads-sockets            6 groups              4.359        1.954          49.448          87.860
+threads-sockets            7 groups              2.845        1.345          41.198          77.102
+threads-sockets            8 groups              2.871        1.404          38.512          74.312
+
+schedstat_parse.py -f tbench_vanilla.log
+case                   load          se_eff%       dom_eff%      fast_rate%    success_rate%
+loopback         28 threads           99.976         18.369          99.995         100.000
+loopback         56 threads           99.222          7.799          99.934         100.000
+loopback         84 threads           19.723          6.819          70.215         100.000
+loopback        112 threads           11.283          5.371          55.371          99.999
+loopback        140 threads            0.000          0.000           0.000           0.000
+loopback        168 threads            0.000          0.000           0.000           0.000
+loopback        196 threads            0.000          0.000           0.000           0.000
+loopback        224 threads            0.000          0.000           0.000           0.000
+
+According to the test above, if the system becomes busy, the
+SIS Search Efficiency(se_eff%) drops significantly. Although some
+benchmarks would finally find an idle CPU(success_rate% = 100%), it is
+doubtful whether it is worth it to search the whole LLC domain.
+
+[Proposal]
+It would be ideal to have a crystal ball to answer this question:
+How many CPUs must a wakeup path walk down, before it can find an idle
+CPU? Many potential metrics could be used to predict the number.
+One candidate is the sum of util_avg in this LLC domain. The benefit
+of choosing util_avg is that it is a metric of accumulated historic
+activity, which seems to be smoother than instantaneous metrics
+(such as rq->nr_running). Besides, choosing the sum of util_avg
+would help predict the load of the LLC domain more precisely, because
+SIS_PROP uses one CPU's idle time to estimate the total LLC domain idle
+time.
+
+In summary, the lower the util_avg is, the more select_idle_cpu()
+should scan for idle CPU, and vice versa. When the sum of util_avg
+in this LLC domain hits 85% or above, the scan stops. The reason to
+choose 85% as the threshold is that this is the imbalance_pct(117)
+when a LLC sched group is overloaded.
+
+Introduce the quadratic function:
+
+y = SCHED_CAPACITY_SCALE - p * x^2
+and y'= y / SCHED_CAPACITY_SCALE
+
+x is the ratio of sum_util compared to the CPU capacity:
+x = sum_util / (llc_weight * SCHED_CAPACITY_SCALE)
+y' is the ratio of CPUs to be scanned in the LLC domain,
+and the number of CPUs to scan is calculated by:
+
+nr_scan = llc_weight * y'
+
+Choosing quadratic function is because:
+[1] Compared to the linear function, it scans more aggressively when the
+    sum_util is low.
+[2] Compared to the exponential function, it is easier to calculate.
+[3] It seems that there is no accurate mapping between the sum of util_avg
+    and the number of CPUs to be scanned. Use heuristic scan for now.
+
+For a platform with 112 CPUs per LLC, the number of CPUs to scan is:
+sum_util%   0    5   15   25  35  45  55   65   75   85   86 ...
+scan_nr   112  111  108  102  93  81  65   47   25    1    0 ...
+
+For a platform with 16 CPUs per LLC, the number of CPUs to scan is:
+sum_util%   0    5   15   25  35  45  55   65   75   85   86 ...
+scan_nr    16   15   15   14  13  11   9    6    3    0    0 ...
+
+Furthermore, to minimize the overhead of calculating the metrics in
+select_idle_cpu(), borrow the statistics from periodic load balance.
+As mentioned by Abel, on a platform with 112 CPUs per LLC, the
+sum_util calculated by periodic load balance after 112 ms would
+decay to about 0.5 * 0.5 * 0.5 * 0.7 = 8.75%, thus bringing a delay
+in reflecting the latest utilization. But it is a trade-off.
+Checking the util_avg in newidle load balance would be more frequent,
+but it brings overhead - multiple CPUs write/read the per-LLC shared
+variable and introduces cache contention. Tim also mentioned that,
+it is allowed to be non-optimal in terms of scheduling for the
+short-term variations, but if there is a long-term trend in the load
+behavior, the scheduler can adjust for that.
+
+When SIS_UTIL is enabled, the select_idle_cpu() uses the nr_scan
+calculated by SIS_UTIL instead of the one from SIS_PROP. As Peter and
+Mel suggested, SIS_UTIL should be enabled by default.
+
+This patch is based on the util_avg, which is very sensitive to the
+CPU frequency invariance. There is an issue that, when the max frequency
+has been clamp, the util_avg would decay insanely fast when
+the CPU is idle. Commit addca285120b ("cpufreq: intel_pstate: Handle no_turbo
+in frequency invariance") could be used to mitigate this symptom, by adjusting
+the arch_max_freq_ratio when turbo is disabled. But this issue is still
+not thoroughly fixed, because the current code is unaware of the user-specified
+max CPU frequency.
+
+[Test result]
+
+netperf and tbench were launched with 25% 50% 75% 100% 125% 150%
+175% 200% of CPU number respectively. Hackbench and schbench were launched
+by 1, 2 ,4, 8 groups. Each test lasts for 100 seconds and repeats 3 times.
+
+The following is the benchmark result comparison between
+baseline:vanilla v5.19-rc1 and compare:patched kernel. Positive compare%
+indicates better performance.
+
+Each netperf test is a:
+netperf -4 -H 127.0.1 -t TCP/UDP_RR -c -C -l 100
+netperf.throughput
+=======
+case                   load            baseline(std%)  compare%( std%)
+TCP_RR                 28 threads       1.00 (  0.34)   -0.16 (  0.40)
+TCP_RR                 56 threads       1.00 (  0.19)   -0.02 (  0.20)
+TCP_RR                 84 threads       1.00 (  0.39)   -0.47 (  0.40)
+TCP_RR                 112 threads      1.00 (  0.21)   -0.66 (  0.22)
+TCP_RR                 140 threads      1.00 (  0.19)   -0.69 (  0.19)
+TCP_RR                 168 threads      1.00 (  0.18)   -0.48 (  0.18)
+TCP_RR                 196 threads      1.00 (  0.16)  +194.70 ( 16.43)
+TCP_RR                 224 threads      1.00 (  0.16)  +197.30 (  7.85)
+UDP_RR                 28 threads       1.00 (  0.37)   +0.35 (  0.33)
+UDP_RR                 56 threads       1.00 ( 11.18)   -0.32 (  0.21)
+UDP_RR                 84 threads       1.00 (  1.46)   -0.98 (  0.32)
+UDP_RR                 112 threads      1.00 ( 28.85)   -2.48 ( 19.61)
+UDP_RR                 140 threads      1.00 (  0.70)   -0.71 ( 14.04)
+UDP_RR                 168 threads      1.00 ( 14.33)   -0.26 ( 11.16)
+UDP_RR                 196 threads      1.00 ( 12.92)  +186.92 ( 20.93)
+UDP_RR                 224 threads      1.00 ( 11.74)  +196.79 ( 18.62)
+
+Take the 224 threads as an example, the SIS search metrics changes are
+illustrated below:
+
+    vanilla                    patched
+   4544492          +237.5%   15338634        sched_debug.cpu.sis_domain_search.avg
+     38539        +39686.8%   15333634        sched_debug.cpu.sis_failed.avg
+  128300000          -87.9%   15551326        sched_debug.cpu.sis_scanned.avg
+   5842896          +162.7%   15347978        sched_debug.cpu.sis_search.avg
+
+There is -87.9% less CPU scans after patched, which indicates lower overhead.
+Besides, with this patch applied, there is -13% less rq lock contention
+in perf-profile.calltrace.cycles-pp._raw_spin_lock.raw_spin_rq_lock_nested
+.try_to_wake_up.default_wake_function.woken_wake_function.
+This might help explain the performance improvement - Because this patch allows
+the waking task to remain on the previous CPU, rather than grabbing other CPUs'
+lock.
+
+Each hackbench test is a:
+hackbench -g $job --process/threads --pipe/sockets -l 1000000 -s 100
+hackbench.throughput
+=========
+case                   load            baseline(std%)  compare%( std%)
+process-pipe           1 group          1.00 (  1.29)   +0.57 (  0.47)
+process-pipe           2 groups         1.00 (  0.27)   +0.77 (  0.81)
+process-pipe           4 groups         1.00 (  0.26)   +1.17 (  0.02)
+process-pipe           8 groups         1.00 (  0.15)   -4.79 (  0.02)
+process-sockets        1 group          1.00 (  0.63)   -0.92 (  0.13)
+process-sockets        2 groups         1.00 (  0.03)   -0.83 (  0.14)
+process-sockets        4 groups         1.00 (  0.40)   +5.20 (  0.26)
+process-sockets        8 groups         1.00 (  0.04)   +3.52 (  0.03)
+threads-pipe           1 group          1.00 (  1.28)   +0.07 (  0.14)
+threads-pipe           2 groups         1.00 (  0.22)   -0.49 (  0.74)
+threads-pipe           4 groups         1.00 (  0.05)   +1.88 (  0.13)
+threads-pipe           8 groups         1.00 (  0.09)   -4.90 (  0.06)
+threads-sockets        1 group          1.00 (  0.25)   -0.70 (  0.53)
+threads-sockets        2 groups         1.00 (  0.10)   -0.63 (  0.26)
+threads-sockets        4 groups         1.00 (  0.19)  +11.92 (  0.24)
+threads-sockets        8 groups         1.00 (  0.08)   +4.31 (  0.11)
+
+Each tbench test is a:
+tbench -t 100 $job 127.0.0.1
+tbench.throughput
+======
+case                   load            baseline(std%)  compare%( std%)
+loopback               28 threads       1.00 (  0.06)   -0.14 (  0.09)
+loopback               56 threads       1.00 (  0.03)   -0.04 (  0.17)
+loopback               84 threads       1.00 (  0.05)   +0.36 (  0.13)
+loopback               112 threads      1.00 (  0.03)   +0.51 (  0.03)
+loopback               140 threads      1.00 (  0.02)   -1.67 (  0.19)
+loopback               168 threads      1.00 (  0.38)   +1.27 (  0.27)
+loopback               196 threads      1.00 (  0.11)   +1.34 (  0.17)
+loopback               224 threads      1.00 (  0.11)   +1.67 (  0.22)
+
+Each schbench test is a:
+schbench -m $job -t 28 -r 100 -s 30000 -c 30000
+schbench.latency_90%_us
+========
+case                   load            baseline(std%)  compare%( std%)
+normal                 1 mthread        1.00 ( 31.22)   -7.36 ( 20.25)*
+normal                 2 mthreads       1.00 (  2.45)   -0.48 (  1.79)
+normal                 4 mthreads       1.00 (  1.69)   +0.45 (  0.64)
+normal                 8 mthreads       1.00 (  5.47)   +9.81 ( 14.28)
+
+*Consider the Standard Deviation, this -7.36% regression might not be valid.
+
+Also, a OLTP workload with a commercial RDBMS has been tested, and there
+is no significant change.
+
+There were concerns that unbalanced tasks among CPUs would cause problems.
+For example, suppose the LLC domain is composed of 8 CPUs, and 7 tasks are
+bound to CPU0~CPU6, while CPU7 is idle:
+
+          CPU0    CPU1    CPU2    CPU3    CPU4    CPU5    CPU6    CPU7
+util_avg  1024    1024    1024    1024    1024    1024    1024    0
+
+Since the util_avg ratio is 87.5%( = 7/8 ), which is higher than 85%,
+select_idle_cpu() will not scan, thus CPU7 is undetected during scan.
+But according to Mel, it is unlikely the CPU7 will be idle all the time
+because CPU7 could pull some tasks via CPU_NEWLY_IDLE.
+
+lkp(kernel test robot) has reported a regression on stress-ng.sock on a
+very busy system. According to the sched_debug statistics, it might be caused
+by SIS_UTIL terminates the scan and chooses a previous CPU earlier, and this
+might introduce more context switch, especially involuntary preemption, which
+impacts a busy stress-ng. This regression has shown that, not all benchmarks
+in every scenario benefit from idle CPU scan limit, and it needs further
+investigation.
+
+Besides, there is slight regression in hackbench's 16 groups case when the
+LLC domain has 16 CPUs. Prateek mentioned that we should scan aggressively
+in an LLC domain with 16 CPUs. Because the cost to search for an idle one
+among 16 CPUs is negligible. The current patch aims to propose a generic
+solution and only considers the util_avg. Something like the below could
+be applied on top of the current patch to fulfill the requirement:
+
+       if (llc_weight <= 16)
+               nr_scan = nr_scan * 32 / llc_weight;
+
+For LLC domain with 16 CPUs, the nr_scan will be expanded to 2 times large.
+The smaller the CPU number this LLC domain has, the larger nr_scan will be
+expanded. This needs further investigation.
+
+There is also ongoing work[2] from Abel to filter out the busy CPUs during
+wakeup, to further speed up the idle CPU scan. And it could be a following-up
+optimization on top of this change.
+
+Suggested-by: Tim Chen <tim.c.chen@intel.com>
+Suggested-by: Peter Zijlstra <peterz@infradead.org>
+Signed-off-by: Chen Yu <yu.c.chen@intel.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Tested-by: Yicong Yang <yangyicong@hisilicon.com>
+Tested-by: Mohini Narkhede <mohini.narkhede@intel.com>
+Tested-by: K Prateek Nayak <kprateek.nayak@amd.com>
+Link: https://lore.kernel.org/r/20220612163428.849378-1-yu.c.chen@intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/sched/topology.h |  1 +
+ kernel/sched/fair.c            | 87 ++++++++++++++++++++++++++++++++++
+ kernel/sched/features.h        |  3 +-
+ 3 files changed, 90 insertions(+), 1 deletion(-)
+
+diff --git a/include/linux/sched/topology.h b/include/linux/sched/topology.h
+index 8f0f778b7c91..63a04a65e310 100644
+--- a/include/linux/sched/topology.h
++++ b/include/linux/sched/topology.h
+@@ -74,6 +74,7 @@ struct sched_domain_shared {
+       atomic_t        ref;
+       atomic_t        nr_busy_cpus;
+       int             has_idle_cores;
++      int             nr_idle_scan;
+ };
+ struct sched_domain {
+diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
+index fcbacc35d2b9..a853e4e9e3c3 100644
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -6280,6 +6280,7 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, bool
+ {
+       struct cpumask *cpus = this_cpu_cpumask_var_ptr(select_idle_mask);
+       int i, cpu, idle_cpu = -1, nr = INT_MAX;
++      struct sched_domain_shared *sd_share;
+       struct rq *this_rq = this_rq();
+       int this = smp_processor_id();
+       struct sched_domain *this_sd;
+@@ -6319,6 +6320,17 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, bool
+               time = cpu_clock(this);
+       }
++      if (sched_feat(SIS_UTIL)) {
++              sd_share = rcu_dereference(per_cpu(sd_llc_shared, target));
++              if (sd_share) {
++                      /* because !--nr is the condition to stop scan */
++                      nr = READ_ONCE(sd_share->nr_idle_scan) + 1;
++                      /* overloaded LLC is unlikely to have idle cpu/core */
++                      if (nr == 1)
++                              return -1;
++              }
++      }
++
+       for_each_cpu_wrap(cpu, cpus, target + 1) {
+               if (has_idle_core) {
+                       i = select_idle_core(p, cpu, cpus, &idle_cpu);
+@@ -9166,6 +9178,77 @@ find_idlest_group(struct sched_domain *sd, struct task_struct *p, int this_cpu)
+       return idlest;
+ }
++static void update_idle_cpu_scan(struct lb_env *env,
++                               unsigned long sum_util)
++{
++      struct sched_domain_shared *sd_share;
++      int llc_weight, pct;
++      u64 x, y, tmp;
++      /*
++       * Update the number of CPUs to scan in LLC domain, which could
++       * be used as a hint in select_idle_cpu(). The update of sd_share
++       * could be expensive because it is within a shared cache line.
++       * So the write of this hint only occurs during periodic load
++       * balancing, rather than CPU_NEWLY_IDLE, because the latter
++       * can fire way more frequently than the former.
++       */
++      if (!sched_feat(SIS_UTIL) || env->idle == CPU_NEWLY_IDLE)
++              return;
++
++      llc_weight = per_cpu(sd_llc_size, env->dst_cpu);
++      if (env->sd->span_weight != llc_weight)
++              return;
++
++      sd_share = rcu_dereference(per_cpu(sd_llc_shared, env->dst_cpu));
++      if (!sd_share)
++              return;
++
++      /*
++       * The number of CPUs to search drops as sum_util increases, when
++       * sum_util hits 85% or above, the scan stops.
++       * The reason to choose 85% as the threshold is because this is the
++       * imbalance_pct(117) when a LLC sched group is overloaded.
++       *
++       * let y = SCHED_CAPACITY_SCALE - p * x^2                       [1]
++       * and y'= y / SCHED_CAPACITY_SCALE
++       *
++       * x is the ratio of sum_util compared to the CPU capacity:
++       * x = sum_util / (llc_weight * SCHED_CAPACITY_SCALE)
++       * y' is the ratio of CPUs to be scanned in the LLC domain,
++       * and the number of CPUs to scan is calculated by:
++       *
++       * nr_scan = llc_weight * y'                                    [2]
++       *
++       * When x hits the threshold of overloaded, AKA, when
++       * x = 100 / pct, y drops to 0. According to [1],
++       * p should be SCHED_CAPACITY_SCALE * pct^2 / 10000
++       *
++       * Scale x by SCHED_CAPACITY_SCALE:
++       * x' = sum_util / llc_weight;                                  [3]
++       *
++       * and finally [1] becomes:
++       * y = SCHED_CAPACITY_SCALE -
++       *     x'^2 * pct^2 / (10000 * SCHED_CAPACITY_SCALE)            [4]
++       *
++       */
++      /* equation [3] */
++      x = sum_util;
++      do_div(x, llc_weight);
++
++      /* equation [4] */
++      pct = env->sd->imbalance_pct;
++      tmp = x * x * pct * pct;
++      do_div(tmp, 10000 * SCHED_CAPACITY_SCALE);
++      tmp = min_t(long, tmp, SCHED_CAPACITY_SCALE);
++      y = SCHED_CAPACITY_SCALE - tmp;
++
++      /* equation [2] */
++      y *= llc_weight;
++      do_div(y, SCHED_CAPACITY_SCALE);
++      if ((int)y != sd_share->nr_idle_scan)
++              WRITE_ONCE(sd_share->nr_idle_scan, (int)y);
++}
++
+ /**
+  * update_sd_lb_stats - Update sched_domain's statistics for load balancing.
+  * @env: The load balancing environment.
+@@ -9178,6 +9261,7 @@ static inline void update_sd_lb_stats(struct lb_env *env, struct sd_lb_stats *sd
+       struct sched_group *sg = env->sd->groups;
+       struct sg_lb_stats *local = &sds->local_stat;
+       struct sg_lb_stats tmp_sgs;
++      unsigned long sum_util = 0;
+       int sg_status = 0;
+       do {
+@@ -9210,6 +9294,7 @@ static inline void update_sd_lb_stats(struct lb_env *env, struct sd_lb_stats *sd
+               sds->total_load += sgs->group_load;
+               sds->total_capacity += sgs->group_capacity;
++              sum_util += sgs->group_util;
+               sg = sg->next;
+       } while (sg != env->sd->groups);
+@@ -9235,6 +9320,8 @@ static inline void update_sd_lb_stats(struct lb_env *env, struct sd_lb_stats *sd
+               WRITE_ONCE(rd->overutilized, SG_OVERUTILIZED);
+               trace_sched_overutilized_tp(rd, SG_OVERUTILIZED);
+       }
++
++      update_idle_cpu_scan(env, sum_util);
+ }
+ #define NUMA_IMBALANCE_MIN 2
+diff --git a/kernel/sched/features.h b/kernel/sched/features.h
+index 7f8dace0964c..c4947c1b5edb 100644
+--- a/kernel/sched/features.h
++++ b/kernel/sched/features.h
+@@ -55,7 +55,8 @@ SCHED_FEAT(TTWU_QUEUE, true)
+ /*
+  * When doing wakeups, attempt to limit superfluous scans of the LLC domain.
+  */
+-SCHED_FEAT(SIS_PROP, true)
++SCHED_FEAT(SIS_PROP, false)
++SCHED_FEAT(SIS_UTIL, true)
+ /*
+  * Issue a WARN when we do multiple update_rq_clock() calls
+-- 
+2.35.1
+
diff --git a/queue-5.15/sched-fix-the-check-of-nr_running-at-queue-wakelist.patch b/queue-5.15/sched-fix-the-check-of-nr_running-at-queue-wakelist.patch
new file mode 100644 (file)
index 0000000..ade221b
--- /dev/null
@@ -0,0 +1,54 @@
+From 717e68c5d89fdda3f3aa495a297ca182cd3f707f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jun 2022 07:34:11 +0800
+Subject: sched: Fix the check of nr_running at queue wakelist
+
+From: Tianchen Ding <dtcccc@linux.alibaba.com>
+
+[ Upstream commit 28156108fecb1f808b21d216e8ea8f0d205a530c ]
+
+The commit 2ebb17717550 ("sched/core: Offload wakee task activation if it
+the wakee is descheduling") checked rq->nr_running <= 1 to avoid task
+stacking when WF_ON_CPU.
+
+Per the ordering of writes to p->on_rq and p->on_cpu, observing p->on_cpu
+(WF_ON_CPU) in ttwu_queue_cond() implies !p->on_rq, IOW p has gone through
+the deactivate_task() in __schedule(), thus p has been accounted out of
+rq->nr_running. As such, the task being the only runnable task on the rq
+implies reading rq->nr_running == 0 at that point.
+
+The benchmark result is in [1].
+
+[1] https://lore.kernel.org/all/e34de686-4e85-bde1-9f3c-9bbc86b38627@linux.alibaba.com/
+
+Suggested-by: Valentin Schneider <vschneid@redhat.com>
+Signed-off-by: Tianchen Ding <dtcccc@linux.alibaba.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Valentin Schneider <vschneid@redhat.com>
+Link: https://lore.kernel.org/r/20220608233412.327341-2-dtcccc@linux.alibaba.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/core.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index 5c7937b504d2..892c06ff9dd0 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -3735,8 +3735,12 @@ static inline bool ttwu_queue_cond(int cpu, int wake_flags)
+        * CPU then use the wakelist to offload the task activation to
+        * the soon-to-be-idle CPU as the current CPU is likely busy.
+        * nr_running is checked to avoid unnecessary task stacking.
++       *
++       * Note that we can only get here with (wakee) p->on_rq=0,
++       * p->on_cpu can be whatever, we've done the dequeue, so
++       * the wakee has been accounted out of ->nr_running.
+        */
+-      if ((wake_flags & WF_ON_CPU) && cpu_rq(cpu)->nr_running <= 1)
++      if ((wake_flags & WF_ON_CPU) && !cpu_rq(cpu)->nr_running)
+               return true;
+       return false;
+-- 
+2.35.1
+
diff --git a/queue-5.15/sched-remove-the-limitation-of-wf_on_cpu-on-wakelist.patch b/queue-5.15/sched-remove-the-limitation-of-wf_on_cpu-on-wakelist.patch
new file mode 100644 (file)
index 0000000..2e5a34c
--- /dev/null
@@ -0,0 +1,236 @@
+From cf042257ea98d41b54d174b521dd688cbabb048c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jun 2022 07:34:12 +0800
+Subject: sched: Remove the limitation of WF_ON_CPU on wakelist if wakee cpu is
+ idle
+
+From: Tianchen Ding <dtcccc@linux.alibaba.com>
+
+[ Upstream commit f3dd3f674555bd9455c5ae7fafce0696bd9931b3 ]
+
+Wakelist can help avoid cache bouncing and offload the overhead of waker
+cpu. So far, using wakelist within the same llc only happens on
+WF_ON_CPU, and this limitation could be removed to further improve
+wakeup performance.
+
+The commit 518cd6234178 ("sched: Only queue remote wakeups when
+crossing cache boundaries") disabled queuing tasks on wakelist when
+the cpus share llc. This is because, at that time, the scheduler must
+send IPIs to do ttwu_queue_wakelist. Nowadays, ttwu_queue_wakelist also
+supports TIF_POLLING, so this is not a problem now when the wakee cpu is
+in idle polling.
+
+Benefits:
+  Queuing the task on idle cpu can help improving performance on waker cpu
+  and utilization on wakee cpu, and further improve locality because
+  the wakee cpu can handle its own rq. This patch helps improving rt on
+  our real java workloads where wakeup happens frequently.
+
+  Consider the normal condition (CPU0 and CPU1 share same llc)
+  Before this patch:
+
+         CPU0                                       CPU1
+
+    select_task_rq()                                idle
+    rq_lock(CPU1->rq)
+    enqueue_task(CPU1->rq)
+    notify CPU1 (by sending IPI or CPU1 polling)
+
+                                                    resched()
+
+  After this patch:
+
+         CPU0                                       CPU1
+
+    select_task_rq()                                idle
+    add to wakelist of CPU1
+    notify CPU1 (by sending IPI or CPU1 polling)
+
+                                                    rq_lock(CPU1->rq)
+                                                    enqueue_task(CPU1->rq)
+                                                    resched()
+
+  We see CPU0 can finish its work earlier. It only needs to put task to
+  wakelist and return.
+  While CPU1 is idle, so let itself handle its own runqueue data.
+
+This patch brings no difference about IPI.
+  This patch only takes effect when the wakee cpu is:
+  1) idle polling
+  2) idle not polling
+
+  For 1), there will be no IPI with or without this patch.
+
+  For 2), there will always be an IPI before or after this patch.
+  Before this patch: waker cpu will enqueue task and check preempt. Since
+  "idle" will be sure to be preempted, waker cpu must send a resched IPI.
+  After this patch: waker cpu will put the task to the wakelist of wakee
+  cpu, and send an IPI.
+
+Benchmark:
+We've tested schbench, unixbench, and hachbench on both x86 and arm64.
+
+On x86 (Intel Xeon Platinum 8269CY):
+  schbench -m 2 -t 8
+
+    Latency percentiles (usec)              before        after
+        50.0000th:                             8            6
+        75.0000th:                            10            7
+        90.0000th:                            11            8
+        95.0000th:                            12            8
+        *99.0000th:                           13           10
+        99.5000th:                            15           11
+        99.9000th:                            18           14
+
+  Unixbench with full threads (104)
+                                            before        after
+    Dhrystone 2 using register variables  3011862938    3009935994  -0.06%
+    Double-Precision Whetstone              617119.3      617298.5   0.03%
+    Execl Throughput                         27667.3       27627.3  -0.14%
+    File Copy 1024 bufsize 2000 maxblocks   785871.4      784906.2  -0.12%
+    File Copy 256 bufsize 500 maxblocks     210113.6      212635.4   1.20%
+    File Copy 4096 bufsize 8000 maxblocks  2328862.2     2320529.1  -0.36%
+    Pipe Throughput                      145535622.8   145323033.2  -0.15%
+    Pipe-based Context Switching           3221686.4     3583975.4  11.25%
+    Process Creation                        101347.1      103345.4   1.97%
+    Shell Scripts (1 concurrent)            120193.5      123977.8   3.15%
+    Shell Scripts (8 concurrent)             17233.4       17138.4  -0.55%
+    System Call Overhead                   5300604.8     5312213.6   0.22%
+
+  hackbench -g 1 -l 100000
+                                            before        after
+    Time                                     3.246        2.251
+
+On arm64 (Ampere Altra):
+  schbench -m 2 -t 8
+
+    Latency percentiles (usec)              before        after
+        50.0000th:                            14           10
+        75.0000th:                            19           14
+        90.0000th:                            22           16
+        95.0000th:                            23           16
+        *99.0000th:                           24           17
+        99.5000th:                            24           17
+        99.9000th:                            28           25
+
+  Unixbench with full threads (80)
+                                            before        after
+    Dhrystone 2 using register variables  3536194249    3537019613   0.02%
+    Double-Precision Whetstone              629383.6      629431.6   0.01%
+    Execl Throughput                         65920.5       65846.2  -0.11%
+    File Copy 1024 bufsize 2000 maxblocks  1063722.8     1064026.8   0.03%
+    File Copy 256 bufsize 500 maxblocks     322684.5      318724.5  -1.23%
+    File Copy 4096 bufsize 8000 maxblocks  2348285.3     2328804.8  -0.83%
+    Pipe Throughput                      133542875.3   131619389.8  -1.44%
+    Pipe-based Context Switching           3215356.1     3576945.1  11.25%
+    Process Creation                        108520.5      120184.6  10.75%
+    Shell Scripts (1 concurrent)            122636.3        121888  -0.61%
+    Shell Scripts (8 concurrent)             17462.1       17381.4  -0.46%
+    System Call Overhead                   4429998.9     4435006.7   0.11%
+
+  hackbench -g 1 -l 100000
+                                            before        after
+    Time                                     4.217        2.916
+
+Our patch has improvement on schbench, hackbench
+and Pipe-based Context Switching of unixbench
+when there exists idle cpus,
+and no obvious regression on other tests of unixbench.
+This can help improve rt in scenes where wakeup happens frequently.
+
+Signed-off-by: Tianchen Ding <dtcccc@linux.alibaba.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Valentin Schneider <vschneid@redhat.com>
+Link: https://lore.kernel.org/r/20220608233412.327341-3-dtcccc@linux.alibaba.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/core.c  | 26 ++++++++++++++------------
+ kernel/sched/sched.h |  1 -
+ 2 files changed, 14 insertions(+), 13 deletions(-)
+
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index 892c06ff9dd0..4499b58ac2ca 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -3714,7 +3714,7 @@ bool cpus_share_cache(int this_cpu, int that_cpu)
+       return per_cpu(sd_llc_id, this_cpu) == per_cpu(sd_llc_id, that_cpu);
+ }
+-static inline bool ttwu_queue_cond(int cpu, int wake_flags)
++static inline bool ttwu_queue_cond(int cpu)
+ {
+       /*
+        * Do not complicate things with the async wake_list while the CPU is
+@@ -3730,17 +3730,21 @@ static inline bool ttwu_queue_cond(int cpu, int wake_flags)
+       if (!cpus_share_cache(smp_processor_id(), cpu))
+               return true;
++      if (cpu == smp_processor_id())
++              return false;
++
+       /*
+-       * If the task is descheduling and the only running task on the
+-       * CPU then use the wakelist to offload the task activation to
+-       * the soon-to-be-idle CPU as the current CPU is likely busy.
+-       * nr_running is checked to avoid unnecessary task stacking.
++       * If the wakee cpu is idle, or the task is descheduling and the
++       * only running task on the CPU, then use the wakelist to offload
++       * the task activation to the idle (or soon-to-be-idle) CPU as
++       * the current CPU is likely busy. nr_running is checked to
++       * avoid unnecessary task stacking.
+        *
+        * Note that we can only get here with (wakee) p->on_rq=0,
+        * p->on_cpu can be whatever, we've done the dequeue, so
+        * the wakee has been accounted out of ->nr_running.
+        */
+-      if ((wake_flags & WF_ON_CPU) && !cpu_rq(cpu)->nr_running)
++      if (!cpu_rq(cpu)->nr_running)
+               return true;
+       return false;
+@@ -3748,10 +3752,7 @@ static inline bool ttwu_queue_cond(int cpu, int wake_flags)
+ static bool ttwu_queue_wakelist(struct task_struct *p, int cpu, int wake_flags)
+ {
+-      if (sched_feat(TTWU_QUEUE) && ttwu_queue_cond(cpu, wake_flags)) {
+-              if (WARN_ON_ONCE(cpu == smp_processor_id()))
+-                      return false;
+-
++      if (sched_feat(TTWU_QUEUE) && ttwu_queue_cond(cpu)) {
+               sched_clock_cpu(cpu); /* Sync clocks across CPUs */
+               __ttwu_queue_wakelist(p, cpu, wake_flags);
+               return true;
+@@ -4073,7 +4074,7 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags)
+        * scheduling.
+        */
+       if (smp_load_acquire(&p->on_cpu) &&
+-          ttwu_queue_wakelist(p, task_cpu(p), wake_flags | WF_ON_CPU))
++          ttwu_queue_wakelist(p, task_cpu(p), wake_flags))
+               goto unlock;
+       /*
+@@ -4589,7 +4590,8 @@ static inline void prepare_task(struct task_struct *next)
+        * Claim the task as running, we do this before switching to it
+        * such that any running task will have this set.
+        *
+-       * See the ttwu() WF_ON_CPU case and its ordering comment.
++       * See the smp_load_acquire(&p->on_cpu) case in ttwu() and
++       * its ordering comment.
+        */
+       WRITE_ONCE(next->on_cpu, 1);
+ #endif
+diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
+index 2bbf1f006d63..e49902898253 100644
+--- a/kernel/sched/sched.h
++++ b/kernel/sched/sched.h
+@@ -2052,7 +2052,6 @@ static inline int task_on_rq_migrating(struct task_struct *p)
+ #define WF_SYNC     0x10 /* Waker goes to sleep after wakeup */
+ #define WF_MIGRATED 0x20 /* Internal use, task got migrated */
+-#define WF_ON_CPU   0x40 /* Wakee is on_cpu */
+ #ifdef CONFIG_SMP
+ static_assert(WF_EXEC == SD_BALANCE_EXEC);
+-- 
+2.35.1
+
diff --git a/queue-5.15/scripts-faddr2line-fix-vmlinux-detection-on-arm64.patch b/queue-5.15/scripts-faddr2line-fix-vmlinux-detection-on-arm64.patch
new file mode 100644 (file)
index 0000000..3ab52e1
--- /dev/null
@@ -0,0 +1,47 @@
+From e4121032c60a9f386a8a2adc23c168273be5d5ca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Jul 2022 11:01:23 -0700
+Subject: scripts/faddr2line: Fix vmlinux detection on arm64
+
+From: Josh Poimboeuf <jpoimboe@kernel.org>
+
+[ Upstream commit b6a5068854cfe372da7dee3224dcf023ed5b00cb ]
+
+Since commit dcea997beed6 ("faddr2line: Fix overlapping text section
+failures, the sequel"), faddr2line is completely broken on arm64.
+
+For some reason, on arm64, the vmlinux ELF object file type is ET_DYN
+rather than ET_EXEC.  Check for both when determining whether the object
+is vmlinux.
+
+Modules and vmlinux.o have type ET_REL on all arches.
+
+Fixes: dcea997beed6 ("faddr2line: Fix overlapping text section failures, the sequel")
+Reported-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Tested-by: John Garry <john.garry@huawei.com>
+Link: https://lore.kernel.org/r/dad1999737471b06d6188ce4cdb11329aa41682c.1658426357.git.jpoimboe@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/faddr2line | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/scripts/faddr2line b/scripts/faddr2line
+index 94ed98dd899f..57099687e5e1 100755
+--- a/scripts/faddr2line
++++ b/scripts/faddr2line
+@@ -112,7 +112,9 @@ __faddr2line() {
+       # section offsets.
+       local file_type=$(${READELF} --file-header $objfile |
+               ${AWK} '$1 == "Type:" { print $2; exit }')
+-      [[ $file_type = "EXEC" ]] && is_vmlinux=1
++      if [[ $file_type = "EXEC" ]] || [[ $file_type == "DYN" ]]; then
++              is_vmlinux=1
++      fi
+       # Go through each of the object's symbols which match the func name.
+       # In rare cases there might be duplicates, in which case we print all
+-- 
+2.35.1
+
diff --git a/queue-5.15/scripts-gdb-fix-lx-dmesg-on-32-bits-arch.patch b/queue-5.15/scripts-gdb-fix-lx-dmesg-on-32-bits-arch.patch
new file mode 100644 (file)
index 0000000..d6a6a99
--- /dev/null
@@ -0,0 +1,125 @@
+From 9ce9f5bd47bfbca397a905fb81de514c9d4cc543 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 14:28:31 +0200
+Subject: scripts/gdb: fix 'lx-dmesg' on 32 bits arch
+
+From: Antonio Borneo <antonio.borneo@foss.st.com>
+
+[ Upstream commit e3c8d33e0d62175c31ca7ab7ab01b18f0b6318d3 ]
+
+The type atomic_long_t can have size 4 or 8 bytes, depending on
+CONFIG_64BIT; it's only content, the field 'counter', is either an
+int or a s64 value.
+
+Current code incorrectly uses the fixed size utils.read_u64() to
+read the field 'counter' inside atomic_long_t.
+
+On 32 bits architectures reading the last element 'tail_id' of the
+struct prb_desc_ring:
+       struct prb_desc_ring {
+               ...
+               atomic_long_t tail_id;
+       };
+causes the utils.read_u64() to access outside the boundary of the
+struct and the gdb command 'lx-dmesg' exits with error:
+       Python Exception <class 'IndexError'>: index out of range
+       Error occurred in Python: index out of range
+
+Query the really used atomic_long_t counter type size.
+
+Link: https://lore.kernel.org/r/20220617143758.137307-1-antonio.borneo@foss.st.com
+Fixes: e60768311af8 ("scripts/gdb: update for lockless printk ringbuffer")
+Signed-off-by: Antonio Borneo <antonio.borneo@foss.st.com>
+[pmladek@suse.com: Query the really used atomic_long_t counter type size]
+Tested-by: Antonio Borneo <antonio.borneo@foss.st.com>
+Reviewed-by: John Ogness <john.ogness@linutronix.de>
+Signed-off-by: Petr Mladek <pmladek@suse.com>
+Link: https://lore.kernel.org/r/20220719122831.19890-1-pmladek@suse.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/gdb/linux/dmesg.py |  9 +++------
+ scripts/gdb/linux/utils.py | 14 ++++++++++++--
+ 2 files changed, 15 insertions(+), 8 deletions(-)
+
+diff --git a/scripts/gdb/linux/dmesg.py b/scripts/gdb/linux/dmesg.py
+index d5983cf3db7d..c771831eb077 100644
+--- a/scripts/gdb/linux/dmesg.py
++++ b/scripts/gdb/linux/dmesg.py
+@@ -22,7 +22,6 @@ prb_desc_type = utils.CachedType("struct prb_desc")
+ prb_desc_ring_type = utils.CachedType("struct prb_desc_ring")
+ prb_data_ring_type = utils.CachedType("struct prb_data_ring")
+ printk_ringbuffer_type = utils.CachedType("struct printk_ringbuffer")
+-atomic_long_type = utils.CachedType("atomic_long_t")
+ class LxDmesg(gdb.Command):
+     """Print Linux kernel log buffer."""
+@@ -68,8 +67,6 @@ class LxDmesg(gdb.Command):
+         off = prb_data_ring_type.get_type()['data'].bitpos // 8
+         text_data_addr = utils.read_ulong(text_data_ring, off)
+-        counter_off = atomic_long_type.get_type()['counter'].bitpos // 8
+-
+         sv_off = prb_desc_type.get_type()['state_var'].bitpos // 8
+         off = prb_desc_type.get_type()['text_blk_lpos'].bitpos // 8
+@@ -89,9 +86,9 @@ class LxDmesg(gdb.Command):
+         # read in tail and head descriptor ids
+         off = prb_desc_ring_type.get_type()['tail_id'].bitpos // 8
+-        tail_id = utils.read_u64(desc_ring, off + counter_off)
++        tail_id = utils.read_atomic_long(desc_ring, off)
+         off = prb_desc_ring_type.get_type()['head_id'].bitpos // 8
+-        head_id = utils.read_u64(desc_ring, off + counter_off)
++        head_id = utils.read_atomic_long(desc_ring, off)
+         did = tail_id
+         while True:
+@@ -102,7 +99,7 @@ class LxDmesg(gdb.Command):
+             desc = utils.read_memoryview(inf, desc_addr + desc_off, desc_sz).tobytes()
+             # skip non-committed record
+-            state = 3 & (utils.read_u64(desc, sv_off + counter_off) >> desc_flags_shift)
++            state = 3 & (utils.read_atomic_long(desc, sv_off) >> desc_flags_shift)
+             if state != desc_committed and state != desc_finalized:
+                 if did == head_id:
+                     break
+diff --git a/scripts/gdb/linux/utils.py b/scripts/gdb/linux/utils.py
+index ff7c1799d588..1553f68716cc 100644
+--- a/scripts/gdb/linux/utils.py
++++ b/scripts/gdb/linux/utils.py
+@@ -35,13 +35,12 @@ class CachedType:
+ long_type = CachedType("long")
+-
++atomic_long_type = CachedType("atomic_long_t")
+ def get_long_type():
+     global long_type
+     return long_type.get_type()
+-
+ def offset_of(typeobj, field):
+     element = gdb.Value(0).cast(typeobj)
+     return int(str(element[field].address).split()[0], 16)
+@@ -129,6 +128,17 @@ def read_ulong(buffer, offset):
+     else:
+         return read_u32(buffer, offset)
++atomic_long_counter_offset = atomic_long_type.get_type()['counter'].bitpos
++atomic_long_counter_sizeof = atomic_long_type.get_type()['counter'].type.sizeof
++
++def read_atomic_long(buffer, offset):
++    global atomic_long_counter_offset
++    global atomic_long_counter_sizeof
++
++    if atomic_long_counter_sizeof == 8:
++        return read_u64(buffer, offset + atomic_long_counter_offset)
++    else:
++        return read_u32(buffer, offset + atomic_long_counter_offset)
+ target_arch = None
+-- 
+2.35.1
+
diff --git a/queue-5.15/scripts-gdb-lx-dmesg-read-records-individually.patch b/queue-5.15/scripts-gdb-lx-dmesg-read-records-individually.patch
new file mode 100644 (file)
index 0000000..c259738
--- /dev/null
@@ -0,0 +1,123 @@
+From 50603e014ba87371c7b5eef24f129c723584c6cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Dec 2021 16:16:22 +0106
+Subject: scripts/gdb: lx-dmesg: read records individually
+
+From: John Ogness <john.ogness@linutronix.de>
+
+[ Upstream commit deaee2704a157dfcca77301ddaa10c62a9840952 ]
+
+For the gdb command lx-dmesg, the entire descriptor, info, and text
+data regions are read into memory before printing any records. For
+large kernel log buffers, this not only causes a huge delay before
+seeing any records, but it may also lead to python errors of too
+much memory allocation.
+
+Rather than reading in all these regions in advance, read them as
+needed and only read the regions for the particular record that is
+being printed.
+
+The gdb macro "dmesg" in Documentation/admin-guide/kdump/gdbmacros.txt
+already prints out the kernel log buffer like this.
+
+Signed-off-by: John Ogness <john.ogness@linutronix.de>
+Signed-off-by: Petr Mladek <pmladek@suse.com>
+Link: https://lore.kernel.org/r/874k79c3a9.fsf@jogness.linutronix.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/gdb/linux/dmesg.py | 35 ++++++++++++++++++-----------------
+ 1 file changed, 18 insertions(+), 17 deletions(-)
+
+diff --git a/scripts/gdb/linux/dmesg.py b/scripts/gdb/linux/dmesg.py
+index a92c55bd8de5..d5983cf3db7d 100644
+--- a/scripts/gdb/linux/dmesg.py
++++ b/scripts/gdb/linux/dmesg.py
+@@ -44,19 +44,17 @@ class LxDmesg(gdb.Command):
+         sz = prb_desc_ring_type.get_type().sizeof
+         desc_ring = utils.read_memoryview(inf, addr, sz).tobytes()
+-        # read in descriptor array
++        # read in descriptor count, size, and address
+         off = prb_desc_ring_type.get_type()['count_bits'].bitpos // 8
+         desc_ring_count = 1 << utils.read_u32(desc_ring, off)
+         desc_sz = prb_desc_type.get_type().sizeof
+         off = prb_desc_ring_type.get_type()['descs'].bitpos // 8
+-        addr = utils.read_ulong(desc_ring, off)
+-        descs = utils.read_memoryview(inf, addr, desc_sz * desc_ring_count).tobytes()
++        desc_addr = utils.read_ulong(desc_ring, off)
+-        # read in info array
++        # read in info size and address
+         info_sz = printk_info_type.get_type().sizeof
+         off = prb_desc_ring_type.get_type()['infos'].bitpos // 8
+-        addr = utils.read_ulong(desc_ring, off)
+-        infos = utils.read_memoryview(inf, addr, info_sz * desc_ring_count).tobytes()
++        info_addr = utils.read_ulong(desc_ring, off)
+         # read in text data ring structure
+         off = printk_ringbuffer_type.get_type()['text_data_ring'].bitpos // 8
+@@ -64,12 +62,11 @@ class LxDmesg(gdb.Command):
+         sz = prb_data_ring_type.get_type().sizeof
+         text_data_ring = utils.read_memoryview(inf, addr, sz).tobytes()
+-        # read in text data
++        # read in text data size and address
+         off = prb_data_ring_type.get_type()['size_bits'].bitpos // 8
+         text_data_sz = 1 << utils.read_u32(text_data_ring, off)
+         off = prb_data_ring_type.get_type()['data'].bitpos // 8
+-        addr = utils.read_ulong(text_data_ring, off)
+-        text_data = utils.read_memoryview(inf, addr, text_data_sz).tobytes()
++        text_data_addr = utils.read_ulong(text_data_ring, off)
+         counter_off = atomic_long_type.get_type()['counter'].bitpos // 8
+@@ -102,17 +99,20 @@ class LxDmesg(gdb.Command):
+             desc_off = desc_sz * ind
+             info_off = info_sz * ind
++            desc = utils.read_memoryview(inf, desc_addr + desc_off, desc_sz).tobytes()
++
+             # skip non-committed record
+-            state = 3 & (utils.read_u64(descs, desc_off + sv_off +
+-                                        counter_off) >> desc_flags_shift)
++            state = 3 & (utils.read_u64(desc, sv_off + counter_off) >> desc_flags_shift)
+             if state != desc_committed and state != desc_finalized:
+                 if did == head_id:
+                     break
+                 did = (did + 1) & desc_id_mask
+                 continue
+-            begin = utils.read_ulong(descs, desc_off + begin_off) % text_data_sz
+-            end = utils.read_ulong(descs, desc_off + next_off) % text_data_sz
++            begin = utils.read_ulong(desc, begin_off) % text_data_sz
++            end = utils.read_ulong(desc, next_off) % text_data_sz
++
++            info = utils.read_memoryview(inf, info_addr + info_off, info_sz).tobytes()
+             # handle data-less record
+             if begin & 1 == 1:
+@@ -125,16 +125,17 @@ class LxDmesg(gdb.Command):
+                 # skip over descriptor id
+                 text_start = begin + utils.get_long_type().sizeof
+-                text_len = utils.read_u16(infos, info_off + len_off)
++                text_len = utils.read_u16(info, len_off)
+                 # handle truncated message
+                 if end - text_start < text_len:
+                     text_len = end - text_start
+-                text = text_data[text_start:text_start + text_len].decode(
+-                    encoding='utf8', errors='replace')
++                text_data = utils.read_memoryview(inf, text_data_addr + text_start,
++                                                  text_len).tobytes()
++                text = text_data[0:text_len].decode(encoding='utf8', errors='replace')
+-            time_stamp = utils.read_u64(infos, info_off + ts_off)
++            time_stamp = utils.read_u64(info, ts_off)
+             for line in text.splitlines():
+                 msg = u"[{time:12.6f}] {line}\n".format(
+-- 
+2.35.1
+
diff --git a/queue-5.15/scsi-hisi_sas-use-managed-pci-functions.patch b/queue-5.15/scsi-hisi_sas-use-managed-pci-functions.patch
new file mode 100644 (file)
index 0000000..398a5bb
--- /dev/null
@@ -0,0 +1,100 @@
+From c9a770ab9fe3ab4cd38b8c15ee602c37597d2c24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Aug 2021 18:00:56 +0800
+Subject: scsi: hisi_sas: Use managed PCI functions
+
+From: Xiang Chen <chenxiang66@hisilicon.com>
+
+[ Upstream commit 4f6094f1663e2ed26a940f1842cdaa15c1dd649a ]
+
+Use managed PCI functions such as pcim_enable_device() and
+pcim_iomap_regions() to simplify exception handling code.
+
+Link: https://lore.kernel.org/r/1629799260-120116-2-git-send-email-john.garry@huawei.com
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@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_v3_hw.c | 20 ++++++++------------
+ 1 file changed, 8 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 15c7451fb30f..fa22cb712be5 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -518,6 +518,8 @@ struct hisi_sas_err_record_v3 {
+ #define CHNL_INT_STS_INT2_MSK BIT(3)
+ #define CHNL_WIDTH 4
++#define BAR_NO_V3_HW  5
++
+ enum {
+       DSM_FUNC_ERR_HANDLE_MSI = 0,
+ };
+@@ -4740,15 +4742,15 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+       struct sas_ha_struct *sha;
+       int rc, phy_nr, port_nr, i;
+-      rc = pci_enable_device(pdev);
++      rc = pcim_enable_device(pdev);
+       if (rc)
+               goto err_out;
+       pci_set_master(pdev);
+-      rc = pci_request_regions(pdev, DRV_NAME);
++      rc = pcim_iomap_regions(pdev, 1 << BAR_NO_V3_HW, DRV_NAME);
+       if (rc)
+-              goto err_out_disable_device;
++              goto err_out;
+       rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+       if (rc)
+@@ -4756,20 +4758,20 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+       if (rc) {
+               dev_err(dev, "No usable DMA addressing method\n");
+               rc = -ENODEV;
+-              goto err_out_regions;
++              goto err_out;
+       }
+       shost = hisi_sas_shost_alloc_pci(pdev);
+       if (!shost) {
+               rc = -ENOMEM;
+-              goto err_out_regions;
++              goto err_out;
+       }
+       sha = SHOST_TO_SAS_HA(shost);
+       hisi_hba = shost_priv(shost);
+       dev_set_drvdata(dev, sha);
+-      hisi_hba->regs = pcim_iomap(pdev, 5, 0);
++      hisi_hba->regs = pcim_iomap_table(pdev)[BAR_NO_V3_HW];
+       if (!hisi_hba->regs) {
+               dev_err(dev, "cannot map register\n");
+               rc = -ENOMEM;
+@@ -4861,10 +4863,6 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ err_out_ha:
+       hisi_sas_free(hisi_hba);
+       scsi_host_put(shost);
+-err_out_regions:
+-      pci_release_regions(pdev);
+-err_out_disable_device:
+-      pci_disable_device(pdev);
+ err_out:
+       return rc;
+ }
+@@ -4901,8 +4899,6 @@ static void hisi_sas_v3_remove(struct pci_dev *pdev)
+       sas_remove_host(sha->core.shost);
+       hisi_sas_v3_destroy_irqs(pdev, hisi_hba);
+-      pci_release_regions(pdev);
+-      pci_disable_device(pdev);
+       hisi_sas_free(hisi_hba);
+       debugfs_exit_v3_hw(hisi_hba);
+       scsi_host_put(shost);
+-- 
+2.35.1
+
diff --git a/queue-5.15/scsi-iscsi-add-helper-to-remove-a-session-from-the-k.patch b/queue-5.15/scsi-iscsi-add-helper-to-remove-a-session-from-the-k.patch
new file mode 100644 (file)
index 0000000..56d6ad0
--- /dev/null
@@ -0,0 +1,107 @@
+From 8521dcbc424028067816eecc2d1bfdf42c5275f3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jun 2022 17:27:36 -0500
+Subject: scsi: iscsi: Add helper to remove a session from the kernel
+
+From: Mike Christie <michael.christie@oracle.com>
+
+[ Upstream commit bb42856bfd54fda1cbc7c470fcf5db1596938f4f ]
+
+During qedi shutdown we need to stop the iSCSI layer from sending new nops
+as pings and from responding to target ones and make sure there is no
+running connection cleanups. Commit d1f2ce77638d ("scsi: qedi: Fix host
+removal with running sessions") converted the driver to use the libicsi
+helper to drive session removal, so the above issues could be handled. The
+problem is that during system shutdown iscsid will not be running so when
+we try to remove the root session we will hang waiting for userspace to
+reply.
+
+Add a helper that will drive the destruction of sessions like these during
+system shutdown.
+
+Link: https://lore.kernel.org/r/20220616222738.5722-5-michael.christie@oracle.com
+Tested-by: Nilesh Javali <njavali@marvell.com>
+Reviewed-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Mike Christie <michael.christie@oracle.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/scsi_transport_iscsi.c | 49 +++++++++++++++++++++++++++++
+ include/scsi/scsi_transport_iscsi.h |  1 +
+ 2 files changed, 50 insertions(+)
+
+diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
+index 671a03b80c30..f46ae5391758 100644
+--- a/drivers/scsi/scsi_transport_iscsi.c
++++ b/drivers/scsi/scsi_transport_iscsi.c
+@@ -2360,6 +2360,55 @@ static void iscsi_cleanup_conn_work_fn(struct work_struct *work)
+       ISCSI_DBG_TRANS_CONN(conn, "cleanup done.\n");
+ }
++static int iscsi_iter_force_destroy_conn_fn(struct device *dev, void *data)
++{
++      struct iscsi_transport *transport;
++      struct iscsi_cls_conn *conn;
++
++      if (!iscsi_is_conn_dev(dev))
++              return 0;
++
++      conn = iscsi_dev_to_conn(dev);
++      transport = conn->transport;
++
++      if (READ_ONCE(conn->state) != ISCSI_CONN_DOWN)
++              iscsi_if_stop_conn(conn, STOP_CONN_TERM);
++
++      transport->destroy_conn(conn);
++      return 0;
++}
++
++/**
++ * iscsi_force_destroy_session - destroy a session from the kernel
++ * @session: session to destroy
++ *
++ * Force the destruction of a session from the kernel. This should only be
++ * used when userspace is no longer running during system shutdown.
++ */
++void iscsi_force_destroy_session(struct iscsi_cls_session *session)
++{
++      struct iscsi_transport *transport = session->transport;
++      unsigned long flags;
++
++      WARN_ON_ONCE(system_state == SYSTEM_RUNNING);
++
++      spin_lock_irqsave(&sesslock, flags);
++      if (list_empty(&session->sess_list)) {
++              spin_unlock_irqrestore(&sesslock, flags);
++              /*
++               * Conn/ep is already freed. Session is being torn down via
++               * async path. For shutdown we don't care about it so return.
++               */
++              return;
++      }
++      spin_unlock_irqrestore(&sesslock, flags);
++
++      device_for_each_child(&session->dev, NULL,
++                            iscsi_iter_force_destroy_conn_fn);
++      transport->destroy_session(session);
++}
++EXPORT_SYMBOL_GPL(iscsi_force_destroy_session);
++
+ void iscsi_free_session(struct iscsi_cls_session *session)
+ {
+       ISCSI_DBG_TRANS_SESSION(session, "Freeing session\n");
+diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
+index 3ecf9702287b..0f2f149ad916 100644
+--- a/include/scsi/scsi_transport_iscsi.h
++++ b/include/scsi/scsi_transport_iscsi.h
+@@ -441,6 +441,7 @@ extern struct iscsi_cls_session *iscsi_create_session(struct Scsi_Host *shost,
+                                               struct iscsi_transport *t,
+                                               int dd_size,
+                                               unsigned int target_id);
++extern void iscsi_force_destroy_session(struct iscsi_cls_session *session);
+ extern void iscsi_remove_session(struct iscsi_cls_session *session);
+ extern void iscsi_free_session(struct iscsi_cls_session *session);
+ extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess,
+-- 
+2.35.1
+
diff --git a/queue-5.15/scsi-iscsi-allow-iscsi_if_stop_conn-to-be-called-fro.patch b/queue-5.15/scsi-iscsi-allow-iscsi_if_stop_conn-to-be-called-fro.patch
new file mode 100644 (file)
index 0000000..56d86b7
--- /dev/null
@@ -0,0 +1,64 @@
+From 77fe3baf9f0579047bad0402373ddd4c04e61141 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jun 2022 17:27:34 -0500
+Subject: scsi: iscsi: Allow iscsi_if_stop_conn() to be called from kernel
+
+From: Mike Christie <michael.christie@oracle.com>
+
+[ Upstream commit 3328333b47f4163504267440ec0a36087a407a5f ]
+
+iscsi_if_stop_conn() is only called from the userspace interface but in a
+subsequent commit we will want to call it from the kernel interface to
+allow drivers like qedi to remove sessions from inside the kernel during
+shutdown. This removes the iscsi_uevent code from iscsi_if_stop_conn() so we
+can call it in a new helper.
+
+Link: https://lore.kernel.org/r/20220616222738.5722-3-michael.christie@oracle.com
+Tested-by: Nilesh Javali <njavali@marvell.com>
+Reviewed-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Mike Christie <michael.christie@oracle.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/scsi_transport_iscsi.c | 17 +++++++----------
+ 1 file changed, 7 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
+index 5947b9d5746e..671a03b80c30 100644
+--- a/drivers/scsi/scsi_transport_iscsi.c
++++ b/drivers/scsi/scsi_transport_iscsi.c
+@@ -2283,16 +2283,8 @@ static void iscsi_if_disconnect_bound_ep(struct iscsi_cls_conn *conn,
+       }
+ }
+-static int iscsi_if_stop_conn(struct iscsi_transport *transport,
+-                            struct iscsi_uevent *ev)
++static int iscsi_if_stop_conn(struct iscsi_cls_conn *conn, int flag)
+ {
+-      int flag = ev->u.stop_conn.flag;
+-      struct iscsi_cls_conn *conn;
+-
+-      conn = iscsi_conn_lookup(ev->u.stop_conn.sid, ev->u.stop_conn.cid);
+-      if (!conn)
+-              return -EINVAL;
+-
+       ISCSI_DBG_TRANS_CONN(conn, "iscsi if conn stop.\n");
+       /*
+        * If this is a termination we have to call stop_conn with that flag
+@@ -3739,7 +3731,12 @@ static int iscsi_if_transport_conn(struct iscsi_transport *transport,
+       case ISCSI_UEVENT_DESTROY_CONN:
+               return iscsi_if_destroy_conn(transport, ev);
+       case ISCSI_UEVENT_STOP_CONN:
+-              return iscsi_if_stop_conn(transport, ev);
++              conn = iscsi_conn_lookup(ev->u.stop_conn.sid,
++                                       ev->u.stop_conn.cid);
++              if (!conn)
++                      return -EINVAL;
++
++              return iscsi_if_stop_conn(conn, ev->u.stop_conn.flag);
+       }
+       /*
+-- 
+2.35.1
+
diff --git a/queue-5.15/scsi-iscsi-fix-session-removal-on-shutdown.patch b/queue-5.15/scsi-iscsi-fix-session-removal-on-shutdown.patch
new file mode 100644 (file)
index 0000000..1ea7786
--- /dev/null
@@ -0,0 +1,198 @@
+From c0e5aa8d282c9e43b0cf9da8d5033fb25eeecda2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jun 2022 17:27:38 -0500
+Subject: scsi: iscsi: Fix session removal on shutdown
+
+From: Mike Christie <michael.christie@oracle.com>
+
+[ Upstream commit 31500e902759322ba3c64b60dabae2704e738df8 ]
+
+When the system is shutting down, iscsid is not running so we will not get
+a response to the ISCSI_ERR_INVALID_HOST error event. The system shutdown
+will then hang waiting on userspace to remove the session.
+
+This has libiscsi force the destruction of the session from the kernel when
+iscsi_host_remove() is called from a driver's shutdown callout.
+
+This fixes a regression added in qedi boot with commit d1f2ce77638d ("scsi:
+qedi: Fix host removal with running sessions") which made qedi use the
+common session removal function that waits on userspace instead of rolling
+its own kernel based removal.
+
+Link: https://lore.kernel.org/r/20220616222738.5722-7-michael.christie@oracle.com
+Fixes: d1f2ce77638d ("scsi: qedi: Fix host removal with running sessions")
+Tested-by: Nilesh Javali <njavali@marvell.com>
+Reviewed-by: Lee Duncan <lduncan@suse.com>
+Reviewed-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Mike Christie <michael.christie@oracle.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/iser/iscsi_iser.c | 4 ++--
+ drivers/scsi/be2iscsi/be_main.c          | 2 +-
+ drivers/scsi/bnx2i/bnx2i_iscsi.c         | 2 +-
+ drivers/scsi/cxgbi/libcxgbi.c            | 2 +-
+ drivers/scsi/iscsi_tcp.c                 | 4 ++--
+ drivers/scsi/libiscsi.c                  | 9 +++++++--
+ drivers/scsi/qedi/qedi_main.c            | 9 ++++++---
+ include/scsi/libiscsi.h                  | 2 +-
+ 8 files changed, 21 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
+index 776e46ee95da..ef2d165d15a8 100644
+--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
++++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
+@@ -584,7 +584,7 @@ iscsi_iser_session_destroy(struct iscsi_cls_session *cls_session)
+       struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
+       iscsi_session_teardown(cls_session);
+-      iscsi_host_remove(shost);
++      iscsi_host_remove(shost, false);
+       iscsi_host_free(shost);
+ }
+@@ -702,7 +702,7 @@ iscsi_iser_session_create(struct iscsi_endpoint *ep,
+       return cls_session;
+ remove_host:
+-      iscsi_host_remove(shost);
++      iscsi_host_remove(shost, false);
+ free_host:
+       iscsi_host_free(shost);
+       return NULL;
+diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
+index e70f69f791db..7974c1326d46 100644
+--- a/drivers/scsi/be2iscsi/be_main.c
++++ b/drivers/scsi/be2iscsi/be_main.c
+@@ -5741,7 +5741,7 @@ static void beiscsi_remove(struct pci_dev *pcidev)
+       cancel_work_sync(&phba->sess_work);
+       beiscsi_iface_destroy_default(phba);
+-      iscsi_host_remove(phba->shost);
++      iscsi_host_remove(phba->shost, false);
+       beiscsi_disable_port(phba, 1);
+       /* after cancelling boot_work */
+diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
+index 2e5241d12dc3..85b5aca4b497 100644
+--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
++++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
+@@ -909,7 +909,7 @@ void bnx2i_free_hba(struct bnx2i_hba *hba)
+ {
+       struct Scsi_Host *shost = hba->shost;
+-      iscsi_host_remove(shost);
++      iscsi_host_remove(shost, false);
+       INIT_LIST_HEAD(&hba->ep_ofld_list);
+       INIT_LIST_HEAD(&hba->ep_active_list);
+       INIT_LIST_HEAD(&hba->ep_destroy_list);
+diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c
+index 4365d52c6430..32abdf0fa9aa 100644
+--- a/drivers/scsi/cxgbi/libcxgbi.c
++++ b/drivers/scsi/cxgbi/libcxgbi.c
+@@ -328,7 +328,7 @@ void cxgbi_hbas_remove(struct cxgbi_device *cdev)
+               chba = cdev->hbas[i];
+               if (chba) {
+                       cdev->hbas[i] = NULL;
+-                      iscsi_host_remove(chba->shost);
++                      iscsi_host_remove(chba->shost, false);
+                       pci_dev_put(cdev->pdev);
+                       iscsi_host_free(chba->shost);
+               }
+diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
+index 1bc37593c88f..0e52c6499eaf 100644
+--- a/drivers/scsi/iscsi_tcp.c
++++ b/drivers/scsi/iscsi_tcp.c
+@@ -898,7 +898,7 @@ iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max,
+ remove_session:
+       iscsi_session_teardown(cls_session);
+ remove_host:
+-      iscsi_host_remove(shost);
++      iscsi_host_remove(shost, false);
+ free_host:
+       iscsi_host_free(shost);
+       return NULL;
+@@ -915,7 +915,7 @@ static void iscsi_sw_tcp_session_destroy(struct iscsi_cls_session *cls_session)
+       iscsi_tcp_r2tpool_free(cls_session->dd_data);
+       iscsi_session_teardown(cls_session);
+-      iscsi_host_remove(shost);
++      iscsi_host_remove(shost, false);
+       iscsi_host_free(shost);
+ }
+diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
+index 0f2c7098f9d6..78de36250b31 100644
+--- a/drivers/scsi/libiscsi.c
++++ b/drivers/scsi/libiscsi.c
+@@ -2830,11 +2830,12 @@ static void iscsi_notify_host_removed(struct iscsi_cls_session *cls_session)
+ /**
+  * iscsi_host_remove - remove host and sessions
+  * @shost: scsi host
++ * @is_shutdown: true if called from a driver shutdown callout
+  *
+  * If there are any sessions left, this will initiate the removal and wait
+  * for the completion.
+  */
+-void iscsi_host_remove(struct Scsi_Host *shost)
++void iscsi_host_remove(struct Scsi_Host *shost, bool is_shutdown)
+ {
+       struct iscsi_host *ihost = shost_priv(shost);
+       unsigned long flags;
+@@ -2843,7 +2844,11 @@ void iscsi_host_remove(struct Scsi_Host *shost)
+       ihost->state = ISCSI_HOST_REMOVED;
+       spin_unlock_irqrestore(&ihost->lock, flags);
+-      iscsi_host_for_each_session(shost, iscsi_notify_host_removed);
++      if (!is_shutdown)
++              iscsi_host_for_each_session(shost, iscsi_notify_host_removed);
++      else
++              iscsi_host_for_each_session(shost, iscsi_force_destroy_session);
++
+       wait_event_interruptible(ihost->session_removal_wq,
+                                ihost->num_sessions == 0);
+       if (signal_pending(current))
+diff --git a/drivers/scsi/qedi/qedi_main.c b/drivers/scsi/qedi/qedi_main.c
+index e6dc0b495a82..a117d11f2b07 100644
+--- a/drivers/scsi/qedi/qedi_main.c
++++ b/drivers/scsi/qedi/qedi_main.c
+@@ -2417,9 +2417,12 @@ static void __qedi_remove(struct pci_dev *pdev, int mode)
+       int rval;
+       u16 retry = 10;
+-      if (mode == QEDI_MODE_NORMAL || mode == QEDI_MODE_SHUTDOWN) {
+-              iscsi_host_remove(qedi->shost);
++      if (mode == QEDI_MODE_NORMAL)
++              iscsi_host_remove(qedi->shost, false);
++      else if (mode == QEDI_MODE_SHUTDOWN)
++              iscsi_host_remove(qedi->shost, true);
++      if (mode == QEDI_MODE_NORMAL || mode == QEDI_MODE_SHUTDOWN) {
+               if (qedi->tmf_thread) {
+                       flush_workqueue(qedi->tmf_thread);
+                       destroy_workqueue(qedi->tmf_thread);
+@@ -2796,7 +2799,7 @@ static int __qedi_probe(struct pci_dev *pdev, int mode)
+ #ifdef CONFIG_DEBUG_FS
+       qedi_dbg_host_exit(&qedi->dbg_ctx);
+ #endif
+-      iscsi_host_remove(qedi->shost);
++      iscsi_host_remove(qedi->shost, false);
+ stop_iscsi_func:
+       qedi_ops->stop(qedi->cdev);
+ stop_slowpath:
+diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
+index 6ad01d7de480..a071f6ffd7fa 100644
+--- a/include/scsi/libiscsi.h
++++ b/include/scsi/libiscsi.h
+@@ -400,7 +400,7 @@ extern int iscsi_host_add(struct Scsi_Host *shost, struct device *pdev);
+ extern struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht,
+                                         int dd_data_size,
+                                         bool xmit_can_sleep);
+-extern void iscsi_host_remove(struct Scsi_Host *shost);
++extern void iscsi_host_remove(struct Scsi_Host *shost, bool is_shutdown);
+ extern void iscsi_host_free(struct Scsi_Host *shost);
+ extern int iscsi_target_alloc(struct scsi_target *starget);
+ extern int iscsi_host_get_max_scsi_cmds(struct Scsi_Host *shost,
+-- 
+2.35.1
+
diff --git a/queue-5.15/scsi-qla2xxx-check-correct-variable-in-qla24xx_async.patch b/queue-5.15/scsi-qla2xxx-check-correct-variable-in-qla24xx_async.patch
new file mode 100644 (file)
index 0000000..2281fd7
--- /dev/null
@@ -0,0 +1,40 @@
+From 98b098638f0aee140303292d9ac2ef7660d1fbe7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jun 2022 09:21:55 +0300
+Subject: scsi: qla2xxx: Check correct variable in qla24xx_async_gffid()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit 7c33e477bd883f79cccec418980cb8f7f2d50347 ]
+
+There is a copy and paste bug here.  It should check ".rsp" instead of
+".req".  The error message is copy and pasted as well so update that too.
+
+Link: https://lore.kernel.org/r/YrK1A/t3L6HKnswO@kili
+Fixes: 9c40c36e75ff ("scsi: qla2xxx: edif: Reduce Initiator-Initiator thrashing")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_gs.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
+index f89911beaade..2c49f12078ac 100644
+--- a/drivers/scsi/qla2xxx/qla_gs.c
++++ b/drivers/scsi/qla2xxx/qla_gs.c
+@@ -3385,9 +3385,9 @@ int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport, bool wait)
+                               sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
+                               &sp->u.iocb_cmd.u.ctarg.rsp_dma,
+           GFP_KERNEL);
+-      if (!sp->u.iocb_cmd.u.ctarg.req) {
++      if (!sp->u.iocb_cmd.u.ctarg.rsp) {
+               ql_log(ql_log_warn, vha, 0xd041,
+-                     "%s: Failed to allocate ct_sns request.\n",
++                     "%s: Failed to allocate ct_sns response.\n",
+                      __func__);
+               goto done_free_sp;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/scsi-qla2xxx-edif-add-retry-for-els-passthrough.patch b/queue-5.15/scsi-qla2xxx-edif-add-retry-for-els-passthrough.patch
new file mode 100644 (file)
index 0000000..6b970da
--- /dev/null
@@ -0,0 +1,142 @@
+From b0065a3eb7d171a0021489c8e7390973941bd131 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jun 2022 21:46:23 -0700
+Subject: scsi: qla2xxx: edif: Add retry for ELS passthrough
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit 0b3f3143d473b489a7aa0779c43bcdb344bd3014 ]
+
+Relating to EDIF, when sending IKE message, updating key or deleting key,
+driver can encounter IOCB queue full. Add additional retries to reduce
+higher level recovery.
+
+Link: https://lore.kernel.org/r/20220607044627.19563-8-njavali@marvell.com
+Fixes: dd30706e73b7 ("scsi: qla2xxx: edif: Add key update")
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_edif.c | 52 +++++++++++++++++++++++----------
+ drivers/scsi/qla2xxx/qla_os.c   |  2 +-
+ 2 files changed, 38 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c
+index bdcc38bd955a..ee8e1ae2c300 100644
+--- a/drivers/scsi/qla2xxx/qla_edif.c
++++ b/drivers/scsi/qla2xxx/qla_edif.c
+@@ -1274,6 +1274,8 @@ qla24xx_check_sadb_avail_slot(struct bsg_job *bsg_job, fc_port_t *fcport,
+ #define QLA_SA_UPDATE_FLAGS_RX_KEY      0x0
+ #define QLA_SA_UPDATE_FLAGS_TX_KEY      0x2
++#define EDIF_MSLEEP_INTERVAL 100
++#define EDIF_RETRY_COUNT  50
+ int
+ qla24xx_sadb_update(struct bsg_job *bsg_job)
+@@ -1286,7 +1288,7 @@ qla24xx_sadb_update(struct bsg_job *bsg_job)
+       struct edif_list_entry *edif_entry = NULL;
+       int                     found = 0;
+       int                     rval = 0;
+-      int result = 0;
++      int result = 0, cnt;
+       struct qla_sa_update_frame sa_frame;
+       struct srb_iocb *iocb_cmd;
+       port_id_t portid;
+@@ -1527,11 +1529,23 @@ qla24xx_sadb_update(struct bsg_job *bsg_job)
+       sp->done = qla2x00_bsg_job_done;
+       iocb_cmd = &sp->u.iocb_cmd;
+       iocb_cmd->u.sa_update.sa_frame  = sa_frame;
+-
++      cnt = 0;
++retry:
+       rval = qla2x00_start_sp(sp);
+-      if (rval != QLA_SUCCESS) {
++      switch (rval) {
++      case QLA_SUCCESS:
++              break;
++      case EAGAIN:
++              msleep(EDIF_MSLEEP_INTERVAL);
++              cnt++;
++              if (cnt < EDIF_RETRY_COUNT)
++                      goto retry;
++
++              fallthrough;
++      default:
+               ql_log(ql_dbg_edif, vha, 0x70e3,
+-                  "qla2x00_start_sp failed=%d.\n", rval);
++                     "%s qla2x00_start_sp failed=%d.\n",
++                     __func__, rval);
+               qla2x00_rel_sp(sp);
+               rval = -EIO;
+@@ -2254,7 +2268,6 @@ qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha, struct qla_work_evt *e)
+       rval = qla2x00_start_sp(sp);
+       if (rval != QLA_SUCCESS) {
+-              rval = QLA_FUNCTION_FAILED;
+               goto done_free_sp;
+       }
+@@ -3383,7 +3396,7 @@ int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+       fc_port_t *fcport = NULL;
+       struct qla_hw_data *ha = vha->hw;
+       srb_t *sp;
+-      int rval =  (DID_ERROR << 16);
++      int rval =  (DID_ERROR << 16), cnt;
+       port_id_t d_id;
+       struct qla_bsg_auth_els_request *p =
+           (struct qla_bsg_auth_els_request *)bsg_job->request;
+@@ -3474,17 +3487,26 @@ int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+       sp->free = qla2x00_bsg_sp_free;
+       sp->done = qla2x00_bsg_job_done;
++      cnt = 0;
++retry:
+       rval = qla2x00_start_sp(sp);
+-
+-      ql_dbg(ql_dbg_edif, vha, 0x700a,
+-          "%s %s %8phN xchg %x ctlflag %x hdl %x reqlen %xh bsg ptr %p\n",
+-          __func__, sc_to_str(p->e.sub_cmd), fcport->port_name,
+-          p->e.extra_rx_xchg_address, p->e.extra_control_flags,
+-          sp->handle, sp->remap.req.len, bsg_job);
+-
+-      if (rval != QLA_SUCCESS) {
++      switch (rval) {
++      case QLA_SUCCESS:
++              ql_dbg(ql_dbg_edif, vha, 0x700a,
++                     "%s %s %8phN xchg %x ctlflag %x hdl %x reqlen %xh bsg ptr %p\n",
++                     __func__, sc_to_str(p->e.sub_cmd), fcport->port_name,
++                     p->e.extra_rx_xchg_address, p->e.extra_control_flags,
++                     sp->handle, sp->remap.req.len, bsg_job);
++              break;
++      case EAGAIN:
++              msleep(EDIF_MSLEEP_INTERVAL);
++              cnt++;
++              if (cnt < EDIF_RETRY_COUNT)
++                      goto retry;
++              fallthrough;
++      default:
+               ql_log(ql_log_warn, vha, 0x700e,
+-                  "qla2x00_start_sp failed = %d\n", rval);
++                  "%s qla2x00_start_sp failed = %d\n", __func__, rval);
+               SET_DID_STATUS(bsg_reply->result, DID_IMM_RETRY);
+               rval = -EIO;
+               goto done_free_remap_rsp;
+diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
+index e683b1c01c9f..e87ad7e0dc94 100644
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -5466,7 +5466,7 @@ qla2x00_do_work(struct scsi_qla_host *vha)
+                           e->u.fcport.fcport, false);
+                       break;
+               case QLA_EVT_SA_REPLACE:
+-                      qla24xx_issue_sa_replace_iocb(vha, e);
++                      rc = qla24xx_issue_sa_replace_iocb(vha, e);
+                       break;
+               }
+-- 
+2.35.1
+
diff --git a/queue-5.15/scsi-qla2xxx-edif-fix-inconsistent-check-of-db_flags.patch b/queue-5.15/scsi-qla2xxx-edif-fix-inconsistent-check-of-db_flags.patch
new file mode 100644 (file)
index 0000000..44a823c
--- /dev/null
@@ -0,0 +1,256 @@
+From 9cc35c650f95179ce8c0f3a765d3a11460d0434a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Oct 2021 04:54:10 -0700
+Subject: scsi: qla2xxx: edif: Fix inconsistent check of db_flags
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit 36f468bfe98c7de7916ab3391ee5dd6fd2549979 ]
+
+db_flags field is a bit field. Replace value check with bit flag check.
+
+Link: https://lore.kernel.org/r/20211026115412.27691-12-njavali@marvell.com
+Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_edif.c   | 26 +++++++++++++-------------
+ drivers/scsi/qla2xxx/qla_edif.h   |  7 +++++--
+ drivers/scsi/qla2xxx/qla_init.c   | 13 ++++++-------
+ drivers/scsi/qla2xxx/qla_iocb.c   |  3 +--
+ drivers/scsi/qla2xxx/qla_target.c |  2 +-
+ 5 files changed, 26 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c
+index 4be876dd9f6b..bdcc38bd955a 100644
+--- a/drivers/scsi/qla2xxx/qla_edif.c
++++ b/drivers/scsi/qla2xxx/qla_edif.c
+@@ -218,7 +218,7 @@ fc_port_t *fcport)
+                   "%s edif not enabled\n", __func__);
+               goto done;
+       }
+-      if (vha->e_dbell.db_flags != EDB_ACTIVE) {
++      if (DBELL_INACTIVE(vha)) {
+               ql_dbg(ql_dbg_edif, vha, 0x09102,
+                   "%s doorbell not enabled\n", __func__);
+               goto done;
+@@ -482,9 +482,9 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+       ql_dbg(ql_dbg_edif, vha, 0x911d, "%s app_vid=%x app_start_flags %x\n",
+            __func__, appstart.app_info.app_vid, appstart.app_start_flags);
+-      if (vha->e_dbell.db_flags != EDB_ACTIVE) {
++      if (DBELL_INACTIVE(vha)) {
+               /* mark doorbell as active since an app is now present */
+-              vha->e_dbell.db_flags = EDB_ACTIVE;
++              vha->e_dbell.db_flags |= EDB_ACTIVE;
+       } else {
+               ql_dbg(ql_dbg_edif, vha, 0x911e, "%s doorbell already active\n",
+                    __func__);
+@@ -1306,7 +1306,7 @@ qla24xx_sadb_update(struct bsg_job *bsg_job)
+               goto done;
+       }
+-      if (vha->e_dbell.db_flags != EDB_ACTIVE) {
++      if (DBELL_INACTIVE(vha)) {
+               ql_log(ql_log_warn, vha, 0x70a1, "App not started\n");
+               rval = -EIO;
+               SET_DID_STATUS(bsg_reply->result, DID_ERROR);
+@@ -1813,7 +1813,7 @@ qla_els_reject_iocb(scsi_qla_host_t *vha, struct qla_qpair *qp,
+ void
+ qla_edb_init(scsi_qla_host_t *vha)
+ {
+-      if (vha->e_dbell.db_flags == EDB_ACTIVE) {
++      if (DBELL_ACTIVE(vha)) {
+               /* list already init'd - error */
+               ql_dbg(ql_dbg_edif, vha, 0x09102,
+                   "edif db already initialized, cannot reinit\n");
+@@ -1856,7 +1856,7 @@ static void qla_edb_clear(scsi_qla_host_t *vha, port_id_t portid)
+       port_id_t sid;
+       LIST_HEAD(edb_list);
+-      if (vha->e_dbell.db_flags != EDB_ACTIVE) {
++      if (DBELL_INACTIVE(vha)) {
+               /* doorbell list not enabled */
+               ql_dbg(ql_dbg_edif, vha, 0x09102,
+                      "%s doorbell not enabled\n", __func__);
+@@ -1908,7 +1908,7 @@ qla_edb_stop(scsi_qla_host_t *vha)
+       unsigned long flags;
+       struct edb_node *node, *q;
+-      if (vha->e_dbell.db_flags != EDB_ACTIVE) {
++      if (DBELL_INACTIVE(vha)) {
+               /* doorbell list not enabled */
+               ql_dbg(ql_dbg_edif, vha, 0x09102,
+                   "%s doorbell not enabled\n", __func__);
+@@ -1959,7 +1959,7 @@ qla_edb_node_add(scsi_qla_host_t *vha, struct edb_node *ptr)
+ {
+       unsigned long           flags;
+-      if (vha->e_dbell.db_flags != EDB_ACTIVE) {
++      if (DBELL_INACTIVE(vha)) {
+               /* doorbell list not enabled */
+               ql_dbg(ql_dbg_edif, vha, 0x09102,
+                   "%s doorbell not enabled\n", __func__);
+@@ -1990,7 +1990,7 @@ qla_edb_eventcreate(scsi_qla_host_t *vha, uint32_t dbtype,
+               return;
+       }
+-      if (vha->e_dbell.db_flags != EDB_ACTIVE) {
++      if (DBELL_INACTIVE(vha)) {
+               if (fcport)
+                       fcport->edif.auth_state = dbtype;
+               /* doorbell list not enabled */
+@@ -2085,7 +2085,7 @@ qla_edif_timer(scsi_qla_host_t *vha)
+       struct qla_hw_data *ha = vha->hw;
+       if (!vha->vp_idx && N2N_TOPO(ha) && ha->flags.n2n_fw_acc_sec) {
+-              if (vha->e_dbell.db_flags != EDB_ACTIVE &&
++              if (DBELL_INACTIVE(vha) &&
+                   ha->edif_post_stop_cnt_down) {
+                       ha->edif_post_stop_cnt_down--;
+@@ -2123,7 +2123,7 @@ edif_doorbell_show(struct device *dev, struct device_attribute *attr,
+       sz = 256;
+       /* stop new threads from waiting if we're not init'd */
+-      if (vha->e_dbell.db_flags != EDB_ACTIVE) {
++      if (DBELL_INACTIVE(vha)) {
+               ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x09122,
+                   "%s error - edif db not enabled\n", __func__);
+               return 0;
+@@ -2480,7 +2480,7 @@ void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp)
+       fcport = qla2x00_find_fcport_by_pid(host, &purex->pur_info.pur_sid);
+-      if (host->e_dbell.db_flags != EDB_ACTIVE ||
++      if (DBELL_INACTIVE(vha) ||
+           (fcport && EDIF_SESSION_DOWN(fcport))) {
+               ql_dbg(ql_dbg_edif, host, 0x0910c, "%s e_dbell.db_flags =%x %06x\n",
+                   __func__, host->e_dbell.db_flags,
+@@ -3506,7 +3506,7 @@ int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+ void qla_edif_sess_down(struct scsi_qla_host *vha, struct fc_port *sess)
+ {
+-      if (sess->edif.app_sess_online && vha->e_dbell.db_flags & EDB_ACTIVE) {
++      if (sess->edif.app_sess_online && DBELL_ACTIVE(vha)) {
+               ql_dbg(ql_dbg_disc, vha, 0xf09c,
+                       "%s: sess %8phN send port_offline event\n",
+                       __func__, sess->port_name);
+diff --git a/drivers/scsi/qla2xxx/qla_edif.h b/drivers/scsi/qla2xxx/qla_edif.h
+index 2517005fb08c..a965ca8e47ce 100644
+--- a/drivers/scsi/qla2xxx/qla_edif.h
++++ b/drivers/scsi/qla2xxx/qla_edif.h
+@@ -41,9 +41,12 @@ struct pur_core {
+ };
+ enum db_flags_t {
+-      EDB_ACTIVE = 0x1,
++      EDB_ACTIVE = BIT_0,
+ };
++#define DBELL_ACTIVE(_v) (_v->e_dbell.db_flags & EDB_ACTIVE)
++#define DBELL_INACTIVE(_v) (!(_v->e_dbell.db_flags & EDB_ACTIVE))
++
+ struct edif_dbell {
+       enum db_flags_t         db_flags;
+       spinlock_t              db_lock;
+@@ -134,7 +137,7 @@ struct enode {
+        !_s->edif.app_sess_online))
+ #define EDIF_NEGOTIATION_PENDING(_fcport) \
+-      ((_fcport->vha.e_dbell.db_flags & EDB_ACTIVE) && \
++      (DBELL_ACTIVE(_fcport->vha) && \
+        (_fcport->disc_state == DSC_LOGIN_AUTH_PEND))
+ #endif        /* __QLA_EDIF_H */
+diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
+index 09ddaa8cb653..2bed5050bcaf 100644
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -341,7 +341,7 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport,
+               lio->u.logio.flags |= SRB_LOGIN_PRLI_ONLY;
+       } else {
+               if (vha->hw->flags.edif_enabled &&
+-                  vha->e_dbell.db_flags & EDB_ACTIVE) {
++                  DBELL_ACTIVE(vha)) {
+                       lio->u.logio.flags |=
+                               (SRB_LOGIN_FCSP | SRB_LOGIN_SKIP_PRLI);
+                       ql_dbg(ql_dbg_disc, vha, 0x2072,
+@@ -881,7 +881,7 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,
+                               break;
+                       case DSC_LS_PLOGI_COMP:
+                               if (vha->hw->flags.edif_enabled &&
+-                                  vha->e_dbell.db_flags & EDB_ACTIVE) {
++                                  DBELL_ACTIVE(vha)) {
+                                       /* check to see if App support secure or not */
+                                       qla24xx_post_gpdb_work(vha, fcport, 0);
+                                       break;
+@@ -1477,7 +1477,7 @@ static int       qla_chk_secure_login(scsi_qla_host_t    *vha, fc_port_t *fcport,
+                       qla2x00_post_aen_work(vha, FCH_EVT_PORT_ONLINE,
+                           fcport->d_id.b24);
+-                      if (vha->e_dbell.db_flags ==  EDB_ACTIVE) {
++                      if (DBELL_ACTIVE(vha)) {
+                               ql_dbg(ql_dbg_disc, vha, 0x20ef,
+                                   "%s %d %8phC EDIF: post DB_AUTH: AUTH needed\n",
+                                   __func__, __LINE__, fcport->port_name);
+@@ -1826,7 +1826,7 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea)
+                               return;
+                       }
+-                      if (vha->hw->flags.edif_enabled && vha->e_dbell.db_flags & EDB_ACTIVE) {
++                      if (vha->hw->flags.edif_enabled && DBELL_ACTIVE(vha)) {
+                               /*
+                                * On ipsec start by remote port, Target port
+                                * may use RSCN to trigger initiator to
+@@ -4266,7 +4266,7 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha)
+                * fw shal not send PRLI after PLOGI Acc
+                */
+               if (ha->flags.edif_enabled &&
+-                  vha->e_dbell.db_flags & EDB_ACTIVE) {
++                  DBELL_ACTIVE(vha)) {
+                       ha->fw_options[3] |= BIT_15;
+                       ha->flags.n2n_fw_acc_sec = 1;
+               } else {
+@@ -5424,8 +5424,7 @@ qla2x00_configure_loop(scsi_qla_host_t *vha)
+                        * use link up to wake up app to get ready for
+                        * authentication.
+                        */
+-                      if (ha->flags.edif_enabled &&
+-                          !(vha->e_dbell.db_flags & EDB_ACTIVE))
++                      if (ha->flags.edif_enabled && DBELL_INACTIVE(vha))
+                               qla2x00_post_aen_work(vha, FCH_EVT_LINKUP,
+                                                     ha->link_data_rate);
+diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
+index 7ff2d9c84bde..46c879923da1 100644
+--- a/drivers/scsi/qla2xxx/qla_iocb.c
++++ b/drivers/scsi/qla2xxx/qla_iocb.c
+@@ -3065,8 +3065,7 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
+       elsio->u.els_plogi.els_cmd = els_opcode;
+       elsio->u.els_plogi.els_plogi_pyld->opcode = els_opcode;
+-      if (els_opcode == ELS_DCMD_PLOGI && vha->hw->flags.edif_enabled &&
+-          vha->e_dbell.db_flags & EDB_ACTIVE) {
++      if (els_opcode == ELS_DCMD_PLOGI && DBELL_ACTIVE(vha)) {
+               struct fc_els_flogi *p = ptr;
+               p->fl_csp.sp_features |= cpu_to_be16(FC_SP_FT_SEC);
+diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
+index ae5eaa4a9283..7ab3c9e4d478 100644
+--- a/drivers/scsi/qla2xxx/qla_target.c
++++ b/drivers/scsi/qla2xxx/qla_target.c
+@@ -4815,7 +4815,7 @@ static int qlt_handle_login(struct scsi_qla_host *vha,
+       }
+       if (vha->hw->flags.edif_enabled) {
+-              if (!(vha->e_dbell.db_flags & EDB_ACTIVE)) {
++              if (DBELL_INACTIVE(vha)) {
+                       ql_dbg(ql_dbg_disc, vha, 0xffff,
+                              "%s %d Term INOT due to app not started lid=%d, NportID %06X ",
+                              __func__, __LINE__, loop_id, port_id.b24);
+-- 
+2.35.1
+
diff --git a/queue-5.15/scsi-qla2xxx-edif-fix-n2n-discovery-issue-with-secur.patch b/queue-5.15/scsi-qla2xxx-edif-fix-n2n-discovery-issue-with-secur.patch
new file mode 100644 (file)
index 0000000..0e2da64
--- /dev/null
@@ -0,0 +1,41 @@
+From 94223303b72e2ae04fea08b4bcf2cec4d184d805 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jun 2022 21:46:25 -0700
+Subject: scsi: qla2xxx: edif: Fix n2n discovery issue with secure target
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit 789d54a4178634850e441f60c0326124138e7269 ]
+
+User failed to see disk via n2n topology. Driver used up all login retries
+before authentication application started. When authentication application
+started, driver did not have enough login retries to connect securely. On
+app_start, driver will reset the login retry attempt count.
+
+Link: https://lore.kernel.org/r/20220607044627.19563-10-njavali@marvell.com
+Fixes: 4de067e5df12 ("scsi: qla2xxx: edif: Add N2N support for EDIF")
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_edif.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c
+index ee8e1ae2c300..8be282339fdd 100644
+--- a/drivers/scsi/qla2xxx/qla_edif.c
++++ b/drivers/scsi/qla2xxx/qla_edif.c
+@@ -491,6 +491,9 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+       }
+       if (N2N_TOPO(vha->hw)) {
++              list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list)
++                      fcport->n2n_link_reset_cnt = 0;
++
+               if (vha->hw->flags.n2n_fw_acc_sec)
+                       set_bit(N2N_LINK_RESET, &vha->dpc_flags);
+               else
+-- 
+2.35.1
+
diff --git a/queue-5.15/scsi-qla2xxx-edif-fix-n2n-login-retry-for-secure-dev.patch b/queue-5.15/scsi-qla2xxx-edif-fix-n2n-login-retry-for-secure-dev.patch
new file mode 100644 (file)
index 0000000..4224474
--- /dev/null
@@ -0,0 +1,46 @@
+From db7a5b3483dd35f175eea8f91367981f4b256f5e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jun 2022 21:46:26 -0700
+Subject: scsi: qla2xxx: edif: Fix n2n login retry for secure device
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit aec55325ddec975216119da000092cb8664a3399 ]
+
+After initiator has burned up all login retries, target authentication
+application begins to run. This triggers a link bounce on target side.
+Initiator will attempt another login. Due to N2N, the PRLI [nvme | fcp] can
+fail because of the mode mismatch with target. This patch add a few more
+login retries to revive the connection.
+
+Link: https://lore.kernel.org/r/20220607044627.19563-11-njavali@marvell.com
+Fixes: 4de067e5df12 ("scsi: qla2xxx: edif: Add N2N support for EDIF")
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_init.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
+index 2bed5050bcaf..49cfe8c9f3bb 100644
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -2125,6 +2125,13 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
+               }
+               if (N2N_TOPO(vha->hw)) {
++                      if (ea->fcport->n2n_link_reset_cnt ==
++                          vha->hw->login_retry_count &&
++                          ea->fcport->flags & FCF_FCSP_DEVICE) {
++                              /* remote authentication app just started */
++                              ea->fcport->n2n_link_reset_cnt = 0;
++                      }
++
+                       if (ea->fcport->n2n_link_reset_cnt <
+                           vha->hw->login_retry_count) {
+                               ea->fcport->n2n_link_reset_cnt++;
+-- 
+2.35.1
+
diff --git a/queue-5.15/scsi-qla2xxx-edif-fix-no-login-after-app-start.patch b/queue-5.15/scsi-qla2xxx-edif-fix-no-login-after-app-start.patch
new file mode 100644 (file)
index 0000000..38d29e8
--- /dev/null
@@ -0,0 +1,46 @@
+From 7d580544d01b39395df2ecd4eb72460d6378547d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jun 2022 04:58:43 -0700
+Subject: scsi: qla2xxx: edif: Fix no login after app start
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit 24c796098f5395477f7f7ebf8e24f3f08a139f71 ]
+
+The scenario is this: User loaded driver but has not started authentication
+app. All sessions to secure device will exhaust all login attempts, fail,
+and in stay in deleted state. Then some time later the app is started. The
+driver will replenish the login retry count, trigger delete to prepare for
+secure login. After deletion, relogin is triggered.
+
+For the session that is already deleted, the delete trigger is a no-op. If
+none of the sessions trigger a relogin, no progress is made.
+
+Add a relogin trigger.
+
+Link: https://lore.kernel.org/r/20220608115849.16693-5-njavali@marvell.com
+Fixes: 7ebb336e45ef ("scsi: qla2xxx: edif: Add start + stop bsgs")
+Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_edif.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c
+index f7953ce17678..c0971888a0a1 100644
+--- a/drivers/scsi/qla2xxx/qla_edif.c
++++ b/drivers/scsi/qla2xxx/qla_edif.c
+@@ -544,6 +544,7 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+                       qlt_schedule_sess_for_deletion(fcport);
+                       qla_edif_sa_ctl_init(vha, fcport);
+               }
++              set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
+       }
+       if (vha->pur_cinfo.enode_flags != ENODE_ACTIVE) {
+-- 
+2.35.1
+
diff --git a/queue-5.15/scsi-qla2xxx-edif-fix-no-logout-on-delete-for-n2n.patch b/queue-5.15/scsi-qla2xxx-edif-fix-no-logout-on-delete-for-n2n.patch
new file mode 100644 (file)
index 0000000..b275070
--- /dev/null
@@ -0,0 +1,43 @@
+From 5b843b881c1bdbe83073cfa6f7d50e380bd449b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jun 2022 04:58:46 -0700
+Subject: scsi: qla2xxx: edif: Fix no logout on delete for N2N
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit ec538eb838f334453b10e7e9b260f0c358018a37 ]
+
+The driver failed to send implicit logout on session delete. For edif, this
+failed to flush any lingering SA index in FW.
+
+Set a flag to turn on implicit logout early in the session recovery to make
+sure the logout will go out in case of error.
+
+Link: https://lore.kernel.org/r/20220608115849.16693-8-njavali@marvell.com
+Fixes: 4de067e5df12 ("scsi: qla2xxx: edif: Add N2N support for EDIF")
+Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_iocb.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
+index 46c879923da1..42ce4e1fe744 100644
+--- a/drivers/scsi/qla2xxx/qla_iocb.c
++++ b/drivers/scsi/qla2xxx/qla_iocb.c
+@@ -2882,6 +2882,9 @@ static void qla2x00_els_dcmd2_sp_done(srb_t *sp, int res)
+           sp->name, res, sp->handle, fcport->d_id.b24, fcport->port_name);
+       fcport->flags &= ~(FCF_ASYNC_SENT|FCF_ASYNC_ACTIVE);
++      /* For edif, set logout on delete to ensure any residual key from FW is flushed.*/
++      fcport->logout_on_delete = 1;
++      fcport->chip_reset = vha->hw->base_qpair->chip_reset;
+       if (sp->flags & SRB_WAKEUP_ON_COMP)
+               complete(&lio->u.els_plogi.comp);
+-- 
+2.35.1
+
diff --git a/queue-5.15/scsi-qla2xxx-edif-fix-potential-stuck-session-in-sa-.patch b/queue-5.15/scsi-qla2xxx-edif-fix-potential-stuck-session-in-sa-.patch
new file mode 100644 (file)
index 0000000..4c0dada
--- /dev/null
@@ -0,0 +1,78 @@
+From 2925a556760c4bdc25c0b39e78241199df8854fe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jun 2022 21:46:21 -0700
+Subject: scsi: qla2xxx: edif: Fix potential stuck session in sa update
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit e0fb8ce2bb9e52c846e54ad2c58b5b7beb13eb09 ]
+
+When a thread is in the process of reestablish a session, a flag is set to
+prevent multiple threads/triggers from doing the same task. This flag was
+left on, and any attempt to relogin was locked out. Clear this flag if the
+attempt has failed.
+
+Link: https://lore.kernel.org/r/20220607044627.19563-6-njavali@marvell.com
+Fixes: dd30706e73b7 ("scsi: qla2xxx: edif: Add key update")
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_edif.c | 17 ++++++++++++++---
+ 1 file changed, 14 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c
+index e42141635377..4be876dd9f6b 100644
+--- a/drivers/scsi/qla2xxx/qla_edif.c
++++ b/drivers/scsi/qla2xxx/qla_edif.c
+@@ -2187,6 +2187,7 @@ edif_doorbell_show(struct device *dev, struct device_attribute *attr,
+ static void qla_noop_sp_done(srb_t *sp, int res)
+ {
++      sp->fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
+ }
+@@ -2211,7 +2212,8 @@ qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha, struct qla_work_evt *e)
+       if (!sa_ctl) {
+               ql_dbg(ql_dbg_edif, vha, 0x70e6,
+                   "sa_ctl allocation failed\n");
+-              return -ENOMEM;
++              rval =  -ENOMEM;
++              goto done;
+       }
+       fcport = sa_ctl->fcport;
+@@ -2221,7 +2223,8 @@ qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha, struct qla_work_evt *e)
+       if (!sp) {
+               ql_dbg(ql_dbg_edif, vha, 0x70e6,
+                "SRB allocation failed\n");
+-              return -ENOMEM;
++              rval = -ENOMEM;
++              goto done;
+       }
+       fcport->flags |= FCF_ASYNC_SENT;
+@@ -2250,9 +2253,17 @@ qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha, struct qla_work_evt *e)
+       rval = qla2x00_start_sp(sp);
+-      if (rval != QLA_SUCCESS)
++      if (rval != QLA_SUCCESS) {
+               rval = QLA_FUNCTION_FAILED;
++              goto done_free_sp;
++      }
++      return rval;
++done_free_sp:
++      kref_put(&sp->cmd_kref, qla2x00_sp_release);
++      fcport->flags &= ~FCF_ASYNC_SENT;
++done:
++      fcport->flags &= ~FCF_ASYNC_ACTIVE;
+       return rval;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/scsi-qla2xxx-edif-fix-session-thrash.patch b/queue-5.15/scsi-qla2xxx-edif-fix-session-thrash.patch
new file mode 100644 (file)
index 0000000..1caff6e
--- /dev/null
@@ -0,0 +1,78 @@
+From 42b00cce586568c5f1c11205ff40fcf5269bec21 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jun 2022 04:58:45 -0700
+Subject: scsi: qla2xxx: edif: Fix session thrash
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit a8fdfb0b39c2b31722c70bdf2272b949d5af4b7b ]
+
+Current code prematurely sends out PRLI before authentication application
+has given the OK to do so. This causes PRLI failure and session teardown.
+
+Prevents PRLI from going out before authentication app gives the OK.
+
+Link: https://lore.kernel.org/r/20220608115849.16693-7-njavali@marvell.com
+Fixes: 91f6f5fbe87b ("scsi: qla2xxx: edif: Reduce connection thrash")
+Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_edif.c |  2 +-
+ drivers/scsi/qla2xxx/qla_edif.h |  4 ++++
+ drivers/scsi/qla2xxx/qla_init.c | 10 +++++++++-
+ 3 files changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c
+index c0971888a0a1..8e9237434e8b 100644
+--- a/drivers/scsi/qla2xxx/qla_edif.c
++++ b/drivers/scsi/qla2xxx/qla_edif.c
+@@ -3437,7 +3437,7 @@ int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+       if (qla_bsg_check(vha, bsg_job, fcport))
+               return 0;
+-      if (fcport->loop_id == FC_NO_LOOP_ID) {
++      if (EDIF_SESS_DELETE(fcport)) {
+               ql_dbg(ql_dbg_edif, vha, 0x910d,
+                   "%s ELS code %x, no loop id.\n", __func__,
+                   bsg_request->rqst_data.r_els.els_code);
+diff --git a/drivers/scsi/qla2xxx/qla_edif.h b/drivers/scsi/qla2xxx/qla_edif.h
+index a965ca8e47ce..b9cedf6defd9 100644
+--- a/drivers/scsi/qla2xxx/qla_edif.h
++++ b/drivers/scsi/qla2xxx/qla_edif.h
+@@ -140,4 +140,8 @@ struct enode {
+       (DBELL_ACTIVE(_fcport->vha) && \
+        (_fcport->disc_state == DSC_LOGIN_AUTH_PEND))
++#define EDIF_SESS_DELETE(_s) \
++      (qla_ini_mode_enabled(_s->vha) && (_s->disc_state == DSC_DELETE_PEND || \
++       _s->disc_state == DSC_DELETED))
++
+ #endif        /* __QLA_EDIF_H */
+diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
+index 49cfe8c9f3bb..edc29d6ebb28 100644
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -1764,8 +1764,16 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport)
+               break;
+       case DSC_LOGIN_PEND:
+-              if (fcport->fw_login_state == DSC_LS_PLOGI_COMP)
++              if (vha->hw->flags.edif_enabled)
++                      break;
++
++              if (fcport->fw_login_state == DSC_LS_PLOGI_COMP) {
++                      ql_dbg(ql_dbg_disc, vha, 0x2118,
++                             "%s %d %8phC post %s PRLI\n",
++                             __func__, __LINE__, fcport->port_name,
++                             NVME_TARGET(vha->hw, fcport) ? "NVME" : "FC");
+                       qla24xx_post_prli_work(vha, fcport);
++              }
+               break;
+       case DSC_UPD_FCPORT:
+-- 
+2.35.1
+
diff --git a/queue-5.15/scsi-qla2xxx-edif-reduce-connection-thrash.patch b/queue-5.15/scsi-qla2xxx-edif-reduce-connection-thrash.patch
new file mode 100644 (file)
index 0000000..f284029
--- /dev/null
@@ -0,0 +1,95 @@
+From 20a54d75b1d2200bb6bbc91e0c3cf43d2bca45a9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Oct 2021 04:54:08 -0700
+Subject: scsi: qla2xxx: edif: Reduce connection thrash
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit 91f6f5fbe87ba834133fcc61d34881cb8ec9e518 ]
+
+On ipsec start by remote port, target port may use RSCN to trigger
+initiator to relogin. If driver is already in the process of a relogin,
+then ignore the RSCN and allow the current relogin to continue. This
+reduces thrashing of the connection.
+
+Link: https://lore.kernel.org/r/20211026115412.27691-10-njavali@marvell.com
+Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_attr.c |  7 ++++++-
+ drivers/scsi/qla2xxx/qla_edif.h |  4 ++++
+ drivers/scsi/qla2xxx/qla_init.c | 24 ++++++++++++++++++++++--
+ 3 files changed, 32 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
+index d3534e7f2d21..bd4ebc1b5c1e 100644
+--- a/drivers/scsi/qla2xxx/qla_attr.c
++++ b/drivers/scsi/qla2xxx/qla_attr.c
+@@ -2754,7 +2754,12 @@ qla2x00_terminate_rport_io(struct fc_rport *rport)
+                       if (fcport->loop_id != FC_NO_LOOP_ID)
+                               fcport->logout_on_delete = 1;
+-                      qlt_schedule_sess_for_deletion(fcport);
++                      if (!EDIF_NEGOTIATION_PENDING(fcport)) {
++                              ql_dbg(ql_dbg_disc, fcport->vha, 0x911e,
++                                     "%s %d schedule session deletion\n", __func__,
++                                     __LINE__);
++                              qlt_schedule_sess_for_deletion(fcport);
++                      }
+               } else {
+                       qla2x00_port_logout(fcport->vha, fcport);
+               }
+diff --git a/drivers/scsi/qla2xxx/qla_edif.h b/drivers/scsi/qla2xxx/qla_edif.h
+index 32800bfb32a3..2517005fb08c 100644
+--- a/drivers/scsi/qla2xxx/qla_edif.h
++++ b/drivers/scsi/qla2xxx/qla_edif.h
+@@ -133,4 +133,8 @@ struct enode {
+        _s->disc_state == DSC_DELETED || \
+        !_s->edif.app_sess_online))
++#define EDIF_NEGOTIATION_PENDING(_fcport) \
++      ((_fcport->vha.e_dbell.db_flags & EDB_ACTIVE) && \
++       (_fcport->disc_state == DSC_LOGIN_AUTH_PEND))
++
+ #endif        /* __QLA_EDIF_H */
+diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
+index be150fc76dba..09ddaa8cb653 100644
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -1825,8 +1825,28 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea)
+                                       fcport->d_id.b24, fcport->port_name);
+                               return;
+                       }
+-                      fcport->scan_needed = 1;
+-                      fcport->rscn_gen++;
++
++                      if (vha->hw->flags.edif_enabled && vha->e_dbell.db_flags & EDB_ACTIVE) {
++                              /*
++                               * On ipsec start by remote port, Target port
++                               * may use RSCN to trigger initiator to
++                               * relogin. If driver is already in the
++                               * process of a relogin, then ignore the RSCN
++                               * and allow the current relogin to continue.
++                               * This reduces thrashing of the connection.
++                               */
++                              if (atomic_read(&fcport->state) == FCS_ONLINE) {
++                                      /*
++                                       * If state = online, then set scan_needed=1 to do relogin.
++                                       * Otherwise we're already in the middle of a relogin
++                                       */
++                                      fcport->scan_needed = 1;
++                                      fcport->rscn_gen++;
++                              }
++                      } else {
++                              fcport->scan_needed = 1;
++                              fcport->rscn_gen++;
++                      }
+               }
+               break;
+       case RSCN_AREA_ADDR:
+-- 
+2.35.1
+
diff --git a/queue-5.15/scsi-qla2xxx-edif-reduce-disruption-due-to-multiple-.patch b/queue-5.15/scsi-qla2xxx-edif-reduce-disruption-due-to-multiple-.patch
new file mode 100644 (file)
index 0000000..824af5b
--- /dev/null
@@ -0,0 +1,48 @@
+From e7c2eef3da6f2d9d756f5445fa13209629402052 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jun 2022 04:58:42 -0700
+Subject: scsi: qla2xxx: edif: Reduce disruption due to multiple app start
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit 0dbfce5255fe8d069a1a3b712a25b263264cfa58 ]
+
+Multiple app start can trigger a session bounce. Make driver skip over
+session teardown if app start is seen more than once.
+
+Link: https://lore.kernel.org/r/20220608115849.16693-4-njavali@marvell.com
+Fixes: 7ebb336e45ef ("scsi: qla2xxx: edif: Add start + stop bsgs")
+Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_edif.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c
+index 69f8d16effa6..f7953ce17678 100644
+--- a/drivers/scsi/qla2xxx/qla_edif.c
++++ b/drivers/scsi/qla2xxx/qla_edif.c
+@@ -486,8 +486,7 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+               /* mark doorbell as active since an app is now present */
+               vha->e_dbell.db_flags |= EDB_ACTIVE;
+       } else {
+-              ql_dbg(ql_dbg_edif, vha, 0x911e, "%s doorbell already active\n",
+-                   __func__);
++              goto out;
+       }
+       if (N2N_TOPO(vha->hw)) {
+@@ -555,6 +554,7 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+                    __func__);
+       }
++out:
+       appreply.host_support_edif = vha->hw->flags.edif_enabled;
+       appreply.edif_enode_active = vha->pur_cinfo.enode_flags;
+       appreply.edif_edb_active = vha->e_dbell.db_flags;
+-- 
+2.35.1
+
diff --git a/queue-5.15/scsi-qla2xxx-edif-reduce-initiator-initiator-thrashi.patch b/queue-5.15/scsi-qla2xxx-edif-reduce-initiator-initiator-thrashi.patch
new file mode 100644 (file)
index 0000000..5347dbc
--- /dev/null
@@ -0,0 +1,325 @@
+From ec30758e8cce8a806e51fb1ed98711fb789b6e2c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jun 2022 21:46:17 -0700
+Subject: scsi: qla2xxx: edif: Reduce Initiator-Initiator thrashing
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit 9c40c36e75ffd49952cd4ead0672defc4b4dbdf7 ]
+
+This patch uses GFFID switch command to scan whether remote device is
+Target or Initiator mode.  Based on that info, driver will not pass up
+Initiator info to authentication application. This helps reduce unnecessary
+stress for authentication application to deal with unused connections.
+
+Link: https://lore.kernel.org/r/20220607044627.19563-2-njavali@marvell.com
+Fixes: 7ebb336e45ef ("scsi: qla2xxx: edif: Add start + stop bsgs")
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_def.h  |   2 +
+ drivers/scsi/qla2xxx/qla_edif.c |  32 ++++++++-
+ drivers/scsi/qla2xxx/qla_gbl.h  |   3 +-
+ drivers/scsi/qla2xxx/qla_gs.c   | 118 +++++++++++++++++++++++---------
+ drivers/scsi/qla2xxx/qla_iocb.c |   2 +-
+ 5 files changed, 120 insertions(+), 37 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
+index 76427c8780f5..883b3fb07c2c 100644
+--- a/drivers/scsi/qla2xxx/qla_def.h
++++ b/drivers/scsi/qla2xxx/qla_def.h
+@@ -3201,6 +3201,8 @@ struct ct_sns_rsp {
+ #define GFF_NVME_OFFSET               23 /* type = 28h */
+               struct {
+                       uint8_t fc4_features[128];
++#define FC4_FF_TARGET    BIT_0
++#define FC4_FF_INITIATOR BIT_1
+               } gff_id;
+               struct {
+                       uint8_t reserved;
+diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c
+index e40b9cc38214..e42141635377 100644
+--- a/drivers/scsi/qla2xxx/qla_edif.c
++++ b/drivers/scsi/qla2xxx/qla_edif.c
+@@ -517,16 +517,28 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+                       if (atomic_read(&vha->loop_state) == LOOP_DOWN)
+                               break;
+-                      fcport->edif.app_started = 1;
+                       fcport->login_retry = vha->hw->login_retry_count;
+-                      /* no activity */
+                       fcport->edif.app_stop = 0;
++                      fcport->edif.app_sess_online = 0;
++                      fcport->edif.app_started = 1;
++
++                      if (fcport->scan_state != QLA_FCPORT_FOUND)
++                              continue;
++
++                      if (fcport->port_type == FCT_UNKNOWN &&
++                          !fcport->fc4_features)
++                              rval = qla24xx_async_gffid(vha, fcport, true);
++
++                      if (!rval && !(fcport->fc4_features & FC4_FF_TARGET ||
++                          fcport->port_type & (FCT_TARGET|FCT_NVME_TARGET)))
++                              continue;
++
++                      rval = 0;
+                       ql_dbg(ql_dbg_edif, vha, 0x911e,
+                              "%s wwpn %8phC calling qla_edif_reset_auth_wait\n",
+                              __func__, fcport->port_name);
+-                      fcport->edif.app_sess_online = 0;
+                       qlt_schedule_sess_for_deletion(fcport);
+                       qla_edif_sa_ctl_init(vha, fcport);
+               }
+@@ -884,6 +896,20 @@ qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+                       app_reply->ports[pcnt].rekey_count =
+                               fcport->edif.rekey_cnt;
++                      if (fcport->scan_state != QLA_FCPORT_FOUND)
++                              continue;
++
++                      if (fcport->port_type == FCT_UNKNOWN && !fcport->fc4_features)
++                              rval = qla24xx_async_gffid(vha, fcport, true);
++
++                      if (!rval &&
++                          !(fcport->fc4_features & FC4_FF_TARGET ||
++                            fcport->port_type &
++                            (FCT_TARGET | FCT_NVME_TARGET)))
++                              continue;
++
++                      rval = 0;
++
+                       app_reply->ports[pcnt].remote_type =
+                               VND_CMD_RTYPE_UNKNOWN;
+                       if (fcport->port_type & (FCT_NVME_TARGET | FCT_TARGET))
+diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
+index 83912787fa2e..2f6afdbd2dfa 100644
+--- a/drivers/scsi/qla2xxx/qla_gbl.h
++++ b/drivers/scsi/qla2xxx/qla_gbl.h
+@@ -334,6 +334,7 @@ extern int qla24xx_configure_prot_mode(srb_t *, uint16_t *);
+ extern int qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha,
+       struct qla_work_evt *e);
+ void qla2x00_sp_release(struct kref *kref);
++void qla2x00_els_dcmd2_iocb_timeout(void *data);
+ /*
+  * Global Function Prototypes in qla_mbx.c source file.
+@@ -722,7 +723,7 @@ int qla24xx_async_gpsc(scsi_qla_host_t *, fc_port_t *);
+ void qla24xx_handle_gpsc_event(scsi_qla_host_t *, struct event_arg *);
+ int qla2x00_mgmt_svr_login(scsi_qla_host_t *);
+ void qla24xx_handle_gffid_event(scsi_qla_host_t *vha, struct event_arg *ea);
+-int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport);
++int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport, bool);
+ int qla24xx_async_gpnft(scsi_qla_host_t *, u8, srb_t *);
+ void qla24xx_async_gpnft_done(scsi_qla_host_t *, srb_t *);
+ void qla24xx_async_gnnft_done(scsi_qla_host_t *, srb_t *);
+diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
+index c54011510b6a..f89911beaade 100644
+--- a/drivers/scsi/qla2xxx/qla_gs.c
++++ b/drivers/scsi/qla2xxx/qla_gs.c
+@@ -3276,19 +3276,12 @@ int qla24xx_async_gpnid(scsi_qla_host_t *vha, port_id_t *id)
+       return rval;
+ }
+-void qla24xx_handle_gffid_event(scsi_qla_host_t *vha, struct event_arg *ea)
+-{
+-      fc_port_t *fcport = ea->fcport;
+-
+-      qla24xx_post_gnl_work(vha, fcport);
+-}
+ void qla24xx_async_gffid_sp_done(srb_t *sp, int res)
+ {
+       struct scsi_qla_host *vha = sp->vha;
+       fc_port_t *fcport = sp->fcport;
+       struct ct_sns_rsp *ct_rsp;
+-      struct event_arg ea;
+       uint8_t fc4_scsi_feat;
+       uint8_t fc4_nvme_feat;
+@@ -3296,10 +3289,10 @@ void qla24xx_async_gffid_sp_done(srb_t *sp, int res)
+              "Async done-%s res %x ID %x. %8phC\n",
+              sp->name, res, fcport->d_id.b24, fcport->port_name);
+-      fcport->flags &= ~FCF_ASYNC_SENT;
+-      ct_rsp = &fcport->ct_desc.ct_sns->p.rsp;
++      ct_rsp = sp->u.iocb_cmd.u.ctarg.rsp;
+       fc4_scsi_feat = ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET];
+       fc4_nvme_feat = ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET];
++      sp->rc = res;
+       /*
+        * FC-GS-7, 5.2.3.12 FC-4 Features - format
+@@ -3320,24 +3313,42 @@ void qla24xx_async_gffid_sp_done(srb_t *sp, int res)
+               }
+       }
+-      memset(&ea, 0, sizeof(ea));
+-      ea.sp = sp;
+-      ea.fcport = sp->fcport;
+-      ea.rc = res;
++      if (sp->flags & SRB_WAKEUP_ON_COMP) {
++              complete(sp->comp);
++      } else  {
++              if (sp->u.iocb_cmd.u.ctarg.req) {
++                      dma_free_coherent(&vha->hw->pdev->dev,
++                              sp->u.iocb_cmd.u.ctarg.req_allocated_size,
++                              sp->u.iocb_cmd.u.ctarg.req,
++                              sp->u.iocb_cmd.u.ctarg.req_dma);
++                      sp->u.iocb_cmd.u.ctarg.req = NULL;
++              }
+-      qla24xx_handle_gffid_event(vha, &ea);
+-      /* ref: INIT */
+-      kref_put(&sp->cmd_kref, qla2x00_sp_release);
++              if (sp->u.iocb_cmd.u.ctarg.rsp) {
++                      dma_free_coherent(&vha->hw->pdev->dev,
++                              sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
++                              sp->u.iocb_cmd.u.ctarg.rsp,
++                              sp->u.iocb_cmd.u.ctarg.rsp_dma);
++                      sp->u.iocb_cmd.u.ctarg.rsp = NULL;
++              }
++
++              /* ref: INIT */
++              kref_put(&sp->cmd_kref, qla2x00_sp_release);
++              /* we should not be here */
++              dump_stack();
++      }
+ }
+ /* Get FC4 Feature with Nport ID. */
+-int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport)
++int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport, bool wait)
+ {
+       int rval = QLA_FUNCTION_FAILED;
+       struct ct_sns_req       *ct_req;
+       srb_t *sp;
++      DECLARE_COMPLETION_ONSTACK(comp);
+-      if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
++      /* this routine does not have handling for no wait */
++      if (!vha->flags.online || !wait)
+               return rval;
+       /* ref: INIT */
+@@ -3345,43 +3356,86 @@ int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport)
+       if (!sp)
+               return rval;
+-      fcport->flags |= FCF_ASYNC_SENT;
+       sp->type = SRB_CT_PTHRU_CMD;
+       sp->name = "gffid";
+       sp->gen1 = fcport->rscn_gen;
+       sp->gen2 = fcport->login_gen;
+       qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha) + 2,
+                             qla24xx_async_gffid_sp_done);
++      sp->comp = &comp;
++      sp->u.iocb_cmd.timeout = qla2x00_els_dcmd2_iocb_timeout;
++
++      if (wait)
++              sp->flags = SRB_WAKEUP_ON_COMP;
++
++      sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
++      sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev,
++                              sp->u.iocb_cmd.u.ctarg.req_allocated_size,
++                              &sp->u.iocb_cmd.u.ctarg.req_dma,
++          GFP_KERNEL);
++      if (!sp->u.iocb_cmd.u.ctarg.req) {
++              ql_log(ql_log_warn, vha, 0xd041,
++                     "%s: Failed to allocate ct_sns request.\n",
++                     __func__);
++              goto done_free_sp;
++      }
++
++      sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt);
++      sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev,
++                              sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
++                              &sp->u.iocb_cmd.u.ctarg.rsp_dma,
++          GFP_KERNEL);
++      if (!sp->u.iocb_cmd.u.ctarg.req) {
++              ql_log(ql_log_warn, vha, 0xd041,
++                     "%s: Failed to allocate ct_sns request.\n",
++                     __func__);
++              goto done_free_sp;
++      }
+       /* CT_IU preamble  */
+-      ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GFF_ID_CMD,
+-          GFF_ID_RSP_SIZE);
++      ct_req = qla2x00_prep_ct_req(sp->u.iocb_cmd.u.ctarg.req, GFF_ID_CMD, GFF_ID_RSP_SIZE);
+       ct_req->req.gff_id.port_id[0] = fcport->d_id.b.domain;
+       ct_req->req.gff_id.port_id[1] = fcport->d_id.b.area;
+       ct_req->req.gff_id.port_id[2] = fcport->d_id.b.al_pa;
+-      sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns;
+-      sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma;
+-      sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns;
+-      sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma;
+       sp->u.iocb_cmd.u.ctarg.req_size = GFF_ID_REQ_SIZE;
+       sp->u.iocb_cmd.u.ctarg.rsp_size = GFF_ID_RSP_SIZE;
+       sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
+-      ql_dbg(ql_dbg_disc, vha, 0x2132,
+-          "Async-%s hdl=%x  %8phC.\n", sp->name,
+-          sp->handle, fcport->port_name);
+-
+       rval = qla2x00_start_sp(sp);
+-      if (rval != QLA_SUCCESS)
++
++      if (rval != QLA_SUCCESS) {
++              rval = QLA_FUNCTION_FAILED;
+               goto done_free_sp;
++      } else {
++              ql_dbg(ql_dbg_disc, vha, 0x3074,
++                     "Async-%s hdl=%x portid %06x\n",
++                     sp->name, sp->handle, fcport->d_id.b24);
++      }
++
++      wait_for_completion(sp->comp);
++      rval = sp->rc;
+-      return rval;
+ done_free_sp:
++      if (sp->u.iocb_cmd.u.ctarg.req) {
++              dma_free_coherent(&vha->hw->pdev->dev,
++                                sp->u.iocb_cmd.u.ctarg.req_allocated_size,
++                                sp->u.iocb_cmd.u.ctarg.req,
++                                sp->u.iocb_cmd.u.ctarg.req_dma);
++              sp->u.iocb_cmd.u.ctarg.req = NULL;
++      }
++
++      if (sp->u.iocb_cmd.u.ctarg.rsp) {
++              dma_free_coherent(&vha->hw->pdev->dev,
++                                sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
++                                sp->u.iocb_cmd.u.ctarg.rsp,
++                                sp->u.iocb_cmd.u.ctarg.rsp_dma);
++              sp->u.iocb_cmd.u.ctarg.rsp = NULL;
++      }
++
+       /* ref: INIT */
+       kref_put(&sp->cmd_kref, qla2x00_sp_release);
+-      fcport->flags &= ~FCF_ASYNC_SENT;
+       return rval;
+ }
+diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
+index 606228f4a8b5..7ff2d9c84bde 100644
+--- a/drivers/scsi/qla2xxx/qla_iocb.c
++++ b/drivers/scsi/qla2xxx/qla_iocb.c
+@@ -2819,7 +2819,7 @@ qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
+       sp->vha->qla_stats.control_requests++;
+ }
+-static void
++void
+ qla2x00_els_dcmd2_iocb_timeout(void *data)
+ {
+       srb_t *sp = data;
+-- 
+2.35.1
+
diff --git a/queue-5.15/scsi-qla2xxx-edif-send-logo-for-unexpected-ike-messa.patch b/queue-5.15/scsi-qla2xxx-edif-send-logo-for-unexpected-ike-messa.patch
new file mode 100644 (file)
index 0000000..464625a
--- /dev/null
@@ -0,0 +1,79 @@
+From 042768c90aeec252e325176d7ea2514b387e0850 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jun 2022 04:58:41 -0700
+Subject: scsi: qla2xxx: edif: Send LOGO for unexpected IKE message
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit 2b659ed67a12f39f56d8dcad9b5d5a74d67c01b3 ]
+
+If the session is down and the local port continues to receive AUTH ELS
+messages, the driver needs to send back LOGO so that the remote device
+knows to tear down its session. Terminate and clean up the AUTH ELS
+exchange followed by a passthrough LOGO.
+
+Link: https://lore.kernel.org/r/20220608115849.16693-3-njavali@marvell.com
+Fixes: 225479296c4f ("scsi: qla2xxx: edif: Reject AUTH ELS on session down")
+Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_edif.c | 19 +++++++++++++++++--
+ drivers/scsi/qla2xxx/qla_fw.h   |  2 +-
+ 2 files changed, 18 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c
+index 8be282339fdd..69f8d16effa6 100644
+--- a/drivers/scsi/qla2xxx/qla_edif.c
++++ b/drivers/scsi/qla2xxx/qla_edif.c
+@@ -2496,8 +2496,7 @@ void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp)
+       fcport = qla2x00_find_fcport_by_pid(host, &purex->pur_info.pur_sid);
+-      if (DBELL_INACTIVE(vha) ||
+-          (fcport && EDIF_SESSION_DOWN(fcport))) {
++      if (DBELL_INACTIVE(vha)) {
+               ql_dbg(ql_dbg_edif, host, 0x0910c, "%s e_dbell.db_flags =%x %06x\n",
+                   __func__, host->e_dbell.db_flags,
+                   fcport ? fcport->d_id.b24 : 0);
+@@ -2507,6 +2506,22 @@ void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp)
+               return;
+       }
++      if (fcport && EDIF_SESSION_DOWN(fcport)) {
++              ql_dbg(ql_dbg_edif, host, 0x13b6,
++                  "%s terminate exchange. Send logo to 0x%x\n",
++                  __func__, a.did.b24);
++
++              a.tx_byte_count = a.tx_len = 0;
++              a.tx_addr = 0;
++              a.control_flags = EPD_RX_XCHG;  /* EPD_RX_XCHG = terminate cmd */
++              qla_els_reject_iocb(host, (*rsp)->qpair, &a);
++              qla_enode_free(host, ptr);
++              /* send logo to let remote port knows to tear down session */
++              fcport->send_els_logo = 1;
++              qlt_schedule_sess_for_deletion(fcport);
++              return;
++      }
++
+       /* add the local enode to the list */
+       qla_enode_add(host, ptr);
+diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h
+index 073d06e88c58..6faf7533958f 100644
+--- a/drivers/scsi/qla2xxx/qla_fw.h
++++ b/drivers/scsi/qla2xxx/qla_fw.h
+@@ -807,7 +807,7 @@ struct els_entry_24xx {
+ #define EPD_ELS_COMMAND               (0 << 13)
+ #define EPD_ELS_ACC           (1 << 13)
+ #define EPD_ELS_RJT           (2 << 13)
+-#define EPD_RX_XCHG           (3 << 13)
++#define EPD_RX_XCHG           (3 << 13)  /* terminate exchange */
+ #define ECF_CLR_PASSTHRU_PEND BIT_12
+ #define ECF_INCL_FRAME_HDR    BIT_11
+ #define ECF_SEC_LOGIN         BIT_3
+-- 
+2.35.1
+
diff --git a/queue-5.15/scsi-qla2xxx-edif-synchronize-npiv-deletion-with-aut.patch b/queue-5.15/scsi-qla2xxx-edif-synchronize-npiv-deletion-with-aut.patch
new file mode 100644 (file)
index 0000000..8dae33d
--- /dev/null
@@ -0,0 +1,57 @@
+From 11d608982c651c2815c8499a706931cd89437481 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jun 2022 21:46:22 -0700
+Subject: scsi: qla2xxx: edif: Synchronize NPIV deletion with authentication
+ application
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit cf79716e6636400ae38c37bc8a652b1e522abbba ]
+
+Notify authentication application of a NPIV deletion event is about to
+occur. This allows app to perform cleanup.
+
+Link: https://lore.kernel.org/r/20220607044627.19563-7-njavali@marvell.com
+Fixes: 9efea843a906 ("scsi: qla2xxx: edif: Add detection of secure device")
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_edif_bsg.h | 2 ++
+ drivers/scsi/qla2xxx/qla_mid.c      | 6 +++++-
+ 2 files changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_edif_bsg.h b/drivers/scsi/qla2xxx/qla_edif_bsg.h
+index 53026d82ebff..af9f1ffb1e4a 100644
+--- a/drivers/scsi/qla2xxx/qla_edif_bsg.h
++++ b/drivers/scsi/qla2xxx/qla_edif_bsg.h
+@@ -217,4 +217,6 @@ struct auth_complete_cmd {
+ #define RX_DELAY_DELETE_TIMEOUT 20
++#define FCH_EVT_VENDOR_UNIQUE_VPORT_DOWN  1
++
+ #endif        /* QLA_EDIF_BSG_H */
+diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
+index e6b5c4ccce97..eb43a5f1b399 100644
+--- a/drivers/scsi/qla2xxx/qla_mid.c
++++ b/drivers/scsi/qla2xxx/qla_mid.c
+@@ -166,9 +166,13 @@ qla24xx_disable_vp(scsi_qla_host_t *vha)
+       int ret = QLA_SUCCESS;
+       fc_port_t *fcport;
+-      if (vha->hw->flags.edif_enabled)
++      if (vha->hw->flags.edif_enabled) {
++              if (DBELL_ACTIVE(vha))
++                      qla2x00_post_aen_work(vha, FCH_EVT_VENDOR_UNIQUE,
++                          FCH_EVT_VENDOR_UNIQUE_VPORT_DOWN);
+               /* delete sessions and flush sa_indexes */
+               qla2x00_wait_for_sess_deletion(vha);
++      }
+       if (vha->hw->flags.fw_started)
+               ret = qla24xx_control_vp(vha, VCE_COMMAND_DISABLE_VPS_LOGO_ALL);
+-- 
+2.35.1
+
diff --git a/queue-5.15/scsi-qla2xxx-edif-tear-down-session-if-keys-have-bee.patch b/queue-5.15/scsi-qla2xxx-edif-tear-down-session-if-keys-have-bee.patch
new file mode 100644 (file)
index 0000000..8f37565
--- /dev/null
@@ -0,0 +1,54 @@
+From 0b4114c2ea9d8021ef005cb18dc8e5656eee2ad2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jun 2022 04:58:44 -0700
+Subject: scsi: qla2xxx: edif: Tear down session if keys have been removed
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit d7e2e4a68fc047a025afcd200e6b7e1fbc8b1999 ]
+
+If all keys for a session have been deleted, trigger a session teardown.
+
+Link: https://lore.kernel.org/r/20220608115849.16693-6-njavali@marvell.com
+Fixes: dd30706e73b7 ("scsi: qla2xxx: edif: Add key update")
+Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_def.h | 5 +++++
+ drivers/scsi/qla2xxx/qla_isr.c | 1 +
+ 2 files changed, 6 insertions(+)
+
+diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
+index 883b3fb07c2c..4fc289815ccb 100644
+--- a/drivers/scsi/qla2xxx/qla_def.h
++++ b/drivers/scsi/qla2xxx/qla_def.h
+@@ -2158,6 +2158,11 @@ typedef struct {
+ #define CS_IOCB_ERROR         0x31    /* Generic error for IOCB request
+                                          failure */
+ #define CS_REJECT_RECEIVED    0x4E    /* Reject received */
++#define CS_EDIF_AUTH_ERROR    0x63    /* decrypt error */
++#define CS_EDIF_PAD_LEN_ERROR 0x65    /* pad > frame size, not 4byte align */
++#define CS_EDIF_INV_REQ               0x66    /* invalid request */
++#define CS_EDIF_SPI_ERROR     0x67    /* rx frame unable to locate sa */
++#define CS_EDIF_HDR_ERROR     0x69    /* data frame != expected len */
+ #define CS_BAD_PAYLOAD                0x80    /* Driver defined */
+ #define CS_UNKNOWN            0x81    /* Driver defined */
+ #define CS_RETRY              0x82    /* Driver defined */
+diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
+index c3711ab68c3d..c41a965eb4a7 100644
+--- a/drivers/scsi/qla2xxx/qla_isr.c
++++ b/drivers/scsi/qla2xxx/qla_isr.c
+@@ -3420,6 +3420,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
+       case CS_PORT_UNAVAILABLE:
+       case CS_TIMEOUT:
+       case CS_RESET:
++      case CS_EDIF_INV_REQ:
+               /*
+                * We are going to have the fc class block the rport
+-- 
+2.35.1
+
diff --git a/queue-5.15/scsi-smartpqi-fix-dma-direction-for-raid-requests.patch b/queue-5.15/scsi-smartpqi-fix-dma-direction-for-raid-requests.patch
new file mode 100644 (file)
index 0000000..58023d6
--- /dev/null
@@ -0,0 +1,68 @@
+From a069bc8a4ef40a50a8dbb4f2e359794e1458528a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Jul 2022 13:47:36 -0500
+Subject: scsi: smartpqi: Fix DMA direction for RAID requests
+
+From: Mahesh Rajashekhara <Mahesh.Rajashekhara@microchip.com>
+
+[ Upstream commit 69695aeaa6621bc49cdd7a8e5a8d1042461e496e ]
+
+Correct a SOP READ and WRITE DMA flags for some requests.
+
+This update corrects DMA direction issues with SCSI commands removed from
+the controller's internal lookup table.
+
+Currently, SCSI READ BLOCK LIMITS (0x5) was removed from the controller
+lookup table and exposed a DMA direction flag issue.
+
+SCSI READ BLOCK LIMITS was recently removed from our controller lookup
+table so the controller uses the respective IU flag field to set the DMA
+data direction. Since the DMA direction is incorrect the FW never completes
+the request causing a hang.
+
+Some SCSI commands which use SCSI READ BLOCK LIMITS
+
+      * sg_map
+      * mt -f /dev/stX status
+
+After updating controller firmware, users may notice their tape units
+failing. This patch resolves the issue.
+
+Also, the AIO path DMA direction is correct.
+
+The DMA direction flag is a day-one bug with no reported BZ.
+
+Fixes: 6c223761eb54 ("smartpqi: initial commit of Microsemi smartpqi driver")
+Link: https://lore.kernel.org/r/165730605618.177165.9054223644512926624.stgit@brunhilda
+Reviewed-by: Scott Benesh <scott.benesh@microchip.com>
+Reviewed-by: Scott Teel <scott.teel@microchip.com>
+Reviewed-by: Mike McGowen <mike.mcgowen@microchip.com>
+Reviewed-by: Kevin Barnett <kevin.barnett@microchip.com>
+Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@microchip.com>
+Signed-off-by: Don Brace <don.brace@microchip.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/smartpqi/smartpqi_init.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index 2e690d8a3444..e3d8de1159b5 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -5310,10 +5310,10 @@ static int pqi_raid_submit_scsi_cmd_with_io_request(
+       }
+       switch (scmd->sc_data_direction) {
+-      case DMA_TO_DEVICE:
++      case DMA_FROM_DEVICE:
+               request->data_direction = SOP_READ_FLAG;
+               break;
+-      case DMA_FROM_DEVICE:
++      case DMA_TO_DEVICE:
+               request->data_direction = SOP_WRITE_FLAG;
+               break;
+       case DMA_NONE:
+-- 
+2.35.1
+
diff --git a/queue-5.15/selftests-bpf-fix-a-test-for-snprintf-overflow.patch b/queue-5.15/selftests-bpf-fix-a-test-for-snprintf-overflow.patch
new file mode 100644 (file)
index 0000000..57e306d
--- /dev/null
@@ -0,0 +1,39 @@
+From d85b8d8465fe458fe43ecf0906265870f00e33c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 12:50:32 +0300
+Subject: selftests/bpf: fix a test for snprintf() overflow
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit c5d22f4cfe8dfb93f1db0a1e7e2e7ebc41395d98 ]
+
+The snprintf() function returns the number of bytes which *would*
+have been copied if there were space.  In other words, it can be
+> sizeof(pin_path).
+
+Fixes: c0fa1b6c3efc ("bpf: btf: Add BTF tests")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Acked-by: Martin KaFai Lau <kafai@fb.com>
+Link: https://lore.kernel.org/r/YtZ+aD/tZMkgOUw+@kili
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/prog_tests/btf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/btf.c b/tools/testing/selftests/bpf/prog_tests/btf.c
+index 649f87382c8d..50afa75bd45b 100644
+--- a/tools/testing/selftests/bpf/prog_tests/btf.c
++++ b/tools/testing/selftests/bpf/prog_tests/btf.c
+@@ -4913,7 +4913,7 @@ static void do_test_pprint(int test_num)
+       ret = snprintf(pin_path, sizeof(pin_path), "%s/%s",
+                      "/sys/fs/bpf", test->map_name);
+-      if (CHECK(ret == sizeof(pin_path), "pin_path %s/%s is too long",
++      if (CHECK(ret >= sizeof(pin_path), "pin_path %s/%s is too long",
+                 "/sys/fs/bpf", test->map_name)) {
+               err = -1;
+               goto done;
+-- 
+2.35.1
+
diff --git a/queue-5.15/selftests-kvm-set-rax-before-vmcall.patch b/queue-5.15/selftests-kvm-set-rax-before-vmcall.patch
new file mode 100644 (file)
index 0000000..a90f807
--- /dev/null
@@ -0,0 +1,46 @@
+From a93c97d65d120a11f10832a6159a03759bb19779 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Jul 2022 16:02:40 -0700
+Subject: selftests: kvm: set rax before vmcall
+
+From: Andrei Vagin <avagin@google.com>
+
+[ Upstream commit 281106f938d3daaea6f8b6723a8217a2a1ef6936 ]
+
+kvm_hypercall has to place the hypercall number in rax.
+
+Trace events show that kvm_pv_test doesn't work properly:
+     kvm_pv_test-53132: kvm_hypercall: nr 0x0 a0 0x0 a1 0x0 a2 0x0 a3 0x0
+     kvm_pv_test-53132: kvm_hypercall: nr 0x0 a0 0x0 a1 0x0 a2 0x0 a3 0x0
+     kvm_pv_test-53132: kvm_hypercall: nr 0x0 a0 0x0 a1 0x0 a2 0x0 a3 0x0
+
+With this change, it starts working as expected:
+     kvm_pv_test-54285: kvm_hypercall: nr 0x5 a0 0x0 a1 0x0 a2 0x0 a3 0x0
+     kvm_pv_test-54285: kvm_hypercall: nr 0xa a0 0x0 a1 0x0 a2 0x0 a3 0x0
+     kvm_pv_test-54285: kvm_hypercall: nr 0xb a0 0x0 a1 0x0 a2 0x0 a3 0x0
+
+Signed-off-by: Andrei Vagin <avagin@google.com>
+Message-Id: <20220722230241.1944655-5-avagin@google.com>
+Fixes: ac4a4d6de22e ("selftests: kvm: test enforcement of paravirtual cpuid features")
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/kvm/lib/x86_64/processor.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c b/tools/testing/selftests/kvm/lib/x86_64/processor.c
+index 46057079d8bb..4f1449fa9592 100644
+--- a/tools/testing/selftests/kvm/lib/x86_64/processor.c
++++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c
+@@ -1326,7 +1326,7 @@ uint64_t kvm_hypercall(uint64_t nr, uint64_t a0, uint64_t a1, uint64_t a2,
+       asm volatile("vmcall"
+                    : "=a"(r)
+-                   : "b"(a0), "c"(a1), "d"(a2), "S"(a3));
++                   : "a"(nr), "b"(a0), "c"(a1), "d"(a2), "S"(a3));
+       return r;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/selftests-livepatch-better-synchronize-test_klp_call.patch b/queue-5.15/selftests-livepatch-better-synchronize-test_klp_call.patch
new file mode 100644 (file)
index 0000000..35b2712
--- /dev/null
@@ -0,0 +1,79 @@
+From 790f872c78baa910b2c4212c55e837ec2ddfedf2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jun 2022 16:32:33 -0400
+Subject: selftests/livepatch: better synchronize test_klp_callbacks_busy
+
+From: Joe Lawrence <joe.lawrence@redhat.com>
+
+[ Upstream commit 55eb9a6c8bf3e2099863118ef53e02d9f44f85a8 ]
+
+The test_klp_callbacks_busy module conditionally blocks a future
+livepatch transition by busy waiting inside its workqueue function,
+busymod_work_func().  After scheduling this work, a test livepatch is
+loaded, introducing the transition under test.
+
+Both events are marked in the kernel log for later verification, but
+there is no synchronization to ensure that busymod_work_func() logs its
+function entry message before subsequent selftest commands log their own
+messages.  This can lead to a rare test failure due to unexpected
+ordering like:
+
+  --- expected
+  +++ result
+  @@ -1,7 +1,7 @@
+   % modprobe test_klp_callbacks_busy block_transition=Y
+   test_klp_callbacks_busy: test_klp_callbacks_busy_init
+  -test_klp_callbacks_busy: busymod_work_func enter
+   % modprobe test_klp_callbacks_demo
+  +test_klp_callbacks_busy: busymod_work_func enter
+   livepatch: enabling patch 'test_klp_callbacks_demo'
+   livepatch: 'test_klp_callbacks_demo': initializing patching transition
+   test_klp_callbacks_demo: pre_patch_callback: vmlinux
+
+Force the module init function to wait until busymod_work_func() has
+started (and logged its message), before exiting to the next selftest
+steps.
+
+Fixes: 547840bd5ae5 ("selftests/livepatch: simplify test-klp-callbacks busy target tests")
+Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
+Reviewed-by: Petr Mladek <pmladek@suse.com>
+Signed-off-by: Petr Mladek <pmladek@suse.com>
+Link: https://lore.kernel.org/r/20220602203233.979681-1-joe.lawrence@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/livepatch/test_klp_callbacks_busy.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/lib/livepatch/test_klp_callbacks_busy.c b/lib/livepatch/test_klp_callbacks_busy.c
+index 7ac845f65be5..133929e0ce8f 100644
+--- a/lib/livepatch/test_klp_callbacks_busy.c
++++ b/lib/livepatch/test_klp_callbacks_busy.c
+@@ -16,10 +16,12 @@ MODULE_PARM_DESC(block_transition, "block_transition (default=false)");
+ static void busymod_work_func(struct work_struct *work);
+ static DECLARE_WORK(work, busymod_work_func);
++static DECLARE_COMPLETION(busymod_work_started);
+ static void busymod_work_func(struct work_struct *work)
+ {
+       pr_info("%s enter\n", __func__);
++      complete(&busymod_work_started);
+       while (READ_ONCE(block_transition)) {
+               /*
+@@ -37,6 +39,12 @@ static int test_klp_callbacks_busy_init(void)
+       pr_info("%s\n", __func__);
+       schedule_work(&work);
++      /*
++       * To synchronize kernel messages, hold the init function from
++       * exiting until the work function's entry message has printed.
++       */
++      wait_for_completion(&busymod_work_started);
++
+       if (!block_transition) {
+               /*
+                * Serialize output: print all messages from the work
+-- 
+2.35.1
+
diff --git a/queue-5.15/selftests-seccomp-fix-compile-warning-when-cc-clang.patch b/queue-5.15/selftests-seccomp-fix-compile-warning-when-cc-clang.patch
new file mode 100644 (file)
index 0000000..14c0436
--- /dev/null
@@ -0,0 +1,47 @@
+From 2af6e2cb3f8ac2518b8122f2781d8e52fbc50105 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 May 2022 22:34:07 +0000
+Subject: selftests/seccomp: Fix compile warning when CC=clang
+
+From: YiFei Zhu <zhuyifei@google.com>
+
+[ Upstream commit 3ce4b78f73e8e00fb86bad67ee7f6fe12019707e ]
+
+clang has -Wconstant-conversion by default, and the constant 0xAAAAAAAAA
+(9 As) being converted to an int, which is generally 32 bits, results
+in the compile warning:
+
+  clang -Wl,-no-as-needed -Wall -isystem ../../../../usr/include/  -lpthread  seccomp_bpf.c -lcap -o seccomp_bpf
+  seccomp_bpf.c:812:67: warning: implicit conversion from 'long' to 'int' changes value from 45812984490 to -1431655766 [-Wconstant-conversion]
+          int kill = kill_how == KILL_PROCESS ? SECCOMP_RET_KILL_PROCESS : 0xAAAAAAAAA;
+              ~~~~                                                         ^~~~~~~~~~~
+  1 warning generated.
+
+-1431655766 is the expected truncation, 0xAAAAAAAA (8 As), so use
+this directly in the code to avoid the warning.
+
+Fixes: 3932fcecd962 ("selftests/seccomp: Add test for unknown SECCOMP_RET kill behavior")
+Signed-off-by: YiFei Zhu <zhuyifei@google.com>
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Link: https://lore.kernel.org/r/20220526223407.1686936-1-zhuyifei@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/seccomp/seccomp_bpf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c
+index 34ebd1fe5eed..ac340a9c0918 100644
+--- a/tools/testing/selftests/seccomp/seccomp_bpf.c
++++ b/tools/testing/selftests/seccomp/seccomp_bpf.c
+@@ -802,7 +802,7 @@ void kill_thread_or_group(struct __test_metadata *_metadata,
+               .len = (unsigned short)ARRAY_SIZE(filter_thread),
+               .filter = filter_thread,
+       };
+-      int kill = kill_how == KILL_PROCESS ? SECCOMP_RET_KILL_PROCESS : 0xAAAAAAAAA;
++      int kill = kill_how == KILL_PROCESS ? SECCOMP_RET_KILL_PROCESS : 0xAAAAAAAA;
+       struct sock_filter filter_process[] = {
+               BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
+                       offsetof(struct seccomp_data, nr)),
+-- 
+2.35.1
+
diff --git a/queue-5.15/selftests-timers-clocksource-switch-fix-passing-erro.patch b/queue-5.15/selftests-timers-clocksource-switch-fix-passing-erro.patch
new file mode 100644 (file)
index 0000000..f295d96
--- /dev/null
@@ -0,0 +1,43 @@
+From 6e819ec7eb8f0f7dddebf6818f2fa9842560b076 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 22:46:17 +0200
+Subject: selftests: timers: clocksource-switch: fix passing errors from child
+
+From: Wolfram Sang <wsa+renesas@sang-engineering.com>
+
+[ Upstream commit 4d8f52ac5fa9eede7b7aa2f2d67c841d9eeb655f ]
+
+The return value from system() is a waitpid-style integer. Do not return
+it directly because with the implicit masking in exit() it will always
+return 0. Access it with appropriate macros to really pass on errors.
+
+Fixes: 7290ce1423c3 ("selftests/timers: Add clocksource-switch test from timetest suite")
+Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Acked-by: John Stultz <jstultz@google.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/timers/clocksource-switch.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/tools/testing/selftests/timers/clocksource-switch.c b/tools/testing/selftests/timers/clocksource-switch.c
+index ef8eb3604595..b57f0a9be490 100644
+--- a/tools/testing/selftests/timers/clocksource-switch.c
++++ b/tools/testing/selftests/timers/clocksource-switch.c
+@@ -110,10 +110,10 @@ int run_tests(int secs)
+       sprintf(buf, "./inconsistency-check -t %i", secs);
+       ret = system(buf);
+-      if (ret)
+-              return ret;
++      if (WIFEXITED(ret) && WEXITSTATUS(ret))
++              return WEXITSTATUS(ret);
+       ret = system("./nanosleep");
+-      return ret;
++      return WIFEXITED(ret) ? WEXITSTATUS(ret) : 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/selftests-timers-valid-adjtimex-build-fix-for-newer-.patch b/queue-5.15/selftests-timers-valid-adjtimex-build-fix-for-newer-.patch
new file mode 100644 (file)
index 0000000..87deaa3
--- /dev/null
@@ -0,0 +1,42 @@
+From 0d4e33e542925a6b0f352186d8b1e31b2b9b40f0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 22:46:13 +0200
+Subject: selftests: timers: valid-adjtimex: build fix for newer toolchains
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Wolfram Sang <wsa+renesas@sang-engineering.com>
+
+[ Upstream commit 9a162977d20436be5678a8e21a8e58eb4616d86a ]
+
+Toolchains with an include file 'sys/timex.h' based on 3.18 will have a
+'clock_adjtime' definition added, so it can't be static in the code:
+
+valid-adjtimex.c:43:12: error: static declaration of ‘clock_adjtime’ follows non-static declaration
+
+Fixes: e03a58c320e1 ("kselftests: timers: Add adjtimex SETOFFSET validity tests")
+Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Acked-by: John Stultz <jstultz@google.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/timers/valid-adjtimex.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/timers/valid-adjtimex.c b/tools/testing/selftests/timers/valid-adjtimex.c
+index 5397de708d3c..48b9a803235a 100644
+--- a/tools/testing/selftests/timers/valid-adjtimex.c
++++ b/tools/testing/selftests/timers/valid-adjtimex.c
+@@ -40,7 +40,7 @@
+ #define ADJ_SETOFFSET 0x0100
+ #include <sys/syscall.h>
+-static int clock_adjtime(clockid_t id, struct timex *tx)
++int clock_adjtime(clockid_t id, struct timex *tx)
+ {
+       return syscall(__NR_clock_adjtime, id, tx);
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/selftests-xsk-destroy-bpf-resources-only-when-ctx-re.patch b/queue-5.15/selftests-xsk-destroy-bpf-resources-only-when-ctx-re.patch
new file mode 100644 (file)
index 0000000..81a6fcd
--- /dev/null
@@ -0,0 +1,77 @@
+From 642355de93a210eef7d4dd52a816572cf7ff05e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Jun 2022 16:34:58 +0200
+Subject: selftests/xsk: Destroy BPF resources only when ctx refcount drops to
+ 0
+
+From: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
+
+[ Upstream commit 39e940d4abfabb08b6937a315546b24d10be67e3 ]
+
+Currently, xsk_socket__delete frees BPF resources regardless of ctx
+refcount. Xdpxceiver has a test to verify whether underlying BPF
+resources would not be wiped out after closing XSK socket that was
+bound to interface with other active sockets. From library's xsk part
+perspective it also means that the internal xsk context is shared and
+its refcount is bumped accordingly.
+
+After a switch to loading XDP prog based on previously opened XSK
+socket, mentioned xdpxceiver test fails with:
+
+  not ok 16 [xdpxceiver.c:swap_xsk_resources:1334]: ERROR: 9/"Bad file descriptor
+
+which means that in swap_xsk_resources(), xsk_socket__delete() released
+xskmap which in turn caused a failure of xsk_socket__update_xskmap().
+
+To fix this, when deleting socket, decrement ctx refcount before
+releasing BPF resources and do so only when refcount dropped to 0 which
+means there are no more active sockets for this ctx so BPF resources can
+be freed safely.
+
+Fixes: 2f6324a3937f ("libbpf: Support shared umems between queues and devices")
+Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Magnus Karlsson <magnus.karlsson@intel.com>
+Link: https://lore.kernel.org/bpf/20220629143458.934337-5-maciej.fijalkowski@intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/xsk.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/tools/lib/bpf/xsk.c b/tools/lib/bpf/xsk.c
+index a27b3141463a..42b8437b0535 100644
+--- a/tools/lib/bpf/xsk.c
++++ b/tools/lib/bpf/xsk.c
+@@ -1164,8 +1164,6 @@ int xsk_socket__create_shared(struct xsk_socket **xsk_ptr,
+               goto out_mmap_tx;
+       }
+-      ctx->prog_fd = -1;
+-
+       if (!(xsk->config.libbpf_flags & XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD)) {
+               err = __xsk_setup_xdp_prog(xsk, NULL);
+               if (err)
+@@ -1246,7 +1244,10 @@ void xsk_socket__delete(struct xsk_socket *xsk)
+       ctx = xsk->ctx;
+       umem = ctx->umem;
+-      if (ctx->prog_fd != -1) {
++
++      xsk_put_ctx(ctx, true);
++
++      if (!ctx->refcount) {
+               xsk_delete_bpf_maps(xsk);
+               close(ctx->prog_fd);
+               if (ctx->has_bpf_link)
+@@ -1265,8 +1266,6 @@ void xsk_socket__delete(struct xsk_socket *xsk)
+               }
+       }
+-      xsk_put_ctx(ctx, true);
+-
+       umem->refcount--;
+       /* Do not close an fd that also has an associated umem connected
+        * to it.
+-- 
+2.35.1
+
diff --git a/queue-5.15/selinux-add-boundary-check-in-put_entry.patch b/queue-5.15/selinux-add-boundary-check-in-put_entry.patch
new file mode 100644 (file)
index 0000000..203d791
--- /dev/null
@@ -0,0 +1,35 @@
+From 9ca03932f3ade5f41f017220efaf8ad27bf7ba34 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jun 2022 10:14:49 +0800
+Subject: selinux: Add boundary check in put_entry()
+
+From: Xiu Jianfeng <xiujianfeng@huawei.com>
+
+[ Upstream commit 15ec76fb29be31df2bccb30fc09875274cba2776 ]
+
+Just like next_entry(), boundary check is necessary to prevent memory
+out-of-bound access.
+
+Signed-off-by: Xiu Jianfeng <xiujianfeng@huawei.com>
+Signed-off-by: Paul Moore <paul@paul-moore.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/selinux/ss/policydb.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
+index c24d4e1063ea..ffc4e7bad205 100644
+--- a/security/selinux/ss/policydb.h
++++ b/security/selinux/ss/policydb.h
+@@ -370,6 +370,8 @@ static inline int put_entry(const void *buf, size_t bytes, int num, struct polic
+ {
+       size_t len = bytes * num;
++      if (len > fp->len)
++              return -EINVAL;
+       memcpy(fp->data, buf, len);
+       fp->data += len;
+       fp->len -= len;
+-- 
+2.35.1
+
diff --git a/queue-5.15/selinux-fix-memleak-in-security_read_state_kernel.patch b/queue-5.15/selinux-fix-memleak-in-security_read_state_kernel.patch
new file mode 100644 (file)
index 0000000..1e06e7e
--- /dev/null
@@ -0,0 +1,49 @@
+From d718a047a48748b8a0b0e0878d0d1e1511384e58 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 21:59:53 +0800
+Subject: selinux: fix memleak in security_read_state_kernel()
+
+From: Xiu Jianfeng <xiujianfeng@huawei.com>
+
+[ Upstream commit 73de1befcc53a7c68b0c5e76b9b5ac41c517760f ]
+
+In this function, it directly returns the result of __security_read_policy
+without freeing the allocated memory in *data, cause memory leak issue,
+so free the memory if __security_read_policy failed.
+
+Signed-off-by: Xiu Jianfeng <xiujianfeng@huawei.com>
+[PM: subject line tweak]
+Signed-off-by: Paul Moore <paul@paul-moore.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/selinux/ss/services.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
+index c4931bf6f92a..e8035e4876df 100644
+--- a/security/selinux/ss/services.c
++++ b/security/selinux/ss/services.c
+@@ -4045,6 +4045,7 @@ int security_read_policy(struct selinux_state *state,
+ int security_read_state_kernel(struct selinux_state *state,
+                              void **data, size_t *len)
+ {
++      int err;
+       struct selinux_policy *policy;
+       policy = rcu_dereference_protected(
+@@ -4057,5 +4058,11 @@ int security_read_state_kernel(struct selinux_state *state,
+       if (!*data)
+               return -ENOMEM;
+-      return __security_read_policy(policy, *data, len);
++      err = __security_read_policy(policy, *data, len);
++      if (err) {
++              vfree(*data);
++              *data = NULL;
++              *len = 0;
++      }
++      return err;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/serial-8250-dma-allow-driver-operations-before-start.patch b/queue-5.15/serial-8250-dma-allow-driver-operations-before-start.patch
new file mode 100644 (file)
index 0000000..8bc0c1c
--- /dev/null
@@ -0,0 +1,88 @@
+From 27b5197938cdc7001ce8ab3adff14c3a76c6b403 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Apr 2022 20:06:11 +0200
+Subject: serial: 8250: dma: Allow driver operations before starting DMA
+ transfers
+
+From: Miquel Raynal <miquel.raynal@bootlin.com>
+
+[ Upstream commit e4fb03fe10c5e7a5d9aef7cefe815253274fb9ee ]
+
+One situation where this could be used is when configuring the UART
+controller to be the DMA flow controller. This is a typical case where
+the driver might need to program a few more registers before starting a
+DMA transfer. Provide the necessary infrastructure to support this
+case.
+
+Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/r/20220422180615.9098-6-miquel.raynal@bootlin.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/8250/8250.h     | 18 ++++++++++++++++++
+ drivers/tty/serial/8250/8250_dma.c |  4 ++++
+ 2 files changed, 22 insertions(+)
+
+diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
+index 0efe4df24622..b3abc29aa927 100644
+--- a/drivers/tty/serial/8250/8250.h
++++ b/drivers/tty/serial/8250/8250.h
+@@ -17,6 +17,8 @@
+ struct uart_8250_dma {
+       int (*tx_dma)(struct uart_8250_port *p);
+       int (*rx_dma)(struct uart_8250_port *p);
++      void (*prepare_tx_dma)(struct uart_8250_port *p);
++      void (*prepare_rx_dma)(struct uart_8250_port *p);
+       /* Filter function */
+       dma_filter_fn           fn;
+@@ -331,6 +333,22 @@ extern int serial8250_rx_dma(struct uart_8250_port *);
+ extern void serial8250_rx_dma_flush(struct uart_8250_port *);
+ extern int serial8250_request_dma(struct uart_8250_port *);
+ extern void serial8250_release_dma(struct uart_8250_port *);
++
++static inline void serial8250_do_prepare_tx_dma(struct uart_8250_port *p)
++{
++      struct uart_8250_dma *dma = p->dma;
++
++      if (dma->prepare_tx_dma)
++              dma->prepare_tx_dma(p);
++}
++
++static inline void serial8250_do_prepare_rx_dma(struct uart_8250_port *p)
++{
++      struct uart_8250_dma *dma = p->dma;
++
++      if (dma->prepare_rx_dma)
++              dma->prepare_rx_dma(p);
++}
+ #else
+ static inline int serial8250_tx_dma(struct uart_8250_port *p)
+ {
+diff --git a/drivers/tty/serial/8250/8250_dma.c b/drivers/tty/serial/8250/8250_dma.c
+index b3c3f7e5851a..1bdc8d6432fe 100644
+--- a/drivers/tty/serial/8250/8250_dma.c
++++ b/drivers/tty/serial/8250/8250_dma.c
+@@ -86,6 +86,8 @@ int serial8250_tx_dma(struct uart_8250_port *p)
+       dma->tx_size = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
++      serial8250_do_prepare_tx_dma(p);
++
+       desc = dmaengine_prep_slave_single(dma->txchan,
+                                          dma->tx_addr + xmit->tail,
+                                          dma->tx_size, DMA_MEM_TO_DEV,
+@@ -123,6 +125,8 @@ int serial8250_rx_dma(struct uart_8250_port *p)
+       if (dma->rx_running)
+               return 0;
++      serial8250_do_prepare_rx_dma(p);
++
+       desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr,
+                                          dma->rx_size, DMA_DEV_TO_MEM,
+                                          DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+-- 
+2.35.1
+
diff --git a/queue-5.15/serial-8250-export-icr-access-helpers-for-internal-u.patch b/queue-5.15/serial-8250-export-icr-access-helpers-for-internal-u.patch
new file mode 100644 (file)
index 0000000..8d46112
--- /dev/null
@@ -0,0 +1,110 @@
+From 886dac69b623a145e74b6da886b4eab25a30cbf1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Apr 2022 16:27:27 +0100
+Subject: serial: 8250: Export ICR access helpers for internal use
+
+From: Maciej W. Rozycki <macro@orcam.me.uk>
+
+[ Upstream commit cb5a40e3143bc64437858b337273fd63cc42e9c2 ]
+
+Make ICR access helpers available outside 8250_port.c, however retain
+them as ordinary static functions so as not to regress code generation.
+
+This is because `serial_icr_write' is currently automatically inlined by
+GCC, however `serial_icr_read' is not.  Making them both static inline
+would grow code produced, e.g.:
+
+$ i386-linux-gnu-size --format=gnu 8250_port-{old,new}.o
+      text       data        bss      total filename
+     15065       3378          0      18443 8250_port-old.o
+     15289       3378          0      18667 8250_port-new.o
+
+and:
+
+$ riscv64-linux-gnu-size --format=gnu 8250_port-{old,new}.o
+      text       data        bss      total filename
+     16980       5306          0      22286 8250_port-old.o
+     17124       5306          0      22430 8250_port-new.o
+
+while making them external would needlessly add a new module interface
+and lose the benefit from `serial_icr_write' getting inlined outside
+8250_port.o.
+
+Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/alpine.DEB.2.21.2204181517500.9383@angie.orcam.me.uk
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/8250/8250.h      | 22 ++++++++++++++++++++++
+ drivers/tty/serial/8250/8250_port.c | 21 ---------------------
+ 2 files changed, 22 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
+index 6473361525d1..0efe4df24622 100644
+--- a/drivers/tty/serial/8250/8250.h
++++ b/drivers/tty/serial/8250/8250.h
+@@ -120,6 +120,28 @@ static inline void serial_out(struct uart_8250_port *up, int offset, int value)
+       up->port.serial_out(&up->port, offset, value);
+ }
++/*
++ * For the 16C950
++ */
++static void serial_icr_write(struct uart_8250_port *up, int offset, int value)
++{
++      serial_out(up, UART_SCR, offset);
++      serial_out(up, UART_ICR, value);
++}
++
++static unsigned int __maybe_unused serial_icr_read(struct uart_8250_port *up,
++                                                 int offset)
++{
++      unsigned int value;
++
++      serial_icr_write(up, UART_ACR, up->acr | UART_ACR_ICRRD);
++      serial_out(up, UART_SCR, offset);
++      value = serial_in(up, UART_ICR);
++      serial_icr_write(up, UART_ACR, up->acr);
++
++      return value;
++}
++
+ void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p);
+ static inline int serial_dl_read(struct uart_8250_port *up)
+diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
+index 4f66825abe67..a5496bd1b650 100644
+--- a/drivers/tty/serial/8250/8250_port.c
++++ b/drivers/tty/serial/8250/8250_port.c
+@@ -537,27 +537,6 @@ serial_port_out_sync(struct uart_port *p, int offset, int value)
+       }
+ }
+-/*
+- * For the 16C950
+- */
+-static void serial_icr_write(struct uart_8250_port *up, int offset, int value)
+-{
+-      serial_out(up, UART_SCR, offset);
+-      serial_out(up, UART_ICR, value);
+-}
+-
+-static unsigned int serial_icr_read(struct uart_8250_port *up, int offset)
+-{
+-      unsigned int value;
+-
+-      serial_icr_write(up, UART_ACR, up->acr | UART_ACR_ICRRD);
+-      serial_out(up, UART_SCR, offset);
+-      value = serial_in(up, UART_ICR);
+-      serial_icr_write(up, UART_ACR, up->acr);
+-
+-      return value;
+-}
+-
+ /*
+  * FIFO support.
+  */
+-- 
+2.35.1
+
diff --git a/queue-5.15/serial-8250_bcm7271-save-restore-rts-in-suspend-resu.patch b/queue-5.15/serial-8250_bcm7271-save-restore-rts-in-suspend-resu.patch
new file mode 100644 (file)
index 0000000..ee40124
--- /dev/null
@@ -0,0 +1,80 @@
+From 414d1541452bdc54a0219f222f2058d49fc2e9b8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 20:13:15 -0700
+Subject: serial: 8250_bcm7271: Save/restore RTS in suspend/resume
+
+From: Doug Berger <opendmb@gmail.com>
+
+[ Upstream commit 3182efd036c1b955403d131258234896cbd9fbeb ]
+
+Commit 9cabe26e65a8 ("serial: 8250_bcm7271: UART errors after resuming
+from S2") prevented an early enabling of RTS during resume, but it did
+not actively restore the RTS state after resume.
+
+Fixes: 9cabe26e65a8 ("serial: 8250_bcm7271: UART errors after resuming from S2")
+Signed-off-by: Doug Berger <opendmb@gmail.com>
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Link: https://lore.kernel.org/r/20220714031316.404918-1-f.fainelli@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/8250/8250_bcm7271.c | 24 ++++++++++++++++++------
+ 1 file changed, 18 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/tty/serial/8250/8250_bcm7271.c b/drivers/tty/serial/8250/8250_bcm7271.c
+index 0877cf24f7de..711cf30e835a 100644
+--- a/drivers/tty/serial/8250/8250_bcm7271.c
++++ b/drivers/tty/serial/8250/8250_bcm7271.c
+@@ -1141,16 +1141,19 @@ static int __maybe_unused brcmuart_suspend(struct device *dev)
+       struct brcmuart_priv *priv = dev_get_drvdata(dev);
+       struct uart_8250_port *up = serial8250_get_port(priv->line);
+       struct uart_port *port = &up->port;
+-
+-      serial8250_suspend_port(priv->line);
+-      clk_disable_unprepare(priv->baud_mux_clk);
++      unsigned long flags;
+       /*
+        * This will prevent resume from enabling RTS before the
+-       *  baud rate has been resored.
++       *  baud rate has been restored.
+        */
++      spin_lock_irqsave(&port->lock, flags);
+       priv->saved_mctrl = port->mctrl;
+-      port->mctrl = 0;
++      port->mctrl &= ~TIOCM_RTS;
++      spin_unlock_irqrestore(&port->lock, flags);
++
++      serial8250_suspend_port(priv->line);
++      clk_disable_unprepare(priv->baud_mux_clk);
+       return 0;
+ }
+@@ -1160,6 +1163,7 @@ static int __maybe_unused brcmuart_resume(struct device *dev)
+       struct brcmuart_priv *priv = dev_get_drvdata(dev);
+       struct uart_8250_port *up = serial8250_get_port(priv->line);
+       struct uart_port *port = &up->port;
++      unsigned long flags;
+       int ret;
+       ret = clk_prepare_enable(priv->baud_mux_clk);
+@@ -1182,7 +1186,15 @@ static int __maybe_unused brcmuart_resume(struct device *dev)
+               start_rx_dma(serial8250_get_port(priv->line));
+       }
+       serial8250_resume_port(priv->line);
+-      port->mctrl = priv->saved_mctrl;
++
++      if (priv->saved_mctrl & TIOCM_RTS) {
++              /* Restore RTS */
++              spin_lock_irqsave(&port->lock, flags);
++              port->mctrl |= TIOCM_RTS;
++              port->ops->set_mctrl(port, port->mctrl);
++              spin_unlock_irqrestore(&port->lock, flags);
++      }
++
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/serial-8250_dw-store-lsr-into-lsr_saved_flags-in-dw8.patch b/queue-5.15/serial-8250_dw-store-lsr-into-lsr_saved_flags-in-dw8.patch
new file mode 100644 (file)
index 0000000..9a3d680
--- /dev/null
@@ -0,0 +1,54 @@
+From c07b345482bac9d1bbe0b7f94aa5dd7e3650bb5b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jun 2022 12:54:31 +0300
+Subject: serial: 8250_dw: Store LSR into lsr_saved_flags in
+ dw8250_tx_wait_empty()
+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 af14f3007e2dca0d112f10f6717ba43093f74e81 ]
+
+Make sure LSR flags are preserved in dw8250_tx_wait_empty(). This
+function is called from a low-level out function and therefore cannot
+call serial_lsr_in() as it would lead to infinite recursion.
+
+It is borderline if the flags need to be saved here at all since this
+code relates to writing LCR register which usually implies no important
+characters should be arriving.
+
+Fixes: 914eaf935ec7 ("serial: 8250_dw: Allow TX FIFO to drain before writing to UART_LCR")
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Link: https://lore.kernel.org/r/20220608095431.18376-7-ilpo.jarvinen@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/8250/8250_dw.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
+index 49559731bbcf..ace221afeb03 100644
+--- a/drivers/tty/serial/8250/8250_dw.c
++++ b/drivers/tty/serial/8250/8250_dw.c
+@@ -124,12 +124,15 @@ static void dw8250_check_lcr(struct uart_port *p, int value)
+ /* Returns once the transmitter is empty or we run out of retries */
+ static void dw8250_tx_wait_empty(struct uart_port *p)
+ {
++      struct uart_8250_port *up = up_to_u8250p(p);
+       unsigned int tries = 20000;
+       unsigned int delay_threshold = tries - 1000;
+       unsigned int lsr;
+       while (tries--) {
+               lsr = readb (p->membase + (UART_LSR << p->regshift));
++              up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
++
+               if (lsr & UART_LSR_TEMT)
+                       break;
+-- 
+2.35.1
+
diff --git a/queue-5.15/serial-8250_fsl-don-t-report-fe-pe-and-oe-twice.patch b/queue-5.15/serial-8250_fsl-don-t-report-fe-pe-and-oe-twice.patch
new file mode 100644 (file)
index 0000000..32d7ce9
--- /dev/null
@@ -0,0 +1,68 @@
+From 0b4f1f3bf51684b3755ce3bb5222a2d330551ff1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Jul 2022 10:51:19 +0200
+Subject: serial: 8250_fsl: Don't report FE, PE and OE twice
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 9d3aaceb73acadf134596a2f8db9c451c1332d3d ]
+
+Some Freescale 8250 implementations have the problem that a single long
+break results in one irq per character frame time. The code in
+fsl8250_handle_irq() that is supposed to handle that uses the BI bit in
+lsr_saved_flags to detect such a situation and then skip the second
+received character. However it also stores other error bits and so after
+a single frame error the character received in the next irq handling is
+passed to the upper layer with a frame error, too.
+
+So after a spike on the data line (which is correctly recognized as a
+frame error) the following valid character is thrown away, because the
+driver reports a frame error for that one, too.
+
+To weaken this problem restrict saving LSR to only the BI bit.
+
+Note however that the handling is still broken:
+
+ - lsr_saved_flags is updated using orig_lsr which is the LSR content
+   for the first received char, but there might be more in the FIFO, so
+   a character is thrown away that is received later and not necessarily
+   the one following the break.
+ - The doubled break might be the 2nd and 3rd char in the FIFO, so the
+   workaround doesn't catch these, because serial8250_rx_chars() doesn't
+   handle the workaround.
+ - lsr_saved_flags might have set UART_LSR_BI at the entry of
+   fsl8250_handle_irq() which doesn't originate from
+   fsl8250_handle_irq()'s "up->lsr_saved_flags |= orig_lsr &
+   UART_LSR_BI;" but from e.g. from serial8250_tx_empty().
+ - For a long or a short break this isn't about two characters, but more
+   or only a single one.
+
+Fixes: 9deaa53ac7fa ("serial: add irq handler for Freescale 16550 errata.")
+Acked-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Link: https://lore.kernel.org/r/20220704085119.55900-1-u.kleine-koenig@pengutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/8250/8250_fsl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/tty/serial/8250/8250_fsl.c b/drivers/tty/serial/8250/8250_fsl.c
+index fc65a2293ce9..af74f82ad782 100644
+--- a/drivers/tty/serial/8250/8250_fsl.c
++++ b/drivers/tty/serial/8250/8250_fsl.c
+@@ -81,7 +81,7 @@ int fsl8250_handle_irq(struct uart_port *port)
+       if ((lsr & UART_LSR_THRE) && (up->ier & UART_IER_THRI))
+               serial8250_tx_chars(up);
+-      up->lsr_saved_flags = orig_lsr;
++      up->lsr_saved_flags |= orig_lsr & UART_LSR_BI;
+       uart_unlock_and_check_sysrq_irqrestore(&up->port, flags);
+-- 
+2.35.1
+
diff --git a/queue-5.15/serial-store-character-timing-information-to-uart_po.patch b/queue-5.15/serial-store-character-timing-information-to-uart_po.patch
new file mode 100644 (file)
index 0000000..165c740
--- /dev/null
@@ -0,0 +1,95 @@
+From f806eacaafd4c9acb429d6421d0ca06dd76e2db8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Apr 2022 17:33:58 +0300
+Subject: serial: Store character timing information to uart_port
+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 31f6bd7fad3b149a1eb6f67fc2e742e4df369b3d ]
+
+Struct uart_port currently stores FIFO timeout. Having character timing
+information readily available is useful. Even serial core itself
+determines char_time from port->timeout using inverse calculation.
+
+Store frame_time directly into uart_port. Character time is stored in
+nanoseconds to have reasonable precision with high rates. To avoid
+overflow, 64-bit math is necessary.
+
+It might be possible to determine timeout from frame_time by
+multiplying it with fifosize as needed but only part of the users seem
+to be protected by a lock. Thus, this patch does not pursue storing
+only frame_time in uart_port.
+
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Link: https://lore.kernel.org/r/20220425143410.12703-2-ilpo.jarvinen@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/serial_core.c | 14 ++++++++------
+ include/linux/serial_core.h      |  1 +
+ 2 files changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
+index 82ddbb92d07d..cdc2f40ccd8b 100644
+--- a/drivers/tty/serial/serial_core.c
++++ b/drivers/tty/serial/serial_core.c
+@@ -24,6 +24,7 @@
+ #include <linux/sysrq.h>
+ #include <linux/delay.h>
+ #include <linux/mutex.h>
++#include <linux/math64.h>
+ #include <linux/security.h>
+ #include <linux/irq.h>
+@@ -333,15 +334,18 @@ void
+ uart_update_timeout(struct uart_port *port, unsigned int cflag,
+                   unsigned int baud)
+ {
+-      unsigned int size;
++      unsigned int size = tty_get_frame_size(cflag);
++      u64 frame_time;
+-      size = tty_get_frame_size(cflag) * port->fifosize;
++      frame_time = (u64)size * NSEC_PER_SEC;
++      size *= port->fifosize;
+       /*
+        * Figure the timeout to send the above number of bits.
+        * Add .02 seconds of slop
+        */
+       port->timeout = (HZ * size) / baud + HZ/50;
++      port->frame_time = DIV64_U64_ROUND_UP(frame_time, baud);
+ }
+ EXPORT_SYMBOL(uart_update_timeout);
+@@ -1614,10 +1618,8 @@ static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
+        * Note: we have to use pretty tight timings here to satisfy
+        * the NIST-PCTS.
+        */
+-      char_time = (port->timeout - HZ/50) / port->fifosize;
+-      char_time = char_time / 5;
+-      if (char_time == 0)
+-              char_time = 1;
++      char_time = max(nsecs_to_jiffies(port->frame_time / 5), 1UL);
++
+       if (timeout && timeout < char_time)
+               char_time = timeout;
+diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
+index 6d07b5f9e3b8..0b38d682d360 100644
+--- a/include/linux/serial_core.h
++++ b/include/linux/serial_core.h
+@@ -232,6 +232,7 @@ struct uart_port {
+       int                     hw_stopped;             /* sw-assisted CTS flow state */
+       unsigned int            mctrl;                  /* current modem ctrl settings */
+       unsigned int            timeout;                /* character-based timeout */
++      unsigned int            frame_time;             /* frame timing in ns */
+       unsigned int            type;                   /* port type */
+       const struct uart_ops   *ops;
+       unsigned int            custom_divisor;
+-- 
+2.35.1
+
index 57e68d97ba4666b21cd2c8bd3a4a74ce6aba3fe2..e9327ca9da2b70983292958bb365d95f60bb3a75 100644 (file)
@@ -108,3 +108,566 @@ netfilter-nf_tables-do-not-allow-chain_id-to-refer-to-another-table.patch
 netfilter-nf_tables-do-not-allow-rule_id-to-refer-to-another-chain.patch
 netfilter-nf_tables-fix-null-deref-due-to-zeroed-list-head.patch
 epoll-autoremove-wakers-even-more-aggressively.patch
+x86-handle-idle-nomwait-cmdline-properly-for-x86_idl.patch
+arch-make-trace_irqflags_nmi_support-generic.patch
+arm64-do-not-forget-syscall-when-starting-a-new-thre.patch
+arm64-fix-oops-in-concurrently-setting-insn_emulatio.patch
+arm64-kasan-revert-arm64-mte-reset-the-page-tag-in-p.patch
+ext2-add-more-validity-checks-for-inode-counts.patch
+sched-fair-introduce-sis_util-to-search-idle-cpu-bas.patch
+genirq-don-t-return-error-on-missing-optional-irq_re.patch
+irqchip-mips-gic-only-register-ipi-domain-when-smp-i.patch
+genirq-generic_irq_ipi-depends-on-smp.patch
+sched-core-always-flush-pending-blk_plug.patch
+irqchip-mips-gic-check-the-return-value-of-ioremap-i.patch
+wait-fix-__wait_event_hrtimeout-for-rt-dl-tasks.patch
+arm-dts-imx6ul-add-missing-properties-for-sram.patch
+arm-dts-imx6ul-change-operating-points-to-uint32-mat.patch
+arm-dts-imx6ul-fix-keypad-compatible.patch
+arm-dts-imx6ul-fix-csi-node-compatible.patch
+arm-dts-imx6ul-fix-lcdif-node-compatible.patch
+arm-dts-imx6ul-fix-qspi-node-compatible.patch
+arm-dts-bcm5301x-add-dt-for-meraki-mr26.patch
+arm-dts-ux500-fix-codina-accelerometer-mounting-matr.patch
+arm-dts-ux500-fix-gavini-accelerometer-mounting-matr.patch
+spi-synquacer-add-missing-clk_disable_unprepare.patch
+arm-omap2-display-fix-refcount-leak-bug.patch
+arm-omap2-pdata-quirks-fix-refcount-leak-bug.patch
+acpi-ec-remove-duplicate-thinkpad-x1-carbon-6th-entr.patch
+acpi-ec-drop-the-ec_flags_ignore_dsdt_gpe-quirk.patch
+acpi-pm-save-nvs-memory-for-lenovo-g40-45.patch
+acpi-lpss-fix-missing-check-in-register_device_clock.patch
+arm-dts-qcom-sdx55-fix-the-irq-trigger-type-for-uart.patch
+arm64-dts-qcom-ipq8074-fix-nand-node-name.patch
+arm64-dts-allwinner-a64-orangepi-win-fix-led-node-na.patch
+arm-shmobile-rcar-gen2-increase-refcount-for-new-ref.patch
+firmware-tegra-fix-error-check-return-value-of-debug.patch
+hwmon-dell-smm-add-dell-xps-13-7390-to-fan-control-w.patch
+hwmon-sht15-fix-wrong-assumptions-in-device-remove-c.patch
+pm-hibernate-defer-device-probing-when-resuming-from.patch
+selinux-fix-memleak-in-security_read_state_kernel.patch
+selinux-add-boundary-check-in-put_entry.patch
+skbuff-don-t-mix-ubuf_info-from-different-sources.patch
+kasan-test-silence-gcc-12-warnings.patch
+drm-amdgpu-remove-one-duplicated-ef-removal.patch
+powerpc-64s-disable-stack-variable-initialisation-fo.patch
+spi-spi-rspi-fix-pio-fallback-on-rz-platforms.patch
+netfilter-nf_tables-add-rescheduling-points-during-l.patch
+arm-findbit-fix-overflowing-offset.patch
+meson-mx-socinfo-fix-refcount-leak-in-meson_mx_socin.patch
+arm64-dts-renesas-beacon-fix-regulator-node-names.patch
+spi-spi-altera-dfl-fix-an-error-handling-path.patch
+arm-bcm-fix-refcount-leak-in-bcm_kona_smc_init.patch
+acpi-processor-idle-annotate-more-functions-to-live-.patch
+arm-dts-imx7d-colibri-emmc-add-cpu1-supply.patch
+soc-renesas-r8a779a0-sysc-fix-a2dp1-and-a2cv-2357-pd.patch
+scsi-hisi_sas-use-managed-pci-functions.patch
+dt-bindings-iio-accel-add-dt-binding-doc-for-adxl355.patch
+soc-amlogic-fix-refcount-leak-in-meson-secure-pwrc.c.patch
+arm64-dts-renesas-fix-thermal-sensors-on-single-zone.patch
+x86-pmem-fix-platform-device-leak-in-error-path.patch
+arm-dts-ast2500-evb-fix-board-compatible.patch
+arm-dts-ast2600-evb-fix-board-compatible.patch
+arm-dts-ast2600-evb-a1-fix-board-compatible.patch
+arm64-dts-mt8192-fix-idle-states-nodes-naming-scheme.patch
+arm64-dts-mt8192-fix-idle-states-entry-method.patch
+arm64-select-trace_irqflags_nmi_support.patch
+arm64-cpufeature-allow-different-pmu-versions-in-id_.patch
+locking-lockdep-fix-lockdep_init_map_-confusion.patch
+arm64-dts-qcom-sc7180-remove-ipa_fw_mem-node-on-trog.patch
+soc-fsl-guts-machine-variable-might-be-unset.patch
+block-fix-infinite-loop-for-invalid-zone-append.patch
+arm-dts-qcom-mdm9615-add-missing-pmic-gpio-reg.patch
+arm-omap2-fix-refcount-leak-in-omapdss_init_of.patch
+arm-omap2-fix-refcount-leak-in-omap3xxx_prm_late_ini.patch
+arm64-dts-qcom-sdm630-disable-gpu-by-default.patch
+arm64-dts-qcom-sdm630-fix-the-qusb2phy-ref-clock.patch
+arm64-dts-qcom-sdm630-fix-gpu-s-interconnect-path.patch
+arm64-dts-qcom-sdm636-sony-xperia-ganges-mermaid-cor.patch
+cpufreq-zynq-fix-refcount-leak-in-zynq_get_revision.patch
+regulator-qcom_smd-fix-pm8916_pldo-range.patch
+acpi-apei-fix-_einj-vs-efi_memory_sp.patch
+arm-dts-qcom-replace-gcc-pxo-with-pxo_board-fixed-cl.patch
+arm-dts-qcom-msm8974-fix-irq-type-on-blsp2_uart1.patch
+soc-qcom-ocmem-fix-refcount-leak-in-of_get_ocmem.patch
+soc-qcom-aoss-fix-refcount-leak-in-qmp_cooling_devic.patch
+arm-dts-qcom-pm8841-add-required-thermal-sensor-cell.patch
+bus-hisi_lpc-fix-missing-platform_device_put-in-hisi.patch
+stack-declare-randomize_-kstack_offset-to-fix-sparse.patch
+arm64-dts-qcom-msm8916-fix-typo-in-pronto-remoteproc.patch
+acpi-apei-explicit-init-of-hest-and-ghes-in-apci_ini.patch
+drivers-iio-remove-all-strcpy-uses.patch
+acpi-viot-fix-acs-setup.patch
+arm64-dts-qcom-sm6125-move-sdc2-pinctrl-from-seine-p.patch
+arm64-dts-qcom-sm6125-append-state-suffix-to-pinctrl.patch
+arm64-dts-qcom-sm8250-add-missing-pcie-phy-clock-cel.patch
+arm64-dts-mt7622-fix-bpi-r64-wps-button.patch
+arm64-tegra-fixup-sysram-references.patch
+arm64-tegra-update-tegra234-bpmp-channel-addresses.patch
+arm64-tegra-mark-bpmp-channels-as-no-memory-wc.patch
+arm64-tegra-fix-sdmmc1-cd-on-p2888.patch
+erofs-avoid-consecutive-detection-for-highmem-memory.patch
+blk-mq-don-t-create-hctx-debugfs-dir-until-q-debugfs.patch
+spi-fix-simplification-of-devm_spi_register_controll.patch
+spi-tegra20-slink-fix-uaf-in-tegra_slink_remove.patch
+hwmon-drivetemp-add-module-alias.patch
+blktrace-trace-remapped-requests-correctly.patch
+pm-domains-ensure-genpd_debugfs_dir-exists-before-re.patch
+dm-writecache-return-void-from-functions.patch
+dm-writecache-count-number-of-blocks-read-not-number.patch
+dm-writecache-count-number-of-blocks-written-not-num.patch
+dm-writecache-count-number-of-blocks-discarded-not-n.patch
+regulator-of-fix-refcount-leak-bug-in-of_get_regulat.patch
+soc-qcom-make-qcom_rpmpd-depend-on-pm.patch
+arm64-dts-qcom-qcs404-fix-incorrect-usb2-phys-assign.patch
+irqdomain-report-irq-number-for-nomap-domains.patch
+drivers-perf-arm_spe-fix-consistency-of-sys_pmscr_el.patch
+nohz-full-sched-rt-fix-missed-tick-reenabling-bug-in.patch
+x86-extable-fix-ex_handler_msr-print-condition.patch
+selftests-seccomp-fix-compile-warning-when-cc-clang.patch
+thermal-tools-tmon-include-pthread-and-time-headers-.patch
+dm-return-early-from-dm_pr_call-if-dm-device-is-susp.patch
+pwm-sifive-simplify-offset-calculation-for-pwmcmp-re.patch
+pwm-sifive-ensure-the-clk-is-enabled-exactly-once-pe.patch
+pwm-sifive-shut-down-hardware-only-after-pwmchip_rem.patch
+pwm-lpc18xx-sct-reduce-number-of-devm-memory-allocat.patch
+pwm-lpc18xx-sct-simplify-driver-by-not-using-pwm_-gs.patch
+pwm-lpc18xx-fix-period-handling.patch
+drm-dp-export-symbol-kerneldoc-fixes-for-dp-aux-bus.patch
+drm-bridge-tc358767-move-e-dp-bridge-endpoint-parsin.patch
+ath10k-do-not-enforce-interrupt-trigger-type.patch
+drm-st7735r-fix-module-autoloading-for-okaya-rh12812.patch
+drm-panel-fix-build-error-when-config_drm_panel_sams.patch
+wifi-rtlwifi-fix-error-codes-in-rtl_debugfs_set_writ.patch
+ath11k-fix-netdev-open-race.patch
+drm-mipi-dbi-align-max_chunk-to-2-in-spi_transfer.patch
+ath11k-fix-incorrect-debug_mask-mappings.patch
+drm-radeon-fix-potential-buffer-overflow-in-ni_set_m.patch
+drm-mediatek-modify-dsi-funcs-to-atomic-operations.patch
+drm-mediatek-separate-poweron-poweroff-from-enable-d.patch
+drm-mediatek-add-pull-down-mipi-operation-in-mtk_dsi.patch
+drm-meson-encoder_hdmi-switch-to-bridge-drm_bridge_a.patch
+drm-meson-encoder_hdmi-fix-refcount-leak-in-meson_en.patch
+drm-bridge-lt9611uxc-cancel-only-driver-s-work.patch
+i2c-npcm-remove-own-slave-addresses-2-10.patch
+i2c-npcm-correct-slave-role-behavior.patch
+i2c-mxs-silence-a-clang-warning.patch
+virtio-gpu-fix-a-missing-check-to-avoid-null-derefer.patch
+drm-shmem-helper-unexport-drm_gem_shmem_create_with_.patch
+drm-shmem-helper-export-dedicated-wrappers-for-gem-o.patch
+drm-shmem-helper-pass-gem-shmem-object-in-public-int.patch
+drm-virtio-fix-null-vs-is_err-checking-in-virtio_gpu.patch
+drm-adv7511-override-i2c-address-of-cec-before-acces.patch
+crypto-sun8i-ss-do-not-allocate-memory-when-handling.patch
+crypto-sun8i-ss-fix-error-codes-in-allocate_flows.patch
+net-fix-sk_wmem_schedule-and-sk_rmem_schedule-errors.patch
+can-netlink-allow-configuring-of-fixed-bit-rates-wit.patch
+can-netlink-allow-configuring-of-fixed-data-bit-rate.patch
+i2c-fix-a-potential-use-after-free.patch
+crypto-sun8i-ss-fix-infinite-loop-in-sun8i_ss_setup_.patch
+media-atmel-atmel-sama7g5-isc-fix-warning-in-configs.patch
+media-tw686x-register-the-irq-at-the-end-of-probe.patch
+media-imx-jpeg-correct-some-definition-according-spe.patch
+media-imx-jpeg-leave-a-blank-space-before-the-config.patch
+media-imx-jpeg-add-pm-runtime-support-for-imx-jpeg.patch
+media-imx-jpeg-use-nv12m-to-represent-non-contiguous.patch
+media-imx-jpeg-set-v4l2_buf_flag_last-at-eos.patch
+media-imx-jpeg-refactor-function-mxc_jpeg_parse.patch
+media-imx-jpeg-identify-and-handle-precision-correct.patch
+media-imx-jpeg-handle-source-change-in-a-function.patch
+media-imx-jpeg-support-dynamic-resolution-change.patch
+media-imx-jpeg-align-upwards-buffer-size.patch
+media-imx-jpeg-implement-drain-using-v4l2-mem2mem-he.patch
+ath9k-fix-use-after-free-in-ath9k_hif_usb_rx_cb.patch
+wifi-iwlegacy-4965-fix-potential-off-by-one-overflow.patch
+drm-radeon-fix-incorrrect-spdx-license-identifiers.patch
+rcutorture-warn-on-individual-rcu_torture_init-error.patch
+rcutorture-don-t-cpuhp_remove_state-if-cpuhp_setup_s.patch
+rcutorture-fix-ksoftirqd-boosting-timing-and-iterati.patch
+test_bpf-fix-incorrect-netdev-features.patch
+crypto-ccp-during-shutdown-check-sev-data-pointer-be.patch
+drm-bridge-adv7511-add-check-for-mipi_dsi_driver_reg.patch
+media-imx-jpeg-disable-slot-interrupt-when-frame-don.patch
+drm-mcde-fix-refcount-leak-in-mcde_dsi_bind.patch
+media-hdpvr-fix-error-value-returns-in-hdpvr_read.patch
+media-v4l2-mem2mem-prevent-pollerr-when-last_buffer_.patch
+media-driver-nxp-imx-jpeg-fix-a-unexpected-return-va.patch
+media-tw686x-fix-memory-leak-in-tw686x_video_init.patch
+drm-vc4-plane-remove-subpixel-positioning-check.patch
+drm-vc4-plane-fix-margin-calculations-for-the-right-.patch
+drm-bridge-add-a-function-to-abstract-away-panels.patch
+drm-vc4-dsi-switch-to-devm_drm_of_get_bridge.patch
+drm-vc4-use-of_device_get_match_data.patch
+drm-vc4-dsi-release-workaround-buffer-and-dma.patch
+drm-vc4-dsi-correct-dsi-divider-calculations.patch
+drm-vc4-dsi-correct-pixel-order-for-dsi0.patch
+drm-vc4-dsi-register-dsi0-as-the-correct-vc4-encoder.patch
+drm-vc4-dsi-fix-dsi0-interrupt-support.patch
+drm-vc4-dsi-add-correct-stop-condition-to-vc4_dsi_en.patch
+drm-vc4-hdmi-fix-hpd-gpio-detection.patch
+drm-vc4-hdmi-avoid-full-hdmi-audio-fifo-writes.patch
+drm-vc4-hdmi-reset-hdmi-misc_control-register.patch
+drm-vc4-hdmi-fix-timings-for-interlaced-modes.patch
+drm-vc4-hdmi-correct-hdmi-timing-registers-for-inter.patch
+crypto-arm64-gcm-select-aead-for-ghash_arm64_ce.patch
+selftests-xsk-destroy-bpf-resources-only-when-ctx-re.patch
+drm-rockchip-vop-don-t-crash-for-invalid-duplicate_s.patch
+drm-rockchip-fix-an-error-handling-path-rockchip_dp_.patch
+drm-mediatek-dpi-remove-output-format-of-yuv.patch
+drm-mediatek-dpi-only-enable-dpi-after-the-bridge-is.patch
+drm-msm-hdmi-enable-core-vcc-core-vdda-supply-for-89.patch
+drm-bridge-sii8620-fix-possible-off-by-one.patch
+hinic-use-the-bitmap-api-when-applicable.patch
+net-hinic-fix-bug-that-ethtool-get-wrong-stats.patch
+net-hinic-avoid-kernel-hung-in-hinic_get_stats64.patch
+drm-msm-mdp5-fix-global-state-lock-backoff.patch
+crypto-hisilicon-sec-don-t-sleep-when-in-softirq.patch
+crypto-hisilicon-kunpeng916-crypto-driver-don-t-slee.patch
+media-platform-mtk-mdp-fix-mdp_ipi_comm-structure-al.patch
+drm-msm-avoid-dirtyfb-stalls-on-video-mode-displays-.patch
+drm-msm-dpu-fix-for-non-visible-planes.patch
+mt76-mt76x02u-fix-possible-memory-leak-in-__mt76x02u.patch
+mt76-mt7615-do-not-update-pm-stats-in-case-of-error.patch
+ieee80211-add-eht-1k-aggregation-definitions.patch
+mt76-mt7921-fix-aggregation-subframes-setting-to-he-.patch
+mt76-mt7921-enlarge-maximum-vht-mpdu-length-to-11454.patch
+mediatek-mt76-mac80211-fix-missing-of_node_put-in-mt.patch
+mediatek-mt76-eeprom-fix-missing-of_node_put-in-mt76.patch
+skmsg-fix-invalid-last-sg-check-in-sk_msg_recvmsg.patch
+drm-exynos-exynos7_drm_decon-free-resources-when-clk.patch
+tcp-make-retransmitted-skb-fit-into-the-send-window.patch
+libbpf-fix-the-name-of-a-reused-map.patch
+selftests-timers-valid-adjtimex-build-fix-for-newer-.patch
+selftests-timers-clocksource-switch-fix-passing-erro.patch
+bpf-fix-subprog-names-in-stack-traces.patch
+fs-check-fmode_lseek-to-control-internal-pipe-splici.patch
+media-cedrus-h265-fix-flag-name.patch
+media-hantro-postproc-fix-motion-vector-space-size.patch
+media-hantro-simplify-postprocessor.patch
+media-hevc-embedded-indexes-in-rps.patch
+media-staging-media-hantro-fix-typos.patch
+wifi-wil6210-debugfs-fix-info-leak-in-wil_write_file.patch
+wifi-p54-fix-an-error-handling-path-in-p54spi_probe.patch
+wifi-p54-add-missing-parentheses-in-p54_flush.patch
+selftests-bpf-fix-a-test-for-snprintf-overflow.patch
+libbpf-fix-an-snprintf-overflow-check.patch
+can-pch_can-do-not-report-txerr-and-rxerr-during-bus.patch
+can-rcar_can-do-not-report-txerr-and-rxerr-during-bu.patch
+can-sja1000-do-not-report-txerr-and-rxerr-during-bus.patch
+can-hi311x-do-not-report-txerr-and-rxerr-during-bus-.patch
+can-sun4i_can-do-not-report-txerr-and-rxerr-during-b.patch
+can-kvaser_usb_hydra-do-not-report-txerr-and-rxerr-d.patch
+can-kvaser_usb_leaf-do-not-report-txerr-and-rxerr-du.patch
+can-usb_8dev-do-not-report-txerr-and-rxerr-during-bu.patch
+can-error-specify-the-values-of-data-5.7-of-can-erro.patch
+can-pch_can-pch_can_error-initialize-errc-before-usi.patch
+bluetooth-hci_intel-add-check-for-platform_driver_re.patch
+i2c-cadence-support-pec-for-smbus-block-read.patch
+i2c-mux-gpmux-add-of_node_put-when-breaking-out-of-l.patch
+wifi-wil6210-debugfs-fix-uninitialized-variable-use-.patch
+wifi-iwlwifi-mvm-fix-double-list_add-at-iwl_mvm_mac_.patch
+wifi-libertas-fix-possible-refcount-leak-in-if_usb_p.patch
+media-cedrus-hevc-add-check-for-invalid-timestamp.patch
+net-mlx5e-remove-warn_on-when-trying-to-offload-an-u.patch
+net-mlx5e-fix-the-value-of-mlx5e_max_rq_num_mtts.patch
+net-mlx5-adjust-log_max_qp-to-be-18-at-most.patch
+crypto-hisilicon-hpre-don-t-use-gfp_kernel-to-alloc-.patch
+crypto-inside-secure-add-missing-module_device_table.patch
+crypto-hisilicon-sec-fix-auth-key-size-error.patch
+inet-add-read_once-sk-sk_bound_dev_if-in-inet_match.patch
+ipv6-add-read_once-sk-sk_bound_dev_if-in-inet6_match.patch
+net-allow-unbound-socket-for-packets-in-vrf-when-tcp.patch
+netdevsim-fib-fix-reference-count-leak-on-route-dele.patch
+wifi-rtw88-check-the-return-value-of-alloc_workqueue.patch
+iavf-fix-max_rate-limiting.patch
+iavf-fix-tc-qdisc-show-listing-too-many-queues.patch
+netdevsim-avoid-allocation-warnings-triggered-from-u.patch
+net-rose-fix-netdev-reference-changes.patch
+net-ionic-fix-error-check-for-vlan-flags-in-ionic_se.patch
+dccp-put-dccp_qpolicy_full-and-dccp_qpolicy_push-in-.patch
+net-usb-make-usb_rtl8153_ecm-non-user-configurable.patch
+wireguard-ratelimiter-use-hrtimer-in-selftest.patch
+wireguard-allowedips-don-t-corrupt-stack-when-detect.patch
+hid-amd_sfh-don-t-show-client-init-failed-as-error-w.patch
+clk-renesas-r9a06g032-fix-uart-clkgrp-bitsel.patch
+mtd-maps-fix-refcount-leak-in-of_flash_probe_versati.patch
+mtd-maps-fix-refcount-leak-in-ap_flash_init.patch
+mtd-rawnand-meson-fix-a-potential-double-free-issue.patch
+of-check-previous-kernel-s-ima-kexec-buffer-against-.patch
+scsi-qla2xxx-edif-reduce-initiator-initiator-thrashi.patch
+scsi-qla2xxx-edif-fix-potential-stuck-session-in-sa-.patch
+scsi-qla2xxx-edif-reduce-connection-thrash.patch
+scsi-qla2xxx-edif-fix-inconsistent-check-of-db_flags.patch
+scsi-qla2xxx-edif-synchronize-npiv-deletion-with-aut.patch
+scsi-qla2xxx-edif-add-retry-for-els-passthrough.patch
+scsi-qla2xxx-edif-fix-n2n-discovery-issue-with-secur.patch
+scsi-qla2xxx-edif-fix-n2n-login-retry-for-secure-dev.patch
+kvm-svm-unwind-speculative-rip-advancement-if-intn-i.patch
+kvm-svm-stuff-next_rip-on-emulated-int3-injection-if.patch
+phy-samsung-exynosautov9-ufs-correct-tsrv-register-c.patch
+pci-microchip-fix-refcount-leak-in-mc_pcie_init_irq_.patch
+pci-tegra194-fix-pm-error-handling-in-tegra_pcie_con.patch
+hid-cp2112-prevent-a-buffer-overflow-in-cp2112_xfer.patch
+mtd-sm_ftl-fix-deadlock-caused-by-cancel_work_sync-i.patch
+mtd-partitions-fix-refcount-leak-in-parse_redboot_of.patch
+mtd-parsers-ofpart-fix-refcount-leak-in-bcm4908_part.patch
+mtd-st_spi_fsm-add-a-clk_disable_unprepare-in-.probe.patch
+pci-mediatek-gen3-fix-refcount-leak-in-mtk_pcie_init.patch
+fpga-altera-pr-ip-fix-unsigned-comparison-with-less-.patch
+usb-host-fix-refcount-leak-in-ehci_hcd_ppc_of_probe.patch
+usb-ohci-nxp-fix-refcount-leak-in-ohci_hcd_nxp_probe.patch
+usb-gadget-tegra-xudc-fix-error-check-in-tegra_xudc_.patch
+usb-xhci-tegra-fix-error-check.patch
+netfilter-xtables-bring-spdx-identifier-back.patch
+scsi-qla2xxx-edif-send-logo-for-unexpected-ike-messa.patch
+scsi-qla2xxx-edif-reduce-disruption-due-to-multiple-.patch
+scsi-qla2xxx-edif-fix-no-login-after-app-start.patch
+scsi-qla2xxx-edif-tear-down-session-if-keys-have-bee.patch
+scsi-qla2xxx-edif-fix-session-thrash.patch
+scsi-qla2xxx-edif-fix-no-logout-on-delete-for-n2n.patch
+iio-accel-bma400-fix-the-scale-min-and-max-macro-val.patch
+platform-chrome-cros_ec-always-expose-last-resume-re.patch
+iio-accel-bma400-reordering-of-header-files.patch
+clk-mediatek-reset-fix-written-reset-bit-offset.patch
+lib-test_hmm-avoid-accessing-uninitialized-pages.patch
+memremap-remove-support-for-external-pgmap-refcounts.patch
+mm-memremap-fix-memunmap_pages-race-with-get_dev_pag.patch
+kvm-don-t-set-accessed-dirty-bits-for-zero_page.patch
+mwifiex-ignore-btcoex-events-from-the-88w8897-firmwa.patch
+mwifiex-fix-sleep-in-atomic-context-bugs-caused-by-d.patch
+scsi-iscsi-allow-iscsi_if_stop_conn-to-be-called-fro.patch
+scsi-iscsi-add-helper-to-remove-a-session-from-the-k.patch
+scsi-iscsi-fix-session-removal-on-shutdown.patch
+dmaengine-dw-edma-fix-edma-rd-wr-channels-and-dma-di.patch
+mtd-dataflash-add-spi-id-table.patch
+clk-qcom-camcc-sm8250-fix-halt-on-boot-by-reducing-d.patch
+misc-rtsx-fix-an-error-handling-path-in-rtsx_pci_pro.patch
+driver-core-fix-potential-deadlock-in-__driver_attac.patch
+clk-qcom-clk-krait-unlock-spin-after-mux-completion.patch
+clk-qcom-gcc-msm8939-add-missing-system_mm_noc_bfdcd.patch
+clk-qcom-gcc-msm8939-fix-bimc_ddr_clk_src-rcgr-base-.patch
+clk-qcom-gcc-msm8939-add-missing-system_mm_noc_bfdcd.patch-18441
+clk-qcom-gcc-msm8939-point-mm-peripherals-to-system_.patch
+usb-host-xhci-use-snprintf-in-xhci_decode_trb.patch
+rdma-rxe-fix-deadlock-in-rxe_do_local_ops.patch
+clk-qcom-ipq8074-fix-nss-core-pll-s.patch
+clk-qcom-ipq8074-sw-workaround-for-ubi32-pll-lock.patch
+clk-qcom-ipq8074-fix-nss-port-frequency-tables.patch
+clk-qcom-ipq8074-set-branch_halt_delay-flag-for-ubi-.patch
+clk-qcom-camcc-sdm845-fix-topology-around-titan_top-.patch
+clk-qcom-camcc-sm8250-fix-topology-around-titan_top-.patch
+clk-qcom-clk-rcg2-fail-duty-cycle-configuration-if-m.patch
+clk-qcom-clk-rcg2-make-sure-to-not-write-d-0-to-the-.patch
+mm-mempolicy-fix-get_nodes-out-of-bound-access.patch
+pci-dwc-stop-link-on-host_init-errors-and-de-initial.patch
+pci-dwc-add-unroll-iatu-space-support-to-dw_pcie_dis.patch
+pci-dwc-disable-outbound-windows-only-for-controller.patch
+pci-dwc-set-increase_region_size-flag-based-on-limit.patch
+pci-dwc-deallocate-epc-memory-on-dw_pcie_ep_init-err.patch
+pci-dwc-always-enable-cdm-check-if-snps-enable-cdm-c.patch
+soundwire-bus_type-fix-remove-and-shutdown-support.patch
+soundwire-revisit-driver-bind-unbind-and-callbacks.patch
+kvm-arm64-don-t-return-from-void-function.patch
+dmaengine-sf-pdma-add-multithread-support-for-a-dma-.patch
+pci-endpoint-don-t-stop-controller-when-unbinding-en.patch
+scsi-qla2xxx-check-correct-variable-in-qla24xx_async.patch
+intel_th-fix-a-resource-leak-in-an-error-handling-pa.patch
+intel_th-msu-sink-potential-dereference-of-null-poin.patch
+intel_th-msu-fix-vmalloced-buffers.patch
+binder-fix-redefinition-of-seq_file-attributes.patch
+staging-rtl8192u-fix-sleep-in-atomic-context-bug-in-.patch
+mmc-sdhci-of-esdhc-fix-refcount-leak-in-esdhc_signal.patch
+mmc-mxcmmc-silence-a-clang-warning.patch
+mmc-renesas_sdhi-get-the-reset-handle-early-in-the-p.patch
+mmc-renesas_sdhi-get-the-reset-handle-early-in-the-p.patch-12121
+memstick-ms_block-fix-some-incorrect-memory-allocati.patch
+memstick-ms_block-fix-a-memory-leak.patch
+mmc-sdhci-of-at91-fix-set_uhs_signaling-rewriting-of.patch
+of-device-fix-missing-of_node_put-in-of_dma_set_rest.patch
+mmc-block-add-single-read-for-4k-sector-cards.patch
+kvm-s390-pv-leak-the-topmost-page-table-when-destroy.patch
+pci-portdrv-don-t-disable-aer-reporting-in-get_port_.patch
+pci-qcom-set-up-rev-2.1.0-parf_phy-before-enabling-c.patch
+scsi-smartpqi-fix-dma-direction-for-raid-requests.patch
+xtensa-iss-network-provide-release-callback.patch
+xtensa-iss-fix-handling-error-cases-in-iss_net_confi.patch
+usb-gadget-udc-amd5536-depends-on-has_dma.patch
+usb-aspeed-vhub-fix-refcount-leak-bug-in-ast_vhub_in.patch
+usb-dwc3-core-deprecate-gctl.coresoftreset.patch
+usb-dwc3-core-do-not-perform-gctl_core_softreset-dur.patch
+usb-dwc3-qcom-fix-missing-optional-irq-warnings.patch
+eeprom-idt_89hpesx-uninitialized-data-in-idt_dbgfs_c.patch
+phy-stm32-fix-error-return-in-stm32_usbphyc_phy_init.patch
+interconnect-imx-fix-max_node_id.patch
+um-random-don-t-initialise-hwrng-struct-with-zero.patch
+rdma-irdma-fix-a-window-for-use-after-free.patch
+rdma-irdma-fix-vlan-connection-with-wildcard-address.patch
+rdma-irdma-fix-setting-of-qp-context-err_rq_idx_vali.patch
+rdma-rtrs-srv-fix-modinfo-output-for-stringify.patch
+rdma-rtrs-fix-warning-when-use-poll-mode-on-client-s.patch
+rdma-rtrs-replace-duplicate-check-with-is_pollqueue-.patch
+rdma-rtrs-introduce-destroy_cq-helper.patch
+rdma-rtrs-do-not-allow-sessname-to-contain-special-s.patch
+rdma-rtrs-rename-rtrs_sess-to-rtrs_path.patch
+rdma-rtrs-srv-rename-rtrs_srv_sess-to-rtrs_srv_path.patch
+rdma-rtrs-clt-rename-rtrs_clt_sess-to-rtrs_clt_path.patch
+rdma-rtrs-clt-replace-list_next_or_null_rr_rcu-with-.patch
+rdma-qedr-fix-potential-memory-leak-in-__qedr_alloc_.patch
+rdma-hns-fix-incorrect-clearing-of-interrupt-status-.patch
+rdma-siw-fix-duplicated-reported-iw_cm_event_connect.patch
+iio-cros-register-fifo-callback-after-sensor-is-regi.patch
+clk-qcom-gcc-msm8939-fix-weird-field-spacing-in-ftbl.patch
+rdma-hfi1-fix-potential-memory-leak-in-setup_base_ct.patch
+gpio-gpiolib-of-fix-refcount-bugs-in-of_mm_gpiochip_.patch
+hid-mcp2221-prevent-a-buffer-overflow-in-mcp_smbus_w.patch
+hid-amd_sfh-add-null-check-for-hid-device.patch
+dmaengine-imx-dma-cast-of_device_get_match_data-with.patch
+scripts-gdb-lx-dmesg-read-records-individually.patch
+scripts-gdb-fix-lx-dmesg-on-32-bits-arch.patch
+rdma-rxe-fix-mw-bind-to-allow-any-consumer-key-porti.patch
+mmc-cavium-octeon-add-of_node_put-when-breaking-out-.patch
+mmc-cavium-thunderx-add-of_node_put-when-breaking-ou.patch
+hid-alps-declare-u1_unicorn_legacy-support.patch
+rdma-rxe-for-invalidate-compare-according-to-set-key.patch
+pci-tegra194-fix-root-port-interrupt-handling.patch
+pci-tegra194-fix-link-up-retry-sequence.patch
+hid-amd_sfh-handle-condition-of-no-sensors.patch
+usb-serial-fix-tty-port-initialized-comments.patch
+usb-cdns3-change-place-of-priv_ep-assignment-in-cdns.patch
+mtd-spi-nor-fix-spi_nor_spimem_setup_op-call-in-spi_.patch
+kvm-nvmx-set-umip-bit-cr4_fixed1-msr-when-emulating-.patch
+platform-olpc-fix-uninitialized-data-in-debugfs-writ.patch
+rdma-srpt-duplicate-port-name-members.patch
+rdma-srpt-introduce-a-reference-count-in-struct-srpt.patch
+rdma-srpt-fix-a-use-after-free.patch
+android-binder-stop-saving-a-pointer-to-the-vma.patch
+mm-mmap.c-fix-missing-call-to-vm_unacct_memory-in-mm.patch
+selftests-kvm-set-rax-before-vmcall.patch
+of-fdt-declared-return-type-does-not-match-actual-re.patch
+rdma-mlx5-add-missing-check-for-return-value-in-get-.patch
+rdma-rxe-add-memory-barriers-to-kernel-queues.patch
+rdma-rxe-remove-the-is_user-members-of-struct-rxe_sq.patch
+rdma-rxe-fix-error-unwind-in-rxe_create_qp.patch
+block-rnbd-srv-set-keep_id-to-true-after-mutex_trylo.patch
+null_blk-fix-ida-error-handling-in-null_add_dev.patch
+nvme-use-command_id-instead-of-req-tag-in-trace_nvme.patch
+nvme-define-compat_ioctl-again-to-unbreak-32-bit-use.patch
+nvme-disable-namespace-access-for-unsupported-metada.patch
+nvme-don-t-return-an-error-from-nvme_configure_metad.patch
+nvme-catch-enodev-from-nvme_revalidate_zones-again.patch
+block-bio-remove-duplicate-append-pages-code.patch
+block-ensure-iov_iter-advances-for-added-pages.patch
+jbd2-fix-outstanding-credits-assert-in-jbd2_journal_.patch
+ext4-recover-csum-seed-of-tmp_inode-after-migrating-.patch
+jbd2-fix-assertion-jh-b_frozen_data-null-failure-whe.patch
+usb-cdns3-don-t-use-priv_dev-uninitialized-in-cdns3_.patch
+opp-fix-error-check-in-dev_pm_opp_attach_genpd.patch
+asoc-cros_ec_codec-fix-refcount-leak-in-cros_ec_code.patch
+asoc-samsung-fix-error-handling-in-aries_audio_probe.patch
+asoc-imx-audmux-silence-a-clang-warning.patch
+asoc-mediatek-mt8173-fix-refcount-leak-in-mt8173_rt5.patch
+asoc-mt6797-mt6351-fix-refcount-leak-in-mt6797_mt635.patch
+asoc-codecs-da7210-add-check-for-i2c_add_driver.patch
+asoc-mediatek-mt8173-rt5650-fix-refcount-leak-in-mt8.patch
+serial-store-character-timing-information-to-uart_po.patch
+serial-8250-export-icr-access-helpers-for-internal-u.patch
+serial-8250-dma-allow-driver-operations-before-start.patch
+serial-8250_dw-store-lsr-into-lsr_saved_flags-in-dw8.patch
+asoc-codecs-msm8916-wcd-digital-move-gains-from-sx_t.patch
+asoc-codecs-wcd9335-move-gains-from-sx_tlv-to-s8_tlv.patch
+rpmsg-char-add-mutex-protection-for-rpmsg_eptdev_ope.patch
+rpmsg-mtk_rpmsg-fix-circular-locking-dependency.patch
+remoteproc-k3-r5-fix-refcount-leak-in-k3_r5_cluster_.patch
+selftests-livepatch-better-synchronize-test_klp_call.patch
+profiling-fix-shift-too-large-makes-kernel-panic.patch
+remoteproc-imx_rproc-fix-refcount-leak-in-imx_rproc_.patch
+asoc-samsung-h1940_uda1380-include-proepr-gpio-consu.patch
+powerpc-perf-optimize-clearing-the-pending-pmi-and-r.patch
+asoc-samsung-change-gpiod_speaker_power-and-rx1950_a.patch
+tty-n_gsm-delete-gsmtty-open-sabm-frame-when-config-.patch
+tty-n_gsm-fix-user-open-not-possible-at-responder-un.patch
+tty-n_gsm-fix-tty-registration-before-control-channe.patch
+tty-n_gsm-fix-wrong-queuing-behavior-in-gsm_dlci_dat.patch
+tty-n_gsm-fix-missing-timer-to-handle-stalled-links.patch
+tty-n_gsm-fix-non-flow-control-frames-during-mux-flo.patch
+tty-n_gsm-fix-packet-re-transmission-without-open-co.patch
+tty-n_gsm-fix-race-condition-in-gsmld_write.patch
+tty-n_gsm-fix-resource-allocation-order-in-gsm_activ.patch
+asoc-qcom-fix-missing-of_node_put-in-asoc_qcom_lpass.patch
+asoc-imx-card-fix-dsd-pdm-mclk-frequency.patch
+remoteproc-qcom-wcnss-fix-handling-of-irqs.patch
+vfio-ccw-do-not-change-fsm-state-in-subchannel-event.patch
+serial-8250_fsl-don-t-report-fe-pe-and-oe-twice.patch
+tty-n_gsm-fix-wrong-t1-retry-count-handling.patch
+tty-n_gsm-fix-dm-command.patch
+tty-n_gsm-fix-missing-corner-cases-in-gsmld_poll.patch
+mips-vdso-utilize-__pa-for-gic_pfn.patch
+swiotlb-fail-map-correctly-with-failed-io_tlb_defaul.patch
+asoc-mt6359-fix-refcount-leak-bug.patch
+serial-8250_bcm7271-save-restore-rts-in-suspend-resu.patch
+iommu-exynos-handle-failed-iommu-device-registration.patch
+9p-fix-a-bunch-of-checkpatch-warnings.patch
+9p-drop-kref-usage.patch
+9p-add-client-parameter-to-p9_req_put.patch
+net-9p-fix-refcount-leak-in-p9_read_work-error-handl.patch
+mips-fixed-__debug_virt_addr_valid.patch
+rpmsg-qcom_smd-fix-refcount-leak-in-qcom_smd_parse_e.patch
+kfifo-fix-kfifo_to_user-return-type.patch
+lib-smp_processor_id-fix-imbalanced-instrumentation_.patch
+proc-fix-a-dentry-lock-race-between-release_task-and.patch
+remoteproc-qcom-pas-check-if-coredump-is-enabled.patch
+remoteproc-sysmon-wait-for-ssctl-service-to-come-up.patch
+mfd-t7l66xb-drop-platform-disable-callback.patch
+mfd-max77620-fix-refcount-leak-in-max77620_initialis.patch
+iommu-arm-smmu-qcom_iommu-add-of_node_put-when-break.patch
+perf-tools-fix-dso_id-inode-generation-comparison.patch
+s390-dump-fix-old-lowcore-virtual-vs-physical-addres.patch
+s390-maccess-fix-semantics-of-memcpy_real-and-its-ca.patch
+s390-crash-fix-incorrect-number-of-bytes-to-copy-to-.patch
+s390-zcore-fix-race-when-reading-from-hardware-syste.patch
+asoc-fsl_asrc-force-cast-the-asrc_format-type.patch
+asoc-fsl-asoc-card-force-cast-the-asrc_format-type.patch
+asoc-fsl_easrc-use-snd_pcm_format_t-type-for-sample_.patch
+asoc-imx-card-use-snd_pcm_format_t-type-for-asrc_for.patch
+asoc-qcom-q6dsp-fix-an-off-by-one-in-q6adm_alloc_cop.patch
+fuse-remove-the-control-interface-for-virtio-fs.patch
+asoc-audio-graph-card-add-of_node_put-in-fail-path.patch
+watchdog-sp5100_tco-fix-a-memory-leak-of-efch-mmio-r.patch
+watchdog-armada_37xx_wdt-check-the-return-value-of-d.patch
+video-fbdev-amba-clcd-fix-refcount-leak-bugs.patch
+video-fbdev-sis-fix-typos-in-sis_getmodeid.patch
+asoc-mchp-spdifrx-disable-end-of-block-interrupt-on-.patch
+powerpc-32-call-mmu_mark_initmem_nx-regardless-of-da.patch
+powerpc-32-do-not-allow-selection-of-e5500-or-e6500-.patch
+powerpc-iommu-fix-iommu_table_in_use-for-a-small-def.patch
+powerpc-pci-prefer-pci-domain-assignment-via-dt-linu.patch
+tty-serial-fsl_lpuart-correct-the-count-of-break-cha.patch
+s390-dump-fix-os_info-virtual-vs-physical-address-co.patch
+s390-smp-cleanup-target-cpu-callback-starting.patch
+s390-smp-cleanup-control-register-update-routines.patch
+s390-maccess-rework-absolute-lowcore-accessors.patch
+s390-smp-enforce-lowcore-protection-on-cpu-restart.patch
+f2fs-fix-to-remove-f2fs_compr_fl-and-tag-f2fs_nocomp.patch
+powerpc-spufs-fix-refcount-leak-in-spufs_init_isolat.patch
+powerpc-xive-fix-refcount-leak-in-xive_get_max_prio.patch
+powerpc-cell-axon_msi-fix-refcount-leak-in-setup_msi.patch
+perf-symbol-fail-to-read-phdr-workaround.patch
+kprobes-forbid-probing-on-trampoline-and-bpf-code-ar.patch
+x86-bus_lock-don-t-assume-the-init-value-of-debugctl.patch
+powerpc-pci-fix-phb-numbering-when-using-opal-phbid.patch
+genelf-use-have_libcrypto_support-not-the-never-defi.patch
+scripts-faddr2line-fix-vmlinux-detection-on-arm64.patch
+sched-deadline-merge-dl_task_can_attach-and-dl_cpu_b.patch
+sched-cpuset-fix-dl_cpu_busy-panic-due-to-empty-cs-c.patch
+x86-numa-use-cpumask_available-instead-of-hardcoded-.patch
+video-fbdev-arkfb-fix-a-divide-by-zero-bug-in-ark_se.patch
+tools-thermal-fix-possible-path-truncations.patch
+sched-fix-the-check-of-nr_running-at-queue-wakelist.patch
+sched-remove-the-limitation-of-wf_on_cpu-on-wakelist.patch
+sched-core-do-not-requeue-task-on-cpu-excluded-from-.patch
+x86-entry-build-thunk_-bits-only-if-config_preemptio.patch
+f2fs-allow-compression-for-mmap-files-in-compress_mo.patch
+f2fs-do-not-allow-to-decompress-files-have-fi_compre.patch
+video-fbdev-vt8623fb-check-the-size-of-screen-before.patch
+video-fbdev-arkfb-check-the-size-of-screen-before-me.patch
+video-fbdev-s3fb-check-the-size-of-screen-before-mem.patch
diff --git a/queue-5.15/skbuff-don-t-mix-ubuf_info-from-different-sources.patch b/queue-5.15/skbuff-don-t-mix-ubuf_info-from-different-sources.patch
new file mode 100644 (file)
index 0000000..5fd809d
--- /dev/null
@@ -0,0 +1,37 @@
+From 3f20263fd2e33b027ad8f19f91a8c40c90c644b9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Jul 2022 21:52:27 +0100
+Subject: skbuff: don't mix ubuf_info from different sources
+
+From: Pavel Begunkov <asml.silence@gmail.com>
+
+[ Upstream commit 1b4b2b09d4fb451029b112f17d34792e0277aeb2 ]
+
+We should not append MSG_ZEROCOPY requests to skbuff with non
+MSG_ZEROCOPY ubuf_info, they might be not compatible.
+
+Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/skbuff.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index 5ebef94e14dc..891db074981e 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -1213,6 +1213,10 @@ struct ubuf_info *msg_zerocopy_realloc(struct sock *sk, size_t size,
+               const u32 byte_limit = 1 << 19;         /* limit to a few TSO */
+               u32 bytelen, next;
++              /* there might be non MSG_ZEROCOPY users */
++              if (uarg->callback != msg_zerocopy_callback)
++                      return NULL;
++
+               /* realloc only when socket is locked (TCP, UDP cork),
+                * so uarg->len and sk_zckey access is serialized
+                */
+-- 
+2.35.1
+
diff --git a/queue-5.15/skmsg-fix-invalid-last-sg-check-in-sk_msg_recvmsg.patch b/queue-5.15/skmsg-fix-invalid-last-sg-check-in-sk_msg_recvmsg.patch
new file mode 100644 (file)
index 0000000..8a97c15
--- /dev/null
@@ -0,0 +1,58 @@
+From 7a1787f1c941cea77ff3bf6c85fa91b4284e799a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Jun 2022 20:36:16 +0800
+Subject: skmsg: Fix invalid last sg check in sk_msg_recvmsg()
+
+From: Liu Jian <liujian56@huawei.com>
+
+[ Upstream commit 9974d37ea75f01b47d16072b5dad305bd8d23fcc ]
+
+In sk_psock_skb_ingress_enqueue function, if the linear area + nr_frags +
+frag_list of the SKB has NR_MSG_FRAG_IDS blocks in total, skb_to_sgvec
+will return NR_MSG_FRAG_IDS, then msg->sg.end will be set to
+NR_MSG_FRAG_IDS, and in addition, (NR_MSG_FRAG_IDS - 1) is set to the last
+SG of msg. Recv the msg in sk_msg_recvmsg, when i is (NR_MSG_FRAG_IDS - 1),
+the sk_msg_iter_var_next(i) will change i to 0 (not NR_MSG_FRAG_IDS), the
+judgment condition "msg_rx->sg.start==msg_rx->sg.end" and
+"i != msg_rx->sg.end" can not work.
+
+As a result, the processed msg cannot be deleted from ingress_msg list.
+But the length of all the sge of the msg has changed to 0. Then the next
+recvmsg syscall will process the msg repeatedly, because the length of sge
+is 0, the -EFAULT error is always returned.
+
+Fixes: 604326b41a6f ("bpf, sockmap: convert to generic sk_msg interface")
+Signed-off-by: Liu Jian <liujian56@huawei.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: John Fastabend <john.fastabend@gmail.com>
+Link: https://lore.kernel.org/bpf/20220628123616.186950-1-liujian56@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/skmsg.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/core/skmsg.c b/net/core/skmsg.c
+index ede0af308f40..f50f8d95b628 100644
+--- a/net/core/skmsg.c
++++ b/net/core/skmsg.c
+@@ -462,7 +462,7 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg,
+                       if (copied == len)
+                               break;
+-              } while (i != msg_rx->sg.end);
++              } while (!sg_is_last(sge));
+               if (unlikely(peek)) {
+                       msg_rx = sk_psock_next_msg(psock, msg_rx);
+@@ -472,7 +472,7 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg,
+               }
+               msg_rx->sg.start = i;
+-              if (!sge->length && msg_rx->sg.start == msg_rx->sg.end) {
++              if (!sge->length && sg_is_last(sge)) {
+                       msg_rx = sk_psock_dequeue_msg(psock);
+                       kfree_sk_msg(msg_rx);
+               }
+-- 
+2.35.1
+
diff --git a/queue-5.15/soc-amlogic-fix-refcount-leak-in-meson-secure-pwrc.c.patch b/queue-5.15/soc-amlogic-fix-refcount-leak-in-meson-secure-pwrc.c.patch
new file mode 100644 (file)
index 0000000..75e314e
--- /dev/null
@@ -0,0 +1,42 @@
+From 798ba7ce641ab77a1f26d07b6035ba10e30da85f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jun 2022 22:49:15 +0800
+Subject: soc: amlogic: Fix refcount leak in meson-secure-pwrc.c
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit d18529a4c12f66d83daac78045ea54063bd43257 ]
+
+In meson_secure_pwrc_probe(), there is a refcount leak in one fail
+path.
+
+Signed-off-by: Liang He <windhl@126.com>
+Acked-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Fixes: b3dde5013e13 ("soc: amlogic: Add support for Secure power domains controller")
+Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
+Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
+Link: https://lore.kernel.org/r/20220616144915.3988071-1-windhl@126.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/amlogic/meson-secure-pwrc.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/soc/amlogic/meson-secure-pwrc.c b/drivers/soc/amlogic/meson-secure-pwrc.c
+index 59bd195fa9c9..2eeea5e1b3b7 100644
+--- a/drivers/soc/amlogic/meson-secure-pwrc.c
++++ b/drivers/soc/amlogic/meson-secure-pwrc.c
+@@ -139,8 +139,10 @@ static int meson_secure_pwrc_probe(struct platform_device *pdev)
+       }
+       pwrc = devm_kzalloc(&pdev->dev, sizeof(*pwrc), GFP_KERNEL);
+-      if (!pwrc)
++      if (!pwrc) {
++              of_node_put(sm_np);
+               return -ENOMEM;
++      }
+       pwrc->fw = meson_sm_get(sm_np);
+       of_node_put(sm_np);
+-- 
+2.35.1
+
diff --git a/queue-5.15/soc-fsl-guts-machine-variable-might-be-unset.patch b/queue-5.15/soc-fsl-guts-machine-variable-might-be-unset.patch
new file mode 100644 (file)
index 0000000..e4d218b
--- /dev/null
@@ -0,0 +1,37 @@
+From 53151fdd5ba6b6d8093366e60563a5f859d4c41b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Apr 2022 11:56:03 +0200
+Subject: soc: fsl: guts: machine variable might be unset
+
+From: Michael Walle <michael@walle.cc>
+
+[ Upstream commit ab3f045774f704c4e7b6a878102f4e9d4ae7bc74 ]
+
+If both the model and the compatible properties are missing, then
+machine will not be set. Initialize it with NULL.
+
+Fixes: 34c1c21e94ac ("soc: fsl: fix section mismatch build warnings")
+Signed-off-by: Michael Walle <michael@walle.cc>
+Acked-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/fsl/guts.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c
+index 75eabfb916cb..0b2c7fdbaa5b 100644
+--- a/drivers/soc/fsl/guts.c
++++ b/drivers/soc/fsl/guts.c
+@@ -141,7 +141,7 @@ static int fsl_guts_probe(struct platform_device *pdev)
+       struct device *dev = &pdev->dev;
+       struct resource *res;
+       const struct fsl_soc_die_attr *soc_die;
+-      const char *machine;
++      const char *machine = NULL;
+       u32 svr;
+       /* Initialize guts */
+-- 
+2.35.1
+
diff --git a/queue-5.15/soc-qcom-aoss-fix-refcount-leak-in-qmp_cooling_devic.patch b/queue-5.15/soc-qcom-aoss-fix-refcount-leak-in-qmp_cooling_devic.patch
new file mode 100644 (file)
index 0000000..4bc1df8
--- /dev/null
@@ -0,0 +1,43 @@
+From baf05ae64cb2d460a684d2ba183aead2630237a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jun 2022 10:42:52 +0400
+Subject: soc: qcom: aoss: Fix refcount leak in qmp_cooling_devices_register
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit e6e0951414a314e7db3e9e24fd924b3e15515288 ]
+
+Every iteration of for_each_available_child_of_node() decrements
+the reference count of the previous node.
+When breaking early from a for_each_available_child_of_node() loop,
+we need to explicitly call of_node_put() on the child node.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: 05589b30b21a ("soc: qcom: Extend AOSS QMP driver to support resources that are used to wake up the SoC.")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220606064252.42595-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/qcom/qcom_aoss.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/soc/qcom/qcom_aoss.c b/drivers/soc/qcom/qcom_aoss.c
+index 8583c1e558ae..3973accdc982 100644
+--- a/drivers/soc/qcom/qcom_aoss.c
++++ b/drivers/soc/qcom/qcom_aoss.c
+@@ -499,8 +499,10 @@ static int qmp_cooling_devices_register(struct qmp *qmp)
+                       continue;
+               ret = qmp_cooling_device_add(qmp, &qmp->cooling_devs[count++],
+                                            child);
+-              if (ret)
++              if (ret) {
++                      of_node_put(child);
+                       goto unroll;
++              }
+       }
+       if (!count)
+-- 
+2.35.1
+
diff --git a/queue-5.15/soc-qcom-make-qcom_rpmpd-depend-on-pm.patch b/queue-5.15/soc-qcom-make-qcom_rpmpd-depend-on-pm.patch
new file mode 100644 (file)
index 0000000..56b9f7a
--- /dev/null
@@ -0,0 +1,37 @@
+From 818baca705f003bd83d4abbef07c96d0b94bf2f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Jul 2022 23:21:58 +0200
+Subject: soc: qcom: Make QCOM_RPMPD depend on PM
+
+From: Konrad Dybcio <konrad.dybcio@somainline.org>
+
+[ Upstream commit a6232f2aa99ce470799992e99e0012945bb5308f ]
+
+QCOM_RPMPD requires PM_GENERIC_DOMAINS/_OF, which in turns requires
+CONFIG_PM. I forgot about the latter in my earlier patch (it's still
+in -next as of the time of committing, hence no Fixes: tag). Fix it.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220707212158.32684-1-konrad.dybcio@somainline.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/qcom/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
+index 79b568f82a1c..499718e131d7 100644
+--- a/drivers/soc/qcom/Kconfig
++++ b/drivers/soc/qcom/Kconfig
+@@ -129,6 +129,7 @@ config QCOM_RPMHPD
+ config QCOM_RPMPD
+       tristate "Qualcomm RPM Power domain driver"
++      depends on PM
+       depends on QCOM_SMD_RPM
+       help
+         QCOM RPM Power domain driver to support power-domains with
+-- 
+2.35.1
+
diff --git a/queue-5.15/soc-qcom-ocmem-fix-refcount-leak-in-of_get_ocmem.patch b/queue-5.15/soc-qcom-ocmem-fix-refcount-leak-in-of_get_ocmem.patch
new file mode 100644 (file)
index 0000000..6fa84c2
--- /dev/null
@@ -0,0 +1,49 @@
+From fb010441a7521fc3e15f61338d682c8d8e5cc9d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jun 2022 08:24:30 +0400
+Subject: soc: qcom: ocmem: Fix refcount leak in of_get_ocmem
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 92a563fcf14b3093226fb36f12e9b5cf630c5a5d ]
+
+of_parse_phandle() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when not need anymore.
+Add missing of_node_put() to avoid refcount leak.
+of_node_put() will check NULL pointer.
+
+Fixes: 88c1e9404f1d ("soc: qcom: add OCMEM driver")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Reviewed-by: Brian Masney <masneyb@onstation.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220602042430.1114-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/qcom/ocmem.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/soc/qcom/ocmem.c b/drivers/soc/qcom/ocmem.c
+index 85f82e195ef8..1dfdd0b9ba24 100644
+--- a/drivers/soc/qcom/ocmem.c
++++ b/drivers/soc/qcom/ocmem.c
+@@ -194,14 +194,17 @@ struct ocmem *of_get_ocmem(struct device *dev)
+       devnode = of_parse_phandle(dev->of_node, "sram", 0);
+       if (!devnode || !devnode->parent) {
+               dev_err(dev, "Cannot look up sram phandle\n");
++              of_node_put(devnode);
+               return ERR_PTR(-ENODEV);
+       }
+       pdev = of_find_device_by_node(devnode->parent);
+       if (!pdev) {
+               dev_err(dev, "Cannot find device node %s\n", devnode->name);
++              of_node_put(devnode);
+               return ERR_PTR(-EPROBE_DEFER);
+       }
++      of_node_put(devnode);
+       ocmem = platform_get_drvdata(pdev);
+       if (!ocmem) {
+-- 
+2.35.1
+
diff --git a/queue-5.15/soc-renesas-r8a779a0-sysc-fix-a2dp1-and-a2cv-2357-pd.patch b/queue-5.15/soc-renesas-r8a779a0-sysc-fix-a2dp1-and-a2cv-2357-pd.patch
new file mode 100644 (file)
index 0000000..eb7da8e
--- /dev/null
@@ -0,0 +1,46 @@
+From afb5f0058940d68c6a5d0b2cbc37da5e2fc2033d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jun 2022 15:51:35 +0200
+Subject: soc: renesas: r8a779a0-sysc: Fix A2DP1 and A2CV[2357] PDR values
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit bccceabb92ce8eb78bbf2de08308e2cc2761a2e5 ]
+
+The PDR values for the A2DP1 and A2CV[2357] power areas on R-Car V3U are
+incorrect (copied-and-pasted from A2DP0 and A2CV[0146]).
+Fix them.
+
+Reported-by: Renesas Vietnam via Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Fixes: 1b4298f000064cc2 ("soc: renesas: r8a779a0-sysc: Add r8a779a0 support")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/87bc2e70ba4082970cf8c65871beae4be3503189.1654696188.git.geert+renesas@glider.be
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/renesas/r8a779a0-sysc.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/soc/renesas/r8a779a0-sysc.c b/drivers/soc/renesas/r8a779a0-sysc.c
+index 7410b9fa9846..7e1aba9abce2 100644
+--- a/drivers/soc/renesas/r8a779a0-sysc.c
++++ b/drivers/soc/renesas/r8a779a0-sysc.c
+@@ -83,11 +83,11 @@ static struct r8a779a0_sysc_area r8a779a0_areas[] __initdata = {
+       { "a2cv6",      R8A779A0_PD_A2CV6, R8A779A0_PD_A3IR },
+       { "a2cn2",      R8A779A0_PD_A2CN2, R8A779A0_PD_A3IR },
+       { "a2imp23",    R8A779A0_PD_A2IMP23, R8A779A0_PD_A3IR },
+-      { "a2dp1",      R8A779A0_PD_A2DP0, R8A779A0_PD_A3IR },
+-      { "a2cv2",      R8A779A0_PD_A2CV0, R8A779A0_PD_A3IR },
+-      { "a2cv3",      R8A779A0_PD_A2CV1, R8A779A0_PD_A3IR },
+-      { "a2cv5",      R8A779A0_PD_A2CV4, R8A779A0_PD_A3IR },
+-      { "a2cv7",      R8A779A0_PD_A2CV6, R8A779A0_PD_A3IR },
++      { "a2dp1",      R8A779A0_PD_A2DP1, R8A779A0_PD_A3IR },
++      { "a2cv2",      R8A779A0_PD_A2CV2, R8A779A0_PD_A3IR },
++      { "a2cv3",      R8A779A0_PD_A2CV3, R8A779A0_PD_A3IR },
++      { "a2cv5",      R8A779A0_PD_A2CV5, R8A779A0_PD_A3IR },
++      { "a2cv7",      R8A779A0_PD_A2CV7, R8A779A0_PD_A3IR },
+       { "a2cn1",      R8A779A0_PD_A2CN1, R8A779A0_PD_A3IR },
+       { "a1cnn0",     R8A779A0_PD_A1CNN0, R8A779A0_PD_A2CN0 },
+       { "a1cnn2",     R8A779A0_PD_A1CNN2, R8A779A0_PD_A2CN2 },
+-- 
+2.35.1
+
diff --git a/queue-5.15/soundwire-bus_type-fix-remove-and-shutdown-support.patch b/queue-5.15/soundwire-bus_type-fix-remove-and-shutdown-support.patch
new file mode 100644 (file)
index 0000000..4a942b6
--- /dev/null
@@ -0,0 +1,54 @@
+From d03ec6abeca1531cb804be263bec9d5fe8adbe31 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jun 2022 09:51:05 +0800
+Subject: soundwire: bus_type: fix remove and shutdown support
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit df6407782964dc7e35ad84230abb38f46314b245 ]
+
+The bus sdw_drv_remove() and sdw_drv_shutdown() helpers are used
+conditionally, if the driver provides these routines.
+
+These helpers already test if the driver provides a .remove or
+.shutdown callback, so there's no harm in invoking the
+sdw_drv_remove() and sdw_drv_shutdown() unconditionally.
+
+In addition, the current code is imbalanced with
+dev_pm_domain_attach() called from sdw_drv_probe(), but
+dev_pm_domain_detach() called from sdw_drv_remove() only if the driver
+provides a .remove callback.
+
+Fixes: 9251345dca24b ("soundwire: Add SoundWire bus type")
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Rander Wang <rander.wang@intel.com>
+Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Link: https://lore.kernel.org/r/20220610015105.25987-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/bus_type.c | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c
+index 893296f3fe39..b81e04dd3a9f 100644
+--- a/drivers/soundwire/bus_type.c
++++ b/drivers/soundwire/bus_type.c
+@@ -193,12 +193,8 @@ int __sdw_register_driver(struct sdw_driver *drv, struct module *owner)
+       drv->driver.owner = owner;
+       drv->driver.probe = sdw_drv_probe;
+-
+-      if (drv->remove)
+-              drv->driver.remove = sdw_drv_remove;
+-
+-      if (drv->shutdown)
+-              drv->driver.shutdown = sdw_drv_shutdown;
++      drv->driver.remove = sdw_drv_remove;
++      drv->driver.shutdown = sdw_drv_shutdown;
+       return driver_register(&drv->driver);
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/soundwire-revisit-driver-bind-unbind-and-callbacks.patch b/queue-5.15/soundwire-revisit-driver-bind-unbind-and-callbacks.patch
new file mode 100644 (file)
index 0000000..1429cf0
--- /dev/null
@@ -0,0 +1,450 @@
+From 809ef86c7c813bb7ec5260530e209d98118a81f9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Jun 2022 17:56:38 -0500
+Subject: soundwire: revisit driver bind/unbind and callbacks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit bd29c00edd0a5dac8b6e7332bb470cd50f92e893 ]
+
+In the SoundWire probe, we store a pointer from the driver ops into
+the 'slave' structure. This can lead to kernel oopses when unbinding
+codec drivers, e.g. with the following sequence to remove machine
+driver and codec driver.
+
+/sbin/modprobe -r snd_soc_sof_sdw
+/sbin/modprobe -r snd_soc_rt711
+
+The full details can be found in the BugLink below, for reference the
+two following examples show different cases of driver ops/callbacks
+being invoked after the driver .remove().
+
+kernel: BUG: kernel NULL pointer dereference, address: 0000000000000150
+kernel: Workqueue: events cdns_update_slave_status_work [soundwire_cadence]
+kernel: RIP: 0010:mutex_lock+0x19/0x30
+kernel: Call Trace:
+kernel:  ? sdw_handle_slave_status+0x426/0xe00 [soundwire_bus 94ff184bf398570c3f8ff7efe9e32529f532e4ae]
+kernel:  ? newidle_balance+0x26a/0x400
+kernel:  ? cdns_update_slave_status_work+0x1e9/0x200 [soundwire_cadence 1bcf98eebe5ba9833cd433323769ac923c9c6f82]
+
+kernel: BUG: unable to handle page fault for address: ffffffffc07654c8
+kernel: Workqueue: pm pm_runtime_work
+kernel: RIP: 0010:sdw_bus_prep_clk_stop+0x6f/0x160 [soundwire_bus]
+kernel: Call Trace:
+kernel:  <TASK>
+kernel:  sdw_cdns_clock_stop+0xb5/0x1b0 [soundwire_cadence 1bcf98eebe5ba9833cd433323769ac923c9c6f82]
+kernel:  intel_suspend_runtime+0x5f/0x120 [soundwire_intel aca858f7c87048d3152a4a41bb68abb9b663a1dd]
+kernel:  ? dpm_sysfs_remove+0x60/0x60
+
+This was not detected earlier in Intel tests since the tests first
+remove the parent PCI device and shut down the bus. The sequence
+above is a corner case which keeps the bus operational but without a
+driver bound.
+
+While trying to solve this kernel oopses, it became clear that the
+existing SoundWire bus does not deal well with the unbind case.
+
+Commit 528be501b7d4a ("soundwire: sdw_slave: add probe_complete structure and new fields")
+added a 'probed' status variable and a 'probe_complete'
+struct completion. This status is however not reset on remove and
+likewise the 'probe complete' is not re-initialized, so the
+bind/unbind/bind test cases would fail. The timeout used before the
+'update_status' callback was also a bad idea in hindsight, there
+should really be no timing assumption as to if and when a driver is
+bound to a device.
+
+An initial draft was based on device_lock() and device_unlock() was
+tested. This proved too complicated, with deadlocks created during the
+suspend-resume sequences, which also use the same device_lock/unlock()
+as the bind/unbind sequences. On a CometLake device, a bad DSDT/BIOS
+caused spurious resumes and the use of device_lock() caused hangs
+during suspend. After multiple weeks or testing and painful
+reverse-engineering of deadlocks on different devices, we looked for
+alternatives that did not interfere with the device core.
+
+A bus notifier was used successfully to keep track of DRIVER_BOUND and
+DRIVER_UNBIND events. This solved the bind-unbind-bind case in tests,
+but it can still be defeated with a theoretical corner case where the
+memory is freed by a .remove while the callback is in use. The
+notifier only helps make sure the driver callbacks are valid, but not
+that the memory allocated in probe remains valid while the callbacks
+are invoked.
+
+This patch suggests the introduction of a new 'sdw_dev_lock' mutex
+protecting probe/remove and all driver callbacks. Since this mutex is
+'local' to SoundWire only, it does not interfere with existing locks
+and does not create deadlocks. In addition, this patch removes the
+'probe_complete' completion, instead we directly invoke the
+'update_status' from the probe routine. That removes any sort of
+timing dependency and a much better support for the device/driver
+model, the driver could be bound before the bus started, or eons after
+the bus started and the hardware would be properly initialized in all
+cases.
+
+BugLink: https://github.com/thesofproject/linux/issues/3531
+Fixes: 56d4fe31af77 ("soundwire: Add MIPI DisCo property helpers")
+Fixes: 528be501b7d4a ("soundwire: sdw_slave: add probe_complete structure and new fields")
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Rander Wang <rander.wang@intel.com>
+Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
+Link: https://lore.kernel.org/r/20220621225641.221170-2-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soundwire/bus.c       | 75 ++++++++++++++++++++---------------
+ drivers/soundwire/bus_type.c  | 30 +++++++++++---
+ drivers/soundwire/slave.c     |  3 +-
+ drivers/soundwire/stream.c    | 53 ++++++++++++++++---------
+ include/linux/soundwire/sdw.h |  6 +--
+ 5 files changed, 106 insertions(+), 61 deletions(-)
+
+diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
+index 67369e941d0d..b7cdfa65157c 100644
+--- a/drivers/soundwire/bus.c
++++ b/drivers/soundwire/bus.c
+@@ -7,6 +7,7 @@
+ #include <linux/pm_runtime.h>
+ #include <linux/soundwire/sdw_registers.h>
+ #include <linux/soundwire/sdw.h>
++#include <linux/soundwire/sdw_type.h>
+ #include "bus.h"
+ #include "sysfs_local.h"
+@@ -846,15 +847,21 @@ static int sdw_slave_clk_stop_callback(struct sdw_slave *slave,
+                                      enum sdw_clk_stop_mode mode,
+                                      enum sdw_clk_stop_type type)
+ {
+-      int ret;
++      int ret = 0;
+-      if (slave->ops && slave->ops->clk_stop) {
+-              ret = slave->ops->clk_stop(slave, mode, type);
+-              if (ret < 0)
+-                      return ret;
++      mutex_lock(&slave->sdw_dev_lock);
++
++      if (slave->probed)  {
++              struct device *dev = &slave->dev;
++              struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
++
++              if (drv->ops && drv->ops->clk_stop)
++                      ret = drv->ops->clk_stop(slave, mode, type);
+       }
+-      return 0;
++      mutex_unlock(&slave->sdw_dev_lock);
++
++      return ret;
+ }
+ static int sdw_slave_clk_stop_prepare(struct sdw_slave *slave,
+@@ -1616,14 +1623,24 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave)
+               }
+               /* Update the Slave driver */
+-              if (slave_notify && slave->ops &&
+-                  slave->ops->interrupt_callback) {
+-                      slave_intr.sdca_cascade = sdca_cascade;
+-                      slave_intr.control_port = clear;
+-                      memcpy(slave_intr.port, &port_status,
+-                             sizeof(slave_intr.port));
+-
+-                      slave->ops->interrupt_callback(slave, &slave_intr);
++              if (slave_notify) {
++                      mutex_lock(&slave->sdw_dev_lock);
++
++                      if (slave->probed) {
++                              struct device *dev = &slave->dev;
++                              struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
++
++                              if (drv->ops && drv->ops->interrupt_callback) {
++                                      slave_intr.sdca_cascade = sdca_cascade;
++                                      slave_intr.control_port = clear;
++                                      memcpy(slave_intr.port, &port_status,
++                                             sizeof(slave_intr.port));
++
++                                      drv->ops->interrupt_callback(slave, &slave_intr);
++                              }
++                      }
++
++                      mutex_unlock(&slave->sdw_dev_lock);
+               }
+               /* Ack interrupt */
+@@ -1697,29 +1714,21 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave)
+ static int sdw_update_slave_status(struct sdw_slave *slave,
+                                  enum sdw_slave_status status)
+ {
+-      unsigned long time;
++      int ret = 0;
+-      if (!slave->probed) {
+-              /*
+-               * the slave status update is typically handled in an
+-               * interrupt thread, which can race with the driver
+-               * probe, e.g. when a module needs to be loaded.
+-               *
+-               * make sure the probe is complete before updating
+-               * status.
+-               */
+-              time = wait_for_completion_timeout(&slave->probe_complete,
+-                              msecs_to_jiffies(DEFAULT_PROBE_TIMEOUT));
+-              if (!time) {
+-                      dev_err(&slave->dev, "Probe not complete, timed out\n");
+-                      return -ETIMEDOUT;
+-              }
++      mutex_lock(&slave->sdw_dev_lock);
++
++      if (slave->probed) {
++              struct device *dev = &slave->dev;
++              struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
++
++              if (drv->ops && drv->ops->update_status)
++                      ret = drv->ops->update_status(slave, status);
+       }
+-      if (!slave->ops || !slave->ops->update_status)
+-              return 0;
++      mutex_unlock(&slave->sdw_dev_lock);
+-      return slave->ops->update_status(slave, status);
++      return ret;
+ }
+ /**
+diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c
+index b81e04dd3a9f..04b3529f8929 100644
+--- a/drivers/soundwire/bus_type.c
++++ b/drivers/soundwire/bus_type.c
+@@ -98,8 +98,6 @@ static int sdw_drv_probe(struct device *dev)
+       if (!id)
+               return -ENODEV;
+-      slave->ops = drv->ops;
+-
+       /*
+        * attach to power domain but don't turn on (last arg)
+        */
+@@ -107,19 +105,23 @@ static int sdw_drv_probe(struct device *dev)
+       if (ret)
+               return ret;
++      mutex_lock(&slave->sdw_dev_lock);
++
+       ret = drv->probe(slave, id);
+       if (ret) {
+               name = drv->name;
+               if (!name)
+                       name = drv->driver.name;
++              mutex_unlock(&slave->sdw_dev_lock);
++
+               dev_err(dev, "Probe of %s failed: %d\n", name, ret);
+               dev_pm_domain_detach(dev, false);
+               return ret;
+       }
+       /* device is probed so let's read the properties now */
+-      if (slave->ops && slave->ops->read_prop)
+-              slave->ops->read_prop(slave);
++      if (drv->ops && drv->ops->read_prop)
++              drv->ops->read_prop(slave);
+       /* init the sysfs as we have properties now */
+       ret = sdw_slave_sysfs_init(slave);
+@@ -139,7 +141,19 @@ static int sdw_drv_probe(struct device *dev)
+                                            slave->prop.clk_stop_timeout);
+       slave->probed = true;
+-      complete(&slave->probe_complete);
++
++      /*
++       * if the probe happened after the bus was started, notify the codec driver
++       * of the current hardware status to e.g. start the initialization.
++       * Errors are only logged as warnings to avoid failing the probe.
++       */
++      if (drv->ops && drv->ops->update_status) {
++              ret = drv->ops->update_status(slave, slave->status);
++              if (ret < 0)
++                      dev_warn(dev, "%s: update_status failed with status %d\n", __func__, ret);
++      }
++
++      mutex_unlock(&slave->sdw_dev_lock);
+       dev_dbg(dev, "probe complete\n");
+@@ -152,9 +166,15 @@ static int sdw_drv_remove(struct device *dev)
+       struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
+       int ret = 0;
++      mutex_lock(&slave->sdw_dev_lock);
++
++      slave->probed = false;
++
+       if (drv->remove)
+               ret = drv->remove(slave);
++      mutex_unlock(&slave->sdw_dev_lock);
++
+       dev_pm_domain_detach(dev, false);
+       return ret;
+diff --git a/drivers/soundwire/slave.c b/drivers/soundwire/slave.c
+index 669d7573320b..25e76b5d4a1a 100644
+--- a/drivers/soundwire/slave.c
++++ b/drivers/soundwire/slave.c
+@@ -12,6 +12,7 @@ static void sdw_slave_release(struct device *dev)
+ {
+       struct sdw_slave *slave = dev_to_sdw_dev(dev);
++      mutex_destroy(&slave->sdw_dev_lock);
+       kfree(slave);
+ }
+@@ -58,9 +59,9 @@ int sdw_slave_add(struct sdw_bus *bus,
+       init_completion(&slave->enumeration_complete);
+       init_completion(&slave->initialization_complete);
+       slave->dev_num = 0;
+-      init_completion(&slave->probe_complete);
+       slave->probed = false;
+       slave->first_interrupt_done = false;
++      mutex_init(&slave->sdw_dev_lock);
+       for (i = 0; i < SDW_MAX_PORTS; i++)
+               init_completion(&slave->port_ready[i]);
+diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c
+index 5d4f6b308ef7..ebbe138a5626 100644
+--- a/drivers/soundwire/stream.c
++++ b/drivers/soundwire/stream.c
+@@ -13,6 +13,7 @@
+ #include <linux/slab.h>
+ #include <linux/soundwire/sdw_registers.h>
+ #include <linux/soundwire/sdw.h>
++#include <linux/soundwire/sdw_type.h>
+ #include <sound/soc.h>
+ #include "bus.h"
+@@ -401,20 +402,26 @@ static int sdw_do_port_prep(struct sdw_slave_runtime *s_rt,
+                           struct sdw_prepare_ch prep_ch,
+                           enum sdw_port_prep_ops cmd)
+ {
+-      const struct sdw_slave_ops *ops = s_rt->slave->ops;
+-      int ret;
++      int ret = 0;
++      struct sdw_slave *slave = s_rt->slave;
+-      if (ops->port_prep) {
+-              ret = ops->port_prep(s_rt->slave, &prep_ch, cmd);
+-              if (ret < 0) {
+-                      dev_err(&s_rt->slave->dev,
+-                              "Slave Port Prep cmd %d failed: %d\n",
+-                              cmd, ret);
+-                      return ret;
++      mutex_lock(&slave->sdw_dev_lock);
++
++      if (slave->probed) {
++              struct device *dev = &slave->dev;
++              struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
++
++              if (drv->ops && drv->ops->port_prep) {
++                      ret = drv->ops->port_prep(slave, &prep_ch, cmd);
++                      if (ret < 0)
++                              dev_err(dev, "Slave Port Prep cmd %d failed: %d\n",
++                                      cmd, ret);
+               }
+       }
+-      return 0;
++      mutex_unlock(&slave->sdw_dev_lock);
++
++      return ret;
+ }
+ static int sdw_prep_deprep_slave_ports(struct sdw_bus *bus,
+@@ -578,7 +585,7 @@ static int sdw_notify_config(struct sdw_master_runtime *m_rt)
+       struct sdw_slave_runtime *s_rt;
+       struct sdw_bus *bus = m_rt->bus;
+       struct sdw_slave *slave;
+-      int ret = 0;
++      int ret;
+       if (bus->ops->set_bus_conf) {
+               ret = bus->ops->set_bus_conf(bus, &bus->params);
+@@ -589,17 +596,27 @@ static int sdw_notify_config(struct sdw_master_runtime *m_rt)
+       list_for_each_entry(s_rt, &m_rt->slave_rt_list, m_rt_node) {
+               slave = s_rt->slave;
+-              if (slave->ops->bus_config) {
+-                      ret = slave->ops->bus_config(slave, &bus->params);
+-                      if (ret < 0) {
+-                              dev_err(bus->dev, "Notify Slave: %d failed\n",
+-                                      slave->dev_num);
+-                              return ret;
++              mutex_lock(&slave->sdw_dev_lock);
++
++              if (slave->probed) {
++                      struct device *dev = &slave->dev;
++                      struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
++
++                      if (drv->ops && drv->ops->bus_config) {
++                              ret = drv->ops->bus_config(slave, &bus->params);
++                              if (ret < 0) {
++                                      dev_err(dev, "Notify Slave: %d failed\n",
++                                              slave->dev_num);
++                                      mutex_unlock(&slave->sdw_dev_lock);
++                                      return ret;
++                              }
+                       }
+               }
++
++              mutex_unlock(&slave->sdw_dev_lock);
+       }
+-      return ret;
++      return 0;
+ }
+ /**
+diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h
+index 76ce3f3ac0f2..bf6f0decb3f6 100644
+--- a/include/linux/soundwire/sdw.h
++++ b/include/linux/soundwire/sdw.h
+@@ -646,9 +646,6 @@ struct sdw_slave_ops {
+  * @dev_num: Current Device Number, values can be 0 or dev_num_sticky
+  * @dev_num_sticky: one-time static Device Number assigned by Bus
+  * @probed: boolean tracking driver state
+- * @probe_complete: completion utility to control potential races
+- * on startup between driver probe/initialization and SoundWire
+- * Slave state changes/implementation-defined interrupts
+  * @enumeration_complete: completion utility to control potential races
+  * on startup between device enumeration and read/write access to the
+  * Slave device
+@@ -663,6 +660,7 @@ struct sdw_slave_ops {
+  * for a Slave happens for the first time after enumeration
+  * @is_mockup_device: status flag used to squelch errors in the command/control
+  * protocol for SoundWire mockup devices
++ * @sdw_dev_lock: mutex used to protect callbacks/remove races
+  */
+ struct sdw_slave {
+       struct sdw_slave_id id;
+@@ -680,12 +678,12 @@ struct sdw_slave {
+       u16 dev_num;
+       u16 dev_num_sticky;
+       bool probed;
+-      struct completion probe_complete;
+       struct completion enumeration_complete;
+       struct completion initialization_complete;
+       u32 unattach_request;
+       bool first_interrupt_done;
+       bool is_mockup_device;
++      struct mutex sdw_dev_lock; /* protect callbacks/remove races */
+ };
+ #define dev_to_sdw_dev(_dev) container_of(_dev, struct sdw_slave, dev)
+-- 
+2.35.1
+
diff --git a/queue-5.15/spi-fix-simplification-of-devm_spi_register_controll.patch b/queue-5.15/spi-fix-simplification-of-devm_spi_register_controll.patch
new file mode 100644 (file)
index 0000000..9ccc456
--- /dev/null
@@ -0,0 +1,72 @@
+From fb373ae9dd5bf7a8df63a98f699ab364eea4007c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Jul 2022 21:55:04 +0800
+Subject: spi: Fix simplification of devm_spi_register_controller
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 43cc5a0afe4184a7fafe1eba32b5a11bb69c9ce0 ]
+
+This reverts commit 59ebbe40fb51 ("spi: simplify
+devm_spi_register_controller").
+
+If devm_add_action() fails in devm_add_action_or_reset(),
+devm_spi_unregister() will be called, it decreases the
+refcount of 'ctlr->dev' to 0, then it will cause uaf in
+the drivers that calling spi_put_controller() in error path.
+
+Fixes: 59ebbe40fb51 ("spi: simplify devm_spi_register_controller")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Link: https://lore.kernel.org/r/20220712135504.1055688-1-yangyingliang@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi.c | 19 ++++++++++++++-----
+ 1 file changed, 14 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
+index d0bbf8f9414d..556d65af5e23 100644
+--- a/drivers/spi/spi.c
++++ b/drivers/spi/spi.c
+@@ -2949,9 +2949,9 @@ int spi_register_controller(struct spi_controller *ctlr)
+ }
+ EXPORT_SYMBOL_GPL(spi_register_controller);
+-static void devm_spi_unregister(void *ctlr)
++static void devm_spi_unregister(struct device *dev, void *res)
+ {
+-      spi_unregister_controller(ctlr);
++      spi_unregister_controller(*(struct spi_controller **)res);
+ }
+ /**
+@@ -2970,13 +2970,22 @@ static void devm_spi_unregister(void *ctlr)
+ int devm_spi_register_controller(struct device *dev,
+                                struct spi_controller *ctlr)
+ {
++      struct spi_controller **ptr;
+       int ret;
++      ptr = devres_alloc(devm_spi_unregister, sizeof(*ptr), GFP_KERNEL);
++      if (!ptr)
++              return -ENOMEM;
++
+       ret = spi_register_controller(ctlr);
+-      if (ret)
+-              return ret;
++      if (!ret) {
++              *ptr = ctlr;
++              devres_add(dev, ptr);
++      } else {
++              devres_free(ptr);
++      }
+-      return devm_add_action_or_reset(dev, devm_spi_unregister, ctlr);
++      return ret;
+ }
+ EXPORT_SYMBOL_GPL(devm_spi_register_controller);
+-- 
+2.35.1
+
diff --git a/queue-5.15/spi-spi-altera-dfl-fix-an-error-handling-path.patch b/queue-5.15/spi-spi-altera-dfl-fix-an-error-handling-path.patch
new file mode 100644 (file)
index 0000000..866f3b8
--- /dev/null
@@ -0,0 +1,68 @@
+From a63f2231dd115ac669e2d147e4b0a92bc1a45ee8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 29 May 2022 08:31:53 +0200
+Subject: spi: spi-altera-dfl: Fix an error handling path
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 8e3ca32f46994e74b7f43c57731150b2aedb2630 ]
+
+The spi_alloc_master() call is not undone in all error handling paths.
+Moreover, there is no .remove function to release the allocated memory.
+
+In order to fix both this issues, switch to devm_spi_alloc_master().
+
+This allows further simplification of the probe.
+
+Fixes: ba2fc167e944 ("spi: altera: Add DFL bus driver for Altera API Controller")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://lore.kernel.org/r/0607bb59f4073f86abe5c585d35245aef0b045c6.1653805901.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-altera-dfl.c | 14 +++++---------
+ 1 file changed, 5 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/spi/spi-altera-dfl.c b/drivers/spi/spi-altera-dfl.c
+index ca40923258af..596e181ae136 100644
+--- a/drivers/spi/spi-altera-dfl.c
++++ b/drivers/spi/spi-altera-dfl.c
+@@ -128,9 +128,9 @@ static int dfl_spi_altera_probe(struct dfl_device *dfl_dev)
+       struct spi_master *master;
+       struct altera_spi *hw;
+       void __iomem *base;
+-      int err = -ENODEV;
++      int err;
+-      master = spi_alloc_master(dev, sizeof(struct altera_spi));
++      master = devm_spi_alloc_master(dev, sizeof(struct altera_spi));
+       if (!master)
+               return -ENOMEM;
+@@ -159,10 +159,9 @@ static int dfl_spi_altera_probe(struct dfl_device *dfl_dev)
+       altera_spi_init_master(master);
+       err = devm_spi_register_master(dev, master);
+-      if (err) {
+-              dev_err(dev, "%s failed to register spi master %d\n", __func__, err);
+-              goto exit;
+-      }
++      if (err)
++              return dev_err_probe(dev, err, "%s failed to register spi master\n",
++                                   __func__);
+       if (dfl_dev->revision == FME_FEATURE_REV_MAX10_SPI_N5010)
+               strscpy(board_info.modalias, "m10-n5010", SPI_NAME_SIZE);
+@@ -179,9 +178,6 @@ static int dfl_spi_altera_probe(struct dfl_device *dfl_dev)
+       }
+       return 0;
+-exit:
+-      spi_master_put(master);
+-      return err;
+ }
+ static const struct dfl_device_id dfl_spi_altera_ids[] = {
+-- 
+2.35.1
+
diff --git a/queue-5.15/spi-spi-rspi-fix-pio-fallback-on-rz-platforms.patch b/queue-5.15/spi-spi-rspi-fix-pio-fallback-on-rz-platforms.patch
new file mode 100644 (file)
index 0000000..efe1e2f
--- /dev/null
@@ -0,0 +1,47 @@
+From 09449c2d70c9d73d7052c521b54518eb54fca129 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Jul 2022 15:34:49 +0100
+Subject: spi: spi-rspi: Fix PIO fallback on RZ platforms
+
+From: Biju Das <biju.das.jz@bp.renesas.com>
+
+[ Upstream commit b620aa3a7be346f04ae7789b165937615c6ee8d3 ]
+
+RSPI IP on RZ/{A, G2L} SoC's has the same signal for both interrupt
+and DMA transfer request. Setting DMARS register for DMA transfer
+makes the signal to work as a DMA transfer request signal and
+subsequent interrupt requests to the interrupt controller
+are masked.
+
+PIO fallback does not work as interrupt signal is disabled.
+
+This patch fixes this issue by re-enabling the interrupts by
+calling dmaengine_synchronize().
+
+Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/20220721143449.879257-1-biju.das.jz@bp.renesas.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-rspi.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
+index d575c935e9f0..f634a405382c 100644
+--- a/drivers/spi/spi-rspi.c
++++ b/drivers/spi/spi-rspi.c
+@@ -612,6 +612,10 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx,
+                                              rspi->dma_callbacked, HZ);
+       if (ret > 0 && rspi->dma_callbacked) {
+               ret = 0;
++              if (tx)
++                      dmaengine_synchronize(rspi->ctlr->dma_tx);
++              if (rx)
++                      dmaengine_synchronize(rspi->ctlr->dma_rx);
+       } else {
+               if (!ret) {
+                       dev_err(&rspi->ctlr->dev, "DMA timeout\n");
+-- 
+2.35.1
+
diff --git a/queue-5.15/spi-synquacer-add-missing-clk_disable_unprepare.patch b/queue-5.15/spi-synquacer-add-missing-clk_disable_unprepare.patch
new file mode 100644 (file)
index 0000000..5c6fbd9
--- /dev/null
@@ -0,0 +1,35 @@
+From dbc6a8050b3c752e16063d578a0a8ffb39e03288 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jun 2022 08:56:14 +0800
+Subject: spi: synquacer: Add missing clk_disable_unprepare()
+
+From: Guo Mengqi <guomengqi3@huawei.com>
+
+[ Upstream commit 917e43de2a56d9b82576f1cc94748261f1988458 ]
+
+Add missing clk_disable_unprepare() in synquacer_spi_resume().
+
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Guo Mengqi <guomengqi3@huawei.com>
+Link: https://lore.kernel.org/r/20220624005614.49434-1-guomengqi3@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-synquacer.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/spi/spi-synquacer.c b/drivers/spi/spi-synquacer.c
+index ea706d9629cb..47cbe73137c2 100644
+--- a/drivers/spi/spi-synquacer.c
++++ b/drivers/spi/spi-synquacer.c
+@@ -783,6 +783,7 @@ static int __maybe_unused synquacer_spi_resume(struct device *dev)
+               ret = synquacer_spi_enable(master);
+               if (ret) {
++                      clk_disable_unprepare(sspi->clk);
+                       dev_err(dev, "failed to enable spi (%d)\n", ret);
+                       return ret;
+               }
+-- 
+2.35.1
+
diff --git a/queue-5.15/spi-tegra20-slink-fix-uaf-in-tegra_slink_remove.patch b/queue-5.15/spi-tegra20-slink-fix-uaf-in-tegra_slink_remove.patch
new file mode 100644 (file)
index 0000000..9b79286
--- /dev/null
@@ -0,0 +1,48 @@
+From fb84855d435e280f7d463059ce7536dbd8bd3804 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 17:40:23 +0800
+Subject: spi: tegra20-slink: fix UAF in tegra_slink_remove()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 7e9984d183bb1e99e766c5c2b950ff21f7f7b6c0 ]
+
+After calling spi_unregister_master(), the refcount of master will
+be decrease to 0, and it will be freed in spi_controller_release(),
+the device data also will be freed, so it will lead a UAF when using
+'tspi'. To fix this, get the master before unregister and put it when
+finish using it.
+
+Fixes: 26c863418221 ("spi: tegra20-slink: Don't use resource-managed spi_register helper")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20220713094024.1508869-1-yangyingliang@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-tegra20-slink.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c
+index 3b44ca455049..cf61bf302a05 100644
+--- a/drivers/spi/spi-tegra20-slink.c
++++ b/drivers/spi/spi-tegra20-slink.c
+@@ -1130,7 +1130,7 @@ static int tegra_slink_probe(struct platform_device *pdev)
+ static int tegra_slink_remove(struct platform_device *pdev)
+ {
+-      struct spi_master *master = platform_get_drvdata(pdev);
++      struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
+       struct tegra_slink_data *tspi = spi_master_get_devdata(master);
+       spi_unregister_master(master);
+@@ -1145,6 +1145,7 @@ static int tegra_slink_remove(struct platform_device *pdev)
+       if (tspi->rx_dma_chan)
+               tegra_slink_deinit_dma_param(tspi, true);
++      spi_master_put(master);
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/stack-declare-randomize_-kstack_offset-to-fix-sparse.patch b/queue-5.15/stack-declare-randomize_-kstack_offset-to-fix-sparse.patch
new file mode 100644 (file)
index 0000000..f39dbe0
--- /dev/null
@@ -0,0 +1,47 @@
+From a1145c720b67f150e937dbd5e7af02f945f663c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Jun 2022 14:04:23 +0800
+Subject: stack: Declare {randomize_,}kstack_offset to fix Sparse warnings
+
+From: GONG, Ruiqi <gongruiqi1@huawei.com>
+
+[ Upstream commit 375561bd6195a31bf4c109732bd538cb97a941f4 ]
+
+Fix the following Sparse warnings that got noticed when the PPC-dev
+patchwork was checking another patch (see the link below):
+
+init/main.c:862:1: warning: symbol 'randomize_kstack_offset' was not declared. Should it be static?
+init/main.c:864:1: warning: symbol 'kstack_offset' was not declared. Should it be static?
+
+Which in fact are triggered on all architectures that have
+HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET support (for instances x86, arm64
+etc).
+
+Link: https://lore.kernel.org/lkml/e7b0d68b-914d-7283-827c-101988923929@huawei.com/T/#m49b2d4490121445ce4bf7653500aba59eefcb67f
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: Xiu Jianfeng <xiujianfeng@huawei.com>
+Signed-off-by: GONG, Ruiqi <gongruiqi1@huawei.com>
+Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Fixes: 39218ff4c625 ("stack: Optionally randomize kernel stack offset each syscall")
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Link: https://lore.kernel.org/r/20220629060423.2515693-1-gongruiqi1@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ init/main.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/init/main.c b/init/main.c
+index cf79b5a766cb..649d9e4201a8 100644
+--- a/init/main.c
++++ b/init/main.c
+@@ -100,6 +100,7 @@
+ #include <linux/kcsan.h>
+ #include <linux/init_syscalls.h>
+ #include <linux/stackdepot.h>
++#include <linux/randomize_kstack.h>
+ #include <net/net_namespace.h>
+ #include <asm/io.h>
+-- 
+2.35.1
+
diff --git a/queue-5.15/staging-rtl8192u-fix-sleep-in-atomic-context-bug-in-.patch b/queue-5.15/staging-rtl8192u-fix-sleep-in-atomic-context-bug-in-.patch
new file mode 100644 (file)
index 0000000..f1f949a
--- /dev/null
@@ -0,0 +1,150 @@
+From b61199642f0bc3e9eb3fec0675a447d88c13a1e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 10 Jul 2022 18:30:02 +0800
+Subject: staging: rtl8192u: Fix sleep in atomic context bug in
+ dm_fsync_timer_callback
+
+From: Duoming Zhou <duoming@zju.edu.cn>
+
+[ Upstream commit 6a0c054930d554ad8f8044ef1fc856d9da391c81 ]
+
+There are sleep in atomic context bugs when dm_fsync_timer_callback is
+executing. The root cause is that the memory allocation functions with
+GFP_KERNEL or GFP_NOIO parameters are called in dm_fsync_timer_callback
+which is a timer handler. The call paths that could trigger bugs are
+shown below:
+
+    (interrupt context)
+dm_fsync_timer_callback
+  write_nic_byte
+    kzalloc(sizeof(data), GFP_KERNEL); //may sleep
+    usb_control_msg
+      kmalloc(.., GFP_NOIO); //may sleep
+  write_nic_dword
+    kzalloc(sizeof(data), GFP_KERNEL); //may sleep
+    usb_control_msg
+      kmalloc(.., GFP_NOIO); //may sleep
+
+This patch uses delayed work to replace timer and moves the operations
+that may sleep into the delayed work in order to mitigate bugs.
+
+Fixes: 8fc8598e61f6 ("Staging: Added Realtek rtl8192u driver to staging")
+Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
+Link: https://lore.kernel.org/r/20220710103002.63283-1-duoming@zju.edu.cn
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/rtl8192u/r8192U.h    |  2 +-
+ drivers/staging/rtl8192u/r8192U_dm.c | 38 +++++++++++++---------------
+ drivers/staging/rtl8192u/r8192U_dm.h |  2 +-
+ 3 files changed, 20 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/staging/rtl8192u/r8192U.h b/drivers/staging/rtl8192u/r8192U.h
+index 4013107cd93a..a23d6d41de9d 100644
+--- a/drivers/staging/rtl8192u/r8192U.h
++++ b/drivers/staging/rtl8192u/r8192U.h
+@@ -1013,7 +1013,7 @@ typedef struct r8192_priv {
+       bool            bis_any_nonbepkts;
+       bool            bcurrent_turbo_EDCA;
+       bool            bis_cur_rdlstate;
+-      struct timer_list fsync_timer;
++      struct delayed_work fsync_work;
+       bool bfsync_processing; /* 500ms Fsync timer is active or not */
+       u32     rate_record;
+       u32     rateCountDiffRecord;
+diff --git a/drivers/staging/rtl8192u/r8192U_dm.c b/drivers/staging/rtl8192u/r8192U_dm.c
+index 725bf5ca9e34..0fcfcaa6500b 100644
+--- a/drivers/staging/rtl8192u/r8192U_dm.c
++++ b/drivers/staging/rtl8192u/r8192U_dm.c
+@@ -2578,19 +2578,20 @@ static void dm_init_fsync(struct net_device *dev)
+       priv->ieee80211->fsync_seconddiff_ratethreshold = 200;
+       priv->ieee80211->fsync_state = Default_Fsync;
+       priv->framesyncMonitor = 1;     /* current default 0xc38 monitor on */
+-      timer_setup(&priv->fsync_timer, dm_fsync_timer_callback, 0);
++      INIT_DELAYED_WORK(&priv->fsync_work, dm_fsync_work_callback);
+ }
+ static void dm_deInit_fsync(struct net_device *dev)
+ {
+       struct r8192_priv *priv = ieee80211_priv(dev);
+-      del_timer_sync(&priv->fsync_timer);
++      cancel_delayed_work_sync(&priv->fsync_work);
+ }
+-void dm_fsync_timer_callback(struct timer_list *t)
++void dm_fsync_work_callback(struct work_struct *work)
+ {
+-      struct r8192_priv *priv = from_timer(priv, t, fsync_timer);
++      struct r8192_priv *priv =
++          container_of(work, struct r8192_priv, fsync_work.work);
+       struct net_device *dev = priv->ieee80211->dev;
+       u32 rate_index, rate_count = 0, rate_count_diff = 0;
+       bool            bSwitchFromCountDiff = false;
+@@ -2657,17 +2658,16 @@ void dm_fsync_timer_callback(struct timer_list *t)
+                       }
+               }
+               if (bDoubleTimeInterval) {
+-                      if (timer_pending(&priv->fsync_timer))
+-                              del_timer_sync(&priv->fsync_timer);
+-                      priv->fsync_timer.expires = jiffies +
+-                              msecs_to_jiffies(priv->ieee80211->fsync_time_interval*priv->ieee80211->fsync_multiple_timeinterval);
+-                      add_timer(&priv->fsync_timer);
++                      cancel_delayed_work_sync(&priv->fsync_work);
++                      schedule_delayed_work(&priv->fsync_work,
++                                            msecs_to_jiffies(priv
++                                            ->ieee80211->fsync_time_interval *
++                                            priv->ieee80211->fsync_multiple_timeinterval));
+               } else {
+-                      if (timer_pending(&priv->fsync_timer))
+-                              del_timer_sync(&priv->fsync_timer);
+-                      priv->fsync_timer.expires = jiffies +
+-                              msecs_to_jiffies(priv->ieee80211->fsync_time_interval);
+-                      add_timer(&priv->fsync_timer);
++                      cancel_delayed_work_sync(&priv->fsync_work);
++                      schedule_delayed_work(&priv->fsync_work,
++                                            msecs_to_jiffies(priv
++                                            ->ieee80211->fsync_time_interval));
+               }
+       } else {
+               /* Let Register return to default value; */
+@@ -2695,7 +2695,7 @@ static void dm_EndSWFsync(struct net_device *dev)
+       struct r8192_priv *priv = ieee80211_priv(dev);
+       RT_TRACE(COMP_HALDM, "%s\n", __func__);
+-      del_timer_sync(&(priv->fsync_timer));
++      cancel_delayed_work_sync(&priv->fsync_work);
+       /* Let Register return to default value; */
+       if (priv->bswitch_fsync) {
+@@ -2736,11 +2736,9 @@ static void dm_StartSWFsync(struct net_device *dev)
+               if (priv->ieee80211->fsync_rate_bitmap &  rateBitmap)
+                       priv->rate_record += priv->stats.received_rate_histogram[1][rateIndex];
+       }
+-      if (timer_pending(&priv->fsync_timer))
+-              del_timer_sync(&priv->fsync_timer);
+-      priv->fsync_timer.expires = jiffies +
+-                      msecs_to_jiffies(priv->ieee80211->fsync_time_interval);
+-      add_timer(&priv->fsync_timer);
++      cancel_delayed_work_sync(&priv->fsync_work);
++      schedule_delayed_work(&priv->fsync_work,
++                            msecs_to_jiffies(priv->ieee80211->fsync_time_interval));
+       write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cd);
+ }
+diff --git a/drivers/staging/rtl8192u/r8192U_dm.h b/drivers/staging/rtl8192u/r8192U_dm.h
+index 0b2a1c688597..2159018b4e38 100644
+--- a/drivers/staging/rtl8192u/r8192U_dm.h
++++ b/drivers/staging/rtl8192u/r8192U_dm.h
+@@ -166,7 +166,7 @@ void dm_force_tx_fw_info(struct net_device *dev,
+ void dm_init_edca_turbo(struct net_device *dev);
+ void dm_rf_operation_test_callback(unsigned long data);
+ void dm_rf_pathcheck_workitemcallback(struct work_struct *work);
+-void dm_fsync_timer_callback(struct timer_list *t);
++void dm_fsync_work_callback(struct work_struct *work);
+ void dm_cck_txpower_adjust(struct net_device *dev, bool  binch14);
+ void dm_shadow_init(struct net_device *dev);
+ void dm_initialize_txpower_tracking(struct net_device *dev);
+-- 
+2.35.1
+
diff --git a/queue-5.15/swiotlb-fail-map-correctly-with-failed-io_tlb_defaul.patch b/queue-5.15/swiotlb-fail-map-correctly-with-failed-io_tlb_defaul.patch
new file mode 100644 (file)
index 0000000..4ebd088
--- /dev/null
@@ -0,0 +1,38 @@
+From 58e6e169c808ec75f381ea210d644d5363fb21ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Jul 2022 08:46:45 +0200
+Subject: swiotlb: fail map correctly with failed io_tlb_default_mem
+
+From: Robin Murphy <robin.murphy@arm.com>
+
+[ Upstream commit c51ba246cb172c9e947dc6fb8868a1eaf0b2a913 ]
+
+In the failure case of trying to use a buffer which we'd previously
+failed to allocate, the "!mem" condition is no longer sufficient since
+io_tlb_default_mem became static and assigned by default. Update the
+condition to work as intended per the rest of that conversion.
+
+Fixes: 463e862ac63e ("swiotlb: Convert io_default_tlb_mem to static allocation")
+Signed-off-by: Robin Murphy <robin.murphy@arm.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/dma/swiotlb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
+index 2ee5419649ed..e62fb7a4da69 100644
+--- a/kernel/dma/swiotlb.c
++++ b/kernel/dma/swiotlb.c
+@@ -551,7 +551,7 @@ phys_addr_t swiotlb_tbl_map_single(struct device *dev, phys_addr_t orig_addr,
+       int index;
+       phys_addr_t tlb_addr;
+-      if (!mem)
++      if (!mem || !mem->nslabs)
+               panic("Can not allocate SWIOTLB buffer earlier and can't now provide you with the DMA bounce buffer");
+       if (mem_encrypt_active())
+-- 
+2.35.1
+
diff --git a/queue-5.15/tcp-make-retransmitted-skb-fit-into-the-send-window.patch b/queue-5.15/tcp-make-retransmitted-skb-fit-into-the-send-window.patch
new file mode 100644 (file)
index 0000000..ae8a852
--- /dev/null
@@ -0,0 +1,112 @@
+From acf8008ea7672ff678eb7dc0f33e605cc71c6cdf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Jul 2022 17:47:18 +0800
+Subject: tcp: make retransmitted SKB fit into the send window
+
+From: Yonglong Li <liyonglong@chinatelecom.cn>
+
+[ Upstream commit 536a6c8e05f95e3d1118c40ae8b3022ee2d05d52 ]
+
+current code of __tcp_retransmit_skb only check TCP_SKB_CB(skb)->seq
+in send window, and TCP_SKB_CB(skb)->seq_end maybe out of send window.
+If receiver has shrunk his window, and skb is out of new window,  it
+should retransmit a smaller portion of the payload.
+
+test packetdrill script:
+    0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+   +0 fcntl(3, F_GETFL) = 0x2 (flags O_RDWR)
+   +0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0
+
+   +0 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress)
+   +0 > S 0:0(0)  win 65535 <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8>
+ +.05 < S. 0:0(0) ack 1 win 6000 <mss 1000,nop,nop,sackOK>
+   +0 > . 1:1(0) ack 1
+
+   +0 write(3, ..., 10000) = 10000
+
+   +0 > . 1:2001(2000) ack 1 win 65535
+   +0 > . 2001:4001(2000) ack 1 win 65535
+   +0 > . 4001:6001(2000) ack 1 win 65535
+
+ +.05 < . 1:1(0) ack 4001 win 1001
+
+and tcpdump show:
+192.168.226.67.55 > 192.0.2.1.8080: Flags [.], seq 1:2001, ack 1, win 65535, length 2000
+192.168.226.67.55 > 192.0.2.1.8080: Flags [.], seq 2001:4001, ack 1, win 65535, length 2000
+192.168.226.67.55 > 192.0.2.1.8080: Flags [P.], seq 4001:5001, ack 1, win 65535, length 1000
+192.168.226.67.55 > 192.0.2.1.8080: Flags [.], seq 5001:6001, ack 1, win 65535, length 1000
+192.0.2.1.8080 > 192.168.226.67.55: Flags [.], ack 4001, win 1001, length 0
+192.168.226.67.55 > 192.0.2.1.8080: Flags [.], seq 5001:6001, ack 1, win 65535, length 1000
+192.168.226.67.55 > 192.0.2.1.8080: Flags [P.], seq 4001:5001, ack 1, win 65535, length 1000
+
+when cient retract window to 1001, send window is [4001,5002],
+but TLP send 5001-6001 packet which is out of send window.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Yonglong Li <liyonglong@chinatelecom.cn>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Link: https://lore.kernel.org/r/1657532838-20200-1-git-send-email-liyonglong@chinatelecom.cn
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_output.c | 23 ++++++++++++++++-------
+ 1 file changed, 16 insertions(+), 7 deletions(-)
+
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
+index 9c9a0f7a3dee..24cadcdb9890 100644
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -3145,7 +3145,7 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs)
+       struct tcp_sock *tp = tcp_sk(sk);
+       unsigned int cur_mss;
+       int diff, len, err;
+-
++      int avail_wnd;
+       /* Inconclusive MTU probe */
+       if (icsk->icsk_mtup.probe_size)
+@@ -3167,17 +3167,25 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs)
+               return -EHOSTUNREACH; /* Routing failure or similar. */
+       cur_mss = tcp_current_mss(sk);
++      avail_wnd = tcp_wnd_end(tp) - TCP_SKB_CB(skb)->seq;
+       /* If receiver has shrunk his window, and skb is out of
+        * new window, do not retransmit it. The exception is the
+        * case, when window is shrunk to zero. In this case
+-       * our retransmit serves as a zero window probe.
++       * our retransmit of one segment serves as a zero window probe.
+        */
+-      if (!before(TCP_SKB_CB(skb)->seq, tcp_wnd_end(tp)) &&
+-          TCP_SKB_CB(skb)->seq != tp->snd_una)
+-              return -EAGAIN;
++      if (avail_wnd <= 0) {
++              if (TCP_SKB_CB(skb)->seq != tp->snd_una)
++                      return -EAGAIN;
++              avail_wnd = cur_mss;
++      }
+       len = cur_mss * segs;
++      if (len > avail_wnd) {
++              len = rounddown(avail_wnd, cur_mss);
++              if (!len)
++                      len = avail_wnd;
++      }
+       if (skb->len > len) {
+               if (tcp_fragment(sk, TCP_FRAG_IN_RTX_QUEUE, skb, len,
+                                cur_mss, GFP_ATOMIC))
+@@ -3191,8 +3199,9 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs)
+               diff -= tcp_skb_pcount(skb);
+               if (diff)
+                       tcp_adjust_pcount(sk, skb, diff);
+-              if (skb->len < cur_mss)
+-                      tcp_retrans_try_collapse(sk, skb, cur_mss);
++              avail_wnd = min_t(int, avail_wnd, cur_mss);
++              if (skb->len < avail_wnd)
++                      tcp_retrans_try_collapse(sk, skb, avail_wnd);
+       }
+       /* RFC3168, section 6.1.1.1. ECN fallback */
+-- 
+2.35.1
+
diff --git a/queue-5.15/test_bpf-fix-incorrect-netdev-features.patch b/queue-5.15/test_bpf-fix-incorrect-netdev-features.patch
new file mode 100644 (file)
index 0000000..d1ef2d2
--- /dev/null
@@ -0,0 +1,42 @@
+From e3a6d63ec212e9d2e2ebd9bc4647d84570a50313 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jun 2022 21:50:02 +0800
+Subject: test_bpf: fix incorrect netdev features
+
+From: Jian Shen <shenjian15@huawei.com>
+
+[ Upstream commit 9676feccacdb0571791c88b23e3b7ac4e7c9c457 ]
+
+The prototype of .features is netdev_features_t, it should use
+NETIF_F_LLTX and NETIF_F_HW_VLAN_STAG_TX, not NETIF_F_LLTX_BIT
+and NETIF_F_HW_VLAN_STAG_TX_BIT.
+
+Fixes: cf204a718357 ("bpf, testing: Introduce 'gso_linear_no_head_frag' skb_segment test")
+Signed-off-by: Jian Shen <shenjian15@huawei.com>
+Acked-by: John Fastabend <john.fastabend@gmail.com>
+Link: https://lore.kernel.org/r/20220622135002.8263-1-shenjian15@huawei.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/test_bpf.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/lib/test_bpf.c b/lib/test_bpf.c
+index 68d125b409f2..84f5dd3b0fc7 100644
+--- a/lib/test_bpf.c
++++ b/lib/test_bpf.c
+@@ -8890,9 +8890,9 @@ static struct skb_segment_test skb_segment_tests[] __initconst = {
+               .build_skb = build_test_skb_linear_no_head_frag,
+               .features = NETIF_F_SG | NETIF_F_FRAGLIST |
+                           NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_GSO |
+-                          NETIF_F_LLTX_BIT | NETIF_F_GRO |
++                          NETIF_F_LLTX | NETIF_F_GRO |
+                           NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM |
+-                          NETIF_F_HW_VLAN_STAG_TX_BIT
++                          NETIF_F_HW_VLAN_STAG_TX
+       }
+ };
+-- 
+2.35.1
+
diff --git a/queue-5.15/thermal-tools-tmon-include-pthread-and-time-headers-.patch b/queue-5.15/thermal-tools-tmon-include-pthread-and-time-headers-.patch
new file mode 100644 (file)
index 0000000..ff7aa64
--- /dev/null
@@ -0,0 +1,62 @@
+From a43de3e1274c98f707fe1e5abf1093e585563f13 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 Jul 2022 20:10:39 -0700
+Subject: thermal/tools/tmon: Include pthread and time headers in tmon.h
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Markus Mayer <mmayer@broadcom.com>
+
+[ Upstream commit 0cf51bfe999524377fbb71becb583b4ca6d07cfc ]
+
+Include sys/time.h and pthread.h in tmon.h, so that types
+"pthread_mutex_t" and "struct timeval tv" are known when tmon.h
+references them.
+
+Without these headers, compiling tmon against musl-libc will fail with
+these errors:
+
+In file included from sysfs.c:31:0:
+tmon.h:47:8: error: unknown type name 'pthread_mutex_t'
+ extern pthread_mutex_t input_lock;
+        ^~~~~~~~~~~~~~~
+make[3]: *** [<builtin>: sysfs.o] Error 1
+make[3]: *** Waiting for unfinished jobs....
+In file included from tui.c:31:0:
+tmon.h:54:17: error: field 'tv' has incomplete type
+  struct timeval tv;
+                 ^~
+make[3]: *** [<builtin>: tui.o] Error 1
+make[2]: *** [Makefile:83: tmon] Error 2
+
+Signed-off-by: Markus Mayer <mmayer@broadcom.com>
+Acked-by: Florian Fainelli <f.fainelli@gmail.com>
+Reviewed-by: Sumeet Pawnikar <sumeet.r.pawnikar@intel.com>
+Acked-by: Alejandro González <alejandro.gonzalez.correo@gmail.com>
+Tested-by: Alejandro González <alejandro.gonzalez.correo@gmail.com>
+Fixes: 94f69966faf8 ("tools/thermal: Introduce tmon, a tool for thermal  subsystem")
+Link: https://lore.kernel.org/r/20220718031040.44714-1-f.fainelli@gmail.com
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/thermal/tmon/tmon.h | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/tools/thermal/tmon/tmon.h b/tools/thermal/tmon/tmon.h
+index c9066ec104dd..44d16d778f04 100644
+--- a/tools/thermal/tmon/tmon.h
++++ b/tools/thermal/tmon/tmon.h
+@@ -27,6 +27,9 @@
+ #define NR_LINES_TZDATA 1
+ #define TMON_LOG_FILE "/var/tmp/tmon.log"
++#include <sys/time.h>
++#include <pthread.h>
++
+ extern unsigned long ticktime;
+ extern double time_elapsed;
+ extern unsigned long target_temp_user;
+-- 
+2.35.1
+
diff --git a/queue-5.15/tools-thermal-fix-possible-path-truncations.patch b/queue-5.15/tools-thermal-fix-possible-path-truncations.patch
new file mode 100644 (file)
index 0000000..57eb4ae
--- /dev/null
@@ -0,0 +1,109 @@
+From b1e3779f9f8ee982beefc0b75516d3432f11cef3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Jul 2022 10:37:54 -0700
+Subject: tools/thermal: Fix possible path truncations
+
+From: Florian Fainelli <f.fainelli@gmail.com>
+
+[ Upstream commit 6c58cf40e3a1d2f47c09d3489857e9476316788a ]
+
+A build with -D_FORTIFY_SOURCE=2 enabled will produce the following warnings:
+
+sysfs.c:63:30: warning: '%s' directive output may be truncated writing up to 255 bytes into a region of size between 0 and 255 [-Wformat-truncation=]
+  snprintf(filepath, 256, "%s/%s", path, filename);
+                              ^~
+Bump up the buffer to PATH_MAX which is the limit and account for all of
+the possible NUL and separators that could lead to exceeding the
+allocated buffer sizes.
+
+Fixes: 94f69966faf8 ("tools/thermal: Introduce tmon, a tool for thermal subsystem")
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/thermal/tmon/sysfs.c | 24 +++++++++++++-----------
+ 1 file changed, 13 insertions(+), 11 deletions(-)
+
+diff --git a/tools/thermal/tmon/sysfs.c b/tools/thermal/tmon/sysfs.c
+index b00b1bfd9d8e..cb1108bc9249 100644
+--- a/tools/thermal/tmon/sysfs.c
++++ b/tools/thermal/tmon/sysfs.c
+@@ -13,6 +13,7 @@
+ #include <stdint.h>
+ #include <dirent.h>
+ #include <libintl.h>
++#include <limits.h>
+ #include <ctype.h>
+ #include <time.h>
+ #include <syslog.h>
+@@ -33,9 +34,9 @@ int sysfs_set_ulong(char *path, char *filename, unsigned long val)
+ {
+       FILE *fd;
+       int ret = -1;
+-      char filepath[256];
++      char filepath[PATH_MAX + 2]; /* NUL and '/' */
+-      snprintf(filepath, 256, "%s/%s", path, filename);
++      snprintf(filepath, sizeof(filepath), "%s/%s", path, filename);
+       fd = fopen(filepath, "w");
+       if (!fd) {
+@@ -57,9 +58,9 @@ static int sysfs_get_ulong(char *path, char *filename, unsigned long *p_ulong)
+ {
+       FILE *fd;
+       int ret = -1;
+-      char filepath[256];
++      char filepath[PATH_MAX + 2]; /* NUL and '/' */
+-      snprintf(filepath, 256, "%s/%s", path, filename);
++      snprintf(filepath, sizeof(filepath), "%s/%s", path, filename);
+       fd = fopen(filepath, "r");
+       if (!fd) {
+@@ -76,9 +77,9 @@ static int sysfs_get_string(char *path, char *filename, char *str)
+ {
+       FILE *fd;
+       int ret = -1;
+-      char filepath[256];
++      char filepath[PATH_MAX + 2]; /* NUL and '/' */
+-      snprintf(filepath, 256, "%s/%s", path, filename);
++      snprintf(filepath, sizeof(filepath), "%s/%s", path, filename);
+       fd = fopen(filepath, "r");
+       if (!fd) {
+@@ -199,8 +200,8 @@ static int find_tzone_cdev(struct dirent *nl, char *tz_name,
+ {
+       unsigned long trip_instance = 0;
+       char cdev_name_linked[256];
+-      char cdev_name[256];
+-      char cdev_trip_name[256];
++      char cdev_name[PATH_MAX];
++      char cdev_trip_name[PATH_MAX];
+       int cdev_id;
+       if (nl->d_type == DT_LNK) {
+@@ -213,7 +214,8 @@ static int find_tzone_cdev(struct dirent *nl, char *tz_name,
+                       return -EINVAL;
+               }
+               /* find the link to real cooling device record binding */
+-              snprintf(cdev_name, 256, "%s/%s", tz_name, nl->d_name);
++              snprintf(cdev_name, sizeof(cdev_name) - 2, "%s/%s",
++                       tz_name, nl->d_name);
+               memset(cdev_name_linked, 0, sizeof(cdev_name_linked));
+               if (readlink(cdev_name, cdev_name_linked,
+                               sizeof(cdev_name_linked) - 1) != -1) {
+@@ -226,8 +228,8 @@ static int find_tzone_cdev(struct dirent *nl, char *tz_name,
+                       /* find the trip point in which the cdev is binded to
+                        * in this tzone
+                        */
+-                      snprintf(cdev_trip_name, 256, "%s%s", nl->d_name,
+-                              "_trip_point");
++                      snprintf(cdev_trip_name, sizeof(cdev_trip_name) - 1,
++                              "%s%s", nl->d_name, "_trip_point");
+                       sysfs_get_ulong(tz_name, cdev_trip_name,
+                                       &trip_instance);
+                       /* validate trip point range, e.g. trip could return -1
+-- 
+2.35.1
+
diff --git a/queue-5.15/tty-n_gsm-delete-gsmtty-open-sabm-frame-when-config-.patch b/queue-5.15/tty-n_gsm-delete-gsmtty-open-sabm-frame-when-config-.patch
new file mode 100644 (file)
index 0000000..1e496a3
--- /dev/null
@@ -0,0 +1,51 @@
+From b6734b32c2fd8b6aa0633afa8c614d2f5531b107 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Aug 2021 20:17:50 +0800
+Subject: tty: n_gsm: Delete gsmtty open SABM frame when config requester
+
+From: Zhenguo Zhao <Zhenguo.Zhao1@unisoc.com>
+
+[ Upstream commit cbff2b32516881bef30bbebf413d1b49495bab1d ]
+
+When n_gsm config "initiator=0",as requester ,it doesn't need to
+send SABM frame data during gsmtty open.
+
+Example,when gsmtty open,it will send SABM frame.for initiator,it
+maybe not want to receive the frame.
+
+[   88.410426] c1 gsmld_output: 00000000: f9 07 3f 01 de f9
+[   88.420839] c1 --> 1) R: SABM(F)
+
+Signed-off-by: Zhenguo Zhao <Zhenguo.Zhao1@unisoc.com>
+Link: https://lore.kernel.org/r/1629461872-26965-6-git-send-email-zhenguo6858@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/n_gsm.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index 4946a241e323..f86c5ebfcf91 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -3214,6 +3214,7 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp)
+ {
+       struct gsm_dlci *dlci = tty->driver_data;
+       struct tty_port *port = &dlci->port;
++      struct gsm_mux *gsm = dlci->gsm;
+       port->count++;
+       tty_port_tty_set(port, tty);
+@@ -3223,7 +3224,8 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp)
+          a DM straight back. This is ok as that will have caused a hangup */
+       tty_port_set_initialized(port, 1);
+       /* Start sending off SABM messages */
+-      gsm_dlci_begin_open(dlci);
++      if (gsm->initiator)
++              gsm_dlci_begin_open(dlci);
+       /* And wait for virtual carrier */
+       return tty_port_block_til_ready(port, tty, filp);
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/tty-n_gsm-fix-dm-command.patch b/queue-5.15/tty-n_gsm-fix-dm-command.patch
new file mode 100644 (file)
index 0000000..c4e86b0
--- /dev/null
@@ -0,0 +1,42 @@
+From a1f4ef5b5f53b121727b0b516331519ecca4a59f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Jul 2022 13:32:21 +0200
+Subject: tty: n_gsm: fix DM command
+
+From: Daniel Starke <daniel.starke@siemens.com>
+
+[ Upstream commit 18a948c7d90995d127785e308fa7b701df4c499f ]
+
+n_gsm is based on the 3GPP 07.010 and its newer version is the 3GPP 27.010.
+See https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=1516
+The changes from 07.010 to 27.010 are non-functional. Therefore, I refer to
+the newer 27.010 here. Chapter 5.3.3 defines the DM response. There exists
+no DM command. However, the current implementation incorrectly sends DM as
+command in case of unexpected UIH frames in gsm_queue().
+Correct this behavior by always sending DM as response.
+
+Fixes: e1eaea46bb40 ("tty: n_gsm line discipline")
+Signed-off-by: Daniel Starke <daniel.starke@siemens.com>
+Link: https://lore.kernel.org/r/20220707113223.3685-2-daniel.starke@siemens.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/n_gsm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index 35504e7e6a35..7a82fff7f5fe 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -2148,7 +2148,7 @@ static void gsm_queue(struct gsm_mux *gsm)
+                       goto invalid;
+ #endif
+               if (dlci == NULL || dlci->state != DLCI_OPEN) {
+-                      gsm_command(gsm, address, DM|PF);
++                      gsm_response(gsm, address, DM|PF);
+                       return;
+               }
+               dlci->data(dlci, gsm->buf, gsm->len);
+-- 
+2.35.1
+
diff --git a/queue-5.15/tty-n_gsm-fix-missing-corner-cases-in-gsmld_poll.patch b/queue-5.15/tty-n_gsm-fix-missing-corner-cases-in-gsmld_poll.patch
new file mode 100644 (file)
index 0000000..c2370a5
--- /dev/null
@@ -0,0 +1,49 @@
+From 321f0c2c27d2bf483a73edb0b384126f39248585 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Jul 2022 13:32:23 +0200
+Subject: tty: n_gsm: fix missing corner cases in gsmld_poll()
+
+From: Daniel Starke <daniel.starke@siemens.com>
+
+[ Upstream commit 7e5b4322cde067e1d0f1bf8f490e93f664a7c843 ]
+
+gsmld_poll() currently fails to handle the following corner cases correctly:
+- remote party closed the associated tty
+
+Add the missing checks and map those to EPOLLHUP.
+Reorder the checks to group them by their reaction.
+
+Fixes: e1eaea46bb40 ("tty: n_gsm line discipline")
+Signed-off-by: Daniel Starke <daniel.starke@siemens.com>
+Link: https://lore.kernel.org/r/20220707113223.3685-4-daniel.starke@siemens.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/n_gsm.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index 7a82fff7f5fe..b89655f585f1 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -2954,12 +2954,15 @@ static __poll_t gsmld_poll(struct tty_struct *tty, struct file *file,
+       poll_wait(file, &tty->read_wait, wait);
+       poll_wait(file, &tty->write_wait, wait);
++
++      if (gsm->dead)
++              mask |= EPOLLHUP;
+       if (tty_hung_up_p(file))
+               mask |= EPOLLHUP;
++      if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
++              mask |= EPOLLHUP;
+       if (!tty_is_writelocked(tty) && tty_write_room(tty) > 0)
+               mask |= EPOLLOUT | EPOLLWRNORM;
+-      if (gsm->dead)
+-              mask |= EPOLLHUP;
+       return mask;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/tty-n_gsm-fix-missing-timer-to-handle-stalled-links.patch b/queue-5.15/tty-n_gsm-fix-missing-timer-to-handle-stalled-links.patch
new file mode 100644 (file)
index 0000000..a53b12e
--- /dev/null
@@ -0,0 +1,147 @@
+From e22f5c3ddbd44b276c451135e141244560a8909b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 08:16:47 +0200
+Subject: tty: n_gsm: fix missing timer to handle stalled links
+
+From: Daniel Starke <daniel.starke@siemens.com>
+
+[ Upstream commit c568f7086c6e771c77aad13d727c70ef70e07243 ]
+
+The current implementation does not handle the situation that no data is in
+the internal queue and needs to be sent out while the user tty fifo is
+full.
+Add a timer that moves more data from user tty down to the internal queue
+which is then serialized on the ldisc. This timer is triggered if no data
+was moved from a user tty to the internal queue within 10 * T1.
+
+Fixes: e1eaea46bb40 ("tty: n_gsm line discipline")
+Signed-off-by: Daniel Starke <daniel.starke@siemens.com>
+Link: https://lore.kernel.org/r/20220701061652.39604-4-daniel.starke@siemens.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/n_gsm.c | 43 +++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 35 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index a554c22e0ee2..271efa7ae793 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -244,6 +244,7 @@ struct gsm_mux {
+       struct list_head tx_list;       /* Pending data packets */
+       /* Control messages */
++      struct timer_list kick_timer;   /* Kick TX queuing on timeout */
+       struct timer_list t2_timer;     /* Retransmit timer for commands */
+       int cretries;                   /* Command retry counter */
+       struct gsm_control *pending_cmd;/* Our current pending command */
+@@ -850,6 +851,7 @@ static void __gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg)
+       list_add_tail(&msg->list, &gsm->tx_list);
+       gsm->tx_bytes += msg->len;
+       gsm_data_kick(gsm, dlci);
++      mod_timer(&gsm->kick_timer, jiffies + 10 * gsm->t1 * HZ / 100);
+ }
+ /**
+@@ -902,9 +904,6 @@ static int gsm_dlci_data_output(struct gsm_mux *gsm, struct gsm_dlci *dlci)
+       size = len + h;
+       msg = gsm_data_alloc(gsm, dlci->addr, size, gsm->ftype);
+-      /* FIXME: need a timer or something to kick this so it can't
+-       * get stuck with no work outstanding and no buffer free
+-       */
+       if (!msg)
+               return -ENOMEM;
+       dp = msg->data;
+@@ -981,9 +980,6 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm,
+       size = len + overhead;
+       msg = gsm_data_alloc(gsm, dlci->addr, size, gsm->ftype);
+-
+-      /* FIXME: need a timer or something to kick this so it can't
+-         get stuck with no work outstanding and no buffer free */
+       if (msg == NULL) {
+               skb_queue_tail(&dlci->skb_list, dlci->skb);
+               dlci->skb = NULL;
+@@ -1079,9 +1075,9 @@ static int gsm_dlci_modem_output(struct gsm_mux *gsm, struct gsm_dlci *dlci,
+  *    renegotiate DLCI priorities with optional stuff. Needs optimising.
+  */
+-static void gsm_dlci_data_sweep(struct gsm_mux *gsm)
++static int gsm_dlci_data_sweep(struct gsm_mux *gsm)
+ {
+-      int len;
++      int len, ret = 0;
+       /* Priority ordering: We should do priority with RR of the groups */
+       int i = 1;
+@@ -1104,7 +1100,11 @@ static void gsm_dlci_data_sweep(struct gsm_mux *gsm)
+               /* DLCI empty - try the next */
+               if (len == 0)
+                       i++;
++              else
++                      ret++;
+       }
++
++      return ret;
+ }
+ /**
+@@ -1837,6 +1837,30 @@ static void gsm_dlci_command(struct gsm_dlci *dlci, const u8 *data, int len)
+       }
+ }
++/**
++ *    gsm_kick_timer  -       transmit if possible
++ *    @t: timer contained in our gsm object
++ *
++ *    Transmit data from DLCIs if the queue is empty. We can't rely on
++ *    a tty wakeup except when we filled the pipe so we need to fire off
++ *    new data ourselves in other cases.
++ */
++static void gsm_kick_timer(struct timer_list *t)
++{
++      struct gsm_mux *gsm = from_timer(gsm, t, kick_timer);
++      unsigned long flags;
++      int sent = 0;
++
++      spin_lock_irqsave(&gsm->tx_lock, flags);
++      /* If we have nothing running then we need to fire up */
++      if (gsm->tx_bytes < TX_THRESH_LO)
++              sent = gsm_dlci_data_sweep(gsm);
++      spin_unlock_irqrestore(&gsm->tx_lock, flags);
++
++      if (sent && debug & 4)
++              pr_info("%s TX queue stalled\n", __func__);
++}
++
+ /*
+  *    Allocate/Free DLCI channels
+  */
+@@ -2326,6 +2350,7 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc)
+       }
+       /* Finish outstanding timers, making sure they are done */
++      del_timer_sync(&gsm->kick_timer);
+       del_timer_sync(&gsm->t2_timer);
+       /* Free up any link layer users and finally the control channel */
+@@ -2358,6 +2383,7 @@ static int gsm_activate_mux(struct gsm_mux *gsm)
+       struct gsm_dlci *dlci;
+       int ret;
++      timer_setup(&gsm->kick_timer, gsm_kick_timer, 0);
+       timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0);
+       init_waitqueue_head(&gsm->event);
+       spin_lock_init(&gsm->control_lock);
+@@ -2762,6 +2788,7 @@ static int gsmld_open(struct tty_struct *tty)
+       gsmld_attach_gsm(tty, gsm);
++      timer_setup(&gsm->kick_timer, gsm_kick_timer, 0);
+       timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0);
+       return 0;
+-- 
+2.35.1
+
diff --git a/queue-5.15/tty-n_gsm-fix-non-flow-control-frames-during-mux-flo.patch b/queue-5.15/tty-n_gsm-fix-non-flow-control-frames-during-mux-flo.patch
new file mode 100644 (file)
index 0000000..860fff7
--- /dev/null
@@ -0,0 +1,116 @@
+From b2c3e5a9973f6ce9318e1ec6c77da7caec6dc8fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 08:16:48 +0200
+Subject: tty: n_gsm: fix non flow control frames during mux flow off
+
+From: Daniel Starke <daniel.starke@siemens.com>
+
+[ Upstream commit bec0224816d19abe4fe503586d16d51890540615 ]
+
+n_gsm is based on the 3GPP 07.010 and its newer version is the 3GPP 27.010.
+See https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=1516
+The changes from 07.010 to 27.010 are non-functional. Therefore, I refer to
+the newer 27.010 here. Chapter 5.4.6.3.6 states that FCoff stops the
+transmission on all channels except the control channel. This is already
+implemented in gsm_data_kick(). However, chapter 5.4.8.1 explains that this
+shall result in the same behavior as software flow control on the ldisc in
+advanced option mode. That means only flow control frames shall be sent
+during flow off. The current implementation does not consider this case.
+
+Change gsm_data_kick() to send only flow control frames if constipated to
+abide the standard. gsm_read_ea_val() and gsm_is_flow_ctrl_msg() are
+introduced as helper functions for this.
+It is planned to use gsm_read_ea_val() in later code cleanups for other
+functions, too.
+
+Fixes: c01af4fec2c8 ("n_gsm : Flow control handling in Mux driver")
+Signed-off-by: Daniel Starke <daniel.starke@siemens.com>
+Link: https://lore.kernel.org/r/20220701061652.39604-5-daniel.starke@siemens.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/n_gsm.c | 54 ++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 53 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index 271efa7ae793..56a3466acfc6 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -425,6 +425,27 @@ static int gsm_read_ea(unsigned int *val, u8 c)
+       return c & EA;
+ }
++/**
++ *    gsm_read_ea_val -       read a value until EA
++ *    @val: variable holding value
++ *    @data: buffer of data
++ *    @dlen: length of data
++ *
++ *    Processes an EA value. Updates the passed variable and
++ *    returns the processed data length.
++ */
++static unsigned int gsm_read_ea_val(unsigned int *val, const u8 *data, int dlen)
++{
++      unsigned int len = 0;
++
++      for (; dlen > 0; dlen--) {
++              len++;
++              if (gsm_read_ea(val, *data++))
++                      break;
++      }
++      return len;
++}
++
+ /**
+  *    gsm_encode_modem        -       encode modem data bits
+  *    @dlci: DLCI to encode from
+@@ -746,6 +767,37 @@ static struct gsm_msg *gsm_data_alloc(struct gsm_mux *gsm, u8 addr, int len,
+       return m;
+ }
++/**
++ *    gsm_is_flow_ctrl_msg    -       checks if flow control message
++ *    @msg: message to check
++ *
++ *    Returns true if the given message is a flow control command of the
++ *    control channel. False is returned in any other case.
++ */
++static bool gsm_is_flow_ctrl_msg(struct gsm_msg *msg)
++{
++      unsigned int cmd;
++
++      if (msg->addr > 0)
++              return false;
++
++      switch (msg->ctrl & ~PF) {
++      case UI:
++      case UIH:
++              cmd = 0;
++              if (gsm_read_ea_val(&cmd, msg->data + 2, msg->len - 2) < 1)
++                      break;
++              switch (cmd & ~PF) {
++              case CMD_FCOFF:
++              case CMD_FCON:
++                      return true;
++              }
++              break;
++      }
++
++      return false;
++}
++
+ /**
+  *    gsm_data_kick           -       poke the queue
+  *    @gsm: GSM Mux
+@@ -765,7 +817,7 @@ static void gsm_data_kick(struct gsm_mux *gsm, struct gsm_dlci *dlci)
+       int len;
+       list_for_each_entry_safe(msg, nmsg, &gsm->tx_list, list) {
+-              if (gsm->constipated && msg->addr)
++              if (gsm->constipated && !gsm_is_flow_ctrl_msg(msg))
+                       continue;
+               if (gsm->encoding != 0) {
+                       gsm->txframe[0] = GSM1_SOF;
+-- 
+2.35.1
+
diff --git a/queue-5.15/tty-n_gsm-fix-packet-re-transmission-without-open-co.patch b/queue-5.15/tty-n_gsm-fix-packet-re-transmission-without-open-co.patch
new file mode 100644 (file)
index 0000000..108560a
--- /dev/null
@@ -0,0 +1,40 @@
+From f25fc23191898b6d29a8eb3d17ebe64231bb1b35 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 08:16:50 +0200
+Subject: tty: n_gsm: fix packet re-transmission without open control channel
+
+From: Daniel Starke <daniel.starke@siemens.com>
+
+[ Upstream commit 4fae831b3a71fc5a44cc5c7d0b8c1267ee7659f5 ]
+
+In the current implementation control packets are re-transmitted even if
+the control channel closed down during T2. This is wrong.
+Check whether the control channel is open before re-transmitting any
+packets. Note that control channel open/close is handled by T1 and not T2
+and remains unaffected by this.
+
+Fixes: e1eaea46bb40 ("tty: n_gsm line discipline")
+Signed-off-by: Daniel Starke <daniel.starke@siemens.com>
+Link: https://lore.kernel.org/r/20220701061652.39604-7-daniel.starke@siemens.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/n_gsm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index 56a3466acfc6..3f65990fc959 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -1546,7 +1546,7 @@ static void gsm_control_retransmit(struct timer_list *t)
+       spin_lock_irqsave(&gsm->control_lock, flags);
+       ctrl = gsm->pending_cmd;
+       if (ctrl) {
+-              if (gsm->cretries == 0) {
++              if (gsm->cretries == 0 || !gsm->dlci[0] || gsm->dlci[0]->dead) {
+                       gsm->pending_cmd = NULL;
+                       ctrl->error = -ETIMEDOUT;
+                       ctrl->done = 1;
+-- 
+2.35.1
+
diff --git a/queue-5.15/tty-n_gsm-fix-race-condition-in-gsmld_write.patch b/queue-5.15/tty-n_gsm-fix-race-condition-in-gsmld_write.patch
new file mode 100644 (file)
index 0000000..bfff4b8
--- /dev/null
@@ -0,0 +1,62 @@
+From 88d80a5c42adaef4bc2f2ea44fe9a6ee815ee499 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 08:16:52 +0200
+Subject: tty: n_gsm: fix race condition in gsmld_write()
+
+From: Daniel Starke <daniel.starke@siemens.com>
+
+[ Upstream commit 32dd59f96924f45e33bc79854f7a00679c0fa28e ]
+
+The function may be used by the user directly and also by the n_gsm
+internal functions. They can lead into a race condition which results in
+interleaved frames if both are writing at the same time. The receiving side
+is not able to decode those interleaved frames correctly.
+
+Add a lock around the low side tty write to avoid race conditions and frame
+interleaving between user originated writes and n_gsm writes.
+
+Fixes: e1eaea46bb40 ("tty: n_gsm line discipline")
+Signed-off-by: Daniel Starke <daniel.starke@siemens.com>
+Link: https://lore.kernel.org/r/20220701061652.39604-9-daniel.starke@siemens.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/n_gsm.c | 21 +++++++++++++++++----
+ 1 file changed, 17 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index 3f65990fc959..23fcb34240ac 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -2911,11 +2911,24 @@ static ssize_t gsmld_read(struct tty_struct *tty, struct file *file,
+ static ssize_t gsmld_write(struct tty_struct *tty, struct file *file,
+                          const unsigned char *buf, size_t nr)
+ {
+-      int space = tty_write_room(tty);
++      struct gsm_mux *gsm = tty->disc_data;
++      unsigned long flags;
++      int space;
++      int ret;
++
++      if (!gsm)
++              return -ENODEV;
++
++      ret = -ENOBUFS;
++      spin_lock_irqsave(&gsm->tx_lock, flags);
++      space = tty_write_room(tty);
+       if (space >= nr)
+-              return tty->ops->write(tty, buf, nr);
+-      set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
+-      return -ENOBUFS;
++              ret = tty->ops->write(tty, buf, nr);
++      else
++              set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
++      spin_unlock_irqrestore(&gsm->tx_lock, flags);
++
++      return ret;
+ }
+ /**
+-- 
+2.35.1
+
diff --git a/queue-5.15/tty-n_gsm-fix-resource-allocation-order-in-gsm_activ.patch b/queue-5.15/tty-n_gsm-fix-resource-allocation-order-in-gsm_activ.patch
new file mode 100644 (file)
index 0000000..807927d
--- /dev/null
@@ -0,0 +1,52 @@
+From 026cdae39c337e0a32e6a9168225dc1bdd3ce385 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 14:23:32 +0200
+Subject: tty: n_gsm: fix resource allocation order in gsm_activate_mux()
+
+From: Daniel Starke <daniel.starke@siemens.com>
+
+[ Upstream commit 7349660438603ed19282e75949561406531785a5 ]
+
+Within gsm_activate_mux() all timers and locks are initiated before the
+actual resource for the control channel is allocated. This can lead to race
+conditions.
+
+Allocate the control channel DLCI object first to avoid race conditions.
+
+Fixes: e1eaea46bb40 ("tty: n_gsm line discipline")
+Signed-off-by: Daniel Starke <daniel.starke@siemens.com>
+Link: https://lore.kernel.org/r/20220701122332.2039-2-daniel.starke@siemens.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/n_gsm.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index 23fcb34240ac..b5ce10b0656f 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -2435,6 +2435,10 @@ static int gsm_activate_mux(struct gsm_mux *gsm)
+       struct gsm_dlci *dlci;
+       int ret;
++      dlci = gsm_dlci_alloc(gsm, 0);
++      if (dlci == NULL)
++              return -ENOMEM;
++
+       timer_setup(&gsm->kick_timer, gsm_kick_timer, 0);
+       timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0);
+       init_waitqueue_head(&gsm->event);
+@@ -2450,9 +2454,6 @@ static int gsm_activate_mux(struct gsm_mux *gsm)
+       if (ret)
+               return ret;
+-      dlci = gsm_dlci_alloc(gsm, 0);
+-      if (dlci == NULL)
+-              return -ENOMEM;
+       gsm->has_devices = true;
+       gsm->dead = false;              /* Tty opens are now permissible */
+       return 0;
+-- 
+2.35.1
+
diff --git a/queue-5.15/tty-n_gsm-fix-tty-registration-before-control-channe.patch b/queue-5.15/tty-n_gsm-fix-tty-registration-before-control-channe.patch
new file mode 100644 (file)
index 0000000..c372bc8
--- /dev/null
@@ -0,0 +1,231 @@
+From 7e734c51dee3e648bed6522e6aaf5b62df8e2272 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 08:16:45 +0200
+Subject: tty: n_gsm: fix tty registration before control channel open
+
+From: Daniel Starke <daniel.starke@siemens.com>
+
+[ Upstream commit 01aecd917114577c423f07cec0d186ad007d76fc ]
+
+The current implementation registers/deregisters the user ttys at mux
+attach/detach. That means that the user devices are available before any
+control channel is open. However, user channel initialization requires an
+open control channel. Furthermore, the user is not informed if the mux
+restarts due to configuration changes.
+Put the registration/deregistration procedure into separate function to
+improve readability.
+Move registration to mux activation and deregistration to mux cleanup to
+keep the user devices only open as long as a control channel exists. The
+user will be informed via the device driver if the mux was reconfigured in
+a way that required a mux re-activation.
+This makes it necessary to add T2 initialization to gsmld_open() for the
+ldisc open code path (not the reconfiguration code path) to avoid deletion
+of an uninitialized T2 at mux cleanup.
+
+Fixes: d50f6dcaf22a ("tty: n_gsm: expose gsmtty device nodes at ldisc open time")
+Signed-off-by: Daniel Starke <daniel.starke@siemens.com>
+Link: https://lore.kernel.org/r/20220701061652.39604-2-daniel.starke@siemens.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/n_gsm.c | 117 ++++++++++++++++++++++++++++++--------------
+ 1 file changed, 79 insertions(+), 38 deletions(-)
+
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index 36d5afa25fbb..9f7a638c6400 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -235,6 +235,7 @@ struct gsm_mux {
+       struct gsm_dlci *dlci[NUM_DLCI];
+       int old_c_iflag;                /* termios c_iflag value before attach */
+       bool constipated;               /* Asked by remote to shut up */
++      bool has_devices;               /* Devices were registered */
+       spinlock_t tx_lock;
+       unsigned int tx_bytes;          /* TX data outstanding */
+@@ -467,6 +468,68 @@ static void gsm_hex_dump_bytes(const char *fname, const u8 *data,
+       kfree(prefix);
+ }
++/**
++ *    gsm_register_devices    -       register all tty devices for a given mux index
++ *
++ *    @driver: the tty driver that describes the tty devices
++ *    @index:  the mux number is used to calculate the minor numbers of the
++ *             ttys for this mux and may differ from the position in the
++ *             mux array.
++ */
++static int gsm_register_devices(struct tty_driver *driver, unsigned int index)
++{
++      struct device *dev;
++      int i;
++      unsigned int base;
++
++      if (!driver || index >= MAX_MUX)
++              return -EINVAL;
++
++      base = index * NUM_DLCI; /* first minor for this index */
++      for (i = 1; i < NUM_DLCI; i++) {
++              /* Don't register device 0 - this is the control channel
++               * and not a usable tty interface
++               */
++              dev = tty_register_device(gsm_tty_driver, base + i, NULL);
++              if (IS_ERR(dev)) {
++                      if (debug & 8)
++                              pr_info("%s failed to register device minor %u",
++                                      __func__, base + i);
++                      for (i--; i >= 1; i--)
++                              tty_unregister_device(gsm_tty_driver, base + i);
++                      return PTR_ERR(dev);
++              }
++      }
++
++      return 0;
++}
++
++/**
++ *    gsm_unregister_devices  -       unregister all tty devices for a given mux index
++ *
++ *    @driver: the tty driver that describes the tty devices
++ *    @index:  the mux number is used to calculate the minor numbers of the
++ *             ttys for this mux and may differ from the position in the
++ *             mux array.
++ */
++static void gsm_unregister_devices(struct tty_driver *driver,
++                                 unsigned int index)
++{
++      int i;
++      unsigned int base;
++
++      if (!driver || index >= MAX_MUX)
++              return;
++
++      base = index * NUM_DLCI; /* first minor for this index */
++      for (i = 1; i < NUM_DLCI; i++) {
++              /* Don't unregister device 0 - this is the control
++               * channel and not a usable tty interface
++               */
++              tty_unregister_device(gsm_tty_driver, base + i);
++      }
++}
++
+ /**
+  *    gsm_print_packet        -       display a frame for debug
+  *    @hdr: header to print before decode
+@@ -2256,6 +2319,10 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc)
+       del_timer_sync(&gsm->t2_timer);
+       /* Free up any link layer users and finally the control channel */
++      if (gsm->has_devices) {
++              gsm_unregister_devices(gsm_tty_driver, gsm->num);
++              gsm->has_devices = false;
++      }
+       for (i = NUM_DLCI - 1; i >= 0; i--)
+               if (gsm->dlci[i])
+                       gsm_dlci_release(gsm->dlci[i]);
+@@ -2279,6 +2346,7 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc)
+ static int gsm_activate_mux(struct gsm_mux *gsm)
+ {
+       struct gsm_dlci *dlci;
++      int ret;
+       timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0);
+       init_waitqueue_head(&gsm->event);
+@@ -2290,9 +2358,14 @@ static int gsm_activate_mux(struct gsm_mux *gsm)
+       else
+               gsm->receive = gsm1_receive;
++      ret = gsm_register_devices(gsm_tty_driver, gsm->num);
++      if (ret)
++              return ret;
++
+       dlci = gsm_dlci_alloc(gsm, 0);
+       if (dlci == NULL)
+               return -ENOMEM;
++      gsm->has_devices = true;
+       gsm->dead = false;              /* Tty opens are now permissible */
+       return 0;
+ }
+@@ -2552,39 +2625,14 @@ static int gsmld_output(struct gsm_mux *gsm, u8 *data, int len)
+  *    will need moving to an ioctl path.
+  */
+-static int gsmld_attach_gsm(struct tty_struct *tty, struct gsm_mux *gsm)
++static void gsmld_attach_gsm(struct tty_struct *tty, struct gsm_mux *gsm)
+ {
+-      unsigned int base;
+-      int ret, i;
+-
+       gsm->tty = tty_kref_get(tty);
+       /* Turn off tty XON/XOFF handling to handle it explicitly. */
+       gsm->old_c_iflag = tty->termios.c_iflag;
+       tty->termios.c_iflag &= (IXON | IXOFF);
+-      ret =  gsm_activate_mux(gsm);
+-      if (ret != 0)
+-              tty_kref_put(gsm->tty);
+-      else {
+-              /* Don't register device 0 - this is the control channel and not
+-                 a usable tty interface */
+-              base = mux_num_to_base(gsm); /* Base for this MUX */
+-              for (i = 1; i < NUM_DLCI; i++) {
+-                      struct device *dev;
+-
+-                      dev = tty_register_device(gsm_tty_driver,
+-                                                      base + i, NULL);
+-                      if (IS_ERR(dev)) {
+-                              for (i--; i >= 1; i--)
+-                                      tty_unregister_device(gsm_tty_driver,
+-                                                              base + i);
+-                              return PTR_ERR(dev);
+-                      }
+-              }
+-      }
+-      return ret;
+ }
+-
+ /**
+  *    gsmld_detach_gsm        -       stop doing 0710 mux
+  *    @tty: tty attached to the mux
+@@ -2595,12 +2643,7 @@ static int gsmld_attach_gsm(struct tty_struct *tty, struct gsm_mux *gsm)
+ static void gsmld_detach_gsm(struct tty_struct *tty, struct gsm_mux *gsm)
+ {
+-      unsigned int base = mux_num_to_base(gsm); /* Base for this MUX */
+-      int i;
+-
+       WARN_ON(tty != gsm->tty);
+-      for (i = 1; i < NUM_DLCI; i++)
+-              tty_unregister_device(gsm_tty_driver, base + i);
+       /* Restore tty XON/XOFF handling. */
+       gsm->tty->termios.c_iflag = gsm->old_c_iflag;
+       tty_kref_put(gsm->tty);
+@@ -2692,7 +2735,6 @@ static void gsmld_close(struct tty_struct *tty)
+ static int gsmld_open(struct tty_struct *tty)
+ {
+       struct gsm_mux *gsm;
+-      int ret;
+       if (tty->ops->write == NULL)
+               return -EINVAL;
+@@ -2708,12 +2750,11 @@ static int gsmld_open(struct tty_struct *tty)
+       /* Attach the initial passive connection */
+       gsm->encoding = 1;
+-      ret = gsmld_attach_gsm(tty, gsm);
+-      if (ret != 0) {
+-              gsm_cleanup_mux(gsm, false);
+-              mux_put(gsm);
+-      }
+-      return ret;
++      gsmld_attach_gsm(tty, gsm);
++
++      timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0);
++
++      return 0;
+ }
+ /**
+-- 
+2.35.1
+
diff --git a/queue-5.15/tty-n_gsm-fix-user-open-not-possible-at-responder-un.patch b/queue-5.15/tty-n_gsm-fix-user-open-not-possible-at-responder-un.patch
new file mode 100644 (file)
index 0000000..aa342ae
--- /dev/null
@@ -0,0 +1,109 @@
+From 7bf74da608384e560baa624015bdea0ad61ffc1f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 08:16:44 +0200
+Subject: tty: n_gsm: fix user open not possible at responder until initiator
+ open
+
+From: Daniel Starke <daniel.starke@siemens.com>
+
+[ Upstream commit ac77f0077c3265197d378158c85a55eee6d21508 ]
+
+After setting up the control channel on both sides the responder side may
+want to open a virtual tty to listen on until the initiator starts an
+application on a user channel. The current implementation allows the
+open() but no other operation, like termios. These fail with EINVAL.
+The responder sided application has no means to detect an open by the
+initiator sided application this way. And the initiator sided applications
+usually expect the responder sided application to listen on the user
+channel upon open.
+Set the user channel into half-open state on responder side once a user
+application opens the virtual tty to allow IO operations on it.
+Furthermore, keep the user channel constipated until the initiator side
+opens it to give the responder sided application the chance to detect the
+new connection and to avoid data loss if the responder sided application
+starts sending before the user channel is open.
+
+Fixes: e1eaea46bb40 ("tty: n_gsm line discipline")
+Signed-off-by: Daniel Starke <daniel.starke@siemens.com>
+Link: https://lore.kernel.org/r/20220701061652.39604-1-daniel.starke@siemens.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/n_gsm.c | 31 +++++++++++++++++++++++++++++--
+ 1 file changed, 29 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index f86c5ebfcf91..36d5afa25fbb 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -1524,6 +1524,8 @@ static void gsm_dlci_close(struct gsm_dlci *dlci)
+       if (debug & 8)
+               pr_debug("DLCI %d goes closed.\n", dlci->addr);
+       dlci->state = DLCI_CLOSED;
++      /* Prevent us from sending data before the link is up again */
++      dlci->constipated = true;
+       if (dlci->addr != 0) {
+               tty_port_tty_hangup(&dlci->port, false);
+               spin_lock_irqsave(&dlci->lock, flags);
+@@ -1553,6 +1555,7 @@ static void gsm_dlci_open(struct gsm_dlci *dlci)
+       del_timer(&dlci->t1);
+       /* This will let a tty open continue */
+       dlci->state = DLCI_OPEN;
++      dlci->constipated = false;
+       if (debug & 8)
+               pr_debug("DLCI %d goes open.\n", dlci->addr);
+       /* Send current modem state */
+@@ -1633,6 +1636,25 @@ static void gsm_dlci_begin_open(struct gsm_dlci *dlci)
+       mod_timer(&dlci->t1, jiffies + gsm->t1 * HZ / 100);
+ }
++/**
++ *    gsm_dlci_set_opening    -       change state to opening
++ *    @dlci: DLCI to open
++ *
++ *    Change internal state to wait for DLCI open from initiator side.
++ *    We set off timers and responses upon reception of an SABM.
++ */
++static void gsm_dlci_set_opening(struct gsm_dlci *dlci)
++{
++      switch (dlci->state) {
++      case DLCI_CLOSED:
++      case DLCI_CLOSING:
++              dlci->state = DLCI_OPENING;
++              break;
++      default:
++              break;
++      }
++}
++
+ /**
+  *    gsm_dlci_begin_close    -       start channel open procedure
+  *    @dlci: DLCI to open
+@@ -1776,10 +1798,13 @@ static struct gsm_dlci *gsm_dlci_alloc(struct gsm_mux *gsm, int addr)
+       dlci->addr = addr;
+       dlci->adaption = gsm->adaption;
+       dlci->state = DLCI_CLOSED;
+-      if (addr)
++      if (addr) {
+               dlci->data = gsm_dlci_data;
+-      else
++              /* Prevent us from sending data before the link is up */
++              dlci->constipated = true;
++      } else {
+               dlci->data = gsm_dlci_command;
++      }
+       gsm->dlci[addr] = dlci;
+       return dlci;
+ }
+@@ -3226,6 +3251,8 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp)
+       /* Start sending off SABM messages */
+       if (gsm->initiator)
+               gsm_dlci_begin_open(dlci);
++      else
++              gsm_dlci_set_opening(dlci);
+       /* And wait for virtual carrier */
+       return tty_port_block_til_ready(port, tty, filp);
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/tty-n_gsm-fix-wrong-queuing-behavior-in-gsm_dlci_dat.patch b/queue-5.15/tty-n_gsm-fix-wrong-queuing-behavior-in-gsm_dlci_dat.patch
new file mode 100644 (file)
index 0000000..32c54f3
--- /dev/null
@@ -0,0 +1,127 @@
+From c0895f1cc4377dc66d840d002952e59d8866389b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 08:16:46 +0200
+Subject: tty: n_gsm: fix wrong queuing behavior in gsm_dlci_data_output()
+
+From: Daniel Starke <daniel.starke@siemens.com>
+
+[ Upstream commit 556fc8ac06513cced381588d6d58c184d95cc4fe ]
+
+1) The function drains the fifo for the given user tty/DLCI without
+considering 'TX_THRESH_HI' and different to gsm_dlci_data_output_framed(),
+which moves only one packet from the user side to the internal transmission
+queue. We can only handle one packet at a time here if we want to allow
+DLCI priority handling in gsm_dlci_data_sweep() to avoid link starvation.
+2) Furthermore, the additional header octet from convergence layer type 2
+is not counted against MTU. It is part of the UI/UIH frame message which
+needs to be limited to MTU. Hence, it is wrong not to consider this octet.
+3) Finally, the waiting user tty is not informed about freed space in its
+send queue.
+
+Take at most one packet worth of data out of the DLCI fifo to fix 1).
+Limit the max user data size per packet to MTU - 1 in case of convergence
+layer type 2 to leave space for the control signal octet which is added in
+the later part of the function. This fixes 2).
+Add tty_port_tty_wakeup() to wake up the user tty if new write space has
+been made available to fix 3).
+
+Fixes: 268e526b935e ("tty/n_gsm: avoid fifo overflow in gsm_dlci_data_output")
+Signed-off-by: Daniel Starke <daniel.starke@siemens.com>
+Link: https://lore.kernel.org/r/20220701061652.39604-3-daniel.starke@siemens.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/n_gsm.c | 74 +++++++++++++++++++++++++--------------------
+ 1 file changed, 42 insertions(+), 32 deletions(-)
+
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index 9f7a638c6400..a554c22e0ee2 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -886,41 +886,51 @@ static int gsm_dlci_data_output(struct gsm_mux *gsm, struct gsm_dlci *dlci)
+ {
+       struct gsm_msg *msg;
+       u8 *dp;
+-      int len, total_size, size;
+-      int h = dlci->adaption - 1;
++      int h, len, size;
+-      total_size = 0;
+-      while (1) {
+-              len = kfifo_len(&dlci->fifo);
+-              if (len == 0)
+-                      return total_size;
+-
+-              /* MTU/MRU count only the data bits */
+-              if (len > gsm->mtu)
+-                      len = gsm->mtu;
+-
+-              size = len + h;
+-
+-              msg = gsm_data_alloc(gsm, dlci->addr, size, gsm->ftype);
+-              /* FIXME: need a timer or something to kick this so it can't
+-                 get stuck with no work outstanding and no buffer free */
+-              if (msg == NULL)
+-                      return -ENOMEM;
+-              dp = msg->data;
+-              switch (dlci->adaption) {
+-              case 1: /* Unstructured */
+-                      break;
+-              case 2: /* Unstructed with modem bits.
+-              Always one byte as we never send inline break data */
+-                      *dp++ = (gsm_encode_modem(dlci) << 1) | EA;
+-                      break;
+-              }
+-              WARN_ON(kfifo_out_locked(&dlci->fifo, dp , len, &dlci->lock) != len);
+-              __gsm_data_queue(dlci, msg);
+-              total_size += size;
++      /* for modem bits without break data */
++      h = ((dlci->adaption == 1) ? 0 : 1);
++
++      len = kfifo_len(&dlci->fifo);
++      if (len == 0)
++              return 0;
++
++      /* MTU/MRU count only the data bits but watch adaption mode */
++      if ((len + h) > gsm->mtu)
++              len = gsm->mtu - h;
++
++      size = len + h;
++
++      msg = gsm_data_alloc(gsm, dlci->addr, size, gsm->ftype);
++      /* FIXME: need a timer or something to kick this so it can't
++       * get stuck with no work outstanding and no buffer free
++       */
++      if (!msg)
++              return -ENOMEM;
++      dp = msg->data;
++      switch (dlci->adaption) {
++      case 1: /* Unstructured */
++              break;
++      case 2: /* Unstructured with modem bits.
++               * Always one byte as we never send inline break data
++               */
++              *dp++ = (gsm_encode_modem(dlci) << 1) | EA;
++              break;
++      default:
++              pr_err("%s: unsupported adaption %d\n", __func__,
++                     dlci->adaption);
++              break;
+       }
++
++      WARN_ON(len != kfifo_out_locked(&dlci->fifo, dp, len,
++              &dlci->lock));
++
++      /* Notify upper layer about available send space. */
++      tty_port_tty_wakeup(&dlci->port);
++
++      __gsm_data_queue(dlci, msg);
+       /* Bytes of data we used up */
+-      return total_size;
++      return size;
+ }
+ /**
+-- 
+2.35.1
+
diff --git a/queue-5.15/tty-n_gsm-fix-wrong-t1-retry-count-handling.patch b/queue-5.15/tty-n_gsm-fix-wrong-t1-retry-count-handling.patch
new file mode 100644 (file)
index 0000000..9f70ed0
--- /dev/null
@@ -0,0 +1,55 @@
+From 3d6adc8810924cca206d77bb24c014b1315624ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Jul 2022 13:32:20 +0200
+Subject: tty: n_gsm: fix wrong T1 retry count handling
+
+From: Daniel Starke <daniel.starke@siemens.com>
+
+[ Upstream commit f30e10caa80aa1f35508bc17fc302dbbde9a833c ]
+
+n_gsm is based on the 3GPP 07.010 and its newer version is the 3GPP 27.010.
+See https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=1516
+The changes from 07.010 to 27.010 are non-functional. Therefore, I refer to
+the newer 27.010 here. Chapter 5.7.3 states that the valid range for the
+maximum number of retransmissions (N2) is from 0 to 255 (both including).
+gsm_dlci_t1() handles this number incorrectly by performing N2 - 1
+retransmission attempts. Setting N2 to zero results in more than 255
+retransmission attempts.
+Fix gsm_dlci_t1() to comply with 3GPP 27.010.
+
+Fixes: e1eaea46bb40 ("tty: n_gsm line discipline")
+Signed-off-by: Daniel Starke <daniel.starke@siemens.com>
+Link: https://lore.kernel.org/r/20220707113223.3685-1-daniel.starke@siemens.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/n_gsm.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index b5ce10b0656f..35504e7e6a35 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -1711,8 +1711,8 @@ static void gsm_dlci_t1(struct timer_list *t)
+       switch (dlci->state) {
+       case DLCI_OPENING:
+-              dlci->retries--;
+               if (dlci->retries) {
++                      dlci->retries--;
+                       gsm_command(dlci->gsm, dlci->addr, SABM|PF);
+                       mod_timer(&dlci->t1, jiffies + gsm->t1 * HZ / 100);
+               } else if (!dlci->addr && gsm->control == (DM | PF)) {
+@@ -1727,8 +1727,8 @@ static void gsm_dlci_t1(struct timer_list *t)
+               break;
+       case DLCI_CLOSING:
+-              dlci->retries--;
+               if (dlci->retries) {
++                      dlci->retries--;
+                       gsm_command(dlci->gsm, dlci->addr, DISC|PF);
+                       mod_timer(&dlci->t1, jiffies + gsm->t1 * HZ / 100);
+               } else
+-- 
+2.35.1
+
diff --git a/queue-5.15/tty-serial-fsl_lpuart-correct-the-count-of-break-cha.patch b/queue-5.15/tty-serial-fsl_lpuart-correct-the-count-of-break-cha.patch
new file mode 100644 (file)
index 0000000..f3840c9
--- /dev/null
@@ -0,0 +1,62 @@
+From e1b7c88945dee1240e0ba6c14298631ddcd760bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Jul 2022 13:01:15 +0800
+Subject: tty: serial: fsl_lpuart: correct the count of break characters
+
+From: Sherry Sun <sherry.sun@nxp.com>
+
+[ Upstream commit 707f816f25590c20e056b3bd4a17ce69b03fe856 ]
+
+The LPUART can't distinguish between a break signal and a framing error,
+so need to count the break characters if there is a framing error and
+received data is zero instead of the parity error.
+
+Fixes: 5541a9bacfe5 ("serial: fsl_lpuart: handle break and make sysrq work")
+Reviewed-by: Michael Walle <michael@walle.cc>
+Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
+Link: https://lore.kernel.org/r/20220725050115.12396-1-sherry.sun@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/fsl_lpuart.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
+index 481107fdd69b..4155bd10711d 100644
+--- a/drivers/tty/serial/fsl_lpuart.c
++++ b/drivers/tty/serial/fsl_lpuart.c
+@@ -982,12 +982,12 @@ static void lpuart32_rxint(struct lpuart_port *sport)
+               if (sr & (UARTSTAT_PE | UARTSTAT_OR | UARTSTAT_FE)) {
+                       if (sr & UARTSTAT_PE) {
++                              sport->port.icount.parity++;
++                      } else if (sr & UARTSTAT_FE) {
+                               if (is_break)
+                                       sport->port.icount.brk++;
+                               else
+-                                      sport->port.icount.parity++;
+-                      } else if (sr & UARTSTAT_FE) {
+-                              sport->port.icount.frame++;
++                                      sport->port.icount.frame++;
+                       }
+                       if (sr & UARTSTAT_OR)
+@@ -1002,12 +1002,12 @@ static void lpuart32_rxint(struct lpuart_port *sport)
+                       sr &= sport->port.read_status_mask;
+                       if (sr & UARTSTAT_PE) {
++                              flg = TTY_PARITY;
++                      } else if (sr & UARTSTAT_FE) {
+                               if (is_break)
+                                       flg = TTY_BREAK;
+                               else
+-                                      flg = TTY_PARITY;
+-                      } else if (sr & UARTSTAT_FE) {
+-                              flg = TTY_FRAME;
++                                      flg = TTY_FRAME;
+                       }
+                       if (sr & UARTSTAT_OR)
+-- 
+2.35.1
+
diff --git a/queue-5.15/um-random-don-t-initialise-hwrng-struct-with-zero.patch b/queue-5.15/um-random-don-t-initialise-hwrng-struct-with-zero.patch
new file mode 100644 (file)
index 0000000..82dba26
--- /dev/null
@@ -0,0 +1,46 @@
+From 08651383f45738824026269998eb69937c845277 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jun 2022 09:58:42 +0100
+Subject: um: random: Don't initialise hwrng struct with zero
+
+From: Christopher Obbard <chris.obbard@collabora.com>
+
+[ Upstream commit 9e70cbd11b03889c92462cf52edb2bd023c798fa ]
+
+Initialising the hwrng struct with zeros causes a
+compile-time sparse warning:
+
+ $ ARCH=um make -j10 W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'
+ ...
+ CHECK   arch/um/drivers/random.c
+ arch/um/drivers/random.c:31:31: sparse: warning: Using plain integer as NULL pointer
+
+Fix the warning by not initialising the hwrng struct
+with zeros as it is initialised anyway during module
+init.
+
+Fixes: 72d3e093afae ("um: random: Register random as hwrng-core device")
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Christopher Obbard <chris.obbard@collabora.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/um/drivers/random.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c
+index 433a3f8f2ef3..32b3341fe970 100644
+--- a/arch/um/drivers/random.c
++++ b/arch/um/drivers/random.c
+@@ -28,7 +28,7 @@
+  * protects against a module being loaded twice at the same time.
+  */
+ static int random_fd = -1;
+-static struct hwrng hwrng = { 0, };
++static struct hwrng hwrng;
+ static DECLARE_COMPLETION(have_data);
+ static int rng_dev_read(struct hwrng *rng, void *buf, size_t max, bool block)
+-- 
+2.35.1
+
diff --git a/queue-5.15/usb-aspeed-vhub-fix-refcount-leak-bug-in-ast_vhub_in.patch b/queue-5.15/usb-aspeed-vhub-fix-refcount-leak-bug-in-ast_vhub_in.patch
new file mode 100644 (file)
index 0000000..42eb31c
--- /dev/null
@@ -0,0 +1,40 @@
+From e68237b082774914e7b642eac2e3be7db62d34cb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 20:05:28 +0800
+Subject: usb: aspeed-vhub: Fix refcount leak bug in ast_vhub_init_desc()
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 220fafb4ed04187e9c17be4152da5a7f2ffbdd8c ]
+
+We should call of_node_put() for the reference returned by
+of_get_child_by_name() which has increased the refcount.
+
+Fixes: 30d2617fd7ed ("usb: gadget: aspeed: allow to set usb strings in device tree")
+Signed-off-by: Liang He <windhl@126.com>
+Link: https://lore.kernel.org/r/20220713120528.368168-1-windhl@126.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/udc/aspeed-vhub/hub.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/udc/aspeed-vhub/hub.c b/drivers/usb/gadget/udc/aspeed-vhub/hub.c
+index b9960fdd8a51..16a12d2d492e 100644
+--- a/drivers/usb/gadget/udc/aspeed-vhub/hub.c
++++ b/drivers/usb/gadget/udc/aspeed-vhub/hub.c
+@@ -1028,8 +1028,10 @@ static int ast_vhub_init_desc(struct ast_vhub *vhub)
+       /* Initialize vhub String Descriptors. */
+       INIT_LIST_HEAD(&vhub->vhub_str_desc);
+       desc_np = of_get_child_by_name(vhub_np, "vhub-strings");
+-      if (desc_np)
++      if (desc_np) {
+               ret = ast_vhub_of_parse_str_desc(vhub, desc_np);
++              of_node_put(desc_np);
++      }
+       else
+               ret = ast_vhub_str_alloc_add(vhub, &ast_vhub_strings);
+-- 
+2.35.1
+
diff --git a/queue-5.15/usb-cdns3-change-place-of-priv_ep-assignment-in-cdns.patch b/queue-5.15/usb-cdns3-change-place-of-priv_ep-assignment-in-cdns.patch
new file mode 100644 (file)
index 0000000..bee290b
--- /dev/null
@@ -0,0 +1,68 @@
+From 6f5f89d115c78772b059a52b3e4fceadde6db687 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 19:00:52 +0300
+Subject: usb: cdns3: change place of 'priv_ep' assignment in
+ cdns3_gadget_ep_dequeue(), cdns3_gadget_ep_enable()
+
+From: Andrey Strachuk <strochuk@ispras.ru>
+
+[ Upstream commit c3ffc9c4ca44bfe9562166793d133e1fb0630ea6 ]
+
+If 'ep' is NULL, result of ep_to_cdns3_ep(ep) is invalid pointer
+and its dereference with priv_ep->cdns3_dev may cause panic.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver")
+Acked-by: Peter Chen <peter.chen@kernel.org>
+Signed-off-by: Andrey Strachuk <strochuk@ispras.ru>
+Link: https://lore.kernel.org/r/20220718160052.4188-1-strochuk@ispras.ru
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/cdns3/cdns3-gadget.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/usb/cdns3/cdns3-gadget.c b/drivers/usb/cdns3/cdns3-gadget.c
+index d6d515d598dc..e0cf62e65075 100644
+--- a/drivers/usb/cdns3/cdns3-gadget.c
++++ b/drivers/usb/cdns3/cdns3-gadget.c
+@@ -2281,14 +2281,15 @@ static int cdns3_gadget_ep_enable(struct usb_ep *ep,
+       int val;
+       priv_ep = ep_to_cdns3_ep(ep);
+-      priv_dev = priv_ep->cdns3_dev;
+-      comp_desc = priv_ep->endpoint.comp_desc;
+       if (!ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT) {
+               dev_dbg(priv_dev->dev, "usbss: invalid parameters\n");
+               return -EINVAL;
+       }
++      comp_desc = priv_ep->endpoint.comp_desc;
++      priv_dev = priv_ep->cdns3_dev;
++
+       if (!desc->wMaxPacketSize) {
+               dev_err(priv_dev->dev, "usbss: missing wMaxPacketSize\n");
+               return -EINVAL;
+@@ -2596,7 +2597,7 @@ int cdns3_gadget_ep_dequeue(struct usb_ep *ep,
+                           struct usb_request *request)
+ {
+       struct cdns3_endpoint *priv_ep = ep_to_cdns3_ep(ep);
+-      struct cdns3_device *priv_dev = priv_ep->cdns3_dev;
++      struct cdns3_device *priv_dev;
+       struct usb_request *req, *req_temp;
+       struct cdns3_request *priv_req;
+       struct cdns3_trb *link_trb;
+@@ -2607,6 +2608,8 @@ int cdns3_gadget_ep_dequeue(struct usb_ep *ep,
+       if (!ep || !request || !ep->desc)
+               return -EINVAL;
++      priv_dev = priv_ep->cdns3_dev;
++
+       spin_lock_irqsave(&priv_dev->lock, flags);
+       priv_req = to_cdns3_request(request);
+-- 
+2.35.1
+
diff --git a/queue-5.15/usb-cdns3-don-t-use-priv_dev-uninitialized-in-cdns3_.patch b/queue-5.15/usb-cdns3-don-t-use-priv_dev-uninitialized-in-cdns3_.patch
new file mode 100644 (file)
index 0000000..cdb2a65
--- /dev/null
@@ -0,0 +1,82 @@
+From a211a6d97612ceecfbaa1d91fe1afd650057e321 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Aug 2022 09:24:22 -0700
+Subject: usb: cdns3: Don't use priv_dev uninitialized in
+ cdns3_gadget_ep_enable()
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+[ Upstream commit 78acd4ca433425e6dd4032cfc2156c60e34931f2 ]
+
+Clang warns:
+
+  drivers/usb/cdns3/cdns3-gadget.c:2290:11: error: variable 'priv_dev' is uninitialized when used here [-Werror,-Wuninitialized]
+                  dev_dbg(priv_dev->dev, "usbss: invalid parameters\n");
+                          ^~~~~~~~
+  include/linux/dev_printk.h:155:18: note: expanded from macro 'dev_dbg'
+          dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
+                          ^~~
+  include/linux/dynamic_debug.h:167:7: note: expanded from macro 'dynamic_dev_dbg'
+                          dev, fmt, ##__VA_ARGS__)
+                          ^~~
+  include/linux/dynamic_debug.h:152:56: note: expanded from macro '_dynamic_func_call'
+          __dynamic_func_call(__UNIQUE_ID(ddebug), fmt, func, ##__VA_ARGS__)
+                                                              ^~~~~~~~~~~
+  include/linux/dynamic_debug.h:134:15: note: expanded from macro '__dynamic_func_call'
+                  func(&id, ##__VA_ARGS__);               \
+                              ^~~~~~~~~~~
+  drivers/usb/cdns3/cdns3-gadget.c:2278:31: note: initialize the variable 'priv_dev' to silence this warning
+          struct cdns3_device *priv_dev;
+                                      ^
+                                      = NULL
+  1 error generated.
+
+The priv_dev assignment was moved below the if statement to avoid
+potentially dereferencing ep before it was checked but priv_dev is used
+in the dev_dbg() call.
+
+To fix this, move the priv_dev and comp_desc assignments back to their
+original spot and hoist the ep check above those assignments with a call
+to pr_debug() instead of dev_dbg().
+
+Fixes: c3ffc9c4ca44 ("usb: cdns3: change place of 'priv_ep' assignment in cdns3_gadget_ep_dequeue(), cdns3_gadget_ep_enable()")
+Link: https://github.com/ClangBuiltLinux/linux/issues/1680
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/cdns3/cdns3-gadget.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/usb/cdns3/cdns3-gadget.c b/drivers/usb/cdns3/cdns3-gadget.c
+index e0cf62e65075..ae049eb28b93 100644
+--- a/drivers/usb/cdns3/cdns3-gadget.c
++++ b/drivers/usb/cdns3/cdns3-gadget.c
+@@ -2280,16 +2280,20 @@ static int cdns3_gadget_ep_enable(struct usb_ep *ep,
+       int ret = 0;
+       int val;
++      if (!ep) {
++              pr_debug("usbss: ep not configured?\n");
++              return -EINVAL;
++      }
++
+       priv_ep = ep_to_cdns3_ep(ep);
++      priv_dev = priv_ep->cdns3_dev;
++      comp_desc = priv_ep->endpoint.comp_desc;
+-      if (!ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT) {
++      if (!desc || desc->bDescriptorType != USB_DT_ENDPOINT) {
+               dev_dbg(priv_dev->dev, "usbss: invalid parameters\n");
+               return -EINVAL;
+       }
+-      comp_desc = priv_ep->endpoint.comp_desc;
+-      priv_dev = priv_ep->cdns3_dev;
+-
+       if (!desc->wMaxPacketSize) {
+               dev_err(priv_dev->dev, "usbss: missing wMaxPacketSize\n");
+               return -EINVAL;
+-- 
+2.35.1
+
diff --git a/queue-5.15/usb-dwc3-core-deprecate-gctl.coresoftreset.patch b/queue-5.15/usb-dwc3-core-deprecate-gctl.coresoftreset.patch
new file mode 100644 (file)
index 0000000..846b12f
--- /dev/null
@@ -0,0 +1,39 @@
+From 02c990733410412a1c065c2087144a3451f69b6f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jun 2022 17:24:32 -0700
+Subject: usb: dwc3: core: Deprecate GCTL.CORESOFTRESET
+
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+
+[ Upstream commit afbd04e66e5d16ca3c7ea2e3c56eca25558eacf3 ]
+
+Synopsys IP DWC_usb32 and DWC_usb31 version 1.90a and above deprecated
+GCTL.CORESOFTRESET. The DRD mode switching flow is updated to remove the
+GCTL soft reset. Add version checks to prevent using deprecated setting
+in mode switching flow.
+
+Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Link: https://lore.kernel.org/r/9df529fde6e55f5508321b6bc26e92848044ef2b.1655338967.git.Thinh.Nguyen@synopsys.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/dwc3/core.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
+index 5cb1350ec66d..8adb26599797 100644
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -159,7 +159,8 @@ static void __dwc3_set_mode(struct work_struct *work)
+       }
+       /* For DRD host or device mode only */
+-      if (dwc->desired_dr_role != DWC3_GCTL_PRTCAP_OTG) {
++      if ((DWC3_IP_IS(DWC3) || DWC3_VER_IS_PRIOR(DWC31, 190A)) &&
++          dwc->desired_dr_role != DWC3_GCTL_PRTCAP_OTG) {
+               reg = dwc3_readl(dwc->regs, DWC3_GCTL);
+               reg |= DWC3_GCTL_CORESOFTRESET;
+               dwc3_writel(dwc->regs, DWC3_GCTL, reg);
+-- 
+2.35.1
+
diff --git a/queue-5.15/usb-dwc3-core-do-not-perform-gctl_core_softreset-dur.patch b/queue-5.15/usb-dwc3-core-do-not-perform-gctl_core_softreset-dur.patch
new file mode 100644 (file)
index 0000000..73068cd
--- /dev/null
@@ -0,0 +1,56 @@
+From c00dcc5ef2cec82cc333a3d436f27e9557aeff25 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 10:26:25 +0530
+Subject: usb: dwc3: core: Do not perform GCTL_CORE_SOFTRESET during bootup
+
+From: Rohith Kollalsi <quic_rkollals@quicinc.com>
+
+[ Upstream commit 07903626d98853e605fe63e5ce149f1b7314bbea ]
+
+According to the programming guide, it is recommended to
+perform a GCTL_CORE_SOFTRESET only when switching the mode
+from device to host or host to device. However, it is found
+that during bootup when __dwc3_set_mode() is called for the
+first time, GCTL_CORESOFTRESET is done with suspendable bit(BIT 17)
+of DWC3_GUSB3PIPECTL set. This some times leads to issues
+like controller going into bad state and controller registers
+reading value zero. Until GCTL_CORESOFTRESET is done and
+run/stop bit is set core initialization is not complete.
+Setting suspendable bit of DWC3_GUSB3PIPECTL and then
+performing GCTL_CORESOFTRESET is therefore not recommended.
+Avoid this by only performing the reset if current_dr_role is set,
+that is, when doing subsequent role switching.
+
+Fixes: f88359e1588b ("usb: dwc3: core: Do core softreset when switch mode")
+Signed-off-by: Rohith Kollalsi <quic_rkollals@quicinc.com>
+Link: https://lore.kernel.org/r/20220714045625.20377-1-quic_rkollals@quicinc.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/dwc3/core.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
+index 8adb26599797..cfac5503aa66 100644
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -158,9 +158,13 @@ static void __dwc3_set_mode(struct work_struct *work)
+               break;
+       }
+-      /* For DRD host or device mode only */
+-      if ((DWC3_IP_IS(DWC3) || DWC3_VER_IS_PRIOR(DWC31, 190A)) &&
+-          dwc->desired_dr_role != DWC3_GCTL_PRTCAP_OTG) {
++      /*
++       * When current_dr_role is not set, there's no role switching.
++       * Only perform GCTL.CoreSoftReset when there's DRD role switching.
++       */
++      if (dwc->current_dr_role && ((DWC3_IP_IS(DWC3) ||
++                      DWC3_VER_IS_PRIOR(DWC31, 190A)) &&
++                      dwc->desired_dr_role != DWC3_GCTL_PRTCAP_OTG)) {
+               reg = dwc3_readl(dwc->regs, DWC3_GCTL);
+               reg |= DWC3_GCTL_CORESOFTRESET;
+               dwc3_writel(dwc->regs, DWC3_GCTL, reg);
+-- 
+2.35.1
+
diff --git a/queue-5.15/usb-dwc3-qcom-fix-missing-optional-irq-warnings.patch b/queue-5.15/usb-dwc3-qcom-fix-missing-optional-irq-warnings.patch
new file mode 100644 (file)
index 0000000..33ebcdf
--- /dev/null
@@ -0,0 +1,44 @@
+From adeafb89fcd47d33b787601ff7030b1d83331e6a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 15:13:36 +0200
+Subject: usb: dwc3: qcom: fix missing optional irq warnings
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+[ Upstream commit 69bb3520db7cecbccc9e497fc568fa5465c9d43f ]
+
+Not all platforms have all of the four currently supported wakeup
+interrupts so use the optional irq helpers when looking up interrupts to
+avoid printing error messages when an optional interrupt is not found:
+
+       dwc3-qcom a6f8800.usb: error -ENXIO: IRQ hs_phy_irq not found
+
+Fixes: a4333c3a6ba9 ("usb: dwc3: Add Qualcomm DWC3 glue driver")
+Reviewed-by: Andrew Halaney <ahalaney@redhat.com>
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Link: https://lore.kernel.org/r/20220713131340.29401-4-johan+linaro@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/dwc3/dwc3-qcom.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c
+index b81a9e1c1315..873bf5041117 100644
+--- a/drivers/usb/dwc3/dwc3-qcom.c
++++ b/drivers/usb/dwc3/dwc3-qcom.c
+@@ -443,9 +443,9 @@ static int dwc3_qcom_get_irq(struct platform_device *pdev,
+       int ret;
+       if (np)
+-              ret = platform_get_irq_byname(pdev_irq, name);
++              ret = platform_get_irq_byname_optional(pdev_irq, name);
+       else
+-              ret = platform_get_irq(pdev_irq, num);
++              ret = platform_get_irq_optional(pdev_irq, num);
+       return ret;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/usb-gadget-tegra-xudc-fix-error-check-in-tegra_xudc_.patch b/queue-5.15/usb-gadget-tegra-xudc-fix-error-check-in-tegra_xudc_.patch
new file mode 100644 (file)
index 0000000..7a441d5
--- /dev/null
@@ -0,0 +1,49 @@
+From 80876feda78243e1e6961b6101c579b252e06eda Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 May 2022 21:53:32 +0800
+Subject: usb: gadget: tegra-xudc: Fix error check in
+ tegra_xudc_powerdomain_init()
+
+From: Tang Bin <tangbin@cmss.chinamobile.com>
+
+[ Upstream commit f08aa7c80dac27ee00fa6827f447597d2fba5465 ]
+
+dev_pm_domain_attach_by_name() may return NULL in some cases,
+so IS_ERR() doesn't meet the requirements. Thus fix it.
+
+Fixes: 49db427232fe ("usb: gadget: Add UDC driver for tegra XUSB device mode controller")
+Signed-off-by: Tang Bin <tangbin@cmss.chinamobile.com>
+Link: https://lore.kernel.org/r/20220525135332.23144-1-tangbin@cmss.chinamobile.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/udc/tegra-xudc.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/usb/gadget/udc/tegra-xudc.c b/drivers/usb/gadget/udc/tegra-xudc.c
+index be76f891b9c5..cb4ddfa52cb0 100644
+--- a/drivers/usb/gadget/udc/tegra-xudc.c
++++ b/drivers/usb/gadget/udc/tegra-xudc.c
+@@ -3689,15 +3689,15 @@ static int tegra_xudc_powerdomain_init(struct tegra_xudc *xudc)
+       int err;
+       xudc->genpd_dev_device = dev_pm_domain_attach_by_name(dev, "dev");
+-      if (IS_ERR(xudc->genpd_dev_device)) {
+-              err = PTR_ERR(xudc->genpd_dev_device);
++      if (IS_ERR_OR_NULL(xudc->genpd_dev_device)) {
++              err = PTR_ERR(xudc->genpd_dev_device) ? : -ENODATA;
+               dev_err(dev, "failed to get device power domain: %d\n", err);
+               return err;
+       }
+       xudc->genpd_dev_ss = dev_pm_domain_attach_by_name(dev, "ss");
+-      if (IS_ERR(xudc->genpd_dev_ss)) {
+-              err = PTR_ERR(xudc->genpd_dev_ss);
++      if (IS_ERR_OR_NULL(xudc->genpd_dev_ss)) {
++              err = PTR_ERR(xudc->genpd_dev_ss) ? : -ENODATA;
+               dev_err(dev, "failed to get SuperSpeed power domain: %d\n", err);
+               return err;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/usb-gadget-udc-amd5536-depends-on-has_dma.patch b/queue-5.15/usb-gadget-udc-amd5536-depends-on-has_dma.patch
new file mode 100644 (file)
index 0000000..7916b68
--- /dev/null
@@ -0,0 +1,49 @@
+From bcc004d28d1a219171fa9320286911e64c7f673a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Jul 2022 18:36:01 -0700
+Subject: usb: gadget: udc: amd5536 depends on HAS_DMA
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 8097cf2fb3b2205257f1c76f4808e3398d66b6d9 ]
+
+USB_AMD5536UDC should depend on HAS_DMA since it selects USB_SNP_CORE,
+which depends on HAS_DMA and since 'select' does not follow any
+dependency chains.
+
+Fixes this kconfig warning:
+
+WARNING: unmet direct dependencies detected for USB_SNP_CORE
+  Depends on [n]: USB_SUPPORT [=y] && USB_GADGET [=y] && (USB_AMD5536UDC [=y] || USB_SNP_UDC_PLAT [=n]) && HAS_DMA [=n]
+  Selected by [y]:
+  - USB_AMD5536UDC [=y] && USB_SUPPORT [=y] && USB_GADGET [=y] && USB_PCI [=y]
+
+Fixes: 97b3ffa233b9 ("usb: gadget: udc: amd5536: split core and PCI layer")
+Cc: Raviteja Garimella <raviteja.garimella@broadcom.com>
+Cc: Felipe Balbi <balbi@kernel.org>
+Cc: linux-usb@vger.kernel.org
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Link: https://lore.kernel.org/r/20220709013601.7536-1-rdunlap@infradead.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/udc/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig
+index 69394dc1cdfb..2cdd37be165a 100644
+--- a/drivers/usb/gadget/udc/Kconfig
++++ b/drivers/usb/gadget/udc/Kconfig
+@@ -311,7 +311,7 @@ source "drivers/usb/gadget/udc/bdc/Kconfig"
+ config USB_AMD5536UDC
+       tristate "AMD5536 UDC"
+-      depends on USB_PCI
++      depends on USB_PCI && HAS_DMA
+       select USB_SNP_CORE
+       help
+          The AMD5536 UDC is part of the AMD Geode CS5536, an x86 southbridge.
+-- 
+2.35.1
+
diff --git a/queue-5.15/usb-host-fix-refcount-leak-in-ehci_hcd_ppc_of_probe.patch b/queue-5.15/usb-host-fix-refcount-leak-in-ehci_hcd_ppc_of_probe.patch
new file mode 100644 (file)
index 0000000..9f32c82
--- /dev/null
@@ -0,0 +1,38 @@
+From c6ff558877c5e3a9fde3585d334f26c5667a6cb3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jun 2022 15:08:49 +0400
+Subject: usb: host: Fix refcount leak in ehci_hcd_ppc_of_probe
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit b5c5b13cb45e2c88181308186b0001992cb41954 ]
+
+of_find_compatible_node() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when done.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: 796bcae7361c ("USB: powerpc: Workaround for the PPC440EPX USBH_23 errata [take 3]")
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Link: https://lore.kernel.org/r/20220602110849.58549-1-linmq006@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/ehci-ppc-of.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c
+index 6bbaee74f7e7..28a19693c19f 100644
+--- a/drivers/usb/host/ehci-ppc-of.c
++++ b/drivers/usb/host/ehci-ppc-of.c
+@@ -148,6 +148,7 @@ static int ehci_hcd_ppc_of_probe(struct platform_device *op)
+               } else {
+                       ehci->has_amcc_usb23 = 1;
+               }
++              of_node_put(np);
+       }
+       if (of_get_property(dn, "big-endian", NULL)) {
+-- 
+2.35.1
+
diff --git a/queue-5.15/usb-host-xhci-use-snprintf-in-xhci_decode_trb.patch b/queue-5.15/usb-host-xhci-use-snprintf-in-xhci_decode_trb.patch
new file mode 100644 (file)
index 0000000..8b39b5b
--- /dev/null
@@ -0,0 +1,42 @@
+From 7c2df4a5617659ebc68c3cb67a0c7e1e7a317502 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Jun 2022 15:46:45 +0300
+Subject: usb: host: xhci: use snprintf() in xhci_decode_trb()
+
+From: Sergey Shtylyov <s.shtylyov@omp.ru>
+
+[ Upstream commit 1ce69c35b86038dd11d3a6115a04501c5b89a940 ]
+
+Commit cbf286e8ef83 ("xhci: fix unsafe memory usage in xhci tracing")
+apparently missed one sprintf() call in xhci_decode_trb() -- replace
+it with the snprintf() call as well...
+
+Found by Linux Verification Center (linuxtesting.org) with the SVACE static
+analysis tool.
+
+Fixes: cbf286e8ef83 ("xhci: fix unsafe memory usage in xhci tracing")
+Signed-off-by: Sergey Shtylyov <s.shtylyov@omp.ru>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20220630124645.1805902-2-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.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
+index 79fa34f1e31c..101f1956a96c 100644
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -2395,7 +2395,7 @@ static inline const char *xhci_decode_trb(char *str, size_t size,
+                       field3 & TRB_CYCLE ? 'C' : 'c');
+               break;
+       case TRB_STOP_RING:
+-              sprintf(str,
++              snprintf(str, size,
+                       "%s: slot %d sp %d ep %d flags %c",
+                       xhci_trb_type_string(type),
+                       TRB_TO_SLOT_ID(field3),
+-- 
+2.35.1
+
diff --git a/queue-5.15/usb-ohci-nxp-fix-refcount-leak-in-ohci_hcd_nxp_probe.patch b/queue-5.15/usb-ohci-nxp-fix-refcount-leak-in-ohci_hcd_nxp_probe.patch
new file mode 100644 (file)
index 0000000..6f6fa8b
--- /dev/null
@@ -0,0 +1,38 @@
+From dac8ee582180d6db736e40121ed977014bbe38b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jun 2022 18:12:30 +0400
+Subject: usb: ohci-nxp: Fix refcount leak in ohci_hcd_nxp_probe
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 302970b4cad3ebfda2c05ce06c322ccdc447d17e ]
+
+of_parse_phandle() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when not need anymore.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: 73108aa90cbf ("USB: ohci-nxp: Use isp1301 driver")
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Link: https://lore.kernel.org/r/20220603141231.979-1-linmq006@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/ohci-nxp.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/usb/host/ohci-nxp.c b/drivers/usb/host/ohci-nxp.c
+index 85878e8ad331..106a6bcefb08 100644
+--- a/drivers/usb/host/ohci-nxp.c
++++ b/drivers/usb/host/ohci-nxp.c
+@@ -164,6 +164,7 @@ static int ohci_hcd_nxp_probe(struct platform_device *pdev)
+       }
+       isp1301_i2c_client = isp1301_get_client(isp1301_node);
++      of_node_put(isp1301_node);
+       if (!isp1301_i2c_client)
+               return -EPROBE_DEFER;
+-- 
+2.35.1
+
diff --git a/queue-5.15/usb-serial-fix-tty-port-initialized-comments.patch b/queue-5.15/usb-serial-fix-tty-port-initialized-comments.patch
new file mode 100644 (file)
index 0000000..6ba542a
--- /dev/null
@@ -0,0 +1,66 @@
+From 97498a3fa2ffa893954648f5c6056c49b8e72e34 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Jul 2022 10:44:57 +0200
+Subject: USB: serial: fix tty-port initialized comments
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit 688ee1d1785c1359f9040f615dd8e6054962bce2 ]
+
+Fix up the tty-port initialized comments which got truncated and
+obfuscated when replacing the old ASYNCB_INITIALIZED flag.
+
+Fixes: d41861ca19c9 ("tty: Replace ASYNC_INITIALIZED bit and update atomically")
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/serial/sierra.c     | 3 ++-
+ drivers/usb/serial/usb-serial.c | 2 +-
+ drivers/usb/serial/usb_wwan.c   | 3 ++-
+ 3 files changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
+index 9d56138133a9..ef6a2891f290 100644
+--- a/drivers/usb/serial/sierra.c
++++ b/drivers/usb/serial/sierra.c
+@@ -737,7 +737,8 @@ static void sierra_close(struct usb_serial_port *port)
+       /*
+        * Need to take susp_lock to make sure port is not already being
+-       * resumed, but no need to hold it due to initialized
++       * resumed, but no need to hold it due to the tty-port initialized
++       * flag.
+        */
+       spin_lock_irq(&intfdata->susp_lock);
+       if (--intfdata->open_ports == 0)
+diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
+index 090a78c948f2..255fb9583c0a 100644
+--- a/drivers/usb/serial/usb-serial.c
++++ b/drivers/usb/serial/usb-serial.c
+@@ -292,7 +292,7 @@ static int serial_open(struct tty_struct *tty, struct file *filp)
+  *
+  * Shut down a USB serial port. Serialized against activate by the
+  * tport mutex and kept to matching open/close pairs
+- * of calls by the initialized flag.
++ * of calls by the tty-port initialized flag.
+  *
+  * Not called if tty is console.
+  */
+diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c
+index cb01283d4d15..f21f25a8cf6f 100644
+--- a/drivers/usb/serial/usb_wwan.c
++++ b/drivers/usb/serial/usb_wwan.c
+@@ -389,7 +389,8 @@ void usb_wwan_close(struct usb_serial_port *port)
+       /*
+        * Need to take susp_lock to make sure port is not already being
+-       * resumed, but no need to hold it due to initialized
++       * resumed, but no need to hold it due to the tty-port initialized
++       * flag.
+        */
+       spin_lock_irq(&intfdata->susp_lock);
+       if (--intfdata->open_ports == 0)
+-- 
+2.35.1
+
diff --git a/queue-5.15/usb-xhci-tegra-fix-error-check.patch b/queue-5.15/usb-xhci-tegra-fix-error-check.patch
new file mode 100644 (file)
index 0000000..357a9cf
--- /dev/null
@@ -0,0 +1,49 @@
+From 87b5af07cc65acb65e6db7668e1d64bca383c6b9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 May 2022 20:14:04 +0800
+Subject: usb: xhci: tegra: Fix error check
+
+From: Tang Bin <tangbin@cmss.chinamobile.com>
+
+[ Upstream commit 18fc7c435be3f17ea26a21b2e2312fcb9088e01f ]
+
+In the function tegra_xusb_powerdomain_init(),
+dev_pm_domain_attach_by_name() may return NULL in some cases,
+so IS_ERR() doesn't meet the requirements. Thus fix it.
+
+Fixes: 6494a9ad86de ("usb: xhci: tegra: Add genpd support")
+Signed-off-by: Tang Bin <tangbin@cmss.chinamobile.com>
+Link: https://lore.kernel.org/r/20220524121404.18376-1-tangbin@cmss.chinamobile.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/xhci-tegra.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c
+index 996958a6565c..bdb776553826 100644
+--- a/drivers/usb/host/xhci-tegra.c
++++ b/drivers/usb/host/xhci-tegra.c
+@@ -1010,15 +1010,15 @@ static int tegra_xusb_powerdomain_init(struct device *dev,
+       int err;
+       tegra->genpd_dev_host = dev_pm_domain_attach_by_name(dev, "xusb_host");
+-      if (IS_ERR(tegra->genpd_dev_host)) {
+-              err = PTR_ERR(tegra->genpd_dev_host);
++      if (IS_ERR_OR_NULL(tegra->genpd_dev_host)) {
++              err = PTR_ERR(tegra->genpd_dev_host) ? : -ENODATA;
+               dev_err(dev, "failed to get host pm-domain: %d\n", err);
+               return err;
+       }
+       tegra->genpd_dev_ss = dev_pm_domain_attach_by_name(dev, "xusb_ss");
+-      if (IS_ERR(tegra->genpd_dev_ss)) {
+-              err = PTR_ERR(tegra->genpd_dev_ss);
++      if (IS_ERR_OR_NULL(tegra->genpd_dev_ss)) {
++              err = PTR_ERR(tegra->genpd_dev_ss) ? : -ENODATA;
+               dev_err(dev, "failed to get superspeed pm-domain: %d\n", err);
+               return err;
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/vfio-ccw-do-not-change-fsm-state-in-subchannel-event.patch b/queue-5.15/vfio-ccw-do-not-change-fsm-state-in-subchannel-event.patch
new file mode 100644 (file)
index 0000000..89754f4
--- /dev/null
@@ -0,0 +1,61 @@
+From 649e93be393bbe10423821ef769bfb8018d24989 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Jul 2022 15:57:29 +0200
+Subject: vfio/ccw: Do not change FSM state in subchannel event
+
+From: Eric Farman <farman@linux.ibm.com>
+
+[ Upstream commit cffcc109fd682075dee79bade3d60a07152a8fd1 ]
+
+The routine vfio_ccw_sch_event() is tasked with handling subchannel events,
+specifically machine checks, on behalf of vfio-ccw. It correctly calls
+cio_update_schib(), and if that fails (meaning the subchannel is gone)
+it makes an FSM event call to mark the subchannel Not Operational.
+
+If that worked, however, then it decides that if the FSM state was already
+Not Operational (implying the subchannel just came back), then it should
+simply change the FSM to partially- or fully-open.
+
+Remove this trickery, since a subchannel returning will require more
+probing than simply "oh all is well again" to ensure it works correctly.
+
+Fixes: bbe37e4cb8970 ("vfio: ccw: introduce a finite state machine")
+Signed-off-by: Eric Farman <farman@linux.ibm.com>
+Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
+Link: https://lore.kernel.org/r/20220707135737.720765-4-farman@linux.ibm.com
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/s390/cio/vfio_ccw_drv.c | 14 +++-----------
+ 1 file changed, 3 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
+index 76099bcb765b..b9091e22ca57 100644
+--- a/drivers/s390/cio/vfio_ccw_drv.c
++++ b/drivers/s390/cio/vfio_ccw_drv.c
+@@ -287,19 +287,11 @@ static int vfio_ccw_sch_event(struct subchannel *sch, int process)
+       if (work_pending(&sch->todo_work))
+               goto out_unlock;
+-      if (cio_update_schib(sch)) {
+-              vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_NOT_OPER);
+-              rc = 0;
+-              goto out_unlock;
+-      }
+-
+-      private = dev_get_drvdata(&sch->dev);
+-      if (private->state == VFIO_CCW_STATE_NOT_OPER) {
+-              private->state = private->mdev ? VFIO_CCW_STATE_IDLE :
+-                               VFIO_CCW_STATE_STANDBY;
+-      }
+       rc = 0;
++      if (cio_update_schib(sch))
++              vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_NOT_OPER);
++
+ out_unlock:
+       spin_unlock_irqrestore(sch->lock, flags);
+-- 
+2.35.1
+
diff --git a/queue-5.15/video-fbdev-amba-clcd-fix-refcount-leak-bugs.patch b/queue-5.15/video-fbdev-amba-clcd-fix-refcount-leak-bugs.patch
new file mode 100644 (file)
index 0000000..ea228fe
--- /dev/null
@@ -0,0 +1,78 @@
+From 781989628154ba98ff018c9c21253bccb1adea2c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 16:25:46 +0800
+Subject: video: fbdev: amba-clcd: Fix refcount leak bugs
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 26c2b7d9fac42eb8317f3ceefa4c1a9a9170ca69 ]
+
+In clcdfb_of_init_display(), we should call of_node_put() for the
+references returned by of_graph_get_next_endpoint() and
+of_graph_get_remote_port_parent() which have increased the refcount.
+
+Besides, we should call of_node_put() both in fail path or when
+the references are not used anymore.
+
+Fixes: d10715be03bd ("video: ARM CLCD: Add DT support")
+Signed-off-by: Liang He <windhl@126.com>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/amba-clcd.c | 24 ++++++++++++++++++------
+ 1 file changed, 18 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/video/fbdev/amba-clcd.c b/drivers/video/fbdev/amba-clcd.c
+index 8080116aea84..f65c96d1394d 100644
+--- a/drivers/video/fbdev/amba-clcd.c
++++ b/drivers/video/fbdev/amba-clcd.c
+@@ -698,16 +698,18 @@ static int clcdfb_of_init_display(struct clcd_fb *fb)
+               return -ENODEV;
+       panel = of_graph_get_remote_port_parent(endpoint);
+-      if (!panel)
+-              return -ENODEV;
++      if (!panel) {
++              err = -ENODEV;
++              goto out_endpoint_put;
++      }
+       err = clcdfb_of_get_backlight(&fb->dev->dev, fb->panel);
+       if (err)
+-              return err;
++              goto out_panel_put;
+       err = clcdfb_of_get_mode(&fb->dev->dev, panel, fb->panel);
+       if (err)
+-              return err;
++              goto out_panel_put;
+       err = of_property_read_u32(fb->dev->dev.of_node, "max-memory-bandwidth",
+                       &max_bandwidth);
+@@ -736,11 +738,21 @@ static int clcdfb_of_init_display(struct clcd_fb *fb)
+       if (of_property_read_u32_array(endpoint,
+                       "arm,pl11x,tft-r0g0b0-pads",
+-                      tft_r0b0g0, ARRAY_SIZE(tft_r0b0g0)) != 0)
+-              return -ENOENT;
++                      tft_r0b0g0, ARRAY_SIZE(tft_r0b0g0)) != 0) {
++              err = -ENOENT;
++              goto out_panel_put;
++      }
++
++      of_node_put(panel);
++      of_node_put(endpoint);
+       return clcdfb_of_init_tft_panel(fb, tft_r0b0g0[0],
+                                       tft_r0b0g0[1],  tft_r0b0g0[2]);
++out_panel_put:
++      of_node_put(panel);
++out_endpoint_put:
++      of_node_put(endpoint);
++      return err;
+ }
+ static int clcdfb_of_vram_setup(struct clcd_fb *fb)
+-- 
+2.35.1
+
diff --git a/queue-5.15/video-fbdev-arkfb-check-the-size-of-screen-before-me.patch b/queue-5.15/video-fbdev-arkfb-check-the-size-of-screen-before-me.patch
new file mode 100644 (file)
index 0000000..d0d48c0
--- /dev/null
@@ -0,0 +1,50 @@
+From ccc10b733a8500e2494993c75c64f9cd7f684402 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Aug 2022 20:41:24 +0800
+Subject: video: fbdev: arkfb: Check the size of screen before memset_io()
+
+From: Zheyu Ma <zheyuma97@gmail.com>
+
+[ Upstream commit 96b550971c65d54d64728d8ba973487878a06454 ]
+
+In the function arkfb_set_par(), the value of 'screen_size' is
+calculated by the user input. If the user provides the improper value,
+the value of 'screen_size' may larger than 'info->screen_size', which
+may cause the following bug:
+
+[  659.399066] BUG: unable to handle page fault for address: ffffc90003000000
+[  659.399077] #PF: supervisor write access in kernel mode
+[  659.399079] #PF: error_code(0x0002) - not-present page
+[  659.399094] RIP: 0010:memset_orig+0x33/0xb0
+[  659.399116] Call Trace:
+[  659.399122]  arkfb_set_par+0x143f/0x24c0
+[  659.399130]  fb_set_var+0x604/0xeb0
+[  659.399161]  do_fb_ioctl+0x234/0x670
+[  659.399189]  fb_ioctl+0xdd/0x130
+
+Fix the this by checking the value of 'screen_size' before memset_io().
+
+Fixes: 681e14730c73 ("arkfb: new framebuffer driver for ARK Logic cards")
+Signed-off-by: Zheyu Ma <zheyuma97@gmail.com>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/arkfb.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/video/fbdev/arkfb.c b/drivers/video/fbdev/arkfb.c
+index d94cc5ad1ef6..8d092b106470 100644
+--- a/drivers/video/fbdev/arkfb.c
++++ b/drivers/video/fbdev/arkfb.c
+@@ -794,6 +794,8 @@ static int arkfb_set_par(struct fb_info *info)
+       value = ((value * hmul / hdiv) / 8) - 5;
+       vga_wcrt(par->state.vgabase, 0x42, (value + 1) / 2);
++      if (screen_size > info->screen_size)
++              screen_size = info->screen_size;
+       memset_io(info->screen_base, 0x00, screen_size);
+       /* Device and screen back on */
+       svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
+-- 
+2.35.1
+
diff --git a/queue-5.15/video-fbdev-arkfb-fix-a-divide-by-zero-bug-in-ark_se.patch b/queue-5.15/video-fbdev-arkfb-fix-a-divide-by-zero-bug-in-ark_se.patch
new file mode 100644 (file)
index 0000000..1ccc5c5
--- /dev/null
@@ -0,0 +1,59 @@
+From 3f551e51ef8a2cdf9ce63539a6b490f126240308 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Aug 2022 17:23:12 +0800
+Subject: video: fbdev: arkfb: Fix a divide-by-zero bug in ark_set_pixclock()
+
+From: Zheyu Ma <zheyuma97@gmail.com>
+
+[ Upstream commit 2f1c4523f7a3aaabe7e53d3ebd378292947e95c8 ]
+
+Since the user can control the arguments of the ioctl() from the user
+space, under special arguments that may result in a divide-by-zero bug
+in:
+  drivers/video/fbdev/arkfb.c:784: ark_set_pixclock(info, (hdiv * info->var.pixclock) / hmul);
+with hdiv=1, pixclock=1 and hmul=2 you end up with (1*1)/2 = (int) 0.
+and then in:
+  drivers/video/fbdev/arkfb.c:504: rv = dac_set_freq(par->dac, 0, 1000000000 / pixclock);
+we'll get a division-by-zero.
+
+The following log can reveal it:
+
+divide error: 0000 [#1] PREEMPT SMP KASAN PTI
+RIP: 0010:ark_set_pixclock drivers/video/fbdev/arkfb.c:504 [inline]
+RIP: 0010:arkfb_set_par+0x10fc/0x24c0 drivers/video/fbdev/arkfb.c:784
+Call Trace:
+ fb_set_var+0x604/0xeb0 drivers/video/fbdev/core/fbmem.c:1034
+ do_fb_ioctl+0x234/0x670 drivers/video/fbdev/core/fbmem.c:1110
+ fb_ioctl+0xdd/0x130 drivers/video/fbdev/core/fbmem.c:1189
+
+Fix this by checking the argument of ark_set_pixclock() first.
+
+Fixes: 681e14730c73 ("arkfb: new framebuffer driver for ARK Logic cards")
+Signed-off-by: Zheyu Ma <zheyuma97@gmail.com>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/arkfb.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/video/fbdev/arkfb.c b/drivers/video/fbdev/arkfb.c
+index edf169d0816e..d94cc5ad1ef6 100644
+--- a/drivers/video/fbdev/arkfb.c
++++ b/drivers/video/fbdev/arkfb.c
+@@ -778,7 +778,12 @@ static int arkfb_set_par(struct fb_info *info)
+               return -EINVAL;
+       }
+-      ark_set_pixclock(info, (hdiv * info->var.pixclock) / hmul);
++      value = (hdiv * info->var.pixclock) / hmul;
++      if (!value) {
++              fb_dbg(info, "invalid pixclock\n");
++              value = 1;
++      }
++      ark_set_pixclock(info, value);
+       svga_set_timings(par->state.vgabase, &ark_timing_regs, &(info->var), hmul, hdiv,
+                        (info->var.vmode & FB_VMODE_DOUBLE)     ? 2 : 1,
+                        (info->var.vmode & FB_VMODE_INTERLACED) ? 2 : 1,
+-- 
+2.35.1
+
diff --git a/queue-5.15/video-fbdev-s3fb-check-the-size-of-screen-before-mem.patch b/queue-5.15/video-fbdev-s3fb-check-the-size-of-screen-before-mem.patch
new file mode 100644 (file)
index 0000000..0e0611c
--- /dev/null
@@ -0,0 +1,49 @@
+From 2b606afdad421a5979fae45d6347712963f5dac0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Aug 2022 20:41:25 +0800
+Subject: video: fbdev: s3fb: Check the size of screen before memset_io()
+
+From: Zheyu Ma <zheyuma97@gmail.com>
+
+[ Upstream commit 6ba592fa014f21f35a8ee8da4ca7b95a018f13e8 ]
+
+In the function s3fb_set_par(), the value of 'screen_size' is
+calculated by the user input. If the user provides the improper value,
+the value of 'screen_size' may larger than 'info->screen_size', which
+may cause the following bug:
+
+[   54.083733] BUG: unable to handle page fault for address: ffffc90003000000
+[   54.083742] #PF: supervisor write access in kernel mode
+[   54.083744] #PF: error_code(0x0002) - not-present page
+[   54.083760] RIP: 0010:memset_orig+0x33/0xb0
+[   54.083782] Call Trace:
+[   54.083788]  s3fb_set_par+0x1ec6/0x4040
+[   54.083806]  fb_set_var+0x604/0xeb0
+[   54.083836]  do_fb_ioctl+0x234/0x670
+
+Fix the this by checking the value of 'screen_size' before memset_io().
+
+Fixes: a268422de8bf ("fbdev driver for S3 Trio/Virge")
+Signed-off-by: Zheyu Ma <zheyuma97@gmail.com>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/s3fb.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/video/fbdev/s3fb.c b/drivers/video/fbdev/s3fb.c
+index 5c74253e7b2c..a936455a3df2 100644
+--- a/drivers/video/fbdev/s3fb.c
++++ b/drivers/video/fbdev/s3fb.c
+@@ -902,6 +902,8 @@ static int s3fb_set_par(struct fb_info *info)
+       value = clamp((htotal + hsstart + 1) / 2 + 2, hsstart + 4, htotal + 1);
+       svga_wcrt_multi(par->state.vgabase, s3_dtpc_regs, value);
++      if (screen_size > info->screen_size)
++              screen_size = info->screen_size;
+       memset_io(info->screen_base, 0x00, screen_size);
+       /* Device and screen back on */
+       svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
+-- 
+2.35.1
+
diff --git a/queue-5.15/video-fbdev-sis-fix-typos-in-sis_getmodeid.patch b/queue-5.15/video-fbdev-sis-fix-typos-in-sis_getmodeid.patch
new file mode 100644 (file)
index 0000000..42f0e78
--- /dev/null
@@ -0,0 +1,47 @@
+From c53186394e4141687e1f5c99b853bec223ad5907 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 15:43:43 +0300
+Subject: video: fbdev: sis: fix typos in SiS_GetModeID()
+
+From: Rustam Subkhankulov <subkhankulov@ispras.ru>
+
+[ Upstream commit 3eb8fccc244bfb41a7961969e4db280d44911226 ]
+
+The second operand of a '&&' operator has no impact on expression
+result for cases 400 and 512 in SiS_GetModeID().
+
+Judging by the logic and the names of the variables, in both cases a
+typo was made.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Signed-off-by: Rustam Subkhankulov <subkhankulov@ispras.ru>
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/sis/init.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/video/fbdev/sis/init.c b/drivers/video/fbdev/sis/init.c
+index b568c646a76c..2ba91d62af92 100644
+--- a/drivers/video/fbdev/sis/init.c
++++ b/drivers/video/fbdev/sis/init.c
+@@ -355,12 +355,12 @@ SiS_GetModeID(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay,
+               }
+               break;
+       case 400:
+-              if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 800) && (LCDwidth >= 600))) {
++              if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 800) && (LCDheight >= 600))) {
+                       if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
+               }
+               break;
+       case 512:
+-              if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 1024) && (LCDwidth >= 768))) {
++              if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 1024) && (LCDheight >= 768))) {
+                       if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
+               }
+               break;
+-- 
+2.35.1
+
diff --git a/queue-5.15/video-fbdev-vt8623fb-check-the-size-of-screen-before.patch b/queue-5.15/video-fbdev-vt8623fb-check-the-size-of-screen-before.patch
new file mode 100644 (file)
index 0000000..7e5fc22
--- /dev/null
@@ -0,0 +1,50 @@
+From c03e2f3b2333cfe2b97549bf7db8a86e94178a06 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Aug 2022 20:41:23 +0800
+Subject: video: fbdev: vt8623fb: Check the size of screen before memset_io()
+
+From: Zheyu Ma <zheyuma97@gmail.com>
+
+[ Upstream commit ec0754c60217248fa77cc9005d66b2b55200ac06 ]
+
+In the function vt8623fb_set_par(), the value of 'screen_size' is
+calculated by the user input. If the user provides the improper value,
+the value of 'screen_size' may larger than 'info->screen_size', which
+may cause the following bug:
+
+[  583.339036] BUG: unable to handle page fault for address: ffffc90005000000
+[  583.339049] #PF: supervisor write access in kernel mode
+[  583.339052] #PF: error_code(0x0002) - not-present page
+[  583.339074] RIP: 0010:memset_orig+0x33/0xb0
+[  583.339110] Call Trace:
+[  583.339118]  vt8623fb_set_par+0x11cd/0x21e0
+[  583.339146]  fb_set_var+0x604/0xeb0
+[  583.339181]  do_fb_ioctl+0x234/0x670
+[  583.339209]  fb_ioctl+0xdd/0x130
+
+Fix the this by checking the value of 'screen_size' before memset_io().
+
+Fixes: 558b7bd86c32 ("vt8623fb: new framebuffer driver for VIA VT8623")
+Signed-off-by: Zheyu Ma <zheyuma97@gmail.com>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/vt8623fb.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/video/fbdev/vt8623fb.c b/drivers/video/fbdev/vt8623fb.c
+index 7a959e5ba90b..c274ec5e965c 100644
+--- a/drivers/video/fbdev/vt8623fb.c
++++ b/drivers/video/fbdev/vt8623fb.c
+@@ -504,6 +504,8 @@ static int vt8623fb_set_par(struct fb_info *info)
+                        (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1, 1,
+                        1, info->node);
++      if (screen_size > info->screen_size)
++              screen_size = info->screen_size;
+       memset_io(info->screen_base, 0x00, screen_size);
+       /* Device and screen back on */
+-- 
+2.35.1
+
diff --git a/queue-5.15/virtio-gpu-fix-a-missing-check-to-avoid-null-derefer.patch b/queue-5.15/virtio-gpu-fix-a-missing-check-to-avoid-null-derefer.patch
new file mode 100644 (file)
index 0000000..b0bb655
--- /dev/null
@@ -0,0 +1,46 @@
+From e6e1c7fab14e48c753c81e24661f1d06b2a54295 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 27 Mar 2022 13:09:45 +0800
+Subject: virtio-gpu: fix a missing check to avoid NULL dereference
+
+From: Xiaomeng Tong <xiam0nd.tong@gmail.com>
+
+[ Upstream commit bd63f11f4c3c46afec07d821f74736161ff6e526 ]
+
+'cache_ent' could be set NULL inside virtio_gpu_cmd_get_capset()
+and it will lead to a NULL dereference by a lately use of it
+(i.e., ptr = cache_ent->caps_cache). Fix it with a NULL check.
+
+Fixes: 62fb7a5e10962 ("virtio-gpu: add 3d/virgl support")
+Signed-off-by: Xiaomeng Tong <xiam0nd.tong@gmail.com>
+Reviewed-by: Chia-I Wu <olvaffe@gmail.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/20220327050945.1614-1-xiam0nd.tong@gmail.com
+
+[ kraxel: minor codestyle fixup ]
+
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/virtio/virtgpu_ioctl.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+index 5c1ad1596889..15c3e63db396 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
++++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+@@ -512,8 +512,10 @@ static int virtio_gpu_get_caps_ioctl(struct drm_device *dev,
+       spin_unlock(&vgdev->display_info_lock);
+       /* not in cache - need to talk to hw */
+-      virtio_gpu_cmd_get_capset(vgdev, found_valid, args->cap_set_ver,
+-                                &cache_ent);
++      ret = virtio_gpu_cmd_get_capset(vgdev, found_valid, args->cap_set_ver,
++                                      &cache_ent);
++      if (ret)
++              return ret;
+       virtio_gpu_notify(vgdev);
+ copy_exit:
+-- 
+2.35.1
+
diff --git a/queue-5.15/wait-fix-__wait_event_hrtimeout-for-rt-dl-tasks.patch b/queue-5.15/wait-fix-__wait_event_hrtimeout-for-rt-dl-tasks.patch
new file mode 100644 (file)
index 0000000..1ef3c10
--- /dev/null
@@ -0,0 +1,62 @@
+From 342b453904ebf7bb441e8932d416e143d1726f33 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 27 Jun 2022 11:50:51 +0200
+Subject: wait: Fix __wait_event_hrtimeout for RT/DL tasks
+
+From: Juri Lelli <juri.lelli@redhat.com>
+
+[ Upstream commit cceeeb6a6d02e7b9a74ddd27a3225013b34174aa ]
+
+Changes to hrtimer mode (potentially made by __hrtimer_init_sleeper on
+PREEMPT_RT) are not visible to hrtimer_start_range_ns, thus not
+accounted for by hrtimer_start_expires call paths. In particular,
+__wait_event_hrtimeout suffers from this problem as we have, for
+example:
+
+fs/aio.c::read_events
+  wait_event_interruptible_hrtimeout
+    __wait_event_hrtimeout
+      hrtimer_init_sleeper_on_stack <- this might "mode |= HRTIMER_MODE_HARD"
+                                       on RT if task runs at RT/DL priority
+        hrtimer_start_range_ns
+          WARN_ON_ONCE(!(mode & HRTIMER_MODE_HARD) ^ !timer->is_hard)
+          fires since the latter doesn't see the change of mode done by
+          init_sleeper
+
+Fix it by making __wait_event_hrtimeout call hrtimer_sleeper_start_expires,
+which is aware of the special RT/DL case, instead of hrtimer_start_range_ns.
+
+Reported-by: Bruno Goncalves <bgoncalv@redhat.com>
+Signed-off-by: Juri Lelli <juri.lelli@redhat.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Daniel Bristot de Oliveira <bristot@kernel.org>
+Reviewed-by: Valentin Schneider <vschneid@redhat.com>
+Link: https://lore.kernel.org/r/20220627095051.42470-1-juri.lelli@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/wait.h | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/include/linux/wait.h b/include/linux/wait.h
+index d22cf2985b8f..21044562aab7 100644
+--- a/include/linux/wait.h
++++ b/include/linux/wait.h
+@@ -544,10 +544,11 @@ do {                                                                             \
+                                                                               \
+       hrtimer_init_sleeper_on_stack(&__t, CLOCK_MONOTONIC,                    \
+                                     HRTIMER_MODE_REL);                        \
+-      if ((timeout) != KTIME_MAX)                                             \
+-              hrtimer_start_range_ns(&__t.timer, timeout,                     \
+-                                     current->timer_slack_ns,                 \
+-                                     HRTIMER_MODE_REL);                       \
++      if ((timeout) != KTIME_MAX) {                                           \
++              hrtimer_set_expires_range_ns(&__t.timer, timeout,               \
++                                      current->timer_slack_ns);               \
++              hrtimer_sleeper_start_expires(&__t, HRTIMER_MODE_REL);          \
++      }                                                                       \
+                                                                               \
+       __ret = ___wait_event(wq_head, condition, state, 0, 0,                  \
+               if (!__t.task) {                                                \
+-- 
+2.35.1
+
diff --git a/queue-5.15/watchdog-armada_37xx_wdt-check-the-return-value-of-d.patch b/queue-5.15/watchdog-armada_37xx_wdt-check-the-return-value-of-d.patch
new file mode 100644 (file)
index 0000000..7ac4d99
--- /dev/null
@@ -0,0 +1,42 @@
+From 937793390abbe9074e70a966b86cf31d6e15c454 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Jul 2022 11:09:38 +0800
+Subject: watchdog: armada_37xx_wdt: check the return value of devm_ioremap()
+ in armada_37xx_wdt_probe()
+
+From: William Dean <williamsukatube@gmail.com>
+
+[ Upstream commit 2d27e52841092e5831dd41f313028c668d816eb0 ]
+
+The function devm_ioremap() in armada_37xx_wdt_probe() can fail, so
+its return value should be checked.
+
+Fixes: 54e3d9b518c8a ("watchdog: Add support for Armada 37xx CPU watchdog")
+Reported-by: Hacash Robot <hacashRobot@santino.com>
+Signed-off-by: William Dean <williamsukatube@gmail.com>
+Reviewed-by: Marek Beh=C3=BAn <kabel@kernel.org>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/20220722030938.2925156-1-williamsukatube@163.com
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/watchdog/armada_37xx_wdt.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/watchdog/armada_37xx_wdt.c b/drivers/watchdog/armada_37xx_wdt.c
+index 1635f421ef2c..854b1cc723cb 100644
+--- a/drivers/watchdog/armada_37xx_wdt.c
++++ b/drivers/watchdog/armada_37xx_wdt.c
+@@ -274,6 +274,8 @@ static int armada_37xx_wdt_probe(struct platform_device *pdev)
+       if (!res)
+               return -ENODEV;
+       dev->reg = devm_ioremap(&pdev->dev, res->start, resource_size(res));
++      if (!dev->reg)
++              return -ENOMEM;
+       /* init clock */
+       dev->clk = devm_clk_get(&pdev->dev, NULL);
+-- 
+2.35.1
+
diff --git a/queue-5.15/watchdog-sp5100_tco-fix-a-memory-leak-of-efch-mmio-r.patch b/queue-5.15/watchdog-sp5100_tco-fix-a-memory-leak-of-efch-mmio-r.patch
new file mode 100644 (file)
index 0000000..39ce721
--- /dev/null
@@ -0,0 +1,42 @@
+From 5cc3c81872884469072226c4cbf5ab4d3763904a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Jun 2022 15:28:40 +0200
+Subject: watchdog: sp5100_tco: Fix a memory leak of EFCH MMIO resource
+
+From: Jean Delvare <jdelvare@suse.de>
+
+[ Upstream commit c6d9c0798ed366a09a9e53d71edcd2266e34a6eb ]
+
+Unlike release_mem_region(), a call to release_resource() does not
+free the resource, so it has to be freed explicitly to avoid a memory
+leak.
+
+Signed-off-by: Jean Delvare <jdelvare@suse.de>
+Fixes: 0578fff4aae5 ("Watchdog: sp5100_tco: Add initialization using EFCH MMIO")
+Cc: Terry Bowman <terry.bowman@amd.com>
+Cc: Wim Van Sebroeck <wim@linux-watchdog.org>
+Cc: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/20220621152840.420a0f4c@endymion.delvare
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/watchdog/sp5100_tco.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/watchdog/sp5100_tco.c b/drivers/watchdog/sp5100_tco.c
+index 4820af929a82..4afc468d8ed1 100644
+--- a/drivers/watchdog/sp5100_tco.c
++++ b/drivers/watchdog/sp5100_tco.c
+@@ -394,6 +394,7 @@ static int sp5100_tco_setupdevice_mmio(struct device *dev,
+               iounmap(addr);
+       release_resource(res);
++      kfree(res);
+       return ret;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/wifi-iwlegacy-4965-fix-potential-off-by-one-overflow.patch b/queue-5.15/wifi-iwlegacy-4965-fix-potential-off-by-one-overflow.patch
new file mode 100644 (file)
index 0000000..b9a18d6
--- /dev/null
@@ -0,0 +1,64 @@
+From 1d362f9fdf1177c3dd0b41e6b2eb0d593af6ffa2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jun 2022 20:16:14 +0300
+Subject: wifi: iwlegacy: 4965: fix potential off-by-one overflow in
+ il4965_rs_fill_link_cmd()
+
+From: Alexey Kodanev <aleksei.kodanev@bell-sw.com>
+
+[ Upstream commit a8eb8e6f7159c7c20c0ddac428bde3d110890aa7 ]
+
+As a result of the execution of the inner while loop, the value
+of 'idx' can be equal to LINK_QUAL_MAX_RETRY_NUM. However, this
+is not checked after the loop and 'idx' is used to write the
+LINK_QUAL_MAX_RETRY_NUM size array 'lq_cmd->rs_table[idx]' below
+in the outer loop.
+
+The fix is to check the new value of 'idx' inside the nested loop,
+and break both loops if index equals the size. Checking it at the
+start is now pointless, so let's remove it.
+
+Detected using the static analysis tool - Svace.
+
+Fixes: be663ab67077 ("iwlwifi: split the drivers for agn and legacy devices 3945/4965")
+Signed-off-by: Alexey Kodanev <aleksei.kodanev@bell-sw.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20220608171614.28891-1-aleksei.kodanev@bell-sw.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlegacy/4965-rs.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/intel/iwlegacy/4965-rs.c b/drivers/net/wireless/intel/iwlegacy/4965-rs.c
+index 9a491e5db75b..532e3b91777d 100644
+--- a/drivers/net/wireless/intel/iwlegacy/4965-rs.c
++++ b/drivers/net/wireless/intel/iwlegacy/4965-rs.c
+@@ -2403,7 +2403,7 @@ il4965_rs_fill_link_cmd(struct il_priv *il, struct il_lq_sta *lq_sta,
+               /* Repeat initial/next rate.
+                * For legacy IL_NUMBER_TRY == 1, this loop will not execute.
+                * For HT IL_HT_NUMBER_TRY == 3, this executes twice. */
+-              while (repeat_rate > 0 && idx < LINK_QUAL_MAX_RETRY_NUM) {
++              while (repeat_rate > 0) {
+                       if (is_legacy(tbl_type.lq_type)) {
+                               if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE)
+                                       ant_toggle_cnt++;
+@@ -2422,6 +2422,8 @@ il4965_rs_fill_link_cmd(struct il_priv *il, struct il_lq_sta *lq_sta,
+                           cpu_to_le32(new_rate);
+                       repeat_rate--;
+                       idx++;
++                      if (idx >= LINK_QUAL_MAX_RETRY_NUM)
++                              goto out;
+               }
+               il4965_rs_get_tbl_info_from_mcs(new_rate, lq_sta->band,
+@@ -2466,6 +2468,7 @@ il4965_rs_fill_link_cmd(struct il_priv *il, struct il_lq_sta *lq_sta,
+               repeat_rate--;
+       }
++out:
+       lq_cmd->agg_params.agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
+       lq_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
+-- 
+2.35.1
+
diff --git a/queue-5.15/wifi-iwlwifi-mvm-fix-double-list_add-at-iwl_mvm_mac_.patch b/queue-5.15/wifi-iwlwifi-mvm-fix-double-list_add-at-iwl_mvm_mac_.patch
new file mode 100644 (file)
index 0000000..f3e4aa6
--- /dev/null
@@ -0,0 +1,70 @@
+From f1b583241dfb02e0671b1b273cd32091695016d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 17:35:42 +0200
+Subject: wifi: iwlwifi: mvm: fix double list_add at iwl_mvm_mac_wake_tx_queue
+
+From: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
+
+[ Upstream commit 14a3aacf517a9de725dd3219dbbcf741e31763c4 ]
+
+After successfull station association, if station queues are disabled for
+some reason, the related lists are not emptied. So if some new element is
+added to the list in iwl_mvm_mac_wake_tx_queue, it can match with the old
+one and produce a BUG like this:
+
+[   46.535263] list_add corruption. prev->next should be next (ffff94c1c318a360), but was 0000000000000000. (prev=ffff94c1d02d3388).
+[   46.535283] ------------[ cut here ]------------
+[   46.535284] kernel BUG at lib/list_debug.c:26!
+[   46.535290] invalid opcode: 0000 [#1] PREEMPT SMP PTI
+[   46.585304] CPU: 0 PID: 623 Comm: wpa_supplicant Not tainted 5.19.0-rc3+ #1
+[   46.592380] Hardware name: Dell Inc. Inspiron 660s/0478VN       , BIOS A07 08/24/2012
+[   46.600336] RIP: 0010:__list_add_valid.cold+0x3d/0x3f
+[   46.605475] Code: f2 4c 89 c1 48 89 fe 48 c7 c7 c8 40 67 93 e8 20 cc fd ff 0f 0b 48 89 d1 4c 89 c6 4c 89 ca 48 c7 c7 70 40 67 93 e8 09 cc fd ff <0f> 0b 48 89 fe 48 c7 c7 00 41 67 93 e8 f8 cb fd ff 0f 0b 48 89 d1
+[   46.624469] RSP: 0018:ffffb20800ab76d8 EFLAGS: 00010286
+[   46.629854] RAX: 0000000000000075 RBX: ffff94c1c318a0e0 RCX: 0000000000000000
+[   46.637105] RDX: 0000000000000201 RSI: ffffffff9365e100 RDI: 00000000ffffffff
+[   46.644356] RBP: ffff94c1c5f43370 R08: 0000000000000075 R09: 3064316334396666
+[   46.651607] R10: 3364323064316334 R11: 39666666663d7665 R12: ffff94c1c5f43388
+[   46.658857] R13: ffff94c1d02d3388 R14: ffff94c1c318a360 R15: ffff94c1cf2289c0
+[   46.666108] FS:  00007f65634ff7c0(0000) GS:ffff94c1da200000(0000) knlGS:0000000000000000
+[   46.674331] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[   46.680170] CR2: 00007f7dfe984460 CR3: 000000010e894003 CR4: 00000000000606f0
+[   46.687422] Call Trace:
+[   46.689906]  <TASK>
+[   46.691950]  iwl_mvm_mac_wake_tx_queue+0xec/0x15c [iwlmvm]
+[   46.697601]  ieee80211_queue_skb+0x4b3/0x720 [mac80211]
+[   46.702973]  ? sta_info_get+0x46/0x60 [mac80211]
+[   46.707703]  ieee80211_tx+0xad/0x110 [mac80211]
+[   46.712355]  __ieee80211_tx_skb_tid_band+0x71/0x90 [mac80211]
+...
+
+In order to avoid this problem, we must also remove the related lists when
+station queues are disabled.
+
+Fixes: cfbc6c4c5b91c ("iwlwifi: mvm: support mac80211 TXQs model")
+Reported-by: Takayuki Nagata <tnagata@redhat.com>
+Reported-by: Petr Stourac <pstourac@redhat.com>
+Tested-by: Petr Stourac <pstourac@redhat.com>
+Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20220719153542.81466-1-jtornosm@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+index a64874c05ced..1bb456daff9e 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+@@ -1794,6 +1794,7 @@ static void iwl_mvm_disable_sta_queues(struct iwl_mvm *mvm,
+                       iwl_mvm_txq_from_mac80211(sta->txq[i]);
+               mvmtxq->txq_id = IWL_MVM_INVALID_QUEUE;
++              list_del_init(&mvmtxq->list);
+       }
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/wifi-libertas-fix-possible-refcount-leak-in-if_usb_p.patch b/queue-5.15/wifi-libertas-fix-possible-refcount-leak-in-if_usb_p.patch
new file mode 100644 (file)
index 0000000..3e52964
--- /dev/null
@@ -0,0 +1,37 @@
+From e0609cbe2eb53a370faa864f5a73ce4f3c620fac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jun 2022 17:23:50 +0800
+Subject: wifi: libertas: Fix possible refcount leak in if_usb_probe()
+
+From: Hangyu Hua <hbh25y@gmail.com>
+
+[ Upstream commit 6fd57e1d120bf13d4dc6c200a7cf914e6347a316 ]
+
+usb_get_dev will be called before lbs_get_firmware_async which means that
+usb_put_dev need to be called when lbs_get_firmware_async fails.
+
+Fixes: ce84bb69f50e ("libertas USB: convert to asynchronous firmware loading")
+Signed-off-by: Hangyu Hua <hbh25y@gmail.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20220620092350.39960-1-hbh25y@gmail.com
+Link: https://lore.kernel.org/r/20220622113402.16969-1-colin.i.king@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/marvell/libertas/if_usb.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/marvell/libertas/if_usb.c b/drivers/net/wireless/marvell/libertas/if_usb.c
+index 5d6dc1dd050d..32fdc4150b60 100644
+--- a/drivers/net/wireless/marvell/libertas/if_usb.c
++++ b/drivers/net/wireless/marvell/libertas/if_usb.c
+@@ -287,6 +287,7 @@ static int if_usb_probe(struct usb_interface *intf,
+       return 0;
+ err_get_fw:
++      usb_put_dev(udev);
+       lbs_remove_card(priv);
+ err_add_card:
+       if_usb_reset_device(cardp);
+-- 
+2.35.1
+
diff --git a/queue-5.15/wifi-p54-add-missing-parentheses-in-p54_flush.patch b/queue-5.15/wifi-p54-add-missing-parentheses-in-p54_flush.patch
new file mode 100644 (file)
index 0000000..1884371
--- /dev/null
@@ -0,0 +1,45 @@
+From 6d54ebff3e812d095c6ed42bf1c9c455958326c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 16:48:31 +0300
+Subject: wifi: p54: add missing parentheses in p54_flush()
+
+From: Rustam Subkhankulov <subkhankulov@ispras.ru>
+
+[ Upstream commit bcfd9d7f6840b06d5988c7141127795cf405805e ]
+
+The assignment of the value to the variable total in the loop
+condition must be enclosed in additional parentheses, since otherwise,
+in accordance with the precedence of the operators, the conjunction
+will be performed first, and only then the assignment.
+
+Due to this error, a warning later in the function after the loop may
+not occur in the situation when it should.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Signed-off-by: Rustam Subkhankulov <subkhankulov@ispras.ru>
+Fixes: 0d4171e2153b ("p54: implement flush callback")
+Acked-by: Christian Lamparter <chunkeey@gmail.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20220714134831.106004-1-subkhankulov@ispras.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intersil/p54/main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/intersil/p54/main.c b/drivers/net/wireless/intersil/p54/main.c
+index a3ca6620dc0c..8fa3ec71603e 100644
+--- a/drivers/net/wireless/intersil/p54/main.c
++++ b/drivers/net/wireless/intersil/p54/main.c
+@@ -682,7 +682,7 @@ static void p54_flush(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
+        * queues have already been stopped and no new frames can sneak
+        * up from behind.
+        */
+-      while ((total = p54_flush_count(priv) && i--)) {
++      while ((total = p54_flush_count(priv)) && i--) {
+               /* waste time */
+               msleep(20);
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.15/wifi-p54-fix-an-error-handling-path-in-p54spi_probe.patch b/queue-5.15/wifi-p54-fix-an-error-handling-path-in-p54spi_probe.patch
new file mode 100644 (file)
index 0000000..58f370d
--- /dev/null
@@ -0,0 +1,52 @@
+From c6640552e06950e71d7fe2c0d9676fc9452a904a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jun 2022 23:12:20 +0200
+Subject: wifi: p54: Fix an error handling path in p54spi_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 83781f0162d080fec7dcb911afd1bc2f5ad04471 ]
+
+If an error occurs after a successful call to p54spi_request_firmware(), it
+must be undone by a corresponding release_firmware() as already done in
+the error handling path of p54spi_request_firmware() and in the .remove()
+function.
+
+Add the missing call in the error handling path and remove it from
+p54spi_request_firmware() now that it is the responsibility of the caller
+to release the firmware
+
+Fixes: cd8d3d321285 ("p54spi: p54spi driver")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Acked-by: Christian Lamparter <chunkeey@gmail.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/297d2547ff2ee627731662abceeab9dbdaf23231.1655068321.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intersil/p54/p54spi.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/intersil/p54/p54spi.c b/drivers/net/wireless/intersil/p54/p54spi.c
+index ab0fe8565851..cdb57819684a 100644
+--- a/drivers/net/wireless/intersil/p54/p54spi.c
++++ b/drivers/net/wireless/intersil/p54/p54spi.c
+@@ -164,7 +164,7 @@ static int p54spi_request_firmware(struct ieee80211_hw *dev)
+       ret = p54_parse_firmware(dev, priv->firmware);
+       if (ret) {
+-              release_firmware(priv->firmware);
++              /* the firmware is released by the caller */
+               return ret;
+       }
+@@ -659,6 +659,7 @@ static int p54spi_probe(struct spi_device *spi)
+       return 0;
+ err_free_common:
++      release_firmware(priv->firmware);
+       free_irq(gpio_to_irq(p54spi_gpio_irq), spi);
+ err_free_gpio_irq:
+       gpio_free(p54spi_gpio_irq);
+-- 
+2.35.1
+
diff --git a/queue-5.15/wifi-rtlwifi-fix-error-codes-in-rtl_debugfs_set_writ.patch b/queue-5.15/wifi-rtlwifi-fix-error-codes-in-rtl_debugfs_set_writ.patch
new file mode 100644 (file)
index 0000000..b8733b0
--- /dev/null
@@ -0,0 +1,57 @@
+From 461e8fe2833ef4b2bf7617a434ef01589aaf1f0a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 May 2022 14:48:44 +0300
+Subject: wifi: rtlwifi: fix error codes in rtl_debugfs_set_write_h2c()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit b88d28146c30a8e14f0f012d56ebf19b68a348f4 ]
+
+If the copy_from_user() fails or the user gives invalid date then the
+correct thing to do is to return a negative error code.  (Currently it
+returns success).
+
+I made a copy additional related cleanups:
+1) There is no need to check "buffer" for NULL.  That's handled by
+copy_from_user().
+2) The "h2c_len" variable cannot be negative because it is unsigned
+and because sscanf() does not return negative error codes.
+
+Fixes: 610247f46feb ("rtlwifi: Improve debugging by using debugfs")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/YoOLnDkHgVltyXK7@kili
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtlwifi/debug.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/realtek/rtlwifi/debug.c b/drivers/net/wireless/realtek/rtlwifi/debug.c
+index 901cdfe3723c..0b1bc04cb6ad 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/debug.c
++++ b/drivers/net/wireless/realtek/rtlwifi/debug.c
+@@ -329,8 +329,8 @@ static ssize_t rtl_debugfs_set_write_h2c(struct file *filp,
+       tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count);
+-      if (!buffer || copy_from_user(tmp, buffer, tmp_len))
+-              return count;
++      if (copy_from_user(tmp, buffer, tmp_len))
++              return -EFAULT;
+       tmp[tmp_len] = '\0';
+@@ -340,8 +340,8 @@ static ssize_t rtl_debugfs_set_write_h2c(struct file *filp,
+                        &h2c_data[4], &h2c_data[5],
+                        &h2c_data[6], &h2c_data[7]);
+-      if (h2c_len <= 0)
+-              return count;
++      if (h2c_len == 0)
++              return -EINVAL;
+       for (i = 0; i < h2c_len; i++)
+               h2c_data_packed[i] = (u8)h2c_data[i];
+-- 
+2.35.1
+
diff --git a/queue-5.15/wifi-rtw88-check-the-return-value-of-alloc_workqueue.patch b/queue-5.15/wifi-rtw88-check-the-return-value-of-alloc_workqueue.patch
new file mode 100644 (file)
index 0000000..2ec4b96
--- /dev/null
@@ -0,0 +1,42 @@
+From 57b28e3c948833660069dcb0e542b1b0a4f94535 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Jul 2022 14:37:56 +0800
+Subject: wifi: rtw88: check the return value of alloc_workqueue()
+
+From: William Dean <williamsukatube@gmail.com>
+
+[ Upstream commit 42bbf810e155efc6129a3a648ae5300f00b79d7b ]
+
+The function alloc_workqueue() in rtw_core_init() can fail, but
+there is no check of its return value. To fix this bug, its return value
+should be checked with new error handling code.
+
+Fixes: fe101716c7c9d ("rtw88: replace tx tasklet with work queue")
+Reported-by: Hacash Robot <hacashRobot@santino.com>
+Signed-off-by: William Dean <williamsukatube@gmail.com>
+Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20220723063756.2956189-1-williamsukatube@163.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtw88/main.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
+index 69512856bb46..5786995d90d4 100644
+--- a/drivers/net/wireless/realtek/rtw88/main.c
++++ b/drivers/net/wireless/realtek/rtw88/main.c
+@@ -1819,6 +1819,10 @@ int rtw_core_init(struct rtw_dev *rtwdev)
+       timer_setup(&rtwdev->tx_report.purge_timer,
+                   rtw_tx_report_purge_timer, 0);
+       rtwdev->tx_wq = alloc_workqueue("rtw_tx_wq", WQ_UNBOUND | WQ_HIGHPRI, 0);
++      if (!rtwdev->tx_wq) {
++              rtw_warn(rtwdev, "alloc_workqueue rtw_tx_wq failed\n");
++              return -ENOMEM;
++      }
+       INIT_DELAYED_WORK(&rtwdev->watch_dog_work, rtw_watch_dog_work);
+       INIT_DELAYED_WORK(&coex->bt_relink_work, rtw_coex_bt_relink_work);
+-- 
+2.35.1
+
diff --git a/queue-5.15/wifi-wil6210-debugfs-fix-info-leak-in-wil_write_file.patch b/queue-5.15/wifi-wil6210-debugfs-fix-info-leak-in-wil_write_file.patch
new file mode 100644 (file)
index 0000000..f95a40e
--- /dev/null
@@ -0,0 +1,52 @@
+From 6368b0be051371e971e382efe0aab889f58ffaae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 13:35:18 +0300
+Subject: wifi: wil6210: debugfs: fix info leak in wil_write_file_wmi()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit 7a4836560a6198d245d5732e26f94898b12eb760 ]
+
+The simple_write_to_buffer() function will succeed if even a single
+byte is initialized.  However, we need to initialize the whole buffer
+to prevent information leaks.  Just use memdup_user().
+
+Fixes: ff974e408334 ("wil6210: debugfs interface to send raw WMI command")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/Ysg14NdKAZF/hcNG@kili
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/wil6210/debugfs.c | 14 ++++----------
+ 1 file changed, 4 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
+index 4c944e595978..c6f8254cb21d 100644
+--- a/drivers/net/wireless/ath/wil6210/debugfs.c
++++ b/drivers/net/wireless/ath/wil6210/debugfs.c
+@@ -1012,18 +1012,12 @@ static ssize_t wil_write_file_wmi(struct file *file, const char __user *buf,
+       u16 cmdid;
+       int rc, rc1;
+-      if (cmdlen < 0)
++      if (cmdlen < 0 || *ppos != 0)
+               return -EINVAL;
+-      wmi = kmalloc(len, GFP_KERNEL);
+-      if (!wmi)
+-              return -ENOMEM;
+-
+-      rc = simple_write_to_buffer(wmi, len, ppos, buf, len);
+-      if (rc < 0) {
+-              kfree(wmi);
+-              return rc;
+-      }
++      wmi = memdup_user(buf, len);
++      if (IS_ERR(wmi))
++              return PTR_ERR(wmi);
+       cmd = (cmdlen > 0) ? &wmi[1] : NULL;
+       cmdid = le16_to_cpu(wmi->command_id);
+-- 
+2.35.1
+
diff --git a/queue-5.15/wifi-wil6210-debugfs-fix-uninitialized-variable-use-.patch b/queue-5.15/wifi-wil6210-debugfs-fix-uninitialized-variable-use-.patch
new file mode 100644 (file)
index 0000000..cd4bf00
--- /dev/null
@@ -0,0 +1,59 @@
+From 4c93aa9aef0a75d4dd19e1cfe9f980b9ce270695 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Jul 2022 20:49:11 +0300
+Subject: wifi: wil6210: debugfs: fix uninitialized variable use in
+ `wil_write_file_wmi()`
+
+From: Ammar Faizi <ammarfaizi2@gnuweeb.org>
+
+[ Upstream commit d578e0af3a003736f6c440188b156483d451b329 ]
+
+Commit 7a4836560a61 changes simple_write_to_buffer() with memdup_user()
+but it forgets to change the value to be returned that came from
+simple_write_to_buffer() call. It results in the following warning:
+
+  warning: variable 'rc' is uninitialized when used here [-Wuninitialized]
+           return rc;
+                  ^~
+
+Remove rc variable and just return the passed in length if the
+memdup_user() succeeds.
+
+Cc: Dan Carpenter <dan.carpenter@oracle.com>
+Reported-by: kernel test robot <lkp@intel.com>
+Fixes: 7a4836560a6198d245d5732e26f94898b12eb760 ("wifi: wil6210: debugfs: fix info leak in wil_write_file_wmi()")
+Fixes: ff974e4083341383d3dd4079e52ed30f57f376f0 ("wil6210: debugfs interface to send raw WMI command")
+Signed-off-by: Ammar Faizi <ammarfaizi2@gnuweeb.org>
+Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20220724202452.61846-1-ammar.faizi@intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/wil6210/debugfs.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
+index c6f8254cb21d..ac7787e1a7f6 100644
+--- a/drivers/net/wireless/ath/wil6210/debugfs.c
++++ b/drivers/net/wireless/ath/wil6210/debugfs.c
+@@ -1010,7 +1010,7 @@ static ssize_t wil_write_file_wmi(struct file *file, const char __user *buf,
+       void *cmd;
+       int cmdlen = len - sizeof(struct wmi_cmd_hdr);
+       u16 cmdid;
+-      int rc, rc1;
++      int rc1;
+       if (cmdlen < 0 || *ppos != 0)
+               return -EINVAL;
+@@ -1027,7 +1027,7 @@ static ssize_t wil_write_file_wmi(struct file *file, const char __user *buf,
+       wil_info(wil, "0x%04x[%d] -> %d\n", cmdid, cmdlen, rc1);
+-      return rc;
++      return len;
+ }
+ static const struct file_operations fops_wmi = {
+-- 
+2.35.1
+
diff --git a/queue-5.15/wireguard-allowedips-don-t-corrupt-stack-when-detect.patch b/queue-5.15/wireguard-allowedips-don-t-corrupt-stack-when-detect.patch
new file mode 100644 (file)
index 0000000..637c9f7
--- /dev/null
@@ -0,0 +1,95 @@
+From ce02f5a7b4cccdcde89d653553d5abbda5080338 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Aug 2022 14:56:12 +0200
+Subject: wireguard: allowedips: don't corrupt stack when detecting overflow
+
+From: Jason A. Donenfeld <Jason@zx2c4.com>
+
+[ Upstream commit c31b14d86dfe7174361e8c6e5df6c2c3a4d5918c ]
+
+In case push_rcu() and related functions are buggy, there's a
+WARN_ON(len >= 128), which the selftest tries to hit by being tricky. In
+case it is hit, we shouldn't corrupt the kernel's stack, though;
+otherwise it may be hard to even receive the report that it's buggy. So
+conditionalize the stack write based on that WARN_ON()'s return value.
+
+Note that this never *actually* happens anyway. The WARN_ON() in the
+first place is bounded by IS_ENABLED(DEBUG), and isn't expected to ever
+actually hit. This is just a debugging sanity check.
+
+Additionally, hoist the constant 128 into a named enum,
+MAX_ALLOWEDIPS_BITS, so that it's clear why this value is chosen.
+
+Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
+Link: https://lore.kernel.org/all/CAHk-=wjJZGA6w_DxA+k7Ejbqsq+uGK==koPai3sqdsfJqemvag@mail.gmail.com/
+Fixes: e7096c131e51 ("net: WireGuard secure network tunnel")
+Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireguard/allowedips.c          | 9 ++++++---
+ drivers/net/wireguard/selftest/allowedips.c | 6 +++---
+ 2 files changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/wireguard/allowedips.c b/drivers/net/wireguard/allowedips.c
+index 9a4c8ff32d9d..5bf7822c53f1 100644
+--- a/drivers/net/wireguard/allowedips.c
++++ b/drivers/net/wireguard/allowedips.c
+@@ -6,6 +6,8 @@
+ #include "allowedips.h"
+ #include "peer.h"
++enum { MAX_ALLOWEDIPS_BITS = 128 };
++
+ static struct kmem_cache *node_cache;
+ static void swap_endian(u8 *dst, const u8 *src, u8 bits)
+@@ -40,7 +42,8 @@ static void push_rcu(struct allowedips_node **stack,
+                    struct allowedips_node __rcu *p, unsigned int *len)
+ {
+       if (rcu_access_pointer(p)) {
+-              WARN_ON(IS_ENABLED(DEBUG) && *len >= 128);
++              if (WARN_ON(IS_ENABLED(DEBUG) && *len >= MAX_ALLOWEDIPS_BITS))
++                      return;
+               stack[(*len)++] = rcu_dereference_raw(p);
+       }
+ }
+@@ -52,7 +55,7 @@ static void node_free_rcu(struct rcu_head *rcu)
+ static void root_free_rcu(struct rcu_head *rcu)
+ {
+-      struct allowedips_node *node, *stack[128] = {
++      struct allowedips_node *node, *stack[MAX_ALLOWEDIPS_BITS] = {
+               container_of(rcu, struct allowedips_node, rcu) };
+       unsigned int len = 1;
+@@ -65,7 +68,7 @@ static void root_free_rcu(struct rcu_head *rcu)
+ static void root_remove_peer_lists(struct allowedips_node *root)
+ {
+-      struct allowedips_node *node, *stack[128] = { root };
++      struct allowedips_node *node, *stack[MAX_ALLOWEDIPS_BITS] = { root };
+       unsigned int len = 1;
+       while (len > 0 && (node = stack[--len])) {
+diff --git a/drivers/net/wireguard/selftest/allowedips.c b/drivers/net/wireguard/selftest/allowedips.c
+index e173204ae7d7..41db10f9be49 100644
+--- a/drivers/net/wireguard/selftest/allowedips.c
++++ b/drivers/net/wireguard/selftest/allowedips.c
+@@ -593,10 +593,10 @@ bool __init wg_allowedips_selftest(void)
+       wg_allowedips_remove_by_peer(&t, a, &mutex);
+       test_negative(4, a, 192, 168, 0, 1);
+-      /* These will hit the WARN_ON(len >= 128) in free_node if something
+-       * goes wrong.
++      /* These will hit the WARN_ON(len >= MAX_ALLOWEDIPS_BITS) in free_node
++       * if something goes wrong.
+        */
+-      for (i = 0; i < 128; ++i) {
++      for (i = 0; i < MAX_ALLOWEDIPS_BITS; ++i) {
+               part = cpu_to_be64(~(1LLU << (i % 64)));
+               memset(&ip, 0xff, 16);
+               memcpy((u8 *)&ip + (i < 64) * 8, &part, 8);
+-- 
+2.35.1
+
diff --git a/queue-5.15/wireguard-ratelimiter-use-hrtimer-in-selftest.patch b/queue-5.15/wireguard-ratelimiter-use-hrtimer-in-selftest.patch
new file mode 100644 (file)
index 0000000..e3c45ad
--- /dev/null
@@ -0,0 +1,137 @@
+From b8b7d23e8d33955ea96c551b2eb174d8df7035f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Aug 2022 14:56:10 +0200
+Subject: wireguard: ratelimiter: use hrtimer in selftest
+
+From: Jason A. Donenfeld <Jason@zx2c4.com>
+
+[ Upstream commit 151c8e499f4705010780189377f85b57400ccbf5 ]
+
+Using msleep() is problematic because it's compared against
+ratelimiter.c's ktime_get_coarse_boottime_ns(), which means on systems
+with slow jiffies (such as UML's forced HZ=100), the result is
+inaccurate. So switch to using schedule_hrtimeout().
+
+However, hrtimer gives us access only to the traditional posix timers,
+and none of the _COARSE variants. So now, rather than being too
+imprecise like jiffies, it's too precise.
+
+One solution would be to give it a large "range" value, but this will
+still fire early on a loaded system. A better solution is to align the
+timeout to the actual coarse timer, and then round up to the nearest
+tick, plus change.
+
+So add the timeout to the current coarse time, and then
+schedule_hrtimer() until the absolute computed time.
+
+This should hopefully reduce flakes in CI as well. Note that we keep the
+retry loop in case the entire function is running behind, because the
+test could still be scheduled out, by either the kernel or by the
+hypervisor's kernel, in which case restarting the test and hoping to not
+be scheduled out still helps.
+
+Fixes: e7096c131e51 ("net: WireGuard secure network tunnel")
+Suggested-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireguard/selftest/ratelimiter.c | 25 +++++++++++---------
+ kernel/time/hrtimer.c                        |  1 +
+ 2 files changed, 15 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/wireguard/selftest/ratelimiter.c b/drivers/net/wireguard/selftest/ratelimiter.c
+index 007cd4457c5f..ba87d294604f 100644
+--- a/drivers/net/wireguard/selftest/ratelimiter.c
++++ b/drivers/net/wireguard/selftest/ratelimiter.c
+@@ -6,28 +6,29 @@
+ #ifdef DEBUG
+ #include <linux/jiffies.h>
++#include <linux/hrtimer.h>
+ static const struct {
+       bool result;
+-      unsigned int msec_to_sleep_before;
++      u64 nsec_to_sleep_before;
+ } expected_results[] __initconst = {
+       [0 ... PACKETS_BURSTABLE - 1] = { true, 0 },
+       [PACKETS_BURSTABLE] = { false, 0 },
+-      [PACKETS_BURSTABLE + 1] = { true, MSEC_PER_SEC / PACKETS_PER_SECOND },
++      [PACKETS_BURSTABLE + 1] = { true, NSEC_PER_SEC / PACKETS_PER_SECOND },
+       [PACKETS_BURSTABLE + 2] = { false, 0 },
+-      [PACKETS_BURSTABLE + 3] = { true, (MSEC_PER_SEC / PACKETS_PER_SECOND) * 2 },
++      [PACKETS_BURSTABLE + 3] = { true, (NSEC_PER_SEC / PACKETS_PER_SECOND) * 2 },
+       [PACKETS_BURSTABLE + 4] = { true, 0 },
+       [PACKETS_BURSTABLE + 5] = { false, 0 }
+ };
+ static __init unsigned int maximum_jiffies_at_index(int index)
+ {
+-      unsigned int total_msecs = 2 * MSEC_PER_SEC / PACKETS_PER_SECOND / 3;
++      u64 total_nsecs = 2 * NSEC_PER_SEC / PACKETS_PER_SECOND / 3;
+       int i;
+       for (i = 0; i <= index; ++i)
+-              total_msecs += expected_results[i].msec_to_sleep_before;
+-      return msecs_to_jiffies(total_msecs);
++              total_nsecs += expected_results[i].nsec_to_sleep_before;
++      return nsecs_to_jiffies(total_nsecs);
+ }
+ static __init int timings_test(struct sk_buff *skb4, struct iphdr *hdr4,
+@@ -42,8 +43,12 @@ static __init int timings_test(struct sk_buff *skb4, struct iphdr *hdr4,
+       loop_start_time = jiffies;
+       for (i = 0; i < ARRAY_SIZE(expected_results); ++i) {
+-              if (expected_results[i].msec_to_sleep_before)
+-                      msleep(expected_results[i].msec_to_sleep_before);
++              if (expected_results[i].nsec_to_sleep_before) {
++                      ktime_t timeout = ktime_add(ktime_add_ns(ktime_get_coarse_boottime(), TICK_NSEC * 4 / 3),
++                                                  ns_to_ktime(expected_results[i].nsec_to_sleep_before));
++                      set_current_state(TASK_UNINTERRUPTIBLE);
++                      schedule_hrtimeout_range_clock(&timeout, 0, HRTIMER_MODE_ABS, CLOCK_BOOTTIME);
++              }
+               if (time_is_before_jiffies(loop_start_time +
+                                          maximum_jiffies_at_index(i)))
+@@ -127,7 +132,7 @@ bool __init wg_ratelimiter_selftest(void)
+       if (IS_ENABLED(CONFIG_KASAN) || IS_ENABLED(CONFIG_UBSAN))
+               return true;
+-      BUILD_BUG_ON(MSEC_PER_SEC % PACKETS_PER_SECOND != 0);
++      BUILD_BUG_ON(NSEC_PER_SEC % PACKETS_PER_SECOND != 0);
+       if (wg_ratelimiter_init())
+               goto out;
+@@ -176,7 +181,6 @@ bool __init wg_ratelimiter_selftest(void)
+                               test += test_count;
+                               goto err;
+                       }
+-                      msleep(500);
+                       continue;
+               } else if (ret < 0) {
+                       test += test_count;
+@@ -195,7 +199,6 @@ bool __init wg_ratelimiter_selftest(void)
+                               test += test_count;
+                               goto err;
+                       }
+-                      msleep(50);
+                       continue;
+               }
+               test += test_count;
+diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
+index 0ea8702eb516..23af5eca11b1 100644
+--- a/kernel/time/hrtimer.c
++++ b/kernel/time/hrtimer.c
+@@ -2311,6 +2311,7 @@ schedule_hrtimeout_range_clock(ktime_t *expires, u64 delta,
+       return !t.task ? 0 : -EINTR;
+ }
++EXPORT_SYMBOL_GPL(schedule_hrtimeout_range_clock);
+ /**
+  * schedule_hrtimeout_range - sleep until timeout
+-- 
+2.35.1
+
diff --git a/queue-5.15/x86-bus_lock-don-t-assume-the-init-value-of-debugctl.patch b/queue-5.15/x86-bus_lock-don-t-assume-the-init-value-of-debugctl.patch
new file mode 100644 (file)
index 0000000..17cebf9
--- /dev/null
@@ -0,0 +1,70 @@
+From a7ced4276ef388d9b5c92e55d8173990ca4cc14d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Aug 2022 11:32:06 +0800
+Subject: x86/bus_lock: Don't assume the init value of
+ DEBUGCTLMSR.BUS_LOCK_DETECT to be zero
+
+From: Chenyi Qiang <chenyi.qiang@intel.com>
+
+[ Upstream commit ffa6482e461ff550325356ae705b79e256702ea9 ]
+
+It's possible that this kernel has been kexec'd from a kernel that
+enabled bus lock detection, or (hypothetically) BIOS/firmware has set
+DEBUGCTLMSR_BUS_LOCK_DETECT.
+
+Disable bus lock detection explicitly if not wanted.
+
+Fixes: ebb1064e7c2e ("x86/traps: Handle #DB for bus lock")
+Signed-off-by: Chenyi Qiang <chenyi.qiang@intel.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Reviewed-by: Tony Luck <tony.luck@intel.com>
+Link: https://lore.kernel.org/r/20220802033206.21333-1-chenyi.qiang@intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/cpu/intel.c | 27 ++++++++++++++-------------
+ 1 file changed, 14 insertions(+), 13 deletions(-)
+
+diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
+index 2c87d62f191e..ae7d4c85f4f4 100644
+--- a/arch/x86/kernel/cpu/intel.c
++++ b/arch/x86/kernel/cpu/intel.c
+@@ -1145,22 +1145,23 @@ static void bus_lock_init(void)
+ {
+       u64 val;
+-      /*
+-       * Warn and fatal are handled by #AC for split lock if #AC for
+-       * split lock is supported.
+-       */
+-      if (!boot_cpu_has(X86_FEATURE_BUS_LOCK_DETECT) ||
+-          (boot_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT) &&
+-          (sld_state == sld_warn || sld_state == sld_fatal)) ||
+-          sld_state == sld_off)
++      if (!boot_cpu_has(X86_FEATURE_BUS_LOCK_DETECT))
+               return;
+-      /*
+-       * Enable #DB for bus lock. All bus locks are handled in #DB except
+-       * split locks are handled in #AC in the fatal case.
+-       */
+       rdmsrl(MSR_IA32_DEBUGCTLMSR, val);
+-      val |= DEBUGCTLMSR_BUS_LOCK_DETECT;
++
++      if ((boot_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT) &&
++          (sld_state == sld_warn || sld_state == sld_fatal)) ||
++          sld_state == sld_off) {
++              /*
++               * Warn and fatal are handled by #AC for split lock if #AC for
++               * split lock is supported.
++               */
++              val &= ~DEBUGCTLMSR_BUS_LOCK_DETECT;
++      } else {
++              val |= DEBUGCTLMSR_BUS_LOCK_DETECT;
++      }
++
+       wrmsrl(MSR_IA32_DEBUGCTLMSR, val);
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.15/x86-entry-build-thunk_-bits-only-if-config_preemptio.patch b/queue-5.15/x86-entry-build-thunk_-bits-only-if-config_preemptio.patch
new file mode 100644 (file)
index 0000000..e6e74ab
--- /dev/null
@@ -0,0 +1,111 @@
+From 8bddba3ae2e5181040a5f7cf581ea4970c918f93 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 09:49:15 +0200
+Subject: x86/entry: Build thunk_$(BITS) only if CONFIG_PREEMPTION=y
+
+From: Andrea Righi <andrea.righi@canonical.com>
+
+[ Upstream commit de979c83574abf6e78f3fa65b716515c91b2613d ]
+
+With CONFIG_PREEMPTION disabled, arch/x86/entry/thunk_$(BITS).o becomes
+an empty object file.
+
+With some old versions of binutils (i.e., 2.35.90.20210113-1ubuntu1) the
+GNU assembler doesn't generate a symbol table for empty object files and
+objtool fails with the following error when a valid symbol table cannot
+be found:
+
+  arch/x86/entry/thunk_64.o: warning: objtool: missing symbol table
+
+To prevent this from happening, build thunk_$(BITS).o only if
+CONFIG_PREEMPTION is enabled.
+
+BugLink: https://bugs.launchpad.net/bugs/1911359
+
+Fixes: 320100a5ffe5 ("x86/entry: Remove the TRACE_IRQS cruft")
+Signed-off-by: Andrea Righi <andrea.righi@canonical.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Link: https://lore.kernel.org/r/Ys/Ke7EWjcX+ZlXO@arighi-desktop
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/entry/Makefile   | 3 ++-
+ arch/x86/entry/thunk_32.S | 2 --
+ arch/x86/entry/thunk_64.S | 4 ----
+ arch/x86/um/Makefile      | 3 ++-
+ 4 files changed, 4 insertions(+), 8 deletions(-)
+
+diff --git a/arch/x86/entry/Makefile b/arch/x86/entry/Makefile
+index eeadbd7d92cc..ca2fe186994b 100644
+--- a/arch/x86/entry/Makefile
++++ b/arch/x86/entry/Makefile
+@@ -11,12 +11,13 @@ CFLAGS_REMOVE_common.o             = $(CC_FLAGS_FTRACE)
+ CFLAGS_common.o                       += -fno-stack-protector
+-obj-y                         := entry.o entry_$(BITS).o thunk_$(BITS).o syscall_$(BITS).o
++obj-y                         := entry.o entry_$(BITS).o syscall_$(BITS).o
+ obj-y                         += common.o
+ obj-y                         += vdso/
+ obj-y                         += vsyscall/
++obj-$(CONFIG_PREEMPTION)      += thunk_$(BITS).o
+ obj-$(CONFIG_IA32_EMULATION)  += entry_64_compat.o syscall_32.o
+ obj-$(CONFIG_X86_X32_ABI)     += syscall_x32.o
+diff --git a/arch/x86/entry/thunk_32.S b/arch/x86/entry/thunk_32.S
+index 7591bab060f7..ff6e7003da97 100644
+--- a/arch/x86/entry/thunk_32.S
++++ b/arch/x86/entry/thunk_32.S
+@@ -29,10 +29,8 @@ SYM_CODE_START_NOALIGN(\name)
+ SYM_CODE_END(\name)
+       .endm
+-#ifdef CONFIG_PREEMPTION
+       THUNK preempt_schedule_thunk, preempt_schedule
+       THUNK preempt_schedule_notrace_thunk, preempt_schedule_notrace
+       EXPORT_SYMBOL(preempt_schedule_thunk)
+       EXPORT_SYMBOL(preempt_schedule_notrace_thunk)
+-#endif
+diff --git a/arch/x86/entry/thunk_64.S b/arch/x86/entry/thunk_64.S
+index 505b488fcc65..f38b07d2768b 100644
+--- a/arch/x86/entry/thunk_64.S
++++ b/arch/x86/entry/thunk_64.S
+@@ -31,14 +31,11 @@ SYM_FUNC_END(\name)
+       _ASM_NOKPROBE(\name)
+       .endm
+-#ifdef CONFIG_PREEMPTION
+       THUNK preempt_schedule_thunk, preempt_schedule
+       THUNK preempt_schedule_notrace_thunk, preempt_schedule_notrace
+       EXPORT_SYMBOL(preempt_schedule_thunk)
+       EXPORT_SYMBOL(preempt_schedule_notrace_thunk)
+-#endif
+-#ifdef CONFIG_PREEMPTION
+ SYM_CODE_START_LOCAL_NOALIGN(__thunk_restore)
+       popq %r11
+       popq %r10
+@@ -53,4 +50,3 @@ SYM_CODE_START_LOCAL_NOALIGN(__thunk_restore)
+       RET
+       _ASM_NOKPROBE(__thunk_restore)
+ SYM_CODE_END(__thunk_restore)
+-#endif
+diff --git a/arch/x86/um/Makefile b/arch/x86/um/Makefile
+index 5ccb18290d71..a8591ec8ae68 100644
+--- a/arch/x86/um/Makefile
++++ b/arch/x86/um/Makefile
+@@ -28,7 +28,8 @@ else
+ obj-y += syscalls_64.o vdso/
+-subarch-y = ../lib/csum-partial_64.o ../lib/memcpy_64.o ../entry/thunk_64.o
++subarch-y = ../lib/csum-partial_64.o ../lib/memcpy_64.o
++subarch-$(CONFIG_PREEMPTION) += ../entry/thunk_64.o
+ endif
+-- 
+2.35.1
+
diff --git a/queue-5.15/x86-extable-fix-ex_handler_msr-print-condition.patch b/queue-5.15/x86-extable-fix-ex_handler_msr-print-condition.patch
new file mode 100644 (file)
index 0000000..f659ac3
--- /dev/null
@@ -0,0 +1,111 @@
+From 19d7979c735180b6ff8eef7670e76b945ebc2f8d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jun 2022 16:52:06 +0200
+Subject: x86/extable: Fix ex_handler_msr() print condition
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+[ Upstream commit a1a5482a2c6e38a3ebed32e571625c56a8cc41a6 ]
+
+On Fri, Jun 17, 2022 at 02:08:52PM +0300, Stephane Eranian wrote:
+> Some changes to the way invalid MSR accesses are reported by the
+> kernel is causing some problems with messages printed on the
+> console.
+>
+> We have seen several cases of ex_handler_msr() printing invalid MSR
+> accesses once but the callstack multiple times causing confusion on
+> the console.
+
+> The problem here is that another earlier commit (5.13):
+>
+> a358f40600b3 ("once: implement DO_ONCE_LITE for non-fast-path "do once" functionality")
+>
+> Modifies all the pr_*_once() calls to always return true claiming
+> that no caller is ever checking the return value of the functions.
+>
+> This is why we are seeing the callstack printed without the
+> associated printk() msg.
+
+Extract the ONCE_IF(cond) part into __ONCE_LTE_IF() and use that to
+implement DO_ONCE_LITE_IF() and fix the extable code.
+
+Fixes: a358f40600b3 ("once: implement DO_ONCE_LITE for non-fast-path "do once" functionality")
+Reported-by: Stephane Eranian <eranian@google.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Tested-by: Stephane Eranian <eranian@google.com>
+Link: https://lkml.kernel.org/r/YqyVFsbviKjVGGZ9@worktop.programming.kicks-ass.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/mm/extable.c     | 16 +++++++++-------
+ include/linux/once_lite.h | 20 ++++++++++++++++----
+ 2 files changed, 25 insertions(+), 11 deletions(-)
+
+diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c
+index 13d838e6030b..a9c7efd4b794 100644
+--- a/arch/x86/mm/extable.c
++++ b/arch/x86/mm/extable.c
+@@ -86,16 +86,18 @@ static bool ex_handler_copy(const struct exception_table_entry *fixup,
+ static bool ex_handler_msr(const struct exception_table_entry *fixup,
+                          struct pt_regs *regs, bool wrmsr, bool safe, int reg)
+ {
+-      if (!safe && wrmsr &&
+-          pr_warn_once("unchecked MSR access error: WRMSR to 0x%x (tried to write 0x%08x%08x) at rIP: 0x%lx (%pS)\n",
+-                       (unsigned int)regs->cx, (unsigned int)regs->dx,
+-                       (unsigned int)regs->ax,  regs->ip, (void *)regs->ip))
++      if (__ONCE_LITE_IF(!safe && wrmsr)) {
++              pr_warn("unchecked MSR access error: WRMSR to 0x%x (tried to write 0x%08x%08x) at rIP: 0x%lx (%pS)\n",
++                      (unsigned int)regs->cx, (unsigned int)regs->dx,
++                      (unsigned int)regs->ax,  regs->ip, (void *)regs->ip);
+               show_stack_regs(regs);
++      }
+-      if (!safe && !wrmsr &&
+-          pr_warn_once("unchecked MSR access error: RDMSR from 0x%x at rIP: 0x%lx (%pS)\n",
+-                       (unsigned int)regs->cx, regs->ip, (void *)regs->ip))
++      if (__ONCE_LITE_IF(!safe && !wrmsr)) {
++              pr_warn("unchecked MSR access error: RDMSR from 0x%x at rIP: 0x%lx (%pS)\n",
++                      (unsigned int)regs->cx, regs->ip, (void *)regs->ip);
+               show_stack_regs(regs);
++      }
+       if (!wrmsr) {
+               /* Pretend that the read succeeded and returned 0. */
+diff --git a/include/linux/once_lite.h b/include/linux/once_lite.h
+index 861e606b820f..b7bce4983638 100644
+--- a/include/linux/once_lite.h
++++ b/include/linux/once_lite.h
+@@ -9,15 +9,27 @@
+  */
+ #define DO_ONCE_LITE(func, ...)                                               \
+       DO_ONCE_LITE_IF(true, func, ##__VA_ARGS__)
+-#define DO_ONCE_LITE_IF(condition, func, ...)                         \
++
++#define __ONCE_LITE_IF(condition)                                     \
+       ({                                                              \
+               static bool __section(".data.once") __already_done;     \
+-              bool __ret_do_once = !!(condition);                     \
++              bool __ret_cond = !!(condition);                        \
++              bool __ret_once = false;                                \
+                                                                       \
+-              if (unlikely(__ret_do_once && !__already_done)) {       \
++              if (unlikely(__ret_cond && !__already_done)) {          \
+                       __already_done = true;                          \
+-                      func(__VA_ARGS__);                              \
++                      __ret_once = true;                              \
+               }                                                       \
++              unlikely(__ret_once);                                   \
++      })
++
++#define DO_ONCE_LITE_IF(condition, func, ...)                         \
++      ({                                                              \
++              bool __ret_do_once = !!(condition);                     \
++                                                                      \
++              if (__ONCE_LITE_IF(__ret_do_once))                      \
++                      func(__VA_ARGS__);                              \
++                                                                      \
+               unlikely(__ret_do_once);                                \
+       })
+-- 
+2.35.1
+
diff --git a/queue-5.15/x86-handle-idle-nomwait-cmdline-properly-for-x86_idl.patch b/queue-5.15/x86-handle-idle-nomwait-cmdline-properly-for-x86_idl.patch
new file mode 100644 (file)
index 0000000..5c131ec
--- /dev/null
@@ -0,0 +1,97 @@
+From add9879988ce34001552943f995653e0cee8758b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jun 2022 23:33:34 +0530
+Subject: x86: Handle idle=nomwait cmdline properly for x86_idle
+
+From: Wyes Karny <wyes.karny@amd.com>
+
+[ Upstream commit 8bcedb4ce04750e1ccc9a6b6433387f6a9166a56 ]
+
+When kernel is booted with idle=nomwait do not use MWAIT as the
+default idle state.
+
+If the user boots the kernel with idle=nomwait, it is a clear
+direction to not use mwait as the default idle state.
+However, the current code does not take this into consideration
+while selecting the default idle state on x86.
+
+Fix it by checking for the idle=nomwait boot option in
+prefer_mwait_c1_over_halt().
+
+Also update the documentation around idle=nomwait appropriately.
+
+[ dhansen: tweak commit message ]
+
+Signed-off-by: Wyes Karny <wyes.karny@amd.com>
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Tested-by: Zhang Rui <rui.zhang@intel.com>
+Link: https://lkml.kernel.org/r/fdc2dc2d0a1bc21c2f53d989ea2d2ee3ccbc0dbe.1654538381.git-series.wyes.karny@amd.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/admin-guide/pm/cpuidle.rst | 15 +++++++++------
+ arch/x86/kernel/process.c                |  9 ++++++---
+ 2 files changed, 15 insertions(+), 9 deletions(-)
+
+diff --git a/Documentation/admin-guide/pm/cpuidle.rst b/Documentation/admin-guide/pm/cpuidle.rst
+index aec2cd2aaea7..19754beb5a4e 100644
+--- a/Documentation/admin-guide/pm/cpuidle.rst
++++ b/Documentation/admin-guide/pm/cpuidle.rst
+@@ -612,8 +612,8 @@ the ``menu`` governor to be used on the systems that use the ``ladder`` governor
+ by default this way, for example.
+ The other kernel command line parameters controlling CPU idle time management
+-described below are only relevant for the *x86* architecture and some of
+-them affect Intel processors only.
++described below are only relevant for the *x86* architecture and references
++to ``intel_idle`` affect Intel processors only.
+ The *x86* architecture support code recognizes three kernel command line
+ options related to CPU idle time management: ``idle=poll``, ``idle=halt``,
+@@ -635,10 +635,13 @@ idle, so it very well may hurt single-thread computations performance as well as
+ energy-efficiency.  Thus using it for performance reasons may not be a good idea
+ at all.]
+-The ``idle=nomwait`` option disables the ``intel_idle`` driver and causes
+-``acpi_idle`` to be used (as long as all of the information needed by it is
+-there in the system's ACPI tables), but it is not allowed to use the
+-``MWAIT`` instruction of the CPUs to ask the hardware to enter idle states.
++The ``idle=nomwait`` option prevents the use of ``MWAIT`` instruction of
++the CPU to enter idle states. When this option is used, the ``acpi_idle``
++driver will use the ``HLT`` instruction instead of ``MWAIT``. On systems
++running Intel processors, this option disables the ``intel_idle`` driver
++and forces the use of the ``acpi_idle`` driver instead. Note that in either
++case, ``acpi_idle`` driver will function only if all the information needed
++by it is in the system's ACPI tables.
+ In addition to the architecture-level kernel command line options affecting CPU
+ idle time management, there are parameters affecting individual ``CPUIdle``
+diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
+index 8d9d72fc27a2..707376453525 100644
+--- a/arch/x86/kernel/process.c
++++ b/arch/x86/kernel/process.c
+@@ -805,6 +805,10 @@ static void amd_e400_idle(void)
+  */
+ static int prefer_mwait_c1_over_halt(const struct cpuinfo_x86 *c)
+ {
++      /* User has disallowed the use of MWAIT. Fallback to HALT */
++      if (boot_option_idle_override == IDLE_NOMWAIT)
++              return 0;
++
+       if (c->x86_vendor != X86_VENDOR_INTEL)
+               return 0;
+@@ -913,9 +917,8 @@ static int __init idle_setup(char *str)
+       } else if (!strcmp(str, "nomwait")) {
+               /*
+                * If the boot option of "idle=nomwait" is added,
+-               * it means that mwait will be disabled for CPU C2/C3
+-               * states. In such case it won't touch the variable
+-               * of boot_option_idle_override.
++               * it means that mwait will be disabled for CPU C1/C2/C3
++               * states.
+                */
+               boot_option_idle_override = IDLE_NOMWAIT;
+       } else
+-- 
+2.35.1
+
diff --git a/queue-5.15/x86-numa-use-cpumask_available-instead-of-hardcoded-.patch b/queue-5.15/x86-numa-use-cpumask_available-instead-of-hardcoded-.patch
new file mode 100644 (file)
index 0000000..a64ed83
--- /dev/null
@@ -0,0 +1,76 @@
+From e8adad2c5fcd5103f24c5e6ec43bf133f11e842d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 31 Jul 2022 21:39:13 +0530
+Subject: x86/numa: Use cpumask_available instead of hardcoded NULL check
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Siddh Raman Pant <code@siddh.me>
+
+[ Upstream commit 625395c4a0f4775e0fe00f616888d2e6c1ba49db ]
+
+GCC-12 started triggering a new warning:
+
+  arch/x86/mm/numa.c: In function ‘cpumask_of_node’:
+  arch/x86/mm/numa.c:916:39: warning: the comparison will always evaluate as ‘false’ for the address of ‘node_to_cpumask_map’ will never be NULL [-Waddress]
+    916 |         if (node_to_cpumask_map[node] == NULL) {
+        |                                       ^~
+
+node_to_cpumask_map is of type cpumask_var_t[].
+
+When CONFIG_CPUMASK_OFFSTACK is set, cpumask_var_t is typedef'd to a
+pointer for dynamic allocation, else to an array of one element. The
+"wicked game" can be checked on line 700 of include/linux/cpumask.h.
+
+The original code in debug_cpumask_set_cpu() and cpumask_of_node() were
+probably written by the original authors with CONFIG_CPUMASK_OFFSTACK=y
+(i.e. dynamic allocation) in mind, checking if the cpumask was available
+via a direct NULL check.
+
+When CONFIG_CPUMASK_OFFSTACK is not set, GCC gives the above warning
+while compiling the kernel.
+
+Fix that by using cpumask_available(), which does the NULL check when
+CONFIG_CPUMASK_OFFSTACK is set, otherwise returns true. Use it wherever
+such checks are made.
+
+Conditional definitions of cpumask_available() can be found along with
+the definition of cpumask_var_t. Check the cpumask.h reference mentioned
+above.
+
+Fixes: c032ef60d1aa ("cpumask: convert node_to_cpumask_map[] to cpumask_var_t")
+Fixes: de2d9445f162 ("x86: Unify node_to_cpumask_map handling between 32 and 64bit")
+Signed-off-by: Siddh Raman Pant <code@siddh.me>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Link: https://lore.kernel.org/r/20220731160913.632092-1-code@siddh.me
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/mm/numa.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
+index 1e9b93b088db..e360c6892a58 100644
+--- a/arch/x86/mm/numa.c
++++ b/arch/x86/mm/numa.c
+@@ -860,7 +860,7 @@ void debug_cpumask_set_cpu(int cpu, int node, bool enable)
+               return;
+       }
+       mask = node_to_cpumask_map[node];
+-      if (!mask) {
++      if (!cpumask_available(mask)) {
+               pr_err("node_to_cpumask_map[%i] NULL\n", node);
+               dump_stack();
+               return;
+@@ -906,7 +906,7 @@ const struct cpumask *cpumask_of_node(int node)
+               dump_stack();
+               return cpu_none_mask;
+       }
+-      if (node_to_cpumask_map[node] == NULL) {
++      if (!cpumask_available(node_to_cpumask_map[node])) {
+               printk(KERN_WARNING
+                       "cpumask_of_node(%d): no node_to_cpumask_map!\n",
+                       node);
+-- 
+2.35.1
+
diff --git a/queue-5.15/x86-pmem-fix-platform-device-leak-in-error-path.patch b/queue-5.15/x86-pmem-fix-platform-device-leak-in-error-path.patch
new file mode 100644 (file)
index 0000000..60623fc
--- /dev/null
@@ -0,0 +1,41 @@
+From 4ef115431cde4723ee6888e31486e27a78e5112c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jun 2022 16:07:23 +0200
+Subject: x86/pmem: Fix platform-device leak in error path
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit 229e73d46994f15314f58b2d39bf952111d89193 ]
+
+Make sure to free the platform device in the unlikely event that
+registration fails.
+
+Fixes: 7a67832c7e44 ("libnvdimm, e820: make CONFIG_X86_PMEM_LEGACY a tristate option")
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Link: https://lore.kernel.org/r/20220620140723.9810-1-johan@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/pmem.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/arch/x86/kernel/pmem.c b/arch/x86/kernel/pmem.c
+index 6b07faaa1579..23154d24b117 100644
+--- a/arch/x86/kernel/pmem.c
++++ b/arch/x86/kernel/pmem.c
+@@ -27,6 +27,11 @@ static __init int register_e820_pmem(void)
+        * simply here to trigger the module to load on demand.
+        */
+       pdev = platform_device_alloc("e820_pmem", -1);
+-      return platform_device_add(pdev);
++
++      rc = platform_device_add(pdev);
++      if (rc)
++              platform_device_put(pdev);
++
++      return rc;
+ }
+ device_initcall(register_e820_pmem);
+-- 
+2.35.1
+
diff --git a/queue-5.15/xtensa-iss-fix-handling-error-cases-in-iss_net_confi.patch b/queue-5.15/xtensa-iss-fix-handling-error-cases-in-iss_net_confi.patch
new file mode 100644 (file)
index 0000000..84a9655
--- /dev/null
@@ -0,0 +1,111 @@
+From 8677cb2b756de489f99e2087c0fb99c221b42c26 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Jul 2022 10:32:29 +0800
+Subject: xtensa: iss: fix handling error cases in iss_net_configure()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 628ccfc8f5f79dd548319408fcc53949fe97b258 ]
+
+The 'pdev' and 'netdev' need to be released in error cases of
+iss_net_configure().
+
+Change the return type of iss_net_configure() to void, because it's
+not used.
+
+Fixes: 7282bee78798 ("[PATCH] xtensa: Architecture support for Tensilica Xtensa Part 8")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/xtensa/platforms/iss/network.c | 32 ++++++++++++++---------------
+ 1 file changed, 15 insertions(+), 17 deletions(-)
+
+diff --git a/arch/xtensa/platforms/iss/network.c b/arch/xtensa/platforms/iss/network.c
+index 4801df4e73e1..08d70c868c13 100644
+--- a/arch/xtensa/platforms/iss/network.c
++++ b/arch/xtensa/platforms/iss/network.c
+@@ -511,16 +511,15 @@ static void iss_net_pdev_release(struct device *dev)
+       free_netdev(lp->dev);
+ }
+-static int iss_net_configure(int index, char *init)
++static void iss_net_configure(int index, char *init)
+ {
+       struct net_device *dev;
+       struct iss_net_private *lp;
+-      int err;
+       dev = alloc_etherdev(sizeof(*lp));
+       if (dev == NULL) {
+               pr_err("eth_configure: failed to allocate device\n");
+-              return 1;
++              return;
+       }
+       /* Initialize private element. */
+@@ -549,7 +548,7 @@ static int iss_net_configure(int index, char *init)
+       if (!tuntap_probe(lp, index, init)) {
+               pr_err("%s: invalid arguments. Skipping device!\n",
+                      dev->name);
+-              goto errout;
++              goto err_free_netdev;
+       }
+       pr_info("Netdevice %d (%pM)\n", index, dev->dev_addr);
+@@ -557,7 +556,8 @@ static int iss_net_configure(int index, char *init)
+       /* sysfs register */
+       if (!driver_registered) {
+-              platform_driver_register(&iss_net_driver);
++              if (platform_driver_register(&iss_net_driver))
++                      goto err_free_netdev;
+               driver_registered = 1;
+       }
+@@ -568,7 +568,8 @@ static int iss_net_configure(int index, char *init)
+       lp->pdev.id = index;
+       lp->pdev.name = DRIVER_NAME;
+       lp->pdev.dev.release = iss_net_pdev_release;
+-      platform_device_register(&lp->pdev);
++      if (platform_device_register(&lp->pdev))
++              goto err_free_netdev;
+       SET_NETDEV_DEV(dev, &lp->pdev.dev);
+       dev->netdev_ops = &iss_netdev_ops;
+@@ -577,23 +578,20 @@ static int iss_net_configure(int index, char *init)
+       dev->irq = -1;
+       rtnl_lock();
+-      err = register_netdevice(dev);
+-      rtnl_unlock();
+-
+-      if (err) {
++      if (register_netdevice(dev)) {
++              rtnl_unlock();
+               pr_err("%s: error registering net device!\n", dev->name);
+-              /* XXX: should we call ->remove() here? */
+-              free_netdev(dev);
+-              return 1;
++              platform_device_unregister(&lp->pdev);
++              return;
+       }
++      rtnl_unlock();
+       timer_setup(&lp->tl, iss_net_user_timer_expire, 0);
+-      return 0;
++      return;
+-errout:
+-      /* FIXME: unregister; free, etc.. */
+-      return -EIO;
++err_free_netdev:
++      free_netdev(dev);
+ }
+ /* ------------------------------------------------------------------------- */
+-- 
+2.35.1
+
diff --git a/queue-5.15/xtensa-iss-network-provide-release-callback.patch b/queue-5.15/xtensa-iss-network-provide-release-callback.patch
new file mode 100644 (file)
index 0000000..66c2503
--- /dev/null
@@ -0,0 +1,50 @@
+From ff117b7db86c262de01366c38ed4f806b8fc81b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Jul 2022 00:23:16 -0700
+Subject: xtensa: iss/network: provide release() callback
+
+From: Max Filippov <jcmvbkbc@gmail.com>
+
+[ Upstream commit 8864fb8359682912ee99235db7db916733a1fd7b ]
+
+Provide release() callback for the platform device embedded into struct
+iss_net_private and registered in the iss_net_configure so that
+platform_device_unregister could be called for it.
+
+Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/xtensa/platforms/iss/network.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/arch/xtensa/platforms/iss/network.c b/arch/xtensa/platforms/iss/network.c
+index 4986226a5ab2..4801df4e73e1 100644
+--- a/arch/xtensa/platforms/iss/network.c
++++ b/arch/xtensa/platforms/iss/network.c
+@@ -502,6 +502,15 @@ static const struct net_device_ops iss_netdev_ops = {
+       .ndo_set_rx_mode        = iss_net_set_multicast_list,
+ };
++static void iss_net_pdev_release(struct device *dev)
++{
++      struct platform_device *pdev = to_platform_device(dev);
++      struct iss_net_private *lp =
++              container_of(pdev, struct iss_net_private, pdev);
++
++      free_netdev(lp->dev);
++}
++
+ static int iss_net_configure(int index, char *init)
+ {
+       struct net_device *dev;
+@@ -558,6 +567,7 @@ static int iss_net_configure(int index, char *init)
+       lp->pdev.id = index;
+       lp->pdev.name = DRIVER_NAME;
++      lp->pdev.dev.release = iss_net_pdev_release;
+       platform_device_register(&lp->pdev);
+       SET_NETDEV_DEV(dev, &lp->pdev.dev);
+-- 
+2.35.1
+