]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.12
authorSasha Levin <sashal@kernel.org>
Sat, 8 May 2021 03:21:15 +0000 (23:21 -0400)
committerSasha Levin <sashal@kernel.org>
Sat, 8 May 2021 03:21:15 +0000 (23:21 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
207 files changed:
queue-5.12/amdgpu-avoid-incorrect-hu-format-string.patch [new file with mode: 0644]
queue-5.12/arm-dts-at91-change-the-key-code-of-the-gpio-key.patch [new file with mode: 0644]
queue-5.12/arm-dts-bcm5301x-fix-reg-formatting-in-memory-node.patch [new file with mode: 0644]
queue-5.12/arm-dts-ux500-fix-up-tvk-r3-sensors.patch [new file with mode: 0644]
queue-5.12/arm-tegra-acer-a500-rename-avdd-to-vdda-of-touchscre.patch [new file with mode: 0644]
queue-5.12/arm64-dts-imx8mq-librem5-r3-mark-buck3-as-always-on.patch [new file with mode: 0644]
queue-5.12/ata-ahci-disable-sxs-for-hisilicon-kunpeng920.patch [new file with mode: 0644]
queue-5.12/atomisp-don-t-let-it-go-past-pipes-array.patch [new file with mode: 0644]
queue-5.12/backlight-qcom-wled-fix-fsc-update-issue-for-wled5.patch [new file with mode: 0644]
queue-5.12/backlight-qcom-wled-use-sink_addr-for-sync-toggle.patch [new file with mode: 0644]
queue-5.12/block-bfq-fix-weight-raising-resume-with-low_latency.patch [new file with mode: 0644]
queue-5.12/block-rnbd-clt-fix-missing-a-memory-free-when-unload.patch [new file with mode: 0644]
queue-5.12/block-rnbd-srv-prevent-a-deadlock-generated-by-acces.patch [new file with mode: 0644]
queue-5.12/btrfs-convert-logic-bug_on-s-in-replace_path-to-asse.patch [new file with mode: 0644]
queue-5.12/btrfs-do-proper-error-handling-in-btrfs_update_reloc.patch [new file with mode: 0644]
queue-5.12/btrfs-do-proper-error-handling-in-create_reloc_root.patch [new file with mode: 0644]
queue-5.12/btrfs-fix-exhaustion-of-the-system-chunk-array-due-t.patch [new file with mode: 0644]
queue-5.12/btrfs-fix-race-between-marking-inode-needs-to-be-log.patch [new file with mode: 0644]
queue-5.12/btrfs-use-btrfs_inode_lock-btrfs_inode_unlock-inode-.patch [new file with mode: 0644]
queue-5.12/bus-mhi-core-clear-context-for-stopped-channels-from.patch [new file with mode: 0644]
queue-5.12/bus-mhi-core-destroy-sbl-devices-when-moving-to-miss.patch [new file with mode: 0644]
queue-5.12/bus-mhi-core-process-execution-environment-changes-s.patch [new file with mode: 0644]
queue-5.12/bus-mhi-pci_generic-implement-pci-shutdown-callback.patch [new file with mode: 0644]
queue-5.12/bus-mhi-pci_generic-no-op-for-device_wake-operations.patch [new file with mode: 0644]
queue-5.12/bus-ti-sysc-probe-for-l4_wkup-and-l4_cfg-interconnec.patch [new file with mode: 0644]
queue-5.12/clk-socfpga-arria10-fix-memory-leak-of-socfpga_clk-o.patch [new file with mode: 0644]
queue-5.12/clocksource-drivers-dw_apb_timer_of-add-handling-for.patch [new file with mode: 0644]
queue-5.12/crypto-api-check-for-err-pointers-in-crypto_destroy_.patch [new file with mode: 0644]
queue-5.12/crypto-hisilicon-sec-fixes-a-printing-error.patch [new file with mode: 0644]
queue-5.12/crypto-omap-aes-fix-pm-reference-leak-on-omap-aes.c.patch [new file with mode: 0644]
queue-5.12/crypto-qat-fix-unmap-invalid-dma-address.patch [new file with mode: 0644]
queue-5.12/crypto-sa2ul-fix-pm-reference-leak-in-sa_ul_probe.patch [new file with mode: 0644]
queue-5.12/crypto-stm32-cryp-fix-pm-reference-leak-on-stm32-cry.patch [new file with mode: 0644]
queue-5.12/crypto-stm32-hash-fix-pm-reference-leak-on-stm32-has.patch [new file with mode: 0644]
queue-5.12/crypto-sun4i-ss-fix-pm-reference-leak-when-pm_runtim.patch [new file with mode: 0644]
queue-5.12/crypto-sun8i-ce-fix-pm-reference-leak-in-sun8i_ce_pr.patch [new file with mode: 0644]
queue-5.12/crypto-sun8i-ss-fix-pm-reference-leak-when-pm_runtim.patch [new file with mode: 0644]
queue-5.12/drm-added-orientation-quirk-for-onegx1-pro.patch [new file with mode: 0644]
queue-5.12/drm-amd-display-align-cursor-cache-address-to-2kb.patch [new file with mode: 0644]
queue-5.12/drm-amd-display-changing-sr-exit-latency.patch [new file with mode: 0644]
queue-5.12/drm-amd-display-check-for-dsc-support-instead-of-asi.patch [new file with mode: 0644]
queue-5.12/drm-amd-display-dc-dce-dce_aux-remove-duplicate-line.patch [new file with mode: 0644]
queue-5.12/drm-amd-display-dchub-underflow-counter-increasing-i.patch [new file with mode: 0644]
queue-5.12/drm-amd-display-don-t-optimize-bandwidth-before-disa.patch [new file with mode: 0644]
queue-5.12/drm-amd-display-fix-debugfs-link_settings-entry.patch [new file with mode: 0644]
queue-5.12/drm-amd-display-fix-dml-prefetch-validation.patch [new file with mode: 0644]
queue-5.12/drm-amd-display-fix-mpc-ogam-power-on-off-sequence.patch [new file with mode: 0644]
queue-5.12/drm-amd-display-fix-potential-memory-leak.patch [new file with mode: 0644]
queue-5.12/drm-amd-display-fix-ubsan-shift-out-of-bounds-warnin.patch [new file with mode: 0644]
queue-5.12/drm-amd-display-fix-ubsan-warning-for-not-a-valid-va.patch [new file with mode: 0644]
queue-5.12/drm-amd-display-return-invalid-state-if-gpint-times-.patch [new file with mode: 0644]
queue-5.12/drm-amd-display-try-ycbcr420-color-when-ycbcr444-fai.patch [new file with mode: 0644]
queue-5.12/drm-amd-display-update-dcn302-sr-exit-latency.patch [new file with mode: 0644]
queue-5.12/drm-amd-pm-do-not-issue-message-while-write-r-into-p.patch [new file with mode: 0644]
queue-5.12/drm-amd-pm-fix-workload-mismatch-on-vega10.patch [new file with mode: 0644]
queue-5.12/drm-amd-pm-swsmu-clean-up-user-profile-function.patch [new file with mode: 0644]
queue-5.12/drm-amdgpu-display-buffer-interrupt_low_irq_context-.patch [new file with mode: 0644]
queue-5.12/drm-amdgpu-display-fix-memory-leak-for-dimgrey-cavef.patch [new file with mode: 0644]
queue-5.12/drm-amdgpu-enable-48-bit-ih-timestamp-counter.patch [new file with mode: 0644]
queue-5.12/drm-amdgpu-enable-retry-fault-wptr-overflow.patch [new file with mode: 0644]
queue-5.12/drm-amdgpu-fix-asic-reset-regression-issue-introduce.patch [new file with mode: 0644]
queue-5.12/drm-amdgpu-fix-memory-leak.patch [new file with mode: 0644]
queue-5.12/drm-amdgpu-fix-null-pointer-dereference.patch [new file with mode: 0644]
queue-5.12/drm-amdgpu-fix-some-unload-driver-issues.patch [new file with mode: 0644]
queue-5.12/drm-amdgpu-mask-the-xgmi-number-of-hops-reported-fro.patch [new file with mode: 0644]
queue-5.12/drm-amdgpu-ttm-fix-memory-leak-userptr-pages.patch [new file with mode: 0644]
queue-5.12/drm-amdkfd-fix-cat-debugfs-hang_hws-file-causes-syst.patch [new file with mode: 0644]
queue-5.12/drm-amdkfd-fix-ubsan-shift-out-of-bounds-warning.patch [new file with mode: 0644]
queue-5.12/drm-ast-fix-invalid-usage-of-ast_max_hwc_width-in-cu.patch [new file with mode: 0644]
queue-5.12/drm-ast-fix-memory-leak-when-unload-the-driver.patch [new file with mode: 0644]
queue-5.12/drm-komeda-fix-bit-check-to-import-to-value-of-prope.patch [new file with mode: 0644]
queue-5.12/drm-msm-a6xx-fix-perfcounter-oob-timeout.patch [new file with mode: 0644]
queue-5.12/drm-msm-dp-fix-incorrect-null-check-kbot-warnings-in.patch [new file with mode: 0644]
queue-5.12/drm-msm-mdp5-configure-pp_sync_height-to-double-the-.patch [new file with mode: 0644]
queue-5.12/drm-msm-mdp5-do-not-multiply-vclk-line-count-by-100.patch [new file with mode: 0644]
queue-5.12/drm-qxl-do-not-run-release-if-qxl-failed-to-init.patch [new file with mode: 0644]
queue-5.12/drm-qxl-release-shadow-on-shutdown.patch [new file with mode: 0644]
queue-5.12/drm-radeon-don-t-evict-if-not-initialized.patch [new file with mode: 0644]
queue-5.12/drm-radeon-ttm-fix-memory-leak-userptr-pages.patch [new file with mode: 0644]
queue-5.12/drm-virtio-fix-possible-leak-unlock-virtio_gpu_objec.patch [new file with mode: 0644]
queue-5.12/drm-vkms-fix-misuse-of-warn_on.patch [new file with mode: 0644]
queue-5.12/efi-libstub-add-clang_flags-to-x86-flags.patch [new file with mode: 0644]
queue-5.12/extcon-arizona-fix-some-issues-when-hpdet-irq-fires-.patch [new file with mode: 0644]
queue-5.12/extcon-arizona-fix-various-races-on-driver-unbind.patch [new file with mode: 0644]
queue-5.12/fpga-dfl-pci-add-did-for-d5005-pac-cards.patch [new file with mode: 0644]
queue-5.12/genirq-matrix-prevent-allocation-counter-corruption.patch [new file with mode: 0644]
queue-5.12/intel_th-consistency-and-off-by-one-fix.patch [new file with mode: 0644]
queue-5.12/io_uring-safer-sq_creds-putting.patch [new file with mode: 0644]
queue-5.12/kselftest-arm64-mte-fix-compilation-with-native-comp.patch [new file with mode: 0644]
queue-5.12/kselftest-arm64-mte-fix-mte-feature-detection.patch [new file with mode: 0644]
queue-5.12/kvfree_rcu-use-same-set-of-gfp-flags-as-does-single-.patch [new file with mode: 0644]
queue-5.12/media-adv7604-fix-possible-use-after-free-in-adv76xx.patch [new file with mode: 0644]
queue-5.12/media-cx23885-add-more-quirks-for-reset-dma-on-some-.patch [new file with mode: 0644]
queue-5.12/media-drivers-media-pci-sta2x11-fix-kconfig-dependen.patch [new file with mode: 0644]
queue-5.12/media-drivers-media-usb-fix-memory-leak-in-zr364xx_p.patch [new file with mode: 0644]
queue-5.12/media-dvb-usb-fix-memory-leak-in-dvb_usb_adapter_ini.patch [new file with mode: 0644]
queue-5.12/media-em28xx-fix-memory-leak.patch [new file with mode: 0644]
queue-5.12/media-gscpa-stv06xx-fix-memory-leak.patch [new file with mode: 0644]
queue-5.12/media-gspca-sq905.c-fix-uninitialized-variable.patch [new file with mode: 0644]
queue-5.12/media-i2c-adv7511-v4l2-fix-possible-use-after-free-i.patch [new file with mode: 0644]
queue-5.12/media-i2c-adv7842-fix-possible-use-after-free-in-adv.patch [new file with mode: 0644]
queue-5.12/media-i2c-tda1997-fix-possible-use-after-free-in-tda.patch [new file with mode: 0644]
queue-5.12/media-imx-capture-return-epipe-from-__capture_legacy.patch [new file with mode: 0644]
queue-5.12/media-ite-cir-check-for-receive-overflow.patch [new file with mode: 0644]
queue-5.12/media-media-saa7164-fix-saa7164_encoder_register-mem.patch [new file with mode: 0644]
queue-5.12/media-platform-sti-fix-runtime-pm-imbalance-in-regs_.patch [new file with mode: 0644]
queue-5.12/media-sun8i-di-fix-runtime-pm-imbalance-in-deinterla.patch [new file with mode: 0644]
queue-5.12/media-tc358743-fix-possible-use-after-free-in-tc3587.patch [new file with mode: 0644]
queue-5.12/media-uvcvideo-fix-xu-id-print-in-forward-scan.patch [new file with mode: 0644]
queue-5.12/media-uvcvideo-support-devices-that-report-an-ot-as-.patch [new file with mode: 0644]
queue-5.12/media-v4l2-ctrls.c-initialize-flags-field-of-p_fwht_.patch [new file with mode: 0644]
queue-5.12/media-venus-core-venc-vdec-fix-probe-dependency-erro.patch [new file with mode: 0644]
queue-5.12/media-vivid-update-edid.patch [new file with mode: 0644]
queue-5.12/mfd-arizona-fix-rumtime-pm-imbalance-on-error.patch [new file with mode: 0644]
queue-5.12/mfd-da9063-support-smbus-and-i2c-mode.patch [new file with mode: 0644]
queue-5.12/mfd-intel-m10-bmc-fix-the-register-access-range.patch [new file with mode: 0644]
queue-5.12/mmc-sdhci-brcmstb-remove-cqe-quirk.patch [new file with mode: 0644]
queue-5.12/mmc-sdhci-esdhc-imx-validate-pinctrl-before-use-it.patch [new file with mode: 0644]
queue-5.12/mmc-sdhci-pci-add-pci-ids-for-intel-lkf.patch [new file with mode: 0644]
queue-5.12/nvmet-avoid-queuing-keep-alive-timer-if-it-is-disabl.patch [new file with mode: 0644]
queue-5.12/nvmet-return-proper-error-code-from-discovery-ctrl.patch [new file with mode: 0644]
queue-5.12/pci-pm-do-not-read-power-state-in-pci_enable_device_.patch [new file with mode: 0644]
queue-5.12/perf-arm_pmu_platform-fix-error-handling.patch [new file with mode: 0644]
queue-5.12/perf-arm_pmu_platform-use-dev_err_probe-for-irq-erro.patch [new file with mode: 0644]
queue-5.12/perf-rework-perf_event_exit_event.patch [new file with mode: 0644]
queue-5.12/phy-phy-twl4030-usb-fix-possible-use-after-free-in-t.patch [new file with mode: 0644]
queue-5.12/platform-x86-intel_pmc_core-don-t-use-global-pmcdev-.patch [new file with mode: 0644]
queue-5.12/platform-x86-isst-account-for-increased-timeout-in-s.patch [new file with mode: 0644]
queue-5.12/power-supply-bq27xxx-fix-power_avg-for-newer-ics.patch [new file with mode: 0644]
queue-5.12/power-supply-cpcap-battery-fix-invalid-usage-of-list.patch [new file with mode: 0644]
queue-5.12/power-supply-cpcap-charger-add-usleep-to-cpcap-charg.patch [new file with mode: 0644]
queue-5.12/power-supply-cpcap-charger-fix-small-mistake-in-curr.patch [new file with mode: 0644]
queue-5.12/power-supply-generic-adc-battery-fix-possible-use-af.patch [new file with mode: 0644]
queue-5.12/power-supply-s3c_adc_battery-fix-possible-use-after-.patch [new file with mode: 0644]
queue-5.12/power-supply-use-irqf_oneshot.patch [new file with mode: 0644]
queue-5.12/random-initialize-chacha20-constants-with-correct-en.patch [new file with mode: 0644]
queue-5.12/regulator-da9121-automotive-variants-identity-fix.patch [new file with mode: 0644]
queue-5.12/resource-prevent-irqresource_disabled-from-erasing-f.patch [new file with mode: 0644]
queue-5.12/s390-archrandom-add-parameter-check-for-s390_arch_ra.patch [new file with mode: 0644]
queue-5.12/s390-pci-expose-uid-uniqueness-guarantee.patch [new file with mode: 0644]
queue-5.12/s390-qdio-let-driver-manage-the-qaob.patch [new file with mode: 0644]
queue-5.12/sched-fair-alternative-sched_slice.patch [new file with mode: 0644]
queue-5.12/sched-fair-bring-back-select_idle_smt-but-differentl.patch [new file with mode: 0644]
queue-5.12/sched-fair-fix-task-utilization-accountability-in-co.patch [new file with mode: 0644]
queue-5.12/sched-fair-ignore-percpu-threads-for-imbalance-pulls.patch [new file with mode: 0644]
queue-5.12/sched-pelt-fix-task-util_est-update-filtering.patch [new file with mode: 0644]
queue-5.12/sched-psi-handle-potential-task-count-underflow-bugs.patch [new file with mode: 0644]
queue-5.12/sched-topology-fix-the-issue-groups-don-t-span-domai.patch [new file with mode: 0644]
queue-5.12/scsi-libfc-fix-a-format-specifier.patch [new file with mode: 0644]
queue-5.12/scsi-lpfc-fix-adisc-handling-that-never-frees-nodes.patch [new file with mode: 0644]
queue-5.12/scsi-lpfc-fix-crash-when-a-reg_rpi-mailbox-fails-tri.patch [new file with mode: 0644]
queue-5.12/scsi-lpfc-fix-error-handling-for-mailboxes-completed.patch [new file with mode: 0644]
queue-5.12/scsi-lpfc-fix-incorrect-dbde-assignment-when-buildin.patch [new file with mode: 0644]
queue-5.12/scsi-lpfc-fix-plogi-acc-to-be-transmit-after-reg_log.patch [new file with mode: 0644]
queue-5.12/scsi-lpfc-fix-pt2pt-connection-does-not-recover-afte.patch [new file with mode: 0644]
queue-5.12/scsi-lpfc-fix-reference-counting-errors-in-lpfc_cmpl.patch [new file with mode: 0644]
queue-5.12/scsi-lpfc-fix-status-returned-in-lpfc_els_retry-erro.patch [new file with mode: 0644]
queue-5.12/scsi-lpfc-remove-unsupported-mbox-port_capabilities-.patch [new file with mode: 0644]
queue-5.12/scsi-mpt3sas-fix-out-of-bounds-warnings-in-_ctl_addn.patch [new file with mode: 0644]
queue-5.12/scsi-qla2xxx-always-check-the-return-value-of-qla24x.patch [new file with mode: 0644]
queue-5.12/scsi-qla2xxx-fix-use-after-free-in-bsg.patch [new file with mode: 0644]
queue-5.12/scsi-scsi_dh_alua-remove-check-for-asc-24h-in-alua_r.patch [new file with mode: 0644]
queue-5.12/scsi-smartpqi-add-new-pci-ids.patch [new file with mode: 0644]
queue-5.12/scsi-smartpqi-correct-request-leakage-during-reset-o.patch [new file with mode: 0644]
queue-5.12/scsi-smartpqi-use-host-wide-tag-space.patch [new file with mode: 0644]
queue-5.12/scsi-target-pscsi-fix-warning-in-pscsi_complete_cmd.patch [new file with mode: 0644]
queue-5.12/selftests-resctrl-clean-up-resctrl-features-check.patch [new file with mode: 0644]
queue-5.12/selftests-resctrl-enable-gcc-checks-to-detect-buffer.patch [new file with mode: 0644]
queue-5.12/selftests-resctrl-fix-checking-for-0-for-unsigned-va.patch [new file with mode: 0644]
queue-5.12/selftests-resctrl-fix-compilation-issues-for-global-.patch [new file with mode: 0644]
queue-5.12/selftests-resctrl-fix-compilation-issues-for-other-g.patch [new file with mode: 0644]
queue-5.12/selftests-resctrl-fix-incorrect-parsing-of-imc-count.patch [new file with mode: 0644]
queue-5.12/selftests-resctrl-fix-missing-options-n-and-p.patch [new file with mode: 0644]
queue-5.12/selftests-resctrl-use-resctrl-info-for-feature-detec.patch [new file with mode: 0644]
queue-5.12/series
queue-5.12/soc-tegra-pmc-fix-completion-of-power-gate-toggling.patch [new file with mode: 0644]
queue-5.12/soundwire-cadence-only-prepare-attached-devices-on-c.patch [new file with mode: 0644]
queue-5.12/spi-ath79-always-call-chipselect-function.patch [new file with mode: 0644]
queue-5.12/spi-ath79-remove-spi-master-setup-and-cleanup-assign.patch [new file with mode: 0644]
queue-5.12/spi-dln2-fix-reference-leak-to-master.patch [new file with mode: 0644]
queue-5.12/spi-omap-100k-fix-reference-leak-to-master.patch [new file with mode: 0644]
queue-5.12/spi-qup-fix-pm-reference-leak-in-spi_qup_remove.patch [new file with mode: 0644]
queue-5.12/spi-sync-up-initial-chipselect-state.patch [new file with mode: 0644]
queue-5.12/staging-wimax-i2400m-fix-byte-order-issue.patch [new file with mode: 0644]
queue-5.12/tee-optee-do-not-check-memref-size-on-return-from-se.patch [new file with mode: 0644]
queue-5.12/tools-power-x86-intel-speed-select-increase-string-s.patch [new file with mode: 0644]
queue-5.12/tty-n_gsm-check-error-while-registering-tty-devices.patch [new file with mode: 0644]
queue-5.12/usb-core-hub-fix-pm-reference-leak-in-usb_port_resum.patch [new file with mode: 0644]
queue-5.12/usb-dwc3-gadget-check-for-disabled-lpm-quirk.patch [new file with mode: 0644]
queue-5.12/usb-dwc3-gadget-ignore-ep-queue-requests-during-bus-.patch [new file with mode: 0644]
queue-5.12/usb-dwc3-pci-add-support-for-the-intel-alder-lake-m.patch [new file with mode: 0644]
queue-5.12/usb-gadget-f_uac1-validate-input-parameters.patch [new file with mode: 0644]
queue-5.12/usb-gadget-f_uac2-validate-input-parameters.patch [new file with mode: 0644]
queue-5.12/usb-gadget-tegra-xudc-fix-possible-use-after-free-in.patch [new file with mode: 0644]
queue-5.12/usb-gadget-uvc-add-binterval-checking-for-hs-mode.patch [new file with mode: 0644]
queue-5.12/usb-musb-fix-pm-reference-leak-in-musb_irq_work.patch [new file with mode: 0644]
queue-5.12/usb-webcam-invalid-size-of-processing-unit-descripto.patch [new file with mode: 0644]
queue-5.12/usb-xhci-fix-port-minor-revision.patch [new file with mode: 0644]
queue-5.12/usb-xhci-mtk-support-quirk-to-disable-usb2-lpm.patch [new file with mode: 0644]
queue-5.12/x86-boot-add-clang_flags-to-compressed-kbuild_cflags.patch [new file with mode: 0644]
queue-5.12/x86-boot-compressed-64-check-sev-encryption-in-the-3.patch [new file with mode: 0644]
queue-5.12/x86-build-propagate-clang_flags-to-realmode_flags.patch [new file with mode: 0644]
queue-5.12/x86-sev-do-not-require-hypervisor-cpuid-bit-for-sev-.patch [new file with mode: 0644]
queue-5.12/xhci-check-control-context-is-valid-before-dereferen.patch [new file with mode: 0644]
queue-5.12/xhci-check-port-array-allocation-was-successful-befo.patch [new file with mode: 0644]
queue-5.12/xhci-fix-potential-array-out-of-bounds-with-several-.patch [new file with mode: 0644]
queue-5.12/xhci-prevent-double-fetch-of-transfer-and-transfer-e.patch [new file with mode: 0644]

diff --git a/queue-5.12/amdgpu-avoid-incorrect-hu-format-string.patch b/queue-5.12/amdgpu-avoid-incorrect-hu-format-string.patch
new file mode 100644 (file)
index 0000000..2c86d76
--- /dev/null
@@ -0,0 +1,50 @@
+From 30f18b933e0dc36b87db507ff5388ad8bd2151e9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Mar 2021 12:54:42 +0100
+Subject: amdgpu: avoid incorrect %hu format string
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 7d98d416c2cc1c1f7d9508e887de4630e521d797 ]
+
+clang points out that the %hu format string does not match the type
+of the variables here:
+
+drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c:263:7: warning: format specifies type 'unsigned short' but the argument has type 'unsigned int' [-Wformat]
+                                  version_major, version_minor);
+                                  ^~~~~~~~~~~~~
+include/drm/drm_print.h:498:19: note: expanded from macro 'DRM_ERROR'
+        __drm_err(fmt, ##__VA_ARGS__)
+                  ~~~    ^~~~~~~~~~~
+
+Change it to a regular %u, the same way a previous patch did for
+another instance of the same warning.
+
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Reviewed-by: Tom Rix <trix@redhat.com>
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
+index e2ed4689118a..c6dbc0801604 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
+@@ -259,7 +259,7 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev)
+               if ((adev->asic_type == CHIP_POLARIS10 ||
+                    adev->asic_type == CHIP_POLARIS11) &&
+                   (adev->uvd.fw_version < FW_1_66_16))
+-                      DRM_ERROR("POLARIS10/11 UVD firmware version %hu.%hu is too old.\n",
++                      DRM_ERROR("POLARIS10/11 UVD firmware version %u.%u is too old.\n",
+                                 version_major, version_minor);
+       } else {
+               unsigned int enc_major, enc_minor, dec_minor;
+-- 
+2.30.2
+
diff --git a/queue-5.12/arm-dts-at91-change-the-key-code-of-the-gpio-key.patch b/queue-5.12/arm-dts-at91-change-the-key-code-of-the-gpio-key.patch
new file mode 100644 (file)
index 0000000..814b9ff
--- /dev/null
@@ -0,0 +1,221 @@
+From 0e9b4693e6494877d27e1896ebbc77db79e82894 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Apr 2021 15:02:27 +0200
+Subject: ARM: dts: at91: change the key code of the gpio key
+
+From: Ludovic Desroches <ludovic.desroches@microchip.com>
+
+[ Upstream commit ca7a049ad1a72ec5f03d1330b53575237fcb727c ]
+
+Having a button code and not a key code causes issues with libinput.
+udev won't set ID_INPUT_KEY. If it is forced, then it causes a bug
+within libinput.
+
+Signed-off-by: Ludovic Desroches <ludovic.desroches@microchip.com>
+Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com>
+Link: https://lore.kernel.org/r/20210402130227.21478-1-nicolas.ferre@microchip.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/at91-sam9x60ek.dts          | 3 ++-
+ arch/arm/boot/dts/at91-sama5d27_som1_ek.dts   | 3 ++-
+ arch/arm/boot/dts/at91-sama5d27_wlsom1_ek.dts | 3 ++-
+ arch/arm/boot/dts/at91-sama5d2_icp.dts        | 3 ++-
+ arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts     | 3 ++-
+ arch/arm/boot/dts/at91-sama5d2_xplained.dts   | 3 ++-
+ arch/arm/boot/dts/at91-sama5d3_xplained.dts   | 3 ++-
+ arch/arm/boot/dts/at91sam9260ek.dts           | 3 ++-
+ arch/arm/boot/dts/at91sam9g20ek_common.dtsi   | 3 ++-
+ 9 files changed, 18 insertions(+), 9 deletions(-)
+
+diff --git a/arch/arm/boot/dts/at91-sam9x60ek.dts b/arch/arm/boot/dts/at91-sam9x60ek.dts
+index 775ceb3acb6c..edca66c232c1 100644
+--- a/arch/arm/boot/dts/at91-sam9x60ek.dts
++++ b/arch/arm/boot/dts/at91-sam9x60ek.dts
+@@ -8,6 +8,7 @@
+  */
+ /dts-v1/;
+ #include "sam9x60.dtsi"
++#include <dt-bindings/input/input.h>
+ / {
+       model = "Microchip SAM9X60-EK";
+@@ -84,7 +85,7 @@
+               sw1 {
+                       label = "SW1";
+                       gpios = <&pioD 18 GPIO_ACTIVE_LOW>;
+-                      linux,code=<0x104>;
++                      linux,code=<KEY_PROG1>;
+                       wakeup-source;
+               };
+       };
+diff --git a/arch/arm/boot/dts/at91-sama5d27_som1_ek.dts b/arch/arm/boot/dts/at91-sama5d27_som1_ek.dts
+index 84e1180f3e89..a9e6fee55a2a 100644
+--- a/arch/arm/boot/dts/at91-sama5d27_som1_ek.dts
++++ b/arch/arm/boot/dts/at91-sama5d27_som1_ek.dts
+@@ -11,6 +11,7 @@
+ #include "at91-sama5d27_som1.dtsi"
+ #include <dt-bindings/mfd/atmel-flexcom.h>
+ #include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/input/input.h>
+ / {
+       model = "Atmel SAMA5D27 SOM1 EK";
+@@ -466,7 +467,7 @@
+               pb4 {
+                       label = "USER";
+                       gpios = <&pioA PIN_PA29 GPIO_ACTIVE_LOW>;
+-                      linux,code = <0x104>;
++                      linux,code = <KEY_PROG1>;
+                       wakeup-source;
+               };
+       };
+diff --git a/arch/arm/boot/dts/at91-sama5d27_wlsom1_ek.dts b/arch/arm/boot/dts/at91-sama5d27_wlsom1_ek.dts
+index 180a08765cb8..ff83967fd008 100644
+--- a/arch/arm/boot/dts/at91-sama5d27_wlsom1_ek.dts
++++ b/arch/arm/boot/dts/at91-sama5d27_wlsom1_ek.dts
+@@ -8,6 +8,7 @@
+  */
+ /dts-v1/;
+ #include "at91-sama5d27_wlsom1.dtsi"
++#include <dt-bindings/input/input.h>
+ / {
+       model = "Microchip SAMA5D27 WLSOM1 EK";
+@@ -35,7 +36,7 @@
+               sw4 {
+                       label = "USER BUTTON";
+                       gpios = <&pioA PIN_PB2 GPIO_ACTIVE_LOW>;
+-                      linux,code = <0x104>;
++                      linux,code = <KEY_PROG1>;
+                       wakeup-source;
+               };
+       };
+diff --git a/arch/arm/boot/dts/at91-sama5d2_icp.dts b/arch/arm/boot/dts/at91-sama5d2_icp.dts
+index 46722a163184..bd64721fa23c 100644
+--- a/arch/arm/boot/dts/at91-sama5d2_icp.dts
++++ b/arch/arm/boot/dts/at91-sama5d2_icp.dts
+@@ -12,6 +12,7 @@
+ #include "sama5d2.dtsi"
+ #include "sama5d2-pinfunc.h"
+ #include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/input/input.h>
+ #include <dt-bindings/mfd/atmel-flexcom.h>
+ / {
+@@ -51,7 +52,7 @@
+               sw4 {
+                       label = "USER_PB1";
+                       gpios = <&pioA PIN_PD0 GPIO_ACTIVE_LOW>;
+-                      linux,code = <0x104>;
++                      linux,code = <KEY_PROG1>;
+                       wakeup-source;
+               };
+       };
+diff --git a/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts b/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts
+index 8de57d164acd..dfd150eb0fd8 100644
+--- a/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts
++++ b/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts
+@@ -11,6 +11,7 @@
+ #include "sama5d2-pinfunc.h"
+ #include <dt-bindings/mfd/atmel-flexcom.h>
+ #include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/input/input.h>
+ #include <dt-bindings/pinctrl/at91.h>
+ / {
+@@ -402,7 +403,7 @@
+               bp1 {
+                       label = "PB_USER";
+                       gpios = <&pioA PIN_PA10 GPIO_ACTIVE_LOW>;
+-                      linux,code = <0x104>;
++                      linux,code = <KEY_PROG1>;
+                       wakeup-source;
+               };
+       };
+diff --git a/arch/arm/boot/dts/at91-sama5d2_xplained.dts b/arch/arm/boot/dts/at91-sama5d2_xplained.dts
+index 4e7cf21f124c..509c732a0d8b 100644
+--- a/arch/arm/boot/dts/at91-sama5d2_xplained.dts
++++ b/arch/arm/boot/dts/at91-sama5d2_xplained.dts
+@@ -10,6 +10,7 @@
+ #include "sama5d2-pinfunc.h"
+ #include <dt-bindings/mfd/atmel-flexcom.h>
+ #include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/input/input.h>
+ #include <dt-bindings/regulator/active-semi,8945a-regulator.h>
+ / {
+@@ -712,7 +713,7 @@
+               bp1 {
+                       label = "PB_USER";
+                       gpios = <&pioA PIN_PB9 GPIO_ACTIVE_LOW>;
+-                      linux,code = <0x104>;
++                      linux,code = <KEY_PROG1>;
+                       wakeup-source;
+               };
+       };
+diff --git a/arch/arm/boot/dts/at91-sama5d3_xplained.dts b/arch/arm/boot/dts/at91-sama5d3_xplained.dts
+index 5179258f9247..9c55a921263b 100644
+--- a/arch/arm/boot/dts/at91-sama5d3_xplained.dts
++++ b/arch/arm/boot/dts/at91-sama5d3_xplained.dts
+@@ -7,6 +7,7 @@
+  */
+ /dts-v1/;
+ #include "sama5d36.dtsi"
++#include <dt-bindings/input/input.h>
+ / {
+       model = "SAMA5D3 Xplained";
+@@ -354,7 +355,7 @@
+               bp3 {
+                       label = "PB_USER";
+                       gpios = <&pioE 29 GPIO_ACTIVE_LOW>;
+-                      linux,code = <0x104>;
++                      linux,code = <KEY_PROG1>;
+                       wakeup-source;
+               };
+       };
+diff --git a/arch/arm/boot/dts/at91sam9260ek.dts b/arch/arm/boot/dts/at91sam9260ek.dts
+index d3446e42b598..ce96345d28a3 100644
+--- a/arch/arm/boot/dts/at91sam9260ek.dts
++++ b/arch/arm/boot/dts/at91sam9260ek.dts
+@@ -7,6 +7,7 @@
+  */
+ /dts-v1/;
+ #include "at91sam9260.dtsi"
++#include <dt-bindings/input/input.h>
+ / {
+       model = "Atmel at91sam9260ek";
+@@ -156,7 +157,7 @@
+               btn4 {
+                       label = "Button 4";
+                       gpios = <&pioA 31 GPIO_ACTIVE_LOW>;
+-                      linux,code = <0x104>;
++                      linux,code = <KEY_PROG1>;
+                       wakeup-source;
+               };
+       };
+diff --git a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
+index 6e6e672c0b86..87bb39060e8b 100644
+--- a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
++++ b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
+@@ -5,6 +5,7 @@
+  * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+  */
+ #include "at91sam9g20.dtsi"
++#include <dt-bindings/input/input.h>
+ / {
+@@ -234,7 +235,7 @@
+               btn4 {
+                       label = "Button 4";
+                       gpios = <&pioA 31 GPIO_ACTIVE_LOW>;
+-                      linux,code = <0x104>;
++                      linux,code = <KEY_PROG1>;
+                       wakeup-source;
+               };
+       };
+-- 
+2.30.2
+
diff --git a/queue-5.12/arm-dts-bcm5301x-fix-reg-formatting-in-memory-node.patch b/queue-5.12/arm-dts-bcm5301x-fix-reg-formatting-in-memory-node.patch
new file mode 100644 (file)
index 0000000..4a5bad1
--- /dev/null
@@ -0,0 +1,393 @@
+From 95b5a67e154287a2f189d0b32ac116a0ae7869e6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Mar 2021 13:55:00 +0100
+Subject: ARM: dts: BCM5301X: fix "reg" formatting in /memory node
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rafał Miłecki <rafal@milecki.pl>
+
+[ Upstream commit 43986f38818278bb71a7fef6de689637bb734afe ]
+
+This fixes warnings/errors like:
+arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dt.yaml: /: memory@0:reg:0: [0, 134217728, 2281701376, 402653184] is too long
+        From schema: /lib/python3.6/site-packages/dtschema/schemas/reg.yaml
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts        | 4 ++--
+ arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts        | 4 ++--
+ arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts  | 4 ++--
+ arch/arm/boot/dts/bcm4708-netgear-r6250.dts        | 4 ++--
+ arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts     | 4 ++--
+ arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts      | 4 ++--
+ arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts        | 4 ++--
+ arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts | 4 ++--
+ arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts  | 4 ++--
+ arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts        | 4 ++--
+ arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts  | 4 ++--
+ arch/arm/boot/dts/bcm4709-linksys-ea9200.dts       | 4 ++--
+ arch/arm/boot/dts/bcm4709-netgear-r7000.dts        | 4 ++--
+ arch/arm/boot/dts/bcm4709-netgear-r8000.dts        | 4 ++--
+ arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts      | 4 ++--
+ arch/arm/boot/dts/bcm47094-linksys-panamera.dts    | 4 ++--
+ arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts      | 4 ++--
+ arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts      | 4 ++--
+ arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts      | 4 ++--
+ arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts      | 4 ++--
+ arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts   | 4 ++--
+ arch/arm/boot/dts/bcm47094-netgear-r8500.dts       | 4 ++--
+ arch/arm/boot/dts/bcm47094-phicomm-k3.dts          | 4 ++--
+ 23 files changed, 46 insertions(+), 46 deletions(-)
+
+diff --git a/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts b/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
+index 6a96655d8626..8ed403767540 100644
+--- a/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
++++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
+@@ -21,8 +21,8 @@
+       memory@0 {
+               device_type = "memory";
+-              reg = <0x00000000 0x08000000
+-                     0x88000000 0x08000000>;
++              reg = <0x00000000 0x08000000>,
++                    <0x88000000 0x08000000>;
+       };
+       leds {
+diff --git a/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts b/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
+index 3b0029e61b4c..667b118ba4ee 100644
+--- a/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
++++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
+@@ -21,8 +21,8 @@
+       memory@0 {
+               device_type = "memory";
+-              reg = <0x00000000 0x08000000
+-                     0x88000000 0x08000000>;
++              reg = <0x00000000 0x08000000>,
++                    <0x88000000 0x08000000>;
+       };
+       leds {
+diff --git a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
+index 90f57bad6b24..ff31ce45831a 100644
+--- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
++++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
+@@ -21,8 +21,8 @@
+       memory@0 {
+               device_type = "memory";
+-              reg = <0x00000000 0x08000000
+-                     0x88000000 0x18000000>;
++              reg = <0x00000000 0x08000000>,
++                    <0x88000000 0x18000000>;
+       };
+       spi {
+diff --git a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
+index fed75e6ab58c..61c7b137607e 100644
+--- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
++++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
+@@ -22,8 +22,8 @@
+       memory {
+               device_type = "memory";
+-              reg = <0x00000000 0x08000000
+-                     0x88000000 0x08000000>;
++              reg = <0x00000000 0x08000000>,
++                    <0x88000000 0x08000000>;
+       };
+       leds {
+diff --git a/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts b/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
+index 79542e18915c..4c60eda296d9 100644
+--- a/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
++++ b/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
+@@ -21,8 +21,8 @@
+       memory@0 {
+               device_type = "memory";
+-              reg = <0x00000000 0x08000000
+-                     0x88000000 0x08000000>;
++              reg = <0x00000000 0x08000000>,
++                    <0x88000000 0x08000000>;
+       };
+       leds {
+diff --git a/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts b/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
+index 51c64f0b2560..9ca6d1b2590d 100644
+--- a/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
++++ b/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
+@@ -21,8 +21,8 @@
+       memory@0 {
+               device_type = "memory";
+-              reg = <0x00000000 0x08000000
+-                     0x88000000 0x08000000>;
++              reg = <0x00000000 0x08000000>,
++                    <0x88000000 0x08000000>;
+       };
+       leds {
+diff --git a/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts b/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
+index c29950b43a95..0e273c598732 100644
+--- a/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
++++ b/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
+@@ -21,8 +21,8 @@
+       memory@0 {
+               device_type = "memory";
+-              reg = <0x00000000 0x08000000
+-                     0x88000000 0x08000000>;
++              reg = <0x00000000 0x08000000>,
++                    <0x88000000 0x08000000>;
+       };
+       leds {
+diff --git a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
+index 2f2d2b0a6893..d857751ec507 100644
+--- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
++++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
+@@ -21,8 +21,8 @@
+       memory@0 {
+               device_type = "memory";
+-              reg = <0x00000000 0x08000000
+-                     0x88000000 0x08000000>;
++              reg = <0x00000000 0x08000000>,
++                    <0x88000000 0x08000000>;
+       };
+       spi {
+diff --git a/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts b/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
+index 0e349e39f608..8b1a05a0f1a1 100644
+--- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
++++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
+@@ -21,8 +21,8 @@
+       memory@0 {
+               device_type = "memory";
+-              reg = <0x00000000 0x08000000
+-                     0x88000000 0x08000000>;
++              reg = <0x00000000 0x08000000>,
++                    <0x88000000 0x08000000>;
+       };
+       spi {
+diff --git a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
+index 8f1e565c3db4..6c6bb7b17d27 100644
+--- a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
++++ b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
+@@ -21,8 +21,8 @@
+       memory {
+               device_type = "memory";
+-              reg = <0x00000000 0x08000000
+-                     0x88000000 0x08000000>;
++              reg = <0x00000000 0x08000000>,
++                    <0x88000000 0x08000000>;
+       };
+       leds {
+diff --git a/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
+index ce888b1835d1..d29e7f80ea6a 100644
+--- a/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
++++ b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
+@@ -21,8 +21,8 @@
+       memory {
+               device_type = "memory";
+-              reg = <0x00000000 0x08000000
+-                     0x88000000 0x18000000>;
++              reg = <0x00000000 0x08000000>,
++                    <0x88000000 0x18000000>;
+       };
+       leds {
+diff --git a/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts b/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts
+index ed8619b54d69..38fbefdf2e4e 100644
+--- a/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts
++++ b/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts
+@@ -18,8 +18,8 @@
+       memory {
+               device_type = "memory";
+-              reg = <0x00000000 0x08000000
+-                     0x88000000 0x08000000>;
++              reg = <0x00000000 0x08000000>,
++                    <0x88000000 0x08000000>;
+       };
+       gpio-keys {
+diff --git a/arch/arm/boot/dts/bcm4709-netgear-r7000.dts b/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
+index 1f87993eae1d..7989a53597d4 100644
+--- a/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
++++ b/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
+@@ -21,8 +21,8 @@
+       memory {
+               device_type = "memory";
+-              reg = <0x00000000 0x08000000
+-                     0x88000000 0x08000000>;
++              reg = <0x00000000 0x08000000>,
++                    <0x88000000 0x08000000>;
+       };
+       leds {
+diff --git a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
+index 6c6199a53d09..87b655be674c 100644
+--- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
++++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
+@@ -32,8 +32,8 @@
+       memory {
+               device_type = "memory";
+-              reg = <0x00000000 0x08000000
+-                     0x88000000 0x08000000>;
++              reg = <0x00000000 0x08000000>,
++                    <0x88000000 0x08000000>;
+       };
+       leds {
+diff --git a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
+index 911c65fbf251..e635a15041dd 100644
+--- a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
++++ b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
+@@ -21,8 +21,8 @@
+       memory@0 {
+               device_type = "memory";
+-              reg = <0x00000000 0x08000000
+-                     0x88000000 0x08000000>;
++              reg = <0x00000000 0x08000000>,
++                    <0x88000000 0x08000000>;
+       };
+       nand: nand@18028000 {
+diff --git a/arch/arm/boot/dts/bcm47094-linksys-panamera.dts b/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
+index 3725f2b0d60b..4b24b25389b5 100644
+--- a/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
++++ b/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
+@@ -18,8 +18,8 @@
+       memory@0 {
+               device_type = "memory";
+-              reg = <0x00000000 0x08000000
+-                     0x88000000 0x08000000>;
++              reg = <0x00000000 0x08000000>,
++                    <0x88000000 0x08000000>;
+       };
+       gpio-keys {
+diff --git a/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts b/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
+index 50f7cd08cfbb..a6dc99955e19 100644
+--- a/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
++++ b/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
+@@ -18,8 +18,8 @@
+       memory@0 {
+               device_type = "memory";
+-              reg = <0x00000000 0x08000000
+-                     0x88000000 0x18000000>;
++              reg = <0x00000000 0x08000000>,
++                    <0x88000000 0x18000000>;
+       };
+       leds {
+diff --git a/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts b/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
+index bcc420f85b56..ff98837bc0db 100644
+--- a/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
++++ b/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
+@@ -18,8 +18,8 @@
+       memory@0 {
+               device_type = "memory";
+-              reg = <0x00000000 0x08000000
+-                     0x88000000 0x18000000>;
++              reg = <0x00000000 0x08000000>,
++                    <0x88000000 0x18000000>;
+       };
+       leds {
+diff --git a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
+index 4f8d777ae18d..452b8d0ab180 100644
+--- a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
++++ b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
+@@ -18,8 +18,8 @@
+       memory {
+               device_type = "memory";
+-              reg = <0x00000000 0x08000000
+-                     0x88000000 0x18000000>;
++              reg = <0x00000000 0x08000000>,
++                    <0x88000000 0x18000000>;
+       };
+       leds {
+diff --git a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
+index e17e9a17fb00..b76bfe6efcd4 100644
+--- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
++++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
+@@ -18,8 +18,8 @@
+       memory@0 {
+               device_type = "memory";
+-              reg = <0x00000000 0x08000000
+-                     0x88000000 0x08000000>;
++              reg = <0x00000000 0x08000000>,
++                    <0x88000000 0x08000000>;
+       };
+       leds {
+diff --git a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
+index 60cc87ecc7ec..32d5a50578ec 100644
+--- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
++++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
+@@ -18,8 +18,8 @@
+       memory@0 {
+               device_type = "memory";
+-              reg = <0x00000000 0x08000000
+-                     0x88000000 0x18000000>;
++              reg = <0x00000000 0x08000000>,
++                    <0x88000000 0x18000000>;
+       };
+       leds {
+diff --git a/arch/arm/boot/dts/bcm47094-netgear-r8500.dts b/arch/arm/boot/dts/bcm47094-netgear-r8500.dts
+index f42a1703f4ab..42097a4c2659 100644
+--- a/arch/arm/boot/dts/bcm47094-netgear-r8500.dts
++++ b/arch/arm/boot/dts/bcm47094-netgear-r8500.dts
+@@ -18,8 +18,8 @@
+       memory@0 {
+               device_type = "memory";
+-              reg = <0x00000000 0x08000000
+-                     0x88000000 0x18000000>;
++              reg = <0x00000000 0x08000000>,
++                    <0x88000000 0x18000000>;
+       };
+       leds {
+diff --git a/arch/arm/boot/dts/bcm47094-phicomm-k3.dts b/arch/arm/boot/dts/bcm47094-phicomm-k3.dts
+index ac3a4483dcb3..a2566ad4619c 100644
+--- a/arch/arm/boot/dts/bcm47094-phicomm-k3.dts
++++ b/arch/arm/boot/dts/bcm47094-phicomm-k3.dts
+@@ -15,8 +15,8 @@
+       memory@0 {
+               device_type = "memory";
+-              reg = <0x00000000 0x08000000
+-                     0x88000000 0x18000000>;
++              reg = <0x00000000 0x08000000>,
++                    <0x88000000 0x18000000>;
+       };
+       gpio-keys {
+-- 
+2.30.2
+
diff --git a/queue-5.12/arm-dts-ux500-fix-up-tvk-r3-sensors.patch b/queue-5.12/arm-dts-ux500-fix-up-tvk-r3-sensors.patch
new file mode 100644 (file)
index 0000000..76bc244
--- /dev/null
@@ -0,0 +1,121 @@
+From 9489bb207b2b6ea10d01cf51e2a51c139ff1734e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 Mar 2021 10:19:11 +0100
+Subject: ARM: dts: ux500: Fix up TVK R3 sensors
+
+From: Linus Walleij <linus.walleij@linaro.org>
+
+[ Upstream commit aeceecd40d94ed3c00bfe1cfe59dd1bfac2fc6fe ]
+
+The TVK1281618 R3 sensors are different from the R2 board,
+some incorrectness is fixed and some new sensors added, we
+also rename the nodes appropriately with accelerometer@
+etc.
+
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/ste-href-tvk1281618-r3.dtsi | 73 +++++++++++++------
+ 1 file changed, 50 insertions(+), 23 deletions(-)
+
+diff --git a/arch/arm/boot/dts/ste-href-tvk1281618-r3.dtsi b/arch/arm/boot/dts/ste-href-tvk1281618-r3.dtsi
+index cb3677f0a1cb..b580397ede83 100644
+--- a/arch/arm/boot/dts/ste-href-tvk1281618-r3.dtsi
++++ b/arch/arm/boot/dts/ste-href-tvk1281618-r3.dtsi
+@@ -8,37 +8,43 @@
+ / {
+       soc {
+               i2c@80128000 {
+-                      /* Marked:
+-                       * 129
+-                       * M35
+-                       * L3GD20
+-                       */
+-                      l3gd20@6a {
+-                              /* Gyroscope */
+-                              compatible = "st,l3gd20";
+-                              status = "disabled";
++                      accelerometer@19 {
++                              compatible = "st,lsm303dlhc-accel";
+                               st,drdy-int-pin = <1>;
+-                              drive-open-drain;
+-                              reg = <0x6a>; // 0x6a or 0x6b
++                              reg = <0x19>;
+                               vdd-supply = <&ab8500_ldo_aux1_reg>;
+                               vddio-supply = <&db8500_vsmps2_reg>;
++                              interrupt-parent = <&gpio2>;
++                              interrupts = <18 IRQ_TYPE_EDGE_RISING>,
++                                           <19 IRQ_TYPE_EDGE_RISING>;
++                              pinctrl-names = "default";
++                              pinctrl-0 = <&accel_tvk_mode>;
+                       };
+-                      /*
+-                       * Marked:
+-                       * 2122
+-                       * C3H
+-                       * DQEEE
+-                       * LIS3DH?
+-                       */
+-                      lis3dh@18 {
+-                              /* Accelerometer */
+-                              compatible = "st,lis3dh-accel";
++                      magnetometer@1e {
++                              compatible = "st,lsm303dlm-magn";
+                               st,drdy-int-pin = <1>;
+-                              reg = <0x18>;
++                              reg = <0x1e>;
+                               vdd-supply = <&ab8500_ldo_aux1_reg>;
+                               vddio-supply = <&db8500_vsmps2_reg>;
++                              // This interrupt is not properly working with the driver
++                              // interrupt-parent = <&gpio1>;
++                              // interrupts = <0 IRQ_TYPE_EDGE_RISING>;
+                               pinctrl-names = "default";
+-                              pinctrl-0 = <&accel_tvk_mode>;
++                              pinctrl-0 = <&magn_tvk_mode>;
++                      };
++                      gyroscope@68 {
++                              /* Gyroscope */
++                              compatible = "st,l3g4200d-gyro";
++                              reg = <0x68>;
++                              vdd-supply = <&ab8500_ldo_aux1_reg>;
++                              vddio-supply = <&db8500_vsmps2_reg>;
++                      };
++                      pressure@5c {
++                              /* Barometer/pressure sensor */
++                              compatible = "st,lps001wp-press";
++                              reg = <0x5c>;
++                              vdd-supply = <&ab8500_ldo_aux1_reg>;
++                              vddio-supply = <&db8500_vsmps2_reg>;
+                       };
+               };
+@@ -54,5 +60,26 @@
+                               };
+                       };
+               };
++
++              pinctrl {
++                      accelerometer {
++                              accel_tvk_mode: accel_tvk {
++                                      /* Accelerometer interrupt lines 1 & 2 */
++                                      tvk_cfg {
++                                              pins = "GPIO82_C1", "GPIO83_D3";
++                                              ste,config = <&gpio_in_pd>;
++                                      };
++                              };
++                      };
++                      magnetometer {
++                              magn_tvk_mode: magn_tvk {
++                                      /* GPIO 32 used for DRDY, pull this down */
++                                      tvk_cfg {
++                                              pins = "GPIO32_V2";
++                                              ste,config = <&gpio_in_pd>;
++                                      };
++                              };
++                      };
++              };
+       };
+ };
+-- 
+2.30.2
+
diff --git a/queue-5.12/arm-tegra-acer-a500-rename-avdd-to-vdda-of-touchscre.patch b/queue-5.12/arm-tegra-acer-a500-rename-avdd-to-vdda-of-touchscre.patch
new file mode 100644 (file)
index 0000000..ed399b9
--- /dev/null
@@ -0,0 +1,35 @@
+From 804866a281609acd78f1ca190b4be9e343e9a0e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Mar 2021 15:09:58 +0300
+Subject: ARM: tegra: acer-a500: Rename avdd to vdda of touchscreen node
+
+From: Dmitry Osipenko <digetx@gmail.com>
+
+[ Upstream commit b27b9689e1f3278919c6183c565d837d0aef6fc1 ]
+
+Rename avdd supply to vdda of the touchscreen node. The old supply name
+was incorrect.
+
+Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/tegra20-acer-a500-picasso.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts b/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts
+index d3b99535d755..f9c0f6884cc1 100644
+--- a/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts
++++ b/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts
+@@ -448,7 +448,7 @@
+                       reset-gpios = <&gpio TEGRA_GPIO(Q, 7) GPIO_ACTIVE_LOW>;
+-                      avdd-supply = <&vdd_3v3_sys>;
++                      vdda-supply = <&vdd_3v3_sys>;
+                       vdd-supply  = <&vdd_3v3_sys>;
+               };
+-- 
+2.30.2
+
diff --git a/queue-5.12/arm64-dts-imx8mq-librem5-r3-mark-buck3-as-always-on.patch b/queue-5.12/arm64-dts-imx8mq-librem5-r3-mark-buck3-as-always-on.patch
new file mode 100644 (file)
index 0000000..b19f40b
--- /dev/null
@@ -0,0 +1,43 @@
+From 2de9e0251a11a9f067cefc02aaa9d697f7b6464d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Mar 2021 09:35:30 +0100
+Subject: arm64: dts: imx8mq-librem5-r3: Mark buck3 as always on
+
+From: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>
+
+[ Upstream commit a362b0cc94d476b097ba0ff466958c1d4e27e219 ]
+
+Commit 99e71c029213 ("arm64: dts: imx8mq-librem5: Don't mark buck3 as always on")
+removed always-on marking from GPU regulator, which is great for power
+saving - however it introduces additional i2c0 traffic which can be deadly
+for devices from the Dogwood batch.
+
+To workaround the i2c0 shutdown issue on Dogwood, this commit marks
+buck3 as always-on again - but only for Dogwood (r3).
+
+Signed-off-by: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>
+Signed-off-by: Martin Kepplinger <martin.kepplinger@puri.sm>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dts | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dts b/arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dts
+index 0d38327043f8..cd3c3edd48fa 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dts
++++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dts
+@@ -28,6 +28,10 @@
+       ti,termination-current = <144000>;  /* uA */
+ };
++&buck3_reg {
++      regulator-always-on;
++};
++
+ &proximity {
+       proximity-near-level = <25>;
+ };
+-- 
+2.30.2
+
diff --git a/queue-5.12/ata-ahci-disable-sxs-for-hisilicon-kunpeng920.patch b/queue-5.12/ata-ahci-disable-sxs-for-hisilicon-kunpeng920.patch
new file mode 100644 (file)
index 0000000..2205e74
--- /dev/null
@@ -0,0 +1,75 @@
+From 3530aae8b030d12d8a363281f2bebe1ada707fec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Mar 2021 18:24:36 +0800
+Subject: ata: ahci: Disable SXS for Hisilicon Kunpeng920
+
+From: Xingui Yang <yangxingui@huawei.com>
+
+[ Upstream commit 234e6d2c18f5b080cde874483c4c361f3ae7cffe ]
+
+On Hisilicon Kunpeng920, ESP is set to 1 by default for all ports of
+SATA controller. In some scenarios, some ports are not external SATA ports,
+and it cause disks connected to these ports to be identified as removable
+disks. So disable the SXS capability on the software side to prevent users
+from mistakenly considering non-removable disks as removable disks and
+performing related operations.
+
+Signed-off-by: Xingui Yang <yangxingui@huawei.com>
+Signed-off-by: Luo Jiaxing <luojiaxing@huawei.com>
+Reviewed-by: John Garry <john.garry@huawei.com>
+Link: https://lore.kernel.org/r/1615544676-61926-1-git-send-email-luojiaxing@huawei.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/ahci.c    | 5 +++++
+ drivers/ata/ahci.h    | 1 +
+ drivers/ata/libahci.c | 5 +++++
+ 3 files changed, 11 insertions(+)
+
+diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
+index 00ba8e5a1ccc..33192a8f687d 100644
+--- a/drivers/ata/ahci.c
++++ b/drivers/ata/ahci.c
+@@ -1772,6 +1772,11 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+               hpriv->flags |= AHCI_HFLAG_NO_DEVSLP;
+ #ifdef CONFIG_ARM64
++      if (pdev->vendor == PCI_VENDOR_ID_HUAWEI &&
++          pdev->device == 0xa235 &&
++          pdev->revision < 0x30)
++              hpriv->flags |= AHCI_HFLAG_NO_SXS;
++
+       if (pdev->vendor == 0x177d && pdev->device == 0xa01c)
+               hpriv->irq_handler = ahci_thunderx_irq_handler;
+ #endif
+diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
+index 98b8baa47dc5..d1f284f0c83d 100644
+--- a/drivers/ata/ahci.h
++++ b/drivers/ata/ahci.h
+@@ -242,6 +242,7 @@ enum {
+                                                       suspend/resume */
+       AHCI_HFLAG_IGN_NOTSUPP_POWER_ON = (1 << 27), /* ignore -EOPNOTSUPP
+                                                       from phy_power_on() */
++      AHCI_HFLAG_NO_SXS               = (1 << 28), /* SXS not supported */
+       /* ap->flags bits */
+diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
+index ea5bf5f4cbed..fec2e9754aed 100644
+--- a/drivers/ata/libahci.c
++++ b/drivers/ata/libahci.c
+@@ -493,6 +493,11 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv)
+               cap |= HOST_CAP_ALPM;
+       }
++      if ((cap & HOST_CAP_SXS) && (hpriv->flags & AHCI_HFLAG_NO_SXS)) {
++              dev_info(dev, "controller does not support SXS, disabling CAP_SXS\n");
++              cap &= ~HOST_CAP_SXS;
++      }
++
+       if (hpriv->force_port_map && port_map != hpriv->force_port_map) {
+               dev_info(dev, "forcing port_map 0x%x -> 0x%x\n",
+                        port_map, hpriv->force_port_map);
+-- 
+2.30.2
+
diff --git a/queue-5.12/atomisp-don-t-let-it-go-past-pipes-array.patch b/queue-5.12/atomisp-don-t-let-it-go-past-pipes-array.patch
new file mode 100644 (file)
index 0000000..0eafa78
--- /dev/null
@@ -0,0 +1,42 @@
+From 489373d5425d45419dcdb9f011a670b3b1521711 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Mar 2021 08:16:03 +0100
+Subject: atomisp: don't let it go past pipes array
+
+From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+[ Upstream commit 1f6c45ac5fd70ab59136ab5babc7def269f3f509 ]
+
+In practice, IA_CSS_PIPE_ID_NUM should never be used when
+calling atomisp_q_video_buffers_to_css(), as the driver should
+discover the right pipe before calling it.
+
+Yet, if some pipe parsing issue happens, it could end using
+it.
+
+So, add a WARN_ON() to prevent such case.
+
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/media/atomisp/pci/atomisp_fops.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp_fops.c
+index 453bb6913550..f1e6b2597853 100644
+--- a/drivers/staging/media/atomisp/pci/atomisp_fops.c
++++ b/drivers/staging/media/atomisp/pci/atomisp_fops.c
+@@ -221,6 +221,9 @@ int atomisp_q_video_buffers_to_css(struct atomisp_sub_device *asd,
+       unsigned long irqflags;
+       int err = 0;
++      if (WARN_ON(css_pipe_id >= IA_CSS_PIPE_ID_NUM))
++              return -EINVAL;
++
+       while (pipe->buffers_in_css < ATOMISP_CSS_Q_DEPTH) {
+               struct videobuf_buffer *vb;
+-- 
+2.30.2
+
diff --git a/queue-5.12/backlight-qcom-wled-fix-fsc-update-issue-for-wled5.patch b/queue-5.12/backlight-qcom-wled-fix-fsc-update-issue-for-wled5.patch
new file mode 100644 (file)
index 0000000..a2a76eb
--- /dev/null
@@ -0,0 +1,80 @@
+From 44d7bb042b41422052b27d3f282bbfdd56bd4841 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Mar 2021 18:09:39 +0530
+Subject: backlight: qcom-wled: Fix FSC update issue for WLED5
+
+From: Kiran Gunda <kgunda@codeaurora.org>
+
+[ Upstream commit 4d6e9cdff7fbb6bef3e5559596fab3eeffaf95ca ]
+
+Currently, for WLED5, the FSC (Full scale current) setting is not
+updated properly due to driver toggling the wrong register after
+an FSC update.
+
+On WLED5 we should only toggle the MOD_SYNC bit after a brightness
+update. For an FSC update we need to toggle the SYNC bits instead.
+
+Fix it by adopting the common wled3_sync_toggle() for WLED5 and
+introducing new code to the brightness update path to compensate.
+
+Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
+Reviewed-by: Daniel Thompson <daniel.thompson@linaro.org>
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/backlight/qcom-wled.c | 25 +++++++++++++++++++------
+ 1 file changed, 19 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/video/backlight/qcom-wled.c b/drivers/video/backlight/qcom-wled.c
+index fc8b443d10fd..e9fbe2483844 100644
+--- a/drivers/video/backlight/qcom-wled.c
++++ b/drivers/video/backlight/qcom-wled.c
+@@ -348,7 +348,7 @@ static int wled3_sync_toggle(struct wled *wled)
+       return rc;
+ }
+-static int wled5_sync_toggle(struct wled *wled)
++static int wled5_mod_sync_toggle(struct wled *wled)
+ {
+       int rc;
+       u8 val;
+@@ -445,10 +445,23 @@ static int wled_update_status(struct backlight_device *bl)
+                       goto unlock_mutex;
+               }
+-              rc = wled->wled_sync_toggle(wled);
+-              if (rc < 0) {
+-                      dev_err(wled->dev, "wled sync failed rc:%d\n", rc);
+-                      goto unlock_mutex;
++              if (wled->version < 5) {
++                      rc = wled->wled_sync_toggle(wled);
++                      if (rc < 0) {
++                              dev_err(wled->dev, "wled sync failed rc:%d\n", rc);
++                              goto unlock_mutex;
++                      }
++              } else {
++                      /*
++                       * For WLED5 toggling the MOD_SYNC_BIT updates the
++                       * brightness
++                       */
++                      rc = wled5_mod_sync_toggle(wled);
++                      if (rc < 0) {
++                              dev_err(wled->dev, "wled mod sync failed rc:%d\n",
++                                      rc);
++                              goto unlock_mutex;
++                      }
+               }
+       }
+@@ -1459,7 +1472,7 @@ static int wled_configure(struct wled *wled)
+               size = ARRAY_SIZE(wled5_opts);
+               *cfg = wled5_config_defaults;
+               wled->wled_set_brightness = wled5_set_brightness;
+-              wled->wled_sync_toggle = wled5_sync_toggle;
++              wled->wled_sync_toggle = wled3_sync_toggle;
+               wled->wled_cabc_config = wled5_cabc_config;
+               wled->wled_ovp_delay = wled5_ovp_delay;
+               wled->wled_auto_detection_required =
+-- 
+2.30.2
+
diff --git a/queue-5.12/backlight-qcom-wled-use-sink_addr-for-sync-toggle.patch b/queue-5.12/backlight-qcom-wled-use-sink_addr-for-sync-toggle.patch
new file mode 100644 (file)
index 0000000..ff79ed8
--- /dev/null
@@ -0,0 +1,53 @@
+From 1ea398b345a18a373d387e557e78b692f25defc4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 14 Mar 2021 11:11:10 +0100
+Subject: backlight: qcom-wled: Use sink_addr for sync toggle
+
+From: Obeida Shamoun <oshmoun100@googlemail.com>
+
+[ Upstream commit cdfd4c689e2a52c313b35ddfc1852ff274f91acb ]
+
+WLED3_SINK_REG_SYNC is, as the name implies, a sink register offset.
+Therefore, use the sink address as base instead of the ctrl address.
+
+This fixes the sync toggle on wled4, which can be observed by the fact
+that adjusting brightness now works.
+
+It has no effect on wled3 because sink and ctrl base addresses are the
+same.  This allows adjusting the brightness without having to disable
+then reenable the module.
+
+Signed-off-by: Obeida Shamoun <oshmoun100@googlemail.com>
+Signed-off-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
+Reviewed-by: Daniel Thompson <daniel.thompson@linaro.org>
+Acked-by: Kiran Gunda <kgunda@codeaurora.org>
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/backlight/qcom-wled.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/video/backlight/qcom-wled.c b/drivers/video/backlight/qcom-wled.c
+index 091f07e7c145..fc8b443d10fd 100644
+--- a/drivers/video/backlight/qcom-wled.c
++++ b/drivers/video/backlight/qcom-wled.c
+@@ -336,13 +336,13 @@ static int wled3_sync_toggle(struct wled *wled)
+       unsigned int mask = GENMASK(wled->max_string_count - 1, 0);
+       rc = regmap_update_bits(wled->regmap,
+-                              wled->ctrl_addr + WLED3_SINK_REG_SYNC,
++                              wled->sink_addr + WLED3_SINK_REG_SYNC,
+                               mask, mask);
+       if (rc < 0)
+               return rc;
+       rc = regmap_update_bits(wled->regmap,
+-                              wled->ctrl_addr + WLED3_SINK_REG_SYNC,
++                              wled->sink_addr + WLED3_SINK_REG_SYNC,
+                               mask, WLED3_SINK_REG_SYNC_CLEAR);
+       return rc;
+-- 
+2.30.2
+
diff --git a/queue-5.12/block-bfq-fix-weight-raising-resume-with-low_latency.patch b/queue-5.12/block-bfq-fix-weight-raising-resume-with-low_latency.patch
new file mode 100644 (file)
index 0000000..a9528e3
--- /dev/null
@@ -0,0 +1,55 @@
+From 8988485a9e1000a8dd7c53f06a58fd0a85754805 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Mar 2021 18:46:25 +0100
+Subject: block, bfq: fix weight-raising resume with !low_latency
+
+From: Paolo Valente <paolo.valente@linaro.org>
+
+[ Upstream commit 8c544770092a3d7532d01903b75721e537d87001 ]
+
+When the io_latency heuristic is off, bfq_queues must not start to be
+weight-raised. Unfortunately, by mistake, this may happen when the
+state of a previously weight-raised bfq_queue is resumed after a queue
+split. This commit fixes this error.
+
+Tested-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
+Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
+Link: https://lore.kernel.org/r/20210304174627.161-5-paolo.valente@linaro.org
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/bfq-iosched.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
+index 95586137194e..20ba5db0f61c 100644
+--- a/block/bfq-iosched.c
++++ b/block/bfq-iosched.c
+@@ -1012,7 +1012,7 @@ static void
+ bfq_bfqq_resume_state(struct bfq_queue *bfqq, struct bfq_data *bfqd,
+                     struct bfq_io_cq *bic, bool bfq_already_existing)
+ {
+-      unsigned int old_wr_coeff = bfqq->wr_coeff;
++      unsigned int old_wr_coeff = 1;
+       bool busy = bfq_already_existing && bfq_bfqq_busy(bfqq);
+       if (bic->saved_has_short_ttime)
+@@ -1033,7 +1033,13 @@ bfq_bfqq_resume_state(struct bfq_queue *bfqq, struct bfq_data *bfqd,
+       bfqq->ttime = bic->saved_ttime;
+       bfqq->io_start_time = bic->saved_io_start_time;
+       bfqq->tot_idle_time = bic->saved_tot_idle_time;
+-      bfqq->wr_coeff = bic->saved_wr_coeff;
++      /*
++       * Restore weight coefficient only if low_latency is on
++       */
++      if (bfqd->low_latency) {
++              old_wr_coeff = bfqq->wr_coeff;
++              bfqq->wr_coeff = bic->saved_wr_coeff;
++      }
+       bfqq->service_from_wr = bic->saved_service_from_wr;
+       bfqq->wr_start_at_switch_to_srt = bic->saved_wr_start_at_switch_to_srt;
+       bfqq->last_wr_start_finish = bic->saved_last_wr_start_finish;
+-- 
+2.30.2
+
diff --git a/queue-5.12/block-rnbd-clt-fix-missing-a-memory-free-when-unload.patch b/queue-5.12/block-rnbd-clt-fix-missing-a-memory-free-when-unload.patch
new file mode 100644 (file)
index 0000000..207f0a2
--- /dev/null
@@ -0,0 +1,60 @@
+From baf14c83990a6e72da1e41dd7fbedadf20bdbcbf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Apr 2021 09:37:15 +0200
+Subject: block/rnbd-clt: Fix missing a memory free when unloading the module
+
+From: Gioh Kim <gi-oh.kim@cloud.ionos.com>
+
+[ Upstream commit 12b06533104e802df73c1fbe159437c19933d6c0 ]
+
+When unloading the rnbd-clt module, it does not free a memory
+including the filename of the symbolic link to /sys/block/rnbdX.
+
+It is found by kmemleak as below.
+
+unreferenced object 0xffff9f1a83d3c740 (size 16):
+  comm "bash", pid 736, jiffies 4295179665 (age 9841.310s)
+  hex dump (first 16 bytes):
+    21 64 65 76 21 6e 75 6c 6c 62 30 40 62 6c 61 00  !dev!nullb0@bla.
+  backtrace:
+    [<0000000039f0c55e>] 0xffffffffc0456c24
+    [<000000001aab9513>] kernfs_fop_write+0xcf/0x1c0
+    [<00000000db5aa4b3>] vfs_write+0xdb/0x1d0
+    [<000000007a2e2207>] ksys_write+0x65/0xe0
+    [<00000000055e280a>] do_syscall_64+0x50/0x1b0
+    [<00000000c2b51831>] entry_SYSCALL_64_after_hwframe+0x49/0xbe
+
+Signed-off-by: Gioh Kim <gi-oh.kim@ionos.com>
+Signed-off-by: Jack Wang <jinpu.wang@ionos.com>
+Link: https://lore.kernel.org/r/20210419073722.15351-13-gi-oh.kim@ionos.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/rnbd/rnbd-clt-sysfs.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/block/rnbd/rnbd-clt-sysfs.c b/drivers/block/rnbd/rnbd-clt-sysfs.c
+index d4aa6bfc9555..526c77cd7a50 100644
+--- a/drivers/block/rnbd/rnbd-clt-sysfs.c
++++ b/drivers/block/rnbd/rnbd-clt-sysfs.c
+@@ -432,10 +432,14 @@ void rnbd_clt_remove_dev_symlink(struct rnbd_clt_dev *dev)
+        * i.e. rnbd_clt_unmap_dev_store() leading to a sysfs warning because
+        * of sysfs link already was removed already.
+        */
+-      if (dev->blk_symlink_name && try_module_get(THIS_MODULE)) {
+-              sysfs_remove_link(rnbd_devs_kobj, dev->blk_symlink_name);
++      if (dev->blk_symlink_name) {
++              if (try_module_get(THIS_MODULE)) {
++                      sysfs_remove_link(rnbd_devs_kobj, dev->blk_symlink_name);
++                      module_put(THIS_MODULE);
++              }
++              /* It should be freed always. */
+               kfree(dev->blk_symlink_name);
+-              module_put(THIS_MODULE);
++              dev->blk_symlink_name = NULL;
+       }
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.12/block-rnbd-srv-prevent-a-deadlock-generated-by-acces.patch b/queue-5.12/block-rnbd-srv-prevent-a-deadlock-generated-by-acces.patch
new file mode 100644 (file)
index 0000000..1576a52
--- /dev/null
@@ -0,0 +1,152 @@
+From 2b77a13acb5d33877a002e6ce4ab93cde1ae7605 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Apr 2021 09:37:12 +0200
+Subject: block/rnbd-srv: Prevent a deadlock generated by accessing sysfs in
+ parallel
+
+From: Gioh Kim <gi-oh.kim@cloud.ionos.com>
+
+[ Upstream commit b168e1d85cf3201663698dd9dcb3d46c7e67f621 ]
+
+We got a warning message below.
+When server tries to close one session by force, it locks the sysfs
+interface and locks the srv_sess lock.
+The problem is that client can send a request to close at the same time.
+By close request, server locks the srv_sess lock and locks the sysfs
+to remove the sysfs interfaces.
+
+The simplest way to prevent that situation could be just use
+mutex_trylock.
+
+[  234.153965] ======================================================
+[  234.154093] WARNING: possible circular locking dependency detected
+[  234.154219] 5.4.84-storage #5.4.84-1+feature+linux+5.4.y+dbg+20201216.1319+b6b887b~deb10 Tainted: G           O
+[  234.154381] ------------------------------------------------------
+[  234.154531] kworker/1:1H/618 is trying to acquire lock:
+[  234.154651] ffff8887a09db0a8 (kn->count#132){++++}, at: kernfs_remove_by_name_ns+0x40/0x80
+[  234.154819]
+               but task is already holding lock:
+[  234.154965] ffff8887ae5f6518 (&srv_sess->lock){+.+.}, at: rnbd_srv_rdma_ev+0x144/0x1590 [rnbd_server]
+[  234.155132]
+               which lock already depends on the new lock.
+
+[  234.155311]
+               the existing dependency chain (in reverse order) is:
+[  234.155462]
+               -> #1 (&srv_sess->lock){+.+.}:
+[  234.155614]        __mutex_lock+0x134/0xcb0
+[  234.155761]        rnbd_srv_sess_dev_force_close+0x36/0x50 [rnbd_server]
+[  234.155889]        rnbd_srv_dev_session_force_close_store+0x69/0xc0 [rnbd_server]
+[  234.156042]        kernfs_fop_write+0x13f/0x240
+[  234.156162]        vfs_write+0xf3/0x280
+[  234.156278]        ksys_write+0xba/0x150
+[  234.156395]        do_syscall_64+0x62/0x270
+[  234.156513]        entry_SYSCALL_64_after_hwframe+0x49/0xbe
+[  234.156632]
+               -> #0 (kn->count#132){++++}:
+[  234.156782]        __lock_acquire+0x129e/0x23a0
+[  234.156900]        lock_acquire+0xf3/0x210
+[  234.157043]        __kernfs_remove+0x42b/0x4c0
+[  234.157161]        kernfs_remove_by_name_ns+0x40/0x80
+[  234.157282]        remove_files+0x3f/0xa0
+[  234.157399]        sysfs_remove_group+0x4a/0xb0
+[  234.157519]        rnbd_srv_destroy_dev_session_sysfs+0x19/0x30 [rnbd_server]
+[  234.157648]        rnbd_srv_rdma_ev+0x14c/0x1590 [rnbd_server]
+[  234.157775]        process_io_req+0x29a/0x6a0 [rtrs_server]
+[  234.157924]        __ib_process_cq+0x8c/0x100 [ib_core]
+[  234.158709]        ib_cq_poll_work+0x31/0xb0 [ib_core]
+[  234.158834]        process_one_work+0x4e5/0xaa0
+[  234.158958]        worker_thread+0x65/0x5c0
+[  234.159078]        kthread+0x1e0/0x200
+[  234.159194]        ret_from_fork+0x24/0x30
+[  234.159309]
+               other info that might help us debug this:
+
+[  234.159513]  Possible unsafe locking scenario:
+
+[  234.159658]        CPU0                    CPU1
+[  234.159775]        ----                    ----
+[  234.159891]   lock(&srv_sess->lock);
+[  234.160005]                                lock(kn->count#132);
+[  234.160128]                                lock(&srv_sess->lock);
+[  234.160250]   lock(kn->count#132);
+[  234.160364]
+                *** DEADLOCK ***
+
+[  234.160536] 3 locks held by kworker/1:1H/618:
+[  234.160677]  #0: ffff8883ca1ed528 ((wq_completion)ib-comp-wq){+.+.}, at: process_one_work+0x40a/0xaa0
+[  234.160840]  #1: ffff8883d2d5fe10 ((work_completion)(&cq->work)){+.+.}, at: process_one_work+0x40a/0xaa0
+[  234.161003]  #2: ffff8887ae5f6518 (&srv_sess->lock){+.+.}, at: rnbd_srv_rdma_ev+0x144/0x1590 [rnbd_server]
+[  234.161168]
+               stack backtrace:
+[  234.161312] CPU: 1 PID: 618 Comm: kworker/1:1H Tainted: G           O      5.4.84-storage #5.4.84-1+feature+linux+5.4.y+dbg+20201216.1319+b6b887b~deb10
+[  234.161490] Hardware name: Supermicro H8QG6/H8QG6, BIOS 3.00       09/04/2012
+[  234.161643] Workqueue: ib-comp-wq ib_cq_poll_work [ib_core]
+[  234.161765] Call Trace:
+[  234.161910]  dump_stack+0x96/0xe0
+[  234.162028]  check_noncircular+0x29e/0x2e0
+[  234.162148]  ? print_circular_bug+0x100/0x100
+[  234.162267]  ? register_lock_class+0x1ad/0x8a0
+[  234.162385]  ? __lock_acquire+0x68e/0x23a0
+[  234.162505]  ? trace_event_raw_event_lock+0x190/0x190
+[  234.162626]  __lock_acquire+0x129e/0x23a0
+[  234.162746]  ? register_lock_class+0x8a0/0x8a0
+[  234.162866]  lock_acquire+0xf3/0x210
+[  234.162982]  ? kernfs_remove_by_name_ns+0x40/0x80
+[  234.163127]  __kernfs_remove+0x42b/0x4c0
+[  234.163243]  ? kernfs_remove_by_name_ns+0x40/0x80
+[  234.163363]  ? kernfs_fop_readdir+0x3b0/0x3b0
+[  234.163482]  ? strlen+0x1f/0x40
+[  234.163596]  ? strcmp+0x30/0x50
+[  234.163712]  kernfs_remove_by_name_ns+0x40/0x80
+[  234.163832]  remove_files+0x3f/0xa0
+[  234.163948]  sysfs_remove_group+0x4a/0xb0
+[  234.164068]  rnbd_srv_destroy_dev_session_sysfs+0x19/0x30 [rnbd_server]
+[  234.164196]  rnbd_srv_rdma_ev+0x14c/0x1590 [rnbd_server]
+[  234.164345]  ? _raw_spin_unlock_irqrestore+0x43/0x50
+[  234.164466]  ? lockdep_hardirqs_on+0x1a8/0x290
+[  234.164597]  ? mlx4_ib_poll_cq+0x927/0x1280 [mlx4_ib]
+[  234.164732]  ? rnbd_get_sess_dev+0x270/0x270 [rnbd_server]
+[  234.164859]  process_io_req+0x29a/0x6a0 [rtrs_server]
+[  234.164982]  ? rnbd_get_sess_dev+0x270/0x270 [rnbd_server]
+[  234.165130]  __ib_process_cq+0x8c/0x100 [ib_core]
+[  234.165279]  ib_cq_poll_work+0x31/0xb0 [ib_core]
+[  234.165404]  process_one_work+0x4e5/0xaa0
+[  234.165550]  ? pwq_dec_nr_in_flight+0x160/0x160
+[  234.165675]  ? do_raw_spin_lock+0x119/0x1d0
+[  234.165796]  worker_thread+0x65/0x5c0
+[  234.165914]  ? process_one_work+0xaa0/0xaa0
+[  234.166031]  kthread+0x1e0/0x200
+[  234.166147]  ? kthread_create_worker_on_cpu+0xc0/0xc0
+[  234.166268]  ret_from_fork+0x24/0x30
+[  234.251591] rnbd_server L243: </dev/loop1@close_device_session>: Device closed
+[  234.604221] rnbd_server L264: RTRS Session close_device_session disconnected
+
+Signed-off-by: Gioh Kim <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/20210419073722.15351-10-gi-oh.kim@ionos.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/rnbd/rnbd-srv.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/block/rnbd/rnbd-srv.c b/drivers/block/rnbd/rnbd-srv.c
+index a6a68d44f517..677770f32843 100644
+--- a/drivers/block/rnbd/rnbd-srv.c
++++ b/drivers/block/rnbd/rnbd-srv.c
+@@ -341,7 +341,9 @@ 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;
+-      mutex_lock(&sess->lock);
++      /* It is already started to close by client's close message. */
++      if (!mutex_trylock(&sess->lock))
++              return;
+       rnbd_srv_destroy_dev_session_sysfs(sess_dev);
+       mutex_unlock(&sess->lock);
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.12/btrfs-convert-logic-bug_on-s-in-replace_path-to-asse.patch b/queue-5.12/btrfs-convert-logic-bug_on-s-in-replace_path-to-asse.patch
new file mode 100644 (file)
index 0000000..13202b4
--- /dev/null
@@ -0,0 +1,48 @@
+From 3d0efef4bc4fdeff2d90de926a228d58a44a354b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Mar 2021 15:25:21 -0500
+Subject: btrfs: convert logic BUG_ON()'s in replace_path to ASSERT()'s
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+[ Upstream commit 7a9213a93546e7eaef90e6e153af6b8fc7553f10 ]
+
+A few BUG_ON()'s in replace_path are purely to keep us from making
+logical mistakes, so replace them with ASSERT()'s.
+
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/relocation.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
+index e76097fb342c..829dc8dcc151 100644
+--- a/fs/btrfs/relocation.c
++++ b/fs/btrfs/relocation.c
+@@ -1205,8 +1205,8 @@ int replace_path(struct btrfs_trans_handle *trans, struct reloc_control *rc,
+       int ret;
+       int slot;
+-      BUG_ON(src->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID);
+-      BUG_ON(dest->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID);
++      ASSERT(src->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID);
++      ASSERT(dest->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID);
+       last_snapshot = btrfs_root_last_snapshot(&src->root_item);
+ again:
+@@ -1237,7 +1237,7 @@ again:
+       parent = eb;
+       while (1) {
+               level = btrfs_header_level(parent);
+-              BUG_ON(level < lowest_level);
++              ASSERT(level >= lowest_level);
+               ret = btrfs_bin_search(parent, &key, &slot);
+               if (ret < 0)
+-- 
+2.30.2
+
diff --git a/queue-5.12/btrfs-do-proper-error-handling-in-btrfs_update_reloc.patch b/queue-5.12/btrfs-do-proper-error-handling-in-btrfs_update_reloc.patch
new file mode 100644 (file)
index 0000000..16f1882
--- /dev/null
@@ -0,0 +1,51 @@
+From f998dc356e18b1e7f492a310363b32086378c625 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Mar 2021 15:25:20 -0500
+Subject: btrfs: do proper error handling in btrfs_update_reloc_root
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+[ Upstream commit 592fbcd50c99b8adf999a2a54f9245caff333139 ]
+
+We call btrfs_update_root in btrfs_update_reloc_root, which can fail for
+all sorts of reasons, including IO errors.  Instead of panicing the box
+lets return the error, now that all callers properly handle those
+errors.
+
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/relocation.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
+index b445b3073dea..e76097fb342c 100644
+--- a/fs/btrfs/relocation.c
++++ b/fs/btrfs/relocation.c
+@@ -897,7 +897,7 @@ int btrfs_update_reloc_root(struct btrfs_trans_handle *trans,
+       int ret;
+       if (!have_reloc_root(root))
+-              goto out;
++              return 0;
+       reloc_root = root->reloc_root;
+       root_item = &reloc_root->root_item;
+@@ -930,10 +930,8 @@ int btrfs_update_reloc_root(struct btrfs_trans_handle *trans,
+       ret = btrfs_update_root(trans, fs_info->tree_root,
+                               &reloc_root->root_key, root_item);
+-      BUG_ON(ret);
+       btrfs_put_root(reloc_root);
+-out:
+-      return 0;
++      return ret;
+ }
+ /*
+-- 
+2.30.2
+
diff --git a/queue-5.12/btrfs-do-proper-error-handling-in-create_reloc_root.patch b/queue-5.12/btrfs-do-proper-error-handling-in-create_reloc_root.patch
new file mode 100644 (file)
index 0000000..2f0b0ad
--- /dev/null
@@ -0,0 +1,101 @@
+From c63f8e0345c6de68b4bec09459c786a2829a81d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Mar 2021 15:25:14 -0500
+Subject: btrfs: do proper error handling in create_reloc_root
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+[ Upstream commit 84c50ba5214c2f3c1be4a931d521ec19f55dfdc8 ]
+
+We do memory allocations here, read blocks from disk, all sorts of
+operations that could easily fail at any given point.  Instead of
+panicing the box, simply return the error back up the chain, all callers
+at this point have proper error handling.
+
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/relocation.c | 34 ++++++++++++++++++++++++++++------
+ 1 file changed, 28 insertions(+), 6 deletions(-)
+
+diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
+index bf269ee17e68..b445b3073dea 100644
+--- a/fs/btrfs/relocation.c
++++ b/fs/btrfs/relocation.c
+@@ -733,10 +733,12 @@ static struct btrfs_root *create_reloc_root(struct btrfs_trans_handle *trans,
+       struct extent_buffer *eb;
+       struct btrfs_root_item *root_item;
+       struct btrfs_key root_key;
+-      int ret;
++      int ret = 0;
++      bool must_abort = false;
+       root_item = kmalloc(sizeof(*root_item), GFP_NOFS);
+-      BUG_ON(!root_item);
++      if (!root_item)
++              return ERR_PTR(-ENOMEM);
+       root_key.objectid = BTRFS_TREE_RELOC_OBJECTID;
+       root_key.type = BTRFS_ROOT_ITEM_KEY;
+@@ -748,7 +750,9 @@ static struct btrfs_root *create_reloc_root(struct btrfs_trans_handle *trans,
+               /* called by btrfs_init_reloc_root */
+               ret = btrfs_copy_root(trans, root, root->commit_root, &eb,
+                                     BTRFS_TREE_RELOC_OBJECTID);
+-              BUG_ON(ret);
++              if (ret)
++                      goto fail;
++
+               /*
+                * Set the last_snapshot field to the generation of the commit
+                * root - like this ctree.c:btrfs_block_can_be_shared() behaves
+@@ -769,9 +773,16 @@ static struct btrfs_root *create_reloc_root(struct btrfs_trans_handle *trans,
+                */
+               ret = btrfs_copy_root(trans, root, root->node, &eb,
+                                     BTRFS_TREE_RELOC_OBJECTID);
+-              BUG_ON(ret);
++              if (ret)
++                      goto fail;
+       }
++      /*
++       * We have changed references at this point, we must abort the
++       * transaction if anything fails.
++       */
++      must_abort = true;
++
+       memcpy(root_item, &root->root_item, sizeof(*root_item));
+       btrfs_set_root_bytenr(root_item, eb->start);
+       btrfs_set_root_level(root_item, btrfs_header_level(eb));
+@@ -789,14 +800,25 @@ static struct btrfs_root *create_reloc_root(struct btrfs_trans_handle *trans,
+       ret = btrfs_insert_root(trans, fs_info->tree_root,
+                               &root_key, root_item);
+-      BUG_ON(ret);
++      if (ret)
++              goto fail;
++
+       kfree(root_item);
+       reloc_root = btrfs_read_tree_root(fs_info->tree_root, &root_key);
+-      BUG_ON(IS_ERR(reloc_root));
++      if (IS_ERR(reloc_root)) {
++              ret = PTR_ERR(reloc_root);
++              goto abort;
++      }
+       set_bit(BTRFS_ROOT_SHAREABLE, &reloc_root->state);
+       reloc_root->last_trans = trans->transid;
+       return reloc_root;
++fail:
++      kfree(root_item);
++abort:
++      if (must_abort)
++              btrfs_abort_transaction(trans, ret);
++      return ERR_PTR(ret);
+ }
+ /*
+-- 
+2.30.2
+
diff --git a/queue-5.12/btrfs-fix-exhaustion-of-the-system-chunk-array-due-t.patch b/queue-5.12/btrfs-fix-exhaustion-of-the-system-chunk-array-due-t.patch
new file mode 100644 (file)
index 0000000..226402a
--- /dev/null
@@ -0,0 +1,322 @@
+From 9b63baa6ff5da75e05940f9f06eb5fdd1f53e8f0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Mar 2021 11:55:50 +0100
+Subject: btrfs: fix exhaustion of the system chunk array due to concurrent
+ allocations
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit eafa4fd0ad06074da8be4e28ff93b4dca9ffa407 ]
+
+When we are running out of space for updating the chunk tree, that is,
+when we are low on available space in the system space info, if we have
+many task concurrently allocating block groups, via fallocate for example,
+many of them can end up all allocating new system chunks when only one is
+needed. In extreme cases this can lead to exhaustion of the system chunk
+array, which has a size limit of 2048 bytes, and results in a transaction
+abort with errno EFBIG, producing a trace in dmesg like the following,
+which was triggered on a PowerPC machine with a node/leaf size of 64K:
+
+  [1359.518899] ------------[ cut here ]------------
+  [1359.518980] BTRFS: Transaction aborted (error -27)
+  [1359.519135] WARNING: CPU: 3 PID: 16463 at ../fs/btrfs/block-group.c:1968 btrfs_create_pending_block_groups+0x340/0x3c0 [btrfs]
+  [1359.519152] Modules linked in: (...)
+  [1359.519239] Supported: Yes, External
+  [1359.519252] CPU: 3 PID: 16463 Comm: stress-ng Tainted: G               X    5.3.18-47-default #1 SLE15-SP3
+  [1359.519274] NIP:  c008000000e36fe8 LR: c008000000e36fe4 CTR: 00000000006de8e8
+  [1359.519293] REGS: c00000056890b700 TRAP: 0700   Tainted: G               X     (5.3.18-47-default)
+  [1359.519317] MSR:  800000000282b033 <SF,VEC,VSX,EE,FP,ME,IR,DR,RI,LE>  CR: 48008222  XER: 00000007
+  [1359.519356] CFAR: c00000000013e170 IRQMASK: 0
+  [1359.519356] GPR00: c008000000e36fe4 c00000056890b990 c008000000e83200 0000000000000026
+  [1359.519356] GPR04: 0000000000000000 0000000000000000 0000d52a3b027651 0000000000000007
+  [1359.519356] GPR08: 0000000000000003 0000000000000001 0000000000000007 0000000000000000
+  [1359.519356] GPR12: 0000000000008000 c00000063fe44600 000000001015e028 000000001015dfd0
+  [1359.519356] GPR16: 000000000000404f 0000000000000001 0000000000010000 0000dd1e287affff
+  [1359.519356] GPR20: 0000000000000001 c000000637c9a000 ffffffffffffffe5 0000000000000000
+  [1359.519356] GPR24: 0000000000000004 0000000000000000 0000000000000100 ffffffffffffffc0
+  [1359.519356] GPR28: c000000637c9a000 c000000630e09230 c000000630e091d8 c000000562188b08
+  [1359.519561] NIP [c008000000e36fe8] btrfs_create_pending_block_groups+0x340/0x3c0 [btrfs]
+  [1359.519613] LR [c008000000e36fe4] btrfs_create_pending_block_groups+0x33c/0x3c0 [btrfs]
+  [1359.519626] Call Trace:
+  [1359.519671] [c00000056890b990] [c008000000e36fe4] btrfs_create_pending_block_groups+0x33c/0x3c0 [btrfs] (unreliable)
+  [1359.519729] [c00000056890ba90] [c008000000d68d44] __btrfs_end_transaction+0xbc/0x2f0 [btrfs]
+  [1359.519782] [c00000056890bae0] [c008000000e309ac] btrfs_alloc_data_chunk_ondemand+0x154/0x610 [btrfs]
+  [1359.519844] [c00000056890bba0] [c008000000d8a0fc] btrfs_fallocate+0xe4/0x10e0 [btrfs]
+  [1359.519891] [c00000056890bd00] [c0000000004a23b4] vfs_fallocate+0x174/0x350
+  [1359.519929] [c00000056890bd50] [c0000000004a3cf8] ksys_fallocate+0x68/0xf0
+  [1359.519957] [c00000056890bda0] [c0000000004a3da8] sys_fallocate+0x28/0x40
+  [1359.519988] [c00000056890bdc0] [c000000000038968] system_call_exception+0xe8/0x170
+  [1359.520021] [c00000056890be20] [c00000000000cb70] system_call_common+0xf0/0x278
+  [1359.520037] Instruction dump:
+  [1359.520049] 7d0049ad 40c2fff4 7c0004ac 71490004 40820024 2f83fffb 419e0048 3c620000
+  [1359.520082] e863bcb8 7ec4b378 48010d91 e8410018 <0fe00000> 3c820000 e884bcc8 7ec6b378
+  [1359.520122] ---[ end trace d6c186e151022e20 ]---
+
+The following steps explain how we can end up in this situation:
+
+1) Task A is at check_system_chunk(), either because it is allocating a
+   new data or metadata block group, at btrfs_chunk_alloc(), or because
+   it is removing a block group or turning a block group RO. It does not
+   matter why;
+
+2) Task A sees that there is not enough free space in the system
+   space_info object, that is 'left' is < 'thresh'. And at this point
+   the system space_info has a value of 0 for its 'bytes_may_use'
+   counter;
+
+3) As a consequence task A calls btrfs_alloc_chunk() in order to allocate
+   a new system block group (chunk) and then reserves 'thresh' bytes in
+   the chunk block reserve with the call to btrfs_block_rsv_add(). This
+   changes the chunk block reserve's 'reserved' and 'size' counters by an
+   amount of 'thresh', and changes the 'bytes_may_use' counter of the
+   system space_info object from 0 to 'thresh'.
+
+   Also during its call to btrfs_alloc_chunk(), we end up increasing the
+   value of the 'total_bytes' counter of the system space_info object by
+   8MiB (the size of a system chunk stripe). This happens through the
+   call chain:
+
+   btrfs_alloc_chunk()
+       create_chunk()
+           btrfs_make_block_group()
+               btrfs_update_space_info()
+
+4) After it finishes the first phase of the block group allocation, at
+   btrfs_chunk_alloc(), task A unlocks the chunk mutex;
+
+5) At this point the new system block group was added to the transaction
+   handle's list of new block groups, but its block group item, device
+   items and chunk item were not yet inserted in the extent, device and
+   chunk trees, respectively. That only happens later when we call
+   btrfs_finish_chunk_alloc() through a call to
+   btrfs_create_pending_block_groups();
+
+   Note that only when we update the chunk tree, through the call to
+   btrfs_finish_chunk_alloc(), we decrement the 'reserved' counter
+   of the chunk block reserve as we COW/allocate extent buffers,
+   through:
+
+   btrfs_alloc_tree_block()
+      btrfs_use_block_rsv()
+         btrfs_block_rsv_use_bytes()
+
+   And the system space_info's 'bytes_may_use' is decremented everytime
+   we allocate an extent buffer for COW operations on the chunk tree,
+   through:
+
+   btrfs_alloc_tree_block()
+      btrfs_reserve_extent()
+         find_free_extent()
+            btrfs_add_reserved_bytes()
+
+   If we end up COWing less chunk btree nodes/leaves than expected, which
+   is the typical case since the amount of space we reserve is always
+   pessimistic to account for the worst possible case, we release the
+   unused space through:
+
+   btrfs_create_pending_block_groups()
+      btrfs_trans_release_chunk_metadata()
+         btrfs_block_rsv_release()
+            block_rsv_release_bytes()
+                btrfs_space_info_free_bytes_may_use()
+
+   But before task A gets into btrfs_create_pending_block_groups()...
+
+6) Many other tasks start allocating new block groups through fallocate,
+   each one does the first phase of block group allocation in a
+   serialized way, since btrfs_chunk_alloc() takes the chunk mutex
+   before calling check_system_chunk() and btrfs_alloc_chunk().
+
+   However before everyone enters the final phase of the block group
+   allocation, that is, before calling btrfs_create_pending_block_groups(),
+   new tasks keep coming to allocate new block groups and while at
+   check_system_chunk(), the system space_info's 'bytes_may_use' keeps
+   increasing each time a task reserves space in the chunk block reserve.
+   This means that eventually some other task can end up not seeing enough
+   free space in the system space_info and decide to allocate yet another
+   system chunk.
+
+   This may repeat several times if yet more new tasks keep allocating
+   new block groups before task A, and all the other tasks, finish the
+   creation of the pending block groups, which is when reserved space
+   in excess is released. Eventually this can result in exhaustion of
+   system chunk array in the superblock, with btrfs_add_system_chunk()
+   returning EFBIG, resulting later in a transaction abort.
+
+   Even when we don't reach the extreme case of exhausting the system
+   array, most, if not all, unnecessarily created system block groups
+   end up being unused since when finishing creation of the first
+   pending system block group, the creation of the following ones end
+   up not needing to COW nodes/leaves of the chunk tree, so we never
+   allocate and deallocate from them, resulting in them never being
+   added to the list of unused block groups - as a consequence they
+   don't get deleted by the cleaner kthread - the only exceptions are
+   if we unmount and mount the filesystem again, which adds any unused
+   block groups to the list of unused block groups, if a scrub is
+   run, which also adds unused block groups to the unused list, and
+   under some circumstances when using a zoned filesystem or async
+   discard, which may also add unused block groups to the unused list.
+
+So fix this by:
+
+*) Tracking the number of reserved bytes for the chunk tree per
+   transaction, which is the sum of reserved chunk bytes by each
+   transaction handle currently being used;
+
+*) When there is not enough free space in the system space_info,
+   if there are other transaction handles which reserved chunk space,
+   wait for some of them to complete in order to have enough excess
+   reserved space released, and then try again. Otherwise proceed with
+   the creation of a new system chunk.
+
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/block-group.c | 58 +++++++++++++++++++++++++++++++++++++++++-
+ fs/btrfs/transaction.c |  5 ++++
+ fs/btrfs/transaction.h |  7 +++++
+ 3 files changed, 69 insertions(+), 1 deletion(-)
+
+diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
+index 744b99ddc28c..a7d9e147dee6 100644
+--- a/fs/btrfs/block-group.c
++++ b/fs/btrfs/block-group.c
+@@ -3269,6 +3269,7 @@ static u64 get_profile_num_devs(struct btrfs_fs_info *fs_info, u64 type)
+  */
+ void check_system_chunk(struct btrfs_trans_handle *trans, u64 type)
+ {
++      struct btrfs_transaction *cur_trans = trans->transaction;
+       struct btrfs_fs_info *fs_info = trans->fs_info;
+       struct btrfs_space_info *info;
+       u64 left;
+@@ -3283,6 +3284,7 @@ void check_system_chunk(struct btrfs_trans_handle *trans, u64 type)
+       lockdep_assert_held(&fs_info->chunk_mutex);
+       info = btrfs_find_space_info(fs_info, BTRFS_BLOCK_GROUP_SYSTEM);
++again:
+       spin_lock(&info->lock);
+       left = info->total_bytes - btrfs_space_info_used(info, true);
+       spin_unlock(&info->lock);
+@@ -3301,6 +3303,58 @@ void check_system_chunk(struct btrfs_trans_handle *trans, u64 type)
+       if (left < thresh) {
+               u64 flags = btrfs_system_alloc_profile(fs_info);
++              u64 reserved = atomic64_read(&cur_trans->chunk_bytes_reserved);
++
++              /*
++               * If there's not available space for the chunk tree (system
++               * space) and there are other tasks that reserved space for
++               * creating a new system block group, wait for them to complete
++               * the creation of their system block group and release excess
++               * reserved space. We do this because:
++               *
++               * *) We can end up allocating more system chunks than necessary
++               *    when there are multiple tasks that are concurrently
++               *    allocating block groups, which can lead to exhaustion of
++               *    the system array in the superblock;
++               *
++               * *) If we allocate extra and unnecessary system block groups,
++               *    despite being empty for a long time, and possibly forever,
++               *    they end not being added to the list of unused block groups
++               *    because that typically happens only when deallocating the
++               *    last extent from a block group - which never happens since
++               *    we never allocate from them in the first place. The few
++               *    exceptions are when mounting a filesystem or running scrub,
++               *    which add unused block groups to the list of unused block
++               *    groups, to be deleted by the cleaner kthread.
++               *    And even when they are added to the list of unused block
++               *    groups, it can take a long time until they get deleted,
++               *    since the cleaner kthread might be sleeping or busy with
++               *    other work (deleting subvolumes, running delayed iputs,
++               *    defrag scheduling, etc);
++               *
++               * This is rare in practice, but can happen when too many tasks
++               * are allocating blocks groups in parallel (via fallocate())
++               * and before the one that reserved space for a new system block
++               * group finishes the block group creation and releases the space
++               * reserved in excess (at btrfs_create_pending_block_groups()),
++               * other tasks end up here and see free system space temporarily
++               * not enough for updating the chunk tree.
++               *
++               * We unlock the chunk mutex before waiting for such tasks and
++               * lock it again after the wait, otherwise we would deadlock.
++               * It is safe to do so because allocating a system chunk is the
++               * first thing done while allocating a new block group.
++               */
++              if (reserved > trans->chunk_bytes_reserved) {
++                      const u64 min_needed = reserved - thresh;
++
++                      mutex_unlock(&fs_info->chunk_mutex);
++                      wait_event(cur_trans->chunk_reserve_wait,
++                         atomic64_read(&cur_trans->chunk_bytes_reserved) <=
++                         min_needed);
++                      mutex_lock(&fs_info->chunk_mutex);
++                      goto again;
++              }
+               /*
+                * Ignore failure to create system chunk. We might end up not
+@@ -3315,8 +3369,10 @@ void check_system_chunk(struct btrfs_trans_handle *trans, u64 type)
+               ret = btrfs_block_rsv_add(fs_info->chunk_root,
+                                         &fs_info->chunk_block_rsv,
+                                         thresh, BTRFS_RESERVE_NO_FLUSH);
+-              if (!ret)
++              if (!ret) {
++                      atomic64_add(thresh, &cur_trans->chunk_bytes_reserved);
+                       trans->chunk_bytes_reserved += thresh;
++              }
+       }
+ }
+diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
+index 3f2c4ee3e762..d56d3e7ca324 100644
+--- a/fs/btrfs/transaction.c
++++ b/fs/btrfs/transaction.c
+@@ -260,6 +260,7 @@ static inline int extwriter_counter_read(struct btrfs_transaction *trans)
+ void btrfs_trans_release_chunk_metadata(struct btrfs_trans_handle *trans)
+ {
+       struct btrfs_fs_info *fs_info = trans->fs_info;
++      struct btrfs_transaction *cur_trans = trans->transaction;
+       if (!trans->chunk_bytes_reserved)
+               return;
+@@ -268,6 +269,8 @@ void btrfs_trans_release_chunk_metadata(struct btrfs_trans_handle *trans)
+       btrfs_block_rsv_release(fs_info, &fs_info->chunk_block_rsv,
+                               trans->chunk_bytes_reserved, NULL);
++      atomic64_sub(trans->chunk_bytes_reserved, &cur_trans->chunk_bytes_reserved);
++      cond_wake_up(&cur_trans->chunk_reserve_wait);
+       trans->chunk_bytes_reserved = 0;
+ }
+@@ -383,6 +386,8 @@ loop:
+       spin_lock_init(&cur_trans->dropped_roots_lock);
+       INIT_LIST_HEAD(&cur_trans->releasing_ebs);
+       spin_lock_init(&cur_trans->releasing_ebs_lock);
++      atomic64_set(&cur_trans->chunk_bytes_reserved, 0);
++      init_waitqueue_head(&cur_trans->chunk_reserve_wait);
+       list_add_tail(&cur_trans->list, &fs_info->trans_list);
+       extent_io_tree_init(fs_info, &cur_trans->dirty_pages,
+                       IO_TREE_TRANS_DIRTY_PAGES, fs_info->btree_inode);
+diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h
+index dd7c3eea08ad..364cfbb4c5c5 100644
+--- a/fs/btrfs/transaction.h
++++ b/fs/btrfs/transaction.h
+@@ -96,6 +96,13 @@ struct btrfs_transaction {
+       spinlock_t releasing_ebs_lock;
+       struct list_head releasing_ebs;
++
++      /*
++       * The number of bytes currently reserved, by all transaction handles
++       * attached to this transaction, for metadata extents of the chunk tree.
++       */
++      atomic64_t chunk_bytes_reserved;
++      wait_queue_head_t chunk_reserve_wait;
+ };
+ #define __TRANS_FREEZABLE     (1U << 0)
+-- 
+2.30.2
+
diff --git a/queue-5.12/btrfs-fix-race-between-marking-inode-needs-to-be-log.patch b/queue-5.12/btrfs-fix-race-between-marking-inode-needs-to-be-log.patch
new file mode 100644 (file)
index 0000000..3e7b4e7
--- /dev/null
@@ -0,0 +1,216 @@
+From 4de3af9e49c17c99df281cc8b1669e1936aa4aeb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Feb 2021 12:08:48 +0000
+Subject: btrfs: fix race between marking inode needs to be logged and log
+ syncing
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit bc0939fcfab0d7efb2ed12896b1af3d819954a14 ]
+
+We have a race between marking that an inode needs to be logged, either
+at btrfs_set_inode_last_trans() or at btrfs_page_mkwrite(), and between
+btrfs_sync_log(). The following steps describe how the race happens.
+
+1) We are at transaction N;
+
+2) Inode I was previously fsynced in the current transaction so it has:
+
+    inode->logged_trans set to N;
+
+3) The inode's root currently has:
+
+   root->log_transid set to 1
+   root->last_log_commit set to 0
+
+   Which means only one log transaction was committed to far, log
+   transaction 0. When a log tree is created we set ->log_transid and
+   ->last_log_commit of its parent root to 0 (at btrfs_add_log_tree());
+
+4) One more range of pages is dirtied in inode I;
+
+5) Some task A starts an fsync against some other inode J (same root), and
+   so it joins log transaction 1.
+
+   Before task A calls btrfs_sync_log()...
+
+6) Task B starts an fsync against inode I, which currently has the full
+   sync flag set, so it starts delalloc and waits for the ordered extent
+   to complete before calling btrfs_inode_in_log() at btrfs_sync_file();
+
+7) During ordered extent completion we have btrfs_update_inode() called
+   against inode I, which in turn calls btrfs_set_inode_last_trans(),
+   which does the following:
+
+     spin_lock(&inode->lock);
+     inode->last_trans = trans->transaction->transid;
+     inode->last_sub_trans = inode->root->log_transid;
+     inode->last_log_commit = inode->root->last_log_commit;
+     spin_unlock(&inode->lock);
+
+   So ->last_trans is set to N and ->last_sub_trans set to 1.
+   But before setting ->last_log_commit...
+
+8) Task A is at btrfs_sync_log():
+
+   - it increments root->log_transid to 2
+   - starts writeback for all log tree extent buffers
+   - waits for the writeback to complete
+   - writes the super blocks
+   - updates root->last_log_commit to 1
+
+   It's a lot of slow steps between updating root->log_transid and
+   root->last_log_commit;
+
+9) The task doing the ordered extent completion, currently at
+   btrfs_set_inode_last_trans(), then finally runs:
+
+     inode->last_log_commit = inode->root->last_log_commit;
+     spin_unlock(&inode->lock);
+
+   Which results in inode->last_log_commit being set to 1.
+   The ordered extent completes;
+
+10) Task B is resumed, and it calls btrfs_inode_in_log() which returns
+    true because we have all the following conditions met:
+
+    inode->logged_trans == N which matches fs_info->generation &&
+    inode->last_subtrans (1) <= inode->last_log_commit (1) &&
+    inode->last_subtrans (1) <= root->last_log_commit (1) &&
+    list inode->extent_tree.modified_extents is empty
+
+    And as a consequence we return without logging the inode, so the
+    existing logged version of the inode does not point to the extent
+    that was written after the previous fsync.
+
+It should be impossible in practice for one task be able to do so much
+progress in btrfs_sync_log() while another task is at
+btrfs_set_inode_last_trans() right after it reads root->log_transid and
+before it reads root->last_log_commit. Even if kernel preemption is enabled
+we know the task at btrfs_set_inode_last_trans() can not be preempted
+because it is holding the inode's spinlock.
+
+However there is another place where we do the same without holding the
+spinlock, which is in the memory mapped write path at:
+
+  vm_fault_t btrfs_page_mkwrite(struct vm_fault *vmf)
+  {
+     (...)
+     BTRFS_I(inode)->last_trans = fs_info->generation;
+     BTRFS_I(inode)->last_sub_trans = BTRFS_I(inode)->root->log_transid;
+     BTRFS_I(inode)->last_log_commit = BTRFS_I(inode)->root->last_log_commit;
+     (...)
+
+So with preemption happening after setting ->last_sub_trans and before
+setting ->last_log_commit, it is less of a stretch to have another task
+do enough progress at btrfs_sync_log() such that the task doing the memory
+mapped write ends up with ->last_sub_trans and ->last_log_commit set to
+the same value. It is still a big stretch to get there, as the task doing
+btrfs_sync_log() has to start writeback, wait for its completion and write
+the super blocks.
+
+So fix this in two different ways:
+
+1) For btrfs_set_inode_last_trans(), simply set ->last_log_commit to the
+   value of ->last_sub_trans minus 1;
+
+2) For btrfs_page_mkwrite() only set the inode's ->last_sub_trans, just
+   like we do for buffered and direct writes at btrfs_file_write_iter(),
+   which is all we need to make sure multiple writes and fsyncs to an
+   inode in the same transaction never result in an fsync missing that
+   the inode changed and needs to be logged. Turn this into a helper
+   function and use it both at btrfs_page_mkwrite() and at
+   btrfs_file_write_iter() - this also fixes the problem that at
+   btrfs_page_mkwrite() we were setting those fields without the
+   protection of the inode's spinlock.
+
+This is an extremely unlikely race to happen in practice.
+
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/btrfs_inode.h | 15 +++++++++++++++
+ fs/btrfs/file.c        | 10 ++--------
+ fs/btrfs/inode.c       |  4 +---
+ fs/btrfs/transaction.h |  2 +-
+ 4 files changed, 19 insertions(+), 12 deletions(-)
+
+diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h
+index 28e202e89660..418903604936 100644
+--- a/fs/btrfs/btrfs_inode.h
++++ b/fs/btrfs/btrfs_inode.h
+@@ -299,6 +299,21 @@ static inline void btrfs_mod_outstanding_extents(struct btrfs_inode *inode,
+                                                 mod);
+ }
++/*
++ * Called every time after doing a buffered, direct IO or memory mapped write.
++ *
++ * This is to ensure that if we write to a file that was previously fsynced in
++ * the current transaction, then try to fsync it again in the same transaction,
++ * we will know that there were changes in the file and that it needs to be
++ * logged.
++ */
++static inline void btrfs_set_inode_last_sub_trans(struct btrfs_inode *inode)
++{
++      spin_lock(&inode->lock);
++      inode->last_sub_trans = inode->root->log_transid;
++      spin_unlock(&inode->lock);
++}
++
+ static inline int btrfs_inode_in_log(struct btrfs_inode *inode, u64 generation)
+ {
+       int ret = 0;
+diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
+index 6d4e15222775..4130523a77c9 100644
+--- a/fs/btrfs/file.c
++++ b/fs/btrfs/file.c
+@@ -2014,14 +2014,8 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb,
+       else
+               num_written = btrfs_buffered_write(iocb, from);
+-      /*
+-       * We also have to set last_sub_trans to the current log transid,
+-       * otherwise subsequent syncs to a file that's been synced in this
+-       * transaction will appear to have already occurred.
+-       */
+-      spin_lock(&inode->lock);
+-      inode->last_sub_trans = inode->root->log_transid;
+-      spin_unlock(&inode->lock);
++      btrfs_set_inode_last_sub_trans(inode);
++
+       if (num_written > 0)
+               num_written = generic_write_sync(iocb, num_written);
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
+index a520775949a0..a922c3bcb65e 100644
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -8619,9 +8619,7 @@ again:
+       set_page_dirty(page);
+       SetPageUptodate(page);
+-      BTRFS_I(inode)->last_trans = fs_info->generation;
+-      BTRFS_I(inode)->last_sub_trans = BTRFS_I(inode)->root->log_transid;
+-      BTRFS_I(inode)->last_log_commit = BTRFS_I(inode)->root->last_log_commit;
++      btrfs_set_inode_last_sub_trans(BTRFS_I(inode));
+       unlock_extent_cached(io_tree, page_start, page_end, &cached_state);
+diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h
+index 6335716e513f..dd7c3eea08ad 100644
+--- a/fs/btrfs/transaction.h
++++ b/fs/btrfs/transaction.h
+@@ -175,7 +175,7 @@ static inline void btrfs_set_inode_last_trans(struct btrfs_trans_handle *trans,
+       spin_lock(&inode->lock);
+       inode->last_trans = trans->transaction->transid;
+       inode->last_sub_trans = inode->root->log_transid;
+-      inode->last_log_commit = inode->root->last_log_commit;
++      inode->last_log_commit = inode->last_sub_trans - 1;
+       spin_unlock(&inode->lock);
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.12/btrfs-use-btrfs_inode_lock-btrfs_inode_unlock-inode-.patch b/queue-5.12/btrfs-use-btrfs_inode_lock-btrfs_inode_unlock-inode-.patch
new file mode 100644 (file)
index 0000000..e54e7fd
--- /dev/null
@@ -0,0 +1,283 @@
+From 6d1f0323117b663c5d350760c7b6cc719a146c15 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Feb 2021 17:14:34 -0500
+Subject: btrfs: use btrfs_inode_lock/btrfs_inode_unlock inode lock helpers
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+[ Upstream commit 64708539cd23b31d0f235a2c12a0cf782f95908a ]
+
+A few places we intermix btrfs_inode_lock with a inode_unlock, and some
+places we just use inode_lock/inode_unlock instead of btrfs_inode_lock.
+
+None of these places are using this incorrectly, but as we adjust some
+of these callers it would be nice to keep everything consistent, so
+convert everybody to use btrfs_inode_lock/btrfs_inode_unlock.
+
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/delayed-inode.c |  4 ++--
+ fs/btrfs/file.c          | 18 +++++++++---------
+ fs/btrfs/ioctl.c         | 26 +++++++++++++-------------
+ fs/btrfs/reflink.c       |  4 ++--
+ fs/btrfs/relocation.c    |  4 ++--
+ 5 files changed, 28 insertions(+), 28 deletions(-)
+
+diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c
+index bf25401c9768..c1d2b6786129 100644
+--- a/fs/btrfs/delayed-inode.c
++++ b/fs/btrfs/delayed-inode.c
+@@ -1589,8 +1589,8 @@ bool btrfs_readdir_get_delayed_items(struct inode *inode,
+        * We can only do one readdir with delayed items at a time because of
+        * item->readdir_list.
+        */
+-      inode_unlock_shared(inode);
+-      inode_lock(inode);
++      btrfs_inode_unlock(inode, BTRFS_ILOCK_SHARED);
++      btrfs_inode_lock(inode, 0);
+       mutex_lock(&delayed_node->mutex);
+       item = __btrfs_first_delayed_insertion_item(delayed_node);
+diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
+index 0e155f013839..6d4e15222775 100644
+--- a/fs/btrfs/file.c
++++ b/fs/btrfs/file.c
+@@ -2122,7 +2122,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
+       if (ret)
+               goto out;
+-      inode_lock(inode);
++      btrfs_inode_lock(inode, 0);
+       atomic_inc(&root->log_batch);
+@@ -2154,7 +2154,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
+        */
+       ret = start_ordered_ops(inode, start, end);
+       if (ret) {
+-              inode_unlock(inode);
++              btrfs_inode_unlock(inode, 0);
+               goto out;
+       }
+@@ -2255,7 +2255,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
+        * file again, but that will end up using the synchronization
+        * inside btrfs_sync_log to keep things safe.
+        */
+-      inode_unlock(inode);
++      btrfs_inode_unlock(inode, 0);
+       if (ret != BTRFS_NO_LOG_SYNC) {
+               if (!ret) {
+@@ -2285,7 +2285,7 @@ out:
+ out_release_extents:
+       btrfs_release_log_ctx_extents(&ctx);
+-      inode_unlock(inode);
++      btrfs_inode_unlock(inode, 0);
+       goto out;
+ }
+@@ -2868,7 +2868,7 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
+       if (ret)
+               return ret;
+-      inode_lock(inode);
++      btrfs_inode_lock(inode, 0);
+       ino_size = round_up(inode->i_size, fs_info->sectorsize);
+       ret = find_first_non_hole(BTRFS_I(inode), &offset, &len);
+       if (ret < 0)
+@@ -2908,7 +2908,7 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
+               truncated_block = true;
+               ret = btrfs_truncate_block(BTRFS_I(inode), offset, 0, 0);
+               if (ret) {
+-                      inode_unlock(inode);
++                      btrfs_inode_unlock(inode, 0);
+                       return ret;
+               }
+       }
+@@ -3009,7 +3009,7 @@ out_only_mutex:
+                               ret = ret2;
+               }
+       }
+-      inode_unlock(inode);
++      btrfs_inode_unlock(inode, 0);
+       return ret;
+ }
+@@ -3377,7 +3377,7 @@ static long btrfs_fallocate(struct file *file, int mode,
+       if (mode & FALLOC_FL_ZERO_RANGE) {
+               ret = btrfs_zero_range(inode, offset, len, mode);
+-              inode_unlock(inode);
++              btrfs_inode_unlock(inode, 0);
+               return ret;
+       }
+@@ -3487,7 +3487,7 @@ out_unlock:
+       unlock_extent_cached(&BTRFS_I(inode)->io_tree, alloc_start, locked_end,
+                            &cached_state);
+ out:
+-      inode_unlock(inode);
++      btrfs_inode_unlock(inode, 0);
+       /* Let go of our reservation. */
+       if (ret != 0 && !(mode & FALLOC_FL_ZERO_RANGE))
+               btrfs_free_reserved_data_space(BTRFS_I(inode), data_reserved,
+diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
+index 49fea3d945f4..5efd6c7fe620 100644
+--- a/fs/btrfs/ioctl.c
++++ b/fs/btrfs/ioctl.c
+@@ -226,7 +226,7 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
+       if (ret)
+               return ret;
+-      inode_lock(inode);
++      btrfs_inode_lock(inode, 0);
+       fsflags = btrfs_mask_fsflags_for_type(inode, fsflags);
+       old_fsflags = btrfs_inode_flags_to_fsflags(binode->flags);
+@@ -353,7 +353,7 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
+  out_end_trans:
+       btrfs_end_transaction(trans);
+  out_unlock:
+-      inode_unlock(inode);
++      btrfs_inode_unlock(inode, 0);
+       mnt_drop_write_file(file);
+       return ret;
+ }
+@@ -449,7 +449,7 @@ static int btrfs_ioctl_fssetxattr(struct file *file, void __user *arg)
+       if (ret)
+               return ret;
+-      inode_lock(inode);
++      btrfs_inode_lock(inode, 0);
+       old_flags = binode->flags;
+       old_i_flags = inode->i_flags;
+@@ -501,7 +501,7 @@ out_unlock:
+               inode->i_flags = old_i_flags;
+       }
+-      inode_unlock(inode);
++      btrfs_inode_unlock(inode, 0);
+       mnt_drop_write_file(file);
+       return ret;
+@@ -1026,7 +1026,7 @@ out_up_read:
+ out_dput:
+       dput(dentry);
+ out_unlock:
+-      inode_unlock(dir);
++      btrfs_inode_unlock(dir, 0);
+       return error;
+ }
+@@ -1624,7 +1624,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
+                       ra_index += cluster;
+               }
+-              inode_lock(inode);
++              btrfs_inode_lock(inode, 0);
+               if (IS_SWAPFILE(inode)) {
+                       ret = -ETXTBSY;
+               } else {
+@@ -1633,13 +1633,13 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
+                       ret = cluster_pages_for_defrag(inode, pages, i, cluster);
+               }
+               if (ret < 0) {
+-                      inode_unlock(inode);
++                      btrfs_inode_unlock(inode, 0);
+                       goto out_ra;
+               }
+               defrag_count += ret;
+               balance_dirty_pages_ratelimited(inode->i_mapping);
+-              inode_unlock(inode);
++              btrfs_inode_unlock(inode, 0);
+               if (newer_than) {
+                       if (newer_off == (u64)-1)
+@@ -1687,9 +1687,9 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
+ out_ra:
+       if (do_compress) {
+-              inode_lock(inode);
++              btrfs_inode_lock(inode, 0);
+               BTRFS_I(inode)->defrag_compress = BTRFS_COMPRESS_NONE;
+-              inode_unlock(inode);
++              btrfs_inode_unlock(inode, 0);
+       }
+       if (!file)
+               kfree(ra);
+@@ -3124,9 +3124,9 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
+               goto out_dput;
+       }
+-      inode_lock(inode);
++      btrfs_inode_lock(inode, 0);
+       err = btrfs_delete_subvolume(dir, dentry);
+-      inode_unlock(inode);
++      btrfs_inode_unlock(inode, 0);
+       if (!err) {
+               fsnotify_rmdir(dir, dentry);
+               d_delete(dentry);
+@@ -3135,7 +3135,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
+ out_dput:
+       dput(dentry);
+ out_unlock_dir:
+-      inode_unlock(dir);
++      btrfs_inode_unlock(dir, 0);
+ free_subvol_name:
+       kfree(subvol_name_ptr);
+ free_parent:
+diff --git a/fs/btrfs/reflink.c b/fs/btrfs/reflink.c
+index 762881b777b3..0abbf050580d 100644
+--- a/fs/btrfs/reflink.c
++++ b/fs/btrfs/reflink.c
+@@ -833,7 +833,7 @@ loff_t btrfs_remap_file_range(struct file *src_file, loff_t off,
+               return -EINVAL;
+       if (same_inode)
+-              inode_lock(src_inode);
++              btrfs_inode_lock(src_inode, 0);
+       else
+               lock_two_nondirectories(src_inode, dst_inode);
+@@ -849,7 +849,7 @@ loff_t btrfs_remap_file_range(struct file *src_file, loff_t off,
+ out_unlock:
+       if (same_inode)
+-              inode_unlock(src_inode);
++              btrfs_inode_unlock(src_inode, 0);
+       else
+               unlock_two_nondirectories(src_inode, dst_inode);
+diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
+index 232d5da7b7be..bf269ee17e68 100644
+--- a/fs/btrfs/relocation.c
++++ b/fs/btrfs/relocation.c
+@@ -2578,7 +2578,7 @@ static noinline_for_stack int prealloc_file_extent_cluster(
+               return btrfs_end_transaction(trans);
+       }
+-      inode_lock(&inode->vfs_inode);
++      btrfs_inode_lock(&inode->vfs_inode, 0);
+       for (nr = 0; nr < cluster->nr; nr++) {
+               start = cluster->boundary[nr] - offset;
+               if (nr + 1 < cluster->nr)
+@@ -2596,7 +2596,7 @@ static noinline_for_stack int prealloc_file_extent_cluster(
+               if (ret)
+                       break;
+       }
+-      inode_unlock(&inode->vfs_inode);
++      btrfs_inode_unlock(&inode->vfs_inode, 0);
+       if (cur_offset < prealloc_end)
+               btrfs_free_reserved_data_space_noquota(inode->root->fs_info,
+-- 
+2.30.2
+
diff --git a/queue-5.12/bus-mhi-core-clear-context-for-stopped-channels-from.patch b/queue-5.12/bus-mhi-core-clear-context-for-stopped-channels-from.patch
new file mode 100644 (file)
index 0000000..794257d
--- /dev/null
@@ -0,0 +1,42 @@
+From 3e08885772b53149aabf59fdf40d035387a98262 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Apr 2021 14:16:11 -0700
+Subject: bus: mhi: core: Clear context for stopped channels from remove()
+
+From: Bhaumik Bhatt <bbhatt@codeaurora.org>
+
+[ Upstream commit 4e44ae3d6d9c2c2a6d9356dd279c925532d5cd8c ]
+
+If a channel was explicitly stopped but not reset and a driver
+remove is issued, clean up the channel context such that it is
+reflected on the device. This move is useful if a client driver
+module is unloaded or a device crash occurs with the host having
+placed the channel in a stopped state.
+
+Signed-off-by: Bhaumik Bhatt <bbhatt@codeaurora.org>
+Reviewed-by: Hemant Kumar <hemantk@codeaurora.org>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/1617311778-1254-3-git-send-email-bbhatt@codeaurora.org
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bus/mhi/core/init.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/bus/mhi/core/init.c b/drivers/bus/mhi/core/init.c
+index 6cb0d67fc921..08b7f4a06bfc 100644
+--- a/drivers/bus/mhi/core/init.c
++++ b/drivers/bus/mhi/core/init.c
+@@ -1304,7 +1304,8 @@ static int mhi_driver_remove(struct device *dev)
+               mutex_lock(&mhi_chan->mutex);
+-              if (ch_state[dir] == MHI_CH_STATE_ENABLED &&
++              if ((ch_state[dir] == MHI_CH_STATE_ENABLED ||
++                   ch_state[dir] == MHI_CH_STATE_STOP) &&
+                   !mhi_chan->offload_ch)
+                       mhi_deinit_chan_ctxt(mhi_cntrl, mhi_chan);
+-- 
+2.30.2
+
diff --git a/queue-5.12/bus-mhi-core-destroy-sbl-devices-when-moving-to-miss.patch b/queue-5.12/bus-mhi-core-destroy-sbl-devices-when-moving-to-miss.patch
new file mode 100644 (file)
index 0000000..63a1673
--- /dev/null
@@ -0,0 +1,113 @@
+From a6f2f9c08718c73de21af72f0afe00b64e4e764b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Feb 2021 15:23:02 -0800
+Subject: bus: mhi: core: Destroy SBL devices when moving to mission mode
+
+From: Bhaumik Bhatt <bbhatt@codeaurora.org>
+
+[ Upstream commit 925089c1900f588615db5bf4e1d9064a5f2c18c7 ]
+
+Currently, client devices are created in SBL or AMSS (mission
+mode) and only destroyed after power down or SYS ERROR. When
+moving between certain execution environments, such as from SBL
+to AMSS, no clean-up is required. This presents an issue where
+SBL-specific channels are left open and client drivers now run in
+an execution environment where they cannot operate. Fix this by
+expanding the mhi_destroy_device() to do an execution environment
+specific clean-up if one is requested. Close the gap and destroy
+devices in such scenarios that allow SBL client drivers to clean
+up once device enters mission mode.
+
+Signed-off-by: Bhaumik Bhatt <bbhatt@codeaurora.org>
+Reviewed-by: Loic Poulain <loic.poulain@linaro.org>
+Reviewed-by: Hemant Kumar <hemantk@codeaurora.org>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/1614208985-20851-2-git-send-email-bbhatt@codeaurora.org
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bus/mhi/core/main.c | 29 +++++++++++++++++++++++++----
+ drivers/bus/mhi/core/pm.c   |  3 +++
+ 2 files changed, 28 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/bus/mhi/core/main.c b/drivers/bus/mhi/core/main.c
+index 34dd430624e4..bd71a2b6f984 100644
+--- a/drivers/bus/mhi/core/main.c
++++ b/drivers/bus/mhi/core/main.c
+@@ -249,8 +249,10 @@ static bool is_valid_ring_ptr(struct mhi_ring *ring, dma_addr_t addr)
+ int mhi_destroy_device(struct device *dev, void *data)
+ {
++      struct mhi_chan *ul_chan, *dl_chan;
+       struct mhi_device *mhi_dev;
+       struct mhi_controller *mhi_cntrl;
++      enum mhi_ee_type ee = MHI_EE_MAX;
+       if (dev->bus != &mhi_bus_type)
+               return 0;
+@@ -262,6 +264,17 @@ int mhi_destroy_device(struct device *dev, void *data)
+       if (mhi_dev->dev_type == MHI_DEVICE_CONTROLLER)
+               return 0;
++      ul_chan = mhi_dev->ul_chan;
++      dl_chan = mhi_dev->dl_chan;
++
++      /*
++       * If execution environment is specified, remove only those devices that
++       * started in them based on ee_mask for the channels as we move on to a
++       * different execution environment
++       */
++      if (data)
++              ee = *(enum mhi_ee_type *)data;
++
+       /*
+        * For the suspend and resume case, this function will get called
+        * without mhi_unregister_controller(). Hence, we need to drop the
+@@ -269,11 +282,19 @@ int mhi_destroy_device(struct device *dev, void *data)
+        * be sure that there will be no instances of mhi_dev left after
+        * this.
+        */
+-      if (mhi_dev->ul_chan)
+-              put_device(&mhi_dev->ul_chan->mhi_dev->dev);
++      if (ul_chan) {
++              if (ee != MHI_EE_MAX && !(ul_chan->ee_mask & BIT(ee)))
++                      return 0;
+-      if (mhi_dev->dl_chan)
+-              put_device(&mhi_dev->dl_chan->mhi_dev->dev);
++              put_device(&ul_chan->mhi_dev->dev);
++      }
++
++      if (dl_chan) {
++              if (ee != MHI_EE_MAX && !(dl_chan->ee_mask & BIT(ee)))
++                      return 0;
++
++              put_device(&dl_chan->mhi_dev->dev);
++      }
+       dev_dbg(&mhi_cntrl->mhi_dev->dev, "destroy device for chan:%s\n",
+                mhi_dev->name);
+diff --git a/drivers/bus/mhi/core/pm.c b/drivers/bus/mhi/core/pm.c
+index 36ab7aa14174..1edce7917b6b 100644
+--- a/drivers/bus/mhi/core/pm.c
++++ b/drivers/bus/mhi/core/pm.c
+@@ -377,6 +377,7 @@ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl)
+ {
+       struct mhi_event *mhi_event;
+       struct device *dev = &mhi_cntrl->mhi_dev->dev;
++      enum mhi_ee_type current_ee = mhi_cntrl->ee;
+       int i, ret;
+       dev_dbg(dev, "Processing Mission Mode transition\n");
+@@ -395,6 +396,8 @@ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl)
+       wake_up_all(&mhi_cntrl->state_event);
++      device_for_each_child(&mhi_cntrl->mhi_dev->dev, &current_ee,
++                            mhi_destroy_device);
+       mhi_cntrl->status_cb(mhi_cntrl, MHI_CB_EE_MISSION_MODE);
+       /* Force MHI to be in M0 state before continuing */
+-- 
+2.30.2
+
diff --git a/queue-5.12/bus-mhi-core-process-execution-environment-changes-s.patch b/queue-5.12/bus-mhi-core-process-execution-environment-changes-s.patch
new file mode 100644 (file)
index 0000000..301ad2a
--- /dev/null
@@ -0,0 +1,144 @@
+From 7c463688a650f82bcae7ee7dd4ce6a1c96c95c68 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Feb 2021 15:23:04 -0800
+Subject: bus: mhi: core: Process execution environment changes serially
+
+From: Bhaumik Bhatt <bbhatt@codeaurora.org>
+
+[ Upstream commit ef2126c4e2ea2b92f543fae00a2a0332e4573c48 ]
+
+In current design, whenever the BHI interrupt is fired, the
+execution environment is updated. This can cause race conditions
+and impede ongoing power up/down processing. For example, if a
+power down is in progress, MHI host updates to a local "disabled"
+execution environment. If a BHI interrupt fires later, that value
+gets replaced with one from the BHI EE register. This impacts the
+controller as it does not expect multiple RDDM execution
+environment change status callbacks as an example. Another issue
+would be that the device can enter mission mode and the execution
+environment is updated, while device creation for SBL channels is
+still going on due to slower PM state worker thread run, leading
+to multiple attempts at opening the same channel.
+
+Ensure that EE changes are handled only from appropriate places
+and occur one after another and handle only PBL modes or RDDM EE
+changes as critical events directly from the interrupt handler.
+Simplify handling by waiting for SYS ERROR before handling RDDM.
+This also makes sure that we use the correct execution environment
+to notify the controller driver when the device resets to one of
+the PBL execution environments.
+
+Signed-off-by: Bhaumik Bhatt <bbhatt@codeaurora.org>
+Reviewed-by: Loic Poulain <loic.poulain@linaro.org>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/1614208985-20851-4-git-send-email-bbhatt@codeaurora.org
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bus/mhi/core/main.c | 40 +++++++++++++++++++------------------
+ drivers/bus/mhi/core/pm.c   |  7 ++++---
+ 2 files changed, 25 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/bus/mhi/core/main.c b/drivers/bus/mhi/core/main.c
+index bd71a2b6f984..61c37b23dd71 100644
+--- a/drivers/bus/mhi/core/main.c
++++ b/drivers/bus/mhi/core/main.c
+@@ -444,7 +444,7 @@ irqreturn_t mhi_intvec_threaded_handler(int irq_number, void *priv)
+       struct device *dev = &mhi_cntrl->mhi_dev->dev;
+       enum mhi_state state = MHI_STATE_MAX;
+       enum mhi_pm_state pm_state = 0;
+-      enum mhi_ee_type ee = 0;
++      enum mhi_ee_type ee = MHI_EE_MAX;
+       write_lock_irq(&mhi_cntrl->pm_lock);
+       if (!MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) {
+@@ -453,8 +453,7 @@ irqreturn_t mhi_intvec_threaded_handler(int irq_number, void *priv)
+       }
+       state = mhi_get_mhi_state(mhi_cntrl);
+-      ee = mhi_cntrl->ee;
+-      mhi_cntrl->ee = mhi_get_exec_env(mhi_cntrl);
++      ee = mhi_get_exec_env(mhi_cntrl);
+       dev_dbg(dev, "local ee:%s device ee:%s dev_state:%s\n",
+               TO_MHI_EXEC_STR(mhi_cntrl->ee), TO_MHI_EXEC_STR(ee),
+               TO_MHI_STATE_STR(state));
+@@ -466,27 +465,30 @@ irqreturn_t mhi_intvec_threaded_handler(int irq_number, void *priv)
+       }
+       write_unlock_irq(&mhi_cntrl->pm_lock);
+-       /* If device supports RDDM don't bother processing SYS error */
+-      if (mhi_cntrl->rddm_image) {
+-              /* host may be performing a device power down already */
+-              if (!mhi_is_active(mhi_cntrl))
+-                      goto exit_intvec;
++      if (pm_state != MHI_PM_SYS_ERR_DETECT || ee == mhi_cntrl->ee)
++              goto exit_intvec;
+-              if (mhi_cntrl->ee == MHI_EE_RDDM && mhi_cntrl->ee != ee) {
++      switch (ee) {
++      case MHI_EE_RDDM:
++              /* proceed if power down is not already in progress */
++              if (mhi_cntrl->rddm_image && mhi_is_active(mhi_cntrl)) {
+                       mhi_cntrl->status_cb(mhi_cntrl, MHI_CB_EE_RDDM);
++                      mhi_cntrl->ee = ee;
+                       wake_up_all(&mhi_cntrl->state_event);
+               }
+-              goto exit_intvec;
+-      }
+-
+-      if (pm_state == MHI_PM_SYS_ERR_DETECT) {
++              break;
++      case MHI_EE_PBL:
++      case MHI_EE_EDL:
++      case MHI_EE_PTHRU:
++              mhi_cntrl->status_cb(mhi_cntrl, MHI_CB_FATAL_ERROR);
++              mhi_cntrl->ee = ee;
+               wake_up_all(&mhi_cntrl->state_event);
+-
+-              /* For fatal errors, we let controller decide next step */
+-              if (MHI_IN_PBL(ee))
+-                      mhi_cntrl->status_cb(mhi_cntrl, MHI_CB_FATAL_ERROR);
+-              else
+-                      mhi_pm_sys_err_handler(mhi_cntrl);
++              mhi_pm_sys_err_handler(mhi_cntrl);
++              break;
++      default:
++              wake_up_all(&mhi_cntrl->state_event);
++              mhi_pm_sys_err_handler(mhi_cntrl);
++              break;
+       }
+ exit_intvec:
+diff --git a/drivers/bus/mhi/core/pm.c b/drivers/bus/mhi/core/pm.c
+index 1edce7917b6b..277704af7eb6 100644
+--- a/drivers/bus/mhi/core/pm.c
++++ b/drivers/bus/mhi/core/pm.c
+@@ -377,21 +377,22 @@ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl)
+ {
+       struct mhi_event *mhi_event;
+       struct device *dev = &mhi_cntrl->mhi_dev->dev;
+-      enum mhi_ee_type current_ee = mhi_cntrl->ee;
++      enum mhi_ee_type ee = MHI_EE_MAX, current_ee = mhi_cntrl->ee;
+       int i, ret;
+       dev_dbg(dev, "Processing Mission Mode transition\n");
+       write_lock_irq(&mhi_cntrl->pm_lock);
+       if (MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state))
+-              mhi_cntrl->ee = mhi_get_exec_env(mhi_cntrl);
++              ee = mhi_get_exec_env(mhi_cntrl);
+-      if (!MHI_IN_MISSION_MODE(mhi_cntrl->ee)) {
++      if (!MHI_IN_MISSION_MODE(ee)) {
+               mhi_cntrl->pm_state = MHI_PM_LD_ERR_FATAL_DETECT;
+               write_unlock_irq(&mhi_cntrl->pm_lock);
+               wake_up_all(&mhi_cntrl->state_event);
+               return -EIO;
+       }
++      mhi_cntrl->ee = ee;
+       write_unlock_irq(&mhi_cntrl->pm_lock);
+       wake_up_all(&mhi_cntrl->state_event);
+-- 
+2.30.2
+
diff --git a/queue-5.12/bus-mhi-pci_generic-implement-pci-shutdown-callback.patch b/queue-5.12/bus-mhi-pci_generic-implement-pci-shutdown-callback.patch
new file mode 100644 (file)
index 0000000..483d9e1
--- /dev/null
@@ -0,0 +1,50 @@
+From 5ca6254fdca6548779b9d58bc7c5c1a508f7be6e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Mar 2021 16:50:37 +0100
+Subject: bus: mhi: pci_generic: Implement PCI shutdown callback
+
+From: Loic Poulain <loic.poulain@linaro.org>
+
+[ Upstream commit 757072abe1c0b67cb226936c709291889658a222 ]
+
+Deinit the device on shutdown to halt MHI/PCI operation on device
+side. This change fixes floating device state with some hosts that
+do not fully shutdown PCIe device when rebooting.
+
+Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/1616169037-7969-1-git-send-email-loic.poulain@linaro.org
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bus/mhi/pci_generic.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/bus/mhi/pci_generic.c b/drivers/bus/mhi/pci_generic.c
+index 356c19ce4bbf..ef549c695b55 100644
+--- a/drivers/bus/mhi/pci_generic.c
++++ b/drivers/bus/mhi/pci_generic.c
+@@ -516,6 +516,12 @@ static void mhi_pci_remove(struct pci_dev *pdev)
+       mhi_unregister_controller(mhi_cntrl);
+ }
++static void mhi_pci_shutdown(struct pci_dev *pdev)
++{
++      mhi_pci_remove(pdev);
++      pci_set_power_state(pdev, PCI_D3hot);
++}
++
+ static void mhi_pci_reset_prepare(struct pci_dev *pdev)
+ {
+       struct mhi_pci_device *mhi_pdev = pci_get_drvdata(pdev);
+@@ -686,6 +692,7 @@ static struct pci_driver mhi_pci_driver = {
+       .id_table       = mhi_pci_id_table,
+       .probe          = mhi_pci_probe,
+       .remove         = mhi_pci_remove,
++      .shutdown       = mhi_pci_shutdown,
+       .err_handler    = &mhi_pci_err_handler,
+       .driver.pm      = &mhi_pci_pm_ops
+ };
+-- 
+2.30.2
+
diff --git a/queue-5.12/bus-mhi-pci_generic-no-op-for-device_wake-operations.patch b/queue-5.12/bus-mhi-pci_generic-no-op-for-device_wake-operations.patch
new file mode 100644 (file)
index 0000000..e76a38c
--- /dev/null
@@ -0,0 +1,86 @@
+From 8c020faa49d8a20345532c0e8f3c10d98381a295 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Mar 2021 20:16:46 +0100
+Subject: bus: mhi: pci_generic: No-Op for device_wake operations
+
+From: Loic Poulain <loic.poulain@linaro.org>
+
+[ Upstream commit e3e5e6508fc1c0e98a5a264853713dd30a60e5e5 ]
+
+The wake_db register presence is highly speculative and can fuze MHI
+devices. Indeed, currently the wake_db register address is defined at
+entry 127 of the 'Channel doorbell array', thus writing to this address
+is equivalent to ringing the doorbell for channel 127, causing trouble
+with some devics (e.g. SDX24 based modems) that get an unexpected
+channel 127 doorbell interrupt.
+
+This change fixes that issue by setting wake get/put as no-op for
+pci_generic devices. The wake device sideband mechanism seems really
+specific to each device, and is AFAIK not defined by the MHI spec.
+
+It also removes zeroing initialization of wake_db register during MMIO
+initialization, the register being set via wake_get/put accessors few
+cycles later during M0 transition.
+
+Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/1614971808-22156-4-git-send-email-loic.poulain@linaro.org
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bus/mhi/core/init.c   |  2 --
+ drivers/bus/mhi/pci_generic.c | 18 ++++++++++++++++++
+ 2 files changed, 18 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/bus/mhi/core/init.c b/drivers/bus/mhi/core/init.c
+index 419d026197ad..6cb0d67fc921 100644
+--- a/drivers/bus/mhi/core/init.c
++++ b/drivers/bus/mhi/core/init.c
+@@ -508,8 +508,6 @@ int mhi_init_mmio(struct mhi_controller *mhi_cntrl)
+       /* Setup wake db */
+       mhi_cntrl->wake_db = base + val + (8 * MHI_DEV_WAKE_DB);
+-      mhi_write_reg(mhi_cntrl, mhi_cntrl->wake_db, 4, 0);
+-      mhi_write_reg(mhi_cntrl, mhi_cntrl->wake_db, 0, 0);
+       mhi_cntrl->wake_set = false;
+       /* Setup channel db address for each channel in tre_ring */
+diff --git a/drivers/bus/mhi/pci_generic.c b/drivers/bus/mhi/pci_generic.c
+index 20673a4b4a3c..356c19ce4bbf 100644
+--- a/drivers/bus/mhi/pci_generic.c
++++ b/drivers/bus/mhi/pci_generic.c
+@@ -230,6 +230,21 @@ static void mhi_pci_status_cb(struct mhi_controller *mhi_cntrl,
+       }
+ }
++static void mhi_pci_wake_get_nop(struct mhi_controller *mhi_cntrl, bool force)
++{
++      /* no-op */
++}
++
++static void mhi_pci_wake_put_nop(struct mhi_controller *mhi_cntrl, bool override)
++{
++      /* no-op */
++}
++
++static void mhi_pci_wake_toggle_nop(struct mhi_controller *mhi_cntrl)
++{
++      /* no-op */
++}
++
+ static bool mhi_pci_is_alive(struct mhi_controller *mhi_cntrl)
+ {
+       struct pci_dev *pdev = to_pci_dev(mhi_cntrl->cntrl_dev);
+@@ -433,6 +448,9 @@ static int mhi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+       mhi_cntrl->status_cb = mhi_pci_status_cb;
+       mhi_cntrl->runtime_get = mhi_pci_runtime_get;
+       mhi_cntrl->runtime_put = mhi_pci_runtime_put;
++      mhi_cntrl->wake_get = mhi_pci_wake_get_nop;
++      mhi_cntrl->wake_put = mhi_pci_wake_put_nop;
++      mhi_cntrl->wake_toggle = mhi_pci_wake_toggle_nop;
+       err = mhi_pci_claim(mhi_cntrl, info->bar_num, DMA_BIT_MASK(info->dma_data_width));
+       if (err)
+-- 
+2.30.2
+
diff --git a/queue-5.12/bus-ti-sysc-probe-for-l4_wkup-and-l4_cfg-interconnec.patch b/queue-5.12/bus-ti-sysc-probe-for-l4_wkup-and-l4_cfg-interconnec.patch
new file mode 100644 (file)
index 0000000..936d987
--- /dev/null
@@ -0,0 +1,90 @@
+From f30798a7f06dc65203e03c7ffcb1cb9816e6cbfc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Mar 2021 11:35:07 +0200
+Subject: bus: ti-sysc: Probe for l4_wkup and l4_cfg interconnect devices first
+
+From: Tony Lindgren <tony@atomide.com>
+
+[ Upstream commit 4700a00755fb5a4bb5109128297d6fd2d1272ee6 ]
+
+We want to probe l4_wkup and l4_cfg interconnect devices first to avoid
+issues with missing resources. Otherwise we attempt to probe l4_per
+devices first causing pointless deferred probe and also annoyingh
+renumbering of the MMC devices for example.
+
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bus/ti-sysc.c | 49 +++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 49 insertions(+)
+
+diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c
+index 3d74f237f005..9e535336689f 100644
+--- a/drivers/bus/ti-sysc.c
++++ b/drivers/bus/ti-sysc.c
+@@ -635,6 +635,51 @@ static int sysc_parse_and_check_child_range(struct sysc *ddata)
+       return 0;
+ }
++/* Interconnect instances to probe before l4_per instances */
++static struct resource early_bus_ranges[] = {
++      /* am3/4 l4_wkup */
++      { .start = 0x44c00000, .end = 0x44c00000 + 0x300000, },
++      /* omap4/5 and dra7 l4_cfg */
++      { .start = 0x4a000000, .end = 0x4a000000 + 0x300000, },
++      /* omap4 l4_wkup */
++      { .start = 0x4a300000, .end = 0x4a300000 + 0x30000,  },
++      /* omap5 and dra7 l4_wkup without dra7 dcan segment */
++      { .start = 0x4ae00000, .end = 0x4ae00000 + 0x30000,  },
++};
++
++static atomic_t sysc_defer = ATOMIC_INIT(10);
++
++/**
++ * sysc_defer_non_critical - defer non_critical interconnect probing
++ * @ddata: device driver data
++ *
++ * We want to probe l4_cfg and l4_wkup interconnect instances before any
++ * l4_per instances as l4_per instances depend on resources on l4_cfg and
++ * l4_wkup interconnects.
++ */
++static int sysc_defer_non_critical(struct sysc *ddata)
++{
++      struct resource *res;
++      int i;
++
++      if (!atomic_read(&sysc_defer))
++              return 0;
++
++      for (i = 0; i < ARRAY_SIZE(early_bus_ranges); i++) {
++              res = &early_bus_ranges[i];
++              if (ddata->module_pa >= res->start &&
++                  ddata->module_pa <= res->end) {
++                      atomic_set(&sysc_defer, 0);
++
++                      return 0;
++              }
++      }
++
++      atomic_dec_if_positive(&sysc_defer);
++
++      return -EPROBE_DEFER;
++}
++
+ static struct device_node *stdout_path;
+ static void sysc_init_stdout_path(struct sysc *ddata)
+@@ -863,6 +908,10 @@ static int sysc_map_and_check_registers(struct sysc *ddata)
+       if (error)
+               return error;
++      error = sysc_defer_non_critical(ddata);
++      if (error)
++              return error;
++
+       sysc_check_children(ddata);
+       error = sysc_parse_registers(ddata);
+-- 
+2.30.2
+
diff --git a/queue-5.12/clk-socfpga-arria10-fix-memory-leak-of-socfpga_clk-o.patch b/queue-5.12/clk-socfpga-arria10-fix-memory-leak-of-socfpga_clk-o.patch
new file mode 100644 (file)
index 0000000..a9309bc
--- /dev/null
@@ -0,0 +1,38 @@
+From d448bcb20aca7449a8e9f371e2356439c0e3c588 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Apr 2021 18:01:15 +0100
+Subject: clk: socfpga: arria10: Fix memory leak of socfpga_clk on error return
+
+From: Colin Ian King <colin.king@canonical.com>
+
+[ Upstream commit 657d4d1934f75a2d978c3cf2086495eaa542e7a9 ]
+
+There is an error return path that is not kfree'ing socfpga_clk leading
+to a memory leak. Fix this by adding in the missing kfree call.
+
+Addresses-Coverity: ("Resource leak")
+Signed-off-by: Colin Ian King <colin.king@canonical.com>
+Link: https://lore.kernel.org/r/20210406170115.430990-1-colin.king@canonical.com
+Acked-by: Dinh Nguyen <dinguyen@kernel.org>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/socfpga/clk-gate-a10.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/clk/socfpga/clk-gate-a10.c b/drivers/clk/socfpga/clk-gate-a10.c
+index cd5df9103614..d62778884208 100644
+--- a/drivers/clk/socfpga/clk-gate-a10.c
++++ b/drivers/clk/socfpga/clk-gate-a10.c
+@@ -146,6 +146,7 @@ static void __init __socfpga_gate_init(struct device_node *node,
+               if (IS_ERR(socfpga_clk->sys_mgr_base_addr)) {
+                       pr_err("%s: failed to find altr,sys-mgr regmap!\n",
+                                       __func__);
++                      kfree(socfpga_clk);
+                       return;
+               }
+       }
+-- 
+2.30.2
+
diff --git a/queue-5.12/clocksource-drivers-dw_apb_timer_of-add-handling-for.patch b/queue-5.12/clocksource-drivers-dw_apb_timer_of-add-handling-for.patch
new file mode 100644 (file)
index 0000000..5fc7abf
--- /dev/null
@@ -0,0 +1,70 @@
+From ac25895deef21497d89067df8f0d98ae69561f36 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Mar 2021 07:18:44 -0500
+Subject: clocksource/drivers/dw_apb_timer_of: Add handling for potential
+ memory leak
+
+From: Dinh Nguyen <dinguyen@kernel.org>
+
+[ Upstream commit 397dc6f7ca3c858dc95800f299357311ccf679e6 ]
+
+Add calls to disable the clock and unmap the timer base address in case
+of any failures.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20210322121844.2271041-1-dinguyen@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clocksource/dw_apb_timer_of.c | 26 +++++++++++++++++++++-----
+ 1 file changed, 21 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/clocksource/dw_apb_timer_of.c b/drivers/clocksource/dw_apb_timer_of.c
+index 42e7e43b8fcd..b1e2b697b21b 100644
+--- a/drivers/clocksource/dw_apb_timer_of.c
++++ b/drivers/clocksource/dw_apb_timer_of.c
+@@ -52,18 +52,34 @@ static int __init timer_get_base_and_rate(struct device_node *np,
+               return 0;
+       timer_clk = of_clk_get_by_name(np, "timer");
+-      if (IS_ERR(timer_clk))
+-              return PTR_ERR(timer_clk);
++      if (IS_ERR(timer_clk)) {
++              ret = PTR_ERR(timer_clk);
++              goto out_pclk_disable;
++      }
+       ret = clk_prepare_enable(timer_clk);
+       if (ret)
+-              return ret;
++              goto out_timer_clk_put;
+       *rate = clk_get_rate(timer_clk);
+-      if (!(*rate))
+-              return -EINVAL;
++      if (!(*rate)) {
++              ret = -EINVAL;
++              goto out_timer_clk_disable;
++      }
+       return 0;
++
++out_timer_clk_disable:
++      clk_disable_unprepare(timer_clk);
++out_timer_clk_put:
++      clk_put(timer_clk);
++out_pclk_disable:
++      if (!IS_ERR(pclk)) {
++              clk_disable_unprepare(pclk);
++              clk_put(pclk);
++      }
++      iounmap(*base);
++      return ret;
+ }
+ static int __init add_clockevent(struct device_node *event_timer)
+-- 
+2.30.2
+
diff --git a/queue-5.12/crypto-api-check-for-err-pointers-in-crypto_destroy_.patch b/queue-5.12/crypto-api-check-for-err-pointers-in-crypto_destroy_.patch
new file mode 100644 (file)
index 0000000..08ecbf5
--- /dev/null
@@ -0,0 +1,149 @@
+From 9779fbdf0ae706715494bb23abbcb3b4c2a62eba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Mar 2021 21:33:03 +0100
+Subject: crypto: api - check for ERR pointers in crypto_destroy_tfm()
+
+From: Ard Biesheuvel <ardb@kernel.org>
+
+[ Upstream commit 83681f2bebb34dbb3f03fecd8f570308ab8b7c2c ]
+
+Given that crypto_alloc_tfm() may return ERR pointers, and to avoid
+crashes on obscure error paths where such pointers are presented to
+crypto_destroy_tfm() (such as [0]), add an ERR_PTR check there
+before dereferencing the second argument as a struct crypto_tfm
+pointer.
+
+[0] https://lore.kernel.org/linux-crypto/000000000000de949705bc59e0f6@google.com/
+
+Reported-by: syzbot+12cf5fbfdeba210a89dd@syzkaller.appspotmail.com
+Reviewed-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ crypto/api.c               | 2 +-
+ include/crypto/acompress.h | 2 ++
+ include/crypto/aead.h      | 2 ++
+ include/crypto/akcipher.h  | 2 ++
+ include/crypto/hash.h      | 4 ++++
+ include/crypto/kpp.h       | 2 ++
+ include/crypto/rng.h       | 2 ++
+ include/crypto/skcipher.h  | 2 ++
+ 8 files changed, 17 insertions(+), 1 deletion(-)
+
+diff --git a/crypto/api.c b/crypto/api.c
+index ed08cbd5b9d3..c4eda56cff89 100644
+--- a/crypto/api.c
++++ b/crypto/api.c
+@@ -562,7 +562,7 @@ void crypto_destroy_tfm(void *mem, struct crypto_tfm *tfm)
+ {
+       struct crypto_alg *alg;
+-      if (unlikely(!mem))
++      if (IS_ERR_OR_NULL(mem))
+               return;
+       alg = tfm->__crt_alg;
+diff --git a/include/crypto/acompress.h b/include/crypto/acompress.h
+index fcde59c65a81..cb3d6b1c655d 100644
+--- a/include/crypto/acompress.h
++++ b/include/crypto/acompress.h
+@@ -165,6 +165,8 @@ static inline struct crypto_acomp *crypto_acomp_reqtfm(struct acomp_req *req)
+  * crypto_free_acomp() -- free ACOMPRESS tfm handle
+  *
+  * @tfm:      ACOMPRESS tfm handle allocated with crypto_alloc_acomp()
++ *
++ * If @tfm is a NULL or error pointer, this function does nothing.
+  */
+ static inline void crypto_free_acomp(struct crypto_acomp *tfm)
+ {
+diff --git a/include/crypto/aead.h b/include/crypto/aead.h
+index fcc12c593ef8..e728469c4ccc 100644
+--- a/include/crypto/aead.h
++++ b/include/crypto/aead.h
+@@ -185,6 +185,8 @@ static inline struct crypto_tfm *crypto_aead_tfm(struct crypto_aead *tfm)
+ /**
+  * crypto_free_aead() - zeroize and free aead handle
+  * @tfm: cipher handle to be freed
++ *
++ * If @tfm is a NULL or error pointer, this function does nothing.
+  */
+ static inline void crypto_free_aead(struct crypto_aead *tfm)
+ {
+diff --git a/include/crypto/akcipher.h b/include/crypto/akcipher.h
+index 1d3aa252caba..5764b46bd1ec 100644
+--- a/include/crypto/akcipher.h
++++ b/include/crypto/akcipher.h
+@@ -174,6 +174,8 @@ static inline struct crypto_akcipher *crypto_akcipher_reqtfm(
+  * crypto_free_akcipher() - free AKCIPHER tfm handle
+  *
+  * @tfm: AKCIPHER tfm handle allocated with crypto_alloc_akcipher()
++ *
++ * If @tfm is a NULL or error pointer, this function does nothing.
+  */
+ static inline void crypto_free_akcipher(struct crypto_akcipher *tfm)
+ {
+diff --git a/include/crypto/hash.h b/include/crypto/hash.h
+index 13f8a6a54ca8..b2bc1e46e86a 100644
+--- a/include/crypto/hash.h
++++ b/include/crypto/hash.h
+@@ -281,6 +281,8 @@ static inline struct crypto_tfm *crypto_ahash_tfm(struct crypto_ahash *tfm)
+ /**
+  * crypto_free_ahash() - zeroize and free the ahash handle
+  * @tfm: cipher handle to be freed
++ *
++ * If @tfm is a NULL or error pointer, this function does nothing.
+  */
+ static inline void crypto_free_ahash(struct crypto_ahash *tfm)
+ {
+@@ -724,6 +726,8 @@ static inline struct crypto_tfm *crypto_shash_tfm(struct crypto_shash *tfm)
+ /**
+  * crypto_free_shash() - zeroize and free the message digest handle
+  * @tfm: cipher handle to be freed
++ *
++ * If @tfm is a NULL or error pointer, this function does nothing.
+  */
+ static inline void crypto_free_shash(struct crypto_shash *tfm)
+ {
+diff --git a/include/crypto/kpp.h b/include/crypto/kpp.h
+index 88b591215d5c..cccceadc164b 100644
+--- a/include/crypto/kpp.h
++++ b/include/crypto/kpp.h
+@@ -154,6 +154,8 @@ static inline void crypto_kpp_set_flags(struct crypto_kpp *tfm, u32 flags)
+  * crypto_free_kpp() - free KPP tfm handle
+  *
+  * @tfm: KPP tfm handle allocated with crypto_alloc_kpp()
++ *
++ * If @tfm is a NULL or error pointer, this function does nothing.
+  */
+ static inline void crypto_free_kpp(struct crypto_kpp *tfm)
+ {
+diff --git a/include/crypto/rng.h b/include/crypto/rng.h
+index 8b4b844b4eef..17bb3673d3c1 100644
+--- a/include/crypto/rng.h
++++ b/include/crypto/rng.h
+@@ -111,6 +111,8 @@ static inline struct rng_alg *crypto_rng_alg(struct crypto_rng *tfm)
+ /**
+  * crypto_free_rng() - zeroize and free RNG handle
+  * @tfm: cipher handle to be freed
++ *
++ * If @tfm is a NULL or error pointer, this function does nothing.
+  */
+ static inline void crypto_free_rng(struct crypto_rng *tfm)
+ {
+diff --git a/include/crypto/skcipher.h b/include/crypto/skcipher.h
+index 6a733b171a5d..ef0fc9ed4342 100644
+--- a/include/crypto/skcipher.h
++++ b/include/crypto/skcipher.h
+@@ -196,6 +196,8 @@ static inline struct crypto_tfm *crypto_skcipher_tfm(
+ /**
+  * crypto_free_skcipher() - zeroize and free cipher handle
+  * @tfm: cipher handle to be freed
++ *
++ * If @tfm is a NULL or error pointer, this function does nothing.
+  */
+ static inline void crypto_free_skcipher(struct crypto_skcipher *tfm)
+ {
+-- 
+2.30.2
+
diff --git a/queue-5.12/crypto-hisilicon-sec-fixes-a-printing-error.patch b/queue-5.12/crypto-hisilicon-sec-fixes-a-printing-error.patch
new file mode 100644 (file)
index 0000000..6cc612e
--- /dev/null
@@ -0,0 +1,35 @@
+From d1d10def76c378d86413109ee2db5e7dd4eb8079 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 13 Mar 2021 15:28:23 +0800
+Subject: crypto: hisilicon/sec - fixes a printing error
+
+From: Longfang Liu <liulongfang@huawei.com>
+
+[ Upstream commit 4b7aef0230418345be1fb77abbb1592801869901 ]
+
+When the log is output here, the device has not
+been initialized yet.
+
+Signed-off-by: Longfang Liu <liulongfang@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 | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c
+index 2eaa516b3231..8adcbb327126 100644
+--- a/drivers/crypto/hisilicon/sec2/sec_crypto.c
++++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c
+@@ -546,7 +546,7 @@ static int sec_skcipher_init(struct crypto_skcipher *tfm)
+       crypto_skcipher_set_reqsize(tfm, sizeof(struct sec_req));
+       ctx->c_ctx.ivsize = crypto_skcipher_ivsize(tfm);
+       if (ctx->c_ctx.ivsize > SEC_IV_SIZE) {
+-              dev_err(SEC_CTX_DEV(ctx), "get error skcipher iv size!\n");
++              pr_err("get error skcipher iv size!\n");
+               return -EINVAL;
+       }
+-- 
+2.30.2
+
diff --git a/queue-5.12/crypto-omap-aes-fix-pm-reference-leak-on-omap-aes.c.patch b/queue-5.12/crypto-omap-aes-fix-pm-reference-leak-on-omap-aes.c.patch
new file mode 100644 (file)
index 0000000..09d92f4
--- /dev/null
@@ -0,0 +1,57 @@
+From b8a76ce4e92c38c11f69ba7025f454e6352d30a3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Apr 2021 15:18:39 +0800
+Subject: crypto: omap-aes - Fix PM reference leak on omap-aes.c
+
+From: Shixin Liu <liushixin2@huawei.com>
+
+[ Upstream commit 1f34cc4a8da34fbb250efb928f9b8c6fe7ee0642 ]
+
+pm_runtime_get_sync will increment pm usage counter even it failed.
+Forgetting to putting operation will result in reference leak here.
+Fix it by replacing it with pm_runtime_resume_and_get to keep usage
+counter balanced.
+
+Signed-off-by: Shixin Liu <liushixin2@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/omap-aes.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
+index a45bdcf3026d..0dd4c6b157de 100644
+--- a/drivers/crypto/omap-aes.c
++++ b/drivers/crypto/omap-aes.c
+@@ -103,9 +103,8 @@ static int omap_aes_hw_init(struct omap_aes_dev *dd)
+               dd->err = 0;
+       }
+-      err = pm_runtime_get_sync(dd->dev);
++      err = pm_runtime_resume_and_get(dd->dev);
+       if (err < 0) {
+-              pm_runtime_put_noidle(dd->dev);
+               dev_err(dd->dev, "failed to get sync: %d\n", err);
+               return err;
+       }
+@@ -1134,7 +1133,7 @@ static int omap_aes_probe(struct platform_device *pdev)
+       pm_runtime_set_autosuspend_delay(dev, DEFAULT_AUTOSUSPEND_DELAY);
+       pm_runtime_enable(dev);
+-      err = pm_runtime_get_sync(dev);
++      err = pm_runtime_resume_and_get(dev);
+       if (err < 0) {
+               dev_err(dev, "%s: failed to get_sync(%d)\n",
+                       __func__, err);
+@@ -1303,7 +1302,7 @@ static int omap_aes_suspend(struct device *dev)
+ static int omap_aes_resume(struct device *dev)
+ {
+-      pm_runtime_get_sync(dev);
++      pm_runtime_resume_and_get(dev);
+       return 0;
+ }
+ #endif
+-- 
+2.30.2
+
diff --git a/queue-5.12/crypto-qat-fix-unmap-invalid-dma-address.patch b/queue-5.12/crypto-qat-fix-unmap-invalid-dma-address.patch
new file mode 100644 (file)
index 0000000..a18a020
--- /dev/null
@@ -0,0 +1,61 @@
+From b1c9899e72f6a854b6c036ebfc17522616d7215f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Mar 2021 14:35:01 +0800
+Subject: crypto: qat - fix unmap invalid dma address
+
+From: Hui Tang <tanghui20@huawei.com>
+
+[ Upstream commit 792b32fad548281e1b7fe14df9063a96c54b32a2 ]
+
+'dma_mapping_error' return a negative value if 'dma_addr' is equal to
+'DMA_MAPPING_ERROR' not zero, so fix initialization of 'dma_addr'.
+
+Signed-off-by: Hui Tang <tanghui20@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/qat/qat_common/qat_algs.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/crypto/qat/qat_common/qat_algs.c b/drivers/crypto/qat/qat_common/qat_algs.c
+index ff78c73c47e3..ea1c6899290d 100644
+--- a/drivers/crypto/qat/qat_common/qat_algs.c
++++ b/drivers/crypto/qat/qat_common/qat_algs.c
+@@ -719,7 +719,7 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst,
+       struct qat_alg_buf_list *bufl;
+       struct qat_alg_buf_list *buflout = NULL;
+       dma_addr_t blp;
+-      dma_addr_t bloutp = 0;
++      dma_addr_t bloutp;
+       struct scatterlist *sg;
+       size_t sz_out, sz = struct_size(bufl, bufers, n + 1);
+@@ -731,6 +731,9 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst,
+       if (unlikely(!bufl))
+               return -ENOMEM;
++      for_each_sg(sgl, sg, n, i)
++              bufl->bufers[i].addr = DMA_MAPPING_ERROR;
++
+       blp = dma_map_single(dev, bufl, sz, DMA_TO_DEVICE);
+       if (unlikely(dma_mapping_error(dev, blp)))
+               goto err_in;
+@@ -764,10 +767,14 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst,
+                                      dev_to_node(&GET_DEV(inst->accel_dev)));
+               if (unlikely(!buflout))
+                       goto err_in;
++
++              bufers = buflout->bufers;
++              for_each_sg(sglout, sg, n, i)
++                      bufers[i].addr = DMA_MAPPING_ERROR;
++
+               bloutp = dma_map_single(dev, buflout, sz_out, DMA_TO_DEVICE);
+               if (unlikely(dma_mapping_error(dev, bloutp)))
+                       goto err_out;
+-              bufers = buflout->bufers;
+               for_each_sg(sglout, sg, n, i) {
+                       int y = sg_nctr;
+-- 
+2.30.2
+
diff --git a/queue-5.12/crypto-sa2ul-fix-pm-reference-leak-in-sa_ul_probe.patch b/queue-5.12/crypto-sa2ul-fix-pm-reference-leak-in-sa_ul_probe.patch
new file mode 100644 (file)
index 0000000..cb759d0
--- /dev/null
@@ -0,0 +1,37 @@
+From fa442dc245b8ab8e12f6310ea5cb0cddd91d1dd5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Apr 2021 15:18:37 +0800
+Subject: crypto: sa2ul - Fix PM reference leak in sa_ul_probe()
+
+From: Shixin Liu <liushixin2@huawei.com>
+
+[ Upstream commit 13343badae093977295341d5a050f51ef128821c ]
+
+pm_runtime_get_sync will increment pm usage counter even it failed.
+Forgetting to putting operation will result in reference leak here.
+Fix it by replacing it with pm_runtime_resume_and_get to keep usage
+counter balanced.
+
+Signed-off-by: Shixin Liu <liushixin2@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/sa2ul.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/sa2ul.c b/drivers/crypto/sa2ul.c
+index f300b0a5958a..d7b1628fb484 100644
+--- a/drivers/crypto/sa2ul.c
++++ b/drivers/crypto/sa2ul.c
+@@ -2350,7 +2350,7 @@ static int sa_ul_probe(struct platform_device *pdev)
+       dev_set_drvdata(sa_k3_dev, dev_data);
+       pm_runtime_enable(dev);
+-      ret = pm_runtime_get_sync(dev);
++      ret = pm_runtime_resume_and_get(dev);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "%s: failed to get sync: %d\n", __func__,
+                       ret);
+-- 
+2.30.2
+
diff --git a/queue-5.12/crypto-stm32-cryp-fix-pm-reference-leak-on-stm32-cry.patch b/queue-5.12/crypto-stm32-cryp-fix-pm-reference-leak-on-stm32-cry.patch
new file mode 100644 (file)
index 0000000..b52eb9f
--- /dev/null
@@ -0,0 +1,46 @@
+From fdb519ebfbf72949044e458985ff51162bd26b4a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Apr 2021 15:18:36 +0800
+Subject: crypto: stm32/cryp - Fix PM reference leak on stm32-cryp.c
+
+From: Shixin Liu <liushixin2@huawei.com>
+
+[ Upstream commit 747bf30fd944f02f341b5f3bc7d97a13f2ae2fbe ]
+
+pm_runtime_get_sync will increment pm usage counter even it failed.
+Forgetting to putting operation will result in reference leak here.
+Fix it by replacing it with pm_runtime_resume_and_get to keep usage
+counter balanced.
+
+Signed-off-by: Shixin Liu <liushixin2@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/stm32/stm32-cryp.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/crypto/stm32/stm32-cryp.c b/drivers/crypto/stm32/stm32-cryp.c
+index 2a4793176c71..7389a0536ff0 100644
+--- a/drivers/crypto/stm32/stm32-cryp.c
++++ b/drivers/crypto/stm32/stm32-cryp.c
+@@ -542,7 +542,7 @@ static int stm32_cryp_hw_init(struct stm32_cryp *cryp)
+       int ret;
+       u32 cfg, hw_mode;
+-      pm_runtime_get_sync(cryp->dev);
++      pm_runtime_resume_and_get(cryp->dev);
+       /* Disable interrupt */
+       stm32_cryp_write(cryp, CRYP_IMSCR, 0);
+@@ -2043,7 +2043,7 @@ static int stm32_cryp_remove(struct platform_device *pdev)
+       if (!cryp)
+               return -ENODEV;
+-      ret = pm_runtime_get_sync(cryp->dev);
++      ret = pm_runtime_resume_and_get(cryp->dev);
+       if (ret < 0)
+               return ret;
+-- 
+2.30.2
+
diff --git a/queue-5.12/crypto-stm32-hash-fix-pm-reference-leak-on-stm32-has.patch b/queue-5.12/crypto-stm32-hash-fix-pm-reference-leak-on-stm32-has.patch
new file mode 100644 (file)
index 0000000..3bab933
--- /dev/null
@@ -0,0 +1,64 @@
+From 305f27c64ad0be0ce6df81bee633c8a6c4690461 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Apr 2021 15:18:35 +0800
+Subject: crypto: stm32/hash - Fix PM reference leak on stm32-hash.c
+
+From: Shixin Liu <liushixin2@huawei.com>
+
+[ Upstream commit 1cb3ad701970e68f18a9e5d090baf2b1b703d729 ]
+
+pm_runtime_get_sync will increment pm usage counter even it failed.
+Forgetting to putting operation will result in reference leak here.
+Fix it by replacing it with pm_runtime_resume_and_get to keep usage
+counter balanced.
+
+Signed-off-by: Shixin Liu <liushixin2@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/stm32/stm32-hash.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/crypto/stm32/stm32-hash.c b/drivers/crypto/stm32/stm32-hash.c
+index 7ac0573ef663..389de9e3302d 100644
+--- a/drivers/crypto/stm32/stm32-hash.c
++++ b/drivers/crypto/stm32/stm32-hash.c
+@@ -813,7 +813,7 @@ static void stm32_hash_finish_req(struct ahash_request *req, int err)
+ static int stm32_hash_hw_init(struct stm32_hash_dev *hdev,
+                             struct stm32_hash_request_ctx *rctx)
+ {
+-      pm_runtime_get_sync(hdev->dev);
++      pm_runtime_resume_and_get(hdev->dev);
+       if (!(HASH_FLAGS_INIT & hdev->flags)) {
+               stm32_hash_write(hdev, HASH_CR, HASH_CR_INIT);
+@@ -962,7 +962,7 @@ static int stm32_hash_export(struct ahash_request *req, void *out)
+       u32 *preg;
+       unsigned int i;
+-      pm_runtime_get_sync(hdev->dev);
++      pm_runtime_resume_and_get(hdev->dev);
+       while ((stm32_hash_read(hdev, HASH_SR) & HASH_SR_BUSY))
+               cpu_relax();
+@@ -1000,7 +1000,7 @@ static int stm32_hash_import(struct ahash_request *req, const void *in)
+       preg = rctx->hw_context;
+-      pm_runtime_get_sync(hdev->dev);
++      pm_runtime_resume_and_get(hdev->dev);
+       stm32_hash_write(hdev, HASH_IMR, *preg++);
+       stm32_hash_write(hdev, HASH_STR, *preg++);
+@@ -1566,7 +1566,7 @@ static int stm32_hash_remove(struct platform_device *pdev)
+       if (!hdev)
+               return -ENODEV;
+-      ret = pm_runtime_get_sync(hdev->dev);
++      ret = pm_runtime_resume_and_get(hdev->dev);
+       if (ret < 0)
+               return ret;
+-- 
+2.30.2
+
diff --git a/queue-5.12/crypto-sun4i-ss-fix-pm-reference-leak-when-pm_runtim.patch b/queue-5.12/crypto-sun4i-ss-fix-pm-reference-leak-when-pm_runtim.patch
new file mode 100644 (file)
index 0000000..ed9dea4
--- /dev/null
@@ -0,0 +1,80 @@
+From b7c0de4d38ee857339ccf2d634e021b6fbbf039f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Apr 2021 15:18:31 +0800
+Subject: crypto: sun4i-ss - Fix PM reference leak when pm_runtime_get_sync()
+ fails
+
+From: Shixin Liu <liushixin2@huawei.com>
+
+[ Upstream commit ac98fc5e1c321112dab9ccac9df892c154540f5d ]
+
+pm_runtime_get_sync will increment pm usage counter even it failed.
+Forgetting to putting operation will result in reference leak here.
+Fix it by replacing it with pm_runtime_resume_and_get to keep usage
+counter balanced.
+
+Signed-off-by: Shixin Liu <liushixin2@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c | 2 +-
+ drivers/crypto/allwinner/sun4i-ss/sun4i-ss-core.c   | 2 +-
+ drivers/crypto/allwinner/sun4i-ss/sun4i-ss-hash.c   | 2 +-
+ drivers/crypto/allwinner/sun4i-ss/sun4i-ss-prng.c   | 2 +-
+ 4 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c
+index c2e6f5ed1d79..dec79fa3ebaf 100644
+--- a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c
++++ b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c
+@@ -561,7 +561,7 @@ int sun4i_ss_cipher_init(struct crypto_tfm *tfm)
+                                   sizeof(struct sun4i_cipher_req_ctx) +
+                                   crypto_skcipher_reqsize(op->fallback_tfm));
+-      err = pm_runtime_get_sync(op->ss->dev);
++      err = pm_runtime_resume_and_get(op->ss->dev);
+       if (err < 0)
+               goto error_pm;
+diff --git a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-core.c b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-core.c
+index 709905ec4680..02a2d34845f2 100644
+--- a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-core.c
++++ b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-core.c
+@@ -459,7 +459,7 @@ static int sun4i_ss_probe(struct platform_device *pdev)
+        * this info could be useful
+        */
+-      err = pm_runtime_get_sync(ss->dev);
++      err = pm_runtime_resume_and_get(ss->dev);
+       if (err < 0)
+               goto error_pm;
+diff --git a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-hash.c b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-hash.c
+index c1b4585e9bbc..d28292762b32 100644
+--- a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-hash.c
++++ b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-hash.c
+@@ -27,7 +27,7 @@ int sun4i_hash_crainit(struct crypto_tfm *tfm)
+       algt = container_of(alg, struct sun4i_ss_alg_template, alg.hash);
+       op->ss = algt->ss;
+-      err = pm_runtime_get_sync(op->ss->dev);
++      err = pm_runtime_resume_and_get(op->ss->dev);
+       if (err < 0)
+               return err;
+diff --git a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-prng.c b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-prng.c
+index 443160a114bb..491fcb7b81b4 100644
+--- a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-prng.c
++++ b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-prng.c
+@@ -29,7 +29,7 @@ int sun4i_ss_prng_generate(struct crypto_rng *tfm, const u8 *src,
+       algt = container_of(alg, struct sun4i_ss_alg_template, alg.rng);
+       ss = algt->ss;
+-      err = pm_runtime_get_sync(ss->dev);
++      err = pm_runtime_resume_and_get(ss->dev);
+       if (err < 0)
+               return err;
+-- 
+2.30.2
+
diff --git a/queue-5.12/crypto-sun8i-ce-fix-pm-reference-leak-in-sun8i_ce_pr.patch b/queue-5.12/crypto-sun8i-ce-fix-pm-reference-leak-in-sun8i_ce_pr.patch
new file mode 100644 (file)
index 0000000..bc2bc67
--- /dev/null
@@ -0,0 +1,37 @@
+From 08c70574dff817306592c2a1b71014f6b9617dc4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Apr 2021 15:18:33 +0800
+Subject: crypto: sun8i-ce - Fix PM reference leak in sun8i_ce_probe()
+
+From: Shixin Liu <liushixin2@huawei.com>
+
+[ Upstream commit cc987ae9150c255352660d235ab27c834aa527be ]
+
+pm_runtime_get_sync will increment pm usage counter even it failed.
+Forgetting to putting operation will result in reference leak here.
+Fix it by replacing it with pm_runtime_resume_and_get to keep usage
+counter balanced.
+
+Signed-off-by: Shixin Liu <liushixin2@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c
+index 158422ff5695..00194d1d9ae6 100644
+--- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c
++++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c
+@@ -932,7 +932,7 @@ static int sun8i_ce_probe(struct platform_device *pdev)
+       if (err)
+               goto error_alg;
+-      err = pm_runtime_get_sync(ce->dev);
++      err = pm_runtime_resume_and_get(ce->dev);
+       if (err < 0)
+               goto error_alg;
+-- 
+2.30.2
+
diff --git a/queue-5.12/crypto-sun8i-ss-fix-pm-reference-leak-when-pm_runtim.patch b/queue-5.12/crypto-sun8i-ss-fix-pm-reference-leak-when-pm_runtim.patch
new file mode 100644 (file)
index 0000000..d506ad7
--- /dev/null
@@ -0,0 +1,52 @@
+From 36ba072ffd2880248f8820559167deb1dc939858 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Apr 2021 15:18:32 +0800
+Subject: crypto: sun8i-ss - Fix PM reference leak when pm_runtime_get_sync()
+ fails
+
+From: Shixin Liu <liushixin2@huawei.com>
+
+[ Upstream commit 06cd7423cf451d68bfab289278d7890c9ae01a14 ]
+
+pm_runtime_get_sync will increment pm usage counter even it failed.
+Forgetting to putting operation will result in reference leak here.
+Fix it by replacing it with pm_runtime_resume_and_get to keep usage
+counter balanced.
+
+Signed-off-by: Shixin Liu <liushixin2@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c | 2 +-
+ drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c   | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
+index ed2a69f82e1c..7c355bc2fb06 100644
+--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
++++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
+@@ -351,7 +351,7 @@ int sun8i_ss_cipher_init(struct crypto_tfm *tfm)
+       op->enginectx.op.prepare_request = NULL;
+       op->enginectx.op.unprepare_request = NULL;
+-      err = pm_runtime_get_sync(op->ss->dev);
++      err = pm_runtime_resume_and_get(op->ss->dev);
+       if (err < 0) {
+               dev_err(op->ss->dev, "pm error %d\n", err);
+               goto error_pm;
+diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
+index e0ddc684798d..80e89066dbd1 100644
+--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
++++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
+@@ -753,7 +753,7 @@ static int sun8i_ss_probe(struct platform_device *pdev)
+       if (err)
+               goto error_alg;
+-      err = pm_runtime_get_sync(ss->dev);
++      err = pm_runtime_resume_and_get(ss->dev);
+       if (err < 0)
+               goto error_alg;
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-added-orientation-quirk-for-onegx1-pro.patch b/queue-5.12/drm-added-orientation-quirk-for-onegx1-pro.patch
new file mode 100644 (file)
index 0000000..86996c6
--- /dev/null
@@ -0,0 +1,56 @@
+From 5d458bfd9994a66605923566bb697b5ce6405f65 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Jan 2021 12:56:26 -0800
+Subject: drm: Added orientation quirk for OneGX1 Pro
+
+From: Jared Baldridge <jrb@expunge.us>
+
+[ Upstream commit 81ad7f9f78e4ff80e95be8282423f511b84f1166 ]
+
+The OneGX1 Pro has a fairly unique combination of generic strings,
+but we additionally match on the BIOS date just to be safe.
+
+Signed-off-by: Jared Baldridge <jrb@expunge.us>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/41288ccb-1012-486b-81c1-a24c31850c91@www.fastmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_panel_orientation_quirks.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c
+index 58f5dc2f6dd5..f6bdec7fa925 100644
+--- a/drivers/gpu/drm/drm_panel_orientation_quirks.c
++++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c
+@@ -84,6 +84,13 @@ static const struct drm_dmi_panel_orientation_data itworks_tw891 = {
+       .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
+ };
++static const struct drm_dmi_panel_orientation_data onegx1_pro = {
++      .width = 1200,
++      .height = 1920,
++      .bios_dates = (const char * const []){ "12/17/2020", NULL },
++      .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
++};
++
+ static const struct drm_dmi_panel_orientation_data lcd720x1280_rightside_up = {
+       .width = 720,
+       .height = 1280,
+@@ -211,6 +218,13 @@ static const struct dmi_system_id orientation_data[] = {
+                 DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad D330-10IGM"),
+               },
+               .driver_data = (void *)&lcd1200x1920_rightside_up,
++      }, {    /* OneGX1 Pro */
++              .matches = {
++                DMI_EXACT_MATCH(DMI_SYS_VENDOR, "SYSTEM_MANUFACTURER"),
++                DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SYSTEM_PRODUCT_NAME"),
++                DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Default string"),
++              },
++              .driver_data = (void *)&onegx1_pro,
+       }, {    /* VIOS LTH17 */
+               .matches = {
+                 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "VIOS"),
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-amd-display-align-cursor-cache-address-to-2kb.patch b/queue-5.12/drm-amd-display-align-cursor-cache-address-to-2kb.patch
new file mode 100644 (file)
index 0000000..3ff19fd
--- /dev/null
@@ -0,0 +1,56 @@
+From b4fe34fd342306dbfcf8823ac49402144c1d32a3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 Feb 2021 19:44:24 -0500
+Subject: drm/amd/display: Align cursor cache address to 2KB
+
+From: Joshua Aberback <joshua.aberback@amd.com>
+
+[ Upstream commit 554ba183b135ef09250b61a202d88512b5bbd03a ]
+
+[Why]
+The registers for the address of the cursor are aligned to 2KB, so all
+cursor surfaces also need to be aligned to 2KB. Currently, the
+provided cursor cache surface is not aligned, so we need a workaround
+until alignment is enforced by the surface provider.
+
+[How]
+ - round up surface address to nearest multiple of 2048
+ - current policy is to provide a much bigger cache size than
+   necessary,so this operation is safe
+
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Joshua Aberback <joshua.aberback@amd.com>
+Reviewed-by: Jun Lei <Jun.Lei@amd.com>
+Acked-by: Eryk Brol <eryk.brol@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+index 06dc1e2e8383..07c8d2e2c09c 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+@@ -848,7 +848,7 @@ bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable)
+                                       cmd.mall.cursor_copy_src.quad_part = cursor_attr.address.quad_part;
+                                       cmd.mall.cursor_copy_dst.quad_part =
+-                                                      plane->address.grph.cursor_cache_addr.quad_part;
++                                                      (plane->address.grph.cursor_cache_addr.quad_part + 2047) & ~2047;
+                                       cmd.mall.cursor_width = cursor_attr.width;
+                                       cmd.mall.cursor_height = cursor_attr.height;
+                                       cmd.mall.cursor_pitch = cursor_attr.pitch;
+@@ -858,8 +858,7 @@ bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable)
+                                       dc_dmub_srv_wait_idle(dc->ctx->dmub_srv);
+                                       /* Use copied cursor, and it's okay to not switch back */
+-                                      cursor_attr.address.quad_part =
+-                                                      plane->address.grph.cursor_cache_addr.quad_part;
++                                      cursor_attr.address.quad_part = cmd.mall.cursor_copy_dst.quad_part;
+                                       dc_stream_set_cursor_attributes(stream, &cursor_attr);
+                               }
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-amd-display-changing-sr-exit-latency.patch b/queue-5.12/drm-amd-display-changing-sr-exit-latency.patch
new file mode 100644 (file)
index 0000000..e1aee0c
--- /dev/null
@@ -0,0 +1,43 @@
+From d6dd4813b5191fe69b8eb103e0613d950794c6b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Feb 2021 16:28:05 -0500
+Subject: drm/amd/display: changing sr exit latency
+
+From: Martin Leung <martin.leung@amd.com>
+
+[ Upstream commit efe213e5a57e0cd92fa4f328dc1963d330549982 ]
+
+[Why]
+Hardware team remeasured, need to update timings
+to increase latency slightly and avoid intermittent
+underflows.
+
+[How]
+sr exit latency update.
+
+Signed-off-by: Martin Leung <martin.leung@amd.com>
+Reviewed-by: Alvin Lee <Alvin.Lee2@amd.com>
+Acked-by: Qingqing Zhuo <Qingqing.Zhuo@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
+index fb7f1dea3c46..71e2d5e02571 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
+@@ -181,7 +181,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_0_soc = {
+               },
+       .min_dcfclk = 500.0, /* TODO: set this to actual min DCFCLK */
+       .num_states = 1,
+-      .sr_exit_time_us = 12,
++      .sr_exit_time_us = 15.5,
+       .sr_enter_plus_exit_time_us = 20,
+       .urgent_latency_us = 4.0,
+       .urgent_latency_pixel_data_only_us = 4.0,
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-amd-display-check-for-dsc-support-instead-of-asi.patch b/queue-5.12/drm-amd-display-check-for-dsc-support-instead-of-asi.patch
new file mode 100644 (file)
index 0000000..7343b73
--- /dev/null
@@ -0,0 +1,44 @@
+From b18a495b4411a2f9c971a99ebaf0a0d00df641e9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Feb 2021 17:09:52 -0500
+Subject: drm/amd/display: Check for DSC support instead of ASIC revision
+
+From: Eryk Brol <eryk.brol@amd.com>
+
+[ Upstream commit 349a19b2f1b01e713268c7de9944ad669ccdf369 ]
+
+[why]
+This check for ASIC revision is no longer useful and causes
+lightup issues after a topology change in MST DSC scenario.
+In this case, DSC configs should be recalculated for the new
+topology. This check prevented that from happening on certain
+ASICs that do, in fact, support DSC.
+
+[how]
+Change the ASIC revision to instead check if DSC is supported.
+
+Signed-off-by: Eryk Brol <eryk.brol@amd.com>
+Acked-by: Bindu Ramamurthy <bindu.r@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index d699a5cf6c11..8ad83ccfcc6a 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -9383,7 +9383,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
+       }
+ #if defined(CONFIG_DRM_AMD_DC_DCN)
+-      if (adev->asic_type >= CHIP_NAVI10) {
++      if (dc_resource_is_dsc_encoding_supported(dc)) {
+               for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
+                       if (drm_atomic_crtc_needs_modeset(new_crtc_state)) {
+                               ret = add_affected_mst_dsc_crtcs(state, crtc);
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-amd-display-dc-dce-dce_aux-remove-duplicate-line.patch b/queue-5.12/drm-amd-display-dc-dce-dce_aux-remove-duplicate-line.patch
new file mode 100644 (file)
index 0000000..ecaad1a
--- /dev/null
@@ -0,0 +1,62 @@
+From 2ba22efa688c3e0d2f217406dab27847d96ccbd8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Mar 2021 13:42:36 +0000
+Subject: drm/amd/display/dc/dce/dce_aux: Remove duplicate line causing 'field
+ overwritten' issue
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Lee Jones <lee.jones@linaro.org>
+
+[ Upstream commit 3e3527f5b765c6f479ba55e5a570ee9538589a74 ]
+
+Fixes the following W=1 kernel build warning(s):
+
+ In file included from drivers/gpu/drm/amd/amdgpu/../display/dc/dce112/dce112_resource.c:59:
+ drivers/gpu/drm/amd/amdgpu/../include/asic_reg/dce/dce_11_2_sh_mask.h:10014:58: warning: initialized field overwritten [-Woverride-init]
+ drivers/gpu/drm/amd/amdgpu/../display/dc/dce/dce_aux.h:214:16: note: in expansion of macro ‘AUX_SW_DATA__AUX_SW_AUTOINCREMENT_DISABLE__SHIFT’
+ drivers/gpu/drm/amd/amdgpu/../display/dc/dce/dce_aux.h:127:2: note: in expansion of macro ‘AUX_SF’
+ drivers/gpu/drm/amd/amdgpu/../display/dc/dce112/dce112_resource.c:177:2: note: in expansion of macro ‘DCE_AUX_MASK_SH_LIST’
+ drivers/gpu/drm/amd/amdgpu/../include/asic_reg/dce/dce_11_2_sh_mask.h:10014:58: note: (near initialization for ‘aux_shift.AUX_SW_AUTOINCREMENT_DISABLE’)
+ drivers/gpu/drm/amd/amdgpu/../display/dc/dce/dce_aux.h:214:16: note: in expansion of macro ‘AUX_SW_DATA__AUX_SW_AUTOINCREMENT_DISABLE__SHIFT’
+ drivers/gpu/drm/amd/amdgpu/../display/dc/dce/dce_aux.h:127:2: note: in expansion of macro ‘AUX_SF’
+ drivers/gpu/drm/amd/amdgpu/../display/dc/dce112/dce112_resource.c:177:2: note: in expansion of macro ‘DCE_AUX_MASK_SH_LIST’
+ drivers/gpu/drm/amd/amdgpu/../include/asic_reg/dce/dce_11_2_sh_mask.h:10013:56: warning: initialized field overwritten [-Woverride-init]
+ drivers/gpu/drm/amd/amdgpu/../display/dc/dce/dce_aux.h:214:16: note: in expansion of macro ‘AUX_SW_DATA__AUX_SW_AUTOINCREMENT_DISABLE_MASK’
+ drivers/gpu/drm/amd/amdgpu/../display/dc/dce/dce_aux.h:127:2: note: in expansion of macro ‘AUX_SF’
+ drivers/gpu/drm/amd/amdgpu/../display/dc/dce112/dce112_resource.c:181:2: note: in expansion of macro ‘DCE_AUX_MASK_SH_LIST’
+ drivers/gpu/drm/amd/amdgpu/../include/asic_reg/dce/dce_11_2_sh_mask.h:10013:56: note: (near initialization for ‘aux_mask.AUX_SW_AUTOINCREMENT_DISABLE’)
+ drivers/gpu/drm/amd/amdgpu/../display/dc/dce/dce_aux.h:214:16: note: in expansion of macro ‘AUX_SW_DATA__AUX_SW_AUTOINCREMENT_DISABLE_MASK’
+ drivers/gpu/drm/amd/amdgpu/../display/dc/dce/dce_aux.h:127:2: note: in expansion of macro ‘AUX_SF’
+
+Cc: Harry Wentland <harry.wentland@amd.com>
+Cc: Leo Li <sunpeng.li@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: "Christian König" <christian.koenig@amd.com>
+Cc: David Airlie <airlied@linux.ie>
+Cc: Daniel Vetter <daniel@ffwll.ch>
+Cc: amd-gfx@lists.freedesktop.org
+Cc: dri-devel@lists.freedesktop.org
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/dce/dce_aux.h | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h
+index 277484cf853e..d4be5954d7aa 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h
++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h
+@@ -99,7 +99,6 @@ struct dce110_aux_registers {
+       AUX_SF(AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\
+       AUX_SF(AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\
+       AUX_SF(AUX_SW_DATA, AUX_SW_DATA_RW, mask_sh),\
+-      AUX_SF(AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\
+       AUX_SF(AUX_SW_DATA, AUX_SW_INDEX, mask_sh),\
+       AUX_SF(AUX_SW_DATA, AUX_SW_DATA, mask_sh),\
+       AUX_SF(AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-amd-display-dchub-underflow-counter-increasing-i.patch b/queue-5.12/drm-amd-display-dchub-underflow-counter-increasing-i.patch
new file mode 100644 (file)
index 0000000..72c7369
--- /dev/null
@@ -0,0 +1,52 @@
+From 5a6cce8c89cfef07e1220dda9630e1ab3cba59c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Mar 2021 15:43:34 -0500
+Subject: drm/amd/display: DCHUB underflow counter increasing in some scenarios
+
+From: Aric Cyr <aric.cyr@amd.com>
+
+[ Upstream commit 4710430a779e6077d81218ac768787545bff8c49 ]
+
+[Why]
+When unplugging a display, the underflow counter can be seen to
+increase because PSTATE switch is allowed even when some planes are not
+blanked.
+
+[How]
+Check that all planes are not active instead of all streams before
+allowing PSTATE change.
+
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Aric Cyr <aric.cyr@amd.com>
+Acked-by: Solomon Chiu <solomon.chiu@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c
+index c7e5a64e06af..81ea5d3a1947 100644
+--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c
++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c
+@@ -252,6 +252,7 @@ static void dcn3_update_clocks(struct clk_mgr *clk_mgr_base,
+       bool force_reset = false;
+       bool update_uclk = false;
+       bool p_state_change_support;
++      int total_plane_count;
+       if (dc->work_arounds.skip_clock_update || !clk_mgr->smu_present)
+               return;
+@@ -292,7 +293,8 @@ static void dcn3_update_clocks(struct clk_mgr *clk_mgr_base,
+               clk_mgr_base->clks.socclk_khz = new_clocks->socclk_khz;
+       clk_mgr_base->clks.prev_p_state_change_support = clk_mgr_base->clks.p_state_change_support;
+-      p_state_change_support = new_clocks->p_state_change_support || (display_count == 0);
++      total_plane_count = clk_mgr_helper_get_active_plane_cnt(dc, context);
++      p_state_change_support = new_clocks->p_state_change_support || (total_plane_count == 0);
+       if (should_update_pstate_support(safe_to_lower, p_state_change_support, clk_mgr_base->clks.p_state_change_support)) {
+               clk_mgr_base->clks.p_state_change_support = p_state_change_support;
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-amd-display-don-t-optimize-bandwidth-before-disa.patch b/queue-5.12/drm-amd-display-don-t-optimize-bandwidth-before-disa.patch
new file mode 100644 (file)
index 0000000..9fab425
--- /dev/null
@@ -0,0 +1,44 @@
+From 1bd2b277086fb95fe7ba6974807fff4da91e145c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Feb 2021 18:13:59 -0500
+Subject: drm/amd/display: Don't optimize bandwidth before disabling planes
+
+From: Aric Cyr <aric.cyr@amd.com>
+
+[ Upstream commit 6ad98e8aeb0106f453bb154933e8355849244990 ]
+
+[Why]
+There is a window of time where we optimize bandwidth due to no streams
+enabled will enable PSTATE changing but HUBPs are not disabled yet.
+This results in underflow counter increasing in some hotplug scenarios.
+
+[How]
+Set the optimize-bandwidth flag for later processing once all the HUBPs
+are properly disabled.
+
+Signed-off-by: Aric Cyr <aric.cyr@amd.com>
+Acked-by: Bindu Ramamurthy <bindu.r@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/core/dc.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
+index 8f8a13c7cf73..c0b827d16268 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
+@@ -2398,7 +2398,8 @@ static void commit_planes_do_stream_update(struct dc *dc,
+                                       if (pipe_ctx->stream_res.audio && !dc->debug.az_endpoint_mute_only)
+                                               pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio);
+-                                      dc->hwss.optimize_bandwidth(dc, dc->current_state);
++                                      dc->optimized_required = true;
++
+                               } else {
+                                       if (dc->optimize_seamless_boot_streams == 0)
+                                               dc->hwss.prepare_bandwidth(dc, dc->current_state);
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-amd-display-fix-debugfs-link_settings-entry.patch b/queue-5.12/drm-amd-display-fix-debugfs-link_settings-entry.patch
new file mode 100644 (file)
index 0000000..ead7a9c
--- /dev/null
@@ -0,0 +1,101 @@
+From efe0f9a650de79e12fc849c401e2115b55942d9b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Mar 2021 11:22:36 -0500
+Subject: drm/amd/display: Fix debugfs link_settings entry
+
+From: Fangzhi Zuo <Jerry.Zuo@amd.com>
+
+[ Upstream commit c006a1c00de29e8cdcde1d0254ac23433ed3fee9 ]
+
+1. Catch invalid link_rate and link_count settings
+2. Call dc interface to overwrite preferred link settings, and wait
+until next stream update to apply the new settings.
+
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
+Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
+Acked-by: Solomon Chiu <solomon.chiu@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+index 360952129b6d..29139b34dbe2 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+@@ -150,7 +150,7 @@ static int parse_write_buffer_into_params(char *wr_buf, uint32_t wr_buf_size,
+  *
+  * --- to get dp configuration
+  *
+- * cat link_settings
++ * cat /sys/kernel/debug/dri/0/DP-x/link_settings
+  *
+  * It will list current, verified, reported, preferred dp configuration.
+  * current -- for current video mode
+@@ -163,7 +163,7 @@ static int parse_write_buffer_into_params(char *wr_buf, uint32_t wr_buf_size,
+  * echo <lane_count>  <link_rate> > link_settings
+  *
+  * for example, to force to  2 lane, 2.7GHz,
+- * echo 4 0xa > link_settings
++ * echo 4 0xa > /sys/kernel/debug/dri/0/DP-x/link_settings
+  *
+  * spread_spectrum could not be changed dynamically.
+  *
+@@ -171,7 +171,7 @@ static int parse_write_buffer_into_params(char *wr_buf, uint32_t wr_buf_size,
+  * done. please check link settings after force operation to see if HW get
+  * programming.
+  *
+- * cat link_settings
++ * cat /sys/kernel/debug/dri/0/DP-x/link_settings
+  *
+  * check current and preferred settings.
+  *
+@@ -255,7 +255,7 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf,
+       int max_param_num = 2;
+       uint8_t param_nums = 0;
+       long param[2];
+-      bool valid_input = false;
++      bool valid_input = true;
+       if (size == 0)
+               return -EINVAL;
+@@ -282,9 +282,9 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf,
+       case LANE_COUNT_ONE:
+       case LANE_COUNT_TWO:
+       case LANE_COUNT_FOUR:
+-              valid_input = true;
+               break;
+       default:
++              valid_input = false;
+               break;
+       }
+@@ -294,9 +294,9 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf,
+       case LINK_RATE_RBR2:
+       case LINK_RATE_HIGH2:
+       case LINK_RATE_HIGH3:
+-              valid_input = true;
+               break;
+       default:
++              valid_input = false;
+               break;
+       }
+@@ -310,10 +310,11 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf,
+        * spread spectrum will not be changed
+        */
+       prefer_link_settings.link_spread = link->cur_link_settings.link_spread;
++      prefer_link_settings.use_link_rate_set = false;
+       prefer_link_settings.lane_count = param[0];
+       prefer_link_settings.link_rate = param[1];
+-      dc_link_set_preferred_link_settings(dc, &prefer_link_settings, link);
++      dc_link_set_preferred_training_settings(dc, &prefer_link_settings, NULL, link, true);
+       kfree(wr_buf);
+       return size;
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-amd-display-fix-dml-prefetch-validation.patch b/queue-5.12/drm-amd-display-fix-dml-prefetch-validation.patch
new file mode 100644 (file)
index 0000000..a24d309
--- /dev/null
@@ -0,0 +1,49 @@
+From 6517d16dc2e050ed226c110489daa14716bdb1b8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Mar 2021 11:04:26 -0500
+Subject: drm/amd/display: fix dml prefetch validation
+
+From: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
+
+[ Upstream commit 8ee0fea4baf90e43efe2275de208a7809f9985bc ]
+
+Incorrect variable used, missing initialization during validation.
+
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
+Reviewed-by: Eric Bernstein <Eric.Bernstein@amd.com>
+Acked-by: Solomon Chiu <solomon.chiu@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c   | 1 +
+ drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c
+index 0f3f510fd83b..9729cf292e84 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c
+@@ -3437,6 +3437,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
+                       mode_lib->vba.DCCEnabledInAnyPlane = true;
+               }
+       }
++      mode_lib->vba.UrgentLatency = mode_lib->vba.UrgentLatencyPixelDataOnly;
+       for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
+               locals->FabricAndDRAMBandwidthPerState[i] = dml_min(
+                               mode_lib->vba.DRAMSpeedPerState[i] * mode_lib->vba.NumberOfChannels
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c
+index 210c96cd5b03..51098c2c9854 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c
+@@ -3544,6 +3544,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
+                       mode_lib->vba.DCCEnabledInAnyPlane = true;
+               }
+       }
++      mode_lib->vba.UrgentLatency = mode_lib->vba.UrgentLatencyPixelDataOnly;
+       for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
+               locals->FabricAndDRAMBandwidthPerState[i] = dml_min(
+                               mode_lib->vba.DRAMSpeedPerState[i] * mode_lib->vba.NumberOfChannels
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-amd-display-fix-mpc-ogam-power-on-off-sequence.patch b/queue-5.12/drm-amd-display-fix-mpc-ogam-power-on-off-sequence.patch
new file mode 100644 (file)
index 0000000..76d6f34
--- /dev/null
@@ -0,0 +1,134 @@
+From 5f765175194f4437904b0894d136c85cb77eb1e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Feb 2021 10:11:30 -0500
+Subject: drm/amd/display: Fix MPC OGAM power on/off sequence
+
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+
+[ Upstream commit 737b2b536a30a467c405d75f2287e17828838a13 ]
+
+[Why]
+Color corruption can occur on bootup into a login
+manager that applies a non-linear gamma LUT because
+the LUT may not actually be powered on before writing.
+
+It's cleared on the next full pipe reprogramming as
+we switch to LUTB from LUTA and the pipe accessing
+the LUT has taken it out of light sleep mode.
+
+[How]
+The MPCC_OGAM_MEM_PWR_FORCE register does not force
+the current power mode when set to 0. It only forces
+when set light sleep, deep sleep or shutdown.
+
+The register to actually force power on and ignore
+sleep modes is MPCC_OGAM_MEM_PWR_DIS - a value of 0
+will enable power requests and a value of 1 will
+disable them.
+
+When PWR_FORCE!=0 is combined with PWR_DIS=0 then
+MPCC OGAM memory is forced into the state specified
+by the force bits.
+
+If PWR_FORCE is 0 then it respects the mode specified
+by MPCC_OGAM_MEM_LOW_PWR_MODE if the RAM LUT is not
+in use.
+
+We set that bit to shutdown on low power, but otherwise
+it inherits from bootup defaults.
+
+So for the fix:
+
+1. Update the sequence to "force" power on when needed
+
+We can use MPCC_OGAM_MEM_PWR_DIS for this to turn on the
+memory even when the block is in bypass and pending to be
+enabled for the next frame.
+
+We need this for both low power enabled or disabled.
+
+If we don't set this then we can run into issues when we
+first program the LUT from bootup.
+
+2. Don't apply FORCE_SEL
+
+Once we enable power requests with DIS=0 we run into the
+issue of the RAM being forced into light sleep and being
+unusable for display output. Leave this 0 like we used to
+for DCN20.
+
+3. Rely on MPCC OGAM init to determine light sleep/deep sleep
+
+MPC low power debug mode isn't enabled on any ASIC currently
+but we'll respect the setting determined during init if it
+is.
+
+Lightly tested as working with IGT tests and desktop color
+adjustment.
+
+4. Change the MPC resource default for DCN30
+
+It was interleaving the dcn20 and dcn30 versions before
+depending on the sequence.
+
+5. REG_WAIT for it to be on whenever we're powering up the
+memory
+
+Otherwise we can write register values too early and we'll
+get corruption.
+
+Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Reviewed-by: Eric Yang <eric.yang2@amd.com>
+Acked-by: Qingqing Zhuo <Qingqing.Zhuo@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c  | 24 ++++++++++---------
+ 1 file changed, 13 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c
+index 3e6f76096119..a7598356f37d 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c
+@@ -143,16 +143,18 @@ static void mpc3_power_on_ogam_lut(
+ {
+       struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
+-      if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) {
+-              // Force power on
+-              REG_UPDATE(MPCC_MEM_PWR_CTRL[mpcc_id], MPCC_OGAM_MEM_PWR_DIS, power_on == true ? 1:0);
+-              // Wait for confirmation when powering on
+-              if (power_on)
+-                      REG_WAIT(MPCC_MEM_PWR_CTRL[mpcc_id], MPCC_OGAM_MEM_PWR_STATE, 0, 10, 10);
+-      } else {
+-              REG_SET(MPCC_MEM_PWR_CTRL[mpcc_id], 0,
+-                              MPCC_OGAM_MEM_PWR_FORCE, power_on == true ? 0 : 1);
+-      }
++      /*
++       * Powering on: force memory active so the LUT can be updated.
++       * Powering off: allow entering memory low power mode
++       *
++       * Memory low power mode is controlled during MPC OGAM LUT init.
++       */
++      REG_UPDATE(MPCC_MEM_PWR_CTRL[mpcc_id],
++                 MPCC_OGAM_MEM_PWR_DIS, power_on != 0);
++
++      /* Wait for memory to be powered on - we won't be able to write to it otherwise. */
++      if (power_on)
++              REG_WAIT(MPCC_MEM_PWR_CTRL[mpcc_id], MPCC_OGAM_MEM_PWR_STATE, 0, 10, 10);
+ }
+ static void mpc3_configure_ogam_lut(
+@@ -1427,7 +1429,7 @@ const struct mpc_funcs dcn30_mpc_funcs = {
+       .acquire_rmu = mpcc3_acquire_rmu,
+       .program_3dlut = mpc3_program_3dlut,
+       .release_rmu = mpcc3_release_rmu,
+-      .power_on_mpc_mem_pwr = mpc20_power_on_ogam_lut,
++      .power_on_mpc_mem_pwr = mpc3_power_on_ogam_lut,
+       .get_mpc_out_mux = mpc1_get_mpc_out_mux,
+ };
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-amd-display-fix-potential-memory-leak.patch b/queue-5.12/drm-amd-display-fix-potential-memory-leak.patch
new file mode 100644 (file)
index 0000000..d4b6d5d
--- /dev/null
@@ -0,0 +1,48 @@
+From b2077211f940fdce36c7b1285bafdb0cad766b58 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Mar 2021 15:10:24 -0500
+Subject: drm/amd/display: Fix potential memory leak
+
+From: Qingqing Zhuo <qingqing.zhuo@amd.com>
+
+[ Upstream commit 51ba691206e35464fd7ec33dd519d141c80b5dff ]
+
+[Why]
+vblank_workqueue is never released.
+
+[How]
+Free it upon dm finish.
+
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
+Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
+Acked-by: Solomon Chiu <solomon.chiu@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index 167e04ab9d5b..9c243f66867a 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -1191,6 +1191,15 @@ static void amdgpu_dm_fini(struct amdgpu_device *adev)
+       if (adev->dm.dc)
+               dc_deinit_callbacks(adev->dm.dc);
+ #endif
++
++#if defined(CONFIG_DRM_AMD_DC_DCN)
++      if (adev->dm.vblank_workqueue) {
++              adev->dm.vblank_workqueue->dm = NULL;
++              kfree(adev->dm.vblank_workqueue);
++              adev->dm.vblank_workqueue = NULL;
++      }
++#endif
++
+       if (adev->dm.dc->ctx->dmub_srv) {
+               dc_dmub_srv_destroy(&adev->dm.dc->ctx->dmub_srv);
+               adev->dm.dc->ctx->dmub_srv = NULL;
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-amd-display-fix-ubsan-shift-out-of-bounds-warnin.patch b/queue-5.12/drm-amd-display-fix-ubsan-shift-out-of-bounds-warnin.patch
new file mode 100644 (file)
index 0000000..2299191
--- /dev/null
@@ -0,0 +1,248 @@
+From 4988cda9b00de599c7034d318926a6317d750853 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Mar 2021 14:25:44 -0500
+Subject: drm/amd/display: Fix UBSAN: shift-out-of-bounds warning
+
+From: Anson Jacob <Anson.Jacob@amd.com>
+
+[ Upstream commit 54718747a6e1037317a8b3610c3be40621b2b75e ]
+
+[Why]
+On NAVI14 CONFIG_UBSAN reported shift-out-of-bounds at
+display_rq_dlg_calc_20v2.c:304:38
+
+rq_param->misc.rq_c.blk256_height is 0 when chroma(*_c) is invalid.
+dml_log2 returns -1023 for log2(0), although log2(0) is undefined.
+
+Which ended up as:
+rq_param->dlg.rq_c.swath_height = 1 << -1023
+
+[How]
+Fix applied on all dml versions.
+1. Ensure dml_log2 is only called if the argument is greater than 0.
+2. Subtract req128_l/req128_c from log2_swath_height_l/log2_swath_height_c
+   only when it is greater than 0.
+
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Anson Jacob <Anson.Jacob@amd.com>
+Reviewed-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
+Reviewed-by: Jun Lei <Jun.Lei@amd.com>
+Acked-by: Solomon Chiu <solomon.chiu@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../dc/dml/dcn20/display_rq_dlg_calc_20.c     | 28 +++++++++++++++----
+ .../dc/dml/dcn20/display_rq_dlg_calc_20v2.c   | 28 +++++++++++++++----
+ .../dc/dml/dcn21/display_rq_dlg_calc_21.c     | 28 +++++++++++++++----
+ .../dc/dml/dcn30/display_rq_dlg_calc_30.c     | 28 +++++++++++++++----
+ .../display/dc/dml/dml1_display_rq_dlg_calc.c | 28 +++++++++++++++----
+ 5 files changed, 115 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
+index 72423dc425dc..799bae229e67 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
+@@ -293,13 +293,31 @@ static void handle_det_buf_split(struct display_mode_lib *mode_lib,
+       if (surf_linear) {
+               log2_swath_height_l = 0;
+               log2_swath_height_c = 0;
+-      } else if (!surf_vert) {
+-              log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l;
+-              log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c;
+       } else {
+-              log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l;
+-              log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c;
++              unsigned int swath_height_l;
++              unsigned int swath_height_c;
++
++              if (!surf_vert) {
++                      swath_height_l = rq_param->misc.rq_l.blk256_height;
++                      swath_height_c = rq_param->misc.rq_c.blk256_height;
++              } else {
++                      swath_height_l = rq_param->misc.rq_l.blk256_width;
++                      swath_height_c = rq_param->misc.rq_c.blk256_width;
++              }
++
++              if (swath_height_l > 0)
++                      log2_swath_height_l = dml_log2(swath_height_l);
++
++              if (req128_l && log2_swath_height_l > 0)
++                      log2_swath_height_l -= 1;
++
++              if (swath_height_c > 0)
++                      log2_swath_height_c = dml_log2(swath_height_c);
++
++              if (req128_c && log2_swath_height_c > 0)
++                      log2_swath_height_c -= 1;
+       }
++
+       rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l;
+       rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c;
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c
+index 9c78446c3a9d..6a6d5970d1d5 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c
+@@ -293,13 +293,31 @@ static void handle_det_buf_split(struct display_mode_lib *mode_lib,
+       if (surf_linear) {
+               log2_swath_height_l = 0;
+               log2_swath_height_c = 0;
+-      } else if (!surf_vert) {
+-              log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l;
+-              log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c;
+       } else {
+-              log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l;
+-              log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c;
++              unsigned int swath_height_l;
++              unsigned int swath_height_c;
++
++              if (!surf_vert) {
++                      swath_height_l = rq_param->misc.rq_l.blk256_height;
++                      swath_height_c = rq_param->misc.rq_c.blk256_height;
++              } else {
++                      swath_height_l = rq_param->misc.rq_l.blk256_width;
++                      swath_height_c = rq_param->misc.rq_c.blk256_width;
++              }
++
++              if (swath_height_l > 0)
++                      log2_swath_height_l = dml_log2(swath_height_l);
++
++              if (req128_l && log2_swath_height_l > 0)
++                      log2_swath_height_l -= 1;
++
++              if (swath_height_c > 0)
++                      log2_swath_height_c = dml_log2(swath_height_c);
++
++              if (req128_c && log2_swath_height_c > 0)
++                      log2_swath_height_c -= 1;
+       }
++
+       rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l;
+       rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c;
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c
+index edd41d358291..dc1c81a6e377 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c
+@@ -277,13 +277,31 @@ static void handle_det_buf_split(
+       if (surf_linear) {
+               log2_swath_height_l = 0;
+               log2_swath_height_c = 0;
+-      } else if (!surf_vert) {
+-              log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l;
+-              log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c;
+       } else {
+-              log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l;
+-              log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c;
++              unsigned int swath_height_l;
++              unsigned int swath_height_c;
++
++              if (!surf_vert) {
++                      swath_height_l = rq_param->misc.rq_l.blk256_height;
++                      swath_height_c = rq_param->misc.rq_c.blk256_height;
++              } else {
++                      swath_height_l = rq_param->misc.rq_l.blk256_width;
++                      swath_height_c = rq_param->misc.rq_c.blk256_width;
++              }
++
++              if (swath_height_l > 0)
++                      log2_swath_height_l = dml_log2(swath_height_l);
++
++              if (req128_l && log2_swath_height_l > 0)
++                      log2_swath_height_l -= 1;
++
++              if (swath_height_c > 0)
++                      log2_swath_height_c = dml_log2(swath_height_c);
++
++              if (req128_c && log2_swath_height_c > 0)
++                      log2_swath_height_c -= 1;
+       }
++
+       rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l;
+       rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c;
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c
+index 0f14f205ebe5..04601a767a8f 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c
+@@ -237,13 +237,31 @@ static void handle_det_buf_split(struct display_mode_lib *mode_lib,
+       if (surf_linear) {
+               log2_swath_height_l = 0;
+               log2_swath_height_c = 0;
+-      } else if (!surf_vert) {
+-              log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l;
+-              log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c;
+       } else {
+-              log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l;
+-              log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c;
++              unsigned int swath_height_l;
++              unsigned int swath_height_c;
++
++              if (!surf_vert) {
++                      swath_height_l = rq_param->misc.rq_l.blk256_height;
++                      swath_height_c = rq_param->misc.rq_c.blk256_height;
++              } else {
++                      swath_height_l = rq_param->misc.rq_l.blk256_width;
++                      swath_height_c = rq_param->misc.rq_c.blk256_width;
++              }
++
++              if (swath_height_l > 0)
++                      log2_swath_height_l = dml_log2(swath_height_l);
++
++              if (req128_l && log2_swath_height_l > 0)
++                      log2_swath_height_l -= 1;
++
++              if (swath_height_c > 0)
++                      log2_swath_height_c = dml_log2(swath_height_c);
++
++              if (req128_c && log2_swath_height_c > 0)
++                      log2_swath_height_c -= 1;
+       }
++
+       rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l;
+       rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c;
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c
+index 4c3e9cc30167..414da64f5734 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c
+@@ -344,13 +344,31 @@ static void handle_det_buf_split(
+       if (surf_linear) {
+               log2_swath_height_l = 0;
+               log2_swath_height_c = 0;
+-      } else if (!surf_vert) {
+-              log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l;
+-              log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c;
+       } else {
+-              log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l;
+-              log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c;
++              unsigned int swath_height_l;
++              unsigned int swath_height_c;
++
++              if (!surf_vert) {
++                      swath_height_l = rq_param->misc.rq_l.blk256_height;
++                      swath_height_c = rq_param->misc.rq_c.blk256_height;
++              } else {
++                      swath_height_l = rq_param->misc.rq_l.blk256_width;
++                      swath_height_c = rq_param->misc.rq_c.blk256_width;
++              }
++
++              if (swath_height_l > 0)
++                      log2_swath_height_l = dml_log2(swath_height_l);
++
++              if (req128_l && log2_swath_height_l > 0)
++                      log2_swath_height_l -= 1;
++
++              if (swath_height_c > 0)
++                      log2_swath_height_c = dml_log2(swath_height_c);
++
++              if (req128_c && log2_swath_height_c > 0)
++                      log2_swath_height_c -= 1;
+       }
++
+       rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l;
+       rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c;
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-amd-display-fix-ubsan-warning-for-not-a-valid-va.patch b/queue-5.12/drm-amd-display-fix-ubsan-warning-for-not-a-valid-va.patch
new file mode 100644 (file)
index 0000000..819f71a
--- /dev/null
@@ -0,0 +1,58 @@
+From 7d266b3e12e0fcf5991f5a05ce1120e2fc7eeb11 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Mar 2021 16:16:36 -0500
+Subject: drm/amd/display: Fix UBSAN warning for not a valid value for type
+ '_Bool'
+
+From: Anson Jacob <Anson.Jacob@amd.com>
+
+[ Upstream commit 6a30a92997eee49554f72b462dce90abe54a496f ]
+
+[Why]
+dc_cursor_position do not initialise position.translate_by_source when
+crtc or plane->state->fb is NULL. UBSAN caught this error in
+dce110_set_cursor_position, as the value was garbage.
+
+[How]
+Initialise dc_cursor_position structure elements to 0 in handle_cursor_update
+before calling get_cursor_position.
+
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1471
+Reported-by: Lyude Paul <lyude@redhat.com>
+Signed-off-by: Anson Jacob <Anson.Jacob@amd.com>
+Reviewed-by: Aurabindo Jayamohanan Pillai <Aurabindo.Pillai@amd.com>
+Acked-by: Solomon Chiu <solomon.chiu@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index 8ad83ccfcc6a..167e04ab9d5b 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -7417,10 +7417,6 @@ static int get_cursor_position(struct drm_plane *plane, struct drm_crtc *crtc,
+       int x, y;
+       int xorigin = 0, yorigin = 0;
+-      position->enable = false;
+-      position->x = 0;
+-      position->y = 0;
+-
+       if (!crtc || !plane->state->fb)
+               return 0;
+@@ -7467,7 +7463,7 @@ static void handle_cursor_update(struct drm_plane *plane,
+       struct dm_crtc_state *crtc_state = crtc ? to_dm_crtc_state(crtc->state) : NULL;
+       struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
+       uint64_t address = afb ? afb->address : 0;
+-      struct dc_cursor_position position;
++      struct dc_cursor_position position = {0};
+       struct dc_cursor_attributes attributes;
+       int ret;
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-amd-display-return-invalid-state-if-gpint-times-.patch b/queue-5.12/drm-amd-display-return-invalid-state-if-gpint-times-.patch
new file mode 100644 (file)
index 0000000..e8091b8
--- /dev/null
@@ -0,0 +1,59 @@
+From e54fbf8b0a383fef93ad9f53ccf493af3eae6584 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Feb 2021 12:21:47 -0500
+Subject: drm/amd/display: Return invalid state if GPINT times out
+
+From: Wyatt Wood <wyatt.wood@amd.com>
+
+[ Upstream commit 8039bc7130ef4206a58e4dc288621bc97eba08eb ]
+
+[Why]
+GPINT timeout is causing PSR_STATE_0 to be returned when it shouldn't.
+We must guarantee that PSR is fully disabled before doing hw programming
+on driver-side.
+
+[How]
+Return invalid state if GPINT command times out. Let existing retry
+logic send the GPINT until successful.
+
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Wyatt Wood <wyatt.wood@amd.com>
+Reviewed-by: Anthony Koo <Anthony.Koo@amd.com>
+Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
+index 69e34bef274c..febccb35ddad 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
++++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
+@@ -81,13 +81,18 @@ static void dmub_psr_get_state(struct dmub_psr *dmub, enum dc_psr_state *state)
+ {
+       struct dmub_srv *srv = dmub->ctx->dmub_srv->dmub;
+       uint32_t raw_state;
++      enum dmub_status status = DMUB_STATUS_INVALID;
+       // Send gpint command and wait for ack
+-      dmub_srv_send_gpint_command(srv, DMUB_GPINT__GET_PSR_STATE, 0, 30);
+-
+-      dmub_srv_get_gpint_response(srv, &raw_state);
+-
+-      *state = convert_psr_state(raw_state);
++      status = dmub_srv_send_gpint_command(srv, DMUB_GPINT__GET_PSR_STATE, 0, 30);
++
++      if (status == DMUB_STATUS_OK) {
++              // GPINT was executed, get response
++              dmub_srv_get_gpint_response(srv, &raw_state);
++              *state = convert_psr_state(raw_state);
++      } else
++              // Return invalid state when GPINT times out
++              *state = 0xFF;
+ }
+ /*
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-amd-display-try-ycbcr420-color-when-ycbcr444-fai.patch b/queue-5.12/drm-amd-display-try-ycbcr420-color-when-ycbcr444-fai.patch
new file mode 100644 (file)
index 0000000..400c8cd
--- /dev/null
@@ -0,0 +1,52 @@
+From 9b3c0961ab4e44ed83de1e6de531bb52c031954f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Mar 2021 16:13:48 +0100
+Subject: drm/amd/display: Try YCbCr420 color when YCbCr444 fails
+
+From: Werner Sembach <wse@tuxedocomputers.com>
+
+[ Upstream commit 68eb3ae3c63708f823aeeb63bb15197c727bd9bf ]
+
+When encoder validation of a display mode fails, retry with less bandwidth
+heavy YCbCr420 color mode, if available. This enables some HDMI 1.4 setups
+to support 4k60Hz output, which previously failed silently.
+
+On some setups, while the monitor and the gpu support display modes with
+pixel clocks of up to 600MHz, the link encoder might not. This prevents
+YCbCr444 and RGB encoding for 4k60Hz, but YCbCr420 encoding might still be
+possible. However, which color mode is used is decided before the link
+encoder capabilities are checked. This patch fixes the problem by retrying
+to find a display mode with YCbCr420 enforced and using it, if it is
+valid.
+
+Reviewed-by: Harry Wentland <harry.wentland@amd.com>
+Signed-off-by: Werner Sembach <wse@tuxedocomputers.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index 9c243f66867a..29ca1708458c 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -5872,6 +5872,15 @@ create_validate_stream_for_sink(struct amdgpu_dm_connector *aconnector,
+       } while (stream == NULL && requested_bpc >= 6);
++      if (dc_result == DC_FAIL_ENC_VALIDATE && !aconnector->force_yuv420_output) {
++              DRM_DEBUG_KMS("Retry forcing YCbCr420 encoding\n");
++
++              aconnector->force_yuv420_output = true;
++              stream = create_validate_stream_for_sink(aconnector, drm_mode,
++                                              dm_state, old_stream);
++              aconnector->force_yuv420_output = false;
++      }
++
+       return stream;
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-amd-display-update-dcn302-sr-exit-latency.patch b/queue-5.12/drm-amd-display-update-dcn302-sr-exit-latency.patch
new file mode 100644 (file)
index 0000000..1e92adf
--- /dev/null
@@ -0,0 +1,38 @@
+From d9913ef7ad76f72bf69838495f72bea7bbd6972f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Apr 2021 17:21:50 -0400
+Subject: drm/amd/display: Update DCN302 SR Exit Latency
+
+From: Joshua Aberback <joshua.aberback@amd.com>
+
+[ Upstream commit 79f02534810c9557fb3217b538616dc42a1de3b9 ]
+
+[Why&How]
+Update SR Exit Latency to fix screen flickering caused due to OTG
+underflow. This is the recommended value given by the hardware IP team.
+
+Signed-off-by: Joshua Aberback <joshua.aberback@amd.com>
+Acked-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
+Reviewed-by: Harry Wentland <harry.wentland@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c
+index 4b659b63f75b..d03b1975e417 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c
+@@ -164,7 +164,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_02_soc = {
+               .min_dcfclk = 500.0, /* TODO: set this to actual min DCFCLK */
+               .num_states = 1,
+-              .sr_exit_time_us = 12,
++              .sr_exit_time_us = 15.5,
+               .sr_enter_plus_exit_time_us = 20,
+               .urgent_latency_us = 4.0,
+               .urgent_latency_pixel_data_only_us = 4.0,
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-amd-pm-do-not-issue-message-while-write-r-into-p.patch b/queue-5.12/drm-amd-pm-do-not-issue-message-while-write-r-into-p.patch
new file mode 100644 (file)
index 0000000..4affdfa
--- /dev/null
@@ -0,0 +1,138 @@
+From 65a80ec153d2cbb24f697ab85e7ac6cbae022114 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Feb 2021 12:27:43 +0800
+Subject: drm/amd/pm: do not issue message while write "r" into
+ pp_od_clk_voltage
+
+From: Huang Rui <ray.huang@amd.com>
+
+[ Upstream commit ca1203d7d7295c49e5707d7def457bdc524a8edb ]
+
+We should commit the value after restore them back to default as well.
+
+$ echo "r" > pp_od_clk_voltage
+$ echo "c" > pp_od_clk_voltage
+
+Signed-off-by: Huang Rui <ray.huang@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c  | 14 -------
+ .../gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c  | 38 -------------------
+ .../gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c   | 18 ---------
+ 3 files changed, 70 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c
+index ed05a30d1139..e2a56a7f3d7a 100644
+--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c
++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c
+@@ -1526,20 +1526,6 @@ static int smu10_set_fine_grain_clk_vol(struct pp_hwmgr *hwmgr,
+               smu10_data->gfx_actual_soft_min_freq = min_freq;
+               smu10_data->gfx_actual_soft_max_freq = max_freq;
+-
+-              ret = smum_send_msg_to_smc_with_parameter(hwmgr,
+-                                      PPSMC_MSG_SetHardMinGfxClk,
+-                                      min_freq,
+-                                      NULL);
+-              if (ret)
+-                      return ret;
+-
+-              ret = smum_send_msg_to_smc_with_parameter(hwmgr,
+-                                      PPSMC_MSG_SetSoftMaxGfxClk,
+-                                      max_freq,
+-                                      NULL);
+-              if (ret)
+-                      return ret;
+       } else if (type == PP_OD_COMMIT_DPM_TABLE) {
+               if (size != 0) {
+                       pr_err("Input parameter number not correct\n");
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c
+index 101eaa20db9b..a80f551771b9 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c
+@@ -1462,7 +1462,6 @@ static int vangogh_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TAB
+                                       long input[], uint32_t size)
+ {
+       int ret = 0;
+-      int i;
+       struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
+       if (!(smu_dpm_ctx->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL)) {
+@@ -1535,43 +1534,6 @@ static int vangogh_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TAB
+                       smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
+                       smu->cpu_actual_soft_min_freq = smu->cpu_default_soft_min_freq;
+                       smu->cpu_actual_soft_max_freq = smu->cpu_default_soft_max_freq;
+-
+-                      ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinGfxClk,
+-                                                                      smu->gfx_actual_hard_min_freq, NULL);
+-                      if (ret) {
+-                              dev_err(smu->adev->dev, "Restore the default hard min sclk failed!");
+-                              return ret;
+-                      }
+-
+-                      ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxGfxClk,
+-                                                                      smu->gfx_actual_soft_max_freq, NULL);
+-                      if (ret) {
+-                              dev_err(smu->adev->dev, "Restore the default soft max sclk failed!");
+-                              return ret;
+-                      }
+-
+-                      if (smu->adev->pm.fw_version < 0x43f1b00) {
+-                              dev_warn(smu->adev->dev, "CPUSoftMax/CPUSoftMin are not supported, please update SBIOS!\n");
+-                              break;
+-                      }
+-
+-                      for (i = 0; i < smu->cpu_core_num; i++) {
+-                              ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMinCclk,
+-                                                                    (i << 20) | smu->cpu_actual_soft_min_freq,
+-                                                                    NULL);
+-                              if (ret) {
+-                                      dev_err(smu->adev->dev, "Set hard min cclk failed!");
+-                                      return ret;
+-                              }
+-
+-                              ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxCclk,
+-                                                                    (i << 20) | smu->cpu_actual_soft_max_freq,
+-                                                                    NULL);
+-                              if (ret) {
+-                                      dev_err(smu->adev->dev, "Set soft max cclk failed!");
+-                                      return ret;
+-                              }
+-                      }
+               }
+               break;
+       case PP_OD_COMMIT_DPM_TABLE:
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c
+index 5493388fcb10..dbe6d0caddb7 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c
+@@ -389,24 +389,6 @@ static int renoir_od_edit_dpm_table(struct smu_context *smu,
+               }
+               smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
+               smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
+-
+-              ret = smu_cmn_send_smc_msg_with_param(smu,
+-                                                              SMU_MSG_SetHardMinGfxClk,
+-                                                              smu->gfx_actual_hard_min_freq,
+-                                                              NULL);
+-              if (ret) {
+-                      dev_err(smu->adev->dev, "Restore the default hard min sclk failed!");
+-                      return ret;
+-              }
+-
+-              ret = smu_cmn_send_smc_msg_with_param(smu,
+-                                                              SMU_MSG_SetSoftMaxGfxClk,
+-                                                              smu->gfx_actual_soft_max_freq,
+-                                                              NULL);
+-              if (ret) {
+-                      dev_err(smu->adev->dev, "Restore the default soft max sclk failed!");
+-                      return ret;
+-              }
+               break;
+       case PP_OD_COMMIT_DPM_TABLE:
+               if (size != 0) {
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-amd-pm-fix-workload-mismatch-on-vega10.patch b/queue-5.12/drm-amd-pm-fix-workload-mismatch-on-vega10.patch
new file mode 100644 (file)
index 0000000..0546a58
--- /dev/null
@@ -0,0 +1,36 @@
+From ab5e8b0c9fb8b6052ed838e83c76403d7e5792cc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Mar 2021 10:28:00 +0800
+Subject: drm/amd/pm: fix workload mismatch on vega10
+
+From: Kenneth Feng <kenneth.feng@amd.com>
+
+[ Upstream commit 0979d43259e13846d86ba17e451e17fec185d240 ]
+
+Workload number mapped to the correct one.
+This issue is only on vega10.
+
+Signed-off-by: Kenneth Feng <kenneth.feng@amd.com>
+Reviewed-by: Kevin Wang <kevin1.wang@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c
+index 599ec9726601..959143eff651 100644
+--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c
++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c
+@@ -5160,7 +5160,7 @@ static int vega10_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, ui
+ out:
+       smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetWorkloadMask,
+-                                              1 << power_profile_mode,
++                                              (!power_profile_mode) ? 0 : 1 << (power_profile_mode - 1),
+                                               NULL);
+       hwmgr->power_profile_mode = power_profile_mode;
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-amd-pm-swsmu-clean-up-user-profile-function.patch b/queue-5.12/drm-amd-pm-swsmu-clean-up-user-profile-function.patch
new file mode 100644 (file)
index 0000000..4a1f789
--- /dev/null
@@ -0,0 +1,143 @@
+From 2d0e608c1ed1d4766887451752c73f87cb003153 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Mar 2021 15:45:13 +0530
+Subject: drm/amd/pm/swsmu: clean up user profile function
+
+From: Arunpravin <Arunpravin.PaneerSelvam@amd.com>
+
+[ Upstream commit d8cce9306801cfbf709055677f7896905094ff95 ]
+
+Remove unnecessary comments, enable restore mode using
+'|=' operator, fixes the alignment to improve the code
+readability.
+
+v2: Move all restoration flag check to bitwise '&' operator
+
+Signed-off-by: Arunpravin <Arunpravin.PaneerSelvam@amd.com>
+Reviewed-by: Evan Quan <evan.quan@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 34 ++++++++---------------
+ 1 file changed, 12 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+index cd905e41080e..42c4dbe3e362 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+@@ -279,35 +279,25 @@ static void smu_set_user_clk_dependencies(struct smu_context *smu, enum smu_clk_
+       if (smu->adev->in_suspend)
+               return;
+-      /*
+-       * mclk, fclk and socclk are interdependent
+-       * on each other
+-       */
+       if (clk == SMU_MCLK) {
+-              /* reset clock dependency */
+               smu->user_dpm_profile.clk_dependency = 0;
+-              /* set mclk dependent clocks(fclk and socclk) */
+               smu->user_dpm_profile.clk_dependency = BIT(SMU_FCLK) | BIT(SMU_SOCCLK);
+       } else if (clk == SMU_FCLK) {
+-              /* give priority to mclk, if mclk dependent clocks are set */
++              /* MCLK takes precedence over FCLK */
+               if (smu->user_dpm_profile.clk_dependency == (BIT(SMU_FCLK) | BIT(SMU_SOCCLK)))
+                       return;
+-              /* reset clock dependency */
+               smu->user_dpm_profile.clk_dependency = 0;
+-              /* set fclk dependent clocks(mclk and socclk) */
+               smu->user_dpm_profile.clk_dependency = BIT(SMU_MCLK) | BIT(SMU_SOCCLK);
+       } else if (clk == SMU_SOCCLK) {
+-              /* give priority to mclk, if mclk dependent clocks are set */
++              /* MCLK takes precedence over SOCCLK */
+               if (smu->user_dpm_profile.clk_dependency == (BIT(SMU_FCLK) | BIT(SMU_SOCCLK)))
+                       return;
+-              /* reset clock dependency */
+               smu->user_dpm_profile.clk_dependency = 0;
+-              /* set socclk dependent clocks(mclk and fclk) */
+               smu->user_dpm_profile.clk_dependency = BIT(SMU_MCLK) | BIT(SMU_FCLK);
+       } else
+-              /* add clk dependencies here, if any */
++              /* Add clk dependencies here, if any */
+               return;
+ }
+@@ -331,7 +321,7 @@ static void smu_restore_dpm_user_profile(struct smu_context *smu)
+               return;
+       /* Enable restore flag */
+-      smu->user_dpm_profile.flags = SMU_DPM_USER_PROFILE_RESTORE;
++      smu->user_dpm_profile.flags |= SMU_DPM_USER_PROFILE_RESTORE;
+       /* set the user dpm power limit */
+       if (smu->user_dpm_profile.power_limit) {
+@@ -354,8 +344,8 @@ static void smu_restore_dpm_user_profile(struct smu_context *smu)
+                               ret = smu_force_clk_levels(smu, clk_type,
+                                               smu->user_dpm_profile.clk_mask[clk_type]);
+                               if (ret)
+-                                      dev_err(smu->adev->dev, "Failed to set clock type = %d\n",
+-                                                      clk_type);
++                                      dev_err(smu->adev->dev,
++                                              "Failed to set clock type = %d\n", clk_type);
+                       }
+               }
+       }
+@@ -1777,7 +1767,7 @@ int smu_force_clk_levels(struct smu_context *smu,
+       if (smu->ppt_funcs && smu->ppt_funcs->force_clk_levels) {
+               ret = smu->ppt_funcs->force_clk_levels(smu, clk_type, mask);
+-              if (!ret && smu->user_dpm_profile.flags != SMU_DPM_USER_PROFILE_RESTORE) {
++              if (!ret && !(smu->user_dpm_profile.flags & SMU_DPM_USER_PROFILE_RESTORE)) {
+                       smu->user_dpm_profile.clk_mask[clk_type] = mask;
+                       smu_set_user_clk_dependencies(smu, clk_type);
+               }
+@@ -2034,7 +2024,7 @@ int smu_set_fan_speed_rpm(struct smu_context *smu, uint32_t speed)
+       if (smu->ppt_funcs->set_fan_speed_percent) {
+               percent = speed * 100 / smu->fan_max_rpm;
+               ret = smu->ppt_funcs->set_fan_speed_percent(smu, percent);
+-              if (!ret && smu->user_dpm_profile.flags != SMU_DPM_USER_PROFILE_RESTORE)
++              if (!ret && !(smu->user_dpm_profile.flags & SMU_DPM_USER_PROFILE_RESTORE))
+                       smu->user_dpm_profile.fan_speed_percent = percent;
+       }
+@@ -2104,7 +2094,7 @@ int smu_set_power_limit(struct smu_context *smu, uint32_t limit)
+       if (smu->ppt_funcs->set_power_limit) {
+               ret = smu->ppt_funcs->set_power_limit(smu, limit);
+-              if (!ret && smu->user_dpm_profile.flags != SMU_DPM_USER_PROFILE_RESTORE)
++              if (!ret && !(smu->user_dpm_profile.flags & SMU_DPM_USER_PROFILE_RESTORE))
+                       smu->user_dpm_profile.power_limit = limit;
+       }
+@@ -2285,7 +2275,7 @@ int smu_set_fan_control_mode(struct smu_context *smu, int value)
+       if (smu->ppt_funcs->set_fan_control_mode) {
+               ret = smu->ppt_funcs->set_fan_control_mode(smu, value);
+-              if (!ret && smu->user_dpm_profile.flags != SMU_DPM_USER_PROFILE_RESTORE)
++              if (!ret && !(smu->user_dpm_profile.flags & SMU_DPM_USER_PROFILE_RESTORE))
+                       smu->user_dpm_profile.fan_mode = value;
+       }
+@@ -2293,7 +2283,7 @@ int smu_set_fan_control_mode(struct smu_context *smu, int value)
+       /* reset user dpm fan speed */
+       if (!ret && value != AMD_FAN_CTRL_MANUAL &&
+-                      smu->user_dpm_profile.flags != SMU_DPM_USER_PROFILE_RESTORE)
++                      !(smu->user_dpm_profile.flags & SMU_DPM_USER_PROFILE_RESTORE))
+               smu->user_dpm_profile.fan_speed_percent = 0;
+       return ret;
+@@ -2335,7 +2325,7 @@ int smu_set_fan_speed_percent(struct smu_context *smu, uint32_t speed)
+               if (speed > 100)
+                       speed = 100;
+               ret = smu->ppt_funcs->set_fan_speed_percent(smu, speed);
+-              if (!ret && smu->user_dpm_profile.flags != SMU_DPM_USER_PROFILE_RESTORE)
++              if (!ret && !(smu->user_dpm_profile.flags & SMU_DPM_USER_PROFILE_RESTORE))
+                       smu->user_dpm_profile.fan_speed_percent = speed;
+       }
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-amdgpu-display-buffer-interrupt_low_irq_context-.patch b/queue-5.12/drm-amdgpu-display-buffer-interrupt_low_irq_context-.patch
new file mode 100644 (file)
index 0000000..b0e9a35
--- /dev/null
@@ -0,0 +1,290 @@
+From b80dedde764327c338cbca7117c5d7f0cfbfdcd5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Feb 2021 12:06:34 -0500
+Subject: drm/amdgpu/display: buffer INTERRUPT_LOW_IRQ_CONTEXT interrupt work
+
+From: Xiaogang Chen <xiaogang.chen@amd.com>
+
+[ Upstream commit b6f91fc183f758461b9462cc93e673adbbf95c2d ]
+
+amdgpu DM handles INTERRUPT_LOW_IRQ_CONTEXT interrupt(hpd, hpd_rx) by using work
+queue and uses single work_struct. If new interrupt is recevied before the
+previous handler finished, new interrupts(same type) will be discarded and
+driver just sends "amdgpu_dm_irq_schedule_work FAILED" message out. If some
+important hpd, hpd_rx related interrupts are missed by driver the hot (un)plug
+devices may cause system hang or instability, such as issues with system
+resume from S3 sleep with mst device connected.
+
+This patch dynamically allocates new amdgpu_dm_irq_handler_data for new
+interrupts if previous INTERRUPT_LOW_IRQ_CONTEXT interrupt work has not been
+handled. So the new interrupt works can be queued to the same workqueue_struct,
+instead of discard the new interrupts. All allocated amdgpu_dm_irq_handler_data
+are put into a single linked list and will be reused after.
+
+Signed-off-by: Xiaogang Chen <xiaogang.chen@amd.com>
+Reviewed-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  14 +--
+ .../drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c | 115 ++++++++++++------
+ 2 files changed, 80 insertions(+), 49 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+index 8bfe901cf237..52cc81705280 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+@@ -68,18 +68,6 @@ struct common_irq_params {
+       enum dc_irq_source irq_src;
+ };
+-/**
+- * struct irq_list_head - Linked-list for low context IRQ handlers.
+- *
+- * @head: The list_head within &struct handler_data
+- * @work: A work_struct containing the deferred handler work
+- */
+-struct irq_list_head {
+-      struct list_head head;
+-      /* In case this interrupt needs post-processing, 'work' will be queued*/
+-      struct work_struct work;
+-};
+-
+ /**
+  * struct dm_compressor_info - Buffer info used by frame buffer compression
+  * @cpu_addr: MMIO cpu addr
+@@ -293,7 +281,7 @@ struct amdgpu_display_manager {
+        * Note that handlers are called in the same order as they were
+        * registered (FIFO).
+        */
+-      struct irq_list_head irq_handler_list_low_tab[DAL_IRQ_SOURCES_NUMBER];
++      struct list_head irq_handler_list_low_tab[DAL_IRQ_SOURCES_NUMBER];
+       /**
+        * @irq_handler_list_high_tab:
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
+index e0000c180ed1..8ce10d0973c5 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
+@@ -82,6 +82,7 @@ struct amdgpu_dm_irq_handler_data {
+       struct amdgpu_display_manager *dm;
+       /* DAL irq source which registered for this interrupt. */
+       enum dc_irq_source irq_source;
++      struct work_struct work;
+ };
+ #define DM_IRQ_TABLE_LOCK(adev, flags) \
+@@ -111,20 +112,10 @@ static void init_handler_common_data(struct amdgpu_dm_irq_handler_data *hcd,
+  */
+ static void dm_irq_work_func(struct work_struct *work)
+ {
+-      struct irq_list_head *irq_list_head =
+-              container_of(work, struct irq_list_head, work);
+-      struct list_head *handler_list = &irq_list_head->head;
+-      struct amdgpu_dm_irq_handler_data *handler_data;
+-
+-      list_for_each_entry(handler_data, handler_list, list) {
+-              DRM_DEBUG_KMS("DM_IRQ: work_func: for dal_src=%d\n",
+-                              handler_data->irq_source);
++      struct amdgpu_dm_irq_handler_data *handler_data =
++              container_of(work, struct amdgpu_dm_irq_handler_data, work);
+-              DRM_DEBUG_KMS("DM_IRQ: schedule_work: for dal_src=%d\n",
+-                      handler_data->irq_source);
+-
+-              handler_data->handler(handler_data->handler_arg);
+-      }
++      handler_data->handler(handler_data->handler_arg);
+       /* Call a DAL subcomponent which registered for interrupt notification
+        * at INTERRUPT_LOW_IRQ_CONTEXT.
+@@ -156,7 +147,7 @@ static struct list_head *remove_irq_handler(struct amdgpu_device *adev,
+               break;
+       case INTERRUPT_LOW_IRQ_CONTEXT:
+       default:
+-              hnd_list = &adev->dm.irq_handler_list_low_tab[irq_source].head;
++              hnd_list = &adev->dm.irq_handler_list_low_tab[irq_source];
+               break;
+       }
+@@ -290,7 +281,8 @@ void *amdgpu_dm_irq_register_interrupt(struct amdgpu_device *adev,
+               break;
+       case INTERRUPT_LOW_IRQ_CONTEXT:
+       default:
+-              hnd_list = &adev->dm.irq_handler_list_low_tab[irq_source].head;
++              hnd_list = &adev->dm.irq_handler_list_low_tab[irq_source];
++              INIT_WORK(&handler_data->work, dm_irq_work_func);
+               break;
+       }
+@@ -372,7 +364,7 @@ void amdgpu_dm_irq_unregister_interrupt(struct amdgpu_device *adev,
+ int amdgpu_dm_irq_init(struct amdgpu_device *adev)
+ {
+       int src;
+-      struct irq_list_head *lh;
++      struct list_head *lh;
+       DRM_DEBUG_KMS("DM_IRQ\n");
+@@ -381,9 +373,7 @@ int amdgpu_dm_irq_init(struct amdgpu_device *adev)
+       for (src = 0; src < DAL_IRQ_SOURCES_NUMBER; src++) {
+               /* low context handler list init */
+               lh = &adev->dm.irq_handler_list_low_tab[src];
+-              INIT_LIST_HEAD(&lh->head);
+-              INIT_WORK(&lh->work, dm_irq_work_func);
+-
++              INIT_LIST_HEAD(lh);
+               /* high context handler init */
+               INIT_LIST_HEAD(&adev->dm.irq_handler_list_high_tab[src]);
+       }
+@@ -400,8 +390,11 @@ int amdgpu_dm_irq_init(struct amdgpu_device *adev)
+ void amdgpu_dm_irq_fini(struct amdgpu_device *adev)
+ {
+       int src;
+-      struct irq_list_head *lh;
++      struct list_head *lh;
++      struct list_head *entry, *tmp;
++      struct amdgpu_dm_irq_handler_data *handler;
+       unsigned long irq_table_flags;
++
+       DRM_DEBUG_KMS("DM_IRQ: releasing resources.\n");
+       for (src = 0; src < DAL_IRQ_SOURCES_NUMBER; src++) {
+               DM_IRQ_TABLE_LOCK(adev, irq_table_flags);
+@@ -410,7 +403,16 @@ void amdgpu_dm_irq_fini(struct amdgpu_device *adev)
+                * (because no code can schedule a new one). */
+               lh = &adev->dm.irq_handler_list_low_tab[src];
+               DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags);
+-              flush_work(&lh->work);
++
++              if (!list_empty(lh)) {
++                      list_for_each_safe(entry, tmp, lh) {
++                              handler = list_entry(
++                                      entry,
++                                      struct amdgpu_dm_irq_handler_data,
++                                      list);
++                              flush_work(&handler->work);
++                      }
++              }
+       }
+ }
+@@ -420,6 +422,8 @@ int amdgpu_dm_irq_suspend(struct amdgpu_device *adev)
+       struct list_head *hnd_list_h;
+       struct list_head *hnd_list_l;
+       unsigned long irq_table_flags;
++      struct list_head *entry, *tmp;
++      struct amdgpu_dm_irq_handler_data *handler;
+       DM_IRQ_TABLE_LOCK(adev, irq_table_flags);
+@@ -430,14 +434,22 @@ int amdgpu_dm_irq_suspend(struct amdgpu_device *adev)
+        * will be disabled from manage_dm_interrupts on disable CRTC.
+        */
+       for (src = DC_IRQ_SOURCE_HPD1; src <= DC_IRQ_SOURCE_HPD6RX; src++) {
+-              hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head;
++              hnd_list_l = &adev->dm.irq_handler_list_low_tab[src];
+               hnd_list_h = &adev->dm.irq_handler_list_high_tab[src];
+               if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h))
+                       dc_interrupt_set(adev->dm.dc, src, false);
+               DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags);
+-              flush_work(&adev->dm.irq_handler_list_low_tab[src].work);
++              if (!list_empty(hnd_list_l)) {
++                      list_for_each_safe (entry, tmp, hnd_list_l) {
++                              handler = list_entry(
++                                      entry,
++                                      struct amdgpu_dm_irq_handler_data,
++                                      list);
++                              flush_work(&handler->work);
++                      }
++              }
+               DM_IRQ_TABLE_LOCK(adev, irq_table_flags);
+       }
+@@ -457,7 +469,7 @@ int amdgpu_dm_irq_resume_early(struct amdgpu_device *adev)
+       /* re-enable short pulse interrupts HW interrupt */
+       for (src = DC_IRQ_SOURCE_HPD1RX; src <= DC_IRQ_SOURCE_HPD6RX; src++) {
+-              hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head;
++              hnd_list_l = &adev->dm.irq_handler_list_low_tab[src];
+               hnd_list_h = &adev->dm.irq_handler_list_high_tab[src];
+               if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h))
+                       dc_interrupt_set(adev->dm.dc, src, true);
+@@ -483,7 +495,7 @@ int amdgpu_dm_irq_resume_late(struct amdgpu_device *adev)
+        * will be enabled from manage_dm_interrupts on enable CRTC.
+        */
+       for (src = DC_IRQ_SOURCE_HPD1; src <= DC_IRQ_SOURCE_HPD6; src++) {
+-              hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head;
++              hnd_list_l = &adev->dm.irq_handler_list_low_tab[src];
+               hnd_list_h = &adev->dm.irq_handler_list_high_tab[src];
+               if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h))
+                       dc_interrupt_set(adev->dm.dc, src, true);
+@@ -500,22 +512,53 @@ int amdgpu_dm_irq_resume_late(struct amdgpu_device *adev)
+ static void amdgpu_dm_irq_schedule_work(struct amdgpu_device *adev,
+                                       enum dc_irq_source irq_source)
+ {
+-      unsigned long irq_table_flags;
+-      struct work_struct *work = NULL;
++      struct  list_head *handler_list = &adev->dm.irq_handler_list_low_tab[irq_source];
++      struct  amdgpu_dm_irq_handler_data *handler_data;
++      bool    work_queued = false;
+-      DM_IRQ_TABLE_LOCK(adev, irq_table_flags);
++      if (list_empty(handler_list))
++              return;
++
++      list_for_each_entry (handler_data, handler_list, list) {
++              if (!queue_work(system_highpri_wq, &handler_data->work)) {
++                      continue;
++              } else {
++                      work_queued = true;
++                      break;
++              }
++      }
+-      if (!list_empty(&adev->dm.irq_handler_list_low_tab[irq_source].head))
+-              work = &adev->dm.irq_handler_list_low_tab[irq_source].work;
++      if (!work_queued) {
++              struct  amdgpu_dm_irq_handler_data *handler_data_add;
++              /*get the amdgpu_dm_irq_handler_data of first item pointed by handler_list*/
++              handler_data = container_of(handler_list->next, struct amdgpu_dm_irq_handler_data, list);
+-      DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags);
++              /*allocate a new amdgpu_dm_irq_handler_data*/
++              handler_data_add = kzalloc(sizeof(*handler_data), GFP_KERNEL);
++              if (!handler_data_add) {
++                      DRM_ERROR("DM_IRQ: failed to allocate irq handler!\n");
++                      return;
++              }
+-      if (work) {
+-              if (!schedule_work(work))
+-                      DRM_INFO("amdgpu_dm_irq_schedule_work FAILED src %d\n",
+-                                              irq_source);
+-      }
++              /*copy new amdgpu_dm_irq_handler_data members from handler_data*/
++              handler_data_add->handler       = handler_data->handler;
++              handler_data_add->handler_arg   = handler_data->handler_arg;
++              handler_data_add->dm            = handler_data->dm;
++              handler_data_add->irq_source    = irq_source;
++              list_add_tail(&handler_data_add->list, handler_list);
++
++              INIT_WORK(&handler_data_add->work, dm_irq_work_func);
++
++              if (queue_work(system_highpri_wq, &handler_data_add->work))
++                      DRM_DEBUG("Queued work for handling interrupt from "
++                                "display for IRQ source %d\n",
++                                irq_source);
++              else
++                      DRM_ERROR("Failed to queue work for handling interrupt "
++                                "from display for IRQ source %d\n",
++                                irq_source);
++      }
+ }
+ /*
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-amdgpu-display-fix-memory-leak-for-dimgrey-cavef.patch b/queue-5.12/drm-amdgpu-display-fix-memory-leak-for-dimgrey-cavef.patch
new file mode 100644 (file)
index 0000000..f504f7b
--- /dev/null
@@ -0,0 +1,35 @@
+From 13ca4c46c48792efa3a4181d0e59a279e1d93d8c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Mar 2021 12:59:26 -0400
+Subject: drm/amdgpu/display: fix memory leak for dimgrey cavefish
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit 42b599732ee1d4ac742760050603fb6046789011 ]
+
+We need to clean up the dcn3 clk_mgr.
+
+Acked-by: Nirmoy Das <nirmoy.das@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
+index 995ffbbf64e7..1ee27f2f28f1 100644
+--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
+@@ -217,6 +217,9 @@ void dc_destroy_clk_mgr(struct clk_mgr *clk_mgr_base)
+               if (ASICREV_IS_SIENNA_CICHLID_P(clk_mgr_base->ctx->asic_id.hw_internal_rev)) {
+                       dcn3_clk_mgr_destroy(clk_mgr);
+               }
++              if (ASICREV_IS_DIMGREY_CAVEFISH_P(clk_mgr_base->ctx->asic_id.hw_internal_rev)) {
++                      dcn3_clk_mgr_destroy(clk_mgr);
++              }
+               break;
+       case FAMILY_VGH:
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-amdgpu-enable-48-bit-ih-timestamp-counter.patch b/queue-5.12/drm-amdgpu-enable-48-bit-ih-timestamp-counter.patch
new file mode 100644 (file)
index 0000000..ff675bd
--- /dev/null
@@ -0,0 +1,36 @@
+From 598aaa47c22826e2026a329b15ecda7741b38051 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jan 2021 17:03:18 -0600
+Subject: drm/amdgpu: enable 48-bit IH timestamp counter
+
+From: Alex Sierra <alex.sierra@amd.com>
+
+[ Upstream commit 9a9c59a8f4f4478d5951eb0bded1d17b936aad6e ]
+
+By default this timestamp is 32 bit counter. It gets
+overflowed in around 10 minutes.
+
+Signed-off-by: Alex Sierra <alex.sierra@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/vega20_ih.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/vega20_ih.c b/drivers/gpu/drm/amd/amdgpu/vega20_ih.c
+index 75b06e1964ab..86dcf448e0c2 100644
+--- a/drivers/gpu/drm/amd/amdgpu/vega20_ih.c
++++ b/drivers/gpu/drm/amd/amdgpu/vega20_ih.c
+@@ -104,6 +104,8 @@ static int vega20_ih_toggle_ring_interrupts(struct amdgpu_device *adev,
+       tmp = RREG32(ih_regs->ih_rb_cntl);
+       tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_ENABLE, (enable ? 1 : 0));
++      tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_GPU_TS_ENABLE, 1);
++
+       /* enable_intr field is only valid in ring0 */
+       if (ih == &adev->irq.ih)
+               tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, ENABLE_INTR, (enable ? 1 : 0));
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-amdgpu-enable-retry-fault-wptr-overflow.patch b/queue-5.12/drm-amdgpu-enable-retry-fault-wptr-overflow.patch
new file mode 100644 (file)
index 0000000..a8f1310
--- /dev/null
@@ -0,0 +1,191 @@
+From b1117435bce79a8ce233996749bc50e636eb196e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Sep 2020 13:09:33 -0400
+Subject: drm/amdgpu: enable retry fault wptr overflow
+
+From: Philip Yang <Philip.Yang@amd.com>
+
+[ Upstream commit b672cb1eee59efe6ca5bb2a2ce90060a22860558 ]
+
+If xnack is on, VM retry fault interrupt send to IH ring1, and ring1
+will be full quickly. IH cannot receive other interrupts, this causes
+deadlock if migrating buffer using sdma and waiting for sdma done while
+handling retry fault.
+
+Remove VMC from IH storm client, enable ring1 write pointer overflow,
+then IH will drop retry fault interrupts and be able to receive other
+interrupts while driver is handling retry fault.
+
+IH ring1 write pointer doesn't writeback to memory by IH, and ring1
+write pointer recorded by self-irq is not updated, so always read
+the latest ring1 write pointer from register.
+
+Signed-off-by: Philip Yang <Philip.Yang@amd.com>
+Signed-off-by: Felix Kuehling <Felix.Kuehling@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/vega10_ih.c | 32 +++++++++-----------------
+ drivers/gpu/drm/amd/amdgpu/vega20_ih.c | 32 +++++++++-----------------
+ 2 files changed, 22 insertions(+), 42 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
+index 88626d83e07b..ca8efa5c6978 100644
+--- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
++++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
+@@ -220,10 +220,8 @@ static int vega10_ih_enable_ring(struct amdgpu_device *adev,
+       tmp = vega10_ih_rb_cntl(ih, tmp);
+       if (ih == &adev->irq.ih)
+               tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RPTR_REARM, !!adev->irq.msi_enabled);
+-      if (ih == &adev->irq.ih1) {
+-              tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_ENABLE, 0);
++      if (ih == &adev->irq.ih1)
+               tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_FULL_DRAIN_ENABLE, 1);
+-      }
+       if (amdgpu_sriov_vf(adev)) {
+               if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp)) {
+                       dev_err(adev->dev, "PSP program IH_RB_CNTL failed!\n");
+@@ -265,7 +263,6 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev)
+       u32 ih_chicken;
+       int ret;
+       int i;
+-      u32 tmp;
+       /* disable irqs */
+       ret = vega10_ih_toggle_interrupts(adev, false);
+@@ -291,15 +288,6 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev)
+               }
+       }
+-      tmp = RREG32_SOC15(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL);
+-      tmp = REG_SET_FIELD(tmp, IH_STORM_CLIENT_LIST_CNTL,
+-                          CLIENT18_IS_STORM_CLIENT, 1);
+-      WREG32_SOC15(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL, tmp);
+-
+-      tmp = RREG32_SOC15(OSSSYS, 0, mmIH_INT_FLOOD_CNTL);
+-      tmp = REG_SET_FIELD(tmp, IH_INT_FLOOD_CNTL, FLOOD_CNTL_ENABLE, 1);
+-      WREG32_SOC15(OSSSYS, 0, mmIH_INT_FLOOD_CNTL, tmp);
+-
+       pci_set_master(adev->pdev);
+       /* enable interrupts */
+@@ -345,11 +333,17 @@ static u32 vega10_ih_get_wptr(struct amdgpu_device *adev,
+       u32 wptr, tmp;
+       struct amdgpu_ih_regs *ih_regs;
+-      wptr = le32_to_cpu(*ih->wptr_cpu);
+-      ih_regs = &ih->ih_regs;
++      if (ih == &adev->irq.ih) {
++              /* Only ring0 supports writeback. On other rings fall back
++               * to register-based code with overflow checking below.
++               */
++              wptr = le32_to_cpu(*ih->wptr_cpu);
+-      if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW))
+-              goto out;
++              if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW))
++                      goto out;
++      }
++
++      ih_regs = &ih->ih_regs;
+       /* Double check that the overflow wasn't already cleared. */
+       wptr = RREG32_NO_KIQ(ih_regs->ih_rb_wptr);
+@@ -440,15 +434,11 @@ static int vega10_ih_self_irq(struct amdgpu_device *adev,
+                             struct amdgpu_irq_src *source,
+                             struct amdgpu_iv_entry *entry)
+ {
+-      uint32_t wptr = cpu_to_le32(entry->src_data[0]);
+-
+       switch (entry->ring_id) {
+       case 1:
+-              *adev->irq.ih1.wptr_cpu = wptr;
+               schedule_work(&adev->irq.ih1_work);
+               break;
+       case 2:
+-              *adev->irq.ih2.wptr_cpu = wptr;
+               schedule_work(&adev->irq.ih2_work);
+               break;
+       default: break;
+diff --git a/drivers/gpu/drm/amd/amdgpu/vega20_ih.c b/drivers/gpu/drm/amd/amdgpu/vega20_ih.c
+index 5a3c867d5881..75b06e1964ab 100644
+--- a/drivers/gpu/drm/amd/amdgpu/vega20_ih.c
++++ b/drivers/gpu/drm/amd/amdgpu/vega20_ih.c
+@@ -220,10 +220,8 @@ static int vega20_ih_enable_ring(struct amdgpu_device *adev,
+       tmp = vega20_ih_rb_cntl(ih, tmp);
+       if (ih == &adev->irq.ih)
+               tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RPTR_REARM, !!adev->irq.msi_enabled);
+-      if (ih == &adev->irq.ih1) {
+-              tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_ENABLE, 0);
++      if (ih == &adev->irq.ih1)
+               tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_FULL_DRAIN_ENABLE, 1);
+-      }
+       if (amdgpu_sriov_vf(adev)) {
+               if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp)) {
+                       dev_err(adev->dev, "PSP program IH_RB_CNTL failed!\n");
+@@ -297,7 +295,6 @@ static int vega20_ih_irq_init(struct amdgpu_device *adev)
+       u32 ih_chicken;
+       int ret;
+       int i;
+-      u32 tmp;
+       /* disable irqs */
+       ret = vega20_ih_toggle_interrupts(adev, false);
+@@ -326,15 +323,6 @@ static int vega20_ih_irq_init(struct amdgpu_device *adev)
+               }
+       }
+-      tmp = RREG32_SOC15(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL);
+-      tmp = REG_SET_FIELD(tmp, IH_STORM_CLIENT_LIST_CNTL,
+-                          CLIENT18_IS_STORM_CLIENT, 1);
+-      WREG32_SOC15(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL, tmp);
+-
+-      tmp = RREG32_SOC15(OSSSYS, 0, mmIH_INT_FLOOD_CNTL);
+-      tmp = REG_SET_FIELD(tmp, IH_INT_FLOOD_CNTL, FLOOD_CNTL_ENABLE, 1);
+-      WREG32_SOC15(OSSSYS, 0, mmIH_INT_FLOOD_CNTL, tmp);
+-
+       pci_set_master(adev->pdev);
+       /* enable interrupts */
+@@ -380,11 +368,17 @@ static u32 vega20_ih_get_wptr(struct amdgpu_device *adev,
+       u32 wptr, tmp;
+       struct amdgpu_ih_regs *ih_regs;
+-      wptr = le32_to_cpu(*ih->wptr_cpu);
+-      ih_regs = &ih->ih_regs;
++      if (ih == &adev->irq.ih) {
++              /* Only ring0 supports writeback. On other rings fall back
++               * to register-based code with overflow checking below.
++               */
++              wptr = le32_to_cpu(*ih->wptr_cpu);
+-      if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW))
+-              goto out;
++              if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW))
++                      goto out;
++      }
++
++      ih_regs = &ih->ih_regs;
+       /* Double check that the overflow wasn't already cleared. */
+       wptr = RREG32_NO_KIQ(ih_regs->ih_rb_wptr);
+@@ -476,15 +470,11 @@ static int vega20_ih_self_irq(struct amdgpu_device *adev,
+                             struct amdgpu_irq_src *source,
+                             struct amdgpu_iv_entry *entry)
+ {
+-      uint32_t wptr = cpu_to_le32(entry->src_data[0]);
+-
+       switch (entry->ring_id) {
+       case 1:
+-              *adev->irq.ih1.wptr_cpu = wptr;
+               schedule_work(&adev->irq.ih1_work);
+               break;
+       case 2:
+-              *adev->irq.ih2.wptr_cpu = wptr;
+               schedule_work(&adev->irq.ih2_work);
+               break;
+       default: break;
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-amdgpu-fix-asic-reset-regression-issue-introduce.patch b/queue-5.12/drm-amdgpu-fix-asic-reset-regression-issue-introduce.patch
new file mode 100644 (file)
index 0000000..4fab8c5
--- /dev/null
@@ -0,0 +1,37 @@
+From ac9ae6af78d71e1731cd1450c0e7c13b9edc15d1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Mar 2021 10:30:15 -0500
+Subject: drm/amdgpu : Fix asic reset regression issue introduce by
+ 8f211fe8ac7c4f
+
+From: shaoyunl <shaoyun.liu@amd.com>
+
+[ Upstream commit c8941550aa66b2a90f4b32c45d59e8571e33336e ]
+
+This recent change introduce SDMA interrupt info printing with irq->process function.
+These functions do not require a set function to enable/disable the irq
+
+Signed-off-by: shaoyunl <shaoyun.liu@amd.com>
+Reviewed-by: Hawking Zhang <Hawking.Zhang@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_irq.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
+index afbbec82a289..9be945d8e72f 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
+@@ -535,7 +535,7 @@ void amdgpu_irq_gpu_reset_resume_helper(struct amdgpu_device *adev)
+               for (j = 0; j < AMDGPU_MAX_IRQ_SRC_ID; ++j) {
+                       struct amdgpu_irq_src *src = adev->irq.client[i].sources[j];
+-                      if (!src)
++                      if (!src || !src->funcs || !src->funcs->set)
+                               continue;
+                       for (k = 0; k < src->num_types; k++)
+                               amdgpu_irq_update(adev, src, k);
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-amdgpu-fix-memory-leak.patch b/queue-5.12/drm-amdgpu-fix-memory-leak.patch
new file mode 100644 (file)
index 0000000..e655c3c
--- /dev/null
@@ -0,0 +1,51 @@
+From ff844105788999cf8e51e9848edda2f359687b5d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Mar 2021 17:33:02 +0800
+Subject: drm/amdgpu: Fix memory leak
+
+From: xinhui pan <xinhui.pan@amd.com>
+
+[ Upstream commit 79fcd446e7e182c52c2c808c76f8de3eb6714349 ]
+
+drm_gem_object_put() should be paired with drm_gem_object_lookup().
+
+All gem objs are saved in fb->base.obj[]. Need put the old first before
+assign a new obj.
+
+Trigger VRAM leak by running command below
+$ service gdm restart
+
+Signed-off-by: xinhui pan <xinhui.pan@amd.com>
+Acked-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+index f753e04fee99..cbe050436c7b 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+@@ -910,8 +910,9 @@ int amdgpu_display_framebuffer_init(struct drm_device *dev,
+       }
+       for (i = 1; i < rfb->base.format->num_planes; ++i) {
++              drm_gem_object_get(rfb->base.obj[0]);
++              drm_gem_object_put(rfb->base.obj[i]);
+               rfb->base.obj[i] = rfb->base.obj[0];
+-              drm_gem_object_get(rfb->base.obj[i]);
+       }
+       return 0;
+@@ -960,6 +961,7 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev,
+               return ERR_PTR(ret);
+       }
++      drm_gem_object_put(obj);
+       return &amdgpu_fb->base;
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-amdgpu-fix-null-pointer-dereference.patch b/queue-5.12/drm-amdgpu-fix-null-pointer-dereference.patch
new file mode 100644 (file)
index 0000000..804928c
--- /dev/null
@@ -0,0 +1,60 @@
+From 8678da45711f99941799c807f01260fda7a4a7ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 Mar 2021 17:52:18 +0800
+Subject: drm/amdgpu: fix NULL pointer dereference
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Guchun Chen <guchun.chen@amd.com>
+
+[ Upstream commit 3c3dc654333f6389803cdcaf03912e94173ae510 ]
+
+ttm->sg needs to be checked before accessing its child member.
+
+Call Trace:
+ amdgpu_ttm_backend_destroy+0x12/0x70 [amdgpu]
+ ttm_bo_cleanup_memtype_use+0x3a/0x60 [ttm]
+ ttm_bo_release+0x17d/0x300 [ttm]
+ amdgpu_bo_unref+0x1a/0x30 [amdgpu]
+ amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu+0x78b/0x8b0 [amdgpu]
+ kfd_ioctl_alloc_memory_of_gpu+0x118/0x220 [amdgpu]
+ kfd_ioctl+0x222/0x400 [amdgpu]
+ ? kfd_dev_is_large_bar+0x90/0x90 [amdgpu]
+ __x64_sys_ioctl+0x8e/0xd0
+ ? __context_tracking_exit+0x52/0x90
+ do_syscall_64+0x33/0x80
+ entry_SYSCALL_64_after_hwframe+0x44/0xa9
+RIP: 0033:0x7f97f264d317
+Code: b3 66 90 48 8b 05 71 4b 2d 00 64 c7 00 26 00 00 00 48 c7 c0 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 41 4b 2d 00 f7 d8 64 89 01 48
+RSP: 002b:00007ffdb402c338 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
+RAX: ffffffffffffffda RBX: 00007f97f3cc63a0 RCX: 00007f97f264d317
+RDX: 00007ffdb402c380 RSI: 00000000c0284b16 RDI: 0000000000000003
+RBP: 00007ffdb402c380 R08: 00007ffdb402c428 R09: 00000000c4000004
+R10: 00000000c4000004 R11: 0000000000000246 R12: 00000000c0284b16
+R13: 0000000000000003 R14: 00007f97f3cc63a0 R15: 00007f8836200000
+
+Signed-off-by: Guchun Chen <guchun.chen@amd.com>
+Acked-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+index f61fd2cf3fee..383c178cf074 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+@@ -942,7 +942,7 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_bo_device *bdev,
+               DMA_BIDIRECTIONAL : DMA_TO_DEVICE;
+       /* double check that we don't free the table twice */
+-      if (!ttm->sg->sgl)
++      if (!ttm->sg || !ttm->sg->sgl)
+               return;
+       /* unmap the pages mapped to the device */
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-amdgpu-fix-some-unload-driver-issues.patch b/queue-5.12/drm-amdgpu-fix-some-unload-driver-issues.patch
new file mode 100644 (file)
index 0000000..3e8f622
--- /dev/null
@@ -0,0 +1,64 @@
+From 9da59260f55b93b47077b119a552f1c076dfef7f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Mar 2021 19:30:51 +0800
+Subject: drm/amdgpu: Fix some unload driver issues
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Emily Deng <Emily.Deng@amd.com>
+
+[ Upstream commit bb0cd09be45ea457f25fdcbcb3d6cf2230f26c46 ]
+
+When unloading driver after killing some applications, it will hit sdma
+flush tlb job timeout which is called by ttm_bo_delay_delete. So
+to avoid the job submit after fence driver fini, call ttm_bo_lock_delayed_workqueue
+before fence driver fini. And also put drm_sched_fini before waiting fence.
+
+Signed-off-by: Emily Deng <Emily.Deng@amd.com>
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 1 +
+ drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c  | 5 +++--
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+index 8a5a8ff5d362..5eee251e3335 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -3613,6 +3613,7 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
+ {
+       dev_info(adev->dev, "amdgpu: finishing device.\n");
+       flush_delayed_work(&adev->delayed_init_work);
++      ttm_bo_lock_delayed_workqueue(&adev->mman.bdev);
+       adev->shutdown = true;
+       kfree(adev->pci_state);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
+index d56f4023ebb3..7e8e46c39dbd 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
+@@ -533,6 +533,8 @@ void amdgpu_fence_driver_fini(struct amdgpu_device *adev)
+               if (!ring || !ring->fence_drv.initialized)
+                       continue;
++              if (!ring->no_scheduler)
++                      drm_sched_fini(&ring->sched);
+               r = amdgpu_fence_wait_empty(ring);
+               if (r) {
+                       /* no need to trigger GPU reset as we are unloading */
+@@ -541,8 +543,7 @@ void amdgpu_fence_driver_fini(struct amdgpu_device *adev)
+               if (ring->fence_drv.irq_src)
+                       amdgpu_irq_put(adev, ring->fence_drv.irq_src,
+                                      ring->fence_drv.irq_type);
+-              if (!ring->no_scheduler)
+-                      drm_sched_fini(&ring->sched);
++
+               del_timer_sync(&ring->fence_drv.fallback_timer);
+               for (j = 0; j <= ring->fence_drv.num_fences_mask; ++j)
+                       dma_fence_put(ring->fence_drv.fences[j]);
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-amdgpu-mask-the-xgmi-number-of-hops-reported-fro.patch b/queue-5.12/drm-amdgpu-mask-the-xgmi-number-of-hops-reported-fro.patch
new file mode 100644 (file)
index 0000000..7163fee
--- /dev/null
@@ -0,0 +1,55 @@
+From 75d2bec6151b7ab0c331da6cd47985a271630096 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Jan 2021 15:24:59 -0500
+Subject: drm/amdgpu: mask the xgmi number of hops reported from psp to kfd
+
+From: Jonathan Kim <jonathan.kim@amd.com>
+
+[ Upstream commit 4ac5617c4b7d0f0a8f879997f8ceaa14636d7554 ]
+
+The psp supplies the link type in the upper 2 bits of the psp xgmi node
+information num_hops field.  With a new link type, Aldebaran has these
+bits set to a non-zero value (1 = xGMI3) so the KFD topology will report
+the incorrect IO link weights without proper masking.
+The actual number of hops is located in the 3 least significant bits of
+this field so mask if off accordingly before passing it to the KFD.
+
+Signed-off-by: Jonathan Kim <jonathan.kim@amd.com>
+Reviewed-by: Amber Lin <amber.lin@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_xgmi.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c
+index 659b385b27b5..4d3a24fdeb9c 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c
+@@ -468,15 +468,22 @@ int amdgpu_xgmi_update_topology(struct amdgpu_hive_info *hive, struct amdgpu_dev
+ }
++/*
++ * NOTE psp_xgmi_node_info.num_hops layout is as follows:
++ * num_hops[7:6] = link type (0 = xGMI2, 1 = xGMI3, 2/3 = reserved)
++ * num_hops[5:3] = reserved
++ * num_hops[2:0] = number of hops
++ */
+ int amdgpu_xgmi_get_hops_count(struct amdgpu_device *adev,
+               struct amdgpu_device *peer_adev)
+ {
+       struct psp_xgmi_topology_info *top = &adev->psp.xgmi_context.top_info;
++      uint8_t num_hops_mask = 0x7;
+       int i;
+       for (i = 0 ; i < top->num_nodes; ++i)
+               if (top->nodes[i].node_id == peer_adev->gmc.xgmi.node_id)
+-                      return top->nodes[i].num_hops;
++                      return top->nodes[i].num_hops & num_hops_mask;
+       return  -EINVAL;
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-amdgpu-ttm-fix-memory-leak-userptr-pages.patch b/queue-5.12/drm-amdgpu-ttm-fix-memory-leak-userptr-pages.patch
new file mode 100644 (file)
index 0000000..ffce4b8
--- /dev/null
@@ -0,0 +1,47 @@
+From cf0e20bfc4ec7349309dae964d80a4214786e0b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Mar 2021 17:08:37 +0100
+Subject: drm/amdgpu/ttm: Fix memory leak userptr pages
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Daniel Gomez <daniel@qtec.com>
+
+[ Upstream commit 0f6f9dd490d524930081a6ef1d60171ce39220b9 ]
+
+If userptr pages have been pinned but not bounded,
+they remain uncleared.
+
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Daniel Gomez <daniel@qtec.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+index 5efa331e3ee8..f61fd2cf3fee 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+@@ -1162,13 +1162,13 @@ static void amdgpu_ttm_backend_unbind(struct ttm_bo_device *bdev,
+       struct amdgpu_ttm_tt *gtt = (void *)ttm;
+       int r;
+-      if (!gtt->bound)
+-              return;
+-
+       /* if the pages have userptr pinning then clear that first */
+       if (gtt->userptr)
+               amdgpu_ttm_tt_unpin_userptr(bdev, ttm);
++      if (!gtt->bound)
++              return;
++
+       if (gtt->offset == AMDGPU_BO_INVALID_OFFSET)
+               return;
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-amdkfd-fix-cat-debugfs-hang_hws-file-causes-syst.patch b/queue-5.12/drm-amdkfd-fix-cat-debugfs-hang_hws-file-causes-syst.patch
new file mode 100644 (file)
index 0000000..feeb18d
--- /dev/null
@@ -0,0 +1,81 @@
+From 96b16d5363c65debcaf1345ebd809454dc4c95d2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 21 Mar 2021 16:28:18 +0800
+Subject: drm/amdkfd: Fix cat debugfs hang_hws file causes system crash bug
+
+From: Qu Huang <jinsdb@126.com>
+
+[ Upstream commit d73610211eec8aa027850982b1a48980aa1bc96e ]
+
+Here is the system crash log:
+[ 1272.884438] BUG: unable to handle kernel NULL pointer dereference at
+(null)
+[ 1272.884444] IP: [<          (null)>]           (null)
+[ 1272.884447] PGD 825b09067 PUD 8267c8067 PMD 0
+[ 1272.884452] Oops: 0010 [#1] SMP
+[ 1272.884509] CPU: 13 PID: 3485 Comm: cat Kdump: loaded Tainted: G
+[ 1272.884515] task: ffff9a38dbd4d140 ti: ffff9a37cd3b8000 task.ti:
+ffff9a37cd3b8000
+[ 1272.884517] RIP: 0010:[<0000000000000000>]  [<          (null)>]
+(null)
+[ 1272.884520] RSP: 0018:ffff9a37cd3bbe68  EFLAGS: 00010203
+[ 1272.884522] RAX: 0000000000000000 RBX: 0000000000000000 RCX:
+0000000000014d5f
+[ 1272.884524] RDX: fffffffffffffff4 RSI: 0000000000000001 RDI:
+ffff9a38aca4d200
+[ 1272.884526] RBP: ffff9a37cd3bbed0 R08: ffff9a38dcd5f1a0 R09:
+ffff9a31ffc07300
+[ 1272.884527] R10: ffff9a31ffc07300 R11: ffffffffaddd5e9d R12:
+ffff9a38b4e0fb00
+[ 1272.884529] R13: 0000000000000001 R14: ffff9a37cd3bbf18 R15:
+ffff9a38aca4d200
+[ 1272.884532] FS:  00007feccaa67740(0000) GS:ffff9a38dcd40000(0000)
+knlGS:0000000000000000
+[ 1272.884534] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 1272.884536] CR2: 0000000000000000 CR3: 00000008267c0000 CR4:
+00000000003407e0
+[ 1272.884537] Call Trace:
+[ 1272.884544]  [<ffffffffade68940>] ? seq_read+0x130/0x440
+[ 1272.884548]  [<ffffffffade40f8f>] vfs_read+0x9f/0x170
+[ 1272.884552]  [<ffffffffade41e4f>] SyS_read+0x7f/0xf0
+[ 1272.884557]  [<ffffffffae374ddb>] system_call_fastpath+0x22/0x27
+[ 1272.884558] Code:  Bad RIP value.
+[ 1272.884562] RIP  [<          (null)>]           (null)
+[ 1272.884564]  RSP <ffff9a37cd3bbe68>
+[ 1272.884566] CR2: 0000000000000000
+
+Signed-off-by: Qu Huang <jinsdb@126.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c b/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c
+index 511712c2e382..673d5e34f213 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c
+@@ -33,6 +33,11 @@ static int kfd_debugfs_open(struct inode *inode, struct file *file)
+       return single_open(file, show, NULL);
+ }
++static int kfd_debugfs_hang_hws_read(struct seq_file *m, void *data)
++{
++      seq_printf(m, "echo gpu_id > hang_hws\n");
++      return 0;
++}
+ static ssize_t kfd_debugfs_hang_hws_write(struct file *file,
+       const char __user *user_buf, size_t size, loff_t *ppos)
+@@ -94,7 +99,7 @@ void kfd_debugfs_init(void)
+       debugfs_create_file("rls", S_IFREG | 0444, debugfs_root,
+                           kfd_debugfs_rls_by_device, &kfd_debugfs_fops);
+       debugfs_create_file("hang_hws", S_IFREG | 0200, debugfs_root,
+-                          NULL, &kfd_debugfs_hang_hws_fops);
++                          kfd_debugfs_hang_hws_read, &kfd_debugfs_hang_hws_fops);
+ }
+ void kfd_debugfs_fini(void)
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-amdkfd-fix-ubsan-shift-out-of-bounds-warning.patch b/queue-5.12/drm-amdkfd-fix-ubsan-shift-out-of-bounds-warning.patch
new file mode 100644 (file)
index 0000000..4f1079e
--- /dev/null
@@ -0,0 +1,67 @@
+From 77c19766f062fa6b9fcc5c7d99a635e3f76ef99d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Mar 2021 12:33:15 -0500
+Subject: drm/amdkfd: Fix UBSAN shift-out-of-bounds warning
+
+From: Anson Jacob <Anson.Jacob@amd.com>
+
+[ Upstream commit 50e2fc36e72d4ad672032ebf646cecb48656efe0 ]
+
+If get_num_sdma_queues or get_num_xgmi_sdma_queues is 0, we end up
+doing a shift operation where the number of bits shifted equals
+number of bits in the operand. This behaviour is undefined.
+
+Set num_sdma_queues or num_xgmi_sdma_queues to ULLONG_MAX, if the
+count is >= number of bits in the operand.
+
+Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1472
+
+Reported-by: Lyude Paul <lyude@redhat.com>
+Signed-off-by: Anson Jacob <Anson.Jacob@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
+Tested-by: Lyude Paul <lyude@redhat.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../drm/amd/amdkfd/kfd_device_queue_manager.c   | 17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+index 4598a9a58125..a4266c4bca13 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+@@ -1128,6 +1128,9 @@ static int set_sched_resources(struct device_queue_manager *dqm)
+ static int initialize_cpsch(struct device_queue_manager *dqm)
+ {
++      uint64_t num_sdma_queues;
++      uint64_t num_xgmi_sdma_queues;
++
+       pr_debug("num of pipes: %d\n", get_pipes_per_mec(dqm));
+       mutex_init(&dqm->lock_hidden);
+@@ -1136,8 +1139,18 @@ static int initialize_cpsch(struct device_queue_manager *dqm)
+       dqm->active_cp_queue_count = 0;
+       dqm->gws_queue_count = 0;
+       dqm->active_runlist = false;
+-      dqm->sdma_bitmap = ~0ULL >> (64 - get_num_sdma_queues(dqm));
+-      dqm->xgmi_sdma_bitmap = ~0ULL >> (64 - get_num_xgmi_sdma_queues(dqm));
++
++      num_sdma_queues = get_num_sdma_queues(dqm);
++      if (num_sdma_queues >= BITS_PER_TYPE(dqm->sdma_bitmap))
++              dqm->sdma_bitmap = ULLONG_MAX;
++      else
++              dqm->sdma_bitmap = (BIT_ULL(num_sdma_queues) - 1);
++
++      num_xgmi_sdma_queues = get_num_xgmi_sdma_queues(dqm);
++      if (num_xgmi_sdma_queues >= BITS_PER_TYPE(dqm->xgmi_sdma_bitmap))
++              dqm->xgmi_sdma_bitmap = ULLONG_MAX;
++      else
++              dqm->xgmi_sdma_bitmap = (BIT_ULL(num_xgmi_sdma_queues) - 1);
+       INIT_WORK(&dqm->hw_exception_work, kfd_process_hw_exception);
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-ast-fix-invalid-usage-of-ast_max_hwc_width-in-cu.patch b/queue-5.12/drm-ast-fix-invalid-usage-of-ast_max_hwc_width-in-cu.patch
new file mode 100644 (file)
index 0000000..c01297e
--- /dev/null
@@ -0,0 +1,38 @@
+From 6a84e2985009d49ed27aa64ffa44cf9c593b286a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Feb 2021 14:46:24 +0100
+Subject: drm/ast: Fix invalid usage of AST_MAX_HWC_WIDTH in cursor
+ atomic_check
+
+From: Thomas Zimmermann <tzimmermann@suse.de>
+
+[ Upstream commit ee4a92d690f30f3793df942939726bec0338e65b ]
+
+Use AST_MAX_HWC_HEIGHT for setting offset_y in the cursor plane's
+atomic_check. The code used AST_MAX_HWC_WIDTH instead. This worked
+because both constants has the same value.
+
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Acked-by: Gerd Hoffmann <kraxel@redhat.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210209134632.12157-3-tzimmermann@suse.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/ast/ast_mode.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
+index 988b270fea5e..758c69aa7232 100644
+--- a/drivers/gpu/drm/ast/ast_mode.c
++++ b/drivers/gpu/drm/ast/ast_mode.c
+@@ -688,7 +688,7 @@ ast_cursor_plane_helper_atomic_update(struct drm_plane *plane,
+       unsigned int offset_x, offset_y;
+       offset_x = AST_MAX_HWC_WIDTH - fb->width;
+-      offset_y = AST_MAX_HWC_WIDTH - fb->height;
++      offset_y = AST_MAX_HWC_HEIGHT - fb->height;
+       if (state->fb != old_state->fb) {
+               /* A new cursor image was installed. */
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-ast-fix-memory-leak-when-unload-the-driver.patch b/queue-5.12/drm-ast-fix-memory-leak-when-unload-the-driver.patch
new file mode 100644 (file)
index 0000000..a1ad4f4
--- /dev/null
@@ -0,0 +1,93 @@
+From 17bf6e9e74028da67c69c05f29c1aec3733f1c26 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 21 Feb 2021 21:33:22 -0500
+Subject: drm/ast: fix memory leak when unload the driver
+
+From: Tong Zhang <ztong0001@gmail.com>
+
+[ Upstream commit dc739820ff90acccd013f6bb420222978a982791 ]
+
+a connector is leaked upon module unload, it seems that we should do
+similar to sample driver as suggested in drm_drv.c.
+
+Adding drm_atomic_helper_shutdown() in ast_pci_remove to prevent leaking.
+
+[  153.822134] WARNING: CPU: 0 PID: 173 at drivers/gpu/drm/drm_mode_config.c:504 drm_mode_config_cle0
+[  153.822698] Modules linked in: ast(-) drm_vram_helper drm_ttm_helper ttm [last unloaded: ttm]
+[  153.823197] CPU: 0 PID: 173 Comm: modprobe Tainted: G        W         5.11.0-03615-g55f62bc873474
+[  153.823708] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-48-gd9c812dda519-4
+[  153.824333] RIP: 0010:drm_mode_config_cleanup+0x418/0x470
+[  153.824637] Code: 0c 00 00 00 00 48 8b 84 24 a8 00 00 00 65 48 33 04 25 28 00 00 00 75 65 48 81 c0
+[  153.825668] RSP: 0018:ffff888103c9fb70 EFLAGS: 00010212
+[  153.825962] RAX: ffff888102b0d100 RBX: ffff888102b0c298 RCX: ffffffff818d8b2b
+[  153.826356] RDX: dffffc0000000000 RSI: 000000007fffffff RDI: ffff888102b0c298
+[  153.826748] RBP: ffff888103c9fba0 R08: 0000000000000001 R09: ffffed1020561857
+[  153.827146] R10: ffff888102b0c2b7 R11: ffffed1020561856 R12: ffff888102b0c000
+[  153.827538] R13: ffff888102b0c2d8 R14: ffff888102b0c2d8 R15: 1ffff11020793f70
+[  153.827935] FS:  00007f24bff456a0(0000) GS:ffff88815b400000(0000) knlGS:0000000000000000
+[  153.828380] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[  153.828697] CR2: 0000000001c39018 CR3: 0000000103c90000 CR4: 00000000000006f0
+[  153.829096] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+[  153.829486] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+[  153.829883] Call Trace:
+[  153.830024]  ? drmm_mode_config_init+0x930/0x930
+[  153.830281]  ? cpumask_next+0x16/0x20
+[  153.830488]  ? mnt_get_count+0x66/0x80
+[  153.830699]  ? drm_mode_config_cleanup+0x470/0x470
+[  153.830972]  drm_managed_release+0xed/0x1c0
+[  153.831208]  drm_dev_release+0x3a/0x50
+[  153.831420]  release_nodes+0x39e/0x410
+[  153.831631]  ? devres_release+0x40/0x40
+[  153.831852]  device_release_driver_internal+0x158/0x270
+[  153.832143]  driver_detach+0x76/0xe0
+[  153.832344]  bus_remove_driver+0x7e/0x100
+[  153.832568]  pci_unregister_driver+0x28/0xf0
+[  153.832821]  __x64_sys_delete_module+0x268/0x300
+[  153.833086]  ? __ia32_sys_delete_module+0x300/0x300
+[  153.833357]  ? call_rcu+0x372/0x4f0
+[  153.833553]  ? fpregs_assert_state_consistent+0x4d/0x60
+[  153.833840]  ? exit_to_user_mode_prepare+0x2f/0x130
+[  153.834118]  do_syscall_64+0x33/0x40
+[  153.834317]  entry_SYSCALL_64_after_hwframe+0x44/0xae
+[  153.834597] RIP: 0033:0x7f24bfec7cf7
+[  153.834797] Code: 48 89 57 30 48 8b 04 24 48 89 47 38 e9 1d a0 02 00 48 89 f8 48 89 f7 48 89 d6 41
+[  153.835812] RSP: 002b:00007fff72e6cb58 EFLAGS: 00000202 ORIG_RAX: 00000000000000b0
+[  153.836234] RAX: ffffffffffffffda RBX: 00007f24bff45690 RCX: 00007f24bfec7cf7
+[  153.836623] RDX: 00000000ffffffff RSI: 0000000000000080 RDI: 0000000001c2fb10
+[  153.837018] RBP: 0000000001c2fac0 R08: 2f2f2f2f2f2f2f2f R09: 0000000001c2fac0
+[  153.837408] R10: fefefefefefefeff R11: 0000000000000202 R12: 0000000001c2fac0
+[  153.837798] R13: 0000000001c2f9d0 R14: 0000000000000000 R15: 0000000000000001
+[  153.838194] ---[ end trace b92031513bbe596c ]---
+[  153.838441] [drm:drm_mode_config_cleanup] *ERROR* connector VGA-1 leaked!
+
+Signed-off-by: Tong Zhang <ztong0001@gmail.com>
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210222023322.984885-1-ztong0001@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/ast/ast_drv.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c
+index ea8164e7a6dc..01837bea18c2 100644
+--- a/drivers/gpu/drm/ast/ast_drv.c
++++ b/drivers/gpu/drm/ast/ast_drv.c
+@@ -30,6 +30,7 @@
+ #include <linux/module.h>
+ #include <linux/pci.h>
++#include <drm/drm_atomic_helper.h>
+ #include <drm/drm_crtc_helper.h>
+ #include <drm/drm_drv.h>
+ #include <drm/drm_fb_helper.h>
+@@ -138,6 +139,7 @@ static void ast_pci_remove(struct pci_dev *pdev)
+       struct drm_device *dev = pci_get_drvdata(pdev);
+       drm_dev_unregister(dev);
++      drm_atomic_helper_shutdown(dev);
+ }
+ static int ast_drm_freeze(struct drm_device *dev)
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-komeda-fix-bit-check-to-import-to-value-of-prope.patch b/queue-5.12/drm-komeda-fix-bit-check-to-import-to-value-of-prope.patch
new file mode 100644 (file)
index 0000000..5bbd8fa
--- /dev/null
@@ -0,0 +1,181 @@
+From 4b2ab92fb0d85e21be301f67ec6b4f59d1698593 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Feb 2021 13:11:02 +0000
+Subject: drm/komeda: Fix bit check to import to value of proper type
+
+From: Carsten Haitzler <carsten.haitzler@arm.com>
+
+[ Upstream commit a1c3be890440a1769ed6f822376a3e3ab0d42994 ]
+
+Another issue found by KASAN. The bit finding is buried inside the
+dp_for_each_set_bit() macro (that passes on to for_each_set_bit() that
+calls the bit stuff. These bit functions want an unsigned long pointer
+as input and just dumbly casting leads to out-of-bounds accesses.
+This fixes that.
+
+Signed-off-by: Carsten Haitzler <carsten.haitzler@arm.com>
+Reviewed-by: Steven Price <steven.price@arm.com>
+Reviewed-by: James Qian Wang <james.qian.wang@arm.com>
+Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210204131102.68658-1-carsten.haitzler@foss.arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../drm/arm/display/include/malidp_utils.h    |  3 ---
+ .../drm/arm/display/komeda/komeda_pipeline.c  | 16 +++++++++++-----
+ .../display/komeda/komeda_pipeline_state.c    | 19 +++++++++++--------
+ 3 files changed, 22 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/gpu/drm/arm/display/include/malidp_utils.h b/drivers/gpu/drm/arm/display/include/malidp_utils.h
+index 3bc383d5bf73..49a1d7f3539c 100644
+--- a/drivers/gpu/drm/arm/display/include/malidp_utils.h
++++ b/drivers/gpu/drm/arm/display/include/malidp_utils.h
+@@ -13,9 +13,6 @@
+ #define has_bit(nr, mask)     (BIT(nr) & (mask))
+ #define has_bits(bits, mask)  (((bits) & (mask)) == (bits))
+-#define dp_for_each_set_bit(bit, mask) \
+-      for_each_set_bit((bit), ((unsigned long *)&(mask)), sizeof(mask) * 8)
+-
+ #define dp_wait_cond(__cond, __tries, __min_range, __max_range)       \
+ ({                                                    \
+       int num_tries = __tries;                        \
+diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
+index 719a79728e24..06c595378dda 100644
+--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
++++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
+@@ -46,8 +46,9 @@ void komeda_pipeline_destroy(struct komeda_dev *mdev,
+ {
+       struct komeda_component *c;
+       int i;
++      unsigned long avail_comps = pipe->avail_comps;
+-      dp_for_each_set_bit(i, pipe->avail_comps) {
++      for_each_set_bit(i, &avail_comps, 32) {
+               c = komeda_pipeline_get_component(pipe, i);
+               komeda_component_destroy(mdev, c);
+       }
+@@ -247,6 +248,7 @@ static void komeda_pipeline_dump(struct komeda_pipeline *pipe)
+ {
+       struct komeda_component *c;
+       int id;
++      unsigned long avail_comps = pipe->avail_comps;
+       DRM_INFO("Pipeline-%d: n_layers: %d, n_scalers: %d, output: %s.\n",
+                pipe->id, pipe->n_layers, pipe->n_scalers,
+@@ -258,7 +260,7 @@ static void komeda_pipeline_dump(struct komeda_pipeline *pipe)
+                pipe->of_output_links[1] ?
+                pipe->of_output_links[1]->full_name : "none");
+-      dp_for_each_set_bit(id, pipe->avail_comps) {
++      for_each_set_bit(id, &avail_comps, 32) {
+               c = komeda_pipeline_get_component(pipe, id);
+               komeda_component_dump(c);
+@@ -270,8 +272,9 @@ static void komeda_component_verify_inputs(struct komeda_component *c)
+       struct komeda_pipeline *pipe = c->pipeline;
+       struct komeda_component *input;
+       int id;
++      unsigned long supported_inputs = c->supported_inputs;
+-      dp_for_each_set_bit(id, c->supported_inputs) {
++      for_each_set_bit(id, &supported_inputs, 32) {
+               input = komeda_pipeline_get_component(pipe, id);
+               if (!input) {
+                       c->supported_inputs &= ~(BIT(id));
+@@ -302,8 +305,9 @@ static void komeda_pipeline_assemble(struct komeda_pipeline *pipe)
+       struct komeda_component *c;
+       struct komeda_layer *layer;
+       int i, id;
++      unsigned long avail_comps = pipe->avail_comps;
+-      dp_for_each_set_bit(id, pipe->avail_comps) {
++      for_each_set_bit(id, &avail_comps, 32) {
+               c = komeda_pipeline_get_component(pipe, id);
+               komeda_component_verify_inputs(c);
+       }
+@@ -355,13 +359,15 @@ void komeda_pipeline_dump_register(struct komeda_pipeline *pipe,
+ {
+       struct komeda_component *c;
+       u32 id;
++      unsigned long avail_comps;
+       seq_printf(sf, "\n======== Pipeline-%d ==========\n", pipe->id);
+       if (pipe->funcs && pipe->funcs->dump_register)
+               pipe->funcs->dump_register(pipe, sf);
+-      dp_for_each_set_bit(id, pipe->avail_comps) {
++      avail_comps = pipe->avail_comps;
++      for_each_set_bit(id, &avail_comps, 32) {
+               c = komeda_pipeline_get_component(pipe, id);
+               seq_printf(sf, "\n------%s------\n", c->name);
+diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+index 5c085116de3f..e672b9cffee3 100644
+--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
++++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+@@ -1231,14 +1231,15 @@ komeda_pipeline_unbound_components(struct komeda_pipeline *pipe,
+       struct komeda_pipeline_state *old = priv_to_pipe_st(pipe->obj.state);
+       struct komeda_component_state *c_st;
+       struct komeda_component *c;
+-      u32 disabling_comps, id;
++      u32 id;
++      unsigned long disabling_comps;
+       WARN_ON(!old);
+       disabling_comps = (~new->active_comps) & old->active_comps;
+       /* unbound all disabling component */
+-      dp_for_each_set_bit(id, disabling_comps) {
++      for_each_set_bit(id, &disabling_comps, 32) {
+               c = komeda_pipeline_get_component(pipe, id);
+               c_st = komeda_component_get_state_and_set_user(c,
+                               drm_st, NULL, new->crtc);
+@@ -1286,7 +1287,8 @@ bool komeda_pipeline_disable(struct komeda_pipeline *pipe,
+       struct komeda_pipeline_state *old;
+       struct komeda_component *c;
+       struct komeda_component_state *c_st;
+-      u32 id, disabling_comps = 0;
++      u32 id;
++      unsigned long disabling_comps;
+       old = komeda_pipeline_get_old_state(pipe, old_state);
+@@ -1296,10 +1298,10 @@ bool komeda_pipeline_disable(struct komeda_pipeline *pipe,
+               disabling_comps = old->active_comps &
+                                 pipe->standalone_disabled_comps;
+-      DRM_DEBUG_ATOMIC("PIPE%d: active_comps: 0x%x, disabling_comps: 0x%x.\n",
++      DRM_DEBUG_ATOMIC("PIPE%d: active_comps: 0x%x, disabling_comps: 0x%lx.\n",
+                        pipe->id, old->active_comps, disabling_comps);
+-      dp_for_each_set_bit(id, disabling_comps) {
++      for_each_set_bit(id, &disabling_comps, 32) {
+               c = komeda_pipeline_get_component(pipe, id);
+               c_st = priv_to_comp_st(c->obj.state);
+@@ -1330,16 +1332,17 @@ void komeda_pipeline_update(struct komeda_pipeline *pipe,
+       struct komeda_pipeline_state *new = priv_to_pipe_st(pipe->obj.state);
+       struct komeda_pipeline_state *old;
+       struct komeda_component *c;
+-      u32 id, changed_comps = 0;
++      u32 id;
++      unsigned long changed_comps;
+       old = komeda_pipeline_get_old_state(pipe, old_state);
+       changed_comps = new->active_comps | old->active_comps;
+-      DRM_DEBUG_ATOMIC("PIPE%d: active_comps: 0x%x, changed: 0x%x.\n",
++      DRM_DEBUG_ATOMIC("PIPE%d: active_comps: 0x%x, changed: 0x%lx.\n",
+                        pipe->id, new->active_comps, changed_comps);
+-      dp_for_each_set_bit(id, changed_comps) {
++      for_each_set_bit(id, &changed_comps, 32) {
+               c = komeda_pipeline_get_component(pipe, id);
+               if (new->active_comps & BIT(c->id))
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-msm-a6xx-fix-perfcounter-oob-timeout.patch b/queue-5.12/drm-msm-a6xx-fix-perfcounter-oob-timeout.patch
new file mode 100644 (file)
index 0000000..940b9bd
--- /dev/null
@@ -0,0 +1,83 @@
+From 32795d1e4f8fc978187b7980b94e383a9e1a8bd2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Apr 2021 19:17:12 +0530
+Subject: drm/msm/a6xx: Fix perfcounter oob timeout
+
+From: Akhil P Oommen <akhilpo@codeaurora.org>
+
+[ Upstream commit 2fc8a92e0a22c483e749232d4f13c77a92139aa7 ]
+
+We were not programing the correct bit while clearing the perfcounter oob.
+So, clear it correctly using the new 'clear' bit. This fixes the below
+error:
+
+[drm:a6xx_gmu_set_oob] *ERROR* Timeout waiting for GMU OOB set PERFCOUNTER: 0x80000000
+
+Signed-off-by: Akhil P Oommen <akhilpo@codeaurora.org>
+Link: https://lore.kernel.org/r/1617630433-36506-1-git-send-email-akhilpo@codeaurora.org
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+index 91cf46f84025..3d55e153fa9c 100644
+--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
++++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+@@ -246,7 +246,7 @@ static int a6xx_gmu_hfi_start(struct a6xx_gmu *gmu)
+ }
+ struct a6xx_gmu_oob_bits {
+-      int set, ack, set_new, ack_new;
++      int set, ack, set_new, ack_new, clear, clear_new;
+       const char *name;
+ };
+@@ -260,6 +260,8 @@ static const struct a6xx_gmu_oob_bits a6xx_gmu_oob_bits[] = {
+               .ack = 24,
+               .set_new = 30,
+               .ack_new = 31,
++              .clear = 24,
++              .clear_new = 31,
+       },
+       [GMU_OOB_PERFCOUNTER_SET] = {
+@@ -268,18 +270,22 @@ static const struct a6xx_gmu_oob_bits a6xx_gmu_oob_bits[] = {
+               .ack = 25,
+               .set_new = 28,
+               .ack_new = 30,
++              .clear = 25,
++              .clear_new = 29,
+       },
+       [GMU_OOB_BOOT_SLUMBER] = {
+               .name = "BOOT_SLUMBER",
+               .set = 22,
+               .ack = 30,
++              .clear = 30,
+       },
+       [GMU_OOB_DCVS_SET] = {
+               .name = "GPU_DCVS",
+               .set = 23,
+               .ack = 31,
++              .clear = 31,
+       },
+ };
+@@ -335,9 +341,9 @@ void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state)
+               return;
+       if (gmu->legacy)
+-              bit = a6xx_gmu_oob_bits[state].ack;
++              bit = a6xx_gmu_oob_bits[state].clear;
+       else
+-              bit = a6xx_gmu_oob_bits[state].ack_new;
++              bit = a6xx_gmu_oob_bits[state].clear_new;
+       gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET, 1 << bit);
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-msm-dp-fix-incorrect-null-check-kbot-warnings-in.patch b/queue-5.12/drm-msm-dp-fix-incorrect-null-check-kbot-warnings-in.patch
new file mode 100644 (file)
index 0000000..669fedf
--- /dev/null
@@ -0,0 +1,45 @@
+From 65b7f93696835d26764c59986c53f800d6055f14 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Mar 2021 11:17:18 -0800
+Subject: drm/msm/dp: Fix incorrect NULL check kbot warnings in DP driver
+
+From: Abhinav Kumar <abhinavk@codeaurora.org>
+
+[ Upstream commit 7d649cfe0314aad2ba18042885ab9de2f13ad809 ]
+
+Fix an incorrect NULL check reported by kbot in the MSM DP driver
+
+smatch warnings:
+drivers/gpu/drm/msm/dp/dp_hpd.c:37 dp_hpd_connect()
+error: we previously assumed 'hpd_priv->dp_cb' could be null
+(see line 37)
+
+Reported-by: kernel test robot <lkp@intel.com>
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Abhinav Kumar <abhinavk@codeaurora.org>
+Reviewed-by: Stephen Boyd <swboyd@chromium.org>
+Link: https://lore.kernel.org/r/1614971839-2686-2-git-send-email-abhinavk@codeaurora.org
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/dp/dp_hpd.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/dp/dp_hpd.c b/drivers/gpu/drm/msm/dp/dp_hpd.c
+index 5b8fe32022b5..e1c90fa47411 100644
+--- a/drivers/gpu/drm/msm/dp/dp_hpd.c
++++ b/drivers/gpu/drm/msm/dp/dp_hpd.c
+@@ -34,8 +34,8 @@ int dp_hpd_connect(struct dp_usbpd *dp_usbpd, bool hpd)
+       dp_usbpd->hpd_high = hpd;
+-      if (!hpd_priv->dp_cb && !hpd_priv->dp_cb->configure
+-                              && !hpd_priv->dp_cb->disconnect) {
++      if (!hpd_priv->dp_cb || !hpd_priv->dp_cb->configure
++                              || !hpd_priv->dp_cb->disconnect) {
+               pr_err("hpd dp_cb not initialized\n");
+               return -EINVAL;
+       }
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-msm-mdp5-configure-pp_sync_height-to-double-the-.patch b/queue-5.12/drm-msm-mdp5-configure-pp_sync_height-to-double-the-.patch
new file mode 100644 (file)
index 0000000..31cf006
--- /dev/null
@@ -0,0 +1,57 @@
+From f3bea4dd10eeb5a3819c2685ad6e7774f0b3903a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Apr 2021 23:47:24 +0200
+Subject: drm/msm/mdp5: Configure PP_SYNC_HEIGHT to double the vtotal
+
+From: Marijn Suijten <marijn.suijten@somainline.org>
+
+[ Upstream commit 2ad52bdb220de5ab348098e3482b01235d15a842 ]
+
+Leaving this at a close-to-maximum register value 0xFFF0 means it takes
+very long for the MDSS to generate a software vsync interrupt when the
+hardware TE interrupt doesn't arrive.  Configuring this to double the
+vtotal (like some downstream kernels) leads to a frame to take at most
+twice before the vsync signal, until hardware TE comes up.
+
+In this case the hardware interrupt responsible for providing this
+signal - "disp-te" gpio - is not hooked up to the mdp5 vsync/pp logic at
+all.  This solves severe panel update issues observed on at least the
+Xperia Loire and Tone series, until said gpio is properly hooked up to
+an irq.
+
+Suggested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
+Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
+Link: https://lore.kernel.org/r/20210406214726.131534-2-marijn.suijten@somainline.org
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c
+index ff2c1d583c79..f6df4d3b1406 100644
+--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c
++++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c
+@@ -49,9 +49,17 @@ static int pingpong_tearcheck_setup(struct drm_encoder *encoder,
+               | MDP5_PP_SYNC_CONFIG_VSYNC_IN_EN;
+       cfg |= MDP5_PP_SYNC_CONFIG_VSYNC_COUNT(vclks_line);
++      /*
++       * Tearcheck emits a blanking signal every vclks_line * vtotal * 2 ticks on
++       * the vsync_clk equating to roughly half the desired panel refresh rate.
++       * This is only necessary as stability fallback if interrupts from the
++       * panel arrive too late or not at all, but is currently used by default
++       * because these panel interrupts are not wired up yet.
++       */
+       mdp5_write(mdp5_kms, REG_MDP5_PP_SYNC_CONFIG_VSYNC(pp_id), cfg);
+       mdp5_write(mdp5_kms,
+-              REG_MDP5_PP_SYNC_CONFIG_HEIGHT(pp_id), 0xfff0);
++              REG_MDP5_PP_SYNC_CONFIG_HEIGHT(pp_id), (2 * mode->vtotal));
++
+       mdp5_write(mdp5_kms,
+               REG_MDP5_PP_VSYNC_INIT_VAL(pp_id), mode->vdisplay);
+       mdp5_write(mdp5_kms, REG_MDP5_PP_RD_PTR_IRQ(pp_id), mode->vdisplay + 1);
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-msm-mdp5-do-not-multiply-vclk-line-count-by-100.patch b/queue-5.12/drm-msm-mdp5-do-not-multiply-vclk-line-count-by-100.patch
new file mode 100644 (file)
index 0000000..612de7a
--- /dev/null
@@ -0,0 +1,71 @@
+From 0d10f8e1764d77d71f5560b83b19f9570614bf19 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Apr 2021 23:47:25 +0200
+Subject: drm/msm/mdp5: Do not multiply vclk line count by 100
+
+From: Marijn Suijten <marijn.suijten@somainline.org>
+
+[ Upstream commit 377569f82ea8228c421cef4da33e056a900b58ca ]
+
+Neither vtotal nor drm_mode_vrefresh contain a value that is
+premultiplied by 100 making the x100 variable name incorrect and
+resulting in vclks_line to become 100 times larger than it is supposed
+to be.  The hardware counts 100 clockticks too many before tearcheck,
+leading to severe panel issues on at least the Sony Xperia lineup.
+
+This is likely an artifact from the original MDSS DSI panel driver where
+the calculation [1] corrected for a premultiplied reference framerate by
+100 [2].  It does not appear that the above values were ever
+premultiplied in the history of the DRM MDP5 driver.
+
+With this change applied the value written to the SYNC_CONFIG_VSYNC
+register is now identical to downstream kernels.
+
+[1]: https://source.codeaurora.org/quic/la/kernel/msm-3.18/tree/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c?h=LA.UM.8.6.c26-02400-89xx.0#n288
+[2]: https://source.codeaurora.org/quic/la/kernel/msm-3.18/tree/drivers/video/msm/mdss/mdss_dsi_panel.c?h=LA.UM.8.6.c26-02400-89xx.0#n1648
+
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
+Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
+Link: https://lore.kernel.org/r/20210406214726.131534-3-marijn.suijten@somainline.org
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c
+index f6df4d3b1406..0392d4dfe270 100644
+--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c
++++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c
+@@ -20,7 +20,7 @@ static int pingpong_tearcheck_setup(struct drm_encoder *encoder,
+ {
+       struct mdp5_kms *mdp5_kms = get_kms(encoder);
+       struct device *dev = encoder->dev->dev;
+-      u32 total_lines_x100, vclks_line, cfg;
++      u32 total_lines, vclks_line, cfg;
+       long vsync_clk_speed;
+       struct mdp5_hw_mixer *mixer = mdp5_crtc_get_mixer(encoder->crtc);
+       int pp_id = mixer->pp;
+@@ -30,8 +30,8 @@ static int pingpong_tearcheck_setup(struct drm_encoder *encoder,
+               return -EINVAL;
+       }
+-      total_lines_x100 = mode->vtotal * drm_mode_vrefresh(mode);
+-      if (!total_lines_x100) {
++      total_lines = mode->vtotal * drm_mode_vrefresh(mode);
++      if (!total_lines) {
+               DRM_DEV_ERROR(dev, "%s: vtotal(%d) or vrefresh(%d) is 0\n",
+                             __func__, mode->vtotal, drm_mode_vrefresh(mode));
+               return -EINVAL;
+@@ -43,7 +43,7 @@ static int pingpong_tearcheck_setup(struct drm_encoder *encoder,
+                                                       vsync_clk_speed);
+               return -EINVAL;
+       }
+-      vclks_line = vsync_clk_speed * 100 / total_lines_x100;
++      vclks_line = vsync_clk_speed / total_lines;
+       cfg = MDP5_PP_SYNC_CONFIG_VSYNC_COUNTER_EN
+               | MDP5_PP_SYNC_CONFIG_VSYNC_IN_EN;
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-qxl-do-not-run-release-if-qxl-failed-to-init.patch b/queue-5.12/drm-qxl-do-not-run-release-if-qxl-failed-to-init.patch
new file mode 100644 (file)
index 0000000..d958f77
--- /dev/null
@@ -0,0 +1,94 @@
+From d12e9cb4544a1da2a15ac9d1fb2ec5e432889d36 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Feb 2021 23:07:27 -0500
+Subject: drm/qxl: do not run release if qxl failed to init
+
+From: Tong Zhang <ztong0001@gmail.com>
+
+[ Upstream commit b91907a6241193465ca92e357adf16822242296d ]
+
+if qxl_device_init() fail, drm device will not be registered,
+in this case, do not run qxl_drm_release()
+
+[    5.258534] ==================================================================
+[    5.258931] BUG: KASAN: user-memory-access in qxl_destroy_monitors_object+0x42/0xa0 [qxl]
+[    5.259388] Write of size 8 at addr 00000000000014dc by task modprobe/95
+[    5.259754]
+[    5.259842] CPU: 0 PID: 95 Comm: modprobe Not tainted 5.11.0-rc6-00007-g88bb507a74ea #62
+[    5.260309] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-48-gd9c812dda54
+[    5.260917] Call Trace:
+[    5.261056]  dump_stack+0x7d/0xa3
+[    5.261245]  kasan_report.cold+0x10c/0x10e
+[    5.261475]  ? qxl_destroy_monitors_object+0x42/0xa0 [qxl]
+[    5.261789]  check_memory_region+0x17c/0x1e0
+[    5.262029]  qxl_destroy_monitors_object+0x42/0xa0 [qxl]
+[    5.262332]  qxl_modeset_fini+0x9/0x20 [qxl]
+[    5.262595]  qxl_drm_release+0x22/0x30 [qxl]
+[    5.262841]  drm_dev_release+0x32/0x50
+[    5.263047]  release_nodes+0x39e/0x410
+[    5.263253]  ? devres_release+0x40/0x40
+[    5.263462]  really_probe+0x2ea/0x420
+[    5.263664]  driver_probe_device+0x6d/0xd0
+[    5.263888]  device_driver_attach+0x82/0x90
+[    5.264116]  ? device_driver_attach+0x90/0x90
+[    5.264353]  __driver_attach+0x60/0x100
+[    5.264563]  ? device_driver_attach+0x90/0x90
+[    5.264801]  bus_for_each_dev+0xe1/0x140
+[    5.265014]  ? subsys_dev_iter_exit+0x10/0x10
+[    5.265251]  ? klist_node_init+0x61/0x80
+[    5.265464]  bus_add_driver+0x254/0x2a0
+[    5.265673]  driver_register+0xd3/0x150
+[    5.265882]  ? 0xffffffffc0048000
+[    5.266064]  do_one_initcall+0x84/0x250
+[    5.266274]  ? trace_event_raw_event_initcall_finish+0x150/0x150
+[    5.266596]  ? unpoison_range+0xf/0x30
+[    5.266801]  ? ____kasan_kmalloc.constprop.0+0x84/0xa0
+[    5.267082]  ? unpoison_range+0xf/0x30
+[    5.267287]  ? unpoison_range+0xf/0x30
+[    5.267491]  do_init_module+0xf8/0x350
+[    5.267697]  load_module+0x3fe6/0x4340
+[    5.267902]  ? vm_unmap_ram+0x1d0/0x1d0
+[    5.268115]  ? module_frob_arch_sections+0x20/0x20
+[    5.268375]  ? __do_sys_finit_module+0x108/0x170
+[    5.268624]  __do_sys_finit_module+0x108/0x170
+[    5.268865]  ? __ia32_sys_init_module+0x40/0x40
+[    5.269111]  ? file_open_root+0x200/0x200
+[    5.269330]  ? do_sys_open+0x85/0xe0
+[    5.269527]  ? filp_open+0x50/0x50
+[    5.269714]  ? exit_to_user_mode_prepare+0xfc/0x130
+[    5.269978]  do_syscall_64+0x33/0x40
+[    5.270176]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
+[    5.270450] RIP: 0033:0x7fa3f685bcf7
+[    5.270646] Code: 48 89 57 30 48 8b 04 24 48 89 47 38 e9 1d a0 02 00 48 89 f8 48 89 f7 48 89 d1
+[    5.271634] RSP: 002b:00007ffca83048d8 EFLAGS: 00000246 ORIG_RAX: 0000000000000139
+[    5.272037] RAX: ffffffffffffffda RBX: 0000000001e94a70 RCX: 00007fa3f685bcf7
+[    5.272416] RDX: 0000000000000000 RSI: 0000000001e939e0 RDI: 0000000000000003
+[    5.272794] RBP: 0000000000000003 R08: 0000000000000000 R09: 0000000000000001
+[    5.273171] R10: 00007fa3f68bf300 R11: 0000000000000246 R12: 0000000001e939e0
+[    5.273550] R13: 0000000000000000 R14: 0000000001e93bd0 R15: 0000000000000001
+[    5.273928] ==================================================================
+
+Signed-off-by: Tong Zhang <ztong0001@gmail.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/20210203040727.868921-1-ztong0001@gmail.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/qxl/qxl_drv.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c
+index 1864467f1063..1b09bbe98055 100644
+--- a/drivers/gpu/drm/qxl/qxl_drv.c
++++ b/drivers/gpu/drm/qxl/qxl_drv.c
+@@ -144,6 +144,8 @@ static void qxl_drm_release(struct drm_device *dev)
+        * reordering qxl_modeset_fini() + qxl_device_fini() calls is
+        * non-trivial though.
+        */
++      if (!dev->registered)
++              return;
+       qxl_modeset_fini(qdev);
+       qxl_device_fini(qdev);
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-qxl-release-shadow-on-shutdown.patch b/queue-5.12/drm-qxl-release-shadow-on-shutdown.patch
new file mode 100644 (file)
index 0000000..d140064
--- /dev/null
@@ -0,0 +1,38 @@
+From af1f3338146fc9b898ad33102a0674264551848f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Feb 2021 15:57:06 +0100
+Subject: drm/qxl: release shadow on shutdown
+
+From: Gerd Hoffmann <kraxel@redhat.com>
+
+[ Upstream commit 4ca77c513537700d3fae69030879f781dde1904c ]
+
+In case we have a shadow surface on shutdown release
+it so it doesn't leak.
+
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
+Link: http://patchwork.freedesktop.org/patch/msgid/20210204145712.1531203-6-kraxel@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/qxl/qxl_display.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c
+index 10738e04c09b..56e0c6c625e9 100644
+--- a/drivers/gpu/drm/qxl/qxl_display.c
++++ b/drivers/gpu/drm/qxl/qxl_display.c
+@@ -1228,6 +1228,10 @@ int qxl_modeset_init(struct qxl_device *qdev)
+ void qxl_modeset_fini(struct qxl_device *qdev)
+ {
++      if (qdev->dumb_shadow_bo) {
++              drm_gem_object_put(&qdev->dumb_shadow_bo->tbo.base);
++              qdev->dumb_shadow_bo = NULL;
++      }
+       qxl_destroy_monitors_object(qdev);
+       drm_mode_config_cleanup(&qdev->ddev);
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-radeon-don-t-evict-if-not-initialized.patch b/queue-5.12/drm-radeon-don-t-evict-if-not-initialized.patch
new file mode 100644 (file)
index 0000000..3d49630
--- /dev/null
@@ -0,0 +1,53 @@
+From 8546292ded5a3e11c5f8cbb47646267338b6c0fc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 21 Mar 2021 11:19:07 -0400
+Subject: drm/radeon: don't evict if not initialized
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Tong Zhang <ztong0001@gmail.com>
+
+[ Upstream commit 05eacc0f8f6c7e27f1841343611f4bed9ee178c1 ]
+
+TTM_PL_VRAM may not initialized at all when calling
+radeon_bo_evict_vram(). We need to check before doing eviction.
+
+[    2.160837] BUG: kernel NULL pointer dereference, address: 0000000000000020
+[    2.161212] #PF: supervisor read access in kernel mode
+[    2.161490] #PF: error_code(0x0000) - not-present page
+[    2.161767] PGD 0 P4D 0
+[    2.163088] RIP: 0010:ttm_resource_manager_evict_all+0x70/0x1c0 [ttm]
+[    2.168506] Call Trace:
+[    2.168641]  radeon_bo_evict_vram+0x1c/0x20 [radeon]
+[    2.168936]  radeon_device_fini+0x28/0xf9 [radeon]
+[    2.169224]  radeon_driver_unload_kms+0x44/0xa0 [radeon]
+[    2.169534]  radeon_driver_load_kms+0x174/0x210 [radeon]
+[    2.169843]  drm_dev_register+0xd9/0x1c0 [drm]
+[    2.170104]  radeon_pci_probe+0x117/0x1a0 [radeon]
+
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Suggested-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Tong Zhang <ztong0001@gmail.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/radeon/radeon_object.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
+index 9b81786782de..499ce55e34cc 100644
+--- a/drivers/gpu/drm/radeon/radeon_object.c
++++ b/drivers/gpu/drm/radeon/radeon_object.c
+@@ -384,6 +384,8 @@ int radeon_bo_evict_vram(struct radeon_device *rdev)
+       }
+ #endif
+       man = ttm_manager_type(bdev, TTM_PL_VRAM);
++      if (!man)
++              return 0;
+       return ttm_resource_manager_evict_all(bdev, man);
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-radeon-ttm-fix-memory-leak-userptr-pages.patch b/queue-5.12/drm-radeon-ttm-fix-memory-leak-userptr-pages.patch
new file mode 100644 (file)
index 0000000..e18db67
--- /dev/null
@@ -0,0 +1,47 @@
+From eac95a61122d1b0c92def954ee74f2bff503fd88 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Mar 2021 09:32:36 +0100
+Subject: drm/radeon/ttm: Fix memory leak userptr pages
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Daniel Gomez <daniel@qtec.com>
+
+[ Upstream commit 5aeaa43e0ef1006320c077cbc49f4a8229ca3460 ]
+
+If userptr pages have been pinned but not bounded,
+they remain uncleared.
+
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Daniel Gomez <daniel@qtec.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/radeon/radeon_ttm.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
+index 78893bea85ae..c0258d213a72 100644
+--- a/drivers/gpu/drm/radeon/radeon_ttm.c
++++ b/drivers/gpu/drm/radeon/radeon_ttm.c
+@@ -485,13 +485,14 @@ static void radeon_ttm_backend_unbind(struct ttm_bo_device *bdev, struct ttm_tt
+       struct radeon_ttm_tt *gtt = (void *)ttm;
+       struct radeon_device *rdev = radeon_get_rdev(bdev);
++      if (gtt->userptr)
++              radeon_ttm_tt_unpin_userptr(bdev, ttm);
++
+       if (!gtt->bound)
+               return;
+       radeon_gart_unbind(rdev, gtt->offset, ttm->num_pages);
+-      if (gtt->userptr)
+-              radeon_ttm_tt_unpin_userptr(bdev, ttm);
+       gtt->bound = false;
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-virtio-fix-possible-leak-unlock-virtio_gpu_objec.patch b/queue-5.12/drm-virtio-fix-possible-leak-unlock-virtio_gpu_objec.patch
new file mode 100644 (file)
index 0000000..310a1e4
--- /dev/null
@@ -0,0 +1,49 @@
+From 0f0bcf1cc1097dd7e6d4371817a69f1b5dff6a49 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Mar 2021 23:18:19 +0800
+Subject: drm/virtio: fix possible leak/unlock virtio_gpu_object_array
+
+From: xndcn <xndchn@gmail.com>
+
+[ Upstream commit 377f8331d0565e6f71ba081c894029a92d0c7e77 ]
+
+virtio_gpu_object array is not freed or unlocked in some
+failed cases.
+
+Signed-off-by: xndcn <xndchn@gmail.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/20210305151819.14330-1-xndchn@gmail.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/virtio/virtgpu_ioctl.c  | 2 +-
+ drivers/gpu/drm/virtio/virtgpu_object.c | 1 +
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+index 23eb6d772e40..669f2ee39515 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
++++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+@@ -174,7 +174,7 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data,
+               if (!sync_file) {
+                       dma_fence_put(&out_fence->f);
+                       ret = -ENOMEM;
+-                      goto out_memdup;
++                      goto out_unresv;
+               }
+               exbuf->fence_fd = out_fence_fd;
+diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c
+index d69a5b6da553..4ff1ec28e630 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_object.c
++++ b/drivers/gpu/drm/virtio/virtgpu_object.c
+@@ -248,6 +248,7 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev,
+       ret = virtio_gpu_object_shmem_init(vgdev, bo, &ents, &nents);
+       if (ret != 0) {
++              virtio_gpu_array_put_free(objs);
+               virtio_gpu_free_object(&shmem_obj->base);
+               return ret;
+       }
+-- 
+2.30.2
+
diff --git a/queue-5.12/drm-vkms-fix-misuse-of-warn_on.patch b/queue-5.12/drm-vkms-fix-misuse-of-warn_on.patch
new file mode 100644 (file)
index 0000000..01b4c68
--- /dev/null
@@ -0,0 +1,47 @@
+From bc86877e5bac071c8a0a36d4cc5ab97a67849cb6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 Mar 2021 14:28:40 +0100
+Subject: drm/vkms: fix misuse of WARN_ON
+
+From: Dmitry Vyukov <dvyukov@google.com>
+
+[ Upstream commit b4142fc4d52d051d4d8df1fb6c569e5b445d369e ]
+
+vkms_vblank_simulate() uses WARN_ON for timing-dependent condition
+(timer overrun). This is a mis-use of WARN_ON, WARN_ON must be used
+to denote kernel bugs. Use pr_warn() instead.
+
+Signed-off-by: Dmitry Vyukov <dvyukov@google.com>
+Reported-by: syzbot+4fc21a003c8332eb0bdd@syzkaller.appspotmail.com
+Cc: Rodrigo Siqueira <rodrigosiqueiramelo@gmail.com>
+Cc: Melissa Wen <melissa.srw@gmail.com>
+Cc: Haneen Mohammed <hamohammed.sa@gmail.com>
+Cc: Daniel Vetter <daniel@ffwll.ch>
+Cc: David Airlie <airlied@linux.ie>
+Cc: dri-devel@lists.freedesktop.org
+Cc: linux-kernel@vger.kernel.org
+Acked-by: Melissa Wen <melissa.srw@gmail.com>
+Signed-off-by: Melissa Wen <melissa.srw@gmail.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210320132840.1315853-1-dvyukov@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vkms/vkms_crtc.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c
+index 0443b7deeaef..758d8a98d96b 100644
+--- a/drivers/gpu/drm/vkms/vkms_crtc.c
++++ b/drivers/gpu/drm/vkms/vkms_crtc.c
+@@ -18,7 +18,8 @@ static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer)
+       ret_overrun = hrtimer_forward_now(&output->vblank_hrtimer,
+                                         output->period_ns);
+-      WARN_ON(ret_overrun != 1);
++      if (ret_overrun != 1)
++              pr_warn("%s: vblank timer overrun\n", __func__);
+       spin_lock(&output->lock);
+       ret = drm_crtc_handle_vblank(crtc);
+-- 
+2.30.2
+
diff --git a/queue-5.12/efi-libstub-add-clang_flags-to-x86-flags.patch b/queue-5.12/efi-libstub-add-clang_flags-to-x86-flags.patch
new file mode 100644 (file)
index 0000000..f906bd3
--- /dev/null
@@ -0,0 +1,49 @@
+From 2fa3cce0d62ab28f57d13975d4aadc7ef63d4dfa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Mar 2021 17:04:35 -0700
+Subject: efi/libstub: Add $(CLANG_FLAGS) to x86 flags
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+[ Upstream commit 58d746c119dfa28e72fc35aacaf3d2a3ac625cd0 ]
+
+When cross compiling x86 on an ARM machine with clang, there are several
+errors along the lines of:
+
+  arch/x86/include/asm/page_64.h:52:7: error: invalid output constraint '=D' in asm
+
+This happens because the x86 flags in the EFI stub are not derived from
+KBUILD_CFLAGS like the other architectures are and the clang flags that
+set the target architecture ('--target=') and the path to the GNU cross
+tools ('--prefix=') are not present, meaning that the host architecture
+is targeted.
+
+These flags are available as $(CLANG_FLAGS) from the main Makefile so
+add them to the cflags for x86 so that cross compiling works as expected.
+
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Acked-by: Ard Biesheuvel <ardb@kernel.org>
+Link: https://lkml.kernel.org/r/20210326000435.4785-4-nathan@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/efi/libstub/Makefile | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
+index c23466e05e60..d0537573501e 100644
+--- a/drivers/firmware/efi/libstub/Makefile
++++ b/drivers/firmware/efi/libstub/Makefile
+@@ -13,7 +13,8 @@ cflags-$(CONFIG_X86)         += -m$(BITS) -D__KERNEL__ \
+                                  -Wno-pointer-sign \
+                                  $(call cc-disable-warning, address-of-packed-member) \
+                                  $(call cc-disable-warning, gnu) \
+-                                 -fno-asynchronous-unwind-tables
++                                 -fno-asynchronous-unwind-tables \
++                                 $(CLANG_FLAGS)
+ # arm64 uses the full KBUILD_CFLAGS so it's necessary to explicitly
+ # disable the stackleak plugin
+-- 
+2.30.2
+
diff --git a/queue-5.12/extcon-arizona-fix-some-issues-when-hpdet-irq-fires-.patch b/queue-5.12/extcon-arizona-fix-some-issues-when-hpdet-irq-fires-.patch
new file mode 100644 (file)
index 0000000..c0b996e
--- /dev/null
@@ -0,0 +1,96 @@
+From b604eeed486865dee95535d94dacf1b49c6db6f0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Mar 2021 16:17:56 +0100
+Subject: extcon: arizona: Fix some issues when HPDET IRQ fires after the jack
+ has been unplugged
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit c309a3e8793f7e01c4a4ec7960658380572cb576 ]
+
+When the jack is partially inserted and then removed again it may be
+removed while the hpdet code is running. In this case the following
+may happen:
+
+1. The "JACKDET rise" or ""JACKDET fall" IRQ triggers
+2. arizona_jackdet runs and takes info->lock
+3. The "HPDET" IRQ triggers
+4. arizona_hpdet_irq runs, blocks on info->lock
+5. arizona_jackdet calls arizona_stop_mic() and clears info->hpdet_done
+6. arizona_jackdet releases info->lock
+7. arizona_hpdet_irq now can continue running and:
+7.1 Calls arizona_start_mic() (if a mic was detected)
+7.2 sets info->hpdet_done
+
+Step 7 is undesirable / a bug:
+7.1 causes the device to stay in a high power-state (with MICVDD enabled)
+7.2 causes hpdet to not run on the next jack insertion, which in turn
+    causes the EXTCON_JACK_HEADPHONE state to never get set
+
+This fixes both issues by skipping these 2 steps when arizona_hpdet_irq
+runs after the jack has been unplugged.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Acked-by: Charles Keepax <ckeepax@opensource.cirrus.com>
+Tested-by: Charles Keepax <ckeepax@opensource.cirrus.com>
+Acked-by: Chanwoo Choi <cw00.choi@samsung.com>
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/extcon/extcon-arizona.c | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c
+index aae82db542a5..f7ef247de46a 100644
+--- a/drivers/extcon/extcon-arizona.c
++++ b/drivers/extcon/extcon-arizona.c
+@@ -601,7 +601,7 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data)
+       struct arizona *arizona = info->arizona;
+       int id_gpio = arizona->pdata.hpdet_id_gpio;
+       unsigned int report = EXTCON_JACK_HEADPHONE;
+-      int ret, reading;
++      int ret, reading, state;
+       bool mic = false;
+       mutex_lock(&info->lock);
+@@ -614,12 +614,11 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data)
+       }
+       /* If the cable was removed while measuring ignore the result */
+-      ret = extcon_get_state(info->edev, EXTCON_MECHANICAL);
+-      if (ret < 0) {
+-              dev_err(arizona->dev, "Failed to check cable state: %d\n",
+-                      ret);
++      state = extcon_get_state(info->edev, EXTCON_MECHANICAL);
++      if (state < 0) {
++              dev_err(arizona->dev, "Failed to check cable state: %d\n", state);
+               goto out;
+-      } else if (!ret) {
++      } else if (!state) {
+               dev_dbg(arizona->dev, "Ignoring HPDET for removed cable\n");
+               goto done;
+       }
+@@ -667,7 +666,7 @@ done:
+               gpio_set_value_cansleep(id_gpio, 0);
+       /* If we have a mic then reenable MICDET */
+-      if (mic || info->mic)
++      if (state && (mic || info->mic))
+               arizona_start_mic(info);
+       if (info->hpdet_active) {
+@@ -675,7 +674,9 @@ done:
+               info->hpdet_active = false;
+       }
+-      info->hpdet_done = true;
++      /* Do not set hp_det done when the cable has been unplugged */
++      if (state)
++              info->hpdet_done = true;
+ out:
+       mutex_unlock(&info->lock);
+-- 
+2.30.2
+
diff --git a/queue-5.12/extcon-arizona-fix-various-races-on-driver-unbind.patch b/queue-5.12/extcon-arizona-fix-various-races-on-driver-unbind.patch
new file mode 100644 (file)
index 0000000..81715ec
--- /dev/null
@@ -0,0 +1,132 @@
+From 4cc7506a272b16f68950def90a9a1f20eb8b12a5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Mar 2021 16:17:57 +0100
+Subject: extcon: arizona: Fix various races on driver unbind
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit e5b499f6fb17bc95a813e85d0796522280203806 ]
+
+We must free/disable all interrupts and cancel all pending works
+before doing further cleanup.
+
+Before this commit arizona_extcon_remove() was doing several
+register writes to shut things down before disabling the IRQs
+and it was cancelling only 1 of the 3 different works used.
+
+Move all the register-writes shutting things down to after
+the disabling of the IRQs and add the 2 missing
+cancel_delayed_work_sync() calls.
+
+This fixes various possible races on driver unbind. One of which
+would always trigger on devices using the mic-clamp feature for
+jack detection. The ARIZONA_MICD_CLAMP_MODE_MASK update was
+done before disabling the IRQs, causing:
+1. arizona_jackdet() to run
+2. detect a jack being inserted (clamp disabled means jack inserted)
+3. call arizona_start_mic() which:
+3.1 Enables the MICVDD regulator
+3.2 takes a pm_runtime_reference
+
+And this was all happening after the ARIZONA_MICD_ENA bit clearing,
+which would undo 3.1 and 3.2 because the ARIZONA_MICD_CLAMP_MODE_MASK
+update was being done after the ARIZONA_MICD_ENA bit clearing.
+
+So this means that arizona_extcon_remove() would exit with
+1. MICVDD enabled and 2. The pm_runtime_reference being unbalanced.
+
+MICVDD still being enabled caused the following oops when the
+regulator is released by the devm framework:
+
+[ 2850.745757] ------------[ cut here ]------------
+[ 2850.745827] WARNING: CPU: 2 PID: 2098 at drivers/regulator/core.c:2123 _regulator_put.part.0+0x19f/0x1b0
+[ 2850.745835] Modules linked in: extcon_arizona ...
+...
+[ 2850.746909] Call Trace:
+[ 2850.746932]  regulator_put+0x2d/0x40
+[ 2850.746946]  release_nodes+0x22a/0x260
+[ 2850.746984]  __device_release_driver+0x190/0x240
+[ 2850.747002]  driver_detach+0xd4/0x120
+...
+[ 2850.747337] ---[ end trace f455dfd7abd9781f ]---
+
+Note this oops is just one of various theoretically possible races caused
+by the wrong ordering inside arizona_extcon_remove(), this fixes the
+ordering fixing all possible races, including the reported oops.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Acked-by: Charles Keepax <ckeepax@opensource.cirrus.com>
+Tested-by: Charles Keepax <ckeepax@opensource.cirrus.com>
+Acked-by: Chanwoo Choi <cw00.choi@samsung.com>
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/extcon/extcon-arizona.c | 40 +++++++++++++++++----------------
+ 1 file changed, 21 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c
+index f7ef247de46a..76aacbac5869 100644
+--- a/drivers/extcon/extcon-arizona.c
++++ b/drivers/extcon/extcon-arizona.c
+@@ -1760,25 +1760,6 @@ static int arizona_extcon_remove(struct platform_device *pdev)
+       bool change;
+       int ret;
+-      ret = regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
+-                                     ARIZONA_MICD_ENA, 0,
+-                                     &change);
+-      if (ret < 0) {
+-              dev_err(&pdev->dev, "Failed to disable micd on remove: %d\n",
+-                      ret);
+-      } else if (change) {
+-              regulator_disable(info->micvdd);
+-              pm_runtime_put(info->dev);
+-      }
+-
+-      gpiod_put(info->micd_pol_gpio);
+-
+-      pm_runtime_disable(&pdev->dev);
+-
+-      regmap_update_bits(arizona->regmap,
+-                         ARIZONA_MICD_CLAMP_CONTROL,
+-                         ARIZONA_MICD_CLAMP_MODE_MASK, 0);
+-
+       if (info->micd_clamp) {
+               jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE;
+               jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL;
+@@ -1794,10 +1775,31 @@ static int arizona_extcon_remove(struct platform_device *pdev)
+       arizona_free_irq(arizona, jack_irq_rise, info);
+       arizona_free_irq(arizona, jack_irq_fall, info);
+       cancel_delayed_work_sync(&info->hpdet_work);
++      cancel_delayed_work_sync(&info->micd_detect_work);
++      cancel_delayed_work_sync(&info->micd_timeout_work);
++
++      ret = regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
++                                     ARIZONA_MICD_ENA, 0,
++                                     &change);
++      if (ret < 0) {
++              dev_err(&pdev->dev, "Failed to disable micd on remove: %d\n",
++                      ret);
++      } else if (change) {
++              regulator_disable(info->micvdd);
++              pm_runtime_put(info->dev);
++      }
++
++      regmap_update_bits(arizona->regmap,
++                         ARIZONA_MICD_CLAMP_CONTROL,
++                         ARIZONA_MICD_CLAMP_MODE_MASK, 0);
+       regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,
+                          ARIZONA_JD1_ENA, 0);
+       arizona_clk32k_disable(arizona);
++      gpiod_put(info->micd_pol_gpio);
++
++      pm_runtime_disable(&pdev->dev);
++
+       return 0;
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.12/fpga-dfl-pci-add-did-for-d5005-pac-cards.patch b/queue-5.12/fpga-dfl-pci-add-did-for-d5005-pac-cards.patch
new file mode 100644 (file)
index 0000000..b24aa7c
--- /dev/null
@@ -0,0 +1,60 @@
+From 7d146faac80606a025becc2400cc900f83943dcb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Apr 2021 16:52:59 -0700
+Subject: fpga: dfl: pci: add DID for D5005 PAC cards
+
+From: Russ Weight <russell.h.weight@intel.com>
+
+[ Upstream commit a78a51a851ed3edc83264a67e2ba77a34f27965f ]
+
+This patch adds the approved PCI Express Device IDs for the
+PF and VF for the card for D5005 PAC cards.
+
+Signed-off-by: Russ Weight <russell.h.weight@intel.com>
+Signed-off-by: Matthew Gerlach <matthew.gerlach@linux.intel.com>
+Signed-off-by: Moritz Fischer <mdf@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/fpga/dfl-pci.c | 18 +++++++++++-------
+ 1 file changed, 11 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/fpga/dfl-pci.c b/drivers/fpga/dfl-pci.c
+index 04e47e266f26..b44523ea8c91 100644
+--- a/drivers/fpga/dfl-pci.c
++++ b/drivers/fpga/dfl-pci.c
+@@ -69,14 +69,16 @@ static void cci_pci_free_irq(struct pci_dev *pcidev)
+ }
+ /* PCI Device ID */
+-#define PCIE_DEVICE_ID_PF_INT_5_X     0xBCBD
+-#define PCIE_DEVICE_ID_PF_INT_6_X     0xBCC0
+-#define PCIE_DEVICE_ID_PF_DSC_1_X     0x09C4
+-#define PCIE_DEVICE_ID_INTEL_PAC_N3000        0x0B30
++#define PCIE_DEVICE_ID_PF_INT_5_X             0xBCBD
++#define PCIE_DEVICE_ID_PF_INT_6_X             0xBCC0
++#define PCIE_DEVICE_ID_PF_DSC_1_X             0x09C4
++#define PCIE_DEVICE_ID_INTEL_PAC_N3000                0x0B30
++#define PCIE_DEVICE_ID_INTEL_PAC_D5005                0x0B2B
+ /* VF Device */
+-#define PCIE_DEVICE_ID_VF_INT_5_X     0xBCBF
+-#define PCIE_DEVICE_ID_VF_INT_6_X     0xBCC1
+-#define PCIE_DEVICE_ID_VF_DSC_1_X     0x09C5
++#define PCIE_DEVICE_ID_VF_INT_5_X             0xBCBF
++#define PCIE_DEVICE_ID_VF_INT_6_X             0xBCC1
++#define PCIE_DEVICE_ID_VF_DSC_1_X             0x09C5
++#define PCIE_DEVICE_ID_INTEL_PAC_D5005_VF     0x0B2C
+ static struct pci_device_id cci_pcie_id_tbl[] = {
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_INT_5_X),},
+@@ -86,6 +88,8 @@ static struct pci_device_id cci_pcie_id_tbl[] = {
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_DSC_1_X),},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_DSC_1_X),},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_PAC_N3000),},
++      {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_PAC_D5005),},
++      {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_PAC_D5005_VF),},
+       {0,}
+ };
+ MODULE_DEVICE_TABLE(pci, cci_pcie_id_tbl);
+-- 
+2.30.2
+
diff --git a/queue-5.12/genirq-matrix-prevent-allocation-counter-corruption.patch b/queue-5.12/genirq-matrix-prevent-allocation-counter-corruption.patch
new file mode 100644 (file)
index 0000000..7ef8698
--- /dev/null
@@ -0,0 +1,51 @@
+From db9f4965f37edaa55fad69d28eec994c9de62e18 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Mar 2021 12:18:23 +0100
+Subject: genirq/matrix: Prevent allocation counter corruption
+
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+
+[ Upstream commit c93a5e20c3c2dabef8ea360a3d3f18c6f68233ab ]
+
+When irq_matrix_free() is called for an unallocated vector the
+managed_allocated and total_allocated counters get out of sync with the
+real state of the matrix. Later, when the last interrupt is freed, these
+counters will underflow resulting in UINTMAX because the counters are
+unsigned.
+
+While this is certainly a problem of the calling code, this can be catched
+in the allocator by checking the allocation bit for the to be freed vector
+which simplifies debugging.
+
+An example of the problem described above:
+https://lore.kernel.org/lkml/20210318192819.636943062@linutronix.de/
+
+Add the missing sanity check and emit a warning when it triggers.
+
+Suggested-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Link: https://lore.kernel.org/r/20210319111823.1105248-1-vkuznets@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/irq/matrix.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/irq/matrix.c b/kernel/irq/matrix.c
+index 651a4ad6d711..8e586858bcf4 100644
+--- a/kernel/irq/matrix.c
++++ b/kernel/irq/matrix.c
+@@ -423,7 +423,9 @@ void irq_matrix_free(struct irq_matrix *m, unsigned int cpu,
+       if (WARN_ON_ONCE(bit < m->alloc_start || bit >= m->alloc_end))
+               return;
+-      clear_bit(bit, cm->alloc_map);
++      if (WARN_ON_ONCE(!test_and_clear_bit(bit, cm->alloc_map)))
++              return;
++
+       cm->allocated--;
+       if(managed)
+               cm->managed_allocated--;
+-- 
+2.30.2
+
diff --git a/queue-5.12/intel_th-consistency-and-off-by-one-fix.patch b/queue-5.12/intel_th-consistency-and-off-by-one-fix.patch
new file mode 100644 (file)
index 0000000..43213d1
--- /dev/null
@@ -0,0 +1,49 @@
+From 07992a1a89cc14c8ad65648602fb13011d130131 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Apr 2021 20:12:49 +0300
+Subject: intel_th: Consistency and off-by-one fix
+
+From: Pavel Machek <pavel@ucw.cz>
+
+[ Upstream commit 18ffbc47d45a1489b664dd68fb3a7610a6e1dea3 ]
+
+Consistently use "< ... +1" in for loops.
+
+Fix of-by-one in for_each_set_bit().
+
+Signed-off-by: Pavel Machek <pavel@denx.de>
+Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Link: https://lore.kernel.org/lkml/20190724095841.GA6952@amd/
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/20210414171251.14672-6-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/gth.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/hwtracing/intel_th/gth.c b/drivers/hwtracing/intel_th/gth.c
+index f72803a02391..28509b02a0b5 100644
+--- a/drivers/hwtracing/intel_th/gth.c
++++ b/drivers/hwtracing/intel_th/gth.c
+@@ -543,7 +543,7 @@ static void intel_th_gth_disable(struct intel_th_device *thdev,
+       output->active = false;
+       for_each_set_bit(master, gth->output[output->port].master,
+-                       TH_CONFIGURABLE_MASTERS) {
++                       TH_CONFIGURABLE_MASTERS + 1) {
+               gth_master_set(gth, master, -1);
+       }
+       spin_unlock(&gth->gth_lock);
+@@ -697,7 +697,7 @@ static void intel_th_gth_unassign(struct intel_th_device *thdev,
+       othdev->output.port = -1;
+       othdev->output.active = false;
+       gth->output[port].output = NULL;
+-      for (master = 0; master <= TH_CONFIGURABLE_MASTERS; master++)
++      for (master = 0; master < TH_CONFIGURABLE_MASTERS + 1; master++)
+               if (gth->master[master] == port)
+                       gth->master[master] = -1;
+       spin_unlock(&gth->gth_lock);
+-- 
+2.30.2
+
diff --git a/queue-5.12/io_uring-safer-sq_creds-putting.patch b/queue-5.12/io_uring-safer-sq_creds-putting.patch
new file mode 100644 (file)
index 0000000..af7c571
--- /dev/null
@@ -0,0 +1,46 @@
+From bc8689be8ff3a24bcd6c468d22998043b17919dc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Apr 2021 12:03:32 +0100
+Subject: io_uring: safer sq_creds putting
+
+From: Pavel Begunkov <asml.silence@gmail.com>
+
+[ Upstream commit 07db298a1c96bdba2102d60ad51fcecb961177c9 ]
+
+Put sq_creds as a part of io_ring_ctx_free(), it's easy to miss doing it
+in io_sq_thread_finish(), especially considering past mistakes related
+to ring creation failures.
+
+Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
+Link: https://lore.kernel.org/r/3becb1866467a1de82a97345a0a90d7fb8ff875e.1618916549.git.asml.silence@gmail.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/io_uring.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/fs/io_uring.c b/fs/io_uring.c
+index dff34975d86b..0bc4727e8a90 100644
+--- a/fs/io_uring.c
++++ b/fs/io_uring.c
+@@ -7200,8 +7200,6 @@ static void io_sq_thread_finish(struct io_ring_ctx *ctx)
+               io_put_sq_data(sqd);
+               ctx->sq_data = NULL;
+-              if (ctx->sq_creds)
+-                      put_cred(ctx->sq_creds);
+       }
+ }
+@@ -8469,6 +8467,8 @@ static void io_ring_ctx_free(struct io_ring_ctx *ctx)
+       mutex_unlock(&ctx->uring_lock);
+       io_eventfd_unregister(ctx);
+       io_destroy_buffers(ctx);
++      if (ctx->sq_creds)
++              put_cred(ctx->sq_creds);
+ #if defined(CONFIG_UNIX)
+       if (ctx->ring_sock) {
+-- 
+2.30.2
+
diff --git a/queue-5.12/kselftest-arm64-mte-fix-compilation-with-native-comp.patch b/queue-5.12/kselftest-arm64-mte-fix-compilation-with-native-comp.patch
new file mode 100644 (file)
index 0000000..7984ed9
--- /dev/null
@@ -0,0 +1,55 @@
+From d8fe5fded582e29ebacba9a4186df9a596c41557 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Mar 2021 16:53:24 +0000
+Subject: kselftest/arm64: mte: Fix compilation with native compiler
+
+From: Andre Przywara <andre.przywara@arm.com>
+
+[ Upstream commit 4a423645bc2690376a7a94b4bb7b2f74bc6206ff ]
+
+The mte selftest Makefile contains a check for GCC, to add the memtag
+-march flag to the compiler options. This check fails if the compiler
+is not explicitly specified, so reverts to the standard "cc", in which
+case --version doesn't mention the "gcc" string we match against:
+$ cc --version | head -n 1
+cc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
+
+This will not add the -march switch to the command line, so compilation
+fails:
+mte_helper.S: Assembler messages:
+mte_helper.S:25: Error: selected processor does not support `irg x0,x0,xzr'
+mte_helper.S:38: Error: selected processor does not support `gmi x1,x0,xzr'
+...
+
+Actually clang accepts the same -march option as well, so we can just
+drop this check and add this unconditionally to the command line, to avoid
+any future issues with this check altogether (gcc actually prints
+basename(argv[0]) when called with --version).
+
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
+Reviewed-by: Mark Brown <broone@kernel.org>
+Link: https://lore.kernel.org/r/20210319165334.29213-2-andre.przywara@arm.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/arm64/mte/Makefile | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/tools/testing/selftests/arm64/mte/Makefile b/tools/testing/selftests/arm64/mte/Makefile
+index 0b3af552632a..df15d44aeb8d 100644
+--- a/tools/testing/selftests/arm64/mte/Makefile
++++ b/tools/testing/selftests/arm64/mte/Makefile
+@@ -6,9 +6,7 @@ SRCS := $(filter-out mte_common_util.c,$(wildcard *.c))
+ PROGS := $(patsubst %.c,%,$(SRCS))
+ #Add mte compiler option
+-ifneq ($(shell $(CC) --version 2>&1 | head -n 1 | grep gcc),)
+ CFLAGS += -march=armv8.5-a+memtag
+-endif
+ #check if the compiler works well
+ mte_cc_support := $(shell if ($(CC) $(CFLAGS) -E -x c /dev/null -o /dev/null 2>&1) then echo "1"; fi)
+-- 
+2.30.2
+
diff --git a/queue-5.12/kselftest-arm64-mte-fix-mte-feature-detection.patch b/queue-5.12/kselftest-arm64-mte-fix-mte-feature-detection.patch
new file mode 100644 (file)
index 0000000..e9037a5
--- /dev/null
@@ -0,0 +1,62 @@
+From 2622b2646ddddae2a951ba38d311a40da8916970 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Mar 2021 16:53:29 +0000
+Subject: kselftest/arm64: mte: Fix MTE feature detection
+
+From: Andre Przywara <andre.przywara@arm.com>
+
+[ Upstream commit 592432862cc4019075a7196d9961562c49507d6f ]
+
+To check whether the CPU and kernel support the MTE features we want
+to test, we use an (emulated) CPU ID register read. However we only
+check against a very particular feature version (0b0010), even though
+the ARM ARM promises ID register features to be backwards compatible.
+
+While this could be fixed by using ">=" instead of "==", we should
+actually use the explicit HWCAP2_MTE hardware capability, exposed by the
+kernel via the ELF auxiliary vectors.
+
+That moves this responsibility to the kernel, and fixes running the
+tests on machines with FEAT_MTE3 capability.
+
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Reviewed-by: Mark Brown <broone@kernel.org>
+Link: https://lore.kernel.org/r/20210319165334.29213-7-andre.przywara@arm.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/arm64/mte/mte_common_util.c | 13 ++-----------
+ 1 file changed, 2 insertions(+), 11 deletions(-)
+
+diff --git a/tools/testing/selftests/arm64/mte/mte_common_util.c b/tools/testing/selftests/arm64/mte/mte_common_util.c
+index 39f8908988ea..70665ba88cbb 100644
+--- a/tools/testing/selftests/arm64/mte/mte_common_util.c
++++ b/tools/testing/selftests/arm64/mte/mte_common_util.c
+@@ -278,22 +278,13 @@ int mte_switch_mode(int mte_option, unsigned long incl_mask)
+       return 0;
+ }
+-#define ID_AA64PFR1_MTE_SHIFT         8
+-#define ID_AA64PFR1_MTE                       2
+-
+ int mte_default_setup(void)
+ {
+-      unsigned long hwcaps = getauxval(AT_HWCAP);
++      unsigned long hwcaps2 = getauxval(AT_HWCAP2);
+       unsigned long en = 0;
+       int ret;
+-      if (!(hwcaps & HWCAP_CPUID)) {
+-              ksft_print_msg("FAIL: CPUID registers unavailable\n");
+-              return KSFT_FAIL;
+-      }
+-      /* Read ID_AA64PFR1_EL1 register */
+-      asm volatile("mrs %0, id_aa64pfr1_el1" : "=r"(hwcaps) : : "memory");
+-      if (((hwcaps >> ID_AA64PFR1_MTE_SHIFT) & MT_TAG_MASK) != ID_AA64PFR1_MTE) {
++      if (!(hwcaps2 & HWCAP2_MTE)) {
+               ksft_print_msg("FAIL: MTE features unavailable\n");
+               return KSFT_SKIP;
+       }
+-- 
+2.30.2
+
diff --git a/queue-5.12/kvfree_rcu-use-same-set-of-gfp-flags-as-does-single-.patch b/queue-5.12/kvfree_rcu-use-same-set-of-gfp-flags-as-does-single-.patch
new file mode 100644 (file)
index 0000000..0ca885a
--- /dev/null
@@ -0,0 +1,97 @@
+From d73e8ddb60f296ccb44681c11cc93ff21b7c542f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Jan 2021 21:05:05 +0100
+Subject: kvfree_rcu: Use same set of GFP flags as does single-argument
+
+From: Uladzislau Rezki (Sony) <urezki@gmail.com>
+
+[ Upstream commit ee6ddf58475cce8a3d3697614679cd8cb4a6f583 ]
+
+Running an rcuscale stress-suite can lead to "Out of memory" of a
+system. This can happen under high memory pressure with a small amount
+of physical memory.
+
+For example, a KVM test configuration with 64 CPUs and 512 megabytes
+can result in OOM when running rcuscale with below parameters:
+
+../kvm.sh --torture rcuscale --allcpus --duration 10 --kconfig CONFIG_NR_CPUS=64 \
+--bootargs "rcuscale.kfree_rcu_test=1 rcuscale.kfree_nthreads=16 rcuscale.holdoff=20 \
+  rcuscale.kfree_loops=10000 torture.disable_onoff_at_boot" --trust-make
+
+<snip>
+[   12.054448] kworker/1:1H invoked oom-killer: gfp_mask=0x2cc0(GFP_KERNEL|__GFP_NOWARN), order=0, oom_score_adj=0
+[   12.055303] CPU: 1 PID: 377 Comm: kworker/1:1H Not tainted 5.11.0-rc3+ #510
+[   12.055416] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.12.0-1 04/01/2014
+[   12.056485] Workqueue: events_highpri fill_page_cache_func
+[   12.056485] Call Trace:
+[   12.056485]  dump_stack+0x57/0x6a
+[   12.056485]  dump_header+0x4c/0x30a
+[   12.056485]  ? del_timer_sync+0x20/0x30
+[   12.056485]  out_of_memory.cold.47+0xa/0x7e
+[   12.056485]  __alloc_pages_slowpath.constprop.123+0x82f/0xc00
+[   12.056485]  __alloc_pages_nodemask+0x289/0x2c0
+[   12.056485]  __get_free_pages+0x8/0x30
+[   12.056485]  fill_page_cache_func+0x39/0xb0
+[   12.056485]  process_one_work+0x1ed/0x3b0
+[   12.056485]  ? process_one_work+0x3b0/0x3b0
+[   12.060485]  worker_thread+0x28/0x3c0
+[   12.060485]  ? process_one_work+0x3b0/0x3b0
+[   12.060485]  kthread+0x138/0x160
+[   12.060485]  ? kthread_park+0x80/0x80
+[   12.060485]  ret_from_fork+0x22/0x30
+[   12.062156] Mem-Info:
+[   12.062350] active_anon:0 inactive_anon:0 isolated_anon:0
+[   12.062350]  active_file:0 inactive_file:0 isolated_file:0
+[   12.062350]  unevictable:0 dirty:0 writeback:0
+[   12.062350]  slab_reclaimable:2797 slab_unreclaimable:80920
+[   12.062350]  mapped:1 shmem:2 pagetables:8 bounce:0
+[   12.062350]  free:10488 free_pcp:1227 free_cma:0
+...
+[   12.101610] Out of memory and no killable processes...
+[   12.102042] Kernel panic - not syncing: System is deadlocked on memory
+[   12.102583] CPU: 1 PID: 377 Comm: kworker/1:1H Not tainted 5.11.0-rc3+ #510
+[   12.102600] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.12.0-1 04/01/2014
+<snip>
+
+Because kvfree_rcu() has a fallback path, memory allocation failure is
+not the end of the world.  Furthermore, the added overhead of aggressive
+GFP settings must be balanced against the overhead of the fallback path,
+which is a cache miss for double-argument kvfree_rcu() and a call to
+synchronize_rcu() for single-argument kvfree_rcu().  The current choice
+of GFP_KERNEL|__GFP_NOWARN can result in longer latencies than a call
+to synchronize_rcu(), so less-tenacious GFP flags would be helpful.
+
+Here is the tradeoff that must be balanced:
+    a) Minimize use of the fallback path,
+    b) Avoid pushing the system into OOM,
+    c) Bound allocation latency to that of synchronize_rcu(), and
+    d) Leave the emergency reserves to use cases lacking fallbacks.
+
+This commit therefore changes GFP flags from GFP_KERNEL|__GFP_NOWARN to
+GFP_KERNEL|__GFP_NORETRY|__GFP_NOMEMALLOC|__GFP_NOWARN.  This combination
+leaves the emergency reserves alone and can initiate reclaim, but will
+not invoke the OOM killer.
+
+Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/rcu/tree.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
+index da6f5213fb74..2a739c5fcca5 100644
+--- a/kernel/rcu/tree.c
++++ b/kernel/rcu/tree.c
+@@ -3464,7 +3464,7 @@ static void fill_page_cache_func(struct work_struct *work)
+       for (i = 0; i < rcu_min_cached_objs; i++) {
+               bnode = (struct kvfree_rcu_bulk_data *)
+-                      __get_free_page(GFP_KERNEL | __GFP_NOWARN);
++                      __get_free_page(GFP_KERNEL | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN);
+               if (bnode) {
+                       raw_spin_lock_irqsave(&krcp->lock, flags);
+-- 
+2.30.2
+
diff --git a/queue-5.12/media-adv7604-fix-possible-use-after-free-in-adv76xx.patch b/queue-5.12/media-adv7604-fix-possible-use-after-free-in-adv76xx.patch
new file mode 100644 (file)
index 0000000..ee9f10e
--- /dev/null
@@ -0,0 +1,43 @@
+From d74395c59e0d50bcddc8351ab044e2ba1e1a014b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Apr 2021 15:42:46 +0200
+Subject: media: adv7604: fix possible use-after-free in adv76xx_remove()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit fa56f5f1fe31c2050675fa63b84963ebd504a5b3 ]
+
+This driver's remove path calls cancel_delayed_work(). However, that
+function does not wait until the work function finishes. This means
+that the callback function may still be running after the driver's
+remove function has finished, which would result in a use-after-free.
+
+Fix by calling cancel_delayed_work_sync(), which ensures that
+the work is properly cancelled, no longer running, and unable
+to re-schedule itself.
+
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.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/i2c/adv7604.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
+index 09004d928d11..d1f58795794f 100644
+--- a/drivers/media/i2c/adv7604.c
++++ b/drivers/media/i2c/adv7604.c
+@@ -3616,7 +3616,7 @@ static int adv76xx_remove(struct i2c_client *client)
+       io_write(sd, 0x6e, 0);
+       io_write(sd, 0x73, 0);
+-      cancel_delayed_work(&state->delayed_work_enable_hotplug);
++      cancel_delayed_work_sync(&state->delayed_work_enable_hotplug);
+       v4l2_async_unregister_subdev(sd);
+       media_entity_cleanup(&sd->entity);
+       adv76xx_unregister_clients(to_state(sd));
+-- 
+2.30.2
+
diff --git a/queue-5.12/media-cx23885-add-more-quirks-for-reset-dma-on-some-.patch b/queue-5.12/media-cx23885-add-more-quirks-for-reset-dma-on-some-.patch
new file mode 100644 (file)
index 0000000..b43d83d
--- /dev/null
@@ -0,0 +1,50 @@
+From 23934cbc0285367738a1768052e7e2ad196aca48 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Jan 2021 05:52:05 +0100
+Subject: media: cx23885: add more quirks for reset DMA on some AMD IOMMU
+
+From: Brad Love <brad@nextdimension.cc>
+
+[ Upstream commit 5f864cfbf59bfed2057bd214ce7fbf6ad420d54b ]
+
+The folowing AMD IOMMU are affected by the RiSC engine stall, requiring a
+reset to maintain continual operation. After being added to the
+broken_dev_id list the systems are functional long term.
+
+0x1481 is the PCI ID for the IOMMU found on Starship/Matisse
+
+0x1419 is the PCI ID for the IOMMU found on 15h (Models 10h-1fh) family
+
+0x5a23 is the PCI ID for the IOMMU found on RD890S/RD990
+
+Signed-off-by: Brad Love <brad@nextdimension.cc>
+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/pci/cx23885/cx23885-core.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c
+index 22f55a7840a6..d0ca260ecf70 100644
+--- a/drivers/media/pci/cx23885/cx23885-core.c
++++ b/drivers/media/pci/cx23885/cx23885-core.c
+@@ -2077,6 +2077,15 @@ static struct {
+        * 0x1423 is the PCI ID for the IOMMU found on Kaveri
+        */
+       { PCI_VENDOR_ID_AMD, 0x1423 },
++      /* 0x1481 is the PCI ID for the IOMMU found on Starship/Matisse
++       */
++      { PCI_VENDOR_ID_AMD, 0x1481 },
++      /* 0x1419 is the PCI ID for the IOMMU found on 15h (Models 10h-1fh) family
++       */
++      { PCI_VENDOR_ID_AMD, 0x1419 },
++      /* 0x5a23 is the PCI ID for the IOMMU found on RD890S/RD990
++       */
++      { PCI_VENDOR_ID_ATI, 0x5a23 },
+ };
+ static bool cx23885_does_need_dma_reset(void)
+-- 
+2.30.2
+
diff --git a/queue-5.12/media-drivers-media-pci-sta2x11-fix-kconfig-dependen.patch b/queue-5.12/media-drivers-media-pci-sta2x11-fix-kconfig-dependen.patch
new file mode 100644 (file)
index 0000000..6e75771
--- /dev/null
@@ -0,0 +1,45 @@
+From 1edf9d1845907aaa8d694daf6c9f47ae21047e73 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Feb 2021 09:06:58 +0100
+Subject: media: drivers: media: pci: sta2x11: fix Kconfig dependency on
+ GPIOLIB
+
+From: Julian Braha <julianbraha@gmail.com>
+
+[ Upstream commit 24df8b74c8b2fb42c49ffe8585562da0c96446ff ]
+
+When STA2X11_VIP is enabled, and GPIOLIB is disabled,
+Kbuild gives the following warning:
+
+WARNING: unmet direct dependencies detected for VIDEO_ADV7180
+  Depends on [n]: MEDIA_SUPPORT [=y] && GPIOLIB [=n] && VIDEO_V4L2 [=y] && I2C [=y]
+  Selected by [y]:
+  - STA2X11_VIP [=y] && MEDIA_SUPPORT [=y] && MEDIA_PCI_SUPPORT [=y] && MEDIA_CAMERA_SUPPORT [=y] && PCI [=y] && VIDEO_V4L2 [=y] && VIRT_TO_BUS [=y] && I2C [=y] && (STA2X11 [=n] || COMPILE_TEST [=y]) && MEDIA_SUBDRV_AUTOSELECT [=y]
+
+This is because STA2X11_VIP selects VIDEO_ADV7180
+without selecting or depending on GPIOLIB,
+despite VIDEO_ADV7180 depending on GPIOLIB.
+
+Signed-off-by: Julian Braha <julianbraha@gmail.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/pci/sta2x11/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/media/pci/sta2x11/Kconfig b/drivers/media/pci/sta2x11/Kconfig
+index 4dd98f94a91e..27bb78513631 100644
+--- a/drivers/media/pci/sta2x11/Kconfig
++++ b/drivers/media/pci/sta2x11/Kconfig
+@@ -3,6 +3,7 @@ config STA2X11_VIP
+       tristate "STA2X11 VIP Video For Linux"
+       depends on PCI && VIDEO_V4L2 && VIRT_TO_BUS && I2C
+       depends on STA2X11 || COMPILE_TEST
++      select GPIOLIB if MEDIA_SUBDRV_AUTOSELECT
+       select VIDEO_ADV7180 if MEDIA_SUBDRV_AUTOSELECT
+       select VIDEOBUF2_DMA_CONTIG
+       select MEDIA_CONTROLLER
+-- 
+2.30.2
+
diff --git a/queue-5.12/media-drivers-media-usb-fix-memory-leak-in-zr364xx_p.patch b/queue-5.12/media-drivers-media-usb-fix-memory-leak-in-zr364xx_p.patch
new file mode 100644 (file)
index 0000000..974c10f
--- /dev/null
@@ -0,0 +1,80 @@
+From 0f6b8ed0115065e8cb80bbcedfef8c50e39b1de8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Mar 2021 21:38:26 +0100
+Subject: media: drivers/media/usb: fix memory leak in zr364xx_probe
+
+From: Pavel Skripkin <paskripkin@gmail.com>
+
+[ Upstream commit 9c39be40c0155c43343f53e3a439290c0fec5542 ]
+
+syzbot reported memory leak in zr364xx_probe()[1].
+The problem was in invalid error handling order.
+All error conditions rigth after v4l2_ctrl_handler_init()
+must call v4l2_ctrl_handler_free().
+
+Reported-by: syzbot+efe9aefc31ae1e6f7675@syzkaller.appspotmail.com
+Signed-off-by: Pavel Skripkin <paskripkin@gmail.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/usb/zr364xx/zr364xx.c | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/media/usb/zr364xx/zr364xx.c b/drivers/media/usb/zr364xx/zr364xx.c
+index d29b861367ea..1ef611e08323 100644
+--- a/drivers/media/usb/zr364xx/zr364xx.c
++++ b/drivers/media/usb/zr364xx/zr364xx.c
+@@ -1430,7 +1430,7 @@ static int zr364xx_probe(struct usb_interface *intf,
+       if (hdl->error) {
+               err = hdl->error;
+               dev_err(&udev->dev, "couldn't register control\n");
+-              goto unregister;
++              goto free_hdlr_and_unreg_dev;
+       }
+       /* save the init method used by this camera */
+       cam->method = id->driver_info;
+@@ -1503,7 +1503,7 @@ static int zr364xx_probe(struct usb_interface *intf,
+       if (!cam->read_endpoint) {
+               err = -ENOMEM;
+               dev_err(&intf->dev, "Could not find bulk-in endpoint\n");
+-              goto unregister;
++              goto free_hdlr_and_unreg_dev;
+       }
+       /* v4l */
+@@ -1515,7 +1515,7 @@ static int zr364xx_probe(struct usb_interface *intf,
+       /* load zr364xx board specific */
+       err = zr364xx_board_init(cam);
+       if (err)
+-              goto unregister;
++              goto free_hdlr_and_unreg_dev;
+       err = v4l2_ctrl_handler_setup(hdl);
+       if (err)
+               goto board_uninit;
+@@ -1533,7 +1533,7 @@ static int zr364xx_probe(struct usb_interface *intf,
+       err = video_register_device(&cam->vdev, VFL_TYPE_VIDEO, -1);
+       if (err) {
+               dev_err(&udev->dev, "video_register_device failed\n");
+-              goto free_handler;
++              goto board_uninit;
+       }
+       cam->v4l2_dev.release = zr364xx_release;
+@@ -1541,11 +1541,10 @@ static int zr364xx_probe(struct usb_interface *intf,
+                video_device_node_name(&cam->vdev));
+       return 0;
+-free_handler:
+-      v4l2_ctrl_handler_free(hdl);
+ board_uninit:
+       zr364xx_board_uninit(cam);
+-unregister:
++free_hdlr_and_unreg_dev:
++      v4l2_ctrl_handler_free(hdl);
+       v4l2_device_unregister(&cam->v4l2_dev);
+ free_cam:
+       kfree(cam);
+-- 
+2.30.2
+
diff --git a/queue-5.12/media-dvb-usb-fix-memory-leak-in-dvb_usb_adapter_ini.patch b/queue-5.12/media-dvb-usb-fix-memory-leak-in-dvb_usb_adapter_ini.patch
new file mode 100644 (file)
index 0000000..59ff1d3
--- /dev/null
@@ -0,0 +1,83 @@
+From a61a98ef44cff57adc5c64daa86563f198cfe835 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 28 Mar 2021 21:32:19 +0200
+Subject: media: dvb-usb: fix memory leak in dvb_usb_adapter_init
+
+From: Pavel Skripkin <paskripkin@gmail.com>
+
+[ Upstream commit b7cd0da982e3043f2eec7235ac5530cb18d6af1d ]
+
+syzbot reported memory leak in dvb-usb. The problem was
+in invalid error handling in dvb_usb_adapter_init().
+
+for (n = 0; n < d->props.num_adapters; n++) {
+....
+       if ((ret = dvb_usb_adapter_stream_init(adap)) ||
+               (ret = dvb_usb_adapter_dvb_init(adap, adapter_nrs)) ||
+               (ret = dvb_usb_adapter_frontend_init(adap))) {
+               return ret;
+       }
+...
+       d->num_adapters_initialized++;
+...
+}
+
+In case of error in dvb_usb_adapter_dvb_init() or
+dvb_usb_adapter_dvb_init() d->num_adapters_initialized won't be
+incremented, but dvb_usb_adapter_exit() relies on it:
+
+       for (n = 0; n < d->num_adapters_initialized; n++)
+
+So, allocated objects won't be freed.
+
+Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
+Reported-by: syzbot+3c2be7424cea3b932b0e@syzkaller.appspotmail.com
+Signed-off-by: Sean Young <sean@mess.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/dvb-usb/dvb-usb-init.c | 20 ++++++++++++++++----
+ 1 file changed, 16 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/media/usb/dvb-usb/dvb-usb-init.c b/drivers/media/usb/dvb-usb/dvb-usb-init.c
+index c1a7634e27b4..adc8b287326b 100644
+--- a/drivers/media/usb/dvb-usb/dvb-usb-init.c
++++ b/drivers/media/usb/dvb-usb/dvb-usb-init.c
+@@ -79,11 +79,17 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs)
+                       }
+               }
+-              if ((ret = dvb_usb_adapter_stream_init(adap)) ||
+-                      (ret = dvb_usb_adapter_dvb_init(adap, adapter_nrs)) ||
+-                      (ret = dvb_usb_adapter_frontend_init(adap))) {
++              ret = dvb_usb_adapter_stream_init(adap);
++              if (ret)
+                       return ret;
+-              }
++
++              ret = dvb_usb_adapter_dvb_init(adap, adapter_nrs);
++              if (ret)
++                      goto dvb_init_err;
++
++              ret = dvb_usb_adapter_frontend_init(adap);
++              if (ret)
++                      goto frontend_init_err;
+               /* use exclusive FE lock if there is multiple shared FEs */
+               if (adap->fe_adap[1].fe)
+@@ -103,6 +109,12 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs)
+       }
+       return 0;
++
++frontend_init_err:
++      dvb_usb_adapter_dvb_exit(adap);
++dvb_init_err:
++      dvb_usb_adapter_stream_exit(adap);
++      return ret;
+ }
+ static int dvb_usb_adapter_exit(struct dvb_usb_device *d)
+-- 
+2.30.2
+
diff --git a/queue-5.12/media-em28xx-fix-memory-leak.patch b/queue-5.12/media-em28xx-fix-memory-leak.patch
new file mode 100644 (file)
index 0000000..1f3bf33
--- /dev/null
@@ -0,0 +1,41 @@
+From 4257adb815eed74cc53d27c7315f2282659b4b6e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Mar 2021 19:07:53 +0100
+Subject: media: em28xx: fix memory leak
+
+From: Muhammad Usama Anjum <musamaanjum@gmail.com>
+
+[ Upstream commit 0ae10a7dc8992ee682ff0b1752ff7c83d472eef1 ]
+
+If some error occurs, URB buffers should also be freed. If they aren't
+freed with the dvb here, the em28xx_dvb_fini call doesn't frees the URB
+buffers as dvb is set to NULL. The function in which error occurs should
+do all the cleanup for the allocations it had done.
+
+Tested the patch with the reproducer provided by syzbot. This patch
+fixes the memleak.
+
+Reported-by: syzbot+889397c820fa56adf25d@syzkaller.appspotmail.com
+Signed-off-by: Muhammad Usama Anjum <musamaanjum@gmail.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/usb/em28xx/em28xx-dvb.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c
+index 526424279637..471bd74667e3 100644
+--- a/drivers/media/usb/em28xx/em28xx-dvb.c
++++ b/drivers/media/usb/em28xx/em28xx-dvb.c
+@@ -2010,6 +2010,7 @@ ret:
+       return result;
+ out_free:
++      em28xx_uninit_usb_xfer(dev, EM28XX_DIGITAL_MODE);
+       kfree(dvb);
+       dev->dvb = NULL;
+       goto ret;
+-- 
+2.30.2
+
diff --git a/queue-5.12/media-gscpa-stv06xx-fix-memory-leak.patch b/queue-5.12/media-gscpa-stv06xx-fix-memory-leak.patch
new file mode 100644 (file)
index 0000000..80eb8bd
--- /dev/null
@@ -0,0 +1,84 @@
+From 3dd9747001e7c3aa7150e48f87d0bf6148520e1a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Apr 2021 12:31:20 +0200
+Subject: media: gscpa/stv06xx: fix memory leak
+
+From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+
+[ Upstream commit 4f4e6644cd876c844cdb3bea2dd7051787d5ae25 ]
+
+For two of the supported sensors the stv06xx driver allocates memory which
+is stored in sd->sensor_priv. This memory is freed on a disconnect, but if
+the probe() fails, then it isn't freed and so this leaks memory.
+
+Add a new probe_error() op that drivers can use to free any allocated
+memory in case there was a probe failure.
+
+Thanks to Pavel Skripkin <paskripkin@gmail.com> for discovering the cause
+of the memory leak.
+
+Reported-and-tested-by: syzbot+e7f4c64a4248a0340c37@syzkaller.appspotmail.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/usb/gspca/gspca.c           | 2 ++
+ drivers/media/usb/gspca/gspca.h           | 1 +
+ drivers/media/usb/gspca/stv06xx/stv06xx.c | 9 +++++++++
+ 3 files changed, 12 insertions(+)
+
+diff --git a/drivers/media/usb/gspca/gspca.c b/drivers/media/usb/gspca/gspca.c
+index 158c8e28ed2c..47d8f28bfdfc 100644
+--- a/drivers/media/usb/gspca/gspca.c
++++ b/drivers/media/usb/gspca/gspca.c
+@@ -1576,6 +1576,8 @@ out:
+ #endif
+       v4l2_ctrl_handler_free(gspca_dev->vdev.ctrl_handler);
+       v4l2_device_unregister(&gspca_dev->v4l2_dev);
++      if (sd_desc->probe_error)
++              sd_desc->probe_error(gspca_dev);
+       kfree(gspca_dev->usb_buf);
+       kfree(gspca_dev);
+       return ret;
+diff --git a/drivers/media/usb/gspca/gspca.h b/drivers/media/usb/gspca/gspca.h
+index b0ced2e14006..a6554d5e9e1a 100644
+--- a/drivers/media/usb/gspca/gspca.h
++++ b/drivers/media/usb/gspca/gspca.h
+@@ -105,6 +105,7 @@ struct sd_desc {
+       cam_cf_op config;       /* called on probe */
+       cam_op init;            /* called on probe and resume */
+       cam_op init_controls;   /* called on probe */
++      cam_v_op probe_error;   /* called if probe failed, do cleanup here */
+       cam_op start;           /* called on stream on after URBs creation */
+       cam_pkt_op pkt_scan;
+ /* optional operations */
+diff --git a/drivers/media/usb/gspca/stv06xx/stv06xx.c b/drivers/media/usb/gspca/stv06xx/stv06xx.c
+index 95673fc0a99c..d9bc2aacc885 100644
+--- a/drivers/media/usb/gspca/stv06xx/stv06xx.c
++++ b/drivers/media/usb/gspca/stv06xx/stv06xx.c
+@@ -529,12 +529,21 @@ static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
+ static int stv06xx_config(struct gspca_dev *gspca_dev,
+                         const struct usb_device_id *id);
++static void stv06xx_probe_error(struct gspca_dev *gspca_dev)
++{
++      struct sd *sd = (struct sd *)gspca_dev;
++
++      kfree(sd->sensor_priv);
++      sd->sensor_priv = NULL;
++}
++
+ /* sub-driver description */
+ static const struct sd_desc sd_desc = {
+       .name = MODULE_NAME,
+       .config = stv06xx_config,
+       .init = stv06xx_init,
+       .init_controls = stv06xx_init_controls,
++      .probe_error = stv06xx_probe_error,
+       .start = stv06xx_start,
+       .stopN = stv06xx_stopN,
+       .pkt_scan = stv06xx_pkt_scan,
+-- 
+2.30.2
+
diff --git a/queue-5.12/media-gspca-sq905.c-fix-uninitialized-variable.patch b/queue-5.12/media-gspca-sq905.c-fix-uninitialized-variable.patch
new file mode 100644 (file)
index 0000000..25a92cb
--- /dev/null
@@ -0,0 +1,36 @@
+From 654d11784153fed58ca3d91aad9d5c90abd488a7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Mar 2021 15:46:40 +0100
+Subject: media: gspca/sq905.c: fix uninitialized variable
+
+From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+
+[ Upstream commit eaaea4681984c79d2b2b160387b297477f0c1aab ]
+
+act_len can be uninitialized if usb_bulk_msg() returns an error.
+Set it to 0 to avoid a KMSAN error.
+
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Reported-by: syzbot+a4e309017a5f3a24c7b3@syzkaller.appspotmail.com
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/gspca/sq905.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/usb/gspca/sq905.c b/drivers/media/usb/gspca/sq905.c
+index 97799cfb832e..949111070971 100644
+--- a/drivers/media/usb/gspca/sq905.c
++++ b/drivers/media/usb/gspca/sq905.c
+@@ -158,7 +158,7 @@ static int
+ sq905_read_data(struct gspca_dev *gspca_dev, u8 *data, int size, int need_lock)
+ {
+       int ret;
+-      int act_len;
++      int act_len = 0;
+       gspca_dev->usb_buf[0] = '\0';
+       if (need_lock)
+-- 
+2.30.2
+
diff --git a/queue-5.12/media-i2c-adv7511-v4l2-fix-possible-use-after-free-i.patch b/queue-5.12/media-i2c-adv7511-v4l2-fix-possible-use-after-free-i.patch
new file mode 100644 (file)
index 0000000..48ed7fb
--- /dev/null
@@ -0,0 +1,44 @@
+From 301d6169f445b1bd39380fdf47ec680e0174cc4d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Apr 2021 15:48:12 +0200
+Subject: media: i2c: adv7511-v4l2: fix possible use-after-free in
+ adv7511_remove()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 2c9541720c66899adf6f3600984cf3ef151295ad ]
+
+This driver's remove path calls cancel_delayed_work(). However, that
+function does not wait until the work function finishes. This means
+that the callback function may still be running after the driver's
+remove function has finished, which would result in a use-after-free.
+
+Fix by calling cancel_delayed_work_sync(), which ensures that
+the work is properly cancelled, no longer running, and unable
+to re-schedule itself.
+
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.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/i2c/adv7511-v4l2.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/i2c/adv7511-v4l2.c b/drivers/media/i2c/adv7511-v4l2.c
+index a3161d709015..ab7883cff8b2 100644
+--- a/drivers/media/i2c/adv7511-v4l2.c
++++ b/drivers/media/i2c/adv7511-v4l2.c
+@@ -1964,7 +1964,7 @@ static int adv7511_remove(struct i2c_client *client)
+       adv7511_set_isr(sd, false);
+       adv7511_init_setup(sd);
+-      cancel_delayed_work(&state->edid_handler);
++      cancel_delayed_work_sync(&state->edid_handler);
+       i2c_unregister_device(state->i2c_edid);
+       i2c_unregister_device(state->i2c_cec);
+       i2c_unregister_device(state->i2c_pktmem);
+-- 
+2.30.2
+
diff --git a/queue-5.12/media-i2c-adv7842-fix-possible-use-after-free-in-adv.patch b/queue-5.12/media-i2c-adv7842-fix-possible-use-after-free-in-adv.patch
new file mode 100644 (file)
index 0000000..4fa14cf
--- /dev/null
@@ -0,0 +1,43 @@
+From 05f6c34f3194de30d6094e1d5a2fe095a06ccb69 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Apr 2021 15:50:53 +0200
+Subject: media: i2c: adv7842: fix possible use-after-free in adv7842_remove()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 4a15275b6a18597079f18241c87511406575179a ]
+
+This driver's remove path calls cancel_delayed_work(). However, that
+function does not wait until the work function finishes. This means
+that the callback function may still be running after the driver's
+remove function has finished, which would result in a use-after-free.
+
+Fix by calling cancel_delayed_work_sync(), which ensures that
+the work is properly cancelled, no longer running, and unable
+to re-schedule itself.
+
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.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/i2c/adv7842.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c
+index 0855f648416d..f7d2b6cd3008 100644
+--- a/drivers/media/i2c/adv7842.c
++++ b/drivers/media/i2c/adv7842.c
+@@ -3586,7 +3586,7 @@ static int adv7842_remove(struct i2c_client *client)
+       struct adv7842_state *state = to_state(sd);
+       adv7842_irq_enable(sd, false);
+-      cancel_delayed_work(&state->delayed_work_enable_hotplug);
++      cancel_delayed_work_sync(&state->delayed_work_enable_hotplug);
+       v4l2_device_unregister_subdev(sd);
+       media_entity_cleanup(&sd->entity);
+       adv7842_unregister_clients(sd);
+-- 
+2.30.2
+
diff --git a/queue-5.12/media-i2c-tda1997-fix-possible-use-after-free-in-tda.patch b/queue-5.12/media-i2c-tda1997-fix-possible-use-after-free-in-tda.patch
new file mode 100644 (file)
index 0000000..948afc7
--- /dev/null
@@ -0,0 +1,43 @@
+From c30057b304ca52cfad4104f91a727c040bc410b3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Apr 2021 15:49:45 +0200
+Subject: media: i2c: tda1997: Fix possible use-after-free in tda1997x_remove()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 7f820ab5d4eebfe2d970d32a76ae496a6c286f0f ]
+
+This driver's remove path calls cancel_delayed_work(). However, that
+function does not wait until the work function finishes. This means
+that the callback function may still be running after the driver's
+remove function has finished, which would result in a use-after-free.
+
+Fix by calling cancel_delayed_work_sync(), which ensures that
+the work is properly cancelled, no longer running, and unable
+to re-schedule itself.
+
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.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/i2c/tda1997x.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/i2c/tda1997x.c b/drivers/media/i2c/tda1997x.c
+index a09bf0a39d05..89bb7e6dc7a4 100644
+--- a/drivers/media/i2c/tda1997x.c
++++ b/drivers/media/i2c/tda1997x.c
+@@ -2804,7 +2804,7 @@ static int tda1997x_remove(struct i2c_client *client)
+       media_entity_cleanup(&sd->entity);
+       v4l2_ctrl_handler_free(&state->hdl);
+       regulator_bulk_disable(TDA1997X_NUM_SUPPLIES, state->supplies);
+-      cancel_delayed_work(&state->delayed_work_enable_hpd);
++      cancel_delayed_work_sync(&state->delayed_work_enable_hpd);
+       mutex_destroy(&state->page_lock);
+       mutex_destroy(&state->lock);
+-- 
+2.30.2
+
diff --git a/queue-5.12/media-imx-capture-return-epipe-from-__capture_legacy.patch b/queue-5.12/media-imx-capture-return-epipe-from-__capture_legacy.patch
new file mode 100644 (file)
index 0000000..9b34c19
--- /dev/null
@@ -0,0 +1,39 @@
+From e20c621aa3d6f354f9a2898230dedf842921a9f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Feb 2021 05:26:47 +0100
+Subject: media: imx: capture: Return -EPIPE from __capture_legacy_try_fmt()
+
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+
+[ Upstream commit cc271b6754691af74d710b761eaf027e3743e243 ]
+
+The correct return code to report an invalid pipeline configuration is
+-EPIPE. Return it instead of -EINVAL from __capture_legacy_try_fmt()
+when the capture format doesn't match the media bus format of the
+connected subdev.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Reviewed-by: Rui Miguel Silva <rmfrfs@gmail.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/imx/imx-media-capture.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/staging/media/imx/imx-media-capture.c b/drivers/staging/media/imx/imx-media-capture.c
+index e10ce103a5b4..94a0467d673b 100644
+--- a/drivers/staging/media/imx/imx-media-capture.c
++++ b/drivers/staging/media/imx/imx-media-capture.c
+@@ -557,7 +557,7 @@ static int capture_validate_fmt(struct capture_priv *priv)
+               priv->vdev.fmt.fmt.pix.height != f.fmt.pix.height ||
+               priv->vdev.cc->cs != cc->cs ||
+               priv->vdev.compose.width != compose.width ||
+-              priv->vdev.compose.height != compose.height) ? -EINVAL : 0;
++              priv->vdev.compose.height != compose.height) ? -EPIPE : 0;
+ }
+ static int capture_start_streaming(struct vb2_queue *vq, unsigned int count)
+-- 
+2.30.2
+
diff --git a/queue-5.12/media-ite-cir-check-for-receive-overflow.patch b/queue-5.12/media-ite-cir-check-for-receive-overflow.patch
new file mode 100644 (file)
index 0000000..7241bb6
--- /dev/null
@@ -0,0 +1,41 @@
+From a74cbe3a1847a05c3f3a801add3aea985c7fb1b9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Feb 2021 09:08:35 +0100
+Subject: media: ite-cir: check for receive overflow
+
+From: Sean Young <sean@mess.org>
+
+[ Upstream commit 28c7afb07ccfc0a939bb06ac1e7afe669901c65a ]
+
+It's best if this condition is reported.
+
+Signed-off-by: Sean Young <sean@mess.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/rc/ite-cir.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c
+index 0c6229592e13..e5c4a6941d26 100644
+--- a/drivers/media/rc/ite-cir.c
++++ b/drivers/media/rc/ite-cir.c
+@@ -276,8 +276,14 @@ static irqreturn_t ite_cir_isr(int irq, void *data)
+       /* read the interrupt flags */
+       iflags = dev->params.get_irq_causes(dev);
++      /* Check for RX overflow */
++      if (iflags & ITE_IRQ_RX_FIFO_OVERRUN) {
++              dev_warn(&dev->rdev->dev, "receive overflow\n");
++              ir_raw_event_reset(dev->rdev);
++      }
++
+       /* check for the receive interrupt */
+-      if (iflags & (ITE_IRQ_RX_FIFO | ITE_IRQ_RX_FIFO_OVERRUN)) {
++      if (iflags & ITE_IRQ_RX_FIFO) {
+               /* read the FIFO bytes */
+               rx_bytes =
+                       dev->params.get_rx_bytes(dev, rx_buf,
+-- 
+2.30.2
+
diff --git a/queue-5.12/media-media-saa7164-fix-saa7164_encoder_register-mem.patch b/queue-5.12/media-media-saa7164-fix-saa7164_encoder_register-mem.patch
new file mode 100644 (file)
index 0000000..ce7a479
--- /dev/null
@@ -0,0 +1,87 @@
+From 6fb00057cf7d015d47cb5b880b6198f6c3090ad8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Mar 2021 03:53:00 +0100
+Subject: media: media/saa7164: fix saa7164_encoder_register() memory leak bugs
+
+From: Daniel Niv <danielniv3@gmail.com>
+
+[ Upstream commit c759b2970c561e3b56aa030deb13db104262adfe ]
+
+Add a fix for the memory leak bugs that can occur when the
+saa7164_encoder_register() function fails.
+The function allocates memory without explicitly freeing
+it when errors occur.
+Add a better error handling that deallocate the unused buffers before the
+function exits during a fail.
+
+Signed-off-by: Daniel Niv <danielniv3@gmail.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/pci/saa7164/saa7164-encoder.c | 20 +++++++++++---------
+ 1 file changed, 11 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/media/pci/saa7164/saa7164-encoder.c b/drivers/media/pci/saa7164/saa7164-encoder.c
+index 11e1eb6a6809..1d1d32e043f1 100644
+--- a/drivers/media/pci/saa7164/saa7164-encoder.c
++++ b/drivers/media/pci/saa7164/saa7164-encoder.c
+@@ -1008,7 +1008,7 @@ int saa7164_encoder_register(struct saa7164_port *port)
+               printk(KERN_ERR "%s() failed (errno = %d), NO PCI configuration\n",
+                       __func__, result);
+               result = -ENOMEM;
+-              goto failed;
++              goto fail_pci;
+       }
+       /* Establish encoder defaults here */
+@@ -1062,7 +1062,7 @@ int saa7164_encoder_register(struct saa7164_port *port)
+                         100000, ENCODER_DEF_BITRATE);
+       if (hdl->error) {
+               result = hdl->error;
+-              goto failed;
++              goto fail_hdl;
+       }
+       port->std = V4L2_STD_NTSC_M;
+@@ -1080,7 +1080,7 @@ int saa7164_encoder_register(struct saa7164_port *port)
+               printk(KERN_INFO "%s: can't allocate mpeg device\n",
+                       dev->name);
+               result = -ENOMEM;
+-              goto failed;
++              goto fail_hdl;
+       }
+       port->v4l_device->ctrl_handler = hdl;
+@@ -1091,10 +1091,7 @@ int saa7164_encoder_register(struct saa7164_port *port)
+       if (result < 0) {
+               printk(KERN_INFO "%s: can't register mpeg device\n",
+                       dev->name);
+-              /* TODO: We're going to leak here if we don't dealloc
+-               The buffers above. The unreg function can't deal wit it.
+-              */
+-              goto failed;
++              goto fail_reg;
+       }
+       printk(KERN_INFO "%s: registered device video%d [mpeg]\n",
+@@ -1116,9 +1113,14 @@ int saa7164_encoder_register(struct saa7164_port *port)
+       saa7164_api_set_encoder(port);
+       saa7164_api_get_encoder(port);
++      return 0;
+-      result = 0;
+-failed:
++fail_reg:
++      video_device_release(port->v4l_device);
++      port->v4l_device = NULL;
++fail_hdl:
++      v4l2_ctrl_handler_free(hdl);
++fail_pci:
+       return result;
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.12/media-platform-sti-fix-runtime-pm-imbalance-in-regs_.patch b/queue-5.12/media-platform-sti-fix-runtime-pm-imbalance-in-regs_.patch
new file mode 100644 (file)
index 0000000..6b8f8f0
--- /dev/null
@@ -0,0 +1,39 @@
+From 97d99f09e5e520dda71095e85f0ae68cb8498479 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Apr 2021 07:43:13 +0200
+Subject: media: platform: sti: Fix runtime PM imbalance in regs_show
+
+From: Dinghao Liu <dinghao.liu@zju.edu.cn>
+
+[ Upstream commit 69306a947b3ae21e0d1cbfc9508f00fec86c7297 ]
+
+pm_runtime_get_sync() will increase the runtime PM counter
+even it returns an error. Thus a pairing decrement is needed
+to prevent refcount leak. Fix this by replacing this API with
+pm_runtime_resume_and_get(), which will not change the runtime
+PM counter on error.
+
+Signed-off-by: Dinghao Liu <dinghao.liu@zju.edu.cn>
+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/sti/bdisp/bdisp-debug.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/platform/sti/bdisp/bdisp-debug.c b/drivers/media/platform/sti/bdisp/bdisp-debug.c
+index 2b270093009c..a27f638df11c 100644
+--- a/drivers/media/platform/sti/bdisp/bdisp-debug.c
++++ b/drivers/media/platform/sti/bdisp/bdisp-debug.c
+@@ -480,7 +480,7 @@ static int regs_show(struct seq_file *s, void *data)
+       int ret;
+       unsigned int i;
+-      ret = pm_runtime_get_sync(bdisp->dev);
++      ret = pm_runtime_resume_and_get(bdisp->dev);
+       if (ret < 0) {
+               seq_puts(s, "Cannot wake up IP\n");
+               return 0;
+-- 
+2.30.2
+
diff --git a/queue-5.12/media-sun8i-di-fix-runtime-pm-imbalance-in-deinterla.patch b/queue-5.12/media-sun8i-di-fix-runtime-pm-imbalance-in-deinterla.patch
new file mode 100644 (file)
index 0000000..2e042b9
--- /dev/null
@@ -0,0 +1,40 @@
+From dffd9e40afd55b444f82ac7bd3202995df55e404 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Apr 2021 07:46:06 +0200
+Subject: media: sun8i-di: Fix runtime PM imbalance in
+ deinterlace_start_streaming
+
+From: Dinghao Liu <dinghao.liu@zju.edu.cn>
+
+[ Upstream commit f1995d5e43cf897f63b4d7a7f84a252d891ae820 ]
+
+pm_runtime_get_sync() will increase the runtime PM counter
+even it returns an error. Thus a pairing decrement is needed
+to prevent refcount leak. Fix this by replacing this API with
+pm_runtime_resume_and_get(), which will not change the runtime
+PM counter on error.
+
+Signed-off-by: Dinghao Liu <dinghao.liu@zju.edu.cn>
+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/sunxi/sun8i-di/sun8i-di.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c b/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c
+index ed863bf5ea80..671e4a928993 100644
+--- a/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c
++++ b/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c
+@@ -589,7 +589,7 @@ static int deinterlace_start_streaming(struct vb2_queue *vq, unsigned int count)
+       int ret;
+       if (V4L2_TYPE_IS_OUTPUT(vq->type)) {
+-              ret = pm_runtime_get_sync(dev);
++              ret = pm_runtime_resume_and_get(dev);
+               if (ret < 0) {
+                       dev_err(dev, "Failed to enable module\n");
+-- 
+2.30.2
+
diff --git a/queue-5.12/media-tc358743-fix-possible-use-after-free-in-tc3587.patch b/queue-5.12/media-tc358743-fix-possible-use-after-free-in-tc3587.patch
new file mode 100644 (file)
index 0000000..c5d23e3
--- /dev/null
@@ -0,0 +1,43 @@
+From c537402fa50a5a4d094eb92e020eac715feded76 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Apr 2021 15:39:29 +0200
+Subject: media: tc358743: fix possible use-after-free in tc358743_remove()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 6107a4fdf8554a7aa9488bdc835bb010062fa8a9 ]
+
+This driver's remove path calls cancel_delayed_work(). However, that
+function does not wait until the work function finishes. This means
+that the callback function may still be running after the driver's
+remove function has finished, which would result in a use-after-free.
+
+Fix by calling cancel_delayed_work_sync(), which ensures that
+the work is properly cancelled, no longer running, and unable
+to re-schedule itself.
+
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.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/i2c/tc358743.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
+index 831b5b54fd78..1b309bb743c7 100644
+--- a/drivers/media/i2c/tc358743.c
++++ b/drivers/media/i2c/tc358743.c
+@@ -2193,7 +2193,7 @@ static int tc358743_remove(struct i2c_client *client)
+               del_timer_sync(&state->timer);
+               flush_work(&state->work_i2c_poll);
+       }
+-      cancel_delayed_work(&state->delayed_work_enable_hotplug);
++      cancel_delayed_work_sync(&state->delayed_work_enable_hotplug);
+       cec_unregister_adapter(state->cec_adap);
+       v4l2_async_unregister_subdev(sd);
+       v4l2_device_unregister_subdev(sd);
+-- 
+2.30.2
+
diff --git a/queue-5.12/media-uvcvideo-fix-xu-id-print-in-forward-scan.patch b/queue-5.12/media-uvcvideo-fix-xu-id-print-in-forward-scan.patch
new file mode 100644 (file)
index 0000000..d596f74
--- /dev/null
@@ -0,0 +1,35 @@
+From 69ff3fe48e39628928f5152fb736a11f3873cc70 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 21 Feb 2021 22:11:50 +0100
+Subject: media: uvcvideo: Fix XU id print in forward scan
+
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+
+[ Upstream commit 3293448632ff2ae8c7cde4c3475da96138e24ca7 ]
+
+An error message in the forward scan code incorrectly prints the ID of
+the source entity instead of the XU entity being scanned. Fix it.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/uvc/uvc_driver.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
+index 30ef2a3110f7..e55cf02baad6 100644
+--- a/drivers/media/usb/uvc/uvc_driver.c
++++ b/drivers/media/usb/uvc/uvc_driver.c
+@@ -1712,7 +1712,7 @@ static int uvc_scan_chain_forward(struct uvc_video_chain *chain,
+                       if (forward->bNrInPins != 1) {
+                               uvc_dbg(chain->dev, DESCR,
+                                       "Extension unit %d has more than 1 input pin\n",
+-                                      entity->id);
++                                      forward->id);
+                               return -EINVAL;
+                       }
+-- 
+2.30.2
+
diff --git a/queue-5.12/media-uvcvideo-support-devices-that-report-an-ot-as-.patch b/queue-5.12/media-uvcvideo-support-devices-that-report-an-ot-as-.patch
new file mode 100644 (file)
index 0000000..7e17455
--- /dev/null
@@ -0,0 +1,85 @@
+From f9a178ce9977d2b5aedb2f29e46d532f4db20fdb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Mar 2021 11:31:28 +0100
+Subject: media: uvcvideo: Support devices that report an OT as an entity
+ source
+
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+
+[ Upstream commit 4ca052b4ea621d0002a5e5feace51f60ad5e6b23 ]
+
+Some devices reference an output terminal as the source of extension
+units. This is incorrect, as output terminals only have an input pin,
+and thus can't be connected to any entity in the forward direction. The
+resulting topology would cause issues when registering the media
+controller graph. To avoid this problem, connect the extension unit to
+the source of the output terminal instead.
+
+While at it, and while no device has been reported to be affected by
+this issue, also handle forward scans where two output terminals would
+be connected together, and skip the terminals found through such an
+invalid connection.
+
+Reported-and-tested-by: John Nealy <jnealy3@yahoo.com>
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/uvc/uvc_driver.c | 32 ++++++++++++++++++++++++++++++
+ 1 file changed, 32 insertions(+)
+
+diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
+index e55cf02baad6..9a791d8ef200 100644
+--- a/drivers/media/usb/uvc/uvc_driver.c
++++ b/drivers/media/usb/uvc/uvc_driver.c
+@@ -1716,6 +1716,31 @@ static int uvc_scan_chain_forward(struct uvc_video_chain *chain,
+                               return -EINVAL;
+                       }
++                      /*
++                       * Some devices reference an output terminal as the
++                       * source of extension units. This is incorrect, as
++                       * output terminals only have an input pin, and thus
++                       * can't be connected to any entity in the forward
++                       * direction. The resulting topology would cause issues
++                       * when registering the media controller graph. To
++                       * avoid this problem, connect the extension unit to
++                       * the source of the output terminal instead.
++                       */
++                      if (UVC_ENTITY_IS_OTERM(entity)) {
++                              struct uvc_entity *source;
++
++                              source = uvc_entity_by_id(chain->dev,
++                                                        entity->baSourceID[0]);
++                              if (!source) {
++                                      uvc_dbg(chain->dev, DESCR,
++                                              "Can't connect extension unit %u in chain\n",
++                                              forward->id);
++                                      break;
++                              }
++
++                              forward->baSourceID[0] = source->id;
++                      }
++
+                       list_add_tail(&forward->chain, &chain->entities);
+                       if (!found)
+                               uvc_dbg_cont(PROBE, " (->");
+@@ -1735,6 +1760,13 @@ static int uvc_scan_chain_forward(struct uvc_video_chain *chain,
+                               return -EINVAL;
+                       }
++                      if (UVC_ENTITY_IS_OTERM(entity)) {
++                              uvc_dbg(chain->dev, DESCR,
++                                      "Unsupported connection between output terminals %u and %u\n",
++                                      entity->id, forward->id);
++                              break;
++                      }
++
+                       list_add_tail(&forward->chain, &chain->entities);
+                       if (!found)
+                               uvc_dbg_cont(PROBE, " (->");
+-- 
+2.30.2
+
diff --git a/queue-5.12/media-v4l2-ctrls.c-initialize-flags-field-of-p_fwht_.patch b/queue-5.12/media-v4l2-ctrls.c-initialize-flags-field-of-p_fwht_.patch
new file mode 100644 (file)
index 0000000..5080dd4
--- /dev/null
@@ -0,0 +1,40 @@
+From 918f11372b6ec19c409936198541ae44cf6b0599 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Mar 2021 09:49:55 +0100
+Subject: media: v4l2-ctrls.c: initialize flags field of p_fwht_params
+
+From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+
+[ Upstream commit ea1611ba3a544b34f89ffa3d1e833caab30a3f09 ]
+
+The V4L2_CID_STATELESS_FWHT_PARAMS compound control was missing a
+proper initialization of the flags field, so after loading the vicodec
+module for the first time, running v4l2-compliance for the stateless
+decoder would fail on this control because the initial control value
+was considered invalid by the vicodec driver.
+
+Initializing the flags field to sane values fixes this.
+
+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/v4l2-core/v4l2-ctrls.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
+index 016cf6204cbb..77f63773096e 100644
+--- a/drivers/media/v4l2-core/v4l2-ctrls.c
++++ b/drivers/media/v4l2-core/v4l2-ctrls.c
+@@ -1675,6 +1675,8 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx,
+               p_fwht_params->version = V4L2_FWHT_VERSION;
+               p_fwht_params->width = 1280;
+               p_fwht_params->height = 720;
++              p_fwht_params->flags = V4L2_FWHT_FL_PIXENC_YUV |
++                      (2 << V4L2_FWHT_FL_COMPONENTS_NUM_OFFSET);
+               break;
+       }
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.12/media-venus-core-venc-vdec-fix-probe-dependency-erro.patch b/queue-5.12/media-venus-core-venc-vdec-fix-probe-dependency-erro.patch
new file mode 100644 (file)
index 0000000..ab45ff0
--- /dev/null
@@ -0,0 +1,346 @@
+From 0b14a234a16163649698797740d2d2f4f467d04d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Feb 2021 19:11:49 +0100
+Subject: media: venus: core, venc, vdec: Fix probe dependency error
+
+From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+
+[ Upstream commit 08b1cf474b7f72750adebe0f0a35f8e9a3eb75f6 ]
+
+Commit aaaa93eda64b ("media] media: venus: venc: add video encoder files")
+is the last in a series of three commits to add core.c vdec.c and venc.c
+adding core, encoder and decoder.
+
+The encoder and decoder check for core drvdata as set and return -EPROBE_DEFER
+if it has not been set, however both the encoder and decoder rely on
+core.v4l2_dev as valid.
+
+core.v4l2_dev will not be valid until v4l2_device_register() has completed
+in core.c's probe().
+
+Normally this is never seen however, Dmitry reported the following
+backtrace when compiling drivers and firmware directly into a kernel image.
+
+[    5.259968] Hardware name: Qualcomm Technologies, Inc. Robotics RB5 (DT)
+[    5.269850] sd 0:0:0:3: [sdd] Optimal transfer size 524288 bytes
+[    5.275505] Workqueue: events deferred_probe_work_func
+[    5.275513] pstate: 60400005 (nZCv daif +PAN -UAO -TCO BTYPE=--)
+[    5.441211] usb 2-1: new SuperSpeedPlus Gen 2 USB device number 2 using xhci-hcd
+[    5.442486] pc : refcount_warn_saturate+0x140/0x148
+[    5.493756] hub 2-1:1.0: USB hub found
+[    5.496266] lr : refcount_warn_saturate+0x140/0x148
+[    5.500982] hub 2-1:1.0: 4 ports detected
+[    5.503440] sp : ffff80001067b730
+[    5.503442] x29: ffff80001067b730
+[    5.592660] usb 1-1: new high-speed USB device number 2 using xhci-hcd
+[    5.598478] x28: ffff6c6bc1c379b8
+[    5.598480] x27: ffffa5c673852960 x26: ffffa5c673852000
+[    5.598484] x25: ffff6c6bc1c37800 x24: 0000000000000001
+[    5.810652] x23: 0000000000000000 x22: ffffa5c673bc7118
+[    5.813777] hub 1-1:1.0: USB hub found
+[    5.816108] x21: ffffa5c674440000 x20: 0000000000000001
+[    5.820846] hub 1-1:1.0: 4 ports detected
+[    5.825415] x19: ffffa5c6744f4000 x18: ffffffffffffffff
+[    5.825418] x17: 0000000000000000 x16: 0000000000000000
+[    5.825421] x15: 00000a4810c193ba x14: 0000000000000000
+[    5.825424] x13: 00000000000002b8 x12: 000000000000f20a
+[    5.825427] x11: 000000000000f20a x10: 0000000000000038
+[    5.845447] usb 2-1.1: new SuperSpeed Gen 1 USB device number 3 using xhci-hcd
+[    5.845904]
+[    5.845905] x9 : 0000000000000000 x8 : ffff6c6d36fae780
+[    5.871208] x7 : ffff6c6d36faf240 x6 : 0000000000000000
+[    5.876664] x5 : 0000000000000004 x4 : 0000000000000085
+[    5.882121] x3 : 0000000000000119 x2 : ffffa5c6741ef478
+[    5.887578] x1 : 3acbb3926faf5f00 x0 : 0000000000000000
+[    5.893036] Call trace:
+[    5.895551]  refcount_warn_saturate+0x140/0x148
+[    5.900202]  __video_register_device+0x64c/0xd10
+[    5.904944]  venc_probe+0xc4/0x148
+[    5.908444]  platform_probe+0x68/0xe0
+[    5.912210]  really_probe+0x118/0x3e0
+[    5.915977]  driver_probe_device+0x5c/0xc0
+[    5.920187]  __device_attach_driver+0x98/0xb8
+[    5.924661]  bus_for_each_drv+0x68/0xd0
+[    5.928604]  __device_attach+0xec/0x148
+[    5.932547]  device_initial_probe+0x14/0x20
+[    5.936845]  bus_probe_device+0x9c/0xa8
+[    5.940788]  device_add+0x3e8/0x7c8
+[    5.944376]  of_device_add+0x4c/0x60
+[    5.948056]  of_platform_device_create_pdata+0xbc/0x140
+[    5.953425]  of_platform_bus_create+0x17c/0x3c0
+[    5.958078]  of_platform_populate+0x80/0x110
+[    5.962463]  venus_probe+0x2ec/0x4d8
+[    5.966143]  platform_probe+0x68/0xe0
+[    5.969907]  really_probe+0x118/0x3e0
+[    5.973674]  driver_probe_device+0x5c/0xc0
+[    5.977882]  __device_attach_driver+0x98/0xb8
+[    5.982356]  bus_for_each_drv+0x68/0xd0
+[    5.986298]  __device_attach+0xec/0x148
+[    5.990242]  device_initial_probe+0x14/0x20
+[    5.994539]  bus_probe_device+0x9c/0xa8
+[    5.998481]  deferred_probe_work_func+0x74/0xb0
+[    6.003132]  process_one_work+0x1e8/0x360
+[    6.007254]  worker_thread+0x208/0x478
+[    6.011106]  kthread+0x150/0x158
+[    6.014431]  ret_from_fork+0x10/0x30
+[    6.018111] ---[ end trace f074246b1ecdb466 ]---
+
+This patch fixes by
+
+- Only setting drvdata after v4l2_device_register() completes
+- Moving v4l2_device_register() so that suspend/reume in core::probe()
+  stays as-is
+- Changes pm_ops->core_function() to take struct venus_core not struct
+  device
+- Minimal rework of v4l2_device_*register in probe/remove
+
+Reported-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/qcom/venus/core.c      | 30 +++++++++++--------
+ .../media/platform/qcom/venus/pm_helpers.c    | 30 ++++++++-----------
+ .../media/platform/qcom/venus/pm_helpers.h    |  7 +++--
+ 3 files changed, 34 insertions(+), 33 deletions(-)
+
+diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c
+index f9896c121fd8..d2842f496b47 100644
+--- a/drivers/media/platform/qcom/venus/core.c
++++ b/drivers/media/platform/qcom/venus/core.c
+@@ -218,7 +218,6 @@ static int venus_probe(struct platform_device *pdev)
+               return -ENOMEM;
+       core->dev = dev;
+-      platform_set_drvdata(pdev, core);
+       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       core->base = devm_ioremap_resource(dev, r);
+@@ -248,7 +247,7 @@ static int venus_probe(struct platform_device *pdev)
+               return -ENODEV;
+       if (core->pm_ops->core_get) {
+-              ret = core->pm_ops->core_get(dev);
++              ret = core->pm_ops->core_get(core);
+               if (ret)
+                       return ret;
+       }
+@@ -273,6 +272,12 @@ static int venus_probe(struct platform_device *pdev)
+       if (ret)
+               goto err_core_put;
++      ret = v4l2_device_register(dev, &core->v4l2_dev);
++      if (ret)
++              goto err_core_deinit;
++
++      platform_set_drvdata(pdev, core);
++
+       pm_runtime_enable(dev);
+       ret = pm_runtime_get_sync(dev);
+@@ -307,10 +312,6 @@ static int venus_probe(struct platform_device *pdev)
+       if (ret)
+               goto err_venus_shutdown;
+-      ret = v4l2_device_register(dev, &core->v4l2_dev);
+-      if (ret)
+-              goto err_core_deinit;
+-
+       ret = pm_runtime_put_sync(dev);
+       if (ret) {
+               pm_runtime_get_noresume(dev);
+@@ -323,8 +324,6 @@ static int venus_probe(struct platform_device *pdev)
+ err_dev_unregister:
+       v4l2_device_unregister(&core->v4l2_dev);
+-err_core_deinit:
+-      hfi_core_deinit(core, false);
+ err_venus_shutdown:
+       venus_shutdown(core);
+ err_runtime_disable:
+@@ -332,9 +331,11 @@ err_runtime_disable:
+       pm_runtime_set_suspended(dev);
+       pm_runtime_disable(dev);
+       hfi_destroy(core);
++err_core_deinit:
++      hfi_core_deinit(core, false);
+ err_core_put:
+       if (core->pm_ops->core_put)
+-              core->pm_ops->core_put(dev);
++              core->pm_ops->core_put(core);
+       return ret;
+ }
+@@ -360,7 +361,9 @@ static int venus_remove(struct platform_device *pdev)
+       pm_runtime_disable(dev);
+       if (pm_ops->core_put)
+-              pm_ops->core_put(dev);
++              pm_ops->core_put(core);
++
++      v4l2_device_unregister(&core->v4l2_dev);
+       hfi_destroy(core);
+@@ -368,6 +371,7 @@ static int venus_remove(struct platform_device *pdev)
+       icc_put(core->cpucfg_path);
+       v4l2_device_unregister(&core->v4l2_dev);
++
+       mutex_destroy(&core->pm_lock);
+       mutex_destroy(&core->lock);
+       venus_dbgfs_deinit(core);
+@@ -396,7 +400,7 @@ static __maybe_unused int venus_runtime_suspend(struct device *dev)
+               return ret;
+       if (pm_ops->core_power) {
+-              ret = pm_ops->core_power(dev, POWER_OFF);
++              ret = pm_ops->core_power(core, POWER_OFF);
+               if (ret)
+                       return ret;
+       }
+@@ -414,7 +418,7 @@ static __maybe_unused int venus_runtime_suspend(struct device *dev)
+ err_video_path:
+       icc_set_bw(core->cpucfg_path, kbps_to_icc(1000), 0);
+ err_cpucfg_path:
+-      pm_ops->core_power(dev, POWER_ON);
++      pm_ops->core_power(core, POWER_ON);
+       return ret;
+ }
+@@ -434,7 +438,7 @@ static __maybe_unused int venus_runtime_resume(struct device *dev)
+               return ret;
+       if (pm_ops->core_power) {
+-              ret = pm_ops->core_power(dev, POWER_ON);
++              ret = pm_ops->core_power(core, POWER_ON);
+               if (ret)
+                       return ret;
+       }
+diff --git a/drivers/media/platform/qcom/venus/pm_helpers.c b/drivers/media/platform/qcom/venus/pm_helpers.c
+index 43c4e3d9e281..e349d01422c5 100644
+--- a/drivers/media/platform/qcom/venus/pm_helpers.c
++++ b/drivers/media/platform/qcom/venus/pm_helpers.c
+@@ -277,16 +277,13 @@ set_freq:
+       return 0;
+ }
+-static int core_get_v1(struct device *dev)
++static int core_get_v1(struct venus_core *core)
+ {
+-      struct venus_core *core = dev_get_drvdata(dev);
+-
+       return core_clks_get(core);
+ }
+-static int core_power_v1(struct device *dev, int on)
++static int core_power_v1(struct venus_core *core, int on)
+ {
+-      struct venus_core *core = dev_get_drvdata(dev);
+       int ret = 0;
+       if (on == POWER_ON)
+@@ -753,12 +750,12 @@ static int venc_power_v4(struct device *dev, int on)
+       return ret;
+ }
+-static int vcodec_domains_get(struct device *dev)
++static int vcodec_domains_get(struct venus_core *core)
+ {
+       int ret;
+       struct opp_table *opp_table;
+       struct device **opp_virt_dev;
+-      struct venus_core *core = dev_get_drvdata(dev);
++      struct device *dev = core->dev;
+       const struct venus_resources *res = core->res;
+       struct device *pd;
+       unsigned int i;
+@@ -809,9 +806,8 @@ opp_attach_err:
+       return ret;
+ }
+-static void vcodec_domains_put(struct device *dev)
++static void vcodec_domains_put(struct venus_core *core)
+ {
+-      struct venus_core *core = dev_get_drvdata(dev);
+       const struct venus_resources *res = core->res;
+       unsigned int i;
+@@ -834,9 +830,9 @@ skip_pmdomains:
+       dev_pm_opp_detach_genpd(core->opp_table);
+ }
+-static int core_get_v4(struct device *dev)
++static int core_get_v4(struct venus_core *core)
+ {
+-      struct venus_core *core = dev_get_drvdata(dev);
++      struct device *dev = core->dev;
+       const struct venus_resources *res = core->res;
+       int ret;
+@@ -875,7 +871,7 @@ static int core_get_v4(struct device *dev)
+               }
+       }
+-      ret = vcodec_domains_get(dev);
++      ret = vcodec_domains_get(core);
+       if (ret) {
+               if (core->has_opp_table)
+                       dev_pm_opp_of_remove_table(dev);
+@@ -886,14 +882,14 @@ static int core_get_v4(struct device *dev)
+       return 0;
+ }
+-static void core_put_v4(struct device *dev)
++static void core_put_v4(struct venus_core *core)
+ {
+-      struct venus_core *core = dev_get_drvdata(dev);
++      struct device *dev = core->dev;
+       if (legacy_binding)
+               return;
+-      vcodec_domains_put(dev);
++      vcodec_domains_put(core);
+       if (core->has_opp_table)
+               dev_pm_opp_of_remove_table(dev);
+@@ -901,9 +897,9 @@ static void core_put_v4(struct device *dev)
+ }
+-static int core_power_v4(struct device *dev, int on)
++static int core_power_v4(struct venus_core *core, int on)
+ {
+-      struct venus_core *core = dev_get_drvdata(dev);
++      struct device *dev = core->dev;
+       struct device *pmctrl = core->pmdomains[0];
+       int ret = 0;
+diff --git a/drivers/media/platform/qcom/venus/pm_helpers.h b/drivers/media/platform/qcom/venus/pm_helpers.h
+index aa2f6afa2354..a492c50c5543 100644
+--- a/drivers/media/platform/qcom/venus/pm_helpers.h
++++ b/drivers/media/platform/qcom/venus/pm_helpers.h
+@@ -4,14 +4,15 @@
+ #define __VENUS_PM_HELPERS_H__
+ struct device;
++struct venus_core;
+ #define POWER_ON      1
+ #define POWER_OFF     0
+ struct venus_pm_ops {
+-      int (*core_get)(struct device *dev);
+-      void (*core_put)(struct device *dev);
+-      int (*core_power)(struct device *dev, int on);
++      int (*core_get)(struct venus_core *core);
++      void (*core_put)(struct venus_core *core);
++      int (*core_power)(struct venus_core *core, int on);
+       int (*vdec_get)(struct device *dev);
+       void (*vdec_put)(struct device *dev);
+-- 
+2.30.2
+
diff --git a/queue-5.12/media-vivid-update-edid.patch b/queue-5.12/media-vivid-update-edid.patch
new file mode 100644 (file)
index 0000000..2865b85
--- /dev/null
@@ -0,0 +1,56 @@
+From 7b331300400776948a5404e352ccb89ad49e4efa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Mar 2021 08:48:21 +0100
+Subject: media: vivid: update EDID
+
+From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+
+[ Upstream commit 443ec4bbc6116f6f492a7a1282bfd8422c862158 ]
+
+The EDID had a few mistakes as reported by edid-decode:
+
+Block 1, CTA-861 Extension Block:
+  Video Data Block: For improved preferred timing interoperability, set 'Native detailed modes' to 1.
+  Video Capability Data Block: S_PT is equal to S_IT and S_CE, so should be set to 0 instead.
+
+Fixed those.
+
+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/test-drivers/vivid/vivid-core.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/media/test-drivers/vivid/vivid-core.c b/drivers/media/test-drivers/vivid/vivid-core.c
+index 0dc65ef3aa14..ca0ebf6ad9cc 100644
+--- a/drivers/media/test-drivers/vivid/vivid-core.c
++++ b/drivers/media/test-drivers/vivid/vivid-core.c
+@@ -205,13 +205,13 @@ static const u8 vivid_hdmi_edid[256] = {
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7b,
+-      0x02, 0x03, 0x3f, 0xf0, 0x51, 0x61, 0x60, 0x5f,
++      0x02, 0x03, 0x3f, 0xf1, 0x51, 0x61, 0x60, 0x5f,
+       0x5e, 0x5d, 0x10, 0x1f, 0x04, 0x13, 0x22, 0x21,
+       0x20, 0x05, 0x14, 0x02, 0x11, 0x01, 0x23, 0x09,
+       0x07, 0x07, 0x83, 0x01, 0x00, 0x00, 0x6d, 0x03,
+       0x0c, 0x00, 0x10, 0x00, 0x00, 0x3c, 0x21, 0x00,
+       0x60, 0x01, 0x02, 0x03, 0x67, 0xd8, 0x5d, 0xc4,
+-      0x01, 0x78, 0x00, 0x00, 0xe2, 0x00, 0xea, 0xe3,
++      0x01, 0x78, 0x00, 0x00, 0xe2, 0x00, 0xca, 0xe3,
+       0x05, 0x00, 0x00, 0xe3, 0x06, 0x01, 0x00, 0x4d,
+       0xd0, 0x00, 0xa0, 0xf0, 0x70, 0x3e, 0x80, 0x30,
+       0x20, 0x35, 0x00, 0xc0, 0x1c, 0x32, 0x00, 0x00,
+@@ -220,7 +220,7 @@ static const u8 vivid_hdmi_edid[256] = {
+       0x00, 0x00, 0x1a, 0x1a, 0x1d, 0x00, 0x80, 0x51,
+       0xd0, 0x1c, 0x20, 0x40, 0x80, 0x35, 0x00, 0xc0,
+       0x1c, 0x32, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63,
++      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82,
+ };
+ static int vidioc_querycap(struct file *file, void  *priv,
+-- 
+2.30.2
+
diff --git a/queue-5.12/mfd-arizona-fix-rumtime-pm-imbalance-on-error.patch b/queue-5.12/mfd-arizona-fix-rumtime-pm-imbalance-on-error.patch
new file mode 100644 (file)
index 0000000..ad0193b
--- /dev/null
@@ -0,0 +1,39 @@
+From a26ab3d20d17fbbb031c81670f6ed34ebc6fe8ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Apr 2021 13:11:49 +0800
+Subject: mfd: arizona: Fix rumtime PM imbalance on error
+
+From: Dinghao Liu <dinghao.liu@zju.edu.cn>
+
+[ Upstream commit fe6df2b48043bbe1e852b2320501d3b169363c35 ]
+
+pm_runtime_get_sync() will increase the rumtime PM counter
+even it returns an error. Thus a pairing decrement is needed
+to prevent refcount leak. Fix this by replacing this API with
+pm_runtime_resume_and_get(), which will not change the runtime
+PM counter on error.
+
+Signed-off-by: Dinghao Liu <dinghao.liu@zju.edu.cn>
+Acked-by: Charles Keepax <ckeepax@opensource.cirrus.com>
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/arizona-irq.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mfd/arizona-irq.c b/drivers/mfd/arizona-irq.c
+index 077d9ab112b7..d919ae9691e2 100644
+--- a/drivers/mfd/arizona-irq.c
++++ b/drivers/mfd/arizona-irq.c
+@@ -100,7 +100,7 @@ static irqreturn_t arizona_irq_thread(int irq, void *data)
+       unsigned int val;
+       int ret;
+-      ret = pm_runtime_get_sync(arizona->dev);
++      ret = pm_runtime_resume_and_get(arizona->dev);
+       if (ret < 0) {
+               dev_err(arizona->dev, "Failed to resume device: %d\n", ret);
+               return IRQ_NONE;
+-- 
+2.30.2
+
diff --git a/queue-5.12/mfd-da9063-support-smbus-and-i2c-mode.patch b/queue-5.12/mfd-da9063-support-smbus-and-i2c-mode.patch
new file mode 100644 (file)
index 0000000..b371889
--- /dev/null
@@ -0,0 +1,80 @@
+From 32ef8e749df72059eda4d3c80556bcad02002a78 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Mar 2021 17:22:37 +0100
+Subject: mfd: da9063: Support SMBus and I2C mode
+
+From: Hubert Streidl <hubert.streidl@de.bosch.com>
+
+[ Upstream commit 586478bfc9f7e16504d6f64cf18bcbdf6fd0cbc9 ]
+
+By default the PMIC DA9063 2-wire interface is SMBus compliant. This
+means the PMIC will automatically reset the interface when the clock
+signal ceases for more than the SMBus timeout of 35 ms.
+
+If the I2C driver / device is not capable of creating atomic I2C
+transactions, a context change can cause a ceasing of the clock signal.
+This can happen if for example a real-time thread is scheduled. Then
+the DA9063 in SMBus mode will reset the 2-wire interface. Subsequently
+a write message could end up in the wrong register. This could cause
+unpredictable system behavior.
+
+The DA9063 PMIC also supports an I2C compliant mode for the 2-wire
+interface. This mode does not reset the interface when the clock
+signal ceases. Thus the problem depicted above does not occur.
+
+This patch tests for the bus functionality "I2C_FUNC_I2C". It can
+reasonably be assumed that the bus cannot obey SMBus timings if
+this functionality is set. SMBus commands most probably are emulated
+in this case which is prone to the latency issue described above.
+
+This patch enables the I2C bus mode if I2C_FUNC_I2C is set or
+otherwise keeps the default SMBus mode.
+
+Signed-off-by: Hubert Streidl <hubert.streidl@de.bosch.com>
+Signed-off-by: Mark Jonas <mark.jonas@de.bosch.com>
+Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/da9063-i2c.c             | 10 ++++++++++
+ include/linux/mfd/da9063/registers.h |  3 +++
+ 2 files changed, 13 insertions(+)
+
+diff --git a/drivers/mfd/da9063-i2c.c b/drivers/mfd/da9063-i2c.c
+index 3781d0bb7786..783a14af18e2 100644
+--- a/drivers/mfd/da9063-i2c.c
++++ b/drivers/mfd/da9063-i2c.c
+@@ -442,6 +442,16 @@ static int da9063_i2c_probe(struct i2c_client *i2c,
+               return ret;
+       }
++      /* If SMBus is not available and only I2C is possible, enter I2C mode */
++      if (i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C)) {
++              ret = regmap_clear_bits(da9063->regmap, DA9063_REG_CONFIG_J,
++                                      DA9063_TWOWIRE_TO);
++              if (ret < 0) {
++                      dev_err(da9063->dev, "Failed to set Two-Wire Bus Mode.\n");
++                      return -EIO;
++              }
++      }
++
+       return da9063_device_init(da9063, i2c->irq);
+ }
+diff --git a/include/linux/mfd/da9063/registers.h b/include/linux/mfd/da9063/registers.h
+index 1dbabf1b3cb8..6e0f66a2e727 100644
+--- a/include/linux/mfd/da9063/registers.h
++++ b/include/linux/mfd/da9063/registers.h
+@@ -1037,6 +1037,9 @@
+ #define               DA9063_NONKEY_PIN_AUTODOWN      0x02
+ #define               DA9063_NONKEY_PIN_AUTOFLPRT     0x03
++/* DA9063_REG_CONFIG_J (addr=0x10F) */
++#define DA9063_TWOWIRE_TO                     0x40
++
+ /* DA9063_REG_MON_REG_5 (addr=0x116) */
+ #define DA9063_MON_A8_IDX_MASK                        0x07
+ #define               DA9063_MON_A8_IDX_NONE          0x00
+-- 
+2.30.2
+
diff --git a/queue-5.12/mfd-intel-m10-bmc-fix-the-register-access-range.patch b/queue-5.12/mfd-intel-m10-bmc-fix-the-register-access-range.patch
new file mode 100644 (file)
index 0000000..9933be0
--- /dev/null
@@ -0,0 +1,37 @@
+From a0b06954d2e0b62275e920cde446887a41b7b4e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Mar 2021 23:55:45 +0800
+Subject: mfd: intel-m10-bmc: Fix the register access range
+
+From: Xu Yilun <yilun.xu@intel.com>
+
+[ Upstream commit d9b326b2c3673f939941806146aee38e5c635fd0 ]
+
+This patch fixes the max register address of MAX 10 BMC. The range
+0x20000000 ~ 0x200000fc are for control registers of the QSPI flash
+controller, which are not accessible to host.
+
+Signed-off-by: Xu Yilun <yilun.xu@intel.com>
+Reviewed-by: Tom Rix <trix@redhat.com>
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/mfd/intel-m10-bmc.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/linux/mfd/intel-m10-bmc.h b/include/linux/mfd/intel-m10-bmc.h
+index 74d4e193966a..9b54ca13eac3 100644
+--- a/include/linux/mfd/intel-m10-bmc.h
++++ b/include/linux/mfd/intel-m10-bmc.h
+@@ -11,7 +11,7 @@
+ #define M10BMC_LEGACY_SYS_BASE                0x300400
+ #define M10BMC_SYS_BASE                       0x300800
+-#define M10BMC_MEM_END                        0x200000fc
++#define M10BMC_MEM_END                        0x1fffffff
+ /* Register offset of system registers */
+ #define NIOS2_FW_VERSION              0x0
+-- 
+2.30.2
+
diff --git a/queue-5.12/mmc-sdhci-brcmstb-remove-cqe-quirk.patch b/queue-5.12/mmc-sdhci-brcmstb-remove-cqe-quirk.patch
new file mode 100644 (file)
index 0000000..44bd6cb
--- /dev/null
@@ -0,0 +1,37 @@
+From e8dd7fe38d89d24c881cf85108dfa429d9b61b8b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Mar 2021 15:28:34 -0400
+Subject: mmc: sdhci-brcmstb: Remove CQE quirk
+
+From: Al Cooper <alcooperx@gmail.com>
+
+[ Upstream commit f0bdf98fab058efe7bf49732f70a0f26d1143154 ]
+
+Remove the CQHCI_QUIRK_SHORT_TXFR_DESC_SZ quirk because the
+latest chips have this fixed and earlier chips have other
+CQE problems that prevent the feature from being enabled.
+
+Signed-off-by: Al Cooper <alcooperx@gmail.com>
+Acked-by: Florian Fainelli <f.fainelli@gmail.com>
+Link: https://lore.kernel.org/r/20210325192834.42955-1-alcooperx@gmail.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/sdhci-brcmstb.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/mmc/host/sdhci-brcmstb.c b/drivers/mmc/host/sdhci-brcmstb.c
+index f9780c65ebe9..f24623aac2db 100644
+--- a/drivers/mmc/host/sdhci-brcmstb.c
++++ b/drivers/mmc/host/sdhci-brcmstb.c
+@@ -199,7 +199,6 @@ static int sdhci_brcmstb_add_host(struct sdhci_host *host,
+       if (dma64) {
+               dev_dbg(mmc_dev(host->mmc), "Using 64 bit DMA\n");
+               cq_host->caps |= CQHCI_TASK_DESC_SZ_128;
+-              cq_host->quirks |= CQHCI_QUIRK_SHORT_TXFR_DESC_SZ;
+       }
+       ret = cqhci_init(cq_host, host->mmc, dma64);
+-- 
+2.30.2
+
diff --git a/queue-5.12/mmc-sdhci-esdhc-imx-validate-pinctrl-before-use-it.patch b/queue-5.12/mmc-sdhci-esdhc-imx-validate-pinctrl-before-use-it.patch
new file mode 100644 (file)
index 0000000..046120d
--- /dev/null
@@ -0,0 +1,44 @@
+From 008fddb716afc293520b8e3e53813d569ef21a7a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Feb 2021 11:10:04 +0800
+Subject: mmc: sdhci-esdhc-imx: validate pinctrl before use it
+
+From: Peng Fan <peng.fan@nxp.com>
+
+[ Upstream commit f410ee0aa2df050a9505f5c261953e9b18e21206 ]
+
+When imx_data->pinctrl is not a valid pointer, pinctrl_lookup_state
+will trigger kernel panic.
+
+When we boot Dual OS on Jailhouse hypervisor, we let the 1st Linux to
+configure pinmux ready for the 2nd OS, so the 2nd OS not have pinctrl
+settings.
+
+Similar to this commit b62eee9f804e ("mmc: sdhci-esdhc-imx: no fail when no pinctrl available").
+
+Reviewed-by: Bough Chen <haobo.chen@nxp.com>
+Reviewed-by: Alice Guo <alice.guo@nxp.com>
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Link: https://lore.kernel.org/r/1614222604-27066-6-git-send-email-peng.fan@oss.nxp.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/sdhci-esdhc-imx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
+index a20459744d21..94327988da91 100644
+--- a/drivers/mmc/host/sdhci-esdhc-imx.c
++++ b/drivers/mmc/host/sdhci-esdhc-imx.c
+@@ -1488,7 +1488,7 @@ sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
+       mmc_of_parse_voltage(np, &host->ocr_mask);
+-      if (esdhc_is_usdhc(imx_data)) {
++      if (esdhc_is_usdhc(imx_data) && !IS_ERR(imx_data->pinctrl)) {
+               imx_data->pins_100mhz = pinctrl_lookup_state(imx_data->pinctrl,
+                                               ESDHC_PINCTRL_STATE_100MHZ);
+               imx_data->pins_200mhz = pinctrl_lookup_state(imx_data->pinctrl,
+-- 
+2.30.2
+
diff --git a/queue-5.12/mmc-sdhci-pci-add-pci-ids-for-intel-lkf.patch b/queue-5.12/mmc-sdhci-pci-add-pci-ids-for-intel-lkf.patch
new file mode 100644 (file)
index 0000000..86d8459
--- /dev/null
@@ -0,0 +1,49 @@
+From 4f553560866a34066738b1ae0d385fca20a81800 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Mar 2021 07:53:56 +0200
+Subject: mmc: sdhci-pci: Add PCI IDs for Intel LKF
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+[ Upstream commit ee629112be8b4eff71d4d3d108a28bc7dc877e13 ]
+
+Add PCI IDs for Intel LKF eMMC and SD card host controllers.
+
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Link: https://lore.kernel.org/r/20210322055356.24923-1-adrian.hunter@intel.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/sdhci-pci-core.c | 2 ++
+ drivers/mmc/host/sdhci-pci.h      | 2 ++
+ 2 files changed, 4 insertions(+)
+
+diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c
+index 936e4db9060f..bf04a08eeba1 100644
+--- a/drivers/mmc/host/sdhci-pci-core.c
++++ b/drivers/mmc/host/sdhci-pci-core.c
+@@ -1930,6 +1930,8 @@ static const struct pci_device_id pci_ids[] = {
+       SDHCI_PCI_DEVICE(INTEL, CMLH_SD,   intel_byt_sd),
+       SDHCI_PCI_DEVICE(INTEL, JSL_EMMC,  intel_glk_emmc),
+       SDHCI_PCI_DEVICE(INTEL, JSL_SD,    intel_byt_sd),
++      SDHCI_PCI_DEVICE(INTEL, LKF_EMMC,  intel_glk_emmc),
++      SDHCI_PCI_DEVICE(INTEL, LKF_SD,    intel_byt_sd),
+       SDHCI_PCI_DEVICE(O2, 8120,     o2),
+       SDHCI_PCI_DEVICE(O2, 8220,     o2),
+       SDHCI_PCI_DEVICE(O2, 8221,     o2),
+diff --git a/drivers/mmc/host/sdhci-pci.h b/drivers/mmc/host/sdhci-pci.h
+index d0ed232af0eb..8f90c4163bb5 100644
+--- a/drivers/mmc/host/sdhci-pci.h
++++ b/drivers/mmc/host/sdhci-pci.h
+@@ -57,6 +57,8 @@
+ #define PCI_DEVICE_ID_INTEL_CMLH_SD   0x06f5
+ #define PCI_DEVICE_ID_INTEL_JSL_EMMC  0x4dc4
+ #define PCI_DEVICE_ID_INTEL_JSL_SD    0x4df8
++#define PCI_DEVICE_ID_INTEL_LKF_EMMC  0x98c4
++#define PCI_DEVICE_ID_INTEL_LKF_SD    0x98f8
+ #define PCI_DEVICE_ID_SYSKONNECT_8000 0x8000
+ #define PCI_DEVICE_ID_VIA_95D0                0x95d0
+-- 
+2.30.2
+
diff --git a/queue-5.12/nvmet-avoid-queuing-keep-alive-timer-if-it-is-disabl.patch b/queue-5.12/nvmet-avoid-queuing-keep-alive-timer-if-it-is-disabl.patch
new file mode 100644 (file)
index 0000000..33fae17
--- /dev/null
@@ -0,0 +1,60 @@
+From b42157c2ac9eecac485b6384fca6a65c5f536bb6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Apr 2021 10:45:21 +0800
+Subject: nvmet: avoid queuing keep-alive timer if it is disabled
+
+From: Hou Pu <houpu.main@gmail.com>
+
+[ Upstream commit 8f864c595bed20ef85fef3e7314212b73800d51d ]
+
+Issue following command:
+nvme set-feature -f 0xf -v 0 /dev/nvme1n1 # disable keep-alive timer
+nvme admin-passthru -o 0x18 /dev/nvme1n1  # send keep-alive command
+will make keep-alive timer fired and thus delete the controller like
+below:
+
+[247459.907635] nvmet: ctrl 1 keep-alive timer (0 seconds) expired!
+[247459.930294] nvmet: ctrl 1 fatal error occurred!
+
+Avoid this by not queuing delayed keep-alive if it is disabled when
+keep-alive command is received from the admin queue.
+
+Signed-off-by: Hou Pu <houpu.main@gmail.com>
+Tested-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/target/admin-cmd.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c
+index fe6b8aa90b53..81224447605b 100644
+--- a/drivers/nvme/target/admin-cmd.c
++++ b/drivers/nvme/target/admin-cmd.c
+@@ -919,15 +919,21 @@ void nvmet_execute_async_event(struct nvmet_req *req)
+ void nvmet_execute_keep_alive(struct nvmet_req *req)
+ {
+       struct nvmet_ctrl *ctrl = req->sq->ctrl;
++      u16 status = 0;
+       if (!nvmet_check_transfer_len(req, 0))
+               return;
++      if (!ctrl->kato) {
++              status = NVME_SC_KA_TIMEOUT_INVALID;
++              goto out;
++      }
++
+       pr_debug("ctrl %d update keep-alive timer for %d secs\n",
+               ctrl->cntlid, ctrl->kato);
+-
+       mod_delayed_work(system_wq, &ctrl->ka_work, ctrl->kato * HZ);
+-      nvmet_req_complete(req, 0);
++out:
++      nvmet_req_complete(req, status);
+ }
+ u16 nvmet_parse_admin_cmd(struct nvmet_req *req)
+-- 
+2.30.2
+
diff --git a/queue-5.12/nvmet-return-proper-error-code-from-discovery-ctrl.patch b/queue-5.12/nvmet-return-proper-error-code-from-discovery-ctrl.patch
new file mode 100644 (file)
index 0000000..5b2630e
--- /dev/null
@@ -0,0 +1,52 @@
+From fec133a142bba60d5741107a132e5dc52af00721 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Mar 2021 14:52:39 +0800
+Subject: nvmet: return proper error code from discovery ctrl
+
+From: Hou Pu <houpu.main@gmail.com>
+
+[ Upstream commit 79695dcd9ad4463a82def7f42960e6d7baa76f0b ]
+
+Return NVME_SC_INVALID_FIELD from discovery controller like normal
+controller when executing identify or get log page command.
+
+Signed-off-by: Hou Pu <houpu.main@gmail.com>
+Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/target/discovery.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/nvme/target/discovery.c b/drivers/nvme/target/discovery.c
+index 682854e0e079..4845d12e374a 100644
+--- a/drivers/nvme/target/discovery.c
++++ b/drivers/nvme/target/discovery.c
+@@ -178,12 +178,14 @@ static void nvmet_execute_disc_get_log_page(struct nvmet_req *req)
+       if (req->cmd->get_log_page.lid != NVME_LOG_DISC) {
+               req->error_loc =
+                       offsetof(struct nvme_get_log_page_command, lid);
+-              status = NVME_SC_INVALID_OPCODE | NVME_SC_DNR;
++              status = NVME_SC_INVALID_FIELD | NVME_SC_DNR;
+               goto out;
+       }
+       /* Spec requires dword aligned offsets */
+       if (offset & 0x3) {
++              req->error_loc =
++                      offsetof(struct nvme_get_log_page_command, lpo);
+               status = NVME_SC_INVALID_FIELD | NVME_SC_DNR;
+               goto out;
+       }
+@@ -250,7 +252,7 @@ static void nvmet_execute_disc_identify(struct nvmet_req *req)
+       if (req->cmd->identify.cns != NVME_ID_CNS_CTRL) {
+               req->error_loc = offsetof(struct nvme_identify, cns);
+-              status = NVME_SC_INVALID_OPCODE | NVME_SC_DNR;
++              status = NVME_SC_INVALID_FIELD | NVME_SC_DNR;
+               goto out;
+       }
+-- 
+2.30.2
+
diff --git a/queue-5.12/pci-pm-do-not-read-power-state-in-pci_enable_device_.patch b/queue-5.12/pci-pm-do-not-read-power-state-in-pci_enable_device_.patch
new file mode 100644 (file)
index 0000000..d8744a2
--- /dev/null
@@ -0,0 +1,72 @@
+From 4e9cb9678126e5b6bb12cb23d6931b620a8ab5f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Mar 2021 16:51:40 +0100
+Subject: PCI: PM: Do not read power state in pci_enable_device_flags()
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 4514d991d99211f225d83b7e640285f29f0755d0 ]
+
+It should not be necessary to update the current_state field of
+struct pci_dev in pci_enable_device_flags() before calling
+do_pci_enable_device() for the device, because none of the
+code between that point and the pci_set_power_state() call in
+do_pci_enable_device() invoked later depends on it.
+
+Moreover, doing that is actively harmful in some cases.  For example,
+if the given PCI device depends on an ACPI power resource whose _STA
+method initially returns 0 ("off"), but the config space of the PCI
+device is accessible and the power state retrieved from the
+PCI_PM_CTRL register is D0, the current_state field in the struct
+pci_dev representing that device will get out of sync with the
+power.state of its ACPI companion object and that will lead to
+power management issues going forward.
+
+To avoid such issues it is better to leave the current_state value
+as is until it is changed to PCI_D0 by do_pci_enable_device() as
+appropriate.  However, the power state of the device is not changed
+to PCI_D0 if it is already enabled when pci_enable_device_flags()
+gets called for it, so update its current_state in that case, but
+use pci_update_current_state() covering platform PM too for that.
+
+Link: https://lore.kernel.org/lkml/20210314000439.3138941-1-luzmaximilian@gmail.com/
+Reported-by: Maximilian Luz <luzmaximilian@gmail.com>
+Tested-by: Maximilian Luz <luzmaximilian@gmail.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pci.c | 16 +++-------------
+ 1 file changed, 3 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
+index 16a17215f633..e4d4e399004b 100644
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -1870,20 +1870,10 @@ static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags)
+       int err;
+       int i, bars = 0;
+-      /*
+-       * Power state could be unknown at this point, either due to a fresh
+-       * boot or a device removal call.  So get the current power state
+-       * so that things like MSI message writing will behave as expected
+-       * (e.g. if the device really is in D0 at enable time).
+-       */
+-      if (dev->pm_cap) {
+-              u16 pmcsr;
+-              pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
+-              dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK);
+-      }
+-
+-      if (atomic_inc_return(&dev->enable_cnt) > 1)
++      if (atomic_inc_return(&dev->enable_cnt) > 1) {
++              pci_update_current_state(dev, dev->current_state);
+               return 0;               /* already enabled */
++      }
+       bridge = pci_upstream_bridge(dev);
+       if (bridge)
+-- 
+2.30.2
+
diff --git a/queue-5.12/perf-arm_pmu_platform-fix-error-handling.patch b/queue-5.12/perf-arm_pmu_platform-fix-error-handling.patch
new file mode 100644 (file)
index 0000000..b43c380
--- /dev/null
@@ -0,0 +1,36 @@
+From 8be80417f6397421cb2b73f19829f2595a16aff5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 Mar 2021 16:02:41 +0000
+Subject: perf/arm_pmu_platform: Fix error handling
+
+From: Robin Murphy <robin.murphy@arm.com>
+
+[ Upstream commit e338cb6bef254821a8c095018fd27254d74bfd6a ]
+
+If we're aborting after failing to register the PMU device,
+we probably don't want to leak the IRQs that we've claimed.
+
+Signed-off-by: Robin Murphy <robin.murphy@arm.com>
+Link: https://lore.kernel.org/r/53031a607fc8412a60024bfb3bb8cd7141f998f5.1616774562.git.robin.murphy@arm.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/perf/arm_pmu_platform.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/perf/arm_pmu_platform.c b/drivers/perf/arm_pmu_platform.c
+index bb6ae955083a..ef9676418c9f 100644
+--- a/drivers/perf/arm_pmu_platform.c
++++ b/drivers/perf/arm_pmu_platform.c
+@@ -235,7 +235,7 @@ int arm_pmu_device_probe(struct platform_device *pdev,
+       ret = armpmu_register(pmu);
+       if (ret)
+-              goto out_free;
++              goto out_free_irqs;
+       return 0;
+-- 
+2.30.2
+
diff --git a/queue-5.12/perf-arm_pmu_platform-use-dev_err_probe-for-irq-erro.patch b/queue-5.12/perf-arm_pmu_platform-use-dev_err_probe-for-irq-erro.patch
new file mode 100644 (file)
index 0000000..fa3af4e
--- /dev/null
@@ -0,0 +1,52 @@
+From 885197a2a2d5b4412cdc5d67d1eaf39153acd3b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 Mar 2021 16:02:40 +0000
+Subject: perf/arm_pmu_platform: Use dev_err_probe() for IRQ errors
+
+From: Robin Murphy <robin.murphy@arm.com>
+
+[ Upstream commit 11fa1dc8020a2a9e0c59998920092d4df3fb7308 ]
+
+By virtue of using platform_irq_get_optional() under the covers,
+platform_irq_count() needs the target interrupt controller to be
+available and may return -EPROBE_DEFER if it isn't. Let's use
+dev_err_probe() to avoid a spurious error log (and help debug any
+deferral issues) in that case.
+
+Reported-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Robin Murphy <robin.murphy@arm.com>
+Link: https://lore.kernel.org/r/073d5e0d3ed1f040592cb47ca6fe3759f40cc7d1.1616774562.git.robin.murphy@arm.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/perf/arm_pmu_platform.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/perf/arm_pmu_platform.c b/drivers/perf/arm_pmu_platform.c
+index 933bd8410fc2..bb6ae955083a 100644
+--- a/drivers/perf/arm_pmu_platform.c
++++ b/drivers/perf/arm_pmu_platform.c
+@@ -6,6 +6,7 @@
+  * Copyright (C) 2010 ARM Ltd., Will Deacon <will.deacon@arm.com>
+  */
+ #define pr_fmt(fmt) "hw perfevents: " fmt
++#define dev_fmt pr_fmt
+ #include <linux/bug.h>
+ #include <linux/cpumask.h>
+@@ -100,10 +101,8 @@ static int pmu_parse_irqs(struct arm_pmu *pmu)
+       struct pmu_hw_events __percpu *hw_events = pmu->hw_events;
+       num_irqs = platform_irq_count(pdev);
+-      if (num_irqs < 0) {
+-              pr_err("unable to count PMU IRQs\n");
+-              return num_irqs;
+-      }
++      if (num_irqs < 0)
++              return dev_err_probe(&pdev->dev, num_irqs, "unable to count PMU IRQs\n");
+       /*
+        * In this case we have no idea which CPUs are covered by the PMU.
+-- 
+2.30.2
+
diff --git a/queue-5.12/perf-rework-perf_event_exit_event.patch b/queue-5.12/perf-rework-perf_event_exit_event.patch
new file mode 100644 (file)
index 0000000..4535b34
--- /dev/null
@@ -0,0 +1,271 @@
+From 7627a5f4b19e8f6f990969acba3d20124af04cc4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Apr 2021 12:35:56 +0200
+Subject: perf: Rework perf_event_exit_event()
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+[ Upstream commit ef54c1a476aef7eef26fe13ea10dc090952c00f8 ]
+
+Make perf_event_exit_event() more robust, such that we can use it from
+other contexts. Specifically the up and coming remove_on_exec.
+
+For this to work we need to address a few issues. Remove_on_exec will
+not destroy the entire context, so we cannot rely on TASK_TOMBSTONE to
+disable event_function_call() and we thus have to use
+perf_remove_from_context().
+
+When using perf_remove_from_context(), there's two races to consider.
+The first is against close(), where we can have concurrent tear-down
+of the event. The second is against child_list iteration, which should
+not find a half baked event.
+
+To address this, teach perf_remove_from_context() to special case
+!ctx->is_active and about DETACH_CHILD.
+
+[ elver@google.com: fix racing parent/child exit in sync_child_event(). ]
+Signed-off-by: Marco Elver <elver@google.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/20210408103605.1676875-2-elver@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/perf_event.h |   1 +
+ kernel/events/core.c       | 142 +++++++++++++++++++++----------------
+ 2 files changed, 80 insertions(+), 63 deletions(-)
+
+diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
+index 3f7f89ea5e51..3d478abf411c 100644
+--- a/include/linux/perf_event.h
++++ b/include/linux/perf_event.h
+@@ -607,6 +607,7 @@ struct swevent_hlist {
+ #define PERF_ATTACH_TASK_DATA 0x08
+ #define PERF_ATTACH_ITRACE    0x10
+ #define PERF_ATTACH_SCHED_CB  0x20
++#define PERF_ATTACH_CHILD     0x40
+ struct perf_cgroup;
+ struct perf_buffer;
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index 43ceb8dae264..c24ea952e7ae 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -2204,6 +2204,26 @@ out:
+       perf_event__header_size(leader);
+ }
++static void sync_child_event(struct perf_event *child_event);
++
++static void perf_child_detach(struct perf_event *event)
++{
++      struct perf_event *parent_event = event->parent;
++
++      if (!(event->attach_state & PERF_ATTACH_CHILD))
++              return;
++
++      event->attach_state &= ~PERF_ATTACH_CHILD;
++
++      if (WARN_ON_ONCE(!parent_event))
++              return;
++
++      lockdep_assert_held(&parent_event->child_mutex);
++
++      sync_child_event(event);
++      list_del_init(&event->child_list);
++}
++
+ static bool is_orphaned_event(struct perf_event *event)
+ {
+       return event->state == PERF_EVENT_STATE_DEAD;
+@@ -2311,6 +2331,7 @@ group_sched_out(struct perf_event *group_event,
+ }
+ #define DETACH_GROUP  0x01UL
++#define DETACH_CHILD  0x02UL
+ /*
+  * Cross CPU call to remove a performance event
+@@ -2334,6 +2355,8 @@ __perf_remove_from_context(struct perf_event *event,
+       event_sched_out(event, cpuctx, ctx);
+       if (flags & DETACH_GROUP)
+               perf_group_detach(event);
++      if (flags & DETACH_CHILD)
++              perf_child_detach(event);
+       list_del_event(event, ctx);
+       if (!ctx->nr_events && ctx->is_active) {
+@@ -2362,25 +2385,21 @@ static void perf_remove_from_context(struct perf_event *event, unsigned long fla
+       lockdep_assert_held(&ctx->mutex);
+-      event_function_call(event, __perf_remove_from_context, (void *)flags);
+-
+       /*
+-       * The above event_function_call() can NO-OP when it hits
+-       * TASK_TOMBSTONE. In that case we must already have been detached
+-       * from the context (by perf_event_exit_event()) but the grouping
+-       * might still be in-tact.
++       * Because of perf_event_exit_task(), perf_remove_from_context() ought
++       * to work in the face of TASK_TOMBSTONE, unlike every other
++       * event_function_call() user.
+        */
+-      WARN_ON_ONCE(event->attach_state & PERF_ATTACH_CONTEXT);
+-      if ((flags & DETACH_GROUP) &&
+-          (event->attach_state & PERF_ATTACH_GROUP)) {
+-              /*
+-               * Since in that case we cannot possibly be scheduled, simply
+-               * detach now.
+-               */
+-              raw_spin_lock_irq(&ctx->lock);
+-              perf_group_detach(event);
++      raw_spin_lock_irq(&ctx->lock);
++      if (!ctx->is_active) {
++              __perf_remove_from_context(event, __get_cpu_context(ctx),
++                                         ctx, (void *)flags);
+               raw_spin_unlock_irq(&ctx->lock);
++              return;
+       }
++      raw_spin_unlock_irq(&ctx->lock);
++
++      event_function_call(event, __perf_remove_from_context, (void *)flags);
+ }
+ /*
+@@ -12373,14 +12392,17 @@ void perf_pmu_migrate_context(struct pmu *pmu, int src_cpu, int dst_cpu)
+ }
+ EXPORT_SYMBOL_GPL(perf_pmu_migrate_context);
+-static void sync_child_event(struct perf_event *child_event,
+-                             struct task_struct *child)
++static void sync_child_event(struct perf_event *child_event)
+ {
+       struct perf_event *parent_event = child_event->parent;
+       u64 child_val;
+-      if (child_event->attr.inherit_stat)
+-              perf_event_read_event(child_event, child);
++      if (child_event->attr.inherit_stat) {
++              struct task_struct *task = child_event->ctx->task;
++
++              if (task && task != TASK_TOMBSTONE)
++                      perf_event_read_event(child_event, task);
++      }
+       child_val = perf_event_count(child_event);
+@@ -12395,60 +12417,53 @@ static void sync_child_event(struct perf_event *child_event,
+ }
+ static void
+-perf_event_exit_event(struct perf_event *child_event,
+-                    struct perf_event_context *child_ctx,
+-                    struct task_struct *child)
++perf_event_exit_event(struct perf_event *event, struct perf_event_context *ctx)
+ {
+-      struct perf_event *parent_event = child_event->parent;
++      struct perf_event *parent_event = event->parent;
++      unsigned long detach_flags = 0;
+-      /*
+-       * Do not destroy the 'original' grouping; because of the context
+-       * switch optimization the original events could've ended up in a
+-       * random child task.
+-       *
+-       * If we were to destroy the original group, all group related
+-       * operations would cease to function properly after this random
+-       * child dies.
+-       *
+-       * Do destroy all inherited groups, we don't care about those
+-       * and being thorough is better.
+-       */
+-      raw_spin_lock_irq(&child_ctx->lock);
+-      WARN_ON_ONCE(child_ctx->is_active);
++      if (parent_event) {
++              /*
++               * Do not destroy the 'original' grouping; because of the
++               * context switch optimization the original events could've
++               * ended up in a random child task.
++               *
++               * If we were to destroy the original group, all group related
++               * operations would cease to function properly after this
++               * random child dies.
++               *
++               * Do destroy all inherited groups, we don't care about those
++               * and being thorough is better.
++               */
++              detach_flags = DETACH_GROUP | DETACH_CHILD;
++              mutex_lock(&parent_event->child_mutex);
++      }
+-      if (parent_event)
+-              perf_group_detach(child_event);
+-      list_del_event(child_event, child_ctx);
+-      perf_event_set_state(child_event, PERF_EVENT_STATE_EXIT); /* is_event_hup() */
+-      raw_spin_unlock_irq(&child_ctx->lock);
++      perf_remove_from_context(event, detach_flags);
++
++      raw_spin_lock_irq(&ctx->lock);
++      if (event->state > PERF_EVENT_STATE_EXIT)
++              perf_event_set_state(event, PERF_EVENT_STATE_EXIT);
++      raw_spin_unlock_irq(&ctx->lock);
+       /*
+-       * Parent events are governed by their filedesc, retain them.
++       * Child events can be freed.
+        */
+-      if (!parent_event) {
+-              perf_event_wakeup(child_event);
++      if (parent_event) {
++              mutex_unlock(&parent_event->child_mutex);
++              /*
++               * Kick perf_poll() for is_event_hup();
++               */
++              perf_event_wakeup(parent_event);
++              free_event(event);
++              put_event(parent_event);
+               return;
+       }
+-      /*
+-       * Child events can be cleaned up.
+-       */
+-
+-      sync_child_event(child_event, child);
+       /*
+-       * Remove this event from the parent's list
+-       */
+-      WARN_ON_ONCE(parent_event->ctx->parent_ctx);
+-      mutex_lock(&parent_event->child_mutex);
+-      list_del_init(&child_event->child_list);
+-      mutex_unlock(&parent_event->child_mutex);
+-
+-      /*
+-       * Kick perf_poll() for is_event_hup().
++       * Parent events are governed by their filedesc, retain them.
+        */
+-      perf_event_wakeup(parent_event);
+-      free_event(child_event);
+-      put_event(parent_event);
++      perf_event_wakeup(event);
+ }
+ static void perf_event_exit_task_context(struct task_struct *child, int ctxn)
+@@ -12505,7 +12520,7 @@ static void perf_event_exit_task_context(struct task_struct *child, int ctxn)
+       perf_event_task(child, child_ctx, 0);
+       list_for_each_entry_safe(child_event, next, &child_ctx->event_list, event_entry)
+-              perf_event_exit_event(child_event, child_ctx, child);
++              perf_event_exit_event(child_event, child_ctx);
+       mutex_unlock(&child_ctx->mutex);
+@@ -12765,6 +12780,7 @@ inherit_event(struct perf_event *parent_event,
+        */
+       raw_spin_lock_irqsave(&child_ctx->lock, flags);
+       add_event_to_ctx(child_event, child_ctx);
++      child_event->attach_state |= PERF_ATTACH_CHILD;
+       raw_spin_unlock_irqrestore(&child_ctx->lock, flags);
+       /*
+-- 
+2.30.2
+
diff --git a/queue-5.12/phy-phy-twl4030-usb-fix-possible-use-after-free-in-t.patch b/queue-5.12/phy-phy-twl4030-usb-fix-possible-use-after-free-in-t.patch
new file mode 100644 (file)
index 0000000..081d710
--- /dev/null
@@ -0,0 +1,45 @@
+From ea01ea98d57cd766f3d407d265196faa3830bd93 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Apr 2021 17:27:16 +0800
+Subject: phy: phy-twl4030-usb: Fix possible use-after-free in
+ twl4030_usb_remove()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit e1723d8b87b73ab363256e7ca3af3ddb75855680 ]
+
+This driver's remove path calls cancel_delayed_work(). However, that
+function does not wait until the work function finishes. This means
+that the callback function may still be running after the driver's
+remove function has finished, which would result in a use-after-free.
+
+Fix by calling cancel_delayed_work_sync(), which ensures that
+the work is properly cancelled, no longer running, and unable
+to re-schedule itself.
+
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20210407092716.3270248-1-yangyingliang@huawei.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/ti/phy-twl4030-usb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/phy/ti/phy-twl4030-usb.c b/drivers/phy/ti/phy-twl4030-usb.c
+index 9887f908f540..812e5409d359 100644
+--- a/drivers/phy/ti/phy-twl4030-usb.c
++++ b/drivers/phy/ti/phy-twl4030-usb.c
+@@ -779,7 +779,7 @@ static int twl4030_usb_remove(struct platform_device *pdev)
+       usb_remove_phy(&twl->phy);
+       pm_runtime_get_sync(twl->dev);
+-      cancel_delayed_work(&twl->id_workaround_work);
++      cancel_delayed_work_sync(&twl->id_workaround_work);
+       device_remove_file(twl->dev, &dev_attr_vbus);
+       /* set transceiver mode to power on defaults */
+-- 
+2.30.2
+
diff --git a/queue-5.12/platform-x86-intel_pmc_core-don-t-use-global-pmcdev-.patch b/queue-5.12/platform-x86-intel_pmc_core-don-t-use-global-pmcdev-.patch
new file mode 100644 (file)
index 0000000..9f95a61
--- /dev/null
@@ -0,0 +1,81 @@
+From e30c5e18b0ab26a9c14dc55c37e65e75effd7b50 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Apr 2021 20:12:44 -0700
+Subject: platform/x86: intel_pmc_core: Don't use global pmcdev in quirks
+
+From: David E. Box <david.e.box@linux.intel.com>
+
+[ Upstream commit c9f86d6ca6b5e23d30d16ade4b9fff5b922a610a ]
+
+The DMI callbacks, used for quirks, currently access the PMC by getting
+the address a global pmc_dev struct. Instead, have the callbacks set a
+global quirk specific variable. In probe, after calling dmi_check_system(),
+pass pmc_dev to a function that will handle each quirk if its variable
+condition is met. This allows removing the global pmc_dev later.
+
+Signed-off-by: David E. Box <david.e.box@linux.intel.com>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Reviewed-by: Rajneesh Bhardwaj <irenic.rajneesh@gmail.com>
+Link: https://lore.kernel.org/r/20210417031252.3020837-2-david.e.box@linux.intel.com
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/intel_pmc_core.c | 19 ++++++++++++++++---
+ 1 file changed, 16 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/platform/x86/intel_pmc_core.c b/drivers/platform/x86/intel_pmc_core.c
+index b5888aeb4bcf..260d49dca1ad 100644
+--- a/drivers/platform/x86/intel_pmc_core.c
++++ b/drivers/platform/x86/intel_pmc_core.c
+@@ -1186,9 +1186,15 @@ static const struct pci_device_id pmc_pci_ids[] = {
+  * the platform BIOS enforces 24Mhz crystal to shutdown
+  * before PMC can assert SLP_S0#.
+  */
++static bool xtal_ignore;
+ static int quirk_xtal_ignore(const struct dmi_system_id *id)
+ {
+-      struct pmc_dev *pmcdev = &pmc;
++      xtal_ignore = true;
++      return 0;
++}
++
++static void pmc_core_xtal_ignore(struct pmc_dev *pmcdev)
++{
+       u32 value;
+       value = pmc_core_reg_read(pmcdev, pmcdev->map->pm_vric1_offset);
+@@ -1197,7 +1203,6 @@ static int quirk_xtal_ignore(const struct dmi_system_id *id)
+       /* Low Voltage Mode Enable */
+       value &= ~SPT_PMC_VRIC1_SLPS0LVEN;
+       pmc_core_reg_write(pmcdev, pmcdev->map->pm_vric1_offset, value);
+-      return 0;
+ }
+ static const struct dmi_system_id pmc_core_dmi_table[]  = {
+@@ -1212,6 +1217,14 @@ static const struct dmi_system_id pmc_core_dmi_table[]  = {
+       {}
+ };
++static void pmc_core_do_dmi_quirks(struct pmc_dev *pmcdev)
++{
++      dmi_check_system(pmc_core_dmi_table);
++
++      if (xtal_ignore)
++              pmc_core_xtal_ignore(pmcdev);
++}
++
+ static int pmc_core_probe(struct platform_device *pdev)
+ {
+       static bool device_initialized;
+@@ -1253,7 +1266,7 @@ static int pmc_core_probe(struct platform_device *pdev)
+       mutex_init(&pmcdev->lock);
+       platform_set_drvdata(pdev, pmcdev);
+       pmcdev->pmc_xram_read_bit = pmc_core_check_read_lock_bit();
+-      dmi_check_system(pmc_core_dmi_table);
++      pmc_core_do_dmi_quirks(pmcdev);
+       /*
+        * On TGL, due to a hardware limitation, the GBE LTR blocks PC10 when
+-- 
+2.30.2
+
diff --git a/queue-5.12/platform-x86-isst-account-for-increased-timeout-in-s.patch b/queue-5.12/platform-x86-isst-account-for-increased-timeout-in-s.patch
new file mode 100644 (file)
index 0000000..87d4636
--- /dev/null
@@ -0,0 +1,116 @@
+From c3ea148c6d024c0fc3b07d63bafb2ca141003dfc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 Mar 2021 15:08:40 -0700
+Subject: platform/x86: ISST: Account for increased timeout in some cases
+
+From: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+
+[ Upstream commit 5c782817a981981917ec3c647cf521022ee07143 ]
+
+In some cases when firmware is busy or updating, some mailbox commands
+still timeout on some newer CPUs. To fix this issue, change how we
+process timeout.
+
+With this change, replaced timeout from using simple count with real
+timeout in micro-seconds using ktime. When the command response takes
+more than average processing time, yield to other tasks. The worst case
+timeout is extended upto 1 milli-second.
+
+Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Link: https://lore.kernel.org/r/20210330220840.3113959-1-srinivas.pandruvada@linux.intel.com
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../intel_speed_select_if/isst_if_mbox_pci.c  | 33 +++++++++++++------
+ 1 file changed, 23 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/platform/x86/intel_speed_select_if/isst_if_mbox_pci.c b/drivers/platform/x86/intel_speed_select_if/isst_if_mbox_pci.c
+index a2a2d923e60c..df1fc6c719f3 100644
+--- a/drivers/platform/x86/intel_speed_select_if/isst_if_mbox_pci.c
++++ b/drivers/platform/x86/intel_speed_select_if/isst_if_mbox_pci.c
+@@ -21,12 +21,16 @@
+ #define PUNIT_MAILBOX_BUSY_BIT                31
+ /*
+- * The average time to complete some commands is about 40us. The current
+- * count is enough to satisfy 40us. But when the firmware is very busy, this
+- * causes timeout occasionally.  So increase to deal with some worst case
+- * scenarios. Most of the command still complete in few us.
++ * The average time to complete mailbox commands is less than 40us. Most of
++ * the commands complete in few micro seconds. But the same firmware handles
++ * requests from all power management features.
++ * We can create a scenario where we flood the firmware with requests then
++ * the mailbox response can be delayed for 100s of micro seconds. So define
++ * two timeouts. One for average case and one for long.
++ * If the firmware is taking more than average, just call cond_resched().
+  */
+-#define OS_MAILBOX_RETRY_COUNT                100
++#define OS_MAILBOX_TIMEOUT_AVG_US     40
++#define OS_MAILBOX_TIMEOUT_MAX_US     1000
+ struct isst_if_device {
+       struct mutex mutex;
+@@ -35,11 +39,13 @@ struct isst_if_device {
+ static int isst_if_mbox_cmd(struct pci_dev *pdev,
+                           struct isst_if_mbox_cmd *mbox_cmd)
+ {
+-      u32 retries, data;
++      s64 tm_delta = 0;
++      ktime_t tm;
++      u32 data;
+       int ret;
+       /* Poll for rb bit == 0 */
+-      retries = OS_MAILBOX_RETRY_COUNT;
++      tm = ktime_get();
+       do {
+               ret = pci_read_config_dword(pdev, PUNIT_MAILBOX_INTERFACE,
+                                           &data);
+@@ -48,11 +54,14 @@ static int isst_if_mbox_cmd(struct pci_dev *pdev,
+               if (data & BIT_ULL(PUNIT_MAILBOX_BUSY_BIT)) {
+                       ret = -EBUSY;
++                      tm_delta = ktime_us_delta(ktime_get(), tm);
++                      if (tm_delta > OS_MAILBOX_TIMEOUT_AVG_US)
++                              cond_resched();
+                       continue;
+               }
+               ret = 0;
+               break;
+-      } while (--retries);
++      } while (tm_delta < OS_MAILBOX_TIMEOUT_MAX_US);
+       if (ret)
+               return ret;
+@@ -74,7 +83,8 @@ static int isst_if_mbox_cmd(struct pci_dev *pdev,
+               return ret;
+       /* Poll for rb bit == 0 */
+-      retries = OS_MAILBOX_RETRY_COUNT;
++      tm_delta = 0;
++      tm = ktime_get();
+       do {
+               ret = pci_read_config_dword(pdev, PUNIT_MAILBOX_INTERFACE,
+                                           &data);
+@@ -83,6 +93,9 @@ static int isst_if_mbox_cmd(struct pci_dev *pdev,
+               if (data & BIT_ULL(PUNIT_MAILBOX_BUSY_BIT)) {
+                       ret = -EBUSY;
++                      tm_delta = ktime_us_delta(ktime_get(), tm);
++                      if (tm_delta > OS_MAILBOX_TIMEOUT_AVG_US)
++                              cond_resched();
+                       continue;
+               }
+@@ -96,7 +109,7 @@ static int isst_if_mbox_cmd(struct pci_dev *pdev,
+               mbox_cmd->resp_data = data;
+               ret = 0;
+               break;
+-      } while (--retries);
++      } while (tm_delta < OS_MAILBOX_TIMEOUT_MAX_US);
+       return ret;
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.12/power-supply-bq27xxx-fix-power_avg-for-newer-ics.patch b/queue-5.12/power-supply-bq27xxx-fix-power_avg-for-newer-ics.patch
new file mode 100644 (file)
index 0000000..f3c2d67
--- /dev/null
@@ -0,0 +1,134 @@
+From 40855c3fe08bd87c6394f29969e1b341a78dfc2f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Mar 2021 10:54:19 +0100
+Subject: power: supply: bq27xxx: fix power_avg for newer ICs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
+
+[ Upstream commit c4d57c22ac65bd503716062a06fad55a01569cac ]
+
+On all newer bq27xxx ICs, the AveragePower register contains a signed
+value; in addition to handling the raw value as unsigned, the driver
+code also didn't convert it to µW as expected.
+
+At least for the BQ28Z610, the reference manual incorrectly states that
+the value is in units of 1mW and not 10mW. I have no way of knowing
+whether the manuals of other supported ICs contain the same error, or if
+there are models that actually use 1mW. At least, the new code shouldn't
+be *less* correct than the old version for any device.
+
+power_avg is removed from the cache structure, se we don't have to
+extend it to store both a signed value and an error code. Always getting
+an up-to-date value may be desirable anyways, as it avoids inconsistent
+current and power readings when switching between charging and
+discharging.
+
+Signed-off-by: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/bq27xxx_battery.c | 51 ++++++++++++++------------
+ include/linux/power/bq27xxx_battery.h  |  1 -
+ 2 files changed, 27 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
+index 4c4a7b1c64c5..0262109ac285 100644
+--- a/drivers/power/supply/bq27xxx_battery.c
++++ b/drivers/power/supply/bq27xxx_battery.c
+@@ -1661,27 +1661,6 @@ static int bq27xxx_battery_read_time(struct bq27xxx_device_info *di, u8 reg)
+       return tval * 60;
+ }
+-/*
+- * Read an average power register.
+- * Return < 0 if something fails.
+- */
+-static int bq27xxx_battery_read_pwr_avg(struct bq27xxx_device_info *di)
+-{
+-      int tval;
+-
+-      tval = bq27xxx_read(di, BQ27XXX_REG_AP, false);
+-      if (tval < 0) {
+-              dev_err(di->dev, "error reading average power register  %02x: %d\n",
+-                      BQ27XXX_REG_AP, tval);
+-              return tval;
+-      }
+-
+-      if (di->opts & BQ27XXX_O_ZERO)
+-              return (tval * BQ27XXX_POWER_CONSTANT) / BQ27XXX_RS;
+-      else
+-              return tval;
+-}
+-
+ /*
+  * Returns true if a battery over temperature condition is detected
+  */
+@@ -1769,8 +1748,6 @@ void bq27xxx_battery_update(struct bq27xxx_device_info *di)
+               }
+               if (di->regs[BQ27XXX_REG_CYCT] != INVALID_REG_ADDR)
+                       cache.cycle_count = bq27xxx_battery_read_cyct(di);
+-              if (di->regs[BQ27XXX_REG_AP] != INVALID_REG_ADDR)
+-                      cache.power_avg = bq27xxx_battery_read_pwr_avg(di);
+               /* We only have to read charge design full once */
+               if (di->charge_design_full <= 0)
+@@ -1833,6 +1810,32 @@ static int bq27xxx_battery_current(struct bq27xxx_device_info *di,
+       return 0;
+ }
++/*
++ * Get the average power in µW
++ * Return < 0 if something fails.
++ */
++static int bq27xxx_battery_pwr_avg(struct bq27xxx_device_info *di,
++                                 union power_supply_propval *val)
++{
++      int power;
++
++      power = bq27xxx_read(di, BQ27XXX_REG_AP, false);
++      if (power < 0) {
++              dev_err(di->dev,
++                      "error reading average power register %02x: %d\n",
++                      BQ27XXX_REG_AP, power);
++              return power;
++      }
++
++      if (di->opts & BQ27XXX_O_ZERO)
++              val->intval = (power * BQ27XXX_POWER_CONSTANT) / BQ27XXX_RS;
++      else
++              /* Other gauges return a signed value in units of 10mW */
++              val->intval = (int)((s16)power) * 10000;
++
++      return 0;
++}
++
+ static int bq27xxx_battery_status(struct bq27xxx_device_info *di,
+                                 union power_supply_propval *val)
+ {
+@@ -2020,7 +2023,7 @@ static int bq27xxx_battery_get_property(struct power_supply *psy,
+               ret = bq27xxx_simple_value(di->cache.energy, val);
+               break;
+       case POWER_SUPPLY_PROP_POWER_AVG:
+-              ret = bq27xxx_simple_value(di->cache.power_avg, val);
++              ret = bq27xxx_battery_pwr_avg(di, val);
+               break;
+       case POWER_SUPPLY_PROP_HEALTH:
+               ret = bq27xxx_simple_value(di->cache.health, val);
+diff --git a/include/linux/power/bq27xxx_battery.h b/include/linux/power/bq27xxx_battery.h
+index 111a40d0d3d5..8d5f4f40fb41 100644
+--- a/include/linux/power/bq27xxx_battery.h
++++ b/include/linux/power/bq27xxx_battery.h
+@@ -53,7 +53,6 @@ struct bq27xxx_reg_cache {
+       int capacity;
+       int energy;
+       int flags;
+-      int power_avg;
+       int health;
+ };
+-- 
+2.30.2
+
diff --git a/queue-5.12/power-supply-cpcap-battery-fix-invalid-usage-of-list.patch b/queue-5.12/power-supply-cpcap-battery-fix-invalid-usage-of-list.patch
new file mode 100644 (file)
index 0000000..4528861
--- /dev/null
@@ -0,0 +1,39 @@
+From 84715f9691a4cd4564e422b9d3eab0e721496b36 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Apr 2021 22:36:50 +0800
+Subject: power: supply: cpcap-battery: fix invalid usage of list cursor
+
+From: Guangqing Zhu <zhuguangqing83@gmail.com>
+
+[ Upstream commit d0a43c12ee9f57ddb284272187bd18726c2c2c98 ]
+
+Fix invalid usage of a list_for_each_entry in cpcap_battery_irq_thread().
+Empty list or fully traversed list points to list head, which is not
+NULL (and before the first element containing real data).
+
+Signed-off-by: Guangqing Zhu <zhuguangqing83@gmail.com>
+Reviewed-by: Tony Lindgren <tony@atomide.com>
+Reviewed-by: Carl Philipp Klemm <philipp@uvos.xyz>
+Tested-by: Carl Philipp Klemm <philipp@uvos.xyz>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/cpcap-battery.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/power/supply/cpcap-battery.c b/drivers/power/supply/cpcap-battery.c
+index 6d5bcdb9f45d..a3fc0084cda0 100644
+--- a/drivers/power/supply/cpcap-battery.c
++++ b/drivers/power/supply/cpcap-battery.c
+@@ -786,7 +786,7 @@ static irqreturn_t cpcap_battery_irq_thread(int irq, void *data)
+                       break;
+       }
+-      if (!d)
++      if (list_entry_is_head(d, &ddata->irq_list, node))
+               return IRQ_NONE;
+       latest = cpcap_battery_latest(ddata);
+-- 
+2.30.2
+
diff --git a/queue-5.12/power-supply-cpcap-charger-add-usleep-to-cpcap-charg.patch b/queue-5.12/power-supply-cpcap-charger-add-usleep-to-cpcap-charg.patch
new file mode 100644 (file)
index 0000000..8ac80f2
--- /dev/null
@@ -0,0 +1,55 @@
+From 8ca181b51ef21ce0f2cfae562c5ca1265b56dd8b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 Jan 2021 22:48:53 +0100
+Subject: power: supply: cpcap-charger: Add usleep to cpcap charger to avoid
+ usb plug bounce
+
+From: Carl Philipp Klemm <philipp@uvos.xyz>
+
+[ Upstream commit 751faedf06e895a17e985a88ef5b6364ffd797ed ]
+
+Adds 80000 us sleep when the usb cable is plugged in to hopefully avoid
+bouncing contacts.
+
+Upon pluging in the usb cable vbus will bounce for some time, causing cpcap to
+dissconnect charging due to detecting an undervoltage condition. This is a
+scope of vbus on xt894 while quickly inserting the usb cable with firm force,
+probed at the far side of the usb socket and vbus loaded with approx 1k:
+http://uvos.xyz/maserati/usbplug.jpg.
+
+As can clearly be seen, vbus is all over the place for the first 15 ms or so
+with a small blip at ~40 ms this causes the cpcap to trip up and disable
+charging again.
+
+The delay helps cpcap_usb_detect avoid the worst of this. It is, however, still
+not ideal as strong vibrations can cause the issue to reapear any time during
+charging. I have however not been able to cause the device to stop charging due
+to this in practice as it is hard to vibrate the device such that the vbus pins
+start bouncing again but cpcap_usb_detect is not called again due to a detected
+disconnect/reconnect event.
+
+Signed-off-by: Carl Philipp Klemm <philipp@uvos.xyz>
+Tested-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/cpcap-charger.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/power/supply/cpcap-charger.c b/drivers/power/supply/cpcap-charger.c
+index 3f06eb826ac2..2a8915c3e73e 100644
+--- a/drivers/power/supply/cpcap-charger.c
++++ b/drivers/power/supply/cpcap-charger.c
+@@ -668,6 +668,9 @@ static void cpcap_usb_detect(struct work_struct *work)
+               return;
+       }
++      /* Delay for 80ms to avoid vbus bouncing when usb cable is plugged in */
++      usleep_range(80000, 120000);
++
+       /* Throttle chrgcurr2 interrupt for charger done and retry */
+       switch (ddata->status) {
+       case POWER_SUPPLY_STATUS_CHARGING:
+-- 
+2.30.2
+
diff --git a/queue-5.12/power-supply-cpcap-charger-fix-small-mistake-in-curr.patch b/queue-5.12/power-supply-cpcap-charger-fix-small-mistake-in-curr.patch
new file mode 100644 (file)
index 0000000..4a9016f
--- /dev/null
@@ -0,0 +1,34 @@
+From d5b8167cc83cd7134b0bf22a6f7fe9a5410b6dd2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 Jan 2021 22:47:45 +0100
+Subject: power: supply: cpcap-charger: fix small mistake in current to
+ register conversion
+
+From: Carl Philipp Klemm <philipp@uvos.xyz>
+
+[ Upstream commit 8a5a0cc13aa927eac7a9eb3ca82dfc1f82cfc28d ]
+
+Signed-off-by: Carl Philipp Klemm <philipp@uvos.xyz>
+Acked-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/cpcap-charger.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/power/supply/cpcap-charger.c b/drivers/power/supply/cpcap-charger.c
+index 641dcad1133f..3f06eb826ac2 100644
+--- a/drivers/power/supply/cpcap-charger.c
++++ b/drivers/power/supply/cpcap-charger.c
+@@ -318,7 +318,7 @@ static int cpcap_charger_current_to_regval(int microamp)
+               return CPCAP_REG_CRM_ICHRG(0x0);
+       if (miliamp < 177)
+               return CPCAP_REG_CRM_ICHRG(0x1);
+-      if (miliamp > 1596)
++      if (miliamp >= 1596)
+               return CPCAP_REG_CRM_ICHRG(0xe);
+       res = microamp / 88666;
+-- 
+2.30.2
+
diff --git a/queue-5.12/power-supply-generic-adc-battery-fix-possible-use-af.patch b/queue-5.12/power-supply-generic-adc-battery-fix-possible-use-af.patch
new file mode 100644 (file)
index 0000000..ea4907e
--- /dev/null
@@ -0,0 +1,43 @@
+From 0e279b14d0ae3de9a1d00de1d971cd1d059b2265 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Apr 2021 17:17:06 +0800
+Subject: power: supply: generic-adc-battery: fix possible use-after-free in
+ gab_remove()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit b6cfa007b3b229771d9588970adb4ab3e0487f49 ]
+
+This driver's remove path calls cancel_delayed_work(). However, that
+function does not wait until the work function finishes. This means
+that the callback function may still be running after the driver's
+remove function has finished, which would result in a use-after-free.
+
+Fix by calling cancel_delayed_work_sync(), which ensures that
+the work is properly cancelled, no longer running, and unable
+to re-schedule itself.
+
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/generic-adc-battery.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/power/supply/generic-adc-battery.c b/drivers/power/supply/generic-adc-battery.c
+index 0032069fbc2b..66039c665dd1 100644
+--- a/drivers/power/supply/generic-adc-battery.c
++++ b/drivers/power/supply/generic-adc-battery.c
+@@ -373,7 +373,7 @@ static int gab_remove(struct platform_device *pdev)
+       }
+       kfree(adc_bat->psy_desc.properties);
+-      cancel_delayed_work(&adc_bat->bat_work);
++      cancel_delayed_work_sync(&adc_bat->bat_work);
+       return 0;
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.12/power-supply-s3c_adc_battery-fix-possible-use-after-.patch b/queue-5.12/power-supply-s3c_adc_battery-fix-possible-use-after-.patch
new file mode 100644 (file)
index 0000000..e2416b0
--- /dev/null
@@ -0,0 +1,44 @@
+From ae70988338f3f92568948865d04d3ce2d2f5591e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Apr 2021 17:19:03 +0800
+Subject: power: supply: s3c_adc_battery: fix possible use-after-free in
+ s3c_adc_bat_remove()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 68ae256945d2abe9036a7b68af4cc65aff79d5b7 ]
+
+This driver's remove path calls cancel_delayed_work(). However, that
+function does not wait until the work function finishes. This means
+that the callback function may still be running after the driver's
+remove function has finished, which would result in a use-after-free.
+
+Fix by calling cancel_delayed_work_sync(), which ensures that
+the work is properly cancelled, no longer running, and unable
+to re-schedule itself.
+
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/s3c_adc_battery.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/power/supply/s3c_adc_battery.c b/drivers/power/supply/s3c_adc_battery.c
+index a2addc24ee8b..3e3a598f114d 100644
+--- a/drivers/power/supply/s3c_adc_battery.c
++++ b/drivers/power/supply/s3c_adc_battery.c
+@@ -395,7 +395,7 @@ static int s3c_adc_bat_remove(struct platform_device *pdev)
+       if (main_bat.charge_finished)
+               free_irq(gpiod_to_irq(main_bat.charge_finished), NULL);
+-      cancel_delayed_work(&bat_work);
++      cancel_delayed_work_sync(&bat_work);
+       if (pdata->exit)
+               pdata->exit();
+-- 
+2.30.2
+
diff --git a/queue-5.12/power-supply-use-irqf_oneshot.patch b/queue-5.12/power-supply-use-irqf_oneshot.patch
new file mode 100644 (file)
index 0000000..ce8b2dd
--- /dev/null
@@ -0,0 +1,83 @@
+From db05971134eeb8ded4134940ff8994038e2fd138 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Mar 2021 19:21:33 +0800
+Subject: power: supply: Use IRQF_ONESHOT
+
+From: dongjian <dongjian@yulong.com>
+
+[ Upstream commit 2469b836fa835c67648acad17d62bc805236a6ea ]
+
+Fixes coccicheck error:
+
+drivers/power/supply/pm2301_charger.c:1089:7-27: ERROR:
+drivers/power/supply/lp8788-charger.c:502:8-28: ERROR:
+drivers/power/supply/tps65217_charger.c:239:8-33: ERROR:
+drivers/power/supply/tps65090-charger.c:303:8-33: ERROR:
+
+Threaded IRQ with no primary handler requested without IRQF_ONESHOT
+
+Signed-off-by: dongjian <dongjian@yulong.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/lp8788-charger.c   | 2 +-
+ drivers/power/supply/pm2301_charger.c   | 2 +-
+ drivers/power/supply/tps65090-charger.c | 2 +-
+ drivers/power/supply/tps65217_charger.c | 2 +-
+ 4 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/power/supply/lp8788-charger.c b/drivers/power/supply/lp8788-charger.c
+index e7931ffb7151..397e5a03b7d9 100644
+--- a/drivers/power/supply/lp8788-charger.c
++++ b/drivers/power/supply/lp8788-charger.c
+@@ -501,7 +501,7 @@ static int lp8788_set_irqs(struct platform_device *pdev,
+               ret = request_threaded_irq(virq, NULL,
+                                       lp8788_charger_irq_thread,
+-                                      0, name, pchg);
++                                      IRQF_ONESHOT, name, pchg);
+               if (ret)
+                       break;
+       }
+diff --git a/drivers/power/supply/pm2301_charger.c b/drivers/power/supply/pm2301_charger.c
+index ac06ecf7fc9c..a3bfb9612b17 100644
+--- a/drivers/power/supply/pm2301_charger.c
++++ b/drivers/power/supply/pm2301_charger.c
+@@ -1089,7 +1089,7 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client,
+       ret = request_threaded_irq(gpio_to_irq(pm2->pdata->gpio_irq_number),
+                               NULL,
+                               pm2xxx_charger_irq[0].isr,
+-                              pm2->pdata->irq_type,
++                              pm2->pdata->irq_type | IRQF_ONESHOT,
+                               pm2xxx_charger_irq[0].name, pm2);
+       if (ret != 0) {
+diff --git a/drivers/power/supply/tps65090-charger.c b/drivers/power/supply/tps65090-charger.c
+index 6b0098e5a88b..0990b2fa6cd8 100644
+--- a/drivers/power/supply/tps65090-charger.c
++++ b/drivers/power/supply/tps65090-charger.c
+@@ -301,7 +301,7 @@ static int tps65090_charger_probe(struct platform_device *pdev)
+       if (irq != -ENXIO) {
+               ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
+-                      tps65090_charger_isr, 0, "tps65090-charger", cdata);
++                      tps65090_charger_isr, IRQF_ONESHOT, "tps65090-charger", cdata);
+               if (ret) {
+                       dev_err(cdata->dev,
+                               "Unable to register irq %d err %d\n", irq,
+diff --git a/drivers/power/supply/tps65217_charger.c b/drivers/power/supply/tps65217_charger.c
+index 814c2b81fdfe..ba33d1617e0b 100644
+--- a/drivers/power/supply/tps65217_charger.c
++++ b/drivers/power/supply/tps65217_charger.c
+@@ -238,7 +238,7 @@ static int tps65217_charger_probe(struct platform_device *pdev)
+       for (i = 0; i < NUM_CHARGER_IRQS; i++) {
+               ret = devm_request_threaded_irq(&pdev->dev, irq[i], NULL,
+                                               tps65217_charger_irq,
+-                                              0, "tps65217-charger",
++                                              IRQF_ONESHOT, "tps65217-charger",
+                                               charger);
+               if (ret) {
+                       dev_err(charger->dev,
+-- 
+2.30.2
+
diff --git a/queue-5.12/random-initialize-chacha20-constants-with-correct-en.patch b/queue-5.12/random-initialize-chacha20-constants-with-correct-en.patch
new file mode 100644 (file)
index 0000000..c53babc
--- /dev/null
@@ -0,0 +1,78 @@
+From a253e539fe321f7ebf81359c75b37f2eaea32d6c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 21 Mar 2021 22:13:47 -0700
+Subject: random: initialize ChaCha20 constants with correct endianness
+
+From: Eric Biggers <ebiggers@google.com>
+
+[ Upstream commit a181e0fdb2164268274453b5b291589edbb9b22d ]
+
+On big endian CPUs, the ChaCha20-based CRNG is using the wrong
+endianness for the ChaCha20 constants.
+
+This doesn't matter cryptographically, but technically it means it's not
+ChaCha20 anymore.  Fix it to always use the standard constants.
+
+Cc: linux-crypto@vger.kernel.org
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: Jann Horn <jannh@google.com>
+Cc: Theodore Ts'o <tytso@mit.edu>
+Acked-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/random.c   | 4 ++--
+ include/crypto/chacha.h | 9 +++++++--
+ 2 files changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/char/random.c b/drivers/char/random.c
+index 0fe9e200e4c8..5d6acfecd919 100644
+--- a/drivers/char/random.c
++++ b/drivers/char/random.c
+@@ -819,7 +819,7 @@ static bool __init crng_init_try_arch_early(struct crng_state *crng)
+ static void __maybe_unused crng_initialize_secondary(struct crng_state *crng)
+ {
+-      memcpy(&crng->state[0], "expand 32-byte k", 16);
++      chacha_init_consts(crng->state);
+       _get_random_bytes(&crng->state[4], sizeof(__u32) * 12);
+       crng_init_try_arch(crng);
+       crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1;
+@@ -827,7 +827,7 @@ static void __maybe_unused crng_initialize_secondary(struct crng_state *crng)
+ static void __init crng_initialize_primary(struct crng_state *crng)
+ {
+-      memcpy(&crng->state[0], "expand 32-byte k", 16);
++      chacha_init_consts(crng->state);
+       _extract_entropy(&input_pool, &crng->state[4], sizeof(__u32) * 12, 0);
+       if (crng_init_try_arch_early(crng) && trust_cpu) {
+               invalidate_batched_entropy();
+diff --git a/include/crypto/chacha.h b/include/crypto/chacha.h
+index 3a1c72fdb7cf..dabaee698718 100644
+--- a/include/crypto/chacha.h
++++ b/include/crypto/chacha.h
+@@ -47,13 +47,18 @@ static inline void hchacha_block(const u32 *state, u32 *out, int nrounds)
+               hchacha_block_generic(state, out, nrounds);
+ }
+-void chacha_init_arch(u32 *state, const u32 *key, const u8 *iv);
+-static inline void chacha_init_generic(u32 *state, const u32 *key, const u8 *iv)
++static inline void chacha_init_consts(u32 *state)
+ {
+       state[0]  = 0x61707865; /* "expa" */
+       state[1]  = 0x3320646e; /* "nd 3" */
+       state[2]  = 0x79622d32; /* "2-by" */
+       state[3]  = 0x6b206574; /* "te k" */
++}
++
++void chacha_init_arch(u32 *state, const u32 *key, const u8 *iv);
++static inline void chacha_init_generic(u32 *state, const u32 *key, const u8 *iv)
++{
++      chacha_init_consts(state);
+       state[4]  = key[0];
+       state[5]  = key[1];
+       state[6]  = key[2];
+-- 
+2.30.2
+
diff --git a/queue-5.12/regulator-da9121-automotive-variants-identity-fix.patch b/queue-5.12/regulator-da9121-automotive-variants-identity-fix.patch
new file mode 100644 (file)
index 0000000..4787216
--- /dev/null
@@ -0,0 +1,192 @@
+From 32eed24e2852db71d9fa23eb981b38ebfd9b1db6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Apr 2021 12:03:06 +0000
+Subject: regulator: da9121: automotive variants identity fix
+
+From: Adam Ward <Adam.Ward.opensource@diasemi.com>
+
+[ Upstream commit 013592be146a10d3567c0062cd1416faab060704 ]
+
+This patch fixes identification of DA913x parts by the DA9121 driver,
+where a lack of clarity lead to implementation on the basis that variant
+IDs were to be identical to the equivalent rated non-automotive parts.
+
+There is a new emphasis on the DT identity to cope with overlap in these
+ID's - this is not considered to be problematic, because projects would
+be exclusively using automotive or consumer grade parts.
+
+Signed-off-by: Adam Ward <Adam.Ward.opensource@diasemi.com>
+Link: https://lore.kernel.org/r/20210421120306.DB5B880007F@slsrvapps-01.diasemi.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/da9121-regulator.c | 80 ++++++++++++++++++----------
+ drivers/regulator/da9121-regulator.h | 13 +++++
+ 2 files changed, 65 insertions(+), 28 deletions(-)
+
+diff --git a/drivers/regulator/da9121-regulator.c b/drivers/regulator/da9121-regulator.c
+index a2ede7d7897e..08cbf688e14d 100644
+--- a/drivers/regulator/da9121-regulator.c
++++ b/drivers/regulator/da9121-regulator.c
+@@ -40,6 +40,7 @@ struct da9121 {
+       unsigned int passive_delay;
+       int chip_irq;
+       int variant_id;
++      int subvariant_id;
+ };
+ /* Define ranges for different variants, enabling translation to/from
+@@ -812,7 +813,6 @@ static struct regmap_config da9121_2ch_regmap_config = {
+ static int da9121_check_device_type(struct i2c_client *i2c, struct da9121 *chip)
+ {
+       u32 device_id;
+-      u8 chip_id = chip->variant_id;
+       u32 variant_id;
+       u8 variant_mrc, variant_vrc;
+       char *type;
+@@ -839,22 +839,34 @@ static int da9121_check_device_type(struct i2c_client *i2c, struct da9121 *chip)
+       variant_vrc = variant_id & DA9121_MASK_OTP_VARIANT_ID_VRC;
+-      switch (variant_vrc) {
+-      case DA9121_VARIANT_VRC:
+-              type = "DA9121/DA9130";
+-              config_match = (chip_id == DA9121_TYPE_DA9121_DA9130);
++      switch (chip->subvariant_id) {
++      case DA9121_SUBTYPE_DA9121:
++              type = "DA9121";
++              config_match = (variant_vrc == DA9121_VARIANT_VRC);
+               break;
+-      case DA9220_VARIANT_VRC:
+-              type = "DA9220/DA9132";
+-              config_match = (chip_id == DA9121_TYPE_DA9220_DA9132);
++      case DA9121_SUBTYPE_DA9130:
++              type = "DA9130";
++              config_match = (variant_vrc == DA9130_VARIANT_VRC);
+               break;
+-      case DA9122_VARIANT_VRC:
+-              type = "DA9122/DA9131";
+-              config_match = (chip_id == DA9121_TYPE_DA9122_DA9131);
++      case DA9121_SUBTYPE_DA9220:
++              type = "DA9220";
++              config_match = (variant_vrc == DA9220_VARIANT_VRC);
+               break;
+-      case DA9217_VARIANT_VRC:
++      case DA9121_SUBTYPE_DA9132:
++              type = "DA9132";
++              config_match = (variant_vrc == DA9132_VARIANT_VRC);
++              break;
++      case DA9121_SUBTYPE_DA9122:
++              type = "DA9122";
++              config_match = (variant_vrc == DA9122_VARIANT_VRC);
++              break;
++      case DA9121_SUBTYPE_DA9131:
++              type = "DA9131";
++              config_match = (variant_vrc == DA9131_VARIANT_VRC);
++              break;
++      case DA9121_SUBTYPE_DA9217:
+               type = "DA9217";
+-              config_match = (chip_id == DA9121_TYPE_DA9217);
++              config_match = (variant_vrc == DA9217_VARIANT_VRC);
+               break;
+       default:
+               type = "Unknown";
+@@ -892,15 +904,27 @@ static int da9121_assign_chip_model(struct i2c_client *i2c,
+       chip->dev = &i2c->dev;
+-      switch (chip->variant_id) {
+-      case DA9121_TYPE_DA9121_DA9130:
+-              fallthrough;
+-      case DA9121_TYPE_DA9217:
++      /* Use configured subtype to select the regulator descriptor index and
++       * register map, common to both consumer and automotive grade variants
++       */
++      switch (chip->subvariant_id) {
++      case DA9121_SUBTYPE_DA9121:
++      case DA9121_SUBTYPE_DA9130:
++              chip->variant_id = DA9121_TYPE_DA9121_DA9130;
+               regmap = &da9121_1ch_regmap_config;
+               break;
+-      case DA9121_TYPE_DA9122_DA9131:
+-              fallthrough;
+-      case DA9121_TYPE_DA9220_DA9132:
++      case DA9121_SUBTYPE_DA9217:
++              chip->variant_id = DA9121_TYPE_DA9217;
++              regmap = &da9121_1ch_regmap_config;
++              break;
++      case DA9121_SUBTYPE_DA9122:
++      case DA9121_SUBTYPE_DA9131:
++              chip->variant_id = DA9121_TYPE_DA9122_DA9131;
++              regmap = &da9121_2ch_regmap_config;
++              break;
++      case DA9121_SUBTYPE_DA9220:
++      case DA9121_SUBTYPE_DA9132:
++              chip->variant_id = DA9121_TYPE_DA9220_DA9132;
+               regmap = &da9121_2ch_regmap_config;
+               break;
+       }
+@@ -975,13 +999,13 @@ regmap_error:
+ }
+ static const struct of_device_id da9121_dt_ids[] = {
+-      { .compatible = "dlg,da9121", .data = (void *) DA9121_TYPE_DA9121_DA9130 },
+-      { .compatible = "dlg,da9130", .data = (void *) DA9121_TYPE_DA9121_DA9130 },
+-      { .compatible = "dlg,da9217", .data = (void *) DA9121_TYPE_DA9217 },
+-      { .compatible = "dlg,da9122", .data = (void *) DA9121_TYPE_DA9122_DA9131 },
+-      { .compatible = "dlg,da9131", .data = (void *) DA9121_TYPE_DA9122_DA9131 },
+-      { .compatible = "dlg,da9220", .data = (void *) DA9121_TYPE_DA9220_DA9132 },
+-      { .compatible = "dlg,da9132", .data = (void *) DA9121_TYPE_DA9220_DA9132 },
++      { .compatible = "dlg,da9121", .data = (void *) DA9121_SUBTYPE_DA9121 },
++      { .compatible = "dlg,da9130", .data = (void *) DA9121_SUBTYPE_DA9130 },
++      { .compatible = "dlg,da9217", .data = (void *) DA9121_SUBTYPE_DA9217 },
++      { .compatible = "dlg,da9122", .data = (void *) DA9121_SUBTYPE_DA9122 },
++      { .compatible = "dlg,da9131", .data = (void *) DA9121_SUBTYPE_DA9131 },
++      { .compatible = "dlg,da9220", .data = (void *) DA9121_SUBTYPE_DA9220 },
++      { .compatible = "dlg,da9132", .data = (void *) DA9121_SUBTYPE_DA9132 },
+       { }
+ };
+ MODULE_DEVICE_TABLE(of, da9121_dt_ids);
+@@ -1011,7 +1035,7 @@ static int da9121_i2c_probe(struct i2c_client *i2c,
+       }
+       chip->pdata = i2c->dev.platform_data;
+-      chip->variant_id = da9121_of_get_id(&i2c->dev);
++      chip->subvariant_id = da9121_of_get_id(&i2c->dev);
+       ret = da9121_assign_chip_model(i2c, chip);
+       if (ret < 0)
+diff --git a/drivers/regulator/da9121-regulator.h b/drivers/regulator/da9121-regulator.h
+index 3c34cb889ca8..357f416e17c1 100644
+--- a/drivers/regulator/da9121-regulator.h
++++ b/drivers/regulator/da9121-regulator.h
+@@ -29,6 +29,16 @@ enum da9121_variant {
+       DA9121_TYPE_DA9217
+ };
++enum da9121_subvariant {
++      DA9121_SUBTYPE_DA9121,
++      DA9121_SUBTYPE_DA9130,
++      DA9121_SUBTYPE_DA9220,
++      DA9121_SUBTYPE_DA9132,
++      DA9121_SUBTYPE_DA9122,
++      DA9121_SUBTYPE_DA9131,
++      DA9121_SUBTYPE_DA9217
++};
++
+ /* Minimum, maximum and default polling millisecond periods are provided
+  * here as an example. It is expected that any final implementation will
+  * include a modification of these settings to match the required
+@@ -279,6 +289,9 @@ enum da9121_variant {
+ #define DA9220_VARIANT_VRC    0x0
+ #define DA9122_VARIANT_VRC    0x2
+ #define DA9217_VARIANT_VRC    0x7
++#define DA9130_VARIANT_VRC    0x0
++#define DA9131_VARIANT_VRC    0x1
++#define DA9132_VARIANT_VRC    0x2
+ /* DA9121_REG_OTP_CUSTOMER_ID */
+-- 
+2.30.2
+
diff --git a/queue-5.12/resource-prevent-irqresource_disabled-from-erasing-f.patch b/queue-5.12/resource-prevent-irqresource_disabled-from-erasing-f.patch
new file mode 100644 (file)
index 0000000..1ecd783
--- /dev/null
@@ -0,0 +1,68 @@
+From 536c3459b63a0089db629fb021f6da44472e2d24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Apr 2021 12:37:59 +0200
+Subject: resource: Prevent irqresource_disabled() from erasing flags
+
+From: Angela Czubak <acz@semihalf.com>
+
+[ Upstream commit d08a745729646f407277e904b02991458f20d261 ]
+
+Some Chromebooks use hard-coded interrupts in their ACPI tables.
+This is an excerpt as dumped on Relm:
+
+...
+            Name (_HID, "ELAN0001")  // _HID: Hardware ID
+            Name (_DDN, "Elan Touchscreen ")  // _DDN: DOS Device Name
+            Name (_UID, 0x05)  // _UID: Unique ID
+            Name (ISTP, Zero)
+            Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
+            {
+                Name (BUF0, ResourceTemplate ()
+                {
+                    I2cSerialBusV2 (0x0010, ControllerInitiated, 0x00061A80,
+                        AddressingMode7Bit, "\\_SB.I2C1",
+                        0x00, ResourceConsumer, , Exclusive,
+                        )
+                    Interrupt (ResourceConsumer, Edge, ActiveLow, Exclusive, ,, )
+                    {
+                        0x000000B8,
+                    }
+                })
+                Return (BUF0) /* \_SB_.I2C1.ETSA._CRS.BUF0 */
+            }
+...
+
+This interrupt is hard-coded to 0xB8 = 184 which is too high to be mapped
+to IO-APIC, so no triggering information is propagated as acpi_register_gsi()
+fails and irqresource_disabled() is issued, which leads to erasing triggering
+and polarity information.
+
+Do not overwrite flags as it leads to erasing triggering and polarity
+information which might be useful in case of hard-coded interrupts.
+This way the information can be read later on even though mapping to
+APIC domain failed.
+
+Signed-off-by: Angela Czubak <acz@semihalf.com>
+[ rjw: Changelog rearrangement ]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/ioport.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/linux/ioport.h b/include/linux/ioport.h
+index 55de385c839c..647744d8514e 100644
+--- a/include/linux/ioport.h
++++ b/include/linux/ioport.h
+@@ -331,7 +331,7 @@ static inline void irqresource_disabled(struct resource *res, u32 irq)
+ {
+       res->start = irq;
+       res->end = irq;
+-      res->flags = IORESOURCE_IRQ | IORESOURCE_DISABLED | IORESOURCE_UNSET;
++      res->flags |= IORESOURCE_IRQ | IORESOURCE_DISABLED | IORESOURCE_UNSET;
+ }
+ extern struct address_space *iomem_get_mapping(void);
+-- 
+2.30.2
+
diff --git a/queue-5.12/s390-archrandom-add-parameter-check-for-s390_arch_ra.patch b/queue-5.12/s390-archrandom-add-parameter-check-for-s390_arch_ra.patch
new file mode 100644 (file)
index 0000000..d236b33
--- /dev/null
@@ -0,0 +1,45 @@
+From 05f902954f2268aa4beb7c141db3d98c1042934d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Apr 2021 08:23:12 +0200
+Subject: s390/archrandom: add parameter check for s390_arch_random_generate
+
+From: Harald Freudenberger <freude@linux.ibm.com>
+
+[ Upstream commit 28096067686c5a5cbd4c35b079749bd805df5010 ]
+
+A review of the code showed, that this function which is exposed
+within the whole kernel should do a parameter check for the
+amount of bytes requested. If this requested bytes is too high
+an unsigned int overflow could happen causing this function to
+try to memcpy a really big memory chunk.
+
+This is not a security issue as there are only two invocations
+of this function from arch/s390/include/asm/archrandom.h and both
+are not exposed to userland.
+
+Reported-by: Sven Schnelle <svens@linux.ibm.com>
+Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/crypto/arch_random.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/s390/crypto/arch_random.c b/arch/s390/crypto/arch_random.c
+index 7b947728d57e..56007c763902 100644
+--- a/arch/s390/crypto/arch_random.c
++++ b/arch/s390/crypto/arch_random.c
+@@ -54,6 +54,10 @@ static DECLARE_DELAYED_WORK(arch_rng_work, arch_rng_refill_buffer);
+ bool s390_arch_random_generate(u8 *buf, unsigned int nbytes)
+ {
++      /* max hunk is ARCH_RNG_BUF_SIZE */
++      if (nbytes > ARCH_RNG_BUF_SIZE)
++              return false;
++
+       /* lock rng buffer */
+       if (!spin_trylock(&arch_rng_lock))
+               return false;
+-- 
+2.30.2
+
diff --git a/queue-5.12/s390-pci-expose-uid-uniqueness-guarantee.patch b/queue-5.12/s390-pci-expose-uid-uniqueness-guarantee.patch
new file mode 100644 (file)
index 0000000..9fdda87
--- /dev/null
@@ -0,0 +1,102 @@
+From 7b9825aa0891087c5c91be0fb75431919e2027e3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Feb 2021 11:29:36 +0100
+Subject: s390/pci: expose UID uniqueness guarantee
+
+From: Niklas Schnelle <schnelle@linux.ibm.com>
+
+[ Upstream commit 408f2c9c15682fc21b645fdec1f726492e235c4b ]
+
+On s390 each PCI device has a user-defined ID (UID) exposed under
+/sys/bus/pci/devices/<dev>/uid. This ID was designed to serve as the PCI
+device's primary index and to match the device within Linux to the
+device configured in the hypervisor. To serve as a primary identifier
+the UID must be unique within the Linux instance, this is guaranteed by
+the platform if and only if the UID Uniqueness Checking flag is set
+within the CLP List PCI Functions response.
+
+While the UID has been exposed to userspace since commit ac4995b9d570
+("s390/pci: add some new arch specific pci attributes") whether or not
+the platform guarantees its uniqueness for the lifetime of the Linux
+instance while defined is not visible from userspace. Remedy this by
+exposing this as a per device attribute at
+
+/sys/bus/pci/devices/<dev>/uid_is_unique
+
+Keeping this a per device attribute allows for maximum flexibility if we
+ever end up with some devices not having a UID or not enjoying the
+guaranteed uniqueness.
+
+Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
+Reviewed-by: Viktor Mihajlovski <mihajlov@linux.ibm.com>
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/s390/pci.rst | 14 +++++++++++---
+ arch/s390/pci/pci_sysfs.c  |  9 +++++++++
+ 2 files changed, 20 insertions(+), 3 deletions(-)
+
+diff --git a/Documentation/s390/pci.rst b/Documentation/s390/pci.rst
+index 492850bff316..8157f0cddbc2 100644
+--- a/Documentation/s390/pci.rst
++++ b/Documentation/s390/pci.rst
+@@ -50,7 +50,8 @@ Entries specific to zPCI functions and entries that hold zPCI information.
+ * /sys/bus/pci/slots/XXXXXXXX
+   The slot entries are set up using the function identifier (FID) of the
+-  PCI function.
++  PCI function. The format depicted as XXXXXXXX above is 8 hexadecimal digits
++  with 0 padding and lower case hexadecimal digitis.
+   - /sys/bus/pci/slots/XXXXXXXX/power
+@@ -88,8 +89,15 @@ Entries specific to zPCI functions and entries that hold zPCI information.
+     is attached to.
+   - uid
+-    The unique identifier (UID) is defined when configuring an LPAR and is
+-    unique in the LPAR.
++    The user identifier (UID) may be defined as part of the machine
++    configuration or the z/VM or KVM guest configuration. If the accompanying
++    uid_is_unique attribute is 1 the platform guarantees that the UID is unique
++    within that instance and no devices with the same UID can be attached
++    during the lifetime of the system.
++
++  - uid_is_unique
++    Indicates whether the user identifier (UID) is guaranteed to be and remain
++    unique within this Linux instance.
+   - pfip/segmentX
+     The segments determine the isolation of a function.
+diff --git a/arch/s390/pci/pci_sysfs.c b/arch/s390/pci/pci_sysfs.c
+index 5c028bee91b9..e14d346dafd6 100644
+--- a/arch/s390/pci/pci_sysfs.c
++++ b/arch/s390/pci/pci_sysfs.c
+@@ -131,6 +131,13 @@ static ssize_t report_error_write(struct file *filp, struct kobject *kobj,
+ }
+ static BIN_ATTR(report_error, S_IWUSR, NULL, report_error_write, PAGE_SIZE);
++static ssize_t uid_is_unique_show(struct device *dev,
++                                struct device_attribute *attr, char *buf)
++{
++      return sysfs_emit(buf, "%d\n", zpci_unique_uid ? 1 : 0);
++}
++static DEVICE_ATTR_RO(uid_is_unique);
++
+ static struct bin_attribute *zpci_bin_attrs[] = {
+       &bin_attr_util_string,
+       &bin_attr_report_error,
+@@ -148,8 +155,10 @@ static struct attribute *zpci_dev_attrs[] = {
+       &dev_attr_uid.attr,
+       &dev_attr_recover.attr,
+       &dev_attr_mio_enabled.attr,
++      &dev_attr_uid_is_unique.attr,
+       NULL,
+ };
++
+ static struct attribute_group zpci_attr_group = {
+       .attrs = zpci_dev_attrs,
+       .bin_attrs = zpci_bin_attrs,
+-- 
+2.30.2
+
diff --git a/queue-5.12/s390-qdio-let-driver-manage-the-qaob.patch b/queue-5.12/s390-qdio-let-driver-manage-the-qaob.patch
new file mode 100644 (file)
index 0000000..6311f2b
--- /dev/null
@@ -0,0 +1,677 @@
+From 7d8e46f457feb644663996cf468ee48d7550cc57 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 30 Jan 2021 14:56:20 +0100
+Subject: s390/qdio: let driver manage the QAOB
+
+From: Julian Wiedmann <jwi@linux.ibm.com>
+
+[ Upstream commit 396c100472dd63bb1a5389d9dfb25a94943c41c9 ]
+
+We are spending way too much effort on qdio-internal bookkeeping for
+QAOB management & caching, and it's still not robust. Once qdio's
+TX path has detached the QAOB from a PENDING buffer, we lost all
+track of it until it shows up in a CQ notification again. So if the
+device is torn down before that notification arrives, we leak the QAOB.
+
+Just have the driver take care of it, and simply pass down a QAOB if
+they want a TX with async-completion capability. For a buffer in PENDING
+state that requires the QAOB for final completion, qeth can now also try
+to recycle the buffer's QAOB rather than unconditionally freeing it.
+
+This also eliminates the qdio_outbuf_state array, which was only needed
+to transfer the aob->user1 tag from the driver to the qdio layer.
+
+Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
+Acked-by: Benjamin Block <bblock@linux.ibm.com>
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/include/asm/qdio.h      |  22 ++-----
+ drivers/s390/cio/qdio.h           |  10 ---
+ drivers/s390/cio/qdio_main.c      |  63 +++---------------
+ drivers/s390/cio/qdio_setup.c     |  49 +-------------
+ drivers/s390/net/qeth_core.h      |   3 +-
+ drivers/s390/net/qeth_core_main.c | 102 ++++++++++++++----------------
+ drivers/s390/scsi/zfcp_qdio.c     |   7 +-
+ 7 files changed, 66 insertions(+), 190 deletions(-)
+
+diff --git a/arch/s390/include/asm/qdio.h b/arch/s390/include/asm/qdio.h
+index d9215c7106f0..8fc52679543d 100644
+--- a/arch/s390/include/asm/qdio.h
++++ b/arch/s390/include/asm/qdio.h
+@@ -246,21 +246,8 @@ struct slsb {
+       u8 val[QDIO_MAX_BUFFERS_PER_Q];
+ } __attribute__ ((packed, aligned(256)));
+-/**
+- * struct qdio_outbuf_state - SBAL related asynchronous operation information
+- *   (for communication with upper layer programs)
+- *   (only required for use with completion queues)
+- * @user: pointer to upper layer program's state information related to SBAL
+- *        (stored in user1 data of QAOB)
+- */
+-struct qdio_outbuf_state {
+-      void *user;
+-};
+-
+-#define CHSC_AC1_INITIATE_INPUTQ      0x80
+-
+-
+ /* qdio adapter-characteristics-1 flag */
++#define CHSC_AC1_INITIATE_INPUTQ      0x80
+ #define AC1_SIGA_INPUT_NEEDED         0x40    /* process input queues */
+ #define AC1_SIGA_OUTPUT_NEEDED                0x20    /* process output queues */
+ #define AC1_SIGA_SYNC_NEEDED          0x10    /* ask hypervisor to sync */
+@@ -338,7 +325,6 @@ typedef void qdio_handler_t(struct ccw_device *, unsigned int, int,
+  * @int_parm: interruption parameter
+  * @input_sbal_addr_array:  per-queue array, each element points to 128 SBALs
+  * @output_sbal_addr_array: per-queue array, each element points to 128 SBALs
+- * @output_sbal_state_array: no_output_qs * 128 state info (for CQ or NULL)
+  */
+ struct qdio_initialize {
+       unsigned char q_format;
+@@ -357,7 +343,6 @@ struct qdio_initialize {
+       unsigned long int_parm;
+       struct qdio_buffer ***input_sbal_addr_array;
+       struct qdio_buffer ***output_sbal_addr_array;
+-      struct qdio_outbuf_state *output_sbal_state_array;
+ };
+ #define QDIO_STATE_INACTIVE           0x00000002 /* after qdio_cleanup */
+@@ -378,9 +363,10 @@ extern int qdio_allocate(struct ccw_device *cdev, unsigned int no_input_qs,
+ extern int qdio_establish(struct ccw_device *cdev,
+                         struct qdio_initialize *init_data);
+ extern int qdio_activate(struct ccw_device *);
++extern struct qaob *qdio_allocate_aob(void);
+ extern void qdio_release_aob(struct qaob *);
+-extern int do_QDIO(struct ccw_device *, unsigned int, int, unsigned int,
+-                 unsigned int);
++extern int do_QDIO(struct ccw_device *cdev, unsigned int callflags, int q_nr,
++                 unsigned int bufnr, unsigned int count, struct qaob *aob);
+ extern int qdio_start_irq(struct ccw_device *cdev);
+ extern int qdio_stop_irq(struct ccw_device *cdev);
+ extern int qdio_get_next_buffers(struct ccw_device *, int, int *, int *);
+diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
+index 34bf2f197c71..0e0044d70844 100644
+--- a/drivers/s390/cio/qdio.h
++++ b/drivers/s390/cio/qdio.h
+@@ -181,12 +181,6 @@ struct qdio_input_q {
+ struct qdio_output_q {
+       /* PCIs are enabled for the queue */
+       int pci_out_enabled;
+-      /* cq: use asynchronous output buffers */
+-      int use_cq;
+-      /* cq: aobs used for particual SBAL */
+-      struct qaob **aobs;
+-      /* cq: sbal state related to asynchronous operation */
+-      struct qdio_outbuf_state *sbal_state;
+       /* timer to check for more outbound work */
+       struct timer_list timer;
+       /* tasklet to check for completions */
+@@ -379,12 +373,8 @@ int qdio_setup_irq(struct qdio_irq *irq_ptr, struct qdio_initialize *init_data);
+ void qdio_shutdown_irq(struct qdio_irq *irq);
+ void qdio_print_subchannel_info(struct qdio_irq *irq_ptr);
+ void qdio_free_queues(struct qdio_irq *irq_ptr);
+-void qdio_free_async_data(struct qdio_irq *irq_ptr);
+ int qdio_setup_init(void);
+ void qdio_setup_exit(void);
+-int qdio_enable_async_operation(struct qdio_output_q *q);
+-void qdio_disable_async_operation(struct qdio_output_q *q);
+-struct qaob *qdio_allocate_aob(void);
+ int debug_get_buf_state(struct qdio_q *q, unsigned int bufnr,
+                       unsigned char *state);
+diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
+index 03a011619908..307ce7ff5ca4 100644
+--- a/drivers/s390/cio/qdio_main.c
++++ b/drivers/s390/cio/qdio_main.c
+@@ -517,24 +517,6 @@ static inline int qdio_inbound_q_done(struct qdio_q *q, unsigned int start)
+       return 1;
+ }
+-static inline unsigned long qdio_aob_for_buffer(struct qdio_output_q *q,
+-                                      int bufnr)
+-{
+-      unsigned long phys_aob = 0;
+-
+-      if (!q->aobs[bufnr]) {
+-              struct qaob *aob = qdio_allocate_aob();
+-              q->aobs[bufnr] = aob;
+-      }
+-      if (q->aobs[bufnr]) {
+-              q->aobs[bufnr]->user1 = (u64) q->sbal_state[bufnr].user;
+-              phys_aob = virt_to_phys(q->aobs[bufnr]);
+-              WARN_ON_ONCE(phys_aob & 0xFF);
+-      }
+-
+-      return phys_aob;
+-}
+-
+ static inline int qdio_tasklet_schedule(struct qdio_q *q)
+ {
+       if (likely(q->irq_ptr->state == QDIO_IRQ_STATE_ACTIVE)) {
+@@ -548,7 +530,6 @@ static int get_outbound_buffer_frontier(struct qdio_q *q, unsigned int start,
+                                       unsigned int *error)
+ {
+       unsigned char state = 0;
+-      unsigned int i;
+       int count;
+       q->timestamp = get_tod_clock_fast();
+@@ -570,10 +551,6 @@ static int get_outbound_buffer_frontier(struct qdio_q *q, unsigned int start,
+       switch (state) {
+       case SLSB_P_OUTPUT_PENDING:
+-              /* detach the utilized QAOBs: */
+-              for (i = 0; i < count; i++)
+-                      q->u.out.aobs[QDIO_BUFNR(start + i)] = NULL;
+-
+               *error = QDIO_ERROR_SLSB_PENDING;
+               fallthrough;
+       case SLSB_P_OUTPUT_EMPTY:
+@@ -999,7 +976,6 @@ int qdio_free(struct ccw_device *cdev)
+       cdev->private->qdio_data = NULL;
+       mutex_unlock(&irq_ptr->setup_mutex);
+-      qdio_free_async_data(irq_ptr);
+       qdio_free_queues(irq_ptr);
+       free_page((unsigned long) irq_ptr->qdr);
+       free_page(irq_ptr->chsc_page);
+@@ -1075,28 +1051,6 @@ err_dbf:
+ }
+ EXPORT_SYMBOL_GPL(qdio_allocate);
+-static void qdio_detect_hsicq(struct qdio_irq *irq_ptr)
+-{
+-      struct qdio_q *q = irq_ptr->input_qs[0];
+-      int i, use_cq = 0;
+-
+-      if (irq_ptr->nr_input_qs > 1 && queue_type(q) == QDIO_IQDIO_QFMT)
+-              use_cq = 1;
+-
+-      for_each_output_queue(irq_ptr, q, i) {
+-              if (use_cq) {
+-                      if (multicast_outbound(q))
+-                              continue;
+-                      if (qdio_enable_async_operation(&q->u.out) < 0) {
+-                              use_cq = 0;
+-                              continue;
+-                      }
+-              } else
+-                      qdio_disable_async_operation(&q->u.out);
+-      }
+-      DBF_EVENT("use_cq:%d", use_cq);
+-}
+-
+ static void qdio_trace_init_data(struct qdio_irq *irq,
+                                struct qdio_initialize *data)
+ {
+@@ -1191,8 +1145,6 @@ int qdio_establish(struct ccw_device *cdev,
+       qdio_setup_ssqd_info(irq_ptr);
+-      qdio_detect_hsicq(irq_ptr);
+-
+       /* qebsm is now setup if available, initialize buffer states */
+       qdio_init_buf_states(irq_ptr);
+@@ -1297,9 +1249,11 @@ static int handle_inbound(struct qdio_q *q, unsigned int callflags,
+  * @callflags: flags
+  * @bufnr: first buffer to process
+  * @count: how many buffers are filled
++ * @aob: asynchronous operation block
+  */
+ static int handle_outbound(struct qdio_q *q, unsigned int callflags,
+-                         unsigned int bufnr, unsigned int count)
++                         unsigned int bufnr, unsigned int count,
++                         struct qaob *aob)
+ {
+       const unsigned int scan_threshold = q->irq_ptr->scan_threshold;
+       unsigned char state = 0;
+@@ -1320,11 +1274,9 @@ static int handle_outbound(struct qdio_q *q, unsigned int callflags,
+               q->u.out.pci_out_enabled = 0;
+       if (queue_type(q) == QDIO_IQDIO_QFMT) {
+-              unsigned long phys_aob = 0;
+-
+-              if (q->u.out.use_cq && count == 1)
+-                      phys_aob = qdio_aob_for_buffer(&q->u.out, bufnr);
++              unsigned long phys_aob = aob ? virt_to_phys(aob) : 0;
++              WARN_ON_ONCE(!IS_ALIGNED(phys_aob, 256));
+               rc = qdio_kick_outbound_q(q, count, phys_aob);
+       } else if (need_siga_sync(q)) {
+               rc = qdio_siga_sync_q(q);
+@@ -1359,9 +1311,10 @@ static int handle_outbound(struct qdio_q *q, unsigned int callflags,
+  * @q_nr: queue number
+  * @bufnr: buffer number
+  * @count: how many buffers to process
++ * @aob: asynchronous operation block (outbound only)
+  */
+ int do_QDIO(struct ccw_device *cdev, unsigned int callflags,
+-          int q_nr, unsigned int bufnr, unsigned int count)
++          int q_nr, unsigned int bufnr, unsigned int count, struct qaob *aob)
+ {
+       struct qdio_irq *irq_ptr = cdev->private->qdio_data;
+@@ -1383,7 +1336,7 @@ int do_QDIO(struct ccw_device *cdev, unsigned int callflags,
+                                     callflags, bufnr, count);
+       else if (callflags & QDIO_FLAG_SYNC_OUTPUT)
+               return handle_outbound(irq_ptr->output_qs[q_nr],
+-                                     callflags, bufnr, count);
++                                     callflags, bufnr, count, aob);
+       return -EINVAL;
+ }
+ EXPORT_SYMBOL_GPL(do_QDIO);
+diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c
+index c8b9620bc688..da67e4979402 100644
+--- a/drivers/s390/cio/qdio_setup.c
++++ b/drivers/s390/cio/qdio_setup.c
+@@ -30,6 +30,7 @@ struct qaob *qdio_allocate_aob(void)
+ {
+       return kmem_cache_zalloc(qdio_aob_cache, GFP_ATOMIC);
+ }
++EXPORT_SYMBOL_GPL(qdio_allocate_aob);
+ void qdio_release_aob(struct qaob *aob)
+ {
+@@ -247,8 +248,6 @@ static void setup_queues(struct qdio_irq *irq_ptr,
+                        struct qdio_initialize *qdio_init)
+ {
+       struct qdio_q *q;
+-      struct qdio_outbuf_state *output_sbal_state_array =
+-                                qdio_init->output_sbal_state_array;
+       int i;
+       for_each_input_queue(irq_ptr, q, i) {
+@@ -265,9 +264,6 @@ static void setup_queues(struct qdio_irq *irq_ptr,
+               DBF_EVENT("outq:%1d", i);
+               setup_queues_misc(q, irq_ptr, qdio_init->output_handler, i);
+-              q->u.out.sbal_state = output_sbal_state_array;
+-              output_sbal_state_array += QDIO_MAX_BUFFERS_PER_Q;
+-
+               q->is_input_q = 0;
+               setup_storage_lists(q, irq_ptr,
+                                   qdio_init->output_sbal_addr_array[i], i);
+@@ -372,30 +368,6 @@ void qdio_setup_ssqd_info(struct qdio_irq *irq_ptr)
+       DBF_EVENT("3:%4x qib:%4x", irq_ptr->ssqd_desc.qdioac3, irq_ptr->qib.ac);
+ }
+-void qdio_free_async_data(struct qdio_irq *irq_ptr)
+-{
+-      struct qdio_q *q;
+-      int i;
+-
+-      for (i = 0; i < irq_ptr->max_output_qs; i++) {
+-              q = irq_ptr->output_qs[i];
+-              if (q->u.out.use_cq) {
+-                      unsigned int n;
+-
+-                      for (n = 0; n < QDIO_MAX_BUFFERS_PER_Q; n++) {
+-                              struct qaob *aob = q->u.out.aobs[n];
+-
+-                              if (aob) {
+-                                      qdio_release_aob(aob);
+-                                      q->u.out.aobs[n] = NULL;
+-                              }
+-                      }
+-
+-                      qdio_disable_async_operation(&q->u.out);
+-              }
+-      }
+-}
+-
+ static void qdio_fill_qdr_desc(struct qdesfmt0 *desc, struct qdio_q *queue)
+ {
+       desc->sliba = virt_to_phys(queue->slib);
+@@ -545,25 +517,6 @@ void qdio_print_subchannel_info(struct qdio_irq *irq_ptr)
+       printk(KERN_INFO "%s", s);
+ }
+-int qdio_enable_async_operation(struct qdio_output_q *outq)
+-{
+-      outq->aobs = kcalloc(QDIO_MAX_BUFFERS_PER_Q, sizeof(struct qaob *),
+-                           GFP_KERNEL);
+-      if (!outq->aobs) {
+-              outq->use_cq = 0;
+-              return -ENOMEM;
+-      }
+-      outq->use_cq = 1;
+-      return 0;
+-}
+-
+-void qdio_disable_async_operation(struct qdio_output_q *q)
+-{
+-      kfree(q->aobs);
+-      q->aobs = NULL;
+-      q->use_cq = 0;
+-}
+-
+ int __init qdio_setup_init(void)
+ {
+       int rc;
+diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
+index 91acff493612..fd9b869d278e 100644
+--- a/drivers/s390/net/qeth_core.h
++++ b/drivers/s390/net/qeth_core.h
+@@ -437,6 +437,7 @@ struct qeth_qdio_out_buffer {
+       struct qeth_qdio_out_q *q;
+       struct list_head list_entry;
++      struct qaob *aob;
+ };
+ struct qeth_card;
+@@ -499,7 +500,6 @@ struct qeth_out_q_stats {
+ struct qeth_qdio_out_q {
+       struct qdio_buffer *qdio_bufs[QDIO_MAX_BUFFERS_PER_Q];
+       struct qeth_qdio_out_buffer *bufs[QDIO_MAX_BUFFERS_PER_Q];
+-      struct qdio_outbuf_state *bufstates; /* convenience pointer */
+       struct list_head pending_bufs;
+       struct qeth_out_q_stats stats;
+       spinlock_t lock;
+@@ -563,7 +563,6 @@ struct qeth_qdio_info {
+       /* output */
+       unsigned int no_out_queues;
+       struct qeth_qdio_out_q *out_qs[QETH_MAX_OUT_QUEUES];
+-      struct qdio_outbuf_state *out_bufstates;
+       /* priority queueing */
+       int do_prio_queueing;
+diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
+index a814698387bc..175b82b98f36 100644
+--- a/drivers/s390/net/qeth_core_main.c
++++ b/drivers/s390/net/qeth_core_main.c
+@@ -369,8 +369,7 @@ static int qeth_cq_init(struct qeth_card *card)
+                                  QDIO_MAX_BUFFERS_PER_Q);
+               card->qdio.c_q->next_buf_to_init = 127;
+               rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT,
+-                           card->qdio.no_in_queues - 1, 0,
+-                           127);
++                           card->qdio.no_in_queues - 1, 0, 127, NULL);
+               if (rc) {
+                       QETH_CARD_TEXT_(card, 2, "1err%d", rc);
+                       goto out;
+@@ -383,48 +382,22 @@ out:
+ static int qeth_alloc_cq(struct qeth_card *card)
+ {
+-      int rc;
+-
+       if (card->options.cq == QETH_CQ_ENABLED) {
+-              int i;
+-              struct qdio_outbuf_state *outbuf_states;
+-
+               QETH_CARD_TEXT(card, 2, "cqon");
+               card->qdio.c_q = qeth_alloc_qdio_queue();
+               if (!card->qdio.c_q) {
+-                      rc = -1;
+-                      goto kmsg_out;
++                      dev_err(&card->gdev->dev, "Failed to create completion queue\n");
++                      return -ENOMEM;
+               }
++
+               card->qdio.no_in_queues = 2;
+-              card->qdio.out_bufstates =
+-                      kcalloc(card->qdio.no_out_queues *
+-                                      QDIO_MAX_BUFFERS_PER_Q,
+-                              sizeof(struct qdio_outbuf_state),
+-                              GFP_KERNEL);
+-              outbuf_states = card->qdio.out_bufstates;
+-              if (outbuf_states == NULL) {
+-                      rc = -1;
+-                      goto free_cq_out;
+-              }
+-              for (i = 0; i < card->qdio.no_out_queues; ++i) {
+-                      card->qdio.out_qs[i]->bufstates = outbuf_states;
+-                      outbuf_states += QDIO_MAX_BUFFERS_PER_Q;
+-              }
+       } else {
+               QETH_CARD_TEXT(card, 2, "nocq");
+               card->qdio.c_q = NULL;
+               card->qdio.no_in_queues = 1;
+       }
+       QETH_CARD_TEXT_(card, 2, "iqc%d", card->qdio.no_in_queues);
+-      rc = 0;
+-out:
+-      return rc;
+-free_cq_out:
+-      qeth_free_qdio_queue(card->qdio.c_q);
+-      card->qdio.c_q = NULL;
+-kmsg_out:
+-      dev_err(&card->gdev->dev, "Failed to create completion queue\n");
+-      goto out;
++      return 0;
+ }
+ static void qeth_free_cq(struct qeth_card *card)
+@@ -434,8 +407,6 @@ static void qeth_free_cq(struct qeth_card *card)
+               qeth_free_qdio_queue(card->qdio.c_q);
+               card->qdio.c_q = NULL;
+       }
+-      kfree(card->qdio.out_bufstates);
+-      card->qdio.out_bufstates = NULL;
+ }
+ static enum iucv_tx_notify qeth_compute_cq_notification(int sbalf15,
+@@ -487,12 +458,12 @@ static void qeth_qdio_handle_aob(struct qeth_card *card,
+       switch (atomic_xchg(&buffer->state, new_state)) {
+       case QETH_QDIO_BUF_PRIMED:
+               /* Faster than TX completion code, let it handle the async
+-               * completion for us.
++               * completion for us. It will also recycle the QAOB.
+                */
+               break;
+       case QETH_QDIO_BUF_PENDING:
+               /* TX completion code is active and will handle the async
+-               * completion for us.
++               * completion for us. It will also recycle the QAOB.
+                */
+               break;
+       case QETH_QDIO_BUF_NEED_QAOB:
+@@ -501,7 +472,7 @@ static void qeth_qdio_handle_aob(struct qeth_card *card,
+               qeth_notify_skbs(buffer->q, buffer, notification);
+               /* Free dangling allocations. The attached skbs are handled by
+-               * qeth_tx_complete_pending_bufs().
++               * qeth_tx_complete_pending_bufs(), and so is the QAOB.
+                */
+               for (i = 0;
+                    i < aob->sb_count && i < QETH_MAX_BUFFER_ELEMENTS(card);
+@@ -520,8 +491,6 @@ static void qeth_qdio_handle_aob(struct qeth_card *card,
+       default:
+               WARN_ON_ONCE(1);
+       }
+-
+-      qdio_release_aob(aob);
+ }
+ static void qeth_setup_ccw(struct ccw1 *ccw, u8 cmd_code, u8 flags, u32 len,
+@@ -1451,6 +1420,13 @@ static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
+       atomic_set(&buf->state, QETH_QDIO_BUF_EMPTY);
+ }
++static void qeth_free_out_buf(struct qeth_qdio_out_buffer *buf)
++{
++      if (buf->aob)
++              qdio_release_aob(buf->aob);
++      kmem_cache_free(qeth_qdio_outbuf_cache, buf);
++}
++
+ static void qeth_tx_complete_pending_bufs(struct qeth_card *card,
+                                         struct qeth_qdio_out_q *queue,
+                                         bool drain)
+@@ -1468,7 +1444,7 @@ static void qeth_tx_complete_pending_bufs(struct qeth_card *card,
+                       qeth_tx_complete_buf(buf, drain, 0);
+                       list_del(&buf->list_entry);
+-                      kmem_cache_free(qeth_qdio_outbuf_cache, buf);
++                      qeth_free_out_buf(buf);
+               }
+       }
+ }
+@@ -1485,7 +1461,7 @@ static void qeth_drain_output_queue(struct qeth_qdio_out_q *q, bool free)
+               qeth_clear_output_buffer(q, q->bufs[j], true, 0);
+               if (free) {
+-                      kmem_cache_free(qeth_qdio_outbuf_cache, q->bufs[j]);
++                      qeth_free_out_buf(q->bufs[j]);
+                       q->bufs[j] = NULL;
+               }
+       }
+@@ -2637,7 +2613,7 @@ static struct qeth_qdio_out_q *qeth_alloc_output_queue(void)
+ err_out_bufs:
+       while (i > 0)
+-              kmem_cache_free(qeth_qdio_outbuf_cache, q->bufs[--i]);
++              qeth_free_out_buf(q->bufs[--i]);
+       qdio_free_buffers(q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q);
+ err_qdio_bufs:
+       kfree(q);
+@@ -3024,7 +3000,8 @@ static int qeth_init_qdio_queues(struct qeth_card *card)
+       }
+       card->qdio.in_q->next_buf_to_init = QDIO_BUFNR(rx_bufs);
+-      rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 0, 0, rx_bufs);
++      rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 0, 0, rx_bufs,
++                   NULL);
+       if (rc) {
+               QETH_CARD_TEXT_(card, 2, "1err%d", rc);
+               return rc;
+@@ -3516,7 +3493,7 @@ static unsigned int qeth_rx_refill_queue(struct qeth_card *card,
+               }
+               rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 0,
+-                           queue->next_buf_to_init, count);
++                           queue->next_buf_to_init, count, NULL);
+               if (rc) {
+                       QETH_CARD_TEXT(card, 2, "qinberr");
+               }
+@@ -3625,6 +3602,7 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index,
+       struct qeth_qdio_out_buffer *buf = queue->bufs[index];
+       unsigned int qdio_flags = QDIO_FLAG_SYNC_OUTPUT;
+       struct qeth_card *card = queue->card;
++      struct qaob *aob = NULL;
+       int rc;
+       int i;
+@@ -3637,16 +3615,24 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index,
+                               SBAL_EFLAGS_LAST_ENTRY;
+               queue->coalesced_frames += buf->frames;
+-              if (queue->bufstates)
+-                      queue->bufstates[bidx].user = buf;
+-
+               if (IS_IQD(card)) {
+                       skb_queue_walk(&buf->skb_list, skb)
+                               skb_tx_timestamp(skb);
+               }
+       }
+-      if (!IS_IQD(card)) {
++      if (IS_IQD(card)) {
++              if (card->options.cq == QETH_CQ_ENABLED &&
++                  !qeth_iqd_is_mcast_queue(card, queue) &&
++                  count == 1) {
++                      if (!buf->aob)
++                              buf->aob = qdio_allocate_aob();
++                      if (buf->aob) {
++                              aob = buf->aob;
++                              aob->user1 = (u64) buf;
++                      }
++              }
++      } else {
+               if (!queue->do_pack) {
+                       if ((atomic_read(&queue->used_buffers) >=
+                               (QETH_HIGH_WATERMARK_PACK -
+@@ -3677,8 +3663,8 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index,
+       }
+       QETH_TXQ_STAT_INC(queue, doorbell);
+-      rc = do_QDIO(CARD_DDEV(queue->card), qdio_flags,
+-                   queue->queue_no, index, count);
++      rc = do_QDIO(CARD_DDEV(card), qdio_flags, queue->queue_no, index, count,
++                   aob);
+       switch (rc) {
+       case 0:
+@@ -3814,8 +3800,7 @@ static void qeth_qdio_cq_handler(struct qeth_card *card, unsigned int qdio_err,
+               qeth_scrub_qdio_buffer(buffer, QDIO_MAX_ELEMENTS_PER_BUFFER);
+       }
+       rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, queue,
+-                  card->qdio.c_q->next_buf_to_init,
+-                  count);
++                   cq->next_buf_to_init, count, NULL);
+       if (rc) {
+               dev_warn(&card->gdev->dev,
+                       "QDIO reported an error, rc=%i\n", rc);
+@@ -5270,7 +5255,6 @@ static int qeth_qdio_establish(struct qeth_card *card)
+       init_data.int_parm               = (unsigned long) card;
+       init_data.input_sbal_addr_array  = in_sbal_ptrs;
+       init_data.output_sbal_addr_array = out_sbal_ptrs;
+-      init_data.output_sbal_state_array = card->qdio.out_bufstates;
+       init_data.scan_threshold         = IS_IQD(card) ? 0 : 32;
+       if (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_ALLOCATED,
+@@ -6069,7 +6053,15 @@ static void qeth_iqd_tx_complete(struct qeth_qdio_out_q *queue,
+       bool error = !!qdio_error;
+       if (qdio_error == QDIO_ERROR_SLSB_PENDING) {
+-              WARN_ON_ONCE(card->options.cq != QETH_CQ_ENABLED);
++              struct qaob *aob = buffer->aob;
++
++              if (!aob) {
++                      netdev_WARN_ONCE(card->dev,
++                                       "Pending TX buffer %#x without QAOB on TX queue %u\n",
++                                       bidx, queue->queue_no);
++                      qeth_schedule_recovery(card);
++                      return;
++              }
+               QETH_CARD_TEXT_(card, 5, "pel%u", bidx);
+@@ -6125,6 +6117,8 @@ static void qeth_iqd_tx_complete(struct qeth_qdio_out_q *queue,
+               default:
+                       WARN_ON_ONCE(1);
+               }
++
++              memset(aob, 0, sizeof(*aob));
+       } else if (card->options.cq == QETH_CQ_ENABLED) {
+               qeth_notify_skbs(queue, buffer,
+                                qeth_compute_cq_notification(sflags, 0));
+diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
+index 23ab16d65f2a..049596cbfb5d 100644
+--- a/drivers/s390/scsi/zfcp_qdio.c
++++ b/drivers/s390/scsi/zfcp_qdio.c
+@@ -128,7 +128,7 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
+       /*
+        * put SBALs back to response queue
+        */
+-      if (do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, idx, count))
++      if (do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, idx, count, NULL))
+               zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdires2");
+ }
+@@ -298,7 +298,7 @@ int zfcp_qdio_send(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)
+       atomic_sub(sbal_number, &qdio->req_q_free);
+       retval = do_QDIO(qdio->adapter->ccw_device, QDIO_FLAG_SYNC_OUTPUT, 0,
+-                       q_req->sbal_first, sbal_number);
++                       q_req->sbal_first, sbal_number, NULL);
+       if (unlikely(retval)) {
+               /* Failed to submit the IO, roll back our modifications. */
+@@ -463,7 +463,8 @@ int zfcp_qdio_open(struct zfcp_qdio *qdio)
+               sbale->addr = 0;
+       }
+-      if (do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, 0, QDIO_MAX_BUFFERS_PER_Q))
++      if (do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, 0, QDIO_MAX_BUFFERS_PER_Q,
++                  NULL))
+               goto failed_qdio;
+       /* set index of first available SBALS / number of available SBALS */
+-- 
+2.30.2
+
diff --git a/queue-5.12/sched-fair-alternative-sched_slice.patch b/queue-5.12/sched-fair-alternative-sched_slice.patch
new file mode 100644 (file)
index 0000000..2e41a2b
--- /dev/null
@@ -0,0 +1,72 @@
+From 8b329745cc57a132320e0848524bf29956b328ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Mar 2021 13:44:46 +0100
+Subject: sched,fair: Alternative sched_slice()
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+[ Upstream commit 0c2de3f054a59f15e01804b75a04355c48de628c ]
+
+The current sched_slice() seems to have issues; there's two possible
+things that could be improved:
+
+ - the 'nr_running' used for __sched_period() is daft when cgroups are
+   considered. Using the RQ wide h_nr_running seems like a much more
+   consistent number.
+
+ - (esp) cgroups can slice it real fine, which makes for easy
+   over-scheduling, ensure min_gran is what the name says.
+
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Tested-by: Valentin Schneider <valentin.schneider@arm.com>
+Link: https://lkml.kernel.org/r/20210412102001.611897312@infradead.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/fair.c     | 12 +++++++++++-
+ kernel/sched/features.h |  3 +++
+ 2 files changed, 14 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
+index d89ddacc1148..0eeeeeb66f33 100644
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -682,7 +682,13 @@ static u64 __sched_period(unsigned long nr_running)
+  */
+ static u64 sched_slice(struct cfs_rq *cfs_rq, struct sched_entity *se)
+ {
+-      u64 slice = __sched_period(cfs_rq->nr_running + !se->on_rq);
++      unsigned int nr_running = cfs_rq->nr_running;
++      u64 slice;
++
++      if (sched_feat(ALT_PERIOD))
++              nr_running = rq_of(cfs_rq)->cfs.h_nr_running;
++
++      slice = __sched_period(nr_running + !se->on_rq);
+       for_each_sched_entity(se) {
+               struct load_weight *load;
+@@ -699,6 +705,10 @@ static u64 sched_slice(struct cfs_rq *cfs_rq, struct sched_entity *se)
+               }
+               slice = __calc_delta(slice, se->load.weight, load);
+       }
++
++      if (sched_feat(BASE_SLICE))
++              slice = max(slice, (u64)sysctl_sched_min_granularity);
++
+       return slice;
+ }
+diff --git a/kernel/sched/features.h b/kernel/sched/features.h
+index 1bc2b158fc51..e911111df83a 100644
+--- a/kernel/sched/features.h
++++ b/kernel/sched/features.h
+@@ -90,3 +90,6 @@ SCHED_FEAT(WA_BIAS, true)
+  */
+ SCHED_FEAT(UTIL_EST, true)
+ SCHED_FEAT(UTIL_EST_FASTUP, true)
++
++SCHED_FEAT(ALT_PERIOD, true)
++SCHED_FEAT(BASE_SLICE, true)
+-- 
+2.30.2
+
diff --git a/queue-5.12/sched-fair-bring-back-select_idle_smt-but-differentl.patch b/queue-5.12/sched-fair-bring-back-select_idle_smt-but-differentl.patch
new file mode 100644 (file)
index 0000000..868a861
--- /dev/null
@@ -0,0 +1,173 @@
+From 357bc86cbf99999b15d03b9d37aaccebb392ac77 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 Mar 2021 15:19:32 -0400
+Subject: sched/fair: Bring back select_idle_smt(), but differently
+
+From: Rik van Riel <riel@surriel.com>
+
+[ Upstream commit c722f35b513f807629603bbf24640b1a48be21b5 ]
+
+Mel Gorman did some nice work in 9fe1f127b913 ("sched/fair: Merge
+select_idle_core/cpu()"), resulting in the kernel being more efficient
+at finding an idle CPU, and in tasks spending less time waiting to be
+run, both according to the schedstats run_delay numbers, and according
+to measured application latencies. Yay.
+
+The flip side of this is that we see more task migrations (about 30%
+more), higher cache misses, higher memory bandwidth utilization, and
+higher CPU use, for the same number of requests/second.
+
+This is most pronounced on a memcache type workload, which saw a
+consistent 1-3% increase in total CPU use on the system, due to those
+increased task migrations leading to higher L2 cache miss numbers, and
+higher memory utilization. The exclusive L3 cache on Skylake does us
+no favors there.
+
+On our web serving workload, that effect is usually negligible.
+
+It appears that the increased number of CPU migrations is generally a
+good thing, since it leads to lower cpu_delay numbers, reflecting the
+fact that tasks get to run faster. However, the reduced locality and
+the corresponding increase in L2 cache misses hurts a little.
+
+The patch below appears to fix the regression, while keeping the
+benefit of the lower cpu_delay numbers, by reintroducing
+select_idle_smt with a twist: when a socket has no idle cores, check
+to see if the sibling of "prev" is idle, before searching all the
+other CPUs.
+
+This fixes both the occasional 9% regression on the web serving
+workload, and the continuous 2% CPU use regression on the memcache
+type workload.
+
+With Mel's patches and this patch together, task migrations are still
+high, but L2 cache misses, memory bandwidth, and CPU time used are
+back down to what they were before. The p95 and p99 response times for
+the memcache type application improve by about 10% over what they were
+before Mel's patches got merged.
+
+Signed-off-by: Rik van Riel <riel@surriel.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Mel Gorman <mgorman@techsingularity.net>
+Acked-by: Vincent Guittot <vincent.guittot@linaro.org>
+Link: https://lkml.kernel.org/r/20210326151932.2c187840@imladris.surriel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/fair.c | 47 ++++++++++++++++++++++++++++++++++++++-------
+ 1 file changed, 40 insertions(+), 7 deletions(-)
+
+diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
+index 2a4041e3178f..54ca03bacddf 100644
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -6107,6 +6107,24 @@ static int select_idle_core(struct task_struct *p, int core, struct cpumask *cpu
+       return -1;
+ }
++/*
++ * Scan the local SMT mask for idle CPUs.
++ */
++static int select_idle_smt(struct task_struct *p, struct sched_domain *sd, int target)
++{
++      int cpu;
++
++      for_each_cpu(cpu, cpu_smt_mask(target)) {
++              if (!cpumask_test_cpu(cpu, p->cpus_ptr) ||
++                  !cpumask_test_cpu(cpu, sched_domain_span(sd)))
++                      continue;
++              if (available_idle_cpu(cpu) || sched_idle_cpu(cpu))
++                      return cpu;
++      }
++
++      return -1;
++}
++
+ #else /* CONFIG_SCHED_SMT */
+ static inline void set_idle_cores(int cpu, int val)
+@@ -6123,6 +6141,11 @@ static inline int select_idle_core(struct task_struct *p, int core, struct cpuma
+       return __select_idle_cpu(core);
+ }
++static inline int select_idle_smt(struct task_struct *p, struct sched_domain *sd, int target)
++{
++      return -1;
++}
++
+ #endif /* CONFIG_SCHED_SMT */
+ /*
+@@ -6130,11 +6153,10 @@ static inline int select_idle_core(struct task_struct *p, int core, struct cpuma
+  * comparing the average scan cost (tracked in sd->avg_scan_cost) against the
+  * average idle time for this rq (as found in rq->avg_idle).
+  */
+-static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int target)
++static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, bool has_idle_core, int target)
+ {
+       struct cpumask *cpus = this_cpu_cpumask_var_ptr(select_idle_mask);
+       int i, cpu, idle_cpu = -1, nr = INT_MAX;
+-      bool smt = test_idle_cores(target, false);
+       int this = smp_processor_id();
+       struct sched_domain *this_sd;
+       u64 time;
+@@ -6145,7 +6167,7 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int t
+       cpumask_and(cpus, sched_domain_span(sd), p->cpus_ptr);
+-      if (sched_feat(SIS_PROP) && !smt) {
++      if (sched_feat(SIS_PROP) && !has_idle_core) {
+               u64 avg_cost, avg_idle, span_avg;
+               /*
+@@ -6165,7 +6187,7 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int t
+       }
+       for_each_cpu_wrap(cpu, cpus, target) {
+-              if (smt) {
++              if (has_idle_core) {
+                       i = select_idle_core(p, cpu, cpus, &idle_cpu);
+                       if ((unsigned int)i < nr_cpumask_bits)
+                               return i;
+@@ -6179,10 +6201,10 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int t
+               }
+       }
+-      if (smt)
++      if (has_idle_core)
+               set_idle_cores(this, false);
+-      if (sched_feat(SIS_PROP) && !smt) {
++      if (sched_feat(SIS_PROP) && !has_idle_core) {
+               time = cpu_clock(this) - time;
+               update_avg(&this_sd->avg_scan_cost, time);
+       }
+@@ -6237,6 +6259,7 @@ static inline bool asym_fits_capacity(int task_util, int cpu)
+  */
+ static int select_idle_sibling(struct task_struct *p, int prev, int target)
+ {
++      bool has_idle_core = false;
+       struct sched_domain *sd;
+       unsigned long task_util;
+       int i, recent_used_cpu;
+@@ -6316,7 +6339,17 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target)
+       if (!sd)
+               return target;
+-      i = select_idle_cpu(p, sd, target);
++      if (sched_smt_active()) {
++              has_idle_core = test_idle_cores(target, false);
++
++              if (!has_idle_core && cpus_share_cache(prev, target)) {
++                      i = select_idle_smt(p, sd, prev);
++                      if ((unsigned int)i < nr_cpumask_bits)
++                              return i;
++              }
++      }
++
++      i = select_idle_cpu(p, sd, has_idle_core, target);
+       if ((unsigned)i < nr_cpumask_bits)
+               return i;
+-- 
+2.30.2
+
diff --git a/queue-5.12/sched-fair-fix-task-utilization-accountability-in-co.patch b/queue-5.12/sched-fair-fix-task-utilization-accountability-in-co.patch
new file mode 100644 (file)
index 0000000..2fe18f4
--- /dev/null
@@ -0,0 +1,124 @@
+From 8c811eb065f19cdccb3addb3434a0ee72f6ae42b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Feb 2021 08:36:11 +0000
+Subject: sched/fair: Fix task utilization accountability in compute_energy()
+
+From: Vincent Donnefort <vincent.donnefort@arm.com>
+
+[ Upstream commit 0372e1cf70c28de6babcba38ef97b6ae3400b101 ]
+
+find_energy_efficient_cpu() (feec()) computes for each perf_domain (pd) an
+energy delta as follows:
+
+  feec(task)
+    for_each_pd
+      base_energy = compute_energy(task, -1, pd)
+        -> for_each_cpu(pd)
+           -> cpu_util_next(cpu, task, -1)
+
+      energy_delta = compute_energy(task, dst_cpu, pd)
+        -> for_each_cpu(pd)
+           -> cpu_util_next(cpu, task, dst_cpu)
+      energy_delta -= base_energy
+
+Then it picks the best CPU as being the one that minimizes energy_delta.
+
+cpu_util_next() estimates the CPU utilization that would happen if the
+task was placed on dst_cpu as follows:
+
+  max(cpu_util + task_util, cpu_util_est + _task_util_est)
+
+The task contribution to the energy delta can then be either:
+
+  (1) _task_util_est, on a mostly idle CPU, where cpu_util is close to 0
+      and _task_util_est > cpu_util.
+  (2) task_util, on a mostly busy CPU, where cpu_util > _task_util_est.
+
+  (cpu_util_est doesn't appear here. It is 0 when a CPU is idle and
+   otherwise must be small enough so that feec() takes the CPU as a
+   potential target for the task placement)
+
+This is problematic for feec(), as cpu_util_next() might give an unfair
+advantage to a CPU which is mostly busy (2) compared to one which is
+mostly idle (1). _task_util_est being always bigger than task_util in
+feec() (as the task is waking up), the task contribution to the energy
+might look smaller on certain CPUs (2) and this breaks the energy
+comparison.
+
+This issue is, moreover, not sporadic. By starving idle CPUs, it keeps
+their cpu_util < _task_util_est (1) while others will maintain cpu_util >
+_task_util_est (2).
+
+Fix this problem by always using max(task_util, _task_util_est) as a task
+contribution to the energy (ENERGY_UTIL). The new estimated CPU
+utilization for the energy would then be:
+
+  max(cpu_util, cpu_util_est) + max(task_util, _task_util_est)
+
+compute_energy() still needs to know which OPP would be selected if the
+task would be migrated in the perf_domain (FREQUENCY_UTIL). Hence,
+cpu_util_next() is still used to estimate the maximum util within the pd.
+
+Signed-off-by: Vincent Donnefort <vincent.donnefort@arm.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Reviewed-by: Quentin Perret <qperret@google.com>
+Reviewed-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
+Link: https://lkml.kernel.org/r/20210225083612.1113823-2-vincent.donnefort@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/fair.c | 24 ++++++++++++++++++++----
+ 1 file changed, 20 insertions(+), 4 deletions(-)
+
+diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
+index 794c2cb945f8..e3c2dcb1b015 100644
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -6518,8 +6518,24 @@ compute_energy(struct task_struct *p, int dst_cpu, struct perf_domain *pd)
+        * its pd list and will not be accounted by compute_energy().
+        */
+       for_each_cpu_and(cpu, pd_mask, cpu_online_mask) {
+-              unsigned long cpu_util, util_cfs = cpu_util_next(cpu, p, dst_cpu);
+-              struct task_struct *tsk = cpu == dst_cpu ? p : NULL;
++              unsigned long util_freq = cpu_util_next(cpu, p, dst_cpu);
++              unsigned long cpu_util, util_running = util_freq;
++              struct task_struct *tsk = NULL;
++
++              /*
++               * When @p is placed on @cpu:
++               *
++               * util_running = max(cpu_util, cpu_util_est) +
++               *                max(task_util, _task_util_est)
++               *
++               * while cpu_util_next is: max(cpu_util + task_util,
++               *                             cpu_util_est + _task_util_est)
++               */
++              if (cpu == dst_cpu) {
++                      tsk = p;
++                      util_running =
++                              cpu_util_next(cpu, p, -1) + task_util_est(p);
++              }
+               /*
+                * Busy time computation: utilization clamping is not
+@@ -6527,7 +6543,7 @@ compute_energy(struct task_struct *p, int dst_cpu, struct perf_domain *pd)
+                * is already enough to scale the EM reported power
+                * consumption at the (eventually clamped) cpu_capacity.
+                */
+-              sum_util += effective_cpu_util(cpu, util_cfs, cpu_cap,
++              sum_util += effective_cpu_util(cpu, util_running, cpu_cap,
+                                              ENERGY_UTIL, NULL);
+               /*
+@@ -6537,7 +6553,7 @@ compute_energy(struct task_struct *p, int dst_cpu, struct perf_domain *pd)
+                * NOTE: in case RT tasks are running, by default the
+                * FREQUENCY_UTIL's utilization can be max OPP.
+                */
+-              cpu_util = effective_cpu_util(cpu, util_cfs, cpu_cap,
++              cpu_util = effective_cpu_util(cpu, util_freq, cpu_cap,
+                                             FREQUENCY_UTIL, tsk);
+               max_util = max(max_util, cpu_util);
+       }
+-- 
+2.30.2
+
diff --git a/queue-5.12/sched-fair-ignore-percpu-threads-for-imbalance-pulls.patch b/queue-5.12/sched-fair-ignore-percpu-threads-for-imbalance-pulls.patch
new file mode 100644 (file)
index 0000000..47bee28
--- /dev/null
@@ -0,0 +1,76 @@
+From 87eb64e863a9a8fa5c8cf1e08674a5e4a678be36 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Apr 2021 23:06:26 +0100
+Subject: sched/fair: Ignore percpu threads for imbalance pulls
+
+From: Lingutla Chandrasekhar <clingutla@codeaurora.org>
+
+[ Upstream commit 9bcb959d05eeb564dfc9cac13a59843a4fb2edf2 ]
+
+During load balance, LBF_SOME_PINNED will be set if any candidate task
+cannot be detached due to CPU affinity constraints. This can result in
+setting env->sd->parent->sgc->group_imbalance, which can lead to a group
+being classified as group_imbalanced (rather than any of the other, lower
+group_type) when balancing at a higher level.
+
+In workloads involving a single task per CPU, LBF_SOME_PINNED can often be
+set due to per-CPU kthreads being the only other runnable tasks on any
+given rq. This results in changing the group classification during
+load-balance at higher levels when in reality there is nothing that can be
+done for this affinity constraint: per-CPU kthreads, as the name implies,
+don't get to move around (modulo hotplug shenanigans).
+
+It's not as clear for userspace tasks - a task could be in an N-CPU cpuset
+with N-1 offline CPUs, making it an "accidental" per-CPU task rather than
+an intended one. KTHREAD_IS_PER_CPU gives us an indisputable signal which
+we can leverage here to not set LBF_SOME_PINNED.
+
+Note that the aforementioned classification to group_imbalance (when
+nothing can be done) is especially problematic on big.LITTLE systems, which
+have a topology the likes of:
+
+  DIE [          ]
+  MC  [    ][    ]
+       0  1  2  3
+       L  L  B  B
+
+  arch_scale_cpu_capacity(L) < arch_scale_cpu_capacity(B)
+
+Here, setting LBF_SOME_PINNED due to a per-CPU kthread when balancing at MC
+level on CPUs [0-1] will subsequently prevent CPUs [2-3] from classifying
+the [0-1] group as group_misfit_task when balancing at DIE level. Thus, if
+CPUs [0-1] are running CPU-bound (misfit) tasks, ill-timed per-CPU kthreads
+can significantly delay the upgmigration of said misfit tasks. Systems
+relying on ASYM_PACKING are likely to face similar issues.
+
+Signed-off-by: Lingutla Chandrasekhar <clingutla@codeaurora.org>
+[Use kthread_is_per_cpu() rather than p->nr_cpus_allowed]
+[Reword changelog]
+Signed-off-by: Valentin Schneider <valentin.schneider@arm.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
+Reviewed-by: Vincent Guittot <vincent.guittot@linaro.org>
+Link: https://lkml.kernel.org/r/20210407220628.3798191-2-valentin.schneider@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/fair.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
+index 54ca03bacddf..d89ddacc1148 100644
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -7597,6 +7597,10 @@ int can_migrate_task(struct task_struct *p, struct lb_env *env)
+       if (throttled_lb_pair(task_group(p), env->src_cpu, env->dst_cpu))
+               return 0;
++      /* Disregard pcpu kthreads; they are where they need to be. */
++      if ((p->flags & PF_KTHREAD) && kthread_is_per_cpu(p))
++              return 0;
++
+       if (!cpumask_test_cpu(env->dst_cpu, p->cpus_ptr)) {
+               int cpu;
+-- 
+2.30.2
+
diff --git a/queue-5.12/sched-pelt-fix-task-util_est-update-filtering.patch b/queue-5.12/sched-pelt-fix-task-util_est-update-filtering.patch
new file mode 100644 (file)
index 0000000..b4e5268
--- /dev/null
@@ -0,0 +1,94 @@
+From a3ab4db7deba6ba248d330bccda0ab43054796a3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Feb 2021 16:58:20 +0000
+Subject: sched/pelt: Fix task util_est update filtering
+
+From: Vincent Donnefort <vincent.donnefort@arm.com>
+
+[ Upstream commit b89997aa88f0b07d8a6414c908af75062103b8c9 ]
+
+Being called for each dequeue, util_est reduces the number of its updates
+by filtering out when the EWMA signal is different from the task util_avg
+by less than 1%. It is a problem for a sudden util_avg ramp-up. Due to the
+decay from a previous high util_avg, EWMA might now be close enough to
+the new util_avg. No update would then happen while it would leave
+ue.enqueued with an out-of-date value.
+
+Taking into consideration the two util_est members, EWMA and enqueued for
+the filtering, ensures, for both, an up-to-date value.
+
+This is for now an issue only for the trace probe that might return the
+stale value. Functional-wise, it isn't a problem, as the value is always
+accessed through max(enqueued, ewma).
+
+This problem has been observed using LISA's UtilConvergence:test_means on
+the sd845c board.
+
+No regression observed with Hackbench on sd845c and Perf-bench sched pipe
+on hikey/hikey960.
+
+Signed-off-by: Vincent Donnefort <vincent.donnefort@arm.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Reviewed-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
+Reviewed-by: Vincent Guittot <vincent.guittot@linaro.org>
+Link: https://lkml.kernel.org/r/20210225165820.1377125-1-vincent.donnefort@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/fair.c | 15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
+index e3c2dcb1b015..2a4041e3178f 100644
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -3941,6 +3941,8 @@ static inline void util_est_dequeue(struct cfs_rq *cfs_rq,
+       trace_sched_util_est_cfs_tp(cfs_rq);
+ }
++#define UTIL_EST_MARGIN (SCHED_CAPACITY_SCALE / 100)
++
+ /*
+  * Check if a (signed) value is within a specified (unsigned) margin,
+  * based on the observation that:
+@@ -3958,7 +3960,7 @@ static inline void util_est_update(struct cfs_rq *cfs_rq,
+                                  struct task_struct *p,
+                                  bool task_sleep)
+ {
+-      long last_ewma_diff;
++      long last_ewma_diff, last_enqueued_diff;
+       struct util_est ue;
+       if (!sched_feat(UTIL_EST))
+@@ -3979,6 +3981,8 @@ static inline void util_est_update(struct cfs_rq *cfs_rq,
+       if (ue.enqueued & UTIL_AVG_UNCHANGED)
+               return;
++      last_enqueued_diff = ue.enqueued;
++
+       /*
+        * Reset EWMA on utilization increases, the moving average is used only
+        * to smooth utilization decreases.
+@@ -3992,12 +3996,17 @@ static inline void util_est_update(struct cfs_rq *cfs_rq,
+       }
+       /*
+-       * Skip update of task's estimated utilization when its EWMA is
++       * Skip update of task's estimated utilization when its members are
+        * already ~1% close to its last activation value.
+        */
+       last_ewma_diff = ue.enqueued - ue.ewma;
+-      if (within_margin(last_ewma_diff, (SCHED_CAPACITY_SCALE / 100)))
++      last_enqueued_diff -= ue.enqueued;
++      if (within_margin(last_ewma_diff, UTIL_EST_MARGIN)) {
++              if (!within_margin(last_enqueued_diff, UTIL_EST_MARGIN))
++                      goto done;
++
+               return;
++      }
+       /*
+        * To avoid overestimation of actual task utilization, skip updates if
+-- 
+2.30.2
+
diff --git a/queue-5.12/sched-psi-handle-potential-task-count-underflow-bugs.patch b/queue-5.12/sched-psi-handle-potential-task-count-underflow-bugs.patch
new file mode 100644 (file)
index 0000000..18ec1f5
--- /dev/null
@@ -0,0 +1,56 @@
+From ac0f5ed80d73fbc9e0d9f450e3d17733c8f6f135 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Apr 2021 20:32:16 +0530
+Subject: sched,psi: Handle potential task count underflow bugs more gracefully
+
+From: Charan Teja Reddy <charante@codeaurora.org>
+
+[ Upstream commit 9d10a13d1e4c349b76f1c675a874a7f981d6d3b4 ]
+
+psi_group_cpu->tasks, represented by the unsigned int, stores the
+number of tasks that could be stalled on a psi resource(io/mem/cpu).
+Decrementing these counters at zero leads to wrapping which further
+leads to the psi_group_cpu->state_mask is being set with the
+respective pressure state. This could result into the unnecessary time
+sampling for the pressure state thus cause the spurious psi events.
+This can further lead to wrong actions being taken at the user land
+based on these psi events.
+
+Though psi_bug is set under these conditions but that just for debug
+purpose. Fix it by decrementing the ->tasks count only when it is
+non-zero.
+
+Signed-off-by: Charan Teja Reddy <charante@codeaurora.org>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Acked-by: Johannes Weiner <hannes@cmpxchg.org>
+Link: https://lkml.kernel.org/r/1618585336-37219-1-git-send-email-charante@codeaurora.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/psi.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/sched/psi.c b/kernel/sched/psi.c
+index 967732c0766c..651218ded981 100644
+--- a/kernel/sched/psi.c
++++ b/kernel/sched/psi.c
+@@ -711,14 +711,15 @@ static void psi_group_change(struct psi_group *group, int cpu,
+       for (t = 0, m = clear; m; m &= ~(1 << t), t++) {
+               if (!(m & (1 << t)))
+                       continue;
+-              if (groupc->tasks[t] == 0 && !psi_bug) {
++              if (groupc->tasks[t]) {
++                      groupc->tasks[t]--;
++              } else if (!psi_bug) {
+                       printk_deferred(KERN_ERR "psi: task underflow! cpu=%d t=%d tasks=[%u %u %u %u] clear=%x set=%x\n",
+                                       cpu, t, groupc->tasks[0],
+                                       groupc->tasks[1], groupc->tasks[2],
+                                       groupc->tasks[3], clear, set);
+                       psi_bug = 1;
+               }
+-              groupc->tasks[t]--;
+       }
+       for (t = 0; set; set &= ~(1 << t), t++)
+-- 
+2.30.2
+
diff --git a/queue-5.12/sched-topology-fix-the-issue-groups-don-t-span-domai.patch b/queue-5.12/sched-topology-fix-the-issue-groups-don-t-span-domai.patch
new file mode 100644 (file)
index 0000000..9aac8a0
--- /dev/null
@@ -0,0 +1,373 @@
+From bf9ce40d9583bfb432752435358029513591754b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Feb 2021 16:09:44 +1300
+Subject: sched/topology: fix the issue groups don't span domain->span for NUMA
+ diameter > 2
+
+From: Barry Song <song.bao.hua@hisilicon.com>
+
+[ Upstream commit 585b6d2723dc927ebc4ad884c4e879e4da8bc21f ]
+
+As long as NUMA diameter > 2, building sched_domain by sibling's child
+domain will definitely create a sched_domain with sched_group which will
+span out of the sched_domain:
+
+               +------+         +------+        +-------+       +------+
+               | node |  12     |node  | 20     | node  |  12   |node  |
+               |  0   +---------+1     +--------+ 2     +-------+3     |
+               +------+         +------+        +-------+       +------+
+
+domain0        node0            node1            node2          node3
+
+domain1        node0+1          node0+1          node2+3        node2+3
+                                                 +
+domain2        node0+1+2                         |
+             group: node0+1                      |
+               group:node2+3 <-------------------+
+
+when node2 is added into the domain2 of node0, kernel is using the child
+domain of node2's domain2, which is domain1(node2+3). Node 3 is outside
+the span of the domain including node0+1+2.
+
+This will make load_balance() run based on screwed avg_load and group_type
+in the sched_group spanning out of the sched_domain, and it also makes
+select_task_rq_fair() pick an idle CPU outside the sched_domain.
+
+Real servers which suffer from this problem include Kunpeng920 and 8-node
+Sun Fire X4600-M2, at least.
+
+Here we move to use the *child* domain of the *child* domain of node2's
+domain2 as the new added sched_group. At the same, we re-use the lower
+level sgc directly.
+               +------+         +------+        +-------+       +------+
+               | node |  12     |node  | 20     | node  |  12   |node  |
+               |  0   +---------+1     +--------+ 2     +-------+3     |
+               +------+         +------+        +-------+       +------+
+
+domain0        node0            node1          +- node2          node3
+                                               |
+domain1        node0+1          node0+1        | node2+3        node2+3
+                                               |
+domain2        node0+1+2                       |
+             group: node0+1                    |
+               group:node2 <-------------------+
+
+While the lower level sgc is re-used, this patch only changes the remote
+sched_groups for those sched_domains playing grandchild trick, therefore,
+sgc->next_update is still safe since it's only touched by CPUs that have
+the group span as local group. And sgc->imbalance is also safe because
+sd_parent remains the same in load_balance and LB only tries other CPUs
+from the local group.
+Moreover, since local groups are not touched, they are still getting
+roughly equal size in a TL. And should_we_balance() only matters with
+local groups, so the pull probability of those groups are still roughly
+equal.
+
+Tested by the below topology:
+qemu-system-aarch64  -M virt -nographic \
+ -smp cpus=8 \
+ -numa node,cpus=0-1,nodeid=0 \
+ -numa node,cpus=2-3,nodeid=1 \
+ -numa node,cpus=4-5,nodeid=2 \
+ -numa node,cpus=6-7,nodeid=3 \
+ -numa dist,src=0,dst=1,val=12 \
+ -numa dist,src=0,dst=2,val=20 \
+ -numa dist,src=0,dst=3,val=22 \
+ -numa dist,src=1,dst=2,val=22 \
+ -numa dist,src=2,dst=3,val=12 \
+ -numa dist,src=1,dst=3,val=24 \
+ -m 4G -cpu cortex-a57 -kernel arch/arm64/boot/Image
+
+w/o patch, we get lots of "groups don't span domain->span":
+[    0.802139] CPU0 attaching sched-domain(s):
+[    0.802193]  domain-0: span=0-1 level=MC
+[    0.802443]   groups: 0:{ span=0 cap=1013 }, 1:{ span=1 cap=979 }
+[    0.802693]   domain-1: span=0-3 level=NUMA
+[    0.802731]    groups: 0:{ span=0-1 cap=1992 }, 2:{ span=2-3 cap=1943 }
+[    0.802811]    domain-2: span=0-5 level=NUMA
+[    0.802829]     groups: 0:{ span=0-3 cap=3935 }, 4:{ span=4-7 cap=3937 }
+[    0.802881] ERROR: groups don't span domain->span
+[    0.803058]     domain-3: span=0-7 level=NUMA
+[    0.803080]      groups: 0:{ span=0-5 mask=0-1 cap=5843 }, 6:{ span=4-7 mask=6-7 cap=4077 }
+[    0.804055] CPU1 attaching sched-domain(s):
+[    0.804072]  domain-0: span=0-1 level=MC
+[    0.804096]   groups: 1:{ span=1 cap=979 }, 0:{ span=0 cap=1013 }
+[    0.804152]   domain-1: span=0-3 level=NUMA
+[    0.804170]    groups: 0:{ span=0-1 cap=1992 }, 2:{ span=2-3 cap=1943 }
+[    0.804219]    domain-2: span=0-5 level=NUMA
+[    0.804236]     groups: 0:{ span=0-3 cap=3935 }, 4:{ span=4-7 cap=3937 }
+[    0.804302] ERROR: groups don't span domain->span
+[    0.804520]     domain-3: span=0-7 level=NUMA
+[    0.804546]      groups: 0:{ span=0-5 mask=0-1 cap=5843 }, 6:{ span=4-7 mask=6-7 cap=4077 }
+[    0.804677] CPU2 attaching sched-domain(s):
+[    0.804687]  domain-0: span=2-3 level=MC
+[    0.804705]   groups: 2:{ span=2 cap=934 }, 3:{ span=3 cap=1009 }
+[    0.804754]   domain-1: span=0-3 level=NUMA
+[    0.804772]    groups: 2:{ span=2-3 cap=1943 }, 0:{ span=0-1 cap=1992 }
+[    0.804820]    domain-2: span=0-5 level=NUMA
+[    0.804836]     groups: 2:{ span=0-3 mask=2-3 cap=3991 }, 4:{ span=0-1,4-7 mask=4-5 cap=5985 }
+[    0.804944] ERROR: groups don't span domain->span
+[    0.805108]     domain-3: span=0-7 level=NUMA
+[    0.805134]      groups: 2:{ span=0-5 mask=2-3 cap=5899 }, 6:{ span=0-1,4-7 mask=6-7 cap=6125 }
+[    0.805223] CPU3 attaching sched-domain(s):
+[    0.805232]  domain-0: span=2-3 level=MC
+[    0.805249]   groups: 3:{ span=3 cap=1009 }, 2:{ span=2 cap=934 }
+[    0.805319]   domain-1: span=0-3 level=NUMA
+[    0.805336]    groups: 2:{ span=2-3 cap=1943 }, 0:{ span=0-1 cap=1992 }
+[    0.805383]    domain-2: span=0-5 level=NUMA
+[    0.805399]     groups: 2:{ span=0-3 mask=2-3 cap=3991 }, 4:{ span=0-1,4-7 mask=4-5 cap=5985 }
+[    0.805458] ERROR: groups don't span domain->span
+[    0.805605]     domain-3: span=0-7 level=NUMA
+[    0.805626]      groups: 2:{ span=0-5 mask=2-3 cap=5899 }, 6:{ span=0-1,4-7 mask=6-7 cap=6125 }
+[    0.805712] CPU4 attaching sched-domain(s):
+[    0.805721]  domain-0: span=4-5 level=MC
+[    0.805738]   groups: 4:{ span=4 cap=984 }, 5:{ span=5 cap=924 }
+[    0.805787]   domain-1: span=4-7 level=NUMA
+[    0.805803]    groups: 4:{ span=4-5 cap=1908 }, 6:{ span=6-7 cap=2029 }
+[    0.805851]    domain-2: span=0-1,4-7 level=NUMA
+[    0.805867]     groups: 4:{ span=4-7 cap=3937 }, 0:{ span=0-3 cap=3935 }
+[    0.805915] ERROR: groups don't span domain->span
+[    0.806108]     domain-3: span=0-7 level=NUMA
+[    0.806130]      groups: 4:{ span=0-1,4-7 mask=4-5 cap=5985 }, 2:{ span=0-3 mask=2-3 cap=3991 }
+[    0.806214] CPU5 attaching sched-domain(s):
+[    0.806222]  domain-0: span=4-5 level=MC
+[    0.806240]   groups: 5:{ span=5 cap=924 }, 4:{ span=4 cap=984 }
+[    0.806841]   domain-1: span=4-7 level=NUMA
+[    0.806866]    groups: 4:{ span=4-5 cap=1908 }, 6:{ span=6-7 cap=2029 }
+[    0.806934]    domain-2: span=0-1,4-7 level=NUMA
+[    0.806953]     groups: 4:{ span=4-7 cap=3937 }, 0:{ span=0-3 cap=3935 }
+[    0.807004] ERROR: groups don't span domain->span
+[    0.807312]     domain-3: span=0-7 level=NUMA
+[    0.807386]      groups: 4:{ span=0-1,4-7 mask=4-5 cap=5985 }, 2:{ span=0-3 mask=2-3 cap=3991 }
+[    0.807686] CPU6 attaching sched-domain(s):
+[    0.807710]  domain-0: span=6-7 level=MC
+[    0.807750]   groups: 6:{ span=6 cap=1017 }, 7:{ span=7 cap=1012 }
+[    0.807840]   domain-1: span=4-7 level=NUMA
+[    0.807870]    groups: 6:{ span=6-7 cap=2029 }, 4:{ span=4-5 cap=1908 }
+[    0.807952]    domain-2: span=0-1,4-7 level=NUMA
+[    0.807985]     groups: 6:{ span=4-7 mask=6-7 cap=4077 }, 0:{ span=0-5 mask=0-1 cap=5843 }
+[    0.808045] ERROR: groups don't span domain->span
+[    0.808257]     domain-3: span=0-7 level=NUMA
+[    0.808571]      groups: 6:{ span=0-1,4-7 mask=6-7 cap=6125 }, 2:{ span=0-5 mask=2-3 cap=5899 }
+[    0.808848] CPU7 attaching sched-domain(s):
+[    0.808860]  domain-0: span=6-7 level=MC
+[    0.808880]   groups: 7:{ span=7 cap=1012 }, 6:{ span=6 cap=1017 }
+[    0.808953]   domain-1: span=4-7 level=NUMA
+[    0.808974]    groups: 6:{ span=6-7 cap=2029 }, 4:{ span=4-5 cap=1908 }
+[    0.809034]    domain-2: span=0-1,4-7 level=NUMA
+[    0.809055]     groups: 6:{ span=4-7 mask=6-7 cap=4077 }, 0:{ span=0-5 mask=0-1 cap=5843 }
+[    0.809128] ERROR: groups don't span domain->span
+[    0.810361]     domain-3: span=0-7 level=NUMA
+[    0.810400]      groups: 6:{ span=0-1,4-7 mask=6-7 cap=5961 }, 2:{ span=0-5 mask=2-3 cap=5903 }
+
+w/ patch, we don't get "groups don't span domain->span" any more:
+[    1.486271] CPU0 attaching sched-domain(s):
+[    1.486820]  domain-0: span=0-1 level=MC
+[    1.500924]   groups: 0:{ span=0 cap=980 }, 1:{ span=1 cap=994 }
+[    1.515717]   domain-1: span=0-3 level=NUMA
+[    1.515903]    groups: 0:{ span=0-1 cap=1974 }, 2:{ span=2-3 cap=1989 }
+[    1.516989]    domain-2: span=0-5 level=NUMA
+[    1.517124]     groups: 0:{ span=0-3 cap=3963 }, 4:{ span=4-5 cap=1949 }
+[    1.517369]     domain-3: span=0-7 level=NUMA
+[    1.517423]      groups: 0:{ span=0-5 mask=0-1 cap=5912 }, 6:{ span=4-7 mask=6-7 cap=4054 }
+[    1.520027] CPU1 attaching sched-domain(s):
+[    1.520097]  domain-0: span=0-1 level=MC
+[    1.520184]   groups: 1:{ span=1 cap=994 }, 0:{ span=0 cap=980 }
+[    1.520429]   domain-1: span=0-3 level=NUMA
+[    1.520487]    groups: 0:{ span=0-1 cap=1974 }, 2:{ span=2-3 cap=1989 }
+[    1.520687]    domain-2: span=0-5 level=NUMA
+[    1.520744]     groups: 0:{ span=0-3 cap=3963 }, 4:{ span=4-5 cap=1949 }
+[    1.520948]     domain-3: span=0-7 level=NUMA
+[    1.521038]      groups: 0:{ span=0-5 mask=0-1 cap=5912 }, 6:{ span=4-7 mask=6-7 cap=4054 }
+[    1.522068] CPU2 attaching sched-domain(s):
+[    1.522348]  domain-0: span=2-3 level=MC
+[    1.522606]   groups: 2:{ span=2 cap=1003 }, 3:{ span=3 cap=986 }
+[    1.522832]   domain-1: span=0-3 level=NUMA
+[    1.522885]    groups: 2:{ span=2-3 cap=1989 }, 0:{ span=0-1 cap=1974 }
+[    1.523043]    domain-2: span=0-5 level=NUMA
+[    1.523092]     groups: 2:{ span=0-3 mask=2-3 cap=4037 }, 4:{ span=4-5 cap=1949 }
+[    1.523302]     domain-3: span=0-7 level=NUMA
+[    1.523352]      groups: 2:{ span=0-5 mask=2-3 cap=5986 }, 6:{ span=0-1,4-7 mask=6-7 cap=6102 }
+[    1.523748] CPU3 attaching sched-domain(s):
+[    1.523774]  domain-0: span=2-3 level=MC
+[    1.523825]   groups: 3:{ span=3 cap=986 }, 2:{ span=2 cap=1003 }
+[    1.524009]   domain-1: span=0-3 level=NUMA
+[    1.524086]    groups: 2:{ span=2-3 cap=1989 }, 0:{ span=0-1 cap=1974 }
+[    1.524281]    domain-2: span=0-5 level=NUMA
+[    1.524331]     groups: 2:{ span=0-3 mask=2-3 cap=4037 }, 4:{ span=4-5 cap=1949 }
+[    1.524534]     domain-3: span=0-7 level=NUMA
+[    1.524586]      groups: 2:{ span=0-5 mask=2-3 cap=5986 }, 6:{ span=0-1,4-7 mask=6-7 cap=6102 }
+[    1.524847] CPU4 attaching sched-domain(s):
+[    1.524873]  domain-0: span=4-5 level=MC
+[    1.524954]   groups: 4:{ span=4 cap=958 }, 5:{ span=5 cap=991 }
+[    1.525105]   domain-1: span=4-7 level=NUMA
+[    1.525153]    groups: 4:{ span=4-5 cap=1949 }, 6:{ span=6-7 cap=2006 }
+[    1.525368]    domain-2: span=0-1,4-7 level=NUMA
+[    1.525428]     groups: 4:{ span=4-7 cap=3955 }, 0:{ span=0-1 cap=1974 }
+[    1.532726]     domain-3: span=0-7 level=NUMA
+[    1.532811]      groups: 4:{ span=0-1,4-7 mask=4-5 cap=6003 }, 2:{ span=0-3 mask=2-3 cap=4037 }
+[    1.534125] CPU5 attaching sched-domain(s):
+[    1.534159]  domain-0: span=4-5 level=MC
+[    1.534303]   groups: 5:{ span=5 cap=991 }, 4:{ span=4 cap=958 }
+[    1.534490]   domain-1: span=4-7 level=NUMA
+[    1.534572]    groups: 4:{ span=4-5 cap=1949 }, 6:{ span=6-7 cap=2006 }
+[    1.534734]    domain-2: span=0-1,4-7 level=NUMA
+[    1.534783]     groups: 4:{ span=4-7 cap=3955 }, 0:{ span=0-1 cap=1974 }
+[    1.536057]     domain-3: span=0-7 level=NUMA
+[    1.536430]      groups: 4:{ span=0-1,4-7 mask=4-5 cap=6003 }, 2:{ span=0-3 mask=2-3 cap=3896 }
+[    1.536815] CPU6 attaching sched-domain(s):
+[    1.536846]  domain-0: span=6-7 level=MC
+[    1.536934]   groups: 6:{ span=6 cap=1005 }, 7:{ span=7 cap=1001 }
+[    1.537144]   domain-1: span=4-7 level=NUMA
+[    1.537262]    groups: 6:{ span=6-7 cap=2006 }, 4:{ span=4-5 cap=1949 }
+[    1.537553]    domain-2: span=0-1,4-7 level=NUMA
+[    1.537613]     groups: 6:{ span=4-7 mask=6-7 cap=4054 }, 0:{ span=0-1 cap=1805 }
+[    1.537872]     domain-3: span=0-7 level=NUMA
+[    1.537998]      groups: 6:{ span=0-1,4-7 mask=6-7 cap=6102 }, 2:{ span=0-5 mask=2-3 cap=5845 }
+[    1.538448] CPU7 attaching sched-domain(s):
+[    1.538505]  domain-0: span=6-7 level=MC
+[    1.538586]   groups: 7:{ span=7 cap=1001 }, 6:{ span=6 cap=1005 }
+[    1.538746]   domain-1: span=4-7 level=NUMA
+[    1.538798]    groups: 6:{ span=6-7 cap=2006 }, 4:{ span=4-5 cap=1949 }
+[    1.539048]    domain-2: span=0-1,4-7 level=NUMA
+[    1.539111]     groups: 6:{ span=4-7 mask=6-7 cap=4054 }, 0:{ span=0-1 cap=1805 }
+[    1.539571]     domain-3: span=0-7 level=NUMA
+[    1.539610]      groups: 6:{ span=0-1,4-7 mask=6-7 cap=6102 }, 2:{ span=0-5 mask=2-3 cap=5845 }
+
+Signed-off-by: Barry Song <song.bao.hua@hisilicon.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Reviewed-by: Valentin Schneider <valentin.schneider@arm.com>
+Tested-by: Meelis Roos <mroos@linux.ee>
+Link: https://lkml.kernel.org/r/20210224030944.15232-1-song.bao.hua@hisilicon.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/topology.c | 91 +++++++++++++++++++++++++++--------------
+ 1 file changed, 61 insertions(+), 30 deletions(-)
+
+diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c
+index 09d35044bd88..12f80587e127 100644
+--- a/kernel/sched/topology.c
++++ b/kernel/sched/topology.c
+@@ -723,35 +723,6 @@ cpu_attach_domain(struct sched_domain *sd, struct root_domain *rd, int cpu)
+       for (tmp = sd; tmp; tmp = tmp->parent)
+               numa_distance += !!(tmp->flags & SD_NUMA);
+-      /*
+-       * FIXME: Diameter >=3 is misrepresented.
+-       *
+-       * Smallest diameter=3 topology is:
+-       *
+-       *   node   0   1   2   3
+-       *     0:  10  20  30  40
+-       *     1:  20  10  20  30
+-       *     2:  30  20  10  20
+-       *     3:  40  30  20  10
+-       *
+-       *   0 --- 1 --- 2 --- 3
+-       *
+-       * NUMA-3       0-3             N/A             N/A             0-3
+-       *  groups:     {0-2},{1-3}                                     {1-3},{0-2}
+-       *
+-       * NUMA-2       0-2             0-3             0-3             1-3
+-       *  groups:     {0-1},{1-3}     {0-2},{2-3}     {1-3},{0-1}     {2-3},{0-2}
+-       *
+-       * NUMA-1       0-1             0-2             1-3             2-3
+-       *  groups:     {0},{1}         {1},{2},{0}     {2},{3},{1}     {3},{2}
+-       *
+-       * NUMA-0       0               1               2               3
+-       *
+-       * The NUMA-2 groups for nodes 0 and 3 are obviously buggered, as the
+-       * group span isn't a subset of the domain span.
+-       */
+-      WARN_ONCE(numa_distance > 2, "Shortest NUMA path spans too many nodes\n");
+-
+       sched_domain_debug(sd, cpu);
+       rq_attach_root(rq, rd);
+@@ -982,6 +953,31 @@ static void init_overlap_sched_group(struct sched_domain *sd,
+       sg->sgc->max_capacity = SCHED_CAPACITY_SCALE;
+ }
++static struct sched_domain *
++find_descended_sibling(struct sched_domain *sd, struct sched_domain *sibling)
++{
++      /*
++       * The proper descendant would be the one whose child won't span out
++       * of sd
++       */
++      while (sibling->child &&
++             !cpumask_subset(sched_domain_span(sibling->child),
++                             sched_domain_span(sd)))
++              sibling = sibling->child;
++
++      /*
++       * As we are referencing sgc across different topology level, we need
++       * to go down to skip those sched_domains which don't contribute to
++       * scheduling because they will be degenerated in cpu_attach_domain
++       */
++      while (sibling->child &&
++             cpumask_equal(sched_domain_span(sibling->child),
++                           sched_domain_span(sibling)))
++              sibling = sibling->child;
++
++      return sibling;
++}
++
+ static int
+ build_overlap_sched_groups(struct sched_domain *sd, int cpu)
+ {
+@@ -1015,6 +1011,41 @@ build_overlap_sched_groups(struct sched_domain *sd, int cpu)
+               if (!cpumask_test_cpu(i, sched_domain_span(sibling)))
+                       continue;
++              /*
++               * Usually we build sched_group by sibling's child sched_domain
++               * But for machines whose NUMA diameter are 3 or above, we move
++               * to build sched_group by sibling's proper descendant's child
++               * domain because sibling's child sched_domain will span out of
++               * the sched_domain being built as below.
++               *
++               * Smallest diameter=3 topology is:
++               *
++               *   node   0   1   2   3
++               *     0:  10  20  30  40
++               *     1:  20  10  20  30
++               *     2:  30  20  10  20
++               *     3:  40  30  20  10
++               *
++               *   0 --- 1 --- 2 --- 3
++               *
++               * NUMA-3       0-3             N/A             N/A             0-3
++               *  groups:     {0-2},{1-3}                                     {1-3},{0-2}
++               *
++               * NUMA-2       0-2             0-3             0-3             1-3
++               *  groups:     {0-1},{1-3}     {0-2},{2-3}     {1-3},{0-1}     {2-3},{0-2}
++               *
++               * NUMA-1       0-1             0-2             1-3             2-3
++               *  groups:     {0},{1}         {1},{2},{0}     {2},{3},{1}     {3},{2}
++               *
++               * NUMA-0       0               1               2               3
++               *
++               * The NUMA-2 groups for nodes 0 and 3 are obviously buggered, as the
++               * group span isn't a subset of the domain span.
++               */
++              if (sibling->child &&
++                  !cpumask_subset(sched_domain_span(sibling->child), span))
++                      sibling = find_descended_sibling(sd, sibling);
++
+               sg = build_group_from_child_sched_domain(sibling, cpu);
+               if (!sg)
+                       goto fail;
+@@ -1022,7 +1053,7 @@ build_overlap_sched_groups(struct sched_domain *sd, int cpu)
+               sg_span = sched_group_span(sg);
+               cpumask_or(covered, covered, sg_span);
+-              init_overlap_sched_group(sd, sg);
++              init_overlap_sched_group(sibling, sg);
+               if (!first)
+                       first = sg;
+-- 
+2.30.2
+
diff --git a/queue-5.12/scsi-libfc-fix-a-format-specifier.patch b/queue-5.12/scsi-libfc-fix-a-format-specifier.patch
new file mode 100644 (file)
index 0000000..5710b1a
--- /dev/null
@@ -0,0 +1,45 @@
+From 331a6c26d960bbf10a70a90ad5ce919e7efb2b8d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Apr 2021 15:08:13 -0700
+Subject: scsi: libfc: Fix a format specifier
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit 90d6697810f06aceea9de71ad836a8c7669789cd ]
+
+Since the 'mfs' member has been declared as 'u32' in include/scsi/libfc.h,
+use the %u format specifier instead of %hu. This patch fixes the following
+clang compiler warning:
+
+warning: format specifies type
+      'unsigned short' but the argument has type 'u32' (aka 'unsigned int')
+      [-Wformat]
+                             "lport->mfs:%hu\n", mfs, lport->mfs);
+                                         ~~~          ^~~~~~~~~~
+                                         %u
+
+Link: https://lore.kernel.org/r/20210415220826.29438-8-bvanassche@acm.org
+Cc: Hannes Reinecke <hare@suse.de>
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/libfc/fc_lport.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
+index 22826544da7e..9989669beec3 100644
+--- a/drivers/scsi/libfc/fc_lport.c
++++ b/drivers/scsi/libfc/fc_lport.c
+@@ -1731,7 +1731,7 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
+       if (mfs < FC_SP_MIN_MAX_PAYLOAD || mfs > FC_SP_MAX_MAX_PAYLOAD) {
+               FC_LPORT_DBG(lport, "FLOGI bad mfs:%hu response, "
+-                           "lport->mfs:%hu\n", mfs, lport->mfs);
++                           "lport->mfs:%u\n", mfs, lport->mfs);
+               fc_lport_error(lport, fp);
+               goto out;
+       }
+-- 
+2.30.2
+
diff --git a/queue-5.12/scsi-lpfc-fix-adisc-handling-that-never-frees-nodes.patch b/queue-5.12/scsi-lpfc-fix-adisc-handling-that-never-frees-nodes.patch
new file mode 100644 (file)
index 0000000..56d92c8
--- /dev/null
@@ -0,0 +1,97 @@
+From 3e07e448a9a3471b158043ca5b2de44ffd54e806 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Mar 2021 09:18:13 -0800
+Subject: scsi: lpfc: Fix ADISC handling that never frees nodes
+
+From: James Smart <jsmart2021@gmail.com>
+
+[ Upstream commit 309b477462df7542355ac984674a6e89c01c89aa ]
+
+While testing target port swap test with ADISC enabled, several nodes
+remain in UNUSED state. These nodes are never freed and rmmod hangs for
+long time before finising with "0233 Nodelist not empty" error.
+
+During PLOGI completion lpfc_plogi_confirm_nport() looks for existing nodes
+with same WWPN. If found, the existing node is used to continue discovery.
+The node on which plogi was performed is freed.  When ADISC is enabled, an
+ADISC els request is triggered in response to an RSCN.  It's possible that
+the ADISC may be rejected by the remote port causing the ADISC completion
+handler to clear the port and node name in the node.  If this occurs, if a
+PLOGI is received it causes a node lookup based on wwpn to now fail,
+causing the port swap logic to kick in which allocates a new node and swaps
+to it. This effectively orphans the original node structure.
+
+Fix the situation by detecting when the lookup fails and forgo the node
+swap and node allocation by using the node on which the PLOGI was issued.
+
+Link: https://lore.kernel.org/r/20210301171821.3427-15-jsmart2021@gmail.com
+Co-developed-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: James Smart <jsmart2021@gmail.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/lpfc/lpfc_els.c | 33 +++++++--------------------------
+ 1 file changed, 7 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
+index beb2fcd2d8e7..04c002eea446 100644
+--- a/drivers/scsi/lpfc/lpfc_els.c
++++ b/drivers/scsi/lpfc/lpfc_els.c
+@@ -1600,7 +1600,7 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
+       struct lpfc_nodelist *new_ndlp;
+       struct serv_parm *sp;
+       uint8_t  name[sizeof(struct lpfc_name)];
+-      uint32_t rc, keepDID = 0, keep_nlp_flag = 0;
++      uint32_t keepDID = 0, keep_nlp_flag = 0;
+       uint32_t keep_new_nlp_flag = 0;
+       uint16_t keep_nlp_state;
+       u32 keep_nlp_fc4_type = 0;
+@@ -1622,7 +1622,7 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
+       new_ndlp = lpfc_findnode_wwpn(vport, &sp->portName);
+       /* return immediately if the WWPN matches ndlp */
+-      if (new_ndlp == ndlp)
++      if (!new_ndlp || (new_ndlp == ndlp))
+               return ndlp;
+       if (phba->sli_rev == LPFC_SLI_REV4) {
+@@ -1641,30 +1641,11 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
+                        (new_ndlp ? new_ndlp->nlp_flag : 0),
+                        (new_ndlp ? new_ndlp->nlp_fc4_type : 0));
+-      if (!new_ndlp) {
+-              rc = memcmp(&ndlp->nlp_portname, name,
+-                          sizeof(struct lpfc_name));
+-              if (!rc) {
+-                      if (active_rrqs_xri_bitmap)
+-                              mempool_free(active_rrqs_xri_bitmap,
+-                                           phba->active_rrq_pool);
+-                      return ndlp;
+-              }
+-              new_ndlp = lpfc_nlp_init(vport, ndlp->nlp_DID);
+-              if (!new_ndlp) {
+-                      if (active_rrqs_xri_bitmap)
+-                              mempool_free(active_rrqs_xri_bitmap,
+-                                           phba->active_rrq_pool);
+-                      return ndlp;
+-              }
+-      } else {
+-              keepDID = new_ndlp->nlp_DID;
+-              if (phba->sli_rev == LPFC_SLI_REV4 &&
+-                  active_rrqs_xri_bitmap)
+-                      memcpy(active_rrqs_xri_bitmap,
+-                             new_ndlp->active_rrqs_xri_bitmap,
+-                             phba->cfg_rrq_xri_bitmap_sz);
+-      }
++      keepDID = new_ndlp->nlp_DID;
++
++      if (phba->sli_rev == LPFC_SLI_REV4 && active_rrqs_xri_bitmap)
++              memcpy(active_rrqs_xri_bitmap, new_ndlp->active_rrqs_xri_bitmap,
++                     phba->cfg_rrq_xri_bitmap_sz);
+       /* At this point in this routine, we know new_ndlp will be
+        * returned. however, any previous GID_FTs that were done
+-- 
+2.30.2
+
diff --git a/queue-5.12/scsi-lpfc-fix-crash-when-a-reg_rpi-mailbox-fails-tri.patch b/queue-5.12/scsi-lpfc-fix-crash-when-a-reg_rpi-mailbox-fails-tri.patch
new file mode 100644 (file)
index 0000000..3431aae
--- /dev/null
@@ -0,0 +1,60 @@
+From 95329fea2d279c1829c834e6e26879117b15dfd5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 11 Apr 2021 18:31:13 -0700
+Subject: scsi: lpfc: Fix crash when a REG_RPI mailbox fails triggering a LOGO
+ response
+
+From: James Smart <jsmart2021@gmail.com>
+
+[ Upstream commit fffd18ec6579c2d9c72b212169259062fe747888 ]
+
+Fix a crash caused by a double put on the node when the driver completed an
+ACC for an unsolicted abort on the same node.  The second put was executed
+by lpfc_nlp_not_used() and is wrong because the completion routine executes
+the nlp_put when the iocbq was released.  Additionally, the driver is
+issuing a LOGO then immediately calls lpfc_nlp_set_state to put the node
+into NPR.  This call does nothing.
+
+Remove the lpfc_nlp_not_used call and additional set_state in the
+completion routine.  Remove the lpfc_nlp_set_state post issue_logo.  Isn't
+necessary.
+
+Link: https://lore.kernel.org/r/20210412013127.2387-3-jsmart2021@gmail.com
+Co-developed-by: Justin Tee <justin.tee@broadcom.com>
+Signed-off-by: Justin Tee <justin.tee@broadcom.com>
+Signed-off-by: James Smart <jsmart2021@gmail.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/lpfc/lpfc_nportdisc.c | 2 --
+ drivers/scsi/lpfc/lpfc_sli.c       | 1 -
+ 2 files changed, 3 deletions(-)
+
+diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
+index 7fc796905a7a..9f05f5e329c6 100644
+--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
++++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
+@@ -1891,8 +1891,6 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport,
+               ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
+               lpfc_issue_els_logo(vport, ndlp, 0);
+-              ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
+-              lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
+               return ndlp->nlp_state;
+       }
+diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
+index 071a13d4d14a..8e34d6076fbc 100644
+--- a/drivers/scsi/lpfc/lpfc_sli.c
++++ b/drivers/scsi/lpfc/lpfc_sli.c
+@@ -18074,7 +18074,6 @@ lpfc_sli4_seq_abort_rsp_cmpl(struct lpfc_hba *phba,
+       if (cmd_iocbq) {
+               ndlp = (struct lpfc_nodelist *)cmd_iocbq->context1;
+               lpfc_nlp_put(ndlp);
+-              lpfc_nlp_not_used(ndlp);
+               lpfc_sli_release_iocbq(phba, cmd_iocbq);
+       }
+-- 
+2.30.2
+
diff --git a/queue-5.12/scsi-lpfc-fix-error-handling-for-mailboxes-completed.patch b/queue-5.12/scsi-lpfc-fix-error-handling-for-mailboxes-completed.patch
new file mode 100644 (file)
index 0000000..f2cf3ef
--- /dev/null
@@ -0,0 +1,299 @@
+From d17cf80e2deb27465031ae4da25e2187286dd5d2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 11 Apr 2021 18:31:17 -0700
+Subject: scsi: lpfc: Fix error handling for mailboxes completed in MBX_POLL
+ mode
+
+From: James Smart <jsmart2021@gmail.com>
+
+[ Upstream commit 304ee43238fed517faa123e034b593905b8679f8 ]
+
+In SLI-4, when performing a mailbox command with MBX_POLL, the driver uses
+the BMBX register to send the command rather than the MQ. A flag is set
+indicating the BMBX register is active and saves the mailbox job struct
+(mboxq) in the mbox_active element of the adapter. The routine then waits
+for completion or timeout. The mailbox job struct is not freed by the
+routine. In cases of timeout, the adapter will be reset. The
+lpfc_sli_mbox_sys_flush() routine will clean up the mbox in preparation for
+the reset. It clears the BMBX active flag and marks the job structure as
+MBX_NOT_FINISHED. But, it never frees the mboxq job structure. Expectation
+in both normal completion and timeout cases is that the issuer of the mbx
+command will free the structure.  Unfortunately, not all calling paths are
+freeing the memory in cases of error.
+
+All calling paths were looked at and updated, if missing, to free the mboxq
+memory regardless of completion status.
+
+Link: https://lore.kernel.org/r/20210412013127.2387-7-jsmart2021@gmail.com
+Co-developed-by: Justin Tee <justin.tee@broadcom.com>
+Signed-off-by: Justin Tee <justin.tee@broadcom.com>
+Signed-off-by: James Smart <jsmart2021@gmail.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/lpfc/lpfc_attr.c | 75 +++++++++++++++++++++--------------
+ drivers/scsi/lpfc/lpfc_init.c |  9 ++---
+ drivers/scsi/lpfc/lpfc_sli.c  | 42 ++++++++++----------
+ 3 files changed, 70 insertions(+), 56 deletions(-)
+
+diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
+index bdd9a29f4201..0496a60735ef 100644
+--- a/drivers/scsi/lpfc/lpfc_attr.c
++++ b/drivers/scsi/lpfc/lpfc_attr.c
+@@ -1687,8 +1687,7 @@ lpfc_set_trunking(struct lpfc_hba *phba, char *buff_out)
+               lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
+                               "0071 Set trunk mode failed with status: %d",
+                               rc);
+-      if (rc != MBX_TIMEOUT)
+-              mempool_free(mbox, phba->mbox_mem_pool);
++      mempool_free(mbox, phba->mbox_mem_pool);
+       return 0;
+ }
+@@ -6793,15 +6792,19 @@ lpfc_get_stats(struct Scsi_Host *shost)
+       pmboxq->ctx_buf = NULL;
+       pmboxq->vport = vport;
+-      if (vport->fc_flag & FC_OFFLINE_MODE)
++      if (vport->fc_flag & FC_OFFLINE_MODE) {
+               rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
+-      else
+-              rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
+-
+-      if (rc != MBX_SUCCESS) {
+-              if (rc != MBX_TIMEOUT)
++              if (rc != MBX_SUCCESS) {
+                       mempool_free(pmboxq, phba->mbox_mem_pool);
+-              return NULL;
++                      return NULL;
++              }
++      } else {
++              rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
++              if (rc != MBX_SUCCESS) {
++                      if (rc != MBX_TIMEOUT)
++                              mempool_free(pmboxq, phba->mbox_mem_pool);
++                      return NULL;
++              }
+       }
+       memset(hs, 0, sizeof (struct fc_host_statistics));
+@@ -6825,15 +6828,19 @@ lpfc_get_stats(struct Scsi_Host *shost)
+       pmboxq->ctx_buf = NULL;
+       pmboxq->vport = vport;
+-      if (vport->fc_flag & FC_OFFLINE_MODE)
++      if (vport->fc_flag & FC_OFFLINE_MODE) {
+               rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
+-      else
+-              rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
+-
+-      if (rc != MBX_SUCCESS) {
+-              if (rc != MBX_TIMEOUT)
++              if (rc != MBX_SUCCESS) {
+                       mempool_free(pmboxq, phba->mbox_mem_pool);
+-              return NULL;
++                      return NULL;
++              }
++      } else {
++              rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
++              if (rc != MBX_SUCCESS) {
++                      if (rc != MBX_TIMEOUT)
++                              mempool_free(pmboxq, phba->mbox_mem_pool);
++                      return NULL;
++              }
+       }
+       hs->link_failure_count = pmb->un.varRdLnk.linkFailureCnt;
+@@ -6906,15 +6913,19 @@ lpfc_reset_stats(struct Scsi_Host *shost)
+       pmboxq->vport = vport;
+       if ((vport->fc_flag & FC_OFFLINE_MODE) ||
+-              (!(psli->sli_flag & LPFC_SLI_ACTIVE)))
++              (!(psli->sli_flag & LPFC_SLI_ACTIVE))) {
+               rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
+-      else
+-              rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
+-
+-      if (rc != MBX_SUCCESS) {
+-              if (rc != MBX_TIMEOUT)
++              if (rc != MBX_SUCCESS) {
+                       mempool_free(pmboxq, phba->mbox_mem_pool);
+-              return;
++                      return;
++              }
++      } else {
++              rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
++              if (rc != MBX_SUCCESS) {
++                      if (rc != MBX_TIMEOUT)
++                              mempool_free(pmboxq, phba->mbox_mem_pool);
++                      return;
++              }
+       }
+       memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t));
+@@ -6924,15 +6935,19 @@ lpfc_reset_stats(struct Scsi_Host *shost)
+       pmboxq->vport = vport;
+       if ((vport->fc_flag & FC_OFFLINE_MODE) ||
+-          (!(psli->sli_flag & LPFC_SLI_ACTIVE)))
++          (!(psli->sli_flag & LPFC_SLI_ACTIVE))) {
+               rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
+-      else
++              if (rc != MBX_SUCCESS) {
++                      mempool_free(pmboxq, phba->mbox_mem_pool);
++                      return;
++              }
++      } else {
+               rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
+-
+-      if (rc != MBX_SUCCESS) {
+-              if (rc != MBX_TIMEOUT)
+-                      mempool_free( pmboxq, phba->mbox_mem_pool);
+-              return;
++              if (rc != MBX_SUCCESS) {
++                      if (rc != MBX_TIMEOUT)
++                              mempool_free(pmboxq, phba->mbox_mem_pool);
++                      return;
++              }
+       }
+       lso->link_failure_count = pmb->un.varRdLnk.linkFailureCnt;
+diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
+index 71f340dd4fbd..302aff50b958 100644
+--- a/drivers/scsi/lpfc/lpfc_init.c
++++ b/drivers/scsi/lpfc/lpfc_init.c
+@@ -9660,8 +9660,7 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba)
+                               "3250 QUERY_FW_CFG mailbox failed with status "
+                               "x%x add_status x%x, mbx status x%x\n",
+                               shdr_status, shdr_add_status, rc);
+-              if (rc != MBX_TIMEOUT)
+-                      mempool_free(mboxq, phba->mbox_mem_pool);
++              mempool_free(mboxq, phba->mbox_mem_pool);
+               rc = -ENXIO;
+               goto out_error;
+       }
+@@ -9677,8 +9676,7 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba)
+                       "ulp1_mode:x%x\n", phba->sli4_hba.fw_func_mode,
+                       phba->sli4_hba.ulp0_mode, phba->sli4_hba.ulp1_mode);
+-      if (rc != MBX_TIMEOUT)
+-              mempool_free(mboxq, phba->mbox_mem_pool);
++      mempool_free(mboxq, phba->mbox_mem_pool);
+       /*
+        * Set up HBA Event Queues (EQs)
+@@ -10276,8 +10274,7 @@ lpfc_pci_function_reset(struct lpfc_hba *phba)
+               shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
+               shdr_add_status = bf_get(lpfc_mbox_hdr_add_status,
+                                        &shdr->response);
+-              if (rc != MBX_TIMEOUT)
+-                      mempool_free(mboxq, phba->mbox_mem_pool);
++              mempool_free(mboxq, phba->mbox_mem_pool);
+               if (shdr_status || shdr_add_status || rc) {
+                       lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
+                                       "0495 SLI_FUNCTION_RESET mailbox "
+diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
+index 8e34d6076fbc..bd31feb3d5e1 100644
+--- a/drivers/scsi/lpfc/lpfc_sli.c
++++ b/drivers/scsi/lpfc/lpfc_sli.c
+@@ -5683,12 +5683,10 @@ lpfc_sli4_get_ctl_attr(struct lpfc_hba *phba)
+                       phba->sli4_hba.lnk_info.lnk_no,
+                       phba->BIOSVersion);
+ out_free_mboxq:
+-      if (rc != MBX_TIMEOUT) {
+-              if (bf_get(lpfc_mqe_command, &mboxq->u.mqe) == MBX_SLI4_CONFIG)
+-                      lpfc_sli4_mbox_cmd_free(phba, mboxq);
+-              else
+-                      mempool_free(mboxq, phba->mbox_mem_pool);
+-      }
++      if (bf_get(lpfc_mqe_command, &mboxq->u.mqe) == MBX_SLI4_CONFIG)
++              lpfc_sli4_mbox_cmd_free(phba, mboxq);
++      else
++              mempool_free(mboxq, phba->mbox_mem_pool);
+       return rc;
+ }
+@@ -5789,12 +5787,10 @@ retrieve_ppname:
+       }
+ out_free_mboxq:
+-      if (rc != MBX_TIMEOUT) {
+-              if (bf_get(lpfc_mqe_command, &mboxq->u.mqe) == MBX_SLI4_CONFIG)
+-                      lpfc_sli4_mbox_cmd_free(phba, mboxq);
+-              else
+-                      mempool_free(mboxq, phba->mbox_mem_pool);
+-      }
++      if (bf_get(lpfc_mqe_command, &mboxq->u.mqe) == MBX_SLI4_CONFIG)
++              lpfc_sli4_mbox_cmd_free(phba, mboxq);
++      else
++              mempool_free(mboxq, phba->mbox_mem_pool);
+       return rc;
+ }
+@@ -17082,8 +17078,7 @@ lpfc_rq_destroy(struct lpfc_hba *phba, struct lpfc_queue *hrq,
+                               "2509 RQ_DESTROY mailbox failed with "
+                               "status x%x add_status x%x, mbx status x%x\n",
+                               shdr_status, shdr_add_status, rc);
+-              if (rc != MBX_TIMEOUT)
+-                      mempool_free(mbox, hrq->phba->mbox_mem_pool);
++              mempool_free(mbox, hrq->phba->mbox_mem_pool);
+               return -ENXIO;
+       }
+       bf_set(lpfc_mbx_rq_destroy_q_id, &mbox->u.mqe.un.rq_destroy.u.request,
+@@ -17180,7 +17175,9 @@ lpfc_sli4_post_sgl(struct lpfc_hba *phba,
+       shdr = (union lpfc_sli4_cfg_shdr *) &post_sgl_pages->header.cfg_shdr;
+       shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
+       shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response);
+-      if (rc != MBX_TIMEOUT)
++      if (!phba->sli4_hba.intr_enable)
++              mempool_free(mbox, phba->mbox_mem_pool);
++      else if (rc != MBX_TIMEOUT)
+               mempool_free(mbox, phba->mbox_mem_pool);
+       if (shdr_status || shdr_add_status || rc) {
+               lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
+@@ -17377,7 +17374,9 @@ lpfc_sli4_post_sgl_list(struct lpfc_hba *phba,
+       shdr = (union lpfc_sli4_cfg_shdr *) &sgl->cfg_shdr;
+       shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
+       shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response);
+-      if (rc != MBX_TIMEOUT)
++      if (!phba->sli4_hba.intr_enable)
++              lpfc_sli4_mbox_cmd_free(phba, mbox);
++      else if (rc != MBX_TIMEOUT)
+               lpfc_sli4_mbox_cmd_free(phba, mbox);
+       if (shdr_status || shdr_add_status || rc) {
+               lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
+@@ -17490,7 +17489,9 @@ lpfc_sli4_post_io_sgl_block(struct lpfc_hba *phba, struct list_head *nblist,
+       shdr = (union lpfc_sli4_cfg_shdr *)&sgl->cfg_shdr;
+       shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
+       shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response);
+-      if (rc != MBX_TIMEOUT)
++      if (!phba->sli4_hba.intr_enable)
++              lpfc_sli4_mbox_cmd_free(phba, mbox);
++      else if (rc != MBX_TIMEOUT)
+               lpfc_sli4_mbox_cmd_free(phba, mbox);
+       if (shdr_status || shdr_add_status || rc) {
+               lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
+@@ -18840,8 +18841,7 @@ lpfc_sli4_post_rpi_hdr(struct lpfc_hba *phba, struct lpfc_rpi_hdr *rpi_page)
+       shdr = (union lpfc_sli4_cfg_shdr *) &hdr_tmpl->header.cfg_shdr;
+       shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
+       shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response);
+-      if (rc != MBX_TIMEOUT)
+-              mempool_free(mboxq, phba->mbox_mem_pool);
++      mempool_free(mboxq, phba->mbox_mem_pool);
+       if (shdr_status || shdr_add_status || rc) {
+               lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
+                               "2514 POST_RPI_HDR mailbox failed with "
+@@ -20085,7 +20085,9 @@ lpfc_wr_object(struct lpfc_hba *phba, struct list_head *dmabuf_list,
+                       break;
+               }
+       }
+-      if (rc != MBX_TIMEOUT)
++      if (!phba->sli4_hba.intr_enable)
++              mempool_free(mbox, phba->mbox_mem_pool);
++      else if (rc != MBX_TIMEOUT)
+               mempool_free(mbox, phba->mbox_mem_pool);
+       if (shdr_status || shdr_add_status || rc) {
+               lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
+-- 
+2.30.2
+
diff --git a/queue-5.12/scsi-lpfc-fix-incorrect-dbde-assignment-when-buildin.patch b/queue-5.12/scsi-lpfc-fix-incorrect-dbde-assignment-when-buildin.patch
new file mode 100644 (file)
index 0000000..52d507c
--- /dev/null
@@ -0,0 +1,41 @@
+From 3ab8c2f4f06d05f221c569176e62723fdd011e05 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Mar 2021 09:18:00 -0800
+Subject: scsi: lpfc: Fix incorrect dbde assignment when building target abts
+ wqe
+
+From: James Smart <jsmart2021@gmail.com>
+
+[ Upstream commit 9302154c07bff4e7f7f43c506a1ac84540303d06 ]
+
+The wqe_dbde field indicates whether a Data BDE is present in Words 0:2 and
+should therefore should be clear in the abts request wqe. By setting the
+bit we can be misleading fw into error cases.
+
+Clear the wqe_dbde field.
+
+Link: https://lore.kernel.org/r/20210301171821.3427-2-jsmart2021@gmail.com
+Co-developed-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: James Smart <jsmart2021@gmail.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/lpfc/lpfc_nvmet.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c
+index bb2a4a0d1295..a3fd959f7431 100644
+--- a/drivers/scsi/lpfc/lpfc_nvmet.c
++++ b/drivers/scsi/lpfc/lpfc_nvmet.c
+@@ -3304,7 +3304,6 @@ lpfc_nvmet_unsol_issue_abort(struct lpfc_hba *phba,
+       bf_set(wqe_rcvoxid, &wqe_abts->xmit_sequence.wqe_com, xri);
+       /* Word 10 */
+-      bf_set(wqe_dbde, &wqe_abts->xmit_sequence.wqe_com, 1);
+       bf_set(wqe_iod, &wqe_abts->xmit_sequence.wqe_com, LPFC_WQE_IOD_WRITE);
+       bf_set(wqe_lenloc, &wqe_abts->xmit_sequence.wqe_com,
+              LPFC_WQE_LENLOC_WORD12);
+-- 
+2.30.2
+
diff --git a/queue-5.12/scsi-lpfc-fix-plogi-acc-to-be-transmit-after-reg_log.patch b/queue-5.12/scsi-lpfc-fix-plogi-acc-to-be-transmit-after-reg_log.patch
new file mode 100644 (file)
index 0000000..26a456e
--- /dev/null
@@ -0,0 +1,366 @@
+From 3e237e6c05a1ef636de321981496b395fa6f456b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Mar 2021 09:18:12 -0800
+Subject: scsi: lpfc: Fix PLOGI ACC to be transmit after REG_LOGIN
+
+From: James Smart <jsmart2021@gmail.com>
+
+[ Upstream commit 143753059b8b957f1cf4355338a3e3a32f3a85bf ]
+
+The driver is seeing a scenario where PLOGI response was issued and traffic
+is arriving while the adapter is still setting up the login context. This
+is resulting in errors handling the traffic.
+
+Change the driver so that PLOGI response is sent after the login context
+has been setup to avoid the situation.
+
+Link: https://lore.kernel.org/r/20210301171821.3427-14-jsmart2021@gmail.com
+Co-developed-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: James Smart <jsmart2021@gmail.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/lpfc/lpfc_nportdisc.c | 239 +++++++++--------------------
+ 1 file changed, 70 insertions(+), 169 deletions(-)
+
+diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
+index ef8feb933cd8..7fc796905a7a 100644
+--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
++++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
+@@ -279,106 +279,43 @@ lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
+       lpfc_cancel_retry_delay_tmo(phba->pport, ndlp);
+ }
+-/* lpfc_defer_pt2pt_acc - Complete SLI3 pt2pt processing on link up
++/* lpfc_defer_plogi_acc - Issue PLOGI ACC after reg_login completes
+  * @phba: pointer to lpfc hba data structure.
+- * @link_mbox: pointer to CONFIG_LINK mailbox object
++ * @login_mbox: pointer to REG_RPI mailbox object
+  *
+- * This routine is only called if we are SLI3, direct connect pt2pt
+- * mode and the remote NPort issues the PLOGI after link up.
++ * The ACC for a rcv'ed PLOGI is deferred until AFTER the REG_RPI completes
+  */
+ static void
+-lpfc_defer_pt2pt_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *link_mbox)
++lpfc_defer_plogi_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *login_mbox)
+ {
+-      LPFC_MBOXQ_t *login_mbox;
+-      MAILBOX_t *mb = &link_mbox->u.mb;
+       struct lpfc_iocbq *save_iocb;
+       struct lpfc_nodelist *ndlp;
++      MAILBOX_t *mb = &login_mbox->u.mb;
++
+       int rc;
+-      ndlp = link_mbox->ctx_ndlp;
+-      login_mbox = link_mbox->context3;
++      ndlp = login_mbox->ctx_ndlp;
+       save_iocb = login_mbox->context3;
+-      link_mbox->context3 = NULL;
+-      login_mbox->context3 = NULL;
+-
+-      /* Check for CONFIG_LINK error */
+-      if (mb->mbxStatus) {
+-              lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
+-                              "4575 CONFIG_LINK fails pt2pt discovery: %x\n",
+-                              mb->mbxStatus);
+-              mempool_free(login_mbox, phba->mbox_mem_pool);
+-              mempool_free(link_mbox, phba->mbox_mem_pool);
+-              kfree(save_iocb);
+-              return;
+-      }
+-      /* Now that CONFIG_LINK completed, and our SID is configured,
+-       * we can now proceed with sending the PLOGI ACC.
+-       */
+-      rc = lpfc_els_rsp_acc(link_mbox->vport, ELS_CMD_PLOGI,
+-                            save_iocb, ndlp, login_mbox);
+-      if (rc) {
+-              lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
+-                              "4576 PLOGI ACC fails pt2pt discovery: %x\n",
+-                              rc);
+-              mempool_free(login_mbox, phba->mbox_mem_pool);
++      if (mb->mbxStatus == MBX_SUCCESS) {
++              /* Now that REG_RPI completed successfully,
++               * we can now proceed with sending the PLOGI ACC.
++               */
++              rc = lpfc_els_rsp_acc(login_mbox->vport, ELS_CMD_PLOGI,
++                                    save_iocb, ndlp, NULL);
++              if (rc) {
++                      lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
++                                      "4576 PLOGI ACC fails pt2pt discovery: "
++                                      "DID %x Data: %x\n", ndlp->nlp_DID, rc);
++              }
+       }
+-      mempool_free(link_mbox, phba->mbox_mem_pool);
++      /* Now process the REG_RPI cmpl */
++      lpfc_mbx_cmpl_reg_login(phba, login_mbox);
++      ndlp->nlp_flag &= ~NLP_ACC_REGLOGIN;
+       kfree(save_iocb);
+ }
+-/**
+- * lpfc_defer_tgt_acc - Progress SLI4 target rcv PLOGI handler
+- * @phba: Pointer to HBA context object.
+- * @pmb: Pointer to mailbox object.
+- *
+- * This function provides the unreg rpi mailbox completion handler for a tgt.
+- * The routine frees the memory resources associated with the completed
+- * mailbox command and transmits the ELS ACC.
+- *
+- * This routine is only called if we are SLI4, acting in target
+- * mode and the remote NPort issues the PLOGI after link up.
+- **/
+-static void
+-lpfc_defer_acc_rsp(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
+-{
+-      struct lpfc_vport *vport = pmb->vport;
+-      struct lpfc_nodelist *ndlp = pmb->ctx_ndlp;
+-      LPFC_MBOXQ_t *mbox = pmb->context3;
+-      struct lpfc_iocbq *piocb = NULL;
+-      int rc;
+-
+-      if (mbox) {
+-              pmb->context3 = NULL;
+-              piocb = mbox->context3;
+-              mbox->context3 = NULL;
+-      }
+-
+-      /*
+-       * Complete the unreg rpi mbx request, and update flags.
+-       * This will also restart any deferred events.
+-       */
+-      lpfc_sli4_unreg_rpi_cmpl_clr(phba, pmb);
+-
+-      if (!piocb) {
+-              lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
+-                               "4578 PLOGI ACC fail\n");
+-              if (mbox)
+-                      mempool_free(mbox, phba->mbox_mem_pool);
+-              return;
+-      }
+-
+-      rc = lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, piocb, ndlp, mbox);
+-      if (rc) {
+-              lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
+-                               "4579 PLOGI ACC fail %x\n", rc);
+-              if (mbox)
+-                      mempool_free(mbox, phba->mbox_mem_pool);
+-      }
+-      kfree(piocb);
+-}
+-
+ static int
+ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+              struct lpfc_iocbq *cmdiocb)
+@@ -395,8 +332,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+       struct lpfc_iocbq *save_iocb;
+       struct ls_rjt stat;
+       uint32_t vid, flag;
+-      u16 rpi;
+-      int rc, defer_acc;
++      int rc;
+       memset(&stat, 0, sizeof (struct ls_rjt));
+       pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
+@@ -445,7 +381,6 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+       else
+               ndlp->nlp_fcp_info |= CLASS3;
+-      defer_acc = 0;
+       ndlp->nlp_class_sup = 0;
+       if (sp->cls1.classValid)
+               ndlp->nlp_class_sup |= FC_COS_CLASS1;
+@@ -539,27 +474,26 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+               memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm));
+-              /* Issue config_link / reg_vfi to account for updated TOV's */
+-
++              /* Issue CONFIG_LINK for SLI3 or REG_VFI for SLI4,
++               * to account for updated TOV's / parameters
++               */
+               if (phba->sli_rev == LPFC_SLI_REV4)
+                       lpfc_issue_reg_vfi(vport);
+               else {
+-                      defer_acc = 1;
+                       link_mbox = mempool_alloc(phba->mbox_mem_pool,
+                                                 GFP_KERNEL);
+                       if (!link_mbox)
+                               goto out;
+                       lpfc_config_link(phba, link_mbox);
+-                      link_mbox->mbox_cmpl = lpfc_defer_pt2pt_acc;
++                      link_mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+                       link_mbox->vport = vport;
+                       link_mbox->ctx_ndlp = ndlp;
+-                      save_iocb = kzalloc(sizeof(*save_iocb), GFP_KERNEL);
+-                      if (!save_iocb)
++                      rc = lpfc_sli_issue_mbox(phba, link_mbox, MBX_NOWAIT);
++                      if (rc == MBX_NOT_FINISHED) {
++                              mempool_free(link_mbox, phba->mbox_mem_pool);
+                               goto out;
+-                      /* Save info from cmd IOCB used in rsp */
+-                      memcpy((uint8_t *)save_iocb, (uint8_t *)cmdiocb,
+-                             sizeof(struct lpfc_iocbq));
++                      }
+               }
+               lpfc_can_disctmo(vport);
+@@ -578,59 +512,28 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+       if (!login_mbox)
+               goto out;
+-      /* Registering an existing RPI behaves differently for SLI3 vs SLI4 */
+-      if (phba->nvmet_support && !defer_acc) {
+-              link_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+-              if (!link_mbox)
+-                      goto out;
+-
+-              /* As unique identifiers such as iotag would be overwritten
+-               * with those from the cmdiocb, allocate separate temporary
+-               * storage for the copy.
+-               */
+-              save_iocb = kzalloc(sizeof(*save_iocb), GFP_KERNEL);
+-              if (!save_iocb)
+-                      goto out;
+-
+-              /* Unreg RPI is required for SLI4. */
+-              rpi = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
+-              lpfc_unreg_login(phba, vport->vpi, rpi, link_mbox);
+-              link_mbox->vport = vport;
+-              link_mbox->ctx_ndlp = lpfc_nlp_get(ndlp);
+-              if (!link_mbox->ctx_ndlp)
+-                      goto out;
+-
+-              link_mbox->mbox_cmpl = lpfc_defer_acc_rsp;
+-
+-              if (((ndlp->nlp_DID & Fabric_DID_MASK) != Fabric_DID_MASK) &&
+-                  (!(vport->fc_flag & FC_OFFLINE_MODE)))
+-                      ndlp->nlp_flag |= NLP_UNREG_INP;
++      save_iocb = kzalloc(sizeof(*save_iocb), GFP_KERNEL);
++      if (!save_iocb)
++              goto out;
+-              /* Save info from cmd IOCB used in rsp */
+-              memcpy(save_iocb, cmdiocb, sizeof(*save_iocb));
++      /* Save info from cmd IOCB to be used in rsp after all mbox completes */
++      memcpy((uint8_t *)save_iocb, (uint8_t *)cmdiocb,
++             sizeof(struct lpfc_iocbq));
+-              /* Delay sending ACC till unreg RPI completes. */
+-              defer_acc = 1;
+-      } else if (phba->sli_rev == LPFC_SLI_REV4)
++      /* Registering an existing RPI behaves differently for SLI3 vs SLI4 */
++      if (phba->sli_rev == LPFC_SLI_REV4)
+               lpfc_unreg_rpi(vport, ndlp);
++      /* Issue REG_LOGIN first, before ACCing the PLOGI, thus we will
++       * always be deferring the ACC.
++       */
+       rc = lpfc_reg_rpi(phba, vport->vpi, icmd->un.rcvels.remoteID,
+                           (uint8_t *)sp, login_mbox, ndlp->nlp_rpi);
+       if (rc)
+               goto out;
+-      /* ACC PLOGI rsp command needs to execute first,
+-       * queue this login_mbox command to be processed later.
+-       */
+       login_mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login;
+-      /*
+-       * login_mbox->ctx_ndlp = lpfc_nlp_get(ndlp) deferred until mailbox
+-       * command issued in lpfc_cmpl_els_acc().
+-       */
+       login_mbox->vport = vport;
+-      spin_lock_irq(&ndlp->lock);
+-      ndlp->nlp_flag |= (NLP_ACC_REGLOGIN | NLP_RCV_PLOGI);
+-      spin_unlock_irq(&ndlp->lock);
+       /*
+        * If there is an outstanding PLOGI issued, abort it before
+@@ -660,7 +563,8 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+                * to register, then unregister the RPI.
+                */
+               spin_lock_irq(&ndlp->lock);
+-              ndlp->nlp_flag |= NLP_RM_DFLT_RPI;
++              ndlp->nlp_flag |= (NLP_RM_DFLT_RPI | NLP_ACC_REGLOGIN |
++                                 NLP_RCV_PLOGI);
+               spin_unlock_irq(&ndlp->lock);
+               stat.un.b.lsRjtRsnCode = LSRJT_INVALID_CMD;
+               stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
+@@ -670,42 +574,39 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+                       mempool_free(login_mbox, phba->mbox_mem_pool);
+               return 1;
+       }
+-      if (defer_acc) {
+-              /* So the order here should be:
+-               * SLI3 pt2pt
+-               *   Issue CONFIG_LINK mbox
+-               *   CONFIG_LINK cmpl
+-               * SLI4 tgt
+-               *   Issue UNREG RPI mbx
+-               *   UNREG RPI cmpl
+-               * Issue PLOGI ACC
+-               * PLOGI ACC cmpl
+-               * Issue REG_LOGIN mbox
+-               */
+-              /* Save the REG_LOGIN mbox for and rcv IOCB copy later */
+-              link_mbox->context3 = login_mbox;
+-              login_mbox->context3 = save_iocb;
++      /* So the order here should be:
++       * SLI3 pt2pt
++       *   Issue CONFIG_LINK mbox
++       *   CONFIG_LINK cmpl
++       * SLI4 pt2pt
++       *   Issue REG_VFI mbox
++       *   REG_VFI cmpl
++       * SLI4
++       *   Issue UNREG RPI mbx
++       *   UNREG RPI cmpl
++       * Issue REG_RPI mbox
++       * REG RPI cmpl
++       * Issue PLOGI ACC
++       * PLOGI ACC cmpl
++       */
++      login_mbox->mbox_cmpl = lpfc_defer_plogi_acc;
++      login_mbox->ctx_ndlp = lpfc_nlp_get(ndlp);
++      login_mbox->context3 = save_iocb; /* For PLOGI ACC */
+-              /* Start the ball rolling by issuing CONFIG_LINK here */
+-              rc = lpfc_sli_issue_mbox(phba, link_mbox, MBX_NOWAIT);
+-              if (rc == MBX_NOT_FINISHED)
+-                      goto out;
+-              return 1;
+-      }
++      spin_lock_irq(&ndlp->lock);
++      ndlp->nlp_flag |= (NLP_ACC_REGLOGIN | NLP_RCV_PLOGI);
++      spin_unlock_irq(&ndlp->lock);
++
++      /* Start the ball rolling by issuing REG_LOGIN here */
++      rc = lpfc_sli_issue_mbox(phba, login_mbox, MBX_NOWAIT);
++      if (rc == MBX_NOT_FINISHED)
++              goto out;
++      lpfc_nlp_set_state(vport, ndlp, NLP_STE_REG_LOGIN_ISSUE);
+-      rc = lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, login_mbox);
+-      if (rc)
+-              mempool_free(login_mbox, phba->mbox_mem_pool);
+       return 1;
+ out:
+-      if (defer_acc)
+-              lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
+-                              "4577 discovery failure: %p %p %p\n",
+-                              save_iocb, link_mbox, login_mbox);
+       kfree(save_iocb);
+-      if (link_mbox)
+-              mempool_free(link_mbox, phba->mbox_mem_pool);
+       if (login_mbox)
+               mempool_free(login_mbox, phba->mbox_mem_pool);
+-- 
+2.30.2
+
diff --git a/queue-5.12/scsi-lpfc-fix-pt2pt-connection-does-not-recover-afte.patch b/queue-5.12/scsi-lpfc-fix-pt2pt-connection-does-not-recover-afte.patch
new file mode 100644 (file)
index 0000000..938e3a9
--- /dev/null
@@ -0,0 +1,50 @@
+From 513e24a5339807e4fcb8f4653ca095b70b394a98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Mar 2021 09:18:06 -0800
+Subject: scsi: lpfc: Fix pt2pt connection does not recover after LOGO
+
+From: James Smart <jsmart2021@gmail.com>
+
+[ Upstream commit bd4f5100424d17d4e560d6653902ef8e49b2fc1f ]
+
+On a pt2pt setup, between 2 initiators, if one side issues a a LOGO, there
+is no relogin attempt. The FC specs are grey in this area on which port
+(higher wwn or not) is to re-login.
+
+As there is no spec guidance, unconditionally re-PLOGI after the logout to
+ensure a login is re-established.
+
+Link: https://lore.kernel.org/r/20210301171821.3427-8-jsmart2021@gmail.com
+Co-developed-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: James Smart <jsmart2021@gmail.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/lpfc/lpfc_nportdisc.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
+index f67cf3c4fab1..ef8feb933cd8 100644
+--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
++++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
+@@ -913,9 +913,14 @@ lpfc_rcv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+               }
+       } else if ((!(ndlp->nlp_type & NLP_FABRIC) &&
+               ((ndlp->nlp_type & NLP_FCP_TARGET) ||
+-              !(ndlp->nlp_type & NLP_FCP_INITIATOR))) ||
++              (ndlp->nlp_type & NLP_NVME_TARGET) ||
++              (vport->fc_flag & FC_PT2PT))) ||
+               (ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) {
+-              /* Only try to re-login if this is NOT a Fabric Node */
++              /* Only try to re-login if this is NOT a Fabric Node
++               * AND the remote NPORT is a FCP/NVME Target or we
++               * are in pt2pt mode. NLP_STE_ADISC_ISSUE is a special
++               * case for LOGO as a response to ADISC behavior.
++               */
+               mod_timer(&ndlp->nlp_delayfunc,
+                         jiffies + msecs_to_jiffies(1000 * 1));
+               spin_lock_irq(&ndlp->lock);
+-- 
+2.30.2
+
diff --git a/queue-5.12/scsi-lpfc-fix-reference-counting-errors-in-lpfc_cmpl.patch b/queue-5.12/scsi-lpfc-fix-reference-counting-errors-in-lpfc_cmpl.patch
new file mode 100644 (file)
index 0000000..2abf15d
--- /dev/null
@@ -0,0 +1,148 @@
+From 4a94d2ed1eee0efbc8c69d39e2656c88f704b8af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 11 Apr 2021 18:31:14 -0700
+Subject: scsi: lpfc: Fix reference counting errors in lpfc_cmpl_els_rsp()
+
+From: James Smart <jsmart2021@gmail.com>
+
+[ Upstream commit f866eb06c087125619457b53e9211a9e758f64f7 ]
+
+Call traces are being seen that result from a nodelist structure ref
+counting error. They are typically seen after transmission of an LS_RJT ELS
+response.
+
+Aged code in lpfc_cmpl_els_rsp() calls lpfc_nlp_not_used() which, if the
+ndlp reference count is exactly 1, will decrement the reference count.
+Previously lpfc_nlp_put() was within lpfc_els_free_iocb(), and the 'put'
+within the free would only be invoked if cmdiocb->context1 was not NULL.
+Since the nodelist structure reference count is decremented when exiting
+lpfc_cmpl_els_rsp() the lpfc_nlp_not_used() calls are no longer required.
+Calling them is causing the reference count issue.
+
+Fix by removing the lpfc_nlp_not_used() calls.
+
+Link: https://lore.kernel.org/r/20210412013127.2387-4-jsmart2021@gmail.com
+Co-developed-by: Justin Tee <justin.tee@broadcom.com>
+Signed-off-by: Justin Tee <justin.tee@broadcom.com>
+Signed-off-by: James Smart <jsmart2021@gmail.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/lpfc/lpfc_els.c | 64 +-----------------------------------
+ 1 file changed, 1 insertion(+), 63 deletions(-)
+
+diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
+index 04c002eea446..fd18ac2acc13 100644
+--- a/drivers/scsi/lpfc/lpfc_els.c
++++ b/drivers/scsi/lpfc/lpfc_els.c
+@@ -4454,10 +4454,7 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
+  * nlp_flag bitmap in the ndlp data structure, if the mbox command reference
+  * field in the command IOCB is not NULL, the referred mailbox command will
+  * be send out, and then invokes the lpfc_els_free_iocb() routine to release
+- * the IOCB. Under error conditions, such as when a LS_RJT is returned or a
+- * link down event occurred during the discovery, the lpfc_nlp_not_used()
+- * routine shall be invoked trying to release the ndlp if no other threads
+- * are currently referring it.
++ * the IOCB.
+  **/
+ static void
+ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+@@ -4467,10 +4464,8 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+       struct lpfc_vport *vport = ndlp ? ndlp->vport : NULL;
+       struct Scsi_Host  *shost = vport ? lpfc_shost_from_vport(vport) : NULL;
+       IOCB_t  *irsp;
+-      uint8_t *pcmd;
+       LPFC_MBOXQ_t *mbox = NULL;
+       struct lpfc_dmabuf *mp = NULL;
+-      uint32_t ls_rjt = 0;
+       irsp = &rspiocb->iocb;
+@@ -4482,18 +4477,6 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+       if (cmdiocb->context_un.mbox)
+               mbox = cmdiocb->context_un.mbox;
+-      /* First determine if this is a LS_RJT cmpl. Note, this callback
+-       * function can have cmdiocb->contest1 (ndlp) field set to NULL.
+-       */
+-      pcmd = (uint8_t *) (((struct lpfc_dmabuf *) cmdiocb->context2)->virt);
+-      if (ndlp && (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT)) {
+-              /* A LS_RJT associated with Default RPI cleanup has its own
+-               * separate code path.
+-               */
+-              if (!(ndlp->nlp_flag & NLP_RM_DFLT_RPI))
+-                      ls_rjt = 1;
+-      }
+-
+       /* Check to see if link went down during discovery */
+       if (!ndlp || lpfc_els_chk_latt(vport)) {
+               if (mbox) {
+@@ -4504,15 +4487,6 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+                       }
+                       mempool_free(mbox, phba->mbox_mem_pool);
+               }
+-              if (ndlp && (ndlp->nlp_flag & NLP_RM_DFLT_RPI))
+-                      if (lpfc_nlp_not_used(ndlp)) {
+-                              ndlp = NULL;
+-                              /* Indicate the node has already released,
+-                               * should not reference to it from within
+-                               * the routine lpfc_els_free_iocb.
+-                               */
+-                              cmdiocb->context1 = NULL;
+-                      }
+               goto out;
+       }
+@@ -4590,29 +4564,6 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+                               "Data: x%x x%x x%x\n",
+                               ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
+                               ndlp->nlp_rpi);
+-
+-                      if (lpfc_nlp_not_used(ndlp)) {
+-                              ndlp = NULL;
+-                              /* Indicate node has already been released,
+-                               * should not reference to it from within
+-                               * the routine lpfc_els_free_iocb.
+-                               */
+-                              cmdiocb->context1 = NULL;
+-                      }
+-              } else {
+-                      /* Do not drop node for lpfc_els_abort'ed ELS cmds */
+-                      if (!lpfc_error_lost_link(irsp) &&
+-                          ndlp->nlp_flag & NLP_ACC_REGLOGIN) {
+-                              if (lpfc_nlp_not_used(ndlp)) {
+-                                      ndlp = NULL;
+-                                      /* Indicate node has already been
+-                                       * released, should not reference
+-                                       * to it from within the routine
+-                                       * lpfc_els_free_iocb.
+-                                       */
+-                                      cmdiocb->context1 = NULL;
+-                              }
+-                      }
+               }
+               mp = (struct lpfc_dmabuf *)mbox->ctx_buf;
+               if (mp) {
+@@ -4628,19 +4579,6 @@ out:
+                       ndlp->nlp_flag &= ~NLP_ACC_REGLOGIN;
+               ndlp->nlp_flag &= ~NLP_RM_DFLT_RPI;
+               spin_unlock_irq(&ndlp->lock);
+-
+-              /* If the node is not being used by another discovery thread,
+-               * and we are sending a reject, we are done with it.
+-               * Release driver reference count here and free associated
+-               * resources.
+-               */
+-              if (ls_rjt)
+-                      if (lpfc_nlp_not_used(ndlp))
+-                              /* Indicate node has already been released,
+-                               * should not reference to it from within
+-                               * the routine lpfc_els_free_iocb.
+-                               */
+-                              cmdiocb->context1 = NULL;
+       }
+       /* Release the originating I/O reference. */
+-- 
+2.30.2
+
diff --git a/queue-5.12/scsi-lpfc-fix-status-returned-in-lpfc_els_retry-erro.patch b/queue-5.12/scsi-lpfc-fix-status-returned-in-lpfc_els_retry-erro.patch
new file mode 100644 (file)
index 0000000..65bba6d
--- /dev/null
@@ -0,0 +1,41 @@
+From 914f78f9c9a055eeaee38f90a66f93e74511f1d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Mar 2021 09:18:10 -0800
+Subject: scsi: lpfc: Fix status returned in lpfc_els_retry() error exit path
+
+From: James Smart <jsmart2021@gmail.com>
+
+[ Upstream commit 148bc64d38fe314475a074c4f757ec9d84537d1c ]
+
+An unlikely error exit path from lpfc_els_retry() returns incorrect status
+to a caller, erroneously indicating that a retry has been successfully
+issued or scheduled.
+
+Change error exit path to indicate no retry.
+
+Link: https://lore.kernel.org/r/20210301171821.3427-12-jsmart2021@gmail.com
+Co-developed-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: James Smart <jsmart2021@gmail.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/lpfc/lpfc_els.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
+index f0a758138ae8..beb2fcd2d8e7 100644
+--- a/drivers/scsi/lpfc/lpfc_els.c
++++ b/drivers/scsi/lpfc/lpfc_els.c
+@@ -3829,7 +3829,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+               did = irsp->un.elsreq64.remoteID;
+               ndlp = lpfc_findnode_did(vport, did);
+               if (!ndlp && (cmd != ELS_CMD_PLOGI))
+-                      return 1;
++                      return 0;
+       }
+       lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
+-- 
+2.30.2
+
diff --git a/queue-5.12/scsi-lpfc-remove-unsupported-mbox-port_capabilities-.patch b/queue-5.12/scsi-lpfc-remove-unsupported-mbox-port_capabilities-.patch
new file mode 100644 (file)
index 0000000..9718b49
--- /dev/null
@@ -0,0 +1,431 @@
+From bf34098d173cd484da2152f710cee98a35ccebef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 11 Apr 2021 18:31:22 -0700
+Subject: scsi: lpfc: Remove unsupported mbox PORT_CAPABILITIES logic
+
+From: James Smart <jsmart2021@gmail.com>
+
+[ Upstream commit b62232ba8caccaf1954e197058104a6478fac1af ]
+
+SLI-4 does not contain a PORT_CAPABILITIES mailbox command (only SLI-3
+does, and SLI-3 doesn't use it), yet there are SLI-4 code paths that have
+code to issue the command.  The command will always fail.
+
+Remove the code for the mailbox command and leave only the resulting
+"failure path" logic.
+
+Link: https://lore.kernel.org/r/20210412013127.2387-12-jsmart2021@gmail.com
+Co-developed-by: Justin Tee <justin.tee@broadcom.com>
+Signed-off-by: Justin Tee <justin.tee@broadcom.com>
+Signed-off-by: James Smart <jsmart2021@gmail.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/lpfc/lpfc_crtn.h |   3 -
+ drivers/scsi/lpfc/lpfc_hw4.h  | 174 +---------------------------------
+ drivers/scsi/lpfc/lpfc_init.c | 103 +-------------------
+ drivers/scsi/lpfc/lpfc_mbox.c |  36 -------
+ 4 files changed, 3 insertions(+), 313 deletions(-)
+
+diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
+index 6e5c4fe07047..763b1eeb0ca8 100644
+--- a/drivers/scsi/lpfc/lpfc_crtn.h
++++ b/drivers/scsi/lpfc/lpfc_crtn.h
+@@ -55,9 +55,6 @@ void lpfc_register_new_vport(struct lpfc_hba *, struct lpfc_vport *,
+ void lpfc_unreg_vpi(struct lpfc_hba *, uint16_t, LPFC_MBOXQ_t *);
+ void lpfc_init_link(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t);
+ void lpfc_request_features(struct lpfc_hba *, struct lpfcMboxq *);
+-void lpfc_supported_pages(struct lpfcMboxq *);
+-void lpfc_pc_sli4_params(struct lpfcMboxq *);
+-int lpfc_pc_sli4_params_get(struct lpfc_hba *, LPFC_MBOXQ_t *);
+ int lpfc_sli4_mbox_rsrc_extent(struct lpfc_hba *, struct lpfcMboxq *,
+                          uint16_t, uint16_t, bool);
+ int lpfc_get_sli4_parameters(struct lpfc_hba *, LPFC_MBOXQ_t *);
+diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
+index 541b9aef6bfe..f5bc2c32a817 100644
+--- a/drivers/scsi/lpfc/lpfc_hw4.h
++++ b/drivers/scsi/lpfc/lpfc_hw4.h
+@@ -124,6 +124,7 @@ struct lpfc_sli_intf {
+ /* Define SLI4 Alignment requirements. */
+ #define LPFC_ALIGN_16_BYTE    16
+ #define LPFC_ALIGN_64_BYTE    64
++#define SLI4_PAGE_SIZE                4096
+ /* Define SLI4 specific definitions. */
+ #define LPFC_MQ_CQE_BYTE_OFFSET       256
+@@ -2976,62 +2977,6 @@ struct lpfc_mbx_request_features {
+ #define lpfc_mbx_rq_ftr_rsp_mrqp_WORD         word3
+ };
+-struct lpfc_mbx_supp_pages {
+-      uint32_t word1;
+-#define qs_SHIFT                              0
+-#define qs_MASK                                       0x00000001
+-#define qs_WORD                                       word1
+-#define wr_SHIFT                              1
+-#define wr_MASK                               0x00000001
+-#define wr_WORD                                       word1
+-#define pf_SHIFT                              8
+-#define pf_MASK                                       0x000000ff
+-#define pf_WORD                                       word1
+-#define cpn_SHIFT                             16
+-#define cpn_MASK                              0x000000ff
+-#define cpn_WORD                              word1
+-      uint32_t word2;
+-#define list_offset_SHIFT                     0
+-#define list_offset_MASK                      0x000000ff
+-#define list_offset_WORD                      word2
+-#define next_offset_SHIFT                     8
+-#define next_offset_MASK                      0x000000ff
+-#define next_offset_WORD                      word2
+-#define elem_cnt_SHIFT                                16
+-#define elem_cnt_MASK                         0x000000ff
+-#define elem_cnt_WORD                         word2
+-      uint32_t word3;
+-#define pn_0_SHIFT                            24
+-#define pn_0_MASK                             0x000000ff
+-#define pn_0_WORD                             word3
+-#define pn_1_SHIFT                            16
+-#define pn_1_MASK                             0x000000ff
+-#define pn_1_WORD                             word3
+-#define pn_2_SHIFT                            8
+-#define pn_2_MASK                             0x000000ff
+-#define pn_2_WORD                             word3
+-#define pn_3_SHIFT                            0
+-#define pn_3_MASK                             0x000000ff
+-#define pn_3_WORD                             word3
+-      uint32_t word4;
+-#define pn_4_SHIFT                            24
+-#define pn_4_MASK                             0x000000ff
+-#define pn_4_WORD                             word4
+-#define pn_5_SHIFT                            16
+-#define pn_5_MASK                             0x000000ff
+-#define pn_5_WORD                             word4
+-#define pn_6_SHIFT                            8
+-#define pn_6_MASK                             0x000000ff
+-#define pn_6_WORD                             word4
+-#define pn_7_SHIFT                            0
+-#define pn_7_MASK                             0x000000ff
+-#define pn_7_WORD                             word4
+-      uint32_t rsvd[27];
+-#define LPFC_SUPP_PAGES                       0
+-#define LPFC_BLOCK_GUARD_PROFILES     1
+-#define LPFC_SLI4_PARAMETERS          2
+-};
+-
+ struct lpfc_mbx_memory_dump_type3 {
+       uint32_t word1;
+ #define lpfc_mbx_memory_dump_type3_type_SHIFT    0
+@@ -3248,121 +3193,6 @@ struct user_eeprom {
+       uint8_t reserved191[57];
+ };
+-struct lpfc_mbx_pc_sli4_params {
+-      uint32_t word1;
+-#define qs_SHIFT                              0
+-#define qs_MASK                                       0x00000001
+-#define qs_WORD                                       word1
+-#define wr_SHIFT                              1
+-#define wr_MASK                                       0x00000001
+-#define wr_WORD                                       word1
+-#define pf_SHIFT                              8
+-#define pf_MASK                                       0x000000ff
+-#define pf_WORD                                       word1
+-#define cpn_SHIFT                             16
+-#define cpn_MASK                              0x000000ff
+-#define cpn_WORD                              word1
+-      uint32_t word2;
+-#define if_type_SHIFT                         0
+-#define if_type_MASK                          0x00000007
+-#define if_type_WORD                          word2
+-#define sli_rev_SHIFT                         4
+-#define sli_rev_MASK                          0x0000000f
+-#define sli_rev_WORD                          word2
+-#define sli_family_SHIFT                      8
+-#define sli_family_MASK                               0x000000ff
+-#define sli_family_WORD                               word2
+-#define featurelevel_1_SHIFT                  16
+-#define featurelevel_1_MASK                   0x000000ff
+-#define featurelevel_1_WORD                   word2
+-#define featurelevel_2_SHIFT                  24
+-#define featurelevel_2_MASK                   0x0000001f
+-#define featurelevel_2_WORD                   word2
+-      uint32_t word3;
+-#define fcoe_SHIFT                            0
+-#define fcoe_MASK                             0x00000001
+-#define fcoe_WORD                             word3
+-#define fc_SHIFT                              1
+-#define fc_MASK                                       0x00000001
+-#define fc_WORD                                       word3
+-#define nic_SHIFT                             2
+-#define nic_MASK                              0x00000001
+-#define nic_WORD                              word3
+-#define iscsi_SHIFT                           3
+-#define iscsi_MASK                            0x00000001
+-#define iscsi_WORD                            word3
+-#define rdma_SHIFT                            4
+-#define rdma_MASK                             0x00000001
+-#define rdma_WORD                             word3
+-      uint32_t sge_supp_len;
+-#define SLI4_PAGE_SIZE 4096
+-      uint32_t word5;
+-#define if_page_sz_SHIFT                      0
+-#define if_page_sz_MASK                               0x0000ffff
+-#define if_page_sz_WORD                               word5
+-#define loopbk_scope_SHIFT                    24
+-#define loopbk_scope_MASK                     0x0000000f
+-#define loopbk_scope_WORD                     word5
+-#define rq_db_window_SHIFT                    28
+-#define rq_db_window_MASK                     0x0000000f
+-#define rq_db_window_WORD                     word5
+-      uint32_t word6;
+-#define eq_pages_SHIFT                                0
+-#define eq_pages_MASK                         0x0000000f
+-#define eq_pages_WORD                         word6
+-#define eqe_size_SHIFT                                8
+-#define eqe_size_MASK                         0x000000ff
+-#define eqe_size_WORD                         word6
+-      uint32_t word7;
+-#define cq_pages_SHIFT                                0
+-#define cq_pages_MASK                         0x0000000f
+-#define cq_pages_WORD                         word7
+-#define cqe_size_SHIFT                                8
+-#define cqe_size_MASK                         0x000000ff
+-#define cqe_size_WORD                         word7
+-      uint32_t word8;
+-#define mq_pages_SHIFT                                0
+-#define mq_pages_MASK                         0x0000000f
+-#define mq_pages_WORD                         word8
+-#define mqe_size_SHIFT                                8
+-#define mqe_size_MASK                         0x000000ff
+-#define mqe_size_WORD                         word8
+-#define mq_elem_cnt_SHIFT                     16
+-#define mq_elem_cnt_MASK                      0x000000ff
+-#define mq_elem_cnt_WORD                      word8
+-      uint32_t word9;
+-#define wq_pages_SHIFT                                0
+-#define wq_pages_MASK                         0x0000ffff
+-#define wq_pages_WORD                         word9
+-#define wqe_size_SHIFT                                8
+-#define wqe_size_MASK                         0x000000ff
+-#define wqe_size_WORD                         word9
+-      uint32_t word10;
+-#define rq_pages_SHIFT                                0
+-#define rq_pages_MASK                         0x0000ffff
+-#define rq_pages_WORD                         word10
+-#define rqe_size_SHIFT                                8
+-#define rqe_size_MASK                         0x000000ff
+-#define rqe_size_WORD                         word10
+-      uint32_t word11;
+-#define hdr_pages_SHIFT                               0
+-#define hdr_pages_MASK                                0x0000000f
+-#define hdr_pages_WORD                                word11
+-#define hdr_size_SHIFT                                8
+-#define hdr_size_MASK                         0x0000000f
+-#define hdr_size_WORD                         word11
+-#define hdr_pp_align_SHIFT                    16
+-#define hdr_pp_align_MASK                     0x0000ffff
+-#define hdr_pp_align_WORD                     word11
+-      uint32_t word12;
+-#define sgl_pages_SHIFT                               0
+-#define sgl_pages_MASK                                0x0000000f
+-#define sgl_pages_WORD                                word12
+-#define sgl_pp_align_SHIFT                    16
+-#define sgl_pp_align_MASK                     0x0000ffff
+-#define sgl_pp_align_WORD                     word12
+-      uint32_t rsvd_13_63[51];
+-};
+ #define SLI4_PAGE_ALIGN(addr) (((addr)+((SLI4_PAGE_SIZE)-1)) \
+                              &(~((SLI4_PAGE_SIZE)-1)))
+@@ -3994,8 +3824,6 @@ struct lpfc_mqe {
+               struct lpfc_mbx_post_hdr_tmpl hdr_tmpl;
+               struct lpfc_mbx_query_fw_config query_fw_cfg;
+               struct lpfc_mbx_set_beacon_config beacon_config;
+-              struct lpfc_mbx_supp_pages supp_pages;
+-              struct lpfc_mbx_pc_sli4_params sli4_params;
+               struct lpfc_mbx_get_sli4_parameters get_sli4_parameters;
+               struct lpfc_mbx_set_link_diag_state link_diag_state;
+               struct lpfc_mbx_set_link_diag_loopback link_diag_loopback;
+diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
+index 302aff50b958..a67051ba3f12 100644
+--- a/drivers/scsi/lpfc/lpfc_init.c
++++ b/drivers/scsi/lpfc/lpfc_init.c
+@@ -6573,8 +6573,6 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
+       LPFC_MBOXQ_t *mboxq;
+       MAILBOX_t *mb;
+       int rc, i, max_buf_size;
+-      uint8_t pn_page[LPFC_MAX_SUPPORTED_PAGES] = {0};
+-      struct lpfc_mqe *mqe;
+       int longs;
+       int extra;
+       uint64_t wwn;
+@@ -6808,32 +6806,6 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
+       lpfc_nvme_mod_param_dep(phba);
+-      /* Get the Supported Pages if PORT_CAPABILITIES is supported by port. */
+-      lpfc_supported_pages(mboxq);
+-      rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
+-      if (!rc) {
+-              mqe = &mboxq->u.mqe;
+-              memcpy(&pn_page[0], ((uint8_t *)&mqe->un.supp_pages.word3),
+-                     LPFC_MAX_SUPPORTED_PAGES);
+-              for (i = 0; i < LPFC_MAX_SUPPORTED_PAGES; i++) {
+-                      switch (pn_page[i]) {
+-                      case LPFC_SLI4_PARAMETERS:
+-                              phba->sli4_hba.pc_sli4_params.supported = 1;
+-                              break;
+-                      default:
+-                              break;
+-                      }
+-              }
+-              /* Read the port's SLI4 Parameters capabilities if supported. */
+-              if (phba->sli4_hba.pc_sli4_params.supported)
+-                      rc = lpfc_pc_sli4_params_get(phba, mboxq);
+-              if (rc) {
+-                      mempool_free(mboxq, phba->mbox_mem_pool);
+-                      rc = -EIO;
+-                      goto out_free_bsmbx;
+-              }
+-      }
+-
+       /*
+        * Get sli4 parameters that override parameters from Port capabilities.
+        * If this call fails, it isn't critical unless the SLI4 parameters come
+@@ -12072,78 +12044,6 @@ lpfc_sli4_hba_unset(struct lpfc_hba *phba)
+               phba->pport->work_port_events = 0;
+ }
+- /**
+- * lpfc_pc_sli4_params_get - Get the SLI4_PARAMS port capabilities.
+- * @phba: Pointer to HBA context object.
+- * @mboxq: Pointer to the mailboxq memory for the mailbox command response.
+- *
+- * This function is called in the SLI4 code path to read the port's
+- * sli4 capabilities.
+- *
+- * This function may be be called from any context that can block-wait
+- * for the completion.  The expectation is that this routine is called
+- * typically from probe_one or from the online routine.
+- **/
+-int
+-lpfc_pc_sli4_params_get(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
+-{
+-      int rc;
+-      struct lpfc_mqe *mqe;
+-      struct lpfc_pc_sli4_params *sli4_params;
+-      uint32_t mbox_tmo;
+-
+-      rc = 0;
+-      mqe = &mboxq->u.mqe;
+-
+-      /* Read the port's SLI4 Parameters port capabilities */
+-      lpfc_pc_sli4_params(mboxq);
+-      if (!phba->sli4_hba.intr_enable)
+-              rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
+-      else {
+-              mbox_tmo = lpfc_mbox_tmo_val(phba, mboxq);
+-              rc = lpfc_sli_issue_mbox_wait(phba, mboxq, mbox_tmo);
+-      }
+-
+-      if (unlikely(rc))
+-              return 1;
+-
+-      sli4_params = &phba->sli4_hba.pc_sli4_params;
+-      sli4_params->if_type = bf_get(if_type, &mqe->un.sli4_params);
+-      sli4_params->sli_rev = bf_get(sli_rev, &mqe->un.sli4_params);
+-      sli4_params->sli_family = bf_get(sli_family, &mqe->un.sli4_params);
+-      sli4_params->featurelevel_1 = bf_get(featurelevel_1,
+-                                           &mqe->un.sli4_params);
+-      sli4_params->featurelevel_2 = bf_get(featurelevel_2,
+-                                           &mqe->un.sli4_params);
+-      sli4_params->proto_types = mqe->un.sli4_params.word3;
+-      sli4_params->sge_supp_len = mqe->un.sli4_params.sge_supp_len;
+-      sli4_params->if_page_sz = bf_get(if_page_sz, &mqe->un.sli4_params);
+-      sli4_params->rq_db_window = bf_get(rq_db_window, &mqe->un.sli4_params);
+-      sli4_params->loopbk_scope = bf_get(loopbk_scope, &mqe->un.sli4_params);
+-      sli4_params->eq_pages_max = bf_get(eq_pages, &mqe->un.sli4_params);
+-      sli4_params->eqe_size = bf_get(eqe_size, &mqe->un.sli4_params);
+-      sli4_params->cq_pages_max = bf_get(cq_pages, &mqe->un.sli4_params);
+-      sli4_params->cqe_size = bf_get(cqe_size, &mqe->un.sli4_params);
+-      sli4_params->mq_pages_max = bf_get(mq_pages, &mqe->un.sli4_params);
+-      sli4_params->mqe_size = bf_get(mqe_size, &mqe->un.sli4_params);
+-      sli4_params->mq_elem_cnt = bf_get(mq_elem_cnt, &mqe->un.sli4_params);
+-      sli4_params->wq_pages_max = bf_get(wq_pages, &mqe->un.sli4_params);
+-      sli4_params->wqe_size = bf_get(wqe_size, &mqe->un.sli4_params);
+-      sli4_params->rq_pages_max = bf_get(rq_pages, &mqe->un.sli4_params);
+-      sli4_params->rqe_size = bf_get(rqe_size, &mqe->un.sli4_params);
+-      sli4_params->hdr_pages_max = bf_get(hdr_pages, &mqe->un.sli4_params);
+-      sli4_params->hdr_size = bf_get(hdr_size, &mqe->un.sli4_params);
+-      sli4_params->hdr_pp_align = bf_get(hdr_pp_align, &mqe->un.sli4_params);
+-      sli4_params->sgl_pages_max = bf_get(sgl_pages, &mqe->un.sli4_params);
+-      sli4_params->sgl_pp_align = bf_get(sgl_pp_align, &mqe->un.sli4_params);
+-
+-      /* Make sure that sge_supp_len can be handled by the driver */
+-      if (sli4_params->sge_supp_len > LPFC_MAX_SGE_SIZE)
+-              sli4_params->sge_supp_len = LPFC_MAX_SGE_SIZE;
+-
+-      return rc;
+-}
+-
+ /**
+  * lpfc_get_sli4_parameters - Get the SLI4 Config PARAMETERS.
+  * @phba: Pointer to HBA context object.
+@@ -12202,7 +12102,8 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
+       else
+               phba->sli3_options &= ~LPFC_SLI4_PHWQ_ENABLED;
+       sli4_params->sge_supp_len = mbx_sli4_parameters->sge_supp_len;
+-      sli4_params->loopbk_scope = bf_get(loopbk_scope, mbx_sli4_parameters);
++      sli4_params->loopbk_scope = bf_get(cfg_loopbk_scope,
++                                         mbx_sli4_parameters);
+       sli4_params->oas_supported = bf_get(cfg_oas, mbx_sli4_parameters);
+       sli4_params->cqv = bf_get(cfg_cqv, mbx_sli4_parameters);
+       sli4_params->mqv = bf_get(cfg_mqv, mbx_sli4_parameters);
+diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c
+index c03a7f12dd65..72dd22ad5dcc 100644
+--- a/drivers/scsi/lpfc/lpfc_mbox.c
++++ b/drivers/scsi/lpfc/lpfc_mbox.c
+@@ -2624,39 +2624,3 @@ lpfc_resume_rpi(struct lpfcMboxq *mbox, struct lpfc_nodelist *ndlp)
+       resume_rpi->event_tag = ndlp->phba->fc_eventTag;
+ }
+-/**
+- * lpfc_supported_pages - Initialize the PORT_CAPABILITIES supported pages
+- *                        mailbox command.
+- * @mbox: pointer to lpfc mbox command to initialize.
+- *
+- * The PORT_CAPABILITIES supported pages mailbox command is issued to
+- * retrieve the particular feature pages supported by the port.
+- **/
+-void
+-lpfc_supported_pages(struct lpfcMboxq *mbox)
+-{
+-      struct lpfc_mbx_supp_pages *supp_pages;
+-
+-      memset(mbox, 0, sizeof(*mbox));
+-      supp_pages = &mbox->u.mqe.un.supp_pages;
+-      bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_PORT_CAPABILITIES);
+-      bf_set(cpn, supp_pages, LPFC_SUPP_PAGES);
+-}
+-
+-/**
+- * lpfc_pc_sli4_params - Initialize the PORT_CAPABILITIES SLI4 Params mbox cmd.
+- * @mbox: pointer to lpfc mbox command to initialize.
+- *
+- * The PORT_CAPABILITIES SLI4 parameters mailbox command is issued to
+- * retrieve the particular SLI4 features supported by the port.
+- **/
+-void
+-lpfc_pc_sli4_params(struct lpfcMboxq *mbox)
+-{
+-      struct lpfc_mbx_pc_sli4_params *sli4_params;
+-
+-      memset(mbox, 0, sizeof(*mbox));
+-      sli4_params = &mbox->u.mqe.un.sli4_params;
+-      bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_PORT_CAPABILITIES);
+-      bf_set(cpn, sli4_params, LPFC_SLI4_PARAMETERS);
+-}
+-- 
+2.30.2
+
diff --git a/queue-5.12/scsi-mpt3sas-fix-out-of-bounds-warnings-in-_ctl_addn.patch b/queue-5.12/scsi-mpt3sas-fix-out-of-bounds-warnings-in-_ctl_addn.patch
new file mode 100644 (file)
index 0000000..5cdd3a3
--- /dev/null
@@ -0,0 +1,132 @@
+From b2af6820253a48e9f7f637bada36e9d3ca483d29 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Apr 2021 11:20:54 -0500
+Subject: scsi: mpt3sas: Fix out-of-bounds warnings in _ctl_addnl_diag_query
+
+From: Gustavo A. R. Silva <gustavoars@kernel.org>
+
+[ Upstream commit 16660db3fc2af8664af5e0a3cac69c4a54bfb794 ]
+
+Fix the following out-of-bounds warnings by embedding existing struct
+htb_rel_query into struct mpt3_addnl_diag_query, instead of duplicating its
+members:
+
+include/linux/fortify-string.h:20:29: warning: '__builtin_memcpy' offset [19, 32] from the object at 'karg' is out of the bounds of referenced subobject 'buffer_rel_condition' with type 'short unsigned int' at offset 16 [-Warray-bounds]
+include/linux/fortify-string.h:22:29: warning: '__builtin_memset' offset [19, 32] from the object at 'karg' is out of the bounds of referenced subobject 'buffer_rel_condition' with type 'short unsigned int' at offset 16 [-Warray-bounds]
+
+The problem is that the original code is trying to copy data into a bunch
+of struct members adjacent to each other in a single call to memcpy(). All
+those members are exactly the same contained in struct htb_rel_query, so
+instead of duplicating them into struct mpt3_addnl_diag_query, replace them
+with new member rel_query of type struct htb_rel_query. So, now that this
+new object is introduced, memcpy() doesn't overrun the length of
+&karg.buffer_rel_condition, because the address of the new struct object
+_rel_query_ is used as destination, instead. The same issue is present when
+calling memset(), and it is fixed with this same approach.
+
+Below is a comparison of struct mpt3_addnl_diag_query, before and after
+this change (the size and cachelines remain the same):
+
+$ pahole -C mpt3_addnl_diag_query drivers/scsi/mpt3sas/mpt3sas_ctl.o
+struct mpt3_addnl_diag_query {
+       struct mpt3_ioctl_header   hdr;                  /*     0    12 */
+       uint32_t                   unique_id;            /*    12     4 */
+       uint16_t                   buffer_rel_condition; /*    16     2 */
+       uint16_t                   reserved1;            /*    18     2 */
+       uint32_t                   trigger_type;         /*    20     4 */
+       uint32_t                   trigger_info_dwords[2]; /*    24     8 */
+       uint32_t                   reserved2[2];         /*    32     8 */
+
+       /* size: 40, cachelines: 1, members: 7 */
+       /* last cacheline: 40 bytes */
+};
+
+$ pahole -C mpt3_addnl_diag_query drivers/scsi/mpt3sas/mpt3sas_ctl.o
+struct mpt3_addnl_diag_query {
+       struct mpt3_ioctl_header   hdr;                  /*     0    12 */
+       uint32_t                   unique_id;            /*    12     4 */
+       struct htb_rel_query       rel_query;            /*    16    16 */
+       uint32_t                   reserved2[2];         /*    32     8 */
+
+       /* size: 40, cachelines: 1, members: 4 */
+       /* last cacheline: 40 bytes */
+};
+
+Also, this helps with the ongoing efforts to globally enable -Warray-bounds
+and get us closer to being able to tighten the FORTIFY_SOURCE routines on
+memcpy().
+
+Link: https://github.com/KSPP/linux/issues/109
+Link: https://lore.kernel.org/lkml/60659889.bJJILx2THu3hlpxW%25lkp@intel.com/
+Link: https://lore.kernel.org/r/20210401162054.GA397186@embeddedor
+Build-tested-by: kernel test robot <lkp@intel.com>
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/mpt3sas/mpt3sas_ctl.c |  5 ++---
+ drivers/scsi/mpt3sas/mpt3sas_ctl.h | 12 ++++--------
+ 2 files changed, 6 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+index 44f9a05db94e..2ec11be62a82 100644
+--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c
++++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+@@ -2507,7 +2507,7 @@ _ctl_addnl_diag_query(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
+                   __func__, karg.unique_id);
+               return -EPERM;
+       }
+-      memset(&karg.buffer_rel_condition, 0, sizeof(struct htb_rel_query));
++      memset(&karg.rel_query, 0, sizeof(karg.rel_query));
+       if ((ioc->diag_buffer_status[buffer_type] &
+           MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) {
+               ioc_info(ioc, "%s: buffer_type(0x%02x) is not registered\n",
+@@ -2520,8 +2520,7 @@ _ctl_addnl_diag_query(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
+                   __func__, buffer_type);
+               return -EPERM;
+       }
+-      memcpy(&karg.buffer_rel_condition, &ioc->htb_rel,
+-          sizeof(struct  htb_rel_query));
++      memcpy(&karg.rel_query, &ioc->htb_rel, sizeof(karg.rel_query));
+ out:
+       if (copy_to_user(arg, &karg, sizeof(struct mpt3_addnl_diag_query))) {
+               ioc_err(ioc, "%s: unable to write mpt3_addnl_diag_query data @ %p\n",
+diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.h b/drivers/scsi/mpt3sas/mpt3sas_ctl.h
+index d2ccdafb8df2..8f6ffb40261c 100644
+--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.h
++++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.h
+@@ -50,6 +50,8 @@
+ #include <linux/miscdevice.h>
+ #endif
++#include "mpt3sas_base.h"
++
+ #ifndef MPT2SAS_MINOR
+ #define MPT2SAS_MINOR         (MPT_MINOR + 1)
+ #endif
+@@ -436,19 +438,13 @@ struct mpt3_diag_read_buffer {
+  * struct mpt3_addnl_diag_query - diagnostic buffer release reason
+  * @hdr - generic header
+  * @unique_id - unique id associated with this buffer.
+- * @buffer_rel_condition - Release condition ioctl/sysfs/reset
+- * @reserved1
+- * @trigger_type - Master/Event/scsi/MPI
+- * @trigger_info_dwords - Data Correspondig to trigger type
++ * @rel_query - release query.
+  * @reserved2
+  */
+ struct mpt3_addnl_diag_query {
+       struct mpt3_ioctl_header hdr;
+       uint32_t unique_id;
+-      uint16_t buffer_rel_condition;
+-      uint16_t reserved1;
+-      uint32_t trigger_type;
+-      uint32_t trigger_info_dwords[2];
++      struct htb_rel_query rel_query;
+       uint32_t reserved2[2];
+ };
+-- 
+2.30.2
+
diff --git a/queue-5.12/scsi-qla2xxx-always-check-the-return-value-of-qla24x.patch b/queue-5.12/scsi-qla2xxx-always-check-the-return-value-of-qla24x.patch
new file mode 100644 (file)
index 0000000..5346e14
--- /dev/null
@@ -0,0 +1,60 @@
+From ac6bb0175482b1ec105650ebfb5604c63ce03e51 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 Mar 2021 16:23:58 -0700
+Subject: scsi: qla2xxx: Always check the return value of
+ qla24xx_get_isp_stats()
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit a2b2cc660822cae08c351c7f6b452bfd1330a4f7 ]
+
+This patch fixes the following Coverity warning:
+
+    CID 361199 (#1 of 1): Unchecked return value (CHECKED_RETURN)
+    3. check_return: Calling qla24xx_get_isp_stats without checking return
+    value (as is done elsewhere 4 out of 5 times).
+
+Link: https://lore.kernel.org/r/20210320232359.941-7-bvanassche@acm.org
+Cc: Quinn Tran <qutran@marvell.com>
+Cc: Mike Christie <michael.christie@oracle.com>
+Cc: Himanshu Madhani <himanshu.madhani@oracle.com>
+Cc: Daniel Wagner <dwagner@suse.de>
+Cc: Lee Duncan <lduncan@suse.com>
+Reviewed-by: Daniel Wagner <dwagner@suse.de>
+Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_attr.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
+index 63391c9be05d..3aa9869f6fae 100644
+--- a/drivers/scsi/qla2xxx/qla_attr.c
++++ b/drivers/scsi/qla2xxx/qla_attr.c
+@@ -2864,6 +2864,8 @@ qla2x00_reset_host_stats(struct Scsi_Host *shost)
+       vha->qla_stats.jiffies_at_last_reset = get_jiffies_64();
+       if (IS_FWI2_CAPABLE(ha)) {
++              int rval;
++
+               stats = dma_alloc_coherent(&ha->pdev->dev,
+                   sizeof(*stats), &stats_dma, GFP_KERNEL);
+               if (!stats) {
+@@ -2873,7 +2875,11 @@ qla2x00_reset_host_stats(struct Scsi_Host *shost)
+               }
+               /* reset firmware statistics */
+-              qla24xx_get_isp_stats(base_vha, stats, stats_dma, BIT_0);
++              rval = qla24xx_get_isp_stats(base_vha, stats, stats_dma, BIT_0);
++              if (rval != QLA_SUCCESS)
++                      ql_log(ql_log_warn, vha, 0x70de,
++                             "Resetting ISP statistics failed: rval = %d\n",
++                             rval);
+               dma_free_coherent(&ha->pdev->dev, sizeof(*stats),
+                   stats, stats_dma);
+-- 
+2.30.2
+
diff --git a/queue-5.12/scsi-qla2xxx-fix-use-after-free-in-bsg.patch b/queue-5.12/scsi-qla2xxx-fix-use-after-free-in-bsg.patch
new file mode 100644 (file)
index 0000000..b8007a2
--- /dev/null
@@ -0,0 +1,61 @@
+From 34f4591a037c247024aecaf8a978c25294ec3ada Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Mar 2021 01:52:22 -0700
+Subject: scsi: qla2xxx: Fix use after free in bsg
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit 2ce35c0821afc2acd5ee1c3f60d149f8b2520ce8 ]
+
+On bsg command completion, bsg_job_done() was called while qla driver
+continued to access the bsg_job buffer. bsg_job_done() would free up
+resources that ended up being reused by other task while the driver
+continued to access the buffers. As a result, driver was reading garbage
+data.
+
+localhost kernel: BUG: KASAN: use-after-free in sg_next+0x64/0x80
+localhost kernel: Read of size 8 at addr ffff8883228a3330 by task swapper/26/0
+localhost kernel:
+localhost kernel: CPU: 26 PID: 0 Comm: swapper/26 Kdump:
+loaded Tainted: G          OE    --------- -  - 4.18.0-193.el8.x86_64+debug #1
+localhost kernel: Hardware name: HP ProLiant DL360
+Gen9/ProLiant DL360 Gen9, BIOS P89 08/12/2016
+localhost kernel: Call Trace:
+localhost kernel: <IRQ>
+localhost kernel: dump_stack+0x9a/0xf0
+localhost kernel: print_address_description.cold.3+0x9/0x23b
+localhost kernel: kasan_report.cold.4+0x65/0x95
+localhost kernel: debug_dma_unmap_sg.part.12+0x10d/0x2d0
+localhost kernel: qla2x00_bsg_sp_free+0xaf6/0x1010 [qla2xxx]
+
+Link: https://lore.kernel.org/r/20210329085229.4367-6-njavali@marvell.com
+Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Saurav Kashyap <skashyap@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_bsg.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
+index bee8cf9f8123..d021e51344f5 100644
+--- a/drivers/scsi/qla2xxx/qla_bsg.c
++++ b/drivers/scsi/qla2xxx/qla_bsg.c
+@@ -25,10 +25,11 @@ void qla2x00_bsg_job_done(srb_t *sp, int res)
+       struct bsg_job *bsg_job = sp->u.bsg_job;
+       struct fc_bsg_reply *bsg_reply = bsg_job->reply;
++      sp->free(sp);
++
+       bsg_reply->result = res;
+       bsg_job_done(bsg_job, bsg_reply->result,
+                      bsg_reply->reply_payload_rcv_len);
+-      sp->free(sp);
+ }
+ void qla2x00_bsg_sp_free(srb_t *sp)
+-- 
+2.30.2
+
diff --git a/queue-5.12/scsi-scsi_dh_alua-remove-check-for-asc-24h-in-alua_r.patch b/queue-5.12/scsi-scsi_dh_alua-remove-check-for-asc-24h-in-alua_r.patch
new file mode 100644 (file)
index 0000000..33fad4b
--- /dev/null
@@ -0,0 +1,42 @@
+From f5eb3aaaabbc2782e97daa1e5b7b1554fb2c2aa2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Mar 2021 16:11:54 -0400
+Subject: scsi: scsi_dh_alua: Remove check for ASC 24h in alua_rtpg()
+
+From: Ewan D. Milne <emilne@redhat.com>
+
+[ Upstream commit bc3f2b42b70eb1b8576e753e7d0e117bbb674496 ]
+
+Some arrays return ILLEGAL_REQUEST with ASC 00h if they don't support the
+RTPG extended header so remove the check for INVALID FIELD IN CDB.
+
+Link: https://lore.kernel.org/r/20210331201154.20348-1-emilne@redhat.com
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Signed-off-by: Ewan D. Milne <emilne@redhat.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/device_handler/scsi_dh_alua.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
+index ea436a14087f..5eff3368143d 100644
+--- a/drivers/scsi/device_handler/scsi_dh_alua.c
++++ b/drivers/scsi/device_handler/scsi_dh_alua.c
+@@ -573,10 +573,11 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg)
+                * even though it shouldn't according to T10.
+                * The retry without rtpg_ext_hdr_req set
+                * handles this.
++               * Note:  some arrays return a sense key of ILLEGAL_REQUEST
++               * with ASC 00h if they don't support the extended header.
+                */
+               if (!(pg->flags & ALUA_RTPG_EXT_HDR_UNSUPP) &&
+-                  sense_hdr.sense_key == ILLEGAL_REQUEST &&
+-                  sense_hdr.asc == 0x24 && sense_hdr.ascq == 0) {
++                  sense_hdr.sense_key == ILLEGAL_REQUEST) {
+                       pg->flags |= ALUA_RTPG_EXT_HDR_UNSUPP;
+                       goto retry;
+               }
+-- 
+2.30.2
+
diff --git a/queue-5.12/scsi-smartpqi-add-new-pci-ids.patch b/queue-5.12/scsi-smartpqi-add-new-pci-ids.patch
new file mode 100644 (file)
index 0000000..71b91d6
--- /dev/null
@@ -0,0 +1,221 @@
+From 8948f7b3d6d017880117dd42e1224cd6e8fc1089 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Mar 2021 14:17:48 -0600
+Subject: scsi: smartpqi: Add new PCI IDs
+
+From: Kevin Barnett <kevin.barnett@microchip.com>
+
+[ Upstream commit 75fbeacca3ad30835e903002dba98dd909b4dfff ]
+
+Add support for newer hardware.
+
+Link: https://lore.kernel.org/r/161549386882.25025.2594251735886014958.stgit@brunhilda
+Reviewed-by: Scott Benesh <scott.benesh@microchip.com>
+Reviewed-by: Scott Teel <scott.teel@microchip.com>
+Acked-by: Martin Wilck <mwilck@suse.com>
+Signed-off-by: Kevin Barnett <kevin.barnett@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 | 156 ++++++++++++++++++++++++++
+ 1 file changed, 156 insertions(+)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index 52e4d5618dc7..c30f6047410f 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -8221,6 +8221,10 @@ static const struct pci_device_id pqi_pci_id_table[] = {
+               PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+                              0x152d, 0x8a37)
+       },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             0x193d, 0x8460)
++      },
+       {
+               PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+                              0x193d, 0x1104)
+@@ -8293,6 +8297,22 @@ static const struct pci_device_id pqi_pci_id_table[] = {
+               PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+                              0x1bd4, 0x004f)
+       },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             0x1bd4, 0x0051)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             0x1bd4, 0x0052)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             0x1bd4, 0x0053)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             0x1bd4, 0x0054)
++      },
+       {
+               PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+                              0x19e5, 0xd227)
+@@ -8453,6 +8473,122 @@ static const struct pci_device_id pqi_pci_id_table[] = {
+               PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+                              PCI_VENDOR_ID_ADAPTEC2, 0x1380)
+       },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             PCI_VENDOR_ID_ADAPTEC2, 0x1400)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             PCI_VENDOR_ID_ADAPTEC2, 0x1402)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             PCI_VENDOR_ID_ADAPTEC2, 0x1410)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             PCI_VENDOR_ID_ADAPTEC2, 0x1411)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             PCI_VENDOR_ID_ADAPTEC2, 0x1412)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             PCI_VENDOR_ID_ADAPTEC2, 0x1420)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             PCI_VENDOR_ID_ADAPTEC2, 0x1430)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             PCI_VENDOR_ID_ADAPTEC2, 0x1440)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             PCI_VENDOR_ID_ADAPTEC2, 0x1441)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             PCI_VENDOR_ID_ADAPTEC2, 0x1450)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             PCI_VENDOR_ID_ADAPTEC2, 0x1452)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             PCI_VENDOR_ID_ADAPTEC2, 0x1460)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             PCI_VENDOR_ID_ADAPTEC2, 0x1461)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             PCI_VENDOR_ID_ADAPTEC2, 0x1462)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             PCI_VENDOR_ID_ADAPTEC2, 0x1470)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             PCI_VENDOR_ID_ADAPTEC2, 0x1471)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             PCI_VENDOR_ID_ADAPTEC2, 0x1472)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             PCI_VENDOR_ID_ADAPTEC2, 0x1480)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             PCI_VENDOR_ID_ADAPTEC2, 0x1490)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             PCI_VENDOR_ID_ADAPTEC2, 0x1491)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             PCI_VENDOR_ID_ADAPTEC2, 0x14a0)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             PCI_VENDOR_ID_ADAPTEC2, 0x14a1)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             PCI_VENDOR_ID_ADAPTEC2, 0x14b0)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             PCI_VENDOR_ID_ADAPTEC2, 0x14b1)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             PCI_VENDOR_ID_ADAPTEC2, 0x14c0)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             PCI_VENDOR_ID_ADAPTEC2, 0x14c1)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             PCI_VENDOR_ID_ADAPTEC2, 0x14d0)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             PCI_VENDOR_ID_ADAPTEC2, 0x14e0)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             PCI_VENDOR_ID_ADAPTEC2, 0x14f0)
++      },
+       {
+               PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+                              PCI_VENDOR_ID_ADVANTECH, 0x8312)
+@@ -8517,6 +8653,10 @@ static const struct pci_device_id pqi_pci_id_table[] = {
+               PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+                              PCI_VENDOR_ID_HP, 0x1001)
+       },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             PCI_VENDOR_ID_HP, 0x1002)
++      },
+       {
+               PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+                              PCI_VENDOR_ID_HP, 0x1100)
+@@ -8525,6 +8665,22 @@ static const struct pci_device_id pqi_pci_id_table[] = {
+               PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+                              PCI_VENDOR_ID_HP, 0x1101)
+       },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             0x1590, 0x0294)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             0x1590, 0x02db)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             0x1590, 0x02dc)
++      },
++      {
++              PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++                             0x1590, 0x032e)
++      },
+       {
+               PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+                              0x1d8d, 0x0800)
+-- 
+2.30.2
+
diff --git a/queue-5.12/scsi-smartpqi-correct-request-leakage-during-reset-o.patch b/queue-5.12/scsi-smartpqi-correct-request-leakage-during-reset-o.patch
new file mode 100644 (file)
index 0000000..152fca6
--- /dev/null
@@ -0,0 +1,52 @@
+From 816c1d6774859a4a008c5302ebf5c679e02a6bf9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Mar 2021 14:15:03 -0600
+Subject: scsi: smartpqi: Correct request leakage during reset operations
+
+From: Murthy Bhat <Murthy.Bhat@microchip.com>
+
+[ Upstream commit b622a601a13ae5974c5b0aeecb990c224b8db0d9 ]
+
+While failing queued I/Os in TMF path, there was a request leak and hence
+stale entries in request pool with ref count being non-zero. In shutdown
+path we have a BUG_ON to catch stuck I/O either in firmware or in the
+driver. The stale requests caused a system crash. The I/O request pool
+leakage also lead to a significant performance drop.
+
+Link: https://lore.kernel.org/r/161549370379.25025.12793264112620796062.stgit@brunhilda
+Reviewed-by: Scott Teel <scott.teel@microchip.com>
+Reviewed-by: Scott Benesh <scott.benesh@microchip.com>
+Reviewed-by: Kevin Barnett <kevin.barnett@microchip.com>
+Signed-off-by: Murthy Bhat <Murthy.Bhat@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, 4 insertions(+)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index 3795804ea869..52e4d5618dc7 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -5488,6 +5488,8 @@ static void pqi_fail_io_queued_for_device(struct pqi_ctrl_info *ctrl_info,
+                               list_del(&io_request->request_list_entry);
+                               set_host_byte(scmd, DID_RESET);
++                              pqi_free_io_request(io_request);
++                              scsi_dma_unmap(scmd);
+                               pqi_scsi_done(scmd);
+                       }
+@@ -5524,6 +5526,8 @@ static void pqi_fail_io_queued_for_all_devices(struct pqi_ctrl_info *ctrl_info)
+                               list_del(&io_request->request_list_entry);
+                               set_host_byte(scmd, DID_RESET);
++                              pqi_free_io_request(io_request);
++                              scsi_dma_unmap(scmd);
+                               pqi_scsi_done(scmd);
+                       }
+-- 
+2.30.2
+
diff --git a/queue-5.12/scsi-smartpqi-use-host-wide-tag-space.patch b/queue-5.12/scsi-smartpqi-use-host-wide-tag-space.patch
new file mode 100644 (file)
index 0000000..a667833
--- /dev/null
@@ -0,0 +1,43 @@
+From 454b5892ab82c8b5b8688cd1502721b9bbd5d2ac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Mar 2021 14:14:57 -0600
+Subject: scsi: smartpqi: Use host-wide tag space
+
+From: Don Brace <don.brace@microchip.com>
+
+[ Upstream commit c6d3ee209b9e863c6251f72101511340451ca324 ]
+
+Correct SCSI midlayer sending more requests than exposed host queue depth
+causing firmware ASSERT and lockup issues by enabling host-wide tags.
+
+Note: This also results in better performance.
+
+Link: https://lore.kernel.org/r/161549369787.25025.8975999483518581619.stgit@brunhilda
+Suggested-by: Ming Lei <ming.lei@redhat.com>
+Suggested-by: John Garry <john.garry@huawei.com>
+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: 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 | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index a1dacb6e993e..3795804ea869 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -6598,6 +6598,7 @@ static int pqi_register_scsi(struct pqi_ctrl_info *ctrl_info)
+       shost->irq = pci_irq_vector(ctrl_info->pci_dev, 0);
+       shost->unique_id = shost->irq;
+       shost->nr_hw_queues = ctrl_info->num_queue_groups;
++      shost->host_tagset = 1;
+       shost->hostdata[0] = (unsigned long)ctrl_info;
+       rc = scsi_add_host(shost, &ctrl_info->pci_dev->dev);
+-- 
+2.30.2
+
diff --git a/queue-5.12/scsi-target-pscsi-fix-warning-in-pscsi_complete_cmd.patch b/queue-5.12/scsi-target-pscsi-fix-warning-in-pscsi_complete_cmd.patch
new file mode 100644 (file)
index 0000000..1a049a8
--- /dev/null
@@ -0,0 +1,46 @@
+From 4a6e3dd94dc0030bfd394df7608ee5287827730f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Feb 2021 21:56:26 -0800
+Subject: scsi: target: pscsi: Fix warning in pscsi_complete_cmd()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
+
+[ Upstream commit fd48c056a32ed6e7754c7c475490f3bed54ed378 ]
+
+This fixes a compilation warning in pscsi_complete_cmd():
+
+     drivers/target/target_core_pscsi.c: In function ‘pscsi_complete_cmd’:
+     drivers/target/target_core_pscsi.c:624:5: warning: suggest braces around empty body in an ‘if’ statement [-Wempty-body]
+     ; /* XXX: TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE */
+
+Link: https://lore.kernel.org/r/20210228055645.22253-5-chaitanya.kulkarni@wdc.com
+Reviewed-by: Mike Christie <michael.christie@oracle.com>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/target/target_core_pscsi.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c
+index 9ee797b8cb7e..508b49b0eaf5 100644
+--- a/drivers/target/target_core_pscsi.c
++++ b/drivers/target/target_core_pscsi.c
+@@ -620,8 +620,9 @@ static void pscsi_complete_cmd(struct se_cmd *cmd, u8 scsi_status,
+                       unsigned char *buf;
+                       buf = transport_kmap_data_sg(cmd);
+-                      if (!buf)
++                      if (!buf) {
+                               ; /* XXX: TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE */
++                      }
+                       if (cdb[0] == MODE_SENSE_10) {
+                               if (!(buf[3] & 0x80))
+-- 
+2.30.2
+
diff --git a/queue-5.12/selftests-resctrl-clean-up-resctrl-features-check.patch b/queue-5.12/selftests-resctrl-clean-up-resctrl-features-check.patch
new file mode 100644 (file)
index 0000000..409b446
--- /dev/null
@@ -0,0 +1,331 @@
+From f6edd1dc49ffb0b03956029180cd711c4f7090b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Mar 2021 02:22:38 +0000
+Subject: selftests/resctrl: Clean up resctrl features check
+
+From: Fenghua Yu <fenghua.yu@intel.com>
+
+[ Upstream commit 2428673638ea28fa93d2a38b1c3e8d70122b00ee ]
+
+Checking resctrl features call strcmp() to compare feature strings
+(e.g. "mba", "cat" etc). The checkings are error prone and don't have
+good coding style. Define the constant strings in macros and call
+strncmp() to solve the potential issues.
+
+Suggested-by: Shuah Khan <skhan@linuxfoundation.org>
+Tested-by: Babu Moger <babu.moger@amd.com>
+Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/resctrl/cache.c       |  8 +++----
+ tools/testing/selftests/resctrl/cat_test.c    |  2 +-
+ tools/testing/selftests/resctrl/cqm_test.c    |  2 +-
+ tools/testing/selftests/resctrl/fill_buf.c    |  4 ++--
+ tools/testing/selftests/resctrl/mba_test.c    |  2 +-
+ tools/testing/selftests/resctrl/mbm_test.c    |  2 +-
+ tools/testing/selftests/resctrl/resctrl.h     |  5 +++++
+ .../testing/selftests/resctrl/resctrl_tests.c | 12 +++++-----
+ tools/testing/selftests/resctrl/resctrl_val.c | 22 +++++++++----------
+ tools/testing/selftests/resctrl/resctrlfs.c   | 17 +++++++-------
+ 10 files changed, 41 insertions(+), 35 deletions(-)
+
+diff --git a/tools/testing/selftests/resctrl/cache.c b/tools/testing/selftests/resctrl/cache.c
+index 38dbf4962e33..5922cc1b0386 100644
+--- a/tools/testing/selftests/resctrl/cache.c
++++ b/tools/testing/selftests/resctrl/cache.c
+@@ -182,7 +182,7 @@ int measure_cache_vals(struct resctrl_val_param *param, int bm_pid)
+       /*
+        * Measure cache miss from perf.
+        */
+-      if (!strcmp(param->resctrl_val, "cat")) {
++      if (!strncmp(param->resctrl_val, CAT_STR, sizeof(CAT_STR))) {
+               ret = get_llc_perf(&llc_perf_miss);
+               if (ret < 0)
+                       return ret;
+@@ -192,7 +192,7 @@ int measure_cache_vals(struct resctrl_val_param *param, int bm_pid)
+       /*
+        * Measure llc occupancy from resctrl.
+        */
+-      if (!strcmp(param->resctrl_val, "cqm")) {
++      if (!strncmp(param->resctrl_val, CQM_STR, sizeof(CQM_STR))) {
+               ret = get_llc_occu_resctrl(&llc_occu_resc);
+               if (ret < 0)
+                       return ret;
+@@ -234,7 +234,7 @@ int cat_val(struct resctrl_val_param *param)
+       if (ret)
+               return ret;
+-      if ((strcmp(resctrl_val, "cat") == 0)) {
++      if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR))) {
+               ret = initialize_llc_perf();
+               if (ret)
+                       return ret;
+@@ -242,7 +242,7 @@ int cat_val(struct resctrl_val_param *param)
+       /* Test runs until the callback setup() tells the test to stop. */
+       while (1) {
+-              if (strcmp(resctrl_val, "cat") == 0) {
++              if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR))) {
+                       ret = param->setup(1, param);
+                       if (ret) {
+                               ret = 0;
+diff --git a/tools/testing/selftests/resctrl/cat_test.c b/tools/testing/selftests/resctrl/cat_test.c
+index bdeeb5772592..20823725daca 100644
+--- a/tools/testing/selftests/resctrl/cat_test.c
++++ b/tools/testing/selftests/resctrl/cat_test.c
+@@ -164,7 +164,7 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type)
+               return -1;
+       struct resctrl_val_param param = {
+-              .resctrl_val    = "cat",
++              .resctrl_val    = CAT_STR,
+               .cpu_no         = cpu_no,
+               .mum_resctrlfs  = 0,
+               .setup          = cat_setup,
+diff --git a/tools/testing/selftests/resctrl/cqm_test.c b/tools/testing/selftests/resctrl/cqm_test.c
+index de33d1c0466e..271752e9ef5b 100644
+--- a/tools/testing/selftests/resctrl/cqm_test.c
++++ b/tools/testing/selftests/resctrl/cqm_test.c
+@@ -145,7 +145,7 @@ int cqm_resctrl_val(int cpu_no, int n, char **benchmark_cmd)
+       }
+       struct resctrl_val_param param = {
+-              .resctrl_val    = "cqm",
++              .resctrl_val    = CQM_STR,
+               .ctrlgrp        = "c1",
+               .mongrp         = "m1",
+               .cpu_no         = cpu_no,
+diff --git a/tools/testing/selftests/resctrl/fill_buf.c b/tools/testing/selftests/resctrl/fill_buf.c
+index 79c611c99a3d..51e5cf22632f 100644
+--- a/tools/testing/selftests/resctrl/fill_buf.c
++++ b/tools/testing/selftests/resctrl/fill_buf.c
+@@ -115,7 +115,7 @@ static int fill_cache_read(unsigned char *start_ptr, unsigned char *end_ptr,
+       while (1) {
+               ret = fill_one_span_read(start_ptr, end_ptr);
+-              if (!strcmp(resctrl_val, "cat"))
++              if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)))
+                       break;
+       }
+@@ -134,7 +134,7 @@ static int fill_cache_write(unsigned char *start_ptr, unsigned char *end_ptr,
+ {
+       while (1) {
+               fill_one_span_write(start_ptr, end_ptr);
+-              if (!strcmp(resctrl_val, "cat"))
++              if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)))
+                       break;
+       }
+diff --git a/tools/testing/selftests/resctrl/mba_test.c b/tools/testing/selftests/resctrl/mba_test.c
+index 7bf8eaa6204b..6449fbd96096 100644
+--- a/tools/testing/selftests/resctrl/mba_test.c
++++ b/tools/testing/selftests/resctrl/mba_test.c
+@@ -141,7 +141,7 @@ void mba_test_cleanup(void)
+ int mba_schemata_change(int cpu_no, char *bw_report, char **benchmark_cmd)
+ {
+       struct resctrl_val_param param = {
+-              .resctrl_val    = "mba",
++              .resctrl_val    = MBA_STR,
+               .ctrlgrp        = "c1",
+               .mongrp         = "m1",
+               .cpu_no         = cpu_no,
+diff --git a/tools/testing/selftests/resctrl/mbm_test.c b/tools/testing/selftests/resctrl/mbm_test.c
+index 4700f7453f81..ec6cfe01c9c2 100644
+--- a/tools/testing/selftests/resctrl/mbm_test.c
++++ b/tools/testing/selftests/resctrl/mbm_test.c
+@@ -114,7 +114,7 @@ void mbm_test_cleanup(void)
+ int mbm_bw_change(int span, int cpu_no, char *bw_report, char **benchmark_cmd)
+ {
+       struct resctrl_val_param param = {
+-              .resctrl_val    = "mbm",
++              .resctrl_val    = MBM_STR,
+               .ctrlgrp        = "c1",
+               .mongrp         = "m1",
+               .span           = span,
+diff --git a/tools/testing/selftests/resctrl/resctrl.h b/tools/testing/selftests/resctrl/resctrl.h
+index 12b77182cb44..36da6136af96 100644
+--- a/tools/testing/selftests/resctrl/resctrl.h
++++ b/tools/testing/selftests/resctrl/resctrl.h
+@@ -62,6 +62,11 @@ struct resctrl_val_param {
+       int             (*setup)(int num, ...);
+ };
++#define MBM_STR                       "mbm"
++#define MBA_STR                       "mba"
++#define CQM_STR                       "cqm"
++#define CAT_STR                       "cat"
++
+ extern pid_t bm_pid, ppid;
+ extern int tests_run;
+diff --git a/tools/testing/selftests/resctrl/resctrl_tests.c b/tools/testing/selftests/resctrl/resctrl_tests.c
+index 425cc85ac883..4b109a59f72d 100644
+--- a/tools/testing/selftests/resctrl/resctrl_tests.c
++++ b/tools/testing/selftests/resctrl/resctrl_tests.c
+@@ -85,13 +85,13 @@ int main(int argc, char **argv)
+                       cqm_test = false;
+                       cat_test = false;
+                       while (token) {
+-                              if (!strcmp(token, "mbm")) {
++                              if (!strncmp(token, MBM_STR, sizeof(MBM_STR))) {
+                                       mbm_test = true;
+-                              } else if (!strcmp(token, "mba")) {
++                              } else if (!strncmp(token, MBA_STR, sizeof(MBA_STR))) {
+                                       mba_test = true;
+-                              } else if (!strcmp(token, "cqm")) {
++                              } else if (!strncmp(token, CQM_STR, sizeof(CQM_STR))) {
+                                       cqm_test = true;
+-                              } else if (!strcmp(token, "cat")) {
++                              } else if (!strncmp(token, CAT_STR, sizeof(CAT_STR))) {
+                                       cat_test = true;
+                               } else {
+                                       printf("invalid argument\n");
+@@ -161,7 +161,7 @@ int main(int argc, char **argv)
+       if (!is_amd && mbm_test) {
+               printf("# Starting MBM BW change ...\n");
+               if (!has_ben)
+-                      sprintf(benchmark_cmd[5], "%s", "mba");
++                      sprintf(benchmark_cmd[5], "%s", MBA_STR);
+               res = mbm_bw_change(span, cpu_no, bw_report, benchmark_cmd);
+               printf("%sok MBM: bw change\n", res ? "not " : "");
+               mbm_test_cleanup();
+@@ -181,7 +181,7 @@ int main(int argc, char **argv)
+       if (cqm_test) {
+               printf("# Starting CQM test ...\n");
+               if (!has_ben)
+-                      sprintf(benchmark_cmd[5], "%s", "cqm");
++                      sprintf(benchmark_cmd[5], "%s", CQM_STR);
+               res = cqm_resctrl_val(cpu_no, no_of_bits, benchmark_cmd);
+               printf("%sok CQM: test\n", res ? "not " : "");
+               cqm_test_cleanup();
+diff --git a/tools/testing/selftests/resctrl/resctrl_val.c b/tools/testing/selftests/resctrl/resctrl_val.c
+index 520fea3606d1..aed71fd0713b 100644
+--- a/tools/testing/selftests/resctrl/resctrl_val.c
++++ b/tools/testing/selftests/resctrl/resctrl_val.c
+@@ -397,10 +397,10 @@ static void initialize_mem_bw_resctrl(const char *ctrlgrp, const char *mongrp,
+               return;
+       }
+-      if (strcmp(resctrl_val, "mbm") == 0)
++      if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)))
+               set_mbm_path(ctrlgrp, mongrp, resource_id);
+-      if ((strcmp(resctrl_val, "mba") == 0)) {
++      if (!strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR))) {
+               if (ctrlgrp)
+                       sprintf(mbm_total_path, CON_MBM_LOCAL_BYTES_PATH,
+                               RESCTRL_PATH, ctrlgrp, resource_id);
+@@ -524,7 +524,7 @@ static void initialize_llc_occu_resctrl(const char *ctrlgrp, const char *mongrp,
+               return;
+       }
+-      if (strcmp(resctrl_val, "cqm") == 0)
++      if (!strncmp(resctrl_val, CQM_STR, sizeof(CQM_STR)))
+               set_cqm_path(ctrlgrp, mongrp, resource_id);
+ }
+@@ -579,8 +579,8 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)
+       if (strcmp(param->filename, "") == 0)
+               sprintf(param->filename, "stdio");
+-      if ((strcmp(resctrl_val, "mba")) == 0 ||
+-          (strcmp(resctrl_val, "mbm")) == 0) {
++      if (!strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR)) ||
++          !strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR))) {
+               ret = validate_bw_report_request(param->bw_report);
+               if (ret)
+                       return ret;
+@@ -674,15 +674,15 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)
+       if (ret)
+               goto out;
+-      if ((strcmp(resctrl_val, "mbm") == 0) ||
+-          (strcmp(resctrl_val, "mba") == 0)) {
++      if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)) ||
++          !strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR))) {
+               ret = initialize_mem_bw_imc();
+               if (ret)
+                       goto out;
+               initialize_mem_bw_resctrl(param->ctrlgrp, param->mongrp,
+                                         param->cpu_no, resctrl_val);
+-      } else if (strcmp(resctrl_val, "cqm") == 0)
++      } else if (!strncmp(resctrl_val, CQM_STR, sizeof(CQM_STR)))
+               initialize_llc_occu_resctrl(param->ctrlgrp, param->mongrp,
+                                           param->cpu_no, resctrl_val);
+@@ -710,8 +710,8 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)
+       /* Test runs until the callback setup() tells the test to stop. */
+       while (1) {
+-              if ((strcmp(resctrl_val, "mbm") == 0) ||
+-                  (strcmp(resctrl_val, "mba") == 0)) {
++              if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)) ||
++                  !strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR))) {
+                       ret = param->setup(1, param);
+                       if (ret) {
+                               ret = 0;
+@@ -721,7 +721,7 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)
+                       ret = measure_vals(param, &bw_resc_start);
+                       if (ret)
+                               break;
+-              } else if (strcmp(resctrl_val, "cqm") == 0) {
++              } else if (!strncmp(resctrl_val, CQM_STR, sizeof(CQM_STR))) {
+                       ret = param->setup(1, param);
+                       if (ret) {
+                               ret = 0;
+diff --git a/tools/testing/selftests/resctrl/resctrlfs.c b/tools/testing/selftests/resctrl/resctrlfs.c
+index 2a16100c9c3f..4174e48e06d1 100644
+--- a/tools/testing/selftests/resctrl/resctrlfs.c
++++ b/tools/testing/selftests/resctrl/resctrlfs.c
+@@ -334,7 +334,7 @@ void run_benchmark(int signum, siginfo_t *info, void *ucontext)
+               operation = atoi(benchmark_cmd[4]);
+               sprintf(resctrl_val, "%s", benchmark_cmd[5]);
+-              if (strcmp(resctrl_val, "cqm") != 0)
++              if (strncmp(resctrl_val, CQM_STR, sizeof(CQM_STR)))
+                       buffer_span = span * MB;
+               else
+                       buffer_span = span;
+@@ -459,8 +459,8 @@ int write_bm_pid_to_resctrl(pid_t bm_pid, char *ctrlgrp, char *mongrp,
+               goto out;
+       /* Create mon grp and write pid into it for "mbm" and "cqm" test */
+-      if ((strcmp(resctrl_val, "cqm") == 0) ||
+-          (strcmp(resctrl_val, "mbm") == 0)) {
++      if (!strncmp(resctrl_val, CQM_STR, sizeof(CQM_STR)) ||
++          !strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR))) {
+               if (strlen(mongrp)) {
+                       sprintf(monitorgroup_p, "%s/mon_groups", controlgroup);
+                       sprintf(monitorgroup, "%s/%s", monitorgroup_p, mongrp);
+@@ -505,9 +505,9 @@ int write_schemata(char *ctrlgrp, char *schemata, int cpu_no, char *resctrl_val)
+       int resource_id, ret = 0;
+       FILE *fp;
+-      if ((strcmp(resctrl_val, "mba") != 0) &&
+-          (strcmp(resctrl_val, "cat") != 0) &&
+-          (strcmp(resctrl_val, "cqm") != 0))
++      if (strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR)) &&
++          strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)) &&
++          strncmp(resctrl_val, CQM_STR, sizeof(CQM_STR)))
+               return -ENOENT;
+       if (!schemata) {
+@@ -528,9 +528,10 @@ int write_schemata(char *ctrlgrp, char *schemata, int cpu_no, char *resctrl_val)
+       else
+               sprintf(controlgroup, "%s/schemata", RESCTRL_PATH);
+-      if (!strcmp(resctrl_val, "cat") || !strcmp(resctrl_val, "cqm"))
++      if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)) ||
++          !strncmp(resctrl_val, CQM_STR, sizeof(CQM_STR)))
+               sprintf(schema, "%s%d%c%s", "L3:", resource_id, '=', schemata);
+-      if (strcmp(resctrl_val, "mba") == 0)
++      if (!strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR)))
+               sprintf(schema, "%s%d%c%s", "MB:", resource_id, '=', schemata);
+       fp = fopen(controlgroup, "w");
+-- 
+2.30.2
+
diff --git a/queue-5.12/selftests-resctrl-enable-gcc-checks-to-detect-buffer.patch b/queue-5.12/selftests-resctrl-enable-gcc-checks-to-detect-buffer.patch
new file mode 100644 (file)
index 0000000..afb34ad
--- /dev/null
@@ -0,0 +1,80 @@
+From e861d8e613f7b69200063d7781886e417288a006 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Mar 2021 02:22:35 +0000
+Subject: selftests/resctrl: Enable gcc checks to detect buffer overflows
+
+From: Fenghua Yu <fenghua.yu@intel.com>
+
+[ Upstream commit a9d26a302dea29eb84f491b1340a57e56c631a71 ]
+
+David reported a buffer overflow error in the check_results() function of
+the cmt unit test and he suggested enabling _FORTIFY_SOURCE gcc compiler
+option to automatically detect any such errors.
+
+Feature Test Macros man page describes_FORTIFY_SOURCE as below
+
+"Defining this macro causes some lightweight checks to be performed to
+detect some buffer overflow errors when employing various string and memory
+manipulation functions (for example, memcpy, memset, stpcpy, strcpy,
+strncpy, strcat, strncat, sprintf, snprintf, vsprintf, vsnprintf, gets, and
+wide character variants thereof). For some functions, argument consistency
+is checked; for example, a check is made that open has been supplied with a
+mode argument when the specified flags include O_CREAT. Not all problems
+are detected, just some common cases.
+
+If _FORTIFY_SOURCE is set to 1, with compiler optimization level 1 (gcc
+-O1) and above, checks that shouldn't change the behavior of conforming
+programs are performed.
+
+With _FORTIFY_SOURCE set to 2, some more checking is added, but some
+conforming programs might fail.
+
+Some of the checks can be performed at compile time (via macros logic
+implemented in header files), and result in compiler warnings; other checks
+take place at run time, and result in a run-time error if the check fails.
+
+Use of this macro requires compiler support, available with gcc since
+version 4.0."
+
+Fix the buffer overflow error in the check_results() function of the cmt
+unit test and enable _FORTIFY_SOURCE gcc check to catch any future buffer
+overflow errors.
+
+Reported-by: David Binderman <dcb314@hotmail.com>
+Suggested-by: David Binderman <dcb314@hotmail.com>
+Tested-by: Babu Moger <babu.moger@amd.com>
+Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/resctrl/Makefile   | 2 +-
+ tools/testing/selftests/resctrl/cqm_test.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/resctrl/Makefile b/tools/testing/selftests/resctrl/Makefile
+index d585cc1948cc..6bcee2ec91a9 100644
+--- a/tools/testing/selftests/resctrl/Makefile
++++ b/tools/testing/selftests/resctrl/Makefile
+@@ -1,5 +1,5 @@
+ CC = $(CROSS_COMPILE)gcc
+-CFLAGS = -g -Wall
++CFLAGS = -g -Wall -O2 -D_FORTIFY_SOURCE=2
+ SRCS=$(wildcard *.c)
+ OBJS=$(SRCS:.c=.o)
+diff --git a/tools/testing/selftests/resctrl/cqm_test.c b/tools/testing/selftests/resctrl/cqm_test.c
+index c8756152bd61..5e7308ac63be 100644
+--- a/tools/testing/selftests/resctrl/cqm_test.c
++++ b/tools/testing/selftests/resctrl/cqm_test.c
+@@ -86,7 +86,7 @@ static int check_results(struct resctrl_val_param *param, int no_of_bits)
+               return errno;
+       }
+-      while (fgets(temp, 1024, fp)) {
++      while (fgets(temp, sizeof(temp), fp)) {
+               char *token = strtok(temp, ":\t");
+               int fields = 0;
+-- 
+2.30.2
+
diff --git a/queue-5.12/selftests-resctrl-fix-checking-for-0-for-unsigned-va.patch b/queue-5.12/selftests-resctrl-fix-checking-for-0-for-unsigned-va.patch
new file mode 100644 (file)
index 0000000..05196c6
--- /dev/null
@@ -0,0 +1,142 @@
+From e5cb74534395d98f129500c9f8e7403fe32a60d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Mar 2021 02:22:54 +0000
+Subject: selftests/resctrl: Fix checking for < 0 for unsigned values
+
+From: Fenghua Yu <fenghua.yu@intel.com>
+
+[ Upstream commit 1205b688c92558a04d8dd4cbc2b213e0fceba5db ]
+
+Dan reported following static checker warnings
+
+tools/testing/selftests/resctrl/resctrl_val.c:545 measure_vals()
+warn: 'bw_imc' unsigned <= 0
+
+tools/testing/selftests/resctrl/resctrl_val.c:549 measure_vals()
+warn: 'bw_resc_end' unsigned <= 0
+
+These warnings are reported because
+1. measure_vals() declares 'bw_imc' and 'bw_resc_end' as unsigned long
+   variables
+2. Return value of get_mem_bw_imc() and get_mem_bw_resctrl() are assigned
+   to 'bw_imc' and 'bw_resc_end' respectively
+3. The returned values are checked for <= 0 to see if the calls failed
+
+Checking for < 0 for an unsigned value doesn't make any sense.
+
+Fix this issue by changing the implementation of get_mem_bw_imc() and
+get_mem_bw_resctrl() such that they now accept reference to a variable
+and set the variable appropriately upon success and return 0, else return
+< 0 on error.
+
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Tested-by: Babu Moger <babu.moger@amd.com>
+Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/resctrl/resctrl_val.c | 41 +++++++++++--------
+ 1 file changed, 23 insertions(+), 18 deletions(-)
+
+diff --git a/tools/testing/selftests/resctrl/resctrl_val.c b/tools/testing/selftests/resctrl/resctrl_val.c
+index 5478c23c62ba..8df557894059 100644
+--- a/tools/testing/selftests/resctrl/resctrl_val.c
++++ b/tools/testing/selftests/resctrl/resctrl_val.c
+@@ -300,9 +300,9 @@ static int initialize_mem_bw_imc(void)
+  * Memory B/W utilized by a process on a socket can be calculated using
+  * iMC counters. Perf events are used to read these counters.
+  *
+- * Return: >= 0 on success. < 0 on failure.
++ * Return: = 0 on success. < 0 on failure.
+  */
+-static float get_mem_bw_imc(int cpu_no, char *bw_report)
++static int get_mem_bw_imc(int cpu_no, char *bw_report, float *bw_imc)
+ {
+       float reads, writes, of_mul_read, of_mul_write;
+       int imc, j, ret;
+@@ -373,13 +373,18 @@ static float get_mem_bw_imc(int cpu_no, char *bw_report)
+               close(imc_counters_config[imc][WRITE].fd);
+       }
+-      if (strcmp(bw_report, "reads") == 0)
+-              return reads;
++      if (strcmp(bw_report, "reads") == 0) {
++              *bw_imc = reads;
++              return 0;
++      }
+-      if (strcmp(bw_report, "writes") == 0)
+-              return writes;
++      if (strcmp(bw_report, "writes") == 0) {
++              *bw_imc = writes;
++              return 0;
++      }
+-      return (reads + writes);
++      *bw_imc = reads + writes;
++      return 0;
+ }
+ void set_mbm_path(const char *ctrlgrp, const char *mongrp, int resource_id)
+@@ -438,9 +443,8 @@ static void initialize_mem_bw_resctrl(const char *ctrlgrp, const char *mongrp,
+  * 1. If con_mon grp is given, then read from it
+  * 2. If con_mon grp is not given, then read from root con_mon grp
+  */
+-static unsigned long get_mem_bw_resctrl(void)
++static int get_mem_bw_resctrl(unsigned long *mbm_total)
+ {
+-      unsigned long mbm_total = 0;
+       FILE *fp;
+       fp = fopen(mbm_total_path, "r");
+@@ -449,7 +453,7 @@ static unsigned long get_mem_bw_resctrl(void)
+               return -1;
+       }
+-      if (fscanf(fp, "%lu", &mbm_total) <= 0) {
++      if (fscanf(fp, "%lu", mbm_total) <= 0) {
+               perror("Could not get mbm local bytes");
+               fclose(fp);
+@@ -457,7 +461,7 @@ static unsigned long get_mem_bw_resctrl(void)
+       }
+       fclose(fp);
+-      return mbm_total;
++      return 0;
+ }
+ pid_t bm_pid, ppid;
+@@ -549,7 +553,8 @@ static void initialize_llc_occu_resctrl(const char *ctrlgrp, const char *mongrp,
+ static int
+ measure_vals(struct resctrl_val_param *param, unsigned long *bw_resc_start)
+ {
+-      unsigned long bw_imc, bw_resc, bw_resc_end;
++      unsigned long bw_resc, bw_resc_end;
++      float bw_imc;
+       int ret;
+       /*
+@@ -559,13 +564,13 @@ measure_vals(struct resctrl_val_param *param, unsigned long *bw_resc_start)
+        * Compare the two values to validate resctrl value.
+        * It takes 1sec to measure the data.
+        */
+-      bw_imc = get_mem_bw_imc(param->cpu_no, param->bw_report);
+-      if (bw_imc <= 0)
+-              return bw_imc;
++      ret = get_mem_bw_imc(param->cpu_no, param->bw_report, &bw_imc);
++      if (ret < 0)
++              return ret;
+-      bw_resc_end = get_mem_bw_resctrl();
+-      if (bw_resc_end <= 0)
+-              return bw_resc_end;
++      ret = get_mem_bw_resctrl(&bw_resc_end);
++      if (ret < 0)
++              return ret;
+       bw_resc = (bw_resc_end - *bw_resc_start) / MB;
+       ret = print_results_bw(param->filename, bm_pid, bw_imc, bw_resc);
+-- 
+2.30.2
+
diff --git a/queue-5.12/selftests-resctrl-fix-compilation-issues-for-global-.patch b/queue-5.12/selftests-resctrl-fix-compilation-issues-for-global-.patch
new file mode 100644 (file)
index 0000000..d7ba49e
--- /dev/null
@@ -0,0 +1,147 @@
+From ee986d817ec1381c5b5de495a37ceac664f7795a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Mar 2021 02:22:36 +0000
+Subject: selftests/resctrl: Fix compilation issues for global variables
+
+From: Fenghua Yu <fenghua.yu@intel.com>
+
+[ Upstream commit 8236c51d85a64643588505a6791e022cc8d84864 ]
+
+Reinette reported following compilation issue on Fedora 32, gcc version
+10.1.1
+
+/usr/bin/ld: cqm_test.o:<src_dir>/cqm_test.c:22: multiple definition of
+`cache_size'; cat_test.o:<src_dir>/cat_test.c:23: first defined here
+
+The same issue is reported for long_mask, cbm_mask, count_of_bits etc
+variables as well. Compiler isn't happy because these variables are
+defined globally in two .c files namely cqm_test.c and cat_test.c and
+the compiler during compilation finds that the variable is already
+defined (multiple definition error).
+
+Taking a closer look at the usage of these variables reveals that these
+variables are used only locally in functions such as cqm_resctrl_val()
+(defined in cqm_test.c) and cat_perf_miss_val() (defined in cat_test.c).
+These variables are not shared between those functions. So, there is no
+need for these variables to be global. Hence, fix this issue by making
+them static variables.
+
+Reported-by: Reinette Chatre <reinette.chatre@intel.com>
+Tested-by: Babu Moger <babu.moger@amd.com>
+Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/resctrl/cat_test.c  | 10 +++++-----
+ tools/testing/selftests/resctrl/cqm_test.c  | 10 +++++-----
+ tools/testing/selftests/resctrl/resctrl.h   |  2 +-
+ tools/testing/selftests/resctrl/resctrlfs.c | 10 +++++-----
+ 4 files changed, 16 insertions(+), 16 deletions(-)
+
+diff --git a/tools/testing/selftests/resctrl/cat_test.c b/tools/testing/selftests/resctrl/cat_test.c
+index 5da43767b973..bdeeb5772592 100644
+--- a/tools/testing/selftests/resctrl/cat_test.c
++++ b/tools/testing/selftests/resctrl/cat_test.c
+@@ -17,10 +17,10 @@
+ #define MAX_DIFF_PERCENT      4
+ #define MAX_DIFF              1000000
+-int count_of_bits;
+-char cbm_mask[256];
+-unsigned long long_mask;
+-unsigned long cache_size;
++static int count_of_bits;
++static char cbm_mask[256];
++static unsigned long long_mask;
++static unsigned long cache_size;
+ /*
+  * Change schemata. Write schemata to specified
+@@ -136,7 +136,7 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type)
+               return -1;
+       /* Get default cbm mask for L3/L2 cache */
+-      ret = get_cbm_mask(cache_type);
++      ret = get_cbm_mask(cache_type, cbm_mask);
+       if (ret)
+               return ret;
+diff --git a/tools/testing/selftests/resctrl/cqm_test.c b/tools/testing/selftests/resctrl/cqm_test.c
+index 5e7308ac63be..de33d1c0466e 100644
+--- a/tools/testing/selftests/resctrl/cqm_test.c
++++ b/tools/testing/selftests/resctrl/cqm_test.c
+@@ -16,10 +16,10 @@
+ #define MAX_DIFF              2000000
+ #define MAX_DIFF_PERCENT      15
+-int count_of_bits;
+-char cbm_mask[256];
+-unsigned long long_mask;
+-unsigned long cache_size;
++static int count_of_bits;
++static char cbm_mask[256];
++static unsigned long long_mask;
++static unsigned long cache_size;
+ static int cqm_setup(int num, ...)
+ {
+@@ -125,7 +125,7 @@ int cqm_resctrl_val(int cpu_no, int n, char **benchmark_cmd)
+       if (!validate_resctrl_feature_request("cqm"))
+               return -1;
+-      ret = get_cbm_mask("L3");
++      ret = get_cbm_mask("L3", cbm_mask);
+       if (ret)
+               return ret;
+diff --git a/tools/testing/selftests/resctrl/resctrl.h b/tools/testing/selftests/resctrl/resctrl.h
+index 39bf59c6b9c5..959c71e39bdc 100644
+--- a/tools/testing/selftests/resctrl/resctrl.h
++++ b/tools/testing/selftests/resctrl/resctrl.h
+@@ -92,7 +92,7 @@ void tests_cleanup(void);
+ void mbm_test_cleanup(void);
+ int mba_schemata_change(int cpu_no, char *bw_report, char **benchmark_cmd);
+ void mba_test_cleanup(void);
+-int get_cbm_mask(char *cache_type);
++int get_cbm_mask(char *cache_type, char *cbm_mask);
+ int get_cache_size(int cpu_no, char *cache_type, unsigned long *cache_size);
+ void ctrlc_handler(int signum, siginfo_t *info, void *ptr);
+ int cat_val(struct resctrl_val_param *param);
+diff --git a/tools/testing/selftests/resctrl/resctrlfs.c b/tools/testing/selftests/resctrl/resctrlfs.c
+index 19c0ec4045a4..2a16100c9c3f 100644
+--- a/tools/testing/selftests/resctrl/resctrlfs.c
++++ b/tools/testing/selftests/resctrl/resctrlfs.c
+@@ -49,8 +49,6 @@ static int find_resctrl_mount(char *buffer)
+       return -ENOENT;
+ }
+-char cbm_mask[256];
+-
+ /*
+  * remount_resctrlfs - Remount resctrl FS at /sys/fs/resctrl
+  * @mum_resctrlfs:    Should the resctrl FS be remounted?
+@@ -205,16 +203,18 @@ int get_cache_size(int cpu_no, char *cache_type, unsigned long *cache_size)
+ /*
+  * get_cbm_mask - Get cbm mask for given cache
+  * @cache_type:       Cache level L2/L3
+- *
+- * Mask is stored in cbm_mask which is global variable.
++ * @cbm_mask: cbm_mask returned as a string
+  *
+  * Return: = 0 on success, < 0 on failure.
+  */
+-int get_cbm_mask(char *cache_type)
++int get_cbm_mask(char *cache_type, char *cbm_mask)
+ {
+       char cbm_mask_path[1024];
+       FILE *fp;
++      if (!cbm_mask)
++              return -1;
++
+       sprintf(cbm_mask_path, "%s/%s/cbm_mask", CBM_MASK_PATH, cache_type);
+       fp = fopen(cbm_mask_path, "r");
+-- 
+2.30.2
+
diff --git a/queue-5.12/selftests-resctrl-fix-compilation-issues-for-other-g.patch b/queue-5.12/selftests-resctrl-fix-compilation-issues-for-other-g.patch
new file mode 100644 (file)
index 0000000..97b1e56
--- /dev/null
@@ -0,0 +1,56 @@
+From f30f6006c878e86baa3606c365b7defc981e025b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Mar 2021 02:22:37 +0000
+Subject: selftests/resctrl: Fix compilation issues for other global variables
+
+From: Fenghua Yu <fenghua.yu@intel.com>
+
+[ Upstream commit 896016d2ad051811ff9c9c087393adc063322fbc ]
+
+Reinette reported following compilation issue on Fedora 32, gcc version
+10.1.1
+
+/usr/bin/ld: resctrl_tests.o:<src_dir>/resctrl.h:65: multiple definition
+of `bm_pid'; cache.o:<src_dir>/resctrl.h:65: first defined here
+
+Other variables are ppid, tests_run, llc_occup_path, is_amd. Compiler
+isn't happy because these variables are defined globally in two .c files
+but are not declared as extern.
+
+To fix issues for the global variables, declare them as extern.
+
+Chang Log:
+- Split this patch from v4's patch 1 (Shuah).
+
+Reported-by: Reinette Chatre <reinette.chatre@intel.com>
+Tested-by: Babu Moger <babu.moger@amd.com>
+Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/resctrl/resctrl.h | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/tools/testing/selftests/resctrl/resctrl.h b/tools/testing/selftests/resctrl/resctrl.h
+index 959c71e39bdc..12b77182cb44 100644
+--- a/tools/testing/selftests/resctrl/resctrl.h
++++ b/tools/testing/selftests/resctrl/resctrl.h
+@@ -62,11 +62,11 @@ struct resctrl_val_param {
+       int             (*setup)(int num, ...);
+ };
+-pid_t bm_pid, ppid;
+-int tests_run;
++extern pid_t bm_pid, ppid;
++extern int tests_run;
+-char llc_occup_path[1024];
+-bool is_amd;
++extern char llc_occup_path[1024];
++extern bool is_amd;
+ bool check_resctrlfs_support(void);
+ int filter_dmesg(void);
+-- 
+2.30.2
+
diff --git a/queue-5.12/selftests-resctrl-fix-incorrect-parsing-of-imc-count.patch b/queue-5.12/selftests-resctrl-fix-incorrect-parsing-of-imc-count.patch
new file mode 100644 (file)
index 0000000..2a7c8e8
--- /dev/null
@@ -0,0 +1,79 @@
+From d303ce8ec2ecf44fc93ff4a0b503d4d27c394bbe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Mar 2021 02:22:53 +0000
+Subject: selftests/resctrl: Fix incorrect parsing of iMC counters
+
+From: Fenghua Yu <fenghua.yu@intel.com>
+
+[ Upstream commit d81343b5eedf84be71a4313e8fd073d0c510afcf ]
+
+iMC (Integrated Memory Controller) counters are usually at
+"/sys/bus/event_source/devices/" and are named as "uncore_imc_<n>".
+num_of_imcs() function tries to count number of such iMC counters so that
+it could appropriately initialize required number of perf_attr structures
+that could be used to read these iMC counters.
+
+num_of_imcs() function assumes that all the directories under this path
+that start with "uncore_imc" are iMC counters. But, on some systems there
+could be directories named as "uncore_imc_free_running" which aren't iMC
+counters. Trying to read from such directories will result in "not found
+file" errors and MBM/MBA tests will fail.
+
+Hence, fix the logic in num_of_imcs() such that it looks at the first
+character after "uncore_imc_" to check if it's a numerical digit or not. If
+it's a digit then the directory represents an iMC counter, else, skip the
+directory.
+
+Reported-by: Reinette Chatre <reinette.chatre@intel.com>
+Tested-by: Babu Moger <babu.moger@amd.com>
+Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/resctrl/resctrl_val.c | 22 +++++++++++++++++--
+ 1 file changed, 20 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/resctrl/resctrl_val.c b/tools/testing/selftests/resctrl/resctrl_val.c
+index aed71fd0713b..5478c23c62ba 100644
+--- a/tools/testing/selftests/resctrl/resctrl_val.c
++++ b/tools/testing/selftests/resctrl/resctrl_val.c
+@@ -221,8 +221,8 @@ static int read_from_imc_dir(char *imc_dir, int count)
+  */
+ static int num_of_imcs(void)
+ {
++      char imc_dir[512], *temp;
+       unsigned int count = 0;
+-      char imc_dir[512];
+       struct dirent *ep;
+       int ret;
+       DIR *dp;
+@@ -230,7 +230,25 @@ static int num_of_imcs(void)
+       dp = opendir(DYN_PMU_PATH);
+       if (dp) {
+               while ((ep = readdir(dp))) {
+-                      if (strstr(ep->d_name, UNCORE_IMC)) {
++                      temp = strstr(ep->d_name, UNCORE_IMC);
++                      if (!temp)
++                              continue;
++
++                      /*
++                       * imc counters are named as "uncore_imc_<n>", hence
++                       * increment the pointer to point to <n>. Note that
++                       * sizeof(UNCORE_IMC) would count for null character as
++                       * well and hence the last underscore character in
++                       * uncore_imc'_' need not be counted.
++                       */
++                      temp = temp + sizeof(UNCORE_IMC);
++
++                      /*
++                       * Some directories under "DYN_PMU_PATH" could have
++                       * names like "uncore_imc_free_running", hence, check if
++                       * first character is a numerical digit or not.
++                       */
++                      if (temp[0] >= '0' && temp[0] <= '9') {
+                               sprintf(imc_dir, "%s/%s/", DYN_PMU_PATH,
+                                       ep->d_name);
+                               ret = read_from_imc_dir(imc_dir, count);
+-- 
+2.30.2
+
diff --git a/queue-5.12/selftests-resctrl-fix-missing-options-n-and-p.patch b/queue-5.12/selftests-resctrl-fix-missing-options-n-and-p.patch
new file mode 100644 (file)
index 0000000..62a1646
--- /dev/null
@@ -0,0 +1,44 @@
+From 8b49b11af4e8851ed1d0bbeec537b6637257a705 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Mar 2021 02:22:40 +0000
+Subject: selftests/resctrl: Fix missing options "-n" and "-p"
+
+From: Fenghua Yu <fenghua.yu@intel.com>
+
+[ Upstream commit d7af3d0d515cbdf63b6c3398a3c15ecb1bc2bd38 ]
+
+resctrl test suite accepts command line arguments (like -b, -t, -n and -p)
+as documented in the help. But passing -n and -p throws an invalid option
+error. This happens because -n and -p are missing in the list of
+characters that getopt() recognizes as valid arguments. Hence, they are
+treated as invalid options.
+
+Fix this by adding them to the list of characters that getopt() recognizes
+as valid arguments. Please note that the main() function already has the
+logic to deal with the values passed as part of these arguments and hence
+no changes are needed there.
+
+Tested-by: Babu Moger <babu.moger@amd.com>
+Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/resctrl/resctrl_tests.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/resctrl/resctrl_tests.c b/tools/testing/selftests/resctrl/resctrl_tests.c
+index 4b109a59f72d..ac2269610aa9 100644
+--- a/tools/testing/selftests/resctrl/resctrl_tests.c
++++ b/tools/testing/selftests/resctrl/resctrl_tests.c
+@@ -73,7 +73,7 @@ int main(int argc, char **argv)
+               }
+       }
+-      while ((c = getopt(argc_new, argv, "ht:b:")) != -1) {
++      while ((c = getopt(argc_new, argv, "ht:b:n:p:")) != -1) {
+               char *token;
+               switch (c) {
+-- 
+2.30.2
+
diff --git a/queue-5.12/selftests-resctrl-use-resctrl-info-for-feature-detec.patch b/queue-5.12/selftests-resctrl-use-resctrl-info-for-feature-detec.patch
new file mode 100644 (file)
index 0000000..89e94f0
--- /dev/null
@@ -0,0 +1,157 @@
+From 27ac4808173b908c69ddf7f03e86cbde06313195 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Mar 2021 02:22:47 +0000
+Subject: selftests/resctrl: Use resctrl/info for feature detection
+
+From: Fenghua Yu <fenghua.yu@intel.com>
+
+[ Upstream commit ee0415681eb661efa1eb2db7acc263f2c7df1e23 ]
+
+Resctrl test suite before running any unit test (like cmt, cat, mbm and
+mba) should first check if the feature is enabled (by kernel and not just
+supported by H/W) on the platform or not.
+validate_resctrl_feature_request() is supposed to do that. This function
+intends to grep for relevant flags in /proc/cpuinfo but there are several
+issues here
+
+1. validate_resctrl_feature_request() calls fgrep() to get flags from
+   /proc/cpuinfo. But, fgrep() can only return a string with maximum of 255
+   characters and hence the complete cpu flags are never returned.
+2. The substring search logic is also busted. If strstr() finds requested
+   resctrl feature in the cpu flags, it returns pointer to the first
+   occurrence. But, the logic negates the return value of strstr() and
+   hence validate_resctrl_feature_request() returns false if the feature is
+   present in the cpu flags and returns true if the feature is not present.
+3. validate_resctrl_feature_request() checks if a resctrl feature is
+   reported in /proc/cpuinfo flags or not. Having a cpu flag means that the
+   H/W supports the feature, but it doesn't mean that the kernel enabled
+   it. A user could selectively enable only a subset of resctrl features
+   using kernel command line arguments. Hence, /proc/cpuinfo isn't a
+   reliable source to check if a feature is enabled or not.
+
+The 3rd issue being the major one and fixing it requires changing the way
+validate_resctrl_feature_request() works. Since, /proc/cpuinfo isn't the
+right place to check if a resctrl feature is enabled or not, a more
+appropriate place is /sys/fs/resctrl/info directory. Change
+validate_resctrl_feature_request() such that,
+
+1. For cat, check if /sys/fs/resctrl/info/L3 directory is present or not
+2. For mba, check if /sys/fs/resctrl/info/MB directory is present or not
+3. For cmt, check if /sys/fs/resctrl/info/L3_MON directory is present and
+   check if /sys/fs/resctrl/info/L3_MON/mon_features has llc_occupancy
+4. For mbm, check if /sys/fs/resctrl/info/L3_MON directory is present and
+   check if /sys/fs/resctrl/info/L3_MON/mon_features has
+   mbm_<total/local>_bytes
+
+Please note that only L3_CAT, L3_CMT, MBA and MBM are supported. CDP and L2
+variants can be added later.
+
+Reported-by: Reinette Chatre <reinette.chatre@intel.com>
+Tested-by: Babu Moger <babu.moger@amd.com>
+Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/resctrl/resctrl.h   |  6 ++-
+ tools/testing/selftests/resctrl/resctrlfs.c | 52 ++++++++++++++++-----
+ 2 files changed, 46 insertions(+), 12 deletions(-)
+
+diff --git a/tools/testing/selftests/resctrl/resctrl.h b/tools/testing/selftests/resctrl/resctrl.h
+index 36da6136af96..9dcc96e1ad3d 100644
+--- a/tools/testing/selftests/resctrl/resctrl.h
++++ b/tools/testing/selftests/resctrl/resctrl.h
+@@ -28,6 +28,10 @@
+ #define RESCTRL_PATH          "/sys/fs/resctrl"
+ #define PHYS_ID_PATH          "/sys/devices/system/cpu/cpu"
+ #define CBM_MASK_PATH         "/sys/fs/resctrl/info"
++#define L3_PATH                       "/sys/fs/resctrl/info/L3"
++#define MB_PATH                       "/sys/fs/resctrl/info/MB"
++#define L3_MON_PATH           "/sys/fs/resctrl/info/L3_MON"
++#define L3_MON_FEATURES_PATH  "/sys/fs/resctrl/info/L3_MON/mon_features"
+ #define PARENT_EXIT(err_msg)                  \
+       do {                                    \
+@@ -79,7 +83,7 @@ int remount_resctrlfs(bool mum_resctrlfs);
+ int get_resource_id(int cpu_no, int *resource_id);
+ int umount_resctrlfs(void);
+ int validate_bw_report_request(char *bw_report);
+-bool validate_resctrl_feature_request(char *resctrl_val);
++bool validate_resctrl_feature_request(const char *resctrl_val);
+ char *fgrep(FILE *inf, const char *str);
+ int taskset_benchmark(pid_t bm_pid, int cpu_no);
+ void run_benchmark(int signum, siginfo_t *info, void *ucontext);
+diff --git a/tools/testing/selftests/resctrl/resctrlfs.c b/tools/testing/selftests/resctrl/resctrlfs.c
+index 4174e48e06d1..b57170f53861 100644
+--- a/tools/testing/selftests/resctrl/resctrlfs.c
++++ b/tools/testing/selftests/resctrl/resctrlfs.c
+@@ -616,26 +616,56 @@ char *fgrep(FILE *inf, const char *str)
+  * validate_resctrl_feature_request - Check if requested feature is valid.
+  * @resctrl_val:      Requested feature
+  *
+- * Return: 0 on success, non-zero on failure
++ * Return: True if the feature is supported, else false
+  */
+-bool validate_resctrl_feature_request(char *resctrl_val)
++bool validate_resctrl_feature_request(const char *resctrl_val)
+ {
+-      FILE *inf = fopen("/proc/cpuinfo", "r");
++      struct stat statbuf;
+       bool found = false;
+       char *res;
++      FILE *inf;
+-      if (!inf)
++      if (!resctrl_val)
+               return false;
+-      res = fgrep(inf, "flags");
+-
+-      if (res) {
+-              char *s = strchr(res, ':');
++      if (remount_resctrlfs(false))
++              return false;
+-              found = s && !strstr(s, resctrl_val);
+-              free(res);
++      if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR))) {
++              if (!stat(L3_PATH, &statbuf))
++                      return true;
++      } else if (!strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR))) {
++              if (!stat(MB_PATH, &statbuf))
++                      return true;
++      } else if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)) ||
++                 !strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR))) {
++              if (!stat(L3_MON_PATH, &statbuf)) {
++                      inf = fopen(L3_MON_FEATURES_PATH, "r");
++                      if (!inf)
++                              return false;
++
++                      if (!strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR))) {
++                              res = fgrep(inf, "llc_occupancy");
++                              if (res) {
++                                      found = true;
++                                      free(res);
++                              }
++                      }
++
++                      if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR))) {
++                              res = fgrep(inf, "mbm_total_bytes");
++                              if (res) {
++                                      free(res);
++                                      res = fgrep(inf, "mbm_local_bytes");
++                                      if (res) {
++                                              found = true;
++                                              free(res);
++                                      }
++                              }
++                      }
++                      fclose(inf);
++              }
+       }
+-      fclose(inf);
+       return found;
+ }
+-- 
+2.30.2
+
index 5a4f12977c1591bfe7b208c07702ddc4a2bdba23..de334f02159fef2a4e6c40e0530ce968415d37e0 100644 (file)
@@ -65,3 +65,209 @@ btrfs-zoned-fail-mount-if-the-device-does-not-support-zone-append.patch
 posix-timers-preserve-return-value-in-clock_adjtime32.patch
 fbdev-zero-fill-colormap-in-fbcmap.c.patch
 cpuidle-tegra-fix-c7-idling-state-on-tegra114.patch
+bus-ti-sysc-probe-for-l4_wkup-and-l4_cfg-interconnec.patch
+staging-wimax-i2400m-fix-byte-order-issue.patch
+spi-ath79-always-call-chipselect-function.patch
+spi-ath79-remove-spi-master-setup-and-cleanup-assign.patch
+bus-mhi-pci_generic-no-op-for-device_wake-operations.patch
+bus-mhi-core-destroy-sbl-devices-when-moving-to-miss.patch
+bus-mhi-core-process-execution-environment-changes-s.patch
+crypto-api-check-for-err-pointers-in-crypto_destroy_.patch
+crypto-qat-fix-unmap-invalid-dma-address.patch
+usb-gadget-uvc-add-binterval-checking-for-hs-mode.patch
+usb-webcam-invalid-size-of-processing-unit-descripto.patch
+x86-sev-do-not-require-hypervisor-cpuid-bit-for-sev-.patch
+x86-boot-compressed-64-check-sev-encryption-in-the-3.patch
+crypto-hisilicon-sec-fixes-a-printing-error.patch
+genirq-matrix-prevent-allocation-counter-corruption.patch
+usb-gadget-f_uac2-validate-input-parameters.patch
+usb-gadget-f_uac1-validate-input-parameters.patch
+usb-dwc3-gadget-ignore-ep-queue-requests-during-bus-.patch
+usb-xhci-fix-port-minor-revision.patch
+kselftest-arm64-mte-fix-compilation-with-native-comp.patch
+arm-tegra-acer-a500-rename-avdd-to-vdda-of-touchscre.patch
+pci-pm-do-not-read-power-state-in-pci_enable_device_.patch
+kselftest-arm64-mte-fix-mte-feature-detection.patch
+arm-dts-bcm5301x-fix-reg-formatting-in-memory-node.patch
+arm-dts-ux500-fix-up-tvk-r3-sensors.patch
+x86-build-propagate-clang_flags-to-realmode_flags.patch
+x86-boot-add-clang_flags-to-compressed-kbuild_cflags.patch
+efi-libstub-add-clang_flags-to-x86-flags.patch
+soc-tegra-pmc-fix-completion-of-power-gate-toggling.patch
+arm64-dts-imx8mq-librem5-r3-mark-buck3-as-always-on.patch
+tee-optee-do-not-check-memref-size-on-return-from-se.patch
+soundwire-cadence-only-prepare-attached-devices-on-c.patch
+perf-arm_pmu_platform-use-dev_err_probe-for-irq-erro.patch
+perf-arm_pmu_platform-fix-error-handling.patch
+random-initialize-chacha20-constants-with-correct-en.patch
+usb-xhci-mtk-support-quirk-to-disable-usb2-lpm.patch
+fpga-dfl-pci-add-did-for-d5005-pac-cards.patch
+xhci-check-port-array-allocation-was-successful-befo.patch
+xhci-check-control-context-is-valid-before-dereferen.patch
+xhci-fix-potential-array-out-of-bounds-with-several-.patch
+xhci-prevent-double-fetch-of-transfer-and-transfer-e.patch
+bus-mhi-core-clear-context-for-stopped-channels-from.patch
+bus-mhi-pci_generic-implement-pci-shutdown-callback.patch
+arm-dts-at91-change-the-key-code-of-the-gpio-key.patch
+tools-power-x86-intel-speed-select-increase-string-s.patch
+platform-x86-isst-account-for-increased-timeout-in-s.patch
+clocksource-drivers-dw_apb_timer_of-add-handling-for.patch
+resource-prevent-irqresource_disabled-from-erasing-f.patch
+spi-dln2-fix-reference-leak-to-master.patch
+spi-omap-100k-fix-reference-leak-to-master.patch
+spi-qup-fix-pm-reference-leak-in-spi_qup_remove.patch
+usb-dwc3-pci-add-support-for-the-intel-alder-lake-m.patch
+usb-gadget-tegra-xudc-fix-possible-use-after-free-in.patch
+usb-musb-fix-pm-reference-leak-in-musb_irq_work.patch
+usb-core-hub-fix-pm-reference-leak-in-usb_port_resum.patch
+usb-dwc3-gadget-check-for-disabled-lpm-quirk.patch
+tty-n_gsm-check-error-while-registering-tty-devices.patch
+intel_th-consistency-and-off-by-one-fix.patch
+phy-phy-twl4030-usb-fix-possible-use-after-free-in-t.patch
+crypto-sun4i-ss-fix-pm-reference-leak-when-pm_runtim.patch
+crypto-sun8i-ss-fix-pm-reference-leak-when-pm_runtim.patch
+crypto-sun8i-ce-fix-pm-reference-leak-in-sun8i_ce_pr.patch
+crypto-stm32-hash-fix-pm-reference-leak-on-stm32-has.patch
+crypto-stm32-cryp-fix-pm-reference-leak-on-stm32-cry.patch
+crypto-sa2ul-fix-pm-reference-leak-in-sa_ul_probe.patch
+crypto-omap-aes-fix-pm-reference-leak-on-omap-aes.c.patch
+platform-x86-intel_pmc_core-don-t-use-global-pmcdev-.patch
+spi-sync-up-initial-chipselect-state.patch
+btrfs-use-btrfs_inode_lock-btrfs_inode_unlock-inode-.patch
+btrfs-fix-race-between-marking-inode-needs-to-be-log.patch
+btrfs-fix-exhaustion-of-the-system-chunk-array-due-t.patch
+btrfs-do-proper-error-handling-in-create_reloc_root.patch
+btrfs-do-proper-error-handling-in-btrfs_update_reloc.patch
+btrfs-convert-logic-bug_on-s-in-replace_path-to-asse.patch
+regulator-da9121-automotive-variants-identity-fix.patch
+drm-added-orientation-quirk-for-onegx1-pro.patch
+drm-qxl-do-not-run-release-if-qxl-failed-to-init.patch
+drm-qxl-release-shadow-on-shutdown.patch
+drm-ast-fix-invalid-usage-of-ast_max_hwc_width-in-cu.patch
+drm-amd-display-changing-sr-exit-latency.patch
+drm-amd-display-fix-mpc-ogam-power-on-off-sequence.patch
+drm-amd-pm-do-not-issue-message-while-write-r-into-p.patch
+drm-ast-fix-memory-leak-when-unload-the-driver.patch
+drm-amd-display-check-for-dsc-support-instead-of-asi.patch
+drm-amd-display-don-t-optimize-bandwidth-before-disa.patch
+drm-amd-display-return-invalid-state-if-gpint-times-.patch
+drm-amdgpu-display-buffer-interrupt_low_irq_context-.patch
+drm-amd-display-dc-dce-dce_aux-remove-duplicate-line.patch
+scsi-lpfc-fix-incorrect-dbde-assignment-when-buildin.patch
+scsi-lpfc-fix-pt2pt-connection-does-not-recover-afte.patch
+scsi-lpfc-fix-status-returned-in-lpfc_els_retry-erro.patch
+scsi-lpfc-fix-plogi-acc-to-be-transmit-after-reg_log.patch
+scsi-lpfc-fix-adisc-handling-that-never-frees-nodes.patch
+drm-amd-pm-swsmu-clean-up-user-profile-function.patch
+drm-amdgpu-fix-some-unload-driver-issues.patch
+sched-fair-fix-task-utilization-accountability-in-co.patch
+sched-pelt-fix-task-util_est-update-filtering.patch
+sched-topology-fix-the-issue-groups-don-t-span-domai.patch
+kvfree_rcu-use-same-set-of-gfp-flags-as-does-single-.patch
+drm-virtio-fix-possible-leak-unlock-virtio_gpu_objec.patch
+scsi-target-pscsi-fix-warning-in-pscsi_complete_cmd.patch
+media-ite-cir-check-for-receive-overflow.patch
+media-drivers-media-pci-sta2x11-fix-kconfig-dependen.patch
+media-drivers-media-usb-fix-memory-leak-in-zr364xx_p.patch
+media-cx23885-add-more-quirks-for-reset-dma-on-some-.patch
+media-imx-capture-return-epipe-from-__capture_legacy.patch
+atomisp-don-t-let-it-go-past-pipes-array.patch
+power-supply-bq27xxx-fix-power_avg-for-newer-ics.patch
+extcon-arizona-fix-some-issues-when-hpdet-irq-fires-.patch
+extcon-arizona-fix-various-races-on-driver-unbind.patch
+media-venus-core-venc-vdec-fix-probe-dependency-erro.patch
+s390-qdio-let-driver-manage-the-qaob.patch
+media-media-saa7164-fix-saa7164_encoder_register-mem.patch
+media-gspca-sq905.c-fix-uninitialized-variable.patch
+media-v4l2-ctrls.c-initialize-flags-field-of-p_fwht_.patch
+power-supply-use-irqf_oneshot.patch
+backlight-qcom-wled-use-sink_addr-for-sync-toggle.patch
+backlight-qcom-wled-fix-fsc-update-issue-for-wled5.patch
+drm-amdgpu-enable-retry-fault-wptr-overflow.patch
+drm-amdgpu-enable-48-bit-ih-timestamp-counter.patch
+drm-amdgpu-mask-the-xgmi-number-of-hops-reported-fro.patch
+drm-amdkfd-fix-ubsan-shift-out-of-bounds-warning.patch
+drm-amd-display-align-cursor-cache-address-to-2kb.patch
+drm-amdgpu-fix-asic-reset-regression-issue-introduce.patch
+drm-amd-pm-fix-workload-mismatch-on-vega10.patch
+drm-amd-display-fix-ubsan-warning-for-not-a-valid-va.patch
+drm-amd-display-dchub-underflow-counter-increasing-i.patch
+drm-amd-display-fix-dml-prefetch-validation.patch
+drm-amd-display-fix-potential-memory-leak.patch
+drm-amdgpu-fix-memory-leak.patch
+scsi-qla2xxx-always-check-the-return-value-of-qla24x.patch
+drm-vkms-fix-misuse-of-warn_on.patch
+block-bfq-fix-weight-raising-resume-with-low_latency.patch
+scsi-qla2xxx-fix-use-after-free-in-bsg.patch
+mmc-sdhci-esdhc-imx-validate-pinctrl-before-use-it.patch
+mmc-sdhci-pci-add-pci-ids-for-intel-lkf.patch
+mmc-sdhci-brcmstb-remove-cqe-quirk.patch
+ata-ahci-disable-sxs-for-hisilicon-kunpeng920.patch
+drm-komeda-fix-bit-check-to-import-to-value-of-prope.patch
+nvmet-return-proper-error-code-from-discovery-ctrl.patch
+selftests-resctrl-enable-gcc-checks-to-detect-buffer.patch
+selftests-resctrl-fix-compilation-issues-for-global-.patch
+selftests-resctrl-fix-compilation-issues-for-other-g.patch
+selftests-resctrl-clean-up-resctrl-features-check.patch
+selftests-resctrl-fix-missing-options-n-and-p.patch
+selftests-resctrl-use-resctrl-info-for-feature-detec.patch
+selftests-resctrl-fix-incorrect-parsing-of-imc-count.patch
+selftests-resctrl-fix-checking-for-0-for-unsigned-va.patch
+power-supply-cpcap-charger-fix-small-mistake-in-curr.patch
+power-supply-cpcap-charger-add-usleep-to-cpcap-charg.patch
+s390-pci-expose-uid-uniqueness-guarantee.patch
+scsi-smartpqi-use-host-wide-tag-space.patch
+scsi-smartpqi-correct-request-leakage-during-reset-o.patch
+scsi-smartpqi-add-new-pci-ids.patch
+scsi-scsi_dh_alua-remove-check-for-asc-24h-in-alua_r.patch
+media-em28xx-fix-memory-leak.patch
+media-vivid-update-edid.patch
+media-uvcvideo-fix-xu-id-print-in-forward-scan.patch
+media-uvcvideo-support-devices-that-report-an-ot-as-.patch
+drm-msm-a6xx-fix-perfcounter-oob-timeout.patch
+drm-msm-dp-fix-incorrect-null-check-kbot-warnings-in.patch
+clk-socfpga-arria10-fix-memory-leak-of-socfpga_clk-o.patch
+power-supply-generic-adc-battery-fix-possible-use-af.patch
+power-supply-s3c_adc_battery-fix-possible-use-after-.patch
+media-tc358743-fix-possible-use-after-free-in-tc3587.patch
+media-adv7604-fix-possible-use-after-free-in-adv76xx.patch
+media-i2c-adv7511-v4l2-fix-possible-use-after-free-i.patch
+media-i2c-tda1997-fix-possible-use-after-free-in-tda.patch
+media-i2c-adv7842-fix-possible-use-after-free-in-adv.patch
+media-platform-sti-fix-runtime-pm-imbalance-in-regs_.patch
+media-sun8i-di-fix-runtime-pm-imbalance-in-deinterla.patch
+media-dvb-usb-fix-memory-leak-in-dvb_usb_adapter_ini.patch
+media-gscpa-stv06xx-fix-memory-leak.patch
+sched-fair-bring-back-select_idle_smt-but-differentl.patch
+sched-fair-ignore-percpu-threads-for-imbalance-pulls.patch
+drm-msm-mdp5-configure-pp_sync_height-to-double-the-.patch
+drm-msm-mdp5-do-not-multiply-vclk-line-count-by-100.patch
+drm-amdgpu-ttm-fix-memory-leak-userptr-pages.patch
+drm-radeon-ttm-fix-memory-leak-userptr-pages.patch
+drm-amd-display-fix-debugfs-link_settings-entry.patch
+drm-amd-display-fix-ubsan-shift-out-of-bounds-warnin.patch
+drm-radeon-don-t-evict-if-not-initialized.patch
+drm-amdkfd-fix-cat-debugfs-hang_hws-file-causes-syst.patch
+amdgpu-avoid-incorrect-hu-format-string.patch
+drm-amdgpu-display-fix-memory-leak-for-dimgrey-cavef.patch
+drm-amd-display-try-ycbcr420-color-when-ycbcr444-fai.patch
+drm-amdgpu-fix-null-pointer-dereference.patch
+drm-amd-display-update-dcn302-sr-exit-latency.patch
+scsi-mpt3sas-fix-out-of-bounds-warnings-in-_ctl_addn.patch
+scsi-lpfc-fix-crash-when-a-reg_rpi-mailbox-fails-tri.patch
+scsi-lpfc-fix-reference-counting-errors-in-lpfc_cmpl.patch
+scsi-lpfc-fix-error-handling-for-mailboxes-completed.patch
+scsi-lpfc-remove-unsupported-mbox-port_capabilities-.patch
+mfd-intel-m10-bmc-fix-the-register-access-range.patch
+mfd-da9063-support-smbus-and-i2c-mode.patch
+mfd-arizona-fix-rumtime-pm-imbalance-on-error.patch
+scsi-libfc-fix-a-format-specifier.patch
+perf-rework-perf_event_exit_event.patch
+sched-fair-alternative-sched_slice.patch
+block-rnbd-srv-prevent-a-deadlock-generated-by-acces.patch
+block-rnbd-clt-fix-missing-a-memory-free-when-unload.patch
+io_uring-safer-sq_creds-putting.patch
+s390-archrandom-add-parameter-check-for-s390_arch_ra.patch
+sched-psi-handle-potential-task-count-underflow-bugs.patch
+nvmet-avoid-queuing-keep-alive-timer-if-it-is-disabl.patch
+power-supply-cpcap-battery-fix-invalid-usage-of-list.patch
diff --git a/queue-5.12/soc-tegra-pmc-fix-completion-of-power-gate-toggling.patch b/queue-5.12/soc-tegra-pmc-fix-completion-of-power-gate-toggling.patch
new file mode 100644 (file)
index 0000000..990cef8
--- /dev/null
@@ -0,0 +1,177 @@
+From 260f4ce2c9e736fda79d6f7096c109cda3d9b352 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Mar 2021 15:24:59 +0300
+Subject: soc/tegra: pmc: Fix completion of power-gate toggling
+
+From: Dmitry Osipenko <digetx@gmail.com>
+
+[ Upstream commit c45e66a6b9f40f2e95bc6d97fbf3daa1ebe88c6b ]
+
+The SW-initiated power gate toggling is dropped by PMC if there is
+contention with a HW-initiated toggling, i.e. when one of CPU cores is
+gated by cpuidle driver. Software should retry the toggling after 10
+microseconds on Tegra20/30 SoCs, hence add the retrying. On Tegra114+ the
+toggling method was changed in hardware, the TOGGLE_START bit indicates
+whether PMC is busy or could accept the command to toggle, hence handle
+that bit properly.
+
+The problem pops up after enabling dynamic power gating of 3D hardware,
+where 3D power domain fails to turn on/off "randomly".
+
+The programming sequence and quirks are documented in TRMs, but PMC
+driver obliviously re-used the Tegra20 logic for Tegra30+, which strikes
+back now. The 10 microseconds and other timeouts aren't documented in TRM,
+they are taken from downstream kernel.
+
+Link: https://nv-tegra.nvidia.com/gitweb/?p=linux-2.6.git;a=commit;h=311dd1c318b70e93bcefec15456a10ff2b9eb0ff
+Link: https://nv-tegra.nvidia.com/gitweb/?p=linux-3.10.git;a=commit;h=7f36693c47cb23730a6b2822e0975be65fb0c51d
+Tested-by: Peter Geis <pgwipeout@gmail.com> # Ouya T30
+Tested-by: Nicolas Chauvet <kwizart@gmail.com> # PAZ00 T20 and TK1 T124
+Tested-by: Matt Merhar <mattmerhar@protonmail.com> # Ouya T30
+Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/tegra/pmc.c | 70 ++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 65 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
+index df9a5ca8c99c..0118bd986f90 100644
+--- a/drivers/soc/tegra/pmc.c
++++ b/drivers/soc/tegra/pmc.c
+@@ -317,6 +317,8 @@ struct tegra_pmc_soc {
+                                  bool invert);
+       int (*irq_set_wake)(struct irq_data *data, unsigned int on);
+       int (*irq_set_type)(struct irq_data *data, unsigned int type);
++      int (*powergate_set)(struct tegra_pmc *pmc, unsigned int id,
++                           bool new_state);
+       const char * const *reset_sources;
+       unsigned int num_reset_sources;
+@@ -517,6 +519,63 @@ static int tegra_powergate_lookup(struct tegra_pmc *pmc, const char *name)
+       return -ENODEV;
+ }
++static int tegra20_powergate_set(struct tegra_pmc *pmc, unsigned int id,
++                               bool new_state)
++{
++      unsigned int retries = 100;
++      bool status;
++      int ret;
++
++      /*
++       * As per TRM documentation, the toggle command will be dropped by PMC
++       * if there is contention with a HW-initiated toggling (i.e. CPU core
++       * power-gated), the command should be retried in that case.
++       */
++      do {
++              tegra_pmc_writel(pmc, PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE);
++
++              /* wait for PMC to execute the command */
++              ret = readx_poll_timeout(tegra_powergate_state, id, status,
++                                       status == new_state, 1, 10);
++      } while (ret == -ETIMEDOUT && retries--);
++
++      return ret;
++}
++
++static inline bool tegra_powergate_toggle_ready(struct tegra_pmc *pmc)
++{
++      return !(tegra_pmc_readl(pmc, PWRGATE_TOGGLE) & PWRGATE_TOGGLE_START);
++}
++
++static int tegra114_powergate_set(struct tegra_pmc *pmc, unsigned int id,
++                                bool new_state)
++{
++      bool status;
++      int err;
++
++      /* wait while PMC power gating is contended */
++      err = readx_poll_timeout(tegra_powergate_toggle_ready, pmc, status,
++                               status == true, 1, 100);
++      if (err)
++              return err;
++
++      tegra_pmc_writel(pmc, PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE);
++
++      /* wait for PMC to accept the command */
++      err = readx_poll_timeout(tegra_powergate_toggle_ready, pmc, status,
++                               status == true, 1, 100);
++      if (err)
++              return err;
++
++      /* wait for PMC to execute the command */
++      err = readx_poll_timeout(tegra_powergate_state, id, status,
++                               status == new_state, 10, 100000);
++      if (err)
++              return err;
++
++      return 0;
++}
++
+ /**
+  * tegra_powergate_set() - set the state of a partition
+  * @pmc: power management controller
+@@ -526,7 +585,6 @@ static int tegra_powergate_lookup(struct tegra_pmc *pmc, const char *name)
+ static int tegra_powergate_set(struct tegra_pmc *pmc, unsigned int id,
+                              bool new_state)
+ {
+-      bool status;
+       int err;
+       if (id == TEGRA_POWERGATE_3D && pmc->soc->has_gpu_clamps)
+@@ -539,10 +597,7 @@ static int tegra_powergate_set(struct tegra_pmc *pmc, unsigned int id,
+               return 0;
+       }
+-      tegra_pmc_writel(pmc, PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE);
+-
+-      err = readx_poll_timeout(tegra_powergate_state, id, status,
+-                               status == new_state, 10, 100000);
++      err = pmc->soc->powergate_set(pmc, id, new_state);
+       mutex_unlock(&pmc->powergates_lock);
+@@ -2699,6 +2754,7 @@ static const struct tegra_pmc_soc tegra20_pmc_soc = {
+       .regs = &tegra20_pmc_regs,
+       .init = tegra20_pmc_init,
+       .setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
++      .powergate_set = tegra20_powergate_set,
+       .reset_sources = NULL,
+       .num_reset_sources = 0,
+       .reset_levels = NULL,
+@@ -2757,6 +2813,7 @@ static const struct tegra_pmc_soc tegra30_pmc_soc = {
+       .regs = &tegra20_pmc_regs,
+       .init = tegra20_pmc_init,
+       .setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
++      .powergate_set = tegra20_powergate_set,
+       .reset_sources = tegra30_reset_sources,
+       .num_reset_sources = ARRAY_SIZE(tegra30_reset_sources),
+       .reset_levels = NULL,
+@@ -2811,6 +2868,7 @@ static const struct tegra_pmc_soc tegra114_pmc_soc = {
+       .regs = &tegra20_pmc_regs,
+       .init = tegra20_pmc_init,
+       .setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
++      .powergate_set = tegra114_powergate_set,
+       .reset_sources = tegra30_reset_sources,
+       .num_reset_sources = ARRAY_SIZE(tegra30_reset_sources),
+       .reset_levels = NULL,
+@@ -2925,6 +2983,7 @@ static const struct tegra_pmc_soc tegra124_pmc_soc = {
+       .regs = &tegra20_pmc_regs,
+       .init = tegra20_pmc_init,
+       .setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
++      .powergate_set = tegra114_powergate_set,
+       .reset_sources = tegra30_reset_sources,
+       .num_reset_sources = ARRAY_SIZE(tegra30_reset_sources),
+       .reset_levels = NULL,
+@@ -3048,6 +3107,7 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = {
+       .regs = &tegra20_pmc_regs,
+       .init = tegra20_pmc_init,
+       .setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
++      .powergate_set = tegra114_powergate_set,
+       .irq_set_wake = tegra210_pmc_irq_set_wake,
+       .irq_set_type = tegra210_pmc_irq_set_type,
+       .reset_sources = tegra210_reset_sources,
+-- 
+2.30.2
+
diff --git a/queue-5.12/soundwire-cadence-only-prepare-attached-devices-on-c.patch b/queue-5.12/soundwire-cadence-only-prepare-attached-devices-on-c.patch
new file mode 100644 (file)
index 0000000..86a327e
--- /dev/null
@@ -0,0 +1,58 @@
+From d00248a1d7fa663f848998ce5d7f717cff9f7b21 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Mar 2021 09:37:07 +0800
+Subject: soundwire: cadence: only prepare attached devices on clock stop
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit 58ef9356260c291a4321e07ff507f31a1d8212af ]
+
+We sometimes see COMMAND_IGNORED responses during the clock stop
+sequence. It turns out we already have information if devices are
+present on a link, so we should only prepare those when they
+are attached.
+
+In addition, even when COMMAND_IGNORED are received, we should still
+proceed with the clock stop. The device will not be prepared but
+that's not a problem.
+
+The only case where the clock stop will fail is if the Cadence IP
+reports an error (including a timeout), or if the devices throw a
+COMMAND_FAILED response.
+
+BugLink: https://github.com/thesofproject/linux/issues/2621
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Rander Wang <rander.wang@intel.com>
+Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
+Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Link: https://lore.kernel.org/r/20210323013707.21455-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/cadence_master.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
+index d05442e646a3..57c59a33ce61 100644
+--- a/drivers/soundwire/cadence_master.c
++++ b/drivers/soundwire/cadence_master.c
+@@ -1450,10 +1450,12 @@ int sdw_cdns_clock_stop(struct sdw_cdns *cdns, bool block_wake)
+       }
+       /* Prepare slaves for clock stop */
+-      ret = sdw_bus_prep_clk_stop(&cdns->bus);
+-      if (ret < 0) {
+-              dev_err(cdns->dev, "prepare clock stop failed %d", ret);
+-              return ret;
++      if (slave_present) {
++              ret = sdw_bus_prep_clk_stop(&cdns->bus);
++              if (ret < 0 && ret != -ENODATA) {
++                      dev_err(cdns->dev, "prepare clock stop failed %d\n", ret);
++                      return ret;
++              }
+       }
+       /*
+-- 
+2.30.2
+
diff --git a/queue-5.12/spi-ath79-always-call-chipselect-function.patch b/queue-5.12/spi-ath79-always-call-chipselect-function.patch
new file mode 100644 (file)
index 0000000..4367890
--- /dev/null
@@ -0,0 +1,39 @@
+From 5c2cff59e0e9d1f4568e72d8ab062e63bc312e1b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Mar 2021 17:08:36 +0100
+Subject: spi: ath79: always call chipselect function
+
+From: David Bauer <mail@david-bauer.net>
+
+[ Upstream commit 19e2132174583beb90c1bd3e9c842bc6d5c944d1 ]
+
+spi-bitbang has to call the chipselect function on the ath79 SPI driver
+in order to communicate with the SPI slave device, as the ath79 SPI
+driver has three dedicated chipselect lines but can also be used with
+GPIOs for the CS lines.
+
+Fixes commit 4a07b8bcd503 ("spi: bitbang: Make chipselect callback optional")
+
+Signed-off-by: David Bauer <mail@david-bauer.net>
+Link: https://lore.kernel.org/r/20210303160837.165771-1-mail@david-bauer.net
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-ath79.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/spi/spi-ath79.c b/drivers/spi/spi-ath79.c
+index eb9a243e9526..436327fb58de 100644
+--- a/drivers/spi/spi-ath79.c
++++ b/drivers/spi/spi-ath79.c
+@@ -158,6 +158,7 @@ static int ath79_spi_probe(struct platform_device *pdev)
+       master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
+       master->setup = spi_bitbang_setup;
+       master->cleanup = spi_bitbang_cleanup;
++      master->flags = SPI_MASTER_GPIO_SS;
+       if (pdata) {
+               master->bus_num = pdata->bus_num;
+               master->num_chipselect = pdata->num_chipselect;
+-- 
+2.30.2
+
diff --git a/queue-5.12/spi-ath79-remove-spi-master-setup-and-cleanup-assign.patch b/queue-5.12/spi-ath79-remove-spi-master-setup-and-cleanup-assign.patch
new file mode 100644 (file)
index 0000000..6bc6d87
--- /dev/null
@@ -0,0 +1,41 @@
+From 6ad25460b9fb244858643a1c8cc0facfefd3a367 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Mar 2021 17:08:37 +0100
+Subject: spi: ath79: remove spi-master setup and cleanup assignment
+
+From: David Bauer <mail@david-bauer.net>
+
+[ Upstream commit ffb597b2bd3cd78b9bfb68f536743cd46dbb2cc4 ]
+
+This removes the assignment of setup and cleanup functions for the ath79
+target. Assigning the setup-method will lead to 'setup_transfer' not
+being assigned in spi_bitbang_init. Because of this, performing any
+TX/RX operation will lead to a kernel oops.
+
+Also drop the redundant cleanup assignment, as it's also assigned in
+spi_bitbang_init.
+
+Signed-off-by: David Bauer <mail@david-bauer.net>
+Link: https://lore.kernel.org/r/20210303160837.165771-2-mail@david-bauer.net
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-ath79.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/spi/spi-ath79.c b/drivers/spi/spi-ath79.c
+index 436327fb58de..98ace748cd98 100644
+--- a/drivers/spi/spi-ath79.c
++++ b/drivers/spi/spi-ath79.c
+@@ -156,8 +156,6 @@ static int ath79_spi_probe(struct platform_device *pdev)
+       master->use_gpio_descriptors = true;
+       master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
+-      master->setup = spi_bitbang_setup;
+-      master->cleanup = spi_bitbang_cleanup;
+       master->flags = SPI_MASTER_GPIO_SS;
+       if (pdata) {
+               master->bus_num = pdata->bus_num;
+-- 
+2.30.2
+
diff --git a/queue-5.12/spi-dln2-fix-reference-leak-to-master.patch b/queue-5.12/spi-dln2-fix-reference-leak-to-master.patch
new file mode 100644 (file)
index 0000000..88aa072
--- /dev/null
@@ -0,0 +1,40 @@
+From 55d29574810db6dcdc32c75666d6b7cf15dc98bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Apr 2021 08:29:55 +0000
+Subject: spi: dln2: Fix reference leak to master
+
+From: Wei Yongjun <weiyongjun1@huawei.com>
+
+[ Upstream commit 9b844b087124c1538d05f40fda8a4fec75af55be ]
+
+Call spi_master_get() holds the reference count to master device, thus
+we need an additional spi_master_put() call to reduce the reference
+count, otherwise we will leak a reference to master.
+
+This commit fix it by removing the unnecessary spi_master_get().
+
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
+Link: https://lore.kernel.org/r/20210409082955.2907950-1-weiyongjun1@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-dln2.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-dln2.c b/drivers/spi/spi-dln2.c
+index 75b33d7d14b0..9a4d942fafcf 100644
+--- a/drivers/spi/spi-dln2.c
++++ b/drivers/spi/spi-dln2.c
+@@ -780,7 +780,7 @@ exit_free_master:
+ static int dln2_spi_remove(struct platform_device *pdev)
+ {
+-      struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
++      struct spi_master *master = platform_get_drvdata(pdev);
+       struct dln2_spi *dln2 = spi_master_get_devdata(master);
+       pm_runtime_disable(&pdev->dev);
+-- 
+2.30.2
+
diff --git a/queue-5.12/spi-omap-100k-fix-reference-leak-to-master.patch b/queue-5.12/spi-omap-100k-fix-reference-leak-to-master.patch
new file mode 100644 (file)
index 0000000..04d8691
--- /dev/null
@@ -0,0 +1,58 @@
+From 81c7a5244502ef2a0c92e4e9be5e5ea7171e127c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Apr 2021 08:29:54 +0000
+Subject: spi: omap-100k: Fix reference leak to master
+
+From: Wei Yongjun <weiyongjun1@huawei.com>
+
+[ Upstream commit a23faea76d4cf5f75decb574491e66f9ecd707e7 ]
+
+Call spi_master_get() holds the reference count to master device, thus
+we need an additional spi_master_put() call to reduce the reference
+count, otherwise we will leak a reference to master.
+
+This commit fix it by removing the unnecessary spi_master_get().
+
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
+Link: https://lore.kernel.org/r/20210409082954.2906933-1-weiyongjun1@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-omap-100k.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/spi/spi-omap-100k.c b/drivers/spi/spi-omap-100k.c
+index 36a4922a134a..ccd817ee4917 100644
+--- a/drivers/spi/spi-omap-100k.c
++++ b/drivers/spi/spi-omap-100k.c
+@@ -424,7 +424,7 @@ err:
+ static int omap1_spi100k_remove(struct platform_device *pdev)
+ {
+-      struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
++      struct spi_master *master = platform_get_drvdata(pdev);
+       struct omap1_spi100k *spi100k = spi_master_get_devdata(master);
+       pm_runtime_disable(&pdev->dev);
+@@ -438,7 +438,7 @@ static int omap1_spi100k_remove(struct platform_device *pdev)
+ #ifdef CONFIG_PM
+ static int omap1_spi100k_runtime_suspend(struct device *dev)
+ {
+-      struct spi_master *master = spi_master_get(dev_get_drvdata(dev));
++      struct spi_master *master = dev_get_drvdata(dev);
+       struct omap1_spi100k *spi100k = spi_master_get_devdata(master);
+       clk_disable_unprepare(spi100k->ick);
+@@ -449,7 +449,7 @@ static int omap1_spi100k_runtime_suspend(struct device *dev)
+ static int omap1_spi100k_runtime_resume(struct device *dev)
+ {
+-      struct spi_master *master = spi_master_get(dev_get_drvdata(dev));
++      struct spi_master *master = dev_get_drvdata(dev);
+       struct omap1_spi100k *spi100k = spi_master_get_devdata(master);
+       int ret;
+-- 
+2.30.2
+
diff --git a/queue-5.12/spi-qup-fix-pm-reference-leak-in-spi_qup_remove.patch b/queue-5.12/spi-qup-fix-pm-reference-leak-in-spi_qup_remove.patch
new file mode 100644 (file)
index 0000000..d987191
--- /dev/null
@@ -0,0 +1,40 @@
+From f346ad1dc987608a46b7ea1ad814d2978b242823 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Apr 2021 09:54:58 +0000
+Subject: spi: qup: fix PM reference leak in spi_qup_remove()
+
+From: Wang Li <wangli74@huawei.com>
+
+[ Upstream commit cec77e0a249892ceb10061bf17b63f9fb111d870 ]
+
+pm_runtime_get_sync will increment pm usage counter even it failed.
+Forgetting to putting operation will result in reference leak here.
+Fix it by replacing it with pm_runtime_resume_and_get to keep usage
+counter balanced.
+
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Wang Li <wangli74@huawei.com>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/20210409095458.29921-1-wangli74@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-qup.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c
+index 8dcb2e70735c..d39dec6d1c91 100644
+--- a/drivers/spi/spi-qup.c
++++ b/drivers/spi/spi-qup.c
+@@ -1263,7 +1263,7 @@ static int spi_qup_remove(struct platform_device *pdev)
+       struct spi_qup *controller = spi_master_get_devdata(master);
+       int ret;
+-      ret = pm_runtime_get_sync(&pdev->dev);
++      ret = pm_runtime_resume_and_get(&pdev->dev);
+       if (ret < 0)
+               return ret;
+-- 
+2.30.2
+
diff --git a/queue-5.12/spi-sync-up-initial-chipselect-state.patch b/queue-5.12/spi-sync-up-initial-chipselect-state.patch
new file mode 100644 (file)
index 0000000..5d30598
--- /dev/null
@@ -0,0 +1,101 @@
+From 0afa01ef281b59ea3bf1740bd41df8ad7adcd42f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Apr 2021 21:59:56 +0200
+Subject: spi: sync up initial chipselect state
+
+From: David Bauer <mail@david-bauer.net>
+
+[ Upstream commit d347b4aaa1a042ea528e385d9070b74c77a14321 ]
+
+When initially probing the SPI slave device, the call for disabling an
+SPI device without the SPI_CS_HIGH flag is not applied, as the
+condition for checking whether or not the state to be applied equals the
+one currently set evaluates to true.
+
+This however might not necessarily be the case, as the chipselect might
+be active.
+
+Add a force flag to spi_set_cs which allows to override this
+early exit condition. Set it to false everywhere except when called
+from spi_setup to sync up the initial CS state.
+
+Fixes commit d40f0b6f2e21 ("spi: Avoid setting the chip select if we don't
+need to")
+
+Signed-off-by: David Bauer <mail@david-bauer.net>
+Link: https://lore.kernel.org/r/20210416195956.121811-1-mail@david-bauer.net
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
+index b08efe88ccd6..927c2a28011f 100644
+--- a/drivers/spi/spi.c
++++ b/drivers/spi/spi.c
+@@ -795,7 +795,7 @@ int spi_register_board_info(struct spi_board_info const *info, unsigned n)
+ /*-------------------------------------------------------------------------*/
+-static void spi_set_cs(struct spi_device *spi, bool enable)
++static void spi_set_cs(struct spi_device *spi, bool enable, bool force)
+ {
+       bool enable1 = enable;
+@@ -803,7 +803,7 @@ static void spi_set_cs(struct spi_device *spi, bool enable)
+        * Avoid calling into the driver (or doing delays) if the chip select
+        * isn't actually changing from the last time this was called.
+        */
+-      if ((spi->controller->last_cs_enable == enable) &&
++      if (!force && (spi->controller->last_cs_enable == enable) &&
+           (spi->controller->last_cs_mode_high == (spi->mode & SPI_CS_HIGH)))
+               return;
+@@ -1253,7 +1253,7 @@ static int spi_transfer_one_message(struct spi_controller *ctlr,
+       struct spi_statistics *statm = &ctlr->statistics;
+       struct spi_statistics *stats = &msg->spi->statistics;
+-      spi_set_cs(msg->spi, true);
++      spi_set_cs(msg->spi, true, false);
+       SPI_STATISTICS_INCREMENT_FIELD(statm, messages);
+       SPI_STATISTICS_INCREMENT_FIELD(stats, messages);
+@@ -1321,9 +1321,9 @@ fallback_pio:
+                                        &msg->transfers)) {
+                               keep_cs = true;
+                       } else {
+-                              spi_set_cs(msg->spi, false);
++                              spi_set_cs(msg->spi, false, false);
+                               _spi_transfer_cs_change_delay(msg, xfer);
+-                              spi_set_cs(msg->spi, true);
++                              spi_set_cs(msg->spi, true, false);
+                       }
+               }
+@@ -1332,7 +1332,7 @@ fallback_pio:
+ out:
+       if (ret != 0 || !keep_cs)
+-              spi_set_cs(msg->spi, false);
++              spi_set_cs(msg->spi, false, false);
+       if (msg->status == -EINPROGRESS)
+               msg->status = ret;
+@@ -3423,11 +3423,11 @@ int spi_setup(struct spi_device *spi)
+                */
+               status = 0;
+-              spi_set_cs(spi, false);
++              spi_set_cs(spi, false, true);
+               pm_runtime_mark_last_busy(spi->controller->dev.parent);
+               pm_runtime_put_autosuspend(spi->controller->dev.parent);
+       } else {
+-              spi_set_cs(spi, false);
++              spi_set_cs(spi, false, true);
+       }
+       mutex_unlock(&spi->controller->io_mutex);
+-- 
+2.30.2
+
diff --git a/queue-5.12/staging-wimax-i2400m-fix-byte-order-issue.patch b/queue-5.12/staging-wimax-i2400m-fix-byte-order-issue.patch
new file mode 100644 (file)
index 0000000..4981ffd
--- /dev/null
@@ -0,0 +1,36 @@
+From 930729389bd8567e0e634d801ce8c4d139a8bc54 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 21 Feb 2021 21:01:05 +0530
+Subject: staging: wimax/i2400m: fix byte-order issue
+
+From: karthik alapati <mail@karthek.com>
+
+[ Upstream commit 0c37baae130df39b19979bba88bde2ee70a33355 ]
+
+fix sparse byte-order warnings by converting host byte-order
+type to __le16 byte-order types before assigning to hdr.length
+
+Signed-off-by: karthik alapati <mail@karthek.com>
+Link: https://lore.kernel.org/r/0ae5c5c4c646506d8be871e7be5705542671a1d5.1613921277.git.mail@karthek.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/wimax/i2400m/op-rfkill.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/staging/wimax/i2400m/op-rfkill.c b/drivers/staging/wimax/i2400m/op-rfkill.c
+index fbddf2e18c14..44698a1aae87 100644
+--- a/drivers/staging/wimax/i2400m/op-rfkill.c
++++ b/drivers/staging/wimax/i2400m/op-rfkill.c
+@@ -86,7 +86,7 @@ int i2400m_op_rfkill_sw_toggle(struct wimax_dev *wimax_dev,
+       if (cmd == NULL)
+               goto error_alloc;
+       cmd->hdr.type = cpu_to_le16(I2400M_MT_CMD_RF_CONTROL);
+-      cmd->hdr.length = sizeof(cmd->sw_rf);
++      cmd->hdr.length = cpu_to_le16(sizeof(cmd->sw_rf));
+       cmd->hdr.version = cpu_to_le16(I2400M_L3L4_VERSION);
+       cmd->sw_rf.hdr.type = cpu_to_le16(I2400M_TLV_RF_OPERATION);
+       cmd->sw_rf.hdr.length = cpu_to_le16(sizeof(cmd->sw_rf.status));
+-- 
+2.30.2
+
diff --git a/queue-5.12/tee-optee-do-not-check-memref-size-on-return-from-se.patch b/queue-5.12/tee-optee-do-not-check-memref-size-on-return-from-se.patch
new file mode 100644 (file)
index 0000000..a9e76f4
--- /dev/null
@@ -0,0 +1,54 @@
+From 716d123cb81535439ee5d07328c008b21abed288 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Mar 2021 11:40:37 +0100
+Subject: tee: optee: do not check memref size on return from Secure World
+
+From: Jerome Forissier <jerome@forissier.org>
+
+[ Upstream commit c650b8dc7a7910eb25af0aac1720f778b29e679d ]
+
+When Secure World returns, it may have changed the size attribute of the
+memory references passed as [in/out] parameters. The GlobalPlatform TEE
+Internal Core API specification does not restrict the values that this
+size can take. In particular, Secure World may increase the value to be
+larger than the size of the input buffer to indicate that it needs more.
+
+Therefore, the size check in optee_from_msg_param() is incorrect and
+needs to be removed. This fixes a number of failed test cases in the
+GlobalPlatform TEE Initial Configuratiom Test Suite v2_0_0_0-2017_06_09
+when OP-TEE is compiled without dynamic shared memory support
+(CFG_CORE_DYN_SHM=n).
+
+Reviewed-by: Sumit Garg <sumit.garg@linaro.org>
+Suggested-by: Jens Wiklander <jens.wiklander@linaro.org>
+Signed-off-by: Jerome Forissier <jerome@forissier.org>
+Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tee/optee/core.c | 10 ----------
+ 1 file changed, 10 deletions(-)
+
+diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
+index 319a1e701163..ddb8f9ecf307 100644
+--- a/drivers/tee/optee/core.c
++++ b/drivers/tee/optee/core.c
+@@ -79,16 +79,6 @@ int optee_from_msg_param(struct tee_param *params, size_t num_params,
+                               return rc;
+                       p->u.memref.shm_offs = mp->u.tmem.buf_ptr - pa;
+                       p->u.memref.shm = shm;
+-
+-                      /* Check that the memref is covered by the shm object */
+-                      if (p->u.memref.size) {
+-                              size_t o = p->u.memref.shm_offs +
+-                                         p->u.memref.size - 1;
+-
+-                              rc = tee_shm_get_pa(shm, o, NULL);
+-                              if (rc)
+-                                      return rc;
+-                      }
+                       break;
+               case OPTEE_MSG_ATTR_TYPE_RMEM_INPUT:
+               case OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT:
+-- 
+2.30.2
+
diff --git a/queue-5.12/tools-power-x86-intel-speed-select-increase-string-s.patch b/queue-5.12/tools-power-x86-intel-speed-select-increase-string-s.patch
new file mode 100644 (file)
index 0000000..cd781e7
--- /dev/null
@@ -0,0 +1,76 @@
+From 67dfb91ebe2cd142012e9f71db01f1b69e4b7621 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Mar 2021 17:31:49 -0800
+Subject: tools/power/x86/intel-speed-select: Increase string size
+
+From: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+
+[ Upstream commit 2e70b710f36c80b6e78cf32a5c30b46dbb72213c ]
+
+The current string size to print cpulist can accommodate upto 80
+logical CPUs per package. But this limit is not enough. So increase
+the string size. Also prevent buffer overflow, if the string size
+reaches limit.
+
+Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/power/x86/intel-speed-select/isst-display.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c
+index 8e54ce47648e..3bf1820c0da1 100644
+--- a/tools/power/x86/intel-speed-select/isst-display.c
++++ b/tools/power/x86/intel-speed-select/isst-display.c
+@@ -25,10 +25,14 @@ static void printcpulist(int str_len, char *str, int mask_size,
+                       index = snprintf(&str[curr_index],
+                                        str_len - curr_index, ",");
+                       curr_index += index;
++                      if (curr_index >= str_len)
++                              break;
+               }
+               index = snprintf(&str[curr_index], str_len - curr_index, "%d",
+                                i);
+               curr_index += index;
++              if (curr_index >= str_len)
++                      break;
+               first = 0;
+       }
+ }
+@@ -64,10 +68,14 @@ static void printcpumask(int str_len, char *str, int mask_size,
+               index = snprintf(&str[curr_index], str_len - curr_index, "%08x",
+                                mask[i]);
+               curr_index += index;
++              if (curr_index >= str_len)
++                      break;
+               if (i) {
+                       strncat(&str[curr_index], ",", str_len - curr_index);
+                       curr_index++;
+               }
++              if (curr_index >= str_len)
++                      break;
+       }
+       free(mask);
+@@ -185,7 +193,7 @@ static void _isst_pbf_display_information(int cpu, FILE *outf, int level,
+                                         int disp_level)
+ {
+       char header[256];
+-      char value[256];
++      char value[512];
+       snprintf(header, sizeof(header), "speed-select-base-freq-properties");
+       format_and_print(outf, disp_level, header, NULL);
+@@ -349,7 +357,7 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level,
+                                  struct isst_pkg_ctdp *pkg_dev)
+ {
+       char header[256];
+-      char value[256];
++      char value[512];
+       static int level;
+       int i;
+-- 
+2.30.2
+
diff --git a/queue-5.12/tty-n_gsm-check-error-while-registering-tty-devices.patch b/queue-5.12/tty-n_gsm-check-error-while-registering-tty-devices.patch
new file mode 100644 (file)
index 0000000..daa7518
--- /dev/null
@@ -0,0 +1,101 @@
+From ccd6eb8964c3514af63d061a4ce1bbbbcfd5b111 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Apr 2021 11:57:58 +0800
+Subject: tty: n_gsm: check error while registering tty devices
+
+From: Hillf Danton <hdanton@sina.com>
+
+[ Upstream commit 0a360e8b65d62fe1a994f0a8da4f8d20877b2100 ]
+
+Add the error path for registering tty devices and roll back in case of error
+in bid to avoid the UAF like the below one reported.
+
+Plus syzbot reported general protection fault in cdev_del() on Sep 24, 2020
+and both cases are down to the kobject_put() in tty_cdev_add().
+
+ ------------[ cut here ]------------
+ refcount_t: underflow; use-after-free.
+ WARNING: CPU: 1 PID: 8923 at lib/refcount.c:28
+ refcount_warn_saturate+0x1cf/0x210 -origin/lib/refcount.c:28
+ Modules linked in:
+ CPU: 1 PID: 8923 Comm: executor Not tainted 5.12.0-rc5+ #8
+ Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
+ 1.13.0-1ubuntu1.1 04/01/2014
+ RIP: 0010:refcount_warn_saturate+0x1cf/0x210 -origin/lib/refcount.c:28
+ Code: 4f ff ff ff e8 32 fa b5 fe 48 c7 c7 3d f8 f6 86 e8 d6 ab c6 fe
+ c6 05 7c 34 67 04 01 48 c7 c7 68 f8 6d 86 31 c0 e8 81 2e 9d fe <0f> 0b
+ e9 22 ff ff ff e8 05 fa b5 fe 48 c7 c7 3e f8 f6 86 e8 a9 ab
+ RSP: 0018:ffffc90001633c60 EFLAGS: 00010246
+ RAX: 15d08b2e34b77800 RBX: 0000000000000003 RCX: ffff88804c056c80
+ RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
+ RBP: 0000000000000003 R08: ffffffff813767aa R09: 0001ffffffffffff
+ R10: 0001ffffffffffff R11: ffff88804c056c80 R12: ffff888040b7d000
+ R13: ffff88804c206938 R14: ffff88804c206900 R15: ffff888041b18488
+ FS:  00000000022c9940(0000) GS:ffff88807ec00000(0000) knlGS:0000000000000000
+ CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 00007f9f9b122008 CR3: 0000000044b4b000 CR4: 0000000000750ee0
+ PKRU: 55555554
+ Call Trace:
+  __refcount_sub_and_test -origin/./include/linux/refcount.h:283 [inline]
+  __refcount_dec_and_test -origin/./include/linux/refcount.h:315 [inline]
+  refcount_dec_and_test -origin/./include/linux/refcount.h:333 [inline]
+  kref_put -origin/./include/linux/kref.h:64 [inline]
+  kobject_put+0x17b/0x180 -origin/lib/kobject.c:753
+  cdev_del+0x4b/0x50 -origin/fs/char_dev.c:597
+  tty_unregister_device+0x99/0xd0 -origin/drivers/tty/tty_io.c:3343
+  gsmld_detach_gsm -origin/drivers/tty/n_gsm.c:2409 [inline]
+  gsmld_close+0x6c/0x140 -origin/drivers/tty/n_gsm.c:2478
+  tty_ldisc_close -origin/drivers/tty/tty_ldisc.c:488 [inline]
+  tty_ldisc_kill -origin/drivers/tty/tty_ldisc.c:636 [inline]
+  tty_ldisc_release+0x1b6/0x400 -origin/drivers/tty/tty_ldisc.c:809
+  tty_release_struct+0x19/0xb0 -origin/drivers/tty/tty_io.c:1714
+  tty_release+0x9ad/0xa00 -origin/drivers/tty/tty_io.c:1885
+  __fput+0x260/0x4e0 -origin/fs/file_table.c:280
+  ____fput+0x11/0x20 -origin/fs/file_table.c:313
+  task_work_run+0x8e/0x110 -origin/kernel/task_work.c:140
+  tracehook_notify_resume -origin/./include/linux/tracehook.h:189 [inline]
+  exit_to_user_mode_loop -origin/kernel/entry/common.c:174 [inline]
+  exit_to_user_mode_prepare+0x16b/0x1a0 -origin/kernel/entry/common.c:208
+  __syscall_exit_to_user_mode_work -origin/kernel/entry/common.c:290 [inline]
+  syscall_exit_to_user_mode+0x20/0x40 -origin/kernel/entry/common.c:301
+  do_syscall_64+0x45/0x80 -origin/arch/x86/entry/common.c:56
+  entry_SYSCALL_64_after_hwframe+0x44/0xae
+
+Reported-by: syzbot+c49fe6089f295a05e6f8@syzkaller.appspotmail.com
+Reported-and-tested-by: Hao Sun <sunhao.th@gmail.com>
+Signed-off-by: Hillf Danton <hdanton@sina.com>
+Link: https://lore.kernel.org/r/20210412035758.1974-1-hdanton@sina.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/n_gsm.c | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index 51dafc06f541..2406653d38b7 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -2384,8 +2384,18 @@ static int gsmld_attach_gsm(struct tty_struct *tty, struct gsm_mux *gsm)
+               /* 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++)
+-                      tty_register_device(gsm_tty_driver, base + i, NULL);
++              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;
+ }
+-- 
+2.30.2
+
diff --git a/queue-5.12/usb-core-hub-fix-pm-reference-leak-in-usb_port_resum.patch b/queue-5.12/usb-core-hub-fix-pm-reference-leak-in-usb_port_resum.patch
new file mode 100644 (file)
index 0000000..4cb8e6c
--- /dev/null
@@ -0,0 +1,39 @@
+From a3631eaf33cba52ffaa249f44b5e4742b12865f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Apr 2021 21:08:31 +0800
+Subject: usb: core: hub: Fix PM reference leak in usb_port_resume()
+
+From: Bixuan Cui <cuibixuan@huawei.com>
+
+[ Upstream commit 025f97d188006eeee4417bb475a6878d1e0eed3f ]
+
+pm_runtime_get_sync will increment pm usage counter even it failed.
+thus a pairing decrement is needed.
+Fix it by replacing it with pm_runtime_resume_and_get to keep usage
+counter balanced.
+
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Bixuan Cui <cuibixuan@huawei.com>
+Link: https://lore.kernel.org/r/20210408130831.56239-1-cuibixuan@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/core/hub.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
+index 7f71218cc1e5..404507d1b76f 100644
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -3556,7 +3556,7 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)
+       u16             portchange, portstatus;
+       if (!test_and_set_bit(port1, hub->child_usage_bits)) {
+-              status = pm_runtime_get_sync(&port_dev->dev);
++              status = pm_runtime_resume_and_get(&port_dev->dev);
+               if (status < 0) {
+                       dev_dbg(&udev->dev, "can't resume usb port, status %d\n",
+                                       status);
+-- 
+2.30.2
+
diff --git a/queue-5.12/usb-dwc3-gadget-check-for-disabled-lpm-quirk.patch b/queue-5.12/usb-dwc3-gadget-check-for-disabled-lpm-quirk.patch
new file mode 100644 (file)
index 0000000..0ee30eb
--- /dev/null
@@ -0,0 +1,95 @@
+From 9f3cf03c7847475d9409c9f86d97efe7cbcef9db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Apr 2021 19:13:18 -0700
+Subject: usb: dwc3: gadget: Check for disabled LPM quirk
+
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+
+[ Upstream commit 475e8be53d0496f9bc6159f4abb3ff5f9b90e8de ]
+
+If the device doesn't support LPM, make sure to disable the LPM
+capability and don't advertise to the host that it supports it.
+
+Acked-by: Felipe Balbi <balbi@kernel.org>
+Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Link: https://lore.kernel.org/r/9e68527ff932b1646f92a7593d4092a903754666.1618366071.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   | 2 ++
+ drivers/usb/dwc3/core.h   | 4 +++-
+ drivers/usb/dwc3/gadget.c | 9 ++++++++-
+ 3 files changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
+index f2448d0a9d39..b46985c9595f 100644
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -1277,6 +1277,8 @@ static void dwc3_get_properties(struct dwc3 *dwc)
+                               "snps,usb3_lpm_capable");
+       dwc->usb2_lpm_disable = device_property_read_bool(dev,
+                               "snps,usb2-lpm-disable");
++      dwc->usb2_gadget_lpm_disable = device_property_read_bool(dev,
++                              "snps,usb2-gadget-lpm-disable");
+       device_property_read_u8(dev, "snps,rx-thr-num-pkt-prd",
+                               &rx_thr_num_pkt_prd);
+       device_property_read_u8(dev, "snps,rx-max-burst-prd",
+diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
+index 052b20d52651..7ae6684a94ae 100644
+--- a/drivers/usb/dwc3/core.h
++++ b/drivers/usb/dwc3/core.h
+@@ -1034,7 +1034,8 @@ struct dwc3_scratchpad_array {
+  * @dis_start_transfer_quirk: set if start_transfer failure SW workaround is
+  *                    not needed for DWC_usb31 version 1.70a-ea06 and below
+  * @usb3_lpm_capable: set if hadrware supports Link Power Management
+- * @usb2_lpm_disable: set to disable usb2 lpm
++ * @usb2_lpm_disable: set to disable usb2 lpm for host
++ * @usb2_gadget_lpm_disable: set to disable usb2 lpm for gadget
+  * @disable_scramble_quirk: set if we enable the disable scramble quirk
+  * @u2exit_lfps_quirk: set if we enable u2exit lfps quirk
+  * @u2ss_inp3_quirk: set if we enable P3 OK for U2/SS Inactive quirk
+@@ -1238,6 +1239,7 @@ struct dwc3 {
+       unsigned                dis_start_transfer_quirk:1;
+       unsigned                usb3_lpm_capable:1;
+       unsigned                usb2_lpm_disable:1;
++      unsigned                usb2_gadget_lpm_disable:1;
+       unsigned                disable_scramble_quirk:1;
+       unsigned                u2exit_lfps_quirk:1;
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index 111ab6f6c055..41bb75a3abe5 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -3469,6 +3469,7 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
+       /* Enable USB2 LPM Capability */
+       if (!DWC3_VER_IS_WITHIN(DWC3, ANY, 194A) &&
++          !dwc->usb2_gadget_lpm_disable &&
+           (speed != DWC3_DSTS_SUPERSPEED) &&
+           (speed != DWC3_DSTS_SUPERSPEED_PLUS)) {
+               reg = dwc3_readl(dwc->regs, DWC3_DCFG);
+@@ -3495,6 +3496,12 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
+               dwc3_gadget_dctl_write_safe(dwc, reg);
+       } else {
++              if (dwc->usb2_gadget_lpm_disable) {
++                      reg = dwc3_readl(dwc->regs, DWC3_DCFG);
++                      reg &= ~DWC3_DCFG_LPM_CAP;
++                      dwc3_writel(dwc->regs, DWC3_DCFG, reg);
++              }
++
+               reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+               reg &= ~DWC3_DCTL_HIRD_THRES_MASK;
+               dwc3_gadget_dctl_write_safe(dwc, reg);
+@@ -3943,7 +3950,7 @@ int dwc3_gadget_init(struct dwc3 *dwc)
+       dwc->gadget->ssp_rate           = USB_SSP_GEN_UNKNOWN;
+       dwc->gadget->sg_supported       = true;
+       dwc->gadget->name               = "dwc3-gadget";
+-      dwc->gadget->lpm_capable        = true;
++      dwc->gadget->lpm_capable        = !dwc->usb2_gadget_lpm_disable;
+       /*
+        * FIXME We might be setting max_speed to <SUPER, however versions
+-- 
+2.30.2
+
diff --git a/queue-5.12/usb-dwc3-gadget-ignore-ep-queue-requests-during-bus-.patch b/queue-5.12/usb-dwc3-gadget-ignore-ep-queue-requests-during-bus-.patch
new file mode 100644 (file)
index 0000000..b7c85b4
--- /dev/null
@@ -0,0 +1,48 @@
+From 8f7a2d26bd2ec9ff4d777c81493e1a67216326cc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Mar 2021 02:31:25 -0700
+Subject: usb: dwc3: gadget: Ignore EP queue requests during bus reset
+
+From: Wesley Cheng <wcheng@codeaurora.org>
+
+[ Upstream commit 71ca43f30df9c642970f9dc9b2d6f463f4967e7b ]
+
+The current dwc3_gadget_reset_interrupt() will stop any active
+transfers, but only addresses blocking of EP queuing for while we are
+coming from a disconnected scenario, i.e. after receiving the disconnect
+event.  If the host decides to issue a bus reset on the device, the
+connected parameter will still be set to true, allowing for EP queuing
+to continue while we are disabling the functions.  To avoid this, set the
+connected flag to false until the stop active transfers is complete.
+
+Signed-off-by: Wesley Cheng <wcheng@codeaurora.org>
+Link: https://lore.kernel.org/r/1616146285-19149-3-git-send-email-wcheng@codeaurora.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/dwc3/gadget.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index c7ef218e7a8c..111ab6f6c055 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -3322,6 +3322,15 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc)
+ {
+       u32                     reg;
++      /*
++       * Ideally, dwc3_reset_gadget() would trigger the function
++       * drivers to stop any active transfers through ep disable.
++       * However, for functions which defer ep disable, such as mass
++       * storage, we will need to rely on the call to stop active
++       * transfers here, and avoid allowing of request queuing.
++       */
++      dwc->connected = false;
++
+       /*
+        * WORKAROUND: DWC3 revisions <1.88a have an issue which
+        * would cause a missing Disconnect Event if there's a
+-- 
+2.30.2
+
diff --git a/queue-5.12/usb-dwc3-pci-add-support-for-the-intel-alder-lake-m.patch b/queue-5.12/usb-dwc3-pci-add-support-for-the-intel-alder-lake-m.patch
new file mode 100644 (file)
index 0000000..132041f
--- /dev/null
@@ -0,0 +1,45 @@
+From 8cdc478c370b58d6c6ae9ae7230728d5613f25c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Apr 2021 11:31:44 +0300
+Subject: usb: dwc3: pci: add support for the Intel Alder Lake-M
+
+From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+
+[ Upstream commit 782de5e7190de0a773417708e17d9461d9109bf9 ]
+
+This patch adds the necessary PCI ID for Intel Alder Lake-M
+devices.
+
+Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20210408083144.69350-1-heikki.krogerus@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/dwc3/dwc3-pci.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
+index 4c5c6972124a..95f954a1d7be 100644
+--- a/drivers/usb/dwc3/dwc3-pci.c
++++ b/drivers/usb/dwc3/dwc3-pci.c
+@@ -41,6 +41,7 @@
+ #define PCI_DEVICE_ID_INTEL_TGPH              0x43ee
+ #define PCI_DEVICE_ID_INTEL_JSP                       0x4dee
+ #define PCI_DEVICE_ID_INTEL_ADLP              0x51ee
++#define PCI_DEVICE_ID_INTEL_ADLM              0x54ee
+ #define PCI_DEVICE_ID_INTEL_ADLS              0x7ae1
+ #define PCI_DEVICE_ID_INTEL_TGL                       0x9a15
+@@ -388,6 +389,9 @@ static const struct pci_device_id dwc3_pci_id_table[] = {
+       { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ADLP),
+         (kernel_ulong_t) &dwc3_pci_intel_swnode, },
++      { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ADLM),
++        (kernel_ulong_t) &dwc3_pci_intel_swnode, },
++
+       { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ADLS),
+         (kernel_ulong_t) &dwc3_pci_intel_swnode, },
+-- 
+2.30.2
+
diff --git a/queue-5.12/usb-gadget-f_uac1-validate-input-parameters.patch b/queue-5.12/usb-gadget-f_uac1-validate-input-parameters.patch
new file mode 100644 (file)
index 0000000..704cef9
--- /dev/null
@@ -0,0 +1,113 @@
+From 57ea43e01d5e8d2e00f8d65b226697869f78583f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Mar 2021 13:49:34 +0200
+Subject: usb: gadget: f_uac1: validate input parameters
+
+From: Ruslan Bilovol <ruslan.bilovol@gmail.com>
+
+[ Upstream commit a59c68a6a3d1b18e2494f526eb19893a34fa6ec6 ]
+
+Currently user can configure UAC1 function with
+parameters that violate UAC1 spec or are not supported
+by UAC1 gadget implementation.
+
+This can lead to incorrect behavior if such gadget
+is connected to the host - like enumeration failure
+or other issues depending on host's UAC1 driver
+implementation, bringing user to a long hours
+of debugging the issue.
+
+Instead of silently accept these parameters, throw
+an error if they are not valid.
+
+Signed-off-by: Ruslan Bilovol <ruslan.bilovol@gmail.com>
+Link: https://lore.kernel.org/r/1614599375-8803-5-git-send-email-ruslan.bilovol@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/function/f_uac1.c | 43 ++++++++++++++++++++++++++++
+ 1 file changed, 43 insertions(+)
+
+diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c
+index 560382e0a8f3..e65f474ad7b3 100644
+--- a/drivers/usb/gadget/function/f_uac1.c
++++ b/drivers/usb/gadget/function/f_uac1.c
+@@ -19,6 +19,9 @@
+ #include "u_audio.h"
+ #include "u_uac1.h"
++/* UAC1 spec: 3.7.2.3 Audio Channel Cluster Format */
++#define UAC1_CHANNEL_MASK 0x0FFF
++
+ struct f_uac1 {
+       struct g_audio g_audio;
+       u8 ac_intf, as_in_intf, as_out_intf;
+@@ -30,6 +33,11 @@ static inline struct f_uac1 *func_to_uac1(struct usb_function *f)
+       return container_of(f, struct f_uac1, g_audio.func);
+ }
++static inline struct f_uac1_opts *g_audio_to_uac1_opts(struct g_audio *audio)
++{
++      return container_of(audio->func.fi, struct f_uac1_opts, func_inst);
++}
++
+ /*
+  * DESCRIPTORS ... most are static, but strings and full
+  * configuration descriptors are built on demand.
+@@ -505,11 +513,42 @@ static void f_audio_disable(struct usb_function *f)
+ /*-------------------------------------------------------------------------*/
++static int f_audio_validate_opts(struct g_audio *audio, struct device *dev)
++{
++      struct f_uac1_opts *opts = g_audio_to_uac1_opts(audio);
++
++      if (!opts->p_chmask && !opts->c_chmask) {
++              dev_err(dev, "Error: no playback and capture channels\n");
++              return -EINVAL;
++      } else if (opts->p_chmask & ~UAC1_CHANNEL_MASK) {
++              dev_err(dev, "Error: unsupported playback channels mask\n");
++              return -EINVAL;
++      } else if (opts->c_chmask & ~UAC1_CHANNEL_MASK) {
++              dev_err(dev, "Error: unsupported capture channels mask\n");
++              return -EINVAL;
++      } else if ((opts->p_ssize < 1) || (opts->p_ssize > 4)) {
++              dev_err(dev, "Error: incorrect playback sample size\n");
++              return -EINVAL;
++      } else if ((opts->c_ssize < 1) || (opts->c_ssize > 4)) {
++              dev_err(dev, "Error: incorrect capture sample size\n");
++              return -EINVAL;
++      } else if (!opts->p_srate) {
++              dev_err(dev, "Error: incorrect playback sampling rate\n");
++              return -EINVAL;
++      } else if (!opts->c_srate) {
++              dev_err(dev, "Error: incorrect capture sampling rate\n");
++              return -EINVAL;
++      }
++
++      return 0;
++}
++
+ /* audio function driver setup/binding */
+ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f)
+ {
+       struct usb_composite_dev        *cdev = c->cdev;
+       struct usb_gadget               *gadget = cdev->gadget;
++      struct device                   *dev = &gadget->dev;
+       struct f_uac1                   *uac1 = func_to_uac1(f);
+       struct g_audio                  *audio = func_to_g_audio(f);
+       struct f_uac1_opts              *audio_opts;
+@@ -519,6 +558,10 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f)
+       int                             rate;
+       int                             status;
++      status = f_audio_validate_opts(audio, dev);
++      if (status)
++              return status;
++
+       audio_opts = container_of(f->fi, struct f_uac1_opts, func_inst);
+       us = usb_gstrings_attach(cdev, uac1_strings, ARRAY_SIZE(strings_uac1));
+-- 
+2.30.2
+
diff --git a/queue-5.12/usb-gadget-f_uac2-validate-input-parameters.patch b/queue-5.12/usb-gadget-f_uac2-validate-input-parameters.patch
new file mode 100644 (file)
index 0000000..ba7982f
--- /dev/null
@@ -0,0 +1,100 @@
+From b1b118b1d4913ef5045fe3d41936e32853668257 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Mar 2021 13:49:33 +0200
+Subject: usb: gadget: f_uac2: validate input parameters
+
+From: Ruslan Bilovol <ruslan.bilovol@gmail.com>
+
+[ Upstream commit 3713d5ceb04d5ab6a5e2b86dfca49170053f3a5e ]
+
+Currently user can configure UAC2 function with
+parameters that violate UAC2 spec or are not supported
+by UAC2 gadget implementation.
+
+This can lead to incorrect behavior if such gadget
+is connected to the host - like enumeration failure
+or other issues depending on host's UAC2 driver
+implementation, bringing user to a long hours
+of debugging the issue.
+
+Instead of silently accept these parameters, throw
+an error if they are not valid.
+
+Signed-off-by: Ruslan Bilovol <ruslan.bilovol@gmail.com>
+Link: https://lore.kernel.org/r/1614599375-8803-4-git-send-email-ruslan.bilovol@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/function/f_uac2.c | 39 ++++++++++++++++++++++++++--
+ 1 file changed, 37 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c
+index 6f03e944e0e3..dd960cea642f 100644
+--- a/drivers/usb/gadget/function/f_uac2.c
++++ b/drivers/usb/gadget/function/f_uac2.c
+@@ -14,6 +14,9 @@
+ #include "u_audio.h"
+ #include "u_uac2.h"
++/* UAC2 spec: 4.1 Audio Channel Cluster Descriptor */
++#define UAC2_CHANNEL_MASK 0x07FFFFFF
++
+ /*
+  * The driver implements a simple UAC_2 topology.
+  * USB-OUT -> IT_1 -> OT_3 -> ALSA_Capture
+@@ -604,6 +607,36 @@ static void setup_descriptor(struct f_uac2_opts *opts)
+       hs_audio_desc[i] = NULL;
+ }
++static int afunc_validate_opts(struct g_audio *agdev, struct device *dev)
++{
++      struct f_uac2_opts *opts = g_audio_to_uac2_opts(agdev);
++
++      if (!opts->p_chmask && !opts->c_chmask) {
++              dev_err(dev, "Error: no playback and capture channels\n");
++              return -EINVAL;
++      } else if (opts->p_chmask & ~UAC2_CHANNEL_MASK) {
++              dev_err(dev, "Error: unsupported playback channels mask\n");
++              return -EINVAL;
++      } else if (opts->c_chmask & ~UAC2_CHANNEL_MASK) {
++              dev_err(dev, "Error: unsupported capture channels mask\n");
++              return -EINVAL;
++      } else if ((opts->p_ssize < 1) || (opts->p_ssize > 4)) {
++              dev_err(dev, "Error: incorrect playback sample size\n");
++              return -EINVAL;
++      } else if ((opts->c_ssize < 1) || (opts->c_ssize > 4)) {
++              dev_err(dev, "Error: incorrect capture sample size\n");
++              return -EINVAL;
++      } else if (!opts->p_srate) {
++              dev_err(dev, "Error: incorrect playback sampling rate\n");
++              return -EINVAL;
++      } else if (!opts->c_srate) {
++              dev_err(dev, "Error: incorrect capture sampling rate\n");
++              return -EINVAL;
++      }
++
++      return 0;
++}
++
+ static int
+ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
+ {
+@@ -612,11 +645,13 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
+       struct usb_composite_dev *cdev = cfg->cdev;
+       struct usb_gadget *gadget = cdev->gadget;
+       struct device *dev = &gadget->dev;
+-      struct f_uac2_opts *uac2_opts;
++      struct f_uac2_opts *uac2_opts = g_audio_to_uac2_opts(agdev);
+       struct usb_string *us;
+       int ret;
+-      uac2_opts = container_of(fn->fi, struct f_uac2_opts, func_inst);
++      ret = afunc_validate_opts(agdev, dev);
++      if (ret)
++              return ret;
+       us = usb_gstrings_attach(cdev, fn_strings, ARRAY_SIZE(strings_fn));
+       if (IS_ERR(us))
+-- 
+2.30.2
+
diff --git a/queue-5.12/usb-gadget-tegra-xudc-fix-possible-use-after-free-in.patch b/queue-5.12/usb-gadget-tegra-xudc-fix-possible-use-after-free-in.patch
new file mode 100644 (file)
index 0000000..a2ff59b
--- /dev/null
@@ -0,0 +1,44 @@
+From 613a6d2e4f988a277e243835ace93ed9f22c1c73 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Apr 2021 17:29:47 +0800
+Subject: usb: gadget: tegra-xudc: Fix possible use-after-free in
+ tegra_xudc_remove()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit a932ee40c276767cd55fadec9e38829bf441db41 ]
+
+This driver's remove path calls cancel_delayed_work(). However, that
+function does not wait until the work function finishes. This means
+that the callback function may still be running after the driver's
+remove function has finished, which would result in a use-after-free.
+
+Fix by calling cancel_delayed_work_sync(), which ensures that
+the work is properly cancelled, no longer running, and unable
+to re-schedule itself.
+
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20210407092947.3271507-1-yangyingliang@huawei.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 | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/udc/tegra-xudc.c b/drivers/usb/gadget/udc/tegra-xudc.c
+index 580bef8eb4cb..2319c9737c2b 100644
+--- a/drivers/usb/gadget/udc/tegra-xudc.c
++++ b/drivers/usb/gadget/udc/tegra-xudc.c
+@@ -3883,7 +3883,7 @@ static int tegra_xudc_remove(struct platform_device *pdev)
+       pm_runtime_get_sync(xudc->dev);
+-      cancel_delayed_work(&xudc->plc_reset_work);
++      cancel_delayed_work_sync(&xudc->plc_reset_work);
+       cancel_work_sync(&xudc->usb_role_sw_work);
+       usb_del_gadget_udc(&xudc->gadget);
+-- 
+2.30.2
+
diff --git a/queue-5.12/usb-gadget-uvc-add-binterval-checking-for-hs-mode.patch b/queue-5.12/usb-gadget-uvc-add-binterval-checking-for-hs-mode.patch
new file mode 100644 (file)
index 0000000..1dacf13
--- /dev/null
@@ -0,0 +1,52 @@
+From cf13f159ae9a2df5e58dff14387978de3e2557fe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Mar 2021 13:53:38 +0100
+Subject: usb: gadget: uvc: add bInterval checking for HS mode
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pawel Laszczak <pawell@cadence.com>
+
+[ Upstream commit 26adde04acdff14a1f28d4a5dce46a8513a3038b ]
+
+Patch adds extra checking for bInterval passed by configfs.
+The 5.6.4 chapter of USB Specification (rev. 2.0) say:
+"A high-bandwidth endpoint must specify a period of 1x125 µs
+(i.e., a bInterval value of 1)."
+
+The issue was observed during testing UVC class on CV.
+I treat this change as improvement because we can control
+bInterval by configfs.
+
+Reviewed-by: Peter Chen <peter.chen@kernel.org>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Pawel Laszczak <pawell@cadence.com>
+Link: https://lore.kernel.org/r/20210308125338.4824-1-pawell@gli-login.cadence.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/function/f_uvc.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c
+index 44b4352a2676..ed77a126a74f 100644
+--- a/drivers/usb/gadget/function/f_uvc.c
++++ b/drivers/usb/gadget/function/f_uvc.c
+@@ -633,7 +633,12 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
+       uvc_hs_streaming_ep.wMaxPacketSize =
+               cpu_to_le16(max_packet_size | ((max_packet_mult - 1) << 11));
+-      uvc_hs_streaming_ep.bInterval = opts->streaming_interval;
++
++      /* A high-bandwidth endpoint must specify a bInterval value of 1 */
++      if (max_packet_mult > 1)
++              uvc_hs_streaming_ep.bInterval = 1;
++      else
++              uvc_hs_streaming_ep.bInterval = opts->streaming_interval;
+       uvc_ss_streaming_ep.wMaxPacketSize = cpu_to_le16(max_packet_size);
+       uvc_ss_streaming_ep.bInterval = opts->streaming_interval;
+-- 
+2.30.2
+
diff --git a/queue-5.12/usb-musb-fix-pm-reference-leak-in-musb_irq_work.patch b/queue-5.12/usb-musb-fix-pm-reference-leak-in-musb_irq_work.patch
new file mode 100644 (file)
index 0000000..d9bbb25
--- /dev/null
@@ -0,0 +1,39 @@
+From 9d1610fd1025ffe659bd7df97eb5a39211ae949b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Apr 2021 17:18:36 +0800
+Subject: usb: musb: fix PM reference leak in musb_irq_work()
+
+From: Bixuan Cui <cuibixuan@huawei.com>
+
+[ Upstream commit 9535b99533904e9bc1607575aa8e9539a55435d7 ]
+
+pm_runtime_get_sync will increment pm usage counter even it failed.
+thus a pairing decrement is needed.
+Fix it by replacing it with pm_runtime_resume_and_get to keep usage
+counter balanced.
+
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Bixuan Cui <cuibixuan@huawei.com>
+Link: https://lore.kernel.org/r/20210408091836.55227-1-cuibixuan@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/musb/musb_core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
+index fc0457db62e1..8f09a387b773 100644
+--- a/drivers/usb/musb/musb_core.c
++++ b/drivers/usb/musb/musb_core.c
+@@ -2070,7 +2070,7 @@ static void musb_irq_work(struct work_struct *data)
+       struct musb *musb = container_of(data, struct musb, irq_work.work);
+       int error;
+-      error = pm_runtime_get_sync(musb->controller);
++      error = pm_runtime_resume_and_get(musb->controller);
+       if (error < 0) {
+               dev_err(musb->controller, "Could not enable: %i\n", error);
+-- 
+2.30.2
+
diff --git a/queue-5.12/usb-webcam-invalid-size-of-processing-unit-descripto.patch b/queue-5.12/usb-webcam-invalid-size-of-processing-unit-descripto.patch
new file mode 100644 (file)
index 0000000..75f0ab5
--- /dev/null
@@ -0,0 +1,75 @@
+From 51501b1683674dfd4cb8f4e57bde604d6106dec3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Mar 2021 08:17:48 +0100
+Subject: usb: webcam: Invalid size of Processing Unit Descriptor
+
+From: Pawel Laszczak <pawell@cadence.com>
+
+[ Upstream commit 6a154ec9ef6762c774cd2b50215c7a8f0f08a862 ]
+
+According with USB Device Class Definition for Video Device the
+Processing Unit Descriptor bLength should be 12 (10 + bmControlSize),
+but it has 11.
+
+Invalid length caused that Processing Unit Descriptor Test Video form
+CV tool failed. To fix this issue patch adds bmVideoStandards into
+uvc_processing_unit_descriptor structure.
+
+The bmVideoStandards field was added in UVC 1.1 and it wasn't part of
+UVC 1.0a.
+
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Pawel Laszczak <pawell@cadence.com>
+Reviewed-by: Peter Chen <peter.chen@kernel.org>
+Link: https://lore.kernel.org/r/20210315071748.29706-1-pawell@gli-login.cadence.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/function/f_uvc.c | 1 +
+ drivers/usb/gadget/legacy/webcam.c  | 1 +
+ include/uapi/linux/usb/video.h      | 3 ++-
+ 3 files changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c
+index ed77a126a74f..f48a00e49794 100644
+--- a/drivers/usb/gadget/function/f_uvc.c
++++ b/drivers/usb/gadget/function/f_uvc.c
+@@ -822,6 +822,7 @@ static struct usb_function_instance *uvc_alloc_inst(void)
+       pd->bmControls[0]               = 1;
+       pd->bmControls[1]               = 0;
+       pd->iProcessing                 = 0;
++      pd->bmVideoStandards            = 0;
+       od = &opts->uvc_output_terminal;
+       od->bLength                     = UVC_DT_OUTPUT_TERMINAL_SIZE;
+diff --git a/drivers/usb/gadget/legacy/webcam.c b/drivers/usb/gadget/legacy/webcam.c
+index a9f8eb8e1c76..2c9eab2b863d 100644
+--- a/drivers/usb/gadget/legacy/webcam.c
++++ b/drivers/usb/gadget/legacy/webcam.c
+@@ -125,6 +125,7 @@ static const struct uvc_processing_unit_descriptor uvc_processing = {
+       .bmControls[0]          = 1,
+       .bmControls[1]          = 0,
+       .iProcessing            = 0,
++      .bmVideoStandards       = 0,
+ };
+ static const struct uvc_output_terminal_descriptor uvc_output_terminal = {
+diff --git a/include/uapi/linux/usb/video.h b/include/uapi/linux/usb/video.h
+index d854cb19c42c..bfdae12cdacf 100644
+--- a/include/uapi/linux/usb/video.h
++++ b/include/uapi/linux/usb/video.h
+@@ -302,9 +302,10 @@ struct uvc_processing_unit_descriptor {
+       __u8   bControlSize;
+       __u8   bmControls[2];
+       __u8   iProcessing;
++      __u8   bmVideoStandards;
+ } __attribute__((__packed__));
+-#define UVC_DT_PROCESSING_UNIT_SIZE(n)                        (9+(n))
++#define UVC_DT_PROCESSING_UNIT_SIZE(n)                        (10+(n))
+ /* 3.7.2.6. Extension Unit Descriptor */
+ struct uvc_extension_unit_descriptor {
+-- 
+2.30.2
+
diff --git a/queue-5.12/usb-xhci-fix-port-minor-revision.patch b/queue-5.12/usb-xhci-fix-port-minor-revision.patch
new file mode 100644 (file)
index 0000000..ec576f6
--- /dev/null
@@ -0,0 +1,51 @@
+From 44a3e18cd7d4765609276c11b8a3b2ae0c36ea33 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Mar 2021 19:43:21 -0800
+Subject: usb: xhci: Fix port minor revision
+
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+
+[ Upstream commit 64364bc912c01b33bba6c22e3ccb849bfca96398 ]
+
+Some hosts incorrectly use sub-minor version for minor version (i.e.
+0x02 instead of 0x20 for bcdUSB 0x320 and 0x01 for bcdUSB 0x310).
+Currently the xHCI driver works around this by just checking for minor
+revision > 0x01 for USB 3.1 everywhere. With the addition of USB 3.2,
+checking this gets a bit cumbersome. Since there is no USB release with
+bcdUSB 0x301 to 0x309, we can assume that sub-minor version 01 to 09 is
+incorrect. Let's try to fix this and use the minor revision that matches
+with the USB/xHCI spec to help with the version checking within the
+driver.
+
+Acked-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Link: https://lore.kernel.org/r/ed330e95a19dc367819c5b4d78bf7a541c35aa0a.1615432770.git.Thinh.Nguyen@synopsys.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/xhci-mem.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
+index f2c4ee7c4786..3708432f5f69 100644
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -2129,6 +2129,15 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports,
+       if (major_revision == 0x03) {
+               rhub = &xhci->usb3_rhub;
++              /*
++               * Some hosts incorrectly use sub-minor version for minor
++               * version (i.e. 0x02 instead of 0x20 for bcdUSB 0x320 and 0x01
++               * for bcdUSB 0x310). Since there is no USB release with sub
++               * minor version 0x301 to 0x309, we can assume that they are
++               * incorrect and fix it here.
++               */
++              if (minor_revision > 0x00 && minor_revision < 0x10)
++                      minor_revision <<= 4;
+       } else if (major_revision <= 0x02) {
+               rhub = &xhci->usb2_rhub;
+       } else {
+-- 
+2.30.2
+
diff --git a/queue-5.12/usb-xhci-mtk-support-quirk-to-disable-usb2-lpm.patch b/queue-5.12/usb-xhci-mtk-support-quirk-to-disable-usb2-lpm.patch
new file mode 100644 (file)
index 0000000..a7e84d8
--- /dev/null
@@ -0,0 +1,58 @@
+From 902b45f28a97a2be8f81feb39046e96956a8de89 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Mar 2021 17:05:53 +0800
+Subject: usb: xhci-mtk: support quirk to disable usb2 lpm
+
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+
+[ Upstream commit bee1f89aad2a51cd3339571bc8eadbb0dc88a683 ]
+
+The xHCI driver support usb2 HW LPM by default, here add support
+XHCI_HW_LPM_DISABLE quirk, then we can disable usb2 lpm when
+need it.
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Link: https://lore.kernel.org/r/1617181553-3503-4-git-send-email-chunfeng.yun@mediatek.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/xhci-mtk.c | 3 +++
+ drivers/usb/host/xhci-mtk.h | 1 +
+ 2 files changed, 4 insertions(+)
+
+diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
+index 2f27dc0d9c6b..1c331577fca9 100644
+--- a/drivers/usb/host/xhci-mtk.c
++++ b/drivers/usb/host/xhci-mtk.c
+@@ -397,6 +397,8 @@ static void xhci_mtk_quirks(struct device *dev, struct xhci_hcd *xhci)
+       xhci->quirks |= XHCI_SPURIOUS_SUCCESS;
+       if (mtk->lpm_support)
+               xhci->quirks |= XHCI_LPM_SUPPORT;
++      if (mtk->u2_lpm_disable)
++              xhci->quirks |= XHCI_HW_LPM_DISABLE;
+       /*
+        * MTK xHCI 0.96: PSA is 1 by default even if doesn't support stream,
+@@ -469,6 +471,7 @@ static int xhci_mtk_probe(struct platform_device *pdev)
+               return ret;
+       mtk->lpm_support = of_property_read_bool(node, "usb3-lpm-capable");
++      mtk->u2_lpm_disable = of_property_read_bool(node, "usb2-lpm-disable");
+       /* optional property, ignore the error if it does not exist */
+       of_property_read_u32(node, "mediatek,u3p-dis-msk",
+                            &mtk->u3p_dis_msk);
+diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h
+index cbb09dfea62e..080109012b9a 100644
+--- a/drivers/usb/host/xhci-mtk.h
++++ b/drivers/usb/host/xhci-mtk.h
+@@ -150,6 +150,7 @@ struct xhci_hcd_mtk {
+       struct phy **phys;
+       int num_phys;
+       bool lpm_support;
++      bool u2_lpm_disable;
+       /* usb remote wakeup */
+       bool uwk_en;
+       struct regmap *uwk;
+-- 
+2.30.2
+
diff --git a/queue-5.12/x86-boot-add-clang_flags-to-compressed-kbuild_cflags.patch b/queue-5.12/x86-boot-add-clang_flags-to-compressed-kbuild_cflags.patch
new file mode 100644 (file)
index 0000000..cab68cd
--- /dev/null
@@ -0,0 +1,47 @@
+From 35df8953855f805d732296fe09183fbcf967e30a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Mar 2021 17:04:34 -0700
+Subject: x86/boot: Add $(CLANG_FLAGS) to compressed KBUILD_CFLAGS
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+[ Upstream commit d5cbd80e302dfea59726c44c56ab7957f822409f ]
+
+When cross compiling x86 on an ARM machine with clang, there are several
+errors along the lines of:
+
+  arch/x86/include/asm/string_64.h:27:10: error: invalid output constraint '=&c' in asm
+
+This happens because the compressed boot Makefile reassigns KBUILD_CFLAGS
+and drops the clang flags that set the target architecture ('--target=')
+and the path to the GNU cross tools ('--prefix='), meaning that the host
+architecture is targeted.
+
+These flags are available as $(CLANG_FLAGS) from the main Makefile so
+add them to the compressed boot folder's KBUILD_CFLAGS so that cross
+compiling works as expected.
+
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Acked-by: Ard Biesheuvel <ardb@kernel.org>
+Link: https://lkml.kernel.org/r/20210326000435.4785-3-nathan@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/boot/compressed/Makefile | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
+index e0bc3988c3fa..6e5522aebbbd 100644
+--- a/arch/x86/boot/compressed/Makefile
++++ b/arch/x86/boot/compressed/Makefile
+@@ -46,6 +46,7 @@ KBUILD_CFLAGS += -D__DISABLE_EXPORTS
+ # Disable relocation relaxation in case the link is not PIE.
+ KBUILD_CFLAGS += $(call as-option,-Wa$(comma)-mrelax-relocations=no)
+ KBUILD_CFLAGS += -include $(srctree)/include/linux/hidden.h
++KBUILD_CFLAGS += $(CLANG_FLAGS)
+ # sev-es.c indirectly inludes inat-table.h which is generated during
+ # compilation and stored in $(objtree). Add the directory to the includes so
+-- 
+2.30.2
+
diff --git a/queue-5.12/x86-boot-compressed-64-check-sev-encryption-in-the-3.patch b/queue-5.12/x86-boot-compressed-64-check-sev-encryption-in-the-3.patch
new file mode 100644 (file)
index 0000000..f35f762
--- /dev/null
@@ -0,0 +1,137 @@
+From 2c622aeb46b16fd945fc681fec16b989940b826d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Mar 2021 13:38:23 +0100
+Subject: x86/boot/compressed/64: Check SEV encryption in the 32-bit boot-path
+
+From: Joerg Roedel <jroedel@suse.de>
+
+[ Upstream commit fef81c86262879d4b1176ef51a834c15b805ebb9 ]
+
+Check whether the hypervisor reported the correct C-bit when running
+as an SEV guest. Using a wrong C-bit position could be used to leak
+sensitive data from the guest to the hypervisor.
+
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Link: https://lkml.kernel.org/r/20210312123824.306-8-joro@8bytes.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/boot/compressed/head_64.S | 83 ++++++++++++++++++++++++++++++
+ 1 file changed, 83 insertions(+)
+
+diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S
+index e94874f4bbc1..f670e0579a3b 100644
+--- a/arch/x86/boot/compressed/head_64.S
++++ b/arch/x86/boot/compressed/head_64.S
+@@ -172,11 +172,21 @@ SYM_FUNC_START(startup_32)
+        */
+       call    get_sev_encryption_bit
+       xorl    %edx, %edx
++#ifdef        CONFIG_AMD_MEM_ENCRYPT
+       testl   %eax, %eax
+       jz      1f
+       subl    $32, %eax       /* Encryption bit is always above bit 31 */
+       bts     %eax, %edx      /* Set encryption mask for page tables */
++      /*
++       * Mark SEV as active in sev_status so that startup32_check_sev_cbit()
++       * will do a check. The sev_status memory will be fully initialized
++       * with the contents of MSR_AMD_SEV_STATUS later in
++       * set_sev_encryption_mask(). For now it is sufficient to know that SEV
++       * is active.
++       */
++      movl    $1, rva(sev_status)(%ebp)
+ 1:
++#endif
+       /* Initialize Page tables to 0 */
+       leal    rva(pgtable)(%ebx), %edi
+@@ -261,6 +271,9 @@ SYM_FUNC_START(startup_32)
+       movl    %esi, %edx
+ 1:
+ #endif
++      /* Check if the C-bit position is correct when SEV is active */
++      call    startup32_check_sev_cbit
++
+       pushl   $__KERNEL_CS
+       pushl   %eax
+@@ -786,6 +799,76 @@ SYM_DATA_START_LOCAL(loaded_image_proto)
+ SYM_DATA_END(loaded_image_proto)
+ #endif
++/*
++ * Check for the correct C-bit position when the startup_32 boot-path is used.
++ *
++ * The check makes use of the fact that all memory is encrypted when paging is
++ * disabled. The function creates 64 bits of random data using the RDRAND
++ * instruction. RDRAND is mandatory for SEV guests, so always available. If the
++ * hypervisor violates that the kernel will crash right here.
++ *
++ * The 64 bits of random data are stored to a memory location and at the same
++ * time kept in the %eax and %ebx registers. Since encryption is always active
++ * when paging is off the random data will be stored encrypted in main memory.
++ *
++ * Then paging is enabled. When the C-bit position is correct all memory is
++ * still mapped encrypted and comparing the register values with memory will
++ * succeed. An incorrect C-bit position will map all memory unencrypted, so that
++ * the compare will use the encrypted random data and fail.
++ */
++SYM_FUNC_START(startup32_check_sev_cbit)
++#ifdef CONFIG_AMD_MEM_ENCRYPT
++      pushl   %eax
++      pushl   %ebx
++      pushl   %ecx
++      pushl   %edx
++
++      /* Check for non-zero sev_status */
++      movl    rva(sev_status)(%ebp), %eax
++      testl   %eax, %eax
++      jz      4f
++
++      /*
++       * Get two 32-bit random values - Don't bail out if RDRAND fails
++       * because it is better to prevent forward progress if no random value
++       * can be gathered.
++       */
++1:    rdrand  %eax
++      jnc     1b
++2:    rdrand  %ebx
++      jnc     2b
++
++      /* Store to memory and keep it in the registers */
++      movl    %eax, rva(sev_check_data)(%ebp)
++      movl    %ebx, rva(sev_check_data+4)(%ebp)
++
++      /* Enable paging to see if encryption is active */
++      movl    %cr0, %edx                       /* Backup %cr0 in %edx */
++      movl    $(X86_CR0_PG | X86_CR0_PE), %ecx /* Enable Paging and Protected mode */
++      movl    %ecx, %cr0
++
++      cmpl    %eax, rva(sev_check_data)(%ebp)
++      jne     3f
++      cmpl    %ebx, rva(sev_check_data+4)(%ebp)
++      jne     3f
++
++      movl    %edx, %cr0      /* Restore previous %cr0 */
++
++      jmp     4f
++
++3:    /* Check failed - hlt the machine */
++      hlt
++      jmp     3b
++
++4:
++      popl    %edx
++      popl    %ecx
++      popl    %ebx
++      popl    %eax
++#endif
++      ret
++SYM_FUNC_END(startup32_check_sev_cbit)
++
+ /*
+  * Stack and heap for uncompression
+  */
+-- 
+2.30.2
+
diff --git a/queue-5.12/x86-build-propagate-clang_flags-to-realmode_flags.patch b/queue-5.12/x86-build-propagate-clang_flags-to-realmode_flags.patch
new file mode 100644 (file)
index 0000000..8a3bf83
--- /dev/null
@@ -0,0 +1,66 @@
+From a7383c36f9fe266eeb21568e9792c26bf05e55bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Mar 2021 17:04:33 -0700
+Subject: x86/build: Propagate $(CLANG_FLAGS) to $(REALMODE_FLAGS)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: John Millikin <john@john-millikin.com>
+
+[ Upstream commit 8abe7fc26ad8f28bfdf78adbed56acd1fa93f82d ]
+
+When cross-compiling with Clang, the `$(CLANG_FLAGS)' variable
+contains additional flags needed to build C and assembly sources
+for the target platform. Normally this variable is automatically
+included in `$(KBUILD_CFLAGS)' via the top-level Makefile.
+
+The x86 real-mode makefile builds `$(REALMODE_CFLAGS)' from a
+plain assignment and therefore drops the Clang flags. This causes
+Clang to not recognize x86-specific assembler directives:
+
+  arch/x86/realmode/rm/header.S:36:1: error: unknown directive
+  .type real_mode_header STT_OBJECT ; .size real_mode_header, .-real_mode_header
+  ^
+
+Explicit propagation of `$(CLANG_FLAGS)' to `$(REALMODE_CFLAGS)',
+which is inherited by real-mode make rules, fixes cross-compilation
+with Clang for x86 targets.
+
+Relevant flags:
+
+* `--target' sets the target architecture when cross-compiling. This
+  flag must be set for both compilation and assembly (`KBUILD_AFLAGS')
+  to support architecture-specific assembler directives.
+
+* `-no-integrated-as' tells clang to assemble with GNU Assembler
+  instead of its built-in LLVM assembler. This flag is set by default
+  unless `LLVM_IAS=1' is set, because the LLVM assembler can't yet
+  parse certain GNU extensions.
+
+Signed-off-by: John Millikin <john@john-millikin.com>
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Acked-by: Ard Biesheuvel <ardb@kernel.org>
+Tested-by: Sedat Dilek <sedat.dilek@gmail.com>
+Link: https://lkml.kernel.org/r/20210326000435.4785-2-nathan@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/Makefile | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/x86/Makefile b/arch/x86/Makefile
+index 9a85eae37b17..78faf9c7e3ae 100644
+--- a/arch/x86/Makefile
++++ b/arch/x86/Makefile
+@@ -33,6 +33,7 @@ REALMODE_CFLAGS += -ffreestanding
+ REALMODE_CFLAGS += -fno-stack-protector
+ REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -Wno-address-of-packed-member)
+ REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), $(cc_stack_align4))
++REALMODE_CFLAGS += $(CLANG_FLAGS)
+ export REALMODE_CFLAGS
+ # BITS is used as extension for files which are available in a 32 bit
+-- 
+2.30.2
+
diff --git a/queue-5.12/x86-sev-do-not-require-hypervisor-cpuid-bit-for-sev-.patch b/queue-5.12/x86-sev-do-not-require-hypervisor-cpuid-bit-for-sev-.patch
new file mode 100644 (file)
index 0000000..8ed0486
--- /dev/null
@@ -0,0 +1,154 @@
+From 24bf497ff8ae69e3564dcba13e4e4a68ceaf31b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Mar 2021 13:38:18 +0100
+Subject: x86/sev: Do not require Hypervisor CPUID bit for SEV guests
+
+From: Joerg Roedel <jroedel@suse.de>
+
+[ Upstream commit eab696d8e8b9c9d600be6fad8dd8dfdfaca6ca7c ]
+
+A malicious hypervisor could disable the CPUID intercept for an SEV or
+SEV-ES guest and trick it into the no-SEV boot path, where it could
+potentially reveal secrets. This is not an issue for SEV-SNP guests,
+as the CPUID intercept can't be disabled for those.
+
+Remove the Hypervisor CPUID bit check from the SEV detection code to
+protect against this kind of attack and add a Hypervisor bit equals zero
+check to the SME detection path to prevent non-encrypted guests from
+trying to enable SME.
+
+This handles the following cases:
+
+       1) SEV(-ES) guest where CPUID intercept is disabled. The guest
+          will still see leaf 0x8000001f and the SEV bit. It can
+          retrieve the C-bit and boot normally.
+
+       2) Non-encrypted guests with intercepted CPUID will check
+          the SEV_STATUS MSR and find it 0 and will try to enable SME.
+          This will fail when the guest finds MSR_K8_SYSCFG to be zero,
+          as it is emulated by KVM. But we can't rely on that, as there
+          might be other hypervisors which return this MSR with bit
+          23 set. The Hypervisor bit check will prevent that the guest
+          tries to enable SME in this case.
+
+       3) Non-encrypted guests on SEV capable hosts with CPUID intercept
+          disabled (by a malicious hypervisor) will try to boot into
+          the SME path. This will fail, but it is also not considered
+          a problem because non-encrypted guests have no protection
+          against the hypervisor anyway.
+
+ [ bp: s/non-SEV/non-encrypted/g ]
+
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Acked-by: Tom Lendacky <thomas.lendacky@amd.com>
+Link: https://lkml.kernel.org/r/20210312123824.306-3-joro@8bytes.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/boot/compressed/mem_encrypt.S |  6 -----
+ arch/x86/kernel/sev-es-shared.c        |  6 +----
+ arch/x86/mm/mem_encrypt_identity.c     | 35 ++++++++++++++------------
+ 3 files changed, 20 insertions(+), 27 deletions(-)
+
+diff --git a/arch/x86/boot/compressed/mem_encrypt.S b/arch/x86/boot/compressed/mem_encrypt.S
+index aa561795efd1..a6dea4e8a082 100644
+--- a/arch/x86/boot/compressed/mem_encrypt.S
++++ b/arch/x86/boot/compressed/mem_encrypt.S
+@@ -23,12 +23,6 @@ SYM_FUNC_START(get_sev_encryption_bit)
+       push    %ecx
+       push    %edx
+-      /* Check if running under a hypervisor */
+-      movl    $1, %eax
+-      cpuid
+-      bt      $31, %ecx               /* Check the hypervisor bit */
+-      jnc     .Lno_sev
+-
+       movl    $0x80000000, %eax       /* CPUID to check the highest leaf */
+       cpuid
+       cmpl    $0x8000001f, %eax       /* See if 0x8000001f is available */
+diff --git a/arch/x86/kernel/sev-es-shared.c b/arch/x86/kernel/sev-es-shared.c
+index cdc04d091242..387b71669818 100644
+--- a/arch/x86/kernel/sev-es-shared.c
++++ b/arch/x86/kernel/sev-es-shared.c
+@@ -186,7 +186,6 @@ void __init do_vc_no_ghcb(struct pt_regs *regs, unsigned long exit_code)
+        * make it accessible to the hypervisor.
+        *
+        * In particular, check for:
+-       *      - Hypervisor CPUID bit
+        *      - Availability of CPUID leaf 0x8000001f
+        *      - SEV CPUID bit.
+        *
+@@ -194,10 +193,7 @@ void __init do_vc_no_ghcb(struct pt_regs *regs, unsigned long exit_code)
+        * can't be checked here.
+        */
+-      if ((fn == 1 && !(regs->cx & BIT(31))))
+-              /* Hypervisor bit */
+-              goto fail;
+-      else if (fn == 0x80000000 && (regs->ax < 0x8000001f))
++      if (fn == 0x80000000 && (regs->ax < 0x8000001f))
+               /* SEV leaf check */
+               goto fail;
+       else if ((fn == 0x8000001f && !(regs->ax & BIT(1))))
+diff --git a/arch/x86/mm/mem_encrypt_identity.c b/arch/x86/mm/mem_encrypt_identity.c
+index 6c5eb6f3f14f..a19374d26101 100644
+--- a/arch/x86/mm/mem_encrypt_identity.c
++++ b/arch/x86/mm/mem_encrypt_identity.c
+@@ -503,14 +503,10 @@ void __init sme_enable(struct boot_params *bp)
+ #define AMD_SME_BIT   BIT(0)
+ #define AMD_SEV_BIT   BIT(1)
+-      /*
+-       * Set the feature mask (SME or SEV) based on whether we are
+-       * running under a hypervisor.
+-       */
+-      eax = 1;
+-      ecx = 0;
+-      native_cpuid(&eax, &ebx, &ecx, &edx);
+-      feature_mask = (ecx & BIT(31)) ? AMD_SEV_BIT : AMD_SME_BIT;
++
++      /* Check the SEV MSR whether SEV or SME is enabled */
++      sev_status   = __rdmsr(MSR_AMD64_SEV);
++      feature_mask = (sev_status & MSR_AMD64_SEV_ENABLED) ? AMD_SEV_BIT : AMD_SME_BIT;
+       /*
+        * Check for the SME/SEV feature:
+@@ -530,19 +526,26 @@ void __init sme_enable(struct boot_params *bp)
+       /* Check if memory encryption is enabled */
+       if (feature_mask == AMD_SME_BIT) {
++              /*
++               * No SME if Hypervisor bit is set. This check is here to
++               * prevent a guest from trying to enable SME. For running as a
++               * KVM guest the MSR_K8_SYSCFG will be sufficient, but there
++               * might be other hypervisors which emulate that MSR as non-zero
++               * or even pass it through to the guest.
++               * A malicious hypervisor can still trick a guest into this
++               * path, but there is no way to protect against that.
++               */
++              eax = 1;
++              ecx = 0;
++              native_cpuid(&eax, &ebx, &ecx, &edx);
++              if (ecx & BIT(31))
++                      return;
++
+               /* For SME, check the SYSCFG MSR */
+               msr = __rdmsr(MSR_K8_SYSCFG);
+               if (!(msr & MSR_K8_SYSCFG_MEM_ENCRYPT))
+                       return;
+       } else {
+-              /* For SEV, check the SEV MSR */
+-              msr = __rdmsr(MSR_AMD64_SEV);
+-              if (!(msr & MSR_AMD64_SEV_ENABLED))
+-                      return;
+-
+-              /* Save SEV_STATUS to avoid reading MSR again */
+-              sev_status = msr;
+-
+               /* SEV state cannot be controlled by a command line option */
+               sme_me_mask = me_mask;
+               sev_enabled = true;
+-- 
+2.30.2
+
diff --git a/queue-5.12/xhci-check-control-context-is-valid-before-dereferen.patch b/queue-5.12/xhci-check-control-context-is-valid-before-dereferen.patch
new file mode 100644 (file)
index 0000000..adea3bd
--- /dev/null
@@ -0,0 +1,42 @@
+From d66e6d53c47af7775b5f74e8db7fae6d573753e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Apr 2021 10:02:06 +0300
+Subject: xhci: check control context is valid before dereferencing it.
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+[ Upstream commit 597899d2f7c5619c87185ee7953d004bd37fd0eb ]
+
+Don't dereference ctrl_ctx before checking it's valid.
+Issue reported by Klockwork
+
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20210406070208.3406266-3-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.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
+index 1975016f46bf..5df780d55df0 100644
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -3269,6 +3269,14 @@ static void xhci_endpoint_reset(struct usb_hcd *hcd,
+       /* config ep command clears toggle if add and drop ep flags are set */
+       ctrl_ctx = xhci_get_input_control_ctx(cfg_cmd->in_ctx);
++      if (!ctrl_ctx) {
++              spin_unlock_irqrestore(&xhci->lock, flags);
++              xhci_free_command(xhci, cfg_cmd);
++              xhci_warn(xhci, "%s: Could not get input context, bad type.\n",
++                              __func__);
++              goto cleanup;
++      }
++
+       xhci_setup_input_ctx_for_config_ep(xhci, cfg_cmd->in_ctx, vdev->out_ctx,
+                                          ctrl_ctx, ep_flag, ep_flag);
+       xhci_endpoint_copy(xhci, cfg_cmd->in_ctx, vdev->out_ctx, ep_index);
+-- 
+2.30.2
+
diff --git a/queue-5.12/xhci-check-port-array-allocation-was-successful-befo.patch b/queue-5.12/xhci-check-port-array-allocation-was-successful-befo.patch
new file mode 100644 (file)
index 0000000..1b02aa9
--- /dev/null
@@ -0,0 +1,38 @@
+From 63bbf36e10e83ef492e3ac59a0ea574e22fb5149 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Apr 2021 10:02:05 +0300
+Subject: xhci: check port array allocation was successful before dereferencing
+ it
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+[ Upstream commit 8a157d2ff104d2849c58226a1fd02365d7d60150 ]
+
+return if rhub->ports is null after rhub->ports = kcalloc_node()
+Klockwork reported issue
+
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20210406070208.3406266-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-mem.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
+index 3708432f5f69..717c122f9449 100644
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -2249,6 +2249,9 @@ static void xhci_create_rhub_port_array(struct xhci_hcd *xhci,
+               return;
+       rhub->ports = kcalloc_node(rhub->num_ports, sizeof(*rhub->ports),
+                       flags, dev_to_node(dev));
++      if (!rhub->ports)
++              return;
++
+       for (i = 0; i < HCS_MAX_PORTS(xhci->hcs_params1); i++) {
+               if (xhci->hw_ports[i].rhub != rhub ||
+                   xhci->hw_ports[i].hcd_portnum == DUPLICATE_ENTRY)
+-- 
+2.30.2
+
diff --git a/queue-5.12/xhci-fix-potential-array-out-of-bounds-with-several-.patch b/queue-5.12/xhci-fix-potential-array-out-of-bounds-with-several-.patch
new file mode 100644 (file)
index 0000000..1ad3cbf
--- /dev/null
@@ -0,0 +1,54 @@
+From 70d135b6e929611731f2bf4468f8fdc9cb2a7e5b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Apr 2021 10:02:07 +0300
+Subject: xhci: fix potential array out of bounds with several interrupters
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+[ Upstream commit 286fd02fd54b6acab65809549cf5fb3f2a886696 ]
+
+The Max Interrupters supported by the controller is given in a 10bit
+wide bitfield, but the driver uses a fixed 128 size array to index these
+interrupters.
+
+Klockwork reports a possible array out of bounds case which in theory
+is possible. In practice this hasn't been hit as a common number of Max
+Interrupters for new controllers is 8, not even close to 128.
+
+This needs to be fixed anyway
+
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20210406070208.3406266-4-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.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
+index 5df780d55df0..6672c2f40303 100644
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -228,6 +228,7 @@ static void xhci_zero_64b_regs(struct xhci_hcd *xhci)
+       struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
+       int err, i;
+       u64 val;
++      u32 intrs;
+       /*
+        * Some Renesas controllers get into a weird state if they are
+@@ -266,7 +267,10 @@ static void xhci_zero_64b_regs(struct xhci_hcd *xhci)
+       if (upper_32_bits(val))
+               xhci_write_64(xhci, 0, &xhci->op_regs->cmd_ring);
+-      for (i = 0; i < HCS_MAX_INTRS(xhci->hcs_params1); i++) {
++      intrs = min_t(u32, HCS_MAX_INTRS(xhci->hcs_params1),
++                    ARRAY_SIZE(xhci->run_regs->ir_set));
++
++      for (i = 0; i < intrs; i++) {
+               struct xhci_intr_reg __iomem *ir;
+               ir = &xhci->run_regs->ir_set[i];
+-- 
+2.30.2
+
diff --git a/queue-5.12/xhci-prevent-double-fetch-of-transfer-and-transfer-e.patch b/queue-5.12/xhci-prevent-double-fetch-of-transfer-and-transfer-e.patch
new file mode 100644 (file)
index 0000000..700a982
--- /dev/null
@@ -0,0 +1,142 @@
+From f1286a76fa79da86c55a54b73416e4b60fca4627 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Apr 2021 10:02:08 +0300
+Subject: xhci: prevent double-fetch of transfer and transfer event TRBs
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+[ Upstream commit e9fcb07704fcef6fa6d0333fd2b3a62442eaf45b ]
+
+The same values are parsed several times from transfer and event
+TRBs by different functions in the same call path, all while processing
+one transfer event.
+
+As the TRBs are in DMA memory and can be accessed by the xHC host we want
+to avoid this to prevent double-fetch issues.
+
+To resolve this pass the already parsed values to the different functions
+in the path of parsing a transfer event
+
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20210406070208.3406266-5-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-ring.c | 42 ++++++++++++++++--------------------
+ 1 file changed, 19 insertions(+), 23 deletions(-)
+
+diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
+index ce38076901e2..59d41d2c200d 100644
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -2129,16 +2129,13 @@ int xhci_is_vendor_info_code(struct xhci_hcd *xhci, unsigned int trb_comp_code)
+       return 0;
+ }
+-static int finish_td(struct xhci_hcd *xhci, struct xhci_td *td,
+-      struct xhci_transfer_event *event, struct xhci_virt_ep *ep)
++static int finish_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep,
++                   struct xhci_ring *ep_ring, struct xhci_td *td,
++                   u32 trb_comp_code)
+ {
+       struct xhci_ep_ctx *ep_ctx;
+-      struct xhci_ring *ep_ring;
+-      u32 trb_comp_code;
+-      ep_ring = xhci_dma_to_transfer_ring(ep, le64_to_cpu(event->buffer));
+       ep_ctx = xhci_get_ep_ctx(xhci, ep->vdev->out_ctx, ep->ep_index);
+-      trb_comp_code = GET_COMP_CODE(le32_to_cpu(event->transfer_len));
+       switch (trb_comp_code) {
+       case COMP_STOPPED_LENGTH_INVALID:
+@@ -2234,9 +2231,9 @@ static int sum_trb_lengths(struct xhci_hcd *xhci, struct xhci_ring *ring,
+ /*
+  * Process control tds, update urb status and actual_length.
+  */
+-static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
+-      union xhci_trb *ep_trb, struct xhci_transfer_event *event,
+-      struct xhci_virt_ep *ep)
++static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep,
++              struct xhci_ring *ep_ring,  struct xhci_td *td,
++                         union xhci_trb *ep_trb, struct xhci_transfer_event *event)
+ {
+       struct xhci_ep_ctx *ep_ctx;
+       u32 trb_comp_code;
+@@ -2324,15 +2321,15 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
+               td->urb->actual_length = requested;
+ finish_td:
+-      return finish_td(xhci, td, event, ep);
++      return finish_td(xhci, ep, ep_ring, td, trb_comp_code);
+ }
+ /*
+  * Process isochronous tds, update urb packet status and actual_length.
+  */
+-static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
+-      union xhci_trb *ep_trb, struct xhci_transfer_event *event,
+-      struct xhci_virt_ep *ep)
++static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep,
++              struct xhci_ring *ep_ring, struct xhci_td *td,
++              union xhci_trb *ep_trb, struct xhci_transfer_event *event)
+ {
+       struct urb_priv *urb_priv;
+       int idx;
+@@ -2409,7 +2406,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
+       td->urb->actual_length += frame->actual_length;
+-      return finish_td(xhci, td, event, ep);
++      return finish_td(xhci, ep, ep_ring, td, trb_comp_code);
+ }
+ static int skip_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
+@@ -2441,17 +2438,15 @@ static int skip_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
+ /*
+  * Process bulk and interrupt tds, update urb status and actual_length.
+  */
+-static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
+-      union xhci_trb *ep_trb, struct xhci_transfer_event *event,
+-      struct xhci_virt_ep *ep)
++static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep,
++              struct xhci_ring *ep_ring, struct xhci_td *td,
++              union xhci_trb *ep_trb, struct xhci_transfer_event *event)
+ {
+       struct xhci_slot_ctx *slot_ctx;
+-      struct xhci_ring *ep_ring;
+       u32 trb_comp_code;
+       u32 remaining, requested, ep_trb_len;
+       slot_ctx = xhci_get_slot_ctx(xhci, ep->vdev->out_ctx);
+-      ep_ring = xhci_dma_to_transfer_ring(ep, le64_to_cpu(event->buffer));
+       trb_comp_code = GET_COMP_CODE(le32_to_cpu(event->transfer_len));
+       remaining = EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
+       ep_trb_len = TRB_LEN(le32_to_cpu(ep_trb->generic.field[2]));
+@@ -2511,7 +2506,8 @@ finish_td:
+                         remaining);
+               td->urb->actual_length = 0;
+       }
+-      return finish_td(xhci, td, event, ep);
++
++      return finish_td(xhci, ep, ep_ring, td, trb_comp_code);
+ }
+ /*
+@@ -2854,11 +2850,11 @@ static int handle_tx_event(struct xhci_hcd *xhci,
+               /* update the urb's actual_length and give back to the core */
+               if (usb_endpoint_xfer_control(&td->urb->ep->desc))
+-                      process_ctrl_td(xhci, td, ep_trb, event, ep);
++                      process_ctrl_td(xhci, ep, ep_ring, td, ep_trb, event);
+               else if (usb_endpoint_xfer_isoc(&td->urb->ep->desc))
+-                      process_isoc_td(xhci, td, ep_trb, event, ep);
++                      process_isoc_td(xhci, ep, ep_ring, td, ep_trb, event);
+               else
+-                      process_bulk_intr_td(xhci, td, ep_trb, event, ep);
++                      process_bulk_intr_td(xhci, ep, ep_ring, td, ep_trb, event);
+ cleanup:
+               handling_skipped_tds = ep->skip &&
+                       trb_comp_code != COMP_MISSED_SERVICE_ERROR &&
+-- 
+2.30.2
+